@zip.js/zip.js 2.8.34 → 2.8.36

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 +494 -221
  5. package/dist/zip-core.min.js +1 -1
  6. package/dist/zip-fs-core.js +471 -221
  7. package/dist/zip-fs-core.min.js +1 -1
  8. package/dist/zip-fs-native.js +498 -227
  9. package/dist/zip-fs-native.min.js +1 -1
  10. package/dist/zip-fs.js +500 -229
  11. package/dist/zip-fs.min.js +1 -1
  12. package/dist/zip-legacy.js +496 -223
  13. package/dist/zip-legacy.min.js +1 -1
  14. package/dist/zip-native.js +497 -224
  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 +499 -226
  19. package/dist/zip.min.js +1 -1
  20. package/index-native.cjs +498 -227
  21. package/index-native.min.js +1 -1
  22. package/index.cjs +500 -229
  23. package/index.d.cts +61 -0
  24. package/index.d.ts +61 -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 +230 -56
  30. package/lib/core/streams/aes-crypto-stream.js +1 -10
  31. package/lib/core/streams/codec-stream.js +37 -16
  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
@@ -161,11 +161,12 @@
161
161
  workerStarvationTimeout: 5000,
162
162
  useWebWorkers: true,
163
163
  useCompressionStream: true,
164
+ transferStreams: true,
164
165
  CompressionStream: typeof CompressionStream != UNDEFINED_TYPE && CompressionStream,
165
166
  DecompressionStream: typeof DecompressionStream != UNDEFINED_TYPE && DecompressionStream
166
167
  };
167
168
 
168
- const config = Object.assign({}, DEFAULT_CONFIGURATION);
169
+ const config = { ...DEFAULT_CONFIGURATION };
169
170
 
170
171
  function getConfiguration() {
171
172
  return config;
@@ -175,6 +176,50 @@
175
176
  return Math.max(config.chunkSize, MINIMUM_CHUNK_SIZE);
176
177
  }
177
178
 
179
+ /*
180
+ Copyright (c) 2026 Gildas Lormeau. All rights reserved.
181
+
182
+ Redistribution and use in source and binary forms, with or without
183
+ modification, are permitted provided that the following conditions are met:
184
+
185
+ 1. Redistributions of source code must retain the above copyright notice,
186
+ this list of conditions and the following disclaimer.
187
+
188
+ 2. Redistributions in binary form must reproduce the above copyright
189
+ notice, this list of conditions and the following disclaimer in
190
+ the documentation and/or other materials provided with the distribution.
191
+
192
+ 3. The names of the authors may not be used to endorse or promote products
193
+ derived from this software without specific prior written permission.
194
+
195
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
196
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
197
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
198
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
199
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
200
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
201
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
202
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
203
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
204
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
205
+ */
206
+
207
+
208
+ function concat(first, second) {
209
+ const result = new Uint8Array(first.length + second.length);
210
+ result.set(first);
211
+ result.set(second, first.length);
212
+ return result;
213
+ }
214
+
215
+ function toExactUint8Array(array) {
216
+ return array.byteOffset || array.byteLength != array.buffer.byteLength ? new Uint8Array(array) : array;
217
+ }
218
+
219
+ function getDataView(array) {
220
+ return new DataView(array.buffer, array.byteOffset, array.byteLength);
221
+ }
222
+
178
223
  /*
179
224
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
180
225
 
@@ -206,6 +251,7 @@
206
251
 
207
252
  const ERR_HTTP_STATUS = "HTTP error ";
208
253
  const ERR_HTTP_RANGE = "HTTP Range not supported";
254
+ const ERR_HTTP_RESOURCE_CHANGED = "HTTP resource changed";
209
255
  const ERR_ITERATOR_COMPLETED_TOO_SOON = "Writer iterator completed too soon";
210
256
  const ERR_WRITER_NOT_INITIALIZED = "Writer not initialized";
211
257
 
@@ -216,13 +262,16 @@
216
262
  const HTTP_HEADER_ACCEPT_RANGES = "Accept-Ranges";
217
263
  const HTTP_HEADER_RANGE = "Range";
218
264
  const HTTP_HEADER_CONTENT_TYPE = "Content-Type";
265
+ const HTTP_HEADER_ETAG = "Etag";
266
+ const HTTP_HEADER_LAST_MODIFIED = "Last-Modified";
219
267
  const HTTP_METHOD_HEAD = "HEAD";
220
268
  const HTTP_METHOD_GET = "GET";
221
269
  const HTTP_RANGE_UNIT = "bytes";
222
- const DEFAULT_CHUNK_SIZE$1 = 64 * 1024;
223
270
  const DEFAULT_BUFFER_SIZE = 256 * 1024;
271
+ const DEFAULT_MAXIMUM_RANGE_SIZE = 16 * 1024 * 1024;
224
272
 
225
273
  const PROPERTY_NAME_WRITABLE = "writable";
274
+ const DISK_BOUNDARY = Symbol();
226
275
 
227
276
  class Stream {
228
277
 
@@ -241,13 +290,13 @@
241
290
  return this.createReadable();
242
291
  }
243
292
 
244
- createReadable({ offset = 0, size, diskNumberStart, chunkSize = DEFAULT_CHUNK_SIZE$1 } = {}) {
293
+ createReadable({ offset = 0, size, chunkSize = getChunkSize(getConfiguration()) } = {}) {
245
294
  const reader = this;
246
295
  let chunkOffset = 0;
247
296
  return new ReadableStream({
248
297
  async pull(controller) {
249
298
  const dataSize = size === UNDEFINED_VALUE ? chunkSize : Math.min(chunkSize, size - chunkOffset);
250
- const data = await readUint8Array(reader, offset + chunkOffset, dataSize, diskNumberStart);
299
+ const data = await readUint8Array(reader, offset + chunkOffset, dataSize);
251
300
  controller.enqueue(data);
252
301
  if ((chunkOffset + chunkSize > size) || (size === UNDEFINED_VALUE && !data.length && dataSize)) {
253
302
  controller.close();
@@ -269,7 +318,7 @@
269
318
  if (!writer.initialized) {
270
319
  throw new Error(ERR_WRITER_NOT_INITIALIZED);
271
320
  }
272
- return writer.writeUint8Array(chunk);
321
+ return writer.writeUint8Array(toExactUint8Array(chunk));
273
322
  }
274
323
  });
275
324
  Object.defineProperty(writer, PROPERTY_NAME_WRITABLE, {
@@ -356,6 +405,27 @@
356
405
  }
357
406
  }
358
407
 
408
+ let blobSliceReliable;
409
+ let blobSliceProbe;
410
+
411
+ function probeBlobSliceReliability() {
412
+ blobSliceProbe = (async () => {
413
+ try {
414
+ const slicedBlob = new Blob([new Uint8Array(3)]).slice(1, 2);
415
+ const streamReader = slicedBlob.stream().getReader();
416
+ let streamedLength = 0;
417
+ let result = await streamReader.read();
418
+ while (!result.done) {
419
+ streamedLength += result.value.length;
420
+ result = await streamReader.read();
421
+ }
422
+ blobSliceReliable = streamedLength == 1;
423
+ } catch {
424
+ blobSliceReliable = false;
425
+ }
426
+ })();
427
+ }
428
+
359
429
  class BlobReader extends Reader {
360
430
 
361
431
  constructor(blob) {
@@ -364,14 +434,32 @@
364
434
  blob,
365
435
  size: blob.size
366
436
  });
437
+ if (!blobSliceProbe) {
438
+ probeBlobSliceReliability();
439
+ }
440
+ }
441
+
442
+ createReadable(options) {
443
+ const reader = this;
444
+ const { blob, size } = reader;
445
+ const { offset = 0, size: readSize = size - offset } = options || {};
446
+ if (!offset && readSize >= size) {
447
+ return blob.stream();
448
+ }
449
+ if (blobSliceReliable) {
450
+ return blob.slice(offset, offset + readSize).stream();
451
+ }
452
+ return super.createReadable(options);
367
453
  }
368
454
 
369
455
  async readUint8Array(offset, length) {
370
456
  const reader = this;
371
457
  const offsetEnd = offset + length;
372
- const blob = offset || offsetEnd < reader.size ? reader.blob.slice(offset, offsetEnd) : reader.blob;
458
+ const readsWholeBlob = !offset && offsetEnd >= reader.size;
459
+ const blob = readsWholeBlob ? reader.blob : reader.blob.slice(offset, offsetEnd);
373
460
  let arrayBuffer = await blob.arrayBuffer();
374
- if (arrayBuffer.byteLength > length) {
461
+ const sliceIgnoredByBuggyImplementation = arrayBuffer.byteLength > length;
462
+ if (sliceIgnoredByBuggyImplementation) {
375
463
  arrayBuffer = arrayBuffer.slice(offset, offsetEnd);
376
464
  }
377
465
  return new Uint8Array(arrayBuffer);
@@ -452,6 +540,18 @@
452
540
  super.init();
453
541
  }
454
542
 
543
+ createReadable(options) {
544
+ const reader = this;
545
+ const { useRangeHeader, forceRangeRequests, size } = reader;
546
+ if ((useRangeHeader || forceRangeRequests) && size !== UNDEFINED_VALUE) {
547
+ const { offset = 0, size: readSize = size - offset } = options || {};
548
+ if (readSize > 0 && offset < size) {
549
+ return createRangeReadable(reader, offset, Math.min(readSize, size - offset));
550
+ }
551
+ }
552
+ return super.createReadable(options);
553
+ }
554
+
455
555
  readUint8Array(index, length) {
456
556
  return readUint8ArrayHttpReader(this, index, length, sendFetchRequest, getFetchRequestData);
457
557
  }
@@ -480,6 +580,8 @@
480
580
  useRangeHeader,
481
581
  forceRangeRequests,
482
582
  combineSizeEocd,
583
+ checkResourceChanges = true,
584
+ maximumRangeSize = DEFAULT_MAXIMUM_RANGE_SIZE,
483
585
  fetch
484
586
  } = options;
485
587
  options = Object.assign({}, options);
@@ -487,6 +589,8 @@
487
589
  delete options.useRangeHeader;
488
590
  delete options.forceRangeRequests;
489
591
  delete options.combineSizeEocd;
592
+ delete options.checkResourceChanges;
593
+ delete options.maximumRangeSize;
490
594
  delete options.useXHR;
491
595
  delete options.fetch;
492
596
  Object.assign(httpReader, {
@@ -496,6 +600,8 @@
496
600
  useRangeHeader,
497
601
  forceRangeRequests,
498
602
  combineSizeEocd,
603
+ checkResourceChanges,
604
+ maximumRangeSize,
499
605
  fetch
500
606
  });
501
607
  }
@@ -520,17 +626,8 @@
520
626
  httpReader.eocdCache = eocdCache;
521
627
  }
522
628
  }
523
- let contentSize;
524
- const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
525
- if (contentRangeHeader) {
526
- const splitHeader = contentRangeHeader.trim().split(/\s*\/\s*/);
527
- if (splitHeader.length) {
528
- const headerValue = splitHeader[1];
529
- if (headerValue && headerValue != "*") {
530
- contentSize = Number(headerValue);
531
- }
532
- }
533
- }
629
+ setResourceValidators(httpReader, response);
630
+ const contentSize = getContentRangeSize(response);
534
631
  if (contentSize === UNDEFINED_VALUE) {
535
632
  await getContentLength(httpReader, sendRequest, getRequestData);
536
633
  } else {
@@ -571,6 +668,8 @@
571
668
  throw new Error(ERR_HTTP_RANGE);
572
669
  }
