@zip.js/zip.js 2.8.34 → 2.8.35

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.
Files changed (52) hide show
  1. package/README.md +13 -1
  2. package/deno.json +5 -2
  3. package/dist/README.md +3 -1
  4. package/dist/zip-core.js +472 -220
  5. package/dist/zip-core.min.js +1 -1
  6. package/dist/zip-fs-core.js +449 -220
  7. package/dist/zip-fs-core.min.js +1 -1
  8. package/dist/zip-fs-native.js +476 -226
  9. package/dist/zip-fs-native.min.js +1 -1
  10. package/dist/zip-fs.js +478 -228
  11. package/dist/zip-fs.min.js +1 -1
  12. package/dist/zip-legacy.js +474 -222
  13. package/dist/zip-legacy.min.js +1 -1
  14. package/dist/zip-native.js +475 -223
  15. package/dist/zip-native.min.js +1 -1
  16. package/dist/zip-web-worker-native.js +1 -1
  17. package/dist/zip-web-worker.js +1 -1
  18. package/dist/zip.js +477 -225
  19. package/dist/zip.min.js +1 -1
  20. package/index-native.cjs +476 -226
  21. package/index-native.min.js +1 -1
  22. package/index.cjs +478 -228
  23. package/index.d.cts +53 -0
  24. package/index.d.ts +53 -0
  25. package/index.min.js +1 -1
  26. package/lib/core/codec-pool.js +2 -2
  27. package/lib/core/codec-worker.js +6 -2
  28. package/lib/core/configuration.js +22 -1
  29. package/lib/core/io.js +209 -56
  30. package/lib/core/streams/aes-crypto-stream.js +1 -10
  31. package/lib/core/streams/codec-stream.js +36 -15
  32. package/lib/core/streams/zip-entry-stream.js +19 -28
  33. package/lib/core/util/array.js +48 -0
  34. package/lib/core/web-worker-base.js +3 -3
  35. package/lib/core/web-worker-inline-native.js +1 -1
  36. package/lib/core/web-worker-inline-wasm.js +1 -1
  37. package/lib/core/zip-fs.js +2 -3
  38. package/lib/core/zip-reader.js +37 -40
  39. package/lib/core/zip-writer.js +58 -51
  40. package/lib/core/zlib-streams-inline.js +1 -1
  41. package/lib/zip-core-base.js +5 -3
  42. package/lib/zip-fs-native.js +2 -2
  43. package/lib/zip-fs-wasm.js +2 -2
  44. package/lib/zip-legacy.js +2 -2
  45. package/lib/zip-module-native.js +2 -2
  46. package/lib/zip-module-wasm.js +3 -3
  47. package/lib/zip-native.js +2 -2
  48. package/lib/zip-wasm.js +2 -2
  49. package/package.json +3 -3
  50. package/worker-message-property-names.js +3 -0
  51. package/.github/workflows/publish.yml +0 -30
  52. package/reserved-property-names.js +0 -50
package/dist/zip-core.js CHANGED
@@ -162,6 +162,7 @@
162
162
  workerStarvationTimeout: 5000,
163
163
  useWebWorkers: true,
164
164
  useCompressionStream: true,
165
+ transferStreams: true,
165
166
  CompressionStream: typeof CompressionStream != UNDEFINED_TYPE && CompressionStream,
166
167
  DecompressionStream: typeof DecompressionStream != UNDEFINED_TYPE && DecompressionStream
167
168
  };
@@ -176,13 +177,14 @@
176
177
  "workerStarvationTimeout",
177
178
  "useCompressionStream",
178
179
  "useWebWorkers",
180
+ "transferStreams",
179
181
  "CompressionStream",
180
182
  "DecompressionStream",
181
183
  "CompressionStreamZlib",
182
184
  "DecompressionStreamZlib"
183
185
  ];
184
186
 
185
- const config = Object.assign({}, DEFAULT_CONFIGURATION);
187
+ const config = { ...DEFAULT_CONFIGURATION };
186
188
 
187
189
  function getConfiguration() {
188
190
  return config;
@@ -201,6 +203,23 @@
201
203
  }
202
204
  }
203
205
 
206
+ function setDefaultConfiguration(configuration) {
207
+ for (const propertyName of CONFIGURABLE_PROPERTY_NAMES) {
208
+ const propertyValue = configuration[propertyName];
209
+ if (propertyValue !== UNDEFINED_VALUE) {
210
+ DEFAULT_CONFIGURATION[propertyName] = propertyValue;
211
+ }
212
+ }
213
+ configure(configuration);
214
+ }
215
+
216
+ function resetConfiguration() {
217
+ for (const propertyName of CONFIGURABLE_PROPERTY_NAMES) {
218
+ delete config[propertyName];
219
+ }
220
+ Object.assign(config, DEFAULT_CONFIGURATION);
221
+ }
222
+
204
223
  /*
205
224
  Copyright (c) 2022 Gildas Lormeau. All rights reserved.
206
225
 
@@ -383,6 +402,50 @@
383
402
  }
384
403
  }
385
404
 
405
+ /*
406
+ Copyright (c) 2026 Gildas Lormeau. All rights reserved.
407
+
408
+ Redistribution and use in source and binary forms, with or without
409
+ modification, are permitted provided that the following conditions are met:
410
+
411
+ 1. Redistributions of source code must retain the above copyright notice,
412
+ this list of conditions and the following disclaimer.
413
+
414
+ 2. Redistributions in binary form must reproduce the above copyright
415
+ notice, this list of conditions and the following disclaimer in
416
+ the documentation and/or other materials provided with the distribution.
417
+
418
+ 3. The names of the authors may not be used to endorse or promote products
419
+ derived from this software without specific prior written permission.
420
+
421
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
422
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
423
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
424
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
425
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
426
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
427
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
428
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
429
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
430
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
431
+ */
432
+
433
+
434
+ function concat(first, second) {
435
+ const result = new Uint8Array(first.length + second.length);
436
+ result.set(first);
437
+ result.set(second, first.length);
438
+ return result;
439
+ }
440
+
441
+ function toExactUint8Array(array) {
442
+ return array.byteOffset || array.byteLength != array.buffer.byteLength ? new Uint8Array(array) : array;
443
+ }
444
+
445
+ function getDataView(array) {
446
+ return new DataView(array.buffer, array.byteOffset, array.byteLength);
447
+ }
448
+
386
449
  // Derived from https://github.com/xqdoo00o/jszip/blob/master/lib/sjcl.js and https://github.com/bitwiseshiftleft/sjcl
387
450
 
388
451
  // deno-lint-ignore-file no-this-alias
@@ -1487,16 +1550,6 @@
1487
1550
  }
1488
1551
  }
1489
1552
 
