@zip.js/zip.js 2.16.1 → 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 (45) hide show
  1. package/deno.json +1 -1
  2. package/dist/zip-core-external.js +169 -119
  3. package/dist/zip-core-external.min.js +1 -1
  4. package/dist/zip-core.js +138 -106
  5. package/dist/zip-core.min.js +1 -1
  6. package/dist/zip-fs-core-external.js +181 -121
  7. package/dist/zip-fs-core-external.min.js +1 -1
  8. package/dist/zip-fs-core.js +150 -108
  9. package/dist/zip-fs-core.min.js +1 -1
  10. package/dist/zip-fs-external.js +181 -121
  11. package/dist/zip-fs-external.min.js +1 -1
  12. package/dist/zip-fs-native.js +153 -111
  13. package/dist/zip-fs-native.min.js +1 -1
  14. package/dist/zip-fs.js +182 -121
  15. package/dist/zip-fs.min.js +1 -1
  16. package/dist/zip-legacy.js +140 -108
  17. package/dist/zip-legacy.min.js +1 -1
  18. package/dist/zip-native.js +141 -109
  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 +170 -119
  23. package/dist/zip.min.js +1 -1
  24. package/index-native.cjs +153 -111
  25. package/index-native.min.js +1 -1
  26. package/index.cjs +182 -121
  27. package/index.d.cts +58 -20
  28. package/index.d.ts +58 -20
  29. package/index.min.js +1 -1
  30. package/lib/core/codec-pool.js +2 -0
  31. package/lib/core/codec-worker-web.js +11 -3
  32. package/lib/core/codec-worker.js +2 -1
  33. package/lib/core/streams/codec-stream.js +2 -0
  34. package/lib/core/streams/zip-entry-stream.js +123 -102
  35. package/lib/core/streams/zlib-js/zlib-streams.min.js +1 -1
  36. package/lib/core/streams/zlib-wasm/zlib-streams.js +31 -12
  37. package/lib/core/version.js +1 -1
  38. package/lib/core/web-worker-base.js +1 -1
  39. package/lib/core/web-worker-inline-native.js +1 -1
  40. package/lib/core/web-worker-inline-wasm.js +1 -1
  41. package/lib/core/zip-fs.js +16 -3
  42. package/lib/core/zip-reader.js +3 -0
  43. package/lib/core/zip-writer.js +1 -0
  44. package/lib/zip-core-reader.js +1 -0
  45. package/package.json +1 -1
