metro-file-map 0.84.4 → 0.85.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.
- package/package.json +3 -3
- package/src/Watcher.d.ts +1 -2
- package/src/Watcher.js +0 -1
- package/src/Watcher.js.flow +6 -6
- package/src/cache/DiskCacheManager.js.flow +2 -2
- package/src/crawlers/node/index.js +9 -92
- package/src/crawlers/node/index.js.flow +9 -98
- package/src/flow-types.d.ts +3 -5
- package/src/flow-types.js.flow +13 -15
- package/src/index.d.ts +1 -2
- package/src/index.js +0 -3
- package/src/index.js.flow +8 -12
- package/src/lib/FileProcessor.js.flow +2 -2
- package/src/lib/FileSystemChangeAggregator.js.flow +6 -6
- package/src/lib/RootPathUtils.js +8 -2
- package/src/lib/RootPathUtils.js.flow +16 -4
- package/src/lib/TreeFS.js +13 -5
- package/src/lib/TreeFS.js.flow +25 -10
- package/src/lib/rootRelativeCacheKeys.js +0 -1
- package/src/lib/rootRelativeCacheKeys.js.flow +0 -1
- package/src/plugins/DependencyPlugin.js +6 -2
- package/src/plugins/DependencyPlugin.js.flow +7 -2
- package/src/plugins/FileDataPlugin.js.flow +2 -2
- package/src/plugins/HastePlugin.js.flow +11 -11
- package/src/plugins/MockPlugin.js.flow +5 -5
- package/src/plugins/dependencies/worker.js +7 -2
- package/src/plugins/dependencies/worker.js.flow +8 -3
- package/src/plugins/haste/worker.js +3 -1
- package/src/plugins/haste/worker.js.flow +4 -2
- package/src/watchers/AbstractWatcher.js.flow +5 -5
- package/src/watchers/FallbackWatcher.js.flow +4 -3
- package/src/watchers/NativeWatcher.d.ts +1 -2
- package/src/watchers/WatchmanWatcher.js.flow +2 -2
- package/src/worker.js +3 -1
- package/src/worker.js.flow +3 -1
- package/src/crawlers/node/hasNativeFindSupport.d.ts +0 -19
- package/src/crawlers/node/hasNativeFindSupport.js +0 -36
- package/src/crawlers/node/hasNativeFindSupport.js.flow +0 -41
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "metro-file-map",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.85.0",
|
|
4
4
|
"description": "[Experimental] - 🚇 File crawling, watching and mapping for Metro",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
13
|
-
"url": "git+https://github.com/
|
|
13
|
+
"url": "git+https://github.com/react/metro.git",
|
|
14
14
|
"directory": "packages/metro-file-map"
|
|
15
15
|
},
|
|
16
16
|
"scripts": {
|
|
@@ -33,6 +33,6 @@
|
|
|
33
33
|
"slash": "^3.0.0"
|
|
34
34
|
},
|
|
35
35
|
"engines": {
|
|
36
|
-
"node": "^
|
|
36
|
+
"node": "^22.13.0 || ^24.3.0 || >= 26.0.0"
|
|
37
37
|
}
|
|
38
38
|
}
|
package/src/Watcher.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
* @noformat
|
|
8
|
-
* @generated SignedSource<<
|
|
8
|
+
* @generated SignedSource<<7e33ffd7eec05b9c9c072189d2ed3ec2>>
|
|
9
9
|
*
|
|
10
10
|
* This file was translated from Flow by scripts/generateTypeScriptDefinitions.js
|
|
11
11
|
* Original file: packages/metro-file-map/src/Watcher.js
|
|
@@ -30,7 +30,6 @@ type WatcherOptions = {
|
|
|
30
30
|
console: Console;
|
|
31
31
|
enableSymlinks: boolean;
|
|
32
32
|
extensions: ReadonlyArray<string>;
|
|
33
|
-
forceNodeFilesystemAPI: boolean;
|
|
34
33
|
healthCheckFilePrefix: string;
|
|
35
34
|
ignoreForCrawl: (filePath: string) => boolean;
|
|
36
35
|
ignorePatternForWatch: RegExp;
|
package/src/Watcher.js
CHANGED
|
@@ -103,7 +103,6 @@ class Watcher extends _events.default {
|
|
|
103
103
|
console: options.console,
|
|
104
104
|
includeSymlinks: options.enableSymlinks,
|
|
105
105
|
extensions: options.extensions,
|
|
106
|
-
forceNodeFilesystemAPI: options.forceNodeFilesystemAPI,
|
|
107
106
|
ignore: ignoreForCrawl,
|
|
108
107
|
onStatus: (status) => {
|
|
109
108
|
this.emit("status", status);
|
package/src/Watcher.js.flow
CHANGED
|
@@ -49,7 +49,6 @@ type WatcherOptions = {
|
|
|
49
49
|
console: Console,
|
|
50
50
|
enableSymlinks: boolean,
|
|
51
51
|
extensions: ReadonlyArray<string>,
|
|
52
|
-
forceNodeFilesystemAPI: boolean,
|
|
53
52
|
healthCheckFilePrefix: string,
|
|
54
53
|
ignoreForCrawl: (filePath: string) => boolean,
|
|
55
54
|
ignorePatternForWatch: RegExp,
|
|
@@ -72,11 +71,13 @@ export type HealthCheckResult =
|
|
|
72
71
|
export class Watcher extends EventEmitter {
|
|
73
72
|
#activeWatcher: ?string;
|
|
74
73
|
#backends: ReadonlyArray<WatcherBackend> = [];
|
|
75
|
-
|
|
74
|
+
readonly #instanceId: number;
|
|
76
75
|
#nextHealthCheckId: number = 0;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
readonly #options: WatcherOptions;
|
|
77
|
+
readonly #pendingHealthChecks: Map<
|
|
78
|
+
/* basename */ string,
|
|
79
|
+
/* resolve */ () => void,
|
|
80
|
+
> = new Map();
|
|
80
81
|
|
|
81
82
|
constructor(options: WatcherOptions) {
|
|
82
83
|
super();
|
|
@@ -131,7 +132,6 @@ export class Watcher extends EventEmitter {
|
|
|
131
132
|
console: options.console,
|
|
132
133
|
includeSymlinks: options.enableSymlinks,
|
|
133
134
|
extensions: options.extensions,
|
|
134
|
-
forceNodeFilesystemAPI: options.forceNodeFilesystemAPI,
|
|
135
135
|
ignore: ignoreForCrawl,
|
|
136
136
|
onStatus: status => {
|
|
137
137
|
this.emit('status', status);
|
|
@@ -42,8 +42,8 @@ const DEFAULT_DIRECTORY = tmpdir();
|
|
|
42
42
|
const DEFAULT_AUTO_SAVE_DEBOUNCE_MS = 5000;
|
|
43
43
|
|
|
44
44
|
export class DiskCacheManager implements CacheManager {
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
readonly #autoSaveOpts: ?AutoSaveOptions;
|
|
46
|
+
readonly #cachePath: string;
|
|
47
47
|
#debounceTimeout: ?Timeout = null;
|
|
48
48
|
#writePromise: Promise<void> = Promise.resolve();
|
|
49
49
|
#hasUnwrittenChanges: boolean = false;
|
|
@@ -5,12 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = nodeCrawl;
|
|
7
7
|
var _RootPathUtils = require("../../lib/RootPathUtils");
|
|
8
|
-
var _hasNativeFindSupport = _interopRequireDefault(
|
|
9
|
-
require("./hasNativeFindSupport"),
|
|
10
|
-
);
|
|
11
|
-
var _child_process = require("child_process");
|
|
12
8
|
var fs = _interopRequireWildcard(require("graceful-fs"));
|
|
13
|
-
var _os = require("os");
|
|
14
9
|
var path = _interopRequireWildcard(require("path"));
|
|
15
10
|
function _interopRequireWildcard(e, t) {
|
|
16
11
|
if ("function" == typeof WeakMap)
|
|
@@ -39,10 +34,6 @@ function _interopRequireWildcard(e, t) {
|
|
|
39
34
|
return f;
|
|
40
35
|
})(e, t);
|
|
41
36
|
}
|
|
42
|
-
function _interopRequireDefault(e) {
|
|
43
|
-
return e && e.__esModule ? e : { default: e };
|
|
44
|
-
}
|
|
45
|
-
const debug = require("debug")("Metro:NodeCrawler");
|
|
46
37
|
function find(
|
|
47
38
|
roots,
|
|
48
39
|
extensions,
|
|
@@ -115,68 +106,11 @@ function find(
|
|
|
115
106
|
callback(result);
|
|
116
107
|
}
|
|
117
108
|
}
|
|
118
|
-
function findNative(
|
|
119
|
-
roots,
|
|
120
|
-
extensions,
|
|
121
|
-
ignore,
|
|
122
|
-
includeSymlinks,
|
|
123
|
-
rootDir,
|
|
124
|
-
console,
|
|
125
|
-
callback,
|
|
126
|
-
) {
|
|
127
|
-
const extensionClause = extensions.length
|
|
128
|
-
? `( ${extensions.map((ext) => `-iname *.${ext}`).join(" -o ")} )`
|
|
129
|
-
: "";
|
|
130
|
-
const expression = `( ( -type f ${extensionClause} ) ${includeSymlinks ? "-o -type l " : ""})`;
|
|
131
|
-
const pathUtils = new _RootPathUtils.RootPathUtils(rootDir);
|
|
132
|
-
const child = (0, _child_process.spawn)(
|
|
133
|
-
"find",
|
|
134
|
-
roots.concat(expression.split(" ")),
|
|
135
|
-
);
|
|
136
|
-
let stdout = "";
|
|
137
|
-
if (child.stdout == null) {
|
|
138
|
-
throw new Error(
|
|
139
|
-
"stdout is null - this should never happen. Please open up an issue at https://github.com/facebook/metro",
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
|
-
child.stdout.setEncoding("utf-8");
|
|
143
|
-
child.stdout.on("data", (data) => (stdout += data));
|
|
144
|
-
child.stdout.on("close", () => {
|
|
145
|
-
const lines = stdout
|
|
146
|
-
.trim()
|
|
147
|
-
.split("\n")
|
|
148
|
-
.filter((x) => !ignore(x));
|
|
149
|
-
const result = new Map();
|
|
150
|
-
let count = lines.length;
|
|
151
|
-
if (!count) {
|
|
152
|
-
callback(new Map());
|
|
153
|
-
} else {
|
|
154
|
-
lines.forEach((path) => {
|
|
155
|
-
fs.lstat(path, (err, stat) => {
|
|
156
|
-
if (!err && stat) {
|
|
157
|
-
result.set(pathUtils.absoluteToNormal(path), [
|
|
158
|
-
stat.mtime.getTime(),
|
|
159
|
-
stat.size,
|
|
160
|
-
0,
|
|
161
|
-
null,
|
|
162
|
-
stat.isSymbolicLink() ? 1 : 0,
|
|
163
|
-
null,
|
|
164
|
-
]);
|
|
165
|
-
}
|
|
166
|
-
if (--count === 0) {
|
|
167
|
-
callback(result);
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
109
|
async function nodeCrawl(options) {
|
|
175
110
|
const {
|
|
176
111
|
console,
|
|
177
112
|
previousState,
|
|
178
113
|
extensions,
|
|
179
|
-
forceNodeFilesystemAPI,
|
|
180
114
|
ignore,
|
|
181
115
|
rootDir,
|
|
182
116
|
includeSymlinks,
|
|
@@ -187,11 +121,6 @@ async function nodeCrawl(options) {
|
|
|
187
121
|
} = options;
|
|
188
122
|
abortSignal?.throwIfAborted();
|
|
189
123
|
perfLogger?.point("nodeCrawl_start");
|
|
190
|
-
const useNativeFind =
|
|
191
|
-
!forceNodeFilesystemAPI &&
|
|
192
|
-
(0, _os.platform)() !== "win32" &&
|
|
193
|
-
(await (0, _hasNativeFindSupport.default)());
|
|
194
|
-
debug("Using system find: %s", useNativeFind);
|
|
195
124
|
return new Promise((resolve, reject) => {
|
|
196
125
|
const callback = (fileData) => {
|
|
197
126
|
const difference = previousState.fileSystem.getDifference(fileData, {
|
|
@@ -205,26 +134,14 @@ async function nodeCrawl(options) {
|
|
|
205
134
|
}
|
|
206
135
|
resolve(difference);
|
|
207
136
|
};
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
);
|
|
218
|
-
} else {
|
|
219
|
-
find(
|
|
220
|
-
roots,
|
|
221
|
-
extensions,
|
|
222
|
-
ignore,
|
|
223
|
-
includeSymlinks,
|
|
224
|
-
rootDir,
|
|
225
|
-
console,
|
|
226
|
-
callback,
|
|
227
|
-
);
|
|
228
|
-
}
|
|
137
|
+
find(
|
|
138
|
+
roots,
|
|
139
|
+
extensions,
|
|
140
|
+
ignore,
|
|
141
|
+
includeSymlinks,
|
|
142
|
+
rootDir,
|
|
143
|
+
console,
|
|
144
|
+
callback,
|
|
145
|
+
);
|
|
229
146
|
});
|
|
230
147
|
}
|
|
@@ -18,15 +18,9 @@ import type {
|
|
|
18
18
|
} from '../../flow-types';
|
|
19
19
|
|
|
20
20
|
import {RootPathUtils} from '../../lib/RootPathUtils';
|
|
21
|
-
import hasNativeFindSupport from './hasNativeFindSupport';
|
|
22
|
-
import {spawn} from 'child_process';
|
|
23
21
|
import * as fs from 'graceful-fs';
|
|
24
|
-
import {platform} from 'os';
|
|
25
22
|
import * as path from 'path';
|
|
26
23
|
|
|
27
|
-
// eslint-disable-next-line import/no-commonjs
|
|
28
|
-
const debug = require('debug')('Metro:NodeCrawler');
|
|
29
|
-
|
|
30
24
|
type Callback = (result: FileData) => void;
|
|
31
25
|
|
|
32
26
|
function find(
|
|
@@ -106,70 +100,6 @@ function find(
|
|
|
106
100
|
}
|
|
107
101
|
}
|
|
108
102
|
|
|
109
|
-
function findNative(
|
|
110
|
-
roots: ReadonlyArray<string>,
|
|
111
|
-
extensions: ReadonlyArray<string>,
|
|
112
|
-
ignore: IgnoreMatcher,
|
|
113
|
-
includeSymlinks: boolean,
|
|
114
|
-
rootDir: string,
|
|
115
|
-
console: Console,
|
|
116
|
-
callback: Callback,
|
|
117
|
-
): void {
|
|
118
|
-
// Examples:
|
|
119
|
-
// ( ( -type f ( -iname *.js ) ) )
|
|
120
|
-
// ( ( -type f ( -iname *.js -o -iname *.ts ) ) )
|
|
121
|
-
// ( ( -type f ( -iname *.js ) ) -o -type l )
|
|
122
|
-
// ( ( -type f ) -o -type l )
|
|
123
|
-
const extensionClause = extensions.length
|
|
124
|
-
? `( ${extensions.map(ext => `-iname *.${ext}`).join(' -o ')} )`
|
|
125
|
-
: ''; // Empty inner expressions eg "( )" are not allowed
|
|
126
|
-
const expression = `( ( -type f ${extensionClause} ) ${
|
|
127
|
-
includeSymlinks ? '-o -type l ' : ''
|
|
128
|
-
})`;
|
|
129
|
-
|
|
130
|
-
const pathUtils = new RootPathUtils(rootDir);
|
|
131
|
-
|
|
132
|
-
const child = spawn('find', roots.concat(expression.split(' ')));
|
|
133
|
-
let stdout = '';
|
|
134
|
-
if (child.stdout == null) {
|
|
135
|
-
throw new Error(
|
|
136
|
-
'stdout is null - this should never happen. Please open up an issue at https://github.com/facebook/metro',
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
child.stdout.setEncoding('utf-8');
|
|
140
|
-
child.stdout.on('data', data => (stdout += data));
|
|
141
|
-
|
|
142
|
-
child.stdout.on('close', () => {
|
|
143
|
-
const lines = stdout
|
|
144
|
-
.trim()
|
|
145
|
-
.split('\n')
|
|
146
|
-
.filter(x => !ignore(x));
|
|
147
|
-
const result: FileData = new Map();
|
|
148
|
-
let count = lines.length;
|
|
149
|
-
if (!count) {
|
|
150
|
-
callback(new Map());
|
|
151
|
-
} else {
|
|
152
|
-
lines.forEach(path => {
|
|
153
|
-
fs.lstat(path, (err, stat) => {
|
|
154
|
-
if (!err && stat) {
|
|
155
|
-
result.set(pathUtils.absoluteToNormal(path), [
|
|
156
|
-
stat.mtime.getTime(),
|
|
157
|
-
stat.size,
|
|
158
|
-
0,
|
|
159
|
-
null,
|
|
160
|
-
stat.isSymbolicLink() ? 1 : 0,
|
|
161
|
-
null,
|
|
162
|
-
]);
|
|
163
|
-
}
|
|
164
|
-
if (--count === 0) {
|
|
165
|
-
callback(result);
|
|
166
|
-
}
|
|
167
|
-
});
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
|
|
173
103
|
export default async function nodeCrawl(
|
|
174
104
|
options: CrawlerOptions,
|
|
175
105
|
): Promise<CrawlResult> {
|
|
@@ -177,7 +107,6 @@ export default async function nodeCrawl(
|
|
|
177
107
|
console,
|
|
178
108
|
previousState,
|
|
179
109
|
extensions,
|
|
180
|
-
forceNodeFilesystemAPI,
|
|
181
110
|
ignore,
|
|
182
111
|
rootDir,
|
|
183
112
|
includeSymlinks,
|
|
@@ -190,12 +119,6 @@ export default async function nodeCrawl(
|
|
|
190
119
|
abortSignal?.throwIfAborted();
|
|
191
120
|
|
|
192
121
|
perfLogger?.point('nodeCrawl_start');
|
|
193
|
-
const useNativeFind =
|
|
194
|
-
!forceNodeFilesystemAPI &&
|
|
195
|
-
platform() !== 'win32' &&
|
|
196
|
-
(await hasNativeFindSupport());
|
|
197
|
-
|
|
198
|
-
debug('Using system find: %s', useNativeFind);
|
|
199
122
|
|
|
200
123
|
return new Promise((resolve, reject) => {
|
|
201
124
|
const callback: Callback = fileData => {
|
|
@@ -214,26 +137,14 @@ export default async function nodeCrawl(
|
|
|
214
137
|
resolve(difference);
|
|
215
138
|
};
|
|
216
139
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
);
|
|
227
|
-
} else {
|
|
228
|
-
find(
|
|
229
|
-
roots,
|
|
230
|
-
extensions,
|
|
231
|
-
ignore,
|
|
232
|
-
includeSymlinks,
|
|
233
|
-
rootDir,
|
|
234
|
-
console,
|
|
235
|
-
callback,
|
|
236
|
-
);
|
|
237
|
-
}
|
|
140
|
+
find(
|
|
141
|
+
roots,
|
|
142
|
+
extensions,
|
|
143
|
+
ignore,
|
|
144
|
+
includeSymlinks,
|
|
145
|
+
rootDir,
|
|
146
|
+
console,
|
|
147
|
+
callback,
|
|
148
|
+
);
|
|
238
149
|
});
|
|
239
150
|
}
|
package/src/flow-types.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @noformat
|
|
8
8
|
* @oncall react_native
|
|
9
|
-
* @generated SignedSource<<
|
|
9
|
+
* @generated SignedSource<<6ff16bb65883df0a1cb70e6ca94461eb>>
|
|
10
10
|
*
|
|
11
11
|
* This file was translated from Flow by scripts/generateTypeScriptDefinitions.js
|
|
12
12
|
* Original file: packages/metro-file-map/src/flow-types.js
|
|
@@ -22,7 +22,6 @@ export type BuildParameters = Readonly<{
|
|
|
22
22
|
computeSha1: boolean;
|
|
23
23
|
enableSymlinks: boolean;
|
|
24
24
|
extensions: ReadonlyArray<string>;
|
|
25
|
-
forceNodeFilesystemAPI: boolean;
|
|
26
25
|
ignorePattern: RegExp;
|
|
27
26
|
plugins: ReadonlyArray<InputFileMapPlugin>;
|
|
28
27
|
retainAllFiles: boolean;
|
|
@@ -95,7 +94,6 @@ export type CrawlerOptions = {
|
|
|
95
94
|
computeSha1: boolean;
|
|
96
95
|
console: Console;
|
|
97
96
|
extensions: ReadonlyArray<string>;
|
|
98
|
-
forceNodeFilesystemAPI: boolean;
|
|
99
97
|
ignore: IgnoreMatcher;
|
|
100
98
|
includeSymlinks: boolean;
|
|
101
99
|
perfLogger?: null | undefined | PerfLogger;
|
|
@@ -192,12 +190,12 @@ export interface FileMapPlugin<
|
|
|
192
190
|
}
|
|
193
191
|
export type InputFileMapPlugin = FileMapPlugin<
|
|
194
192
|
/**
|
|
195
|
-
* >
|
|
193
|
+
* > 233 | export type InputFileMapPlugin = FileMapPlugin<empty, empty>;
|
|
196
194
|
* | ^^^^^ Unsupported feature: Translating "empty type" is currently not supported.
|
|
197
195
|
**/
|
|
198
196
|
any,
|
|
199
197
|
/**
|
|
200
|
-
* >
|
|
198
|
+
* > 233 | export type InputFileMapPlugin = FileMapPlugin<empty, empty>;
|
|
201
199
|
* | ^^^^^ Unsupported feature: Translating "empty type" is currently not supported.
|
|
202
200
|
**/
|
|
203
201
|
any
|
package/src/flow-types.js.flow
CHANGED
|
@@ -19,7 +19,6 @@ export type BuildParameters = Readonly<{
|
|
|
19
19
|
computeSha1: boolean,
|
|
20
20
|
enableSymlinks: boolean,
|
|
21
21
|
extensions: ReadonlyArray<string>,
|
|
22
|
-
forceNodeFilesystemAPI: boolean,
|
|
23
22
|
ignorePattern: RegExp,
|
|
24
23
|
plugins: ReadonlyArray<InputFileMapPlugin>,
|
|
25
24
|
retainAllFiles: boolean,
|
|
@@ -114,7 +113,6 @@ export type CrawlerOptions = {
|
|
|
114
113
|
computeSha1: boolean,
|
|
115
114
|
console: Console,
|
|
116
115
|
extensions: ReadonlyArray<string>,
|
|
117
|
-
forceNodeFilesystemAPI: boolean,
|
|
118
116
|
ignore: IgnoreMatcher,
|
|
119
117
|
includeSymlinks: boolean,
|
|
120
118
|
perfLogger?: ?PerfLogger,
|
|
@@ -171,8 +169,8 @@ export type DuplicatesSet = Map<string, /* type */ number>;
|
|
|
171
169
|
export type DuplicatesIndex = Map<string, Map<string, DuplicatesSet>>;
|
|
172
170
|
|
|
173
171
|
export type FileMapPluginInitOptions<
|
|
174
|
-
|
|
175
|
-
|
|
172
|
+
out SerializableState,
|
|
173
|
+
out PerFileData = void,
|
|
176
174
|
> = Readonly<{
|
|
177
175
|
files: Readonly<{
|
|
178
176
|
fileIterator(
|
|
@@ -183,13 +181,13 @@ export type FileMapPluginInitOptions<
|
|
|
183
181
|
): Iterable<{
|
|
184
182
|
baseName: string,
|
|
185
183
|
canonicalPath: string,
|
|
186
|
-
|
|
184
|
+
readonly pluginData: ?PerFileData,
|
|
187
185
|
}>,
|
|
188
186
|
lookup(
|
|
189
187
|
mixedPath: string,
|
|
190
188
|
):
|
|
191
189
|
| {exists: false}
|
|
192
|
-
| {exists: true, type: 'f',
|
|
190
|
+
| {exists: true, type: 'f', readonly pluginData: PerFileData}
|
|
193
191
|
| {exists: true, type: 'd'},
|
|
194
192
|
}>,
|
|
195
193
|
pluginState: ?SerializableState,
|
|
@@ -214,10 +212,10 @@ export type V8Serializable =
|
|
|
214
212
|
| Readonly<{[key: string]: V8Serializable}>;
|
|
215
213
|
|
|
216
214
|
export interface FileMapPlugin<
|
|
217
|
-
|
|
218
|
-
|
|
215
|
+
in SerializableState extends void | V8Serializable = void | V8Serializable,
|
|
216
|
+
in PerFileData extends void | V8Serializable = void | V8Serializable,
|
|
219
217
|
> {
|
|
220
|
-
|
|
218
|
+
readonly name: string;
|
|
221
219
|
initialize(
|
|
222
220
|
initOptions: FileMapPluginInitOptions<SerializableState, PerFileData>,
|
|
223
221
|
): Promise<void>;
|
|
@@ -461,13 +459,13 @@ export interface FileSystemListener {
|
|
|
461
459
|
fileRemoved(canonicalPath: CanonicalPath, data: FileMetadata): void;
|
|
462
460
|
}
|
|
463
461
|
|
|
464
|
-
export interface ReadonlyFileSystemChanges
|
|
465
|
-
|
|
466
|
-
|
|
462
|
+
export interface ReadonlyFileSystemChanges<out T = FileMetadata> {
|
|
463
|
+
readonly addedDirectories: Iterable<CanonicalPath>;
|
|
464
|
+
readonly removedDirectories: Iterable<CanonicalPath>;
|
|
467
465
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
466
|
+
readonly addedFiles: Iterable<Readonly<[CanonicalPath, T]>>;
|
|
467
|
+
readonly modifiedFiles: Iterable<Readonly<[CanonicalPath, T]>>;
|
|
468
|
+
readonly removedFiles: Iterable<Readonly<[CanonicalPath, T]>>;
|
|
471
469
|
}
|
|
472
470
|
|
|
473
471
|
export interface MutableFileSystem extends FileSystem {
|
package/src/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @noformat
|
|
8
8
|
* @oncall react_native
|
|
9
|
-
* @generated SignedSource<<
|
|
9
|
+
* @generated SignedSource<<220686ad19cc94bec3b8d89f49fa6304>>
|
|
10
10
|
*
|
|
11
11
|
* This file was translated from Flow by scripts/generateTypeScriptDefinitions.js
|
|
12
12
|
* Original file: packages/metro-file-map/src/index.js
|
|
@@ -49,7 +49,6 @@ export type InputOptions = Readonly<{
|
|
|
49
49
|
computeSha1?: null | undefined | boolean;
|
|
50
50
|
enableSymlinks?: null | undefined | boolean;
|
|
51
51
|
extensions: ReadonlyArray<string>;
|
|
52
|
-
forceNodeFilesystemAPI?: null | undefined | boolean;
|
|
53
52
|
ignorePattern?: null | undefined | RegExp;
|
|
54
53
|
plugins?: ReadonlyArray<InputFileMapPlugin>;
|
|
55
54
|
retainAllFiles: boolean;
|
package/src/index.js
CHANGED
|
@@ -164,7 +164,6 @@ class FileMap extends _events.default {
|
|
|
164
164
|
computeSha1: options.computeSha1 || false,
|
|
165
165
|
enableSymlinks: options.enableSymlinks || false,
|
|
166
166
|
extensions: options.extensions,
|
|
167
|
-
forceNodeFilesystemAPI: !!options.forceNodeFilesystemAPI,
|
|
168
167
|
ignorePattern,
|
|
169
168
|
plugins,
|
|
170
169
|
retainAllFiles: options.retainAllFiles,
|
|
@@ -335,7 +334,6 @@ class FileMap extends _events.default {
|
|
|
335
334
|
computeSha1,
|
|
336
335
|
enableSymlinks,
|
|
337
336
|
extensions,
|
|
338
|
-
forceNodeFilesystemAPI,
|
|
339
337
|
ignorePattern,
|
|
340
338
|
retainAllFiles,
|
|
341
339
|
roots,
|
|
@@ -349,7 +347,6 @@ class FileMap extends _events.default {
|
|
|
349
347
|
console: this.#console,
|
|
350
348
|
enableSymlinks,
|
|
351
349
|
extensions,
|
|
352
|
-
forceNodeFilesystemAPI,
|
|
353
350
|
healthCheckFilePrefix: this.#options.healthCheck.filePrefix,
|
|
354
351
|
ignoreForCrawl: (filePath) => {
|
|
355
352
|
const ignoreMatched = ignorePattern.test(filePath);
|
package/src/index.js.flow
CHANGED
|
@@ -78,7 +78,6 @@ export type InputOptions = Readonly<{
|
|
|
78
78
|
computeSha1?: ?boolean,
|
|
79
79
|
enableSymlinks?: ?boolean,
|
|
80
80
|
extensions: ReadonlyArray<string>,
|
|
81
|
-
forceNodeFilesystemAPI?: ?boolean,
|
|
82
81
|
ignorePattern?: ?RegExp,
|
|
83
82
|
plugins?: ReadonlyArray<InputFileMapPlugin>,
|
|
84
83
|
retainAllFiles: boolean,
|
|
@@ -249,18 +248,18 @@ const WATCHMAN_REQUIRED_CAPABILITIES = [
|
|
|
249
248
|
*/
|
|
250
249
|
export default class FileMap extends EventEmitter {
|
|
251
250
|
#buildPromise: ?Promise<BuildResult>;
|
|
252
|
-
|
|
251
|
+
readonly #cacheManager: CacheManager;
|
|
253
252
|
#canUseWatchmanPromise: Promise<boolean>;
|
|
254
253
|
#changeID: number;
|
|
255
254
|
#changeInterval: ?IntervalID;
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
255
|
+
readonly #console: Console;
|
|
256
|
+
readonly #crawlerAbortController: AbortController;
|
|
257
|
+
readonly #fileProcessor: FileProcessor;
|
|
259
258
|
#healthCheckInterval: ?IntervalID;
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
259
|
+
readonly #options: InternalOptions;
|
|
260
|
+
readonly #pathUtils: RootPathUtils;
|
|
261
|
+
readonly #plugins: ReadonlyArray<IndexedPlugin>;
|
|
262
|
+
readonly #startupPerfLogger: ?PerfLogger;
|
|
264
263
|
#watcher: ?Watcher;
|
|
265
264
|
|
|
266
265
|
static create(options: InputOptions): FileMap {
|
|
@@ -318,7 +317,6 @@ export default class FileMap extends EventEmitter {
|
|
|
318
317
|
computeSha1: options.computeSha1 || false,
|
|
319
318
|
enableSymlinks: options.enableSymlinks || false,
|
|
320
319
|
extensions: options.extensions,
|
|
321
|
-
forceNodeFilesystemAPI: !!options.forceNodeFilesystemAPI,
|
|
322
320
|
ignorePattern,
|
|
323
321
|
plugins,
|
|
324
322
|
retainAllFiles: options.retainAllFiles,
|
|
@@ -515,7 +513,6 @@ export default class FileMap extends EventEmitter {
|
|
|
515
513
|
computeSha1,
|
|
516
514
|
enableSymlinks,
|
|
517
515
|
extensions,
|
|
518
|
-
forceNodeFilesystemAPI,
|
|
519
516
|
ignorePattern,
|
|
520
517
|
retainAllFiles,
|
|
521
518
|
roots,
|
|
@@ -530,7 +527,6 @@ export default class FileMap extends EventEmitter {
|
|
|
530
527
|
console: this.#console,
|
|
531
528
|
enableSymlinks,
|
|
532
529
|
extensions,
|
|
533
|
-
forceNodeFilesystemAPI,
|
|
534
530
|
healthCheckFilePrefix: this.#options.healthCheck.filePrefix,
|
|
535
531
|
// TODO: Refactor out the two different ignore strategies here.
|
|
536
532
|
ignoreForCrawl: filePath => {
|
|
@@ -40,8 +40,8 @@ type ProcessFileRequest = Readonly<{
|
|
|
40
40
|
}>;
|
|
41
41
|
|
|
42
42
|
interface AsyncWorker {
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
readonly processFile: WorkerMessage => Promise<WorkerMetadata>;
|
|
44
|
+
readonly end: () => Promise<void>;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
interface MaybeCodedError extends Error {
|
|
@@ -18,16 +18,16 @@ import type {
|
|
|
18
18
|
|
|
19
19
|
export class FileSystemChangeAggregator implements FileSystemListener {
|
|
20
20
|
// Mutually exclusive with removedDirectories
|
|
21
|
-
|
|
21
|
+
readonly #addedDirectories: Set<CanonicalPath> = new Set();
|
|
22
22
|
// Mutually exclusive with addedDirectories
|
|
23
|
-
|
|
23
|
+
readonly #removedDirectories: Set<CanonicalPath> = new Set();
|
|
24
24
|
|
|
25
25
|
// Mutually exclusive with modified and removed files
|
|
26
|
-
|
|
26
|
+
readonly #addedFiles: Map<CanonicalPath, FileMetadata> = new Map();
|
|
27
27
|
// Mutually exclusive with added and removed files
|
|
28
|
-
|
|
28
|
+
readonly #modifiedFiles: Map<CanonicalPath, FileMetadata> = new Map();
|
|
29
29
|
// Mutually exclusive with added and modified files
|
|
30
|
-
|
|
30
|
+
readonly #removedFiles: Map<CanonicalPath, FileMetadata> = new Map();
|
|
31
31
|
|
|
32
32
|
// Removed files must be paired with the file's metadata the last time it was
|
|
33
33
|
// observable by consumers - ie, immediately *before* this batch. To report
|
|
@@ -36,7 +36,7 @@ export class FileSystemChangeAggregator implements FileSystemListener {
|
|
|
36
36
|
// re-added, modified and removed again, we still have the initial metadata.
|
|
37
37
|
// This is particularly important if, say, a regular file is replaced by a
|
|
38
38
|
// symlink, or vice-versa.
|
|
39
|
-
|
|
39
|
+
readonly #initialMetadata: Map<CanonicalPath, FileMetadata> = new Map();
|
|
40
40
|
|
|
41
41
|
directoryAdded(canonicalPath: CanonicalPath): void {
|
|
42
42
|
// Only add to newDirectories if this directory wasn't previously removed
|
package/src/lib/RootPathUtils.js
CHANGED
|
@@ -40,6 +40,8 @@ const UP_FRAGMENT_SEP = ".." + path.sep;
|
|
|
40
40
|
const SEP_UP_FRAGMENT = path.sep + "..";
|
|
41
41
|
const UP_FRAGMENT_SEP_LENGTH = UP_FRAGMENT_SEP.length;
|
|
42
42
|
const CURRENT_FRAGMENT = "." + path.sep;
|
|
43
|
+
const IS_WIN32 = path.sep === "\\";
|
|
44
|
+
const ROOT_BASE_IDX = IS_WIN32 ? 0 : 1;
|
|
43
45
|
class RootPathUtils {
|
|
44
46
|
#rootDir;
|
|
45
47
|
#rootDirnames;
|
|
@@ -114,6 +116,8 @@ class RootPathUtils {
|
|
|
114
116
|
const right = pos === 0 ? normalPath : normalPath.slice(pos);
|
|
115
117
|
if (right.length === 0) {
|
|
116
118
|
return left;
|
|
119
|
+
} else if (IS_WIN32 && pos > this.#rootDepth * UP_FRAGMENT_SEP_LENGTH) {
|
|
120
|
+
return right;
|
|
117
121
|
}
|
|
118
122
|
if (i === this.#rootDepth) {
|
|
119
123
|
return left + right;
|
|
@@ -152,7 +156,9 @@ class RootPathUtils {
|
|
|
152
156
|
normalPath,
|
|
153
157
|
};
|
|
154
158
|
}
|
|
155
|
-
const left = normalPath
|
|
159
|
+
const left = normalPath.endsWith(path.sep)
|
|
160
|
+
? normalPath
|
|
161
|
+
: normalPath + path.sep;
|
|
156
162
|
const rawPath = left + relativePath;
|
|
157
163
|
if (normalPath === ".." || normalPath.endsWith(SEP_UP_FRAGMENT)) {
|
|
158
164
|
const collapsed = this.#tryCollapseIndirectionsInSuffix(rawPath, 0, 0);
|
|
@@ -230,7 +236,7 @@ class RootPathUtils {
|
|
|
230
236
|
collapsedSegments,
|
|
231
237
|
};
|
|
232
238
|
}
|
|
233
|
-
if (totalUpIndirections < this.#rootParts.length -
|
|
239
|
+
if (totalUpIndirections < this.#rootParts.length - ROOT_BASE_IDX) {
|
|
234
240
|
totalUpIndirections++;
|
|
235
241
|
}
|
|
236
242
|
if (nextIndirection !== pos + 1 || fullPath[pos] !== ".") {
|
|
@@ -46,6 +46,9 @@ const SEP_UP_FRAGMENT = path.sep + '..';
|
|
|
46
46
|
const UP_FRAGMENT_SEP_LENGTH = UP_FRAGMENT_SEP.length;
|
|
47
47
|
const CURRENT_FRAGMENT = '.' + path.sep;
|
|
48
48
|
|
|
49
|
+
const IS_WIN32 = path.sep === '\\';
|
|
50
|
+
const ROOT_BASE_IDX = IS_WIN32 ? 0 : 1;
|
|
51
|
+
|
|
49
52
|
export class RootPathUtils {
|
|
50
53
|
#rootDir: string;
|
|
51
54
|
#rootDirnames: ReadonlyArray<string>;
|
|
@@ -149,6 +152,12 @@ export class RootPathUtils {
|
|
|
149
152
|
const right = pos === 0 ? normalPath : normalPath.slice(pos);
|
|
150
153
|
if (right.length === 0) {
|
|
151
154
|
return left;
|
|
155
|
+
} else if (IS_WIN32 && pos > this.#rootDepth * UP_FRAGMENT_SEP_LENGTH) {
|
|
156
|
+
// On a real file system, navigating to `..` at the top level (posix `/`
|
|
157
|
+
// or Windows drive) is a no-op, but we can't respect that on Windows
|
|
158
|
+
// because Metro uses e.g. `..\..\D:\foo` to represent cross-drive
|
|
159
|
+
// relative paths.
|
|
160
|
+
return right;
|
|
152
161
|
}
|
|
153
162
|
// left may already end in a path separator only if it is a filesystem root,
|
|
154
163
|
// '/' or 'X:\'.
|
|
@@ -198,7 +207,9 @@ export class RootPathUtils {
|
|
|
198
207
|
if (relativePath === '') {
|
|
199
208
|
return {collapsedSegments: 0, normalPath};
|
|
200
209
|
}
|
|
201
|
-
const left = normalPath
|
|
210
|
+
const left = normalPath.endsWith(path.sep)
|
|
211
|
+
? normalPath
|
|
212
|
+
: normalPath + path.sep;
|
|
202
213
|
const rawPath = left + relativePath;
|
|
203
214
|
if (normalPath === '..' || normalPath.endsWith(SEP_UP_FRAGMENT)) {
|
|
204
215
|
const collapsed = this.#tryCollapseIndirectionsInSuffix(rawPath, 0, 0);
|
|
@@ -299,9 +310,10 @@ export class RootPathUtils {
|
|
|
299
310
|
};
|
|
300
311
|
}
|
|
301
312
|
|
|
302
|
-
// Cap the number of indirections at the total number of root
|
|
303
|
-
// File systems treat '..' at the root as '.'.
|
|
304
|
-
|
|
313
|
+
// Cap the number of indirections at the total number of root parts.
|
|
314
|
+
// File systems treat '..' at the root as '.'. For Windows, cross-device
|
|
315
|
+
// paths need to survive this.
|
|
316
|
+
if (totalUpIndirections < this.#rootParts.length - ROOT_BASE_IDX) {
|
|
305
317
|
totalUpIndirections++;
|
|
306
318
|
}
|
|
307
319
|
|
package/src/lib/TreeFS.js
CHANGED
|
@@ -341,6 +341,9 @@ class TreeFS {
|
|
|
341
341
|
}
|
|
342
342
|
remove(mixedPath, changeListener) {
|
|
343
343
|
const normalPath = this.#normalizePath(mixedPath);
|
|
344
|
+
this.#removeNormalPath(normalPath, changeListener);
|
|
345
|
+
}
|
|
346
|
+
#removeNormalPath(normalPath, changeListener) {
|
|
344
347
|
const result = this.#lookupByNormalPath(normalPath, {
|
|
345
348
|
followLeaf: false,
|
|
346
349
|
});
|
|
@@ -350,7 +353,7 @@ class TreeFS {
|
|
|
350
353
|
const { parentNode, canonicalPath, node } = result;
|
|
351
354
|
if (isDirectory(node) && node.size > 0) {
|
|
352
355
|
for (const basename of node.keys()) {
|
|
353
|
-
this
|
|
356
|
+
this.#removeNormalPath(
|
|
354
357
|
canonicalPath + _path.default.sep + basename,
|
|
355
358
|
changeListener,
|
|
356
359
|
);
|
|
@@ -367,7 +370,10 @@ class TreeFS {
|
|
|
367
370
|
}
|
|
368
371
|
parentNode.delete(_path.default.basename(canonicalPath));
|
|
369
372
|
if (parentNode.size === 0 && parentNode !== this.#rootNode) {
|
|
370
|
-
this
|
|
373
|
+
this.#removeNormalPath(
|
|
374
|
+
_path.default.dirname(canonicalPath),
|
|
375
|
+
changeListener,
|
|
376
|
+
);
|
|
371
377
|
}
|
|
372
378
|
}
|
|
373
379
|
}
|
|
@@ -831,14 +837,16 @@ class TreeFS {
|
|
|
831
837
|
typeof literalSymlinkTarget === "string",
|
|
832
838
|
"Expected symlink target to be populated.",
|
|
833
839
|
);
|
|
834
|
-
|
|
840
|
+
let absoluteSymlinkTarget = _path.default.resolve(
|
|
835
841
|
this.#rootDir,
|
|
836
842
|
canonicalPathOfSymlink,
|
|
837
843
|
"..",
|
|
838
844
|
literalSymlinkTarget,
|
|
839
845
|
);
|
|
840
|
-
|
|
841
|
-
|
|
846
|
+
if (absoluteSymlinkTarget.endsWith(_path.default.sep)) {
|
|
847
|
+
absoluteSymlinkTarget = absoluteSymlinkTarget.slice(0, -1);
|
|
848
|
+
}
|
|
849
|
+
const normalSymlinkTarget = this.#pathUtils.absoluteToNormal(
|
|
842
850
|
absoluteSymlinkTarget,
|
|
843
851
|
);
|
|
844
852
|
const result = {
|
package/src/lib/TreeFS.js.flow
CHANGED
|
@@ -124,11 +124,13 @@ type MetadataIteratorOptions = Readonly<{
|
|
|
124
124
|
* a trailing slash
|
|
125
125
|
*/
|
|
126
126
|
export default class TreeFS implements MutableFileSystem {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
127
|
+
readonly #cachedNormalSymlinkTargets: WeakMap<
|
|
128
|
+
FileNode,
|
|
129
|
+
NormalizedSymlinkTarget,
|
|
130
|
+
> = new WeakMap();
|
|
131
|
+
readonly #pathUtils: RootPathUtils;
|
|
132
|
+
readonly #processFile: ProcessFileFunction;
|
|
133
|
+
readonly #rootDir: Path;
|
|
132
134
|
#rootNode: DirectoryNode = new Map();
|
|
133
135
|
|
|
134
136
|
constructor(opts: TreeFSOptions) {
|
|
@@ -493,6 +495,13 @@ export default class TreeFS implements MutableFileSystem {
|
|
|
493
495
|
|
|
494
496
|
remove(mixedPath: Path, changeListener?: FileSystemListener): void {
|
|
495
497
|
const normalPath = this.#normalizePath(mixedPath);
|
|
498
|
+
this.#removeNormalPath(normalPath, changeListener);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
#removeNormalPath(
|
|
502
|
+
normalPath: string,
|
|
503
|
+
changeListener?: FileSystemListener,
|
|
504
|
+
): void {
|
|
496
505
|
const result = this.#lookupByNormalPath(normalPath, {followLeaf: false});
|
|
497
506
|
if (!result.exists) {
|
|
498
507
|
return;
|
|
@@ -501,7 +510,10 @@ export default class TreeFS implements MutableFileSystem {
|
|
|
501
510
|
|
|
502
511
|
if (isDirectory(node) && node.size > 0) {
|
|
503
512
|
for (const basename of node.keys()) {
|
|
504
|
-
this
|
|
513
|
+
this.#removeNormalPath(
|
|
514
|
+
canonicalPath + path.sep + basename,
|
|
515
|
+
changeListener,
|
|
516
|
+
);
|
|
505
517
|
}
|
|
506
518
|
// Removing the last file will delete this directory
|
|
507
519
|
return;
|
|
@@ -521,7 +533,7 @@ export default class TreeFS implements MutableFileSystem {
|
|
|
521
533
|
// that's not expected to be a case common enough to justify
|
|
522
534
|
// implementation complexity, or slowing down more common uses of
|
|
523
535
|
// _lookupByNormalPath.
|
|
524
|
-
this
|
|
536
|
+
this.#removeNormalPath(path.dirname(canonicalPath), changeListener);
|
|
525
537
|
}
|
|
526
538
|
}
|
|
527
539
|
}
|
|
@@ -1224,16 +1236,19 @@ export default class TreeFS implements MutableFileSystem {
|
|
|
1224
1236
|
typeof literalSymlinkTarget === 'string',
|
|
1225
1237
|
'Expected symlink target to be populated.',
|
|
1226
1238
|
);
|
|
1227
|
-
|
|
1239
|
+
let absoluteSymlinkTarget = path.resolve(
|
|
1228
1240
|
this.#rootDir,
|
|
1229
1241
|
canonicalPathOfSymlink,
|
|
1230
1242
|
'..', // Symlink target is relative to its containing directory.
|
|
1231
1243
|
literalSymlinkTarget, // May be absolute, in which case the above are ignored
|
|
1232
1244
|
);
|
|
1233
|
-
|
|
1234
|
-
|
|
1245
|
+
if (absoluteSymlinkTarget.endsWith(path.sep)) {
|
|
1246
|
+
absoluteSymlinkTarget = absoluteSymlinkTarget.slice(0, -1);
|
|
1247
|
+
}
|
|
1248
|
+
const normalSymlinkTarget = this.#pathUtils.absoluteToNormal(
|
|
1235
1249
|
absoluteSymlinkTarget,
|
|
1236
1250
|
);
|
|
1251
|
+
|
|
1237
1252
|
const result = {
|
|
1238
1253
|
ancestorOfRootIdx:
|
|
1239
1254
|
this.#pathUtils.getAncestorOfRootIdx(normalSymlinkTarget),
|
|
@@ -16,8 +16,12 @@ class DependencyPlugin extends _FileDataPlugin.default {
|
|
|
16
16
|
const { dependencyExtractor, computeDependencies } = options;
|
|
17
17
|
let cacheKey;
|
|
18
18
|
if (dependencyExtractor != null) {
|
|
19
|
-
const
|
|
20
|
-
|
|
19
|
+
const mod = require(dependencyExtractor);
|
|
20
|
+
let getCacheKey = mod?.getCacheKey;
|
|
21
|
+
if (getCacheKey == null && mod?.__esModule === true) {
|
|
22
|
+
getCacheKey = mod.default?.getCacheKey;
|
|
23
|
+
}
|
|
24
|
+
cacheKey = getCacheKey?.() ?? dependencyExtractor;
|
|
21
25
|
} else {
|
|
22
26
|
cacheKey = "default-dependency-extractor";
|
|
23
27
|
}
|
|
@@ -28,8 +28,13 @@ export default class DependencyPlugin extends FileDataPlugin<ReadonlyArray<strin
|
|
|
28
28
|
let cacheKey: string;
|
|
29
29
|
if (dependencyExtractor != null) {
|
|
30
30
|
// $FlowFixMe[unsupported-syntax] - dynamic require
|
|
31
|
-
const
|
|
32
|
-
|
|
31
|
+
const mod = require(dependencyExtractor);
|
|
32
|
+
let getCacheKey = mod?.getCacheKey; // CJS export or ESM named export
|
|
33
|
+
// Allow for getCacheKey as a prop of an ESM default export
|
|
34
|
+
if (getCacheKey == null && mod?.__esModule === true) {
|
|
35
|
+
getCacheKey = mod.default?.getCacheKey;
|
|
36
|
+
}
|
|
37
|
+
cacheKey = getCacheKey?.() ?? dependencyExtractor;
|
|
33
38
|
} else {
|
|
34
39
|
cacheKey = 'default-dependency-extractor';
|
|
35
40
|
}
|
|
@@ -29,10 +29,10 @@ export type FileDataPluginOptions = Readonly<{
|
|
|
29
29
|
* of lifecycle methods that subclasses can override as needed.
|
|
30
30
|
*/
|
|
31
31
|
export default class FileDataPlugin<
|
|
32
|
-
|
|
32
|
+
in PerFileData extends void | V8Serializable = void | V8Serializable,
|
|
33
33
|
> implements FileMapPlugin<null, PerFileData>
|
|
34
34
|
{
|
|
35
|
-
|
|
35
|
+
readonly name: string;
|
|
36
36
|
|
|
37
37
|
#worker: FileMapPluginWorker;
|
|
38
38
|
#cacheKey: string;
|
|
@@ -55,19 +55,19 @@ export type HasteMapOptions = Readonly<{
|
|
|
55
55
|
export default class HastePlugin
|
|
56
56
|
implements HasteMap, FileMapPlugin<null, string | null>
|
|
57
57
|
{
|
|
58
|
-
|
|
58
|
+
readonly name: 'haste' = 'haste';
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
readonly #console: ?Console;
|
|
61
|
+
readonly #duplicates: DuplicatesIndex = new Map();
|
|
62
|
+
readonly #enableHastePackages: boolean;
|
|
63
|
+
readonly #failValidationOnConflicts: boolean;
|
|
64
64
|
#getModuleNameByPath: string => ?string;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
65
|
+
readonly #hasteImplModulePath: ?string;
|
|
66
|
+
readonly #map: Map<string, HasteMapItem> = new Map();
|
|
67
|
+
readonly #pathUtils: RootPathUtils;
|
|
68
|
+
readonly #perfLogger: ?PerfLogger;
|
|
69
|
+
readonly #platforms: ReadonlySet<string>;
|
|
70
|
+
readonly #rootDir: Path;
|
|
71
71
|
|
|
72
72
|
constructor(options: HasteMapOptions) {
|
|
73
73
|
this.#console = options.console ?? global.console;
|
|
@@ -39,13 +39,13 @@ export type MockMapOptions = Readonly<{
|
|
|
39
39
|
export default class MockPlugin
|
|
40
40
|
implements FileMapPlugin<RawMockMap, void>, IMockMap
|
|
41
41
|
{
|
|
42
|
-
|
|
42
|
+
readonly name: 'mocks' = 'mocks';
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
readonly #mocksPattern: RegExp;
|
|
45
45
|
#raw: RawMockMap;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
readonly #rootDir: Path;
|
|
47
|
+
readonly #pathUtils: RootPathUtils;
|
|
48
|
+
readonly #console: typeof console;
|
|
49
49
|
#throwOnModuleCollision: boolean;
|
|
50
50
|
|
|
51
51
|
constructor({
|
|
@@ -5,7 +5,12 @@ module.exports = class DependencyExtractorWorker {
|
|
|
5
5
|
#dependencyExtractor;
|
|
6
6
|
constructor({ dependencyExtractor }) {
|
|
7
7
|
if (dependencyExtractor != null) {
|
|
8
|
-
|
|
8
|
+
const mod = require(dependencyExtractor);
|
|
9
|
+
let extract = mod?.extract;
|
|
10
|
+
if (extract == null && mod?.__esModule === true) {
|
|
11
|
+
extract = mod.default?.extract;
|
|
12
|
+
}
|
|
13
|
+
this.#dependencyExtractor = extract;
|
|
9
14
|
}
|
|
10
15
|
}
|
|
11
16
|
processFile(data, utils) {
|
|
@@ -13,7 +18,7 @@ module.exports = class DependencyExtractorWorker {
|
|
|
13
18
|
const { filePath } = data;
|
|
14
19
|
const dependencies =
|
|
15
20
|
this.#dependencyExtractor != null
|
|
16
|
-
? this.#dependencyExtractor
|
|
21
|
+
? this.#dependencyExtractor(
|
|
17
22
|
content,
|
|
18
23
|
filePath,
|
|
19
24
|
defaultDependencyExtractor.extract,
|
|
@@ -20,14 +20,19 @@ import type {MetadataWorker, WorkerMessage, V8Serializable, DependencyExtractor}
|
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
22
|
module.exports = class DependencyExtractorWorker /*:: implements MetadataWorker */ {
|
|
23
|
-
/*::
|
|
23
|
+
/*:: readonly */ #dependencyExtractor /*: ?DependencyExtractor['extract'] */;
|
|
24
24
|
|
|
25
25
|
constructor(
|
|
26
26
|
{dependencyExtractor} /*: Readonly<{dependencyExtractor: ?string}> */,
|
|
27
27
|
) {
|
|
28
28
|
if (dependencyExtractor != null) {
|
|
29
29
|
// $FlowFixMe[unsupported-syntax] - dynamic require
|
|
30
|
-
|
|
30
|
+
const mod = require(dependencyExtractor);
|
|
31
|
+
let extract = mod?.extract; // CJS export or ESM named export
|
|
32
|
+
if (extract == null && mod?.__esModule === true) {
|
|
33
|
+
extract = mod.default?.extract;
|
|
34
|
+
}
|
|
35
|
+
this.#dependencyExtractor = extract;
|
|
31
36
|
}
|
|
32
37
|
}
|
|
33
38
|
|
|
@@ -40,7 +45,7 @@ module.exports = class DependencyExtractorWorker /*:: implements MetadataWorker
|
|
|
40
45
|
|
|
41
46
|
const dependencies =
|
|
42
47
|
this.#dependencyExtractor != null
|
|
43
|
-
? this.#dependencyExtractor
|
|
48
|
+
? this.#dependencyExtractor(
|
|
44
49
|
content,
|
|
45
50
|
filePath,
|
|
46
51
|
defaultDependencyExtractor.extract,
|
|
@@ -7,7 +7,9 @@ module.exports = class Worker {
|
|
|
7
7
|
#hasteImpl = null;
|
|
8
8
|
constructor({ hasteImplModulePath }) {
|
|
9
9
|
if (hasteImplModulePath != null) {
|
|
10
|
-
|
|
10
|
+
const mod = require(hasteImplModulePath);
|
|
11
|
+
this.#hasteImpl =
|
|
12
|
+
mod.__esModule === true && "default" in mod ? mod.default : mod;
|
|
11
13
|
}
|
|
12
14
|
}
|
|
13
15
|
processFile(data, utils) {
|
|
@@ -22,7 +22,7 @@ import type {MetadataWorker, WorkerMessage, V8Serializable} from '../../flow-typ
|
|
|
22
22
|
const PACKAGE_JSON = path.sep + 'package.json';
|
|
23
23
|
|
|
24
24
|
module.exports = class Worker /*:: implements MetadataWorker */ {
|
|
25
|
-
/*::
|
|
25
|
+
/*:: readonly */ #hasteImpl /*: ?Readonly<{getHasteName: string => ?string}> */ =
|
|
26
26
|
null;
|
|
27
27
|
|
|
28
28
|
constructor(
|
|
@@ -30,7 +30,9 @@ module.exports = class Worker /*:: implements MetadataWorker */ {
|
|
|
30
30
|
) {
|
|
31
31
|
if (hasteImplModulePath != null) {
|
|
32
32
|
// $FlowFixMe[unsupported-syntax] - dynamic require
|
|
33
|
-
|
|
33
|
+
const mod = require(hasteImplModulePath);
|
|
34
|
+
this.#hasteImpl =
|
|
35
|
+
mod.__esModule === true && 'default' in mod ? mod.default : mod;
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
38
|
|
|
@@ -24,11 +24,11 @@ export type Listeners = Readonly<{
|
|
|
24
24
|
}>;
|
|
25
25
|
|
|
26
26
|
export class AbstractWatcher implements WatcherBackend {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
readonly root: string;
|
|
28
|
+
readonly ignored: ?RegExp;
|
|
29
|
+
readonly globs: ReadonlyArray<string>;
|
|
30
|
+
readonly dot: boolean;
|
|
31
|
+
readonly doIgnore: (path: string) => boolean;
|
|
32
32
|
|
|
33
33
|
#emitter: EventEmitter = new EventEmitter();
|
|
34
34
|
|
|
@@ -42,12 +42,13 @@ const DELETE_EVENT = common.DELETE_EVENT;
|
|
|
42
42
|
const DEBOUNCE_MS = 100;
|
|
43
43
|
|
|
44
44
|
export default class FallbackWatcher extends AbstractWatcher {
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
readonly #changeTimers: Map<string, TimeoutID> = new Map();
|
|
46
|
+
readonly #dirRegistry: {
|
|
47
47
|
[directory: string]: {[file: string]: true, __proto__: null},
|
|
48
48
|
__proto__: null,
|
|
49
49
|
} = Object.create(null);
|
|
50
|
-
|
|
50
|
+
readonly #watched: {[key: string]: FSWatcher, __proto__: null} =
|
|
51
|
+
Object.create(null);
|
|
51
52
|
|
|
52
53
|
async startWatching(): Promise<void> {
|
|
53
54
|
this.#watchdir(this.root);
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
7
|
* @noformat
|
|
8
|
-
* @generated SignedSource<<
|
|
8
|
+
* @generated SignedSource<<6297e6ebfbeb2920f00b15cba9acbce2>>
|
|
9
9
|
*
|
|
10
10
|
* This file was translated from Flow by scripts/generateTypeScriptDefinitions.js
|
|
11
11
|
* Original file: packages/metro-file-map/src/watchers/NativeWatcher.js
|
|
@@ -50,6 +50,5 @@ declare class NativeWatcher extends AbstractWatcher {
|
|
|
50
50
|
* End watching.
|
|
51
51
|
*/
|
|
52
52
|
stopWatching(): Promise<void>;
|
|
53
|
-
_handleEvent(event: string, relativePath: string): void;
|
|
54
53
|
}
|
|
55
54
|
export default NativeWatcher;
|
|
@@ -41,12 +41,12 @@ const SUB_PREFIX = 'metro-file-map';
|
|
|
41
41
|
*/
|
|
42
42
|
export default class WatchmanWatcher extends AbstractWatcher {
|
|
43
43
|
#client: Client;
|
|
44
|
-
|
|
44
|
+
readonly subscriptionName: string;
|
|
45
45
|
#watchProjectInfo: ?Readonly<{
|
|
46
46
|
relativePath: string,
|
|
47
47
|
root: string,
|
|
48
48
|
}>;
|
|
49
|
-
|
|
49
|
+
readonly #watchmanDeferStates: ReadonlyArray<string>;
|
|
50
50
|
#deferringStates: ?Set<string> = null;
|
|
51
51
|
|
|
52
52
|
constructor(dir: string, opts: WatcherOptions) {
|
package/src/worker.js
CHANGED
|
@@ -9,7 +9,9 @@ class Worker {
|
|
|
9
9
|
#plugins;
|
|
10
10
|
constructor({ plugins = [] }) {
|
|
11
11
|
this.#plugins = plugins.map(({ modulePath, setupArgs }) => {
|
|
12
|
-
const
|
|
12
|
+
const mod = require(modulePath);
|
|
13
|
+
const PluginWorker =
|
|
14
|
+
mod.__esModule === true && "default" in mod ? mod.default : mod;
|
|
13
15
|
return new PluginWorker(setupArgs);
|
|
14
16
|
});
|
|
15
17
|
}
|
package/src/worker.js.flow
CHANGED
|
@@ -36,7 +36,9 @@ class Worker {
|
|
|
36
36
|
constructor({plugins = []} /*: WorkerSetupArgs */) {
|
|
37
37
|
this.#plugins = plugins.map(({modulePath, setupArgs}) => {
|
|
38
38
|
// $FlowFixMe[unsupported-syntax] - dynamic require
|
|
39
|
-
const
|
|
39
|
+
const mod = require(modulePath);
|
|
40
|
+
const PluginWorker =
|
|
41
|
+
mod.__esModule === true && 'default' in mod ? mod.default : mod;
|
|
40
42
|
return new PluginWorker(setupArgs);
|
|
41
43
|
});
|
|
42
44
|
}
|
|
@@ -1,19 +0,0 @@
|
|
|
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
|
-
* @noformat
|
|
8
|
-
* @oncall react_native
|
|
9
|
-
* @generated SignedSource<<8b6ff8a24f9156cd7991006c72edd296>>
|
|
10
|
-
*
|
|
11
|
-
* This file was translated from Flow by scripts/generateTypeScriptDefinitions.js
|
|
12
|
-
* Original file: packages/metro-file-map/src/crawlers/node/hasNativeFindSupport.js
|
|
13
|
-
* To regenerate, run:
|
|
14
|
-
* js1 build metro-ts-defs (internal) OR
|
|
15
|
-
* yarn run build-ts-defs (OSS)
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
declare function hasNativeFindSupport(): Promise<boolean>;
|
|
19
|
-
export default hasNativeFindSupport;
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true,
|
|
5
|
-
});
|
|
6
|
-
exports.default = hasNativeFindSupport;
|
|
7
|
-
var _child_process = require("child_process");
|
|
8
|
-
async function hasNativeFindSupport() {
|
|
9
|
-
try {
|
|
10
|
-
return await new Promise((resolve) => {
|
|
11
|
-
const args = [
|
|
12
|
-
".",
|
|
13
|
-
"-type",
|
|
14
|
-
"f",
|
|
15
|
-
"(",
|
|
16
|
-
"-iname",
|
|
17
|
-
"*.ts",
|
|
18
|
-
"-o",
|
|
19
|
-
"-iname",
|
|
20
|
-
"*.js",
|
|
21
|
-
")",
|
|
22
|
-
];
|
|
23
|
-
const child = (0, _child_process.spawn)("find", args, {
|
|
24
|
-
cwd: __dirname,
|
|
25
|
-
});
|
|
26
|
-
child.on("error", () => {
|
|
27
|
-
resolve(false);
|
|
28
|
-
});
|
|
29
|
-
child.on("exit", (code) => {
|
|
30
|
-
resolve(code === 0);
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
} catch {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
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
|
-
* @flow strict-local
|
|
8
|
-
* @format
|
|
9
|
-
* @oncall react_native
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import {spawn} from 'child_process';
|
|
13
|
-
|
|
14
|
-
export default async function hasNativeFindSupport(): Promise<boolean> {
|
|
15
|
-
try {
|
|
16
|
-
return await new Promise(resolve => {
|
|
17
|
-
// Check the find binary supports the non-POSIX -iname parameter wrapped in parens.
|
|
18
|
-
const args = [
|
|
19
|
-
'.',
|
|
20
|
-
'-type',
|
|
21
|
-
'f',
|
|
22
|
-
'(',
|
|
23
|
-
'-iname',
|
|
24
|
-
'*.ts',
|
|
25
|
-
'-o',
|
|
26
|
-
'-iname',
|
|
27
|
-
'*.js',
|
|
28
|
-
')',
|
|
29
|
-
];
|
|
30
|
-
const child = spawn('find', args, {cwd: __dirname});
|
|
31
|
-
child.on('error', () => {
|
|
32
|
-
resolve(false);
|
|
33
|
-
});
|
|
34
|
-
child.on('exit', code => {
|
|
35
|
-
resolve(code === 0);
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
} catch {
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
}
|