/* IMPORT */ import path from 'node:path'; import { DEBOUNCE, DEPTH, LIMIT, HAS_NATIVE_RECURSION, IS_WINDOWS } from './constants.js'; import { FSTargetEvent, FSWatcherEvent, TargetEvent } from './enums.js'; import Utils from './utils.js'; /* MAIN */ class WatcherHandler { /* CONSTRUCTOR */ constructor(watcher, config, base) { this.base = base; this.watcher = watcher; this.handler = config.handler; this.fswatcher = config.watcher; this.options = config.options; this.folderPath = config.folderPath; this.filePath = config.filePath; this.handlerBatched = this.base ? this.base.onWatcherEvent.bind(this.base) : this._makeHandlerBatched(this.options.debounce); //UGLY } /* HELPERS */ _isSubRoot(targetPath) { if (this.filePath) { return targetPath === this.filePath; } else { return targetPath === this.folderPath || Utils.fs.isSubPath(this.folderPath, targetPath); } } _makeHandlerBatched(delay = DEBOUNCE) { return (() => { let lock = this.watcher._readyWait; // ~Ensuring no two flushes are active in parallel, or before the watcher is ready let initials = []; let regulars = new Set(); const flush = async (initials, regulars) => { const initialEvents = this.options.ignoreInitial ? [] : initials; const regularEvents = await this.eventsPopulate([...regulars]); const events = this.eventsDeduplicate([...initialEvents, ...regularEvents]); this.onTargetEvents(events); }; const flushDebounced = Utils.lang.debounce(() => { if (this.watcher.isClosed()) return; lock = flush(initials, regulars); initials = []; regulars = new Set(); }, delay); return async (event, targetPath = '', isInitial = false) => { if (isInitial) { // Poll immediately await this.eventsPopulate([targetPath], initials, true); } else { // Poll later regulars.add(targetPath); } lock.then(flushDebounced); }; })(); } /* EVENT HELPERS */ eventsDeduplicate(events) { if (events.length < 2) return events; const targetsEventPrev = {}; return events.reduce((acc, event) => { const [targetEvent, targetPath] = event; const targetEventPrev = targetsEventPrev[targetPath]; if (targetEvent === targetEventPrev) return acc; // Same event, ignoring if (targetEvent === TargetEvent.CHANGE && targetEventPrev === TargetEvent.ADD) return acc; // "change" after "add", ignoring targetsEventPrev[targetPath] = targetEvent; acc.push(event); return acc; }, []); } async eventsPopulate(targetPaths, events = [], isInitial = false) { await Promise.all(targetPaths.map(async (targetPath) => { const targetEvents = await this.watcher._poller.update(targetPath, this.options.pollingTimeout); await Promise.all(targetEvents.map(async (event) => { events.push([event, targetPath]); if (event === TargetEvent.ADD_DIR) { await this.eventsPopulateAddDir(targetPaths, targetPath, events, isInitial); } else if (event === TargetEvent.UNLINK_DIR) { await this.eventsPopulateUnlinkDir(targetPaths, targetPath, events, isInitial); } })); })); return events; } ; async eventsPopulateAddDir(targetPaths, targetPath, events = [], isInitial = false) { if (isInitial) return events; const depth = this.options.recursive ? this.options.depth ?? DEPTH : Math.min(1, this.options.depth ?? DEPTH); const limit = this.options.limit ?? LIMIT; const [directories, files] = await Utils.fs.readdir(targetPath, this.options.ignore, depth, limit, this.watcher._closeSignal); const targetSubPaths = [...directories, ...files]; await Promise.all(targetSubPaths.map(targetSubPath => { if (this.watcher.isIgnored(targetSubPath, this.options.ignore)) return; if (targetPaths.includes(targetSubPath)) return; return this.eventsPopulate([targetSubPath], events, true); })); return events; } async eventsPopulateUnlinkDir(targetPaths, targetPath, events = [], isInitial = false) { if (isInitial) return events; for (const folderPathOther of this.watcher._poller.stats.keys()) { if (!Utils.fs.isSubPath(targetPath, folderPathOther)) continue; if (targetPaths.includes(folderPathOther)) continue; await this.eventsPopulate([folderPathOther], events, true); } return events; } /* EVENT HANDLERS */ onTargetAdd(targetPath) { if (this._isSubRoot(targetPath)) { if (this.options.renameDetection) { this.watcher._locker.getLockTargetAdd(targetPath, this.options.renameTimeout); } else { this.watcher.event(TargetEvent.ADD, targetPath); } } } onTargetAddDir(targetPath) { if (targetPath !== this.folderPath && this.options.recursive && (!HAS_NATIVE_RECURSION && this.options.native !== false)) { this.watcher.watchDirectory(targetPath, this.options, this.handler, undefined, this.base || this); } if (this._isSubRoot(targetPath)) { if (this.options.renameDetection) { this.watcher._locker.getLockTargetAddDir(targetPath, this.options.renameTimeout); } else { this.watcher.event(TargetEvent.ADD_DIR, targetPath); } } } onTargetChange(targetPath) { if (this._isSubRoot(targetPath)) { this.watcher.event(TargetEvent.CHANGE, targetPath); } } onTargetUnlink(targetPath) { this.watcher.watchersClose(path.dirname(targetPath), targetPath, false); if (this._isSubRoot(targetPath)) { if (this.options.renameDetection) { this.watcher._locker.getLockTargetUnlink(targetPath, this.options.renameTimeout); } else { this.watcher.event(TargetEvent.UNLINK, targetPath); } } } onTargetUnlinkDir(targetPath) { this.watcher.watchersClose(path.dirname(targetPath), targetPath, false); this.watcher.watchersClose(targetPath); if (this._isSubRoot(targetPath)) { if (this.options.renameDetection) { this.watcher._locker.getLockTargetUnlinkDir(targetPath, this.options.renameTimeout); } else { this.watcher.event(TargetEvent.UNLINK_DIR, targetPath); } } } onTargetEvent(event) { const [targetEvent, targetPath] = event; if (targetEvent === TargetEvent.ADD) { this.onTargetAdd(targetPath); } else if (targetEvent === TargetEvent.ADD_DIR) { this.onTargetAddDir(targetPath); } else if (targetEvent === TargetEvent.CHANGE) { this.onTargetChange(targetPath); } else if (targetEvent === TargetEvent.UNLINK) { this.onTargetUnlink(targetPath); } else if (targetEvent === TargetEvent.UNLINK_DIR) { this.onTargetUnlinkDir(targetPath); } } onTargetEvents(events) { for (const event of events) { this.onTargetEvent(event); } } onWatcherEvent(event, targetPath, isInitial = false) { return this.handlerBatched(event, targetPath, isInitial); } onWatcherChange(event = FSTargetEvent.CHANGE, targetName) { if (this.watcher.isClosed()) return; const targetPath = path.resolve(this.folderPath, targetName || ''); if (this.filePath && targetPath !== this.folderPath && targetPath !== this.filePath) return; if (this.watcher.isIgnored(targetPath, this.options.ignore)) return; this.onWatcherEvent(event, targetPath); } onWatcherError(error) { if (IS_WINDOWS && error.code === 'EPERM') { // This may happen when a folder is deleted this.onWatcherChange(FSTargetEvent.CHANGE, ''); } else { this.watcher.error(error); } } /* API */ async init() { await this.initWatcherEvents(); await this.initInitialEvents(); } async initWatcherEvents() { const onChange = this.onWatcherChange.bind(this); this.fswatcher.on(FSWatcherEvent.CHANGE, onChange); const onError = this.onWatcherError.bind(this); this.fswatcher.on(FSWatcherEvent.ERROR, onError); } async initInitialEvents() { const isInitial = !this.watcher.isReady(); // "isInitial" => is ignorable via the "ignoreInitial" option if (this.filePath) { // Single initial path if (this.watcher._poller.stats.has(this.filePath)) return; // Already polled await this.onWatcherEvent(FSTargetEvent.CHANGE, this.filePath, isInitial); } else { // Multiple initial paths const depth = this.options.recursive && (HAS_NATIVE_RECURSION && this.options.native !== false) ? this.options.depth ?? DEPTH : Math.min(1, this.options.depth ?? DEPTH); const limit = this.options.limit ?? LIMIT; const [directories, files] = await Utils.fs.readdir(this.folderPath, this.options.ignore, depth, limit, this.watcher._closeSignal, this.options.readdirMap); const targetPaths = [this.folderPath, ...directories, ...files]; await Promise.all(targetPaths.map(targetPath => { if (this.watcher._poller.stats.has(targetPath)) return; // Already polled if (this.watcher.isIgnored(targetPath, this.options.ignore)) return; return this.onWatcherEvent(FSTargetEvent.CHANGE, targetPath, isInitial); })); } } } /* EXPORT */ export default WatcherHandler; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2F0Y2hlcl9oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvd2F0Y2hlcl9oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLFlBQVk7QUFFWixPQUFPLElBQUksTUFBTSxXQUFXLENBQUM7QUFDN0IsT0FBTyxFQUFDLFFBQVEsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLG9CQUFvQixFQUFFLFVBQVUsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQ3hGLE9BQU8sRUFBQyxhQUFhLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBQyxNQUFNLFlBQVksQ0FBQztBQUN0RSxPQUFPLEtBQUssTUFBTSxZQUFZLENBQUM7QUFJL0IsVUFBVTtBQUVWLE1BQU0sY0FBYztJQWFsQixpQkFBaUI7SUFFakIsWUFBYyxPQUFnQixFQUFFLE1BQXFCLEVBQUUsSUFBcUI7UUFFMUUsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDO1FBQzlCLElBQUksQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQztRQUNoQyxJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUM7UUFDOUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDO1FBQ3BDLElBQUksQ0FBQyxRQUFRLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQztRQUVoQyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBRyxJQUFJLENBQUMsSUFBSSxDQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBRSxD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