metro-file-map 0.83.3 → 0.83.5
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 +3 -2
- package/src/Watcher.d.ts +51 -5
- package/src/Watcher.js +59 -52
- package/src/Watcher.js.flow +39 -39
- package/src/cache/DiskCacheManager.d.ts +16 -12
- package/src/cache/DiskCacheManager.js.flow +3 -3
- package/src/constants.d.ts +15 -0
- package/src/constants.js +9 -8
- package/src/constants.js.flow +6 -18
- package/src/crawlers/node/hasNativeFindSupport.d.ts +12 -0
- package/src/crawlers/node/index.d.ts +16 -0
- package/src/crawlers/node/index.js +27 -25
- package/src/crawlers/node/index.js.flow +6 -8
- package/src/crawlers/watchman/index.d.ts +23 -0
- package/src/crawlers/watchman/index.js +26 -22
- package/src/crawlers/watchman/index.js.flow +3 -4
- package/src/crawlers/watchman/planQuery.d.ts +24 -0
- package/src/crawlers/watchman/planQuery.js.flow +4 -4
- package/src/flow-types.d.ts +217 -166
- package/src/flow-types.js.flow +125 -87
- package/src/index.d.ts +114 -36
- package/src/index.js +267 -237
- package/src/index.js.flow +267 -278
- package/src/lib/FileProcessor.d.ts +53 -0
- package/src/lib/FileProcessor.js +76 -54
- package/src/lib/FileProcessor.js.flow +93 -72
- package/src/lib/RootPathUtils.d.ts +23 -0
- package/src/lib/RootPathUtils.js +25 -21
- package/src/lib/RootPathUtils.js.flow +4 -4
- package/src/lib/TreeFS.d.ts +159 -0
- package/src/lib/TreeFS.js +72 -77
- package/src/lib/TreeFS.js.flow +104 -124
- package/src/lib/checkWatchmanCapabilities.d.ts +13 -0
- package/src/lib/checkWatchmanCapabilities.js.flow +4 -4
- package/src/lib/dependencyExtractor.d.ts +14 -0
- package/src/lib/normalizePathSeparatorsToPosix.d.ts +13 -0
- package/src/lib/normalizePathSeparatorsToPosix.js +25 -21
- package/src/lib/normalizePathSeparatorsToPosix.js.flow +3 -3
- package/src/lib/normalizePathSeparatorsToSystem.d.ts +13 -0
- package/src/lib/normalizePathSeparatorsToSystem.js +25 -21
- package/src/lib/normalizePathSeparatorsToSystem.js.flow +3 -3
- package/src/lib/rootRelativeCacheKeys.d.ts +17 -0
- package/src/lib/rootRelativeCacheKeys.js +0 -20
- package/src/lib/rootRelativeCacheKeys.js.flow +1 -23
- package/src/lib/sorting.d.ts +16 -0
- package/src/plugins/DependencyPlugin.d.ts +56 -0
- package/src/plugins/DependencyPlugin.js +75 -0
- package/src/plugins/DependencyPlugin.js.flow +144 -0
- package/src/plugins/HastePlugin.d.ts +70 -0
- package/src/plugins/HastePlugin.js +84 -39
- package/src/plugins/HastePlugin.js.flow +105 -51
- package/src/plugins/MockPlugin.d.ts +43 -0
- package/src/plugins/MockPlugin.js +9 -6
- package/src/plugins/MockPlugin.js.flow +25 -16
- package/src/plugins/dependencies/dependencyExtractor.d.ts +14 -0
- package/src/{lib → plugins/dependencies}/dependencyExtractor.js.flow +3 -6
- package/src/plugins/dependencies/worker.d.ts +24 -0
- package/src/plugins/dependencies/worker.js +24 -0
- package/src/plugins/dependencies/worker.js.flow +53 -0
- package/src/{lib → plugins/haste}/DuplicateHasteCandidatesError.d.ts +2 -2
- package/src/plugins/haste/HasteConflictsError.d.ts +16 -0
- package/src/plugins/haste/HasteConflictsError.js.flow +2 -2
- package/src/plugins/haste/computeConflicts.d.ts +27 -0
- package/src/plugins/haste/computeConflicts.js +2 -1
- package/src/plugins/haste/computeConflicts.js.flow +11 -12
- package/src/plugins/haste/getPlatformExtension.d.ts +14 -0
- package/src/plugins/haste/getPlatformExtension.js.flow +2 -2
- package/src/plugins/haste/worker.d.ts +24 -0
- package/src/plugins/haste/worker.js +35 -0
- package/src/plugins/haste/worker.js.flow +64 -0
- package/src/plugins/mocks/getMockName.d.ts +13 -0
- package/src/plugins/mocks/getMockName.js +27 -23
- package/src/plugins/mocks/getMockName.js.flow +2 -4
- package/src/watchers/AbstractWatcher.d.ts +34 -0
- package/src/watchers/AbstractWatcher.js +27 -22
- package/src/watchers/AbstractWatcher.js.flow +6 -5
- package/src/watchers/FallbackWatcher.d.ts +21 -0
- package/src/watchers/FallbackWatcher.js +88 -84
- package/src/watchers/FallbackWatcher.js.flow +65 -65
- package/src/watchers/NativeWatcher.d.ts +48 -0
- package/src/watchers/NativeWatcher.js +25 -21
- package/src/watchers/NativeWatcher.js.flow +3 -3
- package/src/watchers/RecrawlWarning.d.ts +25 -0
- package/src/watchers/RecrawlWarning.js.flow +1 -1
- package/src/watchers/WatchmanWatcher.d.ts +27 -0
- package/src/watchers/WatchmanWatcher.js +61 -53
- package/src/watchers/WatchmanWatcher.js.flow +39 -38
- package/src/watchers/common.d.ts +61 -0
- package/src/watchers/common.js.flow +5 -5
- package/src/worker.d.ts +36 -0
- package/src/worker.js +16 -58
- package/src/worker.js.flow +19 -69
- package/src/workerExclusionList.d.ts +12 -0
- package/src/workerExclusionList.js.flow +1 -1
- /package/src/{lib → plugins/dependencies}/dependencyExtractor.js +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "metro-file-map",
|
|
3
|
-
"version": "0.83.
|
|
3
|
+
"version": "0.83.5",
|
|
4
4
|
"description": "[Experimental] - 🚇 File crawling, watching and mapping for Metro",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
},
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
13
|
-
"url": "git
|
|
13
|
+
"url": "git+https://github.com/facebook/metro.git",
|
|
14
|
+
"directory": "packages/metro-file-map"
|
|
14
15
|
},
|
|
15
16
|
"scripts": {
|
|
16
17
|
"prepare-release": "test -d build && rm -rf src.real && mv src src.real && mv build src",
|
package/src/Watcher.d.ts
CHANGED
|
@@ -5,20 +5,66 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
* @format
|
|
8
|
-
* @oncall react_native
|
|
9
8
|
*/
|
|
10
9
|
|
|
10
|
+
import type {
|
|
11
|
+
Console,
|
|
12
|
+
CrawlerOptions,
|
|
13
|
+
FileData,
|
|
14
|
+
Path,
|
|
15
|
+
PerfLogger,
|
|
16
|
+
WatcherBackendChangeEvent,
|
|
17
|
+
WatchmanClocks,
|
|
18
|
+
} from './flow-types';
|
|
19
|
+
|
|
20
|
+
import EventEmitter from 'events';
|
|
21
|
+
|
|
22
|
+
type CrawlResult = {
|
|
23
|
+
changedFiles: FileData;
|
|
24
|
+
clocks?: WatchmanClocks;
|
|
25
|
+
removedFiles: Set<Path>;
|
|
26
|
+
};
|
|
27
|
+
type WatcherOptions = {
|
|
28
|
+
abortSignal: AbortSignal;
|
|
29
|
+
computeSha1: boolean;
|
|
30
|
+
console: Console;
|
|
31
|
+
enableSymlinks: boolean;
|
|
32
|
+
extensions: ReadonlyArray<string>;
|
|
33
|
+
forceNodeFilesystemAPI: boolean;
|
|
34
|
+
healthCheckFilePrefix: string;
|
|
35
|
+
ignoreForCrawl: (filePath: string) => boolean;
|
|
36
|
+
ignorePatternForWatch: RegExp;
|
|
37
|
+
previousState: CrawlerOptions['previousState'];
|
|
38
|
+
perfLogger: null | undefined | PerfLogger;
|
|
39
|
+
roots: ReadonlyArray<string>;
|
|
40
|
+
rootDir: string;
|
|
41
|
+
useWatchman: boolean;
|
|
42
|
+
watch: boolean;
|
|
43
|
+
watchmanDeferStates: ReadonlyArray<string>;
|
|
44
|
+
};
|
|
11
45
|
export type HealthCheckResult =
|
|
12
|
-
| {
|
|
46
|
+
| {
|
|
47
|
+
type: 'error';
|
|
48
|
+
timeout: number;
|
|
49
|
+
error: Error;
|
|
50
|
+
watcher: null | undefined | string;
|
|
51
|
+
}
|
|
13
52
|
| {
|
|
14
53
|
type: 'success';
|
|
15
54
|
timeout: number;
|
|
16
55
|
timeElapsed: number;
|
|
17
|
-
watcher:
|
|
56
|
+
watcher: null | undefined | string;
|
|
18
57
|
}
|
|
19
58
|
| {
|
|
20
59
|
type: 'timeout';
|
|
21
60
|
timeout: number;
|
|
22
|
-
watcher:
|
|
23
|
-
pauseReason:
|
|
61
|
+
watcher: null | undefined | string;
|
|
62
|
+
pauseReason: null | undefined | string;
|
|
24
63
|
};
|
|
64
|
+
export declare class Watcher extends EventEmitter {
|
|
65
|
+
constructor(options: WatcherOptions);
|
|
66
|
+
crawl(): Promise<CrawlResult>;
|
|
67
|
+
watch(onChange: (change: WatcherBackendChangeEvent) => void): void;
|
|
68
|
+
close(): void;
|
|
69
|
+
checkHealth(timeout: number): Promise<HealthCheckResult>;
|
|
70
|
+
}
|
package/src/Watcher.js
CHANGED
|
@@ -21,28 +21,32 @@ var fs = _interopRequireWildcard(require("fs"));
|
|
|
21
21
|
var _nullthrows = _interopRequireDefault(require("nullthrows"));
|
|
22
22
|
var path = _interopRequireWildcard(require("path"));
|
|
23
23
|
var _perf_hooks = require("perf_hooks");
|
|
24
|
-
function
|
|
25
|
-
if ("function"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
var n = { __proto__: null },
|
|
39
|
-
a = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
40
|
-
for (var u in e)
|
|
41
|
-
if ("default" !== u && {}.hasOwnProperty.call(e, u)) {
|
|
42
|
-
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null;
|
|
43
|
-
i && (i.get || i.set) ? Object.defineProperty(n, u, i) : (n[u] = e[u]);
|
|
24
|
+
function _interopRequireWildcard(e, t) {
|
|
25
|
+
if ("function" == typeof WeakMap)
|
|
26
|
+
var r = new WeakMap(),
|
|
27
|
+
n = new WeakMap();
|
|
28
|
+
return (_interopRequireWildcard = function (e, t) {
|
|
29
|
+
if (!t && e && e.__esModule) return e;
|
|
30
|
+
var o,
|
|
31
|
+
i,
|
|
32
|
+
f = { __proto__: null, default: e };
|
|
33
|
+
if (null === e || ("object" != typeof e && "function" != typeof e))
|
|
34
|
+
return f;
|
|
35
|
+
if ((o = t ? n : r)) {
|
|
36
|
+
if (o.has(e)) return o.get(e);
|
|
37
|
+
o.set(e, f);
|
|
44
38
|
}
|
|
45
|
-
|
|
39
|
+
for (const t in e)
|
|
40
|
+
"default" !== t &&
|
|
41
|
+
{}.hasOwnProperty.call(e, t) &&
|
|
42
|
+
((i =
|
|
43
|
+
(o = Object.defineProperty) &&
|
|
44
|
+
Object.getOwnPropertyDescriptor(e, t)) &&
|
|
45
|
+
(i.get || i.set)
|
|
46
|
+
? o(f, t, i)
|
|
47
|
+
: (f[t] = e[t]));
|
|
48
|
+
return f;
|
|
49
|
+
})(e, t);
|
|
46
50
|
}
|
|
47
51
|
function _interopRequireDefault(e) {
|
|
48
52
|
return e && e.__esModule ? e : { default: e };
|
|
@@ -51,20 +55,23 @@ const debug = require("debug")("Metro:Watcher");
|
|
|
51
55
|
const MAX_WAIT_TIME = 240000;
|
|
52
56
|
let nextInstanceId = 0;
|
|
53
57
|
class Watcher extends _events.default {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
#activeWatcher;
|
|
59
|
+
#backends = [];
|
|
60
|
+
#instanceId;
|
|
61
|
+
#nextHealthCheckId = 0;
|
|
62
|
+
#options;
|
|
63
|
+
#pendingHealthChecks = new Map();
|
|
57
64
|
constructor(options) {
|
|
58
65
|
super();
|
|
59
|
-
this
|
|
60
|
-
this
|
|
66
|
+
this.#options = options;
|
|
67
|
+
this.#instanceId = nextInstanceId++;
|
|
61
68
|
}
|
|
62
69
|
async crawl() {
|
|
63
|
-
this.
|
|
64
|
-
const options = this
|
|
70
|
+
this.#options.perfLogger?.point("crawl_start");
|
|
71
|
+
const options = this.#options;
|
|
65
72
|
const ignoreForCrawl = (filePath) =>
|
|
66
73
|
options.ignoreForCrawl(filePath) ||
|
|
67
|
-
path.basename(filePath).startsWith(this.
|
|
74
|
+
path.basename(filePath).startsWith(this.#options.healthCheckFilePrefix);
|
|
68
75
|
const crawl = options.useWatchman ? _watchman.default : _node.default;
|
|
69
76
|
let crawler = crawl === _watchman.default ? "watchman" : "node";
|
|
70
77
|
options.abortSignal.throwIfAborted();
|
|
@@ -114,7 +121,7 @@ class Watcher extends _events.default {
|
|
|
114
121
|
delta.removedFiles.size,
|
|
115
122
|
delta.clocks?.size ?? 0,
|
|
116
123
|
);
|
|
117
|
-
this.
|
|
124
|
+
this.#options.perfLogger?.point("crawl_end");
|
|
118
125
|
return delta;
|
|
119
126
|
};
|
|
120
127
|
debug('Beginning crawl with "%s".', crawler);
|
|
@@ -125,7 +132,7 @@ class Watcher extends _events.default {
|
|
|
125
132
|
}
|
|
126
133
|
}
|
|
127
134
|
async watch(onChange) {
|
|
128
|
-
const { extensions, ignorePatternForWatch, useWatchman } = this
|
|
135
|
+
const { extensions, ignorePatternForWatch, useWatchman } = this.#options;
|
|
129
136
|
const WatcherImpl = useWatchman
|
|
130
137
|
? _WatchmanWatcher.default
|
|
131
138
|
: _NativeWatcher.default.isSupported()
|
|
@@ -138,22 +145,22 @@ class Watcher extends _events.default {
|
|
|
138
145
|
watcher = "native";
|
|
139
146
|
}
|
|
140
147
|
debug(`Using watcher: ${watcher}`);
|
|
141
|
-
this.
|
|
148
|
+
this.#options.perfLogger?.annotate({
|
|
142
149
|
string: {
|
|
143
150
|
watcher,
|
|
144
151
|
},
|
|
145
152
|
});
|
|
146
|
-
this
|
|
153
|
+
this.#activeWatcher = watcher;
|
|
147
154
|
const createWatcherBackend = (root) => {
|
|
148
155
|
const watcherOptions = {
|
|
149
156
|
dot: true,
|
|
150
157
|
globs: [
|
|
151
158
|
"**/package.json",
|
|
152
|
-
"**/" + this.
|
|
159
|
+
"**/" + this.#options.healthCheckFilePrefix + "*",
|
|
153
160
|
...extensions.map((extension) => "**/*." + extension),
|
|
154
161
|
],
|
|
155
162
|
ignored: ignorePatternForWatch,
|
|
156
|
-
watchmanDeferStates: this.
|
|
163
|
+
watchmanDeferStates: this.#options.watchmanDeferStates,
|
|
157
164
|
};
|
|
158
165
|
const watcher = new WatcherImpl(root, watcherOptions);
|
|
159
166
|
return new Promise(async (resolve, reject) => {
|
|
@@ -163,14 +170,14 @@ class Watcher extends _events.default {
|
|
|
163
170
|
);
|
|
164
171
|
watcher.onFileEvent((change) => {
|
|
165
172
|
const basename = path.basename(change.relativePath);
|
|
166
|
-
if (basename.startsWith(this.
|
|
173
|
+
if (basename.startsWith(this.#options.healthCheckFilePrefix)) {
|
|
167
174
|
if (change.event === _common.TOUCH_EVENT) {
|
|
168
175
|
debug(
|
|
169
176
|
"Observed possible health check cookie: %s in %s",
|
|
170
177
|
change.relativePath,
|
|
171
178
|
root,
|
|
172
179
|
);
|
|
173
|
-
this
|
|
180
|
+
this.#handleHealthCheckObservation(basename);
|
|
174
181
|
}
|
|
175
182
|
return;
|
|
176
183
|
}
|
|
@@ -181,36 +188,36 @@ class Watcher extends _events.default {
|
|
|
181
188
|
resolve(watcher);
|
|
182
189
|
});
|
|
183
190
|
};
|
|
184
|
-
this
|
|
185
|
-
this.
|
|
191
|
+
this.#backends = await Promise.all(
|
|
192
|
+
this.#options.roots.map(createWatcherBackend),
|
|
186
193
|
);
|
|
187
194
|
}
|
|
188
|
-
|
|
189
|
-
const resolveHealthCheck = this.
|
|
195
|
+
#handleHealthCheckObservation(basename) {
|
|
196
|
+
const resolveHealthCheck = this.#pendingHealthChecks.get(basename);
|
|
190
197
|
if (!resolveHealthCheck) {
|
|
191
198
|
return;
|
|
192
199
|
}
|
|
193
200
|
resolveHealthCheck();
|
|
194
201
|
}
|
|
195
202
|
async close() {
|
|
196
|
-
await Promise.all(this.
|
|
197
|
-
this
|
|
203
|
+
await Promise.all(this.#backends.map((watcher) => watcher.stopWatching()));
|
|
204
|
+
this.#activeWatcher = null;
|
|
198
205
|
}
|
|
199
206
|
async checkHealth(timeout) {
|
|
200
|
-
const healthCheckId = this
|
|
207
|
+
const healthCheckId = this.#nextHealthCheckId++;
|
|
201
208
|
if (healthCheckId === Number.MAX_SAFE_INTEGER) {
|
|
202
|
-
this
|
|
209
|
+
this.#nextHealthCheckId = 0;
|
|
203
210
|
}
|
|
204
|
-
const watcher = this
|
|
211
|
+
const watcher = this.#activeWatcher;
|
|
205
212
|
const basename =
|
|
206
|
-
this.
|
|
213
|
+
this.#options.healthCheckFilePrefix +
|
|
207
214
|
"-" +
|
|
208
215
|
process.pid +
|
|
209
216
|
"-" +
|
|
210
|
-
this
|
|
217
|
+
this.#instanceId +
|
|
211
218
|
"-" +
|
|
212
219
|
healthCheckId;
|
|
213
|
-
const healthCheckPath = path.join(this.
|
|
220
|
+
const healthCheckPath = path.join(this.#options.rootDir, basename);
|
|
214
221
|
let result;
|
|
215
222
|
const timeoutPromise = new Promise((resolve) =>
|
|
216
223
|
setTimeout(resolve, timeout),
|
|
@@ -218,7 +225,7 @@ class Watcher extends _events.default {
|
|
|
218
225
|
if (!result) {
|
|
219
226
|
result = {
|
|
220
227
|
type: "timeout",
|
|
221
|
-
pauseReason: this
|
|
228
|
+
pauseReason: this.#backends[0]?.getPauseReason(),
|
|
222
229
|
timeout,
|
|
223
230
|
watcher,
|
|
224
231
|
};
|
|
@@ -239,7 +246,7 @@ class Watcher extends _events.default {
|
|
|
239
246
|
}
|
|
240
247
|
});
|
|
241
248
|
const observationPromise = new Promise((resolve) => {
|
|
242
|
-
this.
|
|
249
|
+
this.#pendingHealthChecks.set(basename, resolve);
|
|
243
250
|
}).then(() => {
|
|
244
251
|
if (!result) {
|
|
245
252
|
result = {
|
|
@@ -254,7 +261,7 @@ class Watcher extends _events.default {
|
|
|
254
261
|
timeoutPromise,
|
|
255
262
|
creationPromise.then(() => observationPromise),
|
|
256
263
|
]);
|
|
257
|
-
this.
|
|
264
|
+
this.#pendingHealthChecks.delete(basename);
|
|
258
265
|
creationPromise.then(() =>
|
|
259
266
|
fs.promises.unlink(healthCheckPath).catch(() => {}),
|
|
260
267
|
);
|
package/src/Watcher.js.flow
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @format
|
|
8
7
|
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import type {
|
|
@@ -48,18 +48,18 @@ type WatcherOptions = {
|
|
|
48
48
|
computeSha1: boolean,
|
|
49
49
|
console: Console,
|
|
50
50
|
enableSymlinks: boolean,
|
|
51
|
-
extensions:
|
|
51
|
+
extensions: ReadonlyArray<string>,
|
|
52
52
|
forceNodeFilesystemAPI: boolean,
|
|
53
53
|
healthCheckFilePrefix: string,
|
|
54
|
-
ignoreForCrawl: string => boolean,
|
|
54
|
+
ignoreForCrawl: (filePath: string) => boolean,
|
|
55
55
|
ignorePatternForWatch: RegExp,
|
|
56
56
|
previousState: CrawlerOptions['previousState'],
|
|
57
57
|
perfLogger: ?PerfLogger,
|
|
58
|
-
roots:
|
|
58
|
+
roots: ReadonlyArray<string>,
|
|
59
59
|
rootDir: string,
|
|
60
60
|
useWatchman: boolean,
|
|
61
61
|
watch: boolean,
|
|
62
|
-
watchmanDeferStates:
|
|
62
|
+
watchmanDeferStates: ReadonlyArray<string>,
|
|
63
63
|
};
|
|
64
64
|
|
|
65
65
|
let nextInstanceId = 0;
|
|
@@ -70,27 +70,27 @@ export type HealthCheckResult =
|
|
|
70
70
|
| {type: 'timeout', timeout: number, watcher: ?string, pauseReason: ?string};
|
|
71
71
|
|
|
72
72
|
export class Watcher extends EventEmitter {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
73
|
+
#activeWatcher: ?string;
|
|
74
|
+
#backends: ReadonlyArray<WatcherBackend> = [];
|
|
75
|
+
+#instanceId: number;
|
|
76
|
+
#nextHealthCheckId: number = 0;
|
|
77
|
+
+#options: WatcherOptions;
|
|
78
|
+
+#pendingHealthChecks: Map</* basename */ string, /* resolve */ () => void> =
|
|
78
79
|
new Map();
|
|
79
|
-
_activeWatcher: ?string;
|
|
80
80
|
|
|
81
81
|
constructor(options: WatcherOptions) {
|
|
82
82
|
super();
|
|
83
|
-
this
|
|
84
|
-
this
|
|
83
|
+
this.#options = options;
|
|
84
|
+
this.#instanceId = nextInstanceId++;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
async crawl(): Promise<CrawlResult> {
|
|
88
|
-
this.
|
|
88
|
+
this.#options.perfLogger?.point('crawl_start');
|
|
89
89
|
|
|
90
|
-
const options = this
|
|
90
|
+
const options = this.#options;
|
|
91
91
|
const ignoreForCrawl = (filePath: string) =>
|
|
92
92
|
options.ignoreForCrawl(filePath) ||
|
|
93
|
-
path.basename(filePath).startsWith(this.
|
|
93
|
+
path.basename(filePath).startsWith(this.#options.healthCheckFilePrefix);
|
|
94
94
|
const crawl = options.useWatchman ? watchmanCrawl : nodeCrawl;
|
|
95
95
|
let crawler = crawl === watchmanCrawl ? 'watchman' : 'node';
|
|
96
96
|
|
|
@@ -146,7 +146,7 @@ export class Watcher extends EventEmitter {
|
|
|
146
146
|
delta.removedFiles.size,
|
|
147
147
|
delta.clocks?.size ?? 0,
|
|
148
148
|
);
|
|
149
|
-
this.
|
|
149
|
+
this.#options.perfLogger?.point('crawl_end');
|
|
150
150
|
return delta;
|
|
151
151
|
};
|
|
152
152
|
|
|
@@ -160,7 +160,7 @@ export class Watcher extends EventEmitter {
|
|
|
160
160
|
}
|
|
161
161
|
|
|
162
162
|
async watch(onChange: (change: WatcherBackendChangeEvent) => void) {
|
|
163
|
-
const {extensions, ignorePatternForWatch, useWatchman} = this
|
|
163
|
+
const {extensions, ignorePatternForWatch, useWatchman} = this.#options;
|
|
164
164
|
|
|
165
165
|
// WatchmanWatcher > NativeWatcher > FallbackWatcher
|
|
166
166
|
const WatcherImpl = useWatchman
|
|
@@ -176,8 +176,8 @@ export class Watcher extends EventEmitter {
|
|
|
176
176
|
watcher = 'native';
|
|
177
177
|
}
|
|
178
178
|
debug(`Using watcher: ${watcher}`);
|
|
179
|
-
this.
|
|
180
|
-
this
|
|
179
|
+
this.#options.perfLogger?.annotate({string: {watcher}});
|
|
180
|
+
this.#activeWatcher = watcher;
|
|
181
181
|
|
|
182
182
|
const createWatcherBackend = (root: Path): Promise<WatcherBackend> => {
|
|
183
183
|
const watcherOptions: WatcherBackendOptions = {
|
|
@@ -187,11 +187,11 @@ export class Watcher extends EventEmitter {
|
|
|
187
187
|
/// module resolution.
|
|
188
188
|
'**/package.json',
|
|
189
189
|
// Ensure we always watch any health check files
|
|
190
|
-
'**/' + this.
|
|
190
|
+
'**/' + this.#options.healthCheckFilePrefix + '*',
|
|
191
191
|
...extensions.map(extension => '**/*.' + extension),
|
|
192
192
|
],
|
|
193
193
|
ignored: ignorePatternForWatch,
|
|
194
|
-
watchmanDeferStates: this.
|
|
194
|
+
watchmanDeferStates: this.#options.watchmanDeferStates,
|
|
195
195
|
};
|
|
196
196
|
const watcher: WatcherBackend = new WatcherImpl(root, watcherOptions);
|
|
197
197
|
|
|
@@ -203,14 +203,14 @@ export class Watcher extends EventEmitter {
|
|
|
203
203
|
|
|
204
204
|
watcher.onFileEvent(change => {
|
|
205
205
|
const basename = path.basename(change.relativePath);
|
|
206
|
-
if (basename.startsWith(this.
|
|
206
|
+
if (basename.startsWith(this.#options.healthCheckFilePrefix)) {
|
|
207
207
|
if (change.event === TOUCH_EVENT) {
|
|
208
208
|
debug(
|
|
209
209
|
'Observed possible health check cookie: %s in %s',
|
|
210
210
|
change.relativePath,
|
|
211
211
|
root,
|
|
212
212
|
);
|
|
213
|
-
this
|
|
213
|
+
this.#handleHealthCheckObservation(basename);
|
|
214
214
|
}
|
|
215
215
|
return;
|
|
216
216
|
}
|
|
@@ -222,13 +222,13 @@ export class Watcher extends EventEmitter {
|
|
|
222
222
|
});
|
|
223
223
|
};
|
|
224
224
|
|
|
225
|
-
this
|
|
226
|
-
this.
|
|
225
|
+
this.#backends = await Promise.all(
|
|
226
|
+
this.#options.roots.map(createWatcherBackend),
|
|
227
227
|
);
|
|
228
228
|
}
|
|
229
229
|
|
|
230
|
-
|
|
231
|
-
const resolveHealthCheck = this.
|
|
230
|
+
#handleHealthCheckObservation(basename: string) {
|
|
231
|
+
const resolveHealthCheck = this.#pendingHealthChecks.get(basename);
|
|
232
232
|
if (!resolveHealthCheck) {
|
|
233
233
|
return;
|
|
234
234
|
}
|
|
@@ -236,25 +236,25 @@ export class Watcher extends EventEmitter {
|
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
async close() {
|
|
239
|
-
await Promise.all(this.
|
|
240
|
-
this
|
|
239
|
+
await Promise.all(this.#backends.map(watcher => watcher.stopWatching()));
|
|
240
|
+
this.#activeWatcher = null;
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
async checkHealth(timeout: number): Promise<HealthCheckResult> {
|
|
244
|
-
const healthCheckId = this
|
|
244
|
+
const healthCheckId = this.#nextHealthCheckId++;
|
|
245
245
|
if (healthCheckId === Number.MAX_SAFE_INTEGER) {
|
|
246
|
-
this
|
|
246
|
+
this.#nextHealthCheckId = 0;
|
|
247
247
|
}
|
|
248
|
-
const watcher = this
|
|
248
|
+
const watcher = this.#activeWatcher;
|
|
249
249
|
const basename =
|
|
250
|
-
this.
|
|
250
|
+
this.#options.healthCheckFilePrefix +
|
|
251
251
|
'-' +
|
|
252
252
|
process.pid +
|
|
253
253
|
'-' +
|
|
254
|
-
this
|
|
254
|
+
this.#instanceId +
|
|
255
255
|
'-' +
|
|
256
256
|
healthCheckId;
|
|
257
|
-
const healthCheckPath = path.join(this.
|
|
257
|
+
const healthCheckPath = path.join(this.#options.rootDir, basename);
|
|
258
258
|
let result: ?HealthCheckResult;
|
|
259
259
|
const timeoutPromise = new Promise(resolve =>
|
|
260
260
|
setTimeout(resolve, timeout),
|
|
@@ -262,7 +262,7 @@ export class Watcher extends EventEmitter {
|
|
|
262
262
|
if (!result) {
|
|
263
263
|
result = {
|
|
264
264
|
type: 'timeout',
|
|
265
|
-
pauseReason: this
|
|
265
|
+
pauseReason: this.#backends[0]?.getPauseReason(),
|
|
266
266
|
timeout,
|
|
267
267
|
watcher,
|
|
268
268
|
};
|
|
@@ -283,7 +283,7 @@ export class Watcher extends EventEmitter {
|
|
|
283
283
|
}
|
|
284
284
|
});
|
|
285
285
|
const observationPromise = new Promise(resolve => {
|
|
286
|
-
this.
|
|
286
|
+
this.#pendingHealthChecks.set(basename, resolve);
|
|
287
287
|
}).then(() => {
|
|
288
288
|
if (!result) {
|
|
289
289
|
result = {
|
|
@@ -298,7 +298,7 @@ export class Watcher extends EventEmitter {
|
|
|
298
298
|
timeoutPromise,
|
|
299
299
|
creationPromise.then(() => observationPromise),
|
|
300
300
|
]);
|
|
301
|
-
this.
|
|
301
|
+
this.#pendingHealthChecks.delete(basename);
|
|
302
302
|
// Chain a deletion to the creation promise (which may not have even settled yet!),
|
|
303
303
|
// don't await it, and swallow errors. This is just best-effort cleanup.
|
|
304
304
|
// $FlowFixMe[unused-promise]
|
|
@@ -12,27 +12,31 @@ import type {
|
|
|
12
12
|
BuildParameters,
|
|
13
13
|
CacheData,
|
|
14
14
|
CacheManager,
|
|
15
|
+
CacheManagerFactoryOptions,
|
|
15
16
|
CacheManagerWriteOptions,
|
|
16
17
|
} from '../flow-types';
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
export class DiskCacheManager implements CacheManager {
|
|
25
|
-
constructor(
|
|
19
|
+
type AutoSaveOptions = Readonly<{debounceMs: number}>;
|
|
20
|
+
type DiskCacheConfig = Readonly<{
|
|
21
|
+
autoSave?: Partial<AutoSaveOptions> | boolean;
|
|
22
|
+
cacheFilePrefix?: null | undefined | string;
|
|
23
|
+
cacheDirectory?: null | undefined | string;
|
|
24
|
+
}>;
|
|
25
|
+
export declare class DiskCacheManager implements CacheManager {
|
|
26
|
+
constructor(
|
|
27
|
+
$$PARAM_0$$: CacheManagerFactoryOptions,
|
|
28
|
+
$$PARAM_1$$: DiskCacheConfig,
|
|
29
|
+
);
|
|
26
30
|
static getCacheFilePath(
|
|
27
31
|
buildParameters: BuildParameters,
|
|
28
|
-
cacheFilePrefix?:
|
|
29
|
-
cacheDirectory?:
|
|
32
|
+
cacheFilePrefix?: null | undefined | string,
|
|
33
|
+
cacheDirectory?: null | undefined | string,
|
|
30
34
|
): string;
|
|
31
35
|
getCacheFilePath(): string;
|
|
32
|
-
read(): Promise<
|
|
36
|
+
read(): Promise<null | undefined | CacheData>;
|
|
33
37
|
write(
|
|
34
38
|
getSnapshot: () => CacheData,
|
|
35
|
-
|
|
39
|
+
$$PARAM_1$$: CacheManagerWriteOptions,
|
|
36
40
|
): Promise<void>;
|
|
37
41
|
end(): Promise<void>;
|
|
38
42
|
}
|
|
@@ -27,11 +27,11 @@ import {deserialize, serialize} from 'v8';
|
|
|
27
27
|
// eslint-disable-next-line import/no-commonjs
|
|
28
28
|
const debug = require('debug')('Metro:FileMapCache');
|
|
29
29
|
|
|
30
|
-
type AutoSaveOptions =
|
|
30
|
+
type AutoSaveOptions = Readonly<{
|
|
31
31
|
debounceMs: number,
|
|
32
32
|
}>;
|
|
33
33
|
|
|
34
|
-
type DiskCacheConfig =
|
|
34
|
+
type DiskCacheConfig = Readonly<{
|
|
35
35
|
autoSave?: Partial<AutoSaveOptions> | boolean,
|
|
36
36
|
cacheFilePrefix?: ?string,
|
|
37
37
|
cacheDirectory?: ?string,
|
|
@@ -150,7 +150,7 @@ export class DiskCacheManager implements CacheManager {
|
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
async end() {
|
|
153
|
+
async end(): Promise<void> {
|
|
154
154
|
// Clear any timers
|
|
155
155
|
if (this.#debounceTimeout) {
|
|
156
156
|
clearTimeout(this.#debounceTimeout);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type {HType} from './flow-types';
|
|
11
|
+
|
|
12
|
+
declare const $$EXPORT_DEFAULT_DECLARATION$$: HType;
|
|
13
|
+
declare type $$EXPORT_DEFAULT_DECLARATION$$ =
|
|
14
|
+
typeof $$EXPORT_DEFAULT_DECLARATION$$;
|
|
15
|
+
export default $$EXPORT_DEFAULT_DECLARATION$$;
|
package/src/constants.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true,
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _default = (exports.default = {
|
|
5
8
|
MTIME: 0,
|
|
6
9
|
SIZE: 1,
|
|
7
10
|
VISITED: 2,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
ID: 6,
|
|
11
|
+
SHA1: 3,
|
|
12
|
+
SYMLINK: 4,
|
|
13
|
+
PLUGINDATA: 5,
|
|
12
14
|
PATH: 0,
|
|
13
15
|
TYPE: 1,
|
|
14
16
|
MODULE: 0,
|
|
15
17
|
PACKAGE: 1,
|
|
16
18
|
GENERIC_PLATFORM: "g",
|
|
17
19
|
NATIVE_PLATFORM: "native",
|
|
18
|
-
};
|
|
19
|
-
module.exports = constants;
|
|
20
|
+
});
|