@zip.js/zip.js 2.12.0 → 2.13.1

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 (41) hide show
  1. package/deno.json +1 -1
  2. package/dist/zip-core-external.js +158 -41
  3. package/dist/zip-core-external.min.js +1 -1
  4. package/dist/zip-core.js +158 -41
  5. package/dist/zip-core.min.js +1 -1
  6. package/dist/zip-fs-core-external.js +159 -42
  7. package/dist/zip-fs-core-external.min.js +1 -1
  8. package/dist/zip-fs-core.js +159 -42
  9. package/dist/zip-fs-core.min.js +1 -1
  10. package/dist/zip-fs-external.js +159 -42
  11. package/dist/zip-fs-external.min.js +1 -1
  12. package/dist/zip-fs-native.js +161 -44
  13. package/dist/zip-fs-native.min.js +1 -1
  14. package/dist/zip-fs.js +160 -43
  15. package/dist/zip-fs.min.js +1 -1
  16. package/dist/zip-legacy.js +160 -43
  17. package/dist/zip-legacy.min.js +1 -1
  18. package/dist/zip-native.js +160 -43
  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 +159 -42
  23. package/dist/zip.min.js +1 -1
  24. package/index-native.cjs +161 -44
  25. package/index-native.min.js +1 -1
  26. package/index.cjs +160 -43
  27. package/index.d.cts +19 -7
  28. package/index.d.ts +19 -7
  29. package/index.min.js +1 -1
  30. package/lib/core/codec-worker-web.js +96 -30
  31. package/lib/core/codec-worker.js +15 -3
  32. package/lib/core/util/error.js +35 -0
  33. package/lib/core/version.js +1 -1
  34. package/lib/core/web-worker-base.js +43 -7
  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 -1
  38. package/lib/core/zip-reader.js +9 -4
  39. package/lib/core/zip-writer.js +8 -3
  40. package/package.json +1 -1
  41. package/worker-message-property-names.js +1 -1
@@ -516,6 +516,39 @@ function getDataView(array) {
516
516
  return new DataView(array.buffer, array.byteOffset, array.byteLength);
517
517
  }
518
518
 
