webpack 5.53.0 → 5.56.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/lib/AsyncDependenciesBlock.js +9 -2
- package/lib/CacheFacade.js +10 -3
- package/lib/ChunkGraph.js +19 -8
- package/lib/CodeGenerationResults.js +7 -2
- package/lib/Compilation.js +586 -143
- package/lib/Compiler.js +13 -4
- package/lib/DefinePlugin.js +13 -8
- package/lib/Dependency.js +11 -0
- package/lib/DependencyTemplates.js +8 -2
- package/lib/EvalDevToolModulePlugin.js +2 -1
- package/lib/EvalSourceMapDevToolPlugin.js +2 -1
- package/lib/ExternalModule.js +18 -9
- package/lib/FileSystemInfo.js +101 -170
- package/lib/FlagDependencyExportsPlugin.js +25 -16
- package/lib/JavascriptMetaInfoPlugin.js +6 -1
- package/lib/ModuleFactory.js +1 -0
- package/lib/ModuleFilenameHelpers.js +21 -7
- package/lib/ModuleGraph.js +90 -21
- package/lib/NormalModuleFactory.js +8 -43
- package/lib/SourceMapDevToolPlugin.js +7 -3
- package/lib/WebpackOptionsApply.js +19 -1
- package/lib/cache/PackFileCacheStrategy.js +2 -1
- package/lib/cache/getLazyHashedEtag.js +35 -8
- package/lib/config/defaults.js +18 -7
- package/lib/dependencies/CachedConstDependency.js +4 -3
- package/lib/dependencies/CommonJsExportRequireDependency.js +19 -9
- package/lib/dependencies/CommonJsFullRequireDependency.js +11 -9
- package/lib/dependencies/ConstDependency.js +12 -4
- package/lib/dependencies/ContextDependency.js +8 -0
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +179 -163
- package/lib/dependencies/HarmonyImportDependency.js +4 -1
- package/lib/dependencies/JsonExportsDependency.js +7 -1
- package/lib/dependencies/ModuleDecoratorDependency.js +5 -2
- package/lib/dependencies/ModuleDependency.js +8 -0
- package/lib/dependencies/NullDependency.js +8 -4
- package/lib/dependencies/ProvidedDependency.js +6 -2
- package/lib/dependencies/PureExpressionDependency.js +5 -1
- package/lib/dependencies/RuntimeRequirementsDependency.js +5 -1
- package/lib/dependencies/WebAssemblyExportImportedDependency.js +9 -0
- package/lib/ids/IdHelpers.js +21 -8
- package/lib/ids/NamedChunkIdsPlugin.js +3 -0
- package/lib/ids/NamedModuleIdsPlugin.js +3 -1
- package/lib/index.js +6 -0
- package/lib/javascript/BasicEvaluatedExpression.js +3 -0
- package/lib/javascript/JavascriptParser.js +22 -4
- package/lib/javascript/JavascriptParserHelpers.js +0 -2
- package/lib/optimize/ConcatenatedModule.js +25 -4
- package/lib/optimize/InnerGraph.js +22 -2
- package/lib/optimize/ModuleConcatenationPlugin.js +2 -1
- package/lib/schemes/HttpUriPlugin.js +1 -2
- package/lib/serialization/BinaryMiddleware.js +11 -2
- package/lib/serialization/FileMiddleware.js +24 -7
- package/lib/serialization/ObjectMiddleware.js +19 -8
- package/lib/util/WeakTupleMap.js +95 -92
- package/lib/util/createHash.js +10 -0
- package/lib/util/hash/BatchedHash.js +65 -0
- package/lib/util/hash/xxhash64.js +154 -0
- package/lib/util/serialization.js +4 -4
- package/package.json +10 -6
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +12 -0
- package/schemas/plugins/HashedModuleIdsPlugin.check.js +1 -1
- package/schemas/plugins/HashedModuleIdsPlugin.json +20 -2
- package/types.d.ts +205 -20
@@ -5,10 +5,12 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
+
const Dependency = require("../Dependency");
|
8
9
|
const makeSerializable = require("../util/makeSerializable");
|
9
10
|
const ModuleDependency = require("./ModuleDependency");
|
10
11
|
|
11
12
|
/** @typedef {import("../Dependency").ReferencedExport} ReferencedExport */
|
13
|
+
/** @typedef {import("../Dependency").TRANSITIVE} TRANSITIVE */
|
12
14
|
/** @typedef {import("../ModuleGraph")} ModuleGraph */
|
13
15
|
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
|
14
16
|
|
@@ -23,6 +25,13 @@ class WebAssemblyExportImportedDependency extends ModuleDependency {
|
|
23
25
|
this.valueType = valueType;
|
24
26
|
}
|
25
27
|
|
28
|
+
/**
|
29
|
+
* @returns {boolean | TRANSITIVE} true, when changes to the referenced module could affect the referencing module; TRANSITIVE, when changes to the referenced module could affect referencing modules of the referencing module
|
30
|
+
*/
|
31
|
+
couldAffectReferencingModule() {
|
32
|
+
return Dependency.TRANSITIVE;
|
33
|
+
}
|
34
|
+
|
26
35
|
/**
|
27
36
|
* Returns list of exports referenced by this dependency
|
28
37
|
* @param {ModuleGraph} moduleGraph module graph
|
package/lib/ids/IdHelpers.js
CHANGED
@@ -13,14 +13,16 @@ const numberHash = require("../util/numberHash");
|
|
13
13
|
/** @typedef {import("../ChunkGraph")} ChunkGraph */
|
14
14
|
/** @typedef {import("../Compilation")} Compilation */
|
15
15
|
/** @typedef {import("../Module")} Module */
|
16
|
+
/** @typedef {typeof import("../util/Hash")} Hash */
|
16
17
|
|
17
18
|
/**
|
18
19
|
* @param {string} str string to hash
|
19
20
|
* @param {number} len max length of the hash
|
21
|
+
* @param {string | Hash} hashFunction hash function to use
|
20
22
|
* @returns {string} hash
|
21
23
|
*/
|
22
|
-
const getHash = (str, len) => {
|
23
|
-
const hash = createHash(
|
24
|
+
const getHash = (str, len, hashFunction) => {
|
25
|
+
const hash = createHash(hashFunction);
|
24
26
|
hash.update(str);
|
25
27
|
const digest = /** @type {string} */ (hash.digest("hex"));
|
26
28
|
return digest.substr(0, len);
|
@@ -61,12 +63,15 @@ exports.requestToId = requestToId;
|
|
61
63
|
/**
|
62
64
|
* @param {string} string the string
|
63
65
|
* @param {string} delimiter separator for string and hash
|
66
|
+
* @param {string | Hash} hashFunction hash function to use
|
64
67
|
* @returns {string} string with limited max length to 100 chars
|
65
68
|
*/
|
66
|
-
const shortenLongString = (string, delimiter) => {
|
69
|
+
const shortenLongString = (string, delimiter, hashFunction) => {
|
67
70
|
if (string.length < 100) return string;
|
68
71
|
return (
|
69
|
-
string.slice(0, 100 - 6 - delimiter.length) +
|
72
|
+
string.slice(0, 100 - 6 - delimiter.length) +
|
73
|
+
delimiter +
|
74
|
+
getHash(string, 6, hashFunction)
|
70
75
|
);
|
71
76
|
};
|
72
77
|
|
@@ -92,6 +97,7 @@ exports.getShortModuleName = getShortModuleName;
|
|
92
97
|
* @param {string} shortName the short name
|
93
98
|
* @param {Module} module the module
|
94
99
|
* @param {string} context context directory
|
100
|
+
* @param {string | Hash} hashFunction hash function to use
|
95
101
|
* @param {Object=} associatedObjectForCache an object to which the cache will be attached
|
96
102
|
* @returns {string} long module name
|
97
103
|
*/
|
@@ -99,10 +105,11 @@ const getLongModuleName = (
|
|
99
105
|
shortName,
|
100
106
|
module,
|
101
107
|
context,
|
108
|
+
hashFunction,
|
102
109
|
associatedObjectForCache
|
103
110
|
) => {
|
104
111
|
const fullName = getFullModuleName(module, context, associatedObjectForCache);
|
105
|
-
return `${shortName}?${getHash(fullName, 4)}`;
|
112
|
+
return `${shortName}?${getHash(fullName, 4, hashFunction)}`;
|
106
113
|
};
|
107
114
|
exports.getLongModuleName = getLongModuleName;
|
108
115
|
|
@@ -126,6 +133,7 @@ exports.getFullModuleName = getFullModuleName;
|
|
126
133
|
* @param {ChunkGraph} chunkGraph the chunk graph
|
127
134
|
* @param {string} context context directory
|
128
135
|
* @param {string} delimiter delimiter for names
|
136
|
+
* @param {string | Hash} hashFunction hash function to use
|
129
137
|
* @param {Object=} associatedObjectForCache an object to which the cache will be attached
|
130
138
|
* @returns {string} short chunk name
|
131
139
|
*/
|
@@ -134,6 +142,7 @@ const getShortChunkName = (
|
|
134
142
|
chunkGraph,
|
135
143
|
context,
|
136
144
|
delimiter,
|
145
|
+
hashFunction,
|
137
146
|
associatedObjectForCache
|
138
147
|
) => {
|
139
148
|
const modules = chunkGraph.getChunkRootModules(chunk);
|
@@ -145,7 +154,7 @@ const getShortChunkName = (
|
|
145
154
|
.concat(shortModuleNames)
|
146
155
|
.filter(Boolean)
|
147
156
|
.join(delimiter);
|
148
|
-
return shortenLongString(chunkName, delimiter);
|
157
|
+
return shortenLongString(chunkName, delimiter, hashFunction);
|
149
158
|
};
|
150
159
|
exports.getShortChunkName = getShortChunkName;
|
151
160
|
|
@@ -154,6 +163,7 @@ exports.getShortChunkName = getShortChunkName;
|
|
154
163
|
* @param {ChunkGraph} chunkGraph the chunk graph
|
155
164
|
* @param {string} context context directory
|
156
165
|
* @param {string} delimiter delimiter for names
|
166
|
+
* @param {string | Hash} hashFunction hash function to use
|
157
167
|
* @param {Object=} associatedObjectForCache an object to which the cache will be attached
|
158
168
|
* @returns {string} short chunk name
|
159
169
|
*/
|
@@ -162,6 +172,7 @@ const getLongChunkName = (
|
|
162
172
|
chunkGraph,
|
163
173
|
context,
|
164
174
|
delimiter,
|
175
|
+
hashFunction,
|
165
176
|
associatedObjectForCache
|
166
177
|
) => {
|
167
178
|
const modules = chunkGraph.getChunkRootModules(chunk);
|
@@ -169,14 +180,16 @@ const getLongChunkName = (
|
|
169
180
|
requestToId(getShortModuleName(m, context, associatedObjectForCache))
|
170
181
|
);
|
171
182
|
const longModuleNames = modules.map(m =>
|
172
|
-
requestToId(
|
183
|
+
requestToId(
|
184
|
+
getLongModuleName("", m, context, hashFunction, associatedObjectForCache)
|
185
|
+
)
|
173
186
|
);
|
174
187
|
chunk.idNameHints.sort();
|
175
188
|
const chunkName = Array.from(chunk.idNameHints)
|
176
189
|
.concat(shortModuleNames, longModuleNames)
|
177
190
|
.filter(Boolean)
|
178
191
|
.join(delimiter);
|
179
|
-
return shortenLongString(chunkName, delimiter);
|
192
|
+
return shortenLongString(chunkName, delimiter, hashFunction);
|
180
193
|
};
|
181
194
|
exports.getLongChunkName = getLongChunkName;
|
182
195
|
|
@@ -31,6 +31,7 @@ class NamedChunkIdsPlugin {
|
|
31
31
|
*/
|
32
32
|
apply(compiler) {
|
33
33
|
compiler.hooks.compilation.tap("NamedChunkIdsPlugin", compilation => {
|
34
|
+
const { hashFunction } = compilation.outputOptions;
|
34
35
|
compilation.hooks.chunkIds.tap("NamedChunkIdsPlugin", chunks => {
|
35
36
|
const chunkGraph = compilation.chunkGraph;
|
36
37
|
const context = this.context ? this.context : compiler.context;
|
@@ -50,6 +51,7 @@ class NamedChunkIdsPlugin {
|
|
50
51
|
chunkGraph,
|
51
52
|
context,
|
52
53
|
delimiter,
|
54
|
+
hashFunction,
|
53
55
|
compiler.root
|
54
56
|
),
|
55
57
|
chunk =>
|
@@ -58,6 +60,7 @@ class NamedChunkIdsPlugin {
|
|
58
60
|
chunkGraph,
|
59
61
|
context,
|
60
62
|
delimiter,
|
63
|
+
hashFunction,
|
61
64
|
compiler.root
|
62
65
|
),
|
63
66
|
compareChunksNatural(chunkGraph),
|
@@ -30,6 +30,7 @@ class NamedModuleIdsPlugin {
|
|
30
30
|
apply(compiler) {
|
31
31
|
const { root } = compiler;
|
32
32
|
compiler.hooks.compilation.tap("NamedModuleIdsPlugin", compilation => {
|
33
|
+
const { hashFunction } = compilation.outputOptions;
|
33
34
|
compilation.hooks.moduleIds.tap("NamedModuleIdsPlugin", modules => {
|
34
35
|
const chunkGraph = compilation.chunkGraph;
|
35
36
|
const context = this.options.context
|
@@ -43,7 +44,8 @@ class NamedModuleIdsPlugin {
|
|
43
44
|
return chunkGraph.getModuleId(module) === null;
|
44
45
|
}),
|
45
46
|
m => getShortModuleName(m, context, root),
|
46
|
-
(m, shortName) =>
|
47
|
+
(m, shortName) =>
|
48
|
+
getLongModuleName(shortName, m, context, hashFunction, root),
|
47
49
|
compareModulesByIdentifier,
|
48
50
|
getUsedModuleIds(compilation),
|
49
51
|
(m, name) => chunkGraph.setModuleId(m, name)
|
package/lib/index.js
CHANGED
@@ -394,6 +394,9 @@ module.exports = mergeExports(fn, {
|
|
394
394
|
"DEP_WEBPACK_AGGRESSIVE_SPLITTING_PLUGIN"
|
395
395
|
)();
|
396
396
|
},
|
397
|
+
get InnerGraph() {
|
398
|
+
return require("./optimize/InnerGraph");
|
399
|
+
},
|
397
400
|
get LimitChunkCountPlugin() {
|
398
401
|
return require("./optimize/LimitChunkCountPlugin");
|
399
402
|
},
|
@@ -535,6 +538,9 @@ module.exports = mergeExports(fn, {
|
|
535
538
|
get comparators() {
|
536
539
|
return require("./util/comparators");
|
537
540
|
},
|
541
|
+
get runtime() {
|
542
|
+
return require("./util/runtime");
|
543
|
+
},
|
538
544
|
get serialization() {
|
539
545
|
return require("./util/serialization");
|
540
546
|
},
|
@@ -417,23 +417,41 @@ class JavascriptParser extends Parser {
|
|
417
417
|
|
418
418
|
const left = this.evaluateExpression(expr.left);
|
419
419
|
if (!left) return;
|
420
|
+
let returnRight = false;
|
421
|
+
/** @type {boolean|undefined} */
|
422
|
+
let allowedRight;
|
420
423
|
if (expr.operator === "&&") {
|
421
424
|
const leftAsBool = left.asBool();
|
422
425
|
if (leftAsBool === false) return left.setRange(expr.range);
|
423
|
-
|
426
|
+
returnRight = leftAsBool === true;
|
427
|
+
allowedRight = false;
|
424
428
|
} else if (expr.operator === "||") {
|
425
429
|
const leftAsBool = left.asBool();
|
426
430
|
if (leftAsBool === true) return left.setRange(expr.range);
|
427
|
-
|
431
|
+
returnRight = leftAsBool === false;
|
432
|
+
allowedRight = true;
|
428
433
|
} else if (expr.operator === "??") {
|
429
434
|
const leftAsNullish = left.asNullish();
|
430
435
|
if (leftAsNullish === false) return left.setRange(expr.range);
|
431
436
|
if (leftAsNullish !== true) return;
|
437
|
+
returnRight = true;
|
432
438
|
} else return;
|
433
439
|
const right = this.evaluateExpression(expr.right);
|
434
440
|
if (!right) return;
|
435
|
-
if (
|
436
|
-
|
441
|
+
if (returnRight) {
|
442
|
+
if (left.couldHaveSideEffects()) right.setSideEffects();
|
443
|
+
return right.setRange(expr.range);
|
444
|
+
}
|
445
|
+
|
446
|
+
const asBool = right.asBool();
|
447
|
+
|
448
|
+
if (allowedRight === true && asBool === true) {
|
449
|
+
return new BasicEvaluatedExpression()
|
450
|
+
.setRange(expr.range)
|
451
|
+
.setTruthy();
|
452
|
+
} else if (allowedRight === false && asBool === false) {
|
453
|
+
return new BasicEvaluatedExpression().setRange(expr.range).setFalsy();
|
454
|
+
}
|
437
455
|
});
|
438
456
|
|
439
457
|
const valueAsExpression = (value, expr, sideEffects) => {
|
@@ -76,10 +76,8 @@ exports.evaluateToIdentifier = (identifier, rootInfo, getMembers, truthy) => {
|
|
76
76
|
switch (truthy) {
|
77
77
|
case true:
|
78
78
|
evaluatedExpression.setTruthy();
|
79
|
-
evaluatedExpression.setNullish(false);
|
80
79
|
break;
|
81
80
|
case null:
|
82
|
-
evaluatedExpression.setFalsy();
|
83
81
|
evaluatedExpression.setNullish(true);
|
84
82
|
break;
|
85
83
|
case false:
|
@@ -58,6 +58,7 @@ const {
|
|
58
58
|
/** @typedef {import("../WebpackError")} WebpackError */
|
59
59
|
/** @typedef {import("../javascript/JavascriptModulesPlugin").ChunkRenderContext} ChunkRenderContext */
|
60
60
|
/** @typedef {import("../util/Hash")} Hash */
|
61
|
+
/** @typedef {typeof import("../util/Hash")} HashConstructor */
|
61
62
|
/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
|
62
63
|
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
|
63
64
|
|
@@ -647,13 +648,21 @@ class ConcatenatedModule extends Module {
|
|
647
648
|
* @param {Set<Module>} modules all modules in the concatenation (including the root module)
|
648
649
|
* @param {RuntimeSpec} runtime the runtime
|
649
650
|
* @param {Object=} associatedObjectForCache object for caching
|
651
|
+
* @param {string | HashConstructor=} hashFunction hash function to use
|
650
652
|
* @returns {ConcatenatedModule} the module
|
651
653
|
*/
|
652
|
-
static create(
|
654
|
+
static create(
|
655
|
+
rootModule,
|
656
|
+
modules,
|
657
|
+
runtime,
|
658
|
+
associatedObjectForCache,
|
659
|
+
hashFunction = "md4"
|
660
|
+
) {
|
653
661
|
const identifier = ConcatenatedModule._createIdentifier(
|
654
662
|
rootModule,
|
655
663
|
modules,
|
656
|
-
associatedObjectForCache
|
664
|
+
associatedObjectForCache,
|
665
|
+
hashFunction
|
657
666
|
);
|
658
667
|
return new ConcatenatedModule({
|
659
668
|
identifier,
|
@@ -1010,7 +1019,19 @@ class ConcatenatedModule extends Module {
|
|
1010
1019
|
return list;
|
1011
1020
|
}
|
1012
1021
|
|
1013
|
-
|
1022
|
+
/**
|
1023
|
+
* @param {Module} rootModule the root module of the concatenation
|
1024
|
+
* @param {Set<Module>} modules all modules in the concatenation (including the root module)
|
1025
|
+
* @param {Object=} associatedObjectForCache object for caching
|
1026
|
+
* @param {string | HashConstructor=} hashFunction hash function to use
|
1027
|
+
* @returns {string} the identifier
|
1028
|
+
*/
|
1029
|
+
static _createIdentifier(
|
1030
|
+
rootModule,
|
1031
|
+
modules,
|
1032
|
+
associatedObjectForCache,
|
1033
|
+
hashFunction = "md4"
|
1034
|
+
) {
|
1014
1035
|
const cachedMakePathsRelative = makePathsRelative.bindContextCache(
|
1015
1036
|
rootModule.context,
|
1016
1037
|
associatedObjectForCache
|
@@ -1020,7 +1041,7 @@ class ConcatenatedModule extends Module {
|
|
1020
1041
|
identifiers.push(cachedMakePathsRelative(module.identifier()));
|
1021
1042
|
}
|
1022
1043
|
identifiers.sort();
|
1023
|
-
const hash = createHash(
|
1044
|
+
const hash = createHash(hashFunction);
|
1024
1045
|
hash.update(identifiers.join(" "));
|
1025
1046
|
return rootModule.identifier() + "|" + hash.digest("hex");
|
1026
1047
|
}
|
@@ -16,7 +16,7 @@ const { UsageState } = require("../ExportsInfo");
|
|
16
16
|
/** @typedef {import("../javascript/JavascriptParser")} JavascriptParser */
|
17
17
|
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
|
18
18
|
|
19
|
-
/** @typedef {Map<TopLevelSymbol, Set<string | TopLevelSymbol> | true>} InnerGraph */
|
19
|
+
/** @typedef {Map<TopLevelSymbol | null, Set<string | TopLevelSymbol> | true>} InnerGraph */
|
20
20
|
/** @typedef {function(boolean | Set<string> | undefined): void} UsageCallback */
|
21
21
|
|
22
22
|
/**
|
@@ -75,7 +75,7 @@ exports.isEnabled = parserState => {
|
|
75
75
|
|
76
76
|
/**
|
77
77
|
* @param {ParserState} state parser state
|
78
|
-
* @param {TopLevelSymbol} symbol the symbol
|
78
|
+
* @param {TopLevelSymbol | null} symbol the symbol, or null for all symbols
|
79
79
|
* @param {string | TopLevelSymbol | true} usage usage data
|
80
80
|
* @returns {void}
|
81
81
|
*/
|
@@ -172,6 +172,26 @@ exports.inferDependencyUsage = state => {
|
|
172
172
|
}
|
173
173
|
if (isTerminal) {
|
174
174
|
nonTerminal.delete(key);
|
175
|
+
|
176
|
+
// For the global key, merge with all other keys
|
177
|
+
if (key === null) {
|
178
|
+
const globalValue = innerGraph.get(null);
|
179
|
+
if (globalValue) {
|
180
|
+
for (const [key, value] of innerGraph) {
|
181
|
+
if (key !== null && value !== true) {
|
182
|
+
if (globalValue === true) {
|
183
|
+
innerGraph.set(key, true);
|
184
|
+
} else {
|
185
|
+
const newSet = new Set(value);
|
186
|
+
for (const item of globalValue) {
|
187
|
+
newSet.add(item);
|
188
|
+
}
|
189
|
+
innerGraph.set(key, newSet);
|
190
|
+
}
|
191
|
+
}
|
192
|
+
}
|
193
|
+
}
|
194
|
+
}
|
175
195
|
}
|
176
196
|
}
|
177
197
|
}
|
@@ -311,8 +311,7 @@ class HttpUriPlugin {
|
|
311
311
|
: lockfileLocation + ".data";
|
312
312
|
const upgrade = this._upgrade || false;
|
313
313
|
const frozen = this._frozen || false;
|
314
|
-
const hashFunction =
|
315
|
-
this._hashFunction || compilation.outputOptions.hashFunction;
|
314
|
+
const hashFunction = this._hashFunction || "sha512";
|
316
315
|
const hashDigest =
|
317
316
|
this._hashDigest || compilation.outputOptions.hashDigest;
|
318
317
|
const hashDigestLength =
|
@@ -299,12 +299,21 @@ class BinaryMiddleware extends SerializerMiddleware {
|
|
299
299
|
writeU8(STRING_HEADER);
|
300
300
|
writeU32(len);
|
301
301
|
currentBuffer.write(thing, currentPosition);
|
302
|
-
|
302
|
+
currentPosition += len;
|
303
|
+
} else if (len >= 70) {
|
303
304
|
allocate(len + HEADER_SIZE);
|
304
305
|
writeU8(SHORT_STRING_HEADER | len);
|
306
|
+
|
305
307
|
currentBuffer.write(thing, currentPosition, "latin1");
|
308
|
+
currentPosition += len;
|
309
|
+
} else {
|
310
|
+
allocate(len + HEADER_SIZE);
|
311
|
+
writeU8(SHORT_STRING_HEADER | len);
|
312
|
+
|
313
|
+
for (let i = 0; i < len; i++) {
|
314
|
+
currentBuffer[currentPosition++] = thing.charCodeAt(i);
|
315
|
+
}
|
306
316
|
}
|
307
|
-
currentPosition += len;
|
308
317
|
break;
|
309
318
|
}
|
310
319
|
case "number": {
|
@@ -18,6 +18,7 @@ const { dirname, join, mkdirp } = require("../util/fs");
|
|
18
18
|
const memoize = require("../util/memoize");
|
19
19
|
const SerializerMiddleware = require("./SerializerMiddleware");
|
20
20
|
|
21
|
+
/** @typedef {typeof import("../util/Hash")} Hash */
|
21
22
|
/** @typedef {import("../util/fs").IntermediateFileSystem} IntermediateFileSystem */
|
22
23
|
/** @typedef {import("./types").BufferSerializableType} BufferSerializableType */
|
23
24
|
|
@@ -39,8 +40,14 @@ Section -> Buffer
|
|
39
40
|
|
40
41
|
// "wpc" + 1 in little-endian
|
41
42
|
const VERSION = 0x01637077;
|
42
|
-
|
43
|
-
|
43
|
+
|
44
|
+
/**
|
45
|
+
* @param {Buffer[]} buffers buffers
|
46
|
+
* @param {string | Hash} hashFunction hash function to use
|
47
|
+
* @returns {string} hash
|
48
|
+
*/
|
49
|
+
const hashForName = (buffers, hashFunction) => {
|
50
|
+
const hash = createHash(hashFunction);
|
44
51
|
for (const buf of buffers) hash.update(buf);
|
45
52
|
return /** @type {string} */ (hash.digest("hex"));
|
46
53
|
};
|
@@ -81,9 +88,16 @@ const readUInt64LE = Buffer.prototype.readBigUInt64LE
|
|
81
88
|
* @param {BufferSerializableType[] | Promise<BufferSerializableType[]>} data data to be serialized
|
82
89
|
* @param {string | boolean} name file base name
|
83
90
|
* @param {function(string | false, Buffer[]): Promise<void>} writeFile writes a file
|
91
|
+
* @param {string | Hash} hashFunction hash function to use
|
84
92
|
* @returns {Promise<SerializeResult>} resulting file pointer and promise
|
85
93
|
*/
|
86
|
-
const serialize = async (
|
94
|
+
const serialize = async (
|
95
|
+
middleware,
|
96
|
+
data,
|
97
|
+
name,
|
98
|
+
writeFile,
|
99
|
+
hashFunction = "md4"
|
100
|
+
) => {
|
87
101
|
/** @type {(Buffer[] | Buffer | SerializeResult | Promise<SerializeResult>)[]} */
|
88
102
|
const processedData = [];
|
89
103
|
/** @type {WeakMap<SerializeResult, function(): any | Promise<any>>} */
|
@@ -118,7 +132,8 @@ const serialize = async (middleware, data, name, writeFile) => {
|
|
118
132
|
middleware,
|
119
133
|
content,
|
120
134
|
(options && options.name) || true,
|
121
|
-
writeFile
|
135
|
+
writeFile,
|
136
|
+
hashFunction
|
122
137
|
).then(result => {
|
123
138
|
/** @type {any} */ (item).options.size = result.size;
|
124
139
|
resultToLazy.set(result, item);
|
@@ -195,7 +210,7 @@ const serialize = async (middleware, data, name, writeFile) => {
|
|
195
210
|
}
|
196
211
|
}
|
197
212
|
if (name === true) {
|
198
|
-
name = hashForName(buf);
|
213
|
+
name = hashForName(buf, hashFunction);
|
199
214
|
}
|
200
215
|
backgroundJobs.push(writeFile(name, buf));
|
201
216
|
let size = 0;
|
@@ -386,10 +401,12 @@ const deserialize = async (middleware, name, readFile) => {
|
|
386
401
|
class FileMiddleware extends SerializerMiddleware {
|
387
402
|
/**
|
388
403
|
* @param {IntermediateFileSystem} fs filesystem
|
404
|
+
* @param {string | Hash} hashFunction hash function to use
|
389
405
|
*/
|
390
|
-
constructor(fs) {
|
406
|
+
constructor(fs, hashFunction = "md4") {
|
391
407
|
super();
|
392
408
|
this.fs = fs;
|
409
|
+
this._hashFunction = hashFunction;
|
393
410
|
}
|
394
411
|
/**
|
395
412
|
* @param {DeserializedType} data data
|
@@ -446,7 +463,7 @@ class FileMiddleware extends SerializerMiddleware {
|
|
446
463
|
};
|
447
464
|
|
448
465
|
resolve(
|
449
|
-
serialize(this, data, false, writeFile).then(
|
466
|
+
serialize(this, data, false, writeFile, this._hashFunction).then(
|
450
467
|
async ({ backgroundJob }) => {
|
451
468
|
await backgroundJob;
|
452
469
|
|
@@ -15,6 +15,7 @@ const RegExpObjectSerializer = require("./RegExpObjectSerializer");
|
|
15
15
|
const SerializerMiddleware = require("./SerializerMiddleware");
|
16
16
|
const SetObjectSerializer = require("./SetObjectSerializer");
|
17
17
|
|
18
|
+
/** @typedef {typeof import("../util/Hash")} Hash */
|
18
19
|
/** @typedef {import("./types").ComplexSerializableType} ComplexSerializableType */
|
19
20
|
/** @typedef {import("./types").PrimitiveSerializableType} PrimitiveSerializableType */
|
20
21
|
|
@@ -76,8 +77,13 @@ const setMapSize = (map, size) => {
|
|
76
77
|
}
|
77
78
|
};
|
78
79
|
|
79
|
-
|
80
|
-
|
80
|
+
/**
|
81
|
+
* @param {Buffer} buffer buffer
|
82
|
+
* @param {string | Hash} hashFunction hash function to use
|
83
|
+
* @returns {string} hash
|
84
|
+
*/
|
85
|
+
const toHash = (buffer, hashFunction) => {
|
86
|
+
const hash = createHash(hashFunction);
|
81
87
|
hash.update(buffer);
|
82
88
|
return /** @type {string} */ (hash.digest("latin1"));
|
83
89
|
};
|
@@ -149,9 +155,14 @@ const loaders = new Map();
|
|
149
155
|
* @extends {SerializerMiddleware<DeserializedType, SerializedType>}
|
150
156
|
*/
|
151
157
|
class ObjectMiddleware extends SerializerMiddleware {
|
152
|
-
|
158
|
+
/**
|
159
|
+
* @param {function(any): void} extendContext context extensions
|
160
|
+
* @param {string | Hash} hashFunction hash function to use
|
161
|
+
*/
|
162
|
+
constructor(extendContext, hashFunction = "md4") {
|
153
163
|
super();
|
154
164
|
this.extendContext = extendContext;
|
165
|
+
this._hashFunction = hashFunction;
|
155
166
|
}
|
156
167
|
/**
|
157
168
|
* @param {RegExp} regExp RegExp for which the request is tested
|
@@ -275,11 +286,11 @@ class ObjectMiddleware extends SerializerMiddleware {
|
|
275
286
|
bufferDedupeMap.set(len, [entry, buf]);
|
276
287
|
return buf;
|
277
288
|
} else {
|
278
|
-
const hash = toHash(entry);
|
289
|
+
const hash = toHash(entry, this._hashFunction);
|
279
290
|
const newMap = new Map();
|
280
291
|
newMap.set(hash, entry);
|
281
292
|
bufferDedupeMap.set(len, newMap);
|
282
|
-
const hashBuf = toHash(buf);
|
293
|
+
const hashBuf = toHash(buf, this._hashFunction);
|
283
294
|
if (hash === hashBuf) {
|
284
295
|
return entry;
|
285
296
|
}
|
@@ -296,10 +307,10 @@ class ObjectMiddleware extends SerializerMiddleware {
|
|
296
307
|
return buf;
|
297
308
|
} else {
|
298
309
|
const newMap = new Map();
|
299
|
-
const hash = toHash(buf);
|
310
|
+
const hash = toHash(buf, this._hashFunction);
|
300
311
|
let found;
|
301
312
|
for (const item of entry) {
|
302
|
-
const itemHash = toHash(item);
|
313
|
+
const itemHash = toHash(item, this._hashFunction);
|
303
314
|
newMap.set(itemHash, item);
|
304
315
|
if (found === undefined && itemHash === hash) found = item;
|
305
316
|
}
|
@@ -312,7 +323,7 @@ class ObjectMiddleware extends SerializerMiddleware {
|
|
312
323
|
}
|
313
324
|
}
|
314
325
|
} else {
|
315
|
-
const hash = toHash(buf);
|
326
|
+
const hash = toHash(buf, this._hashFunction);
|
316
327
|
const item = entry.get(hash);
|
317
328
|
if (item !== undefined) {
|
318
329
|
return item;
|