webpack 5.49.0 → 5.51.2

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 (41) hide show
  1. package/README.md +4 -16
  2. package/bin/webpack.js +0 -0
  3. package/lib/ChunkGraph.js +75 -1
  4. package/lib/CompatibilityPlugin.js +21 -4
  5. package/lib/Compilation.js +10 -1
  6. package/lib/Compiler.js +7 -0
  7. package/lib/EvalSourceMapDevToolPlugin.js +2 -2
  8. package/lib/FileSystemInfo.js +660 -191
  9. package/lib/HotModuleReplacementPlugin.js +14 -0
  10. package/lib/NormalModule.js +13 -3
  11. package/lib/Parser.js +1 -0
  12. package/lib/RuntimeGlobals.js +5 -0
  13. package/lib/RuntimeModule.js +2 -1
  14. package/lib/SourceMapDevToolPlugin.js +2 -2
  15. package/lib/Watching.js +8 -10
  16. package/lib/config/defaults.js +1 -1
  17. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +6 -2
  18. package/lib/esm/ModuleChunkLoadingRuntimeModule.js +10 -1
  19. package/lib/javascript/JavascriptParser.js +2 -0
  20. package/lib/library/ModuleLibraryPlugin.js +4 -0
  21. package/lib/node/ReadFileChunkLoadingRuntimeModule.js +7 -1
  22. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +2 -2
  23. package/lib/node/ReadFileCompileWasmPlugin.js +2 -1
  24. package/lib/node/RequireChunkLoadingRuntimeModule.js +7 -1
  25. package/lib/optimize/ConcatenatedModule.js +3 -3
  26. package/lib/optimize/SplitChunksPlugin.js +1 -1
  27. package/lib/runtime/GetChunkFilenameRuntimeModule.js +1 -0
  28. package/lib/serialization/BinaryMiddleware.js +293 -265
  29. package/lib/util/fs.js +40 -0
  30. package/lib/util/identifier.js +26 -8
  31. package/lib/util/propertyAccess.js +54 -1
  32. package/lib/wasm-async/{AsyncWasmChunkLoadingRuntimeModule.js → AsyncWasmLoadingRuntimeModule.js} +3 -3
  33. package/lib/wasm-sync/WasmChunkLoadingRuntimeModule.js +18 -2
  34. package/lib/web/FetchCompileAsyncWasmPlugin.js +2 -2
  35. package/lib/web/FetchCompileWasmPlugin.js +2 -1
  36. package/lib/web/JsonpChunkLoadingRuntimeModule.js +21 -8
  37. package/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js +7 -1
  38. package/package.json +2 -1
  39. package/schemas/WebpackOptions.json +1 -1
  40. package/schemas/plugins/schemes/HttpUriPlugin.json +1 -1
  41. package/types.d.ts +63 -9
