| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,17 +19,18 @@ const { addAbortListener } = require('internal/events/abort_listener'); | |||
| 19 | 19 | const { watch } = require('fs'); | |
| 20 | 20 | const { fileURLToPath } = require('internal/url'); | |
| 21 | 21 | const { resolve, dirname } = require('path'); | |
| 22 | - const { setTimeout } = require('timers'); | ||
| 22 | + const { setTimeout, clearTimeout } = require('timers'); | ||
| 23 | 23 | ||
| 24 | 24 | const supportsRecursiveWatching = process.platform === 'win32' || | |
| 25 | 25 | process.platform === 'darwin'; | |
| 26 | 26 | ||
| 27 | 27 | class FilesWatcher extends EventEmitter { | |
| 28 | 28 | #watchers = new SafeMap(); | |
| 29 | 29 | #filteredFiles = new SafeSet(); | |
| 30 | - #debouncing = new SafeSet(); | ||
| 31 | 30 | #depencencyOwners = new SafeMap(); | |
| 32 | 31 | #ownerDependencies = new SafeMap(); | |
| 32 | + #debounceOwners = new SafeSet(); | ||
| 33 | + #debounceTimer; | ||
| 33 | 34 | #debounce; | |
| 34 | 35 | #mode; | |
| 35 | 36 | #signal; | |
@@ -80,17 +81,20 @@ class FilesWatcher extends EventEmitter { | |||
| 80 | 81 | } | |
| 81 | 82 | ||
| 82 | 83 | #onChange(trigger) { | |
| 83 | - if (this.#debouncing.has(trigger)) { | ||
| 84 | - return; | ||
| 85 | - } | ||
| 86 | 84 | if (this.#mode === 'filter' && !this.#filteredFiles.has(trigger)) { | |
| 87 | 85 | return; | |
| 88 | 86 | } | |
| 89 | - this.#debouncing.add(trigger); | ||
| 90 | 87 | const owners = this.#depencencyOwners.get(trigger); | |
| 91 | - setTimeout(() => { | ||
| 92 | - this.#debouncing.delete(trigger); | ||
| 93 | - this.emit('changed', { owners }); | ||
| 88 | + if (owners) { | ||
| 89 | + for (const owner of owners) { | ||
| 90 | + this.#debounceOwners.add(owner); | ||
| 91 | + } | ||
| 92 | + } | ||
| 93 | + clearTimeout(this.#debounceTimer); | ||
| 94 | + this.#debounceTimer = setTimeout(() => { | ||
| 95 | + this.#debounceTimer = null; | ||
| 96 | + this.emit('changed', { owners: this.#debounceOwners }); | ||
| 97 | + this.#debounceOwners.clear(); | ||
| 94 | 98 | }, this.#debounce).unref(); | |
| 95 | 99 | } | |
| 96 | 100 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -70,6 +70,29 @@ describe('watch mode file watcher', () => { | |||
| 70 | 70 | assert.ok(changesCount < 5); | |
| 71 | 71 | }); | |
| 72 | 72 | ||
| 73 | + it('should debounce changes on multiple files', async () => { | ||
| 74 | + const files = []; | ||
| 75 | + for (let i = 0; i < 10; i++) { | ||
| 76 | + const file = tmpdir.resolve(`file-debounced-${i}`); | ||
| 77 | + writeFileSync(file, 'written'); | ||
| 78 | + watcher.filterFile(file); | ||
| 79 | + files.push(file); | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + files.forEach((file) => writeFileSync(file, '1')); | ||
| 83 | + files.forEach((file) => writeFileSync(file, '2')); | ||
| 84 | + files.forEach((file) => writeFileSync(file, '3')); | ||
| 85 | + files.forEach((file) => writeFileSync(file, '4')); | ||
| 86 | + | ||
| 87 | + await setTimeout(200); // debounce * 2 | ||
| 88 | + files.forEach((file) => writeFileSync(file, '5')); | ||
| 89 | + const changed = once(watcher, 'changed'); | ||
| 90 | + files.forEach((file) => writeFileSync(file, 'after')); | ||
| 91 | + await changed; | ||
| 92 | + // Unfortunately testing that changesCount === 2 is flaky | ||
| 93 | + assert.ok(changesCount < 5); | ||
| 94 | + }); | ||
| 95 | + | ||
| 73 | 96 | it('should ignore files in watched directory if they are not filtered', | |
| 74 | 97 | { skip: !supportsRecursiveWatching }, async () => { | |
| 75 | 98 | watcher.on('changed', common.mustNotCall()); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments