@zip.js/zip.js 2.5.3 → 2.5.7

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 (51) hide show
  1. package/dist/z-worker-fflate.js +1 -1
  2. package/dist/z-worker-pako.js +1 -1
  3. package/dist/z-worker.js +1 -1
  4. package/dist/zip-fs-full.js +470 -499
  5. package/dist/zip-fs-full.min.js +1 -1
  6. package/dist/zip-fs.js +470 -499
  7. package/dist/zip-fs.min.js +1 -1
  8. package/dist/zip-full.js +470 -499
  9. package/dist/zip-full.min.js +1 -1
  10. package/dist/zip-no-worker-deflate.min.js +1 -1
  11. package/dist/zip-no-worker-inflate.min.js +1 -1
  12. package/dist/zip-no-worker.min.js +1 -1
  13. package/dist/zip.js +470 -499
  14. package/dist/zip.min.js +1 -1
  15. package/index-fflate.js +1 -1
  16. package/index.d.ts +1 -1
  17. package/index.js +3 -3
  18. package/lib/core/{engine.js → codec-interface.js} +52 -50
  19. package/lib/core/{codecs/codec-pool-worker.js → codec-pool-worker.js} +55 -29
  20. package/lib/core/{codecs/codec-pool.js → codec-pool.js} +28 -9
  21. package/lib/core/configuration.js +10 -1
  22. package/lib/core/io.js +102 -100
  23. package/lib/core/{codecs → streams}/aes-crypto-stream.js +68 -54
  24. package/lib/core/{codecs → streams}/codec-stream.js +6 -6
  25. package/lib/core/{codecs → streams/codecs}/crc32.js +0 -0
  26. package/lib/core/{codecs → streams/codecs}/deflate.js +0 -0
  27. package/lib/core/{codecs → streams/codecs}/inflate.js +0 -0
  28. package/lib/core/{codecs → streams/codecs}/sjcl.js +0 -0
  29. package/lib/core/{codecs → streams}/crc32-stream.js +3 -4
  30. package/lib/core/{codecs → streams}/zip-crypto-stream.js +28 -32
  31. package/lib/core/streams/zip-entry-stream.js +185 -0
  32. package/lib/core/z-worker-core.js +30 -15
  33. package/lib/core/zip-fs-core.js +1 -1
  34. package/lib/core/zip-reader.js +21 -12
  35. package/lib/core/zip-writer.js +33 -25
  36. package/lib/z-worker-fflate.js +4 -1
  37. package/lib/z-worker-inline.js +1 -1
  38. package/lib/z-worker.js +2 -2
  39. package/lib/zip-fflate-shim.js +4 -1
  40. package/lib/zip-fs.js +6 -2
  41. package/lib/zip-full-fflate.js +6 -3
  42. package/lib/zip-full.js +8 -5
  43. package/lib/zip-no-worker-deflate.js +7 -3
  44. package/lib/zip-no-worker-fflate-deflate.js +6 -2
  45. package/lib/zip-no-worker-fflate-inflate.js +6 -3
  46. package/lib/zip-no-worker-fflate.js +6 -3
  47. package/lib/zip-no-worker-inflate.js +7 -4
  48. package/lib/zip-no-worker.js +8 -5
  49. package/lib/zip.js +6 -3
  50. package/package.json +2 -8
  51. package/lib/core/codecs/codec.js +0 -246
@@ -29,12 +29,12 @@
29
29
  /* global crypto, TransformStream */
30
30
  // deno-lint-ignore-file no-this-alias
31
31
 
32
- import Crc32 from "./crc32.js";
32
+ import Crc32 from "./codecs/crc32.js";
33
33
  import { ERR_INVALID_PASSWORD } from "./aes-crypto-stream.js";
34
34
 
35
35
  const HEADER_LENGTH = 12;
36
36
 
