@rspack/core 2.1.0-beta.0 → 2.1.0-rc.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/compiled/http-proxy-middleware/package.json +1 -1
- package/compiled/watchpack/index.js +474 -235
- package/compiled/watchpack/package.json +1 -1
- package/compiled/watchpack/types/DirectoryWatcher.d.ts +2 -0
- package/compiled/watchpack/types/index.d.ts +121 -113
- package/compiled/watchpack/types/util/globToRegExp.d.ts +2 -0
- package/compiled/watchpack/types/watchpack.d.ts +1 -1
- package/compiled/webpack-sources/index.js +953 -351
- package/compiled/webpack-sources/package.json +1 -1
- package/compiled/webpack-sources/types.d.ts +40 -1
- package/dist/config/types.d.ts +6 -5
- package/dist/index.js +45 -47
- package/dist/node/NodeWatchFileSystem.d.ts +3 -1
- package/package.json +7 -7
|
@@ -1,143 +1,6 @@
|
|
|
1
1
|
/******/ (() => { // webpackBootstrap
|
|
2
2
|
/******/ var __webpack_modules__ = ({
|
|
3
3
|
|
|
4
|
-
/***/ 428:
|
|
5
|
-
/***/ ((module) => {
|
|
6
|
-
|
|
7
|
-
module.exports = function (glob, opts) {
|
|
8
|
-
if (typeof glob !== 'string') {
|
|
9
|
-
throw new TypeError('Expected a string');
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
var str = String(glob);
|
|
13
|
-
|
|
14
|
-
// The regexp we are building, as a string.
|
|
15
|
-
var reStr = "";
|
|
16
|
-
|
|
17
|
-
// Whether we are matching so called "extended" globs (like bash) and should
|
|
18
|
-
// support single character matching, matching ranges of characters, group
|
|
19
|
-
// matching, etc.
|
|
20
|
-
var extended = opts ? !!opts.extended : false;
|
|
21
|
-
|
|
22
|
-
// When globstar is _false_ (default), '/foo/*' is translated a regexp like
|
|
23
|
-
// '^\/foo\/.*$' which will match any string beginning with '/foo/'
|
|
24
|
-
// When globstar is _true_, '/foo/*' is translated to regexp like
|
|
25
|
-
// '^\/foo\/[^/]*$' which will match any string beginning with '/foo/' BUT
|
|
26
|
-
// which does not have a '/' to the right of it.
|
|
27
|
-
// E.g. with '/foo/*' these will match: '/foo/bar', '/foo/bar.txt' but
|
|
28
|
-
// these will not '/foo/bar/baz', '/foo/bar/baz.txt'
|
|
29
|
-
// Lastely, when globstar is _true_, '/foo/**' is equivelant to '/foo/*' when
|
|
30
|
-
// globstar is _false_
|
|
31
|
-
var globstar = opts ? !!opts.globstar : false;
|
|
32
|
-
|
|
33
|
-
// If we are doing extended matching, this boolean is true when we are inside
|
|
34
|
-
// a group (eg {*.html,*.js}), and false otherwise.
|
|
35
|
-
var inGroup = false;
|
|
36
|
-
|
|
37
|
-
// RegExp flags (eg "i" ) to pass in to RegExp constructor.
|
|
38
|
-
var flags = opts && typeof( opts.flags ) === "string" ? opts.flags : "";
|
|
39
|
-
|
|
40
|
-
var c;
|
|
41
|
-
for (var i = 0, len = str.length; i < len; i++) {
|
|
42
|
-
c = str[i];
|
|
43
|
-
|
|
44
|
-
switch (c) {
|
|
45
|
-
case "/":
|
|
46
|
-
case "$":
|
|
47
|
-
case "^":
|
|
48
|
-
case "+":
|
|
49
|
-
case ".":
|
|
50
|
-
case "(":
|
|
51
|
-
case ")":
|
|
52
|
-
case "=":
|
|
53
|
-
case "!":
|
|
54
|
-
case "|":
|
|
55
|
-
reStr += "\\" + c;
|
|
56
|
-
break;
|
|
57
|
-
|
|
58
|
-
case "?":
|
|
59
|
-
if (extended) {
|
|
60
|
-
reStr += ".";
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
case "[":
|
|
65
|
-
case "]":
|
|
66
|
-
if (extended) {
|
|
67
|
-
reStr += c;
|
|
68
|
-
break;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
case "{":
|
|
72
|
-
if (extended) {
|
|
73
|
-
inGroup = true;
|
|
74
|
-
reStr += "(";
|
|
75
|
-
break;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
case "}":
|
|
79
|
-
if (extended) {
|
|
80
|
-
inGroup = false;
|
|
81
|
-
reStr += ")";
|
|
82
|
-
break;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
case ",":
|
|
86
|
-
if (inGroup) {
|
|
87
|
-
reStr += "|";
|
|
88
|
-
break;
|
|
89
|
-
}
|
|
90
|
-
reStr += "\\" + c;
|
|
91
|
-
break;
|
|
92
|
-
|
|
93
|
-
case "*":
|
|
94
|
-
// Move over all consecutive "*"'s.
|
|
95
|
-
// Also store the previous and next characters
|
|
96
|
-
var prevChar = str[i - 1];
|
|
97
|
-
var starCount = 1;
|
|
98
|
-
while(str[i + 1] === "*") {
|
|
99
|
-
starCount++;
|
|
100
|
-
i++;
|
|
101
|
-
}
|
|
102
|
-
var nextChar = str[i + 1];
|
|
103
|
-
|
|
104
|
-
if (!globstar) {
|
|
105
|
-
// globstar is disabled, so treat any number of "*" as one
|
|
106
|
-
reStr += ".*";
|
|
107
|
-
} else {
|
|
108
|
-
// globstar is enabled, so determine if this is a globstar segment
|
|
109
|
-
var isGlobstar = starCount > 1 // multiple "*"'s
|
|
110
|
-
&& (prevChar === "/" || prevChar === undefined) // from the start of the segment
|
|
111
|
-
&& (nextChar === "/" || nextChar === undefined) // to the end of the segment
|
|
112
|
-
|
|
113
|
-
if (isGlobstar) {
|
|
114
|
-
// it's a globstar, so match zero or more path segments
|
|
115
|
-
reStr += "((?:[^/]*(?:\/|$))*)";
|
|
116
|
-
i++; // move over the "/"
|
|
117
|
-
} else {
|
|
118
|
-
// it's not a globstar, so only match one path segment
|
|
119
|
-
reStr += "([^/]*)";
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
break;
|
|
123
|
-
|
|
124
|
-
default:
|
|
125
|
-
reStr += c;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// When regexp 'g' flag is specified don't
|
|
130
|
-
// constrain the regular expression with ^ & $
|
|
131
|
-
if (!flags || !~flags.indexOf('g')) {
|
|
132
|
-
reStr = "^" + reStr + "$";
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
return new RegExp(reStr, flags);
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
/***/ }),
|
|
140
|
-
|
|
141
4
|
/***/ 648:
|
|
142
5
|
/***/ ((module) => {
|
|
143
6
|
|
|
@@ -1111,7 +974,7 @@ function patch (fs) {
|
|
|
1111
974
|
|
|
1112
975
|
/***/ }),
|
|
1113
976
|
|
|
1114
|
-
/***/
|
|
977
|
+
/***/ 409:
|
|
1115
978
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
|
1116
979
|
|
|
1117
980
|
"use strict";
|
|
@@ -1125,7 +988,7 @@ const { EventEmitter } = __nccwpck_require__(434);
|
|
|
1125
988
|
const path = __nccwpck_require__(928);
|
|
1126
989
|
const fs = __nccwpck_require__(692);
|
|
1127
990
|
|
|
1128
|
-
const watchEventSource = __nccwpck_require__(
|
|
991
|
+
const watchEventSource = __nccwpck_require__(92);
|
|
1129
992
|
|
|
1130
993
|
/** @typedef {import("./index").IgnoredFunction} IgnoredFunction */
|
|
1131
994
|
/** @typedef {import("./index").EventType} EventType */
|
|
@@ -1145,13 +1008,28 @@ let FS_ACCURACY = 2000;
|
|
|
1145
1008
|
const IS_OSX = (__nccwpck_require__(857).platform)() === "darwin";
|
|
1146
1009
|
const IS_WIN = (__nccwpck_require__(857).platform)() === "win32";
|
|
1147
1010
|
|
|
1148
|
-
const { WATCHPACK_POLLING } = process.env;
|
|
1011
|
+
const { WATCHPACK_POLLING, WATCHPACK_RETRIES } = process.env;
|
|
1149
1012
|
const FORCE_POLLING =
|
|
1150
1013
|
// @ts-expect-error avoid additional checks
|
|
1151
1014
|
`${+WATCHPACK_POLLING}` === WATCHPACK_POLLING
|
|
1152
1015
|
? +WATCHPACK_POLLING
|
|
1153
1016
|
: Boolean(WATCHPACK_POLLING) && WATCHPACK_POLLING !== "false";
|
|
1154
1017
|
|
|
1018
|
+
// Number of retries (and delay between retries, in ms) when an fs operation
|
|
1019
|
+
// returns EBUSY. EBUSY is transient on Windows when an AV scanner, indexer,
|
|
1020
|
+
// or another process briefly locks a file; retrying avoids incorrectly
|
|
1021
|
+
// reporting the file as removed (see webpack/watchpack#223, #44).
|
|
1022
|
+
//
|
|
1023
|
+
// Configurable via `WATCHPACK_RETRIES` env var: an integer >= 0, or "false"
|
|
1024
|
+
// to disable retries entirely. Unset / invalid values fall back to 3.
|
|
1025
|
+
const BUSY_RETRIES = (() => {
|
|
1026
|
+
if (WATCHPACK_RETRIES === undefined) return 3;
|
|
1027
|
+
if (WATCHPACK_RETRIES === "false") return 0;
|
|
1028
|
+
const n = Number(WATCHPACK_RETRIES);
|
|
1029
|
+
return Number.isFinite(n) && n >= 0 ? Math.floor(n) : 3;
|
|
1030
|
+
})();
|
|
1031
|
+
const BUSY_RETRY_DELAY = 100;
|
|
1032
|
+
|
|
1155
1033
|
/**
|
|
1156
1034
|
* @param {string} str string
|
|
1157
1035
|
* @returns {string} lower cased string
|
|
@@ -1194,6 +1072,38 @@ function ensureFsAccuracy(mtime) {
|
|
|
1194
1072
|
else if (FS_ACCURACY > 1000 && mtime % 1000 !== 0) FS_ACCURACY = 1000;
|
|
1195
1073
|
}
|
|
1196
1074
|
|
|
1075
|
+
/**
|
|
1076
|
+
* Call `fs.lstat` with retries on EBUSY. Transient EBUSY errors are common
|
|
1077
|
+
* on Windows when another process (AV scanner, indexer, editor) holds an
|
|
1078
|
+
* open handle on the file. See webpack/watchpack#223, #44.
|
|
1079
|
+
*
|
|
1080
|
+
* The retry count is taken from the `WATCHPACK_RETRIES` env var (default
|
|
1081
|
+
* 3, set to "0" or "false" to disable retrying). The hot path is a single
|
|
1082
|
+
* `fs.lstat` call with one inline callback; the timer and the recursive
|
|
1083
|
+
* call are only scheduled when an EBUSY is actually observed.
|
|
1084
|
+
* @param {string} target target path
|
|
1085
|
+
* @param {{ closed: boolean }} watcher owning watcher (checked between retries)
|
|
1086
|
+
* @param {(err: NodeJS.ErrnoException | null, stats: import("fs").Stats) => void} callback callback
|
|
1087
|
+
* @param {number=} remaining retries remaining (defaults to `BUSY_RETRIES`)
|
|
1088
|
+
*/
|
|
1089
|
+
function lstatWithRetry(target, watcher, callback, remaining = BUSY_RETRIES) {
|
|
1090
|
+
fs.lstat(target, (err, stats) => {
|
|
1091
|
+
if (
|
|
1092
|
+
err &&
|
|
1093
|
+
/** @type {NodeJS.ErrnoException} */ (err).code === "EBUSY" &&
|
|
1094
|
+
remaining > 0 &&
|
|
1095
|
+
!watcher.closed
|
|
1096
|
+
) {
|
|
1097
|
+
setTimeout(
|
|
1098
|
+
() => lstatWithRetry(target, watcher, callback, remaining - 1),
|
|
1099
|
+
BUSY_RETRY_DELAY,
|
|
1100
|
+
);
|
|
1101
|
+
return;
|
|
1102
|
+
}
|
|
1103
|
+
callback(err, stats);
|
|
1104
|
+
});
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1197
1107
|
/**
|
|
1198
1108
|
* @typedef {object} FileWatcherEvents
|
|
1199
1109
|
* @property {(type: EventType) => void} initial-missing initial missing event
|
|
@@ -1284,6 +1194,8 @@ class DirectoryWatcher extends EventEmitter {
|
|
|
1284
1194
|
this.filesWithoutCase = new Map();
|
|
1285
1195
|
/** @type {Map<string, Watcher<DirectoryWatcherEvents> | boolean>} */
|
|
1286
1196
|
this.directories = new Map();
|
|
1197
|
+
/** @type {Map<string, Watcher<FileWatcherEvents>>} */
|
|
1198
|
+
this._symlinkTargetWatchers = new Map();
|
|
1287
1199
|
this.lastWatchEvent = 0;
|
|
1288
1200
|
this.initialScan = true;
|
|
1289
1201
|
this.ignored = options.ignored || (() => false);
|
|
@@ -1544,6 +1456,10 @@ class DirectoryWatcher extends EventEmitter {
|
|
|
1544
1456
|
(watcher).close();
|
|
1545
1457
|
this.directories.set(directory, true);
|
|
1546
1458
|
}
|
|
1459
|
+
for (const w of this._symlinkTargetWatchers.values()) {
|
|
1460
|
+
w.close();
|
|
1461
|
+
}
|
|
1462
|
+
this._symlinkTargetWatchers.clear();
|
|
1547
1463
|
}
|
|
1548
1464
|
}
|
|
1549
1465
|
}
|
|
@@ -1667,7 +1583,7 @@ class DirectoryWatcher extends EventEmitter {
|
|
|
1667
1583
|
const checkStats = () => {
|
|
1668
1584
|
if (this.closed) return;
|
|
1669
1585
|
this._activeEvents.set(filename, false);
|
|
1670
|
-
|
|
1586
|
+
lstatWithRetry(target, this, (err, stats) => {
|
|
1671
1587
|
if (this.closed) return;
|
|
1672
1588
|
if (this._activeEvents.get(filename) === true) {
|
|
1673
1589
|
process.nextTick(checkStats);
|
|
@@ -1676,6 +1592,9 @@ class DirectoryWatcher extends EventEmitter {
|
|
|
1676
1592
|
this._activeEvents.delete(filename);
|
|
1677
1593
|
// ENOENT happens when the file/directory doesn't exist
|
|
1678
1594
|
// EPERM happens when the containing directory doesn't exist
|
|
1595
|
+
// EBUSY happens when another process has the file locked (e.g.
|
|
1596
|
+
// Windows AV scanner). lstatWithRetry already retried before
|
|
1597
|
+
// giving up here.
|
|
1679
1598
|
if (err) {
|
|
1680
1599
|
if (
|
|
1681
1600
|
err.code !== "ENOENT" &&
|
|
@@ -1692,6 +1611,13 @@ class DirectoryWatcher extends EventEmitter {
|
|
|
1692
1611
|
}
|
|
1693
1612
|
this.lastWatchEvent = Date.now();
|
|
1694
1613
|
if (!stats) {
|
|
1614
|
+
// On EBUSY we keep the tracked state: the file is likely still
|
|
1615
|
+
// there and a later event or scan will reconcile. Emitting a
|
|
1616
|
+
// remove here would make the watch appear to stop after a
|
|
1617
|
+
// transient lock (webpack/watchpack#223, #44).
|
|
1618
|
+
if (err && err.code === "EBUSY" && BUSY_RETRIES > 0) {
|
|
1619
|
+
return;
|
|
1620
|
+
}
|
|
1695
1621
|
this.setMissing(target, false, eventType);
|
|
1696
1622
|
} else if (stats.isDirectory()) {
|
|
1697
1623
|
this.setDirectory(target, +stats.birthtime || 1, false, eventType);
|
|
@@ -1841,7 +1767,20 @@ class DirectoryWatcher extends EventEmitter {
|
|
|
1841
1767
|
fs.readdir(this.path, (err, items) => {
|
|
1842
1768
|
if (this.closed) return;
|
|
1843
1769
|
if (err) {
|
|
1844
|
-
|
|
1770
|
+
// Mirror the lstat error handling below: treat permission /
|
|
1771
|
+
// invalid-argument / no-device errors on the directory itself
|
|
1772
|
+
// as removed rather than logging "Watchpack Error (initial
|
|
1773
|
+
// scan)". These surface for unreadable mounts (WSL `/mnt/c`,
|
|
1774
|
+
// fuse mounts), unmounted devices (`/efi`), and libuv's
|
|
1775
|
+
// post-Node 22.17 `EINVAL` on protected Windows paths
|
|
1776
|
+
// (see #187).
|
|
1777
|
+
if (
|
|
1778
|
+
err.code === "ENOENT" ||
|
|
1779
|
+
err.code === "EPERM" ||
|
|
1780
|
+
err.code === "EACCES" ||
|
|
1781
|
+
err.code === "ENODEV" ||
|
|
1782
|
+
(err.code === "EINVAL" && IS_WIN)
|
|
1783
|
+
) {
|
|
1845
1784
|
this.onDirectoryRemoved("scan readdir failed");
|
|
1846
1785
|
} else {
|
|
1847
1786
|
this.onScanError(err);
|
|
@@ -1918,7 +1857,7 @@ class DirectoryWatcher extends EventEmitter {
|
|
|
1918
1857
|
}
|
|
1919
1858
|
});
|
|
1920
1859
|
for (const itemPath of itemPaths) {
|
|
1921
|
-
|
|
1860
|
+
lstatWithRetry(itemPath, this, (err2, stats) => {
|
|
1922
1861
|
if (this.closed) return;
|
|
1923
1862
|
if (err2) {
|
|
1924
1863
|
if (
|
|
@@ -1926,39 +1865,115 @@ class DirectoryWatcher extends EventEmitter {
|
|
|
1926
1865
|
err2.code === "EPERM" ||
|
|
1927
1866
|
err2.code === "EACCES" ||
|
|
1928
1867
|
err2.code === "EBUSY" ||
|
|
1868
|
+
err2.code === "ENODEV" ||
|
|
1929
1869
|
// TODO https://github.com/libuv/libuv/pull/4566
|
|
1930
1870
|
(err2.code === "EINVAL" && IS_WIN)
|
|
1931
1871
|
) {
|
|
1932
|
-
|
|
1872
|
+
// readdir saw the entry but we can't stat it due to a
|
|
1873
|
+
// transient lock — keep the previously-known entry instead
|
|
1874
|
+
// of incorrectly flagging it as missing.
|
|
1875
|
+
if (
|
|
1876
|
+
!(
|
|
1877
|
+
err2.code === "EBUSY" &&
|
|
1878
|
+
BUSY_RETRIES > 0 &&
|
|
1879
|
+
this.files.has(itemPath)
|
|
1880
|
+
)
|
|
1881
|
+
) {
|
|
1882
|
+
this.setMissing(itemPath, initial, `scan (${err2.code})`);
|
|
1883
|
+
}
|
|
1933
1884
|
} else {
|
|
1934
1885
|
this.onScanError(err2);
|
|
1935
1886
|
}
|
|
1936
1887
|
itemFinished();
|
|
1937
1888
|
return;
|
|
1938
1889
|
}
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1890
|
+
/**
|
|
1891
|
+
* @param {string | null} realPath resolved real path for an outside-dir symlink target
|
|
1892
|
+
*/
|
|
1893
|
+
const apply = (realPath) => {
|
|
1894
|
+
if (stats.isFile() || stats.isSymbolicLink()) {
|
|
1895
|
+
if (stats.mtime) ensureFsAccuracy(+stats.mtime);
|
|
1896
|
+
this.setFileTime(
|
|
1897
|
+
itemPath,
|
|
1898
|
+
+stats.mtime || +stats.ctime || 1,
|
|
1899
|
+
initial,
|
|
1900
|
+
true,
|
|
1901
|
+
"scan (file)",
|
|
1902
|
+
);
|
|
1903
|
+
if (realPath && !this._symlinkTargetWatchers.has(itemPath)) {
|
|
1904
|
+
const w = this.watcherManager.watchFile(realPath, Date.now());
|
|
1905
|
+
if (w) {
|
|
1906
|
+
w.on("change", (mtime, type, wInitial) => {
|
|
1907
|
+
if (wInitial) return;
|
|
1908
|
+
this.setFileTime(itemPath, mtime, false, false, type);
|
|
1909
|
+
});
|
|
1910
|
+
this._symlinkTargetWatchers.set(itemPath, w);
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
} else if (
|
|
1914
|
+
stats.isDirectory() &&
|
|
1915
|
+
(!initial || !this.directories.has(itemPath))
|
|
1916
|
+
) {
|
|
1917
|
+
this.setDirectory(
|
|
1918
|
+
itemPath,
|
|
1919
|
+
+stats.birthtime || 1,
|
|
1920
|
+
initial,
|
|
1921
|
+
"scan (dir)",
|
|
1922
|
+
);
|
|
1942
1923
|
}
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
);
|
|
1950
|
-
} else if (
|
|
1951
|
-
stats.isDirectory() &&
|
|
1952
|
-
(!initial || !this.directories.has(itemPath))
|
|
1924
|
+
itemFinished();
|
|
1925
|
+
};
|
|
1926
|
+
if (
|
|
1927
|
+
this.options.followSymlinks &&
|
|
1928
|
+
this.nestedWatching &&
|
|
1929
|
+
stats.isSymbolicLink()
|
|
1953
1930
|
) {
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1931
|
+
fs.realpath(itemPath, (err3, realPath) => {
|
|
1932
|
+
if (this.closed) return;
|
|
1933
|
+
if (
|
|
1934
|
+
err3 ||
|
|
1935
|
+
!realPath ||
|
|
1936
|
+
withoutCase(path.dirname(realPath)) === withoutCase(this.path)
|
|
1937
|
+
) {
|
|
1938
|
+
apply(null);
|
|
1939
|
+
return;
|
|
1940
|
+
}
|
|
1941
|
+
// Cycle protection: when the symlink's target is the symlink
|
|
1942
|
+
// path itself or one of its ancestors, descending would
|
|
1943
|
+
// create an unbounded chain of `DirectoryWatcher`s as we walk
|
|
1944
|
+
// back into territory we are already watching. Treat the
|
|
1945
|
+
// symlink as a plain entry instead so the symlink itself is
|
|
1946
|
+
// still tracked but no recursion happens.
|
|
1947
|
+
const rel = path.relative(realPath, itemPath);
|
|
1948
|
+
if (!path.isAbsolute(rel) && !rel.startsWith("..")) {
|
|
1949
|
+
apply(null);
|
|
1950
|
+
return;
|
|
1951
|
+
}
|
|
1952
|
+
fs.stat(realPath, (err4, targetStats) => {
|
|
1953
|
+
if (this.closed) return;
|
|
1954
|
+
if (err4 || !targetStats) {
|
|
1955
|
+
apply(null);
|
|
1956
|
+
} else if (targetStats.isFile()) {
|
|
1957
|
+
apply(realPath);
|
|
1958
|
+
} else if (targetStats.isDirectory()) {
|
|
1959
|
+
// Treat a symlink whose target is a directory as a
|
|
1960
|
+
// nested watched directory so files inside the target
|
|
1961
|
+
// propagate change events to the symlink path.
|
|
1962
|
+
this.setDirectory(
|
|
1963
|
+
itemPath,
|
|
1964
|
+
+targetStats.birthtime || +stats.birthtime || 1,
|
|
1965
|
+
initial,
|
|
1966
|
+
"scan (dir)",
|
|
1967
|
+
);
|
|
1968
|
+
itemFinished();
|
|
1969
|
+
} else {
|
|
1970
|
+
apply(null);
|
|
1971
|
+
}
|
|
1972
|
+
});
|
|
1973
|
+
});
|
|
1974
|
+
return;
|
|
1960
1975
|
}
|
|
1961
|
-
|
|
1976
|
+
apply(null);
|
|
1962
1977
|
});
|
|
1963
1978
|
}
|
|
1964
1979
|
itemFinished();
|
|
@@ -2056,6 +2071,7 @@ class DirectoryWatcher extends EventEmitter {
|
|
|
2056
2071
|
}
|
|
2057
2072
|
|
|
2058
2073
|
close() {
|
|
2074
|
+
if (this.closed) return;
|
|
2059
2075
|
this.closed = true;
|
|
2060
2076
|
this.initialScan = false;
|
|
2061
2077
|
if (this.watcher) {
|
|
@@ -2069,6 +2085,10 @@ class DirectoryWatcher extends EventEmitter {
|
|
|
2069
2085
|
}
|
|
2070
2086
|
this.directories.clear();
|
|
2071
2087
|
}
|
|
2088
|
+
for (const w of this._symlinkTargetWatchers.values()) {
|
|
2089
|
+
w.close();
|
|
2090
|
+
}
|
|
2091
|
+
this._symlinkTargetWatchers.clear();
|
|
2072
2092
|
if (this.parentWatcher) {
|
|
2073
2093
|
this.parentWatcher.close();
|
|
2074
2094
|
this.parentWatcher = null;
|
|
@@ -2084,7 +2104,7 @@ module.exports.Watcher = Watcher;
|
|
|
2084
2104
|
|
|
2085
2105
|
/***/ }),
|
|
2086
2106
|
|
|
2087
|
-
/***/
|
|
2107
|
+
/***/ 366:
|
|
2088
2108
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
|
2089
2109
|
|
|
2090
2110
|
"use strict";
|
|
@@ -2206,7 +2226,7 @@ module.exports = LinkResolver;
|
|
|
2206
2226
|
|
|
2207
2227
|
/***/ }),
|
|
2208
2228
|
|
|
2209
|
-
/***/
|
|
2229
|
+
/***/ 213:
|
|
2210
2230
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
|
2211
2231
|
|
|
2212
2232
|
"use strict";
|
|
@@ -2217,7 +2237,7 @@ module.exports = LinkResolver;
|
|
|
2217
2237
|
|
|
2218
2238
|
|
|
2219
2239
|
const path = __nccwpck_require__(928);
|
|
2220
|
-
const DirectoryWatcher = __nccwpck_require__(
|
|
2240
|
+
const DirectoryWatcher = __nccwpck_require__(409);
|
|
2221
2241
|
|
|
2222
2242
|
/** @typedef {import("./index").EventMap} EventMap */
|
|
2223
2243
|
/** @typedef {import("./DirectoryWatcher").DirectoryWatcherOptions} DirectoryWatcherOptions */
|
|
@@ -2294,7 +2314,7 @@ module.exports.WatcherManager = WatcherManager;
|
|
|
2294
2314
|
|
|
2295
2315
|
/***/ }),
|
|
2296
2316
|
|
|
2297
|
-
/***/
|
|
2317
|
+
/***/ 934:
|
|
2298
2318
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
|
2299
2319
|
|
|
2300
2320
|
"use strict";
|
|
@@ -2305,10 +2325,10 @@ module.exports.WatcherManager = WatcherManager;
|
|
|
2305
2325
|
|
|
2306
2326
|
|
|
2307
2327
|
const { EventEmitter } = __nccwpck_require__(434);
|
|
2308
|
-
const
|
|
2309
|
-
const
|
|
2310
|
-
const
|
|
2311
|
-
const watchEventSource = __nccwpck_require__(
|
|
2328
|
+
const LinkResolver = __nccwpck_require__(366);
|
|
2329
|
+
const getWatcherManager = __nccwpck_require__(213);
|
|
2330
|
+
const globToRegExp = __nccwpck_require__(737);
|
|
2331
|
+
const watchEventSource = __nccwpck_require__(92);
|
|
2312
2332
|
|
|
2313
2333
|
/** @typedef {import("./getWatcherManager").WatcherManager} WatcherManager */
|
|
2314
2334
|
/** @typedef {import("./DirectoryWatcher")} DirectoryWatcher */
|
|
@@ -2345,8 +2365,9 @@ const watchEventSource = __nccwpck_require__(313);
|
|
|
2345
2365
|
/** @typedef {`scan (${string})` | "change" | "rename" | `watch ${string}` | `directory-removed ${string}`} EventType */
|
|
2346
2366
|
/** @typedef {{ safeTime: number, timestamp: number, accuracy: number }} Entry */
|
|
2347
2367
|
/** @typedef {{ safeTime: number }} OnlySafeTimeEntry */
|
|
2368
|
+
|
|
2348
2369
|
// eslint-disable-next-line jsdoc/ts-no-empty-object-type
|
|
2349
|
-
/** @typedef {{}} ExistenceOnlyTimeEntry */
|
|
2370
|
+
/** @typedef {{ }} ExistenceOnlyTimeEntry */
|
|
2350
2371
|
/** @typedef {Map<string, Entry | OnlySafeTimeEntry | ExistenceOnlyTimeEntry | null>} TimeInfoEntries */
|
|
2351
2372
|
/** @typedef {Set<string>} Changes */
|
|
2352
2373
|
/** @typedef {Set<string>} Removals */
|
|
@@ -2360,10 +2381,8 @@ const watchEventSource = __nccwpck_require__(313);
|
|
|
2360
2381
|
*/
|
|
2361
2382
|
function addWatchersToSet(watchers, set) {
|
|
2362
2383
|
for (const ww of watchers) {
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
set.add(w.directoryWatcher);
|
|
2366
|
-
}
|
|
2384
|
+
// Set.add is already idempotent, so skip the redundant has() probe.
|
|
2385
|
+
set.add(ww.watcher.directoryWatcher);
|
|
2367
2386
|
}
|
|
2368
2387
|
}
|
|
2369
2388
|
|
|
@@ -2375,31 +2394,47 @@ const stringToRegexp = (ignored) => {
|
|
|
2375
2394
|
if (ignored.length === 0) {
|
|
2376
2395
|
return;
|
|
2377
2396
|
}
|
|
2378
|
-
|
|
2379
|
-
return `${source.slice(0, -1)}(?:$|\\/)`;
|
|
2397
|
+
return `^${globToRegExp(ignored)}(?:$|\\/)`;
|
|
2380
2398
|
};
|
|
2381
2399
|
|
|
2400
|
+
/**
|
|
2401
|
+
* Normalizes path separators for regex testing. `String.prototype.replace`
|
|
2402
|
+
* always allocates a new string, even when the pattern finds nothing; for
|
|
2403
|
+
* POSIX paths (the common case) that allocation is pure overhead. Check for
|
|
2404
|
+
* a backslash with `indexOf` first so we skip the copy on paths that are
|
|
2405
|
+
* already normalized.
|
|
2406
|
+
* @param {string} item item
|
|
2407
|
+
* @returns {string} item with backslashes normalized to forward slashes
|
|
2408
|
+
*/
|
|
2409
|
+
const normalizeSeparators = (item) =>
|
|
2410
|
+
item.includes("\\") ? item.replace(/\\/g, "/") : item;
|
|
2411
|
+
|
|
2382
2412
|
/**
|
|
2383
2413
|
* @param {Ignored=} ignored ignored
|
|
2384
2414
|
* @returns {(item: string) => boolean} ignored to function
|
|
2385
2415
|
*/
|
|
2386
2416
|
const ignoredToFunction = (ignored) => {
|
|
2387
2417
|
if (Array.isArray(ignored)) {
|
|
2388
|
-
const stringRegexps =
|
|
2418
|
+
const stringRegexps =
|
|
2419
|
+
/** @type {string[]} */
|
|
2420
|
+
(ignored.map((i) => stringToRegexp(i)).filter(Boolean));
|
|
2389
2421
|
if (stringRegexps.length === 0) {
|
|
2390
2422
|
return () => false;
|
|
2391
2423
|
}
|
|
2392
|
-
const regexp =
|
|
2393
|
-
|
|
2424
|
+
const regexp =
|
|
2425
|
+
stringRegexps.length === 1
|
|
2426
|
+
? new RegExp(stringRegexps[0])
|
|
2427
|
+
: new RegExp(stringRegexps.join("|"));
|
|
2428
|
+
return (item) => regexp.test(normalizeSeparators(item));
|
|
2394
2429
|
} else if (typeof ignored === "string") {
|
|
2395
2430
|
const stringRegexp = stringToRegexp(ignored);
|
|
2396
2431
|
if (!stringRegexp) {
|
|
2397
2432
|
return () => false;
|
|
2398
2433
|
}
|
|
2399
2434
|
const regexp = new RegExp(stringRegexp);
|
|
2400
|
-
return (item) => regexp.test(item
|
|
2435
|
+
return (item) => regexp.test(normalizeSeparators(item));
|
|
2401
2436
|
} else if (ignored instanceof RegExp) {
|
|
2402
|
-
return (item) => ignored.test(item
|
|
2437
|
+
return (item) => ignored.test(normalizeSeparators(item));
|
|
2403
2438
|
} else if (typeof ignored === "function") {
|
|
2404
2439
|
return ignored;
|
|
2405
2440
|
} else if (ignored) {
|
|
@@ -2763,8 +2798,10 @@ class Watchpack extends EventEmitter {
|
|
|
2763
2798
|
/** @type {Record<string, number>} */
|
|
2764
2799
|
const obj = Object.create(null);
|
|
2765
2800
|
for (const w of directoryWatchers) {
|
|
2801
|
+
// getTimes() returns a prototype-less object, so for...in is safe
|
|
2802
|
+
// and avoids the throwaway array that Object.keys would allocate.
|
|
2766
2803
|
const times = w.getTimes();
|
|
2767
|
-
for (const file
|
|
2804
|
+
for (const file in times) obj[file] = times[file];
|
|
2768
2805
|
}
|
|
2769
2806
|
return obj;
|
|
2770
2807
|
}
|
|
@@ -2851,12 +2888,35 @@ class Watchpack extends EventEmitter {
|
|
|
2851
2888
|
}
|
|
2852
2889
|
}
|
|
2853
2890
|
|
|
2854
|
-
|
|
2891
|
+
/**
|
|
2892
|
+
* @template A
|
|
2893
|
+
* @template B
|
|
2894
|
+
* @param {A} obj input a
|
|
2895
|
+
* @param {B} exports input b
|
|
2896
|
+
* @returns {A & B} merged
|
|
2897
|
+
*/
|
|
2898
|
+
const mergeExports = (obj, exports) => {
|
|
2899
|
+
const descriptors = Object.getOwnPropertyDescriptors(exports);
|
|
2900
|
+
Object.defineProperties(obj, descriptors);
|
|
2901
|
+
return /** @type {A & B} */ (Object.freeze(obj));
|
|
2902
|
+
};
|
|
2903
|
+
|
|
2904
|
+
/** @typedef {typeof Watchpack & { util: { readonly globToRegExp: typeof globToRegExp } }} WatchpackExports */
|
|
2905
|
+
|
|
2906
|
+
module.exports = /** @type {WatchpackExports} */ (
|
|
2907
|
+
mergeExports(Watchpack, {
|
|
2908
|
+
util: {
|
|
2909
|
+
get globToRegExp() {
|
|
2910
|
+
return globToRegExp;
|
|
2911
|
+
},
|
|
2912
|
+
},
|
|
2913
|
+
})
|
|
2914
|
+
);
|
|
2855
2915
|
|
|
2856
2916
|
|
|
2857
2917
|
/***/ }),
|
|
2858
2918
|
|
|
2859
|
-
/***/
|
|
2919
|
+
/***/ 817:
|
|
2860
2920
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
|
2861
2921
|
|
|
2862
2922
|
"use strict";
|
|
@@ -2929,45 +2989,66 @@ module.exports = (plan, limit) => {
|
|
|
2929
2989
|
}
|
|
2930
2990
|
}
|
|
2931
2991
|
}
|
|
2932
|
-
// Reduce until limit reached
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2992
|
+
// Reduce until limit reached. When no reduction is needed at all, skip
|
|
2993
|
+
// building the candidate set entirely to avoid paying for the setup on the
|
|
2994
|
+
// common fast path.
|
|
2995
|
+
if (currentCount > limit) {
|
|
2996
|
+
// Pre-filter candidate nodes so the inner selection loop skips structural
|
|
2997
|
+
// non-candidates entirely. `children` length and parent presence are
|
|
2998
|
+
// fixed after tree construction; only `entries` can change (it can only
|
|
2999
|
+
// decrease), so a node that fails the `entries` check in a later round
|
|
3000
|
+
// is simply skipped via `continue`. When we merge a subtree we drop the
|
|
3001
|
+
// descendants from the candidate set to keep it shrinking over
|
|
3002
|
+
// iterations.
|
|
3003
|
+
/** @type {Set<TreeNode<T>>} */
|
|
3004
|
+
const candidates = new Set();
|
|
2938
3005
|
for (const node of treeMap.values()) {
|
|
2939
|
-
if (node.
|
|
3006
|
+
if (!node.parent || !node.children) continue;
|
|
2940
3007
|
if (node.children.length === 0) continue;
|
|
2941
3008
|
if (node.children.length === 1 && !node.value) continue;
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
3009
|
+
candidates.add(node);
|
|
3010
|
+
}
|
|
3011
|
+
const costBias = limit * 0.3;
|
|
3012
|
+
while (currentCount > limit) {
|
|
3013
|
+
// Select node that helps reaching the limit most effectively without overmerging
|
|
3014
|
+
const overLimit = currentCount - limit;
|
|
3015
|
+
let bestNode;
|
|
3016
|
+
let bestCost = Infinity;
|
|
3017
|
+
for (const node of candidates) {
|
|
3018
|
+
if (node.entries <= 1) continue;
|
|
3019
|
+
// Try to select the node with has just a bit more entries than we need to reduce
|
|
3020
|
+
// When just a bit more is over 30% over the limit,
|
|
3021
|
+
// also consider just a bit less entries then we need to reduce
|
|
3022
|
+
const diff = node.entries - 1 - overLimit;
|
|
3023
|
+
const cost = diff >= 0 ? diff : -diff + costBias;
|
|
3024
|
+
if (cost < bestCost) {
|
|
3025
|
+
bestNode = node;
|
|
3026
|
+
bestCost = cost;
|
|
3027
|
+
// A cost of 0 means the merge reduces exactly to the limit;
|
|
3028
|
+
// no further candidate can improve on that, so stop scanning.
|
|
3029
|
+
if (cost === 0) break;
|
|
3030
|
+
}
|
|
2952
3031
|
}
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
3032
|
+
if (!bestNode) break;
|
|
3033
|
+
// Merge all children
|
|
3034
|
+
const reduction = bestNode.entries - 1;
|
|
3035
|
+
bestNode.active = true;
|
|
3036
|
+
bestNode.entries = 1;
|
|
3037
|
+
candidates.delete(bestNode);
|
|
3038
|
+
currentCount -= reduction;
|
|
3039
|
+
let { parent } = bestNode;
|
|
3040
|
+
while (parent) {
|
|
3041
|
+
parent.entries -= reduction;
|
|
3042
|
+
parent = parent.parent;
|
|
3043
|
+
}
|
|
3044
|
+
const queue = new Set(bestNode.children);
|
|
3045
|
+
for (const node of queue) {
|
|
3046
|
+
node.active = false;
|
|
3047
|
+
node.entries = 0;
|
|
3048
|
+
candidates.delete(node);
|
|
3049
|
+
if (node.children) {
|
|
3050
|
+
for (const child of node.children) queue.add(child);
|
|
3051
|
+
}
|
|
2971
3052
|
}
|
|
2972
3053
|
}
|
|
2973
3054
|
}
|
|
@@ -3002,7 +3083,157 @@ module.exports = (plan, limit) => {
|
|
|
3002
3083
|
|
|
3003
3084
|
/***/ }),
|
|
3004
3085
|
|
|
3005
|
-
/***/
|
|
3086
|
+
/***/ 737:
|
|
3087
|
+
/***/ ((module) => {
|
|
3088
|
+
|
|
3089
|
+
"use strict";
|
|
3090
|
+
/*
|
|
3091
|
+
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
3092
|
+
Author Haijie Xie @hai-x
|
|
3093
|
+
*/
|
|
3094
|
+
|
|
3095
|
+
|
|
3096
|
+
|
|
3097
|
+
// Based on https://github.com/fitzgen/glob-to-regexp (MIT)
|
|
3098
|
+
// Specialized for watchpack: `extended` and `globstar` always enabled.
|
|
3099
|
+
// Returns the regexp source without `^`/`$` anchors.
|
|
3100
|
+
|
|
3101
|
+
const CC_EXCLAMATION = 33; // "!"
|
|
3102
|
+
const CC_DOLLAR = 36; // "$"
|
|
3103
|
+
const CC_LEFT_PARENTHESIS = 40; // "("
|
|
3104
|
+
const CC_RIGHT_PARENTHESIS = 41; // ")"
|
|
3105
|
+
const CC_ASTERISK = 42; // "*"
|
|
3106
|
+
const CC_PLUS = 43; // "+"
|
|
3107
|
+
const CC_COMMA = 44; // ","
|
|
3108
|
+
const CC_DOT = 46; // "."
|
|
3109
|
+
const CC_SLASH = 47; // "/"
|
|
3110
|
+
const CC_EQUAL = 61; // "="
|
|
3111
|
+
const CC_QUESTION_MARK = 63; // "?"
|
|
3112
|
+
const CC_LEFT_BRACKET = 91; // "["
|
|
3113
|
+
const CC_RIGHT_BRACKET = 93; // "]"
|
|
3114
|
+
const CC_CARET = 94; // "^"
|
|
3115
|
+
const CC_LEFT_BRACE = 123; // "{"
|
|
3116
|
+
const CC_PIPE = 124; // "|"
|
|
3117
|
+
const CC_RIGHT_BRACE = 125; // "}"
|
|
3118
|
+
|
|
3119
|
+
/**
|
|
3120
|
+
* @param {string} glob glob pattern
|
|
3121
|
+
* @returns {string} regexp source without anchors
|
|
3122
|
+
*/
|
|
3123
|
+
module.exports = (glob) => {
|
|
3124
|
+
if (typeof glob !== "string") {
|
|
3125
|
+
throw new TypeError("Expected a string");
|
|
3126
|
+
}
|
|
3127
|
+
|
|
3128
|
+
const len = glob.length;
|
|
3129
|
+
let reStr = "";
|
|
3130
|
+
let inGroup = false;
|
|
3131
|
+
// Start of the current run of literal characters, copied with one slice
|
|
3132
|
+
let literalStart = 0;
|
|
3133
|
+
|
|
3134
|
+
for (let i = 0; i < len; i++) {
|
|
3135
|
+
const cc = glob.charCodeAt(i);
|
|
3136
|
+
const tokenStart = i;
|
|
3137
|
+
let mapped;
|
|
3138
|
+
|
|
3139
|
+
switch (cc) {
|
|
3140
|
+
case CC_SLASH:
|
|
3141
|
+
mapped = "\\/";
|
|
3142
|
+
break;
|
|
3143
|
+
case CC_DOLLAR:
|
|
3144
|
+
mapped = "\\$";
|
|
3145
|
+
break;
|
|
3146
|
+
case CC_CARET:
|
|
3147
|
+
mapped = "\\^";
|
|
3148
|
+
break;
|
|
3149
|
+
case CC_PLUS:
|
|
3150
|
+
mapped = "\\+";
|
|
3151
|
+
break;
|
|
3152
|
+
case CC_DOT:
|
|
3153
|
+
mapped = "\\.";
|
|
3154
|
+
break;
|
|
3155
|
+
case CC_LEFT_PARENTHESIS:
|
|
3156
|
+
mapped = "\\(";
|
|
3157
|
+
break;
|
|
3158
|
+
case CC_RIGHT_PARENTHESIS:
|
|
3159
|
+
mapped = "\\)";
|
|
3160
|
+
break;
|
|
3161
|
+
case CC_EQUAL:
|
|
3162
|
+
mapped = "\\=";
|
|
3163
|
+
break;
|
|
3164
|
+
case CC_EXCLAMATION:
|
|
3165
|
+
mapped = "\\!";
|
|
3166
|
+
break;
|
|
3167
|
+
case CC_PIPE:
|
|
3168
|
+
mapped = "\\|";
|
|
3169
|
+
break;
|
|
3170
|
+
case CC_QUESTION_MARK:
|
|
3171
|
+
mapped = ".";
|
|
3172
|
+
break;
|
|
3173
|
+
case CC_LEFT_BRACKET:
|
|
3174
|
+
mapped = "[";
|
|
3175
|
+
break;
|
|
3176
|
+
case CC_RIGHT_BRACKET:
|
|
3177
|
+
mapped = "]";
|
|
3178
|
+
break;
|
|
3179
|
+
case CC_LEFT_BRACE:
|
|
3180
|
+
inGroup = true;
|
|
3181
|
+
mapped = "(";
|
|
3182
|
+
break;
|
|
3183
|
+
case CC_RIGHT_BRACE:
|
|
3184
|
+
inGroup = false;
|
|
3185
|
+
mapped = ")";
|
|
3186
|
+
break;
|
|
3187
|
+
case CC_COMMA:
|
|
3188
|
+
mapped = inGroup ? "|" : "\\,";
|
|
3189
|
+
break;
|
|
3190
|
+
case CC_ASTERISK: {
|
|
3191
|
+
const atStart = i === 0;
|
|
3192
|
+
const afterSlash = !atStart && glob.charCodeAt(i - 1) === CC_SLASH;
|
|
3193
|
+
let starCount = 1;
|
|
3194
|
+
while (i + 1 < len && glob.charCodeAt(i + 1) === CC_ASTERISK) {
|
|
3195
|
+
starCount++;
|
|
3196
|
+
i++;
|
|
3197
|
+
}
|
|
3198
|
+
const atEnd = i + 1 === len;
|
|
3199
|
+
const beforeSlash = !atEnd && glob.charCodeAt(i + 1) === CC_SLASH;
|
|
3200
|
+
if (
|
|
3201
|
+
starCount > 1 &&
|
|
3202
|
+
(atStart || afterSlash) &&
|
|
3203
|
+
(atEnd || beforeSlash)
|
|
3204
|
+
) {
|
|
3205
|
+
// Globstar segment, matches zero or more path segments
|
|
3206
|
+
mapped = "((?:[^/]*(?:\\/|$))*)";
|
|
3207
|
+
i++; // Move over the "/"
|
|
3208
|
+
} else {
|
|
3209
|
+
// Not a globstar, matches one path segment
|
|
3210
|
+
mapped = "([^/]*)";
|
|
3211
|
+
}
|
|
3212
|
+
break;
|
|
3213
|
+
}
|
|
3214
|
+
default:
|
|
3215
|
+
// Literal character, extend the current run
|
|
3216
|
+
continue;
|
|
3217
|
+
}
|
|
3218
|
+
|
|
3219
|
+
if (literalStart < tokenStart) {
|
|
3220
|
+
reStr += glob.slice(literalStart, tokenStart);
|
|
3221
|
+
}
|
|
3222
|
+
reStr += mapped;
|
|
3223
|
+
literalStart = i + 1;
|
|
3224
|
+
}
|
|
3225
|
+
|
|
3226
|
+
if (literalStart < len) {
|
|
3227
|
+
reStr += literalStart === 0 ? glob : glob.slice(literalStart);
|
|
3228
|
+
}
|
|
3229
|
+
|
|
3230
|
+
return reStr;
|
|
3231
|
+
};
|
|
3232
|
+
|
|
3233
|
+
|
|
3234
|
+
/***/ }),
|
|
3235
|
+
|
|
3236
|
+
/***/ 92:
|
|
3006
3237
|
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
|
|
3007
3238
|
|
|
3008
3239
|
"use strict";
|
|
@@ -3015,7 +3246,7 @@ module.exports = (plan, limit) => {
|
|
|
3015
3246
|
const { EventEmitter } = __nccwpck_require__(434);
|
|
3016
3247
|
const fs = __nccwpck_require__(896);
|
|
3017
3248
|
const path = __nccwpck_require__(928);
|
|
3018
|
-
const reducePlan = __nccwpck_require__(
|
|
3249
|
+
const reducePlan = __nccwpck_require__(817);
|
|
3019
3250
|
|
|
3020
3251
|
/** @typedef {import("fs").FSWatcher} FSWatcher */
|
|
3021
3252
|
/** @typedef {import("./index").EventType} EventType */
|
|
@@ -3069,6 +3300,9 @@ function createEPERMError(filePath) {
|
|
|
3069
3300
|
* @returns {(type: "rename" | "change", filename: string) => void} handler of change event
|
|
3070
3301
|
*/
|
|
3071
3302
|
function createHandleChangeEvent(watcher, filePath, handleChangeEvent) {
|
|
3303
|
+
// path.basename(filePath) is invariant for the lifetime of the watcher,
|
|
3304
|
+
// so compute it once rather than on every dispatched event.
|
|
3305
|
+
const ownBasename = path.basename(filePath);
|
|
3072
3306
|
return (type, filename) => {
|
|
3073
3307
|
// TODO: After Node.js v22, fs.watch(dir) and deleting a dir will trigger the rename change event.
|
|
3074
3308
|
// Here we just ignore it and keep the same behavior as before v22
|
|
@@ -3076,7 +3310,7 @@ function createHandleChangeEvent(watcher, filePath, handleChangeEvent) {
|
|
|
3076
3310
|
if (
|
|
3077
3311
|
type === "rename" &&
|
|
3078
3312
|
path.isAbsolute(filename) &&
|
|
3079
|
-
path.basename(filename) ===
|
|
3313
|
+
path.basename(filename) === ownBasename
|
|
3080
3314
|
) {
|
|
3081
3315
|
if (!IS_OSX) {
|
|
3082
3316
|
// Before v22, windows will throw EPERM error
|
|
@@ -3437,16 +3671,21 @@ module.exports.watch = (filePath) => {
|
|
|
3437
3671
|
directWatcher.add(watcher);
|
|
3438
3672
|
return watcher;
|
|
3439
3673
|
}
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3674
|
+
// Only platforms with recursive fs.watch ever populate recursiveWatchers,
|
|
3675
|
+
// so skip the entire parent walk when the map is empty (always the case
|
|
3676
|
+
// on Linux and the common case before the watcher limit is reached).
|
|
3677
|
+
if (recursiveWatchers.size !== 0) {
|
|
3678
|
+
let current = filePath;
|
|
3679
|
+
for (;;) {
|
|
3680
|
+
const recursiveWatcher = recursiveWatchers.get(current);
|
|
3681
|
+
if (recursiveWatcher !== undefined) {
|
|
3682
|
+
recursiveWatcher.add(filePath, watcher);
|
|
3683
|
+
return watcher;
|
|
3684
|
+
}
|
|
3685
|
+
const parent = path.dirname(current);
|
|
3686
|
+
if (parent === current) break;
|
|
3687
|
+
current = parent;
|
|
3446
3688
|
}
|
|
3447
|
-
const parent = path.dirname(current);
|
|
3448
|
-
if (parent === current) break;
|
|
3449
|
-
current = parent;
|
|
3450
3689
|
}
|
|
3451
3690
|
// Queue up watcher for creation
|
|
3452
3691
|
pendingWatchers.set(watcher, filePath);
|
|
@@ -3565,7 +3804,7 @@ module.exports = require("util");
|
|
|
3565
3804
|
/******/ // startup
|
|
3566
3805
|
/******/ // Load entry module and return exports
|
|
3567
3806
|
/******/ // This entry module is referenced by other modules so it can't be inlined
|
|
3568
|
-
/******/ var __webpack_exports__ = __nccwpck_require__(
|
|
3807
|
+
/******/ var __webpack_exports__ = __nccwpck_require__(934);
|
|
3569
3808
|
/******/ module.exports = __webpack_exports__;
|
|
3570
3809
|
/******/
|
|
3571
3810
|
/******/ })()
|