573
670
  }
671
+ checkResourceValidators(httpReader, response);
672
+ setResourceValidators(httpReader, response);
574
673
  const data = new Uint8Array(await response.arrayBuffer());
575
674
  if (data.length != length) {
576
675
  throw new Error(ERR_HTTP_RANGE);
@@ -582,7 +681,114 @@
582
681
  if (!data) {
583
682
  await getRequestData(httpReader, options);
584
683
  }
585
- return new Uint8Array(httpReader.data.subarray(index, index + length));
684
+ return httpReader.data.subarray(index, index + length);
685
+ }
686
+ }
687
+
688
+ function createRangeReadable(httpReader, offset, size) {
689
+ let bodyReader;
690
+ let windowOffset = offset;
691
+ let windowRemainingLength = 0;
692
+ let remainingLength = size;
693
+ return new ReadableStream({
694
+ start() {
695
+ return openWindow();
696
+ },
697
+ async pull(controller) {
698
+ if (!bodyReader) {
699
+ await openWindow();
700
+ }
701
+ const { value, done } = await bodyReader.read();
702
+ if (done) {
703
+ throw new Error(ERR_HTTP_RANGE);
704
+ }
705
+ const chunk = value.length > windowRemainingLength ? value.subarray(0, windowRemainingLength) : value;
706
+ windowRemainingLength -= chunk.length;
707
+ remainingLength -= chunk.length;
708
+ if (chunk.length) {
709
+ controller.enqueue(chunk);
710
+ }
711
+ if (!windowRemainingLength) {
712
+ await closeWindow();
713
+ if (!remainingLength) {
714
+ controller.close();
715
+ }
716
+ }
717
+ },
718
+ cancel(reason) {
719
+ return bodyReader && bodyReader.cancel(reason);
720
+ }
721
+ });
722
+
723
+ async function openWindow() {
724
+ const windowLength = Math.min(httpReader.maximumRangeSize, remainingLength);
725
+ const response = await sendFetchRequest(HTTP_METHOD_GET, httpReader, getRangeHeaders(httpReader, windowOffset, windowLength));
726
+ if (response.status != 206) {
727
+ throw new Error(ERR_HTTP_RANGE);
728
+ }
729
+ const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
730
+ if (contentRangeHeader) {
731
+ const rangeStart = Number(contentRangeHeader.trim().split(/[\s-]+/)[1]);
732
+ if (!Number.isNaN(rangeStart) && rangeStart != windowOffset) {
733
+ throw new Error(ERR_HTTP_RANGE);
734
+ }
735
+ }
736
+ checkResourceValidators(httpReader, response);
737
+ setResourceValidators(httpReader, response);
738
+ windowOffset += windowLength;
739
+ windowRemainingLength = windowLength;
740
+ bodyReader = response.body.getReader();
741
+ }
742
+
743
+ async function closeWindow() {
744
+ const currentBodyReader = bodyReader;
745
+ bodyReader = UNDEFINED_VALUE;
746
+ await currentBodyReader.cancel();
747
+ }
748
+ }
749
+
750
+ function getContentRangeSize(response) {
751
+ const contentRangeHeader = response.headers.get(HTTP_HEADER_CONTENT_RANGE);
752
+ if (contentRangeHeader) {
753
+ const headerValue = contentRangeHeader.trim().split(/\s*\/\s*/)[1];
754
+ if (headerValue && headerValue != "*") {
755
+ const contentSize = Number(headerValue);
756
+ if (!Number.isNaN(contentSize)) {
757
+ return contentSize;
758
+ }
759
+ }
760
+ }
761
+ }
762
+
763
+ function getResourceValidators({ headers }) {
764
+ return {
765
+ etag: headers.get(HTTP_HEADER_ETAG) || UNDEFINED_VALUE,
766
+ lastModified: headers.get(HTTP_HEADER_LAST_MODIFIED) || UNDEFINED_VALUE
767
+ };
768
+ }
769
+
770
+ function setResourceValidators(httpReader, response) {
771
+ const { checkResourceChanges, resourceValidators } = httpReader;
772
+ if (checkResourceChanges && !resourceValidators && response.status == 206) {
773
+ httpReader.resourceValidators = getResourceValidators(response);
774
+ }
775
+ }
776
+
777
+ function checkResourceValidators(httpReader, response) {
778
+ const { checkResourceChanges, resourceValidators, size } = httpReader;
779
+ if (checkResourceChanges) {
780
+ const contentRangeSize = getContentRangeSize(response);
781
+ if (contentRangeSize !== UNDEFINED_VALUE && size !== UNDEFINED_VALUE && contentRangeSize != size) {
782
+ throw new Error(ERR_HTTP_RESOURCE_CHANGED);
783
+ }
784
+ if (resourceValidators) {
785
+ const validators = getResourceValidators(response);
786
+ const changed = Object.entries(resourceValidators).some(([name, value]) =>
787
+ value !== UNDEFINED_VALUE && validators[name] !== UNDEFINED_VALUE && value != validators[name]);
788
+ if (changed) {
789
+ throw new Error(ERR_HTTP_RESOURCE_CHANGED);
790
+ }
791
+ }
586
792
  }
587
793
  }
588
794
 
@@ -693,6 +899,10 @@
693
899
  super.init();
694
900
  }
695
901
 
902
+ createReadable(options) {
903
+ return this.reader.createReadable(options);
904
+ }
905
+
696
906
  readUint8Array(index, length) {
697
907
  return this.reader.readUint8Array(index, length);
698
908
  }
@@ -766,25 +976,26 @@
766
976
  const reader = this;
767
977
  const { readers } = reader;
768
978
  reader.lastDiskNumber = 0;
769
- reader.lastDiskOffset = 0;
770
- await Promise.all(readers.map(async (diskReader, indexDiskReader) => {
771
- await initStream(diskReader);
772
- if (indexDiskReader != readers.length - 1) {
773
- reader.lastDiskOffset += diskReader.size;
774
- }
979
+ await Promise.all(readers.map(diskReader => initStream(diskReader)));
980
+ reader.diskOffsets = readers.map(diskReader => {
981
+ const diskOffset = reader.size;
775
982
  reader.size += diskReader.size;
776
- }));
983
+ return diskOffset;
984
+ });
777
985
  super.init();
778
986
  }
779
987
 
