diff --git a/flow-typed/fsevents.js b/flow-typed/fsevents.js new file mode 100644 index 0000000000..6f3b0e2a75 --- /dev/null +++ b/flow-typed/fsevents.js @@ -0,0 +1,73 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict + * @format + * @oncall react_native + */ + +declare module 'fsevents' { + declare type Event = + | 'created' + | 'cloned' + | 'modified' + | 'deleted' + | 'moved' + | 'root-changed' + | 'unknown'; + + declare type Type = 'file' | 'directory' | 'symlink'; + + declare type FileChanges = { + inode: boolean, + finder: boolean, + access: boolean, + xattrs: boolean, + }; + + declare type Info = { + event: Event, + path: string, + type: Type, + changes: FileChanges, + flags: number, + }; + + declare type WatchHandler = (path: string, flags: number, id: string) => void; + + declare type FSEvents = { + watch(path: string, handler: WatchHandler): () => Promise, + getInfo(path: string, flags: number): Info, + constants: { + None: 0x00000000, + MustScanSubDirs: 0x00000001, + UserDropped: 0x00000002, + KernelDropped: 0x00000004, + EventIdsWrapped: 0x00000008, + HistoryDone: 0x00000010, + RootChanged: 0x00000020, + Mount: 0x00000040, + Unmount: 0x00000080, + ItemCreated: 0x00000100, + ItemRemoved: 0x00000200, + ItemInodeMetaMod: 0x00000400, + ItemRenamed: 0x00000800, + ItemModified: 0x00001000, + ItemFinderInfoMod: 0x00002000, + ItemChangeOwner: 0x00004000, + ItemXattrMod: 0x00008000, + ItemIsFile: 0x00010000, + ItemIsDir: 0x00020000, + ItemIsSymlink: 0x00040000, + ItemIsHardlink: 0x00100000, + ItemIsLastHardlink: 0x00200000, + OwnEvent: 0x00080000, + ItemCloned: 0x00400000, + }, + }; + + declare module.exports: FSEvents; +} diff --git a/packages/metro-file-map/package.json b/packages/metro-file-map/package.json index bdb709751c..9df1d82393 100644 --- a/packages/metro-file-map/package.json +++ b/packages/metro-file-map/package.json @@ -30,6 +30,6 @@ "slash": "^3.0.0" }, "optionalDependencies": { - "fsevents": "^2.1.2" + "fsevents": "^2.3.2" } } diff --git a/packages/metro-file-map/src/watchers/FSEventsWatcher.js b/packages/metro-file-map/src/watchers/FSEventsWatcher.js index a02e15ed54..4a8d59a6cc 100644 --- a/packages/metro-file-map/src/watchers/FSEventsWatcher.js +++ b/packages/metro-file-map/src/watchers/FSEventsWatcher.js @@ -16,13 +16,17 @@ import * as path from 'path'; // $FlowFixMe[untyped-import] - walker import walker from 'walker'; +// $FlowFixMe[cannot-resolve-module] - Optional, Darwin only +import type {FSEvents} from 'fsevents'; + // $FlowFixMe[untyped-import] - micromatch const micromatch = require('micromatch'); +const debug = require('debug')('Metro:FSEventsWatcher'); + type Matcher = typeof anymatch.Matcher; -// $FlowFixMe[unclear-type] - fsevents -let fsevents: any = null; +let fsevents: ?FSEvents = null; try { // $FlowFixMe[cannot-resolve-module] - Optional, Darwin only fsevents = require('fsevents'); @@ -116,12 +120,13 @@ export default class FSEventsWatcher extends EventEmitter { this.doIgnore = opts.ignored ? anymatch(opts.ignored) : () => false; this.root = path.resolve(dir); - this.fsEventsWatchStopper = fsevents.watch( - this.root, - // $FlowFixMe[method-unbinding] - Refactor - this._handleEvent.bind(this), + + this.fsEventsWatchStopper = fsevents.watch(this.root, path => + this._handleEvent(path), ); + debug(`Watching ${this.root}`); + this._tracked = new Set(); FSEventsWatcher._recReaddir( this.root,