e', (eventType, fileName) => { // `fileName` can be `null` if it cannot be determined. See // https://github.com/nodejs/node/pull/49891#issuecomment-1744673430. this.#onChange(recursive ? resolve(path, fileName ?? '') : path, eventType); }); this.#watchers.set(path, { handle: watcher, recursive }); if (recursive) { this.#removeWatchedChildren(path); } } filterFile(file, owner) { if (!file) return; if (supportsRecursiveWatching) { this.watchPath(dirname(file)); } else { // Having multiple FSWatcher's seems to be slower // than a single recursive FSWatcher this.watchPath(file, false); } this.#filteredFiles.add(file); if (owner) { const owners = this.#dependencyOwners.get(file) ?? new SafeSet(); const dependencies = this.#ownerDependencies.get(file) ?? new SafeSet(); owners.add(owner); dependencies.add(file); this.#dependencyOwners.set(file, owners); this.#ownerDependencies.set(owner, dependencies); } } #setupIPC(child) { const handlers = { __proto__: null, parentToChild: (message) => child.send(message), childToParent: (message) => process.send(message), }; this.#ipcHandlers.set(child, handlers); process.on('message', handlers.parentToChild); child.on('message', handlers.childToParent); } destroyIPC(child) { const handlers = this.#ipcHandlers.get(child); if (this.#passthroughIPC && handlers !== undefined) { process.off('message', handlers.parentToChild); child.off('message', handlers.childToParent); } } watchChildProcessModules(child, key = null) { if (this.#passthroughIPC) { this.#setupIPC(child); } child.on('message', (message) => { try { if (ArrayIsArray(message['watch:require'])) { ArrayPrototypeForEach(message['watch:require'], (file) => this.filterFile(file, key)); } if (ArrayIsArray(message['watch:import'])) { ArrayPrototypeForEach(message['watch:import'], (file) => this.filterFile(fileURLToPath(file), key)); } } catch { // Failed watching file. ignore } }); } unfilterFilesOwnedBy(owners) { owners.forEach((owner) => { this.#ownerDependencies.get(owner)?.forEach((dependency) => { this.#filteredFiles.delete(dependency); this.#dependencyOwners.get(dependency)?.delete(owner); if (this.#dependencyOwners.get(dependency)?.size === 0) { this.#dependencyOwners.delete(dependency); } }); this.#filteredFiles.delete(owner); this.#dependencyOwners.delete(owner); this.#ownerDependencies.delete(owner); }); } clearFileFilters() { this.#filteredFiles.clear(); } clear() { this.#watchers.forEach(this.#unwatch); this.#watchers.clear(); this.#filteredFiles.clear(); this.#dependencyOwners.clear(); this.#ownerDependencies.clear(); } } module.exports = { FilesWatcher };