metro-file-map 0.83.3 → 0.84.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/package.json +4 -3
  2. package/src/Watcher.js +59 -52
  3. package/src/Watcher.js.flow +39 -39
  4. package/src/cache/DiskCacheManager.js.flow +3 -3
  5. package/src/constants.js +9 -8
  6. package/src/constants.js.flow +6 -18
  7. package/src/crawlers/node/index.js +27 -25
  8. package/src/crawlers/node/index.js.flow +6 -8
  9. package/src/crawlers/watchman/index.js +26 -22
  10. package/src/crawlers/watchman/index.js.flow +3 -4
  11. package/src/crawlers/watchman/planQuery.d.ts +24 -0
  12. package/src/crawlers/watchman/planQuery.js.flow +4 -4
  13. package/src/flow-types.js.flow +125 -87
  14. package/src/index.js +267 -235
  15. package/src/index.js.flow +269 -275
  16. package/src/lib/FileProcessor.js +76 -54
  17. package/src/lib/FileProcessor.js.flow +93 -72
  18. package/src/lib/RootPathUtils.js +25 -21
  19. package/src/lib/RootPathUtils.js.flow +4 -4
  20. package/src/lib/TreeFS.js +72 -77
  21. package/src/lib/TreeFS.js.flow +104 -124
  22. package/src/lib/checkWatchmanCapabilities.js.flow +4 -4
  23. package/src/lib/dependencyExtractor.d.ts +14 -0
  24. package/src/lib/normalizePathSeparatorsToPosix.js +25 -21
  25. package/src/lib/normalizePathSeparatorsToPosix.js.flow +3 -3
  26. package/src/lib/normalizePathSeparatorsToSystem.js +25 -21
  27. package/src/lib/normalizePathSeparatorsToSystem.js.flow +3 -3
  28. package/src/lib/rootRelativeCacheKeys.js +0 -20
  29. package/src/lib/rootRelativeCacheKeys.js.flow +1 -23
  30. package/src/plugins/DependencyPlugin.js +75 -0
  31. package/src/plugins/DependencyPlugin.js.flow +144 -0
  32. package/src/plugins/HastePlugin.js +83 -38
  33. package/src/plugins/HastePlugin.js.flow +105 -51
  34. package/src/plugins/MockPlugin.js +7 -4
  35. package/src/plugins/MockPlugin.js.flow +24 -15
  36. package/src/plugins/dependencies/dependencyExtractor.d.ts +14 -0
  37. package/src/{lib → plugins/dependencies}/dependencyExtractor.js.flow +3 -6
  38. package/src/plugins/dependencies/worker.d.ts +24 -0
  39. package/src/plugins/dependencies/worker.js +24 -0
  40. package/src/plugins/dependencies/worker.js.flow +53 -0
  41. package/src/plugins/haste/HasteConflictsError.js.flow +2 -2
  42. package/src/plugins/haste/computeConflicts.js +2 -1
  43. package/src/plugins/haste/computeConflicts.js.flow +11 -12
  44. package/src/plugins/haste/getPlatformExtension.js.flow +2 -2
  45. package/src/plugins/haste/worker.d.ts +24 -0
  46. package/src/plugins/haste/worker.js +35 -0
  47. package/src/plugins/haste/worker.js.flow +64 -0
  48. package/src/plugins/mocks/getMockName.js +27 -23
  49. package/src/plugins/mocks/getMockName.js.flow +2 -4
  50. package/src/watchers/AbstractWatcher.js +27 -22
  51. package/src/watchers/AbstractWatcher.js.flow +6 -5
  52. package/src/watchers/FallbackWatcher.js +88 -84
  53. package/src/watchers/FallbackWatcher.js.flow +65 -65
  54. package/src/watchers/NativeWatcher.js +25 -21
  55. package/src/watchers/NativeWatcher.js.flow +3 -3
  56. package/src/watchers/RecrawlWarning.js.flow +1 -1
  57. package/src/watchers/WatchmanWatcher.js +61 -53
  58. package/src/watchers/WatchmanWatcher.js.flow +39 -38
  59. package/src/watchers/common.js.flow +5 -5
  60. package/src/worker.d.ts +36 -0
  61. package/src/worker.js +16 -58
  62. package/src/worker.js.flow +19 -69
  63. package/src/workerExclusionList.d.ts +12 -0
  64. package/src/workerExclusionList.js.flow +1 -1
  65. package/src/Watcher.d.ts +0 -24
  66. package/src/cache/DiskCacheManager.d.ts +0 -38
  67. package/src/flow-types.d.ts +0 -353
  68. package/src/index.d.ts +0 -97
  69. package/src/lib/DuplicateHasteCandidatesError.d.ts +0 -24
  70. /package/src/{lib → plugins/dependencies}/dependencyExtractor.js +0 -0
package/src/index.js CHANGED
@@ -3,6 +3,12 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true,
5
5
  });