519
+ /*
520
+ Copyright (c) 2026 Gildas Lormeau. All rights reserved.
521
+
522
+ Redistribution and use in source and binary forms, with or without
523
+ modification, are permitted provided that the following conditions are met:
524
+
525
+ 1. Redistributions of source code must retain the above copyright notice,
526
+ this list of conditions and the following disclaimer.
527
+
528
+ 2. Redistributions in binary form must reproduce the above copyright
529
+ notice, this list of conditions and the following disclaimer in
530
+ the documentation and/or other materials provided with the distribution.
531
+
532
+ 3. The names of the authors may not be used to endorse or promote products
533
+ derived from this software without specific prior written permission.
534
+
535
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
536
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
537
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
538
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
539
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
540
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
541
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
542
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
543
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
544
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
545
+ */
546
+
547
+
548
+ function isErrorObject(error) {
549
+ return Boolean(error) && typeof error == "object";
550
+ }
551
+
519
552
  /*
520
553
  Copyright (c) 2022 Gildas Lormeau. All rights reserved.
521
554
 
@@ -2787,7 +2820,9 @@ function disableWebWorker(workerData) {
2787
2820
 
2788
2821
  class CodecWorker {
2789
2822
 
2790
- constructor(workerData, { readable, writable }, { options, config, streamOptions, useWebWorkers, transferStreams, workerURI, createWorker }, onTaskFinished) {
2823
+ constructor(workerData, { readable, writable }, workerOptions, onTaskFinished) {
2824
+ const { options, config, streamOptions, useWebWorkers, transferStreams, workerURI } = workerOptions;
2825
+ let { createWorker } = workerOptions;
2791
2826
  const { signal } = streamOptions;
2792
2827
  if (createWorkerFailed) {
2793
2828
  createWorker = UNDEFINED_VALUE;
@@ -2800,6 +2835,7 @@ class CodecWorker {
2800
2835
  .pipeThrough(new ProgressWatcherStream(streamOptions), { signal }),
2801
2836
  writable,
2802
2837
  options: Object.assign({}, options),
2838
+ workerOptions,
2803
2839
  workerURI,
2804
2840
  createWorker,
2805
2841
  transferStreams,
@@ -2881,7 +2917,7 @@ function createWorkerInterface(workerData, config) {
2881
2917
  };
2882
2918
  }
2883
2919
 
2884
- async function runWorker$1({ options, readable, writable, onTaskFinished }, config) {
2920
+ async function runWorker$1({ options, readable, writable, onTaskFinished, workerOptions }, config) {
2885
2921
  let codecStream, chunkStream;
2886
2922
  try {
2887
2923
  if (options.compressed && !options.format) {
@@ -2922,7 +2958,15 @@ async function runWorker$1({ options, readable, writable, onTaskFinished }, conf
2922
2958
  };
2923
2959
  } catch (error) {
2924
2960
  if (codecStream) {
2925
- error.outputSize = chunkStream ? chunkStream.outputSize : 0;
2961
+ const outputSize = chunkStream ? chunkStream.outputSize : 0;
2962
+ workerOptions.outputSize = outputSize;
2963
+ if (isErrorObject(error)) {
2964
+ try {
2965
+ error.outputSize = outputSize;
2966
+ } catch {
2967
+ // ignored
2968
+ }
2969
+ }
2926
2970
  }
2927
2971
  throw error;
2928
2972
  } finally {
@@ -3032,8 +3076,14 @@ async function runWebWorker(workerData, config) {
3032
3076
  const result = new Promise((resolve, reject) => {
3033
3077
  resolveResult = resolve;
3034
3078
  rejectResult = error => {
3035
- if (error && error.outputSize === UNDEFINED_VALUE) {
3036
- error.outputSize = workerData.outputSize;
3079
+ const { outputSize, workerOptions } = workerData;
3080
+ workerOptions.outputSize = outputSize;
3081
+ if (isErrorObject(error)) {
3082
+ try {
3083
+ error.outputSize = outputSize;
3084
+ } catch {
3085
+ // ignored
3086
+ }
3037
3087
  }
3038
3088
  reject(error);
3039
3089
  };
@@ -3042,12 +3092,14 @@ async function runWebWorker(workerData, config) {
3042
3092
  reader: null,
3043
3093
  writer: null,
3044
3094
  outputSize: 0,
3095
+ destinationFailed: false,
3096
+ destinationError: null,
3045
3097
  resolveResult,
3046
3098
  rejectResult,
3047
3099
  result
3048
3100
  });
3049
3101
  const { readable, options } = workerData;
3050
- const { writable, closed, abortPipe } = watchClosedStream(workerData.writable);
3102
+ const { writable, closed, abortPipe } = watchClosedStream(workerData.writable, workerData);
3051
3103
  let streamsTransferred;
3052
3104
  try {
3053
3105
  streamsTransferred = sendMessage({
@@ -3090,7 +3142,18 @@ async function runWebWorker(workerData, config) {
3090
3142
  } catch {
3091
3143
  // ignored
3092
3144
  }
3093
- throw error;
3145
+ const { outputSize, workerOptions, destinationFailed, destinationError } = workerData;
3146
+ workerOptions.outputSize = outputSize;
3147
+ const workerFailed = isErrorObject(error) && (error.codecImportFailed || error.workerStartupFailed);
3148
+ const reportedError = destinationFailed && !workerFailed ? destinationError : error;
3149
+ if (isErrorObject(reportedError)) {
3150
+ try {
3151
+ reportedError.outputSize = outputSize;
3152
+ } catch {
3153
+ // ignored
3154
+ }
3155
+ }
3156
+ throw reportedError;
3094
3157
  }
3095
3158
 
3096
3159
  async function closeWritable() {
@@ -3104,12 +3167,27 @@ async function runWebWorker(workerData, config) {
3104
3167
  }
3105
3168
  }
3106
3169
 
3107
- function watchClosedStream(writableSource) {
3170
+ function watchClosedStream(writableSource, workerData) {
3108
3171
  const abortController = new AbortController();
3109
- const { writable, readable } = new TransformStream();
3172
+ let aborting;
3173
+ const { writable, readable } = new TransformStream({
3174
+ transform(chunk, controller) {
3175
+ workerData.outputSize += chunk.length;
3176
+ controller.enqueue(chunk);
3177
+ }
3178
+ });
3110
3179
  const closed = readable.pipeTo(writableSource, { preventClose: true, preventAbort: true, signal: abortController.signal });
3111
- closed.catch(() => { });
3112
- return { writable, closed, abortPipe: () => abortController.abort() };
3180
+ closed.catch(error => {
3181
+ if (!aborting) {
3182
+ Object.assign(workerData, { destinationFailed: true, destinationError: error });
3183
+ }
3184
+ });
3185
+ return {
3186
+ writable, closed, abortPipe: () => {
3187
+ aborting = true;
3188
+ abortController.abort();
3189
+ }
3190
+ };
3113
3191
  }
3114
3192
 
3115
3193
  function releaseWorkerStreams(workerData) {
@@ -3302,21 +3380,12 @@ function sendMessage(message, { worker, writer, transferStreams, workerAlive })
3302
3380
  }
3303
3381
 
3304
3382
  async function onMessage({ data }, workerData) {
3305
- const { type, value, messageId, result, error } = data;
3383
+ const { type, value, messageId, result, error, errorValue } = data;
3306
3384
  const { reader, writer, resolveResult, rejectResult, onTaskFinished, generation } = workerData;
3307
3385
  const stale = () => workerData.generation != generation;
3308
3386
  try {
3309
3387
  if (error) {
3310
- const { message, stack, code, name, outputSize, cause, codecImportFailed } = error;
3311
- const responseError = new Error(message);
3312
- Object.assign(responseError, { stack, code, name, outputSize });
3313
- if (cause) {
3314
- responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
3315
- }
3316
- if (codecImportFailed) {
3317
- responseError.codecImportFailed = true;
3318
- }
3319
- close(responseError);
3388
+ fail(getResponseError(error, errorValue));
3320
3389
  } else {
3321
3390
  if (type == MESSAGE_PULL) {
3322
3391
  const { value, done } = await reader.read();
@@ -3328,38 +3397,78 @@ async function onMessage({ data }, workerData) {
3328
3397
  const chunk = new Uint8Array(value);
3329
3398
  await writer.ready;
3330
3399
  await writer.write(chunk);
3331
- workerData.outputSize += chunk.length;
3332
3400
  if (!stale()) {
3333
3401
  sendMessage({ type: MESSAGE_ACK_DATA, messageId }, workerData);
3334
3402
  }
3335
3403
  }
3336
3404
  if (type == MESSAGE_CLOSE) {
3337
- close(null, result);
3405
+ succeed(result);
3338
3406
  }
3339
3407
  }
3340
3408
  } catch (error) {
3341
3409
  if (!stale()) {
3342
3410
  terminateWorker$1(workerData);
3343
- close(error);
3411
+ fail(error);
3344
3412
  }
3345
3413
  }
3346
3414
 
3347
- function close(error, result) {
3348
- if (stale()) {
3349
- return;
3350
- }
3351
- if (error) {
3415
+ function fail(error) {
3416
+ if (!stale()) {
3352
3417
  rejectResult(error);
3353
- } else {
3418
+ releaseWriter();
3419
+ if (!(isErrorObject(error) && error.codecImportFailed)) {
3420
+ onTaskFinished();
3421
+ }
3422
+ }
3423
+ }
3424
+
3425
+ function succeed(result) {
3426
+ if (!stale()) {
3354
3427
  resolveResult(result);
3428
+ releaseWriter();
3429
+ onTaskFinished();
3355
3430
  }
3431
+ }
3432
+
3433
+ function releaseWriter() {
3356
3434
  if (writer) {
3357
3435
  writer.releaseLock();
3358
3436
  }
3359
- if (!(error && error.codecImportFailed)) {
3360
- onTaskFinished();
3437
+ }
3438
+ }
3439
+
3440
+ function getResponseError(errorData, errorValue) {
3441
+ const { message, stack, code, name, outputSize, cause, codecImportFailed } = errorData;
3442
+ let responseError;
3443
+ if (errorValue) {
3444
+ responseError = errorValue.value;
3445
+ } else {
3446
+ responseError = Object.assign(new Error(message), { stack, code, name });
3447
+ if (cause) {
3448
+ responseError.cause = Object.assign(new Error(cause.message), { name: cause.name });
3449
+ }
3450
+ }
3451
+ if (isErrorObject(responseError)) {
3452
+ try {
3453
+ if (outputSize !== UNDEFINED_VALUE) {
3454
+ responseError.outputSize = outputSize;
3455
+ }
3456
+ if (codecImportFailed) {
3457
+ responseError.codecImportFailed = true;
3458
+ }
3459
+ if (errorValue) {
3460
+ if (responseError.name !== name) {
3461
+ responseError.name = name;
3462
+ }
3463
+ if (responseError.code !== code) {
3464
+ responseError.code = code;
3465
+ }
3466
+ }
3467
+ } catch {
3468
+ // ignored
3361
3469
  }
3362
3470
  }
3471
+ return responseError;
3363
3472
  }
3364
3473
 
3365
3474
  /*
@@ -5641,7 +5750,7 @@ let ZipEntry$1 = class ZipEntry {
5641
5750
  readRanges
5642
5751
  });
5643
5752
  }
5644
- let writable, abortError;
5753
+ let writable, abortError, aborted;
5645
5754
  try {
5646
5755
  if (!checkOverlappingEntryOnly) {
5647
5756
  if (checkPasswordOnly) {
@@ -5657,18 +5766,22 @@ let ZipEntry$1 = class ZipEntry {
5657
5766
  writer.size += writtenSize;
5658
5767
  }
5659
5768
  } catch (error) {
5660
- if (error.outputSize !== UNDEFINED_VALUE) {
5769
+ const { outputSize: failedOutputSize } = workerOptions;
5770
+ if (failedOutputSize !== UNDEFINED_VALUE) {
5771
+ writer.size += failedOutputSize;
5772
+ } else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
5661
5773
  writer.size += error.outputSize;
5662
5774
  }
5663
- if (!checkPasswordOnly || error.message != ERR_ABORT_CHECK_PASSWORD) {
5775
+ if (!checkPasswordOnly || !isErrorObject(error) || error.message != ERR_ABORT_CHECK_PASSWORD) {
5664
5776
  abortError = error;
5777
+ aborted = true;
5665
5778
  throw error;
5666
5779
  }
5667
5780
  } finally {
5668
5781
  const preventClose = !ownsWritable(writer) && getOptionValue$1(zipEntry, options, OPTION_PREVENT_CLOSE);
5669
5782
  if (!preventClose && writable && !writable.locked) {
5670
5783
  const writableWriter = writable.getWriter();
5671
- if (abortError) {
5784
+ if (aborted) {
5672
5785
  try {
5673
5786
  await writableWriter.abort(abortError);
5674
5787
  } catch {
@@ -6728,7 +6841,7 @@ class ZipWriter {
6728
6841
  await Promise.allSettled(Array.from(pendingAddFileCalls));
6729
6842
  }
6730
6843
  await Promise.allSettled(zipWriter.pendingErrors.map(watcher => watcher.recorded));
6731
- const unobservedWatchers = zipWriter.pendingErrors.filter(watcher => watcher.error && !watcher.observed);
6844
+ const unobservedWatchers = zipWriter.pendingErrors.filter(watcher => watcher.failed && !watcher.observed);
6732
6845
  if (unobservedWatchers.length) {
6733
6846
  const unobservedErrors = unobservedWatchers.map(watcher => watcher.error);
6734
6847
  unobservedWatchers.forEach(watcher => watcher.observed = true);
@@ -6837,7 +6950,8 @@ function watchPromiseError(zipWriter, promise) {
6837
6950
  const watchedPromise = new WatchedPromise((resolve, reject) => Promise.prototype.then.call(promise, resolve, reject));
6838
6951
  const watcher = {};
6839
6952
  watchedPromise.watcher = watcher;
6840
- watcher.recorded = Promise.prototype.then.call(watchedPromise, UNDEFINED_VALUE, error => watcher.error = error);
6953
+ watcher.recorded = Promise.prototype.then.call(watchedPromise, UNDEFINED_VALUE,
6954
+ error => Object.assign(watcher, { failed: true, error }));
6841
6955
  zipWriter.pendingErrors.push(watcher);
6842
6956
  return watchedPromise;
6843
6957
  }
@@ -7851,7 +7965,10 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
7851
7965
  throw new Error(ERR_UNSUPPORTED_FORMAT);
7852
7966
  }
7853
7967
  } catch (error) {
7854
- if (error.outputSize !== UNDEFINED_VALUE) {
7968
+ const { outputSize: failedOutputSize } = workerOptions;
7969
+ if (failedOutputSize !== UNDEFINED_VALUE) {
7970
+ writer.size += failedOutputSize;
7971
+ } else if (isErrorObject(error) && error.outputSize !== UNDEFINED_VALUE) {
7855
7972
  writer.size += error.outputSize;
7856
7973
  }
7857
7974
  throw error;
@@ -9016,7 +9133,7 @@ function formatSupported(StreamClass, format) {
9016
9133
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
9017
9134
  */
9018
9135
 
9019
- const VERSION = "2.12.0";
9136
+ const VERSION = "2.13.1";
9020
9137
 
9021
9138
  /*
9022
9139
  Copyright (c) 2025 Gildas Lormeau. All rights reserved.
@@ -10023,7 +10140,7 @@ class ZipFileEntry extends ZipEntry {
10023
10140
  }));
10024
10141
  return true;
10025
10142
  } catch (error) {
10026
- if (error.message == ERR_INVALID_PASSWORD) {
10143
+ if (isErrorObject(error) && error.message == ERR_INVALID_PASSWORD) {
10027
10144
  return false;
10028
10145
  } else {
10029
10146
  throw error;