diff --git a/packages/metro-file-map/src/watchers/FSEventsWatcher.js b/packages/metro-file-map/src/watchers/FSEventsWatcher.js index a0e9d7f70..0b11ddf07 100644 --- a/packages/metro-file-map/src/watchers/FSEventsWatcher.js +++ b/packages/metro-file-map/src/watchers/FSEventsWatcher.js @@ -40,12 +40,6 @@ const DELETE_EVENT = 'delete'; const ADD_EVENT = 'add'; const ALL_EVENT = 'all'; -type FsEventsWatcherEvent = - | typeof CHANGE_EVENT - | typeof DELETE_EVENT - | typeof ADD_EVENT - | typeof ALL_EVENT; - /** * Export `FSEventsWatcher` class. * Watches `dir`. @@ -168,10 +162,10 @@ export default class FSEventsWatcher extends EventEmitter { }; if (this._tracked.has(filepath)) { - this._emit(CHANGE_EVENT, relativePath, metadata); + this._emit({event: CHANGE_EVENT, relativePath, metadata}); } else { this._tracked.add(filepath); - this._emit(ADD_EVENT, relativePath, metadata); + this._emit({event: ADD_EVENT, relativePath, metadata}); } } catch (error) { if (error?.code !== 'ENOENT') { @@ -184,7 +178,7 @@ export default class FSEventsWatcher extends EventEmitter { return; } - this._emit(DELETE_EVENT, relativePath); + this._emit({event: DELETE_EVENT, relativePath}); this._tracked.delete(filepath); } } @@ -192,13 +186,23 @@ export default class FSEventsWatcher extends EventEmitter { /** * Emit events. */ - _emit( - type: FsEventsWatcherEvent, - file: string, - metadata?: ChangeEventMetadata, - ) { - this.emit(type, file, this.root, metadata); - this.emit(ALL_EVENT, type, file, this.root, metadata); + _emit({ + event, + relativePath, + metadata, + }: + | { + event: 'change' | 'add', + relativePath: string, + metadata: ChangeEventMetadata, + } + | { + event: 'delete', + relativePath: string, + metadata?: void, + }) { + this.emit(event, relativePath, this.root, metadata); + this.emit(ALL_EVENT, event, relativePath, this.root, metadata); } getPauseReason(): ?string { diff --git a/packages/metro-file-map/src/watchers/NodeWatcher.js b/packages/metro-file-map/src/watchers/NodeWatcher.js index 183d99b1d..59e9e556d 100644 --- a/packages/metro-file-map/src/watchers/NodeWatcher.js +++ b/packages/metro-file-map/src/watchers/NodeWatcher.js @@ -298,19 +298,27 @@ module.exports = class NodeWatcher extends EventEmitter { path.resolve(this.root, relativePath), (dir, stats) => { if (this._watchdir(dir)) { - this._emitEvent(ADD_EVENT, path.relative(this.root, dir), { - modifiedTime: stats.mtime.getTime(), - size: stats.size, - type: 'd', + this._emitEvent({ + event: ADD_EVENT, + relativePath: path.relative(this.root, dir), + metadata: { + modifiedTime: stats.mtime.getTime(), + size: stats.size, + type: 'd', + }, }); } }, (file, stats) => { if (this._register(file, 'f')) { - this._emitEvent(ADD_EVENT, path.relative(this.root, file), { - modifiedTime: stats.mtime.getTime(), - size: stats.size, - type: 'f', + this._emitEvent({ + event: ADD_EVENT, + relativePath: path.relative(this.root, file), + metadata: { + modifiedTime: stats.mtime.getTime(), + size: stats.size, + type: 'f', + }, }); } }, @@ -338,10 +346,10 @@ module.exports = class NodeWatcher extends EventEmitter { type, }; if (registered) { - this._emitEvent(CHANGE_EVENT, relativePath, metadata); + this._emitEvent({event: CHANGE_EVENT, relativePath, metadata}); } else { if (this._register(fullPath, type)) { - this._emitEvent(ADD_EVENT, relativePath, metadata); + this._emitEvent({event: ADD_EVENT, relativePath, metadata}); } } } @@ -353,7 +361,7 @@ module.exports = class NodeWatcher extends EventEmitter { this._unregister(fullPath); this._unregisterDir(fullPath); if (registered) { - this._emitEvent(DELETE_EVENT, relativePath); + this._emitEvent({event: DELETE_EVENT, relativePath}); } await this._stopWatching(fullPath); } @@ -366,10 +374,24 @@ module.exports = class NodeWatcher extends EventEmitter { * * See also note above for DEBOUNCE_MS. */ - _emitEvent(type: string, file: string, metadata?: ChangeEventMetadata) { - const key = type + '-' + file; - const addKey = ADD_EVENT + '-' + file; - if (type === CHANGE_EVENT && this._changeTimers.has(addKey)) { + _emitEvent({ + event, + relativePath, + metadata, + }: + | { + event: 'change' | 'add', + relativePath: string, + metadata: ChangeEventMetadata, + } + | { + event: 'delete', + relativePath: string, + metadata?: void, + }) { + const key = event + '-' + relativePath; + const addKey = ADD_EVENT + '-' + relativePath; + if (event === CHANGE_EVENT && this._changeTimers.has(addKey)) { // Ignore the change event that is immediately fired after an add event. // (This happens on Linux). return; @@ -382,7 +404,7 @@ module.exports = class NodeWatcher extends EventEmitter { key, setTimeout(() => { this._changeTimers.delete(key); - this._rawEmitEvent(type, file, metadata); + this._rawEmitEvent(event, relativePath, metadata); }, DEBOUNCE_MS), ); } diff --git a/packages/metro-file-map/src/watchers/WatchmanWatcher.js b/packages/metro-file-map/src/watchers/WatchmanWatcher.js index 3a0d57133..ee2938d9d 100644 --- a/packages/metro-file-map/src/watchers/WatchmanWatcher.js +++ b/packages/metro-file-map/src/watchers/WatchmanWatcher.js @@ -272,7 +272,7 @@ export default class WatchmanWatcher extends EventEmitter { } if (!exists) { - self._emitEvent(DELETE_EVENT, relativePath, self.root); + self._emitEvent({event: DELETE_EVENT, relativePath}); } else { const eventType = isNew ? ADD_EVENT : CHANGE_EVENT; invariant( @@ -290,10 +290,14 @@ export default class WatchmanWatcher extends EventEmitter { !(type === 'd' && eventType === CHANGE_EVENT) ) { const mtime = Number(mtime_ms); - self._emitEvent(eventType, relativePath, self.root, { - modifiedTime: mtime !== 0 ? mtime : null, - size, - type, + self._emitEvent({ + event: eventType, + relativePath, + metadata: { + modifiedTime: mtime !== 0 ? mtime : null, + size, + type, + }, }); } } @@ -302,14 +306,23 @@ export default class WatchmanWatcher extends EventEmitter { /** * Dispatches the event. */ - _emitEvent( - eventType: string, - filepath: string, - root: string, - changeMetadata?: ChangeEventMetadata, - ) { - this.emit(eventType, filepath, root, changeMetadata); - this.emit(ALL_EVENT, eventType, filepath, root, changeMetadata); + _emitEvent({ + event, + relativePath, + metadata, + }: + | { + event: 'change' | 'add', + relativePath: string, + metadata: ChangeEventMetadata, + } + | { + event: 'delete', + relativePath: string, + metadata?: void, + }) { + this.emit(event, relativePath, this.root, metadata); + this.emit(ALL_EVENT, event, relativePath, this.root, metadata); } /**