webpack 5.112.0 → 5.112.1
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/bin/webpack.js +13 -7
- package/lib/Compilation.js +152 -60
- package/lib/Compiler.js +12 -25
- package/lib/asset/AssetBytesGenerator.js +14 -6
- package/lib/asset/AssetBytesParser.js +10 -8
- package/lib/asset/AssetGenerator.js +36 -48
- package/lib/asset/AssetModule.js +11 -0
- package/lib/asset/AssetModulesPlugin.js +5 -4
- package/lib/asset/AssetParser.js +8 -8
- package/lib/asset/AssetSourceGenerator.js +16 -8
- package/lib/asset/AssetSourceParser.js +10 -8
- package/lib/asset/WebManifestGenerator.js +11 -6
- package/lib/asset/WebManifestParser.js +3 -3
- package/lib/async-modules/AsyncModuleHelpers.js +8 -2
- package/lib/async-modules/InferAsyncModulesPlugin.js +7 -2
- package/lib/cache/CacheFacade.js +1 -1
- package/lib/cache/PackFileCacheStrategy.js +6 -10
- package/lib/cache/ResolverCachePlugin.js +58 -8
- package/lib/config/WebpackOptionsApply.js +8 -28
- package/lib/config/cli.js +9 -6
- package/lib/config/defaults.js +24 -13
- package/lib/config/getClaimedAssetTypes.js +2 -2
- package/lib/config/target.js +1 -1
- package/lib/context/ContextModule.js +1 -1
- package/lib/context/ContextModuleFactory.js +1 -1
- package/lib/context/ContextReplacementPlugin.js +3 -9
- package/lib/css/CssGenerator.js +40 -37
- package/lib/css/CssModule.js +10 -0
- package/lib/css/CssModulesPlugin.js +2 -2
- package/lib/css/CssParser.js +33 -32
- package/lib/css/conventions.js +1 -1
- package/lib/css/data.js +224 -219
- package/lib/css/syntax-parser.js +1159 -298
- package/lib/css/syntax-printer.js +90 -35
- package/lib/debug/ProfilingPlugin.js +65 -43
- package/lib/define/DefinePlugin.js +10 -15
- package/lib/define/DotenvPlugin.js +10 -6
- package/lib/define/EnvironmentPlugin.js +4 -2
- package/lib/dependencies/amd/AMDDefineDependencyParserPlugin.js +1 -2
- package/lib/dependencies/amd/AMDRequireDependenciesBlockParserPlugin.js +4 -1
- package/lib/dependencies/commonjs/CommonJsExportRequireDependency.js +1 -4
- package/lib/dependencies/commonjs/CommonJsExportsParserPlugin.js +18 -33
- package/lib/dependencies/commonjs/CommonJsImportsParserPlugin.js +1 -3
- package/lib/dependencies/commonjs/CommonJsObjectExportDependency.js +4 -4
- package/lib/dependencies/commonjs/CommonJsPlugin.js +2 -5
- package/lib/dependencies/commonjs/RequireEnsureDependenciesBlockParserPlugin.js +4 -1
- package/lib/dependencies/context/ImportMetaContextDependencyParserPlugin.js +1 -2
- package/lib/dependencies/context/ImportMetaGlobDependencyParserPlugin.js +4 -7
- package/lib/dependencies/context/ImportMetaGlobHelpers.js +8 -10
- package/lib/dependencies/core/CachedConstDependency.js +9 -6
- package/lib/dependencies/css/CssIcssExportDependency.js +6 -7
- package/lib/dependencies/css/CssIcssImportDependency.js +1 -3
- package/lib/dependencies/css/CssUrlDependency.js +2 -6
- package/lib/dependencies/esm/ESMDetectionParserPlugin.js +2 -4
- package/lib/dependencies/esm/ESMExportExpressionDependency.js +2 -2
- package/lib/dependencies/esm/ESMExportImportedSpecifierDependency.js +16 -18
- package/lib/dependencies/esm/ESMExportSpecifierDependency.js +20 -3
- package/lib/dependencies/esm/ESMExports.js +2 -10
- package/lib/dependencies/esm/ESMImportDependency.js +17 -2
- package/lib/dependencies/esm/ESMImportDependencyParserPlugin.js +6 -17
- package/lib/dependencies/esm/ESMImportGuard.js +11 -23
- package/lib/dependencies/esm/ESMImportSideEffectDependency.js +1 -1
- package/lib/dependencies/esm/ESMImportSpecifierDependency.js +4 -1
- package/lib/dependencies/esm/ESMLiveExportDependency.js +311 -0
- package/lib/dependencies/esm/ESMLiveExportParserPlugin.js +862 -0
- package/lib/dependencies/esm/ESMModulesPlugin.js +1 -3
- package/lib/dependencies/esm/TopLevelAwaitDependency.js +1 -8
- package/lib/dependencies/helpers/DynamicExports.js +4 -6
- package/lib/dependencies/html/HtmlEntryDependency.js +5 -14
- package/lib/dependencies/html/HtmlInlineHtmlDependency.js +1 -4
- package/lib/dependencies/html/HtmlInlineScriptDependency.js +2 -6
- package/lib/dependencies/html/HtmlInlineStyleDependency.js +1 -4
- package/lib/dependencies/import/ImportParserPlugin.js +3 -6
- package/lib/dependencies/import-meta/ImportMetaPlugin.js +4 -6
- package/lib/dependencies/url/URLParserPlugin.js +1 -1
- package/lib/dependencies/worker/WorkerAndWorkletPlugin.js +51 -20
- package/lib/devtool/ModuleFilenameHelpers.js +1 -1
- package/lib/devtool/SourceMapDevToolPlugin.js +1 -1
- package/lib/dll/DelegatedModule.js +3 -3
- package/lib/dll/DllModule.js +3 -1
- package/lib/dll/DllReferencePlugin.js +1 -4
- package/lib/errors/AbstractMethodError.js +1 -1
- package/lib/errors/ErrorHelpers.js +2 -1
- package/lib/errors/HookWebpackError.js +2 -1
- package/lib/errors/JSONParseError.js +4 -4
- package/lib/errors/WebpackError.js +3 -2
- package/lib/esm/ModuleChunkFormatPlugin.js +36 -1
- package/lib/externals/ExternalModule.js +12 -9
- package/lib/externals/ExternalModuleFactoryPlugin.js +1 -2
- package/lib/externals/ExternalsPlugin.js +1 -1
- package/lib/fs/FileSystemInfo.js +4 -4
- package/lib/graph/AsyncDependenciesBlock.js +1 -1
- package/lib/graph/ChunkGraph.js +5 -0
- package/lib/graph/Dependency.js +8 -2
- package/lib/graph/ExportsInfo.js +1 -1
- package/lib/graph/ModuleGraph.js +14 -3
- package/lib/graph/buildChunkGraph.js +17 -19
- package/lib/graph/findGraphRoots.js +1 -1
- package/lib/hmr/HotModuleReplacement.runtime.js +10 -9
- package/lib/hmr/HotModuleReplacementPlugin.js +5 -11
- package/lib/hmr/JavascriptHotModuleReplacement.runtime.js +16 -19
- package/lib/hmr/LazyCompilationPlugin.js +1 -7
- package/lib/html/HtmlGenerator.js +25 -17
- package/lib/html/HtmlModule.js +11 -1
- package/lib/html/HtmlModulesPlugin.js +12 -11
- package/lib/html/HtmlParser.js +10 -9
- package/lib/html/builtinEmbeddedRenderer.js +31 -33
- package/lib/html/data.js +42 -21
- package/lib/html/htmlMinify.js +4 -1
- package/lib/html/syntax-parser.js +34 -35
- package/lib/html/syntax-printer.js +2 -3
- package/lib/html/xmlMinify.js +4 -1
- package/lib/ids/HashedModuleIdsPlugin.js +1 -1
- package/lib/index.js +13 -12
- package/lib/javascript/APIPlugin.js +7 -13
- package/lib/javascript/BasicEvaluatedExpression.js +5 -5
- package/lib/javascript/CommonJsChunkFormatPlugin.js +2 -7
- package/lib/javascript/ConstPlugin.js +1 -1
- package/lib/javascript/JavascriptGenerator.js +16 -11
- package/lib/javascript/JavascriptMetaInfoPlugin.js +3 -15
- package/lib/javascript/JavascriptModule.js +10 -0
- package/lib/javascript/JavascriptModulesPlugin.js +2 -4
- package/lib/javascript/JavascriptParser.js +99 -11
- package/lib/javascript/ScopeAnalyzer.js +183 -107
- package/lib/javascript/UseStrictPlugin.js +2 -5
- package/lib/javascript/jsMinify.js +1 -1
- package/lib/javascript/regexp.js +2 -2
- package/lib/javascript/syntax-parser.js +2114 -1506
- package/lib/javascript/syntax-printer-data.js +167 -1
- package/lib/javascript/syntax-printer.js +9554 -2782
- package/lib/json/JsonGenerator.js +15 -7
- package/lib/json/JsonModule.js +11 -0
- package/lib/json/JsonParser.js +7 -6
- package/lib/library/AssignLibraryPlugin.js +1 -1
- package/lib/library/JsonpLibraryPlugin.js +1 -1
- package/lib/library/ModuleLibraryPlugin.js +399 -23
- package/lib/loaders/LoaderRunner.js +76 -38
- package/lib/loaders/loadLoader.js +16 -10
- package/lib/module/Generator.js +17 -9
- package/lib/module/Module.js +2 -2
- package/lib/module/NormalModule.js +7 -5
- package/lib/module/NormalModuleFactory.js +11 -17
- package/lib/module/Parser.js +9 -2
- package/lib/module/extractSourceMap.js +69 -18
- package/lib/module/findCaseMismatch.js +2 -2
- package/lib/node/ExternalModuleInitFragment.js +2 -2
- package/lib/node/ReadFileCompileAsyncWasmPlugin.js +4 -12
- package/lib/node/ReadFileCompileWasmPlugin.js +2 -6
- package/lib/node/nodeConsole.js +4 -3
- package/lib/optimize/CircularModulesPlugin.js +1 -1
- package/lib/optimize/ConcatenatedModule.js +2 -6
- package/lib/optimize/FlagDependencyExportsPlugin.js +6 -11
- package/lib/optimize/FlagDependencyUsagePlugin.js +28 -3
- package/lib/optimize/InlineExports.js +4 -7
- package/lib/optimize/LazyBarrels.js +41 -5
- package/lib/optimize/ModuleConcatenationPlugin.js +8 -10
- package/lib/optimize/RealContentHashPlugin.js +2 -6
- package/lib/optimize/SideEffectsFlagPlugin.js +7 -21
- package/lib/optimize/SplitChunksPlugin.js +11 -24
- package/lib/optimize/TupleQueue.js +1 -1
- package/lib/output/CleanPlugin.js +3 -1
- package/lib/output/CopyPlugin.js +3 -4
- package/lib/performance/EvalUsagePlugin.js +1 -3
- package/lib/performance/HotspotsPlugin.js +33 -9
- package/lib/performance/PureAnnotationsPlugin.js +16 -10
- package/lib/performance/TopLevelThisPlugin.js +17 -9
- package/lib/prefetch/ResourceHintPlugin.js +1 -1
- package/lib/provide/ProvidedDependency.js +36 -4
- package/lib/rules/BasicEffectRulePlugin.js +1 -1
- package/lib/rules/RuleSetCompiler.js +15 -5
- package/lib/rules/UseEffectRulePlugin.js +1 -3
- package/lib/runtime/AsyncModuleRuntimeModule.js +7 -1
- package/lib/runtime/GetChunkFilenameRuntimeModule.js +1 -5
- package/lib/runtime/RuntimeGlobals.js +6 -0
- package/lib/runtime/RuntimePlugin.js +2 -0
- package/lib/schemes/HttpUriPlugin.js +1 -2
- package/lib/schemes/VirtualUrlPlugin.js +3 -1
- package/lib/serialization/AggregateErrorSerializer.js +3 -3
- package/lib/serialization/BinaryMiddleware.js +4 -1
- package/lib/serialization/ErrorObjectSerializer.js +2 -5
- package/lib/serialization/ObjectMiddleware.js +17 -15
- package/lib/serialization/PlainObjectSerializer.js +3 -7
- package/lib/serialization/Serializer.js +21 -11
- package/lib/serialization/SerializerMiddleware.js +8 -6
- package/lib/stats/DefaultStatsFactoryPlugin.js +35 -35
- package/lib/stats/DefaultStatsPresetPlugin.js +2 -6
- package/lib/stats/DefaultStatsPrinterPlugin.js +12 -11
- package/lib/stats/StatsFactory.js +194 -24
- package/lib/stats/StatsPrinter.js +126 -13
- package/lib/template/DependencyTemplate.js +1 -1
- package/lib/template/RuntimeTemplate.js +13 -32
- package/lib/template/Template.js +1 -1
- package/lib/util/SourceProcessor.js +98 -15
- package/lib/util/WeakTupleMap.js +10 -4
- package/lib/util/cleverMerge.js +61 -33
- package/lib/util/comparators.js +9 -5
- package/lib/util/dataURL.js +2 -0
- package/lib/util/deprecation.js +4 -3
- package/lib/util/globUtils.js +1 -4
- package/lib/util/internalSerializables.js +2 -0
- package/lib/util/makeSerializable.js +6 -4
- package/lib/util/memoize.js +1 -1
- package/lib/util/parseJson.js +2 -2
- package/lib/util/serialization.js +31 -27
- package/lib/wasm/AsyncWasmModule.js +12 -2
- package/lib/wasm/AsyncWebAssemblyGenerator.js +12 -4
- package/lib/wasm/AsyncWebAssemblyJavascriptGenerator.js +13 -5
- package/lib/wasm/AsyncWebAssemblyParser.js +7 -5
- package/lib/wasm/UniversalCompileAsyncWasmPlugin.js +2 -6
- package/lib/wasm-sync/SyncWasmModule.js +16 -1
- package/lib/wasm-sync/WebAssemblyGenerator.js +15 -10
- package/lib/wasm-sync/WebAssemblyJavascriptGenerator.js +13 -5
- package/lib/wasm-sync/WebAssemblyParser.js +10 -12
- package/lib/web/FetchCompileAsyncWasmPlugin.js +4 -12
- package/lib/web/FetchCompileWasmPlugin.js +2 -6
- package/package.json +16 -18
- package/schemas/WebpackOptions.check.js +3 -3
- package/schemas/WebpackOptions.json +2 -2
- package/schemas/plugins/BannerPlugin.check.js +3 -3
- package/schemas/plugins/HtmlGeneratorOptions.check.js +3 -3
- package/schemas/plugins/HtmlParserOptions.check.js +3 -3
- package/schemas/plugins/IgnorePlugin.check.js +3 -3
- package/schemas/plugins/LoaderOptionsPlugin.check.js +3 -3
- package/schemas/plugins/ManifestPlugin.check.js +3 -3
- package/schemas/plugins/ProgressPlugin.check.js +3 -3
- package/schemas/plugins/SSRManifestPlugin.check.js +3 -3
- package/schemas/plugins/SourceMapDevToolPlugin.check.js +3 -3
- package/schemas/plugins/WatchIgnorePlugin.check.js +3 -3
- package/schemas/plugins/asset/AssetGeneratorOptions.check.js +3 -3
- package/schemas/plugins/asset/AssetInlineGeneratorOptions.check.js +3 -3
- package/schemas/plugins/asset/AssetParserOptions.check.js +3 -3
- package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +3 -3
- package/schemas/plugins/container/ContainerPlugin.check.js +3 -3
- package/schemas/plugins/container/ContainerReferencePlugin.check.js +3 -3
- package/schemas/plugins/container/ExternalsType.check.js +3 -3
- package/schemas/plugins/container/ModuleFederationPlugin.check.js +3 -3
- package/schemas/plugins/css/CssAutoOrModuleParserOptions.check.js +3 -3
- package/schemas/plugins/css/CssGeneratorOptions.check.js +3 -3
- package/schemas/plugins/css/CssModuleGeneratorOptions.check.js +3 -3
- package/schemas/plugins/css/CssModuleParserOptions.check.js +3 -3
- package/schemas/plugins/css/CssParserOptions.check.js +3 -3
- package/schemas/plugins/debug/ProfilingPlugin.check.js +3 -3
- package/schemas/plugins/define/DotenvPluginOptions.check.js +7 -0
- package/schemas/plugins/define/DotenvPluginOptions.json +3 -0
- package/schemas/plugins/dll/DllPlugin.check.js +3 -3
- package/schemas/plugins/dll/DllReferencePlugin.check.js +3 -3
- package/schemas/plugins/ids/HashedModuleIdsPlugin.check.js +3 -3
- package/schemas/plugins/ids/OccurrenceChunkIdsPlugin.check.js +3 -3
- package/schemas/plugins/ids/OccurrenceModuleIdsPlugin.check.js +3 -3
- package/schemas/plugins/json/JsonModulesPluginGenerator.check.js +3 -3
- package/schemas/plugins/json/JsonModulesPluginParser.check.js +3 -3
- package/schemas/plugins/optimize/AggressiveSplittingPlugin.check.js +3 -3
- package/schemas/plugins/optimize/LimitChunkCountPlugin.check.js +3 -3
- package/schemas/plugins/optimize/MergeDuplicateChunksPlugin.check.js +3 -3
- package/schemas/plugins/optimize/MinChunkSizePlugin.check.js +3 -3
- package/schemas/plugins/output/CleanOptions.check.js +7 -0
- package/schemas/plugins/output/CleanOptions.json +3 -0
- package/schemas/plugins/schemes/HttpUriPlugin.check.js +3 -3
- package/schemas/plugins/schemes/VirtualUrlPlugin.check.js +3 -3
- package/schemas/plugins/sharing/ConsumeSharedPlugin.check.js +3 -3
- package/schemas/plugins/sharing/ProvideSharedPlugin.check.js +3 -3
- package/schemas/plugins/sharing/SharePlugin.check.js +3 -3
- package/types.d.ts +1482 -358
|
@@ -414,11 +414,11 @@ function getGlobalObject(definition) {
|
|
|
414
414
|
|
|
415
415
|
if (
|
|
416
416
|
// identifier, we do not need real identifier regarding ECMAScript/Unicode
|
|
417
|
-
/^[_\p{L}][_0-9\p{L}]*$/
|
|
417
|
+
/^[_\p{L}][_0-9\p{L}]*$/u.test(trimmed) ||
|
|
418
418
|
// iife
|
|
419
419
|
// call expression
|
|
420
420
|
// expression in parentheses
|
|
421
|
-
/^(?:[_\p{L}][_0-9\p{L}]*)?\(.*\)$/
|
|
421
|
+
/^(?:[_\p{L}][_0-9\p{L}]*)?\(.*\)$/u.test(trimmed)
|
|
422
422
|
) {
|
|
423
423
|
return trimmed;
|
|
424
424
|
}
|
|
@@ -1386,7 +1386,7 @@ class RuntimeTemplate {
|
|
|
1386
1386
|
const spellable =
|
|
1387
1387
|
this._getAnalyzableFileSpecifier(
|
|
1388
1388
|
module,
|
|
1389
|
-
|
|
1389
|
+
chunkGraph,
|
|
1390
1390
|
[["literal", "x"]],
|
|
1391
1391
|
true
|
|
1392
1392
|
) !== null;
|
|
@@ -2888,7 +2888,7 @@ class RuntimeTemplate {
|
|
|
2888
2888
|
* @returns {boolean} true when the hash exists by the time the target is hashed
|
|
2889
2889
|
*/
|
|
2890
2890
|
_hashRoundBefore(chunk, target) {
|
|
2891
|
-
const chunkGraph =
|
|
2891
|
+
const chunkGraph = this.compilation.chunkGraph;
|
|
2892
2892
|
const round = hashRound(chunk, chunkGraph);
|
|
2893
2893
|
const targetRound = hashRound(target, chunkGraph);
|
|
2894
2894
|
if (round !== targetRound) return round < targetRound;
|
|
@@ -2956,8 +2956,7 @@ class RuntimeTemplate {
|
|
|
2956
2956
|
*/
|
|
2957
2957
|
_settlesLate(chunk) {
|
|
2958
2958
|
return (
|
|
2959
|
-
|
|
2960
|
-
(this.compilation.chunkGraph).getChunkFullHashModulesIterable(chunk) !==
|
|
2959
|
+
this.compilation.chunkGraph.getChunkFullHashModulesIterable(chunk) !==
|
|
2961
2960
|
undefined
|
|
2962
2961
|
);
|
|
2963
2962
|
}
|
|
@@ -2989,7 +2988,7 @@ class RuntimeTemplate {
|
|
|
2989
2988
|
_markChunksSettlingLate() {
|
|
2990
2989
|
this._chunksBakingFullHash = new Set();
|
|
2991
2990
|
const { compilation } = this;
|
|
2992
|
-
const chunkGraph =
|
|
2991
|
+
const chunkGraph = compilation.chunkGraph;
|
|
2993
2992
|
const results = compilation.codeGenerationResults;
|
|
2994
2993
|
if (results === undefined) return;
|
|
2995
2994
|
/** @type {Map<Chunk, Set<string>>} */
|
|
@@ -3234,11 +3233,7 @@ class RuntimeTemplate {
|
|
|
3234
3233
|
const undo =
|
|
3235
3234
|
shape === undefined
|
|
3236
3235
|
? null
|
|
3237
|
-
: getUndoPath(
|
|
3238
|
-
`${shape}x`,
|
|
3239
|
-
/** @type {string} */ (this.outputOptions.path),
|
|
3240
|
-
true
|
|
3241
|
-
);
|
|
3236
|
+
: getUndoPath(`${shape}x`, this.outputOptions.path, true);
|
|
3242
3237
|
this._publicPathClimbText = undo === "./" ? "" : undo;
|
|
3243
3238
|
}
|
|
3244
3239
|
return this._publicPathClimbText;
|
|
@@ -3273,11 +3268,7 @@ class RuntimeTemplate {
|
|
|
3273
3268
|
undo:
|
|
3274
3269
|
chunkName === null
|
|
3275
3270
|
? null
|
|
3276
|
-
: getUndoPath(
|
|
3277
|
-
chunkName,
|
|
3278
|
-
/** @type {string} */ (outputOptions.path),
|
|
3279
|
-
true
|
|
3280
|
-
),
|
|
3271
|
+
: getUndoPath(chunkName, outputOptions.path, true),
|
|
3281
3272
|
// A chunk in an initial group and an async one both is served at two urls,
|
|
3282
3273
|
// one public path apart, so no one literal in it is right for both.
|
|
3283
3274
|
loaded: chunk.isOnlyInitial() ? false : chunk.canBeInitial() ? null : true
|
|
@@ -3338,11 +3329,7 @@ class RuntimeTemplate {
|
|
|
3338
3329
|
: shape,
|
|
3339
3330
|
{ chunk, contentHashType: JAVASCRIPT_TYPE }
|
|
3340
3331
|
);
|
|
3341
|
-
return getUndoPath(
|
|
3342
|
-
name,
|
|
3343
|
-
/** @type {string} */ (this.outputOptions.path),
|
|
3344
|
-
enforceRelative
|
|
3345
|
-
);
|
|
3332
|
+
return getUndoPath(name, this.outputOptions.path, enforceRelative);
|
|
3346
3333
|
}
|
|
3347
3334
|
|
|
3348
3335
|
/**
|
|
@@ -3495,7 +3482,7 @@ class RuntimeTemplate {
|
|
|
3495
3482
|
const filename =
|
|
3496
3483
|
deferred && !settled
|
|
3497
3484
|
? ""
|
|
3498
|
-
: compilation.getPath(
|
|
3485
|
+
: compilation.getPath(template, {
|
|
3499
3486
|
chunk,
|
|
3500
3487
|
// Matches what names the asset, or a placeholder resolved here would
|
|
3501
3488
|
// not be the one on disk.
|
|
@@ -4113,7 +4100,7 @@ class RuntimeTemplate {
|
|
|
4113
4100
|
}
|
|
4114
4101
|
const undo = getUndoPath(
|
|
4115
4102
|
this.compilation.getPath(this._hotUpdateShapeText, { chunk }),
|
|
4116
|
-
|
|
4103
|
+
outputOptions.path,
|
|
4117
4104
|
true
|
|
4118
4105
|
);
|
|
4119
4106
|
this._hotUpdateUndoByChunk.set(chunk, undo);
|
|
@@ -4131,9 +4118,7 @@ class RuntimeTemplate {
|
|
|
4131
4118
|
*/
|
|
4132
4119
|
getAnalyzableWasmUrl(module, chunkGraph, runtime, runtimeRequirements) {
|
|
4133
4120
|
const { compilation } = this;
|
|
4134
|
-
const template =
|
|
4135
|
-
this.outputOptions.webassemblyModuleFilename
|
|
4136
|
-
);
|
|
4121
|
+
const template = this.outputOptions.webassemblyModuleFilename;
|
|
4137
4122
|
// The module's own hash and id are settled here, the compilation's is not — and
|
|
4138
4123
|
// a placeholder nothing answers is left in the name, so what comes back is either
|
|
4139
4124
|
// the final name or a template carrying only `[fullhash]`.
|
|
@@ -4500,11 +4485,7 @@ class RuntimeTemplate {
|
|
|
4500
4485
|
} else if (kind === "literal") {
|
|
4501
4486
|
specifier += value;
|
|
4502
4487
|
} else if (kind === "undo") {
|
|
4503
|
-
specifier += getUndoPath(
|
|
4504
|
-
assetName,
|
|
4505
|
-
/** @type {string} */ (outputOptions.path),
|
|
4506
|
-
true
|
|
4507
|
-
);
|
|
4488
|
+
specifier += getUndoPath(assetName, outputOptions.path, true);
|
|
4508
4489
|
} else if (kind === "template") {
|
|
4509
4490
|
specifier += compilation.getPath(
|
|
4510
4491
|
/** @type {string} */ (value),
|
package/lib/template/Template.js
CHANGED
|
@@ -53,7 +53,7 @@ const LINE_SEPARATOR_REGEX = /\r?\n/g;
|
|
|
53
53
|
const IDENTIFIER_NAME_REPLACE_REGEX = /^([^a-z$_])/i;
|
|
54
54
|
const IDENTIFIER_ALPHA_NUMERIC_NAME_REPLACE_REGEX = /[^a-z0-9$]+/gi;
|
|
55
55
|
const COMMENT_END_REGEX = /\*\//g;
|
|
56
|
-
const PATH_NAME_NORMALIZE_REPLACE_REGEX = /[^a-
|
|
56
|
+
const PATH_NAME_NORMALIZE_REPLACE_REGEX = /[^a-zA-Z0-9_!§$()=\-^°]+/g;
|
|
57
57
|
const MATCH_PADDED_HYPHENS_REPLACE_REGEX = /^-|-$/g;
|
|
58
58
|
|
|
59
59
|
/**
|
|
@@ -186,11 +186,11 @@ const declineDeferredWrites = (text, writes) =>
|
|
|
186
186
|
*/
|
|
187
187
|
/**
|
|
188
188
|
* What part `M` gives the node type `R` says it is; every part `D` when `R`
|
|
189
|
-
* says none (a plain node reads `
|
|
189
|
+
* says none (a plain node reads `number` there).
|
|
190
190
|
* @template R
|
|
191
191
|
* @template {Record<number, number>} M
|
|
192
192
|
* @template D
|
|
193
|
-
* @typedef {number extends (R & { readonly __nodeType:
|
|
193
|
+
* @typedef {number extends (R & { readonly __nodeType: number })["__nodeType"] ? D : M[(R & { readonly __nodeType: number })["__nodeType"]]} PartOf
|
|
194
194
|
*/
|
|
195
195
|
/**
|
|
196
196
|
* A language's parts, by node type: what its `Field`s and `Flag`s apply to.
|
|
@@ -281,7 +281,10 @@ const declineDeferredWrites = (text, writes) =>
|
|
|
281
281
|
const deferredKey = (offer) => {
|
|
282
282
|
let key = "";
|
|
283
283
|
for (const name of Object.keys(offer).sort()) {
|
|
284
|
-
const value =
|
|
284
|
+
const value =
|
|
285
|
+
/** @type {Record<string, DeferredWrite[keyof DeferredWrite]>} */ (offer)[
|
|
286
|
+
name
|
|
287
|
+
];
|
|
285
288
|
if (typeof value !== "function") key += `${name}\0${value}\0`;
|
|
286
289
|
}
|
|
287
290
|
return key;
|
|
@@ -402,10 +405,13 @@ class PrintContext {
|
|
|
402
405
|
this._printer = printer;
|
|
403
406
|
// Printed text by node handle, in two columns rather than one `Map`: the
|
|
404
407
|
// handles are dense integers, and `_moveEpoch` keeps the live set small.
|
|
405
|
-
/** @type {string[]} each finished node's printed text */
|
|
408
|
+
/** @type {(string | null)[]} each finished node's printed text */
|
|
406
409
|
this._storeText = [];
|
|
407
410
|
/** @type {Int32Array} the epoch each slot was written in */
|
|
408
411
|
this._storeGen = new Int32Array(0);
|
|
412
|
+
// A slot holding `null` prints as its source, read only once asked for.
|
|
413
|
+
/** @type {((node: TNode) => string) | undefined} reads a `null` slot's text */
|
|
414
|
+
this._sourceText = undefined;
|
|
409
415
|
/** @type {number} current epoch; a slot from an older one reads as absent */
|
|
410
416
|
this._gen = 1;
|
|
411
417
|
/** @type {number} lowest slot written since the epoch last moved */
|
|
@@ -417,6 +423,8 @@ class PrintContext {
|
|
|
417
423
|
// for retractable text alone, so no other emit pays for that ability.
|
|
418
424
|
/** @type {string[]} pieces already cut off, in output order */
|
|
419
425
|
this._chunks = [];
|
|
426
|
+
/** @type {Map<number, { readonly text: string }> | null} pieces whose text is read only once the output is */
|
|
427
|
+
this._deferred = null;
|
|
420
428
|
/** @type {string} output after the last cut piece */
|
|
421
429
|
this._tail = "";
|
|
422
430
|
/** @type {number} characters in `_tail`, so its length is not read off a rope */
|
|
@@ -593,6 +601,7 @@ class PrintContext {
|
|
|
593
601
|
* @param {number} charCode the character to drop
|
|
594
602
|
*/
|
|
595
603
|
dropTrailing(from, charCode) {
|
|
604
|
+
this._settleDeferred();
|
|
596
605
|
const chunks = this._chunks;
|
|
597
606
|
for (let i = chunks.length; i >= from; i--) {
|
|
598
607
|
let text = i === chunks.length ? this._tail : chunks[i];
|
|
@@ -622,6 +631,7 @@ class PrintContext {
|
|
|
622
631
|
* @returns {boolean} true when the output ended that way and was rewritten
|
|
623
632
|
*/
|
|
624
633
|
replaceEnd(printed, text, closer) {
|
|
634
|
+
this._settleDeferred();
|
|
625
635
|
this._cutTail();
|
|
626
636
|
const chunks = this._chunks;
|
|
627
637
|
// Joined once: this runs only where a value ran into the end of the input.
|
|
@@ -656,7 +666,16 @@ class PrintContext {
|
|
|
656
666
|
* @param {TPath} path the language accessor, positioned on `node`
|
|
657
667
|
*/
|
|
658
668
|
printNode(node, path) {
|
|
659
|
-
|
|
669
|
+
this.printedAs(node, this._printer(path, this));
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
/**
|
|
673
|
+
* Store `text` as what `node` printed, where the grammar already knows what
|
|
674
|
+
* the node printer would return and so does not call it.
|
|
675
|
+
* @param {TNode} node the finished node
|
|
676
|
+
* @param {string} text its printed text
|
|
677
|
+
*/
|
|
678
|
+
printedAs(node, text) {
|
|
660
679
|
const n = /** @type {number} */ (node);
|
|
661
680
|
if (n >= this._storeText.length) this._growStore(n + 1);
|
|
662
681
|
this._storeText[n] = text;
|
|
@@ -665,6 +684,22 @@ class PrintContext {
|
|
|
665
684
|
if (n > this._storeHigh) this._storeHigh = n;
|
|
666
685
|
}
|
|
667
686
|
|
|
687
|
+
/**
|
|
688
|
+
* Store that `node` printed as its source, which `sourceText` reads only once
|
|
689
|
+
* something asks for its text.
|
|
690
|
+
* @param {TNode} node the finished node
|
|
691
|
+
* @param {(node: TNode) => string} sourceText reads a node's source
|
|
692
|
+
*/
|
|
693
|
+
printedSource(node, sourceText) {
|
|
694
|
+
const n = /** @type {number} */ (node);
|
|
695
|
+
if (n >= this._storeText.length) this._growStore(n + 1);
|
|
696
|
+
this._sourceText = sourceText;
|
|
697
|
+
this._storeText[n] = null;
|
|
698
|
+
this._storeGen[n] = this._gen;
|
|
699
|
+
if (n < this._storeLow) this._storeLow = n;
|
|
700
|
+
if (n > this._storeHigh) this._storeHigh = n;
|
|
701
|
+
}
|
|
702
|
+
|
|
668
703
|
/**
|
|
669
704
|
* Print one node and hand its text straight back — for a node inside one being
|
|
670
705
|
* printed in pieces, whose text is emitted as it is printed, so the store
|
|
@@ -682,9 +717,16 @@ class PrintContext {
|
|
|
682
717
|
*/
|
|
683
718
|
get(node) {
|
|
684
719
|
const n = /** @type {number} */ (node);
|
|
685
|
-
|
|
686
|
-
|
|
720
|
+
if (this._storeGen[n] !== this._gen) {
|
|
721
|
+
return /** @type {string} */ (/** @type {unknown} */ (undefined));
|
|
722
|
+
}
|
|
723
|
+
const text = this._storeText[n];
|
|
724
|
+
if (text !== null) return text;
|
|
725
|
+
const source = /** @type {(node: TNode) => string} */ (this._sourceText)(
|
|
726
|
+
node
|
|
687
727
|
);
|
|
728
|
+
this._storeText[n] = source;
|
|
729
|
+
return source;
|
|
688
730
|
}
|
|
689
731
|
|
|
690
732
|
/**
|
|
@@ -742,6 +784,7 @@ class PrintContext {
|
|
|
742
784
|
* @param {number} index the piece's index, from {@link emitRetractable}
|
|
743
785
|
*/
|
|
744
786
|
retract(index) {
|
|
787
|
+
if (this._deferred !== null) this._deferred.delete(index);
|
|
745
788
|
this._chunks[index] = "";
|
|
746
789
|
if (this._retractableMappings === null) return;
|
|
747
790
|
const mapping = this._retractableMappings[index];
|
|
@@ -755,6 +798,7 @@ class PrintContext {
|
|
|
755
798
|
* @returns {boolean} true when it does
|
|
756
799
|
*/
|
|
757
800
|
writesNonAscii(index) {
|
|
801
|
+
this._settleDeferred();
|
|
758
802
|
const chunks = this._chunks;
|
|
759
803
|
for (let i = index + 1; i < chunks.length; i++) {
|
|
760
804
|
if (NON_ASCII_RE.test(chunks[i])) return true;
|
|
@@ -776,6 +820,7 @@ class PrintContext {
|
|
|
776
820
|
* @param {string} text what to fold in, its own closer included
|
|
777
821
|
*/
|
|
778
822
|
foldIntoRetractable(index, text) {
|
|
823
|
+
this._settleDeferred();
|
|
779
824
|
const piece = this._chunks[index];
|
|
780
825
|
this._chunks[index] = `${piece.slice(0, -1)}${text}`;
|
|
781
826
|
}
|
|
@@ -788,9 +833,31 @@ class PrintContext {
|
|
|
788
833
|
* @param {string} text what the piece says now
|
|
789
834
|
*/
|
|
790
835
|
rewriteRetractable(index, text) {
|
|
836
|
+
if (this._deferred !== null) this._deferred.delete(index);
|
|
791
837
|
this._chunks[index] = text;
|
|
792
838
|
}
|
|
793
839
|
|
|
840
|
+
/**
|
|
841
|
+
* {@link rewriteRetractable} with text that is asked for only once the output
|
|
842
|
+
* is read: a piece rewritten many times over is then built once, not each time.
|
|
843
|
+
* @param {number} index the piece's index, from {@link emitRetractable}
|
|
844
|
+
* @param {{ readonly text: string }} source what holds the piece's text
|
|
845
|
+
*/
|
|
846
|
+
deferRetractable(index, source) {
|
|
847
|
+
if (this._deferred === null) this._deferred = new Map();
|
|
848
|
+
this._deferred.set(index, source);
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
/**
|
|
852
|
+
* Write every deferred piece's text in, before anything reads the pieces.
|
|
853
|
+
*/
|
|
854
|
+
_settleDeferred() {
|
|
855
|
+
const deferred = this._deferred;
|
|
856
|
+
if (deferred === null) return;
|
|
857
|
+
this._deferred = null;
|
|
858
|
+
for (const [index, source] of deferred) this._chunks[index] = source.text;
|
|
859
|
+
}
|
|
860
|
+
|
|
794
861
|
/**
|
|
795
862
|
* {@link take} for a top-level node a later sibling may still make dead — the
|
|
796
863
|
* unprefixed twin of a vendor-prefixed rule, which can stand anywhere after
|
|
@@ -953,6 +1020,7 @@ class PrintContext {
|
|
|
953
1020
|
* @returns {SourceMap} the input->output source map
|
|
954
1021
|
*/
|
|
955
1022
|
sourceMap(options, code) {
|
|
1023
|
+
this._settleDeferred();
|
|
956
1024
|
let out = "";
|
|
957
1025
|
let genLine = 0;
|
|
958
1026
|
let genCol = 0;
|
|
@@ -1024,6 +1092,7 @@ class PrintContext {
|
|
|
1024
1092
|
* @returns {void}
|
|
1025
1093
|
*/
|
|
1026
1094
|
substitute(resolve, infix) {
|
|
1095
|
+
this._settleDeferred();
|
|
1027
1096
|
const chunks = this._chunks;
|
|
1028
1097
|
const mappings = this._mappings;
|
|
1029
1098
|
// Both pieces and mappings are output-ordered, so one cursor walks them
|
|
@@ -1086,6 +1155,7 @@ class PrintContext {
|
|
|
1086
1155
|
* @param {string} text the output to keep instead
|
|
1087
1156
|
*/
|
|
1088
1157
|
replaceAll(text) {
|
|
1158
|
+
this._deferred = null;
|
|
1089
1159
|
this._chunks.length = 0;
|
|
1090
1160
|
this._tail = text;
|
|
1091
1161
|
this._tailLength = text.length;
|
|
@@ -1097,6 +1167,7 @@ class PrintContext {
|
|
|
1097
1167
|
}
|
|
1098
1168
|
|
|
1099
1169
|
result() {
|
|
1170
|
+
this._settleDeferred();
|
|
1100
1171
|
// Trailing kept comments (after the last top-level node) flush here.
|
|
1101
1172
|
if (this._insertIdx < this._inserts.length) this._flushBefore(Infinity);
|
|
1102
1173
|
// Nothing was ever cut into its own piece, so there is nothing to join.
|
|
@@ -1175,8 +1246,8 @@ class SourceProcessor {
|
|
|
1175
1246
|
* @returns {SourceProcessor<TPath, TNode, TProcessOptions, TPrintOptions, TParts, TState, TVisitors>} `this`, for chaining
|
|
1176
1247
|
*/
|
|
1177
1248
|
/**
|
|
1178
|
-
* @param {
|
|
1179
|
-
* @param {VisitorBucket<
|
|
1249
|
+
* @param {number[] | TVisitors | VisitorMap<TPath>} map visitor map, or the node types `bucket` visits
|
|
1250
|
+
* @param {VisitorBucket<TypedNodePath<TPath, TNode, TParts, number, TState>>=} bucket the visitor, with an array of types
|
|
1180
1251
|
* @returns {SourceProcessor<TPath, TNode, TProcessOptions, TPrintOptions, TParts, TState, TVisitors>} `this`, for chaining
|
|
1181
1252
|
*/
|
|
1182
1253
|
use(map, bucket) {
|
|
@@ -1186,14 +1257,23 @@ class SourceProcessor {
|
|
|
1186
1257
|
"SourceProcessor.use(types, bucket): a visitor is required"
|
|
1187
1258
|
);
|
|
1188
1259
|
}
|
|
1189
|
-
for (let i = 0; i < map.length; i++)
|
|
1260
|
+
for (let i = 0; i < map.length; i++) {
|
|
1261
|
+
this._add(
|
|
1262
|
+
map[i],
|
|
1263
|
+
/** @type {VisitorBucket<TPath>} */ (
|
|
1264
|
+
/** @type {VisitorBucket<TPath> | VisitorBucket<TypedNodePath<TPath, TNode, TParts, number, TState>>} */ (
|
|
1265
|
+
bucket
|
|
1266
|
+
)
|
|
1267
|
+
)
|
|
1268
|
+
);
|
|
1269
|
+
}
|
|
1190
1270
|
return this;
|
|
1191
1271
|
}
|
|
1192
1272
|
// `map`'s keys are node-type enum members; `Object.keys` stringifies them,
|
|
1193
1273
|
// so index the compiled array by the number to match the numeric `node.type`.
|
|
1194
|
-
for (const type of Object.keys(map)) {
|
|
1274
|
+
for (const type of Object.keys(/** @type {VisitorMap<TPath>} */ (map))) {
|
|
1195
1275
|
const key = Number(type);
|
|
1196
|
-
this._add(key, map[key]);
|
|
1276
|
+
this._add(key, /** @type {VisitorMap<TPath>} */ (map)[key]);
|
|
1197
1277
|
}
|
|
1198
1278
|
return this;
|
|
1199
1279
|
}
|
|
@@ -1291,9 +1371,9 @@ class SourceProcessor {
|
|
|
1291
1371
|
// along is inert, since a printer reads only what its own type declares.
|
|
1292
1372
|
const ctx = new PrintContext(
|
|
1293
1373
|
/** @type {PrintOptions & TPrintOptions} */ (
|
|
1294
|
-
/** @type {
|
|
1374
|
+
/** @type {typeof opts | (PrintOptions & TPrintOptions)} */ (opts)
|
|
1295
1375
|
),
|
|
1296
|
-
|
|
1376
|
+
this._printer
|
|
1297
1377
|
);
|
|
1298
1378
|
this._run(input, ctx, opts);
|
|
1299
1379
|
const name = /** @type {{ source?: string, content?: string }} */ (opts);
|
|
@@ -1343,7 +1423,10 @@ class SourceProcessor {
|
|
|
1343
1423
|
// renderer's answer widened, which `Omit` cannot say and nothing reads.
|
|
1344
1424
|
const opts =
|
|
1345
1425
|
/** @type {TProcessOptions & { mode: PrintOptions["mode"] }} */
|
|
1346
|
-
(
|
|
1426
|
+
(
|
|
1427
|
+
/** @type {typeof options | (TProcessOptions & { mode: PrintOptions["mode"] })} */
|
|
1428
|
+
(options)
|
|
1429
|
+
);
|
|
1347
1430
|
|
|
1348
1431
|
if (render === undefined) {
|
|
1349
1432
|
return /** @type {{ code: string, map: SourceMap | undefined }} */ (
|
package/lib/util/WeakTupleMap.js
CHANGED
|
@@ -5,10 +5,16 @@
|
|
|
5
5
|
|
|
6
6
|
"use strict";
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* A value one position of a tuple key may hold: a primitive kept in a `Map`, or
|
|
10
|
+
* an object (functions included) kept in a `WeakMap`.
|
|
11
|
+
* @typedef {string | number | bigint | boolean | symbol | EXPECTED_OBJECT | null | undefined} TupleElement
|
|
12
|
+
*/
|
|
13
|
+
|
|
8
14
|
/**
|
|
9
15
|
* Strong-key child map used for tuple elements that cannot be stored in a
|
|
10
16
|
* `WeakMap`.
|
|
11
|
-
* @template {
|
|
17
|
+
* @template {TupleElement[]} T
|
|
12
18
|
* @template V
|
|
13
19
|
* @typedef {Map<ArrayElement<T>, WeakTupleMap<T, V>>} M
|
|
14
20
|
*/
|
|
@@ -16,7 +22,7 @@
|
|
|
16
22
|
/**
|
|
17
23
|
* Weak-key child map used for tuple elements that are objects and can be held
|
|
18
24
|
* without preventing garbage collection.
|
|
19
|
-
* @template {
|
|
25
|
+
* @template {TupleElement[]} T
|
|
20
26
|
* @template V
|
|
21
27
|
* @typedef {WeakMap<ArrayElement<T> & EXPECTED_OBJECT, WeakTupleMap<T, V>>} W
|
|
22
28
|
*/
|
|
@@ -31,14 +37,14 @@ const isWeakKey = (thing) => typeof thing === "object" && thing !== null;
|
|
|
31
37
|
|
|
32
38
|
/**
|
|
33
39
|
* Extracts the element type from a tuple-like array.
|
|
34
|
-
* @template
|
|
40
|
+
* @template T
|
|
35
41
|
* @typedef {T extends ReadonlyArray<infer ElementType> ? ElementType : never} ArrayElement
|
|
36
42
|
*/
|
|
37
43
|
|
|
38
44
|
/**
|
|
39
45
|
* Stores values by tuple keys while using `WeakMap` for object elements so the
|
|
40
46
|
* cache can release entries when those objects are collected.
|
|
41
|
-
* @template {
|
|
47
|
+
* @template {TupleElement[]} K
|
|
42
48
|
* @template V
|
|
43
49
|
*/
|
|
44
50
|
class WeakTupleMap {
|
package/lib/util/cleverMerge.js
CHANGED
|
@@ -88,19 +88,27 @@ const cachedSetProperty = (obj, property, value) => {
|
|
|
88
88
|
|
|
89
89
|
/**
|
|
90
90
|
* Defines the by values type used by this module.
|
|
91
|
-
* @
|
|
91
|
+
* @template V
|
|
92
|
+
* @typedef {Map<string, V>} ByValues
|
|
92
93
|
*/
|
|
93
94
|
|
|
94
95
|
/**
|
|
95
96
|
* Defines the object parsed property entry type used by this module.
|
|
96
97
|
* @template T
|
|
98
|
+
* @template [V=T[keyof T]]
|
|
97
99
|
* @typedef {object} ObjectParsedPropertyEntry
|
|
98
|
-
* @property {
|
|
100
|
+
* @property {V | undefined} base base value
|
|
99
101
|
* @property {`by${string}` | undefined} byProperty the name of the selector property
|
|
100
|
-
* @property {ByValues | undefined} byValues value depending on selector property, merged with base
|
|
102
|
+
* @property {ByValues<V | undefined> | undefined} byValues value depending on selector property, merged with base
|
|
101
103
|
*/
|
|
102
104
|
|
|
103
|
-
/**
|
|
105
|
+
/**
|
|
106
|
+
* Result of merging a value of type `A` with a value of type `B`.
|
|
107
|
+
* @template A, B
|
|
108
|
+
* @typedef {A & B | (A | B)[] | A | A[] | B | B[]} MergedValue
|
|
109
|
+
*/
|
|
110
|
+
|
|
111
|
+
/** @typedef {((...values: never[]) => object) & { [DYNAMIC_INFO]: [DynamicFunction, object] }} DynamicFunction */
|
|
104
112
|
|
|
105
113
|
/**
|
|
106
114
|
* Defines the parsed object static type used by this module.
|
|
@@ -139,7 +147,11 @@ const cachedParseObject = (obj) => {
|
|
|
139
147
|
return result;
|
|
140
148
|
};
|
|
141
149
|
|
|
142
|
-
/**
|
|
150
|
+
/**
|
|
151
|
+
* Defines the by object type used by this module.
|
|
152
|
+
* @template T
|
|
153
|
+
* @typedef {{ [p: string]: Partial<T> } | DynamicFunction} ByObject
|
|
154
|
+
*/
|
|
143
155
|
|
|
144
156
|
/**
|
|
145
157
|
* Returns parsed object.
|
|
@@ -172,7 +184,7 @@ const parseObject = (obj) => {
|
|
|
172
184
|
const key = /** @type {keyof T} */ (key_);
|
|
173
185
|
if (typeof key === "string" && key.startsWith("by")) {
|
|
174
186
|
const byProperty = key;
|
|
175
|
-
const byObj = /** @type {ByObject} */ (obj[byProperty]);
|
|
187
|
+
const byObj = /** @type {ByObject<T>} */ (obj[byProperty]);
|
|
176
188
|
if (typeof byObj === "object") {
|
|
177
189
|
for (const byValue of Object.keys(byObj)) {
|
|
178
190
|
const obj = byObj[/** @type {keyof (keyof T)} */ (byValue)];
|
|
@@ -183,20 +195,20 @@ const parseObject = (obj) => {
|
|
|
183
195
|
entry.byValues = new Map();
|
|
184
196
|
} else if (entry.byProperty !== byProperty) {
|
|
185
197
|
throw new Error(
|
|
186
|
-
`${
|
|
198
|
+
`${byProperty} and ${entry.byProperty} for a single property is not supported`
|
|
187
199
|
);
|
|
188
200
|
}
|
|
189
|
-
/** @type {ByValues} */
|
|
190
|
-
(entry.byValues).set(byValue, obj[key]);
|
|
201
|
+
/** @type {ByValues<T[keyof T] | undefined>} */
|
|
202
|
+
(entry.byValues).set(byValue, obj[/** @type {keyof T} */ (key)]);
|
|
191
203
|
if (byValue === "default") {
|
|
192
204
|
for (const otherByValue of Object.keys(byObj)) {
|
|
193
205
|
if (
|
|
194
206
|
!(
|
|
195
|
-
/** @type {ByValues} */
|
|
207
|
+
/** @type {ByValues<T[keyof T] | undefined>} */
|
|
196
208
|
(entry.byValues).has(otherByValue)
|
|
197
209
|
)
|
|
198
210
|
) {
|
|
199
|
-
/** @type {ByValues} */
|
|
211
|
+
/** @type {ByValues<T[keyof T] | undefined>} */
|
|
200
212
|
(entry.byValues).set(otherByValue, undefined);
|
|
201
213
|
}
|
|
202
214
|
}
|
|
@@ -237,13 +249,19 @@ const parseObject = (obj) => {
|
|
|
237
249
|
* @returns {T} the object
|
|
238
250
|
*/
|
|
239
251
|
const serializeObject = (info, dynamicInfo) => {
|
|
240
|
-
const obj =
|
|
252
|
+
const obj =
|
|
253
|
+
/** @type {Record<PropertyKey, T[keyof T] | Record<string, Record<PropertyKey, T[keyof T]>> | DynamicFunction>} */
|
|
254
|
+
({});
|
|
241
255
|
// Setup byProperty structure
|
|
242
256
|
for (const entry of info.values()) {
|
|
243
257
|
if (entry.byProperty !== undefined) {
|
|
244
258
|
const byProperty = entry.byProperty;
|
|
245
|
-
const byObj =
|
|
246
|
-
|
|
259
|
+
const byObj =
|
|
260
|
+
/** @type {Record<string, Record<PropertyKey, T[keyof T]>>} */
|
|
261
|
+
(obj[byProperty] = obj[byProperty] || {});
|
|
262
|
+
for (const byValue of /** @type {ByValues<T[keyof T] | undefined>} */ (
|
|
263
|
+
entry.byValues
|
|
264
|
+
).keys()) {
|
|
247
265
|
byObj[byValue] = byObj[byValue] || {};
|
|
248
266
|
}
|
|
249
267
|
}
|
|
@@ -255,10 +273,12 @@ const serializeObject = (info, dynamicInfo) => {
|
|
|
255
273
|
// Fill byProperty structure
|
|
256
274
|
if (entry.byProperty !== undefined) {
|
|
257
275
|
const byProperty = entry.byProperty;
|
|
258
|
-
const byObj =
|
|
276
|
+
const byObj =
|
|
277
|
+
/** @type {Record<string, Record<PropertyKey, T[keyof T]>>} */
|
|
278
|
+
(obj[byProperty] = obj[byProperty] || {});
|
|
259
279
|
for (const byValue of Object.keys(byObj)) {
|
|
260
280
|
const value = getFromByValues(
|
|
261
|
-
/** @type {ByValues} */
|
|
281
|
+
/** @type {ByValues<T[keyof T] | undefined>} */
|
|
262
282
|
(entry.byValues),
|
|
263
283
|
byValue
|
|
264
284
|
);
|
|
@@ -269,7 +289,7 @@ const serializeObject = (info, dynamicInfo) => {
|
|
|
269
289
|
if (dynamicInfo !== undefined) {
|
|
270
290
|
obj[dynamicInfo.byProperty] = dynamicInfo.fn;
|
|
271
291
|
}
|
|
272
|
-
return obj;
|
|
292
|
+
return /** @type {T} */ (obj);
|
|
273
293
|
};
|
|
274
294
|
|
|
275
295
|
const VALUE_TYPE_UNDEFINED = 0;
|
|
@@ -395,7 +415,7 @@ const _cleverMerge = (first, second, internalCaching = false) => {
|
|
|
395
415
|
* @param {ObjectParsedPropertyEntry<T>} firstEntry a
|
|
396
416
|
* @param {ObjectParsedPropertyEntry<O>} secondEntry b
|
|
397
417
|
* @param {boolean} internalCaching should parsing of objects and nested merges be cached
|
|
398
|
-
* @returns {ObjectParsedPropertyEntry<T> | ObjectParsedPropertyEntry<O> | ObjectParsedPropertyEntry<T & O
|
|
418
|
+
* @returns {ObjectParsedPropertyEntry<T> | ObjectParsedPropertyEntry<O> | ObjectParsedPropertyEntry<T & O, MergedValue<T[keyof T] | undefined, O[keyof O] | undefined>>} new entry
|
|
399
419
|
*/
|
|
400
420
|
const mergeEntries = (firstEntry, secondEntry, internalCaching) => {
|
|
401
421
|
switch (getValueType(secondEntry.base)) {
|
|
@@ -420,13 +440,16 @@ const mergeEntries = (firstEntry, secondEntry, internalCaching) => {
|
|
|
420
440
|
} else {
|
|
421
441
|
// = first.base + (first.byProperty + second.byProperty)
|
|
422
442
|
// need to merge first and second byValues
|
|
423
|
-
/** @type {
|
|
443
|
+
/** @type {ByValues<MergedValue<T[keyof T] | undefined, O[keyof O] | undefined>>} */
|
|
424
444
|
const newByValues = new Map(firstEntry.byValues);
|
|
425
|
-
for (const [
|
|
445
|
+
for (const [
|
|
446
|
+
key,
|
|
447
|
+
value
|
|
448
|
+
] of /** @type {ByValues<O[keyof O] | undefined>} */ (
|
|
426
449
|
secondEntry.byValues
|
|
427
450
|
)) {
|
|
428
451
|
const firstValue = getFromByValues(
|
|
429
|
-
/** @type {ByValues} */
|
|
452
|
+
/** @type {ByValues<T[keyof T] | undefined>} */
|
|
430
453
|
(firstEntry.byValues),
|
|
431
454
|
key
|
|
432
455
|
);
|
|
@@ -461,7 +484,7 @@ const mergeEntries = (firstEntry, secondEntry, internalCaching) => {
|
|
|
461
484
|
}
|
|
462
485
|
/** @type {O[keyof O] | T[keyof T] | (T[keyof T] & O[keyof O]) | (T[keyof T] | undefined)[] | (O[keyof O] | undefined)[] | (O[keyof O] | T[keyof T] | undefined)[] | undefined} */
|
|
463
486
|
let newBase;
|
|
464
|
-
/** @type {
|
|
487
|
+
/** @type {ByValues<MergedValue<T[keyof T] | undefined, O[keyof O] | undefined>>} */
|
|
465
488
|
const intermediateByValues = new Map(firstEntry.byValues);
|
|
466
489
|
for (const [key, value] of intermediateByValues) {
|
|
467
490
|
intermediateByValues.set(
|
|
@@ -470,12 +493,14 @@ const mergeEntries = (firstEntry, secondEntry, internalCaching) => {
|
|
|
470
493
|
);
|
|
471
494
|
}
|
|
472
495
|
if (
|
|
473
|
-
[
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
496
|
+
[
|
|
497
|
+
.../** @type {ByValues<T[keyof T] | undefined>} */ (
|
|
498
|
+
firstEntry.byValues
|
|
499
|
+
).values()
|
|
500
|
+
].every((value) => {
|
|
501
|
+
const type = getValueType(value);
|
|
502
|
+
return type === VALUE_TYPE_ATOM || type === VALUE_TYPE_DELETE;
|
|
503
|
+
})
|
|
479
504
|
) {
|
|
480
505
|
// = (first.base + second.base) + ((first.byProperty + second.base) + second.byProperty)
|
|
481
506
|
newBase = mergeSingleValue(
|
|
@@ -502,9 +527,12 @@ const mergeEntries = (firstEntry, secondEntry, internalCaching) => {
|
|
|
502
527
|
`${firstEntry.byProperty} and ${secondEntry.byProperty} for a single property is not supported`
|
|
503
528
|
);
|
|
504
529
|
}
|
|
505
|
-
/** @type {
|
|
530
|
+
/** @type {ByValues<MergedValue<T[keyof T] | undefined, O[keyof O] | undefined>>} */
|
|
506
531
|
const newByValues = new Map(intermediateByValues);
|
|
507
|
-
for (const [
|
|
532
|
+
for (const [
|
|
533
|
+
key,
|
|
534
|
+
value
|
|
535
|
+
] of /** @type {ByValues<O[keyof O] | undefined>} */ (
|
|
508
536
|
secondEntry.byValues
|
|
509
537
|
)) {
|
|
510
538
|
const firstValue = getFromByValues(intermediateByValues, key);
|
|
@@ -525,7 +553,7 @@ const mergeEntries = (firstEntry, secondEntry, internalCaching) => {
|
|
|
525
553
|
/**
|
|
526
554
|
* Gets from by values.
|
|
527
555
|
* @template V
|
|
528
|
-
* @param {ByValues} byValues all values
|
|
556
|
+
* @param {ByValues<V>} byValues all values
|
|
529
557
|
* @param {string} key value of the selector
|
|
530
558
|
* @returns {V | undefined} value
|
|
531
559
|
*/
|
|
@@ -543,7 +571,7 @@ const getFromByValues = (byValues, key) => {
|
|
|
543
571
|
* @param {A | A[]} a value
|
|
544
572
|
* @param {B | B[]} b value
|
|
545
573
|
* @param {boolean} internalCaching should parsing of objects and nested merges be cached
|
|
546
|
-
* @returns {A
|
|
574
|
+
* @returns {MergedValue<A, B>} value
|
|
547
575
|
*/
|
|
548
576
|
const mergeSingleValue = (a, b, internalCaching) => {
|
|
549
577
|
const bType = getValueType(b);
|
|
@@ -635,7 +663,7 @@ const removeOperations = (obj, keysToKeepOriginalValue = []) => {
|
|
|
635
663
|
newObj[key] =
|
|
636
664
|
/** @type {T[keyof T]} */
|
|
637
665
|
(
|
|
638
|
-
/** @type {
|
|
666
|
+
/** @type {T[keyof T] extends readonly (infer E)[] ? E[] : never} */
|
|
639
667
|
(value).filter((i) => i !== "...")
|
|
640
668
|
);
|
|
641
669
|
break;
|