6
+ Object.defineProperty(exports, "DependencyPlugin", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _DependencyPlugin.default;
10
+ },
11
+ });
6
12
  Object.defineProperty(exports, "DiskCacheManager", {
7
13
  enumerable: true,
8
14
  get: function () {
@@ -42,8 +48,6 @@ var _normalizePathSeparatorsToSystem = _interopRequireDefault(
42
48
  );
43
49
  var _RootPathUtils = require("./lib/RootPathUtils");
44
50
  var _TreeFS = _interopRequireDefault(require("./lib/TreeFS"));
45
- var _HastePlugin = _interopRequireDefault(require("./plugins/HastePlugin"));
46
- var _MockPlugin = _interopRequireDefault(require("./plugins/MockPlugin"));
47
51
  var _Watcher = require("./Watcher");
48
52
  var _events = _interopRequireDefault(require("events"));
49
53
  var _fs = require("fs");
@@ -51,39 +55,46 @@ var _invariant = _interopRequireDefault(require("invariant"));
51
55
  var _nullthrows = _interopRequireDefault(require("nullthrows"));
52
56
  var path = _interopRequireWildcard(require("path"));
53
57
  var _perf_hooks = require("perf_hooks");
58
+ var _DependencyPlugin = _interopRequireDefault(
59
+ require("./plugins/DependencyPlugin"),
60
+ );
54
61
  var _DuplicateHasteCandidatesError = require("./plugins/haste/DuplicateHasteCandidatesError");
55
62
  var _HasteConflictsError = require("./plugins/haste/HasteConflictsError");
56
- function _getRequireWildcardCache(e) {
57
- if ("function" != typeof WeakMap) return null;
58
- var r = new WeakMap(),
59
- t = new WeakMap();
60
- return (_getRequireWildcardCache = function (e) {
61
- return e ? t : r;
62
- })(e);
63
- }
64
- function _interopRequireWildcard(e, r) {
65
- if (!r && e && e.__esModule) return e;
66
- if (null === e || ("object" != typeof e && "function" != typeof e))
67
- return { default: e };
68
- var t = _getRequireWildcardCache(r);
69
- if (t && t.has(e)) return t.get(e);
70
- var n = { __proto__: null },
71
- a = Object.defineProperty && Object.getOwnPropertyDescriptor;
72
- for (var u in e)
73
- if ("default" !== u && {}.hasOwnProperty.call(e, u)) {
74
- var i = a ? Object.getOwnPropertyDescriptor(e, u) : null;
75
- i && (i.get || i.set) ? Object.defineProperty(n, u, i) : (n[u] = e[u]);
63
+ var _HastePlugin = _interopRequireDefault(require("./plugins/HastePlugin"));
64
+ function _interopRequireWildcard(e, t) {
65
+ if ("function" == typeof WeakMap)
66
+ var r = new WeakMap(),
67
+ n = new WeakMap();
68
+ return (_interopRequireWildcard = function (e, t) {
69
+ if (!t && e && e.__esModule) return e;
70
+ var o,
71
+ i,
72
+ f = { __proto__: null, default: e };
73
+ if (null === e || ("object" != typeof e && "function" != typeof e))
74
+ return f;
75
+ if ((o = t ? n : r)) {
76
+ if (o.has(e)) return o.get(e);
77
+ o.set(e, f);
76
78
  }
77
- return ((n.default = e), t && t.set(e, n), n);
79
+ for (const t in e)
80
+ "default" !== t &&
81
+ {}.hasOwnProperty.call(e, t) &&
82
+ ((i =
83
+ (o = Object.defineProperty) &&
84
+ Object.getOwnPropertyDescriptor(e, t)) &&
85
+ (i.get || i.set)
86
+ ? o(f, t, i)
87
+ : (f[t] = e[t]));
88
+ return f;
89
+ })(e, t);
78
90
  }
79
91
  function _interopRequireDefault(e) {
80
92
  return e && e.__esModule ? e : { default: e };
81
93
  }
82
94
  const debug = require("debug")("Metro:FileMap");
83
- const CACHE_BREAKER = "10";
95
+ const CACHE_BREAKER = "11";
84
96
  const CHANGE_INTERVAL = 30;
85
97
  const NODE_MODULES = path.sep + "node_modules" + path.sep;
86
- const PACKAGE_JSON = path.sep + "package.json";
87
98
  const VCS_DIRECTORIES = /[/\\]\.(git|hg)[/\\]/.source;
88
99
  const WATCHMAN_REQUIRED_CAPABILITIES = [
89
100
  "field-content.sha1hex",
@@ -92,18 +103,29 @@ const WATCHMAN_REQUIRED_CAPABILITIES = [
92
103
  "wildmatch",
93
104
  ];
94
105
  class FileMap extends _events.default {
95
- #hastePlugin;
96
- #mockPlugin = null;
106
+ #buildPromise;
107
+ #cacheManager;
108
+ #canUseWatchmanPromise;
109
+ #changeID;
110
+ #changeInterval;
111
+ #console;
112
+ #crawlerAbortController;
113
+ #fileProcessor;
114
+ #healthCheckInterval;
115
+ #options;
116
+ #pathUtils;
97
117
  #plugins;
118
+ #startupPerfLogger;
119
+ #watcher;
98
120
  static create(options) {
99
121
  return new FileMap(options);
100
122
  }
101
123
  constructor(options) {
102
124
  super();
103
125
  if (options.perfLoggerFactory) {
104
- this._startupPerfLogger =
126
+ this.#startupPerfLogger =
105
127
  options.perfLoggerFactory?.("START_UP").subSpan("fileMap") ?? null;
106
- this._startupPerfLogger?.point("constructor_start");
128
+ this.#startupPerfLogger?.point("constructor_start");
107
129
  }
108
130
  let ignorePattern;
109
131
  if (options.ignorePattern) {
@@ -121,49 +143,35 @@ class FileMap extends _events.default {
121
143
  } else {
122
144
  ignorePattern = new RegExp(VCS_DIRECTORIES);
123
145
  }
124
- this._console = options.console || global.console;
125
- const throwOnModuleCollision = Boolean(options.throwOnModuleCollision);
126
- const enableHastePackages = options.enableHastePackages ?? true;
127
- this.#hastePlugin = new _HastePlugin.default({
128
- console: this._console,
129
- enableHastePackages,
130
- perfLogger: this._startupPerfLogger,
131
- platforms: new Set(options.platforms),
132
- rootDir: options.rootDir,
133
- failValidationOnConflicts: throwOnModuleCollision,
134
- });
135
- const plugins = [this.#hastePlugin];
136
- if (options.mocksPattern != null && options.mocksPattern !== "") {
137
- this.#mockPlugin = new _MockPlugin.default({
138
- console: this._console,
139
- mocksPattern: new RegExp(options.mocksPattern),
140
- rootDir: options.rootDir,
141
- throwOnModuleCollision,
146
+ this.#console = options.console || global.console;
147
+ let dataSlot = _constants.default.PLUGINDATA;
148
+ const indexedPlugins = [];
149
+ const pluginWorkers = [];
150
+ const plugins = options.plugins ?? [];
151
+ for (const plugin of plugins) {
152
+ const maybeWorker = plugin.getWorker();
153
+ indexedPlugins.push({
154
+ plugin,
155
+ dataIdx: maybeWorker != null ? dataSlot++ : null,
142
156
  });
143
- plugins.push(this.#mockPlugin);
157
+ if (maybeWorker != null) {
158
+ pluginWorkers.push(maybeWorker);
159
+ }
144
160
  }
145
- this.#plugins = plugins;
161
+ this.#plugins = indexedPlugins;
146
162
  const buildParameters = {
147
- computeDependencies:
148
- options.computeDependencies == null
149
- ? true
150
- : options.computeDependencies,
163
+ cacheBreaker: CACHE_BREAKER,
151
164
  computeSha1: options.computeSha1 || false,
152
- dependencyExtractor: options.dependencyExtractor ?? null,
153
- enableHastePackages,
154
165
  enableSymlinks: options.enableSymlinks || false,
155
166
  extensions: options.extensions,
156
167
  forceNodeFilesystemAPI: !!options.forceNodeFilesystemAPI,
157
- hasteImplModulePath: options.hasteImplModulePath,
158
168
  ignorePattern,
159
- plugins: options.plugins ?? [],
169
+ plugins,
160
170
  retainAllFiles: options.retainAllFiles,
161
171
  rootDir: options.rootDir,
162
172
  roots: Array.from(new Set(options.roots)),
163
- skipPackageJson: !!options.skipPackageJson,
164
- cacheBreaker: CACHE_BREAKER,
165
173
  };
166
- this._options = {
174
+ this.#options = {
167
175
  ...buildParameters,
168
176
  healthCheck: options.healthCheck,
169
177
  perfLoggerFactory: options.perfLoggerFactory,
@@ -175,30 +183,28 @@ class FileMap extends _events.default {
175
183
  const cacheFactoryOptions = {
176
184
  buildParameters,
177
185
  };
178
- this._cacheManager = options.cacheManagerFactory
186
+ this.#cacheManager = options.cacheManagerFactory
179
187
  ? options.cacheManagerFactory.call(null, cacheFactoryOptions)
180
188
  : new _DiskCacheManager.DiskCacheManager(cacheFactoryOptions, {});
181
- this._fileProcessor = new _FileProcessor.FileProcessor({
182
- dependencyExtractor: buildParameters.dependencyExtractor,
183
- enableHastePackages: buildParameters.enableHastePackages,
184
- enableWorkerThreads: options.enableWorkerThreads ?? false,
185
- hasteImplModulePath: buildParameters.hasteImplModulePath,
189
+ this.#fileProcessor = new _FileProcessor.FileProcessor({
186
190
  maxFilesPerWorker: options.maxFilesPerWorker,
187
191
  maxWorkers: options.maxWorkers,
188
- perfLogger: this._startupPerfLogger,
192
+ perfLogger: this.#startupPerfLogger,
193
+ pluginWorkers,
194
+ rootDir: options.rootDir,
189
195
  });
190
- this._buildPromise = null;
191
- this._pathUtils = new _RootPathUtils.RootPathUtils(options.rootDir);
192
- this._startupPerfLogger?.point("constructor_end");
193
- this._crawlerAbortController = new AbortController();
194
- this._changeID = 0;
196
+ this.#buildPromise = null;
197
+ this.#pathUtils = new _RootPathUtils.RootPathUtils(options.rootDir);
198
+ this.#startupPerfLogger?.point("constructor_end");
199
+ this.#crawlerAbortController = new AbortController();
200
+ this.#changeID = 0;
195
201
  }
196
202
  build() {
197
- this._startupPerfLogger?.point("build_start");
198
- if (!this._buildPromise) {
199
- this._buildPromise = (async () => {
203
+ this.#startupPerfLogger?.point("build_start");
204
+ if (!this.#buildPromise) {
205
+ this.#buildPromise = (async () => {
200
206
  let initialData;
201
- if (this._options.resetCache !== true) {
207
+ if (this.#options.resetCache !== true) {
202
208
  initialData = await this.read();
203
209
  }
204
210
  if (!initialData) {
@@ -206,53 +212,82 @@ class FileMap extends _events.default {
206
212
  } else {
207
213
  debug("Cache loaded (%d clock(s))", initialData.clocks.size);
208
214
  }
209
- const rootDir = this._options.rootDir;
210
- this._startupPerfLogger?.point("constructFileSystem_start");
211
- const processFile = (absolutePath, metadata, opts) => {
212
- const result = this._fileProcessor.processRegularFile(
213
- absolutePath,
215
+ const rootDir = this.#options.rootDir;
216
+ this.#startupPerfLogger?.point("constructFileSystem_start");
217
+ const processFile = (normalPath, metadata, opts) => {
218
+ const result = this.#fileProcessor.processRegularFile(
219
+ normalPath,
214
220
  metadata,
215
221
  {
216
222
  computeSha1: opts.computeSha1,
217
- computeDependencies: false,
218
223
  maybeReturnContent: true,
219
224
  },
220
225
  );
221
- debug("Lazily processed file: %s", absolutePath);
226
+ debug("Lazily processed file: %s", normalPath);
222
227
  this.emit("metadata");
223
228
  return result?.content;
224
229
  };
225
230
  const fileSystem =
226
231
  initialData != null
227
232
  ? _TreeFS.default.fromDeserializedSnapshot({
228
- rootDir,
229
233
  fileSystemData: initialData.fileSystemData,
230
234
  processFile,
235
+ rootDir,
231
236
  })
232
237
  : new _TreeFS.default({
233
- rootDir,
234
238
  processFile,
239
+ rootDir,
235
240
  });
236
- this._startupPerfLogger?.point("constructFileSystem_end");
241
+ this.#startupPerfLogger?.point("constructFileSystem_end");
237
242
  const plugins = this.#plugins;
238
243
  const [fileDelta] = await Promise.all([
239
- this._buildFileDelta({
240
- fileSystem,
244
+ this.#buildFileDelta({
241
245
  clocks: initialData?.clocks ?? new Map(),
246
+ fileSystem,
242
247
  }),
243
248
  Promise.all(
244
- plugins.map((plugin) =>
249
+ plugins.map(({ plugin, dataIdx }) =>
245
250
  plugin.initialize({
246
- files: fileSystem,
251
+ files: {
252
+ lookup: (mixedPath) => {
253
+ const result = fileSystem.lookup(mixedPath);
254
+ if (!result.exists) {
255
+ return {
256
+ exists: false,
257
+ };
258
+ }
259
+ if (result.type === "d") {
260
+ return {
261
+ exists: true,
262
+ type: "d",
263
+ };
264
+ }
265
+ return {
266
+ exists: true,
267
+ type: "f",
268
+ pluginData:
269
+ dataIdx != null ? result.metadata[dataIdx] : null,
270
+ };
271
+ },
272
+ fileIterator: (opts) =>
273
+ mapIterator(
274
+ fileSystem.metadataIterator(opts),
275
+ ({ baseName, canonicalPath, metadata }) => ({
276
+ baseName,
277
+ canonicalPath,
278
+ pluginData: dataIdx != null ? metadata[dataIdx] : null,
279
+ }),
280
+ ),
281
+ },
247
282
  pluginState: initialData?.plugins.get(plugin.name),
248
283
  }),
249
284
  ),
250
285
  ),
251
286
  ]);
252
- await this._applyFileDelta(fileSystem, plugins, fileDelta);
253
- plugins.forEach((plugin) => plugin.assertValid());
287
+ await this.#applyFileDelta(fileSystem, plugins, fileDelta);
288
+ plugins.forEach(({ plugin }) => plugin.assertValid());
254
289
  const watchmanClocks = new Map(fileDelta.clocks ?? []);
255
- await this._takeSnapshotAndPersist(
290
+ await this.#takeSnapshotAndPersist(
256
291
  fileSystem,
257
292
  watchmanClocks,
258
293
  plugins,
@@ -264,40 +299,38 @@ class FileMap extends _events.default {
264
299
  fileDelta.changedFiles.size,
265
300
  fileDelta.removedFiles.size,
266
301
  );
267
- await this._watch(fileSystem, watchmanClocks, plugins);
302
+ await this.#watch(fileSystem, watchmanClocks, plugins);
268
303
  return {
269
304
  fileSystem,
270
- hasteMap: this.#hastePlugin,
271
- mockMap: this.#mockPlugin,
272
305
  };
273
306
  })();
274
307
  }
275
- return this._buildPromise.then((result) => {
276
- this._startupPerfLogger?.point("build_end");
308
+ return this.#buildPromise.then((result) => {
309
+ this.#startupPerfLogger?.point("build_end");
277
310
  return result;
278
311
  });
279
312
  }
280
313
  async read() {
281
314
  let data;
282
- this._startupPerfLogger?.point("read_start");
315
+ this.#startupPerfLogger?.point("read_start");
283
316
  try {
284
- data = await this._cacheManager.read();
317
+ data = await this.#cacheManager.read();
285
318
  } catch (e) {
286
- this._console.warn(
319
+ this.#console.warn(
287
320
  "Error while reading cache, falling back to a full crawl:\n",
288
321
  e,
289
322
  );
290
- this._startupPerfLogger?.annotate({
323
+ this.#startupPerfLogger?.annotate({
291
324
  string: {
292
325
  cacheReadError: e.toString(),
293
326
  },
294
327
  });
295
328
  }
296
- this._startupPerfLogger?.point("read_end");
329
+ this.#startupPerfLogger?.point("read_end");
297
330
  return data;
298
331
  }
299
- async _buildFileDelta(previousState) {
300
- this._startupPerfLogger?.point("buildFileDelta_start");
332
+ async #buildFileDelta(previousState) {
333
+ this.#startupPerfLogger?.point("buildFileDelta_start");
301
334
  const {
302
335
  computeSha1,
303
336
  enableSymlinks,
@@ -309,15 +342,15 @@ class FileMap extends _events.default {
309
342
  rootDir,
310
343
  watch,
311
344
  watchmanDeferStates,
312
- } = this._options;
313
- this._watcher = new _Watcher.Watcher({
314
- abortSignal: this._crawlerAbortController.signal,
345
+ } = this.#options;
346
+ this.#watcher = new _Watcher.Watcher({
347
+ abortSignal: this.#crawlerAbortController.signal,
315
348
  computeSha1,
316
- console: this._console,
349
+ console: this.#console,
317
350
  enableSymlinks,
318
351
  extensions,
319
352
  forceNodeFilesystemAPI,
320
- healthCheckFilePrefix: this._options.healthCheck.filePrefix,
353
+ healthCheckFilePrefix: this.#options.healthCheck.filePrefix,
321
354
  ignoreForCrawl: (filePath) => {
322
355
  const ignoreMatched = ignorePattern.test(filePath);
323
356
  return (
@@ -325,36 +358,38 @@ class FileMap extends _events.default {
325
358
  );
326
359
  },
327
360
  ignorePatternForWatch: ignorePattern,
328
- perfLogger: this._startupPerfLogger,
361
+ perfLogger: this.#startupPerfLogger,
329
362
  previousState,
330
- roots,
331
363
  rootDir,
332
- useWatchman: await this._shouldUseWatchman(),
364
+ roots,
365
+ useWatchman: await this.#shouldUseWatchman(),
333
366
  watch,
334
367
  watchmanDeferStates,
335
368
  });
336
- const watcher = this._watcher;
369
+ const watcher = this.#watcher;
337
370
  watcher.on("status", (status) => this.emit("status", status));
338
371
  return watcher.crawl().then((result) => {
339
- this._startupPerfLogger?.point("buildFileDelta_end");
372
+ this.#startupPerfLogger?.point("buildFileDelta_end");
340
373
  return result;
341
374
  });
342
375
  }
343
- _maybeReadLink(filePath, fileMetadata) {
376
+ #maybeReadLink(normalPath, fileMetadata) {
344
377
  if (fileMetadata[_constants.default.SYMLINK] === 1) {
345
- return _fs.promises.readlink(filePath).then((symlinkTarget) => {
346
- fileMetadata[_constants.default.VISITED] = 1;
347
- fileMetadata[_constants.default.SYMLINK] = symlinkTarget;
348
- });
378
+ return _fs.promises
379
+ .readlink(this.#pathUtils.normalToAbsolute(normalPath))
380
+ .then((symlinkTarget) => {
381
+ fileMetadata[_constants.default.VISITED] = 1;
382
+ fileMetadata[_constants.default.SYMLINK] = symlinkTarget;
383
+ });
349
384
  }
350
385
  return null;
351
386
  }
352
- async _applyFileDelta(fileSystem, plugins, delta) {
353
- this._startupPerfLogger?.point("applyFileDelta_start");
387
+ async #applyFileDelta(fileSystem, plugins, delta) {
388
+ this.#startupPerfLogger?.point("applyFileDelta_start");
354
389
  const { changedFiles, removedFiles } = delta;
355
- this._startupPerfLogger?.point("applyFileDelta_preprocess_start");
390
+ this.#startupPerfLogger?.point("applyFileDelta_preprocess_start");
356
391
  const missingFiles = new Set();
357
- this._startupPerfLogger?.point("applyFileDelta_remove_start");
392
+ this.#startupPerfLogger?.point("applyFileDelta_remove_start");
358
393
  const removed = [];
359
394
  for (const relativeFilePath of removedFiles) {
360
395
  const metadata = fileSystem.remove(relativeFilePath);
@@ -362,42 +397,23 @@ class FileMap extends _events.default {
362
397
  removed.push([relativeFilePath, metadata]);
363
398
  }
364
399
  }
365
- this._startupPerfLogger?.point("applyFileDelta_remove_end");
400
+ this.#startupPerfLogger?.point("applyFileDelta_remove_end");
366
401
  const readLinkPromises = [];
367
402
  const readLinkErrors = [];
368
403
  const filesToProcess = [];
369
- for (const [relativeFilePath, fileData] of changedFiles) {
404
+ for (const [normalFilePath, fileData] of changedFiles) {
370
405
  if (fileData[_constants.default.VISITED] === 1) {
371
406
  continue;
372
407
  }
373
- if (
374
- this._options.skipPackageJson &&
375
- relativeFilePath.endsWith(PACKAGE_JSON)
376
- ) {
377
- continue;
378
- }
379
- if (
380
- fileData[_constants.default.SYMLINK] === 0 &&
381
- !this._options.computeDependencies &&
382
- !this._options.computeSha1 &&
383
- this._options.hasteImplModulePath == null &&
384
- !(
385
- this._options.enableHastePackages &&
386
- relativeFilePath.endsWith(PACKAGE_JSON)
387
- )
388
- ) {
389
- continue;
390
- }
391
- const absolutePath = this._pathUtils.normalToAbsolute(relativeFilePath);
392
408
  if (fileData[_constants.default.SYMLINK] === 0) {
393
- filesToProcess.push([absolutePath, fileData]);
409
+ filesToProcess.push([normalFilePath, fileData]);
394
410
  } else {
395
- const maybeReadLink = this._maybeReadLink(absolutePath, fileData);
411
+ const maybeReadLink = this.#maybeReadLink(normalFilePath, fileData);
396
412
  if (maybeReadLink) {
397
413
  readLinkPromises.push(
398
414
  maybeReadLink.catch((error) =>
399
415
  readLinkErrors.push({
400
- absolutePath,
416
+ normalFilePath,
401
417
  error,
402
418
  }),
403
419
  ),
@@ -405,28 +421,27 @@ class FileMap extends _events.default {
405
421
  }
406
422
  }
407
423
  }
408
- this._startupPerfLogger?.point("applyFileDelta_preprocess_end");
424
+ this.#startupPerfLogger?.point("applyFileDelta_preprocess_end");
409
425
  debug(
410
- "Visiting %d added/modified files and %d symlinks.",
426
+ "Found %d added/modified files and %d symlinks.",
411
427
  filesToProcess.length,
412
428
  readLinkPromises.length,
413
429
  );
414
- this._startupPerfLogger?.point("applyFileDelta_process_start");
430
+ this.#startupPerfLogger?.point("applyFileDelta_process_start");
415
431
  const [batchResult] = await Promise.all([
416
- this._fileProcessor.processBatch(filesToProcess, {
417
- computeSha1: this._options.computeSha1,
418
- computeDependencies: this._options.computeDependencies,
432
+ this.#fileProcessor.processBatch(filesToProcess, {
433
+ computeSha1: this.#options.computeSha1,
419
434
  maybeReturnContent: false,
420
435
  }),
421
436
  Promise.all(readLinkPromises),
422
437
  ]);
423
- this._startupPerfLogger?.point("applyFileDelta_process_end");
424
- this._startupPerfLogger?.point("applyFileDelta_missing_start");
425
- for (const { absolutePath, error } of batchResult.errors.concat(
438
+ this.#startupPerfLogger?.point("applyFileDelta_process_end");
439
+ this.#startupPerfLogger?.point("applyFileDelta_missing_start");
440
+ for (const { normalFilePath, error } of batchResult.errors.concat(
426
441
  readLinkErrors,
427
442
  )) {
428
443
  if (["ENOENT", "EACCESS"].includes(error.code)) {
429
- missingFiles.add(this._pathUtils.absoluteToNormal(absolutePath));
444
+ missingFiles.add(normalFilePath);
430
445
  } else {
431
446
  throw error;
432
447
  }
@@ -438,30 +453,34 @@ class FileMap extends _events.default {
438
453
  removed.push([relativeFilePath, metadata]);
439
454
  }
440
455
  }
441
- this._startupPerfLogger?.point("applyFileDelta_missing_end");
442
- this._startupPerfLogger?.point("applyFileDelta_add_start");
456
+ this.#startupPerfLogger?.point("applyFileDelta_missing_end");
457
+ this.#startupPerfLogger?.point("applyFileDelta_add_start");
443
458
  fileSystem.bulkAddOrModify(changedFiles);
444
- this._startupPerfLogger?.point("applyFileDelta_add_end");
445
- this._startupPerfLogger?.point("applyFileDelta_updatePlugins_start");
459
+ this.#startupPerfLogger?.point("applyFileDelta_add_end");
460
+ this.#startupPerfLogger?.point("applyFileDelta_updatePlugins_start");
446
461
  await Promise.all([
447
- plugins.map((plugin) =>
448
- plugin.bulkUpdate({
449
- addedOrModified: changedFiles,
450
- removed,
451
- }),
452
- ),
462
+ plugins.map(({ plugin, dataIdx }) => {
463
+ const mapFn =
464
+ dataIdx != null
465
+ ? ([relativePath, fileData]) => [relativePath, fileData[dataIdx]]
466
+ : ([relativePath, fileData]) => [relativePath, null];
467
+ return plugin.bulkUpdate({
468
+ addedOrModified: mapIterator(changedFiles.entries(), mapFn),
469
+ removed: mapIterator(removed.values(), mapFn),
470
+ });
471
+ }),
453
472
  ]);
454
- this._startupPerfLogger?.point("applyFileDelta_updatePlugins_end");
455
- this._startupPerfLogger?.point("applyFileDelta_end");
473
+ this.#startupPerfLogger?.point("applyFileDelta_updatePlugins_end");
474
+ this.#startupPerfLogger?.point("applyFileDelta_end");
456
475
  }
457
- async _takeSnapshotAndPersist(fileSystem, clocks, plugins, changed, removed) {
458
- this._startupPerfLogger?.point("persist_start");
459
- await this._cacheManager.write(
476
+ async #takeSnapshotAndPersist(fileSystem, clocks, plugins, changed, removed) {
477
+ this.#startupPerfLogger?.point("persist_start");
478
+ await this.#cacheManager.write(
460
479
  () => ({
461
- fileSystemData: fileSystem.getSerializableSnapshot(),
462
480
  clocks: new Map(clocks),
481
+ fileSystemData: fileSystem.getSerializableSnapshot(),
463
482
  plugins: new Map(
464
- plugins.map((plugin) => [
483
+ plugins.map(({ plugin }) => [
465
484
  plugin.name,
466
485
  plugin.getSerializableSnapshot(),
467
486
  ]),
@@ -480,20 +499,20 @@ class FileMap extends _events.default {
480
499
  },
481
500
  },
482
501
  onWriteError: (error) => {
483
- this._console.warn("[metro-file-map] Cache write error\n:", error);
502
+ this.#console.warn("[metro-file-map] Cache write error\n:", error);
484
503
  },
485
504
  },
486
505
  );
487
- this._startupPerfLogger?.point("persist_end");
506
+ this.#startupPerfLogger?.point("persist_end");
488
507
  }
489
- async _watch(fileSystem, clocks, plugins) {
490
- this._startupPerfLogger?.point("watch_start");
491
- if (!this._options.watch) {
492
- this._startupPerfLogger?.point("watch_end");
508
+ async #watch(fileSystem, clocks, plugins) {
509
+ this.#startupPerfLogger?.point("watch_start");
510
+ if (!this.#options.watch) {
511
+ this.#startupPerfLogger?.point("watch_end");
493
512
  return;
494
513
  }
495
514
  const hasWatchedExtension = (filePath) =>
496
- this._options.extensions.some((ext) => filePath.endsWith(ext));
515
+ this.#options.extensions.some((ext) => filePath.endsWith(ext));
497
516
  let changeQueue = Promise.resolve();
498
517
  let nextEmit = null;
499
518
  const emitChange = () => {
@@ -502,8 +521,8 @@ class FileMap extends _events.default {
502
521
  }
503
522
  const { eventsQueue, firstEventTimestamp, firstEnqueuedTimestamp } =
504
523
  nextEmit;
505
- const hmrPerfLogger = this._options.perfLoggerFactory?.("HMR", {
506
- key: this._getNextChangeID(),
524
+ const hmrPerfLogger = this.#options.perfLoggerFactory?.("HMR", {
525
+ key: this.#getNextChangeID(),
507
526
  });
508
527
  if (hmrPerfLogger != null) {
509
528
  hmrPerfLogger.start({
@@ -521,8 +540,8 @@ class FileMap extends _events.default {
521
540
  hmrPerfLogger.point("fileChange_start");
522
541
  }
523
542
  const changeEvent = {
524
- logger: hmrPerfLogger,
525
543
  eventsQueue,
544
+ logger: hmrPerfLogger,
526
545
  };
527
546
  this.emit("change", changeEvent);
528
547
  nextEmit = null;
@@ -533,7 +552,7 @@ class FileMap extends _events.default {
533
552
  (change.metadata.type === "d" ||
534
553
  (change.metadata.type === "f" &&
535
554
  !hasWatchedExtension(change.relativePath)) ||
536
- (!this._options.enableSymlinks && change.metadata?.type === "l"))
555
+ (!this.#options.enableSymlinks && change.metadata?.type === "l"))
537
556
  ) {
538
557
  return;
539
558
  }
@@ -541,11 +560,11 @@ class FileMap extends _events.default {
541
560
  change.root,
542
561
  (0, _normalizePathSeparatorsToSystem.default)(change.relativePath),
543
562
  );
544
- if (this._options.ignorePattern.test(absoluteFilePath)) {
563
+ if (this.#options.ignorePattern.test(absoluteFilePath)) {
545
564
  return;
546
565
  }
547
566
  const relativeFilePath =
548
- this._pathUtils.absoluteToNormal(absoluteFilePath);
567
+ this.#pathUtils.absoluteToNormal(absoluteFilePath);
549
568
  const linkStats = fileSystem.linkStats(relativeFilePath);
550
569
  if (
551
570
  change.event === "touch" &&
@@ -592,10 +611,10 @@ class FileMap extends _events.default {
592
611
  if (nextEmit == null) {
593
612
  nextEmit = {
594
613
  eventsQueue: [event],
595
- firstEventTimestamp: onChangeStartTime,
596
614
  firstEnqueuedTimestamp:
597
615
  _perf_hooks.performance.timeOrigin +
598
616
  _perf_hooks.performance.now(),
617
+ firstEventTimestamp: onChangeStartTime,
599
618
  };
600
619
  } else {
601
620
  nextEmit.eventsQueue.push(event);
@@ -611,29 +630,32 @@ class FileMap extends _events.default {
611
630
  change.metadata.modifiedTime,
612
631
  change.metadata.size,
613
632
  0,
614
- "",
615
633
  null,
616
634
  change.metadata.type === "l" ? 1 : 0,
617
- "",
635
+ null,
618
636
  ];
619
637
  try {
620
638
  if (change.metadata.type === "l") {
621
- await this._maybeReadLink(absoluteFilePath, fileMetadata);
639
+ await this.#maybeReadLink(relativeFilePath, fileMetadata);
622
640
  } else {
623
- await this._fileProcessor.processRegularFile(
624
- absoluteFilePath,
641
+ await this.#fileProcessor.processRegularFile(
642
+ relativeFilePath,
625
643
  fileMetadata,
626
644
  {
627
- computeSha1: this._options.computeSha1,
628
- computeDependencies: this._options.computeDependencies,
645
+ computeSha1: this.#options.computeSha1,
629
646
  maybeReturnContent: false,
630
647
  },
631
648
  );
632
649
  }
633
650
  fileSystem.addOrModify(relativeFilePath, fileMetadata);
634
- this._updateClock(clocks, change.clock);
635
- plugins.forEach((plugin) =>
636
- plugin.onNewOrModifiedFile(relativeFilePath, fileMetadata),
651
+ this.#updateClock(clocks, change.clock);
652
+ plugins.forEach(({ plugin, dataIdx }) =>
653
+ dataIdx != null
654
+ ? plugin.onNewOrModifiedFile(
655
+ relativeFilePath,
656
+ fileMetadata[dataIdx],
657
+ )
658
+ : plugin.onNewOrModifiedFile(relativeFilePath),
637
659
  );
638
660
  enqueueEvent(change.metadata);
639
661
  } catch (e) {
@@ -648,9 +670,11 @@ class FileMap extends _events.default {
648
670
  const metadata = (0, _nullthrows.default)(
649
671
  fileSystem.remove(relativeFilePath),
650
672
  );
651
- this._updateClock(clocks, change.clock);
652
- plugins.forEach((plugin) =>
653
- plugin.onRemovedFile(relativeFilePath, metadata),
673
+ this.#updateClock(clocks, change.clock);
674
+ plugins.forEach(({ plugin, dataIdx }) =>
675
+ dataIdx != null
676
+ ? plugin.onRemovedFile(relativeFilePath, metadata[dataIdx])
677
+ : plugin.onRemovedFile(relativeFilePath),
654
678
  );
655
679
  enqueueEvent({
656
680
  modifiedTime: null,
@@ -665,60 +689,60 @@ class FileMap extends _events.default {
665
689
  return null;
666
690
  })
667
691
  .catch((error) => {
668
- this._console.error(
692
+ this.#console.error(
669
693
  `metro-file-map: watch error:\n ${error.stack}\n`,
670
694
  );
671
695
  });
672
696
  };
673
- this._changeInterval = setInterval(emitChange, CHANGE_INTERVAL);
697
+ this.#changeInterval = setInterval(emitChange, CHANGE_INTERVAL);
674
698
  (0, _invariant.default)(
675
- this._watcher != null,
676
- "Expected _watcher to have been initialised by build()",
699
+ this.#watcher != null,
700
+ "Expected #watcher to have been initialised by build()",
677
701
  );
678
- await this._watcher.watch(onChange);
679
- if (this._options.healthCheck.enabled) {
702
+ await this.#watcher.watch(onChange);
703
+ if (this.#options.healthCheck.enabled) {
680
704
  const performHealthCheck = () => {
681
- if (!this._watcher) {
705
+ if (!this.#watcher) {
682
706
  return;
683
707
  }
684
- this._watcher
685
- .checkHealth(this._options.healthCheck.timeout)
708
+ this.#watcher
709
+ .checkHealth(this.#options.healthCheck.timeout)
686
710
  .then((result) => {
687
711
  this.emit("healthCheck", result);
688
712
  });
689
713
  };
690
714
  performHealthCheck();
691
- this._healthCheckInterval = setInterval(
715
+ this.#healthCheckInterval = setInterval(
692
716
  performHealthCheck,
693
- this._options.healthCheck.interval,
717
+ this.#options.healthCheck.interval,
694
718
  );
695
719
  }
696
- this._startupPerfLogger?.point("watch_end");
720
+ this.#startupPerfLogger?.point("watch_end");
697
721
  }
698
722
  async end() {
699
- if (this._changeInterval) {
700
- clearInterval(this._changeInterval);
723
+ if (this.#changeInterval) {
724
+ clearInterval(this.#changeInterval);
701
725
  }
702
- if (this._healthCheckInterval) {
703
- clearInterval(this._healthCheckInterval);
726
+ if (this.#healthCheckInterval) {
727
+ clearInterval(this.#healthCheckInterval);
704
728
  }
705
- this._crawlerAbortController.abort();
729
+ this.#crawlerAbortController.abort();
706
730
  await Promise.all([
707
- this._fileProcessor.end(),
708
- this._watcher?.close(),
709
- this._cacheManager.end(),
731
+ this.#fileProcessor.end(),
732
+ this.#watcher?.close(),
733
+ this.#cacheManager.end(),
710
734
  ]);
711
735
  }
712
- async _shouldUseWatchman() {
713
- if (!this._options.useWatchman) {
736
+ async #shouldUseWatchman() {
737
+ if (!this.#options.useWatchman) {
714
738
  return false;
715
739
  }
716
- if (!this._canUseWatchmanPromise) {
717
- this._canUseWatchmanPromise = (0, _checkWatchmanCapabilities.default)(
740
+ if (!this.#canUseWatchmanPromise) {
741
+ this.#canUseWatchmanPromise = (0, _checkWatchmanCapabilities.default)(
718
742
  WATCHMAN_REQUIRED_CAPABILITIES,
719
743
  )
720
744
  .then(({ version }) => {
721
- this._startupPerfLogger?.annotate({
745
+ this.#startupPerfLogger?.annotate({
722
746
  string: {
723
747
  watchmanVersion: version,
724
748
  },
@@ -726,7 +750,7 @@ class FileMap extends _events.default {
726
750
  return true;
727
751
  })
728
752
  .catch((e) => {
729
- this._startupPerfLogger?.annotate({
753
+ this.#startupPerfLogger?.annotate({
730
754
  string: {
731
755
  watchmanFailedCapabilityCheck: e?.message ?? "[missing]",
732
756
  },
@@ -734,20 +758,20 @@ class FileMap extends _events.default {
734
758
  return false;
735
759
  });
736
760
  }
737
- return this._canUseWatchmanPromise;
761
+ return this.#canUseWatchmanPromise;
738
762
  }
739
- _getNextChangeID() {
740
- if (this._changeID >= Number.MAX_SAFE_INTEGER) {
741
- this._changeID = 0;
763
+ #getNextChangeID() {
764
+ if (this.#changeID >= Number.MAX_SAFE_INTEGER) {
765
+ this.#changeID = 0;
742
766
  }
743
- return ++this._changeID;
767
+ return ++this.#changeID;
744
768
  }
745
- _updateClock(clocks, newClock) {
769
+ #updateClock(clocks, newClock) {
746
770
  if (newClock == null) {
747
771
  return;
748
772
  }
749
773
  const [absoluteWatchRoot, clockSpec] = newClock;
750
- const relativeFsRoot = this._pathUtils.absoluteToNormal(absoluteWatchRoot);
774
+ const relativeFsRoot = this.#pathUtils.absoluteToNormal(absoluteWatchRoot);
751
775
  clocks.set(
752
776
  (0, _normalizePathSeparatorsToPosix.default)(relativeFsRoot),
753
777
  clockSpec,
@@ -756,3 +780,11 @@ class FileMap extends _events.default {
756
780
  static H = _constants.default;
757
781
  }
758
782
  exports.default = FileMap;
783
+ const mapIterator = (it, fn) =>
784
+ "map" in it
785
+ ? it.map(fn)
786
+ : (function* mapped() {
787
+ for (const item of it) {
788
+ yield fn(item);
789
+ }
790
+ })();