@zip.js/zip.js 2.16.0 → 2.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/deno.json +1 -1
  2. package/dist/zip-core-external.js +429 -274
  3. package/dist/zip-core-external.min.js +1 -1
  4. package/dist/zip-core.js +230 -151
  5. package/dist/zip-core.min.js +1 -1
  6. package/dist/zip-fs-core-external.js +580 -283
  7. package/dist/zip-fs-core-external.min.js +1 -1
  8. package/dist/zip-fs-core.js +383 -160
  9. package/dist/zip-fs-core.min.js +1 -1
  10. package/dist/zip-fs-external.js +580 -283
  11. package/dist/zip-fs-external.min.js +1 -1
  12. package/dist/zip-fs-native.js +386 -163
  13. package/dist/zip-fs-native.min.js +1 -1
  14. package/dist/zip-fs.js +583 -283
  15. package/dist/zip-fs.min.js +1 -1
  16. package/dist/zip-legacy.js +232 -153
  17. package/dist/zip-legacy.min.js +1 -1
  18. package/dist/zip-native.js +233 -154
  19. package/dist/zip-native.min.js +1 -1
  20. package/dist/zip-web-worker-native.js +1 -1
  21. package/dist/zip-web-worker.js +1 -1
  22. package/dist/zip.js +430 -274
  23. package/dist/zip.min.js +1 -1
  24. package/eslint.config.mjs +1 -1
  25. package/index-native.cjs +386 -163
  26. package/index-native.min.js +1 -1
  27. package/index.cjs +583 -283
  28. package/index.d.cts +168 -29
  29. package/index.d.ts +168 -29
  30. package/index.min.js +1 -1
  31. package/lib/core/codec-pool.js +2 -0
  32. package/lib/core/codec-worker-web.js +11 -3
  33. package/lib/core/codec-worker.js +2 -1
  34. package/lib/core/streams/aes-crypto-stream.js +60 -17
  35. package/lib/core/streams/codec-stream.js +2 -0
  36. package/lib/core/streams/zip-crypto-stream.js +7 -7
  37. package/lib/core/streams/zip-entry-stream.js +130 -113
  38. package/lib/core/streams/zlib-js/zlib-streams.min.js +1 -1
  39. package/lib/core/streams/zlib-wasm/zlib-streams.js +199 -122
  40. package/lib/core/util/compatible-streams.js +10 -5
  41. package/lib/core/version.js +1 -1
  42. package/lib/core/web-worker-base.js +1 -1
  43. package/lib/core/web-worker-inline-native.js +1 -1
  44. package/lib/core/web-worker-inline-wasm.js +1 -1
  45. package/lib/core/zip-fs.js +157 -10
  46. package/lib/core/zip-reader.js +8 -5
  47. package/lib/core/zip-writer.js +5 -2
  48. package/lib/zip-core-reader.js +1 -0
  49. package/package.json +3 -2
@@ -1310,12 +1310,12 @@ let createEngine$1 = createEngine$2;
1310
1310
  class AESDecryptionStream extends TransformStream {
1311
1311
 
1312
1312
  constructor({ password, rawPassword, encryptionStrength, checkPasswordOnly, checkAuthenticationCode = true }) {
1313
+ const aesCrypto = {};
1313
1314
  super({
1314
1315
  start() {
1315
- initAesCrypto(this, password, rawPassword, encryptionStrength);
1316
+ initAesCrypto(aesCrypto, password, rawPassword, encryptionStrength);
1316
1317
  },
1317
1318
  async transform(chunk, controller) {
1318
- const aesCrypto = this;
1319
1319
  const {
1320
1320
  password,
1321
1321
  strength,
@@ -1334,6 +1334,9 @@ class AESDecryptionStream extends TransformStream {
1334
1334
  } else {
1335
1335
  await ready;
1336
1336
  }
1337
+ if (aesCrypto.discarded) {
1338
+ return;
1339
+ }
1337
1340
  const output = new Uint8Array(chunk.length - AUTHENTICATION_CODE_LENGTH - ((chunk.length - AUTHENTICATION_CODE_LENGTH) % BLOCK_LENGTH));
1338
1341
  controller.enqueue(append(aesCrypto, chunk, output, 0, AUTHENTICATION_CODE_LENGTH, true));
1339
1342
  },
@@ -1342,9 +1345,12 @@ class AESDecryptionStream extends TransformStream {
1342
1345
  engine,
1343
1346
  pendingInput,
1344
1347
  ready
1345
- } = this;
1348
+ } = aesCrypto;
1346
1349
  if (engine) {
1347
1350
  await ready;
1351
+ if (aesCrypto.discarded) {
1352
+ return;
1353
+ }
1348
1354
  const originalAuthenticationCode = subarray(pendingInput, pendingInput.length - AUTHENTICATION_CODE_LENGTH);
1349
1355
  const decryptedChunkArray = new Uint8Array(subarray(pendingInput, 0, pendingInput.length - AUTHENTICATION_CODE_LENGTH));
1350
1356
  engine.process(decryptedChunkArray, true);
@@ -1354,27 +1360,26 @@ class AESDecryptionStream extends TransformStream {
1354
1360
  invalidAuthenticationCode |= authenticationCode[indexByte] ^ originalAuthenticationCode[indexByte];
1355
1361
  }
1356
1362
  if (invalidAuthenticationCode && checkAuthenticationCode) {
1357
- throw new Error(ERR_INVALID_AUTHENTICATION_CODE);
1363
+ controller.error(new Error(ERR_INVALID_AUTHENTICATION_CODE));
1364
+ return;
1358
1365
  }
1359
1366
  controller.enqueue(decryptedChunkArray);
1360
1367
  }
1361
- },
1362
- cancel() {
1363
- disposeEngine(this);
1364
1368
  }
1365
1369
  });
1370
+ setDisposingReadable(this, aesCrypto);
1366
1371
  }
1367
1372
  }
1368
1373
 
1369
1374
  class AESEncryptionStream extends TransformStream {
1370
1375
 
1371
1376
  constructor({ password, rawPassword, encryptionStrength }) {
1377
+ const aesCrypto = {};
1372
1378
  super({
1373
1379
  start() {
1374
- initAesCrypto(this, password, rawPassword, encryptionStrength);
1380
+ initAesCrypto(aesCrypto, password, rawPassword, encryptionStrength);
1375
1381
  },
1376
1382
  async transform(chunk, controller) {
1377
- const aesCrypto = this;
1378
1383
  const {
1379
1384
  password,
1380
1385
  strength,
@@ -1388,6 +1393,9 @@ class AESEncryptionStream extends TransformStream {
1388
1393
  } else {
1389
1394
  await ready;
1390
1395
  }
1396
+ if (aesCrypto.discarded) {
1397
+ return;
1398
+ }
1391
1399
  const output = new Uint8Array(preamble.length + chunk.length - (chunk.length % BLOCK_LENGTH));
1392
1400
  output.set(preamble, 0);
1393
1401
  controller.enqueue(append(aesCrypto, chunk, output, preamble.length, 0, false));
@@ -1397,19 +1405,20 @@ class AESEncryptionStream extends TransformStream {
1397
1405
  engine,
1398
1406
  pendingInput,
1399
1407
  ready
1400
- } = this;
1408
+ } = aesCrypto;
1401
1409
  if (engine) {
1402
1410
  await ready;
1411
+ if (aesCrypto.discarded) {
1412
+ return;
1413
+ }
1403
1414
  const encryptedChunkArray = new Uint8Array(pendingInput);
1404
1415
  engine.process(encryptedChunkArray, false);
1405
1416
  const authenticationCode = subarray(engine.digest(), 0, AUTHENTICATION_CODE_LENGTH);
1406
1417
  controller.enqueue(concat(encryptedChunkArray, authenticationCode));
1407
1418
  }
1408
- },
1409
- cancel() {
1410
- disposeEngine(this);
1411
1419
  }
1412
1420
  });
1421
+ setDisposingReadable(this, aesCrypto);
1413
1422
  }
1414
1423
  }
1415
1424
 
