webpack 5.110.3 → 5.111.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/lib/APIPlugin.js +23 -7
- package/lib/AutomaticPrefetchPlugin.js +1 -1
- package/lib/Cache.js +8 -3
- package/lib/CacheFacade.js +1 -1
- package/lib/CircularModulesPlugin.js +157 -55
- package/lib/CleanPlugin.js +2 -2
- package/lib/Compilation.js +320 -302
- package/lib/Compiler.js +209 -46
- package/lib/ContextModule.js +17 -81
- package/lib/ContextModuleFactory.js +1 -1
- package/lib/CopyPlugin.js +1054 -0
- package/lib/DefinePlugin.js +24 -8
- package/lib/ExternalModule.js +41 -14
- package/lib/FileSystemInfo.js +17 -14
- package/lib/FlagDependencyExportsPlugin.js +45 -21
- package/lib/HotModuleReplacementPlugin.js +53 -7
- package/lib/JavascriptMetaInfoPlugin.js +5 -3
- package/lib/MainTemplate.js +5 -1
- package/lib/Module.js +16 -7
- package/lib/MultiCompiler.js +1 -1
- package/lib/MultiWatching.js +1 -1
- package/lib/NormalModule.js +45 -12
- package/lib/NormalModuleFactory.js +1 -1
- package/lib/RuntimeGlobals.js +21 -7
- package/lib/RuntimeModule.js +28 -12
- package/lib/RuntimePlugin.js +30 -3
- package/lib/RuntimeTemplate.js +780 -475
- package/lib/SourceMapDevToolPlugin.js +1 -1
- package/lib/Watching.js +9 -0
- package/lib/WebpackOptionsApply.js +84 -91
- package/lib/asset/AssetGenerator.js +25 -8
- package/lib/asset/AssetModule.js +3 -0
- package/lib/asset/WebManifestParser.js +7 -5
- package/lib/cache/AddBuildDependenciesPlugin.js +33 -4
- package/lib/cache/IdleFileCachePlugin.js +2 -2
- package/lib/cache/PackFileCacheStrategy.js +14 -1
- package/lib/config/browserslistTargetHandler.js +19 -0
- package/lib/config/defaults.js +86 -50
- package/lib/config/normalization.js +82 -12
- package/lib/config/target.js +10 -0
- package/lib/container/ContainerReferencePlugin.js +6 -0
- package/lib/container/RemoteRuntimeModule.js +9 -0
- package/lib/container/declaredRemotes.js +39 -0
- package/lib/css/CssGenerator.js +8 -0
- package/lib/css/CssInjectStyleRuntimeModule.js +9 -0
- package/lib/css/CssLoadingRuntimeModule.js +94 -36
- package/lib/css/CssModule.js +1 -1
- package/lib/css/CssModulesPlugin.js +7 -6
- package/lib/css/CssParser.js +144 -11
- package/lib/css/CssServerStylesRuntimeModule.js +9 -0
- package/lib/css/cssMinify.js +11 -3
- package/lib/css/data.js +2814 -678
- package/lib/css/syntax.js +4082 -248
- package/lib/debug/ProfilingPlugin.js +4 -0
- package/lib/dependencies/AMDDefineDependencyParserPlugin.js +6 -3
- package/lib/dependencies/AMDRuntimeModules.js +18 -0
- package/lib/dependencies/CommonJsExportRequireDependency.js +3 -1
- package/lib/dependencies/CommonJsExportsParserPlugin.js +12 -13
- package/lib/dependencies/CommonJsImportsParserPlugin.js +1 -0
- package/lib/dependencies/CommonJsPlugin.js +19 -3
- package/lib/dependencies/CommonJsRequireDependency.js +14 -5
- package/lib/dependencies/CssIcssExportDependency.js +7 -1
- package/lib/dependencies/HarmonyCompatibilityDependency.js +58 -4
- package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +8 -3
- package/lib/dependencies/HarmonyExportExpressionDependency.js +44 -29
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +71 -13
- package/lib/dependencies/HarmonyExportInitFragment.js +99 -19
- package/lib/dependencies/HarmonyExportSpecifierDependency.js +18 -30
- package/lib/dependencies/HarmonyImportBareSideEffectDependency.js +59 -0
- package/lib/dependencies/HarmonyImportDependency.js +6 -1
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +8 -1
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +24 -1
- package/lib/dependencies/HarmonyModulesPlugin.js +20 -0
- package/lib/dependencies/HtmlEntryDependency.js +50 -0
- package/lib/dependencies/ImportMetaMainDependency.js +104 -0
- package/lib/dependencies/ImportMetaPlugin.js +59 -15
- package/lib/dependencies/SystemRuntimeModule.js +9 -0
- package/lib/dependencies/WorkerDependency.js +1 -2
- package/lib/dependencies/WorkletDependency.js +1 -2
- package/lib/dll/DelegatedModule.js +18 -1
- package/lib/dll/DllReferencePlugin.js +11 -8
- package/lib/dll/LibManifestPlugin.js +1 -1
- package/lib/errors/AnalyzableBailoutsWarning.js +41 -0
- package/lib/errors/DuplicateModulesWarning.js +12 -7
- package/lib/errors/EmptyCopyPatternWarning.js +26 -0
- package/lib/errors/ExternalStarReexportError.js +44 -0
- package/lib/errors/MissingSourceMapsWarning.js +36 -0
- package/lib/errors/ModuleParseError.js +2 -1
- package/lib/errors/UnusedAssetsWarning.js +36 -0
- package/lib/errors/UnusedFederationWarning.js +35 -0
- package/lib/errors/UnusedModulesWarning.js +38 -0
- package/lib/esm/ExportWebpackRequireRuntimeModule.js +9 -0
- package/lib/esm/ModuleChunkFormatPlugin.js +28 -3
- package/lib/esm/ModuleChunkLoadingPlugin.js +30 -11
- package/lib/esm/ModuleChunkLoadingRuntimeModule.js +92 -60
- package/lib/hmr/HotModuleReplacement.runtime.js +8 -2
- package/lib/hmr/HotModuleReplacementRuntimeModule.js +9 -0
- package/lib/html/HtmlGenerator.js +11 -5
- package/lib/html/HtmlModulesPlugin.js +331 -62
- package/lib/html/HtmlParser.js +13 -6
- package/lib/html/builtinEmbeddedRenderer.js +107 -0
- package/lib/html/data.js +121 -7
- package/lib/html/htmlMinify.js +84 -113
- package/lib/html/syntax.js +763 -426
- package/lib/ids/HashedModuleIdsPlugin.js +2 -1
- package/lib/index.js +3 -0
- package/lib/javascript/JavascriptModule.js +1 -0
- package/lib/javascript/JavascriptModulesPlugin.js +52 -24
- package/lib/javascript/JavascriptParser.js +1255 -728
- package/lib/javascript/StartupHelpers.js +27 -3
- package/lib/javascript/data.js +172 -0
- package/lib/javascript/grammar.js +5546 -0
- package/lib/javascript/parser.js +1494 -0
- package/lib/javascript/regexp.js +1762 -0
- package/lib/javascript/regexpData.js +51 -0
- package/lib/javascript/syntax.js +8696 -5225
- package/lib/library/ModuleLibraryPlugin.js +116 -5
- package/lib/node/ReadFileChunkLoadingRuntimeModule.js +22 -0
- package/lib/node/RequireChunkLoadingRuntimeModule.js +22 -0
- package/lib/optimize/ConcatenatedModule.js +97 -20
- package/lib/optimize/ConstExportsPlugin.js +50 -39
- package/lib/optimize/InlineExports.js +20 -123
- package/lib/optimize/MangleExportsPlugin.js +10 -0
- package/lib/optimize/ModuleConcatenationPlugin.js +24 -1
- package/lib/optimize/RealContentHashPlugin.js +68 -9
- package/lib/optimize/SideEffectsFlagPlugin.js +17 -9
- package/lib/performance/AnalyzableBailoutsPlugin.js +115 -0
- package/lib/performance/CacheEffectivenessPlugin.js +4 -3
- package/lib/performance/DuplicateModulesPlugin.js +57 -13
- package/lib/performance/EvalUsagePlugin.js +5 -2
- package/lib/performance/MissingSourceMapsPlugin.js +115 -0
- package/lib/performance/PureAnnotationsPlugin.js +6 -3
- package/lib/performance/TopLevelThisPlugin.js +5 -4
- package/lib/performance/UnusedAssetsPlugin.js +109 -0
- package/lib/performance/UnusedFederationPlugin.js +147 -0
- package/lib/performance/UnusedModulesPlugin.js +141 -0
- package/lib/performance/UnusedReexportsPlugin.js +1 -55
- package/lib/performance/isOnlyReexported.js +65 -0
- package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +25 -5
- package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +2 -0
- package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +9 -0
- package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +9 -0
- package/lib/prefetch/ChunkPreloadTriggerRuntimeModule.js +9 -0
- package/lib/prefetch/ResourceHintPlugin.js +1 -2
- package/lib/prefetch/ResourceHintRuntimeModule.js +9 -0
- package/lib/prefetch/StartupAssetHintRuntimeModule.js +9 -0
- package/lib/rules/RuleSetCompiler.js +211 -4
- package/lib/runtime/AsyncModuleRuntimeModule.js +100 -66
- package/lib/runtime/AutoPublicPathRuntimeModule.js +9 -0
- package/lib/runtime/BaseUriRuntimeModule.js +9 -0
- package/lib/runtime/ChunkNameRuntimeModule.js +9 -0
- package/lib/runtime/EnsureChunkRuntimeModule.js +35 -16
- package/lib/runtime/GetChunkFilenameRuntimeModule.js +9 -0
- package/lib/runtime/GetFullHashRuntimeModule.js +9 -0
- package/lib/runtime/GetMainFilenameRuntimeModule.js +9 -0
- package/lib/runtime/GetWorkletBootstrapRuntimeModule.js +9 -0
- package/lib/runtime/GlobalRuntimeModule.js +9 -0
- package/lib/runtime/HasOwnPropertyRuntimeModule.js +9 -0
- package/lib/runtime/HelperRuntimeModule.js +10 -0
- package/lib/runtime/MakeDeferredNamespaceObjectRuntime.js +330 -219
- package/lib/runtime/NonceRuntimeModule.js +9 -0
- package/lib/runtime/OnChunksLoadedRuntimeModule.js +67 -20
- package/lib/runtime/PublicPathRuntimeModule.js +9 -0
- package/lib/runtime/RuntimeIdRuntimeModule.js +9 -0
- package/lib/runtime/SpecNamespaceObjectRuntimeModule.js +90 -0
- package/lib/runtime/StartupChunkDependenciesRuntimeModule.js +9 -0
- package/lib/runtime/StartupEntrypointRuntimeModule.js +9 -0
- package/lib/runtime/SystemContextRuntimeModule.js +9 -0
- package/lib/runtime/ToBinaryRuntimeModule.js +9 -0
- package/lib/serialization/ObjectMiddleware.js +138 -106
- package/lib/sharing/ConsumeSharedPlugin.js +12 -0
- package/lib/sharing/ConsumeSharedRuntimeModule.js +11 -0
- package/lib/sharing/ShareRuntimeModule.js +9 -0
- package/lib/sharing/declaredShared.js +47 -0
- package/lib/stats/DefaultStatsFactoryPlugin.js +3 -1
- package/lib/stats/DefaultStatsPrinterPlugin.js +3 -0
- package/lib/util/SourceProcessor.js +76 -69
- package/lib/util/async.js +292 -0
- package/lib/util/buildDiagnostics.js +69 -0
- package/lib/util/fs.js +27 -1
- package/lib/util/handlerKeys.js +40 -0
- package/lib/util/identifier.js +20 -0
- package/lib/util/internalSerializables.js +4 -0
- package/lib/util/registerExternalSerializer.js +6 -45
- package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +9 -0
- package/lib/wasm-async/AsyncWasmLoadingRuntimeModule.js +9 -0
- package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +9 -0
- package/lib/web/JsonpChunkLoadingRuntimeModule.js +36 -0
- package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +19 -0
- package/package.json +22 -16
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +379 -66
- package/schemas/plugins/LoaderOptionsPlugin.check.js +1 -1
- package/schemas/plugins/ManifestPlugin.check.js +1 -1
- package/schemas/plugins/SourceMapDevToolPlugin.check.js +1 -1
- package/schemas/plugins/asset/AssetGeneratorOptions.check.js +1 -1
- package/schemas/plugins/asset/AssetResourceGeneratorOptions.check.js +1 -1
- package/schemas/plugins/container/ContainerPlugin.check.js +1 -1
- package/schemas/plugins/container/ModuleFederationPlugin.check.js +1 -1
- package/schemas/plugins/debug/ProfilingPlugin.check.js +1 -1
- package/schemas/plugins/dll/DllReferencePlugin.check.js +1 -1
- package/schemas/plugins/ids/HashedModuleIdsPlugin.check.js +1 -1
- package/schemas/plugins/schemes/HttpUriPlugin.check.js +1 -1
- package/types.d.ts +1414 -314
- package/lib/dependencies/ExportBindingInitFragment.js +0 -191
- package/lib/errors/EntrypointOverlapWarning.js +0 -45
- package/lib/performance/EntrypointOverlapPlugin.js +0 -122
|
@@ -15,6 +15,7 @@ const ConsumeSharedFallbackDependency = require("./ConsumeSharedFallbackDependen
|
|
|
15
15
|
const ConsumeSharedModule = require("./ConsumeSharedModule");
|
|
16
16
|
const ConsumeSharedRuntimeModule = require("./ConsumeSharedRuntimeModule");
|
|
17
17
|
const ProvideForSharedDependency = require("./ProvideForSharedDependency");
|
|
18
|
+
const { addDeclaredShared } = require("./declaredShared");
|
|
18
19
|
const { resolveMatchedConfigs } = require("./resolveMatchedConfigs");
|
|
19
20
|
const {
|
|
20
21
|
getDescriptionFile,
|
|
@@ -137,6 +138,17 @@ class ConsumeSharedPlugin {
|
|
|
137
138
|
normalModuleFactory
|
|
138
139
|
);
|
|
139
140
|
|
|
141
|
+
// A key ending in a slash shares everything under it, and the
|
|
142
|
+
// modules then carry the remainder appended to the share key.
|
|
143
|
+
addDeclaredShared(
|
|
144
|
+
compilation,
|
|
145
|
+
consumes.map(([key, config]) => ({
|
|
146
|
+
name: key,
|
|
147
|
+
shareKey: config.shareKey,
|
|
148
|
+
prefix: key.endsWith("/")
|
|
149
|
+
}))
|
|
150
|
+
);
|
|
151
|
+
|
|
140
152
|
/** @typedef {Map<string, ConsumeOptions>} Consumes */
|
|
141
153
|
|
|
142
154
|
/** @type {Consumes} */
|
|
@@ -33,6 +33,17 @@ class ConsumeSharedRuntimeModule extends RuntimeModule {
|
|
|
33
33
|
this._runtimeRequirements = runtimeRequirements;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* The `[handlerMap, key]` pairs this module installs onto a chunk handler map
|
|
38
|
+
* such as `__webpack_require__.f`, or `null` where it cannot name them.
|
|
39
|
+
* @returns {[string, string][] | null} installed chunk handlers (do not mutate)
|
|
40
|
+
*/
|
|
41
|
+
getInstalledChunkHandlers() {
|
|
42
|
+
return this._runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers)
|
|
43
|
+
? [[RuntimeGlobals.ensureChunkHandlers, "consumes"]]
|
|
44
|
+
: [];
|
|
45
|
+
}
|
|
46
|
+
|
|
36
47
|
/**
|
|
37
48
|
* Generates runtime code for this runtime module.
|
|
38
49
|
* @returns {string | null} runtime code
|
|
@@ -23,6 +23,15 @@ class ShareRuntimeModule extends RuntimeModule {
|
|
|
23
23
|
super("sharing");
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* The `[handlerMap, key]` pairs this module installs onto a chunk handler map
|
|
28
|
+
* such as `__webpack_require__.f`, or `null` where it cannot name them.
|
|
29
|
+
* @returns {[string, string][] | null} installed chunk handlers (do not mutate)
|
|
30
|
+
*/
|
|
31
|
+
getInstalledChunkHandlers() {
|
|
32
|
+
return RuntimeModule.NO_CHUNK_HANDLERS;
|
|
33
|
+
}
|
|
34
|
+
|
|
26
35
|
/**
|
|
27
36
|
* Generates runtime code for this runtime module.
|
|
28
37
|
* @returns {string | null} runtime code
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/*
|
|
2
|
+
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
3
|
+
Author Alexander Akait @alexander-akait
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
/** @import Compilation from "../Compilation" */
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {object} SharedDeclaration
|
|
12
|
+
* @property {string} name the config key, as the config spells it
|
|
13
|
+
* @property {string} shareKey the key the modules created for it carry
|
|
14
|
+
* @property {boolean} prefix whether it shares everything under the key
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** @type {WeakMap<Compilation, SharedDeclaration[]>} */
|
|
18
|
+
const DECLARED_SHARED = new WeakMap();
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* What this build declared as shared, one entry per config key, since several
|
|
22
|
+
* may name one share key. `performance.unusedConfig` matches modules on the
|
|
23
|
+
* share key and reports the config key.
|
|
24
|
+
* @param {Compilation} compilation the compilation
|
|
25
|
+
* @returns {SharedDeclaration[] | undefined} the declarations, when any were made
|
|
26
|
+
*/
|
|
27
|
+
const getDeclaredShared = (compilation) => DECLARED_SHARED.get(compilation);
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Records declarations, appending when a build applies the plugin more than
|
|
31
|
+
* once, as `ModuleFederationPlugin` and `SharePlugin` do.
|
|
32
|
+
* @param {Compilation} compilation the compilation
|
|
33
|
+
* @param {SharedDeclaration[]} declarations what this application declared
|
|
34
|
+
* @returns {void}
|
|
35
|
+
*/
|
|
36
|
+
const addDeclaredShared = (compilation, declarations) => {
|
|
37
|
+
const declared = DECLARED_SHARED.get(compilation);
|
|
38
|
+
|
|
39
|
+
if (declared === undefined) {
|
|
40
|
+
DECLARED_SHARED.set(compilation, [...declarations]);
|
|
41
|
+
} else {
|
|
42
|
+
for (const declaration of declarations) declared.push(declaration);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
module.exports.addDeclaredShared = addDeclaredShared;
|
|
47
|
+
module.exports.getDeclaredShared = getDeclaredShared;
|
|
@@ -1340,9 +1340,11 @@ const SIMPLE_EXTRACTORS = {
|
|
|
1340
1340
|
const warnings = module.getWarnings();
|
|
1341
1341
|
const warningsCount =
|
|
1342
1342
|
warnings !== undefined ? countIterable(warnings) : 0;
|
|
1343
|
-
const { cacheable,
|
|
1343
|
+
const { cacheable, diagnostics } = /** @type {BuildInfo} */ (
|
|
1344
1344
|
module.buildInfo
|
|
1345
1345
|
);
|
|
1346
|
+
const notCacheableReasons =
|
|
1347
|
+
diagnostics === undefined ? undefined : diagnostics.notCacheableReasons;
|
|
1346
1348
|
const preOrderIndex = /** @type {number} */ (
|
|
1347
1349
|
moduleGraph.getPreOrderIndex(module)
|
|
1348
1350
|
);
|
|
@@ -460,6 +460,8 @@ const ASSET_SIMPLE_PRINTERS = {
|
|
|
460
460
|
javascriptModule ? formatFlag("javascript module") : undefined,
|
|
461
461
|
"asset.info.sourceFilename": (sourceFilename, { formatFlag }) =>
|
|
462
462
|
sourceFilename ? formatFlag(`from: ${sourceFilename}`) : undefined,
|
|
463
|
+
"asset.info.copied": (copied, { green, formatFlag }) =>
|
|
464
|
+
copied ? green(formatFlag("copied")) : undefined,
|
|
463
465
|
"asset.info.development": (development, { green, formatFlag }) =>
|
|
464
466
|
development ? green(formatFlag("dev")) : undefined,
|
|
465
467
|
"asset.info.hotModuleReplacement": (
|
|
@@ -1045,6 +1047,7 @@ const PREFERRED_ORDERS = {
|
|
|
1045
1047
|
"asset.info": [
|
|
1046
1048
|
"immutable",
|
|
1047
1049
|
"sourceFilename",
|
|
1050
|
+
"copied",
|
|
1048
1051
|
"javascriptModule",
|
|
1049
1052
|
"development",
|
|
1050
1053
|
"hotModuleReplacement"
|
|
@@ -261,14 +261,17 @@ class PrintContext {
|
|
|
261
261
|
/** @type {NodePrinter<TPath, TNode, TPrintOptions>} */
|
|
262
262
|
this._printer = printer;
|
|
263
263
|
// Printed text by node handle, in two columns rather than one `Map`: the
|
|
264
|
-
// handles are dense integers, and
|
|
265
|
-
// a store that never holds more than a few dozen of them at once.
|
|
264
|
+
// handles are dense integers, and `_moveEpoch` keeps the live set small.
|
|
266
265
|
/** @type {string[]} each finished node's printed text */
|
|
267
266
|
this._storeText = [];
|
|
268
267
|
/** @type {Int32Array} the epoch each slot was written in */
|
|
269
268
|
this._storeGen = new Int32Array(0);
|
|
270
269
|
/** @type {number} current epoch; a slot from an older one reads as absent */
|
|
271
270
|
this._gen = 1;
|
|
271
|
+
/** @type {number} lowest slot written since the epoch last moved */
|
|
272
|
+
this._storeLow = 0x7fffffff;
|
|
273
|
+
/** @type {number} highest slot written since the epoch last moved */
|
|
274
|
+
this._storeHigh = -1;
|
|
272
275
|
// Output accumulates into `_tail`, a plain string append, so printing that
|
|
273
276
|
// never takes anything back costs exactly what appending to one string
|
|
274
277
|
// costs. A piece is cut off into `_chunks` only for text that may still be
|
|
@@ -285,7 +288,7 @@ class PrintContext {
|
|
|
285
288
|
this._flattened = 0;
|
|
286
289
|
/** @type {[number, number, number, number][]} `[chunkIndex, offsetInChunk, srcLine, srcCol]`, output-ordered; a `srcLine` of -1 is one {@link retract} took back with its piece */
|
|
287
290
|
this._mappings = [];
|
|
288
|
-
/** @type {
|
|
291
|
+
/** @type {number[] | null} by retractable piece index, the mapping anchored to it, so taking the piece back takes its mapping too */
|
|
289
292
|
this._retractableMappings = null;
|
|
290
293
|
// A map is built only for a caller that named the input, and that is known
|
|
291
294
|
// before printing — so a print nobody asks a map of collects none.
|
|
@@ -424,8 +427,25 @@ class PrintContext {
|
|
|
424
427
|
* node's text.
|
|
425
428
|
*/
|
|
426
429
|
dropStore() {
|
|
427
|
-
|
|
428
|
-
|
|
430
|
+
this._moveEpoch();
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Move the epoch on and release the text every slot written under the old one
|
|
435
|
+
* holds. Only the range actually written is walked, so the drop stays O(1)
|
|
436
|
+
* per node.
|
|
437
|
+
* @returns {void}
|
|
438
|
+
*/
|
|
439
|
+
_moveEpoch() {
|
|
440
|
+
const high = this._storeHigh;
|
|
441
|
+
if (high !== -1) {
|
|
442
|
+
// `""` rather than a hole: the column is packed, and a hole in it would
|
|
443
|
+
// cost every read after this one.
|
|
444
|
+
const text = this._storeText;
|
|
445
|
+
for (let i = this._storeLow; i <= high; i++) text[i] = "";
|
|
446
|
+
this._storeLow = 0x7fffffff;
|
|
447
|
+
this._storeHigh = -1;
|
|
448
|
+
}
|
|
429
449
|
this._gen++;
|
|
430
450
|
}
|
|
431
451
|
|
|
@@ -469,6 +489,8 @@ class PrintContext {
|
|
|
469
489
|
if (n >= this._storeText.length) this._growStore(n + 1);
|
|
470
490
|
this._storeText[n] = text;
|
|
471
491
|
this._storeGen[n] = this._gen;
|
|
492
|
+
if (n < this._storeLow) this._storeLow = n;
|
|
493
|
+
if (n > this._storeHigh) this._storeHigh = n;
|
|
472
494
|
}
|
|
473
495
|
|
|
474
496
|
/**
|
|
@@ -552,7 +574,7 @@ class PrintContext {
|
|
|
552
574
|
retract(index) {
|
|
553
575
|
this._chunks[index] = "";
|
|
554
576
|
if (this._retractableMappings === null) return;
|
|
555
|
-
const mapping = this._retractableMappings
|
|
577
|
+
const mapping = this._retractableMappings[index];
|
|
556
578
|
if (mapping !== undefined) this._mappings[mapping][2] = -1;
|
|
557
579
|
}
|
|
558
580
|
|
|
@@ -598,12 +620,12 @@ class PrintContext {
|
|
|
598
620
|
this.anchor(srcOffset, srcLine, srcCol);
|
|
599
621
|
const mapping = this._mappings.length > before ? before : -1;
|
|
600
622
|
const at = this.emitRetractable(text === undefined ? this.get(node) : text);
|
|
601
|
-
this.
|
|
623
|
+
this._moveEpoch();
|
|
602
624
|
if (mapping !== -1) {
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
this._retractableMappings
|
|
625
|
+
// Indexed by piece rather than a `Map`: pieces are dense integers, and
|
|
626
|
+
// nearly every rule minifying goes out as one.
|
|
627
|
+
if (this._retractableMappings === null) this._retractableMappings = [];
|
|
628
|
+
this._retractableMappings[at] = mapping;
|
|
607
629
|
}
|
|
608
630
|
return at;
|
|
609
631
|
}
|
|
@@ -627,7 +649,7 @@ class PrintContext {
|
|
|
627
649
|
this._emit(
|
|
628
650
|
text === undefined ? this.get(/** @type {TNode} */ (node)) : text
|
|
629
651
|
);
|
|
630
|
-
this.
|
|
652
|
+
this._moveEpoch();
|
|
631
653
|
}
|
|
632
654
|
|
|
633
655
|
/**
|
|
@@ -739,68 +761,44 @@ class PrintContext {
|
|
|
739
761
|
|
|
740
762
|
/**
|
|
741
763
|
* @param {SourceMapOptions} options the input's name / content
|
|
764
|
+
* @param {string=} code the output {@link result} built, walked for its line breaks
|
|
742
765
|
* @returns {SourceMap} the input->output source map
|
|
743
766
|
*/
|
|
744
|
-
sourceMap(options) {
|
|
767
|
+
sourceMap(options, code) {
|
|
745
768
|
let out = "";
|
|
746
769
|
let genLine = 0;
|
|
747
770
|
let genCol = 0;
|
|
748
771
|
let srcLine = 0;
|
|
749
772
|
let srcCol = 0;
|
|
750
773
|
let atLineStart = true;
|
|
751
|
-
//
|
|
752
|
-
//
|
|
753
|
-
|
|
754
|
-
// its start, since output accumulates into the piece it is appending to.
|
|
774
|
+
// Walked over the flat output rather than piece by piece: a piece is a rope
|
|
775
|
+
// until something reads it, and reading each one flattens each one.
|
|
776
|
+
const text = code === undefined ? this.result() : code;
|
|
755
777
|
const chunks = this._chunks;
|
|
756
|
-
const tail = this._tail;
|
|
757
|
-
/**
|
|
758
|
-
* @param {number} i piece index, `chunks.length` being the tail
|
|
759
|
-
* @returns {string} that piece
|
|
760
|
-
*/
|
|
761
|
-
const pieceAt = (i) => (i === chunks.length ? tail : chunks[i]);
|
|
762
778
|
let atChunk = 0;
|
|
779
|
+
let chunkStart = 0;
|
|
763
780
|
let atOffset = 0;
|
|
764
781
|
let atLine = 0;
|
|
765
782
|
let atCol = 0;
|
|
766
|
-
// Offset of the next newline at or after the cursor, `-1` for none left
|
|
767
|
-
//
|
|
768
|
-
|
|
769
|
-
// the end of the piece every time — and minified output, the case with no
|
|
770
|
-
// newlines at all, is the one where that is the whole piece.
|
|
771
|
-
let nextNewline = pieceAt(0).indexOf("\n");
|
|
772
|
-
/**
|
|
773
|
-
* @param {string} text the piece to walk
|
|
774
|
-
* @param {number} to offset to walk to
|
|
775
|
-
*/
|
|
776
|
-
const advanceOver = (text, to) => {
|
|
777
|
-
while (nextNewline !== -1 && nextNewline < to) {
|
|
778
|
-
atLine++;
|
|
779
|
-
atCol = 0;
|
|
780
|
-
atOffset = nextNewline + 1;
|
|
781
|
-
nextNewline = text.indexOf("\n", atOffset);
|
|
782
|
-
}
|
|
783
|
-
atCol += to - atOffset;
|
|
784
|
-
atOffset = to;
|
|
785
|
-
};
|
|
786
|
-
/**
|
|
787
|
-
* @param {number} chunk piece index to advance to
|
|
788
|
-
* @param {number} offset offset within it
|
|
789
|
-
*/
|
|
790
|
-
const advanceTo = (chunk, offset) => {
|
|
791
|
-
while (atChunk < chunk) {
|
|
792
|
-
const text = pieceAt(atChunk);
|
|
793
|
-
advanceOver(text, text.length);
|
|
794
|
-
atChunk++;
|
|
795
|
-
atOffset = 0;
|
|
796
|
-
nextNewline = pieceAt(atChunk).indexOf("\n");
|
|
797
|
-
}
|
|
798
|
-
if (offset > atOffset) advanceOver(pieceAt(atChunk), offset);
|
|
799
|
-
};
|
|
783
|
+
// Offset of the next newline at or after the cursor, `-1` for none left.
|
|
784
|
+
// Carried rather than searched for per mapping: `indexOf` has no end bound.
|
|
785
|
+
let nextNewline = text.indexOf("\n");
|
|
800
786
|
for (const [chunkIndex, chunkOffset, sl, sc] of this._mappings) {
|
|
801
787
|
// Its piece was taken back, so there is no output left to anchor.
|
|
802
788
|
if (sl === -1) continue;
|
|
803
|
-
|
|
789
|
+
// A piece's length is stored, so summing them costs nothing per byte.
|
|
790
|
+
while (atChunk < chunkIndex) chunkStart += chunks[atChunk++].length;
|
|
791
|
+
const to = chunkStart + chunkOffset;
|
|
792
|
+
if (to > atOffset) {
|
|
793
|
+
while (nextNewline !== -1 && nextNewline < to) {
|
|
794
|
+
atLine++;
|
|
795
|
+
atCol = 0;
|
|
796
|
+
atOffset = nextNewline + 1;
|
|
797
|
+
nextNewline = text.indexOf("\n", atOffset);
|
|
798
|
+
}
|
|
799
|
+
atCol += to - atOffset;
|
|
800
|
+
atOffset = to;
|
|
801
|
+
}
|
|
804
802
|
const gl = atLine;
|
|
805
803
|
const gc = atCol;
|
|
806
804
|
while (genLine < gl) {
|
|
@@ -915,7 +913,11 @@ class PrintContext {
|
|
|
915
913
|
if (this._insertIdx < this._inserts.length) this._flushBefore(Infinity);
|
|
916
914
|
// Nothing was ever cut into its own piece, so there is nothing to join.
|
|
917
915
|
const chunks = this._chunks;
|
|
918
|
-
|
|
916
|
+
if (chunks.length === 0) return this._tail;
|
|
917
|
+
// The tail joins as a piece of its own, so the output comes back flat
|
|
918
|
+
// rather than as a rope over the join that every reader flattens again.
|
|
919
|
+
this._cutTail();
|
|
920
|
+
return chunks.join("");
|
|
919
921
|
}
|
|
920
922
|
}
|
|
921
923
|
|
|
@@ -1030,16 +1032,21 @@ class SourceProcessor {
|
|
|
1030
1032
|
);
|
|
1031
1033
|
this._grammar(input, this._visitors, ctx, opts);
|
|
1032
1034
|
const name = /** @type {{ source?: string, content?: string }} */ (opts);
|
|
1033
|
-
const build = () =>
|
|
1034
|
-
code
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1035
|
+
const build = () => {
|
|
1036
|
+
const code = ctx.result();
|
|
1037
|
+
return {
|
|
1038
|
+
code,
|
|
1039
|
+
// Built only for a caller that named the input: a map walks the whole
|
|
1040
|
+
// output, and an inline `style=""` asks for none thousands of times a page.
|
|
1041
|
+
map:
|
|
1042
|
+
name.source === undefined
|
|
1043
|
+
? undefined
|
|
1044
|
+
: ctx.sourceMap(
|
|
1045
|
+
{ source: name.source, content: name.content },
|
|
1046
|
+
code
|
|
1047
|
+
)
|
|
1048
|
+
};
|
|
1049
|
+
};
|
|
1043
1050
|
if (this._deferred !== null) {
|
|
1044
1051
|
const finish = this._deferred;
|
|
1045
1052
|
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/*
|
|
2
|
+
MIT License http://www.opensource.org/licenses/mit-license.php
|
|
3
|
+
Author Alexander Akait @alexander-akait
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Wraps the shared completion callback for one item, so an iterator that
|
|
10
|
+
* reports twice fails loudly instead of settling the run early.
|
|
11
|
+
* @template E
|
|
12
|
+
* @param {(err?: E | null) => void} done shared completion callback
|
|
13
|
+
* @returns {(err?: E | null) => void} completion callback for a single item
|
|
14
|
+
*/
|
|
15
|
+
const once = (done) => {
|
|
16
|
+
/** @type {((err?: E | null) => void) | undefined} */
|
|
17
|
+
let pending = done;
|
|
18
|
+
return (err) => {
|
|
19
|
+
const fn = pending;
|
|
20
|
+
if (fn === undefined) throw new Error("Callback was already called");
|
|
21
|
+
pending = undefined;
|
|
22
|
+
fn(err);
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Runs `iterator` over every item with unlimited concurrency.
|
|
28
|
+
* Every item is started from one flat loop, so a synchronous iterator never
|
|
29
|
+
* grows the stack.
|
|
30
|
+
* @template T
|
|
31
|
+
* @template E
|
|
32
|
+
* @param {Iterable<T>} collection items to iterate
|
|
33
|
+
* @param {(item: T, callback: (err?: E | null) => void) => void} iterator called once per item
|
|
34
|
+
* @param {(err?: E | null) => void} callback called when every item is done, or with the first error
|
|
35
|
+
* @returns {void}
|
|
36
|
+
*/
|
|
37
|
+
const each = (collection, iterator, callback) => {
|
|
38
|
+
let remaining = 1;
|
|
39
|
+
let finished = false;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {(E | null)=} err error
|
|
43
|
+
* @returns {void}
|
|
44
|
+
*/
|
|
45
|
+
const done = (err) => {
|
|
46
|
+
if (finished) return;
|
|
47
|
+
if (err) {
|
|
48
|
+
finished = true;
|
|
49
|
+
callback(err);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (--remaining === 0) {
|
|
53
|
+
finished = true;
|
|
54
|
+
callback(null);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
if (Array.isArray(collection)) {
|
|
59
|
+
const array = /** @type {T[]} */ (collection);
|
|
60
|
+
const length = array.length;
|
|
61
|
+
if (length === 0) return callback(null);
|
|
62
|
+
remaining = length;
|
|
63
|
+
// Dispatching continues past an error on purpose: callers rely on every
|
|
64
|
+
// item being started, e.g. to close every watcher when one close fails.
|
|
65
|
+
for (let i = 0; i < length; i++) iterator(array[i], once(done));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// `remaining` starts at 1 so that completion cannot fire while items of a
|
|
70
|
+
// collection of unknown length are still being dispatched.
|
|
71
|
+
for (const item of collection) {
|
|
72
|
+
remaining++;
|
|
73
|
+
iterator(item, once(done));
|
|
74
|
+
}
|
|
75
|
+
done(null);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Runs `iterator` over every item, keeping at most `limit` of them in flight.
|
|
80
|
+
* A synchronous iterator is drained by the dispatch loop instead of by
|
|
81
|
+
* recursion, so the stack stays flat however long the collection is.
|
|
82
|
+
* @template T
|
|
83
|
+
* @template E
|
|
84
|
+
* @param {Iterable<T>} collection items to iterate
|
|
85
|
+
* @param {number} limit maximum number of items in flight
|
|
86
|
+
* @param {(item: T, callback: (err?: E | null) => void) => void} iterator called once per item
|
|
87
|
+
* @param {(err?: E | null) => void} callback called when every item is done, or with the first error
|
|
88
|
+
* @returns {void}
|
|
89
|
+
*/
|
|
90
|
+
const eachLimit = (collection, limit, iterator, callback) => {
|
|
91
|
+
const array = Array.isArray(collection)
|
|
92
|
+
? /** @type {T[]} */ (collection)
|
|
93
|
+
: undefined;
|
|
94
|
+
const length = array === undefined ? 0 : array.length;
|
|
95
|
+
const values =
|
|
96
|
+
array === undefined ? collection[Symbol.iterator]() : undefined;
|
|
97
|
+
let index = 0;
|
|
98
|
+
let running = 0;
|
|
99
|
+
let exhausted = false;
|
|
100
|
+
let finished = false;
|
|
101
|
+
let dispatching = false;
|
|
102
|
+
|
|
103
|
+
const dispatch = () => {
|
|
104
|
+
// A re-entrant call returns at once; the loop already running sees the
|
|
105
|
+
// slot the completed item freed and takes the next one itself.
|
|
106
|
+
if (dispatching) return;
|
|
107
|
+
dispatching = true;
|
|
108
|
+
while (running < limit && !exhausted) {
|
|
109
|
+
// `finished` is set from `done`, which an iterator may call before it
|
|
110
|
+
// returns, so it has to be re-read on every turn of this loop.
|
|
111
|
+
if (finished) break;
|
|
112
|
+
/** @type {T} */
|
|
113
|
+
let item;
|
|
114
|
+
if (array === undefined) {
|
|
115
|
+
const next = /** @type {Iterator<T>} */ (values).next();
|
|
116
|
+
if (next.done) {
|
|
117
|
+
exhausted = true;
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
item = next.value;
|
|
121
|
+
} else {
|
|
122
|
+
if (index === length) {
|
|
123
|
+
exhausted = true;
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
item = array[index++];
|
|
127
|
+
}
|
|
128
|
+
running++;
|
|
129
|
+
iterator(item, once(done));
|
|
130
|
+
}
|
|
131
|
+
dispatching = false;
|
|
132
|
+
if (exhausted && running === 0 && !finished) {
|
|
133
|
+
finished = true;
|
|
134
|
+
callback(null);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* @param {(E | null)=} err error
|
|
140
|
+
* @returns {void}
|
|
141
|
+
*/
|
|
142
|
+
const done = (err) => {
|
|
143
|
+
if (finished) return;
|
|
144
|
+
running--;
|
|
145
|
+
if (err) {
|
|
146
|
+
finished = true;
|
|
147
|
+
callback(err);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
dispatch();
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
if (limit < 1) return callback(null);
|
|
154
|
+
|
|
155
|
+
dispatch();
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Runs `iterator` over every item with unlimited concurrency and collects the
|
|
160
|
+
* results in the order of the collection, not the order of completion.
|
|
161
|
+
* @template T
|
|
162
|
+
* @template R
|
|
163
|
+
* @template E
|
|
164
|
+
* @param {Iterable<T>} collection items to iterate
|
|
165
|
+
* @param {(item: T, callback: (err?: E | null, result?: R) => void) => void} iterator called once per item
|
|
166
|
+
* @param {(err?: E | null, results?: R[]) => void} callback called with every result, or with the first error
|
|
167
|
+
* @returns {void}
|
|
168
|
+
*/
|
|
169
|
+
const map = (collection, iterator, callback) => {
|
|
170
|
+
const array = Array.isArray(collection)
|
|
171
|
+
? /** @type {T[]} */ (collection)
|
|
172
|
+
: undefined;
|
|
173
|
+
// Pre-sized, because growing it or `Array.from` costs measurably more on
|
|
174
|
+
// the small collections this is called with.
|
|
175
|
+
/** @type {R[]} */
|
|
176
|
+
// eslint-disable-next-line unicorn/no-new-array
|
|
177
|
+
const results = array === undefined ? [] : new Array(array.length);
|
|
178
|
+
let remaining = 1;
|
|
179
|
+
let finished = false;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* @param {(E | null)=} err error
|
|
183
|
+
* @returns {void}
|
|
184
|
+
*/
|
|
185
|
+
const settle = (err) => {
|
|
186
|
+
if (finished) return;
|
|
187
|
+
if (err) {
|
|
188
|
+
finished = true;
|
|
189
|
+
callback(err, results);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (--remaining === 0) {
|
|
193
|
+
finished = true;
|
|
194
|
+
callback(null, results);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* @param {number} index position the result of that item belongs at
|
|
200
|
+
* @returns {(err?: E | null, result?: R) => void} completion callback for that item
|
|
201
|
+
*/
|
|
202
|
+
const createCallback = (index) => {
|
|
203
|
+
let position = index;
|
|
204
|
+
return (err, result) => {
|
|
205
|
+
const at = position;
|
|
206
|
+
if (at === -1) throw new Error("Callback was already called");
|
|
207
|
+
position = -1;
|
|
208
|
+
// A result arriving after the run settled must not reach `results`,
|
|
209
|
+
// which the callback already handed to the caller.
|
|
210
|
+
if (finished) return;
|
|
211
|
+
if (!err) results[at] = /** @type {R} */ (result);
|
|
212
|
+
settle(err);
|
|
213
|
+
};
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
if (array !== undefined) {
|
|
217
|
+
const length = array.length;
|
|
218
|
+
if (length === 0) return callback(null, results);
|
|
219
|
+
remaining = length;
|
|
220
|
+
for (let i = 0; i < length; i++) iterator(array[i], createCallback(i));
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
let index = 0;
|
|
225
|
+
for (const item of collection) {
|
|
226
|
+
remaining++;
|
|
227
|
+
iterator(item, createCallback(index++));
|
|
228
|
+
}
|
|
229
|
+
results.length = index;
|
|
230
|
+
settle(null);
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Runs `iterator` over every item, at most `limit` of them in flight, and
|
|
235
|
+
* collects the results in the order of the collection, not of completion.
|
|
236
|
+
* @template T
|
|
237
|
+
* @template R
|
|
238
|
+
* @template E
|
|
239
|
+
* @param {Iterable<T>} collection items to iterate
|
|
240
|
+
* @param {number} limit maximum number of items in flight
|
|
241
|
+
* @param {(item: T, callback: (err?: E | null, result?: R) => void) => void} iterator called once per item
|
|
242
|
+
* @param {(err?: E | null, results?: R[]) => void} callback called with every result, or with the first error
|
|
243
|
+
* @returns {void}
|
|
244
|
+
*/
|
|
245
|
+
const mapLimit = (collection, limit, iterator, callback) => {
|
|
246
|
+
/** @type {R[]} */
|
|
247
|
+
const results = [];
|
|
248
|
+
let index = 0;
|
|
249
|
+
eachLimit(
|
|
250
|
+
collection,
|
|
251
|
+
limit,
|
|
252
|
+
(item, done) => {
|
|
253
|
+
// the dispatch loop hands out one item at a time, so this counts the
|
|
254
|
+
// position of the item rather than of whichever finishes first
|
|
255
|
+
const position = index++;
|
|
256
|
+
iterator(item, (err, result) => {
|
|
257
|
+
if (err) return done(err);
|
|
258
|
+
results[position] = /** @type {R} */ (result);
|
|
259
|
+
done(null);
|
|
260
|
+
});
|
|
261
|
+
},
|
|
262
|
+
(err) => {
|
|
263
|
+
if (err) return callback(err);
|
|
264
|
+
callback(null, results);
|
|
265
|
+
}
|
|
266
|
+
);
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* @template R
|
|
271
|
+
* @template E
|
|
272
|
+
* @param {(callback: (err?: E | null, result?: R) => void) => void} task task to run
|
|
273
|
+
* @param {(err?: E | null, result?: R) => void} callback called when the task is done
|
|
274
|
+
* @returns {void}
|
|
275
|
+
*/
|
|
276
|
+
const runTask = (task, callback) => task(callback);
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Runs every task in parallel and collects the results in task order.
|
|
280
|
+
* @template R
|
|
281
|
+
* @template E
|
|
282
|
+
* @param {((callback: (err?: E | null, result?: R) => void) => void)[]} tasks tasks to run
|
|
283
|
+
* @param {(err?: E | null, results?: R[]) => void} callback called with every result, or with the first error
|
|
284
|
+
* @returns {void}
|
|
285
|
+
*/
|
|
286
|
+
const parallel = (tasks, callback) => map(tasks, runTask, callback);
|
|
287
|
+
|
|
288
|
+
module.exports.each = each;
|
|
289
|
+
module.exports.eachLimit = eachLimit;
|
|
290
|
+
module.exports.map = map;
|
|
291
|
+
module.exports.mapLimit = mapLimit;
|
|
292
|
+
module.exports.parallel = parallel;
|