@zip.js/zip.js 2.7.32 → 2.7.34

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.
@@ -56,26 +56,28 @@ let indexWorker = 0;
56
56
  async function runWorker(stream, workerOptions) {
57
57
  const { options, config } = workerOptions;
58
58
  const { transferStreams, useWebWorkers, useCompressionStream, codecType, compressed, signed, encrypted } = options;
59
- const { workerScripts, maxWorkers, terminateWorkerTimeout } = config;
59
+ const { workerScripts, maxWorkers } = config;
60
60
  workerOptions.transferStreams = transferStreams || transferStreams === UNDEFINED_VALUE;
61
61
  const streamCopy = !compressed && !signed && !encrypted && !workerOptions.transferStreams;
62
62
  workerOptions.useWebWorkers = !streamCopy && (useWebWorkers || (useWebWorkers === UNDEFINED_VALUE && config.useWebWorkers));
63
63
  workerOptions.scripts = workerOptions.useWebWorkers && workerScripts ? workerScripts[codecType] : [];
64
64
  options.useCompressionStream = useCompressionStream || (useCompressionStream === UNDEFINED_VALUE && config.useCompressionStream);
65
- let worker;
66
- const workerData = pool.find(workerData => !workerData.busy);
67
- if (workerData) {
68
- clearTerminateTimeout(workerData);
69
- worker = new CodecWorker(workerData, stream, workerOptions, onTaskFinished);
70
- } else if (pool.length < maxWorkers) {
71
- const workerData = { indexWorker };
72
- indexWorker++;
73
- pool.push(workerData);
74
- worker = new CodecWorker(workerData, stream, workerOptions, onTaskFinished);
75
- } else {
76
- worker = await new Promise(resolve => pendingRequests.push({ resolve, stream, workerOptions }));
65
+ return (await getWorker()).run();
66
+
67
+ async function getWorker() {
68
+ const workerData = pool.find(workerData => !workerData.busy);
69
+ if (workerData) {
70
+ clearTerminateTimeout(workerData);
71
+ return new CodecWorker(workerData, stream, workerOptions, onTaskFinished);
72
+ } else if (pool.length < maxWorkers) {
73
+ const workerData = { indexWorker };
74
+ indexWorker++;
75
+ pool.push(workerData);
76
+ return new CodecWorker(workerData, stream, workerOptions, onTaskFinished);
77
+ } else {
78
+ return new Promise(resolve => pendingRequests.push({ resolve, stream, workerOptions }));
79
+ }
77
80
  }
78
- return worker.run();
79
81
 
80
82
  function onTaskFinished(workerData) {
81
83
  if (pendingRequests.length) {
@@ -83,18 +85,32 @@ async function runWorker(stream, workerOptions) {
83
85
  resolve(new CodecWorker(workerData, stream, workerOptions, onTaskFinished));
84
86
  } else if (workerData.worker) {
85
87
  clearTerminateTimeout(workerData);
86
- if (Number.isFinite(terminateWorkerTimeout) && terminateWorkerTimeout >= 0) {
87
- workerData.terminateTimeout = setTimeout(() => {
88
- pool = pool.filter(data => data != workerData);
89
- workerData.terminate();
90
- }, terminateWorkerTimeout);
91
- }
88
+ terminateWorker(workerData, workerOptions);
92
89
  } else {
93
90
  pool = pool.filter(data => data != workerData);
94
91
  }
95
92
  }
96
93
  }
97
94
 
95
+ function terminateWorker(workerData, workerOptions) {
96
+ const { config } = workerOptions;
97
+ const { terminateWorkerTimeout } = config;
98
+ if (Number.isFinite(terminateWorkerTimeout) && terminateWorkerTimeout >= 0) {
99
+ if (workerData.terminated) {
100
+ workerData.terminated = false;
101
+ } else {
102
+ workerData.terminateTimeout = setTimeout(async () => {
103
+ pool = pool.filter(data => data != workerData);
104
+ try {
105
+ await workerData.terminate();
106
+ } catch (_error) {
107
+ // ignored
108
+ }
109
+ }, terminateWorkerTimeout);
110
+ }
111
+ }
112
+ }
113
+
98
114
  function clearTerminateTimeout(workerData) {
99
115
  const { terminateTimeout } = workerData;
100
116
  if (terminateTimeout) {
@@ -103,9 +119,9 @@ function clearTerminateTimeout(workerData) {
103
119
  }
104
120
  }
105
121
 
106
- function terminateWorkers() {
107
- pool.forEach(workerData => {
122
+ async function terminateWorkers() {
123
+ await Promise.allSettled(pool.map(workerData => {
108
124
  clearTerminateTimeout(workerData);
109
- workerData.terminate();
110
- });
125
+ return workerData.terminate();
126
+ }));
111
127
  }
@@ -34,6 +34,7 @@ import {
34
34
  } from "./constants.js";
35
35
  import {
36
36
  CodecStream,
37
+ ChunkStream,
37
38
  MESSAGE_EVENT_TYPE,
38
39
  MESSAGE_START,
39
40
  MESSAGE_PULL,
@@ -43,7 +44,7 @@ import {
43
44
  } from "./streams/codec-stream.js";
44
45
 
45
46
  // deno-lint-ignore valid-typeof
46
- const WEB_WORKERS_SUPPORTED = typeof Worker != UNDEFINED_TYPE;
47
+ let WEB_WORKERS_SUPPORTED = typeof Worker != UNDEFINED_TYPE;
47
48
 
48
49
  export {
49
50
  CodecWorker
@@ -55,19 +56,37 @@ class CodecWorker {
55
56
  const { signal } = streamOptions;
56
57
  Object.assign(workerData, {
57
58
  busy: true,
58
- readable: readable.pipeThrough(new ProgressWatcherStream(readable, streamOptions, config), { signal }),
59
+ readable: readable
60
+ .pipeThrough(new ChunkStream(config.chunkSize))
61
+ .pipeThrough(new ProgressWatcherStream(readable, streamOptions), { signal }),
59
62
  writable,
60
63
  options: Object.assign({}, options),
61
64
  scripts,
62
65
  transferStreams,
63
66
  terminate() {
64
- const { worker, busy } = workerData;
65
- if (worker && !busy) {
66
- worker.terminate();
67
- workerData.interface = null;
68
- }
67
+ return new Promise(resolve => {
68
+ const { worker, busy } = workerData;
69
+ if (worker) {
70
+ if (busy) {
71
+ workerData.resolveTerminated = resolve;
72
+ } else {
73
+ worker.terminate();
74
+ resolve();
75
+ }
76
+ workerData.interface = null;
77
+ } else {
78
+ resolve();
79
+ }
80
+ });
69
81
  },
70
82
  onTaskFinished() {
83
+ const { resolveTerminated } = workerData;
84
+ if (resolveTerminated) {
85
+ workerData.resolveTerminated = null;
86
+ workerData.terminated = true;
87
+ workerData.worker.terminate();
88
+ resolveTerminated();
89
+ }
71
90
  workerData.busy = false;
72
91
  onTaskFinished(workerData);
73
92
  }
@@ -78,12 +97,12 @@ class CodecWorker {
78
97
 
79
98
  class ProgressWatcherStream extends TransformStream {
80
99
 
81
- constructor(readableSource, { onstart, onprogress, size, onend }, { chunkSize }) {
100
+ constructor(readableSource, { onstart, onprogress, size, onend }) {
82
101
  let chunkOffset = 0;
83
102
  super({
84
- start() {
103
+ async start() {
85
104
  if (onstart) {
86
- callHandler(onstart, size);
105
+ await callHandler(onstart, size);
87
106
  }
88
107
  },
89
108
  async transform(chunk, controller) {
@@ -93,13 +112,13 @@ class ProgressWatcherStream extends TransformStream {
93
112
  }
94
113
  controller.enqueue(chunk);
95
114
  },
96
- flush() {
115
+ async flush() {
97
116
  readableSource.size = chunkOffset;
98
117
  if (onend) {
99
- callHandler(onend, chunkOffset);
118
+ await callHandler(onend, chunkOffset);
100
119
  }
101
120
  }
102
- }, { highWaterMark: 1, size: () => chunkSize });
121
+ });
103
122
  }
104
123
  }
105
124
 
@@ -117,10 +136,18 @@ function createWorkerInterface(workerData, config) {
117
136
  };
118
137
  }
119
138
 
120
- function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
139
+ function createWebWorkerInterface(workerData, config) {
140
+ const { baseURL, chunkSize } = config;
121
141
  if (!workerData.interface) {
142
+ let worker;
143
+ try {
144
+ worker = getWebWorker(workerData.scripts[0], baseURL, workerData);
145
+ } catch (error) {
146
+ WEB_WORKERS_SUPPORTED = false;
147
+ return createWorkerInterface(workerData, config);
148
+ }
122
149
  Object.assign(workerData, {
123
- worker: getWebWorker(workerData.scripts[0], baseURL, workerData),
150
+ worker,
124
151
  interface: {
125
152
  run: () => runWebWorker(workerData, { chunkSize })
126
153
  }
@@ -130,16 +157,18 @@ function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
130
157
  }
131
158
 
132
159
  async function runWorker({ options, readable, writable, onTaskFinished }, config) {
133
- const codecStream = new CodecStream(options, config);
134
160
  try {
161
+ const codecStream = new CodecStream(options, config);
135
162
  await readable.pipeThrough(codecStream).pipeTo(writable, { preventClose: true, preventAbort: true });
136
163
  const {
137
164
  signature,
138
- size
165
+ inputSize,
166
+ outputSize
139
167
  } = codecStream;
140
168
  return {
141
169
  signature,
142
- size
170
+ inputSize,
171
+ outputSize
143
172
  };
144
173
  } finally {
145
174
  onTaskFinished();
@@ -186,19 +215,20 @@ async function runWebWorker(workerData, config) {
186
215
  }
187
216
 
188
217
  function watchClosedStream(writableSource) {
189
- const writer = writableSource.getWriter();
190
218
  let resolveStreamClosed;
191
219
  const closed = new Promise(resolve => resolveStreamClosed = resolve);
192
220
  const writable = new WritableStream({
193
221
  async write(chunk) {
222
+ const writer = writableSource.getWriter();
194
223
  await writer.ready;
195
224
  await writer.write(chunk);
225
+ writer.releaseLock();
196
226
  },
197
227
  close() {
198
- writer.releaseLock();
199
228
  resolveStreamClosed();
200
229
  },
201
230
  abort(reason) {
231
+ const writer = writableSource.getWriter();
202
232
  return writer.abort(reason);
203
233
  }
204
234
  });
@@ -302,6 +332,7 @@ async function onMessage({ data }, workerData) {
302
332
  }
303
333
  }
304
334
  } catch (error) {
335
+ sendMessage({ type: MESSAGE_CLOSE, messageId }, workerData);
305
336
  close(error);
306
337
  }
307
338
 
package/lib/core/io.js CHANGED
@@ -262,7 +262,7 @@ class FetchReader extends Reader {
262
262
 
263
263
  constructor(url, options) {
264
264
  super();
265
- createHtpReader(this, url, options);
265
+ createHttpReader(this, url, options);
266
266
  }
267
267
 
268
268
  async init() {
@@ -279,7 +279,7 @@ class XHRReader extends Reader {
279
279
 
280
280
  constructor(url, options) {
281
281
  super();
282
- createHtpReader(this, url, options);
282
+ createHttpReader(this, url, options);
283
283
  }
284
284
 
285
285
  async init() {
@@ -292,7 +292,7 @@ class XHRReader extends Reader {
292
292
  }
293
293
  }
294
294
 
295
- function createHtpReader(httpReader, url, options) {
295
+ function createHttpReader(httpReader, url, options) {
296
296
  const {
297
297
  preventHeadRequest,
298
298
  useRangeHeader,
@@ -689,8 +689,7 @@ function initWriter(writer) {
689
689
  if (writable.size === UNDEFINED_VALUE) {
690
690
  writable.size = 0;
691
691
  }
692
- const splitZipFile = writer instanceof SplitDataWriter;
693
- if (!splitZipFile) {
692
+ if (!(writer instanceof SplitDataWriter)) {
694
693
  Object.assign(writer, {
695
694
  diskNumber: 0,
696
695
  diskOffset: 0,
@@ -29,6 +29,7 @@
29
29
  /* global crypto, TransformStream */
30
30
  // deno-lint-ignore-file no-this-alias
31
31
 
32
+ import { UNDEFINED_VALUE, UNDEFINED_TYPE, FUNCTION_TYPE } from "../constants.js";
32
33
  import { encodeText } from "./../util/encode-text.js";
33
34
  import {
34
35
  cipher,
@@ -55,8 +56,6 @@ const SALT_LENGTH = [8, 12, 16];
55
56
  const KEY_LENGTH = [16, 24, 32];
56
57
  const SIGNATURE_LENGTH = 10;
57
58
  const COUNTER_DEFAULT_VALUE = [0, 0, 0, 0];
58
- const UNDEFINED_TYPE = "undefined";
59
- const FUNCTION_TYPE = "function";
60
59
  // deno-lint-ignore valid-typeof
61
60
  const CRYPTO_API_SUPPORTED = typeof crypto != UNDEFINED_TYPE;
62
61
  const subtle = CRYPTO_API_SUPPORTED && crypto.subtle;
@@ -71,12 +70,12 @@ let DERIVE_BITS_SUPPORTED = CRYPTO_API_SUPPORTED && SUBTLE_API_SUPPORTED && type
71
70
 
72
71
  class AESDecryptionStream extends TransformStream {
73
72
 
74
- constructor({ password, signed, encryptionStrength, checkPasswordOnly }) {
73
+ constructor({ password, rawPassword, signed, encryptionStrength, checkPasswordOnly }) {
75
74
  super({
76
75
  start() {
77
76
  Object.assign(this, {
78
77
  ready: new Promise(resolve => this.resolveReady = resolve),
79
- password,
78
+ password: encodePassword(password, rawPassword),
80
79
  signed,
81
80
  strength: encryptionStrength - 1,
82
81
  pending: new Uint8Array()
@@ -140,14 +139,14 @@ class AESDecryptionStream extends TransformStream {
140
139
 
141
140
  class AESEncryptionStream extends TransformStream {
142
141
 
143
- constructor({ password, encryptionStrength }) {
142
+ constructor({ password, rawPassword, encryptionStrength }) {
144
143
  // deno-lint-ignore prefer-const
145
144
  let stream;
146
145
  super({
147
146
  start() {
148
147
  Object.assign(this, {
149
148
  ready: new Promise(resolve => this.resolveReady = resolve),
150
- password,
149
+ password: encodePassword(password, rawPassword),
151
150
  strength: encryptionStrength - 1,
152
151
  pending: new Uint8Array()
153
152
  });
@@ -244,8 +243,7 @@ async function createEncryptionKeys(encrypt, strength, password) {
244
243
 
245
244
  async function createKeys(aesCrypto, strength, password, salt) {
246
245
  aesCrypto.password = null;
247
- const encodedPassword = encodeText(password);
248
- const baseKey = await importKey(RAW_FORMAT, encodedPassword, BASE_KEY_ALGORITHM, false, DERIVED_BITS_USAGE);
246
+ const baseKey = await importKey(RAW_FORMAT, password, BASE_KEY_ALGORITHM, false, DERIVED_BITS_USAGE);
249
247
  const derivedBits = await deriveBits(Object.assign({ salt }, DERIVED_BITS_ALGORITHM), baseKey, 8 * ((KEY_LENGTH[strength] * 2) + 2));
250
248
  const compositeKey = new Uint8Array(derivedBits);
251
249
  const key = toBits(codecBytes, subarray(compositeKey, 0, KEY_LENGTH[strength]));
@@ -289,6 +287,14 @@ async function deriveBits(algorithm, baseKey, length) {
289
287
  }
290
288
  }
291
289
 
290
+ function encodePassword(password, rawPassword) {
291
+ if (rawPassword === UNDEFINED_VALUE) {
292
+ return encodeText(password);
293
+ } else {
294
+ return rawPassword;
295
+ }
296
+ }
297
+
292
298
  function concat(leftArray, rightArray) {
293
299
  let array = leftArray;
294
300
  if (leftArray.length + rightArray.length) {
@@ -65,7 +65,8 @@ export {
65
65
  ERR_INVALID_PASSWORD,
66
66
  ERR_INVALID_SIGNATURE,
67
67
  ERR_ABORT_CHECK_PASSWORD,
68
- CodecStream
68
+ CodecStream,
69
+ ChunkStream
69
70
  };
70
71
 
71
72
  class CodecStream extends TransformStream {
@@ -80,13 +81,27 @@ class CodecStream extends TransformStream {
80
81
  } else if (codecType.startsWith(CODEC_INFLATE)) {
81
82
  Stream = InflateStream;
82
83
  }
83
- let size = 0;
84
+ let outputSize = 0;
85
+ let inputSize = 0;
84
86
  const stream = new Stream(options, config);
85
87
  const readable = super.readable;
86
- const transformStream = new TransformStream({
88
+ const inputSizeStream = new TransformStream({
87
89
  transform(chunk, controller) {
88
90
  if (chunk && chunk.length) {
89
- size += chunk.length;
91
+ inputSize += chunk.length;
92
+ controller.enqueue(chunk);
93
+ }
94
+ },
95
+ flush() {
96
+ Object.assign(codec, {
97
+ inputSize
98
+ });
99
+ }
100
+ });
101
+ const outputSizeStream = new TransformStream({
102
+ transform(chunk, controller) {
103
+ if (chunk && chunk.length) {
104
+ outputSize += chunk.length;
90
105
  controller.enqueue(chunk);
91
106
  }
92
107
  },
@@ -94,14 +109,46 @@ class CodecStream extends TransformStream {
94
109
  const { signature } = stream;
95
110
  Object.assign(codec, {
96
111
  signature,
97
- size
112
+ outputSize,
113
+ inputSize
98
114
  });
99
115
  }
100
116
  });
101
117
  Object.defineProperty(codec, "readable", {
102
118
  get() {
103
- return readable.pipeThrough(stream).pipeThrough(transformStream);
119
+ return readable.pipeThrough(inputSizeStream).pipeThrough(stream).pipeThrough(outputSizeStream);
104
120
  }
105
121
  });
106
122
  }
123
+ }
124
+
125
+ class ChunkStream extends TransformStream {
126
+
127
+ constructor(chunkSize) {
128
+ let pendingChunk;
129
+ super({
130
+ transform,
131
+ flush(controller) {
132
+ if (pendingChunk && pendingChunk.length) {
133
+ controller.enqueue(pendingChunk);
134
+ }
135
+ }
136
+ });
137
+
138
+ function transform(chunk, controller) {
139
+ if (pendingChunk) {
140
+ const newChunk = new Uint8Array(pendingChunk.length + chunk.length);
141
+ newChunk.set(pendingChunk);
142
+ newChunk.set(chunk, pendingChunk.length);
143
+ chunk = newChunk;
144
+ pendingChunk = null;
145
+ }
146
+ if (chunk.length > chunkSize) {
147
+ controller.enqueue(chunk.slice(0, chunkSize));
148
+ transform(chunk.slice(chunkSize), controller);
149
+ } else {
150
+ pendingChunk = chunk;
151
+ }
152
+ }
153
+ }
107
154
  }
@@ -28,11 +28,12 @@
28
28
 
29
29
  /* global crypto */
30
30
 
31
+ import { FUNCTION_TYPE, UNDEFINED_TYPE } from "../constants.js";
31
32
  import {
32
33
  random
33
34
  } from "./codecs/sjcl.js";
34
35
 
35
- const GET_RANDOM_VALUES_SUPPORTED = typeof crypto != "undefined" && typeof crypto.getRandomValues == "function";
36
+ const GET_RANDOM_VALUES_SUPPORTED = typeof crypto != UNDEFINED_TYPE && typeof crypto.getRandomValues == FUNCTION_TYPE;
36
37
 
37
38
  const ERR_INVALID_PASSWORD = "Invalid password";
38
39
  const ERR_INVALID_SIGNATURE = "Invalid signature";
@@ -148,9 +148,13 @@ function pipeThroughCommpressionStream(readable, useCompressionStream, options,
148
148
  readable = pipeThrough(readable, new CompressionStream(COMPRESSION_FORMAT, options));
149
149
  } catch (error) {
150
150
  if (useCompressionStream) {
151
- readable = pipeThrough(readable, new CodecStream(COMPRESSION_FORMAT, options));
151
+ try {
152
+ readable = pipeThrough(readable, new CodecStream(COMPRESSION_FORMAT, options));
153
+ } catch (error) {
154
+ return readable;
155
+ }
152
156
  } else {
153
- throw error;
157
+ return readable;
154
158
  }
155
159
  }
156
160
  return readable;
@@ -28,12 +28,14 @@
28
28
 
29
29
  /* global TextEncoder */
30
30
 
31
+ import { UNDEFINED_TYPE } from "../constants.js";
32
+
31
33
  export {
32
34
  encodeText
33
35
  };
34
36
 
35
37
  function encodeText(value) {
36
- if (typeof TextEncoder == "undefined") {
38
+ if (typeof TextEncoder == UNDEFINED_TYPE) {
37
39
  value = unescape(encodeURIComponent(value));
38
40
  const result = new Uint8Array(value.length);
39
41
  for (let i = 0; i < result.length; i++) {
@@ -29,6 +29,8 @@
29
29
 
30
30
  // deno-lint-ignore-file no-this-alias
31
31
 
32
+ import { FUNCTION_TYPE, UNDEFINED_VALUE } from "../constants.js";
33
+
32
34
  export {
33
35
  initShimAsyncCodec
34
36
  };
@@ -42,7 +44,7 @@ function initShimAsyncCodec(library, options = {}, registerDataHandler) {
42
44
 
43
45
  function objectHasOwn(object, propertyName) {
44
46
  // eslint-disable-next-line no-prototype-builtins
45
- return typeof Object.hasOwn === "function" ? Object.hasOwn(object, propertyName) : object.hasOwnProperty(propertyName);
47
+ return typeof Object.hasOwn === FUNCTION_TYPE ? Object.hasOwn(object, propertyName) : object.hasOwnProperty(propertyName);
46
48
  }
47
49
 
48
50
  function createCodecClass(constructor, constructorOptions, registerDataHandler) {
@@ -61,7 +63,7 @@ function createCodecClass(constructor, constructorOptions, registerDataHandler)
61
63
  codecAdapter.pendingData = new Uint8Array(data);
62
64
  }
63
65
  };
64
- if (objectHasOwn(options, "level") && options.level === undefined) {
66
+ if (objectHasOwn(options, "level") && options.level === UNDEFINED_VALUE) {
65
67
  delete options.level;
66
68
  }
67
69
  codecAdapter.codec = new constructor(Object.assign({}, constructorOptions, options));
@@ -26,12 +26,13 @@
26
26
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
27
  */
28
28
 
29
- /* global self, importScripts, addEventListener, postMessage, ReadableStream, WritableStream */
29
+ /* global self, importScripts, addEventListener, postMessage, ReadableStream, WritableStream, AbortController */
30
30
 
31
31
  import { UNDEFINED_VALUE } from "./constants.js";
32
32
  import { StreamAdapter } from "./streams/stream-adapter.js";
33
33
  import {
34
34
  CodecStream,
35
+ ChunkStream,
35
36
  MESSAGE_EVENT_TYPE,
36
37
  MESSAGE_START,
37
38
  MESSAGE_PULL,
@@ -43,7 +44,7 @@ import {
43
44
  const pendingPullMessages = new Map();
44
45
  const pendingDataMessages = new Map();
45
46
 
46
- let messageId = 0;
47
+ let abortController, messageId = 0, importScriptSupported = true;
47
48
 
48
49
  addEventListener(MESSAGE_EVENT_TYPE, ({ data }) => {
49
50
  const { type, messageId, value, done } = data;
@@ -61,6 +62,9 @@ addEventListener(MESSAGE_EVENT_TYPE, ({ data }) => {
61
62
  pendingDataMessages.delete(messageId);
62
63
  resolve();
63
64
  }
65
+ if (type == MESSAGE_CLOSE) {
66
+ abortController.abort();
67
+ }
64
68
  } catch (error) {
65
69
  sendErrorMessage(error);
66
70
  }
@@ -70,7 +74,16 @@ async function init(message) {
70
74
  try {
71
75
  const { options, scripts, config } = message;
72
76
  if (scripts && scripts.length) {
73
- importScripts.apply(UNDEFINED_VALUE, scripts);
77
+ try {
78
+ if (importScriptSupported) {
79
+ importScripts.apply(UNDEFINED_VALUE, scripts);
80
+ } else {
81
+ await imporModuleScripts(scripts);
82
+ }
83
+ } catch (error) {
84
+ importScriptSupported = false;
85
+ await imporModuleScripts(scripts);
86
+ }
74
87
  }
75
88
  if (self.initCodec) {
76
89
  self.initCodec();
@@ -83,7 +96,7 @@ async function init(message) {
83
96
  if (self.Inflate) {
84
97
  config.DecompressionStream = new StreamAdapter(self.Inflate);
85
98
  }
86
- const strategy = { highWaterMark: 1, size: () => config.chunkSize };
99
+ const strategy = { highWaterMark: 1 };
87
100
  const readable = message.readable || new ReadableStream({
88
101
  async pull(controller) {
89
102
  const result = new Promise(resolve => pendingPullMessages.set(messageId, resolve));
@@ -107,7 +120,12 @@ async function init(message) {
107
120
  }
108
121
  }, strategy);
109
122
  const codecStream = new CodecStream(options, config);
110
- await readable.pipeThrough(codecStream).pipeTo(writable, { preventClose: true, preventAbort: true });
123
+ abortController = new AbortController();
124
+ const { signal } = abortController;
125
+ await readable
126
+ .pipeThrough(codecStream)
127
+ .pipeThrough(new ChunkStream(config.chunkSize))
128
+ .pipeTo(writable, { signal, preventClose: true, preventAbort: true });
111
129
  try {
112
130
  await writable.getWriter().close();
113
131
  } catch (_error) {
@@ -115,13 +133,15 @@ async function init(message) {
115
133
  }
116
134
  const {
117
135
  signature,
118
- size
136
+ inputSize,
137
+ outputSize
119
138
  } = codecStream;
120
139
  sendMessage({
121
140
  type: MESSAGE_CLOSE,
122
141
  result: {
123
142
  signature,
124
- size
143
+ inputSize,
144
+ outputSize
125
145
  }
126
146
  });
127
147
  } catch (error) {
@@ -129,6 +149,12 @@ async function init(message) {
129
149
  }
130
150
  }
131
151
 
152
+ async function imporModuleScripts(scripts) {
153
+ for (const script of scripts) {
154
+ await import(script);
155
+ }
156
+ }
157
+
132
158
  function sendMessage(message) {
133
159
  let { value } = message;
134
160
  if (value) {
@@ -52,6 +52,7 @@ import {
52
52
  import {
53
53
  Entry
54
54
  } from "./zip-entry.js";
55
+ import { UNDEFINED_VALUE } from "./constants.js";
55
56
 
56
57
  class ZipEntry {
57
58
 
@@ -433,7 +434,7 @@ class ZipDirectoryEntry extends ZipEntry {
433
434
 
434
435
  async exportZip(writer, options) {
435
436
  const zipEntry = this;
436
- if (options.bufferedWrite === undefined) {
437
+ if (options.bufferedWrite === UNDEFINED_VALUE) {
437
438
  options.bufferedWrite = true;
438
439
  }
439
440
  await Promise.all([initReaders(zipEntry, options.readerOptions), initStream(writer)]);
@@ -372,7 +372,9 @@ class ZipEntry {
372
372
  const dataArray = await readUint8Array(reader, offset, 30, diskNumberStart);
373
373
  const dataView = getDataView(dataArray);
374
374
  let password = getOptionValue(zipEntry, options, "password");
375
+ let rawPassword = getOptionValue(zipEntry, options, "rawPassword");
375
376
  password = password && password.length && password;
377
+ rawPassword = rawPassword && rawPassword.length && rawPassword;
376
378
  if (extraFieldAES) {
377
379
  if (extraFieldAES.originalCompressionMethod != COMPRESSION_METHOD_AES) {
378
380
  throw new Error(ERR_UNSUPPORTED_COMPRESSION);
@@ -398,7 +400,7 @@ class ZipEntry {
398
400
  if (encrypted) {
399
401
  if (!zipCrypto && extraFieldAES.strength === UNDEFINED_VALUE) {
400
402
  throw new Error(ERR_UNSUPPORTED_ENCRYPTION);
401
- } else if (!password) {
403
+ } else if (!password && !rawPassword) {
402
404
  throw new Error(ERR_ENCRYPTED);
403
405
  }
404
406
  }
@@ -423,6 +425,7 @@ class ZipEntry {
423
425
  options: {
424
426
  codecType: CODEC_INFLATE,
425
427
  password,
428
+ rawPassword,
426
429
  zipCrypto,
427
430
  encryptionStrength: extraFieldAES && extraFieldAES.strength,
428
431
  signed: getOptionValue(zipEntry, options, "checkSignature"),
@@ -452,7 +455,7 @@ class ZipEntry {
452
455
  await writable.getWriter().close();
453
456
  }
454
457
  }
455
- return checkPasswordOnly ? undefined : writer.getData ? writer.getData() : writable;
458
+ return checkPasswordOnly ? UNDEFINED_VALUE : writer.getData ? writer.getData() : writable;
456
459
  }
457
460
  }
458
461