metro-file-map 0.84.2 → 0.84.3
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.
- package/package.json +1 -1
- package/src/Watcher.d.ts +6 -9
- package/src/Watcher.js +66 -39
- package/src/Watcher.js.flow +84 -51
- package/src/crawlers/node/index.d.ts +3 -5
- package/src/crawlers/node/index.js +4 -1
- package/src/crawlers/node/index.js.flow +8 -6
- package/src/crawlers/watchman/index.d.ts +5 -12
- package/src/crawlers/watchman/index.js.flow +2 -6
- package/src/flow-types.d.ts +81 -32
- package/src/flow-types.js.flow +89 -29
- package/src/index.d.ts +4 -4
- package/src/index.js +145 -120
- package/src/index.js.flow +199 -149
- package/src/lib/FileSystemChangeAggregator.d.ts +40 -0
- package/src/lib/FileSystemChangeAggregator.js +89 -0
- package/src/lib/FileSystemChangeAggregator.js.flow +143 -0
- package/src/lib/TreeFS.d.ts +16 -8
- package/src/lib/TreeFS.js +67 -16
- package/src/lib/TreeFS.js.flow +89 -16
- package/src/plugins/DependencyPlugin.d.ts +2 -13
- package/src/plugins/DependencyPlugin.js +1 -3
- package/src/plugins/DependencyPlugin.js.flow +1 -16
- package/src/plugins/HastePlugin.d.ts +3 -11
- package/src/plugins/HastePlugin.js +11 -11
- package/src/plugins/HastePlugin.js.flow +12 -12
- package/src/plugins/MockPlugin.d.ts +3 -5
- package/src/plugins/MockPlugin.js +17 -20
- package/src/plugins/MockPlugin.js.flow +18 -22
- package/src/watchers/FallbackWatcher.js +19 -3
- package/src/watchers/FallbackWatcher.js.flow +28 -5
- package/src/watchers/NativeWatcher.d.ts +2 -2
- package/src/watchers/NativeWatcher.js +27 -5
- package/src/watchers/NativeWatcher.js.flow +33 -6
- package/src/watchers/common.d.ts +3 -1
- package/src/watchers/common.js +6 -1
- package/src/watchers/common.js.flow +1 -0
package/src/index.js
CHANGED
|
@@ -40,6 +40,7 @@ var _checkWatchmanCapabilities = _interopRequireDefault(
|
|
|
40
40
|
require("./lib/checkWatchmanCapabilities"),
|
|
41
41
|
);
|
|
42
42
|
var _FileProcessor = require("./lib/FileProcessor");
|
|
43
|
+
var _FileSystemChangeAggregator = require("./lib/FileSystemChangeAggregator");
|
|
43
44
|
var _normalizePathSeparatorsToPosix = _interopRequireDefault(
|
|
44
45
|
require("./lib/normalizePathSeparatorsToPosix"),
|
|
45
46
|
);
|
|
@@ -52,7 +53,6 @@ var _Watcher = require("./Watcher");
|
|
|
52
53
|
var _events = _interopRequireDefault(require("events"));
|
|
53
54
|
var _fs = require("fs");
|
|
54
55
|
var _invariant = _interopRequireDefault(require("invariant"));
|
|
55
|
-
var _nullthrows = _interopRequireDefault(require("nullthrows"));
|
|
56
56
|
var path = _interopRequireWildcard(require("path"));
|
|
57
57
|
var _perf_hooks = require("perf_hooks");
|
|
58
58
|
var _DependencyPlugin = _interopRequireDefault(
|
|
@@ -270,7 +270,7 @@ class FileMap extends _events.default {
|
|
|
270
270
|
};
|
|
271
271
|
},
|
|
272
272
|
fileIterator: (opts) =>
|
|
273
|
-
|
|
273
|
+
mapIterable(
|
|
274
274
|
fileSystem.metadataIterator(opts),
|
|
275
275
|
({ baseName, canonicalPath, metadata }) => ({
|
|
276
276
|
baseName,
|
|
@@ -284,21 +284,21 @@ class FileMap extends _events.default {
|
|
|
284
284
|
),
|
|
285
285
|
),
|
|
286
286
|
]);
|
|
287
|
-
await this.#applyFileDelta(
|
|
287
|
+
const actualChanges = await this.#applyFileDelta(
|
|
288
|
+
fileSystem,
|
|
289
|
+
plugins,
|
|
290
|
+
fileDelta,
|
|
291
|
+
);
|
|
292
|
+
const changeSize = actualChanges.getSize();
|
|
288
293
|
plugins.forEach(({ plugin }) => plugin.assertValid());
|
|
289
294
|
const watchmanClocks = new Map(fileDelta.clocks ?? []);
|
|
290
295
|
await this.#takeSnapshotAndPersist(
|
|
291
296
|
fileSystem,
|
|
292
297
|
watchmanClocks,
|
|
293
298
|
plugins,
|
|
294
|
-
|
|
295
|
-
fileDelta.removedFiles,
|
|
296
|
-
);
|
|
297
|
-
debug(
|
|
298
|
-
"Finished mapping files (%d changes, %d removed).",
|
|
299
|
-
fileDelta.changedFiles.size,
|
|
300
|
-
fileDelta.removedFiles.size,
|
|
299
|
+
changeSize > 0,
|
|
301
300
|
);
|
|
301
|
+
debug("Finished mapping files (%d changes).", changeSize);
|
|
302
302
|
await this.#watch(fileSystem, watchmanClocks, plugins);
|
|
303
303
|
return {
|
|
304
304
|
fileSystem,
|
|
@@ -368,10 +368,9 @@ class FileMap extends _events.default {
|
|
|
368
368
|
});
|
|
369
369
|
const watcher = this.#watcher;
|
|
370
370
|
watcher.on("status", (status) => this.emit("status", status));
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
});
|
|
371
|
+
const result = await watcher.crawl();
|
|
372
|
+
this.#startupPerfLogger?.point("buildFileDelta_end");
|
|
373
|
+
return result;
|
|
375
374
|
}
|
|
376
375
|
#maybeReadLink(normalPath, fileMetadata) {
|
|
377
376
|
if (fileMetadata[_constants.default.SYMLINK] === 1) {
|
|
@@ -388,14 +387,11 @@ class FileMap extends _events.default {
|
|
|
388
387
|
this.#startupPerfLogger?.point("applyFileDelta_start");
|
|
389
388
|
const { changedFiles, removedFiles } = delta;
|
|
390
389
|
this.#startupPerfLogger?.point("applyFileDelta_preprocess_start");
|
|
391
|
-
const missingFiles = new Set();
|
|
392
390
|
this.#startupPerfLogger?.point("applyFileDelta_remove_start");
|
|
393
|
-
const
|
|
391
|
+
const changeAggregator =
|
|
392
|
+
new _FileSystemChangeAggregator.FileSystemChangeAggregator();
|
|
394
393
|
for (const relativeFilePath of removedFiles) {
|
|
395
|
-
|
|
396
|
-
if (metadata) {
|
|
397
|
-
removed.push([relativeFilePath, metadata]);
|
|
398
|
-
}
|
|
394
|
+
fileSystem.remove(relativeFilePath, changeAggregator);
|
|
399
395
|
}
|
|
400
396
|
this.#startupPerfLogger?.point("applyFileDelta_remove_end");
|
|
401
397
|
const readLinkPromises = [];
|
|
@@ -411,12 +407,12 @@ class FileMap extends _events.default {
|
|
|
411
407
|
const maybeReadLink = this.#maybeReadLink(normalFilePath, fileData);
|
|
412
408
|
if (maybeReadLink) {
|
|
413
409
|
readLinkPromises.push(
|
|
414
|
-
maybeReadLink.catch((error) =>
|
|
410
|
+
maybeReadLink.catch((error) => {
|
|
415
411
|
readLinkErrors.push({
|
|
416
412
|
normalFilePath,
|
|
417
413
|
error,
|
|
418
|
-
})
|
|
419
|
-
),
|
|
414
|
+
});
|
|
415
|
+
}),
|
|
420
416
|
);
|
|
421
417
|
}
|
|
422
418
|
}
|
|
@@ -441,37 +437,34 @@ class FileMap extends _events.default {
|
|
|
441
437
|
readLinkErrors,
|
|
442
438
|
)) {
|
|
443
439
|
if (["ENOENT", "EACCESS"].includes(error.code)) {
|
|
444
|
-
|
|
440
|
+
delta.changedFiles.delete(normalFilePath);
|
|
441
|
+
fileSystem.remove(normalFilePath, changeAggregator);
|
|
445
442
|
} else {
|
|
446
443
|
throw error;
|
|
447
444
|
}
|
|
448
445
|
}
|
|
449
|
-
for (const relativeFilePath of missingFiles) {
|
|
450
|
-
changedFiles.delete(relativeFilePath);
|
|
451
|
-
const metadata = fileSystem.remove(relativeFilePath);
|
|
452
|
-
if (metadata) {
|
|
453
|
-
removed.push([relativeFilePath, metadata]);
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
446
|
this.#startupPerfLogger?.point("applyFileDelta_missing_end");
|
|
457
447
|
this.#startupPerfLogger?.point("applyFileDelta_add_start");
|
|
458
|
-
fileSystem.bulkAddOrModify(changedFiles);
|
|
448
|
+
fileSystem.bulkAddOrModify(changedFiles, changeAggregator);
|
|
459
449
|
this.#startupPerfLogger?.point("applyFileDelta_add_end");
|
|
460
450
|
this.#startupPerfLogger?.point("applyFileDelta_updatePlugins_start");
|
|
461
|
-
plugins.forEach(({ plugin, dataIdx }) => {
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
? ([
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
addedOrModified: mapIterator(changedFiles.entries(), mapFn),
|
|
468
|
-
removed: mapIterator(removed.values(), mapFn),
|
|
469
|
-
});
|
|
451
|
+
this.#plugins.forEach(({ plugin, dataIdx }) => {
|
|
452
|
+
plugin.onChanged(
|
|
453
|
+
changeAggregator.getMappedView(
|
|
454
|
+
dataIdx != null ? (metadata) => metadata[dataIdx] : () => null,
|
|
455
|
+
),
|
|
456
|
+
);
|
|
470
457
|
});
|
|
471
458
|
this.#startupPerfLogger?.point("applyFileDelta_updatePlugins_end");
|
|
472
459
|
this.#startupPerfLogger?.point("applyFileDelta_end");
|
|
460
|
+
return changeAggregator;
|
|
473
461
|
}
|
|
474
|
-
async #takeSnapshotAndPersist(
|
|
462
|
+
async #takeSnapshotAndPersist(
|
|
463
|
+
fileSystem,
|
|
464
|
+
clocks,
|
|
465
|
+
plugins,
|
|
466
|
+
changedSinceCacheRead,
|
|
467
|
+
) {
|
|
475
468
|
this.#startupPerfLogger?.point("persist_start");
|
|
476
469
|
await this.#cacheManager.write(
|
|
477
470
|
() => ({
|
|
@@ -485,7 +478,7 @@ class FileMap extends _events.default {
|
|
|
485
478
|
),
|
|
486
479
|
}),
|
|
487
480
|
{
|
|
488
|
-
changedSinceCacheRead
|
|
481
|
+
changedSinceCacheRead,
|
|
489
482
|
eventSource: {
|
|
490
483
|
onChange: (cb) => {
|
|
491
484
|
this.on("change", cb);
|
|
@@ -511,14 +504,46 @@ class FileMap extends _events.default {
|
|
|
511
504
|
}
|
|
512
505
|
const hasWatchedExtension = (filePath) =>
|
|
513
506
|
this.#options.extensions.some((ext) => filePath.endsWith(ext));
|
|
514
|
-
let changeQueue = Promise.resolve();
|
|
515
507
|
let nextEmit = null;
|
|
516
508
|
const emitChange = () => {
|
|
517
|
-
if (nextEmit == null
|
|
509
|
+
if (nextEmit == null) {
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
const { events, firstEventTimestamp, firstEnqueuedTimestamp } = nextEmit;
|
|
513
|
+
const changeAggregator =
|
|
514
|
+
new _FileSystemChangeAggregator.FileSystemChangeAggregator();
|
|
515
|
+
for (const event of events) {
|
|
516
|
+
const { relativeFilePath, clock } = event;
|
|
517
|
+
if (event.type === "delete") {
|
|
518
|
+
fileSystem.remove(relativeFilePath, changeAggregator);
|
|
519
|
+
} else {
|
|
520
|
+
fileSystem.addOrModify(
|
|
521
|
+
relativeFilePath,
|
|
522
|
+
event.metadata,
|
|
523
|
+
changeAggregator,
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
this.#updateClock(clocks, clock);
|
|
527
|
+
}
|
|
528
|
+
const changeSize = changeAggregator.getSize();
|
|
529
|
+
if (changeSize === 0) {
|
|
530
|
+
nextEmit = null;
|
|
518
531
|
return;
|
|
519
532
|
}
|
|
520
|
-
const
|
|
521
|
-
|
|
533
|
+
const _netChange = changeAggregator.getView();
|
|
534
|
+
this.#plugins.forEach(({ plugin, dataIdx }) => {
|
|
535
|
+
plugin.onChanged(
|
|
536
|
+
changeAggregator.getMappedView(
|
|
537
|
+
dataIdx != null ? (metadata) => metadata[dataIdx] : () => null,
|
|
538
|
+
),
|
|
539
|
+
);
|
|
540
|
+
});
|
|
541
|
+
const toPublicMetadata = (metadata) => ({
|
|
542
|
+
isSymlink: metadata[_constants.default.SYMLINK] !== 0,
|
|
543
|
+
modifiedTime: metadata[_constants.default.MTIME] ?? null,
|
|
544
|
+
});
|
|
545
|
+
const changesWithMetadata =
|
|
546
|
+
changeAggregator.getMappedView(toPublicMetadata);
|
|
522
547
|
const hmrPerfLogger = this.#options.perfLoggerFactory?.("HMR", {
|
|
523
548
|
key: this.#getNextChangeID(),
|
|
524
549
|
});
|
|
@@ -532,20 +557,23 @@ class FileMap extends _events.default {
|
|
|
532
557
|
hmrPerfLogger.point("waitingForChangeInterval_end");
|
|
533
558
|
hmrPerfLogger.annotate({
|
|
534
559
|
int: {
|
|
535
|
-
|
|
560
|
+
changeSize,
|
|
536
561
|
},
|
|
537
562
|
});
|
|
538
563
|
hmrPerfLogger.point("fileChange_start");
|
|
539
564
|
}
|
|
540
565
|
const changeEvent = {
|
|
541
|
-
|
|
566
|
+
changes: changesWithMetadata,
|
|
542
567
|
logger: hmrPerfLogger,
|
|
568
|
+
rootDir: this.#options.rootDir,
|
|
543
569
|
};
|
|
544
570
|
this.emit("change", changeEvent);
|
|
545
571
|
nextEmit = null;
|
|
546
572
|
};
|
|
573
|
+
let changeQueue = Promise.resolve();
|
|
547
574
|
const onChange = (change) => {
|
|
548
575
|
if (
|
|
576
|
+
change.event !== "recrawl" &&
|
|
549
577
|
change.metadata &&
|
|
550
578
|
(change.metadata.type === "d" ||
|
|
551
579
|
(change.metadata.type === "f" &&
|
|
@@ -563,62 +591,36 @@ class FileMap extends _events.default {
|
|
|
563
591
|
}
|
|
564
592
|
const relativeFilePath =
|
|
565
593
|
this.#pathUtils.absoluteToNormal(absoluteFilePath);
|
|
566
|
-
const linkStats = fileSystem.linkStats(relativeFilePath);
|
|
567
|
-
if (
|
|
568
|
-
change.event === "touch" &&
|
|
569
|
-
linkStats != null &&
|
|
570
|
-
change.metadata.modifiedTime != null &&
|
|
571
|
-
linkStats.modifiedTime === change.metadata.modifiedTime
|
|
572
|
-
) {
|
|
573
|
-
return;
|
|
574
|
-
}
|
|
575
|
-
const eventTypeToEmit =
|
|
576
|
-
change.event === "touch"
|
|
577
|
-
? linkStats == null
|
|
578
|
-
? "add"
|
|
579
|
-
: "change"
|
|
580
|
-
: "delete";
|
|
581
594
|
const onChangeStartTime =
|
|
582
595
|
_perf_hooks.performance.timeOrigin + _perf_hooks.performance.now();
|
|
596
|
+
const enqueueEvent = (event) => {
|
|
597
|
+
nextEmit ??= {
|
|
598
|
+
events: [],
|
|
599
|
+
firstEnqueuedTimestamp:
|
|
600
|
+
_perf_hooks.performance.timeOrigin + _perf_hooks.performance.now(),
|
|
601
|
+
firstEventTimestamp: onChangeStartTime,
|
|
602
|
+
};
|
|
603
|
+
nextEmit.events.push(event);
|
|
604
|
+
};
|
|
583
605
|
changeQueue = changeQueue
|
|
584
606
|
.then(async () => {
|
|
585
607
|
if (
|
|
586
608
|
nextEmit != null &&
|
|
587
|
-
nextEmit.
|
|
609
|
+
nextEmit.events.find(
|
|
588
610
|
(event) =>
|
|
589
|
-
event.type ===
|
|
590
|
-
event.
|
|
611
|
+
event.type === change.event &&
|
|
612
|
+
event.relativeFilePath === relativeFilePath &&
|
|
591
613
|
((!event.metadata && !change.metadata) ||
|
|
592
614
|
(event.metadata &&
|
|
593
615
|
change.metadata &&
|
|
594
|
-
event.metadata.
|
|
616
|
+
event.metadata[_constants.default.MTIME] != null &&
|
|
595
617
|
change.metadata.modifiedTime != null &&
|
|
596
|
-
event.metadata.
|
|
618
|
+
event.metadata[_constants.default.MTIME] ===
|
|
597
619
|
change.metadata.modifiedTime)),
|
|
598
620
|
)
|
|
599
621
|
) {
|
|
600
622
|
return null;
|
|
601
623
|
}
|
|
602
|
-
const linkStats = fileSystem.linkStats(relativeFilePath);
|
|
603
|
-
const enqueueEvent = (metadata) => {
|
|
604
|
-
const event = {
|
|
605
|
-
filePath: absoluteFilePath,
|
|
606
|
-
metadata,
|
|
607
|
-
type: eventTypeToEmit,
|
|
608
|
-
};
|
|
609
|
-
if (nextEmit == null) {
|
|
610
|
-
nextEmit = {
|
|
611
|
-
eventsQueue: [event],
|
|
612
|
-
firstEnqueuedTimestamp:
|
|
613
|
-
_perf_hooks.performance.timeOrigin +
|
|
614
|
-
_perf_hooks.performance.now(),
|
|
615
|
-
firstEventTimestamp: onChangeStartTime,
|
|
616
|
-
};
|
|
617
|
-
} else {
|
|
618
|
-
nextEmit.eventsQueue.push(event);
|
|
619
|
-
}
|
|
620
|
-
return null;
|
|
621
|
-
};
|
|
622
624
|
if (change.event === "touch") {
|
|
623
625
|
(0, _invariant.default)(
|
|
624
626
|
change.metadata.size != null,
|
|
@@ -645,40 +647,65 @@ class FileMap extends _events.default {
|
|
|
645
647
|
},
|
|
646
648
|
);
|
|
647
649
|
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
fileMetadata[dataIdx],
|
|
655
|
-
)
|
|
656
|
-
: plugin.onNewOrModifiedFile(relativeFilePath),
|
|
657
|
-
);
|
|
658
|
-
enqueueEvent(change.metadata);
|
|
650
|
+
enqueueEvent({
|
|
651
|
+
clock: change.clock,
|
|
652
|
+
relativeFilePath,
|
|
653
|
+
metadata: fileMetadata,
|
|
654
|
+
type: change.event,
|
|
655
|
+
});
|
|
659
656
|
} catch (e) {
|
|
660
657
|
if (!["ENOENT", "EACCESS"].includes(e.code)) {
|
|
661
658
|
throw e;
|
|
662
659
|
}
|
|
663
660
|
}
|
|
664
661
|
} else if (change.event === "delete") {
|
|
665
|
-
|
|
662
|
+
enqueueEvent({
|
|
663
|
+
clock: change.clock,
|
|
664
|
+
relativeFilePath,
|
|
665
|
+
type: "delete",
|
|
666
|
+
});
|
|
667
|
+
} else if (change.event === "recrawl") {
|
|
668
|
+
emitChange();
|
|
669
|
+
const absoluteDirPath = path.join(
|
|
670
|
+
change.root,
|
|
671
|
+
(0, _normalizePathSeparatorsToSystem.default)(
|
|
672
|
+
change.relativePath,
|
|
673
|
+
),
|
|
674
|
+
);
|
|
675
|
+
const subpath = this.#pathUtils.absoluteToNormal(absoluteDirPath);
|
|
676
|
+
const watcher = this.#watcher;
|
|
677
|
+
(0, _invariant.default)(
|
|
678
|
+
watcher != null,
|
|
679
|
+
"Watcher must be initialized",
|
|
680
|
+
);
|
|
681
|
+
const crawlResult = await watcher.recrawl(subpath, fileSystem);
|
|
682
|
+
if (
|
|
683
|
+
crawlResult.changedFiles.size === 0 &&
|
|
684
|
+
crawlResult.removedFiles.size === 0
|
|
685
|
+
) {
|
|
666
686
|
return null;
|
|
667
687
|
}
|
|
668
|
-
const
|
|
669
|
-
fileSystem
|
|
688
|
+
const recrawlChangeAggregator = await this.#applyFileDelta(
|
|
689
|
+
fileSystem,
|
|
690
|
+
this.#plugins,
|
|
691
|
+
crawlResult,
|
|
670
692
|
);
|
|
671
693
|
this.#updateClock(clocks, change.clock);
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
modifiedTime: null,
|
|
679
|
-
size: null,
|
|
680
|
-
type: linkStats.fileType,
|
|
694
|
+
if (recrawlChangeAggregator.getSize() === 0) {
|
|
695
|
+
return null;
|
|
696
|
+
}
|
|
697
|
+
const toPublicMetadata = (metadata) => ({
|
|
698
|
+
isSymlink: metadata[_constants.default.SYMLINK] !== 0,
|
|
699
|
+
modifiedTime: metadata[_constants.default.MTIME] ?? null,
|
|
681
700
|
});
|
|
701
|
+
const changesWithMetadata =
|
|
702
|
+
recrawlChangeAggregator.getMappedView(toPublicMetadata);
|
|
703
|
+
const changeEvent = {
|
|
704
|
+
changes: changesWithMetadata,
|
|
705
|
+
logger: null,
|
|
706
|
+
rootDir: this.#options.rootDir,
|
|
707
|
+
};
|
|
708
|
+
this.emit("change", changeEvent);
|
|
682
709
|
} else {
|
|
683
710
|
throw new Error(
|
|
684
711
|
`metro-file-map: Unrecognized event type from watcher: ${change.event}`,
|
|
@@ -778,11 +805,9 @@ class FileMap extends _events.default {
|
|
|
778
805
|
static H = _constants.default;
|
|
779
806
|
}
|
|
780
807
|
exports.default = FileMap;
|
|
781
|
-
const
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
}
|
|
788
|
-
})();
|
|
808
|
+
const mapIterable = (it, fn) =>
|
|
809
|
+
(function* mapped() {
|
|
810
|
+
for (const item of it) {
|
|
811
|
+
yield fn(item);
|
|
812
|
+
}
|
|
813
|
+
})();
|