@@ -133,17 +133,29 @@ class BinaryMiddleware extends SerializerMiddleware {
133
133
  /**
134
134
  * @param {DeserializedType} data data
135
135
  * @param {Object} context context object
136
+ * @param {{ leftOverBuffer: Buffer | null, allocationSize: number, increaseCounter: number }} allocationScope allocation scope
136
137
  * @returns {SerializedType} serialized data
137
138
  */
138
- _serialize(data, context) {
139
- /** @type {Buffer} */
140
- let currentBuffer = null;
139
+ _serialize(
140
+ data,
141
+ context,
142
+ allocationScope = {
143
+ allocationSize: 1024,
144
+ increaseCounter: 0,
145
+ leftOverBuffer: null
146
+ }
147
+ ) {
141
148
  /** @type {Buffer} */
142
149
  let leftOverBuffer = null;
143
- let currentPosition = 0;
144
150
  /** @type {BufferSerializableType[]} */
145
151
  let buffers = [];
146
- let buffersTotalLength = 0;
152
+ /** @type {Buffer} */
153
+ let currentBuffer = allocationScope ? allocationScope.leftOverBuffer : null;
154
+ allocationScope.leftOverBuffer = null;
155
+ let currentPosition = 0;
156
+ if (currentBuffer === null) {
157
+ currentBuffer = Buffer.allocUnsafe(allocationScope.allocationSize);
158
+ }
147
159
  const allocate = bytesNeeded => {
148
160
  if (currentBuffer !== null) {
149
161
  if (currentBuffer.length - currentPosition >= bytesNeeded) return;
@@ -154,22 +166,28 @@ class BinaryMiddleware extends SerializerMiddleware {
154
166
  leftOverBuffer = null;
155
167
  } else {
156
168
  currentBuffer = Buffer.allocUnsafe(
157
- Math.max(
158
- bytesNeeded,
159
- Math.min(Math.max(buffersTotalLength, 1024), 16384)
160
- )
169
+ Math.max(bytesNeeded, allocationScope.allocationSize)
161
170
  );
171
+ if (
172
+ !(allocationScope.increaseCounter =
173
+ (allocationScope.increaseCounter + 1) % 4) &&
174
+ allocationScope.allocationSize < 16777216
175
+ ) {
176
+ allocationScope.allocationSize = allocationScope.allocationSize << 1;
177
+ }
162
178
  }
163
179
  };
164
180
  const flush = () => {
165
181
  if (currentBuffer !== null) {
166
- buffers.push(
167
- Buffer.from(
168
- currentBuffer.buffer,
169
- currentBuffer.byteOffset,
170
- currentPosition
171
- )
172
- );
182
+ if (currentPosition > 0) {
183
+ buffers.push(
184
+ Buffer.from(
185
+ currentBuffer.buffer,
186
+ currentBuffer.byteOffset,
187
+ currentPosition
188
+ )
189
+ );
190
+ }
173
191
  if (
174
192
  !leftOverBuffer ||
175
193
  leftOverBuffer.length < currentBuffer.length - currentPosition
@@ -180,8 +198,8 @@ class BinaryMiddleware extends SerializerMiddleware {
180
198
  currentBuffer.byteLength - currentPosition
181
199
  );
182
200
  }
201
+
183
202
  currentBuffer = null;
184
- buffersTotalLength += currentPosition;
185
203
  currentPosition = 0;
186
204
  }
187
205
  };
@@ -205,232 +223,237 @@ class BinaryMiddleware extends SerializerMiddleware {
205
223
  }
206
224
  return size;
207
225
  };
208
- const serializeData = data => {
209
- for (let i = 0; i < data.length; i++) {
210
- const thing = data[i];
211
- switch (typeof thing) {
212
- case "function": {
213
- if (!SerializerMiddleware.isLazy(thing))
214
- throw new Error("Unexpected function " + thing);
215
- /** @type {SerializedType | (() => SerializedType)} */
216
- let serializedData =
217
- SerializerMiddleware.getLazySerializedValue(thing);
218
- if (serializedData === undefined) {
219
- if (SerializerMiddleware.isLazy(thing, this)) {
220
- const data = this._serialize(thing(), context);
221
- SerializerMiddleware.setLazySerializedValue(thing, data);
222
- serializedData = data;
223
- } else {
224
- serializedData = this._serializeLazy(thing, context);
225
- }
226
+ for (let i = 0; i < data.length; i++) {
227
+ const thing = data[i];
228
+ switch (typeof thing) {
229
+ case "function": {
230
+ if (!SerializerMiddleware.isLazy(thing))
231
+ throw new Error("Unexpected function " + thing);
232
+ /** @type {SerializedType | (() => SerializedType)} */
233
+ let serializedData =
234
+ SerializerMiddleware.getLazySerializedValue(thing);
235
+ if (serializedData === undefined) {
236
+ if (SerializerMiddleware.isLazy(thing, this)) {
237
+ flush();
238
+ allocationScope.leftOverBuffer = leftOverBuffer;
239
+ const result =
240
+ /** @type {(Exclude<PrimitiveSerializableType, Promise<PrimitiveSerializableType>>)[]} */ (
241
+ thing()
242
+ );
243
+ const data = this._serialize(result, context, allocationScope);
244
+ leftOverBuffer = allocationScope.leftOverBuffer;
245
+ allocationScope.leftOverBuffer = null;
246
+ SerializerMiddleware.setLazySerializedValue(thing, data);
247
+ serializedData = data;
248
+ } else {
249
+ serializedData = this._serializeLazy(thing, context);
250
+ flush();
251
+ buffers.push(serializedData);
252
+ break;
226
253
  }
254
+ } else {
227
255
  if (typeof serializedData === "function") {
228
256
  flush();
229
257
  buffers.push(serializedData);
230
- } else {
231
- const lengths = [];
232
- for (const item of serializedData) {
233
- let last;
234
- if (typeof item === "function") {
235
- lengths.push(0);
236
- } else if (item.length === 0) {
237
- // ignore
238
- } else if (
239
- lengths.length > 0 &&
240
- (last = lengths[lengths.length - 1]) !== 0
241
- ) {
242
- const remaining = 0xffffffff - last;
243
- if (remaining >= item.length) {
244
- lengths[lengths.length - 1] += item.length;
245
- } else {
246
- lengths.push(item.length - remaining);
247
- lengths[lengths.length - 2] = 0xffffffff;
248
- }
249
- } else {
250
- lengths.push(item.length);
251
- }
252
- }
253
- allocate(5 + lengths.length * 4);
254
- writeU8(LAZY_HEADER);
255
- writeU32(lengths.length);
256
- for (const l of lengths) {
257
- writeU32(l);
258
- }
259
- flush();
260
- for (const item of serializedData) {
261
- buffers.push(item);
262
- }
258
+ break;
263
259
  }
264
- break;
265
260
  }
266
- case "string": {
267
- const len = Buffer.byteLength(thing);
268
- if (len >= 128 || len !== thing.length) {
269
- allocate(len + HEADER_SIZE + I32_SIZE);
270
- writeU8(STRING_HEADER);
271
- writeU32(len);
272
- currentBuffer.write(thing, currentPosition);
261
+ const lengths = [];
262
+ for (const item of serializedData) {
263
+ let last;
264
+ if (typeof item === "function") {
265
+ lengths.push(0);
266
+ } else if (item.length === 0) {
267
+ // ignore
268
+ } else if (
269
+ lengths.length > 0 &&
270
+ (last = lengths[lengths.length - 1]) !== 0
271
+ ) {
272
+ const remaining = 0xffffffff - last;
273
+ if (remaining >= item.length) {
274
+ lengths[lengths.length - 1] += item.length;
275
+ } else {
276
+ lengths.push(item.length - remaining);
277
+ lengths[lengths.length - 2] = 0xffffffff;
278
+ }
273
279
  } else {
274
- allocate(len + HEADER_SIZE);
275
- writeU8(SHORT_STRING_HEADER | len);
276
- currentBuffer.write(thing, currentPosition, "latin1");
280
+ lengths.push(item.length);
277
281
  }
278
- currentPosition += len;
282
+ }
283
+ allocate(5 + lengths.length * 4);
284
+ writeU8(LAZY_HEADER);
285
+ writeU32(lengths.length);
286
+ for (const l of lengths) {
287
+ writeU32(l);
288
+ }
289
+ flush();
290
+ for (const item of serializedData) {
291
+ buffers.push(item);
292
+ }
293
+ break;
294
+ }
295
+ case "string": {
296
+ const len = Buffer.byteLength(thing);
297
+ if (len >= 128 || len !== thing.length) {
298
+ allocate(len + HEADER_SIZE + I32_SIZE);
299
+ writeU8(STRING_HEADER);
300
+ writeU32(len);
301
+ currentBuffer.write(thing, currentPosition);
302
+ } else {
303
+ allocate(len + HEADER_SIZE);
304
+ writeU8(SHORT_STRING_HEADER | len);
305
+ currentBuffer.write(thing, currentPosition, "latin1");
306
+ }
307
+ currentPosition += len;
308
+ break;
309
+ }
310
+ case "number": {
311
+ const type = identifyNumber(thing);
312
+ if (type === 0 && thing >= 0 && thing <= 10) {
313
+ // shortcut for very small numbers
314
+ allocate(I8_SIZE);
315
+ writeU8(thing);
279
316
  break;
280
317
  }
281
- case "number": {
282
- const type = identifyNumber(thing);
283
- if (type === 0 && thing >= 0 && thing <= 10) {
284
- // shortcut for very small numbers
285
- allocate(I8_SIZE);
286
- writeU8(thing);
318
+ /**
319
+ * amount of numbers to write
320
+ * @type {number}
321
+ */
322
+ let n = 1;
323
+ for (; n < 32 && i + n < data.length; n++) {
324
+ const item = data[i + n];
325
+ if (typeof item !== "number") break;
326
+ if (identifyNumber(item) !== type) break;
327
+ }
328
+ switch (type) {
329
+ case 0:
330
+ allocate(HEADER_SIZE + I8_SIZE * n);
331
+ writeU8(I8_HEADER | (n - 1));
332
+ while (n > 0) {
333
+ currentBuffer.writeInt8(
334
+ /** @type {number} */ (data[i]),
335
+ currentPosition
336
+ );
337
+ currentPosition += I8_SIZE;
338
+ n--;
339
+ i++;
340
+ }
287
341
  break;
288
- }
289
- /**
290
- * amount of numbers to write
291
- * @type {number}
292
- */
293
- let n = 1;
294
- for (; n < 32 && i + n < data.length; n++) {
295
- const item = data[i + n];
296
- if (typeof item !== "number") break;
297
- if (identifyNumber(item) !== type) break;
298
- }
299
- switch (type) {
300
- case 0:
301
- allocate(HEADER_SIZE + I8_SIZE * n);
302
- writeU8(I8_HEADER | (n - 1));
303
- while (n > 0) {
304
- currentBuffer.writeInt8(
305
- /** @type {number} */ (data[i]),
306
- currentPosition
307
- );
308
- currentPosition += I8_SIZE;
309
- n--;
310
- i++;
311
- }
312
- break;
313
- case 1:
314
- allocate(HEADER_SIZE + I32_SIZE * n);
315
- writeU8(I32_HEADER | (n - 1));
316
- while (n > 0) {
317
- currentBuffer.writeInt32LE(
318
- /** @type {number} */ (data[i]),
319
- currentPosition
320
- );
321
- currentPosition += I32_SIZE;
322
- n--;
323
- i++;
324
- }
325
- break;
326
- case 2:
327
- allocate(HEADER_SIZE + F64_SIZE * n);
328
- writeU8(F64_HEADER | (n - 1));
329
- while (n > 0) {
330
- currentBuffer.writeDoubleLE(
331
- /** @type {number} */ (data[i]),
332
- currentPosition
333
- );
334
- currentPosition += F64_SIZE;
335
- n--;
336
- i++;
337
- }
338
- break;
339
- }
342
+ case 1:
343
+ allocate(HEADER_SIZE + I32_SIZE * n);
344
+ writeU8(I32_HEADER | (n - 1));
345
+ while (n > 0) {
346
+ currentBuffer.writeInt32LE(
347
+ /** @type {number} */ (data[i]),
348
+ currentPosition
349
+ );
350
+ currentPosition += I32_SIZE;
351
+ n--;
352
+ i++;
353
+ }
354
+ break;
355
+ case 2:
356
+ allocate(HEADER_SIZE + F64_SIZE * n);
357
+ writeU8(F64_HEADER | (n - 1));
358
+ while (n > 0) {
359
+ currentBuffer.writeDoubleLE(
360
+ /** @type {number} */ (data[i]),
361
+ currentPosition
362
+ );
363
+ currentPosition += F64_SIZE;
364
+ n--;
365
+ i++;
366
+ }
367
+ break;
368
+ }
340
369
 
341
- i--;
342
- break;
370
+ i--;
371
+ break;
372
+ }
373
+ case "boolean": {
374
+ let lastByte = thing === true ? 1 : 0;
375
+ const bytes = [];
376
+ let count = 1;
377
+ let n;
378
+ for (n = 1; n < 0xffffffff && i + n < data.length; n++) {
379
+ const item = data[i + n];
380
+ if (typeof item !== "boolean") break;
381
+ const pos = count & 0x7;
382
+ if (pos === 0) {
383
+ bytes.push(lastByte);
384
+ lastByte = item === true ? 1 : 0;
385
+ } else if (item === true) {
386
+ lastByte |= 1 << pos;
387
+ }
388
+ count++;
389
+ }
390
+ i += count - 1;
391
+ if (count === 1) {
392
+ allocate(HEADER_SIZE);
393
+ writeU8(lastByte === 1 ? TRUE_HEADER : FALSE_HEADER);
394
+ } else if (count === 2) {
395
+ allocate(HEADER_SIZE * 2);
396
+ writeU8(lastByte & 1 ? TRUE_HEADER : FALSE_HEADER);
397
+ writeU8(lastByte & 2 ? TRUE_HEADER : FALSE_HEADER);
398
+ } else if (count <= 6) {
399
+ allocate(HEADER_SIZE + I8_SIZE);
400
+ writeU8(BOOLEANS_HEADER);
401
+ writeU8((1 << count) | lastByte);
402
+ } else if (count <= 133) {
403
+ allocate(HEADER_SIZE + I8_SIZE + I8_SIZE * bytes.length + I8_SIZE);
404
+ writeU8(BOOLEANS_HEADER);
405
+ writeU8(0x80 | (count - 7));
406
+ for (const byte of bytes) writeU8(byte);
407
+ writeU8(lastByte);
408
+ } else {
409
+ allocate(
410
+ HEADER_SIZE +
411
+ I8_SIZE +
412
+ I32_SIZE +
413
+ I8_SIZE * bytes.length +
414
+ I8_SIZE
415
+ );
416
+ writeU8(BOOLEANS_HEADER);
417
+ writeU8(0xff);
418
+ writeU32(count);
419
+ for (const byte of bytes) writeU8(byte);
420
+ writeU8(lastByte);
343
421
  }
344
- case "boolean": {
345
- let lastByte = thing === true ? 1 : 0;
346
- const bytes = [];
347
- let count = 1;
422
+ break;
423
+ }
424
+ case "object": {
425
+ if (thing === null) {
348
426
  let n;
349
- for (n = 1; n < 0xffffffff && i + n < data.length; n++) {
427
+ for (n = 1; n < 0x100000104 && i + n < data.length; n++) {
350
428
  const item = data[i + n];
351
- if (typeof item !== "boolean") break;
352
- const pos = count & 0x7;
353
- if (pos === 0) {
354
- bytes.push(lastByte);
355
- lastByte = item === true ? 1 : 0;
356
- } else if (item === true) {
357
- lastByte |= 1 << pos;
358
- }
359
- count++;
360
- }
361
- i += count - 1;
362
- if (count === 1) {
363
- allocate(HEADER_SIZE);
364
- writeU8(lastByte === 1 ? TRUE_HEADER : FALSE_HEADER);
365
- } else if (count === 2) {
366
- allocate(HEADER_SIZE * 2);
367
- writeU8(lastByte & 1 ? TRUE_HEADER : FALSE_HEADER);
368
- writeU8(lastByte & 2 ? TRUE_HEADER : FALSE_HEADER);
369
- } else if (count <= 6) {
370
- allocate(HEADER_SIZE + I8_SIZE);
371
- writeU8(BOOLEANS_HEADER);
372
- writeU8((1 << count) | lastByte);
373
- } else if (count <= 133) {
374
- allocate(
375
- HEADER_SIZE + I8_SIZE + I8_SIZE * bytes.length + I8_SIZE
376
- );
377
- writeU8(BOOLEANS_HEADER);
378
- writeU8(0x80 | (count - 7));
379
- for (const byte of bytes) writeU8(byte);
380
- writeU8(lastByte);
381
- } else {
382
- allocate(
383
- HEADER_SIZE +
384
- I8_SIZE +
385
- I32_SIZE +
386
- I8_SIZE * bytes.length +
387
- I8_SIZE
388
- );
389
- writeU8(BOOLEANS_HEADER);
390
- writeU8(0xff);
391
- writeU32(count);
392
- for (const byte of bytes) writeU8(byte);
393
- writeU8(lastByte);
429
+ if (item !== null) break;
394
430
  }
395
- break;
396
- }
397
- case "object": {
398
- if (thing === null) {
399
- let n;
400
- for (n = 1; n < 0x100000104 && i + n < data.length; n++) {
401
- const item = data[i + n];
402
- if (item !== null) break;
403
- }
404
- i += n - 1;
405
- if (n === 1) {
406
- if (i + 1 < data.length) {
407
- const next = data[i + 1];
408
- if (next === true) {
409
- allocate(HEADER_SIZE);
410
- writeU8(NULL_AND_TRUE_HEADER);
431
+ i += n - 1;
432
+ if (n === 1) {
433
+ if (i + 1 < data.length) {
434
+ const next = data[i + 1];
435
+ if (next === true) {
436
+ allocate(HEADER_SIZE);
437
+ writeU8(NULL_AND_TRUE_HEADER);
438
+ i++;
439
+ } else if (next === false) {
440
+ allocate(HEADER_SIZE);
441
+ writeU8(NULL_AND_FALSE_HEADER);
442
+ i++;
443
+ } else if (typeof next === "number") {
444
+ const type = identifyNumber(next);
445
+ if (type === 0) {
446
+ allocate(HEADER_SIZE + I8_SIZE);
447
+ writeU8(NULL_AND_I8_HEADER);
448
+ currentBuffer.writeInt8(next, currentPosition);
449
+ currentPosition += I8_SIZE;
411
450
  i++;
412
- } else if (next === false) {
413
- allocate(HEADER_SIZE);
414
- writeU8(NULL_AND_FALSE_HEADER);
451
+ } else if (type === 1) {
452
+ allocate(HEADER_SIZE + I32_SIZE);
453
+ writeU8(NULL_AND_I32_HEADER);
454
+ currentBuffer.writeInt32LE(next, currentPosition);
455
+ currentPosition += I32_SIZE;
415
456
  i++;
416
- } else if (typeof next === "number") {
417
- const type = identifyNumber(next);
418
- if (type === 0) {
419
- allocate(HEADER_SIZE + I8_SIZE);
420
- writeU8(NULL_AND_I8_HEADER);
421
- currentBuffer.writeInt8(next, currentPosition);
422
- currentPosition += I8_SIZE;
423
- i++;
424
- } else if (type === 1) {
425
- allocate(HEADER_SIZE + I32_SIZE);
426
- writeU8(NULL_AND_I32_HEADER);
427
- currentBuffer.writeInt32LE(next, currentPosition);
428
- currentPosition += I32_SIZE;
429
- i++;
430
- } else {
431
- allocate(HEADER_SIZE);
432
- writeU8(NULL_HEADER);
433
- }
434
457
  } else {
435
458
  allocate(HEADER_SIZE);
436
459
  writeU8(NULL_HEADER);
@@ -439,59 +462,64 @@ class BinaryMiddleware extends SerializerMiddleware {
439
462
  allocate(HEADER_SIZE);
440
463
  writeU8(NULL_HEADER);
441
464
  }
442
- } else if (n === 2) {
443
- allocate(HEADER_SIZE);
444
- writeU8(NULL2_HEADER);
445
- } else if (n === 3) {
446
- allocate(HEADER_SIZE);
447
- writeU8(NULL3_HEADER);
448
- } else if (n < 260) {
449
- allocate(HEADER_SIZE + I8_SIZE);
450
- writeU8(NULLS8_HEADER);
451
- writeU8(n - 4);
452
- } else {
453
- allocate(HEADER_SIZE + I32_SIZE);
454
- writeU8(NULLS32_HEADER);
455
- writeU32(n - 260);
456
- }
457
- } else if (Buffer.isBuffer(thing)) {
458
- if (thing.length < 8192) {
459
- allocate(HEADER_SIZE + I32_SIZE + thing.length);
460
- writeU8(BUFFER_HEADER);
461
- writeU32(thing.length);
462
- thing.copy(currentBuffer, currentPosition);
463
- currentPosition += thing.length;
464
465
  } else {
465
- allocate(HEADER_SIZE + I32_SIZE);
466
- writeU8(BUFFER_HEADER);
467
- writeU32(thing.length);
468
- flush();
469
- buffers.push(thing);
466
+ allocate(HEADER_SIZE);
467
+ writeU8(NULL_HEADER);
470
468
  }
469
+ } else if (n === 2) {
470
+ allocate(HEADER_SIZE);
471
+ writeU8(NULL2_HEADER);
472
+ } else if (n === 3) {
473
+ allocate(HEADER_SIZE);
474
+ writeU8(NULL3_HEADER);
475
+ } else if (n < 260) {
476
+ allocate(HEADER_SIZE + I8_SIZE);
477
+ writeU8(NULLS8_HEADER);
478
+ writeU8(n - 4);
479
+ } else {
480
+ allocate(HEADER_SIZE + I32_SIZE);
481
+ writeU8(NULLS32_HEADER);
482
+ writeU32(n - 260);
471
483
  }
472
- break;
473
- }
474
- case "symbol": {
475
- if (thing === MEASURE_START_OPERATION) {
476
- measureStart();
477
- } else if (thing === MEASURE_END_OPERATION) {
478
- const size = measureEnd();
484
+ } else if (Buffer.isBuffer(thing)) {
485
+ if (thing.length < 8192) {
486
+ allocate(HEADER_SIZE + I32_SIZE + thing.length);
487
+ writeU8(BUFFER_HEADER);
488
+ writeU32(thing.length);
489
+ thing.copy(currentBuffer, currentPosition);
490
+ currentPosition += thing.length;
491
+ } else {
479
492
  allocate(HEADER_SIZE + I32_SIZE);
480
- writeU8(I32_HEADER);
481
- currentBuffer.writeInt32LE(size, currentPosition);
482
- currentPosition += I32_SIZE;
493
+ writeU8(BUFFER_HEADER);
494
+ writeU32(thing.length);
495
+ flush();
496
+ buffers.push(thing);
483
497
  }
484
- break;
485
498
  }
499
+ break;
500
+ }
501
+ case "symbol": {
502
+ if (thing === MEASURE_START_OPERATION) {
503
+ measureStart();
504
+ } else if (thing === MEASURE_END_OPERATION) {
505
+ const size = measureEnd();
506
+ allocate(HEADER_SIZE + I32_SIZE);
507
+ writeU8(I32_HEADER);
508
+ currentBuffer.writeInt32LE(size, currentPosition);
509
+ currentPosition += I32_SIZE;
510
+ }
511
+ break;
486
512
  }
487
513
  }
488
- };
489
- serializeData(data);
514
+ }
490
515
  flush();
491
516
 
517
+ allocationScope.leftOverBuffer = leftOverBuffer;
518
+
492
519
  // avoid leaking memory
493
520
  currentBuffer = null;
494
521
  leftOverBuffer = null;
522
+ allocationScope = undefined;
495
523
  const _buffers = buffers;
496
524
  buffers = undefined;
497
525
  return _buffers;
package/lib/util/fs.js CHANGED
@@ -59,6 +59,7 @@ const path = require("path");
59
59
  /** @typedef {function((NodeJS.ErrnoException | null)=, number=): void} NumberCallback */
60
60
  /** @typedef {function((NodeJS.ErrnoException | null)=, IStats=): void} StatsCallback */
61
61
  /** @typedef {function((NodeJS.ErrnoException | Error | null)=, any=): void} ReadJsonCallback */
62
+ /** @typedef {function((NodeJS.ErrnoException | Error | null)=, IStats|string=): void} LstatReadlinkAbsoluteCallback */
62
63
 
63
64
  /**
64
65
  * @typedef {Object} Watcher
@@ -103,6 +104,7 @@ const path = require("path");
103
104
  * @property {function(string, BufferOrStringCallback): void} readlink
104
105
  * @property {function(string, DirentArrayCallback): void} readdir
105
106
  * @property {function(string, StatsCallback): void} stat
107
+ * @property {function(string, StatsCallback): void=} lstat
106
108
  * @property {(function(string, BufferOrStringCallback): void)=} realpath
107
109
  * @property {(function(string=): void)=} purge
108
110
  * @property {(function(string, string): string)=} join
@@ -282,3 +284,41 @@ const readJson = (fs, p, callback) => {
282
284
  });
283
285
  };
284
286
  exports.readJson = readJson;
287
+
288
+ /**
289
+ * @param {InputFileSystem} fs a file system
290
+ * @param {string} p an absolute path
291
+ * @param {ReadJsonCallback} callback callback
292
+ * @returns {void}
293
+ */
294
+ const lstatReadlinkAbsolute = (fs, p, callback) => {
295
+ let i = 3;
296
+ const doReadLink = () => {
297
+ fs.readlink(p, (err, target) => {
298
+ if (err && --i > 0) {
299
+ // It might was just changed from symlink to file
300
+ // we retry 2 times to catch this case before throwing the error
301
+ return doStat();
302
+ }
303
+ if (err || !target) return doStat();
304
+ const value = target.toString();
305
+ callback(null, join(fs, dirname(fs, p), value));
306
+ });
307
+ };
308
+ const doStat = () => {
309
+ if ("lstat" in fs) {
310
+ return fs.lstat(p, (err, stats) => {
311
+ if (err) return callback(err);
312
+ if (stats.isSymbolicLink()) {
313
+ return doReadLink();
314
+ }
315
+ callback(null, stats);
316
+ });
317
+ } else {
318
+ return fs.stat(p, callback);
319
+ }
320
+ };
321
+ if ("lstat" in fs) return doStat();
322
+ doReadLink();
323
+ };
324
+ exports.lstatReadlinkAbsolute = lstatReadlinkAbsolute;