metro-file-map 0.83.3 → 0.84.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -3
- package/src/Watcher.js +59 -52
- package/src/Watcher.js.flow +39 -39
- package/src/cache/DiskCacheManager.js.flow +3 -3
- package/src/constants.js +9 -8
- package/src/constants.js.flow +6 -18
- package/src/crawlers/node/index.js +27 -25
- package/src/crawlers/node/index.js.flow +6 -8
- 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.js.flow +125 -87
- package/src/index.js +267 -235
- package/src/index.js.flow +269 -275
- package/src/lib/FileProcessor.js +76 -54
- package/src/lib/FileProcessor.js.flow +93 -72
- package/src/lib/RootPathUtils.js +25 -21
- package/src/lib/RootPathUtils.js.flow +4 -4
- package/src/lib/TreeFS.js +72 -77
- package/src/lib/TreeFS.js.flow +104 -124
- package/src/lib/checkWatchmanCapabilities.js.flow +4 -4
- package/src/lib/dependencyExtractor.d.ts +14 -0
- package/src/lib/normalizePathSeparatorsToPosix.js +25 -21
- package/src/lib/normalizePathSeparatorsToPosix.js.flow +3 -3
- package/src/lib/normalizePathSeparatorsToSystem.js +25 -21
- package/src/lib/normalizePathSeparatorsToSystem.js.flow +3 -3
- package/src/lib/rootRelativeCacheKeys.js +0 -20
- package/src/lib/rootRelativeCacheKeys.js.flow +1 -23
- package/src/plugins/DependencyPlugin.js +75 -0
- package/src/plugins/DependencyPlugin.js.flow +144 -0
- package/src/plugins/HastePlugin.js +83 -38
- package/src/plugins/HastePlugin.js.flow +105 -51
- package/src/plugins/MockPlugin.js +7 -4
- package/src/plugins/MockPlugin.js.flow +24 -15
- 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/plugins/haste/HasteConflictsError.js.flow +2 -2
- package/src/plugins/haste/computeConflicts.js +2 -1
- package/src/plugins/haste/computeConflicts.js.flow +11 -12
- 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.js +27 -23
- package/src/plugins/mocks/getMockName.js.flow +2 -4
- package/src/watchers/AbstractWatcher.js +27 -22
- package/src/watchers/AbstractWatcher.js.flow +6 -5
- package/src/watchers/FallbackWatcher.js +88 -84
- package/src/watchers/FallbackWatcher.js.flow +65 -65
- package/src/watchers/NativeWatcher.js +25 -21
- package/src/watchers/NativeWatcher.js.flow +3 -3
- package/src/watchers/RecrawlWarning.js.flow +1 -1
- package/src/watchers/WatchmanWatcher.js +61 -53
- package/src/watchers/WatchmanWatcher.js.flow +39 -38
- 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/Watcher.d.ts +0 -24
- package/src/cache/DiskCacheManager.d.ts +0 -38
- package/src/flow-types.d.ts +0 -353
- package/src/index.d.ts +0 -97
- package/src/lib/DuplicateHasteCandidatesError.d.ts +0 -24
- /package/src/{lib → plugins/dependencies}/dependencyExtractor.js +0 -0
|
@@ -0,0 +1,24 @@
|
|
|
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 {
|
|
11
|
+
MetadataWorker,
|
|
12
|
+
V8Serializable,
|
|
13
|
+
WorkerMessage,
|
|
14
|
+
} from '../../flow-types';
|
|
15
|
+
|
|
16
|
+
declare class Worker implements MetadataWorker {
|
|
17
|
+
constructor(opts: Readonly<{hasteImplModulePath: null | undefined | string}>);
|
|
18
|
+
processFile(
|
|
19
|
+
data: WorkerMessage,
|
|
20
|
+
utils: Readonly<{getContent: () => Buffer}>,
|
|
21
|
+
): V8Serializable;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export = Worker;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const excludedExtensions = require("../../workerExclusionList");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const PACKAGE_JSON = path.sep + "package.json";
|
|
6
|
+
module.exports = class Worker {
|
|
7
|
+
#hasteImpl = null;
|
|
8
|
+
constructor({ hasteImplModulePath }) {
|
|
9
|
+
if (hasteImplModulePath != null) {
|
|
10
|
+
this.#hasteImpl = require(hasteImplModulePath);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
processFile(data, utils) {
|
|
14
|
+
let hasteName = null;
|
|
15
|
+
const { filePath } = data;
|
|
16
|
+
if (filePath.endsWith(PACKAGE_JSON)) {
|
|
17
|
+
try {
|
|
18
|
+
const fileData = JSON.parse(utils.getContent().toString());
|
|
19
|
+
if (fileData.name) {
|
|
20
|
+
hasteName = fileData.name;
|
|
21
|
+
}
|
|
22
|
+
} catch (err) {
|
|
23
|
+
throw new Error(`Cannot parse ${filePath} as JSON: ${err.message}`);
|
|
24
|
+
}
|
|
25
|
+
} else if (
|
|
26
|
+
!excludedExtensions.has(filePath.substr(filePath.lastIndexOf(".")))
|
|
27
|
+
) {
|
|
28
|
+
if (!this.#hasteImpl) {
|
|
29
|
+
throw new Error("computeHaste is true but hasteImplModulePath not set");
|
|
30
|
+
}
|
|
31
|
+
hasteName = this.#hasteImpl.getHasteName(filePath) || null;
|
|
32
|
+
}
|
|
33
|
+
return hasteName;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
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
|
+
*/
|
|
10
|
+
|
|
11
|
+
/* eslint-disable import/no-commonjs */
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
const excludedExtensions = require('../../workerExclusionList');
|
|
16
|
+
const path = require('path');
|
|
17
|
+
|
|
18
|
+
/*::
|
|
19
|
+
import type {MetadataWorker, WorkerMessage, V8Serializable} from '../../flow-types';
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
const PACKAGE_JSON = path.sep + 'package.json';
|
|
23
|
+
|
|
24
|
+
module.exports = class Worker /*:: implements MetadataWorker */ {
|
|
25
|
+
/*:: + */ #hasteImpl /*: ?Readonly<{getHasteName: string => ?string}> */ =
|
|
26
|
+
null;
|
|
27
|
+
|
|
28
|
+
constructor(
|
|
29
|
+
{hasteImplModulePath} /*: Readonly<{hasteImplModulePath: ?string}> */,
|
|
30
|
+
) {
|
|
31
|
+
if (hasteImplModulePath != null) {
|
|
32
|
+
// $FlowFixMe[unsupported-syntax] - dynamic require
|
|
33
|
+
this.#hasteImpl = require(hasteImplModulePath);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
processFile(
|
|
38
|
+
data /*: WorkerMessage */,
|
|
39
|
+
utils /*: Readonly<{getContent: () => Buffer }> */,
|
|
40
|
+
) /*: V8Serializable */ {
|
|
41
|
+
let hasteName /*: string | null */ = null;
|
|
42
|
+
const {filePath} = data;
|
|
43
|
+
if (filePath.endsWith(PACKAGE_JSON)) {
|
|
44
|
+
// Process a package.json that is returned as a PACKAGE type with its name.
|
|
45
|
+
try {
|
|
46
|
+
const fileData = JSON.parse(utils.getContent().toString());
|
|
47
|
+
if (fileData.name) {
|
|
48
|
+
hasteName = fileData.name;
|
|
49
|
+
}
|
|
50
|
+
} catch (err) {
|
|
51
|
+
throw new Error(`Cannot parse ${filePath} as JSON: ${err.message}`);
|
|
52
|
+
}
|
|
53
|
+
} else if (
|
|
54
|
+
!excludedExtensions.has(filePath.substr(filePath.lastIndexOf('.')))
|
|
55
|
+
) {
|
|
56
|
+
if (!this.#hasteImpl) {
|
|
57
|
+
throw new Error('computeHaste is true but hasteImplModulePath not set');
|
|
58
|
+
}
|
|
59
|
+
// Process a random file that is returned as a MODULE.
|
|
60
|
+
hasteName = this.#hasteImpl.getHasteName(filePath) || null;
|
|
61
|
+
}
|
|
62
|
+
return hasteName;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
@@ -5,34 +5,38 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var path = _interopRequireWildcard(require("path"));
|
|
8
|
-
function
|
|
9
|
-
if ("function"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
return (
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
var n = { __proto__: null },
|
|
23
|
-
a = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
24
|
-
for (var u in e)
|
|
25
|
-
if ("default" !== u && {}.hasOwnProperty.call(e, u)) {
|
|
26
|
-
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null;
|
|
27
|
-
i && (i.get || i.set) ? Object.defineProperty(n, u, i) : (n[u] = e[u]);
|
|
8
|
+
function _interopRequireWildcard(e, t) {
|
|
9
|
+
if ("function" == typeof WeakMap)
|
|
10
|
+
var r = new WeakMap(),
|
|
11
|
+
n = new WeakMap();
|
|
12
|
+
return (_interopRequireWildcard = function (e, t) {
|
|
13
|
+
if (!t && e && e.__esModule) return e;
|
|
14
|
+
var o,
|
|
15
|
+
i,
|
|
16
|
+
f = { __proto__: null, default: e };
|
|
17
|
+
if (null === e || ("object" != typeof e && "function" != typeof e))
|
|
18
|
+
return f;
|
|
19
|
+
if ((o = t ? n : r)) {
|
|
20
|
+
if (o.has(e)) return o.get(e);
|
|
21
|
+
o.set(e, f);
|
|
28
22
|
}
|
|
29
|
-
|
|
23
|
+
for (const t in e)
|
|
24
|
+
"default" !== t &&
|
|
25
|
+
{}.hasOwnProperty.call(e, t) &&
|
|
26
|
+
((i =
|
|
27
|
+
(o = Object.defineProperty) &&
|
|
28
|
+
Object.getOwnPropertyDescriptor(e, t)) &&
|
|
29
|
+
(i.get || i.set)
|
|
30
|
+
? o(f, t, i)
|
|
31
|
+
: (f[t] = e[t]));
|
|
32
|
+
return f;
|
|
33
|
+
})(e, t);
|
|
30
34
|
}
|
|
31
35
|
const MOCKS_PATTERN = path.sep + "__mocks__" + path.sep;
|
|
32
|
-
|
|
36
|
+
var _default = (filePath) => {
|
|
33
37
|
const mockPath = filePath.split(MOCKS_PATTERN)[1];
|
|
34
38
|
return mockPath
|
|
35
39
|
.substring(0, mockPath.lastIndexOf(path.extname(mockPath)))
|
|
36
40
|
.replaceAll("\\", "/");
|
|
37
41
|
};
|
|
38
|
-
|
|
42
|
+
exports.default = _default;
|
|
@@ -4,19 +4,17 @@
|
|
|
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
|
|
8
|
+
* @format
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import * as path from 'path';
|
|
12
12
|
|
|
13
13
|
const MOCKS_PATTERN = path.sep + '__mocks__' + path.sep;
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
export default (filePath: string): string => {
|
|
16
16
|
const mockPath = filePath.split(MOCKS_PATTERN)[1];
|
|
17
17
|
return mockPath
|
|
18
18
|
.substring(0, mockPath.lastIndexOf(path.extname(mockPath)))
|
|
19
19
|
.replaceAll('\\', '/');
|
|
20
20
|
};
|
|
21
|
-
|
|
22
|
-
export default getMockName;
|
|
@@ -7,35 +7,40 @@ exports.AbstractWatcher = void 0;
|
|
|
7
7
|
var _common = require("./common");
|
|
8
8
|
var _events = _interopRequireDefault(require("events"));
|
|
9
9
|
var path = _interopRequireWildcard(require("path"));
|
|
10
|
-
function
|
|
11
|
-
if ("function"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
var n = { __proto__: null },
|
|
25
|
-
a = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
26
|
-
for (var u in e)
|
|
27
|
-
if ("default" !== u && {}.hasOwnProperty.call(e, u)) {
|
|
28
|
-
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null;
|
|
29
|
-
i && (i.get || i.set) ? Object.defineProperty(n, u, i) : (n[u] = e[u]);
|
|
10
|
+
function _interopRequireWildcard(e, t) {
|
|
11
|
+
if ("function" == typeof WeakMap)
|
|
12
|
+
var r = new WeakMap(),
|
|
13
|
+
n = new WeakMap();
|
|
14
|
+
return (_interopRequireWildcard = function (e, t) {
|
|
15
|
+
if (!t && e && e.__esModule) return e;
|
|
16
|
+
var o,
|
|
17
|
+
i,
|
|
18
|
+
f = { __proto__: null, default: e };
|
|
19
|
+
if (null === e || ("object" != typeof e && "function" != typeof e))
|
|
20
|
+
return f;
|
|
21
|
+
if ((o = t ? n : r)) {
|
|
22
|
+
if (o.has(e)) return o.get(e);
|
|
23
|
+
o.set(e, f);
|
|
30
24
|
}
|
|
31
|
-
|
|
25
|
+
for (const t in e)
|
|
26
|
+
"default" !== t &&
|
|
27
|
+
{}.hasOwnProperty.call(e, t) &&
|
|
28
|
+
((i =
|
|
29
|
+
(o = Object.defineProperty) &&
|
|
30
|
+
Object.getOwnPropertyDescriptor(e, t)) &&
|
|
31
|
+
(i.get || i.set)
|
|
32
|
+
? o(f, t, i)
|
|
33
|
+
: (f[t] = e[t]));
|
|
34
|
+
return f;
|
|
35
|
+
})(e, t);
|
|
32
36
|
}
|
|
33
37
|
function _interopRequireDefault(e) {
|
|
34
38
|
return e && e.__esModule ? e : { default: e };
|
|
35
39
|
}
|
|
36
40
|
class AbstractWatcher {
|
|
37
41
|
#emitter = new _events.default();
|
|
38
|
-
constructor(dir,
|
|
42
|
+
constructor(dir, opts) {
|
|
43
|
+
const { ignored, globs, dot } = opts;
|
|
39
44
|
this.dot = dot || false;
|
|
40
45
|
this.ignored = ignored;
|
|
41
46
|
this.globs = globs;
|
|
@@ -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 {
|
|
@@ -18,7 +18,7 @@ import {posixPathMatchesPattern} from './common';
|
|
|
18
18
|
import EventEmitter from 'events';
|
|
19
19
|
import * as path from 'path';
|
|
20
20
|
|
|
21
|
-
export type Listeners =
|
|
21
|
+
export type Listeners = Readonly<{
|
|
22
22
|
onFileEvent: (event: WatcherBackendChangeEvent) => void,
|
|
23
23
|
onError: (error: Error) => void,
|
|
24
24
|
}>;
|
|
@@ -26,13 +26,14 @@ export type Listeners = $ReadOnly<{
|
|
|
26
26
|
export class AbstractWatcher implements WatcherBackend {
|
|
27
27
|
+root: string;
|
|
28
28
|
+ignored: ?RegExp;
|
|
29
|
-
+globs:
|
|
29
|
+
+globs: ReadonlyArray<string>;
|
|
30
30
|
+dot: boolean;
|
|
31
31
|
+doIgnore: (path: string) => boolean;
|
|
32
32
|
|
|
33
33
|
#emitter: EventEmitter = new EventEmitter();
|
|
34
34
|
|
|
35
|
-
constructor(dir: string,
|
|
35
|
+
constructor(dir: string, opts: WatcherBackendOptions) {
|
|
36
|
+
const {ignored, globs, dot} = opts;
|
|
36
37
|
this.dot = dot || false;
|
|
37
38
|
this.ignored = ignored;
|
|
38
39
|
this.globs = globs;
|
|
@@ -63,7 +64,7 @@ export class AbstractWatcher implements WatcherBackend {
|
|
|
63
64
|
// Must be implemented by subclasses
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
async stopWatching() {
|
|
67
|
+
async stopWatching(): Promise<void> {
|
|
67
68
|
this.#emitter.removeAllListeners();
|
|
68
69
|
}
|
|
69
70
|
|
|
@@ -13,28 +13,32 @@ var _walker = _interopRequireDefault(require("walker"));
|
|
|
13
13
|
function _interopRequireDefault(e) {
|
|
14
14
|
return e && e.__esModule ? e : { default: e };
|
|
15
15
|
}
|
|
16
|
-
function
|
|
17
|
-
if ("function"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return (
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
var n = { __proto__: null },
|
|
31
|
-
a = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
32
|
-
for (var u in e)
|
|
33
|
-
if ("default" !== u && {}.hasOwnProperty.call(e, u)) {
|
|
34
|
-
var i = a ? Object.getOwnPropertyDescriptor(e, u) : null;
|
|
35
|
-
i && (i.get || i.set) ? Object.defineProperty(n, u, i) : (n[u] = e[u]);
|
|
16
|
+
function _interopRequireWildcard(e, t) {
|
|
17
|
+
if ("function" == typeof WeakMap)
|
|
18
|
+
var r = new WeakMap(),
|
|
19
|
+
n = new WeakMap();
|
|
20
|
+
return (_interopRequireWildcard = function (e, t) {
|
|
21
|
+
if (!t && e && e.__esModule) return e;
|
|
22
|
+
var o,
|
|
23
|
+
i,
|
|
24
|
+
f = { __proto__: null, default: e };
|
|
25
|
+
if (null === e || ("object" != typeof e && "function" != typeof e))
|
|
26
|
+
return f;
|
|
27
|
+
if ((o = t ? n : r)) {
|
|
28
|
+
if (o.has(e)) return o.get(e);
|
|
29
|
+
o.set(e, f);
|
|
36
30
|
}
|
|
37
|
-
|
|
31
|
+
for (const t in e)
|
|
32
|
+
"default" !== t &&
|
|
33
|
+
{}.hasOwnProperty.call(e, t) &&
|
|
34
|
+
((i =
|
|
35
|
+
(o = Object.defineProperty) &&
|
|
36
|
+
Object.getOwnPropertyDescriptor(e, t)) &&
|
|
37
|
+
(i.get || i.set)
|
|
38
|
+
? o(f, t, i)
|
|
39
|
+
: (f[t] = e[t]));
|
|
40
|
+
return f;
|
|
41
|
+
})(e, t);
|
|
38
42
|
}
|
|
39
43
|
const platform = _os.default.platform();
|
|
40
44
|
const fsPromises = _fs.default.promises;
|
|
@@ -42,35 +46,35 @@ const TOUCH_EVENT = common.TOUCH_EVENT;
|
|
|
42
46
|
const DELETE_EVENT = common.DELETE_EVENT;
|
|
43
47
|
const DEBOUNCE_MS = 100;
|
|
44
48
|
class FallbackWatcher extends _AbstractWatcher.AbstractWatcher {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
watched = Object.create(null);
|
|
49
|
+
#changeTimers = new Map();
|
|
50
|
+
#dirRegistry = Object.create(null);
|
|
51
|
+
#watched = Object.create(null);
|
|
48
52
|
async startWatching() {
|
|
49
|
-
this
|
|
53
|
+
this.#watchdir(this.root);
|
|
50
54
|
await new Promise((resolve) => {
|
|
51
55
|
recReaddir(
|
|
52
56
|
this.root,
|
|
53
57
|
(dir) => {
|
|
54
|
-
this
|
|
58
|
+
this.#watchdir(dir);
|
|
55
59
|
},
|
|
56
60
|
(filename) => {
|
|
57
|
-
this
|
|
61
|
+
this.#register(filename, "f");
|
|
58
62
|
},
|
|
59
63
|
(symlink) => {
|
|
60
|
-
this
|
|
64
|
+
this.#register(symlink, "l");
|
|
61
65
|
},
|
|
62
66
|
() => {
|
|
63
67
|
resolve();
|
|
64
68
|
},
|
|
65
|
-
this
|
|
69
|
+
this.#checkedEmitError,
|
|
66
70
|
this.ignored,
|
|
67
71
|
);
|
|
68
72
|
});
|
|
69
73
|
}
|
|
70
|
-
|
|
74
|
+
#register(filepath, type) {
|
|
71
75
|
const dir = _path.default.dirname(filepath);
|
|
72
76
|
const filename = _path.default.basename(filepath);
|
|
73
|
-
if (this
|
|
77
|
+
if (this.#dirRegistry[dir] && this.#dirRegistry[dir][filename]) {
|
|
74
78
|
return false;
|
|
75
79
|
}
|
|
76
80
|
const relativePath = _path.default.relative(this.root, filepath);
|
|
@@ -81,39 +85,39 @@ class FallbackWatcher extends _AbstractWatcher.AbstractWatcher {
|
|
|
81
85
|
) {
|
|
82
86
|
return false;
|
|
83
87
|
}
|
|
84
|
-
if (!this
|
|
85
|
-
this
|
|
88
|
+
if (!this.#dirRegistry[dir]) {
|
|
89
|
+
this.#dirRegistry[dir] = Object.create(null);
|
|
86
90
|
}
|
|
87
|
-
this
|
|
91
|
+
this.#dirRegistry[dir][filename] = true;
|
|
88
92
|
return true;
|
|
89
93
|
}
|
|
90
|
-
|
|
94
|
+
#unregister(filepath) {
|
|
91
95
|
const dir = _path.default.dirname(filepath);
|
|
92
|
-
if (this
|
|
96
|
+
if (this.#dirRegistry[dir]) {
|
|
93
97
|
const filename = _path.default.basename(filepath);
|
|
94
|
-
delete this
|
|
98
|
+
delete this.#dirRegistry[dir][filename];
|
|
95
99
|
}
|
|
96
100
|
}
|
|
97
|
-
|
|
98
|
-
if (this
|
|
99
|
-
delete this
|
|
101
|
+
#unregisterDir(dirpath) {
|
|
102
|
+
if (this.#dirRegistry[dirpath]) {
|
|
103
|
+
delete this.#dirRegistry[dirpath];
|
|
100
104
|
}
|
|
101
105
|
}
|
|
102
|
-
|
|
106
|
+
#registered(fullpath) {
|
|
103
107
|
const dir = _path.default.dirname(fullpath);
|
|
104
108
|
return !!(
|
|
105
|
-
this
|
|
106
|
-
(this
|
|
107
|
-
this
|
|
109
|
+
this.#dirRegistry[fullpath] ||
|
|
110
|
+
(this.#dirRegistry[dir] &&
|
|
111
|
+
this.#dirRegistry[dir][_path.default.basename(fullpath)])
|
|
108
112
|
);
|
|
109
113
|
}
|
|
110
|
-
|
|
114
|
+
#checkedEmitError = (error) => {
|
|
111
115
|
if (!isIgnorableFileError(error)) {
|
|
112
116
|
this.emitError(error);
|
|
113
117
|
}
|
|
114
118
|
};
|
|
115
|
-
|
|
116
|
-
if (this
|
|
119
|
+
#watchdir = (dir) => {
|
|
120
|
+
if (this.#watched[dir]) {
|
|
117
121
|
return false;
|
|
118
122
|
}
|
|
119
123
|
const watcher = _fs.default.watch(
|
|
@@ -121,39 +125,39 @@ class FallbackWatcher extends _AbstractWatcher.AbstractWatcher {
|
|
|
121
125
|
{
|
|
122
126
|
persistent: true,
|
|
123
127
|
},
|
|
124
|
-
(event, filename) => this
|
|
128
|
+
(event, filename) => this.#normalizeChange(dir, event, filename),
|
|
125
129
|
);
|
|
126
|
-
this
|
|
127
|
-
watcher.on("error", this
|
|
130
|
+
this.#watched[dir] = watcher;
|
|
131
|
+
watcher.on("error", this.#checkedEmitError);
|
|
128
132
|
if (this.root !== dir) {
|
|
129
|
-
this
|
|
133
|
+
this.#register(dir, "d");
|
|
130
134
|
}
|
|
131
135
|
return true;
|
|
132
136
|
};
|
|
133
|
-
async
|
|
134
|
-
if (this
|
|
137
|
+
async #stopWatching(dir) {
|
|
138
|
+
if (this.#watched[dir]) {
|
|
135
139
|
await new Promise((resolve) => {
|
|
136
|
-
this
|
|
137
|
-
this
|
|
138
|
-
delete this
|
|
140
|
+
this.#watched[dir].once("close", () => process.nextTick(resolve));
|
|
141
|
+
this.#watched[dir].close();
|
|
142
|
+
delete this.#watched[dir];
|
|
139
143
|
});
|
|
140
144
|
}
|
|
141
145
|
}
|
|
142
146
|
async stopWatching() {
|
|
143
147
|
await super.stopWatching();
|
|
144
|
-
const promises = Object.keys(this
|
|
145
|
-
this
|
|
148
|
+
const promises = Object.keys(this.#watched).map((dir) =>
|
|
149
|
+
this.#stopWatching(dir),
|
|
146
150
|
);
|
|
147
151
|
await Promise.all(promises);
|
|
148
152
|
}
|
|
149
|
-
|
|
150
|
-
if (!this
|
|
153
|
+
#detectChangedFile(dir, event, callback) {
|
|
154
|
+
if (!this.#dirRegistry[dir]) {
|
|
151
155
|
return;
|
|
152
156
|
}
|
|
153
157
|
let found = false;
|
|
154
158
|
let closest = null;
|
|
155
159
|
let c = 0;
|
|
156
|
-
Object.keys(this
|
|
160
|
+
Object.keys(this.#dirRegistry[dir]).forEach((file, i, arr) => {
|
|
157
161
|
_fs.default.lstat(_path.default.join(dir, file), (error, stat) => {
|
|
158
162
|
if (found) {
|
|
159
163
|
return;
|
|
@@ -179,28 +183,28 @@ class FallbackWatcher extends _AbstractWatcher.AbstractWatcher {
|
|
|
179
183
|
});
|
|
180
184
|
});
|
|
181
185
|
}
|
|
182
|
-
|
|
186
|
+
#normalizeChange(dir, event, file) {
|
|
183
187
|
if (!file) {
|
|
184
|
-
this
|
|
188
|
+
this.#detectChangedFile(dir, event, (actualFile) => {
|
|
185
189
|
if (actualFile) {
|
|
186
|
-
this
|
|
190
|
+
this.#processChange(dir, event, actualFile).catch((error) =>
|
|
187
191
|
this.emitError(error),
|
|
188
192
|
);
|
|
189
193
|
}
|
|
190
194
|
});
|
|
191
195
|
} else {
|
|
192
|
-
this
|
|
196
|
+
this.#processChange(dir, event, _path.default.normalize(file)).catch(
|
|
193
197
|
(error) => this.emitError(error),
|
|
194
198
|
);
|
|
195
199
|
}
|
|
196
200
|
}
|
|
197
|
-
async
|
|
201
|
+
async #processChange(dir, event, file) {
|
|
198
202
|
const fullPath = _path.default.join(dir, file);
|
|
199
203
|
const relativePath = _path.default.join(
|
|
200
204
|
_path.default.relative(this.root, dir),
|
|
201
205
|
file,
|
|
202
206
|
);
|
|
203
|
-
const registered = this
|
|
207
|
+
const registered = this.#registered(fullPath);
|
|
204
208
|
try {
|
|
205
209
|
const stat = await fsPromises.lstat(fullPath);
|
|
206
210
|
if (stat.isDirectory()) {
|
|
@@ -216,8 +220,8 @@ class FallbackWatcher extends _AbstractWatcher.AbstractWatcher {
|
|
|
216
220
|
recReaddir(
|
|
217
221
|
_path.default.resolve(this.root, relativePath),
|
|
218
222
|
(dir, stats) => {
|
|
219
|
-
if (this
|
|
220
|
-
this
|
|
223
|
+
if (this.#watchdir(dir)) {
|
|
224
|
+
this.#emitEvent({
|
|
221
225
|
event: TOUCH_EVENT,
|
|
222
226
|
relativePath: _path.default.relative(this.root, dir),
|
|
223
227
|
metadata: {
|
|
@@ -229,8 +233,8 @@ class FallbackWatcher extends _AbstractWatcher.AbstractWatcher {
|
|
|
229
233
|
}
|
|
230
234
|
},
|
|
231
235
|
(file, stats) => {
|
|
232
|
-
if (this
|
|
233
|
-
this
|
|
236
|
+
if (this.#register(file, "f")) {
|
|
237
|
+
this.#emitEvent({
|
|
234
238
|
event: TOUCH_EVENT,
|
|
235
239
|
relativePath: _path.default.relative(this.root, file),
|
|
236
240
|
metadata: {
|
|
@@ -242,7 +246,7 @@ class FallbackWatcher extends _AbstractWatcher.AbstractWatcher {
|
|
|
242
246
|
}
|
|
243
247
|
},
|
|
244
248
|
(symlink, stats) => {
|
|
245
|
-
if (this
|
|
249
|
+
if (this.#register(symlink, "l")) {
|
|
246
250
|
this.emitFileEvent({
|
|
247
251
|
event: TOUCH_EVENT,
|
|
248
252
|
relativePath: _path.default.relative(this.root, symlink),
|
|
@@ -255,7 +259,7 @@ class FallbackWatcher extends _AbstractWatcher.AbstractWatcher {
|
|
|
255
259
|
}
|
|
256
260
|
},
|
|
257
261
|
function endCallback() {},
|
|
258
|
-
this
|
|
262
|
+
this.#checkedEmitError,
|
|
259
263
|
this.ignored,
|
|
260
264
|
);
|
|
261
265
|
} else {
|
|
@@ -269,14 +273,14 @@ class FallbackWatcher extends _AbstractWatcher.AbstractWatcher {
|
|
|
269
273
|
type,
|
|
270
274
|
};
|
|
271
275
|
if (registered) {
|
|
272
|
-
this
|
|
276
|
+
this.#emitEvent({
|
|
273
277
|
event: TOUCH_EVENT,
|
|
274
278
|
relativePath,
|
|
275
279
|
metadata,
|
|
276
280
|
});
|
|
277
281
|
} else {
|
|
278
|
-
if (this
|
|
279
|
-
this
|
|
282
|
+
if (this.#register(fullPath, type)) {
|
|
283
|
+
this.#emitEvent({
|
|
280
284
|
event: TOUCH_EVENT,
|
|
281
285
|
relativePath,
|
|
282
286
|
metadata,
|
|
@@ -289,28 +293,28 @@ class FallbackWatcher extends _AbstractWatcher.AbstractWatcher {
|
|
|
289
293
|
this.emitError(error);
|
|
290
294
|
return;
|
|
291
295
|
}
|
|
292
|
-
this
|
|
293
|
-
this
|
|
296
|
+
this.#unregister(fullPath);
|
|
297
|
+
this.#unregisterDir(fullPath);
|
|
294
298
|
if (registered) {
|
|
295
|
-
this
|
|
299
|
+
this.#emitEvent({
|
|
296
300
|
event: DELETE_EVENT,
|
|
297
301
|
relativePath,
|
|
298
302
|
});
|
|
299
303
|
}
|
|
300
|
-
await this
|
|
304
|
+
await this.#stopWatching(fullPath);
|
|
301
305
|
}
|
|
302
306
|
}
|
|
303
|
-
|
|
307
|
+
#emitEvent(change) {
|
|
304
308
|
const { event, relativePath } = change;
|
|
305
309
|
const key = event + "-" + relativePath;
|
|
306
|
-
const existingTimer = this.
|
|
310
|
+
const existingTimer = this.#changeTimers.get(key);
|
|
307
311
|
if (existingTimer) {
|
|
308
312
|
clearTimeout(existingTimer);
|
|
309
313
|
}
|
|
310
|
-
this.
|
|
314
|
+
this.#changeTimers.set(
|
|
311
315
|
key,
|
|
312
316
|
setTimeout(() => {
|
|
313
|
-
this.
|
|
317
|
+
this.#changeTimers.delete(key);
|
|
314
318
|
this.emitFileEvent(change);
|
|
315
319
|
}, DEBOUNCE_MS),
|
|
316
320
|
);
|