metro-file-map 0.71.2 → 0.72.1
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 +2 -1
- package/src/HasteFS.js +38 -1
- package/src/HasteFS.js.flow +49 -6
- package/src/ModuleMap.js.flow +1 -1
- package/src/cache/DiskCacheManager.js +0 -1
- package/src/cache/DiskCacheManager.js.flow +0 -1
- package/src/crawlers/watchman.js +59 -7
- package/src/crawlers/watchman.js.flow +29 -12
- package/src/flow-types.js.flow +3 -0
- package/src/index.js +14 -2
- package/src/index.js.flow +22 -4
- package/src/watchers/FSEventsWatcher.js.flow +3 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "metro-file-map",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.72.1",
|
|
4
4
|
"description": "[Experimental] - 🚇 File crawling, watching and mapping for Metro",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"repository": {
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"dependencies": {
|
|
16
|
+
"abort-controller": "^3.0.0",
|
|
16
17
|
"anymatch": "^3.0.3",
|
|
17
18
|
"debug": "^2.2.0",
|
|
18
19
|
"fb-watchman": "^2.0.0",
|
package/src/HasteFS.js
CHANGED
|
@@ -9,6 +9,8 @@ var _constants = _interopRequireDefault(require("./constants"));
|
|
|
9
9
|
|
|
10
10
|
var fastPath = _interopRequireWildcard(require("./lib/fast_path"));
|
|
11
11
|
|
|
12
|
+
var path = _interopRequireWildcard(require("path"));
|
|
13
|
+
|
|
12
14
|
var _jestUtil = require("jest-util");
|
|
13
15
|
|
|
14
16
|
function _getRequireWildcardCache(nodeInterop) {
|
|
@@ -66,7 +68,6 @@ function _interopRequireDefault(obj) {
|
|
|
66
68
|
* @format
|
|
67
69
|
*
|
|
68
70
|
*/
|
|
69
|
-
// $FlowFixMe[untyped-import] - jest-util
|
|
70
71
|
class HasteFS {
|
|
71
72
|
constructor({ rootDir, files }) {
|
|
72
73
|
this._rootDir = rootDir;
|
|
@@ -141,6 +142,42 @@ class HasteFS {
|
|
|
141
142
|
|
|
142
143
|
return files;
|
|
143
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* Given a search context, return a list of file paths matching the query.
|
|
147
|
+
* The query matches against normalized paths which start with `./`,
|
|
148
|
+
* for example: `a/b.js` -> `./a/b.js`
|
|
149
|
+
*/
|
|
150
|
+
|
|
151
|
+
matchFilesWithContext(root, context) {
|
|
152
|
+
const files = [];
|
|
153
|
+
const prefix = "./";
|
|
154
|
+
|
|
155
|
+
for (const file of this.getAbsoluteFileIterator()) {
|
|
156
|
+
const filePath = fastPath.relative(root, file);
|
|
157
|
+
const isUnderRoot = filePath && !filePath.startsWith(".."); // Ignore everything outside of the provided `root`.
|
|
158
|
+
|
|
159
|
+
if (!isUnderRoot) {
|
|
160
|
+
continue;
|
|
161
|
+
} // Prevent searching in child directories during a non-recursive search.
|
|
162
|
+
|
|
163
|
+
if (!context.recursive && filePath.includes(path.sep)) {
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (
|
|
168
|
+
context.filter.test(
|
|
169
|
+
// NOTE(EvanBacon): Ensure files start with `./` for matching purposes
|
|
170
|
+
// this ensures packages work across Metro and Webpack (ex: Storybook for React DOM / React Native).
|
|
171
|
+
// `a/b.js` -> `./a/b.js`
|
|
172
|
+
prefix + filePath.replace(/\\/g, "/")
|
|
173
|
+
)
|
|
174
|
+
) {
|
|
175
|
+
files.push(file);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return files;
|
|
180
|
+
}
|
|
144
181
|
|
|
145
182
|
matchFilesWithGlob(globs, root) {
|
|
146
183
|
const files = new Set();
|
package/src/HasteFS.js.flow
CHANGED
|
@@ -8,16 +8,13 @@
|
|
|
8
8
|
* @flow strict-local
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type {FileData, Path} from './flow-types';
|
|
11
|
+
import type {FileData, FileMetaData, Glob, Path} from './flow-types';
|
|
12
12
|
|
|
13
13
|
import H from './constants';
|
|
14
14
|
import * as fastPath from './lib/fast_path';
|
|
15
|
-
|
|
15
|
+
import * as path from 'path';
|
|
16
16
|
import {globsToMatcher, replacePathSepForGlob} from 'jest-util';
|
|
17
17
|
|
|
18
|
-
// $FlowFixMe[unclear-type] - Check TS Config.Glob
|
|
19
|
-
type Glob = any;
|
|
20
|
-
|
|
21
18
|
export default class HasteFS {
|
|
22
19
|
+_rootDir: Path;
|
|
23
20
|
+_files: FileData;
|
|
@@ -84,6 +81,52 @@ export default class HasteFS {
|
|
|
84
81
|
return files;
|
|
85
82
|
}
|
|
86
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Given a search context, return a list of file paths matching the query.
|
|
86
|
+
* The query matches against normalized paths which start with `./`,
|
|
87
|
+
* for example: `a/b.js` -> `./a/b.js`
|
|
88
|
+
*/
|
|
89
|
+
matchFilesWithContext(
|
|
90
|
+
root: Path,
|
|
91
|
+
context: $ReadOnly<{
|
|
92
|
+
/* Should search for files recursively. */
|
|
93
|
+
recursive: boolean,
|
|
94
|
+
/* Filter relative paths against a pattern. */
|
|
95
|
+
filter: RegExp,
|
|
96
|
+
}>,
|
|
97
|
+
): Array<Path> {
|
|
98
|
+
const files = [];
|
|
99
|
+
const prefix = './';
|
|
100
|
+
|
|
101
|
+
for (const file of this.getAbsoluteFileIterator()) {
|
|
102
|
+
const filePath = fastPath.relative(root, file);
|
|
103
|
+
|
|
104
|
+
const isUnderRoot = filePath && !filePath.startsWith('..');
|
|
105
|
+
// Ignore everything outside of the provided `root`.
|
|
106
|
+
if (!isUnderRoot) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Prevent searching in child directories during a non-recursive search.
|
|
111
|
+
if (!context.recursive && filePath.includes(path.sep)) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (
|
|
116
|
+
context.filter.test(
|
|
117
|
+
// NOTE(EvanBacon): Ensure files start with `./` for matching purposes
|
|
118
|
+
// this ensures packages work across Metro and Webpack (ex: Storybook for React DOM / React Native).
|
|
119
|
+
// `a/b.js` -> `./a/b.js`
|
|
120
|
+
prefix + filePath.replace(/\\/g, '/'),
|
|
121
|
+
)
|
|
122
|
+
) {
|
|
123
|
+
files.push(file);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return files;
|
|
128
|
+
}
|
|
129
|
+
|
|
87
130
|
matchFilesWithGlob(globs: $ReadOnlyArray<Glob>, root: ?Path): Set<Path> {
|
|
88
131
|
const files = new Set<string>();
|
|
89
132
|
const matcher = globsToMatcher(globs);
|
|
@@ -97,7 +140,7 @@ export default class HasteFS {
|
|
|
97
140
|
return files;
|
|
98
141
|
}
|
|
99
142
|
|
|
100
|
-
_getFileData(file: Path) {
|
|
143
|
+
_getFileData(file: Path): void | FileMetaData {
|
|
101
144
|
const relativePath = fastPath.relative(this._rootDir, file);
|
|
102
145
|
return this._files.get(relativePath);
|
|
103
146
|
}
|
package/src/ModuleMap.js.flow
CHANGED
|
@@ -19,7 +19,6 @@ import rootRelativeCacheKeys from '../lib/rootRelativeCacheKeys';
|
|
|
19
19
|
import {readFileSync, writeFileSync} from 'graceful-fs';
|
|
20
20
|
import {tmpdir} from 'os';
|
|
21
21
|
import path from 'path';
|
|
22
|
-
// $FlowFixMe[missing-export] - serialize and deserialize missing typedefs
|
|
23
22
|
import {deserialize, serialize} from 'v8';
|
|
24
23
|
|
|
25
24
|
type DiskCacheConfig = {
|
package/src/crawlers/watchman.js
CHANGED
|
@@ -91,8 +91,12 @@ async function capabilityCheck(client, caps) {
|
|
|
91
91
|
// @ts-expect-error: incorrectly typed
|
|
92
92
|
caps,
|
|
93
93
|
(error, response) => {
|
|
94
|
-
if (error) {
|
|
95
|
-
reject(
|
|
94
|
+
if (error != null || response == null) {
|
|
95
|
+
reject(
|
|
96
|
+
error !== null && error !== void 0
|
|
97
|
+
? error
|
|
98
|
+
: new Error("capabilityCheck: Response missing")
|
|
99
|
+
);
|
|
96
100
|
} else {
|
|
97
101
|
resolve(response);
|
|
98
102
|
}
|
|
@@ -102,6 +106,8 @@ async function capabilityCheck(client, caps) {
|
|
|
102
106
|
}
|
|
103
107
|
|
|
104
108
|
module.exports = async function watchmanCrawl(options) {
|
|
109
|
+
var _options$abortSignal;
|
|
110
|
+
|
|
105
111
|
const fields = ["name", "exists", "mtime_ms", "size"];
|
|
106
112
|
const { data, extensions, ignore, rootDir, roots, perfLogger } = options;
|
|
107
113
|
const clocks = data.clocks;
|
|
@@ -109,6 +115,10 @@ module.exports = async function watchmanCrawl(options) {
|
|
|
109
115
|
? void 0
|
|
110
116
|
: perfLogger.point("watchmanCrawl_start");
|
|
111
117
|
const client = new watchman.Client();
|
|
118
|
+
(_options$abortSignal = options.abortSignal) === null ||
|
|
119
|
+
_options$abortSignal === void 0
|
|
120
|
+
? void 0
|
|
121
|
+
: _options$abortSignal.addEventListener("abort", () => client.end());
|
|
112
122
|
perfLogger === null || perfLogger === void 0
|
|
113
123
|
? void 0
|
|
114
124
|
: perfLogger.point("watchmanCrawl/negotiateCapabilities_start"); // https://facebook.github.io/watchman/docs/capabilities.html
|
|
@@ -273,7 +283,7 @@ module.exports = async function watchmanCrawl(options) {
|
|
|
273
283
|
* directories. Therefore `glob` < `suffix`.
|
|
274
284
|
*/
|
|
275
285
|
|
|
276
|
-
let queryGenerator
|
|
286
|
+
let queryGenerator;
|
|
277
287
|
|
|
278
288
|
if (since != null) {
|
|
279
289
|
// Use the `since` generator and filter by both path and extension.
|
|
@@ -346,6 +356,7 @@ module.exports = async function watchmanCrawl(options) {
|
|
|
346
356
|
const changedFiles = new Map();
|
|
347
357
|
let results;
|
|
348
358
|
let isFresh = false;
|
|
359
|
+
let queryError;
|
|
349
360
|
|
|
350
361
|
try {
|
|
351
362
|
const watchmanRoots = await getWatchmanRoots(roots);
|
|
@@ -359,15 +370,56 @@ module.exports = async function watchmanCrawl(options) {
|
|
|
359
370
|
}
|
|
360
371
|
|
|
361
372
|
results = watchmanFileResults.results;
|
|
362
|
-
}
|
|
363
|
-
|
|
373
|
+
} catch (e) {
|
|
374
|
+
queryError = e;
|
|
364
375
|
}
|
|
365
376
|
|
|
366
|
-
|
|
377
|
+
client.end();
|
|
378
|
+
|
|
379
|
+
if (results == null) {
|
|
380
|
+
var _ref, _queryError;
|
|
381
|
+
|
|
382
|
+
if (clientError) {
|
|
383
|
+
var _clientError$message;
|
|
384
|
+
|
|
385
|
+
perfLogger === null || perfLogger === void 0
|
|
386
|
+
? void 0
|
|
387
|
+
: perfLogger.annotate({
|
|
388
|
+
string: {
|
|
389
|
+
"watchmanCrawl/client_error":
|
|
390
|
+
(_clientError$message = clientError.message) !== null &&
|
|
391
|
+
_clientError$message !== void 0
|
|
392
|
+
? _clientError$message
|
|
393
|
+
: "[message missing]",
|
|
394
|
+
},
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (queryError) {
|
|
399
|
+
var _queryError$message;
|
|
400
|
+
|
|
401
|
+
perfLogger === null || perfLogger === void 0
|
|
402
|
+
? void 0
|
|
403
|
+
: perfLogger.annotate({
|
|
404
|
+
string: {
|
|
405
|
+
"watchmanCrawl/query_error":
|
|
406
|
+
(_queryError$message = queryError.message) !== null &&
|
|
407
|
+
_queryError$message !== void 0
|
|
408
|
+
? _queryError$message
|
|
409
|
+
: "[message missing]",
|
|
410
|
+
},
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
|
|
367
414
|
perfLogger === null || perfLogger === void 0
|
|
368
415
|
? void 0
|
|
369
416
|
: perfLogger.point("watchmanCrawl_end");
|
|
370
|
-
throw
|
|
417
|
+
throw (_ref =
|
|
418
|
+
(_queryError = queryError) !== null && _queryError !== void 0
|
|
419
|
+
? _queryError
|
|
420
|
+
: clientError) !== null && _ref !== void 0
|
|
421
|
+
? _ref
|
|
422
|
+
: new Error("Watchman file results missing");
|
|
371
423
|
}
|
|
372
424
|
|
|
373
425
|
perfLogger === null || perfLogger === void 0
|
|
@@ -91,8 +91,8 @@ async function capabilityCheck(
|
|
|
91
91
|
// @ts-expect-error: incorrectly typed
|
|
92
92
|
caps,
|
|
93
93
|
(error, response) => {
|
|
94
|
-
if (error) {
|
|
95
|
-
reject(error);
|
|
94
|
+
if (error != null || response == null) {
|
|
95
|
+
reject(error ?? new Error('capabilityCheck: Response missing'));
|
|
96
96
|
} else {
|
|
97
97
|
resolve(response);
|
|
98
98
|
}
|
|
@@ -114,6 +114,7 @@ module.exports = async function watchmanCrawl(
|
|
|
114
114
|
|
|
115
115
|
perfLogger?.point('watchmanCrawl_start');
|
|
116
116
|
const client = new watchman.Client();
|
|
117
|
+
options.abortSignal?.addEventListener('abort', () => client.end());
|
|
117
118
|
|
|
118
119
|
perfLogger?.point('watchmanCrawl/negotiateCapabilities_start');
|
|
119
120
|
// https://facebook.github.io/watchman/docs/capabilities.html
|
|
@@ -268,11 +269,7 @@ module.exports = async function watchmanCrawl(
|
|
|
268
269
|
* repo but Haste map projects are focused on a handful of
|
|
269
270
|
* directories. Therefore `glob` < `suffix`.
|
|
270
271
|
*/
|
|
271
|
-
let queryGenerator: ?
|
|
272
|
-
| $TEMPORARY$string<'glob'>
|
|
273
|
-
| $TEMPORARY$string<'since'>
|
|
274
|
-
| $TEMPORARY$string<'suffix'>
|
|
275
|
-
) = undefined;
|
|
272
|
+
let queryGenerator: ?string;
|
|
276
273
|
if (since != null) {
|
|
277
274
|
// Use the `since` generator and filter by both path and extension.
|
|
278
275
|
query.since = since;
|
|
@@ -339,6 +336,7 @@ module.exports = async function watchmanCrawl(
|
|
|
339
336
|
const changedFiles = new Map();
|
|
340
337
|
let results: Map<string, WatchmanQueryResponse>;
|
|
341
338
|
let isFresh = false;
|
|
339
|
+
let queryError: ?Error;
|
|
342
340
|
try {
|
|
343
341
|
const watchmanRoots = await getWatchmanRoots(roots);
|
|
344
342
|
const watchmanFileResults = await queryWatchmanForDirs(watchmanRoots);
|
|
@@ -352,13 +350,32 @@ module.exports = async function watchmanCrawl(
|
|
|
352
350
|
}
|
|
353
351
|
|
|
354
352
|
results = watchmanFileResults.results;
|
|
355
|
-
}
|
|
356
|
-
|
|
353
|
+
} catch (e) {
|
|
354
|
+
queryError = e;
|
|
357
355
|
}
|
|
358
|
-
|
|
359
|
-
|
|
356
|
+
client.end();
|
|
357
|
+
|
|
358
|
+
if (results == null) {
|
|
359
|
+
if (clientError) {
|
|
360
|
+
perfLogger?.annotate({
|
|
361
|
+
string: {
|
|
362
|
+
'watchmanCrawl/client_error':
|
|
363
|
+
clientError.message ?? '[message missing]',
|
|
364
|
+
},
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
if (queryError) {
|
|
368
|
+
perfLogger?.annotate({
|
|
369
|
+
string: {
|
|
370
|
+
'watchmanCrawl/query_error':
|
|
371
|
+
queryError.message ?? '[message missing]',
|
|
372
|
+
},
|
|
373
|
+
});
|
|
374
|
+
}
|
|
360
375
|
perfLogger?.point('watchmanCrawl_end');
|
|
361
|
-
throw
|
|
376
|
+
throw (
|
|
377
|
+
queryError ?? clientError ?? new Error('Watchman file results missing')
|
|
378
|
+
);
|
|
362
379
|
}
|
|
363
380
|
|
|
364
381
|
perfLogger?.point('watchmanCrawl/processResults_start');
|
package/src/flow-types.js.flow
CHANGED
|
@@ -61,6 +61,7 @@ export type ChangeEvent = {
|
|
|
61
61
|
export type Console = typeof global.console;
|
|
62
62
|
|
|
63
63
|
export type CrawlerOptions = {
|
|
64
|
+
abortSignal: ?AbortSignal,
|
|
64
65
|
computeSha1: boolean,
|
|
65
66
|
enableSymlinks: boolean,
|
|
66
67
|
data: InternalData,
|
|
@@ -125,6 +126,8 @@ export type FileMetaData = [
|
|
|
125
126
|
/* sha1 */ ?string,
|
|
126
127
|
];
|
|
127
128
|
|
|
129
|
+
export type Glob = string;
|
|
130
|
+
|
|
128
131
|
export interface IModuleMap<S = SerializableModuleMap> {
|
|
129
132
|
getModule(
|
|
130
133
|
name: string,
|
package/src/index.js
CHANGED
|
@@ -72,6 +72,8 @@ var _jestWorker = require("jest-worker");
|
|
|
72
72
|
|
|
73
73
|
var path = _interopRequireWildcard(require("path"));
|
|
74
74
|
|
|
75
|
+
var _abortController = _interopRequireDefault(require("abort-controller"));
|
|
76
|
+
|
|
75
77
|
function _getRequireWildcardCache(nodeInterop) {
|
|
76
78
|
if (typeof WeakMap !== "function") return null;
|
|
77
79
|
var cacheBabelInterop = new WeakMap();
|
|
@@ -131,6 +133,7 @@ function _interopRequireDefault(obj) {
|
|
|
131
133
|
// $FlowFixMe[untyped-import] - WatchmanWatcher
|
|
132
134
|
// $FlowFixMe[untyped-import] - jest-regex-util
|
|
133
135
|
// $FlowFixMe[untyped-import] - jest-worker
|
|
136
|
+
// $FlowFixMe[untyped-import] - this is a polyfill
|
|
134
137
|
const nodeCrawl = require("./crawlers/node");
|
|
135
138
|
|
|
136
139
|
const watchmanCrawl = require("./crawlers/watchman");
|
|
@@ -141,7 +144,7 @@ exports.DuplicateHasteCandidatesError = DuplicateHasteCandidatesError;
|
|
|
141
144
|
// This should be bumped whenever a code change to `metro-file-map` itself
|
|
142
145
|
// would cause a change to the cache data structure and/or content (for a given
|
|
143
146
|
// filesystem state and build parameters).
|
|
144
|
-
const CACHE_BREAKER = "
|
|
147
|
+
const CACHE_BREAKER = "2";
|
|
145
148
|
const CHANGE_INTERVAL = 30;
|
|
146
149
|
const MAX_WAIT_TIME = 240000;
|
|
147
150
|
const NODE_MODULES = path.sep + "node_modules" + path.sep;
|
|
@@ -341,6 +344,7 @@ class HasteMap extends _events.default {
|
|
|
341
344
|
_this$_options$perfLo === void 0
|
|
342
345
|
? void 0
|
|
343
346
|
: _this$_options$perfLo.point("constructor_end");
|
|
347
|
+
this._crawlerAbortController = new _abortController.default();
|
|
344
348
|
}
|
|
345
349
|
|
|
346
350
|
static getCacheFilePath(cacheDirectory, cacheFilePrefix, buildParameters) {
|
|
@@ -889,6 +893,7 @@ class HasteMap extends _events.default {
|
|
|
889
893
|
const crawl =
|
|
890
894
|
canUseWatchman && this._options.useWatchman ? watchmanCrawl : nodeCrawl;
|
|
891
895
|
const crawlerOptions = {
|
|
896
|
+
abortSignal: this._crawlerAbortController.signal,
|
|
892
897
|
computeSha1: options.computeSha1,
|
|
893
898
|
data: hasteMap,
|
|
894
899
|
enableSymlinks: options.enableSymlinks,
|
|
@@ -983,7 +988,12 @@ class HasteMap extends _events.default {
|
|
|
983
988
|
const createWatcher = (root) => {
|
|
984
989
|
const watcher = new WatcherImpl(root, {
|
|
985
990
|
dot: true,
|
|
986
|
-
glob:
|
|
991
|
+
glob: [
|
|
992
|
+
// Ensure we always include package.json files, which are crucial for
|
|
993
|
+
/// module resolution.
|
|
994
|
+
"**/package.json",
|
|
995
|
+
...extensions.map((extension) => "**/*." + extension),
|
|
996
|
+
],
|
|
987
997
|
ignored: ignorePattern,
|
|
988
998
|
watchmanDeferStates: this._options.watchmanDeferStates,
|
|
989
999
|
});
|
|
@@ -1255,6 +1265,8 @@ class HasteMap extends _events.default {
|
|
|
1255
1265
|
|
|
1256
1266
|
await Promise.all(this._watchers.map((watcher) => watcher.close()));
|
|
1257
1267
|
this._watchers = [];
|
|
1268
|
+
|
|
1269
|
+
this._crawlerAbortController.abort();
|
|
1258
1270
|
}
|
|
1259
1271
|
/**
|
|
1260
1272
|
* Helpers
|
package/src/index.js.flow
CHANGED
|
@@ -56,6 +56,8 @@ import {escapePathForRegex} from 'jest-regex-util';
|
|
|
56
56
|
// $FlowFixMe[untyped-import] - jest-worker
|
|
57
57
|
import {Worker} from 'jest-worker';
|
|
58
58
|
import * as path from 'path';
|
|
59
|
+
// $FlowFixMe[untyped-import] - this is a polyfill
|
|
60
|
+
import AbortController from 'abort-controller';
|
|
59
61
|
|
|
60
62
|
const nodeCrawl = require('./crawlers/node');
|
|
61
63
|
const watchmanCrawl = require('./crawlers/watchman');
|
|
@@ -133,7 +135,7 @@ export type {
|
|
|
133
135
|
// This should be bumped whenever a code change to `metro-file-map` itself
|
|
134
136
|
// would cause a change to the cache data structure and/or content (for a given
|
|
135
137
|
// filesystem state and build parameters).
|
|
136
|
-
const CACHE_BREAKER = '
|
|
138
|
+
const CACHE_BREAKER = '2';
|
|
137
139
|
|
|
138
140
|
const CHANGE_INTERVAL = 30;
|
|
139
141
|
const MAX_WAIT_TIME = 240000;
|
|
@@ -237,6 +239,7 @@ export default class HasteMap extends EventEmitter {
|
|
|
237
239
|
_watchers: Array<Watcher>;
|
|
238
240
|
_worker: ?WorkerInterface;
|
|
239
241
|
_cacheManager: CacheManager;
|
|
242
|
+
_crawlerAbortController: typeof AbortController;
|
|
240
243
|
|
|
241
244
|
static create(options: InputOptions): HasteMap {
|
|
242
245
|
return new HasteMap(options);
|
|
@@ -320,6 +323,7 @@ export default class HasteMap extends EventEmitter {
|
|
|
320
323
|
this._watchers = [];
|
|
321
324
|
this._worker = null;
|
|
322
325
|
this._options.perfLogger?.point('constructor_end');
|
|
326
|
+
this._crawlerAbortController = new AbortController();
|
|
323
327
|
}
|
|
324
328
|
|
|
325
329
|
static getCacheFilePath(
|
|
@@ -774,13 +778,21 @@ export default class HasteMap extends EventEmitter {
|
|
|
774
778
|
return this._worker;
|
|
775
779
|
}
|
|
776
780
|
|
|
777
|
-
_crawl(hasteMap: InternalData)
|
|
781
|
+
_crawl(hasteMap: InternalData): Promise<?(
|
|
782
|
+
| Promise<{
|
|
783
|
+
changedFiles?: FileData,
|
|
784
|
+
hasteMap: InternalData,
|
|
785
|
+
removedFiles: FileData,
|
|
786
|
+
}>
|
|
787
|
+
| {changedFiles?: FileData, hasteMap: InternalData, removedFiles: FileData}
|
|
788
|
+
)> {
|
|
778
789
|
this._options.perfLogger?.point('crawl_start');
|
|
779
790
|
const options = this._options;
|
|
780
|
-
const ignore = filePath => this._ignore(filePath);
|
|
791
|
+
const ignore = (filePath: string) => this._ignore(filePath);
|
|
781
792
|
const crawl =
|
|
782
793
|
canUseWatchman && this._options.useWatchman ? watchmanCrawl : nodeCrawl;
|
|
783
794
|
const crawlerOptions: CrawlerOptions = {
|
|
795
|
+
abortSignal: this._crawlerAbortController.signal,
|
|
784
796
|
computeSha1: options.computeSha1,
|
|
785
797
|
data: hasteMap,
|
|
786
798
|
enableSymlinks: options.enableSymlinks,
|
|
@@ -862,7 +874,12 @@ export default class HasteMap extends EventEmitter {
|
|
|
862
874
|
const createWatcher = (root: Path): Promise<Watcher> => {
|
|
863
875
|
const watcher = new WatcherImpl(root, {
|
|
864
876
|
dot: true,
|
|
865
|
-
glob:
|
|
877
|
+
glob: [
|
|
878
|
+
// Ensure we always include package.json files, which are crucial for
|
|
879
|
+
/// module resolution.
|
|
880
|
+
'**/package.json',
|
|
881
|
+
...extensions.map(extension => '**/*.' + extension),
|
|
882
|
+
],
|
|
866
883
|
ignored: ignorePattern,
|
|
867
884
|
watchmanDeferStates: this._options.watchmanDeferStates,
|
|
868
885
|
});
|
|
@@ -1118,6 +1135,7 @@ export default class HasteMap extends EventEmitter {
|
|
|
1118
1135
|
await Promise.all(this._watchers.map(watcher => watcher.close()));
|
|
1119
1136
|
|
|
1120
1137
|
this._watchers = [];
|
|
1138
|
+
this._crawlerAbortController.abort();
|
|
1121
1139
|
}
|
|
1122
1140
|
|
|
1123
1141
|
/**
|
|
@@ -61,7 +61,8 @@ export default class FSEventsWatcher extends EventEmitter {
|
|
|
61
61
|
|
|
62
62
|
static _normalizeProxy(
|
|
63
63
|
callback: (normalizedPath: string, stats: fs.Stats) => void,
|
|
64
|
-
|
|
64
|
+
// $FlowFixMe[cannot-resolve-name]
|
|
65
|
+
): (filepath: string, stats: Stats) => void {
|
|
65
66
|
return (filepath: string, stats: fs.Stats): void =>
|
|
66
67
|
callback(path.normalize(filepath), stats);
|
|
67
68
|
}
|
|
@@ -149,7 +150,7 @@ export default class FSEventsWatcher extends EventEmitter {
|
|
|
149
150
|
}
|
|
150
151
|
}
|
|
151
152
|
|
|
152
|
-
_isFileIncluded(relativePath: string) {
|
|
153
|
+
_isFileIncluded(relativePath: string): boolean {
|
|
153
154
|
if (this.doIgnore(relativePath)) {
|
|
154
155
|
return false;
|
|
155
156
|
}
|