diff --git a/libs/remixd/src/services/foundryClient.ts b/libs/remixd/src/services/foundryClient.ts index 85b5a9319b..b7b49fbea0 100644 --- a/libs/remixd/src/services/foundryClient.ts +++ b/libs/remixd/src/services/foundryClient.ts @@ -46,6 +46,7 @@ export class FoundryClient extends PluginClient { listenOnFoundryFolder() { try { + if(this.watcher) this.watcher.close() this.watcher = chokidar.watch(this.currentSharedFolder, { depth: 1, ignorePermissionErrors: true, ignoreInitial: true }) // watch for new folders this.watcher.on('addDir', () => { @@ -86,7 +87,6 @@ export class FoundryClient extends PluginClient { } checkPath() { - console.log('checkPath', fs.existsSync(this.buildPath), fs.existsSync(this.cachePath), fs.existsSync(join(this.cachePath, 'solidity-files-cache.json'))) if (!fs.existsSync(this.buildPath) || !fs.existsSync(this.cachePath)) { this.listenOnFoundryFolder() return false @@ -119,8 +119,9 @@ export class FoundryClient extends PluginClient { clearTimeout(this.logTimeout) this.logTimeout = setTimeout(() => { // @ts-ignore - this.call('terminal', 'log', { type: 'log', value: 'receiving compilation result from Foundry' }), 1000 - }) + this.call('terminal', 'log', { type: 'log', value: 'receiving compilation result from Foundry' }) + console.log('Syncing compilation result from Foundry') + }, 1000) } catch (e) { console.log(e) diff --git a/libs/remixd/src/services/hardhatClient.ts b/libs/remixd/src/services/hardhatClient.ts index 6207cdb091..e3d198156a 100644 --- a/libs/remixd/src/services/hardhatClient.ts +++ b/libs/remixd/src/services/hardhatClient.ts @@ -13,6 +13,8 @@ export class HardhatClient extends PluginClient { watcher: chokidar.FSWatcher warnLog: boolean buildPath: string + logTimeout: NodeJS.Timeout + processingTimeout: NodeJS.Timeout constructor(private readOnly = false) { super() @@ -30,14 +32,14 @@ export class HardhatClient extends PluginClient { sharedFolder(currentSharedFolder: string): void { this.currentSharedFolder = currentSharedFolder this.buildPath = utils.absolutePath('artifacts/contracts', this.currentSharedFolder) - if(fs.existsSync(this.buildPath)) { + if (fs.existsSync(this.buildPath)) { this.listenOnHardhatCompilation() - }else{ + } else { console.log('Hardhat artifacts folder doesn\'t exist... waiting for the first compilation.') console.log('If you are using Hardhat, run `npx hardhat compile` or run the compilation with `Enable Hardhat Compilation` checked from the Remix IDE.') this.listenOnHardHatFolder() } - + } compile(configPath: string) { @@ -67,7 +69,16 @@ export class HardhatClient extends PluginClient { }) } + checkPath() { + if (!fs.existsSync(this.buildPath)) { + this.listenOnHardHatFolder() + return false + } + return true + } + private async processArtifact() { + if (!this.checkPath()) return // resolving the files const folderFiles = await fs.readdir(this.buildPath) const targetsSynced = [] @@ -111,18 +122,27 @@ export class HardhatClient extends PluginClient { } } } - if (!this.warnLog) { - this.call('terminal', 'log', { value: 'receiving compilation result from Hardhat', type: 'log'} ) - this.warnLog = true - } - if (targetsSynced.length) { - console.log(`Processing artifacts for files: ${[...new Set(targetsSynced)].join(', ')}`) - this.call('terminal', 'log', { type: 'log', value: `synced with Hardhat: ${[...new Set(targetsSynced)].join(', ')}` }) - } + + clearTimeout(this.logTimeout) + this.logTimeout = setTimeout(() => { + this.call('terminal', 'log', { value: 'receiving compilation result from Hardhat', type: 'log' }) + if (targetsSynced.length) { + console.log(`Processing artifacts for files: ${[...new Set(targetsSynced)].join(', ')}`) + // @ts-ignore + this.call('terminal', 'log', { type: 'log', value: `synced with Hardhat: ${[...new Set(targetsSynced)].join(', ')}` }) + } else { + console.log('No artifacts to process') + // @ts-ignore + this.call('terminal', 'log', { type: 'log', value: 'No artifacts from Hardhat to process' }) + } + }, 1000) + + } listenOnHardHatFolder() { try { + this.watcher = chokidar.watch(this.currentSharedFolder, { depth: 1, ignorePermissionErrors: true, ignoreInitial: true }) // watch for new folders this.watcher.on('addDir', () => { @@ -135,15 +155,21 @@ export class HardhatClient extends PluginClient { } } + async triggerProcessArtifact() { + // prevent multiple calls + clearTimeout(this.processingTimeout) + this.processingTimeout = setTimeout(async () => await this.processArtifact(), 1000) + } + listenOnHardhatCompilation() { try { console.log('listening on Hardhat compilation...') this.watcher = chokidar.watch(this.buildPath, { depth: 1, ignorePermissionErrors: true, ignoreInitial: true }) - this.watcher.on('change', () => this.processArtifact()) - this.watcher.on('add', () => this.processArtifact()) + this.watcher.on('change', async () => await this.triggerProcessArtifact()) + this.watcher.on('add', async () => await this.triggerProcessArtifact()) // process the artifact on activation - setTimeout(() => this.processArtifact(), 1000) + this.processArtifact() } catch (e) { console.log(e) } @@ -151,14 +177,7 @@ export class HardhatClient extends PluginClient { async sync() { console.log('syncing from Hardhat') - if(fs.existsSync(this.buildPath)) { - this.processArtifact() - }else{ - console.log('No compilation result found') - this.listenOnHardHatFolder() - // ts-ignore - this.call('terminal', 'log', { type: 'log', value: 'No compilation result found' }) - } + this.processArtifact() } async feedContractArtifactFile(artifactContent, compilationResultPart) { diff --git a/libs/remixd/src/services/truffleClient.ts b/libs/remixd/src/services/truffleClient.ts index e1a998c8aa..b11d4f8bf1 100644 --- a/libs/remixd/src/services/truffleClient.ts +++ b/libs/remixd/src/services/truffleClient.ts @@ -13,13 +13,15 @@ export class TruffleClient extends PluginClient { watcher: chokidar.FSWatcher warnLog: boolean buildPath: string + logTimeout: NodeJS.Timeout + processingTimeout: NodeJS.Timeout - constructor (private readOnly = false) { + constructor(private readOnly = false) { super() this.methods = ['compile', 'sync'] } - setWebSocket (websocket: WS): void { + setWebSocket(websocket: WS): void { this.websocket = websocket this.websocket.addEventListener('close', () => { this.warnLog = false @@ -27,18 +29,19 @@ export class TruffleClient extends PluginClient { }) } - sharedFolder (currentSharedFolder: string): void { + sharedFolder(currentSharedFolder: string): void { this.currentSharedFolder = currentSharedFolder this.buildPath = utils.absolutePath('build/contracts', this.currentSharedFolder) if (fs.existsSync(this.buildPath)) { - this.listenOnTruffleCompilation()} + this.listenOnTruffleCompilation() + } else { console.log('Truffle build folder doesn\'t exist... waiting for the first compilation.') this.listenOnTruffleFolder() } } - listenOnTruffleFolder () { + listenOnTruffleFolder() { try { this.watcher = chokidar.watch(this.currentSharedFolder, { depth: 1, ignorePermissionErrors: true, ignoreInitial: true }) // watch for new folders @@ -52,7 +55,7 @@ export class TruffleClient extends PluginClient { } } - compile (configPath: string) { + compile(configPath: string) { return new Promise((resolve, reject) => { if (this.readOnly) { const errMsg = '[Truffle Compilation]: Cannot compile in read-only mode' @@ -79,8 +82,19 @@ export class TruffleClient extends PluginClient { }) } - private async processArtifact () { - const folderFiles = await fs.readdir(this.buildPath) + checkPath() { + if (!fs.existsSync(this.buildPath)) { + this.listenOnTruffleFolder() + return false + } + return true + } + + + private async processArtifact() { + if (!this.checkPath()) return + const folderFiles = await fs.readdir(this.buildPath) + const filesFound = folderFiles.filter(file => file.endsWith('.json')) // name of folders are file names for (const file of folderFiles) { if (file.endsWith('.json')) { @@ -98,27 +112,38 @@ export class TruffleClient extends PluginClient { this.emit('compilationFinished', compilationResult.compilationTarget, { sources: compilationResult.input }, 'soljson', compilationResult.output, compilationResult.solcVersion) } } - if (!this.warnLog) { - // @ts-ignore - this.call('terminal', 'log', { type: 'log', value: 'receiving compilation result from Truffle' }) - this.warnLog = true - } + clearTimeout(this.logTimeout) + this.logTimeout = setTimeout(() => { + if (filesFound.length === 0) { + // @ts-ignore + this.call('terminal', 'log', { value: 'No contract found in the Truffle build folder', type: 'log' }) + } else { + // @ts-ignore + this.call('terminal', 'log', { value: 'receiving compilation result from Truffle', type: 'log' }) + } + }, 1000) + } + + async triggerProcessArtifact() { + // prevent multiple calls + clearTimeout(this.processingTimeout) + this.processingTimeout = setTimeout(async () => await this.processArtifact(), 1000) } - listenOnTruffleCompilation () { - try { + listenOnTruffleCompilation() { + try { this.watcher = chokidar.watch(this.buildPath, { depth: 3, ignorePermissionErrors: true, ignoreInitial: true }) - - this.watcher.on('change', async (f: string) => this.processArtifact()) - this.watcher.on('add', async (f: string) => this.processArtifact()) + + this.watcher.on('change', async () => await this.triggerProcessArtifact()) + this.watcher.on('add', async () => await this.triggerProcessArtifact()) // process the artifact on activation - setTimeout(() => this.processArtifact(), 1000) + this.triggerProcessArtifact() } catch (e) { console.log(e) - } + } } - async feedContractArtifactFile (path, content, compilationResultPart) { + async feedContractArtifactFile(path, content, compilationResultPart) { const contentJSON = JSON.parse(content) const contractName = basename(path).replace('.json', '') compilationResultPart.solcVersion = contentJSON.compiler.version @@ -129,10 +154,10 @@ export class TruffleClient extends PluginClient { // extract data const relPath = utils.relativePath(filepath, this.currentSharedFolder) if (!compilationResultPart.output['sources'][relPath]) compilationResultPart.output['sources'][relPath] = {} - + const location = contentJSON.ast.src.split(':') const id = parseInt(location[location.length - 1]) - + compilationResultPart.output['sources'][relPath] = { ast: contentJSON.ast, id @@ -156,17 +181,7 @@ export class TruffleClient extends PluginClient { } } - async sync () { - if (fs.existsSync(this.buildPath)) { - console.log('syncing from Truffle') - this.processArtifact() - // @ts-ignore - this.call('terminal', 'log', { type: 'log', value: 'synced with Truffle' }) - }else{ - console.log('Truffle build folder doesn\'t exist... waiting for the first compilation.') - this.listenOnTruffleFolder() - // @ts-ignore - this.call('terminal', 'log', { type: 'log', value: 'Truffle build folder doesn\'t exist... waiting for the first compilation.' }) - } + async sync() { + this.processArtifact() } }