780
- async readUint8Array(offset, length, diskNumber = 0) {
988
+ getDiskOffset(diskNumber) {
989
+ const { diskOffsets, size } = this;
990
+ const diskOffset = diskOffsets.at(diskNumber);
991
+ return diskOffset === UNDEFINED_VALUE ? size : diskOffset;
992
+ }
993
+
994
+ async readUint8Array(offset, length) {
781
995
  const reader = this;
782
996
  const { readers } = this;
783
997
  let result;
784
- let currentDiskNumber = diskNumber;
785
- if (currentDiskNumber == -1) {
786
- currentDiskNumber = readers.length - 1;
787
- }
998
+ let currentDiskNumber = 0;
788
999
  let currentReaderOffset = offset;
789
1000
  while (readers[currentDiskNumber] && currentReaderOffset >= readers[currentDiskNumber].size) {
790
1001
  currentReaderOffset -= readers[currentDiskNumber].size;
@@ -797,14 +1008,9 @@
797
1008
  result = await readUint8Array(currentReader, currentReaderOffset, length);
798
1009
  } else {
799
1010
  const chunkLength = currentReaderSize - currentReaderOffset;
800
- result = new Uint8Array(length);
801
1011
  const firstPart = await readUint8Array(currentReader, currentReaderOffset, chunkLength);
802
- result.set(firstPart, 0);
803
- const secondPart = await reader.readUint8Array(offset + chunkLength, length - chunkLength, diskNumber);
804
- result.set(secondPart, chunkLength);
805
- if (firstPart.length + secondPart.length < length) {
806
- result = result.subarray(0, firstPart.length + secondPart.length);
807
- }
1012
+ const secondPart = await reader.readUint8Array(offset + chunkLength, length - chunkLength);
1013
+ result = concat(firstPart, secondPart);
808
1014
  }
809
1015
  } else {
810
1016
  result = EMPTY_UINT8_ARRAY;
@@ -829,6 +1035,12 @@
829
1035
  let diskSourceWriter, diskWritable, diskWriter;
830
1036
  const writable = new WritableStream({
831
1037
  async write(chunk) {
1038
+ if (chunk === DISK_BOUNDARY) {
1039
+ if (diskWriter) {
1040
+ await endDisk();
1041
+ }
1042
+ return;
1043
+ }
832
1044
  const { availableSize } = writer;
833
1045
  if (!diskWriter) {
834
1046
  const { value, done } = await writerGenerator.next();
@@ -848,11 +1060,7 @@
848
1060
  await this.write(chunk);
849
1061
  } else if (chunk.length >= availableSize) {
850
1062
  await writeChunk(chunk.subarray(0, availableSize));
851
- await closeDisk();
852
- writer.diskOffset += diskSourceWriter.size;
853
- writer.diskNumber++;
854
- diskWriter = null;
855
- writer.availableSize = writer.maxSize;
1063
+ await endDisk();
856
1064
  if (chunk.length > availableSize) {
857
1065
  await this.write(chunk.subarray(availableSize));
858
1066
  }
@@ -863,7 +1071,7 @@
863
1071
  async close() {
864
1072
  if (diskWriter) {
865
1073
  await diskWriter.ready;
866
- await closeDisk();
1074
+ await closeDiskWriter();
867
1075
  }
868
1076
  },
869
1077
  async abort(reason) {
@@ -888,10 +1096,28 @@
888
1096
  }
889
1097
  }
890
1098
 
891
- async function closeDisk() {
1099
+ async function endDisk() {
1100
+ await closeDiskWriter();
1101
+ writer.diskOffset += diskSourceWriter.size;
1102
+ writer.diskNumber++;
1103
+ diskWriter = null;
1104
+ writer.availableSize = writer.maxSize;
1105
+ }
1106
+
1107
+ async function closeDiskWriter() {
892
1108
  await diskWriter.close();
893
1109
  }
894
1110
  }
1111
+
1112
+ async closeDisk() {
1113
+ const streamWriter = this.writable.getWriter();
1114
+ try {
1115
+ await streamWriter.ready;
1116
+ await streamWriter.write(DISK_BOUNDARY);
1117
+ } finally {
1118
+ streamWriter.releaseLock();
1119
+ }
1120
+ }
895
1121
  }
896
1122
 
897
1123
  class GenericReader {
@@ -923,14 +1149,6 @@
923
1149
  if (writer.size === UNDEFINED_VALUE) {
924
1150
  writer.size = 0;
925
1151
  }
926
- if (!(writer instanceof SplitDataWriter)) {
927
- Object.assign(writer, {
928
- diskNumber: 0,
929
- diskOffset: 0,
930
- availableSize: INFINITY_VALUE,
931
- maxSize: INFINITY_VALUE
932
- });
933
- }
934
1152
  return writer;
935
1153
  }
936
1154
  }
@@ -949,8 +1167,8 @@
949
1167
  }
950
1168
  }
951
1169
 
952
- function readUint8Array(reader, offset, size, diskNumber) {
953
- return reader.readUint8Array(offset, size, diskNumber);
1170
+ function readUint8Array(reader, offset, size) {
1171
+ return reader.readUint8Array(offset, size);
954
1172
  }
955
1173
 
956
1174
  /*
@@ -2239,16 +2457,6 @@
2239
2457
  }
2240
2458
  }
2241
2459
 
2242
- function concat(leftArray, rightArray) {
2243
- let array = leftArray;
2244
- if (leftArray.length + rightArray.length) {
2245
- array = new Uint8Array(leftArray.length + rightArray.length);
2246
- array.set(leftArray, 0);
2247
- array.set(rightArray, leftArray.length);
2248
- }
2249
- return array;
2250
- }
2251
-
2252
2460
  function expand(inputArray, length) {
2253
2461
  if (length && length > inputArray.length) {
2254
2462
  const array = inputArray;
@@ -2510,44 +2718,34 @@
2510
2718
  constructor() {
2511
2719
  // deno-lint-ignore prefer-const
2512
2720
  let stream;
2513
- let headerLeft = GZIP_HEADER_LENGTH;
2514
- let tail = new Uint8Array(0);
2721
+ let headerBytesLeft = GZIP_HEADER_LENGTH;
2722
+ let trailerCandidate = new Uint8Array(0);
2515
2723
  super({
2516
2724
  transform(chunk, controller) {
2517
- if (headerLeft) {
2518
- const dropped = Math.min(headerLeft, chunk.length);
2519
- headerLeft -= dropped;
2520
- chunk = chunk.subarray(dropped);
2725
+ if (headerBytesLeft) {
2726
+ const droppedLength = Math.min(headerBytesLeft, chunk.length);
2727
+ headerBytesLeft -= droppedLength;
2728
+ chunk = chunk.subarray(droppedLength);
2521
2729
  if (!chunk.length) {
2522
2730
  return;
2523
2731
  }
2524
2732
  }
2525
- const available = tail.length + chunk.length;
2526
- if (available <= GZIP_TRAILER_LENGTH) {
2527
- const pending = new Uint8Array(available);
2528
- pending.set(tail);
2529
- pending.set(chunk, tail.length);
2530
- tail = pending;
2733
+ const availableLength = trailerCandidate.length + chunk.length;
2734
+ if (availableLength <= GZIP_TRAILER_LENGTH) {
2735
+ trailerCandidate = concat(trailerCandidate, chunk);
2531
2736
  return;
2532
2737
  }
2533
- const emitLength = available - GZIP_TRAILER_LENGTH;
2534
- const output = new Uint8Array(emitLength);
2535
- const fromTail = Math.min(emitLength, tail.length);
2536
- output.set(tail.subarray(0, fromTail), 0);
2537
- if (emitLength > fromTail) {
2538
- output.set(chunk.subarray(0, emitLength - fromTail), fromTail);
2539
- }
2540
- controller.enqueue(output);
2541
- const nextTail = new Uint8Array(GZIP_TRAILER_LENGTH);
2542
- const tailRemaining = tail.length - fromTail;
2543
- if (tailRemaining) {
2544
- nextTail.set(tail.subarray(fromTail), 0);
2545
- }
2546
- nextTail.set(chunk.subarray(emitLength - fromTail), tailRemaining);
2547
- tail = nextTail;
2738
+ const emitLength = availableLength - GZIP_TRAILER_LENGTH;
2739
+ const emittedFromTrailer = Math.min(emitLength, trailerCandidate.length);
2740
+ controller.enqueue(concat(
2741
+ trailerCandidate.subarray(0, emittedFromTrailer),
2742
+ chunk.subarray(0, emitLength - emittedFromTrailer)));
2743
+ trailerCandidate = concat(
2744
+ trailerCandidate.subarray(emittedFromTrailer),
2745
+ chunk.subarray(emitLength - emittedFromTrailer));
2548
2746
  },
2549
2747
  flush() {
2550
- const dataView = new DataView(tail.buffer, tail.byteOffset, tail.byteLength);
2748
+ const dataView = getDataView(trailerCandidate);
2551
2749
  stream.signature = dataView.getUint32(0, true);
2552
2750
  stream.uncompressedSize = dataView.getUint32(4, true);
2553
2751
  }
@@ -2790,33 +2988,54 @@
2790
2988
  class ChunkStream extends TransformStream {
2791
2989
 
2792
2990
  constructor(chunkSize) {
2793
- let pendingChunk;
2794
- if (!(chunkSize >= 1)) {
2991
+ const pendingChunks = [];
2992
+ let pendingLength = 0;
2993
+ if (!Number.isFinite(chunkSize) || chunkSize < 1) {
2795
2994
  chunkSize = DEFAULT_CHUNK_SIZE;
2796
2995
  }
2797
2996
  super({
2798
- transform,
2997
+ transform(chunk, controller) {
2998
+ pendingChunks.push(chunk);
2999
+ pendingLength += chunk.length;
3000
+ while (pendingLength > chunkSize) {
3001
+ controller.enqueue(shiftChunk());
3002
+ }
3003
+ },
2799
3004
  flush(controller) {
2800
- if (pendingChunk && pendingChunk.length) {
2801
- controller.enqueue(pendingChunk);
3005
+ if (pendingLength) {
3006
+ controller.enqueue(concatChunks(pendingChunks, pendingLength));
2802
3007
  }
2803
3008
  }
2804
3009
  });
2805
3010
 
2806
- function transform(chunk, controller) {
2807
- if (pendingChunk) {
2808
- const newChunk = new Uint8Array(pendingChunk.length + chunk.length);
2809
- newChunk.set(pendingChunk);
2810
- newChunk.set(chunk, pendingChunk.length);
2811
- chunk = newChunk;
2812
- pendingChunk = null;
3011
+ function shiftChunk() {
3012
+ const result = new Uint8Array(chunkSize);
3013
+ let resultOffset = 0;
3014
+ while (resultOffset < chunkSize) {
3015
+ const firstChunk = pendingChunks[0];
3016
+ const remainingLength = chunkSize - resultOffset;
3017
+ if (firstChunk.length <= remainingLength) {
3018
+ result.set(firstChunk, resultOffset);
3019
+ resultOffset += firstChunk.length;
3020
+ pendingChunks.shift();
3021
+ } else {
3022
+ result.set(firstChunk.subarray(0, remainingLength), resultOffset);
3023
+ pendingChunks[0] = firstChunk.subarray(remainingLength);
3024
+ resultOffset += remainingLength;
3025
+ }
2813
3026
  }
3027
+ pendingLength -= chunkSize;
3028
+ return result;
3029
+ }
3030
+
3031
+ function concatChunks(chunks, length) {
3032
+ const result = new Uint8Array(length);
2814
3033
  let offset = 0;
2815
- while (chunk.length - offset > chunkSize) {
2816
- controller.enqueue(chunk.slice(offset, offset + chunkSize));
2817
- offset += chunkSize;
3034
+ for (const chunk of chunks) {
3035
+ result.set(chunk, offset);
3036
+ offset += chunk.length;
2818
3037
  }
2819
- pendingChunk = offset ? chunk.slice(offset) : chunk;
3038
+ return result;
2820
3039
  }
2821
3040
  }
2822
3041
  }
@@ -2998,7 +3217,10 @@
2998
3217
  }
2999
3218
  }
3000
3219
  codecStream = new CodecStream(options, config);
3001
- await readable.pipeThrough(codecStream).pipeTo(writable, { preventClose: true, preventAbort: true });
3220
+ await readable
3221
+ .pipeThrough(codecStream)
3222
+ .pipeThrough(new ChunkStream(getChunkSize(config)))
3223
+ .pipeTo(writable, { preventClose: true, preventAbort: true });
3002
3224
  const {
3003
3225
  signature,
3004
3226
  inputSize,
@@ -3197,7 +3419,7 @@
3197
3419
  const { value, readable, writable } = message;
3198
3420
  const transferables = [];
3199
3421
  if (value) {
3200
- message.value = value.byteOffset || value.byteLength != value.buffer.byteLength ? new Uint8Array(value) : value;
3422
+ message.value = toExactUint8Array(value);
3201
3423
  transferables.push(message.value.buffer);
3202
3424
  }
3203
3425
  if (transferStreams && transferStreamsSupported) {
@@ -3321,8 +3543,8 @@
3321
3543
  const { options, config } = workerOptions;
3322
3544
  const { transferStreams, useWebWorkers, useCompressionStream, compressed, signed, encrypted } = options;
3323
3545
  const { workerURI, maxWorkers } = config;
3324
- workerOptions.transferStreams = transferStreams || transferStreams === UNDEFINED_VALUE;
3325
- const streamCopy = !compressed && !signed && !encrypted && !workerOptions.transferStreams;
3546
+ workerOptions.transferStreams = transferStreams || (transferStreams === UNDEFINED_VALUE && config.transferStreams);
3547
+ const streamCopy = !compressed && !signed && !encrypted;
3326
3548
  workerOptions.useWebWorkers = !streamCopy && (useWebWorkers || (useWebWorkers === UNDEFINED_VALUE && config.useWebWorkers));
3327
3549
  workerOptions.workerURI = workerOptions.useWebWorkers && workerURI ? workerURI : UNDEFINED_VALUE;
3328
3550
  options.useCompressionStream = useCompressionStream || (useCompressionStream === UNDEFINED_VALUE && config.useCompressionStream);
@@ -3791,7 +4013,7 @@
3791
4013
  const { endOfDirectoryInfo, endOfDirectoryReachingEndCount } = await findEndOfCentralDirectory(reader, rejectAmbiguousEndOfDirectory, maxAppendedDataSize);
3792
4014
  if (!endOfDirectoryInfo) {
3793
4015
  const signatureArray = await readUint8Array(reader, 0, 4);
3794
- const signatureView = getDataView$1(signatureArray);
4016
+ const signatureView = getDataView(signatureArray);
3795
4017
  if (getUint32(signatureView) == SPLIT_ZIP_FILE_SIGNATURE) {
3796
4018
  throw new Error(ERR_SPLIT_ZIP_FILE);
3797
4019
  } else {
@@ -3801,7 +4023,7 @@
3801
4023
  if (rejectAmbiguousEndOfDirectory && endOfDirectoryReachingEndCount > 1) {
3802
4024
  throwAmbiguousArchive("multiple end of central directory records");
3803
4025
  }
3804
- const endOfDirectoryView = getDataView$1(endOfDirectoryInfo);
4026
+ const endOfDirectoryView = getDataView(endOfDirectoryInfo);
3805
4027
  let directoryDataLength = getUint32(endOfDirectoryView, 12);
3806
4028
  let directoryDataOffset = getUint32(endOfDirectoryView, 16);
3807
4029
  const commentOffset = endOfDirectoryInfo.offset;
@@ -3817,17 +4039,21 @@
3817
4039
  let prependedDataLength = 0;
3818
4040
  let startOffset;
3819
4041
  let zip64EndOfDirectory;
3820
- if (directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS) {
4042
+ const requiresZip64 = directoryDataOffset == MAX_32_BITS || directoryDataLength == MAX_32_BITS || filesLength == MAX_16_BITS || diskNumber == MAX_16_BITS;
4043
+ if (directoryDataOffset != MAX_32_BITS && diskNumber != MAX_16_BITS) {
4044
+ directoryDataOffset += getDiskOffset$1(reader, diskNumber);
4045
+ }
4046
+ if (requiresZip64) {
3821
4047
  const endOfDirectoryLocatorArray = endOfDirectoryInfo.offset >= ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH ?
3822
4048
  await readUint8Array(reader, endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH, ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH) :
3823
4049
  EMPTY_UINT8_ARRAY;
3824
- const endOfDirectoryLocatorView = getDataView$1(endOfDirectoryLocatorArray);
4050
+ const endOfDirectoryLocatorView = getDataView(endOfDirectoryLocatorArray);
3825
4051
  if (endOfDirectoryLocatorArray.length == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH &&
3826
4052
  getUint32(endOfDirectoryLocatorView, 0) == ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE) {
3827
- directoryDataOffset = getBigUint64(endOfDirectoryLocatorView, 8);
3828
- let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH, -1);
3829
- let endOfDirectoryView = getDataView$1(endOfDirectoryArray);
3830
- const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH - (reader.lastDiskOffset || 0);
4053
+ directoryDataOffset = getDiskOffset$1(reader, getUint32(endOfDirectoryLocatorView, 4)) + getBigUint64(endOfDirectoryLocatorView, 8);
4054
+ let endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
4055
+ let endOfDirectoryView = getDataView(endOfDirectoryArray);
4056
+ const expectedDirectoryDataOffset = endOfDirectoryInfo.offset - ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH - ZIP64_END_OF_CENTRAL_DIR_LENGTH;
3831
4057
  if ((endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) &&
3832
4058
  directoryDataOffset != expectedDirectoryDataOffset && expectedDirectoryDataOffset >= 0) {
3833
4059
  const originalDirectoryDataOffset = directoryDataOffset;
@@ -3835,8 +4061,8 @@
3835
4061
  if (directoryDataOffset > originalDirectoryDataOffset) {
3836
4062
  prependedDataLength = directoryDataOffset - originalDirectoryDataOffset;
3837
4063
  }
3838
- endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH, -1);
3839
- endOfDirectoryView = getDataView$1(endOfDirectoryArray);
4064
+ endOfDirectoryArray = await readUint8Array(reader, directoryDataOffset, ZIP64_END_OF_CENTRAL_DIR_LENGTH);
4065
+ endOfDirectoryView = getDataView(endOfDirectoryArray);
3840
4066
  }
3841
4067
  if (endOfDirectoryArray.length < ZIP64_END_OF_CENTRAL_DIR_LENGTH || getUint32(endOfDirectoryView, 0) != ZIP64_END_OF_CENTRAL_DIR_SIGNATURE) {
3842
4068
  throw new Error(ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND);
@@ -3862,7 +4088,7 @@
3862
4088
  } else if (checkAmbiguity && directoryDataLength != getBigUint64(endOfDirectoryView, 40)) {
3863
4089
  throwAmbiguousArchive("mismatched zip64 end of central directory record");
3864
4090
  }
3865
- directoryDataOffset = getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
4091
+ directoryDataOffset = getDiskOffset$1(reader, diskNumber) + getBigUint64(endOfDirectoryView, 48) + prependedDataLength;
3866
4092
  }
3867
4093
  }
3868
4094
  const declaredDirectoryDataLength = directoryDataLength;
@@ -3879,19 +4105,19 @@
3879
4105
  throw new Error(ERR_BAD_FORMAT);
3880
4106
  }
3881
4107
  let offset = 0;
3882
- let directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber);
3883
- let directoryView = getDataView$1(directoryArray);
4108
+ let directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
4109
+ let directoryView = getDataView(directoryArray);
3884
4110
  if (directoryDataLength) {
3885
4111
  if (directoryArray.length < 4) {
3886
4112
  throw new Error(ERR_BAD_FORMAT);
3887
4113
  }
3888
- const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength - (reader.lastDiskOffset || 0);
4114
+ const expectedDirectoryDataOffset = centralDirectoryEndOffset - directoryDataLength;
3889
4115
  if (directoryDataOffset != expectedDirectoryDataOffset && diskNumber == lastDiskNumber) {
3890
4116
  const storedPointsAtDirectory = getUint32(directoryView, offset) == CENTRAL_FILE_HEADER_SIGNATURE;
3891
4117
  let reconcile = !storedPointsAtDirectory;
3892
4118
  if (!reconcile && expectedDirectoryDataOffset >= 0 && expectedDirectoryDataOffset + 4 <= reader.size) {
3893
- const expectedSignatureArray = await readUint8Array(reader, expectedDirectoryDataOffset, 4, diskNumber);
3894
- reconcile = getUint32(getDataView$1(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
4119
+ const expectedSignatureArray = await readUint8Array(reader, expectedDirectoryDataOffset, 4);
4120
+ reconcile = getUint32(getDataView(expectedSignatureArray), 0) == CENTRAL_FILE_HEADER_SIGNATURE;
3895
4121
  }
3896
4122
  if (reconcile) {
3897
4123
  const originalDirectoryDataOffset = directoryDataOffset;
@@ -3899,16 +4125,16 @@
3899
4125
  if (directoryDataOffset > originalDirectoryDataOffset) {
3900
4126
  prependedDataLength += directoryDataOffset - originalDirectoryDataOffset;
3901
4127
  }
3902
- directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber);
3903
- directoryView = getDataView$1(directoryArray);
4128
+ directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
4129
+ directoryView = getDataView(directoryArray);
3904
4130
  }
3905
4131
  }
3906
4132
  }
3907
- const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset - (reader.lastDiskOffset || 0);
4133
+ const expectedDirectoryDataLength = centralDirectoryEndOffset - directoryDataOffset;
3908
4134
  if (directoryDataLength != expectedDirectoryDataLength && expectedDirectoryDataLength >= 0 && diskNumber == lastDiskNumber) {
3909
4135
  directoryDataLength = expectedDirectoryDataLength;
3910
- directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength, diskNumber);
3911
- directoryView = getDataView$1(directoryArray);
4136
+ directoryArray = await readUint8Array(reader, directoryDataOffset, directoryDataLength);
4137
+ directoryView = getDataView(directoryArray);
3912
4138
  }
3913
4139
  if (directoryDataOffset < 0 || directoryDataOffset >= reader.size) {
3914
4140
  throw new Error(ERR_BAD_FORMAT);
@@ -3981,7 +4207,7 @@
3981
4207
  });
3982
4208
  readCommonFooter(fileEntry, fileEntry, directoryView, offset + 6);
3983
4209
  fileEntry.offset += prependedDataLength;
3984
- startOffset = Math.min(fileEntry.offset, startOffset);
4210
+ startOffset = Math.min(getDiskOffset$1(reader, fileEntry.diskNumberStart) + fileEntry.offset, startOffset);
3985
4211
  if (checkAmbiguity) {
3986
4212
  if (filenames.has(fileEntry.filename)) {
3987
4213
  duplicateFilename = true;
@@ -4095,8 +4321,9 @@
4095
4321
  dataDescriptor
4096
4322
  } = bitFlag;
4097
4323
  const localDirectory = fileEntry.localDirectory = {};
4098
- const dataArray = await readUint8Array(reader, offset, HEADER_SIZE, diskNumberStart);
4099
- const dataView = getDataView$1(dataArray);
4324
+ const localHeaderOffset = getDiskOffset$1(reader, diskNumberStart) + offset;
4325
+ const dataArray = await readUint8Array(reader, localHeaderOffset, HEADER_SIZE);
4326
+ const dataView = getDataView(dataArray);
4100
4327
  let password = getOptionValue$1(zipEntry, options, OPTION_PASSWORD);
4101
4328
  let rawPassword = getOptionValue$1(zipEntry, options, OPTION_RAW_PASSWORD);
4102
4329
  const passThrough = getOptionValue$1(zipEntry, options, OPTION_PASS_THROUGH);
@@ -4121,12 +4348,12 @@
4121
4348
  const checkAmbiguity = getStrictness(getOptionValue$1(zipEntry, options, OPTION_STRICTNESS), getOptionValue$1(zipEntry, options, OPTION_CHECK_AMBIGUITY)) == STRICTNESS_STRICT;
4122
4349
  let rawLocalFilename = EMPTY_UINT8_ARRAY;
4123
4350
  if (checkAmbiguity && (filenameLength || extraFieldLength)) {
4124
- const trailingDataArray = await readUint8Array(reader, offset + HEADER_SIZE, filenameLength + extraFieldLength, diskNumberStart);
4351
+ const trailingDataArray = await readUint8Array(reader, localHeaderOffset + HEADER_SIZE, filenameLength + extraFieldLength);
4125
4352
  rawLocalFilename = trailingDataArray.subarray(0, filenameLength);
4126
4353
  localDirectory.rawExtraField = trailingDataArray.subarray(filenameLength);
4127
4354
  } else {
4128
4355
  localDirectory.rawExtraField = extraFieldLength ?
4129
- await readUint8Array(reader, offset + HEADER_SIZE + filenameLength, extraFieldLength, diskNumberStart) :
4356
+ await readUint8Array(reader, localHeaderOffset + HEADER_SIZE + filenameLength, extraFieldLength) :
4130
4357
  EMPTY_UINT8_ARRAY;
4131
4358
  }
4132
4359
  readCommonFooter(zipEntry, localDirectory, dataView, 4, true);
@@ -4152,9 +4379,9 @@
4152
4379
  throw new Error(ERR_ENCRYPTED);
4153
4380
  }
4154
4381
  }
4155
- const dataOffset = offset + HEADER_SIZE + filenameLength + extraFieldLength;
4382
+ const dataOffset = localHeaderOffset + HEADER_SIZE + filenameLength + extraFieldLength;
4156
4383
  const size = compressedSize;
4157
- const readable = reader.createReadable({ offset: dataOffset, size, diskNumberStart, chunkSize: getChunkSize(config) });
4384
+ const readable = reader.createReadable({ offset: dataOffset, size });
4158
4385
  const signal = getOptionValue$1(zipEntry, options, OPTION_SIGNAL);
4159
4386
  const checkPasswordOnly = getOptionValue$1(zipEntry, options, OPTION_CHECK_PASSWORD_ONLY);
4160
4387
  let checkOverlappingEntry = getOptionValue$1(zipEntry, options, OPTION_CHECK_OVERLAPPING_ENTRY);
@@ -4195,8 +4422,7 @@
4195
4422
  reader,
4196
4423
  fileEntry,
4197
4424
  index,
4198
- offset,
4199
- diskNumberStart,
4425
+ offset: localHeaderOffset,
4200
4426
  signature,
4201
4427
  compressedSize,
4202
4428
  uncompressedSize,
@@ -4260,7 +4486,7 @@
4260
4486
  function readCommonFooter(fileEntry, directory, dataView, offset, localDirectory) {
4261
4487
  const { rawExtraField } = directory;
4262
4488
  const extraField = directory.extraField = new Map();
4263
- const rawExtraFieldView = getDataView$1(new Uint8Array(rawExtraField));
4489
+ const rawExtraFieldView = getDataView(rawExtraField);
4264
4490
  let offsetExtraField = 0;
4265
4491
  try {
4266
4492
  while (offsetExtraField < rawExtraField.length) {
@@ -4332,7 +4558,7 @@
4332
4558
 
4333
4559
  function readExtraFieldZip64(extraFieldZip64, directory) {
4334
4560
  directory.zip64 = true;
4335
- const extraFieldView = getDataView$1(extraFieldZip64.data);
4561
+ const extraFieldView = getDataView(extraFieldZip64.data);
4336
4562
  const missingProperties = ZIP64_PROPERTIES.filter(([propertyName, max]) => directory[propertyName] == max);
4337
4563
  const requiredLength = missingProperties.reduce((length, [, max]) => length + ZIP64_EXTRACTION[max].bytes, 0);
4338
4564
  if (extraFieldZip64.data.length < requiredLength) {
@@ -4351,10 +4577,10 @@
4351
4577
  extraFieldUnicode.valid = false;
4352
4578
  return;
4353
4579
  }
4354
- const extraFieldView = getDataView$1(extraFieldUnicode.data);
4580
+ const extraFieldView = getDataView(extraFieldUnicode.data);
4355
4581
  const crc32 = new Crc32();
4356
4582
  crc32.append(fileEntry[rawPropertyName]);
4357
- const dataViewSignature = getDataView$1(new Uint8Array(4));
4583
+ const dataViewSignature = getDataView(new Uint8Array(4));
4358
4584
  dataViewSignature.setUint32(0, crc32.get(), true);
4359
4585
  const signature = getUint32(extraFieldView, 1);
4360
4586
  Object.assign(extraFieldUnicode, {
@@ -4369,7 +4595,7 @@
4369
4595
  }
4370
4596
 
4371
4597
  function readExtraFieldAES(extraFieldAES, directory, compressionMethod) {
4372
- const extraFieldView = getDataView$1(extraFieldAES.data);
4598
+ const extraFieldView = getDataView(extraFieldAES.data);
4373
4599
  const strength = getUint8(extraFieldView, 4);
4374
4600
  Object.assign(extraFieldAES, {
4375
4601
  vendorVersion: getUint8(extraFieldView, 0),
@@ -4382,7 +4608,7 @@
4382
4608
  }
4383
4609
 
4384
4610
  function readExtraFieldNTFS(extraFieldNTFS, directory) {
4385
- const extraFieldView = getDataView$1(extraFieldNTFS.data);
4611
+ const extraFieldView = getDataView(extraFieldNTFS.data);
4386
4612
  let offsetExtraField = 4;
4387
4613
  let tag1Data;
4388
4614
  try {
@@ -4399,7 +4625,7 @@
4399
4625
  }
4400
4626
  try {
4401
4627
  if (tag1Data && tag1Data.length == 24) {
4402
- const tag1View = getDataView$1(tag1Data);
4628
+ const tag1View = getDataView(tag1Data);
4403
4629
  const rawLastModDate = tag1View.getBigUint64(0, true);
4404
4630
  const rawLastAccessDate = tag1View.getBigUint64(8, true);
4405
4631
  const rawCreationDate = tag1View.getBigUint64(16, true);
@@ -4422,7 +4648,7 @@
4422
4648
 
4423
4649
  function readExtraFieldUnix(extraField, directory, isInfoZip) {
4424
4650
  try {
4425
- const view = getDataView$1(new Uint8Array(extraField.data));
4651
+ const view = getDataView(extraField.data);
4426
4652
  let uid, gid;
4427
4653
  if (isInfoZip) {
4428
4654
  let offset = 0;
@@ -4460,7 +4686,7 @@
4460
4686
  if (!extraFieldExtendedTimestamp.data.length) {
4461
4687
  return;
4462
4688
  }
4463
- const extraFieldView = getDataView$1(extraFieldExtendedTimestamp.data);
4689
+ const extraFieldView = getDataView(extraFieldExtendedTimestamp.data);
4464
4690
  const flags = getUint8(extraFieldView, 0);
4465
4691
  const timeProperties = [];
4466
4692
  const timeRawProperties = [];
@@ -4498,7 +4724,6 @@
4498
4724
  fileEntry,
4499
4725
  index,
4500
4726
  offset,
4501
- diskNumberStart,
4502
4727
  signature,
4503
4728
  compressedSize,
4504
4729
  uncompressedSize,
@@ -4507,12 +4732,6 @@
4507
4732
  extraFieldZip64,
4508
4733
  readRanges
4509
4734
  }) {
4510
- let diskOffset = 0;
4511
- if (diskNumberStart && reader.readers) {
4512
- for (let indexReader = 0; indexReader < Math.min(diskNumberStart, reader.readers.length); indexReader++) {
4513
- diskOffset += reader.readers[indexReader].size;
4514
- }
4515
- }
4516
4735
  let dataDescriptorLength = 0;
4517
4736
  if (dataDescriptor) {
4518
4737
  if (extraFieldZip64) {
@@ -4522,19 +4741,19 @@
4522
4741
  }
4523
4742
  }
4524
4743
  if (dataDescriptorLength) {
4525
- const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH, diskNumberStart);
4744
+ const dataDescriptorArray = await readUint8Array(reader, dataOffset + compressedSize, dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH);
4526
4745
  const dataDescriptorSignature = dataDescriptorArray.length == dataDescriptorLength + DATA_DESCRIPTOR_RECORD_SIGNATURE_LENGTH &&
4527
- getUint32(getDataView$1(dataDescriptorArray), 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
4746
+ getUint32(getDataView(dataDescriptorArray), 0) == DATA_DESCRIPTOR_RECORD_SIGNATURE;
4528
4747
  if (dataDescriptorSignature) {
4529
- const readSignature = getUint32(getDataView$1(dataDescriptorArray), 4);
4748
+ const readSignature = getUint32(getDataView(dataDescriptorArray), 4);
4530
4749
  let readCompressedSize;
4531
4750
  let readUncompressedSize;
4532
4751
  if (extraFieldZip64) {
4533
- readCompressedSize = getBigUint64(getDataView$1(dataDescriptorArray), 8);
4534
- readUncompressedSize = getBigUint64(getDataView$1(dataDescriptorArray), 16);
4752
+ readCompressedSize = getBigUint64(getDataView(dataDescriptorArray), 8);
4753
+ readUncompressedSize = getBigUint64(getDataView(dataDescriptorArray), 16);
4535
4754
  } else {
4536
- readCompressedSize = getUint32(getDataView$1(dataDescriptorArray), 8);
4537
- readUncompressedSize = getUint32(getDataView$1(dataDescriptorArray), 12);
4755
+ readCompressedSize = getUint32(getDataView(dataDescriptorArray), 8);
4756
+ readUncompressedSize = getUint32(getDataView(dataDescriptorArray), 12);
4538
4757
  }
4539
4758
  const matchSignature = (fileEntry.encrypted && !fileEntry.zipCrypto) || readSignature == signature;
4540
4759
  if (matchSignature &&
@@ -4545,8 +4764,8 @@
4545
4764
  }
4546
4765
  }
4547
4766
  const range = {
4548
- start: diskOffset + offset,
4549
- end: diskOffset + dataOffset + compressedSize + dataDescriptorLength,
4767
+ start: offset,
4768
+ end: dataOffset + compressedSize + dataDescriptorLength,
4550
4769
  fileEntry
4551
4770
  };
4552
4771
  for (const [otherIndex, otherRange] of readRanges) {
@@ -4559,6 +4778,10 @@
4559
4778
  readRanges.set(index, range);
4560
4779
  }
4561
4780
 
4781
+ function getDiskOffset$1(reader, diskNumber) {
4782
+ return reader.getDiskOffset ? reader.getDiskOffset(diskNumber) : 0;
4783
+ }
4784
+
4562
4785
  function getStrictness(strictness, checkAmbiguity) {
4563
4786
  if (strictness === UNDEFINED_VALUE) {
4564
4787
  return checkAmbiguity ? STRICTNESS_STRICT : STRICTNESS_BALANCED;
@@ -4642,7 +4865,7 @@
4642
4865
  async function* scanEndOfCentralDirectory(reader, scanLength) {
4643
4866
  const scanOffset = reader.size - scanLength;
4644
4867
  const scanArray = await readUint8Array(reader, scanOffset, scanLength);
4645
- const scanView = getDataView$1(scanArray);
4868
+ const scanView = getDataView(scanArray);
4646
4869
  for (let indexByte = scanArray.length - END_OF_CENTRAL_DIR_LENGTH; indexByte >= 0; indexByte--) {
4647
4870
  if (getUint32(scanView, indexByte) == END_OF_CENTRAL_DIR_SIGNATURE) {
4648
4871
  yield [scanView, scanOffset, scanArray, indexByte, scanOffset + indexByte];
@@ -4665,7 +4888,8 @@
4665
4888
  if (!filesLength && !directoryDataLength) {
4666
4889
  return CENTRAL_DIRECTORY_PLAUSIBLE;
4667
4890
  }
4668
- for (const centralDirectoryOffset of [offset - directoryDataLength, directoryDataOffset]) {
4891
+ const directoryDiskNumber = getUint16(view, indexByte + 6);
4892
+ for (const centralDirectoryOffset of [offset - directoryDataLength, getDiskOffset$1(reader, directoryDiskNumber) + directoryDataOffset]) {
4669
4893
  if (await readSignature(reader, view, anchoredOffset, centralDirectoryOffset, size, remoteProbeBudget) == CENTRAL_FILE_HEADER_SIGNATURE) {
4670
4894
  return CENTRAL_DIRECTORY_REACHABLE;
4671
4895
  }
@@ -4683,7 +4907,7 @@
4683
4907
  if (remoteProbeBudget.count > 0) {
4684
4908
  remoteProbeBudget.count--;
4685
4909
  const signatureArray = await readUint8Array(reader, signatureOffset, 4);
4686
- return getUint32(getDataView$1(signatureArray), 0);
4910
+ return getUint32(getDataView(signatureArray), 0);
4687
4911
  }
4688
4912
  return UNDEFINED_VALUE;
4689
4913
  }
@@ -4748,9 +4972,26 @@
4748
4972
  return Number(view.getBigUint64(offset, true));
4749
4973
  }
4750
4974
 
4751
- function getDataView$1(array) {
4752
- return new DataView(array.buffer, array.byteOffset, array.byteLength);
4753
- }
4975
+ var zipReader = /*#__PURE__*/Object.freeze({
4976
+ __proto__: null,
4977
+ ERR_AMBIGUOUS_ARCHIVE: ERR_AMBIGUOUS_ARCHIVE,
4978
+ ERR_BAD_FORMAT: ERR_BAD_FORMAT,
4979
+ ERR_CENTRAL_DIRECTORY_NOT_FOUND: ERR_CENTRAL_DIRECTORY_NOT_FOUND,
4980
+ ERR_ENCRYPTED: ERR_ENCRYPTED,
4981
+ ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND: ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND,
4982
+ ERR_EOCDR_NOT_FOUND: ERR_EOCDR_NOT_FOUND,
4983
+ ERR_EXTRAFIELD_ZIP64_NOT_FOUND: ERR_EXTRAFIELD_ZIP64_NOT_FOUND,
4984
+ ERR_INVALID_COMPRESSED_DATA: ERR_INVALID_COMPRESSED_DATA,
4985
+ ERR_INVALID_PASSWORD: ERR_INVALID_PASSWORD,
4986
+ ERR_INVALID_SIGNATURE: ERR_INVALID_SIGNATURE,
4987
+ ERR_INVALID_UNCOMPRESSED_SIZE: ERR_INVALID_UNCOMPRESSED_SIZE,
4988
+ ERR_LOCAL_FILE_HEADER_NOT_FOUND: ERR_LOCAL_FILE_HEADER_NOT_FOUND,
4989
+ ERR_OVERLAPPING_ENTRY: ERR_OVERLAPPING_ENTRY,
4990
+ ERR_SPLIT_ZIP_FILE: ERR_SPLIT_ZIP_FILE,
4991
+ ERR_UNSUPPORTED_COMPRESSION: ERR_UNSUPPORTED_COMPRESSION$1,
4992
+ ERR_UNSUPPORTED_ENCRYPTION: ERR_UNSUPPORTED_ENCRYPTION,
4993
+ ZipReader: ZipReader
4994
+ });
4754
4995
 
4755
4996
  /*
4756
4997
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
@@ -4815,9 +5056,10 @@
4815
5056
 
4816
5057
  constructor(writer, options = {}) {
4817
5058
  writer = new GenericWriter(writer);
5059
+ const { availableSize = INFINITY_VALUE, maxSize = INFINITY_VALUE } = writer;
4818
5060
  const addSplitZipSignature =
4819
- writer.availableSize !== UNDEFINED_VALUE && writer.availableSize > 0 && writer.availableSize !== INFINITY_VALUE &&
4820
- writer.maxSize !== UNDEFINED_VALUE && writer.maxSize > 0 && writer.maxSize !== INFINITY_VALUE;
5061
+ availableSize > 0 && availableSize !== INFINITY_VALUE &&
5062
+ maxSize > 0 && maxSize !== INFINITY_VALUE;
4821
5063
  Object.assign(this, {
4822
5064
  writer,
4823
5065
  addSplitZipSignature,
@@ -4839,9 +5081,10 @@
4839
5081
  }
4840
5082
  reader = new GenericReader(reader);
4841
5083
  await initStream(reader);
4842
- const zipReader = new ZipReader(reader.readable);
4843
- const entries = await zipReader.getEntries();
4844
- await zipReader.close();
5084
+ const { ZipReader } = await Promise.resolve().then(function () { return zipReader; });
5085
+ const zipReader$1 = new ZipReader(reader.readable);
5086
+ const entries = await zipReader$1.getEntries();
5087
+ await zipReader$1.close();
4845
5088
  await initStream(this.writer);
4846
5089
  await reader.readable.pipeTo(this.writer.writable, { preventClose: true, preventAbort: true });
4847
5090
  this.writer.size = this.offset = reader.size;
@@ -4857,8 +5100,6 @@
4857
5100
  encrypted,
4858
5101
  uncompressedSize,
4859
5102
  compressedSize,
4860
- diskOffset,
4861
- diskNumber,
4862
5103
  zip64
4863
5104
  } = entry;
4864
5105
  let {
@@ -4906,8 +5147,9 @@
4906
5147
  Object.assign(entry, {
4907
5148
  zip64UncompressedSize,
4908
5149
  zip64CompressedSize,
4909
- zip64Offset: zip64 && this.offset - diskOffset >= MAX_32_BITS,
4910
- zip64DiskNumberStart: zip64 && diskNumber >= MAX_16_BITS,
5150
+ zip64Offset: zip64 && entry.offset >= MAX_32_BITS,
5151
+ diskNumberStart: 0,
5152
+ zip64DiskNumberStart: false,
4911
5153
  rawExtraFieldZip64,
4912
5154
  rawExtraFieldAES,
4913
5155
  rawExtraFieldExtendedTimestamp,
@@ -5012,7 +5254,8 @@
5012
5254
  try {
5013
5255
  const sizesInfo = await resolveSizes(zipWriter, reader, metadataInfo, options);
5014
5256
  ({ reader } = sizesInfo);
5015
- const { diskOffset, diskNumber } = zipWriter.writer;
5257
+ const diskOffset = getDiskOffset(zipWriter.writer);
5258
+ const diskNumber = getDiskNumber(zipWriter.writer);
5016
5259
  options = Object.assign({}, options, attributesInfo.resolvedOptions, metadataInfo.resolvedOptions, sizesInfo.resolvedOptions, {
5017
5260
  internalFileAttribute: metadataInfo.resolvedOptions.internalFileAttributes,
5018
5261
  externalFileAttribute: attributesInfo.resolvedOptions.externalFileAttributes,
@@ -5189,7 +5432,7 @@
5189
5432
  const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
5190
5433
  const keepOrder = getOptionValue(zipWriter, options, OPTION_KEEP_ORDER, true);
5191
5434
  const useWebWorkers = getOptionValue(zipWriter, options, OPTION_USE_WEB_WORKERS);
5192
- const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS, true);
5435
+ const transferStreams = getOptionValue(zipWriter, options, OPTION_TRANSFER_STREAMS);
5193
5436
  const bufferedWrite = getOptionValue(zipWriter, options, OPTION_BUFFERED_WRITE);
5194
5437
  const createTempStream = getOptionValue(zipWriter, options, OPTION_CREATE_TEMP_STREAM);
5195
5438
  const dataDescriptorSignature = getOptionValue(zipWriter, options, OPTION_DATA_DESCRIPTOR_SIGNATURE, true);
@@ -5387,7 +5630,7 @@
5387
5630
  await requestLockWriter();
5388
5631
  }
5389
5632
  await initStream(fileWriter);
5390
- const { diskOffset } = writer;
5633
+ const diskOffset = getDiskOffset(writer);
5391
5634
  if (zipWriter.addSplitZipSignature) {
5392
5635
  delete zipWriter.addSplitZipSignature;
5393
5636
  const signatureArray = new Uint8Array(4);
@@ -5404,7 +5647,7 @@
5404
5647
  await lockPreviousFileEntry;
5405
5648
  await skipDiskIfNeeded();
5406
5649
  }
5407
- const diskNumberStart = writer.diskNumber;
5650
+ const diskNumberStart = getDiskNumber(writer);
5408
5651
  const entryOffset = getSegmentOffset(zipWriter, writer);
5409
5652
  fileEntry.diskNumberStart = diskNumberStart;
5410
5653
  if (!bufferedWrite) {
@@ -5424,11 +5667,11 @@
5424
5667
  writingBufferedEntryData = true;
5425
5668
  writerSizeBeforeEntry = writer.size;
5426
5669
  await skipDiskIfNeeded();
5427
- fileEntry.diskNumberStart = writer.diskNumber;
5670
+ fileEntry.diskNumberStart = getDiskNumber(writer);
5428
5671
  fileEntry.offset = getSegmentOffset(zipWriter, writer);
5429
5672
  if (usdz) {
5430
5673
  const previousMetadataSize = entryInfo.metadataSize;
5431
- appendExtraFieldUSDZ(entryInfo, zipWriter.offset - writer.diskOffset);
5674
+ appendExtraFieldUSDZ(entryInfo, zipWriter.offset - getDiskOffset(writer));
5432
5675
  fileEntry.size += entryInfo.metadataSize - previousMetadataSize;
5433
5676
  }
5434
5677
  updateLocalHeader(fileEntry, headerInfo.localHeaderView, options);
@@ -5493,9 +5736,8 @@
5493
5736
  }
5494
5737
 
5495
5738
  async function skipDiskIfNeeded() {
5496
- if (getLength(headerInfo.localHeaderArray) > writer.availableSize) {
5497
- writer.availableSize = 0;
5498
- await writeData(writer, EMPTY_UINT8_ARRAY);
5739
+ if (exceedsAvailableSize(writer, getLength(headerInfo.localHeaderArray))) {
5740
+ await writer.closeDisk();
5499
5741
  }
5500
5742
  }
5501
5743
  }
@@ -5606,7 +5848,7 @@
5606
5848
  }
5607
5849
  const { writable } = writer;
5608
5850
  if (reader) {
5609
- const readable = reader.createReadable ? reader.createReadable({ chunkSize: getChunkSize(config) }) : reader.readable;
5851
+ const readable = reader.createReadable ? reader.createReadable() : reader.readable;
5610
5852
  const size = reader.size;
5611
5853
  const workerOptions = {
5612
5854
  options: {
@@ -6038,8 +6280,8 @@
6038
6280
 
6039
6281
  async function closeFile(zipWriter, comment, options) {
6040
6282
  const directoryDataLength = createDirectoryRecords(zipWriter.files);
6041
- const { cdStartDiskNumber, cdStartDiskOffset } = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
6042
- await writeEndOfDirectoryRecord(zipWriter, comment, options, { cdStartDiskNumber, cdStartDiskOffset, directoryDataLength });
6283
+ const directoryStart = await writeDirectoryRecords(zipWriter, directoryDataLength, options);
6284
+ await writeEndOfDirectoryRecord(zipWriter, comment, options, { directoryStart, directoryDataLength });
6043
6285
  }
6044
6286
 
6045
6287
  function createDirectoryRecords(files) {
@@ -6121,8 +6363,8 @@
6121
6363
  await initStream(writer);
6122
6364
  let offset = 0;
6123
6365
  let directoryDiskOffset = 0;
6124
- let cdStartDiskNumber = writer.diskNumber;
6125
- let cdStartDiskOffset = writer.diskOffset;
6366
+ let directoryStartDiskNumber = getDiskNumber(writer);
6367
+ let directoryStartDiskOffset = getDiskOffset(writer);
6126
6368
  for (const [indexFileEntry, fileEntry] of Array.from(files.values()).entries()) {
6127
6369
  const {
6128
6370
  offset: fileEntryOffset,
@@ -6149,15 +6391,14 @@
6149
6391
  } = fileEntry;
6150
6392
  const extraFieldLength = getLength(rawExtraFieldZip64, rawExtraFieldAES, rawExtraFieldExtendedTimestamp, rawExtraFieldNTFS, rawExtraFieldUnix, rawExtraField);
6151
6393
  const directoryRecordLength = CENTRAL_FILE_HEADER_LENGTH + getLength(rawFilename, rawComment) + extraFieldLength;
6152
- if (offset + directoryRecordLength - directoryDiskOffset > writer.availableSize) {
6394
+ if (exceedsAvailableSize(writer, offset + directoryRecordLength - directoryDiskOffset)) {
6153
6395
  await writeData(writer, directoryArray.slice(directoryDiskOffset, offset));
6154
6396
  directoryDiskOffset = offset;
6155
- writer.availableSize = 0;
6156
- await writeData(writer, EMPTY_UINT8_ARRAY);
6397
+ await writer.closeDisk();
6157
6398
  }
6158
6399
  if (indexFileEntry == 0) {
6159
- cdStartDiskNumber = writer.diskNumber;
6160
- cdStartDiskOffset = writer.diskOffset;
6400
+ directoryStartDiskNumber = getDiskNumber(writer);
6401
+ directoryStartDiskOffset = getDiskOffset(writer);
6161
6402
  }
6162
6403
  if (!zip64UncompressedSize) {
6163
6404
  setUint32(headerView, HEADER_OFFSET_UNCOMPRESSED_SIZE, uncompressedSize);
@@ -6197,18 +6438,18 @@
6197
6438
  }
6198
6439
  }
6199
6440
  await writeData(writer, directoryDiskOffset ? directoryArray.slice(directoryDiskOffset) : directoryArray);
6200
- return { cdStartDiskNumber, cdStartDiskOffset };
6441
+ return { diskNumber: directoryStartDiskNumber, diskOffset: directoryStartDiskOffset };
6201
6442
  }
6202
6443
 
6203
6444
  async function writeEndOfDirectoryRecord(zipWriter, comment, options, cdInfo) {
6204
6445
  const { writer } = zipWriter;
6205
- const { cdStartDiskNumber, cdStartDiskOffset } = cdInfo;
6446
+ const { directoryStart } = cdInfo;
6206
6447
  let { directoryDataLength } = cdInfo;
6207
6448
  let filesLength = zipWriter.files.size;
6208
- let diskNumber = cdStartDiskNumber;
6209
- let directoryOffset = zipWriter.offset - cdStartDiskOffset - (cdStartDiskNumber ? zipWriter.initialOffset : 0);
6210
- let lastDiskNumber = writer.diskNumber;
6211
- if (writer.availableSize < END_OF_CENTRAL_DIR_LENGTH) {
6449
+ let diskNumber = directoryStart.diskNumber;
6450
+ let directoryOffset = getSegmentOffset(zipWriter, directoryStart);
6451
+ let lastDiskNumber = getDiskNumber(writer);
6452
+ if (exceedsAvailableSize(writer, END_OF_CENTRAL_DIR_LENGTH)) {
6212
6453
  lastDiskNumber++;
6213
6454
  }
6214
6455
  let zip64 = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIP64);
@@ -6224,11 +6465,10 @@
6224
6465
  throw new Error(ERR_INVALID_COMMENT);
6225
6466
  }
6226
6467
  const endOfdirectoryRecord = createRecordWriter(zip64 ? ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH : END_OF_CENTRAL_DIR_LENGTH);
6227
- if (getLength(endOfdirectoryRecord.array) + commentLength > writer.availableSize) {
6228
- writer.availableSize = 0;
6229
- await writeData(writer, EMPTY_UINT8_ARRAY);
6468
+ if (exceedsAvailableSize(writer, getLength(endOfdirectoryRecord.array) + commentLength)) {
6469
+ await writer.closeDisk();
6230
6470
  }
6231
- lastDiskNumber = writer.diskNumber;
6471
+ lastDiskNumber = getDiskNumber(writer);
6232
6472
  if (zip64) {
6233
6473
  endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_SIGNATURE);
6234
6474
  endOfdirectoryRecord.uint64(44);
@@ -6242,7 +6482,7 @@
6242
6482
  endOfdirectoryRecord.uint64(directoryOffset);
6243
6483
  endOfdirectoryRecord.uint32(ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIGNATURE);
6244
6484
  endOfdirectoryRecord.uint32(lastDiskNumber);
6245
- endOfdirectoryRecord.uint64(BigInt(zipWriter.offset) + BigInt(directoryDataLength) - BigInt(writer.diskOffset) - BigInt(writer.diskNumber ? zipWriter.initialOffset : 0));
6485
+ endOfdirectoryRecord.uint64(BigInt(getSegmentOffset(zipWriter, writer)) + BigInt(directoryDataLength));
6246
6486
  endOfdirectoryRecord.uint32(lastDiskNumber + 1);
6247
6487
  const supportZip64SplitFile = getOptionValue(zipWriter, options, OPTION_SUPPORT_ZIP64_SPLIT_FILE, true);
6248
6488
  if (supportZip64SplitFile) {
@@ -6282,8 +6522,23 @@
6282
6522
  };
6283
6523
  }
6284
6524
 
6285
- function getSegmentOffset(zipWriter, writer) {
6286
- return zipWriter.offset - writer.diskOffset - (writer.diskNumber ? zipWriter.initialOffset : 0);
6525
+ function getDiskNumber(writer) {
6526
+ const { diskNumber = 0 } = writer;
6527
+ return diskNumber;
6528
+ }
6529
+
6530
+ function getDiskOffset(writer) {
6531
+ const { diskOffset = 0 } = writer;
6532
+ return diskOffset;
6533
+ }
6534
+
6535
+ function exceedsAvailableSize(writer, length) {
6536
+ const { availableSize = INFINITY_VALUE } = writer;
6537
+ return length > availableSize;
6538
+ }
6539
+
6540
+ function getSegmentOffset(zipWriter, { diskNumber = 0, diskOffset = 0 }) {
6541
+ return zipWriter.offset - diskOffset - (diskNumber ? zipWriter.initialOffset : 0);
6287
6542
  }
6288
6543
 
6289
6544
  async function writeData(writer, array) {
@@ -6360,9 +6615,6 @@
6360
6615
  array.set(typedArray, offset);
6361
6616
  }
6362
6617
 
6363
- function getDataView(array) {
6364
- return new DataView(array.buffer, array.byteOffset, array.byteLength);
6365
- }
6366
6618
 
6367
6619
  function getLength(...arrayLikes) {
6368
6620
  let result = 0;
@@ -6620,9 +6872,7 @@
6620
6872
 
6621
6873
  async getArrayBuffer(options) {
6622
6874
  const array = await this.getUint8Array(options);
6623
- return array.byteOffset || array.byteLength != array.buffer.byteLength
6624
- ? array.buffer.slice(array.byteOffset, array.byteOffset + array.byteLength)
6625
- : array.buffer;
6875
+ return toExactUint8Array(array).buffer;
6626
6876
  }
6627
6877
 
6628
6878
  replaceBlob(blob) {