37
- class ZipCryptoDecryptStream extends TransformStream {
37
+ class ZipCryptoDecryptionStream extends TransformStream {
38
38
 
39
39
  constructor(password, passwordVerification) {
40
40
  let stream;
@@ -47,18 +47,16 @@ class ZipCryptoDecryptStream extends TransformStream {
47
47
  createKeys(this, password);
48
48
  },
49
49
  transform(chunk, controller) {
50
- if (chunk && chunk.length) {
51
- const zipCrypto = this;
52
- if (zipCrypto.password) {
53
- const decryptedHeader = decrypt(zipCrypto, chunk.subarray(0, HEADER_LENGTH));
54
- zipCrypto.password = null;
55
- if (decryptedHeader[HEADER_LENGTH - 1] != zipCrypto.passwordVerification) {
56
- throw new Error(ERR_INVALID_PASSWORD);
57
- }
58
- chunk = chunk.subarray(HEADER_LENGTH);
50
+ const zipCrypto = this;
51
+ if (zipCrypto.password) {
52
+ const decryptedHeader = decrypt(zipCrypto, chunk.subarray(0, HEADER_LENGTH));
53
+ zipCrypto.password = null;
54
+ if (decryptedHeader[HEADER_LENGTH - 1] != zipCrypto.passwordVerification) {
55
+ throw new Error(ERR_INVALID_PASSWORD);
59
56
  }
60
- controller.enqueue(decrypt(zipCrypto, chunk));
57
+ chunk = chunk.subarray(HEADER_LENGTH);
61
58
  }
59
+ controller.enqueue(decrypt(zipCrypto, chunk));
62
60
  },
63
61
  flush() {
64
62
  stream.valid = true;
@@ -68,7 +66,7 @@ class ZipCryptoDecryptStream extends TransformStream {
68
66
  }
69
67
  }
70
68
 
71
- class ZipCryptoEncryptStream extends TransformStream {
69
+ class ZipCryptoEncryptionStream extends TransformStream {
72
70
 
73
71
  constructor(password, passwordVerification) {
74
72
  super({
@@ -80,24 +78,22 @@ class ZipCryptoEncryptStream extends TransformStream {
80
78
  createKeys(this, password);
81
79
  },
82
80
  transform(chunk, controller) {
83
- if (chunk && chunk.length) {
84
- const zipCrypto = this;
85
- let output;
86
- let offset;
87
- if (zipCrypto.password) {
88
- zipCrypto.password = null;
89
- const header = crypto.getRandomValues(new Uint8Array(HEADER_LENGTH));
90
- header[HEADER_LENGTH - 1] = zipCrypto.passwordVerification;
91
- output = new Uint8Array(chunk.length + header.length);
92
- output.set(encrypt(zipCrypto, header), 0);
93
- offset = HEADER_LENGTH;
94
- } else {
95
- output = new Uint8Array(chunk.length);
96
- offset = 0;
97
- }
98
- output.set(encrypt(zipCrypto, chunk), offset);
99
- controller.enqueue(output);
81
+ const zipCrypto = this;
82
+ let output;
83
+ let offset;
84
+ if (zipCrypto.password) {
85
+ zipCrypto.password = null;
86
+ const header = crypto.getRandomValues(new Uint8Array(HEADER_LENGTH));
87
+ header[HEADER_LENGTH - 1] = zipCrypto.passwordVerification;
88
+ output = new Uint8Array(chunk.length + header.length);
89
+ output.set(encrypt(zipCrypto, header), 0);
90
+ offset = HEADER_LENGTH;
91
+ } else {
92
+ output = new Uint8Array(chunk.length);
93
+ offset = 0;
100
94
  }
95
+ output.set(encrypt(zipCrypto, chunk), offset);
96
+ controller.enqueue(output);
101
97
  },
102
98
  flush() {
103
99
  }
@@ -106,8 +102,8 @@ class ZipCryptoEncryptStream extends TransformStream {
106
102
  }
107
103
 
108
104
  export {
109
- ZipCryptoDecryptStream,
110
- ZipCryptoEncryptStream,
105
+ ZipCryptoDecryptionStream,
106
+ ZipCryptoEncryptionStream,
111
107
  ERR_INVALID_PASSWORD
112
108
  };
113
109
 
@@ -0,0 +1,185 @@
1
+ /*
2
+ Copyright (c) 2022 Gildas Lormeau. All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ 2. Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in
12
+ the documentation and/or other materials provided with the distribution.
13
+
14
+ 3. The names of the authors may not be used to endorse or promote products
15
+ derived from this software without specific prior written permission.
16
+
17
+ THIS SOFTWARE IS PROVIDED ''AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
18
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
20
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
21
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ */
28
+
29
+ /* global CompressionStream, DecompressionStream, TransformStream */
30
+
31
+ import Crc32Stream from "./crc32-stream.js";
32
+ import {
33
+ AESEncryptionStream,
34
+ AESDecryptionStream
35
+ } from "./aes-crypto-stream.js";
36
+ import {
37
+ ZipCryptoEncryptionStream,
38
+ ZipCryptoDecryptionStream,
39
+ ERR_INVALID_PASSWORD
40
+ } from "./zip-crypto-stream.js";
41
+ import CodecStream from "./codec-stream.js";
42
+
43
+ const ERR_INVALID_SIGNATURE = "Invalid signature";
44
+ const COMPRESSION_FORMAT = "deflate-raw";
45
+ const UNDEFINED_TYPE = "undefined";
46
+ const COMPRESSION_STREAM_API_SUPPORTED = typeof CompressionStream == UNDEFINED_TYPE;
47
+ const DECOMPRESSION_STREAM_API_SUPPORTED = typeof DecompressionStream == UNDEFINED_TYPE;
48
+ let INFLATE_RAW_SUPPORTED = true;
49
+ let DEFLATE_RAW_SUPPORTED = true;
50
+
51
+ class DeflateStream extends TransformStream {
52
+
53
+ constructor(codecConstructor, options, { chunkSize }, ...strategies) {
54
+ super({}, ...strategies);
55
+ const { compressed, useCompressionStream, password, passwordVerification, encryptionStrength, zipCrypto, signed } = options;
56
+ const stream = this;
57
+ let crc32Stream, encryptionStream;
58
+ let readable = filterEmptyChunks(super.readable);
59
+ const encrypted = Boolean(password);
60
+ if ((!encrypted || zipCrypto) && signed) {
61
+ [readable, crc32Stream] = readable.tee();
62
+ crc32Stream = crc32Stream.pipeThrough(new Crc32Stream());
63
+ }
64
+ if (compressed) {
65
+ if ((useCompressionStream !== undefined && !useCompressionStream) || (COMPRESSION_STREAM_API_SUPPORTED && !DEFLATE_RAW_SUPPORTED)) {
66
+ readable = pipeCodecStream(codecConstructor, readable, chunkSize);
67
+ } else {
68
+ try {
69
+ const compressionStream = new CompressionStream(COMPRESSION_FORMAT);
70
+ readable = readable.pipeThrough(compressionStream);
71
+ } catch (_error) {
72
+ DEFLATE_RAW_SUPPORTED = false;
73
+ readable = pipeCodecStream(codecConstructor, readable, chunkSize);
74
+ }
75
+ }
76
+ }
77
+ if (encrypted) {
78
+ if (zipCrypto) {
79
+ readable = readable.pipeThrough(new ZipCryptoEncryptionStream(password, passwordVerification));
80
+ } else {
81
+ encryptionStream = new AESEncryptionStream(password, encryptionStrength);
82
+ readable = readable.pipeThrough(encryptionStream);
83
+ }
84
+ }
85
+ setReadable(stream, readable, async () => {
86
+ let signature;
87
+ if (encrypted && !zipCrypto) {
88
+ signature = encryptionStream.signature;
89
+ }
90
+ if ((!encrypted || zipCrypto) && signed) {
91
+ signature = await crc32Stream.getReader().read();
92
+ signature = new DataView(signature.value.buffer).getUint32(0);
93
+ }
94
+ stream.signature = signature;
95
+ });
96
+ }
97
+ }
98
+
99
+ class InflateStream extends TransformStream {
100
+
101
+ constructor(codecConstructor, options, { chunkSize }, ...strategies) {
102
+ super({}, ...strategies);
103
+ const { zipCrypto, password, passwordVerification, signed, encryptionStrength, compressed, useCompressionStream } = options;
104
+ const stream = this;
105
+ let crc32Stream, decryptionStream;
106
+ let readable = filterEmptyChunks(super.readable);
107
+ const encrypted = Boolean(password);
108
+ if (encrypted) {
109
+ if (zipCrypto) {
110
+ readable = readable.pipeThrough(new ZipCryptoDecryptionStream(password, passwordVerification));
111
+ } else {
112
+ decryptionStream = new AESDecryptionStream(password, signed, encryptionStrength);
113
+ readable = readable.pipeThrough(decryptionStream);
114
+ }
115
+ }
116
+ if (compressed) {
117
+ if ((useCompressionStream !== undefined && !useCompressionStream) || (DECOMPRESSION_STREAM_API_SUPPORTED && !INFLATE_RAW_SUPPORTED)) {
118
+ readable = pipeCodecStream(codecConstructor, readable, chunkSize);
119
+ } else {
120
+ try {
121
+ readable = readable.pipeThrough(new DecompressionStream(COMPRESSION_FORMAT));
122
+ } catch (_error) {
123
+ INFLATE_RAW_SUPPORTED = false;
124
+ readable = pipeCodecStream(codecConstructor, readable, chunkSize);
125
+ }
126
+ }
127
+ }
128
+ if ((!encrypted || zipCrypto) && signed) {
129
+ [readable, crc32Stream] = readable.tee();
130
+ crc32Stream = crc32Stream.pipeThrough(new Crc32Stream());
131
+ }
132
+ setReadable(stream, readable, async () => {
133
+ if (encrypted && !zipCrypto) {
134
+ if (!decryptionStream.valid) {
135
+ throw new Error(ERR_INVALID_SIGNATURE);
136
+ }
137
+ }
138
+ if ((!encrypted || zipCrypto) && signed) {
139
+ const signature = await crc32Stream.getReader().read();
140
+ const dataViewSignature = new DataView(signature.value.buffer);
141
+ if (signature != dataViewSignature.getUint32(0, false)) {
142
+ throw new Error(ERR_INVALID_SIGNATURE);
143
+ }
144
+ }
145
+ });
146
+ }
147
+ }
148
+
149
+ export {
150
+ DeflateStream,
151
+ InflateStream,
152
+ ERR_INVALID_PASSWORD,
153
+ ERR_INVALID_SIGNATURE
154
+ };
155
+
156
+ function pipeCodecStream(codecConstructor, stream, chunkSize) {
157
+ return stream.pipeThrough(new CodecStream(codecConstructor, { chunkSize }));
158
+ }
159
+
160
+ function filterEmptyChunks(readable) {
161
+ return readable.pipeThrough(new TransformStream({
162
+ transform(chunk, controller) {
163
+ if (chunk && chunk.length) {
164
+ controller.enqueue(chunk);
165
+ }
166
+ }
167
+ }));
168
+ }
169
+
170
+ function setReadable(stream, readable, flush) {
171
+ stream.length = 0;
172
+ readable = readable.pipeThrough(new TransformStream({
173
+ transform(chunk, controller) {
174
+ if (chunk && chunk.length) {
175
+ stream.length += chunk.length;
176
+ controller.enqueue(chunk);
177
+ }
178
+ }, flush
179
+ }));
180
+ Object.defineProperty(stream, "readable", {
181
+ get() {
182
+ return readable;
183
+ }
184
+ });
185
+ }
@@ -26,7 +26,7 @@
26
26
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
27
  */
28
28
 
29
- /* global self, importScripts, addEventListener, postMessage */
29
+ /* global self, importScripts, addEventListener, postMessage, ReadableStream, WritableStream */
30
30
 
31
31
  import {
32
32
  createCodec,
@@ -37,7 +37,8 @@ import {
37
37
  MESSAGE_PULL,
38
38
  MESSAGE_DATA,
39
39
  MESSAGE_ABORT,
40
- } from "./codecs/codec.js";
40
+ MESSAGE_CLOSE
41
+ } from "./codec-interface.js";
41
42
 
42
43
  const pendingMessages = new Map();
43
44
  let codec;
@@ -78,16 +79,30 @@ async function init(message) {
78
79
  } else if (options.codecType.startsWith(CODEC_INFLATE)) {
79
80
  codecConstructor = self.Inflate;
80
81
  }
81
- codec = createCodec(codecConstructor, options, message.config);
82
- codec.ondata = data => sendMessage({ type: MESSAGE_DATA, data });
83
- codec.onerror = error => postMessage({ error: { message: error.message, stack: error.stack } });
84
- codec.pull = () => {
85
- const result = new Promise((resolve, reject) => pendingMessages.set(messageId, { resolve, reject }));
86
- sendMessage({ type: MESSAGE_PULL, messageId });
87
- messageId++;
88
- return result;
89
- };
90
- await codec.start();
82
+ const readable = new ReadableStream({
83
+ async pull(controller) {
84
+ let result = new Promise((resolve, reject) => pendingMessages.set(messageId, { resolve, reject }));
85
+ sendMessage({ type: MESSAGE_PULL, messageId });
86
+ messageId++;
87
+ const { value, done } = await result;
88
+ // debugger;
89
+ controller.enqueue(value);
90
+ if (done) {
91
+ controller.close();
92
+ }
93
+ }
94
+ }, {
95
+ highWaterMark: 1
96
+ });
97
+ const writable = new WritableStream({
98
+ write(data) {
99
+ sendMessage({ type: MESSAGE_DATA, data });
100
+ }
101
+ });
102
+ codec = createCodec(codecConstructor, readable, writable, options, message.config);
103
+ const result = await codec.run();
104
+ sendMessage({ type: MESSAGE_CLOSE, result });
105
+
91
106
  } catch (error) {
92
107
  postMessage({ error: { message: error.message, stack: error.stack } });
93
108
  }
@@ -95,11 +110,11 @@ async function init(message) {
95
110
 
96
111
  function sendMessage(message) {
97
112
  if (message.data) {
98
- const data = message.data.value.data;
113
+ const data = message.data;
99
114
  if (data && data.length) {
100
115
  try {
101
- message.data.value.data = data.buffer;
102
- postMessage(message, [message.data.value.data]);
116
+ message.data = data.buffer;
117
+ postMessage(message, [message.data]);
103
118
  } catch (_error) {
104
119
  postMessage(message);
105
120
  }
@@ -26,7 +26,6 @@
26
26
  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
27
  */
28
28
 
29
- export { ERR_ABORT } from "./engine.js";
30
29
  import {
31
30
  Reader,
32
31
  TextReader,
@@ -419,6 +418,7 @@ class FS {
419
418
  }
420
419
 
421
420
  const fs = { FS, ZipDirectoryEntry, ZipFileEntry };
421
+ export { ERR_ABORT } from "./codec-pool.js";
422
422
  export { fs };
423
423
 
424
424
  function getTotalSize(entries, propertyName) {
@@ -56,11 +56,18 @@ import {
56
56
  FILE_ATTR_MSDOS_DIR_MASK,
57
57
  DIRECTORY_SIGNATURE
58
58
  } from "./constants.js";
59
- import { getConfiguration } from "./configuration.js";
60
- import { createCodec, CODEC_INFLATE, ERR_INVALID_SIGNATURE, ERR_INVALID_PASSWORD } from "./codecs/codec-pool.js";
59
+ import {
60
+ getConfiguration,
61
+ getChunkSize
62
+ } from "./configuration.js";
63
+ import {
64
+ runCodec,
65
+ CODEC_INFLATE,
66
+ ERR_INVALID_SIGNATURE,
67
+ ERR_INVALID_PASSWORD
68
+ } from "./codec-pool.js";
61
69
  import decodeText from "./util/decode-text.js";
62
- import Crc32 from "./codecs/crc32.js";
63
- import { processData } from "./engine.js";
70
+ import Crc32 from "./streams/codecs/crc32.js";
64
71
  import Entry from "./zip-entry.js";
65
72
 
66
73
  const ERR_BAD_FORMAT = "File format is not recognized";
@@ -292,7 +299,15 @@ class ZipEntry {
292
299
  throw new Error(ERR_ENCRYPTED);
293
300
  }
294
301
  }
295
- const codec = await createCodec(config.Inflate, {
302
+ const dataOffset = offset + 30 + localDirectory.filenameLength + localDirectory.extraFieldLength;
303
+ const size = () => compressedSize;
304
+ const readable = reader.getStream({ offset: dataOffset, size, chunkSize: getChunkSize(config) });
305
+ const writable = writer.getStream();
306
+ const signal = getOptionValue(zipEntry, options, "signal");
307
+ if (!writer.initialized) {
308
+ await writer.init();
309
+ }
310
+ await runCodec(config.Inflate, readable, writable, {
296
311
  codecType: CODEC_INFLATE,
297
312
  password,
298
313
  zipCrypto,
@@ -304,13 +319,7 @@ class ZipEntry {
304
319
  encrypted,
305
320
  useWebWorkers: getOptionValue(zipEntry, options, "useWebWorkers"),
306
321
  useCompressionStream: getOptionValue(zipEntry, options, "useCompressionStream")
307
- }, config);
308
- if (!writer.initialized) {
309
- await writer.init();
310
- }
311
- const signal = getOptionValue(zipEntry, options, "signal");
312
- const dataOffset = offset + 30 + localDirectory.filenameLength + localDirectory.extraFieldLength;
313
- await processData(codec, reader, writer, dataOffset, () => compressedSize, config, { onprogress: options.onprogress, signal });
322
+ }, config, { signal, onprogress: options.onprogress, size });
314
323
  return writer.getData();
315
324
  }
316
325
  }
@@ -59,11 +59,16 @@ import {
59
59
  MIN_DATE,
60
60
  MAX_DATE
61
61
  } from "./constants.js";
62
- import { getConfiguration } from "./configuration.js";
63
- import { CODEC_DEFLATE, createCodec } from "./codecs/codec-pool.js";
62
+ import {
63
+ getConfiguration,
64
+ getChunkSize
65
+ } from "./configuration.js";
66
+ import {
67
+ CODEC_DEFLATE,
68
+ runCodec
69
+ } from "./codec-pool.js";
64
70
  import encodeText from "./util/encode-text.js";
65
71
  import { BlobWriter } from "./io.js";
66
- import { processData } from "./engine.js";
67
72
  import Entry from "./zip-entry.js";
68
73
 
69
74
  const ERR_DUPLICATED_NAME = "File already exists";
@@ -204,9 +209,6 @@ async function addFile(zipWriter, name, reader, options) {
204
209
  }
205
210
  let maximumCompressedSize = 0;
206
211
  let keepOrder = getOptionValue(zipWriter, options, "keepOrder");
207
- if (keepOrder === undefined) {
208
- keepOrder = true;
209
- }
210
212
  let uncompressedSize = 0;
211
213
  let msDosCompatible = getOptionValue(zipWriter, options, "msDosCompatible");
212
214
  if (msDosCompatible === undefined) {
@@ -280,8 +282,8 @@ async function addFile(zipWriter, name, reader, options) {
280
282
  }
281
283
 
282
284
  async function getFileEntry(zipWriter, name, reader, options) {
283
- const files = zipWriter.files;
284
- const writer = zipWriter.writer;
285
+ const { files, writer } = zipWriter;
286
+ const streamWriter = writer.getStream().getWriter();
285
287
  const previousFileEntry = Array.from(files.values()).pop();
286
288
  let fileEntry = {};
287
289
  let bufferedWrite;
@@ -307,7 +309,7 @@ async function getFileEntry(zipWriter, name, reader, options) {
307
309
  }
308
310
  fileWriter = writer;
309
311
  }
310
- fileEntry = await createFileEntry(reader, fileWriter, zipWriter.config, options);
312
+ fileEntry = await createFileEntry(reader, fileWriter.getStream(), fileWriter.getStream().getWriter(), zipWriter.config, options);
311
313
  fileEntry.lock = lockCurrentFileEntry;
312
314
  files.set(name, fileEntry);
313
315
  fileEntry.filename = name;
@@ -337,10 +339,10 @@ async function getFileEntry(zipWriter, name, reader, options) {
337
339
  setUint32(arrayBufferView, 18, fileEntry.compressedSize);
338
340
  setUint32(arrayBufferView, 22, fileEntry.uncompressedSize);
339
341
  }
340
- await writer.writeUint8Array(new Uint8Array(arrayBuffer));
342
+ await writeUint8Array(streamWriter, new Uint8Array(arrayBuffer));
341
343
  indexWrittenData = headerLength;
342
344
  }
343
- await writeBlob(writer, blob, indexWrittenData);
345
+ await writeBlob(streamWriter, blob, indexWrittenData);
344
346
  delete fileEntry.writingBufferedData;
345
347
  }
346
348
  fileEntry.offset = zipWriter.offset;
@@ -369,7 +371,7 @@ async function getFileEntry(zipWriter, name, reader, options) {
369
371
  }
370
372
  }
371
373
 
372
- async function createFileEntry(reader, writer, config, options) {
374
+ async function createFileEntry(reader, writable, streamWriter, config, options) {
373
375
  const {
374
376
  rawFilename,
375
377
  lastAccessDate,
@@ -516,7 +518,11 @@ async function createFileEntry(reader, writer, config, options) {
516
518
  let result;
517
519
  let compressedSize = 0;
518
520
  if (reader) {
519
- const codec = await createCodec(config.Deflate, {
521
+ await writeUint8Array(streamWriter, localHeaderArray);
522
+ fileEntry.dataWritten = true;
523
+ const size = () => reader.size;
524
+ const readable = reader.getStream({ offset: 0, size, chunkSize: getChunkSize(config) });
525
+ result = await runCodec(config.Deflate, readable, writable, {
520
526
  codecType: CODEC_DEFLATE,
521
527
  level,
522
528
  password,
@@ -528,14 +534,11 @@ async function createFileEntry(reader, writer, config, options) {
528
534
  encrypted,
529
535
  useWebWorkers,
530
536
  useCompressionStream
531
- }, config);
532
- await writer.writeUint8Array(localHeaderArray);
533
- fileEntry.dataWritten = true;
534
- result = await processData(codec, reader, writer, 0, () => reader.size, config, { onprogress, signal });
537
+ }, config, { signal, onprogress, size });
535
538
  uncompressedSize = fileEntry.uncompressedSize = reader.size;
536
539
  compressedSize = result.length;
537
540
  } else {
538
- await writer.writeUint8Array(localHeaderArray);
541
+ await writeUint8Array(streamWriter, localHeaderArray);
539
542
  fileEntry.dataWritten = true;
540
543
  }
541
544
  let dataDescriptorArray = new Uint8Array(0);
@@ -579,7 +582,7 @@ async function createFileEntry(reader, writer, config, options) {
579
582
  }
580
583
  }
581
584
  if (dataDescriptor) {
582
- await writer.writeUint8Array(dataDescriptorArray);
585
+ await writeUint8Array(streamWriter, dataDescriptorArray);
583
586
  }
584
587
  const length = localHeaderArray.length + compressedSize + dataDescriptorArray.length;
585
588
  Object.assign(fileEntry, { compressedSize, lastModDate, rawLastModDate, creationDate, lastAccessDate, encrypted, length });
@@ -587,8 +590,8 @@ async function createFileEntry(reader, writer, config, options) {
587
590
  }
588
591
 
589
592
  async function closeFile(zipWriter, comment, options) {
590
- const writer = zipWriter.writer;
591
- const files = zipWriter.files;
593
+ const { files } = zipWriter;
594
+ const streamWriter = zipWriter.writer.getStream().getWriter();
592
595
  let offset = 0;
593
596
  let directoryDataLength = 0;
594
597
  let directoryOffset = zipWriter.offset;
@@ -703,9 +706,9 @@ async function closeFile(zipWriter, comment, options) {
703
706
  setUint16(directoryView, offset + 10, filesLength);
704
707
  setUint32(directoryView, offset + 12, directoryDataLength);
705
708
  setUint32(directoryView, offset + 16, directoryOffset);
706
- await writer.writeUint8Array(directoryArray);
709
+ await writeUint8Array(streamWriter, directoryArray);
707
710
  if (comment && comment.length) {
708
- await writer.writeUint8Array(comment);
711
+ await writeUint8Array(streamWriter, comment);
709
712
  }
710
713
  }
711
714
 
@@ -726,20 +729,25 @@ function sliceAsArrayBuffer(blob, start, end) {
726
729
  }
727
730
  }
728
731
 
729
- async function writeBlob(writer, blob, start = 0) {
732
+ async function writeBlob(streamWriter, blob, start = 0) {
730
733
  const blockSize = 512 * 1024 * 1024;
731
734
  await writeSlice();
732
735
 
733
736
  async function writeSlice() {
734
737
  if (start < blob.size) {
735
738
  const arrayBuffer = await sliceAsArrayBuffer(blob, start, start + blockSize);
736
- await writer.writeUint8Array(new Uint8Array(arrayBuffer));
739
+ await writeUint8Array(streamWriter, new Uint8Array(arrayBuffer));
737
740
  start += blockSize;
738
741
  await writeSlice();
739
742
  }
740
743
  }
741
744
  }
742
745
 
746
+ async function writeUint8Array(streamWriter, array) {
747
+ await streamWriter.ready;
748
+ await streamWriter.write(array);
749
+ }
750
+
743
751
  function getTimeNTFS(date) {
744
752
  if (date) {
745
753
  return ((BigInt(date.getTime()) + BigInt(11644473600000)) * BigInt(10000));
@@ -29,7 +29,10 @@
29
29
  /* global self */
30
30
 
31
31
  import "./core/z-worker-core.js";
32
- import { Deflate, Inflate } from "./zip-fflate-shim.js";
32
+ import {
33
+ Deflate,
34
+ Inflate
35
+ } from "./zip-fflate-shim.js";
33
36
 
34
37
  self.initCodec = () => {
35
38
  self.Deflate = Deflate;