webpack 5.10.0 → 5.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of webpack might be problematic. Click here for more details.

Files changed (40) hide show
  1. package/bin/webpack.js +0 -0
  2. package/lib/Compilation.js +5 -21
  3. package/lib/Compiler.js +58 -13
  4. package/lib/FlagAllModulesAsUsedPlugin.js +4 -0
  5. package/lib/MainTemplate.js +2 -2
  6. package/lib/Module.js +1 -1
  7. package/lib/ModuleInfoHeaderPlugin.js +1 -1
  8. package/lib/NormalModule.js +4 -2
  9. package/lib/RuntimeGlobals.js +11 -1
  10. package/lib/RuntimeModule.js +20 -0
  11. package/lib/RuntimeTemplate.js +4 -0
  12. package/lib/cache/PackFileCacheStrategy.js +4 -2
  13. package/lib/hmr/HotModuleReplacementRuntimeModule.js +1 -1
  14. package/lib/index.js +5 -0
  15. package/lib/javascript/JavascriptModulesPlugin.js +82 -26
  16. package/lib/node/NodeTargetPlugin.js +4 -0
  17. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +1 -1
  18. package/lib/node/RequireChunkLoadingRuntimeModule.js +1 -1
  19. package/lib/optimize/SideEffectsFlagPlugin.js +9 -13
  20. package/lib/prefetch/ChunkPrefetchFunctionRuntimeModule.js +1 -1
  21. package/lib/prefetch/ChunkPrefetchPreloadPlugin.js +1 -1
  22. package/lib/prefetch/ChunkPrefetchStartupRuntimeModule.js +1 -1
  23. package/lib/prefetch/ChunkPrefetchTriggerRuntimeModule.js +1 -1
  24. package/lib/rules/RuleSetCompiler.js +4 -2
  25. package/lib/runtime/AutoPublicPathRuntimeModule.js +1 -1
  26. package/lib/runtime/CompatRuntimeModule.js +1 -1
  27. package/lib/runtime/PublicPathRuntimeModule.js +1 -1
  28. package/lib/serialization/BinaryMiddleware.js +467 -136
  29. package/lib/serialization/FileMiddleware.js +227 -37
  30. package/lib/serialization/ObjectMiddleware.js +89 -5
  31. package/lib/sharing/ConsumeSharedRuntimeModule.js +1 -1
  32. package/lib/util/fs.js +4 -0
  33. package/lib/util/source.js +61 -0
  34. package/lib/validateSchema.js +84 -73
  35. package/lib/wasm-async/AsyncWasmChunkLoadingRuntimeModule.js +1 -1
  36. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +1 -1
  37. package/lib/web/JsonpChunkLoadingRuntimeModule.js +54 -55
  38. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +1 -1
  39. package/package.json +8 -8
  40. package/types.d.ts +1170 -578
@@ -4,6 +4,7 @@
4
4
 
5
5
  "use strict";
6
6
 
7
+ const { constants } = require("buffer");
7
8
  const createHash = require("../util/createHash");
8
9
  const { dirname, join, mkdirp } = require("../util/fs");
9
10
  const memorize = require("../util/memorize");
@@ -28,14 +29,35 @@ Section -> Buffer
28
29
 
29
30
  */
30
31
 
31
- // "wpc" + 0 in little-endian
32
- const VERSION = 0x00637077;
32
+ // "wpc" + 1 in little-endian
33
+ const VERSION = 0x01637077;
33
34
  const hashForName = buffers => {
34
35
  const hash = createHash("md4");
35
36
  for (const buf of buffers) hash.update(buf);
36
37
  return /** @type {string} */ (hash.digest("hex"));
37
38
  };
38
39
 