package/deno.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zip-js/zip-js",
3
- "version": "2.16.1",
3
+ "version": "2.17.0",
4
4
  "exports": {
5
5
  ".": "./index.js",
6
6
  "./external": "./lib/zip-fs-external.js",
@@ -1931,7 +1931,9 @@ async function ensureCodecStreams(format, codecURI) {
1931
1931
 
1932
1932
  const ERR_INVALID_UNCOMPRESSED_SIZE = "Invalid uncompressed size";
1933
1933
  const ERR_INVALID_COMPRESSED_DATA = "Invalid compressed data";
1934
+ const ERR_CODEC_OUT_OF_MEMORY = "Codec out of memory";
1934
1935
  const ERR_INVALID_CRC32 = "Invalid CRC32";
1936
+ const Z_MEM_ERROR_CODE$1 = "Z_MEM_ERROR";
1935
1937
  const FORMAT_DEFLATE_RAW$1 = "deflate-raw";
1936
1938
  const FORMAT_DEFLATE64_RAW$1 = "deflate64-raw";
1937
1939
  const FORMAT_GZIP$1 = "gzip";
@@ -1966,13 +1968,13 @@ class DeflateStream extends TransformStream {
1966
1968
  readable = pipeThroughCompressionStream(readable, useCompressionStream, { level, chunkSize }, CompressionStream, CompressionStreamFallback);
1967
1969
  } catch (error) {
1968
1970
  if (!useCompressionStream && CompressionStreamFallback) {
1969
- throw error;
1971
+ throw mapMemoryError(error);
1970
1972
  }
1971
1973
  let gzipStream;
1972
1974
  try {
1973
1975
  gzipStream = new CompressionStream(FORMAT_GZIP$1);
1974
1976
  } catch {
1975
- throw error;
1977
+ throw mapMemoryError(error);
1976
1978
  }
1977
1979
  readable = pipeThroughBackpressured(readable, gzipStream);
1978
1980
  readable = pipeThrough(readable, new GzipToRawDeflateStream());
@@ -2036,50 +2038,30 @@ class GzipToRawDeflateStream extends TransformStream {
2036
2038
  }
2037
2039
  }
2038
2040
 
2039
- function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32) {
2041
+ function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32, sourceErrors) {
2040
2042
  const writer = gzipStream.writable.getWriter();
2041
2043
  const reader = gzipStream.readable.getReader();
2042
2044
  const outputCrc32 = crc32 === UNDEFINED_VALUE ? new Crc32() : UNDEFINED_VALUE;
2043
2045
  let outputLength = 0;
2044
- let inputDone = false;
2045
2046
  let trailerWritten = false;
2046
- let idleCheckArmed = false;
2047
- let readCount = 0;
2048
- let readPending = false;
2049
- let resolveTrailerReady, rejectTrailerReady;
2050
- const trailerReady = new Promise((resolve, reject) => {
2051
- resolveTrailerReady = resolve;
2052
- rejectTrailerReady = reject;
2053
- });
2054
- trailerReady.catch(() => { });
2055
- pump();
2056
- return new ReadableStream({
2057
- async pull(controller) {
2058
- try {
2059
- const { value, done } = await read();
2060
- if (done) {
2061
- controller.close();
2062
- } else {
2063
- outputLength += value.length;
2064
- if (outputLength > outputSize) {
2065
- throw new Error(ERR_INVALID_UNCOMPRESSED_SIZE);
2066
- }
2067
- if (outputCrc32) {
2068
- outputCrc32.append(value);
2069
- }
2070
- controller.enqueue(value);
2071
- }
2072
- } catch (error) {
2073
- rejectTrailerReady(error);
2074
- await cancel(reader, error);
2075
- throw trailerWritten ? getTrailerError(error) : error;
2076
- }
2047
+ let settled = false;
2048
+ let resolvePull, controller;
2049
+ const output = new ReadableStream({
2050
+ start(streamController) {
2051
+ controller = streamController;
2052
+ },
2053
+ pull() {
2054
+ resumePump();
2077
2055
  },
2078
2056
  cancel(reason) {
2079
- rejectTrailerReady(reason);
2057
+ settled = true;
2058
+ resumePump();
2080
2059
  return reader.cancel(reason);
2081
2060
  }
2082
2061
  });
2062
+ pump();
2063
+ drain();
2064
+ return output;
2083
2065
 
2084
2066
  async function pump() {
2085
2067
  const inputReader = readable.getReader();
@@ -2088,19 +2070,16 @@ function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, cr
2088
2070
  header.set(GZIP_HEADER_BYTES);
2089
2071
  await writer.write(header);
2090
2072
  for (; ;) {
2073
+ await outputCapacity();
2091
2074
  await writer.ready;
2092
- const { value, done } = await inputReader.read();
2075
+ const { value, done } = await readSource(inputReader, sourceErrors);
2093
2076
  if (done) {
2094
2077
  break;
2095
2078
  }
2096
2079
  await writer.write(value);
2097
2080
  }
2098
- inputDone = true;
2099
2081
  if (outputCrc32) {
2100
- if (readPending) {
2101
- armIdleCheck();
2102
- }
2103
- await trailerReady;
2082
+ await writer.write(new Uint8Array(0));
2104
2083
  }
2105
2084
  const trailer = new Uint8Array(GZIP_TRAILER_LENGTH);
2106
2085
  const dataView = getDataView(trailer);
@@ -2115,54 +2094,68 @@ function pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, cr
2115
2094
  }
2116
2095
  }
2117
2096
 
2118
- function read() {
2119
- readCount++;
2120
- readPending = true;
2121
- const result = reader.read();
2122
- result.then(onReadSettled, onReadSettled);
2123
- if (inputDone && outputCrc32) {
2124
- 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);
2125
2120
  }
2126
- return result;
2127
2121
  }
2128
2122
 
2129
- function onReadSettled() {
2130
- readPending = false;
2131
- }
2132
-
2133
- async function armIdleCheck() {
2134
- if (!idleCheckArmed) {
2135
- idleCheckArmed = true;
2136
- const count = readCount;
2137
- await nextTask();
2138
- idleCheckArmed = false;
2139
- if (readPending) {
2140
- if (readCount == count) {
2141
- resolveTrailerReady();
2142
- } else {
2143
- armIdleCheck();
2123
+ function read() {
2124
+ return reader.read().catch(error => {
2125
+ if (trailerWritten) {
2126
+ if (!outputCrc32) {
2127
+ throw mapError(error, ERR_INVALID_CRC32);
2144
2128
  }
2129
+ if (outputLength != outputSize) {
2130
+ throw mapError(error, ERR_INVALID_UNCOMPRESSED_SIZE);
2131
+ }
2132
+ return { done: true };
2145
2133
  }
2146
- }
2134
+ throw mapCodecError(error, sourceErrors);
2135
+ });
2147
2136
  }
2148
2137
 
2149
- function getTrailerError(error) {
2150
- const trailerError = new Error(outputLength == outputSize ? ERR_INVALID_CRC32 : ERR_INVALID_UNCOMPRESSED_SIZE);
2151
- trailerError.cause = error;
2152
- return trailerError;
2138
+ function outputCapacity() {
2139
+ if (!settled && controller.desiredSize <= 0) {
2140
+ return new Promise(resolve => resolvePull = resolve);
2141
+ }
2153
2142
  }
2154
- }
2155
2143
 
2156
- function nextTask() {
2157
- return new Promise(resolve => {
2158
- const { port1, port2 } = new MessageChannel();
2159
- port2.onmessage = () => {
2160
- port1.close();
2161
- port2.close();
2144
+ function resumePump() {
2145
+ if (resolvePull) {
2146
+ const resolve = resolvePull;
2147
+ resolvePull = UNDEFINED_VALUE;
2162
2148
  resolve();
2163
- };
2164
- port1.postMessage(UNDEFINED_VALUE);
2165
- });
2149
+ }
2150
+ }
2151
+
2152
+ function fail(error) {
2153
+ if (!settled) {
2154
+ settled = true;
2155
+ controller.error(error);
2156
+ resumePump();
2157
+ }
2158
+ }
2166
2159
  }
2167
2160
 
2168
2161
  class InflateStream extends TransformStream {
@@ -2181,11 +2174,12 @@ class InflateStream extends TransformStream {
2181
2174
  }
2182
2175
  }
2183
2176
  if (compressed) {
2177
+ const sourceErrors = new Set();
2184
2178
  const codecStreams = format && getCodecStreams(format);
2179
+ let gzipStream;
2185
2180
  if (codecStreams) {
2186
- 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);
2187
2182
  } else {
2188
- let gzipStream;
2189
2183
  const GzipDecompressionStream = getGzipCodecStream(useCompressionStream, DecompressionStream, DecompressionStreamFallback);
2190
2184
  if (checkCrc32 && !deflate64 && crc32 !== UNDEFINED_VALUE && outputSize !== UNDEFINED_VALUE && GzipDecompressionStream) {
2191
2185
  try {
@@ -2196,24 +2190,25 @@ class InflateStream extends TransformStream {
2196
2190
  }
2197
2191
  if (!gzipStream) {
2198
2192
  try {
2199
- readable = pipeThroughCompressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream, DecompressionStreamFallback);
2193
+ readable = pipeThroughCompressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream, DecompressionStreamFallback, sourceErrors);
2200
2194
  } catch (error) {
2201
2195
  if (deflate64 || outputSize === UNDEFINED_VALUE || (!useCompressionStream && DecompressionStreamFallback)) {
2202
- throw error;
2196
+ throw mapMemoryError(error);
2203
2197
  }
2204
2198
  try {
2205
2199
  gzipStream = new DecompressionStream(FORMAT_GZIP$1);
2206
2200
  } catch {
2207
- throw error;
2201
+ throw mapMemoryError(error);
2208
2202
  }
2209
2203
  }
2210
2204
  }
2211
- if (gzipStream) {
2212
- gzipCrc32 = true;
2213
- readable = pipeThroughGzipDecompressionStream(readable, gzipStream, outputSize, crc32);
2214
- }
2215
2205
  }
2216
- 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
+ }
2217
2212
  }
2218
2213
  if (checkCrc32 && !gzipCrc32) {
2219
2214
  crc32Stream = new Crc32Stream();
@@ -2286,7 +2281,7 @@ function getGzipCodecStream(useCompressionStream, CodecStreamNative, CodecStream
2286
2281
  }
2287
2282
  }
2288
2283
 
2289
- function pipeThroughCompressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamFallback) {
2284
+ function pipeThroughCompressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamFallback, sourceErrors) {
2290
2285
  const Stream = useCompressionStream && CompressionStreamNative ?
2291
2286
  CompressionStreamNative :
2292
2287
  CompressionStreamFallback || CompressionStreamNative;
@@ -2301,14 +2296,14 @@ function pipeThroughCompressionStream(readable, useCompressionStream, options, C
2301
2296
  throw error;
2302
2297
  }
2303
2298
  }
2304
- return pipeThroughBackpressured(readable, codecStream);
2299
+ return pipeThroughBackpressured(readable, codecStream, sourceErrors);
2305
2300
  }
2306
2301
 
2307
2302
  function pipeThrough(readable, transformStream) {
2308
2303
  return toCompatibleReadable(readable).pipeThrough(transformStream);
2309
2304
  }
2310
2305
 
2311
- function pipeThroughBackpressured(readable, transformStream) {
2306
+ function pipeThroughBackpressured(readable, transformStream, sourceErrors) {
2312
2307
  const writer = transformStream.writable.getWriter();
2313
2308
  const reader = readable.getReader();
2314
2309
  pump();
@@ -2318,7 +2313,7 @@ function pipeThroughBackpressured(readable, transformStream) {
2318
2313
  try {
2319
2314
  for (; ;) {
2320
2315
  await writer.ready;
2321
- const result = await reader.read();
2316
+ const result = await readSource(reader, sourceErrors);
2322
2317
  if (result.done) {
2323
2318
  await writer.close();
2324
2319
  break;
@@ -2348,7 +2343,36 @@ async function cancel(reader, error) {
2348
2343
  }
2349
2344
  }
2350
2345
 
2351
- 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) {
2352
2376
  const reader = readable.getReader();
2353
2377
  return new ReadableStream({
2354
2378
  async pull(controller) {
@@ -2361,12 +2385,7 @@ function mapInflateStreamError(readable) {
2361
2385
  }
2362
2386
  } catch (error) {
2363
2387
  await cancel(reader, error);
2364
- if (error && error.message) {
2365
- throw error;
2366
- }
2367
- const mappedError = new Error(ERR_INVALID_COMPRESSED_DATA);
2368
- mappedError.cause = error;
2369
- throw mappedError;
2388
+ throw mapCodecError(error, sourceErrors);
2370
2389
  }
2371
2390
  },
2372
2391
  cancel(reason) {
@@ -2734,10 +2753,11 @@ async function runWorker$1({ options, readable, writable, onTaskFinished, worker
2734
2753
  }
2735
2754
  codecStream = new CodecStream(options, config);
2736
2755
  chunkStream = new ChunkStream(getChunkSize(config));
2756
+ const { signal } = workerOptions.streamOptions;
2737
2757
  await readable
2738
2758
  .pipeThrough(codecStream)
2739
2759
  .pipeThrough(chunkStream)
2740
- .pipeTo(writable, { preventClose: true, preventAbort: true });
2760
+ .pipeTo(writable, { preventClose: true, preventAbort: true, signal });
2741
2761
  const {
2742
2762
  crc32,
2743
2763
  inputSize,
@@ -2805,6 +2825,7 @@ async function runWorker$1({ options, readable, writable, onTaskFinished, worker
2805
2825
  const MODULE_WORKER_OPTIONS = { type: "module" };
2806
2826
  const ERROR_EVENT_TYPE = "error";
2807
2827
  const MESSAGE_ERROR_EVENT_TYPE = "messageerror";
2828
+ const ABORT_EVENT_TYPE = "abort";
2808
2829
 
2809
2830
  let webWorkerSource, webWorkerURI, webWorkerOptions;
2810
2831
  let transferStreamsSupported = true;
@@ -2981,6 +3002,13 @@ function watchClosedStream(writableSource, workerData) {
2981
3002
  Object.assign(workerData, { destinationFailed: true, destinationError: error });
2982
3003
  }
2983
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
+ }
2984
3012
  return {
2985
3013
  writable, closed, abortPipe: () => {
2986
3014
  aborting = true;
@@ -3243,9 +3271,6 @@ function getResponseError(errorData, errorValue) {
3243
3271
  responseError = errorValue.value;
3244
3272
  } else {
3245
3273
  responseError = Object.assign(new Error(message), { stack, code, name });
3246
- if (cause) {
3247
- responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
3248
- }
3249
3274
  }
3250
3275
  if (isErrorObject(responseError)) {
3251
3276
  try {
@@ -3255,6 +3280,9 @@ function getResponseError(errorData, errorValue) {
3255
3280
  if (codecImportFailed) {
3256
3281
  responseError.codecImportFailed = true;
3257
3282
  }
3283
+ if (cause && !isErrorObject(responseError.cause)) {
3284
+ responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
3285
+ }
3258
3286
  if (errorValue) {
3259
3287
  if (responseError.name !== name) {
3260
3288
  responseError.name = name;
@@ -5577,6 +5605,7 @@ class ZipEntry {
5577
5605
  ({ writable } = writer);
5578
5606
  const readable = toCompatibleReadable(reader.createReadable({ offset: dataOffset, size }));
5579
5607
  const { outputSize: writtenSize } = await runWorker({ readable, writable }, workerOptions);
5608
+ throwIfAborted(signal);
5580
5609
  if (writtenSize != outputSize) {
5581
5610
  throw Object.assign(new Error(ERR_INVALID_UNCOMPRESSED_SIZE), { outputSize: writtenSize });
5582
5611
  }
@@ -6372,6 +6401,7 @@ var zipReader = /*#__PURE__*/Object.freeze({
6372
6401
  ERR_AMBIGUOUS_ARCHIVE: ERR_AMBIGUOUS_ARCHIVE,
6373
6402
  ERR_BAD_FORMAT: ERR_BAD_FORMAT,
6374
6403
  ERR_CENTRAL_DIRECTORY_NOT_FOUND: ERR_CENTRAL_DIRECTORY_NOT_FOUND,
6404
+ ERR_CODEC_OUT_OF_MEMORY: ERR_CODEC_OUT_OF_MEMORY,
6375
6405
  ERR_ENCRYPTED: ERR_ENCRYPTED,
6376
6406
  ERR_ENCRYPTED_CENTRAL_DIRECTORY: ERR_ENCRYPTED_CENTRAL_DIRECTORY,
6377
6407
  ERR_ENTRY_DATA_OUT_OF_BOUNDS: ERR_ENTRY_DATA_OUT_OF_BOUNDS,
@@ -7721,6 +7751,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7721
7751
  const result = await runWorker({ readable, writable }, workerOptions);
7722
7752
  compressedSize = result.outputSize;
7723
7753
  writer.size += compressedSize;
7754
+ throwIfAborted(signal);
7724
7755
  if (!passThroughCompression) {
7725
7756
  uncompressedSize = result.inputSize;
7726
7757
  if (!encrypted || zipCrypto) {
@@ -8900,7 +8931,7 @@ function formatSupported(StreamClass, format) {
8900
8931
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8901
8932
  */
8902
8933
 
8903
- const VERSION = "2.16.1";
8934
+ const VERSION = "2.17.0";
8904
8935
 
8905
8936
  /*
8906
8937
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
@@ -9383,6 +9414,10 @@ const FORMAT_DEFLATE = "deflate";
9383
9414
  const FORMAT_DEFLATE_RAW = "deflate-raw";
9384
9415
  const FORMAT_DEFLATE64_RAW = "deflate64-raw";
9385
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];
9386
9421
 
9387
9422
  let wasm$1, malloc, free, memory, initError;
9388
9423
 
@@ -9403,7 +9438,17 @@ function resetWasmExports$1() {
9403
9438
  wasm$1 = malloc = free = memory = initError = null;
9404
9439
  }
9405
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
+
9406
9448
  function _make(isCompress, type, options = {}) {
9449
+ if (!(isCompress ? COMPRESSION_FORMATS : DECOMPRESSION_FORMATS).includes(type)) {
9450
+ throw new TypeError("Unsupported format: " + type);
9451
+ }
9407
9452
  if (!wasm$1) {
9408
9453
  const error = new Error("WASM module not loaded");
9409
9454
  error.cause = initError;
@@ -9412,7 +9457,7 @@ function _make(isCompress, type, options = {}) {
9412
9457
  const level = (typeof options.level === "number") ? options.level : -1;
9413
9458
  const outBufferSize = (typeof options.outBuffer === "number") ? options.outBuffer : 64 * 1024;
9414
9459
  const inBufferSize = (typeof options.inBufferSize === "number") ? options.inBufferSize : 64 * 1024;
9415
- const state = { out: 0, in: 0, inBufferSize: 0, streamHandle: 0 };
9460
+ const state = { out: 0, in: 0, inBufferSize: 0, streamHandle: 0, streamEnded: false };
9416
9461
  let readableController, writableController, resolveWrite, cancelReason;
9417
9462
  let backpressure = true;
9418
9463
  let cancelled = false;
@@ -9465,7 +9510,7 @@ function _make(isCompress, type, options = {}) {
9465
9510
  }
9466
9511
  const result = disposeStream(state);
9467
9512
  if (result !== 0) {
9468
- const error = new Error("end error:" + result);
9513
+ const error = setZlibCode(new Error("end error:" + result), result);
9469
9514
  readableController.error(error);
9470
9515
  throw error;
9471
9516
  }
@@ -9485,7 +9530,7 @@ function _make(isCompress, type, options = {}) {
9485
9530
  state.in = malloc(inBufferSize);
9486
9531
  state.inBufferSize = inBufferSize;
9487
9532
  if (!state.out || !state.in) {
9488
- throw new Error("allocation failed");
9533
+ throw setZlibCode(new Error("allocation failed"), Z_MEM_ERROR);
9489
9534
  }
9490
9535
  if (isCompress) {
9491
9536
  state._process = wasm$1.deflate_process;
@@ -9521,7 +9566,7 @@ function _make(isCompress, type, options = {}) {
9521
9566
  }
9522
9567
  }
9523
9568
  if (result !== 0) {
9524
- throw new Error("init failed:" + result);
9569
+ throw setZlibCode(new Error("init failed:" + result), result);
9525
9570
  }
9526
9571
  } catch (error) {
9527
9572
  disposeStream(state);
@@ -9536,6 +9581,9 @@ function _make(isCompress, type, options = {}) {
9536
9581
  const out = state.out;
9537
9582
  let offset = 0;
9538
9583
  while (offset < chunk.length) {
9584
+ if (state.streamEnded) {
9585
+ throw new Error("trailing data after the end of the stream");
9586
+ }
9539
9587
  const toRead = Math.min(chunk.length - offset, 32 * 1024);
9540
9588
  if (!state.in || state.inBufferSize < toRead) {
9541
9589
  if (state.in && free) {
@@ -9545,7 +9593,7 @@ function _make(isCompress, type, options = {}) {
9545
9593
  state.in = malloc(toRead);
9546
9594
  state.inBufferSize = toRead;
9547
9595
  if (!state.in) {
9548
- throw new Error("allocation failed");
9596
+ throw setZlibCode(new Error("allocation failed"), Z_MEM_ERROR);
9549
9597
  }
9550
9598
  }
9551
9599
  heap.set(chunk.subarray(offset, offset + toRead), state.in);
@@ -9554,14 +9602,16 @@ function _make(isCompress, type, options = {}) {
9554
9602
  const code = (result >> 24) & 0xff;
9555
9603
  const signedCode = (code & 0x80) ? code - 256 : code;
9556
9604
  if (signedCode < 0) {
9557
- throw new Error("process error:" + signedCode);
9605
+ throw setZlibCode(new Error("process error:" + signedCode), signedCode);
9558
9606
  }
9559
9607
  const prod = result & 0x00ffffff;
9560
9608
  if (prod) {
9561
9609
  enqueue(heap.slice(out, out + prod));
9562
9610
  }
9563
9611
  const consumed = last_consumed(state.streamHandle);
9564
- if (consumed === 0 && prod === 0) {
9612
+ if (code === 1) {
9613
+ state.streamEnded = true;
9614
+ } else if (consumed === 0 && prod === 0) {
9565
9615
  break;
9566
9616
  }
9567
9617
  offset += consumed;
@@ -9577,7 +9627,7 @@ function _make(isCompress, type, options = {}) {
9577
9627
  const code = (result >> 24) & 0xff;
9578
9628
  const signedCode = (code & 0x80) ? code - 256 : code;
9579
9629
  if (signedCode < 0) {
9580
- throw new Error("process error:" + signedCode);
9630
+ throw setZlibCode(new Error("process error:" + signedCode), signedCode);
9581
9631
  }
9582
9632
  const produced = result & 0x00ffffff;
9583
9633
  if (produced) {
@@ -9636,10 +9686,10 @@ class DecompressionStreamZlib {
9636
9686
  CompressionStreamZlib.requiresModule = true;
9637
9687
  DecompressionStreamZlib.requiresModule = true;
9638
9688
  // Constructing these classes before the module is loaded throws, so capability probes cannot rely
9639
- // on trying the constructor; the formats are declared instead, next to the branches implementing
9640
- // them in _make().
9641
- CompressionStreamZlib.supportedFormats = [FORMAT_DEFLATE, FORMAT_DEFLATE_RAW, FORMAT_GZIP];
9642
- 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;
9643
9693
 
9644
9694
  /*
9645
9695
  Copyright (c) 2026 Gildas Lormeau. All rights reserved.
@@ -9886,4 +9936,4 @@ async function terminateWorkersAndModule() {
9886
9936
 
9887
9937
  configureExternalAssets();
9888
9938
 
9889
- 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 };