@depup/webpack-sources 3.3.4-depup.0 → 3.6.0-depup.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 +2 -2
- package/changes.json +1 -1
- package/lib/CachedSource.js +257 -63
- package/lib/CompatSource.js +42 -1
- package/lib/ConcatSource.js +100 -28
- package/lib/OriginalSource.js +111 -45
- package/lib/PrefixSource.js +60 -11
- package/lib/RawSource.js +85 -29
- package/lib/ReplaceSource.js +269 -73
- package/lib/SizeOnlySource.js +10 -1
- package/lib/Source.js +39 -0
- package/lib/SourceMapSource.js +92 -10
- package/lib/helpers/createMappingsSerializer.js +307 -54
- package/lib/helpers/getFromStreamChunks.js +165 -73
- package/lib/helpers/getGeneratedSourceInfo.js +7 -4
- package/lib/helpers/readMappings.js +6 -3
- package/lib/helpers/scopes.js +438 -0
- package/lib/helpers/splitIntoLines.js +10 -9
- package/lib/helpers/splitIntoPotentialTokens.js +99 -26
- package/lib/helpers/streamAndGetSourceAndMap.js +61 -22
- package/lib/helpers/streamChunks.js +3 -2
- package/lib/helpers/streamChunksOfCombinedSourceMap.js +7 -3
- package/lib/helpers/streamChunksOfRawSource.js +23 -15
- package/lib/helpers/streamChunksOfSourceMap.js +50 -42
- package/lib/index.js +3 -0
- package/package.json +34 -23
- package/types/CachedSource.d.ts +192 -0
- package/types/CompatSource.d.ts +87 -0
- package/types/ConcatSource.d.ts +75 -0
- package/types/OriginalSource.d.ts +87 -0
- package/types/PrefixSource.d.ts +59 -0
- package/types/RawSource.d.ts +75 -0
- package/types/ReplaceSource.d.ts +107 -0
- package/types/SizeOnlySource.d.ts +24 -0
- package/types/Source.d.ts +189 -0
- package/types/SourceMapSource.d.ts +136 -0
- package/types/helpers/createMappingsSerializer.d.ts +60 -0
- package/types/helpers/getFromStreamChunks.d.ts +16 -0
- package/types/helpers/getGeneratedSourceInfo.d.ts +31 -0
- package/types/helpers/getName.d.ts +15 -0
- package/types/helpers/getSource.d.ts +15 -0
- package/types/helpers/readMappings.d.ts +19 -0
- package/types/helpers/scopes.d.ts +119 -0
- package/types/helpers/splitIntoLines.d.ts +6 -0
- package/types/helpers/splitIntoPotentialTokens.d.ts +37 -0
- package/types/helpers/streamAndGetSourceAndMap.d.ts +39 -0
- package/types/helpers/streamChunks.d.ts +56 -0
- package/types/helpers/streamChunksOfCombinedSourceMap.d.ts +42 -0
- package/types/helpers/streamChunksOfRawSource.d.ts +16 -0
- package/types/helpers/streamChunksOfSourceMap.d.ts +19 -0
- package/types/helpers/stringBufferUtils.d.ts +55 -0
- package/types/index.d.ts +50 -0
- package/types.d.ts +42 -439
package/README.md
CHANGED
|
@@ -13,8 +13,8 @@ npm install @depup/webpack-sources
|
|
|
13
13
|
|
|
14
14
|
| Field | Value |
|
|
15
15
|
|-------|-------|
|
|
16
|
-
| Original | [webpack-sources](https://www.npmjs.com/package/webpack-sources) @ 3.
|
|
17
|
-
| Processed | 2026-
|
|
16
|
+
| Original | [webpack-sources](https://www.npmjs.com/package/webpack-sources) @ 3.6.0 |
|
|
17
|
+
| Processed | 2026-09-27 |
|
|
18
18
|
| Smoke test | passed |
|
|
19
19
|
| Deps updated | 0 |
|
|
20
20
|
|
package/changes.json
CHANGED
package/lib/CachedSource.js
CHANGED
|
@@ -13,6 +13,7 @@ const {
|
|
|
13
13
|
isDualStringBufferCachingEnabled,
|
|
14
14
|
} = require("./helpers/stringBufferUtils");
|
|
15
15
|
|
|
16
|
+
/** @typedef {import("./Source").ClearCacheOptions} ClearCacheOptions */
|
|
16
17
|
/** @typedef {import("./Source").HashLike} HashLike */
|
|
17
18
|
/** @typedef {import("./Source").MapOptions} MapOptions */
|
|
18
19
|
/** @typedef {import("./Source").RawSourceMap} RawSourceMap */
|
|
@@ -23,6 +24,7 @@ const {
|
|
|
23
24
|
/** @typedef {import("./helpers/streamChunks").OnName} OnName */
|
|
24
25
|
/** @typedef {import("./helpers/streamChunks").OnSource} OnSource */
|
|
25
26
|
/** @typedef {import("./helpers/streamChunks").Options} Options */
|
|
27
|
+
/** @typedef {import("./helpers/streamChunks").ScopeBindings} ScopeBindings */
|
|
26
28
|
|
|
27
29
|
/**
|
|
28
30
|
* @typedef {object} BufferedMap
|
|
@@ -55,6 +57,25 @@ const mapToBufferedMap = (map) => {
|
|
|
55
57
|
return bufferedMap;
|
|
56
58
|
};
|
|
57
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Encodes every string a recorded hash update holds as a buffer, so cached data
|
|
62
|
+
* handed to a caller carries no big string: a string goes into the serialized
|
|
63
|
+
* payload, where it is copied in and rebuilt on every deserialization, while a
|
|
64
|
+
* buffer is carried alongside it. Hashing reads a string as utf8, so the
|
|
65
|
+
* encoded update hashes the same. It encodes in place, so a source handed out
|
|
66
|
+
* repeatedly is encoded once, and one that never is keeps its string uncopied.
|
|
67
|
+
* @param {(string | Buffer)[]=} update recorded hash update
|
|
68
|
+
* @returns {(string | Buffer)[]=} the update, holding no string
|
|
69
|
+
*/
|
|
70
|
+
const bufferHashUpdate = (update) => {
|
|
71
|
+
if (update === undefined) return undefined;
|
|
72
|
+
for (let index = 0; index < update.length; index++) {
|
|
73
|
+
const item = update[index];
|
|
74
|
+
if (typeof item === "string") update[index] = Buffer.from(item, "utf8");
|
|
75
|
+
}
|
|
76
|
+
return update;
|
|
77
|
+
};
|
|
78
|
+
|
|
58
79
|
/**
|
|
59
80
|
* @param {null | BufferedMap} bufferedMap buffered map
|
|
60
81
|
* @returns {null | RawSourceMap} map
|
|
@@ -75,9 +96,51 @@ const bufferedMapToMap = (bufferedMap) => {
|
|
|
75
96
|
return map;
|
|
76
97
|
};
|
|
77
98
|
|
|
78
|
-
/**
|
|
99
|
+
/**
|
|
100
|
+
* What replaying an entry streamed for a `scopes` request needs besides its
|
|
101
|
+
* map. The map only keeps the encoded `scopes` field, so `bindings` holds, by
|
|
102
|
+
* source index, the bindings each source reported. The field also appended
|
|
103
|
+
* names to the map, and `names` counts the ones the stream itself reported,
|
|
104
|
+
* so a replay reports the same names a fresh stream would.
|
|
105
|
+
* @typedef {object} ScopesReplay
|
|
106
|
+
* @property {(ScopeBindings | undefined)[]} bindings bindings by source index
|
|
107
|
+
* @property {number} names number of names the stream reported
|
|
108
|
+
*/
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @typedef {{ map?: null | RawSourceMap, bufferedMap?: null | BufferedMap, scopes?: ScopesReplay }} BufferEntry
|
|
112
|
+
*/
|
|
79
113
|
/** @typedef {Map<string, BufferEntry>} BufferedMaps */
|
|
80
114
|
|
|
115
|
+
const CACHE_KEY_EMPTY = "{}";
|
|
116
|
+
const CACHE_KEY_COLUMNS_FALSE = '{"columns":false}';
|
|
117
|
+
const CACHE_KEY_COLUMNS_TRUE = '{"columns":true}';
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Fast-path replacement for `JSON.stringify(options)` when used as a cache
|
|
121
|
+
* key. MapOptions / streamChunks Options are both small boolean-only shapes
|
|
122
|
+
* and the overwhelmingly common shapes (`undefined`, `{}`, `{columns}`) can
|
|
123
|
+
* be keyed without calling `JSON.stringify`, which dominates short-circuit
|
|
124
|
+
* cache lookups. Falls back to `JSON.stringify` for any other shape so keys
|
|
125
|
+
* remain compatible with previously cached `BufferedMaps` entries.
|
|
126
|
+
* @param {undefined | MapOptions | Options} options options
|
|
127
|
+
* @returns {string} cache key
|
|
128
|
+
*/
|
|
129
|
+
const getCacheKey = (options) => {
|
|
130
|
+
if (!options) return CACHE_KEY_EMPTY;
|
|
131
|
+
const { columns } = options;
|
|
132
|
+
if (
|
|
133
|
+
/** @type {Options} */ (options).source === undefined &&
|
|
134
|
+
/** @type {Options} */ (options).finalSource === undefined &&
|
|
135
|
+
/** @type {MapOptions} */ (options).module === undefined &&
|
|
136
|
+
/** @type {MapOptions} */ (options).scopes === undefined
|
|
137
|
+
) {
|
|
138
|
+
if (columns === undefined) return CACHE_KEY_EMPTY;
|
|
139
|
+
return columns ? CACHE_KEY_COLUMNS_TRUE : CACHE_KEY_COLUMNS_FALSE;
|
|
140
|
+
}
|
|
141
|
+
return JSON.stringify(options);
|
|
142
|
+
};
|
|
143
|
+
|
|
81
144
|
/**
|
|
82
145
|
* @typedef {object} CachedData
|
|
83
146
|
* @property {boolean=} source source
|
|
@@ -95,40 +158,56 @@ class CachedSource extends Source {
|
|
|
95
158
|
constructor(source, cachedData) {
|
|
96
159
|
super();
|
|
97
160
|
/**
|
|
98
|
-
* @private
|
|
99
161
|
* @type {Source | (() => Source)}
|
|
100
162
|
*/
|
|
101
163
|
this._source = source;
|
|
102
164
|
/**
|
|
103
|
-
* @private
|
|
104
|
-
* @type {boolean | undefined}
|
|
105
|
-
*/
|
|
106
|
-
this._cachedSourceType = cachedData ? cachedData.source : undefined;
|
|
107
|
-
/**
|
|
108
|
-
* @private
|
|
109
165
|
* @type {undefined | string}
|
|
110
166
|
*/
|
|
111
167
|
this._cachedSource = undefined;
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
168
|
+
// Split on `cachedData` once instead of re-evaluating the ternary for
|
|
169
|
+
// every field. Under the interpreter (and CodSpeed's simulation) each
|
|
170
|
+
// ternary is a separate branch; consolidating cuts the per-instance
|
|
171
|
+
// branch count roughly in half.
|
|
172
|
+
if (cachedData) {
|
|
173
|
+
/**
|
|
174
|
+
* @type {boolean | undefined}
|
|
175
|
+
*/
|
|
176
|
+
this._cachedSourceType = cachedData.source;
|
|
177
|
+
/**
|
|
178
|
+
* @type {Buffer | undefined}
|
|
179
|
+
*/
|
|
180
|
+
this._cachedBuffer = cachedData.buffer;
|
|
181
|
+
/**
|
|
182
|
+
* @type {number | undefined}
|
|
183
|
+
*/
|
|
184
|
+
this._cachedSize = cachedData.size;
|
|
185
|
+
/**
|
|
186
|
+
* @type {BufferedMaps | undefined}
|
|
187
|
+
*/
|
|
188
|
+
this._cachedMaps = cachedData.maps;
|
|
189
|
+
/**
|
|
190
|
+
* @type {(string | Buffer)[] | undefined}
|
|
191
|
+
*/
|
|
192
|
+
this._cachedHashUpdate = cachedData.hash;
|
|
193
|
+
} else {
|
|
194
|
+
this._cachedSourceType = undefined;
|
|
195
|
+
this._cachedBuffer = undefined;
|
|
196
|
+
this._cachedSize = undefined;
|
|
197
|
+
this._cachedMaps = undefined;
|
|
198
|
+
this._cachedHashUpdate = undefined;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* The map cache, created on first use: a source nobody asks a map of holds
|
|
204
|
+
* none, since V8 allocates a Map's hash table whether or not it is filled.
|
|
205
|
+
* @returns {BufferedMaps} map cache
|
|
206
|
+
*/
|
|
207
|
+
_getOrCreateCachedMaps() {
|
|
208
|
+
const cachedMaps = this._cachedMaps;
|
|
209
|
+
if (cachedMaps !== undefined) return cachedMaps;
|
|
210
|
+
return (this._cachedMaps = new Map());
|
|
132
211
|
}
|
|
133
212
|
|
|
134
213
|
/**
|
|
@@ -137,26 +216,36 @@ class CachedSource extends Source {
|
|
|
137
216
|
getCachedData() {
|
|
138
217
|
/** @type {BufferedMaps} */
|
|
139
218
|
const bufferedMaps = new Map();
|
|
140
|
-
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
cacheEntry.bufferedMap
|
|
144
|
-
|
|
145
|
-
|
|
219
|
+
if (this._cachedMaps !== undefined) {
|
|
220
|
+
for (const pair of this._cachedMaps) {
|
|
221
|
+
const [, cacheEntry] = pair;
|
|
222
|
+
if (cacheEntry.bufferedMap === undefined) {
|
|
223
|
+
cacheEntry.bufferedMap = mapToBufferedMap(
|
|
224
|
+
this._getMapFromCacheEntry(cacheEntry),
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
/** @type {BufferEntry} */
|
|
228
|
+
const bufferEntry = {
|
|
229
|
+
map: undefined,
|
|
230
|
+
bufferedMap: cacheEntry.bufferedMap,
|
|
231
|
+
};
|
|
232
|
+
// Keep the bindings a `scopes` request recorded, so a source
|
|
233
|
+
// restored from this data replays them without its original.
|
|
234
|
+
if (cacheEntry.scopes !== undefined) {
|
|
235
|
+
bufferEntry.scopes = cacheEntry.scopes;
|
|
236
|
+
}
|
|
237
|
+
bufferedMaps.set(pair[0], bufferEntry);
|
|
146
238
|
}
|
|
147
|
-
bufferedMaps.set(pair[0], {
|
|
148
|
-
map: undefined,
|
|
149
|
-
bufferedMap: cacheEntry.bufferedMap,
|
|
150
|
-
});
|
|
151
239
|
}
|
|
152
240
|
return {
|
|
153
|
-
//
|
|
154
|
-
//
|
|
155
|
-
//
|
|
156
|
-
//
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
241
|
+
// `CachedData.buffer` is required (it is the on-disk
|
|
242
|
+
// serialization format consumed by the
|
|
243
|
+
// `new CachedSource(source, cachedData)` constructor).
|
|
244
|
+
// `_cachedBuffer` is populated by `buffer()` calls but a
|
|
245
|
+
// caller may invoke `getCachedData()` after `clearCache()`
|
|
246
|
+
// has dropped it; `this.buffer()` rehydrates via the
|
|
247
|
+
// wrapped source so the contract holds in every state.
|
|
248
|
+
buffer: this.buffer(),
|
|
160
249
|
source:
|
|
161
250
|
this._cachedSourceType !== undefined
|
|
162
251
|
? this._cachedSourceType
|
|
@@ -167,7 +256,7 @@ class CachedSource extends Source {
|
|
|
167
256
|
: undefined,
|
|
168
257
|
size: this._cachedSize,
|
|
169
258
|
maps: bufferedMaps,
|
|
170
|
-
hash: this._cachedHashUpdate,
|
|
259
|
+
hash: bufferHashUpdate(this._cachedHashUpdate),
|
|
171
260
|
};
|
|
172
261
|
}
|
|
173
262
|
|
|
@@ -184,15 +273,27 @@ class CachedSource extends Source {
|
|
|
184
273
|
* @returns {SourceValue} source
|
|
185
274
|
*/
|
|
186
275
|
source() {
|
|
187
|
-
|
|
188
|
-
|
|
276
|
+
// Fully inlined _getCachedSource: both warm- and cold-cache paths skip
|
|
277
|
+
// the prototype method lookup / stack frame the interpreter would
|
|
278
|
+
// otherwise pay on every call.
|
|
279
|
+
if (this._cachedSource !== undefined) return this._cachedSource;
|
|
280
|
+
const cachedBuffer = this._cachedBuffer;
|
|
281
|
+
const cachedSourceType = this._cachedSourceType;
|
|
282
|
+
if (cachedBuffer !== undefined && cachedSourceType !== undefined) {
|
|
283
|
+
const value = cachedSourceType
|
|
284
|
+
? cachedBuffer.toString("utf8")
|
|
285
|
+
: cachedBuffer;
|
|
286
|
+
if (isDualStringBufferCachingEnabled()) {
|
|
287
|
+
this._cachedSource = /** @type {string} */ (value);
|
|
288
|
+
}
|
|
289
|
+
return /** @type {string} */ (value);
|
|
290
|
+
}
|
|
189
291
|
return (this._cachedSource =
|
|
190
292
|
/** @type {string} */
|
|
191
293
|
(this.original().source()));
|
|
192
294
|
}
|
|
193
295
|
|
|
194
296
|
/**
|
|
195
|
-
* @private
|
|
196
297
|
* @param {BufferEntry} cacheEntry cache entry
|
|
197
298
|
* @returns {null | RawSourceMap} raw source map
|
|
198
299
|
*/
|
|
@@ -207,7 +308,6 @@ class CachedSource extends Source {
|
|
|
207
308
|
}
|
|
208
309
|
|
|
209
310
|
/**
|
|
210
|
-
* @private
|
|
211
311
|
* @returns {undefined | string} cached source
|
|
212
312
|
*/
|
|
213
313
|
_getCachedSource() {
|
|
@@ -228,6 +328,9 @@ class CachedSource extends Source {
|
|
|
228
328
|
*/
|
|
229
329
|
buffer() {
|
|
230
330
|
if (this._cachedBuffer !== undefined) return this._cachedBuffer;
|
|
331
|
+
if (this._cachedBuffers !== undefined) {
|
|
332
|
+
return (this._cachedBuffer = Buffer.concat(this._cachedBuffers));
|
|
333
|
+
}
|
|
231
334
|
if (this._cachedSource !== undefined) {
|
|
232
335
|
const value = Buffer.isBuffer(this._cachedSource)
|
|
233
336
|
? this._cachedSource
|
|
@@ -251,6 +354,21 @@ class CachedSource extends Source {
|
|
|
251
354
|
return value;
|
|
252
355
|
}
|
|
253
356
|
|
|
357
|
+
/**
|
|
358
|
+
* @returns {Buffer[]} buffers
|
|
359
|
+
*/
|
|
360
|
+
buffers() {
|
|
361
|
+
if (this._cachedBuffers !== undefined) return this._cachedBuffers;
|
|
362
|
+
if (this._cachedBuffer !== undefined) {
|
|
363
|
+
return (this._cachedBuffers = [this._cachedBuffer]);
|
|
364
|
+
}
|
|
365
|
+
const original = this.original();
|
|
366
|
+
if (typeof original.buffers === "function") {
|
|
367
|
+
return (this._cachedBuffers = original.buffers());
|
|
368
|
+
}
|
|
369
|
+
return (this._cachedBuffers = [this.buffer()]);
|
|
370
|
+
}
|
|
371
|
+
|
|
254
372
|
/**
|
|
255
373
|
* @returns {number} size
|
|
256
374
|
*/
|
|
@@ -271,8 +389,10 @@ class CachedSource extends Source {
|
|
|
271
389
|
* @returns {SourceAndMap} source and map
|
|
272
390
|
*/
|
|
273
391
|
sourceAndMap(options) {
|
|
274
|
-
const key =
|
|
275
|
-
const
|
|
392
|
+
const key = getCacheKey(options);
|
|
393
|
+
const cachedMaps = this._cachedMaps;
|
|
394
|
+
const cacheEntry =
|
|
395
|
+
cachedMaps === undefined ? undefined : cachedMaps.get(key);
|
|
276
396
|
// Look for a cached map
|
|
277
397
|
if (cacheEntry !== undefined) {
|
|
278
398
|
// We have a cached map in some representation
|
|
@@ -294,7 +414,7 @@ class CachedSource extends Source {
|
|
|
294
414
|
map = sourceAndMap.map;
|
|
295
415
|
this._cachedSource = source;
|
|
296
416
|
}
|
|
297
|
-
this.
|
|
417
|
+
this._getOrCreateCachedMaps().set(key, {
|
|
298
418
|
map,
|
|
299
419
|
bufferedMap: undefined,
|
|
300
420
|
});
|
|
@@ -309,19 +429,39 @@ class CachedSource extends Source {
|
|
|
309
429
|
* @returns {GeneratedSourceInfo} generated source info
|
|
310
430
|
*/
|
|
311
431
|
streamChunks(options, onChunk, onSource, onName) {
|
|
312
|
-
const key =
|
|
432
|
+
const key = getCacheKey(options);
|
|
433
|
+
const scopes = Boolean(
|
|
434
|
+
options && /** @type {MapOptions} */ (options).scopes,
|
|
435
|
+
);
|
|
436
|
+
const cachedMaps = this._cachedMaps;
|
|
437
|
+
const cacheEntry =
|
|
438
|
+
cachedMaps === undefined ? undefined : cachedMaps.get(key);
|
|
313
439
|
if (
|
|
314
|
-
|
|
440
|
+
cacheEntry !== undefined &&
|
|
441
|
+
// An entry filled without streaming never saw the bindings, so a
|
|
442
|
+
// scopes request streams the original once to record them.
|
|
443
|
+
(!scopes || cacheEntry.scopes !== undefined) &&
|
|
315
444
|
(this._cachedBuffer !== undefined || this._cachedSource !== undefined)
|
|
316
445
|
) {
|
|
317
446
|
const { source, map } = this.sourceAndMap(options);
|
|
318
447
|
if (map) {
|
|
448
|
+
const replay = scopes ? cacheEntry.scopes : undefined;
|
|
319
449
|
return streamChunksOfSourceMap(
|
|
320
450
|
/** @type {string} */
|
|
321
451
|
(source),
|
|
322
|
-
map
|
|
452
|
+
replay !== undefined && map.names.length > replay.names
|
|
453
|
+
? { ...map, names: map.names.slice(0, replay.names) }
|
|
454
|
+
: map,
|
|
323
455
|
onChunk,
|
|
324
|
-
|
|
456
|
+
replay !== undefined
|
|
457
|
+
? (sourceIndex, source, sourceContent) =>
|
|
458
|
+
onSource(
|
|
459
|
+
sourceIndex,
|
|
460
|
+
source,
|
|
461
|
+
sourceContent,
|
|
462
|
+
replay.bindings[sourceIndex],
|
|
463
|
+
)
|
|
464
|
+
: onSource,
|
|
325
465
|
onName,
|
|
326
466
|
Boolean(options && options.finalSource),
|
|
327
467
|
true,
|
|
@@ -336,17 +476,30 @@ class CachedSource extends Source {
|
|
|
336
476
|
Boolean(options && options.finalSource),
|
|
337
477
|
);
|
|
338
478
|
}
|
|
479
|
+
/** @type {ScopesReplay | undefined} */
|
|
480
|
+
const replay = scopes ? { bindings: [], names: 0 } : undefined;
|
|
339
481
|
const sourceAndMap = streamAndGetSourceAndMap(
|
|
340
482
|
this.original(),
|
|
341
483
|
options,
|
|
342
484
|
onChunk,
|
|
343
|
-
|
|
344
|
-
|
|
485
|
+
replay !== undefined
|
|
486
|
+
? (sourceIndex, source, sourceContent, bindings) => {
|
|
487
|
+
replay.bindings[sourceIndex] = bindings;
|
|
488
|
+
onSource(sourceIndex, source, sourceContent, bindings);
|
|
489
|
+
}
|
|
490
|
+
: onSource,
|
|
491
|
+
replay !== undefined
|
|
492
|
+
? (nameIndex, name) => {
|
|
493
|
+
if (nameIndex >= replay.names) replay.names = nameIndex + 1;
|
|
494
|
+
onName(nameIndex, name);
|
|
495
|
+
}
|
|
496
|
+
: onName,
|
|
345
497
|
);
|
|
346
498
|
this._cachedSource = sourceAndMap.source;
|
|
347
|
-
this.
|
|
499
|
+
this._getOrCreateCachedMaps().set(key, {
|
|
348
500
|
map: /** @type {RawSourceMap} */ (sourceAndMap.map),
|
|
349
501
|
bufferedMap: undefined,
|
|
502
|
+
scopes: replay,
|
|
350
503
|
});
|
|
351
504
|
return sourceAndMap.result;
|
|
352
505
|
}
|
|
@@ -356,19 +509,60 @@ class CachedSource extends Source {
|
|
|
356
509
|
* @returns {RawSourceMap | null} map
|
|
357
510
|
*/
|
|
358
511
|
map(options) {
|
|
359
|
-
const key =
|
|
360
|
-
const
|
|
512
|
+
const key = getCacheKey(options);
|
|
513
|
+
const cachedMaps = this._cachedMaps;
|
|
514
|
+
const cacheEntry =
|
|
515
|
+
cachedMaps === undefined ? undefined : cachedMaps.get(key);
|
|
361
516
|
if (cacheEntry !== undefined) {
|
|
362
517
|
return this._getMapFromCacheEntry(cacheEntry);
|
|
363
518
|
}
|
|
364
519
|
const map = this.original().map(options);
|
|
365
|
-
this.
|
|
520
|
+
this._getOrCreateCachedMaps().set(key, {
|
|
366
521
|
map,
|
|
367
522
|
bufferedMap: undefined,
|
|
368
523
|
});
|
|
369
524
|
return map;
|
|
370
525
|
}
|
|
371
526
|
|
|
527
|
+
/**
|
|
528
|
+
* Release cached data held by this source. clearCache is a memory
|
|
529
|
+
* hint: it never affects correctness or output, only how expensive
|
|
530
|
+
* the next read is. Subclasses override; the base is a no-op so
|
|
531
|
+
* every Source supports the call. Composite sources always recurse
|
|
532
|
+
* into wrapped sources. When the same child is reachable via several
|
|
533
|
+
* parents (e.g. modules shared across webpack chunks), pass a shared
|
|
534
|
+
* `visited` WeakSet so each subtree is walked at most once.
|
|
535
|
+
* Not safe to call concurrently with source/map/sourceAndMap/
|
|
536
|
+
* streamChunks/updateHash on the same instance.
|
|
537
|
+
* @param {ClearCacheOptions=} options selectors
|
|
538
|
+
* @param {WeakSet<Source>=} visited de-duplication set shared across calls
|
|
539
|
+
* @returns {void}
|
|
540
|
+
*/
|
|
541
|
+
clearCache(options, visited) {
|
|
542
|
+
if (visited !== undefined && visited.has(this)) return;
|
|
543
|
+
const clearSource = !options || options.source !== false;
|
|
544
|
+
const clearMaps = !options || options.maps !== false;
|
|
545
|
+
if (clearSource) {
|
|
546
|
+
this._cachedSource = undefined;
|
|
547
|
+
this._cachedSourceType = undefined;
|
|
548
|
+
this._cachedBuffer = undefined;
|
|
549
|
+
this._cachedBuffers = undefined;
|
|
550
|
+
}
|
|
551
|
+
if (clearMaps && this._cachedMaps !== undefined) {
|
|
552
|
+
// Reusing the Map avoids per-call allocation churn when builds
|
|
553
|
+
// call clearCache thousands of times.
|
|
554
|
+
this._cachedMaps.clear();
|
|
555
|
+
}
|
|
556
|
+
if (typeof this._source !== "function") {
|
|
557
|
+
let v = visited;
|
|
558
|
+
if (v === undefined) v = new WeakSet();
|
|
559
|
+
v.add(this);
|
|
560
|
+
this._source.clearCache(options, v);
|
|
561
|
+
} else if (visited !== undefined) {
|
|
562
|
+
visited.add(this);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
372
566
|
/**
|
|
373
567
|
* @param {HashLike} hash hash
|
|
374
568
|
* @returns {void}
|
package/lib/CompatSource.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
const Source = require("./Source");
|
|
9
9
|
|
|
10
|
+
/** @typedef {import("./Source").ClearCacheOptions} ClearCacheOptions */
|
|
10
11
|
/** @typedef {import("./Source").HashLike} HashLike */
|
|
11
12
|
/** @typedef {import("./Source").MapOptions} MapOptions */
|
|
12
13
|
/** @typedef {import("./Source").RawSourceMap} RawSourceMap */
|
|
@@ -17,10 +18,12 @@ const Source = require("./Source");
|
|
|
17
18
|
* @typedef {object} SourceLike
|
|
18
19
|
* @property {() => SourceValue} source source
|
|
19
20
|
* @property {(() => Buffer)=} buffer buffer
|
|
21
|
+
* @property {(() => Buffer[])=} buffers buffers
|
|
20
22
|
* @property {(() => number)=} size size
|
|
21
23
|
* @property {((options?: MapOptions) => RawSourceMap | null)=} map map
|
|
22
24
|
* @property {((options?: MapOptions) => SourceAndMap)=} sourceAndMap source and map
|
|
23
25
|
* @property {((hash: HashLike) => void)=} updateHash hash updater
|
|
26
|
+
* @property {((options?: ClearCacheOptions, visited?: WeakSet<Source>) => void)=} clearCache clear cache
|
|
24
27
|
*/
|
|
25
28
|
|
|
26
29
|
class CompatSource extends Source {
|
|
@@ -40,7 +43,6 @@ class CompatSource extends Source {
|
|
|
40
43
|
constructor(sourceLike) {
|
|
41
44
|
super();
|
|
42
45
|
/**
|
|
43
|
-
* @private
|
|
44
46
|
* @type {SourceLike}
|
|
45
47
|
*/
|
|
46
48
|
this._sourceLike = sourceLike;
|
|
@@ -53,6 +55,9 @@ class CompatSource extends Source {
|
|
|
53
55
|
return this._sourceLike.source();
|
|
54
56
|
}
|
|
55
57
|
|
|
58
|
+
/**
|
|
59
|
+
* @returns {Buffer} buffer
|
|
60
|
+
*/
|
|
56
61
|
buffer() {
|
|
57
62
|
if (typeof this._sourceLike.buffer === "function") {
|
|
58
63
|
return this._sourceLike.buffer();
|
|
@@ -60,6 +65,19 @@ class CompatSource extends Source {
|
|
|
60
65
|
return super.buffer();
|
|
61
66
|
}
|
|
62
67
|
|
|
68
|
+
/**
|
|
69
|
+
* @returns {Buffer[]} buffers
|
|
70
|
+
*/
|
|
71
|
+
buffers() {
|
|
72
|
+
if (typeof this._sourceLike.buffers === "function") {
|
|
73
|
+
return this._sourceLike.buffers();
|
|
74
|
+
}
|
|
75
|
+
return super.buffers();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @returns {number} size
|
|
80
|
+
*/
|
|
63
81
|
size() {
|
|
64
82
|
if (typeof this._sourceLike.size === "function") {
|
|
65
83
|
return this._sourceLike.size();
|
|
@@ -89,6 +107,29 @@ class CompatSource extends Source {
|
|
|
89
107
|
return super.sourceAndMap(options);
|
|
90
108
|
}
|
|
91
109
|
|
|
110
|
+
/**
|
|
111
|
+
* Release cached data held by this source. clearCache is a memory
|
|
112
|
+
* hint: it never affects correctness or output, only how expensive
|
|
113
|
+
* the next read is. Subclasses override; the base is a no-op so
|
|
114
|
+
* every Source supports the call. Composite sources always recurse
|
|
115
|
+
* into wrapped sources. When the same child is reachable via several
|
|
116
|
+
* parents (e.g. modules shared across webpack chunks), pass a shared
|
|
117
|
+
* `visited` WeakSet so each subtree is walked at most once.
|
|
118
|
+
* Not safe to call concurrently with source/map/sourceAndMap/
|
|
119
|
+
* streamChunks/updateHash on the same instance.
|
|
120
|
+
* @param {ClearCacheOptions=} options selectors
|
|
121
|
+
* @param {WeakSet<Source>=} visited de-duplication set shared across calls
|
|
122
|
+
* @returns {void}
|
|
123
|
+
*/
|
|
124
|
+
clearCache(options, visited) {
|
|
125
|
+
if (visited !== undefined && visited.has(this)) return;
|
|
126
|
+
if (visited !== undefined) visited.add(this);
|
|
127
|
+
const sourceLike = this._sourceLike;
|
|
128
|
+
if (typeof sourceLike.clearCache === "function") {
|
|
129
|
+
sourceLike.clearCache(options, visited);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
92
133
|
/**
|
|
93
134
|
* @param {HashLike} hash hash
|
|
94
135
|
* @returns {void}
|