1490
- function concat(leftArray, rightArray) {
1491
- let array = leftArray;
1492
- if (leftArray.length + rightArray.length) {
1493
- array = new Uint8Array(leftArray.length + rightArray.length);
1494
- array.set(leftArray, 0);
1495
- array.set(rightArray, leftArray.length);
1496
- }
1497
- return array;
1498
- }
1499
-
1500
1553
  function expand(inputArray, length) {
1501
1554
  if (length && length > inputArray.length) {
1502
1555
  const array = inputArray;
@@ -1758,44 +1811,34 @@
1758
1811
  constructor() {
1759
1812
  // deno-lint-ignore prefer-const
1760
1813
  let stream;
1761
- let headerLeft = GZIP_HEADER_LENGTH;
1762
- let tail = new Uint8Array(0);
1814
+ let headerBytesLeft = GZIP_HEADER_LENGTH;
1815
+ let trailerCandidate = new Uint8Array(0);
1763
1816
  super({
1764
1817
  transform(chunk, controller) {
1765
- if (headerLeft) {
1766
- const dropped = Math.min(headerLeft, chunk.length);
1767
- headerLeft -= dropped;
1768
- chunk = chunk.subarray(dropped);
1818
+ if (headerBytesLeft) {
1819
+ const droppedLength = Math.min(headerBytesLeft, chunk.length);
1820
+ headerBytesLeft -= droppedLength;
1821
+ chunk = chunk.subarray(droppedLength);
1769
1822
  if (!chunk.length) {
1770
1823
  return;
1771
1824
  }
1772
1825
  }
1773
- const available = tail.length + chunk.length;
1774
- if (available <= GZIP_TRAILER_LENGTH) {
1775
- const pending = new Uint8Array(available);
1776
- pending.set(tail);
1777
- pending.set(chunk, tail.length);
1778
- tail = pending;
1826
+ const availableLength = trailerCandidate.length + chunk.length;
1827
+ if (availableLength <= GZIP_TRAILER_LENGTH) {
1828
+ trailerCandidate = concat(trailerCandidate, chunk);
1779
1829
  return;
1780
1830
  }
1781
- const emitLength = available - GZIP_TRAILER_LENGTH;
1782
- const output = new Uint8Array(emitLength);
1783
- const fromTail = Math.min(emitLength, tail.length);
1784
- output.set(tail.subarray(0, fromTail), 0);
1785
- if (emitLength > fromTail) {
1786
- output.set(chunk.subarray(0, emitLength - fromTail), fromTail);
1787
- }
1788
- controller.enqueue(output);
1789
- const nextTail = new Uint8Array(GZIP_TRAILER_LENGTH);
1790
- const tailRemaining = tail.length - fromTail;
1791
- if (tailRemaining) {
1792
- nextTail.set(tail.subarray(fromTail), 0);
1793
- }
1794
- nextTail.set(chunk.subarray(emitLength - fromTail), tailRemaining);
1795
- tail = nextTail;
1831
+ const emitLength = availableLength - GZIP_TRAILER_LENGTH;
1832
+ const emittedFromTrailer = Math.min(emitLength, trailerCandidate.length);
1833
+ controller.enqueue(concat(
1834
+ trailerCandidate.subarray(0, emittedFromTrailer),
1835
+ chunk.subarray(0, emitLength - emittedFromTrailer)));
1836
+ trailerCandidate = concat(
1837
+ trailerCandidate.subarray(emittedFromTrailer),
1838
+ chunk.subarray(emitLength - emittedFromTrailer));
1796
1839
  },
1797
1840
  flush() {
1798
- const dataView = new DataView(tail.buffer, tail.byteOffset, tail.byteLength);
1841
+ const dataView = getDataView(trailerCandidate);
1799
1842
  stream.signature = dataView.getUint32(0, true);
1800
1843
  stream.uncompressedSize = dataView.getUint32(4, true);
1801
1844
  }
@@ -1970,7 +2013,7 @@
1970
2013
  */
1971
2014
 
1972
2015
 
1973
- const DEFAULT_CHUNK_SIZE$1 = 64 * 1024;
2016
+ const DEFAULT_CHUNK_SIZE = 64 * 1024;
1974
2017
  const MESSAGE_EVENT_TYPE = "message";
1975
2018
  const MESSAGE_START = "start";
1976
2019
  const MESSAGE_PULL = "pull";
@@ -2038,33 +2081,54 @@
2038
2081
  class ChunkStream extends TransformStream {
2039
2082
 
2040
2083
  constructor(chunkSize) {
2041
- let pendingChunk;
2084
+ const pendingChunks = [];
2085
+ let pendingLength = 0;
2042
2086
  if (!(chunkSize >= 1)) {
2043
- chunkSize = DEFAULT_CHUNK_SIZE$1;
2087
+ chunkSize = DEFAULT_CHUNK_SIZE;
2044
2088
  }
2045
2089
  super({
2046
- transform,
2090
+ transform(chunk, controller) {
2091
+ pendingChunks.push(chunk);
2092
+ pendingLength += chunk.length;
2093
+ while (pendingLength > chunkSize) {
2094
+ controller.enqueue(shiftChunk());
2095
+ }
2096
+ },
2047
2097
  flush(controller) {
2048
- if (pendingChunk && pendingChunk.length) {
2049
- controller.enqueue(pendingChunk);
2098
+ if (pendingLength) {
2099
+ controller.enqueue(concatChunks(pendingChunks, pendingLength));
2050
2100
  }
2051
2101
  }
2052
2102
  });
2053
2103
 
2054
- function transform(chunk, controller) {
2055
- if (pendingChunk) {
2056
- const newChunk = new Uint8Array(pendingChunk.length + chunk.length);
2057
- newChunk.set(pendingChunk);
2058
- newChunk.set(chunk, pendingChunk.length);
2059
- chunk = newChunk;
2060
- pendingChunk = null;
2104
+ function shiftChunk() {
2105
+ const result = new Uint8Array(chunkSize);
2106
+ let resultOffset = 0;
2107
+ while (resultOffset < chunkSize) {
2108
+ const firstChunk = pendingChunks[0];
2109
+ const remainingLength = chunkSize - resultOffset;
2110
+ if (firstChunk.length <= remainingLength) {
2111
+ result.set(firstChunk, resultOffset);
2112
+ resultOffset += firstChunk.length;
2113
+ pendingChunks.shift();
2114
+ } else {
2115
+ result.set(firstChunk.subarray(0, remainingLength), resultOffset);
2116
+ pendingChunks[0] = firstChunk.subarray(remainingLength);
2117
+ resultOffset += remainingLength;
2118
+ }
2061
2119
  }
2120
+ pendingLength -= chunkSize;
2121
+ return result;
2122
+ }
2123
+
2124
+ function concatChunks(chunks, length) {
2125
+ const result = new Uint8Array(length);
2062
2126
  let offset = 0;
2063
- while (chunk.length - offset > chunkSize) {
2064
- controller.enqueue(chunk.slice(offset, offset + chunkSize));
2065
- offset += chunkSize;
2127
+ for (const chunk of chunks) {
2128
+ result.set(chunk, offset);
2129
+ offset += chunk.length;
2066
2130
  }
2067
- pendingChunk = offset ? chunk.slice(offset) : chunk;
2131
+ return result;
2068
2132
  }
2069
2133
  }
2070
2134
  }
@@ -2246,7 +2310,10 @@
2246
2310
  }
2247
2311
  }
2248
2312
  codecStream = new CodecStream(options, config);
2249
- await readable.pipeThrough(codecStream).pipeTo(writable, { preventClose: true, preventAbort: true });
2313
+ await readable
2314
+ .pipeThrough(codecStream)
2315
+ .pipeThrough(new ChunkStream(getChunkSize(config)))
2316
+ .pipeTo(writable, { preventClose: true, preventAbort: true });
2250
2317
  const {
2251
2318
  signature,
2252
2319
  inputSize,
@@ -2445,7 +2512,7 @@
2445
2512
  const { value, readable, writable } = message;
2446
2513
  const transferables = [];
2447
2514
  if (value) {
2448
- message.value = value.byteOffset || value.byteLength != value.buffer.byteLength ? new Uint8Array(value) : value;
2515
+ message.value = toExactUint8Array(value);
2449
2516
  transferables.push(message.value.buffer);
2450
2517
  }
2451
2518
  if (transferStreams && transferStreamsSupported) {
@@ -2569,8 +2636,8 @@
2569
2636
  const { options, config } = workerOptions;
2570
2637
  const { transferStreams, useWebWorkers, useCompressionStream, compressed, signed, encrypted } = options;
2571
2638
  const { workerURI, maxWorkers } = config;
2572
- workerOptions.transferStreams = transferStreams || transferStreams === UNDEFINED_VALUE;
2573
- const streamCopy = !compressed && !signed && !encrypted && !workerOptions.transferStreams;
2639
+ workerOptions.transferStreams = transferStreams || (transferStreams === UNDEFINED_VALUE && config.transferStreams);
2640
+ const streamCopy = !compressed && !signed && !encrypted;
2574
2641
  workerOptions.useWebWorkers = !streamCopy && (useWebWorkers || (useWebWorkers === UNDEFINED_VALUE && config.useWebWorkers));
2575
2642
  workerOptions.workerURI = workerOptions.useWebWorkers && workerURI ? workerURI : UNDEFINED_VALUE;
2576
2643
  options.useCompressionStream = useCompressionStream || (useCompressionStream === UNDEFINED_VALUE && config.useCompressionStream);
@@ -2704,6 +2771,7 @@
2704
2771
 
2705
2772
  const ERR_HTTP_STATUS = "HTTP error ";
2706
2773
  const ERR_HTTP_RANGE = "HTTP Range not supported";
2774
+ const ERR_HTTP_RESOURCE_CHANGED = "HTTP resource changed";
2707
2775
  const ERR_ITERATOR_COMPLETED_TOO_SOON = "Writer iterator completed too soon";
2708
2776
  const ERR_WRITER_NOT_INITIALIZED = "Writer not initialized";
2709
2777
 
@@ -2714,13 +2782,15 @@
2714
2782
  const HTTP_HEADER_ACCEPT_RANGES = "Accept-Ranges";
2715
2783
  const HTTP_HEADER_RANGE = "Range";
2716
2784
  const HTTP_HEADER_CONTENT_TYPE = "Content-Type";
2785
+ const HTTP_HEADER_ETAG = "Etag";
2786
+ const HTTP_HEADER_LAST_MODIFIED = "Last-Modified";
2717
2787
  const HTTP_METHOD_HEAD = "HEAD";
2718
2788
  const HTTP_METHOD_GET = "GET";
2719
2789
  const HTTP_RANGE_UNIT = "bytes";
2720
- const DEFAULT_CHUNK_SIZE = 64 * 1024;
2721
2790
  const DEFAULT_BUFFER_SIZE = 256 * 1024;
2722
2791
 
2723
2792
  const PROPERTY_NAME_WRITABLE = "writable";
2793
+ const DISK_BOUNDARY = Symbol();
2724
2794
 
2725
2795
  class Stream {
2726
2796
 
@@ -2739,13 +2809,13 @@
2739
2809
  return this.createReadable();
2740
2810
  }
2741
2811
 
2742
- createReadable({ offset = 0, size, diskNumberStart, chunkSize = DEFAULT_CHUNK_SIZE } = {}) {
2812
+ createReadable({ offset = 0, size, chunkSize = getChunkSize(getConfiguration()) } = {}) {
2743
2813
  const reader = this;
2744
2814
  let chunkOffset = 0;
2745
2815
  return new ReadableStream({
2746
2816
  async pull(controller) {
2747
2817
  const dataSize = size === UNDEFINED_VALUE ? chunkSize : Math.min(chunkSize, size - chunkOffset);
2748
- const data = await readUint8Array(reader, offset + chunkOffset, dataSize, diskNumberStart);
2818
+ const data = await readUint8Array(reader, offset + chunkOffset, dataSize);
2749
2819
  controller.enqueue(data);
2750
2820
  if ((chunkOffset + chunkSize > size) || (size === UNDEFINED_VALUE && !data.length && dataSize)) {
2751
2821
  controller.close();
@@ -2767,7 +2837,7 @@
2767
2837
  if (!writer.initialized) {
2768
2838
  throw new Error(ERR_WRITER_NOT_INITIALIZED);
2769
2839
  }
2770
- return writer.writeUint8Array(chunk);
2840
+ return writer.writeUint8Array(toExactUint8Array(chunk));
2771
2841
  }
2772
2842
  });
2773
2843
  Object.defineProperty(writer, PROPERTY_NAME_WRITABLE, {
@@ -2854,6 +2924,27 @@
2854
2924
  }
2855
2925
  }
2856
2926
 
2927
+ let blobSliceReliable;
2928
+ let blobSliceProbe;
2929
+
2930
+ function probeBlobSliceReliability() {
2931
+ blobSliceProbe = (async () => {
2932
+ try {
2933
+ const slicedBlob = new Blob([new Uint8Array(3)]).slice(1, 2);
2934
+ const streamReader = slicedBlob.stream().getReader();
2935
+ let streamedLength = 0;
2936
+ let result = await streamReader.read();
2937
+ while (!result.done) {
2938
+ streamedLength += result.value.length;
2939
+ result = await streamReader.read();
2940
+ }
2941
+ blobSliceReliable = streamedLength == 1;
2942
+ } catch {
2943
+ blobSliceReliable = false;
2944
+ }
2945
+ })();
2946
+ }
2947
+
2857
2948
  class BlobReader extends Reader {
2858
2949
 
2859
2950
  constructor(blob) {
@@ -2862,14 +2953,32 @@
2862
2953
  blob,
2863
2954
  size: blob.size
2864
2955
  });
2956
+ if (!blobSliceProbe) {
2957
+ probeBlobSliceReliability();
2958
+ }
2959
+ }
2960
+
2961
+ createReadable(options) {
2962
+ const reader = this;
2963
+ const { blob, size } = reader;
2964
+ const { offset = 0, size: readSize = size - offset } = options || {};
2965
+ if (!offset && readSize >= size) {
2966
+ return blob.stream();
2967
+ }
2968
+ if (blobSliceReliable) {
2969
+ return blob.slice(offset, offset + readSize).stream();
2970
+ }
2971
+ return super.createReadable(options);
2865
2972
  }
2866
2973
 
2867
2974
  async readUint8Array(offset, length) {
2868
2975
  const reader = this;
2869
2976
  const offsetEnd = offset + length;
2870
- const blob = offset || offsetEnd < reader.size ? reader.blob.slice(offset, offsetEnd) : reader.blob;
2977
+ const readsWholeBlob = !offset && offsetEnd >= reader.size;
2978
+ const blob = readsWholeBlob ? reader.blob : reader.blob.slice(offset, offsetEnd);
2871
2979
  let arrayBuffer = await blob.arrayBuffer();
2872
- if (arrayBuffer.byteLength > length) {
2980
+ const sliceIgnoredByBuggyImplementation = arrayBuffer.byteLength > length;
2981
+ if (sliceIgnoredByBuggyImplementation) {
2873
2982
  arrayBuffer = arrayBuffer.slice(offset, offsetEnd);
2874
2983
  }
2875
2984
  return new Uint8Array(arrayBuffer);
@@ -2950,6 +3059,18 @@
2950
3059
  super.init();
2951
3060
  }
2952
3061
 
3062
+ createReadable(options) {
3063
+ const reader = this;
3064
+ const { useRangeHeader, forceRangeRequests, size } = reader;
3065
+ if ((useRangeHeader || forceRangeRequests) && size !== UNDEFINED_VALUE) {
3066
+ const { offset = 0, size: readSize = size - offset } = options || {};
3067
+ if (readSize > 0 && offset < size) {
3068
+ return createRangeReadable(reader, offset, Math.min(readSize, size - offset));
3069
+ }
3070
+ }
3071
+ return super.createReadable(options);
3072
+ }
3073
+
2953
3074
  readUint8Array(index, length) {
2954
3075
  return readUint8ArrayHttpReader(this, index, length, sendFetchRequest, getFetchRequestData);
2955
3076
  }
@@ -2978,6 +3099,7 @@
2978
3099
  useRangeHeader,
2979
3100
  forceRangeRequests,
2980
3101
  combineSizeEocd,
3102
+ checkResourceChanges = true,
2981
3103
  fetch
2982
3104
  } = options;
2983
3105
  options = Object.assign({}, options);
@@ -2985,6 +3107,7 @@
2985
3107
  delete options.useRangeHeader;
2986
3108
  delete options.forceRangeRequests;
2987
3109
  delete options.combineSizeEocd;
3110
+ delete options.checkResourceChanges;
2988
3111
  delete options.useXHR;
2989
3112
  delete options.fetch;
2990
3113
  Object.assign(httpReader, {
@@ -2994,6 +3117,7 @@
2994
3117
  useRangeHeader,
2995
3118
  forceRangeRequests,
2996
3119
  combineSizeEocd,
3120
+ checkResourceChanges,
2997
3121
  fetch
2998
3122
  });
2999
3123
  }
@@ -3018,17 +3142,8 @@
3018
3142
  httpReader.eocdCache = eocdCache;
3019
3143
  }
3020
3144
  }
3021
- let contentSize;
3022
- const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
3023
- if (contentRangeHeader) {
3024
- const splitHeader = contentRangeHeader.trim().split(/\s*\/\s*/);
3025
- if (splitHeader.length) {
3026
- const headerValue = splitHeader[1];
3027
- if (headerValue && headerValue != "*") {
3028
- contentSize = Number(headerValue);
3029
- }
3030
- }
3031
- }
3145
+ setResourceValidators(httpReader, response);
3146
+ const contentSize = getContentRangeSize(response);
3032
3147
  if (contentSize === UNDEFINED_VALUE) {
3033
3148
  await getContentLength(httpReader, sendRequest, getRequestData);
3034
3149
  } else {
@@ -3069,6 +3184,8 @@
3069
3184
  throw new Error(ERR_HTTP_RANGE);
3070
3185
  }
3071
3186
  }
3187
+ checkResourceValidators(httpReader, response);
3188
+ setResourceValidators(httpReader, response);
3072
3189
  const data = new Uint8Array(await response.arrayBuffer());
3073
3190
  if (data.length != length) {
3074
3191
  throw new Error(ERR_HTTP_RANGE);
@@ -3080,7 +3197,97 @@
3080
3197
  if (!data) {
3081
3198
  await getRequestData(httpReader, options);
3082
3199
  }
3083
- return new Uint8Array(httpReader.data.subarray(index, index + length));
3200
+ return httpReader.data.subarray(index, index + length);
3201
+ }
3202
+ }
3203
+
3204
+ function createRangeReadable(httpReader, offset, size) {
3205
+ let bodyReader;
3206
+ let remainingLength = size;
3207
+ return new ReadableStream({
3208
+ async start() {
3209
+ const response = await sendFetchRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, offset, size));
3210
+ if (response.status != 206) {
3211
+ throw new Error(ERR_HTTP_RANGE);
3212
+ }
3213
+ const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
3214
+ if (contentRangeHeader) {
3215
+ const rangeStart = Number(contentRangeHeader.trim().split(/[\s-]+/)[1]);
3216
+ if (!Number.isNaN(rangeStart) && rangeStart != offset) {
3217
+ throw new Error(ERR_HTTP_RANGE);
3218
+ }
3219
+ }
3220
+ checkResourceValidators(httpReader, response);
3221
+ setResourceValidators(httpReader, response);
3222
+ bodyReader = response.body.getReader();
3223
+ },
3224
+ async pull(controller) {
3225
+ const { value, done } = await bodyReader.read();
3226
+ if (done) {
3227
+ if (remainingLength) {
3228
+ throw new Error(ERR_HTTP_RANGE);
3229
+ }
3230
+ controller.close();
3231
+ } else {
3232
+ const chunk = value.length > remainingLength ? value.subarray(0, remainingLength) : value;
3233
+ remainingLength -= chunk.length;
3234
+ if (chunk.length) {
3235
+ controller.enqueue(chunk);
3236
+ }
3237
+ if (!remainingLength) {
3238
+ controller.close();
3239
+ await bodyReader.cancel();
3240
+ }
3241
+ }
3242
+ },
3243
+ cancel(reason) {
3244
+ return bodyReader && bodyReader.cancel(reason);
3245
+ }
3246
+ });
3247
+ }
3248
+
3249
+ function getContentRangeSize(response) {
3250
+ const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
3251
+ if (contentRangeHeader) {
3252
+ const headerValue = contentRangeHeader.trim().split(/\s*\/\s*/)[1];
3253
+ if (headerValue && headerValue != "*") {
3254
+ const contentSize = Number(headerValue);
3255
+ if (!Number.isNaN(contentSize)) {
3256
+ return contentSize;
3257
+ }
3258
+ }
3259
+ }
3260
+ }
3261
+
3262
+ function getResourceValidators({ headers }) {
3263
+ return {
3264
+ etag: headers.get(HTTP_HEADER_ETAG) || UNDEFINED_VALUE,
3265
+ lastModified: headers.get(HTTP_HEADER_LAST_MODIFIED) || UNDEFINED_VALUE
3266
+ };
3267
+ }
3268
+
3269
+ function setResourceValidators(httpReader, response) {
3270
+ const { checkResourceChanges, resourceValidators } = httpReader;
3271
+ if (checkResourceChanges && !resourceValidators && response.status == 206) {
3272
+ httpReader.resourceValidators = getResourceValidators(response);
3273
+ }
3274
+ }
3275
+
3276
+ function checkResourceValidators(httpReader, response) {
3277
+ const { checkResourceChanges, resourceValidators, size } = httpReader;
3278
+ if (checkResourceChanges) {
3279
+ const contentRangeSize = getContentRangeSize(response);
3280
+ if (contentRangeSize !== UNDEFINED_VALUE && size !== UNDEFINED_VALUE && contentRangeSize != size) {
3281
+ throw new Error(ERR_HTTP_RESOURCE_CHANGED);
3282
+ }
3283
+ if (resourceValidators) {
3284
+ const validators = getResourceValidators(response);
3285
+ const changed = Object.entries(resourceValidators).some(([name, value]) =>
3286
+ value !== UNDEFINED_VALUE && validators[name] !== UNDEFINED_VALUE && value != validators[name]);
3287
+ if (changed) {
3288
+ throw new Error(ERR_HTTP_RESOURCE_CHANGED);
3289
+ }
3290
+ }
3084
3291
  }
3085
3292
  }
3086
3293
 
@@ -3191,6 +3398,10 @@
3191
3398
  super.init();
3192
3399
  }
3193
3400
 
3401
+ createReadable(options) {
3402
+ return this.reader.createReadable(options);
3403
+ }
3404
+
3194
3405
  readUint8Array(index, length) {
3195
3406
  return this.reader.readUint8Array(index, length);
3196
3407
  }
@@ -3271,25 +3482,26 @@
3271
3482
  const reader = this;
3272
3483
  const { readers } = reader;
3273
3484
  reader.lastDiskNumber = 0;
3274
- reader.lastDiskOffset = 0;
3275
- await Promise.all(readers.map(async (diskReader, indexDiskReader) => {
3276
- await initStream(diskReader);
3277
- if (indexDiskReader != readers.length - 1) {
3278
- reader.lastDiskOffset += diskReader.size;
3279
- }
3485
+ await Promise.all(readers.map(diskReader => initStream(diskReader)));
3486
+ reader.diskOffsets = readers.map(diskReader => {
3487
+ const diskOffset = reader.size;
3280
3488
  reader.size += diskReader.size;
3281
- }));
3489
+ return diskOffset;
3490
+ });
3282
3491
  super.init();
3283
3492
  }
3284
3493
 
3285
- async readUint8Array(offset, length, diskNumber = 0) {
3494
+ getDiskOffset(diskNumber) {
3495
+ const { diskOffsets, size } = this;
3496
+ const diskOffset = diskOffsets.at(diskNumber);
3497
+ return diskOffset === UNDEFINED_VALUE ? size : diskOffset;
3498
+ }
3499
+
3500
+ async readUint8Array(offset, length) {
3286
3501
  const reader = this;
3287
3502
  const { readers } = this;
3288
3503
  let result;
3289
- let currentDiskNumber = diskNumber;
3290
- if (currentDiskNumber == -1) {
3291
- currentDiskNumber = readers.length - 1;
3292
- }
3504
+ let currentDiskNumber = 0;
3293
3505
  let currentReaderOffset = offset;
3294
3506
  while (readers[currentDiskNumber] && currentReaderOffset >= readers[currentDiskNumber].size) {
3295
3507
  currentReaderOffset -= readers[currentDiskNumber].size;
@@ -3302,14 +3514,9 @@
3302
3514
  result = await readUint8Array(currentReader, currentReaderOffset, length);
3303
3515
  } else {
3304
3516
  const chunkLength = currentReaderSize - currentReaderOffset;
3305
- result = new Uint8Array(length);
3306
3517
  const firstPart = await readUint8Array(currentReader, currentReaderOffset, chunkLength);
3307
- result.set(firstPart, 0);
3308
- const secondPart = await reader.readUint8Array(offset + chunkLength, length - chunkLength, diskNumber);
3309
- result.set(secondPart, chunkLength);
3310
- if (firstPart.length + secondPart.length < length) {
3311
- result = result.subarray(0, firstPart.length + secondPart.length);
3312
- }
3518
+ const secondPart = await reader.readUint8Array(offset + chunkLength, length - chunkLength);
3519
+ result = concat(firstPart, secondPart);
3313
3520
  }
3314
3521
  } else {
3315
3522
  result = EMPTY_UINT8_ARRAY;
@@ -3334,6 +3541,12 @@
3334
3541
  let diskSourceWriter, diskWritable, diskWriter;
3335
3542
  const writable = new WritableStream({
3336
3543
  async write(chunk) {
3544
+ if (chunk === DISK_BOUNDARY) {
3545
+ if (diskWriter) {
3546
+ await endDisk();
3547
+ }
3548
+ return;
3549
+ }
3337
3550
  const { availableSize } = writer;
3338
3551
  if (!diskWriter) {
3339
3552
  const { value, done } = await writerGenerator.next();
@@ -3353,11 +3566,7 @@
3353
3566
  await this.write(chunk);
3354
3567
  } else if (chunk.length >= availableSize) {
3355
3568
  await writeChunk(chunk.subarray(0, availableSize));
3356
- await closeDisk();
3357
- writer.diskOffset += diskSourceWriter.size;
3358
- writer.diskNumber++;
3359
- diskWriter = null;
3360
- writer.availableSize = writer.maxSize;
3569
+ await endDisk();
3361
3570
  if (chunk.length > availableSize) {
3362
3571
  await this.write(chunk.subarray(availableSize));
3363
3572
  }
@@ -3368,7 +3577,7 @@
3368
3577
  async close() {
3369
3578
  if (diskWriter) {
3370
3579
  await diskWriter.ready;
3371
- await closeDisk();
3580
+ await closeDiskWriter();
3372
3581
  }
3373
3582
  },
3374
3583
  async abort(reason) {
@@ -3393,10 +3602,28 @@
3393
3602
  }
3394
3603
  }
3395
3604
 
3396
- async function closeDisk() {
3605
+ async function endDisk() {
3606
+ await closeDiskWriter();
3607
+ writer.diskOffset += diskSourceWriter.size;
3608
+ writer.diskNumber++;
3609
+ diskWriter = null;
3610
+ writer.availableSize = writer.maxSize;
3611
+ }
3612
+
3613
+ async function closeDiskWriter() {
3397
3614
  await diskWriter.close();
3398
3615
  }
3399
3616
  }
3617
+
3618
+ async closeDisk() {
3619
+ const streamWriter = this.writable.getWriter();
3620
+ try {
3621
+ await streamWriter.ready;
3622
+ await streamWriter.write(DISK_BOUNDARY);
3623
+ } finally {
3624
+ streamWriter.releaseLock();
3625
+ }
3626
+ }
3400
3627
  }
3401
3628
 
3402
3629
  class GenericReader {
@@ -3428,14 +3655,6 @@
3428
3655
  if (writer.size === UNDEFINED_VALUE) {
3429
3656
  writer.size = 0;
3430
3657
  }
3431
- if (!(writer instanceof SplitDataWriter)) {
3432
- Object.assign(writer, {
3433
- diskNumber: 0,
3434
- diskOffset: 0,
3435
- availableSize: INFINITY_VALUE,
3436
- maxSize: INFINITY_VALUE
3437
- });
3438
- }
3439
3658
  return writer;
3440
3659
  }
3441
3660
  }
@@ -3454,8 +3673,8 @@
3454
3673
  }
3455
3674
  }
3456
3675
 
3457
- function readUint8Array(reader, offset, size, diskNumber) {
3458
- return reader.readUint8Array(offset, size, diskNumber);
3676
+ function readUint8Array(reader, offset, size) {
3677
+ return reader.readUint8Array(offset, size);
3459
3678
  }
3460
3679
 
3461
3680
  /*
@@ -3831,7 +4050,7 @@
3831
4050
  const { endOfDirectoryInfo, endOfDirectoryReachingEndCount } = await findEndOfCentralDirectory(reader, rejectAmbiguousEndOfDirectory, maxAppendedDataSize);
3832
4051
  if (!endOfDirectoryInfo) {
3833
4052
  const signatureArray = await readUint8Array(reader, 0, 4);
3834
- const signatureView = getDataView$1(signatureArray);
4053
+ const signatureView = getDataView(signatureArray);
3835
4054
  if (getUint32(signatureView) == SPLIT_ZIP_FILE_SIGNATURE) {
3836
4055
  throw new Error(ERR_SPLIT_ZIP_FILE);
3837
4056
  } else {
@@ -3841,7 +4060,7 @@
3841
4060
  if (rejectAmbiguousEndOfDirectory && endOfDirectoryReachingEndCount > 1) {
3842
4061
  throwAmbiguousArchive("multiple end of central directory records");
3843
4062
  }
3844
- const endOfDirectoryView = getDataView$1(endOfDirectoryInfo);
4063
+ const endOfDirectoryView = getDataView(endOfDirectoryInfo);
3845
4064
  let directoryDataLength = getUint32(endOfDirectoryView, 12);
3846
4065
  let directoryDataOffset = getUint32(endOfDirectoryView, 16);
3847
4066
  const commentOffset = endOfDirectoryInfo.offset;
@@ -3857,17 +4076,21 @@
3857
4076
  let prependedDataLength = 0;
3858
4077
  let startOffset;
3859
4078
  let zip64EndOfDirectory;
3860
- if (directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS) {
4079
+ const requiresZip64 = directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS;
4080
+ if (directoryDataOffset != MAX_32_BITS && diskNumber != MAX_16_BITS) {
4081
+ directoryDataOffset += getDiskOffset$1(reader, diskNumber);
4082
+ }
4083
+ if (requiresZip64) {
3861
4084
  const endOfDirectoryLocatorArray = endOfDirectoryInfo.offset >= ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH ?
3862
4085
  await readUint8Array(reader, endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH) :
3863
4086
  EMPTY_UINT8_ARRAY;
3864
- const endOfDirectoryLocatorView = getDataView$1(endOfDirectoryLocatorArray);
4087
+ const endOfDirectoryLocatorView = getDataView(endOfDirectoryLocatorArray);
3865
4088
  if (endOfDirectoryLocatorArray.length == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH &&
3866
4089
  getUint32(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
3867
- directoryDataOffset = getBigUint64(endOfDirectoryLocatorView, 8);
3868
- let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH, -1);
3869
- let endOfDirectoryView = getDataView$1(endOfDirectoryArray);
3870
- const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH - (reader.lastDiskOffset || 0);
4090
+ directoryDataOffset = getDiskOffset$1(reader, getUint32(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
4091
+ let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
4092
+ let endOfDirectoryView = getDataView(endOfDirectoryArray);
4093
+ const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
3871
4094
  if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
3872
4095
  directoryDataOffset != expectedDirectoryDataOffset && expectedDirectoryDataOffset >= 0) {
3873
4096
  const originalDirectoryDataOffset = directoryDataOffset;
@@ -3875,8 +4098,8 @@
3875
4098
  if (directoryDataOffset > originalDirectoryDataOffset) {
3876
4099
  prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
3877
4100
  }
3878
- endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH, -1);
3879
- endOfDirectoryView = getDataView$1(endOfDirectoryArray);
4101
+ endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
4102
+ endOfDirectoryView = getDataView(endOfDirectoryArray);
3880
4103
  }
3881
4104
  if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
3882
4105
  throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
@@ -3902,7 +4125,7 @@
3902
4125
  } else if (checkAmbiguity && directoryDataLength != getBigUint64(endOfDirectoryView, 40)) {
3903
4126
  throwAmbiguousArchive("mismatched zip64 end of central directory record");
3904
4127
  }
3905
- directoryDataOffset = getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
4128
+ directoryDataOffset = getDiskOffset$1(reader, diskNumber) + getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
3906
4129
  }
3907
4130
  }
3908
4131
  const declaredDirectoryDataLength = directoryDataLength;
@@ -3919,19 +4142,19 @@
3919
4142
  throw new Error(ERR_BAD_FORMAT);
3920
4143
  }
3921
4144
  let offset = 0;
3922
- let directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber);
3923
- let directoryView = getDataView$1(directoryArray);
4145
+ let directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
4146
+ let directoryView = getDataView(directoryArray);
3924
4147
  if (directoryDataLength) {
3925
4148
  if (directoryArray.length < 4) {
3926
4149
  throw new Error(ERR_BAD_FORMAT);
3927
4150
  }
3928
- const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength - (reader.lastDiskOffset || 0);
4151
+ const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
3929
4152
  if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
3930
4153
  const storedPointsAtDirectory = getUint32(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE;
3931
4154
  let reconcile = !storedPointsAtDirectory;
3932
4155
  if (!reconcile && expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
3933
- const expectedSignatureArray = await readUint8Array(reader, expectedDirectoryDataOffset, 4, diskNumber);
3934
- reconcile = getUint32(getDataView$1(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
4156
+ const expectedSignatureArray = await readUint8Array(reader, expectedDirectoryDataOffset, 4);
4157
+ reconcile = getUint32(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
3935
4158
  }
3936
4159
  if (reconcile) {
3937
4160
  const originalDirectoryDataOffset = directoryDataOffset;
@@ -3939,16 +4162,16 @@
3939
4162
  if (directoryDataOffset > originalDirectoryDataOffset) {
3940
4163
  prependedDataLength += directoryDataOffset - originalDirectoryDataOffset;
3941
4164
  }
3942
- directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber);
3943
- directoryView = getDataView$1(directoryArray);
4165
+ directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
4166
+ directoryView = getDataView(directoryArray);
3944
4167
  }
3945
4168
  }
3946
4169
  }
3947
- const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset - (reader.lastDiskOffset || 0);
4170
+ const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
3948
4171
  if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
3949
4172
  directoryDataLength = expectedDirectoryDataLength;
3950
- directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber);
3951
- directoryView = getDataView$1(directoryArray);
4173
+ directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
4174
+ directoryView = getDataView(directoryArray);
3952
4175
  }
3953
4176
  if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) {
3954
4177
  throw new Error(ERR_BAD_FORMAT);
@@ -4021,7 +4244,7 @@
4021
4244
  });
4022
4245
  readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6);
4023
4246
  fileEntry.offset += prependedDataLength;
4024
- startOffset = Math.min(fileEntry.offset, startOffset);
4247
+ startOffset = Math.min(getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset, startOffset);
4025
4248
  if (checkAmbiguity) {
4026
4249
  if (filenames.has(fileEntry.filename)) {
4027
4250
  duplicateFilename = true;
@@ -4175,8 +4398,9 @@
4175
4398
  dataDescriptor
4176
4399
  } = bitFlag;
4177
4400
  const localDirectory = fileEntry.localDirectory = {};
4178
- const dataArray = await readUint8Array(reader, offset, HEADER_SIZE, diskNumberStart);
4179
- const dataView = getDataView$1(dataArray);
4401
+ const localHeaderOffset = getDiskOffset$1(reader, diskNumberStart) + offset;
4402
+ const dataArray = await readUint8Array(reader, localHeaderOffset, HEADER_SIZE);
4403
+ const dataView = getDataView(dataArray);
4180
4404
  let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
4181
4405
  let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
4182
4406
  const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
@@ -4201,12 +4425,12 @@
4201
4425
  const checkAmbiguity = getStrictness(getOptionValue$1(zipEntry, options, OPTION_STRICTNESS), getOptionValue$1(zipEntry, options, OPTION_CHECK_AMBIGUITY)) == STRICTNESS_STRICT;
4202
4426
  let rawLocalFilename = EMPTY_UINT8_ARRAY;
4203
4427
  if (checkAmbiguity && (filenameLength || extraFieldLength)) {
4204
- const trailingDataArray = await readUint8Array(reader, offset + HEADER_SIZE, filenameLength + extraFieldLength, diskNumberStart);
4428
+ const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
4205
4429
  rawLocalFilename = trailingDataArray.subarray(0, filenameLength);
4206
4430
  localDirectory.rawExtraField = trailingDataArray.subarray(filenameLength);
4207
4431
  } else {
4208
4432
  localDirectory.rawExtraField = extraFieldLength ?
4209
- await readUint8Array(reader, offset + HEADER_SIZE + filenameLength, extraFieldLength, diskNumberStart) :
4433
+ await readUint8Array(reader, localHeaderOffset + HEADER_SIZE + filenameLength, extraFieldLength) :
4210
4434
  EMPTY_UINT8_ARRAY;
4211
4435
  }
4212
4436
  readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
@@ -4232,9 +4456,9 @@
4232
4456
  throw new Error(ERR_ENCRYPTED);
4233
4457
  }
4234
4458
  }
4235
- const dataOffset = offset + HEADER_SIZE + filenameLength + extraFieldLength;
4459
+ const dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
4236
4460
  const size = compressedSize;
4237
- const readable = reader.createReadable({ offset: dataOffset, size, diskNumberStart, chunkSize: getChunkSize(config) });
4461
+ const readable = reader.createReadable({ offset: dataOffset, size });
4238
4462
  const signal = getOptionValue$1(zipEntry, options, OPTION_SIGNAL);
4239
4463
  const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
4240
4464
  let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
@@ -4275,8 +4499,7 @@
4275
4499
  reader,
4276
4500
  fileEntry,
4277
4501
  index,
4278
- offset,
4279
- diskNumberStart,
4502
+ offset: localHeaderOffset,
4280
4503
  signature,
4281
4504
  compressedSize,
4282
4505
  uncompressedSize,
@@ -4340,7 +4563,7 @@
4340
4563
  function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory) {
4341
4564
  const { rawExtraField } = directory;
4342
4565
  const extraField = directory.extraField = new Map();
4343
- const rawExtraFieldView = getDataView$1(new Uint8Array(rawExtraField));
4566
+ const rawExtraFieldView = getDataView(rawExtraField);
4344
4567
  let offsetExtraField = 0;
4345
4568
  try {
4346
4569
  while (offsetExtraField < rawExtraField.length) {
@@ -4412,7 +4635,7 @@
4412
4635
 
4413
4636
  function readExtraFieldZip64(extraFieldZip64, directory) {
4414
4637
  directory.zip64 = true;
4415
- const extraFieldView = getDataView$1(extraFieldZip64.data);
4638
+ const extraFieldView = getDataView(extraFieldZip64.data);
4416
4639
  const missingProperties = ZIP64_PROPERTIES.filter(([propertyName, max]) => directory[propertyName] == max);
4417
4640
  const requiredLength = missingProperties.reduce((length, [, max]) => length + ZIP64_EXTRACTION[max].bytes, 0);
4418
4641
  if (extraFieldZip64.data.length < requiredLength) {
@@ -4431,10 +4654,10 @@
4431
4654
  extraFieldUnicode.valid = false;
4432
4655
  return;
4433
4656
  }
4434
- const extraFieldView = getDataView$1(extraFieldUnicode.data);
4657
+ const extraFieldView = getDataView(extraFieldUnicode.data);
4435
4658
  const crc32 = new Crc32();
4436
4659
  crc32.append(fileEntry[rawPropertyName]);
4437
- const dataViewSignature = getDataView$1(new Uint8Array(4));
4660
+ const dataViewSignature = getDataView(new Uint8Array(4));
4438
4661
  dataViewSignature.setUint32(0, crc32.get(), true);
4439
4662
  const signature = getUint32(extraFieldView, 1);
4440
4663
  Object.assign(extraFieldUnicode, {
@@ -4449,7 +4672,7 @@
4449
4672
  }
4450
4673
 
4451
4674
  function readExtraFieldAES(extraFieldAES, directory, compressionMethod) {
4452
- const extraFieldView = getDataView$1(extraFieldAES.data);
4675
+ const extraFieldView = getDataView(extraFieldAES.data);
4453
4676
  const strength = getUint8(extraFieldView, 4);
4454
4677
  Object.assign(extraFieldAES, {
4455
4678
  vendorVersion: getUint8(extraFieldView, 0),
@@ -4462,7 +4685,7 @@
4462
4685
  }
4463
4686
 
4464
4687
  function readExtraFieldNTFS(extraFieldNTFS, directory) {
4465
- const extraFieldView = getDataView$1(extraFieldNTFS.data);
4688
+ const extraFieldView = getDataView(extraFieldNTFS.data);
4466
4689
  let offsetExtraField = 4;
4467
4690
  let tag1Data;
4468
4691
  try {
@@ -4479,7 +4702,7 @@
4479
4702
  }
4480
4703
  try {
4481
4704
  if (tag1Data && tag1Data.length == 24) {
4482
- const tag1View = getDataView$1(tag1Data);
4705
+ const tag1View = getDataView(tag1Data);
4483
4706
  const rawLastModDate = tag1View.getBigUint64(0, true);
4484
4707
  const rawLastAccessDate = tag1View.getBigUint64(8, true);
4485
4708
  const rawCreationDate = tag1View.getBigUint64(16, true);
@@ -4502,7 +4725,7 @@
4502
4725
 
4503
4726
  function readExtraFieldUnix(extraField, directory, isInfoZip) {
4504
4727
  try {
4505
- const view = getDataView$1(new Uint8Array(extraField.data));
4728
+ const view = getDataView(extraField.data);
4506
4729
  let uid, gid;
4507
4730
  if (isInfoZip) {
4508
4731
  let offset = 0;
@@ -4540,7 +4763,7 @@
4540
4763
  if (!extraFieldExtendedTimestamp.data.length) {
4541
4764
  return;
4542
4765
  }
4543
- const extraFieldView = getDataView$1(extraFieldExtendedTimestamp.data);
4766
+ const extraFieldView = getDataView(extraFieldExtendedTimestamp.data);
4544
4767
  const flags = getUint8(extraFieldView, 0);
4545
4768
  const timeProperties = [];
4546
4769
  const timeRawProperties = [];
@@ -4578,7 +4801,6 @@
4578
4801
  fileEntry,
4579
4802
  index,
4580
4803
  offset,
4581
- diskNumberStart,
4582
4804
  signature,
4583
4805
  compressedSize,
4584
4806
  uncompressedSize,
@@ -4587,12 +4809,6 @@
4587
4809
  extraFieldZip64,
4588
4810
  readRanges
4589
4811
  }) {
4590
- let diskOffset = 0;
4591
- if (diskNumberStart && reader.readers) {
4592
- for (let indexReader = 0; indexReader < Math.min(diskNumberStart, reader.readers.length); indexReader++) {
4593
- diskOffset += reader.readers[indexReader].size;
4594
- }
4595
- }
4596
4812
  let dataDescriptorLength = 0;
4597
4813
  if (dataDescriptor) {
4598
4814
  if (extraFieldZip64) {
@@ -4602,19 +4818,19 @@
4602
4818
  }
4603
4819
  }
4604
4820
  if (dataDescriptorLength) {
4605
- const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH, diskNumberStart);
4821
+ const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
4606
4822
  const dataDescriptorSignature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
4607
- getUint32(getDataView$1(dataDescriptorArray), 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
4823
+ getUint32(getDataView(dataDescriptorArray), 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
4608
4824
  if (dataDescriptorSignature) {
4609
- const readSignature = getUint32(getDataView$1(dataDescriptorArray), 4);
4825
+ const readSignature = getUint32(getDataView(dataDescriptorArray), 4);
4610
4826
  let readCompressedSize;
4611
4827
  let readUncompressedSize;
4612
4828
  if (extraFieldZip64) {
4613
- readCompressedSize = getBigUint64(getDataView$1(dataDescriptorArray), 8);
4614
- readUncompressedSize = getBigUint64(getDataView$1(dataDescriptorArray), 16);
4829
+ readCompressedSize = getBigUint64(getDataView(dataDescriptorArray), 8);
4830
+ readUncompressedSize = getBigUint64(getDataView(dataDescriptorArray), 16);
4615
4831
  } else {
4616
- readCompressedSize = getUint32(getDataView$1(dataDescriptorArray), 8);
4617
- readUncompressedSize = getUint32(getDataView$1(dataDescriptorArray), 12);
4832
+ readCompressedSize = getUint32(getDataView(dataDescriptorArray), 8);
4833
+ readUncompressedSize = getUint32(getDataView(dataDescriptorArray), 12);
4618
4834
  }
4619
4835
  const matchSignature = (fileEntry.encrypted && !fileEntry.zipCrypto) || readSignature == signature;
4620
4836
  if (matchSignature &&
@@ -4625,8 +4841,8 @@
4625
4841
  }
4626
4842
  }
4627
4843
  const range = {
4628
- start: diskOffset + offset,
4629
- end: diskOffset + dataOffset + compressedSize + dataDescriptorLength,
4844
+ start: offset,
4845
+ end: dataOffset + compressedSize + dataDescriptorLength,
4630
4846
  fileEntry
4631
4847
  };
4632
4848
  for (const [otherIndex, otherRange] of readRanges) {
@@ -4639,6 +4855,10 @@
4639
4855
  readRanges.set(index, range);
4640
4856
  }
4641
4857
 
4858
+ function getDiskOffset$1(reader, diskNumber) {
4859
+ return reader.getDiskOffset ? reader.getDiskOffset(diskNumber) : 0;
4860
+ }
4861
+
4642
4862
  function getStrictness(strictness, checkAmbiguity) {
4643
4863
  if (strictness === UNDEFINED_VALUE) {
4644
4864
  return checkAmbiguity ? STRICTNESS_STRICT : STRICTNESS_BALANCED;
@@ -4722,7 +4942,7 @@
4722
4942
  async function* scanEndOfCentralDirectory(reader, scanLength) {
4723
4943
  const scanOffset = reader.size - scanLength;
4724
4944
  const scanArray = await readUint8Array(reader, scanOffset, scanLength);
4725
- const scanView = getDataView$1(scanArray);
4945
+ const scanView = getDataView(scanArray);
4726
4946
  for (let indexByte = scanArray.length - END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
4727
4947
  if (getUint32(scanView, indexByte) == END_OF_CENTRAL_DIR_SIGNATURE) {
4728
4948
  yield [scanView, scanOffset, scanArray, indexByte, scanOffset + indexByte];
@@ -4745,7 +4965,8 @@
4745
4965
  if (!filesLength && !directoryDataLength) {
4746
4966
  return CENTRAL_DIRECTORY_PLAUSIBLE;
4747
4967
  }
4748
- for (const centralDirectoryOffset of [offset - directoryDataLength, directoryDataOffset]) {
4968
+ const directoryDiskNumber = getUint16(view, indexByte + 6);
4969
+ for (const centralDirectoryOffset of [offset - directoryDataLength, getDiskOffset$1(reader, directoryDiskNumber) + directoryDataOffset]) {
4749
4970
  if (await readSignature(reader, view, anchoredOffset, centralDirectoryOffset, size, remoteProbeBudget) == CENTRAL_FILE_HEADER_SIGNATURE) {
4750
4971
  return CENTRAL_DIRECTORY_REACHABLE;
4751
4972
  }
@@ -4763,7 +4984,7 @@
4763
4984
  if (remoteProbeBudget.count > 0) {
4764
4985
  remoteProbeBudget.count--;
4765
4986
  const signatureArray = await readUint8Array(reader, signatureOffset, 4);
4766
- return getUint32(getDataView$1(signatureArray), 0);
4987
+ return getUint32(getDataView(signatureArray), 0);
4767
4988
  }
4768
4989
  return UNDEFINED_VALUE;
4769
4990
  }
@@ -4828,9 +5049,27 @@
4828
5049
  return Number(view.getBigUint64(offset, true));
4829
5050
  }
4830
5051
 
4831
- function getDataView$1(array) {
4832
- return new DataView(array.buffer, array.byteOffset, array.byteLength);
4833
- }
5052
+ var zipReader = /*#__PURE__*/Object.freeze({
5053
+ __proto__: null,
5054
+ ERR_AMBIGUOUS_ARCHIVE: ERR_AMBIGUOUS_ARCHIVE,
5055
+ ERR_BAD_FORMAT: ERR_BAD_FORMAT,
5056
+ ERR_CENTRAL_DIRECTORY_NOT_FOUND: ERR_CENTRAL_DIRECTORY_NOT_FOUND,
5057
+ ERR_ENCRYPTED: ERR_ENCRYPTED,
5058
+ ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND: ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND,
5059
+ ERR_EOCDR_NOT_FOUND: ERR_EOCDR_NOT_FOUND,
5060
+ ERR_EXTRAFIELD_ZIP64_NOT_FOUND: ERR_EXTRAFIELD_ZIP64_NOT_FOUND,
5061
+ ERR_INVALID_COMPRESSED_DATA: ERR_INVALID_COMPRESSED_DATA,
5062
+ ERR_INVALID_PASSWORD: ERR_INVALID_PASSWORD,
5063
+ ERR_INVALID_SIGNATURE: ERR_INVALID_SIGNATURE,
5064
+ ERR_INVALID_UNCOMPRESSED_SIZE: ERR_INVALID_UNCOMPRESSED_SIZE,
5065
+ ERR_LOCAL_FILE_HEADER_NOT_FOUND: ERR_LOCAL_FILE_HEADER_NOT_FOUND,
5066
+ ERR_OVERLAPPING_ENTRY: ERR_OVERLAPPING_ENTRY,
5067
+ ERR_SPLIT_ZIP_FILE: ERR_SPLIT_ZIP_FILE,
5068
+ ERR_UNSUPPORTED_COMPRESSION: ERR_UNSUPPORTED_COMPRESSION$1,
5069
+ ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
5070
+ ZipReader: ZipReader,
5071
+ ZipReaderStream: ZipReaderStream
5072
+ });
4834
5073
 
4835
5074
  /*
4836
5075
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
@@ -4895,9 +5134,10 @@
4895
5134
 
4896
5135
  constructor(writer, options = {}) {
4897
5136
  writer = new GenericWriter(writer);
5137
+ const { availableSize = INFINITY_VALUE, maxSize = INFINITY_VALUE } = writer;
4898
5138
  const addSplitZipSignature =
4899
- writer.availableSize !== UNDEFINED_VALUE && writer.availableSize > 0 && writer.availableSize !== INFINITY_VALUE &&
4900
- writer.maxSize !== UNDEFINED_VALUE && writer.maxSize > 0 && writer.maxSize !== INFINITY_VALUE;
5139
+ availableSize > 0 && availableSize !== INFINITY_VALUE &&
5140
+ maxSize > 0 && maxSize !== INFINITY_VALUE;
4901
5141
  Object.assign(this, {
4902
5142
  writer,
4903
5143
  addSplitZipSignature,
@@ -4919,9 +5159,10 @@
4919
5159
  }
4920
5160
  reader = new GenericReader(reader);
4921
5161
  await initStream(reader);
4922
- const zipReader = new ZipReader(reader.readable);
4923
- const entries = await zipReader.getEntries();
4924
- await zipReader.close();
5162
+ const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
5163
+ const zipReader$1 = new ZipReader(reader.readable);
5164
+ const entries = await zipReader$1.getEntries();
5165
+ await zipReader$1.close();
4925
5166
  await initStream(this.writer);
4926
5167
  await reader.readable.pipeTo(this.writer.writable, { preventClose: true, preventAbort: true });
4927
5168
  this.writer.size = this.offset = reader.size;
@@ -4937,8 +5178,6 @@
4937
5178
  encrypted,
4938
5179
  uncompressedSize,
4939
5180
  compressedSize,
4940
- diskOffset,
4941
- diskNumber,
4942
5181
  zip64
4943
5182
  } = entry;
4944
5183
  let {
@@ -4986,8 +5225,9 @@
4986
5225
  Object.assign(entry, {
4987
5226
  zip64UncompressedSize,
4988
5227
  zip64CompressedSize,
4989
- zip64Offset: zip64 && this.offset - diskOffset >= MAX_32_BITS,
4990
- zip64DiskNumberStart: zip64 && diskNumber >= MAX_16_BITS,
5228
+ zip64Offset: zip64 && entry.offset >= MAX_32_BITS,
5229
+ diskNumberStart: 0,
5230
+ zip64DiskNumberStart: false,
4991
5231
  rawExtraFieldZip64,
4992
5232
  rawExtraFieldAES,
4993
5233
  rawExtraFieldExtendedTimestamp,
@@ -5154,7 +5394,8 @@
5154
5394
  try {
5155
5395
  const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
5156
5396
  ({ reader } = sizesInfo);
5157
- const { diskOffset, diskNumber } = zipWriter.writer;
5397
+ const diskOffset = getDiskOffset(zipWriter.writer);
5398
+ const diskNumber = getDiskNumber(zipWriter.writer);
5158
5399
  options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
5159
5400
  internalFileAttribute: metadataInfo.resolvedOptions.internalFileAttributes,
5160
5401
  externalFileAttribute: attributesInfo.resolvedOptions.externalFileAttributes,
@@ -5331,7 +5572,7 @@
5331
5572
  const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
5332
5573
  const keepOrder = getOptionValue(zipWriter, options, OPTION_KEEP_ORDER, true);
5333
5574
  const useWebWorkers = getOptionValue(zipWriter, options, OPTION_USE_WEB_WORKERS);
5334
- const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS, true);
5575
+ const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS);
5335
5576
  const bufferedWrite = getOptionValue(zipWriter, options, OPTION_BUFFERED_WRITE);
5336
5577
  const createTempStream = getOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
5337
5578
  const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
@@ -5529,7 +5770,7 @@
5529
5770
  await requestLockWriter();
5530
5771
  }
5531
5772
  await initStream(fileWriter);
5532
- const { diskOffset } = writer;
5773
+ const diskOffset = getDiskOffset(writer);
5533
5774
  if (zipWriter.addSplitZipSignature) {
5534
5775
  delete zipWriter.addSplitZipSignature;
5535
5776
  const signatureArray = new Uint8Array(4);
@@ -5546,7 +5787,7 @@
5546
5787
  await lockPreviousFileEntry;
5547
5788
  await skipDiskIfNeeded();
5548
5789
  }
5549
- const diskNumberStart = writer.diskNumber;
5790
+ const diskNumberStart = getDiskNumber(writer);
5550
5791
  const entryOffset = getSegmentOffset(zipWriter, writer);
5551
5792
  fileEntry.diskNumberStart = diskNumberStart;
5552
5793
  if (!bufferedWrite) {
@@ -5566,11 +5807,11 @@
5566
5807
  writingBufferedEntryData = true;
5567
5808
  writerSizeBeforeEntry = writer.size;
5568
5809
  await skipDiskIfNeeded();
5569
- fileEntry.diskNumberStart = writer.diskNumber;
5810
+ fileEntry.diskNumberStart = getDiskNumber(writer);
5570
5811
  fileEntry.offset = getSegmentOffset(zipWriter, writer);
5571
5812
  if (usdz) {
5572
5813
  const previousMetadataSize = entryInfo.metadataSize;
5573
- appendExtraFieldUSDZ(entryInfo, zipWriter.offset - writer.diskOffset);
5814
+ appendExtraFieldUSDZ(entryInfo, zipWriter.offset - getDiskOffset(writer));
5574
5815
  fileEntry.size += entryInfo.metadataSize - previousMetadataSize;
5575
5816
  }
5576
5817
  updateLocalHeader(fileEntry, headerInfo.localHeaderView, options);
@@ -5635,9 +5876,8 @@
5635
5876
  }
5636
5877
 
5637
5878
  async function skipDiskIfNeeded() {
5638
- if (getLength(headerInfo.localHeaderArray) > writer.availableSize) {
5639
- writer.availableSize = 0;
5640
- await writeData(writer, EMPTY_UINT8_ARRAY);
5879
+ if (exceedsAvailableSize(writer, getLength(headerInfo.localHeaderArray))) {
5880
+ await writer.closeDisk();
5641
5881
  }
5642
5882
  }
5643
5883
  }
@@ -5748,7 +5988,7 @@
5748
5988
  }
5749
5989
  const { writable } = writer;
5750
5990
  if (reader) {
5751
- const readable = reader.createReadable ? reader.createReadable({ chunkSize: getChunkSize(config) }) : reader.readable;
5991
+ const readable = reader.createReadable ? reader.createReadable() : reader.readable;
5752
5992
  const size = reader.size;
5753
5993
  const workerOptions = {
5754
5994
  options: {
@@ -6180,8 +6420,8 @@
6180
6420
 
6181
6421
  async function closeFile(zipWriter, comment, options) {
6182
6422
  const directoryDataLength = createDirectoryRecords(zipWriter.files);
6183
- const { cdStartDiskNumber, cdStartDiskOffset } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
6184
- await writeEndOfDirectoryRecord(zipWriter, comment, options, { cdStartDiskNumber, cdStartDiskOffset, directoryDataLength });
6423
+ const directoryStart = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
6424
+ await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength });
6185
6425
  }
6186
6426
 
6187
6427
  function createDirectoryRecords(files) {
@@ -6263,8 +6503,8 @@
6263
6503
  await initStream(writer);
6264
6504
  let offset = 0;
6265
6505
  let directoryDiskOffset = 0;
6266
- let cdStartDiskNumber = writer.diskNumber;
6267
- let cdStartDiskOffset = writer.diskOffset;
6506
+ let directoryStartDiskNumber = getDiskNumber(writer);
6507
+ let directoryStartDiskOffset = getDiskOffset(writer);
6268
6508
  for (const [indexFileEntry, fileEntry] of Array.from(files.values()).entries()) {
6269
6509
  const {
6270
6510
  offset: fileEntryOffset,
@@ -6291,15 +6531,14 @@
6291
6531
  } = fileEntry;
6292
6532
  const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
6293
6533
  const directoryRecordLength = CENTRAL_FILE_HEADER_LENGTH + getLength(rawFilename, rawComment) + extraFieldLength;
6294
- if (offset + directoryRecordLength - directoryDiskOffset > writer.availableSize) {
6534
+ if (exceedsAvailableSize(writer, offset + directoryRecordLength - directoryDiskOffset)) {
6295
6535
  await writeData(writer, directoryArray.slice(directoryDiskOffset, offset));
6296
6536
  directoryDiskOffset = offset;
6297
- writer.availableSize = 0;
6298
- await writeData(writer, EMPTY_UINT8_ARRAY);
6537
+ await writer.closeDisk();
6299
6538
  }
6300
6539
  if (indexFileEntry == 0) {
6301
- cdStartDiskNumber = writer.diskNumber;
6302
- cdStartDiskOffset = writer.diskOffset;
6540
+ directoryStartDiskNumber = getDiskNumber(writer);
6541
+ directoryStartDiskOffset = getDiskOffset(writer);
6303
6542
  }
6304
6543
  if (!zip64UncompressedSize) {
6305
6544
  setUint32(headerView, HEADER_OFFSET_UNCOMPRESSED_SIZE, uncompressedSize);
@@ -6339,18 +6578,18 @@
6339
6578
  }
6340
6579
  }
6341
6580
  await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
6342
- return { cdStartDiskNumber, cdStartDiskOffset };
6581
+ return { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset };
6343
6582
  }
6344
6583
 
6345
6584
  async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
6346
6585
  const { writer } = zipWriter;
6347
- const { cdStartDiskNumber, cdStartDiskOffset } = cdInfo;
6586
+ const { directoryStart } = cdInfo;
6348
6587
  let { directoryDataLength } = cdInfo;
6349
6588
  let filesLength = zipWriter.files.size;
6350
- let diskNumber = cdStartDiskNumber;
6351
- let directoryOffset = zipWriter.offset - cdStartDiskOffset - (cdStartDiskNumber ? zipWriter.initialOffset : 0);
6352
- let lastDiskNumber = writer.diskNumber;
6353
- if (writer.availableSize < END_OF_CENTRAL_DIR_LENGTH) {
6589
+ let diskNumber = directoryStart.diskNumber;
6590
+ let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
6591
+ let lastDiskNumber = getDiskNumber(writer);
6592
+ if (exceedsAvailableSize(writer, END_OF_CENTRAL_DIR_LENGTH)) {
6354
6593
  lastDiskNumber++;
6355
6594
  }
6356
6595
  let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
@@ -6366,11 +6605,10 @@
6366
6605
  throw new Error(ERR_INVALID_COMMENT);
6367
6606
  }
6368
6607
  const endOfdirectoryRecord = createRecordWriter(zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
6369
- if (getLength(endOfdirectoryRecord.array) + commentLength > writer.availableSize) {
6370
- writer.availableSize = 0;
6371
- await writeData(writer, EMPTY_UINT8_ARRAY);
6608
+ if (exceedsAvailableSize(writer, getLength(endOfdirectoryRecord.array) + commentLength)) {
6609
+ await writer.closeDisk();
6372
6610
  }
6373
- lastDiskNumber = writer.diskNumber;
6611
+ lastDiskNumber = getDiskNumber(writer);
6374
6612
  if (zip64) {
6375
6613
  endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
6376
6614
  endOfdirectoryRecord.uint64(44);
@@ -6384,7 +6622,7 @@
6384
6622
  endOfdirectoryRecord.uint64(directoryOffset);
6385
6623
  endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
6386
6624
  endOfdirectoryRecord.uint32(lastDiskNumber);
6387
- endOfdirectoryRecord.uint64(BigInt(zipWriter.offset) + BigInt(directoryDataLength) - BigInt(writer.diskOffset) - BigInt(writer.diskNumber ? zipWriter.initialOffset : 0));
6625
+ endOfdirectoryRecord.uint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength));
6388
6626
  endOfdirectoryRecord.uint32(lastDiskNumber + 1);
6389
6627
  const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true);
6390
6628
  if (supportZip64SplitFile) {
@@ -6424,8 +6662,23 @@
6424
6662
  };
6425
6663
  }
6426
6664
 
6427
- function getSegmentOffset(zipWriter, writer) {
6428
- return zipWriter.offset - writer.diskOffset - (writer.diskNumber ? zipWriter.initialOffset : 0);
6665
+ function getDiskNumber(writer) {
6666
+ const { diskNumber = 0 } = writer;
6667
+ return diskNumber;
6668
+ }
6669
+
6670
+ function getDiskOffset(writer) {
6671
+ const { diskOffset = 0 } = writer;
6672
+ return diskOffset;
6673
+ }
6674
+
6675
+ function exceedsAvailableSize(writer, length) {
6676
+ const { availableSize = INFINITY_VALUE } = writer;
6677
+ return length > availableSize;
6678
+ }
6679
+
6680
+ function getSegmentOffset(zipWriter, { diskNumber = 0, diskOffset = 0 }) {
6681
+ return zipWriter.offset - diskOffset - (diskNumber ? zipWriter.initialOffset : 0);
6429
6682
  }
6430
6683
 
6431
6684
  async function writeData(writer, array) {
@@ -6502,9 +6755,6 @@
6502
6755
  array.set(typedArray, offset);
6503
6756
  }
6504
6757
 
6505
- function getDataView(array) {
6506
- return new DataView(array.buffer, array.byteOffset, array.byteLength);
6507
- }
6508
6758
 
6509
6759
  function getLength(...arrayLikes) {
6510
6760
  let result = 0;
@@ -7045,7 +7295,7 @@
7045
7295
 
7046
7296
 
7047
7297
  try {
7048
- configure({ baseURI: (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('zip-core.js', document.baseURI).href)) });
7298
+ setDefaultConfiguration({ baseURI: (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('zip-core.js', document.baseURI).href)) });
7049
7299
  } catch {
7050
7300
  // ignored
7051
7301
  }
@@ -7063,6 +7313,7 @@
7063
7313
  exports.ERR_EOCDR_NOT_FOUND = ERR_EOCDR_NOT_FOUND;
7064
7314
  exports.ERR_EXTRAFIELD_ZIP64_NOT_FOUND = ERR_EXTRAFIELD_ZIP64_NOT_FOUND;
7065
7315
  exports.ERR_HTTP_RANGE = ERR_HTTP_RANGE;
7316
+ exports.ERR_HTTP_RESOURCE_CHANGED = ERR_HTTP_RESOURCE_CHANGED;
7066
7317
  exports.ERR_INVALID_COMMENT = ERR_INVALID_COMMENT;
7067
7318
  exports.ERR_INVALID_COMPRESSED_DATA = ERR_INVALID_COMPRESSED_DATA;
7068
7319
  exports.ERR_INVALID_ENCRYPTION_STRENGTH = ERR_INVALID_ENCRYPTION_STRENGTH;
@@ -7104,6 +7355,7 @@
7104
7355
  exports.createOPFSTempStream = createOPFSTempStream;
7105
7356
  exports.createSyncAccessHandleTempStream = createSyncAccessHandleTempStream;
7106
7357
  exports.getMimeType = getMimeType;
7358
+ exports.resetConfiguration = resetConfiguration;
7107
7359
  exports.terminateWorkers = terminateWorkers;
7108
7360
 
7109
7361
  }));