40
+ const writeUInt64LE = Buffer.prototype.writeBigUInt64LE
41
+ ? (buf, value, offset) => {
42
+ buf.writeBigUInt64LE(BigInt(value), offset);
43
+ }
44
+ : (buf, value, offset) => {
45
+ const low = value % 0x100000000;
46
+ const high = (value - low) / 0x100000000;
47
+ buf.writeUInt32LE(low, offset);
48
+ buf.writeUInt32LE(high, offset + 4);
49
+ };
50
+
51
+ const readUInt64LE = Buffer.prototype.readBigUInt64LE
52
+ ? (buf, offset) => {
53
+ return Number(buf.readBigUInt64LE(offset));
54
+ }
55
+ : (buf, offset) => {
56
+ const low = buf.readUInt32LE(offset);
57
+ const high = buf.readUInt32LE(offset + 4);
58
+ return high * 0x100000000 + low;
59
+ };
60
+
39
61
  /**
40
62
  * @typedef {Object} SerializeResult
41
63
  * @property {string | false} name
@@ -122,24 +144,29 @@ const serialize = async (middleware, data, name, writeFile) => {
122
144
  // create pointer buffer from size and name
123
145
  const name = /** @type {string} */ (item.name);
124
146
  const nameBuffer = Buffer.from(name);
125
- const buf = Buffer.allocUnsafe(4 + nameBuffer.length);
126
- buf.writeUInt32LE(item.size, 0);
127
- nameBuffer.copy(buf, 4, 0);
147
+ const buf = Buffer.allocUnsafe(8 + nameBuffer.length);
148
+ writeUInt64LE(buf, item.size, 0);
149
+ nameBuffer.copy(buf, 8, 0);
128
150
  const lazy = resultToLazy.get(item);
129
151
  SerializerMiddleware.setLazySerializedValue(lazy, buf);
130
152
  return buf;
131
153
  });
132
- const lengths = resolvedData.map(item => {
154
+ const lengths = [];
155
+ for (const item of resolvedData) {
133
156
  if (Array.isArray(item)) {
134
157
  let l = 0;
135
158
  for (const b of item) l += b.length;
136
- return l;
159
+ while (l > 0x7fffffff) {
160
+ lengths.push(0x7fffffff);
161
+ l -= 0x7fffffff;
162
+ }
163
+ lengths.push(l);
137
164
  } else if (item) {
138
- return -item.length;
165
+ lengths.push(-item.length);
139
166
  } else {
140
167
  throw new Error("Unexpected falsy value in resolved data " + item);
141
168
  }
142
- });
169
+ }
143
170
  const header = Buffer.allocUnsafe(8 + lengths.length * 4);
144
171
  header.writeUInt32LE(VERSION, 0);
145
172
  header.writeUInt32LE(lengths.length, 4);
