diff --git a/packages/metro-file-map/src/watchers/FSEventsWatcher.js b/packages/metro-file-map/src/watchers/FSEventsWatcher.js index c646f77fb..fe3e16bbe 100644 --- a/packages/metro-file-map/src/watchers/FSEventsWatcher.js +++ b/packages/metro-file-map/src/watchers/FSEventsWatcher.js @@ -9,24 +9,19 @@ */ import type {ChangeEventMetadata} from '../flow-types'; -import type {Stats} from 'fs'; // $FlowFixMe[cannot-resolve-module] - Optional, Darwin only // $FlowFixMe[untyped-type-import] import type {FSEvents} from 'fsevents'; -import {isIncluded, typeFromStat} from './common'; +import {isIncluded, recReaddir, typeFromStat} from './common'; // $FlowFixMe[untyped-import] - anymatch import anymatch from 'anymatch'; import EventEmitter from 'events'; import {promises as fsPromises} from 'fs'; import * as path from 'path'; -// $FlowFixMe[untyped-import] - walker -import walker from 'walker'; const debug = require('debug')('Metro:FSEventsWatcher'); -type Matcher = typeof anymatch.Matcher; - // $FlowFixMe[value-as-type] let fsevents: ?FSEvents = null; try { @@ -54,7 +49,7 @@ type FsEventsWatcherEvent = */ export default class FSEventsWatcher extends EventEmitter { +root: string; - +ignored: ?Matcher; + +ignored: ?RegExp; +glob: $ReadOnlyArray; +dot: boolean; +doIgnore: (path: string) => boolean; @@ -66,38 +61,10 @@ export default class FSEventsWatcher extends EventEmitter { return fsevents != null; } - static _normalizeProxy( - callback: (normalizedPath: string, stats: Stats) => void, - ): (filepath: string, stats: Stats) => void { - return (filepath: string, stats: Stats): void => - callback(path.normalize(filepath), stats); - } - - static _recReaddir( - dir: string, - dirCallback: (normalizedPath: string, stats: Stats) => void, - fileCallback: (normalizedPath: string, stats: Stats) => void, - symlinkCallback: (normalizedPath: string, stats: Stats) => void, - endCallback: () => void, - // $FlowFixMe[unclear-type] Add types for callback - errorCallback: Function, - ignored?: Matcher, - ) { - walker(dir) - .filterDir( - (currentDir: string) => !ignored || !anymatch(ignored, currentDir), - ) - .on('dir', FSEventsWatcher._normalizeProxy(dirCallback)) - .on('file', FSEventsWatcher._normalizeProxy(fileCallback)) - .on('symlink', FSEventsWatcher._normalizeProxy(symlinkCallback)) - .on('error', errorCallback) - .on('end', endCallback); - } - constructor( dir: string, opts: $ReadOnly<{ - ignored?: Matcher, + ignored: ?RegExp, glob: string | $ReadOnlyArray, dot: boolean, ... @@ -128,10 +95,10 @@ export default class FSEventsWatcher extends EventEmitter { this._tracked = new Set(); const trackPath = (filePath: string) => { - this._tracked.add(filePath); + this._tracked.add(path.normalize(filePath)); }; this.watcherInitialReaddirPromise = new Promise(resolve => { - FSEventsWatcher._recReaddir( + recReaddir( this.root, trackPath, trackPath, diff --git a/packages/metro-file-map/src/watchers/NodeWatcher.js b/packages/metro-file-map/src/watchers/NodeWatcher.js index 4304f2cc8..183d99b1d 100644 --- a/packages/metro-file-map/src/watchers/NodeWatcher.js +++ b/packages/metro-file-map/src/watchers/NodeWatcher.js @@ -48,7 +48,7 @@ module.exports = class NodeWatcher extends EventEmitter { doIgnore: string => boolean; dot: boolean; globs: $ReadOnlyArray; - ignored: ?(boolean | RegExp); + ignored: ?RegExp; root: string; watched: {[key: string]: FSWatcher, __proto__: null}; watchmanDeferStates: $ReadOnlyArray; diff --git a/packages/metro-file-map/src/watchers/__tests__/WatchmanWatcher-test.js b/packages/metro-file-map/src/watchers/__tests__/WatchmanWatcher-test.js index f4cccde53..876340d90 100644 --- a/packages/metro-file-map/src/watchers/__tests__/WatchmanWatcher-test.js +++ b/packages/metro-file-map/src/watchers/__tests__/WatchmanWatcher-test.js @@ -36,7 +36,7 @@ describe('WatchmanWatcher', () => { test('initializes with watch-project, clock, subscribe', () => { const watchmanWatcher = new WatchmanWatcher('/project/subdir/js', { dot: true, - ignored: false, + ignored: null, glob: ['**/*.js'], watchmanDeferStates: ['busy'], }); @@ -86,7 +86,7 @@ describe('WatchmanWatcher', () => { beforeEach(() => { watchmanWatcher = new WatchmanWatcher('/project/subdir/js', { dot: true, - ignored: false, + ignored: null, glob: ['**/*.js'], watchmanDeferStates: ['busy'], }); diff --git a/packages/metro-file-map/src/watchers/common.js b/packages/metro-file-map/src/watchers/common.js index 2dbdb6d99..099ba1626 100644 --- a/packages/metro-file-map/src/watchers/common.js +++ b/packages/metro-file-map/src/watchers/common.js @@ -39,7 +39,7 @@ export const ALL_EVENT = 'all'; export type WatcherOptions = $ReadOnly<{ glob: $ReadOnlyArray, dot: boolean, - ignored: boolean | RegExp, + ignored: ?RegExp, watchmanDeferStates: $ReadOnlyArray, watchman?: mixed, watchmanPath?: string, @@ -49,7 +49,7 @@ interface Watcher { doIgnore: string => boolean; dot: boolean; globs: $ReadOnlyArray; - ignored?: ?(boolean | RegExp); + ignored?: ?RegExp; watchmanDeferStates: $ReadOnlyArray; watchmanPath?: ?string; } @@ -68,16 +68,14 @@ export const assignOptions = function ( ): WatcherOptions { watcher.globs = opts.glob ?? []; watcher.dot = opts.dot ?? false; - watcher.ignored = opts.ignored ?? false; + watcher.ignored = opts.ignored ?? null; watcher.watchmanDeferStates = opts.watchmanDeferStates; if (!Array.isArray(watcher.globs)) { watcher.globs = [watcher.globs]; } watcher.doIgnore = - opts.ignored != null && opts.ignored !== false - ? anymatch(opts.ignored) - : () => false; + opts.ignored != null ? anymatch(opts.ignored) : () => false; if (opts.watchman == true && opts.watchmanPath != null) { watcher.watchmanPath = opts.watchmanPath; @@ -117,7 +115,7 @@ export function recReaddir( symlinkCallback: (string, Stats) => void, endCallback: () => void, errorCallback: Error => void, - ignored: ?(boolean | RegExp), + ignored: ?RegExp, ) { walker(dir) .filterDir(currentDir => !anymatch(ignored, currentDir))