@@ -1422,7 +1431,37 @@ function initAesCrypto(aesCrypto, password, rawPassword, encryptionStrength) {
1422
1431
  ready: new Promise(resolve => aesCrypto.resolveReady = resolve),
1423
1432
  password: encodePassword(password, rawPassword),
1424
1433
  strength: encryptionStrength - 1,
1425
- pendingInput: EMPTY_UINT8_ARRAY
1434
+ pendingInput: EMPTY_UINT8_ARRAY,
1435
+ discarded: false
1436
+ });
1437
+ }
1438
+
1439
+ function setDisposingReadable(stream, aesCrypto) {
1440
+ const reader = stream.readable.getReader();
1441
+ const readable = new ReadableStream({
1442
+ async pull(controller) {
1443
+ try {
1444
+ const { value, done } = await reader.read();
1445
+ if (done) {
1446
+ controller.close();
1447
+ } else {
1448
+ controller.enqueue(value);
1449
+ }
1450
+ } catch (error) {
1451
+ disposeEngine(aesCrypto);
1452
+ reader.cancel(error).catch(() => { });
1453
+ throw error;
1454
+ }
1455
+ },
1456
+ cancel(reason) {
1457
+ disposeEngine(aesCrypto);
1458
+ return reader.cancel(reason);
1459
+ }
1460
+ });
1461
+ Object.defineProperty(stream, "readable", {
1462
+ get() {
1463
+ return readable;
1464
+ }
1426
1465
  });
1427
1466
  }
1428
1467
 
@@ -1455,7 +1494,9 @@ async function createDecryptionKeys(decrypt, strength, password, preamble) {
1455
1494
  }
1456
1495
  }
1457
1496
 