@@ -173,45 +200,145 @@ const serialize = async (middleware, data, name, writeFile) => {
173
200
  /**
174
201
  * @param {FileMiddleware} middleware this
175
202
  * @param {string | false} name filename
176
- * @param {function(string | false): Promise<Buffer>} readFile read content of a file
203
+ * @param {function(string | false): Promise<Buffer[]>} readFile read content of a file
177
204
  * @returns {Promise<BufferSerializableType[]>} deserialized data
178
205
  */
179
206
  const deserialize = async (middleware, name, readFile) => {
180
- const content = await readFile(name);
181
- if (content.length === 0) throw new Error("Empty file " + name);
182
- const version = content.readUInt32LE(0);
207
+ const contents = await readFile(name);
208
+ if (contents.length === 0) throw new Error("Empty file " + name);
209
+ let contentsIndex = 0;
210
+ let contentItem = contents[0];
211
+ let contentItemLength = contentItem.length;
212
+ let contentPosition = 0;
213
+ if (contentItemLength === 0) throw new Error("Empty file " + name);
214
+ const nextContent = () => {
215
+ contentsIndex++;
216
+ contentItem = contents[contentsIndex];
217
+ contentItemLength = contentItem.length;
218
+ contentPosition = 0;
219
+ };
220
+ const ensureData = n => {
221
+ if (contentPosition === contentItemLength) {
222
+ nextContent();
223
+ }
224
+ while (contentItemLength - contentPosition < n) {
225
+ const remaining = contentItem.slice(contentPosition);
226
+ let lengthFromNext = n - remaining.length;
227
+ const buffers = [remaining];
228
+ for (let i = contentsIndex + 1; i < contents.length; i++) {
229
+ const l = contents[i].length;
230
+ if (l > lengthFromNext) {
231
+ buffers.push(contents[i].slice(0, lengthFromNext));
232
+ contents[i] = contents[i].slice(lengthFromNext);
233
+ lengthFromNext = 0;
234
+ break;
235
+ } else {
236
+ buffers.push(contents[i]);
237
+ contentsIndex = i;
238
+ lengthFromNext -= l;
239
+ }
240
+ }
241
+ if (lengthFromNext > 0) throw new Error("Unexpected end of data");
242
+ contentItem = Buffer.concat(buffers, n);
243
+ contentItemLength = n;
244
+ contentPosition = 0;
245
+ }
246
+ };
247
+ const readUInt32LE = () => {
248
+ ensureData(4);
249
+ const value = contentItem.readUInt32LE(contentPosition);
250
+ contentPosition += 4;
251
+ return value;
252
+ };
253
+ const readInt32LE = () => {
254
+ ensureData(4);
255
+ const value = contentItem.readInt32LE(contentPosition);
256
+ contentPosition += 4;
257
+ return value;
258
+ };
259
+ const readSlice = l => {
260
+ ensureData(l);
261
+ if (contentPosition === 0 && contentItemLength === l) {
262
+ const result = contentItem;
263
+ if (contentsIndex + 1 < contents.length) {
264
+ nextContent();
265
+ } else {
266
+ contentPosition = l;
267
+ }
268
+ return result;
269
+ }
270
+ const result = contentItem.slice(contentPosition, contentPosition + l);
271
+ contentPosition += l;
272
+ // we clone the buffer here to allow the original content to be garbage collected
273
+ return l * 2 < contentItem.buffer.byteLength ? Buffer.from(result) : result;
274
+ };
275
+ const version = readUInt32LE();
183
276
  if (version !== VERSION) {
184
277
  throw new Error("Invalid file version");
185
278
  }
186
- const sectionCount = content.readUInt32LE(4);
279
+ const sectionCount = readUInt32LE();
187
280
  const lengths = [];
188
281
  for (let i = 0; i < sectionCount; i++) {
189
- lengths.push(content.readInt32LE(8 + 4 * i));
282
+ lengths.push(readInt32LE());
190
283
  }
191
- let position = sectionCount * 4 + 8;
192
- const result = lengths.map(length => {
193
- const l = Math.abs(length);
194
- const section = content.slice(position, position + l);
195
- position += l;
284
+ const result = [];
285
+ for (let length of lengths) {
196
286
  if (length < 0) {
197
- // we clone the buffer here to allow the original content to be garbage collected
198
- const clone = Buffer.from(section);
199
- const size = section.readUInt32LE(0);
200
- const nameBuffer = clone.slice(4);
287
+ const slice = readSlice(-length);
288
+ const size = Number(readUInt64LE(slice, 0));
289
+ const nameBuffer = slice.slice(8);
201
290
  const name = nameBuffer.toString();
202
- return SerializerMiddleware.createLazy(
203
- memorize(() => deserialize(middleware, name, readFile)),
204
- middleware,
205
- {
206
- name,
207
- size
208
- },
209
- clone
291
+ result.push(
292
+ SerializerMiddleware.createLazy(
293
+ memorize(() => deserialize(middleware, name, readFile)),
294
+ middleware,
295
+ {
296
+ name,
297
+ size
298
+ },
299
+ slice
300
+ )
210
301
  );
211
302
  } else {
212
- return section;
303
+ if (contentPosition === contentItemLength) {
304
+ nextContent();
305
+ } else if (contentPosition !== 0) {
306
+ if (length <= contentItemLength - contentPosition) {
307
+ result.push(
308
+ contentItem.slice(contentPosition, contentPosition + length)
309
+ );
310
+ contentPosition += length;
311
+ length = 0;
312
+ } else {
313
+ result.push(contentItem.slice(contentPosition));
314
+ length -= contentItemLength - contentPosition;
315
+ contentPosition = contentItemLength;
316
+ }
317
+ } else {
318
+ if (length >= contentItemLength) {
319
+ result.push(contentItem);
320
+ length -= contentItemLength;
321
+ contentPosition = contentItemLength;
322
+ } else {
323
+ result.push(contentItem.slice(0, length));
324
+ contentPosition += length;
325
+ length = 0;
326
+ }
327
+ }
328
+ while (length > 0) {
329
+ nextContent();
330
+ if (length >= contentItemLength) {
331
+ result.push(contentItem);
332
+ length -= contentItemLength;
333
+ contentPosition = contentItemLength;
334
+ } else {
335
+ result.push(contentItem.slice(0, length));
336
+ contentPosition += length;
337
+ length = 0;
338
+ }
339
+ }
213
340
  }
214
- });
341
+ }
215
342
  return result;
216
343
  };
217
344
 
@@ -309,9 +436,72 @@ class FileMiddleware extends SerializerMiddleware {
309
436
  const file = name
310
437
  ? join(this.fs, filename, `../${name}${extension}`)
311
438
  : filename;
312
- return this.fs.readFile(file, (err, content) => {
313
- if (err) return reject(err);
314
- resolve(content);
439
+ this.fs.stat(file, (err, stats) => {
440
+ if (err) {
441
+ reject(err);
442
+ return;
443
+ }
444
+ let remaining = stats.size;
445
+ let currentBuffer;
446
+ let currentBufferUsed;
447
+ const buf = [];
448
+ this.fs.open(file, "r", (err, fd) => {
449
+ if (err) {
450
+ reject(err);
451
+ return;
452
+ }
453
+ const read = () => {
454
+ if (currentBuffer === undefined) {
455
+ currentBuffer = Buffer.allocUnsafeSlow(
456
+ Math.min(constants.MAX_LENGTH, remaining)
457
+ );
458
+ currentBufferUsed = 0;
459
+ }
460
+ let readBuffer = currentBuffer;
461
+ let readOffset = currentBufferUsed;
462
+ let readLength = currentBuffer.length - currentBufferUsed;
463
+ if (readOffset > 0x7fffffff) {
464
+ readBuffer = currentBuffer.slice(readOffset);
465
+ readOffset = 0;
466
+ }
467
+ if (readLength > 0x7fffffff) {
468
+ readLength = 0x7fffffff;
469
+ }
470
+ this.fs.read(
471
+ fd,
472
+ readBuffer,
473
+ readOffset,
474
+ readLength,
475
+ null,
476
+ (err, bytesRead) => {
477
+ if (err) {
478
+ this.fs.close(fd, () => {
479
+ reject(err);
480
+ });
481
+ return;
482
+ }
483
+ currentBufferUsed += bytesRead;
484
+ remaining -= bytesRead;
485
+ if (currentBufferUsed === currentBuffer.length) {
486
+ buf.push(currentBuffer);
487
+ currentBuffer = undefined;
488
+ if (remaining === 0) {
489
+ this.fs.close(fd, err => {
490
+ if (err) {
491
+ reject(err);
492
+ return;
493
+ }
494
+ resolve(buf);
495
+ });
496
+ return;
497
+ }
498
+ }
499
+ read();
500
+ }
501
+ );
502
+ };
503
+ read();
504
+ });
315
505
  });
316
506
  });
317
507
  return deserialize(this, false, readFile);
@@ -4,6 +4,7 @@
4
4
 
5
5
  "use strict";
6
6
 
7
+ const createHash = require("../util/createHash");
7
8
  const ArraySerializer = require("./ArraySerializer");
8
9
  const DateObjectSerializer = require("./DateObjectSerializer");
9
10
  const ErrorObjectSerializer = require("./ErrorObjectSerializer");
@@ -75,6 +76,12 @@ const setMapSize = (map, size) => {
75
76
  }
76
77
  };
77
78
 
79
+ const toHash = buffer => {
80
+ const hash = createHash("md4");
81
+ hash.update(buffer);
82
+ return /** @type {string} */ (hash.digest("latin1"));
83
+ };
84
+
78
85
  const ESCAPE = null;
79
86
  const ESCAPE_ESCAPE_VALUE = null;
80
87
  const ESCAPE_END_OBJECT = true;
@@ -244,6 +251,68 @@ class ObjectMiddleware extends SerializerMiddleware {
244
251
  const addReferenceable = item => {
245
252
  referenceable.set(item, currentPos++);
246
253
  };
254
+ const bufferDedupeMap = new Map();
255
+ const dedupeBuffer = buf => {
256
+ const len = buf.length;
257
+ const entry = bufferDedupeMap.get(len);
258
+ if (entry === undefined) {
259
+ bufferDedupeMap.set(len, buf);
260
+ return buf;
261
+ }
262
+ if (Buffer.isBuffer(entry)) {
263
+ if (len < 32) {
264
+ if (buf.equals(entry)) {
265
+ return entry;
266
+ }
267
+ bufferDedupeMap.set(len, [entry, buf]);
268
+ return buf;
269
+ } else {
270
+ const hash = toHash(entry);
271
+ const newMap = new Map();
272
+ newMap.set(hash, entry);
273
+ bufferDedupeMap.set(len, newMap);
274
+ const hashBuf = toHash(buf);
275
+ if (hash === hashBuf) {
276
+ return entry;
277
+ }
278
+ return buf;
279
+ }
280
+ } else if (Array.isArray(entry)) {
281
+ if (entry.length < 16) {
282
+ for (const item of entry) {
283
+ if (buf.equals(item)) {
284
+ return item;
285
+ }
286
+ }
287
+ entry.push(buf);
288
+ return buf;
289
+ } else {
290
+ const newMap = new Map();
291
+ const hash = toHash(buf);
292
+ let found;
293
+ for (const item of entry) {
294
+ const itemHash = toHash(item);
295
+ newMap.set(itemHash, item);
296
+ if (found === undefined && itemHash === hash) found = item;
297
+ }
298
+ bufferDedupeMap.set(len, newMap);
299
+ if (found === undefined) {
300
+ newMap.set(hash, buf);
301
+ return buf;
302
+ } else {
303
+ return found;
304
+ }
305
+ }
306
+ } else {
307
+ const hash = toHash(buf);
308
+ const item = entry.get(hash);
309
+ if (item !== undefined) {
310
+ return item;
311
+ }
312
+ entry.set(hash, buf);
313
+ return buf;
314
+ }
315
+ };
247
316
  let currentPosTypeLookup = 0;
248
317
  const objectTypeLookup = new Map();
249
318
  const cycleStack = new Set();
@@ -339,6 +408,16 @@ class ObjectMiddleware extends SerializerMiddleware {
339
408
  }
340
409
 
341
410
  if (Buffer.isBuffer(item)) {
411
+ const alreadyUsedBuffer = dedupeBuffer(item);
412
+ if (alreadyUsedBuffer !== item) {
413
+ const ref = referenceable.get(alreadyUsedBuffer);
414
+ if (ref !== undefined) {
415
+ referenceable.set(item, ref);
416
+ result.push(ESCAPE, ref - currentPos);
417
+ return;
418
+ }
419
+ item = alreadyUsedBuffer;
420
+ }
342
421
  addReferenceable(item);
343
422
 
344
423
  result.push(item);
@@ -373,8 +452,8 @@ class ObjectMiddleware extends SerializerMiddleware {
373
452
 
374
453
  addReferenceable(item);
375
454
  } else if (typeof item === "string") {
376
- if (item !== "") {
377
- // empty strings are shorter when not emitting a reference (this saves 1 byte per empty string)
455
+ if (item.length > 1) {
456
+ // short strings are shorter when not emitting a reference (this saves 1 byte per empty string)
378
457
  addReferenceable(item);
379
458
  }
380
459
 
@@ -449,13 +528,13 @@ class ObjectMiddleware extends SerializerMiddleware {
449
528
  throw new Error("Version mismatch, serializer changed");
450
529
 
451
530
  let currentPos = 0;
452
- const referenceable = [];
531
+ let referenceable = [];
453
532
  const addReferenceable = item => {
454
533
  referenceable.push(item);
455
534
  currentPos++;
456
535
  };
457
536
  let currentPosTypeLookup = 0;
458
- const objectTypeLookup = [];
537
+ let objectTypeLookup = [];
459
538
  const result = [];
460
539
  const ctx = {
461
540
  read() {
@@ -558,7 +637,7 @@ class ObjectMiddleware extends SerializerMiddleware {
558
637
  }
559
638
  }
560
639
  } else if (typeof item === "string") {
561
- if (item !== "") {
640
+ if (item.length > 1) {
562
641
  addReferenceable(item);
563
642
  }
564
643
 
@@ -581,6 +660,11 @@ class ObjectMiddleware extends SerializerMiddleware {
581
660
  result.push(decodeValue());
582
661
  }
583
662
 
663
+ // Help the GC, as functions above might be cached in inline caches
664
+ referenceable = undefined;
665
+ objectTypeLookup = undefined;
666
+ data = undefined;
667
+
584
668
  return result;
585
669
  }
586
670
  }
@@ -22,7 +22,7 @@ const {
22
22
 
23
23
  class ConsumeSharedRuntimeModule extends RuntimeModule {
24
24
  constructor(runtimeRequirements) {
25
- super("consumes", 10);
25
+ super("consumes", RuntimeModule.STAGE_ATTACH);
26
26
  this._runtimeRequirements = runtimeRequirements;
27
27
  }
28
28
 
package/lib/util/fs.js CHANGED
@@ -16,6 +16,7 @@ const path = require("path");
16
16
  /** @typedef {function(NodeJS.ErrnoException=, Buffer|string=): void} BufferOrStringCallback */
17
17
  /** @typedef {function(NodeJS.ErrnoException=, string[]=): void} StringArrayCallback */
18
18
  /** @typedef {function(NodeJS.ErrnoException=, string=): void} StringCallback */
19
+ /** @typedef {function(NodeJS.ErrnoException=, number=): void} NumberCallback */
19
20
  /** @typedef {function(NodeJS.ErrnoException=, NodeFsStats=): void} StatsCallback */
20
21
  /** @typedef {function((NodeJS.ErrnoException | Error)=, any=): void} ReadJsonCallback */
21
22
 
@@ -73,6 +74,9 @@ const path = require("path");
73
74
  * @typedef {Object} IntermediateFileSystemExtras
74
75
  * @property {function(string): void} mkdirSync
75
76
  * @property {function(string): import("fs").WriteStream} createWriteStream
77
+ * @property {function(string, string, NumberCallback): void} open
78
+ * @property {function(number, Buffer, number, number, number, NumberCallback): void} read
79
+ * @property {function(number, Callback): void} close
76
80
  * @property {function(string, string, Callback): void} rename
77
81
  */
78
82
 
@@ -0,0 +1,61 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Tobias Koppers @sokra
4
+ */
5
+
6
+ "use strict";
7
+
8
+ /** @typedef {import("webpack-sources").Source} Source */
9
+
10
+ /** @type {WeakMap<Source, WeakMap<Source, boolean>>} */
11
+ const equalityCache = new WeakMap();
12
+
13
+ /**
14
+ * @param {Source} a a source
15
+ * @param {Source} b another source
16
+ * @returns {boolean} true, when both sources are equal
17
+ */
18
+ const _isSourceEqual = (a, b) => {
19
+ // prefer .buffer(), it's called anyway during emit
20
+ /** @type {Buffer|string} */
21
+ let aSource = typeof a.buffer === "function" ? a.buffer() : a.source();
22
+ /** @type {Buffer|string} */
23
+ let bSource = typeof b.buffer === "function" ? b.buffer() : b.source();
24
+ if (aSource === bSource) return true;
25
+ if (typeof aSource === "string" && typeof bSource === "string") return false;
26
+ if (!Buffer.isBuffer(aSource)) aSource = Buffer.from(aSource, "utf-8");
27
+ if (!Buffer.isBuffer(bSource)) bSource = Buffer.from(bSource, "utf-8");
28
+ return aSource.equals(bSource);
29
+ };
30
+
31
+ /**
32
+ * @param {Source} a a source
33
+ * @param {Source} b another source
34
+ * @returns {boolean} true, when both sources are equal
35
+ */
36
+ const isSourceEqual = (a, b) => {
37
+ if (a === b) return true;
38
+ const cache1 = equalityCache.get(a);
39
+ if (cache1 !== undefined) {
40
+ const result = cache1.get(b);
41
+ if (result !== undefined) return result;
42
+ }
43
+ const result = _isSourceEqual(a, b);
44
+ if (cache1 !== undefined) {
45
+ cache1.set(b, result);
46
+ } else {
47
+ const map = new WeakMap();
48
+ map.set(b, result);
49
+ equalityCache.set(a, map);
50
+ }
51
+ const cache2 = equalityCache.get(b);
52
+ if (cache2 !== undefined) {
53
+ cache2.set(a, result);
54
+ } else {
55
+ const map = new WeakMap();
56
+ map.set(a, result);
57
+ equalityCache.set(b, map);
58
+ }
59
+ return result;
60
+ };
61
+ exports.isSourceEqual = isSourceEqual;