webpack 5.58.2 → 5.61.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.
Potentially problematic release.
This version of webpack might be problematic. Click here for more details.
- package/hot/lazy-compilation-node.js +3 -1
- package/lib/Compilation.js +11 -14
- package/lib/Compiler.js +2 -2
- package/lib/DefinePlugin.js +1 -1
- package/lib/FileSystemInfo.js +50 -7
- package/lib/NormalModule.js +40 -14
- package/lib/RuntimeTemplate.js +1 -1
- package/lib/WebpackOptionsApply.js +12 -11
- package/lib/cache/AddManagedPathsPlugin.js +2 -2
- package/lib/cache/PackFileCacheStrategy.js +6 -3
- package/lib/config/defaults.js +65 -43
- package/lib/config/normalization.js +6 -1
- package/lib/hmr/LazyCompilationPlugin.js +9 -5
- package/lib/hmr/lazyCompilationBackend.js +42 -10
- package/lib/node/NodeTargetPlugin.js +2 -0
- package/lib/optimize/ConcatenatedModule.js +1 -1
- package/lib/optimize/SplitChunksPlugin.js +49 -1
- package/lib/schemes/HttpUriPlugin.js +108 -31
- package/lib/util/createHash.js +12 -0
- package/lib/util/fs.js +2 -0
- package/lib/util/hash/BatchedHash.js +3 -4
- package/lib/util/hash/md4.js +20 -0
- package/lib/util/hash/wasm-hash.js +163 -0
- package/lib/util/hash/xxhash64.js +5 -139
- package/lib/util/propertyAccess.js +2 -2
- package/package.json +1 -1
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +324 -55
- package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
- package/schemas/plugins/schemes/HttpUriPlugin.json +28 -0
- package/types.d.ts +135 -83
@@ -5,21 +5,46 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
/** @typedef {import("http").ServerOptions} HttpServerOptions */
|
9
|
+
/** @typedef {import("https").ServerOptions} HttpsServerOptions */
|
10
|
+
/** @typedef {import("../../declarations/WebpackOptions").LazyCompilationDefaultBackendOptions} LazyCompilationDefaultBackendOptions */
|
10
11
|
/** @typedef {import("../Compiler")} Compiler */
|
11
12
|
|
12
13
|
/**
|
14
|
+
* @callback BackendHandler
|
13
15
|
* @param {Compiler} compiler compiler
|
14
|
-
* @param {string} client client reference
|
15
16
|
* @param {function(Error?, any?): void} callback callback
|
16
17
|
* @returns {void}
|
17
18
|
*/
|
18
|
-
|
19
|
+
|
20
|
+
/**
|
21
|
+
* @param {Omit<LazyCompilationDefaultBackendOptions, "client"> & { client: NonNullable<LazyCompilationDefaultBackendOptions["client"]>}} options additional options for the backend
|
22
|
+
* @returns {BackendHandler} backend
|
23
|
+
*/
|
24
|
+
module.exports = options => (compiler, callback) => {
|
19
25
|
const logger = compiler.getInfrastructureLogger("LazyCompilationBackend");
|
20
26
|
const activeModules = new Map();
|
21
27
|
const prefix = "/lazy-compilation-using-";
|
22
28
|
|
29
|
+
const isHttps =
|
30
|
+
options.protocol === "https" ||
|
31
|
+
(typeof options.server === "object" &&
|
32
|
+
("key" in options.server || "pfx" in options.server));
|
33
|
+
|
34
|
+
const createServer =
|
35
|
+
typeof options.server === "function"
|
36
|
+
? options.server
|
37
|
+
: (() => {
|
38
|
+
const http = isHttps ? require("https") : require("http");
|
39
|
+
return http.createServer.bind(http, options.server);
|
40
|
+
})();
|
41
|
+
const listen =
|
42
|
+
typeof options.listen === "function"
|
43
|
+
? options.listen
|
44
|
+
: server => server.listen(options.listen);
|
45
|
+
|
46
|
+
const protocol = options.protocol || (isHttps ? "https" : "http");
|
47
|
+
|
23
48
|
const requestListener = (req, res) => {
|
24
49
|
const keys = req.url.slice(prefix.length).split("@");
|
25
50
|
req.socket.on("close", () => {
|
@@ -52,7 +77,10 @@ module.exports = (compiler, client, callback) => {
|
|
52
77
|
}
|
53
78
|
if (moduleActivated && compiler.watching) compiler.watching.invalidate();
|
54
79
|
};
|
55
|
-
|
80
|
+
|
81
|
+
const server = /** @type {import("net").Server} */ (createServer());
|
82
|
+
server.on("request", requestListener);
|
83
|
+
|
56
84
|
let isClosing = false;
|
57
85
|
/** @type {Set<import("net").Socket>} */
|
58
86
|
const sockets = new Set();
|
@@ -63,16 +91,19 @@ module.exports = (compiler, client, callback) => {
|
|
63
91
|
});
|
64
92
|
if (isClosing) socket.destroy();
|
65
93
|
});
|
66
|
-
server.
|
94
|
+
server.on("clientError", e => {
|
95
|
+
if (e.message !== "Server is disposing") logger.warn(e);
|
96
|
+
});
|
97
|
+
server.on("listening", err => {
|
67
98
|
if (err) return callback(err);
|
68
99
|
const addr = server.address();
|
69
100
|
if (typeof addr === "string") throw new Error("addr must not be a string");
|
70
101
|
const urlBase =
|
71
102
|
addr.address === "::" || addr.address === "0.0.0.0"
|
72
|
-
?
|
103
|
+
? `${protocol}://localhost:${addr.port}`
|
73
104
|
: addr.family === "IPv6"
|
74
|
-
?
|
75
|
-
:
|
105
|
+
? `${protocol}://[${addr.address}]:${addr.port}`
|
106
|
+
: `${protocol}://${addr.address}:${addr.port}`;
|
76
107
|
logger.log(
|
77
108
|
`Server-Sent-Events server for lazy compilation open at ${urlBase}.`
|
78
109
|
);
|
@@ -94,11 +125,12 @@ module.exports = (compiler, client, callback) => {
|
|
94
125
|
).replace(/%(2F|3A|24|26|2B|2C|3B|3D|3A)/g, decodeURIComponent)}`;
|
95
126
|
const active = activeModules.get(key) > 0;
|
96
127
|
return {
|
97
|
-
client: `${client}?${encodeURIComponent(urlBase + prefix)}`,
|
128
|
+
client: `${options.client}?${encodeURIComponent(urlBase + prefix)}`,
|
98
129
|
data: key,
|
99
130
|
active
|
100
131
|
};
|
101
132
|
}
|
102
133
|
});
|
103
134
|
});
|
135
|
+
listen(server);
|
104
136
|
};
|
@@ -59,6 +59,7 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning");
|
|
59
59
|
* @property {ChunkFilterFunction=} chunksFilter
|
60
60
|
* @property {boolean=} enforce
|
61
61
|
* @property {SplitChunksSizes} minSize
|
62
|
+
* @property {SplitChunksSizes} minSizeReduction
|
62
63
|
* @property {SplitChunksSizes} minRemainingSize
|
63
64
|
* @property {SplitChunksSizes} enforceSizeThreshold
|
64
65
|
* @property {SplitChunksSizes} maxAsyncSize
|
@@ -80,6 +81,7 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning");
|
|
80
81
|
* @property {GetName=} getName
|
81
82
|
* @property {ChunkFilterFunction=} chunksFilter
|
82
83
|
* @property {SplitChunksSizes} minSize
|
84
|
+
* @property {SplitChunksSizes} minSizeReduction
|
83
85
|
* @property {SplitChunksSizes} minRemainingSize
|
84
86
|
* @property {SplitChunksSizes} enforceSizeThreshold
|
85
87
|
* @property {SplitChunksSizes} maxAsyncSize
|
@@ -132,6 +134,7 @@ const MinMaxSizeWarning = require("./MinMaxSizeWarning");
|
|
132
134
|
* @property {ChunkFilterFunction} chunksFilter
|
133
135
|
* @property {string[]} defaultSizeTypes
|
134
136
|
* @property {SplitChunksSizes} minSize
|
137
|
+
* @property {SplitChunksSizes} minSizeReduction
|
135
138
|
* @property {SplitChunksSizes} minRemainingSize
|
136
139
|
* @property {SplitChunksSizes} enforceSizeThreshold
|
137
140
|
* @property {SplitChunksSizes} maxInitialSize
|
@@ -336,6 +339,21 @@ const checkMinSize = (sizes, minSize) => {
|
|
336
339
|
return true;
|
337
340
|
};
|
338
341
|
|
342
|
+
/**
|
343
|
+
* @param {SplitChunksSizes} sizes the sizes
|
344
|
+
* @param {SplitChunksSizes} minSizeReduction the min sizes
|
345
|
+
* @param {number} chunkCount number of chunks
|
346
|
+
* @returns {boolean} true if there are sizes and all existing sizes are at least `minSizeReduction`
|
347
|
+
*/
|
348
|
+
const checkMinSizeReduction = (sizes, minSizeReduction, chunkCount) => {
|
349
|
+
for (const key of Object.keys(minSizeReduction)) {
|
350
|
+
const size = sizes[key];
|
351
|
+
if (size === undefined || size === 0) continue;
|
352
|
+
if (size * chunkCount < minSizeReduction[key]) return false;
|
353
|
+
}
|
354
|
+
return true;
|
355
|
+
};
|
356
|
+
|
339
357
|
/**
|
340
358
|
* @param {SplitChunksSizes} sizes the sizes
|
341
359
|
* @param {SplitChunksSizes} minSize the min sizes
|
@@ -548,6 +566,10 @@ const checkModuleLayer = (test, module) => {
|
|
548
566
|
*/
|
549
567
|
const createCacheGroupSource = (options, key, defaultSizeTypes) => {
|
550
568
|
const minSize = normalizeSizes(options.minSize, defaultSizeTypes);
|
569
|
+
const minSizeReduction = normalizeSizes(
|
570
|
+
options.minSizeReduction,
|
571
|
+
defaultSizeTypes
|
572
|
+
);
|
551
573
|
const maxSize = normalizeSizes(options.maxSize, defaultSizeTypes);
|
552
574
|
return {
|
553
575
|
key,
|
@@ -556,6 +578,7 @@ const createCacheGroupSource = (options, key, defaultSizeTypes) => {
|
|
556
578
|
chunksFilter: normalizeChunksFilter(options.chunks),
|
557
579
|
enforce: options.enforce,
|
558
580
|
minSize,
|
581
|
+
minSizeReduction,
|
559
582
|
minRemainingSize: mergeSizes(
|
560
583
|
normalizeSizes(options.minRemainingSize, defaultSizeTypes),
|
561
584
|
minSize
|
@@ -594,6 +617,10 @@ module.exports = class SplitChunksPlugin {
|
|
594
617
|
];
|
595
618
|
const fallbackCacheGroup = options.fallbackCacheGroup || {};
|
596
619
|
const minSize = normalizeSizes(options.minSize, defaultSizeTypes);
|
620
|
+
const minSizeReduction = normalizeSizes(
|
621
|
+
options.minSizeReduction,
|
622
|
+
defaultSizeTypes
|
623
|
+
);
|
597
624
|
const maxSize = normalizeSizes(options.maxSize, defaultSizeTypes);
|
598
625
|
|
599
626
|
/** @type {SplitChunksOptions} */
|
@@ -601,6 +628,7 @@ module.exports = class SplitChunksPlugin {
|
|
601
628
|
chunksFilter: normalizeChunksFilter(options.chunks || "all"),
|
602
629
|
defaultSizeTypes,
|
603
630
|
minSize,
|
631
|
+
minSizeReduction,
|
604
632
|
minRemainingSize: mergeSizes(
|
605
633
|
normalizeSizes(options.minRemainingSize, defaultSizeTypes),
|
606
634
|
minSize
|
@@ -668,6 +696,10 @@ module.exports = class SplitChunksPlugin {
|
|
668
696
|
cacheGroupSource.minSize,
|
669
697
|
cacheGroupSource.enforce ? undefined : this.options.minSize
|
670
698
|
);
|
699
|
+
const minSizeReduction = mergeSizes(
|
700
|
+
cacheGroupSource.minSizeReduction,
|
701
|
+
cacheGroupSource.enforce ? undefined : this.options.minSizeReduction
|
702
|
+
);
|
671
703
|
const minRemainingSize = mergeSizes(
|
672
704
|
cacheGroupSource.minRemainingSize,
|
673
705
|
cacheGroupSource.enforce ? undefined : this.options.minRemainingSize
|
@@ -681,6 +713,7 @@ module.exports = class SplitChunksPlugin {
|
|
681
713
|
priority: cacheGroupSource.priority || 0,
|
682
714
|
chunksFilter: cacheGroupSource.chunksFilter || this.options.chunksFilter,
|
683
715
|
minSize,
|
716
|
+
minSizeReduction,
|
684
717
|
minRemainingSize,
|
685
718
|
enforceSizeThreshold,
|
686
719
|
maxAsyncSize: mergeSizes(
|
@@ -1244,6 +1277,14 @@ module.exports = class SplitChunksPlugin {
|
|
1244
1277
|
for (const [key, info] of chunksInfoMap) {
|
1245
1278
|
if (removeMinSizeViolatingModules(info)) {
|
1246
1279
|
chunksInfoMap.delete(key);
|
1280
|
+
} else if (
|
1281
|
+
!checkMinSizeReduction(
|
1282
|
+
info.sizes,
|
1283
|
+
info.cacheGroup.minSizeReduction,
|
1284
|
+
info.chunks.size
|
1285
|
+
)
|
1286
|
+
) {
|
1287
|
+
chunksInfoMap.delete(key);
|
1247
1288
|
}
|
1248
1289
|
}
|
1249
1290
|
|
@@ -1531,7 +1572,14 @@ module.exports = class SplitChunksPlugin {
|
|
1531
1572
|
chunksInfoMap.delete(key);
|
1532
1573
|
continue;
|
1533
1574
|
}
|
1534
|
-
if (
|
1575
|
+
if (
|
1576
|
+
removeMinSizeViolatingModules(info) ||
|
1577
|
+
!checkMinSizeReduction(
|
1578
|
+
info.sizes,
|
1579
|
+
info.cacheGroup.minSizeReduction,
|
1580
|
+
info.chunks.size
|
1581
|
+
)
|
1582
|
+
) {
|
1535
1583
|
chunksInfoMap.delete(key);
|
1536
1584
|
continue;
|
1537
1585
|
}
|
@@ -5,12 +5,13 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
-
const {
|
8
|
+
const { extname, basename } = require("path");
|
9
9
|
const { URL } = require("url");
|
10
10
|
const { createGunzip, createBrotliDecompress, createInflate } = require("zlib");
|
11
11
|
const NormalModule = require("../NormalModule");
|
12
|
+
const createSchemaValidation = require("../util/create-schema-validation");
|
12
13
|
const createHash = require("../util/createHash");
|
13
|
-
const { mkdirp } = require("../util/fs");
|
14
|
+
const { mkdirp, dirname, join } = require("../util/fs");
|
14
15
|
const memoize = require("../util/memoize");
|
15
16
|
|
16
17
|
/** @typedef {import("../../declarations/plugins/schemes/HttpUriPlugin").HttpUriPluginOptions} HttpUriPluginOptions */
|
@@ -19,6 +20,18 @@ const memoize = require("../util/memoize");
|
|
19
20
|
const getHttp = memoize(() => require("http"));
|
20
21
|
const getHttps = memoize(() => require("https"));
|
21
22
|
|
23
|
+
/** @type {(() => void)[] | undefined} */
|
24
|
+
let inProgressWrite = undefined;
|
25
|
+
|
26
|
+
const validate = createSchemaValidation(
|
27
|
+
require("../../schemas/plugins/schemes/HttpUriPlugin.check.js"),
|
28
|
+
() => require("../../schemas/plugins/schemes/HttpUriPlugin.json"),
|
29
|
+
{
|
30
|
+
name: "Http Uri Plugin",
|
31
|
+
baseDataPath: "options"
|
32
|
+
}
|
33
|
+
);
|
34
|
+
|
22
35
|
const toSafePath = str =>
|
23
36
|
str
|
24
37
|
.replace(/^[^a-zA-Z0-9]+|[^a-zA-Z0-9]+$/g, "")
|
@@ -104,7 +117,6 @@ class Lockfile {
|
|
104
117
|
this.version = 1;
|
105
118
|
/** @type {Map<string, LockfileEntry | "ignore" | "no-cache">} */
|
106
119
|
this.entries = new Map();
|
107
|
-
this.outdated = false;
|
108
120
|
}
|
109
121
|
|
110
122
|
static parse(content) {
|
@@ -251,25 +263,17 @@ const cachedWithKey = (fn, forceFn = fn) => {
|
|
251
263
|
return resultFn;
|
252
264
|
};
|
253
265
|
|
254
|
-
/**
|
255
|
-
* @typedef {Object} HttpUriPluginAdvancedOptions
|
256
|
-
* @property {string | typeof import("../util/Hash")=} hashFunction
|
257
|
-
* @property {string=} hashDigest
|
258
|
-
* @property {number=} hashDigestLength
|
259
|
-
*/
|
260
|
-
|
261
266
|
class HttpUriPlugin {
|
262
267
|
/**
|
263
|
-
* @param {HttpUriPluginOptions
|
268
|
+
* @param {HttpUriPluginOptions} options options
|
264
269
|
*/
|
265
|
-
constructor(options
|
270
|
+
constructor(options) {
|
271
|
+
validate(options);
|
266
272
|
this._lockfileLocation = options.lockfileLocation;
|
267
273
|
this._cacheLocation = options.cacheLocation;
|
268
274
|
this._upgrade = options.upgrade;
|
269
275
|
this._frozen = options.frozen;
|
270
|
-
this.
|
271
|
-
this._hashDigest = options.hashDigest;
|
272
|
-
this._hashDigestLength = options.hashDigestLength;
|
276
|
+
this._allowedUris = options.allowedUris;
|
273
277
|
}
|
274
278
|
|
275
279
|
/**
|
@@ -299,7 +303,8 @@ class HttpUriPlugin {
|
|
299
303
|
const logger = compilation.getLogger("webpack.HttpUriPlugin");
|
300
304
|
const lockfileLocation =
|
301
305
|
this._lockfileLocation ||
|
302
|
-
|
306
|
+
join(
|
307
|
+
intermediateFs,
|
303
308
|
compiler.context,
|
304
309
|
compiler.name
|
305
310
|
? `${toSafePath(compiler.name)}.webpack.lock`
|
@@ -311,11 +316,10 @@ class HttpUriPlugin {
|
|
311
316
|
: lockfileLocation + ".data";
|
312
317
|
const upgrade = this._upgrade || false;
|
313
318
|
const frozen = this._frozen || false;
|
314
|
-
const hashFunction =
|
315
|
-
const hashDigest =
|
316
|
-
|
317
|
-
const
|
318
|
-
this._hashDigestLength || compilation.outputOptions.hashDigestLength;
|
319
|
+
const hashFunction = "sha512";
|
320
|
+
const hashDigest = "hex";
|
321
|
+
const hashDigestLength = 20;
|
322
|
+
const allowedUris = this._allowedUris;
|
319
323
|
|
320
324
|
let warnedAboutEol = false;
|
321
325
|
|
@@ -400,11 +404,13 @@ class HttpUriPlugin {
|
|
400
404
|
}
|
401
405
|
);
|
402
406
|
|
403
|
-
|
407
|
+
/** @type {Map<string, LockfileEntry | "ignore" | "no-cache"> | undefined} */
|
408
|
+
let lockfileUpdates = undefined;
|
404
409
|
const storeLockEntry = (lockfile, url, entry) => {
|
405
410
|
const oldEntry = lockfile.entries.get(url);
|
411
|
+
if (lockfileUpdates === undefined) lockfileUpdates = new Map();
|
412
|
+
lockfileUpdates.set(url, entry);
|
406
413
|
lockfile.entries.set(url, entry);
|
407
|
-
outdatedLockfile = lockfile;
|
408
414
|
if (!oldEntry) {
|
409
415
|
logger.log(`${url} added to lockfile`);
|
410
416
|
} else if (typeof oldEntry === "string") {
|
@@ -440,8 +446,8 @@ class HttpUriPlugin {
|
|
440
446
|
if (!cacheLocation || !result.content)
|
441
447
|
return callback(null, result);
|
442
448
|
const key = getCacheKey(result.entry.resolved);
|
443
|
-
const filePath =
|
444
|
-
mkdirp(intermediateFs, dirname(filePath), err => {
|
449
|
+
const filePath = join(intermediateFs, cacheLocation, key);
|
450
|
+
mkdirp(intermediateFs, dirname(intermediateFs, filePath), err => {
|
445
451
|
if (err) return callback(err);
|
446
452
|
intermediateFs.writeFile(filePath, result.content, err => {
|
447
453
|
if (err) return callback(err);
|
@@ -671,6 +677,19 @@ class HttpUriPlugin {
|
|
671
677
|
(url, callback) => fetchContentRaw(url, undefined, callback)
|
672
678
|
);
|
673
679
|
|
680
|
+
const isAllowed = uri => {
|
681
|
+
for (const allowed of allowedUris) {
|
682
|
+
if (typeof allowed === "string") {
|
683
|
+
if (uri.startsWith(allowed)) return true;
|
684
|
+
} else if (typeof allowed === "function") {
|
685
|
+
if (allowed(uri)) return true;
|
686
|
+
} else {
|
687
|
+
if (allowed.test(uri)) return true;
|
688
|
+
}
|
689
|
+
}
|
690
|
+
return false;
|
691
|
+
};
|
692
|
+
|
674
693
|
const getInfo = cachedWithKey(
|
675
694
|
/**
|
676
695
|
* @param {string} url the url
|
@@ -678,6 +697,15 @@ class HttpUriPlugin {
|
|
678
697
|
* @returns {void}
|
679
698
|
*/
|
680
699
|
(url, callback) => {
|
700
|
+
if (!isAllowed(url)) {
|
701
|
+
return callback(
|
702
|
+
new Error(
|
703
|
+
`${url} doesn't match the allowedUris policy. These URIs are allowed:\n${allowedUris
|
704
|
+
.map(uri => ` - ${uri}`)
|
705
|
+
.join("\n")}`
|
706
|
+
)
|
707
|
+
);
|
708
|
+
}
|
681
709
|
getLockfile((err, lockfile) => {
|
682
710
|
if (err) return callback(err);
|
683
711
|
const entryOrString = lockfile.entries.get(url);
|
@@ -789,7 +817,7 @@ Remove this line from the lockfile to force upgrading.`
|
|
789
817
|
// When there is a lockfile cache
|
790
818
|
// we read the content from there
|
791
819
|
const key = getCacheKey(entry.resolved);
|
792
|
-
const filePath =
|
820
|
+
const filePath = join(intermediateFs, cacheLocation, key);
|
793
821
|
fs.readFile(filePath, (err, result) => {
|
794
822
|
const content = /** @type {Buffer} */ (result);
|
795
823
|
if (err) {
|
@@ -934,6 +962,7 @@ Run build with un-frozen lockfile to automatically fix lockfile.`
|
|
934
962
|
.tapAsync("HttpUriPlugin", (resource, module, callback) => {
|
935
963
|
return getInfo(resource, (err, result) => {
|
936
964
|
if (err) return callback(err);
|
965
|
+
module.buildInfo.resourceIntegrity = result.entry.integrity;
|
937
966
|
callback(null, result.content);
|
938
967
|
});
|
939
968
|
});
|
@@ -963,12 +992,60 @@ Run build with un-frozen lockfile to automatically fix lockfile.`
|
|
963
992
|
compilation.hooks.finishModules.tapAsync(
|
964
993
|
"HttpUriPlugin",
|
965
994
|
(modules, callback) => {
|
966
|
-
if (!
|
967
|
-
|
968
|
-
|
969
|
-
|
970
|
-
|
995
|
+
if (!lockfileUpdates) return callback();
|
996
|
+
const ext = extname(lockfileLocation);
|
997
|
+
const tempFile = join(
|
998
|
+
intermediateFs,
|
999
|
+
dirname(intermediateFs, lockfileLocation),
|
1000
|
+
`.${basename(lockfileLocation, ext)}.${
|
1001
|
+
(Math.random() * 10000) | 0
|
1002
|
+
}${ext}`
|
971
1003
|
);
|
1004
|
+
|
1005
|
+
const writeDone = () => {
|
1006
|
+
const nextOperation = inProgressWrite.shift();
|
1007
|
+
if (nextOperation) {
|
1008
|
+
nextOperation();
|
1009
|
+
} else {
|
1010
|
+
inProgressWrite = undefined;
|
1011
|
+
}
|
1012
|
+
};
|
1013
|
+
const runWrite = () => {
|
1014
|
+
intermediateFs.readFile(lockfileLocation, (err, buffer) => {
|
1015
|
+
if (err && err.code !== "ENOENT") {
|
1016
|
+
writeDone();
|
1017
|
+
return callback(err);
|
1018
|
+
}
|
1019
|
+
const lockfile = buffer
|
1020
|
+
? Lockfile.parse(buffer.toString("utf-8"))
|
1021
|
+
: new Lockfile();
|
1022
|
+
for (const [key, value] of lockfileUpdates) {
|
1023
|
+
lockfile.entries.set(key, value);
|
1024
|
+
}
|
1025
|
+
intermediateFs.writeFile(tempFile, lockfile.toString(), err => {
|
1026
|
+
if (err) {
|
1027
|
+
writeDone();
|
1028
|
+
return intermediateFs.unlink(tempFile, () => callback(err));
|
1029
|
+
}
|
1030
|
+
intermediateFs.rename(tempFile, lockfileLocation, err => {
|
1031
|
+
if (err) {
|
1032
|
+
writeDone();
|
1033
|
+
return intermediateFs.unlink(tempFile, () =>
|
1034
|
+
callback(err)
|
1035
|
+
);
|
1036
|
+
}
|
1037
|
+
writeDone();
|
1038
|
+
callback();
|
1039
|
+
});
|
1040
|
+
});
|
1041
|
+
});
|
1042
|
+
};
|
1043
|
+
if (inProgressWrite) {
|
1044
|
+
inProgressWrite.push(runWrite);
|
1045
|
+
} else {
|
1046
|
+
inProgressWrite = [];
|
1047
|
+
runWrite();
|
1048
|
+
}
|
972
1049
|
}
|
973
1050
|
);
|
974
1051
|
}
|
package/lib/util/createHash.js
CHANGED
@@ -126,6 +126,7 @@ class DebugHash extends Hash {
|
|
126
126
|
|
127
127
|
let crypto = undefined;
|
128
128
|
let createXXHash64 = undefined;
|
129
|
+
let createMd4 = undefined;
|
129
130
|
let BatchedHash = undefined;
|
130
131
|
|
131
132
|
/**
|
@@ -149,6 +150,17 @@ module.exports = algorithm => {
|
|
149
150
|
}
|
150
151
|
}
|
151
152
|
return new BatchedHash(createXXHash64());
|
153
|
+
case "md4":
|
154
|
+
if (createMd4 === undefined) {
|
155
|
+
createMd4 = require("./hash/md4");
|
156
|
+
if (BatchedHash === undefined) {
|
157
|
+
BatchedHash = require("./hash/BatchedHash");
|
158
|
+
}
|
159
|
+
}
|
160
|
+
return new BatchedHash(createMd4());
|
161
|
+
case "native-md4":
|
162
|
+
if (crypto === undefined) crypto = require("crypto");
|
163
|
+
return new BulkUpdateDecorator(() => crypto.createHash("md4"), "md4");
|
152
164
|
default:
|
153
165
|
if (crypto === undefined) crypto = require("crypto");
|
154
166
|
return new BulkUpdateDecorator(
|
package/lib/util/fs.js
CHANGED
@@ -6,8 +6,7 @@
|
|
6
6
|
"use strict";
|
7
7
|
|
8
8
|
const Hash = require("../Hash");
|
9
|
-
|
10
|
-
const MAX_STRING_LENGTH = 21845;
|
9
|
+
const MAX_SHORT_STRING = require("./wasm-hash").MAX_SHORT_STRING;
|
11
10
|
|
12
11
|
class BatchedHash extends Hash {
|
13
12
|
constructor(hash) {
|
@@ -28,7 +27,7 @@ class BatchedHash extends Hash {
|
|
28
27
|
if (
|
29
28
|
typeof data === "string" &&
|
30
29
|
inputEncoding === this.encoding &&
|
31
|
-
this.string.length + data.length <
|
30
|
+
this.string.length + data.length < MAX_SHORT_STRING
|
32
31
|
) {
|
33
32
|
this.string += data;
|
34
33
|
return this;
|
@@ -37,7 +36,7 @@ class BatchedHash extends Hash {
|
|
37
36
|
this.string = undefined;
|
38
37
|
}
|
39
38
|
if (typeof data === "string") {
|
40
|
-
if (data.length <
|
39
|
+
if (data.length < MAX_SHORT_STRING) {
|
41
40
|
this.string = data;
|
42
41
|
this.encoding = inputEncoding;
|
43
42
|
} else {
|
@@ -0,0 +1,20 @@
|
|
1
|
+
/*
|
2
|
+
MIT License http://www.opensource.org/licenses/mit-license.php
|
3
|
+
Author Tobias Koppers @sokra
|
4
|
+
*/
|
5
|
+
|
6
|
+
"use strict";
|
7
|
+
|
8
|
+
const create = require("./wasm-hash");
|
9
|
+
|
10
|
+
//#region wasm code: md4 (../../../assembly/hash/md4.asm.ts) --initialMemory 1
|
11
|
+
const md4 = new WebAssembly.Module(
|
12
|
+
Buffer.from(
|
13
|
+
// 2150 bytes
|
14
|
+
"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",
|
15
|
+
"base64"
|
16
|
+
)
|
17
|
+
);
|
18
|
+
//#endregion
|
19
|
+
|
20
|
+
module.exports = create.bind(null, md4, [], 64, 32);
|