1458
- function disposeEngine({ engine }) {
1497
+ function disposeEngine(aesCrypto) {
1498
+ const { engine } = aesCrypto;
1499
+ aesCrypto.discarded = true;
1459
1500
  if (engine && engine.dispose) {
1460
1501
  engine.dispose();
1461
1502
  }
@@ -1472,6 +1513,9 @@ async function createKeys$1(aesCrypto, strength, password, salt) {
1472
1513
  const keyLength = KEY_LENGTH[strength];
1473
1514
  const compositeKey = await deriveKey(password, salt, keyLength * 2 + PASSWORD_VERIFICATION_LENGTH);
1474
1515
  aesCrypto.engine = createEngine$1(subarray(compositeKey, 0, keyLength), subarray(compositeKey, keyLength, keyLength * 2));
1516
+ if (aesCrypto.discarded) {
1517
+ disposeEngine(aesCrypto);
1518
+ }
1475
1519
  return subarray(compositeKey, keyLength * 2);
1476
1520
  }
1477
1521
 
@@ -1623,11 +1667,11 @@ function encrypt(target, input) {
1623
1667
  }
1624
1668
 
1625
1669
  function createKeys(target, password, rawPassword) {
1626
- const keys = [0x12345678, 0x23456789, 0x34567890];
1670
+ const cryptoKeys = [0x12345678, 0x23456789, 0x34567890];
1627
1671
  Object.assign(target, {
1628
- keys,
1629
- crcKey0: new Crc32(keys[0]),
1630
- crcKey2: new Crc32(keys[2])
1672
+ cryptoKeys,
1673
+ crcKey0: new Crc32(cryptoKeys[0]),
1674
+ crcKey2: new Crc32(cryptoKeys[2])
1631
1675
  });
1632
1676
  if (rawPassword) {
1633
1677
  for (let index = 0; index < rawPassword.length; index++) {
@@ -1641,17 +1685,17 @@ function createKeys(target, password, rawPassword) {
1641
1685
  }
1642
1686
 
1643
1687
  function updateKeys(target, byte) {
1644
- let [, key1] = target.keys;
1688
+ let [, key1] = target.cryptoKeys;
1645
1689
  target.crcKey0.append([byte]);
1646
1690
  const key0 = ~target.crcKey0.get();
1647
1691
  key1 = getInt32(Math.imul(getInt32(key1 + getInt8(key0)), 134775813) + 1);
1648
1692
  target.crcKey2.append([key1 >>> 24]);
1649
1693
  const key2 = ~target.crcKey2.get();
1650
- target.keys = [key0, key1, key2];
1694
+ target.cryptoKeys = [key0, key1, key2];
1651
1695
  }
1652
1696
 
1653
1697
  function getByte(target) {
1654
- const temp = target.keys[2] | 2;
1698
+ const temp = target.cryptoKeys[2] | 2;
1655
1699
  return getInt8(Math.imul(temp, (temp ^ 1)) >>> 8);
1656
1700
  }
1657
1701
 
@@ -1699,11 +1743,16 @@ function toCompatibleReadable(readable) {
1699
1743
  const reader = readable.getReader();
1700
1744
  return new ReadableStream({
1701
1745
  async pull(controller) {
1702
- const { value, done } = await reader.read();
1703
- if (done) {
1704
- controller.close();
1705
- } else {
1706
- controller.enqueue(value);
1746
+ try {
1747
+ const { value, done } = await reader.read();
1748
+ if (done) {
1749
+ controller.close();
1750
+ } else {
1751
+ controller.enqueue(value);
1752
+ }
1753
+ } catch (error) {
1754
+ reader.cancel(error).catch(() => { });
1755
+ throw error;
1707
1756
  }
1708
1757
  },
1709
1758
  cancel(reason) {
@@ -1882,7 +1931,9 @@ async function ensureCodecStreams(format, codecURI) {
1882
1931
 
1883
1932
  const ERR_INVALID_UNCOMPRESSED_SIZE = "Invalid uncompressed size";
1884
1933
  const ERR_INVALID_COMPRESSED_DATA = "Invalid compressed data";
1934
+ const ERR_CODEC_OUT_OF_MEMORY = "Codec out of memory";
1885
1935
  const ERR_INVALID_CRC32 = "Invalid CRC32";
1936
+ const Z_MEM_ERROR_CODE$1 = "Z_MEM_ERROR";
1886
1937
  const FORMAT_DEFLATE_RAW$1 = "deflate-raw";
1887
1938
  const FORMAT_DEFLATE64_RAW$1 = "deflate64-raw";
1888
1939
  const FORMAT_GZIP$1 = "gzip";
@@ -1917,13 +1968,13 @@ class DeflateStream extends TransformStream {
1917
1968
  readable = pipeThroughCompressionStream(readable, useCompressionStream, { level, chunkSize }, CompressionStream, CompressionStreamFallback);
1918
1969
  } catch (error) {
1919
1970
  if (!useCompressionStream && CompressionStreamFallback) {
1920
- throw error;
1971
+ throw mapMemoryError(error);
1921
1972
  }
1922
1973
  let gzipStream;
1923
1974
  try {
1924
1975
  gzipStream = new CompressionStream(FORMAT_GZIP$1);
1925
1976
  } catch {
1926
- throw error;
1977
+ throw mapMemoryError(error);
1927
1978
  }
1928
1979
  readable = pipeThroughBackpressured(readable, gzipStream);
1929
1980
  readable = pipeThrough(readable, new GzipToRawDeflateStream());
@@ -1987,53 +2038,30 @@ class GzipToRawDeflateStream extends TransformStream {
1987
2038
  }
1988
2039
  }
1989
2040
 
1990
- function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32) {
2041
+ function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32, sourceErrors) {
1991
2042
  const writer = gzipStream.writable.getWriter();
1992
2043
  const reader = gzipStream.readable.getReader();
1993
2044
  const outputCrc32 = crc32 === UNDEFINED_VALUE ? new Crc32() : UNDEFINED_VALUE;
1994
2045
  let outputLength = 0;
1995
- let inputDone = false;
1996
2046
  let trailerWritten = false;
1997
- let idleCheckArmed = false;
1998
- let readCount = 0;
1999
- let readPending = false;
2000
- let resolveTrailerReady, rejectTrailerReady;
2001
- const trailerReady = new Promise((resolve, reject) => {
2002
- resolveTrailerReady = resolve;
2003
- rejectTrailerReady = reject;
2004
- });
2005
- trailerReady.catch(() => { });
2006
- pump();
2007
- return new ReadableStream({
2008
- async pull(controller) {
2009
- let result;
2010
- try {
2011
- result = await read();
2012
- } catch (error) {
2013
- throw trailerWritten ? getTrailerError(error) : error;
2014
- }
2015
- const { value, done } = result;
2016
- if (done) {
2017
- controller.close();
2018
- } else {
2019
- outputLength += value.length;
2020
- if (outputLength > outputSize) {
2021
- const error = new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
2022
- rejectTrailerReady(error);
2023
- await cancel(reader, error);
2024
- throw error;
2025
- }
2026
- if (outputCrc32) {
2027
- outputCrc32.append(value);
2028
- }
2029
- controller.enqueue(value);
2030
- }
2047
+ let settled = false;
2048
+ let resolvePull, controller;
2049
+ const output = new ReadableStream({
2050
+ start(streamController) {
2051
+ controller = streamController;
2052
+ },
2053
+ pull() {
2054
+ resumePump();
2031
2055
  },
2032
2056
  cancel(reason) {
2033
- rejectTrailerReady(reason);
2057
+ settled = true;
2058
+ resumePump();
2034
2059
  return reader.cancel(reason);
2035
2060
  }
2036
2061
  });
2062
+ pump();
2063
+ drain();
2064
+ return output;
2037
2065
 
2038
2066
  async function pump() {
2039
2067
  const inputReader = readable.getReader();
@@ -2042,19 +2070,16 @@ function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, cr
2042
2070
  header.set(GZIP_HEADER_BYTES);
2043
2071
  await writer.write(header);
2044
2072
  for (; ;) {
2073
+ await outputCapacity();
2045
2074
  await writer.ready;
2046
- const { value, done } = await inputReader.read();
2075
+ const { value, done } = await readSource(inputReader, sourceErrors);
2047
2076
  if (done) {
2048
2077
  break;
2049
2078
  }
2050
2079
  await writer.write(value);
2051
2080
  }
2052
- inputDone = true;
2053
2081
  if (outputCrc32) {
2054
- if (readPending) {
2055
- armIdleCheck();
2056
- }
2057
- await trailerReady;
2082
+ await writer.write(new Uint8Array(0));
2058
2083
  }
2059
2084
  const trailer = new Uint8Array(GZIP_TRAILER_LENGTH);
2060
2085
  const dataView = getDataView(trailer);
@@ -2069,54 +2094,68 @@ function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, cr
2069
2094
  }
2070
2095
  }
2071
2096
 
2072
- function read() {
2073
- readCount++;
2074
- readPending = true;
2075
- const result = reader.read();
2076
- result.then(onReadSettled, onReadSettled);
2077
- if (inputDone && outputCrc32) {
2078
- armIdleCheck();
2097
+ async function drain() {
2098
+ try {
2099
+ for (; ;) {
2100
+ const { value, done } = await read();
2101
+ if (done) {
2102
+ break;
2103
+ }
2104
+ outputLength += value.length;
2105
+ if (outputLength > outputSize) {
2106
+ throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
2107
+ }
2108
+ if (outputCrc32) {
2109
+ outputCrc32.append(value);
2110
+ }
2111
+ controller.enqueue(value);
2112
+ }
2113
+ if (!settled) {
2114
+ settled = true;
2115
+ controller.close();
2116
+ }
2117
+ } catch (error) {
2118
+ fail(error);
2119
+ await cancel(reader, error);
2079
2120
  }
2080
- return result;
2081
2121
  }
2082
2122
 
2083
- function onReadSettled() {
2084
- readPending = false;
2085
- }
2086
-
2087
- async function armIdleCheck() {
2088
- if (!idleCheckArmed) {
2089
- idleCheckArmed = true;
2090
- const count = readCount;
2091
- await nextTask();
2092
- idleCheckArmed = false;
2093
- if (readPending) {
2094
- if (readCount == count) {
2095
- resolveTrailerReady();
2096
- } else {
2097
- armIdleCheck();
2123
+ function read() {
2124
+ return reader.read().catch(error => {
2125
+ if (trailerWritten) {
2126
+ if (!outputCrc32) {
2127
+ throw mapError(error, ERR_INVALID_CRC32);
2128
+ }
2129
+ if (outputLength != outputSize) {
2130
+ throw mapError(error, ERR_INVALID_UNCOMPRESSED_SIZE);
2098
2131
  }
2132
+ return { done: true };
2099
2133
  }
2100
- }
2134
+ throw mapCodecError(error, sourceErrors);
2135
+ });
2101
2136
  }
2102
2137
 
2103
- function getTrailerError(error) {
2104
- const trailerError = new Error(outputLength == outputSize ? ERR_INVALID_CRC32 : ERR_INVALID_UNCOMPRESSED_SIZE);
2105
- trailerError.cause = error;
2106
- return trailerError;
2138
+ function outputCapacity() {
2139
+ if (!settled && controller.desiredSize <= 0) {
2140
+ return new Promise(resolve => resolvePull = resolve);
2141
+ }
2107
2142
  }
2108
- }
2109
2143
 
2110
- function nextTask() {
2111
- return new Promise(resolve => {
2112
- const { port1, port2 } = new MessageChannel();
2113
- port2.onmessage = () => {
2114
- port1.close();
2115
- port2.close();
2144
+ function resumePump() {
2145
+ if (resolvePull) {
2146
+ const resolve = resolvePull;
2147
+ resolvePull = UNDEFINED_VALUE;
2116
2148
  resolve();
2117
- };
2118
- port1.postMessage(UNDEFINED_VALUE);
2119
- });
2149
+ }
2150
+ }
2151
+
2152
+ function fail(error) {
2153
+ if (!settled) {
2154
+ settled = true;
2155
+ controller.error(error);
2156
+ resumePump();
2157
+ }
2158
+ }
2120
2159
  }
2121
2160
 
2122
2161
  class InflateStream extends TransformStream {
@@ -2135,11 +2174,12 @@ class InflateStream extends TransformStream {
2135
2174
  }
2136
2175
  }
2137
2176
  if (compressed) {
2177
+ const sourceErrors = new Set();
2138
2178
  const codecStreams = format && getCodecStreams(format);
2179
+ let gzipStream;
2139
2180
  if (codecStreams) {
2140
- readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.DecompressionStream, format, { chunkSize, compressionMethod, rawBitFlag, uncompressedSize: outputSize }));
2181
+ readable = pipeThroughBackpressured(readable, createCodecStream(codecStreams.DecompressionStream, format, { chunkSize, compressionMethod, rawBitFlag, uncompressedSize: outputSize }), sourceErrors);
2141
2182
  } else {
2142
- let gzipStream;
2143
2183
  const GzipDecompressionStream = getGzipCodecStream(useCompressionStream, DecompressionStream, DecompressionStreamFallback);
2144
2184
  if (checkCrc32 && !deflate64 && crc32 !== UNDEFINED_VALUE && outputSize !== UNDEFINED_VALUE && GzipDecompressionStream) {
2145
2185
  try {
@@ -2150,24 +2190,25 @@ class InflateStream extends TransformStream {
2150
2190
  }
2151
2191
  if (!gzipStream) {
2152
2192
  try {
2153
- readable = pipeThroughCompressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream, DecompressionStreamFallback);
2193
+ readable = pipeThroughCompressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream, DecompressionStreamFallback, sourceErrors);
2154
2194
  } catch (error) {
2155
2195
  if (deflate64 || outputSize === UNDEFINED_VALUE || (!useCompressionStream && DecompressionStreamFallback)) {
2156
- throw error;
2196
+ throw mapMemoryError(error);
2157
2197
  }
2158
2198
  try {
2159
2199
  gzipStream = new DecompressionStream(FORMAT_GZIP$1);
2160
2200
  } catch {
2161
- throw error;
2201
+ throw mapMemoryError(error);
2162
2202
  }
2163
2203
  }
2164
2204
  }
2165
- if (gzipStream) {
2166
- gzipCrc32 = true;
2167
- readable = pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32);
2168
- }
2169
2205
  }
2170
- readable = mapInflateStreamError(readable);
2206
+ if (gzipStream) {
2207
+ gzipCrc32 = true;
2208
+ readable = pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32, sourceErrors);
2209
+ } else {
2210
+ readable = mapInflateStreamError(readable, sourceErrors);
2211
+ }
2171
2212
  }
2172
2213
  if (checkCrc32 && !gzipCrc32) {
2173
2214
  crc32Stream = new Crc32Stream();
@@ -2240,7 +2281,7 @@ function getGzipCodecStream(useCompressionStream, CodecStreamNative, CodecStream
2240
2281
  }
2241
2282
  }
2242
2283
 
2243
- function pipeThroughCompressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamFallback) {
2284
+ function pipeThroughCompressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamFallback, sourceErrors) {
2244
2285
  const Stream = useCompressionStream && CompressionStreamNative ?
2245
2286
  CompressionStreamNative :
2246
2287
  CompressionStreamFallback || CompressionStreamNative;
@@ -2255,14 +2296,14 @@ function pipeThroughCompressionStream(readable, useCompressionStream, options, C
2255
2296
  throw error;
2256
2297
  }
2257
2298
  }
2258
- return pipeThroughBackpressured(readable, codecStream);
2299
+ return pipeThroughBackpressured(readable, codecStream, sourceErrors);
2259
2300
  }
2260
2301
 
2261
2302
  function pipeThrough(readable, transformStream) {
2262
2303
  return toCompatibleReadable(readable).pipeThrough(transformStream);
2263
2304
  }
2264
2305
 
2265
- function pipeThroughBackpressured(readable, transformStream) {
2306
+ function pipeThroughBackpressured(readable, transformStream, sourceErrors) {
2266
2307
  const writer = transformStream.writable.getWriter();
2267
2308
  const reader = readable.getReader();
2268
2309
  pump();
@@ -2272,7 +2313,7 @@ function pipeThroughBackpressured(readable, transformStream) {
2272
2313
  try {
2273
2314
  for (; ;) {
2274
2315
  await writer.ready;
2275
- const result = await reader.read();
2316
+ const result = await readSource(reader, sourceErrors);
2276
2317
  if (result.done) {
2277
2318
  await writer.close();
2278
2319
  break;
@@ -2302,26 +2343,49 @@ async function cancel(reader, error) {
2302
2343
  }
2303
2344
  }
2304
2345
 
2305
- function mapInflateStreamError(readable) {
2346
+ function readSource(reader, sourceErrors) {
2347
+ const result = reader.read();
2348
+ return sourceErrors ? result.catch(error => {
2349
+ sourceErrors.add(error);
2350
+ throw error;
2351
+ }) : result;
2352
+ }
2353
+
2354
+ function mapCodecError(error, sourceErrors) {
2355
+ if (sourceErrors.has(error)) {
2356
+ return error;
2357
+ }
2358
+ return mapError(error, isMemoryError(error) ? ERR_CODEC_OUT_OF_MEMORY : ERR_INVALID_COMPRESSED_DATA);
2359
+ }
2360
+
2361
+ function mapMemoryError(error) {
2362
+ return isMemoryError(error) ? mapError(error, ERR_CODEC_OUT_OF_MEMORY) : error;
2363
+ }
2364
+
2365
+ function isMemoryError(error) {
2366
+ return isErrorObject(error) && error.code == Z_MEM_ERROR_CODE$1;
2367
+ }
2368
+
2369
+ function mapError(error, message) {
2370
+ const mappedError = new Error(message);
2371
+ mappedError.cause = error;
2372
+ return mappedError;
2373
+ }
2374
+
2375
+ function mapInflateStreamError(readable, sourceErrors) {
2306
2376
  const reader = readable.getReader();
2307
2377
  return new ReadableStream({
2308
2378
  async pull(controller) {
2309
- let result;
2310
2379
  try {
2311
- result = await reader.read();
2312
- } catch (error) {
2313
- if (error && error.message) {
2314
- throw error;
2380
+ const { value, done } = await reader.read();
2381
+ if (done) {
2382
+ controller.close();
2383
+ } else {
2384
+ controller.enqueue(value);
2315
2385
  }
2316
- const mappedError = new Error(ERR_INVALID_COMPRESSED_DATA);
2317
- mappedError.cause = error;
2318
- throw mappedError;
2319
- }
2320
- const { value, done } = result;
2321
- if (done) {
2322
- controller.close();
2323
- } else {
2324
- controller.enqueue(value);
2386
+ } catch (error) {
2387
+ await cancel(reader, error);
2388
+ throw mapCodecError(error, sourceErrors);
2325
2389
  }
2326
2390
  },
2327
2391
  cancel(reason) {
@@ -2689,10 +2753,11 @@ async function runWorker$1({ options, readable, writable, onTaskFinished, worker
2689
2753
  }
2690
2754
  codecStream = new CodecStream(options, config);
2691
2755
  chunkStream = new ChunkStream(getChunkSize(config));
2756
+ const { signal } = workerOptions.streamOptions;
2692
2757
  await readable
2693
2758
  .pipeThrough(codecStream)
2694
2759
  .pipeThrough(chunkStream)
2695
- .pipeTo(writable, { preventClose: true, preventAbort: true });
2760
+ .pipeTo(writable, { preventClose: true, preventAbort: true, signal });
2696
2761
  const {
2697
2762
  crc32,
2698
2763
  inputSize,
@@ -2760,6 +2825,7 @@ async function runWorker$1({ options, readable, writable, onTaskFinished, worker
2760
2825
  const MODULE_WORKER_OPTIONS = { type: "module" };
2761
2826
  const ERROR_EVENT_TYPE = "error";
2762
2827
  const MESSAGE_ERROR_EVENT_TYPE = "messageerror";
2828
+ const ABORT_EVENT_TYPE = "abort";
2763
2829
 
2764
2830
  let webWorkerSource, webWorkerURI, webWorkerOptions;
2765
2831
  let transferStreamsSupported = true;
@@ -2936,6 +3002,13 @@ function watchClosedStream(writableSource, workerData) {
2936
3002
  Object.assign(workerData, { destinationFailed: true, destinationError: error });
2937
3003
  }
2938
3004
  });
3005
+ const { signal } = workerData.workerOptions.streamOptions;
3006
+ if (signal) {
3007
+ const onAbort = () => abortController.abort(signal.reason);
3008
+ const removeAbortListener = () => signal.removeEventListener(ABORT_EVENT_TYPE, onAbort);
3009
+ signal.addEventListener(ABORT_EVENT_TYPE, onAbort);
3010
+ closed.then(removeAbortListener, removeAbortListener);
3011
+ }
2939
3012
  return {
2940
3013
  writable, closed, abortPipe: () => {
2941
3014
  aborting = true;
@@ -3198,9 +3271,6 @@ function getResponseError(errorData, errorValue) {
3198
3271
  responseError = errorValue.value;
3199
3272
  } else {
3200
3273
  responseError = Object.assign(new Error(message), { stack, code, name });
3201
- if (cause) {
3202
- responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
3203
- }
3204
3274
  }
3205
3275
  if (isErrorObject(responseError)) {
3206
3276
  try {
@@ -3210,6 +3280,9 @@ function getResponseError(errorData, errorValue) {
3210
3280
  if (codecImportFailed) {
3211
3281
  responseError.codecImportFailed = true;
3212
3282
  }
3283
+ if (cause && !isErrorObject(responseError.cause)) {
3284
+ responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
3285
+ }
3213
3286
  if (errorValue) {
3214
3287
  if (responseError.name !== name) {
3215
3288
  responseError.name = name;
@@ -5381,8 +5454,8 @@ class ZipEntry {
5381
5454
  const passThroughCompression = Boolean(passThrough);
5382
5455
  const passThroughEncryption = passThrough === true;
5383
5456
  checkPasswordOption(password, rawPassword);
5384
- password = password && password.length && password;
5385
- rawPassword = rawPassword && rawPassword.length && rawPassword;
5457
+ password = password && password.length ? password : UNDEFINED_VALUE;
5458
+ rawPassword = rawPassword && rawPassword.length ? rawPassword : UNDEFINED_VALUE;
5386
5459
  if (extraFieldAES) {
5387
5460
  if (extraFieldAES.originalCompressionMethod != COMPRESSION_METHOD_AES) {
5388
5461
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
@@ -5532,6 +5605,7 @@ class ZipEntry {
5532
5605
  ({ writable } = writer);
5533
5606
  const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
5534
5607
  const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
5608
+ throwIfAborted(signal);
5535
5609
  if (writtenSize != outputSize) {
5536
5610
  throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
5537
5611
  }
@@ -6143,7 +6217,7 @@ function getMaxAppendedDataSize(maxAppendedDataSize, strictness) {
6143
6217
  async function findEndOfCentralDirectory(reader, rejectAmbiguous, maxAppendedDataSize) {
6144
6218
  const { size } = reader;
6145
6219
  const anchoredLength = Math.min(size, END_OF_CENTRAL_DIR_LENGTH + MAX_16_BITS);
6146
- const remoteProbeBudget = { count: MAX_END_OF_CENTRAL_DIR_PROBES };
6220
+ const remoteProbeBudget = { remaining: MAX_END_OF_CENTRAL_DIR_PROBES };
6147
6221
  let endOfDirectoryInfo;
6148
6222
  let plausibleEndOfDirectoryInfo;
6149
6223
  let endOfDirectoryReachingEndCount = 0;
@@ -6236,8 +6310,8 @@ async function readSignature(reader, view, anchoredOffset, signatureOffset, size
6236
6310
  if (signatureOffset >= anchoredOffset) {
6237
6311
  return getUint32$1(view, signatureOffset - anchoredOffset);
6238
6312
  }
6239
- if (remoteProbeBudget.count > 0) {
6240
- remoteProbeBudget.count--;
6313
+ if (remoteProbeBudget.remaining > 0) {
6314
+ remoteProbeBudget.remaining--;
6241
6315
  const signatureArray = await readUint8Array(reader, signatureOffset, 4);
6242
6316
  return getUint32$1(getDataView(signatureArray), 0);
6243
6317
  }
@@ -6327,6 +6401,7 @@ var zipReader = /*#__PURE__*/Object.freeze({
6327
6401
  ERR_AMBIGUOUS_ARCHIVE: ERR_AMBIGUOUS_ARCHIVE,
6328
6402
  ERR_BAD_FORMAT: ERR_BAD_FORMAT,
6329
6403
  ERR_CENTRAL_DIRECTORY_NOT_FOUND: ERR_CENTRAL_DIRECTORY_NOT_FOUND,
6404
+ ERR_CODEC_OUT_OF_MEMORY: ERR_CODEC_OUT_OF_MEMORY,
6330
6405
  ERR_ENCRYPTED: ERR_ENCRYPTED,
6331
6406
  ERR_ENCRYPTED_CENTRAL_DIRECTORY: ERR_ENCRYPTED_CENTRAL_DIRECTORY,
6332
6407
  ERR_ENTRY_DATA_OUT_OF_BOUNDS: ERR_ENTRY_DATA_OUT_OF_BOUNDS,
@@ -7153,9 +7228,11 @@ function resolveMetadata(zipWriter, name, options) {
7153
7228
  const passThrough = checkPassThroughOption(getOptionValue(zipWriter, options, OPTION_PASS_THROUGH));
7154
7229
  const passThroughCompression = Boolean(passThrough);
7155
7230
  const passThroughEncryption = passThrough === true;
7156
- const password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
7157
- const rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
7231
+ let password = getOptionValue(zipWriter, options, OPTION_PASSWORD);
7232
+ let rawPassword = getOptionValue(zipWriter, options, OPTION_RAW_PASSWORD);
7158
7233
  checkPasswordOption(password, rawPassword);
7234
+ password = password && password.length ? password : UNDEFINED_VALUE;
7235
+ rawPassword = rawPassword && rawPassword.length ? rawPassword : UNDEFINED_VALUE;
7159
7236
  const encryptionStrength = getNumberOptionValue(zipWriter, options, OPTION_ENCRYPTION_STRENGTH, 3);
7160
7237
  const zipCrypto = getOptionValue(zipWriter, options, PROPERTY_NAME_ZIPCRYPTO);
7161
7238
  const extendedTimestamp = getOptionValue(zipWriter, options, OPTION_EXTENDED_TIMESTAMP, true);
@@ -7674,6 +7751,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7674
7751
  const result = await runWorker({ readable, writable }, workerOptions);
7675
7752
  compressedSize = result.outputSize;
7676
7753
  writer.size += compressedSize;
7754
+ throwIfAborted(signal);
7677
7755
  if (!passThroughCompression) {
7678
7756
  uncompressedSize = result.inputSize;
7679
7757
  if (!encrypted || zipCrypto) {
@@ -8853,7 +8931,7 @@ function formatSupported(StreamClass, format) {
8853
8931
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8854
8932
  */
8855
8933
 
8856
- const VERSION = "2.16.0";
8934
+ const VERSION = "2.17.0";
8857
8935
 
8858
8936
  /*
8859
8937
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
@@ -9330,12 +9408,16 @@ try {
9330
9408
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9331
9409
  */
9332
9410
 
9333
- /* global TransformStream */
9411
+ /* global ReadableStream, WritableStream */
9334
9412
 
9335
9413
  const FORMAT_DEFLATE = "deflate";
9336
9414
  const FORMAT_DEFLATE_RAW = "deflate-raw";
9337
9415
  const FORMAT_DEFLATE64_RAW = "deflate64-raw";
9338
9416
  const FORMAT_GZIP = "gzip";
9417
+ const Z_MEM_ERROR = -4;
9418
+ const Z_MEM_ERROR_CODE = "Z_MEM_ERROR";
9419
+ const COMPRESSION_FORMATS = [FORMAT_DEFLATE, FORMAT_DEFLATE_RAW, FORMAT_GZIP];
9420
+ const DECOMPRESSION_FORMATS = [FORMAT_DEFLATE, FORMAT_DEFLATE_RAW, FORMAT_GZIP, FORMAT_DEFLATE64_RAW];
9339
9421
 
9340
9422
  let wasm$1, malloc, free, memory, initError;
9341
9423
 
@@ -9356,7 +9438,17 @@ function resetWasmExports$1() {
9356
9438
  wasm$1 = malloc = free = memory = initError = null;
9357
9439
  }
9358
9440
 
9441
+ function setZlibCode(error, result) {
9442
+ if (result === Z_MEM_ERROR) {
9443
+ error.code = Z_MEM_ERROR_CODE;
9444
+ }
9445
+ return error;
9446
+ }
9447
+
9359
9448
  function _make(isCompress, type, options = {}) {
9449
+ if (!(isCompress ? COMPRESSION_FORMATS : DECOMPRESSION_FORMATS).includes(type)) {
9450
+ throw new TypeError("Unsupported format: " + type);
9451
+ }
9360
9452
  if (!wasm$1) {
9361
9453
  const error = new Error("WASM module not loaded");
9362
9454
  error.cause = initError;
@@ -9365,137 +9457,200 @@ function _make(isCompress, type, options = {}) {
9365
9457
  const level = (typeof options.level === "number") ? options.level : -1;
9366
9458
  const outBufferSize = (typeof options.outBuffer === "number") ? options.outBuffer : 64 * 1024;
9367
9459
  const inBufferSize = (typeof options.inBufferSize === "number") ? options.inBufferSize : 64 * 1024;
9368
-
9369
- return new TransformStream({
9370
- start() {
9460
+ const state = { out: 0, in: 0, inBufferSize: 0, streamHandle: 0, streamEnded: false };
9461
+ let readableController, writableController, resolveWrite, cancelReason;
9462
+ let backpressure = true;
9463
+ let cancelled = false;
9464
+ initStream();
9465
+ const readable = new ReadableStream({
9466
+ start(controller) {
9467
+ readableController = controller;
9468
+ },
9469
+ pull() {
9470
+ backpressure = false;
9471
+ resumeWrite();
9472
+ },
9473
+ cancel(reason) {
9474
+ cancelled = true;
9475
+ cancelReason = reason;
9476
+ disposeStream(state);
9477
+ writableController.error(reason);
9478
+ resumeWrite();
9479
+ }
9480
+ }, { highWaterMark: 0 });
9481
+ const writable = new WritableStream({
9482
+ start(controller) {
9483
+ writableController = controller;
9484
+ },
9485
+ async write(chunk) {
9486
+ if (backpressure) {
9487
+ await new Promise(resolve => resolveWrite = resolve);
9488
+ }
9489
+ if (cancelled) {
9490
+ throw cancelReason;
9491
+ }
9371
9492
  try {
9372
- let result;
9373
- this.out = malloc(outBufferSize);
9374
- this.in = malloc(inBufferSize);
9375
- this.inBufferSize = inBufferSize;
9376
- if (!this.out || !this.in) {
9377
- throw new Error("allocation failed");
9378
- }
9379
- if (isCompress) {
9380
- this._process = wasm$1.deflate_process;
9381
- this._last_consumed = wasm$1.deflate_last_consumed;
9382
- this._end = wasm$1.deflate_end;
9383
- this.streamHandle = wasm$1.deflate_new();
9384
- if (type === FORMAT_GZIP) {
9385
- result = wasm$1.deflate_init_gzip(this.streamHandle, level);
9386
- } else if (type === FORMAT_DEFLATE_RAW) {
9387
- result = wasm$1.deflate_init_raw(this.streamHandle, level);
9388
- } else {
9389
- result = wasm$1.deflate_init(this.streamHandle, level);
9390
- }
9391
- } else {
9392
- if (type === FORMAT_DEFLATE64_RAW) {
9393
- this._process = wasm$1.inflate9_process;
9394
- this._last_consumed = wasm$1.inflate9_last_consumed;
9395
- this._end = wasm$1.inflate9_end;
9396
- this.streamHandle = wasm$1.inflate9_new();
9397
- result = wasm$1.inflate9_init_raw(this.streamHandle);
9398
- } else {
9399
- this._process = wasm$1.inflate_process;
9400
- this._last_consumed = wasm$1.inflate_last_consumed;
9401
- this._end = wasm$1.inflate_end;
9402
- this.streamHandle = wasm$1.inflate_new();
9403
- if (type === FORMAT_DEFLATE_RAW) {
9404
- result = wasm$1.inflate_init_raw(this.streamHandle);
9405
- } else if (type === FORMAT_GZIP) {
9406
- result = wasm$1.inflate_init_gzip(this.streamHandle);
9407
- } else {
9408
- result = wasm$1.inflate_init(this.streamHandle);
9409
- }
9410
- }
9411
- }
9412
- if (result !== 0) {
9413
- throw new Error("init failed:" + result);
9414
- }
9493
+ processChunk(chunk);
9415
9494
  } catch (error) {
9416
- disposeStream(this);
9495
+ disposeStream(state);
9496
+ readableController.error(error);
9417
9497
  throw error;
9418
9498
  }
9419
9499
  },
9420
- transform(chunk, controller) {
9500
+ close() {
9501
+ if (cancelled) {
9502
+ return;
9503
+ }
9421
9504
  try {
9422
- const buffer = chunk;
9423
- const heap = new Uint8Array(memory.buffer);
9424
- const process = this._process;
9425
- const last_consumed = this._last_consumed;
9426
- const out = this.out;
9427
- let offset = 0;
9428
- while (offset < buffer.length) {
9429
- const toRead = Math.min(buffer.length - offset, 32 * 1024);
9430
- if (!this.in || this.inBufferSize < toRead) {
9431
- if (this.in && free) {
9432
- free(this.in);
9433
- this.in = 0;
9434
- }
9435
- this.in = malloc(toRead);
9436
- this.inBufferSize = toRead;
9437
- if (!this.in) {
9438
- throw new Error("allocation failed");
9439
- }
9440
- }
9441
- heap.set(buffer.subarray(offset, offset + toRead), this.in);
9442
- const result = process(this.streamHandle, this.in, toRead, out, outBufferSize, 0);
9443
- // checked before the byte count is used, so a status code can never be read as one
9444
- const code = (result >> 24) & 0xff;
9445
- const signedCode = (code & 0x80) ? code - 256 : code;
9446
- if (signedCode < 0) {
9447
- throw new Error("process error:" + signedCode);
9448
- }
9449
- const prod = result & 0x00ffffff;
9450
- if (prod) {
9451
- controller.enqueue(heap.slice(out, out + prod));
9452
- }
9453
- const consumed = last_consumed(this.streamHandle);
9454
- if (consumed === 0 && prod === 0) {
9455
- break;
9456
- }
9457
- offset += consumed;
9458
- }
9505
+ flushStream();
9459
9506
  } catch (error) {
9460
- disposeStream(this);
9461
- controller.error(error);
9507
+ disposeStream(state);
9508
+ readableController.error(error);
9509
+ throw error;
9462
9510
  }
9511
+ const result = disposeStream(state);
9512
+ if (result !== 0) {
9513
+ const error = setZlibCode(new Error("end error:" + result), result);
9514
+ readableController.error(error);
9515
+ throw error;
9516
+ }
9517
+ readableController.close();
9463
9518
  },
9464
- flush(controller) {
9465
- try {
9466
- const heap = new Uint8Array(memory.buffer);
9467
- const process = this._process;
9468
- const out = this.out;
9469
- while (true) {
9470
- const result = process(this.streamHandle, 0, 0, out, outBufferSize, 4);
9471
- const code = (result >> 24) & 0xff;
9472
- const signedCode = (code & 0x80) ? code - 256 : code;
9473
- if (signedCode < 0) {
9474
- throw new Error("process error:" + signedCode);
9475
- }
9476
- const produced = result & 0x00ffffff;
9477
- if (produced) {
9478
- controller.enqueue(heap.slice(out, out + produced));
9479
- }
9480
- if (code === 1 || produced === 0) {
9481
- break;
9519
+ abort(reason) {
9520
+ disposeStream(state);
9521
+ readableController.error(reason);
9522
+ }
9523
+ }, { highWaterMark: 1 });
9524
+ return { readable, writable };
9525
+
9526
+ function initStream() {
9527
+ try {
9528
+ let result;
9529
+ state.out = malloc(outBufferSize);
9530
+ state.in = malloc(inBufferSize);
9531
+ state.inBufferSize = inBufferSize;
9532
+ if (!state.out || !state.in) {
9533
+ throw setZlibCode(new Error("allocation failed"), Z_MEM_ERROR);
9534
+ }
9535
+ if (isCompress) {
9536
+ state._process = wasm$1.deflate_process;
9537
+ state._last_consumed = wasm$1.deflate_last_consumed;
9538
+ state._end = wasm$1.deflate_end;
9539
+ state.streamHandle = wasm$1.deflate_new();
9540
+ if (type === FORMAT_GZIP) {
9541
+ result = wasm$1.deflate_init_gzip(state.streamHandle, level);
9542
+ } else if (type === FORMAT_DEFLATE_RAW) {
9543
+ result = wasm$1.deflate_init_raw(state.streamHandle, level);
9544
+ } else {
9545
+ result = wasm$1.deflate_init(state.streamHandle, level);
9546
+ }
9547
+ } else {
9548
+ if (type === FORMAT_DEFLATE64_RAW) {
9549
+ state._process = wasm$1.inflate9_process;
9550
+ state._last_consumed = wasm$1.inflate9_last_consumed;
9551
+ state._end = wasm$1.inflate9_end;
9552
+ state.streamHandle = wasm$1.inflate9_new();
9553
+ result = wasm$1.inflate9_init_raw(state.streamHandle);
9554
+ } else {
9555
+ state._process = wasm$1.inflate_process;
9556
+ state._last_consumed = wasm$1.inflate_last_consumed;
9557
+ state._end = wasm$1.inflate_end;
9558
+ state.streamHandle = wasm$1.inflate_new();
9559
+ if (type === FORMAT_DEFLATE_RAW) {
9560
+ result = wasm$1.inflate_init_raw(state.streamHandle);
9561
+ } else if (type === FORMAT_GZIP) {
9562
+ result = wasm$1.inflate_init_gzip(state.streamHandle);
9563
+ } else {
9564
+ result = wasm$1.inflate_init(state.streamHandle);
9482
9565
  }
9483
9566
  }
9484
- } catch (error) {
9485
- controller.error(error);
9486
- } finally {
9487
- const result = disposeStream(this);
9488
- if (result !== 0) {
9489
- controller.error(new Error("end error:" + result));
9567
+ }
9568
+ if (result !== 0) {
9569
+ throw setZlibCode(new Error("init failed:" + result), result);
9570
+ }
9571
+ } catch (error) {
9572
+ disposeStream(state);
9573
+ throw error;
9574
+ }
9575
+ }
9576
+
9577
+ function processChunk(chunk) {
9578
+ const heap = new Uint8Array(memory.buffer);
9579
+ const process = state._process;
9580
+ const last_consumed = state._last_consumed;
9581
+ const out = state.out;
9582
+ let offset = 0;
9583
+ while (offset < chunk.length) {
9584
+ if (state.streamEnded) {
9585
+ throw new Error("trailing data after the end of the stream");
9586
+ }
9587
+ const toRead = Math.min(chunk.length - offset, 32 * 1024);
9588
+ if (!state.in || state.inBufferSize < toRead) {
9589
+ if (state.in && free) {
9590
+ free(state.in);
9591
+ state.in = 0;
9592
+ }
9593
+ state.in = malloc(toRead);
9594
+ state.inBufferSize = toRead;
9595
+ if (!state.in) {
9596
+ throw setZlibCode(new Error("allocation failed"), Z_MEM_ERROR);
9490
9597
  }
9491
9598
  }
9492
- },
9493
- cancel() {
9494
- // release the stream handle and buffers when the pipeline is aborted,
9495
- // they would be leaked in the process-lifetime wasm heap otherwise
9496
- disposeStream(this);
9599
+ heap.set(chunk.subarray(offset, offset + toRead), state.in);
9600
+ const result = process(state.streamHandle, state.in, toRead, out, outBufferSize, 0);
9601
+ // checked before the byte count is used, so a status code can never be read as one
9602
+ const code = (result >> 24) & 0xff;
9603
+ const signedCode = (code & 0x80) ? code - 256 : code;
9604
+ if (signedCode < 0) {
9605
+ throw setZlibCode(new Error("process error:" + signedCode), signedCode);
9606
+ }
9607
+ const prod = result & 0x00ffffff;
9608
+ if (prod) {
9609
+ enqueue(heap.slice(out, out + prod));
9610
+ }
9611
+ const consumed = last_consumed(state.streamHandle);
9612
+ if (code === 1) {
9613
+ state.streamEnded = true;
9614
+ } else if (consumed === 0 && prod === 0) {
9615
+ break;
9616
+ }
9617
+ offset += consumed;
9497
9618
  }
9498
- });
9619
+ }
9620
+
9621
+ function flushStream() {
9622
+ const heap = new Uint8Array(memory.buffer);
9623
+ const process = state._process;
9624
+ const out = state.out;
9625
+ while (true) {
9626
+ const result = process(state.streamHandle, 0, 0, out, outBufferSize, 4);
9627
+ const code = (result >> 24) & 0xff;
9628
+ const signedCode = (code & 0x80) ? code - 256 : code;
9629
+ if (signedCode < 0) {
9630
+ throw setZlibCode(new Error("process error:" + signedCode), signedCode);
9631
+ }
9632
+ const produced = result & 0x00ffffff;
9633
+ if (produced) {
9634
+ enqueue(heap.slice(out, out + produced));
9635
+ }
9636
+ if (code === 1 || produced === 0) {
9637
+ break;
9638
+ }
9639
+ }
9640
+ }
9641
+
9642
+ function enqueue(chunk) {
9643
+ backpressure = true;
9644
+ readableController.enqueue(chunk);
9645
+ }
9646
+
9647
+ function resumeWrite() {
9648
+ if (resolveWrite) {
9649
+ const resolve = resolveWrite;
9650
+ resolveWrite = null;
9651
+ resolve();
9652
+ }
9653
+ }
9499
9654
 
9500
9655
  function disposeStream(state) {
9501
9656
  let endResult = 0;
@@ -9531,10 +9686,10 @@ class DecompressionStreamZlib {
9531
9686
  CompressionStreamZlib.requiresModule = true;
9532
9687
  DecompressionStreamZlib.requiresModule = true;
9533
9688
  // Constructing these classes before the module is loaded throws, so capability probes cannot rely
9534
- // on trying the constructor; the formats are declared instead, next to the branches implementing
9535
- // them in _make().
9536
- CompressionStreamZlib.supportedFormats = [FORMAT_DEFLATE, FORMAT_DEFLATE_RAW, FORMAT_GZIP];
9537
- DecompressionStreamZlib.supportedFormats = [FORMAT_DEFLATE, FORMAT_DEFLATE_RAW, FORMAT_GZIP, FORMAT_DEFLATE64_RAW];
9689
+ // on trying the constructor; the formats are declared instead, the lists _make() checks a format
9690
+ // against before anything else.
9691
+ CompressionStreamZlib.supportedFormats = COMPRESSION_FORMATS;
9692
+ DecompressionStreamZlib.supportedFormats = DECOMPRESSION_FORMATS;
9538
9693
 
9539
9694
  /*
9540
9695
  Copyright (c) 2026 Gildas Lormeau. All rights reserved.
@@ -9781,4 +9936,4 @@ async function terminateWorkersAndModule() {
9781
9936
 
9782
9937
  configureExternalAssets();
9783
9938
 
9784
- export { BlobReader, BlobWriter, Data64URIReader, Data64URIWriter, ERR_ABORTED, ERR_AMBIGUOUS_ARCHIVE, ERR_BAD_FORMAT, ERR_CENTRAL_DIRECTORY_NOT_FOUND, ERR_DUPLICATED_NAME, ERR_ENCRYPTED, ERR_ENCRYPTED_CENTRAL_DIRECTORY, ERR_ENTRY_DATA_OUT_OF_BOUNDS, ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND, ERR_EOCDR_NOT_FOUND, ERR_EXTRAFIELD_ZIP64_NOT_FOUND, ERR_HTTP_RANGE, ERR_HTTP_RESOURCE_CHANGED, ERR_HTTP_STATUS, ERR_INVALID_AUTHENTICATION_CODE, ERR_INVALID_BASE_URI, ERR_INVALID_CODEC_DEFINITION, ERR_INVALID_CODEC_MODULE, ERR_INVALID_COMMENT, ERR_INVALID_COMMENT_TYPE, ERR_INVALID_COMPRESSED_DATA, ERR_INVALID_CRC32, ERR_INVALID_DATE, ERR_INVALID_ENCRYPTION_STRENGTH, ERR_INVALID_ENTRY, ERR_INVALID_ENTRY_COMMENT, ERR_INVALID_ENTRY_COMMENT_TYPE, ERR_INVALID_ENTRY_NAME, ERR_INVALID_EXTRAFIELD, ERR_INVALID_EXTRAFIELD_DATA, ERR_INVALID_EXTRAFIELD_DATA_TYPE, ERR_INVALID_EXTRAFIELD_TYPE, ERR_INVALID_FILENAME_VALIDATION, ERR_INVALID_FUNCTION_OPTION, ERR_INVALID_GID, ERR_INVALID_LEVEL, ERR_INVALID_MAX_APPENDED_DATA_SIZE, ERR_INVALID_MAX_WORKERS, ERR_INVALID_MSDOS_ATTRIBUTES, ERR_INVALID_MSDOS_DATA, ERR_INVALID_PASSWORD, ERR_INVALID_PASSWORD_TYPE, ERR_INVALID_PASS_THROUGH_VALUE, ERR_INVALID_READER, ERR_INVALID_SIGNAL, ERR_INVALID_SIGNATURE_DATA, ERR_INVALID_STRICTNESS, ERR_INVALID_UID, ERR_INVALID_UNCOMPRESSED_SIZE, ERR_INVALID_UNIX_EXTRA_FIELD_TYPE, ERR_INVALID_UNIX_ID_SIZE, ERR_INVALID_UNIX_MODE, ERR_INVALID_URI, ERR_INVALID_VERSION, ERR_ITERATOR_COMPLETED_TOO_SOON, ERR_LOCAL_FILE_HEADER_NOT_FOUND, ERR_OVERLAPPING_ENTRY, ERR_RESERVED_COMPRESSION_METHOD, ERR_SPLIT_ZIP_FILE, ERR_UNDEFINED_COMPRESSION_METHOD, ERR_UNDEFINED_CRC32, ERR_UNDEFINED_READER, ERR_UNDEFINED_UNCOMPRESSED_SIZE, ERR_UNDETERMINED_SIZE, ERR_UNSAFE_FILENAME, ERR_UNSUPPORTED_COMPRESSION, ERR_UNSUPPORTED_CONTEXT, ERR_UNSUPPORTED_CRYPTO_API, ERR_UNSUPPORTED_ENCRYPTION, ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH, ERR_UNSUPPORTED_ENCRYPTION_USDZ, ERR_UNSUPPORTED_FORMAT, ERR_UNSUPPORTED_SPLIT_USDZ, ERR_UNSUPPORTED_UINT64, ERR_WORKER_STARTUP_TIMEOUT, ERR_WRITER_NOT_INITIALIZED, ERR_WRITER_SIZE_NOT_WRITABLE, ERR_ZIP_CRYPTO_LAST_MOD_DATE, ERR_ZIP_NOT_EMPTY, HttpRangeReader, HttpReader, Reader, SplitDataReader, SplitDataWriter, TextReader, TextWriter, Uint8ArrayReader, Uint8ArrayWriter, VERSION, WARNING_APPENDED_DATA, WARNING_CLAMPED_LAST_MODIFICATION_DATE, WARNING_COMPRESSED_PATCHED_DATA, WARNING_COMPRESSION_UNAVAILABLE, WARNING_DUPLICATE_FILENAME, WARNING_MALFORMED_EXTRA_FIELD, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG, WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES, WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY, WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY, WARNING_PREPENDED_CENTRAL_DIRECTORY, WARNING_PREPENDED_DATA, WARNING_TRAILING_CENTRAL_DIRECTORY_DATA, WARNING_UNKNOWN_VERSION, WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA, WARNING_UNSORTED_CENTRAL_DIRECTORY, WARNING_WRAPPED_ENTRIES_COUNT, Writer, ZipReader, ZipReaderStream, ZipWriter, ZipWriterStream, configure, createBlobTempStream, createOPFSTempStream, createSyncAccessHandleTempStream, getMimeType, getRegisteredCodecs, getSupportedCompressionMethods, isZipFile, registerCodec, resetConfiguration, terminateWorkersAndModule as terminateWorkers, unregisterCodec };
9939
+ export { BlobReader, BlobWriter, Data64URIReader, Data64URIWriter, ERR_ABORTED, ERR_AMBIGUOUS_ARCHIVE, ERR_BAD_FORMAT, ERR_CENTRAL_DIRECTORY_NOT_FOUND, ERR_CODEC_OUT_OF_MEMORY, ERR_DUPLICATED_NAME, ERR_ENCRYPTED, ERR_ENCRYPTED_CENTRAL_DIRECTORY, ERR_ENTRY_DATA_OUT_OF_BOUNDS, ERR_EOCDR_LOCATOR_ZIP64_NOT_FOUND, ERR_EOCDR_NOT_FOUND, ERR_EXTRAFIELD_ZIP64_NOT_FOUND, ERR_HTTP_RANGE, ERR_HTTP_RESOURCE_CHANGED, ERR_HTTP_STATUS, ERR_INVALID_AUTHENTICATION_CODE, ERR_INVALID_BASE_URI, ERR_INVALID_CODEC_DEFINITION, ERR_INVALID_CODEC_MODULE, ERR_INVALID_COMMENT, ERR_INVALID_COMMENT_TYPE, ERR_INVALID_COMPRESSED_DATA, ERR_INVALID_CRC32, ERR_INVALID_DATE, ERR_INVALID_ENCRYPTION_STRENGTH, ERR_INVALID_ENTRY, ERR_INVALID_ENTRY_COMMENT, ERR_INVALID_ENTRY_COMMENT_TYPE, ERR_INVALID_ENTRY_NAME, ERR_INVALID_EXTRAFIELD, ERR_INVALID_EXTRAFIELD_DATA, ERR_INVALID_EXTRAFIELD_DATA_TYPE, ERR_INVALID_EXTRAFIELD_TYPE, ERR_INVALID_FILENAME_VALIDATION, ERR_INVALID_FUNCTION_OPTION, ERR_INVALID_GID, ERR_INVALID_LEVEL, ERR_INVALID_MAX_APPENDED_DATA_SIZE, ERR_INVALID_MAX_WORKERS, ERR_INVALID_MSDOS_ATTRIBUTES, ERR_INVALID_MSDOS_DATA, ERR_INVALID_PASSWORD, ERR_INVALID_PASSWORD_TYPE, ERR_INVALID_PASS_THROUGH_VALUE, ERR_INVALID_READER, ERR_INVALID_SIGNAL, ERR_INVALID_SIGNATURE_DATA, ERR_INVALID_STRICTNESS, ERR_INVALID_UID, ERR_INVALID_UNCOMPRESSED_SIZE, ERR_INVALID_UNIX_EXTRA_FIELD_TYPE, ERR_INVALID_UNIX_ID_SIZE, ERR_INVALID_UNIX_MODE, ERR_INVALID_URI, ERR_INVALID_VERSION, ERR_ITERATOR_COMPLETED_TOO_SOON, ERR_LOCAL_FILE_HEADER_NOT_FOUND, ERR_OVERLAPPING_ENTRY, ERR_RESERVED_COMPRESSION_METHOD, ERR_SPLIT_ZIP_FILE, ERR_UNDEFINED_COMPRESSION_METHOD, ERR_UNDEFINED_CRC32, ERR_UNDEFINED_READER, ERR_UNDEFINED_UNCOMPRESSED_SIZE, ERR_UNDETERMINED_SIZE, ERR_UNSAFE_FILENAME, ERR_UNSUPPORTED_COMPRESSION, ERR_UNSUPPORTED_CONTEXT, ERR_UNSUPPORTED_CRYPTO_API, ERR_UNSUPPORTED_ENCRYPTION, ERR_UNSUPPORTED_ENCRYPTION_PASS_THROUGH, ERR_UNSUPPORTED_ENCRYPTION_USDZ, ERR_UNSUPPORTED_FORMAT, ERR_UNSUPPORTED_SPLIT_USDZ, ERR_UNSUPPORTED_UINT64, ERR_WORKER_STARTUP_TIMEOUT, ERR_WRITER_NOT_INITIALIZED, ERR_WRITER_SIZE_NOT_WRITABLE, ERR_ZIP_CRYPTO_LAST_MOD_DATE, ERR_ZIP_NOT_EMPTY, HttpRangeReader, HttpReader, Reader, SplitDataReader, SplitDataWriter, TextReader, TextWriter, Uint8ArrayReader, Uint8ArrayWriter, VERSION, WARNING_APPENDED_DATA, WARNING_CLAMPED_LAST_MODIFICATION_DATE, WARNING_COMPRESSED_PATCHED_DATA, WARNING_COMPRESSION_UNAVAILABLE, WARNING_DUPLICATE_FILENAME, WARNING_MALFORMED_EXTRA_FIELD, WARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG, WARNING_MISMATCHED_LOCAL_FILE_HEADER_COMPRESSION_METHOD, WARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES, WARNING_MISMATCHED_LOCAL_FILE_HEADER_FILENAME, WARNING_MISMATCHED_ZIP64_END_OF_CENTRAL_DIRECTORY, WARNING_MULTIPLE_END_OF_CENTRAL_DIRECTORY, WARNING_PREPENDED_CENTRAL_DIRECTORY, WARNING_PREPENDED_DATA, WARNING_TRAILING_CENTRAL_DIRECTORY_DATA, WARNING_UNKNOWN_VERSION, WARNING_UNKNOWN_ZIP64_EXTENSIBLE_DATA, WARNING_UNSORTED_CENTRAL_DIRECTORY, WARNING_WRAPPED_ENTRIES_COUNT, Writer, ZipReader, ZipReaderStream, ZipWriter, ZipWriterStream, configure, createBlobTempStream, createOPFSTempStream, createSyncAccessHandleTempStream, getMimeType, getRegisteredCodecs, getSupportedCompressionMethods, isZipFile, registerCodec, resetConfiguration, terminateWorkersAndModule as terminateWorkers, unregisterCodec };