@zip.js/zip.js 2.5.3 → 2.5.4
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.
- package/dist/z-worker-fflate.js +1 -1
- package/dist/z-worker-pako.js +1 -1
- package/dist/z-worker.js +1 -1
- package/dist/zip-fs-full.js +227 -182
- package/dist/zip-fs-full.min.js +1 -1
- package/dist/zip-fs.js +227 -182
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-full.js +227 -182
- package/dist/zip-full.min.js +1 -1
- package/dist/zip-no-worker-deflate.min.js +1 -1
- package/dist/zip-no-worker-inflate.min.js +1 -1
- package/dist/zip-no-worker.min.js +1 -1
- package/dist/zip.js +227 -182
- package/dist/zip.min.js +1 -1
- package/index.d.ts +1 -1
- package/lib/core/codecs/aes-crypto-stream.js +35 -23
- package/lib/core/codecs/codec-stream.js +2 -2
- package/lib/core/codecs/codec.js +28 -28
- package/lib/core/codecs/crc32-stream.js +1 -1
- package/lib/core/codecs/zip-crypto-stream.js +4 -4
- package/lib/core/configuration.js +7 -1
- package/lib/core/engine.js +10 -14
- package/lib/core/io.js +113 -98
- package/lib/core/zip-reader.js +8 -2
- package/lib/core/zip-writer.js +28 -17
- package/lib/z-worker-inline.js +1 -1
- package/package.json +1 -1
|
@@ -45,14 +45,19 @@ const SALT_LENGTH = [8, 12, 16];
|
|
|
45
45
|
const KEY_LENGTH = [16, 24, 32];
|
|
46
46
|
const SIGNATURE_LENGTH = 10;
|
|
47
47
|
const COUNTER_DEFAULT_VALUE = [0, 0, 0, 0];
|
|
48
|
-
const
|
|
49
|
-
const
|
|
48
|
+
const UNDEFINED_TYPE = "undefined";
|
|
49
|
+
const FUNCTION_TYPE = "function";
|
|
50
|
+
const CRYPTO_API_SUPPORTED = typeof crypto != UNDEFINED_TYPE;
|
|
51
|
+
const SUBTLE_API_SUPPORTED = CRYPTO_API_SUPPORTED && typeof crypto.subtle != UNDEFINED_TYPE;
|
|
52
|
+
const GET_RANDOM_VALUES_SUPPORTED = CRYPTO_API_SUPPORTED && typeof crypto.getRandomValues == FUNCTION_TYPE;
|
|
53
|
+
const IMPORT_KEY_SUPPORTED = CRYPTO_API_SUPPORTED && SUBTLE_API_SUPPORTED && typeof crypto.subtle.importKey == FUNCTION_TYPE;
|
|
54
|
+
const DERIVE_BITS_SUPPORTED = CRYPTO_API_SUPPORTED && SUBTLE_API_SUPPORTED && typeof crypto.subtle.deriveBits == FUNCTION_TYPE;
|
|
50
55
|
const codecBytes = codec.bytes;
|
|
51
56
|
const Aes = cipher.aes;
|
|
52
57
|
const CtrGladman = mode.ctrGladman;
|
|
53
58
|
const HmacSha1 = misc.hmacSha1;
|
|
54
59
|
|
|
55
|
-
class
|
|
60
|
+
class AESDecryptionStream extends TransformStream {
|
|
56
61
|
|
|
57
62
|
constructor(password, signed, strength) {
|
|
58
63
|
let stream;
|
|
@@ -74,7 +79,7 @@ class AESDecryptStream extends TransformStream {
|
|
|
74
79
|
aesCrypto.password = null;
|
|
75
80
|
const preamble = subarray(chunk, 0, SALT_LENGTH[aesCrypto.strength] + 2);
|
|
76
81
|
await createDecryptionKeys(aesCrypto, preamble, password);
|
|
77
|
-
aesCrypto.
|
|
82
|
+
aesCrypto.ctr = new CtrGladman(new Aes(aesCrypto.keys.key), Array.from(COUNTER_DEFAULT_VALUE));
|
|
78
83
|
aesCrypto.hmac = new HmacSha1(aesCrypto.keys.authentication);
|
|
79
84
|
chunk = subarray(chunk, SALT_LENGTH[aesCrypto.strength] + 2);
|
|
80
85
|
aesCrypto.resolveReady();
|
|
@@ -93,14 +98,14 @@ class AESDecryptStream extends TransformStream {
|
|
|
93
98
|
const originalSignature = subarray(pending, pending.length - SIGNATURE_LENGTH);
|
|
94
99
|
let decryptedChunkArray = new Uint8Array(0);
|
|
95
100
|
if (chunkToDecrypt.length) {
|
|
96
|
-
const encryptedChunk =
|
|
101
|
+
const encryptedChunk = toBits(codecBytes, chunkToDecrypt);
|
|
97
102
|
aesCrypto.hmac.update(encryptedChunk);
|
|
98
|
-
const decryptedChunk = aesCrypto.
|
|
99
|
-
decryptedChunkArray =
|
|
103
|
+
const decryptedChunk = aesCrypto.ctr.update(encryptedChunk);
|
|
104
|
+
decryptedChunkArray = fromBits(codecBytes, decryptedChunk);
|
|
100
105
|
}
|
|
101
106
|
stream.valid = true;
|
|
102
107
|
if (aesCrypto.signed) {
|
|
103
|
-
const signature = subarray(
|
|
108
|
+
const signature = subarray(fromBits(codecBytes, aesCrypto.hmac.digest()), 0, SIGNATURE_LENGTH);
|
|
104
109
|
for (let indexSignature = 0; indexSignature < SIGNATURE_LENGTH; indexSignature++) {
|
|
105
110
|
if (signature[indexSignature] != originalSignature[indexSignature]) {
|
|
106
111
|
stream.valid = false;
|
|
@@ -114,7 +119,7 @@ class AESDecryptStream extends TransformStream {
|
|
|
114
119
|
}
|
|
115
120
|
}
|
|
116
121
|
|
|
117
|
-
class
|
|
122
|
+
class AESEncryptionStream extends TransformStream {
|
|
118
123
|
|
|
119
124
|
constructor(password, strength) {
|
|
120
125
|
let stream;
|
|
@@ -135,7 +140,7 @@ class AESEncryptStream extends TransformStream {
|
|
|
135
140
|
const password = aesCrypto.password;
|
|
136
141
|
aesCrypto.password = null;
|
|
137
142
|
preamble = await createEncryptionKeys(aesCrypto, password);
|
|
138
|
-
aesCrypto.
|
|
143
|
+
aesCrypto.ctr = new CtrGladman(new Aes(aesCrypto.keys.key), Array.from(COUNTER_DEFAULT_VALUE));
|
|
139
144
|
aesCrypto.hmac = new HmacSha1(aesCrypto.keys.authentication);
|
|
140
145
|
aesCrypto.resolveReady();
|
|
141
146
|
} else {
|
|
@@ -151,11 +156,11 @@ class AESEncryptStream extends TransformStream {
|
|
|
151
156
|
await aesCrypto.ready;
|
|
152
157
|
let encryptedChunkArray = new Uint8Array(0);
|
|
153
158
|
if (aesCrypto.pending.length) {
|
|
154
|
-
const encryptedChunk = aesCrypto.
|
|
159
|
+
const encryptedChunk = aesCrypto.ctr.update(toBits(codecBytes, aesCrypto.pending));
|
|
155
160
|
aesCrypto.hmac.update(encryptedChunk);
|
|
156
|
-
encryptedChunkArray =
|
|
161
|
+
encryptedChunkArray = fromBits(codecBytes, encryptedChunk);
|
|
157
162
|
}
|
|
158
|
-
stream.signature =
|
|
163
|
+
stream.signature = fromBits(codecBytes, aesCrypto.hmac.digest()).slice(0, SIGNATURE_LENGTH);
|
|
159
164
|
controller.enqueue(concat(encryptedChunkArray, stream.signature));
|
|
160
165
|
}
|
|
161
166
|
});
|
|
@@ -164,8 +169,8 @@ class AESEncryptStream extends TransformStream {
|
|
|
164
169
|
}
|
|
165
170
|
|
|
166
171
|
export {
|
|
167
|
-
|
|
168
|
-
|
|
172
|
+
AESDecryptionStream,
|
|
173
|
+
AESEncryptionStream,
|
|
169
174
|
ERR_INVALID_PASSWORD
|
|
170
175
|
};
|
|
171
176
|
|
|
@@ -177,15 +182,15 @@ function append(aesCrypto, input, output, paddingStart, paddingEnd, verifySignat
|
|
|
177
182
|
}
|
|
178
183
|
let offset;
|
|
179
184
|
for (offset = 0; offset <= inputLength - BLOCK_LENGTH; offset += BLOCK_LENGTH) {
|
|
180
|
-
const inputChunk =
|
|
185
|
+
const inputChunk = toBits(codecBytes, subarray(input, offset, offset + BLOCK_LENGTH));
|
|
181
186
|
if (verifySignature) {
|
|
182
187
|
aesCrypto.hmac.update(inputChunk);
|
|
183
188
|
}
|
|
184
|
-
const outputChunk = aesCrypto.
|
|
189
|
+
const outputChunk = aesCrypto.ctr.update(inputChunk);
|
|
185
190
|
if (!verifySignature) {
|
|
186
191
|
aesCrypto.hmac.update(outputChunk);
|
|
187
192
|
}
|
|
188
|
-
output.set(
|
|
193
|
+
output.set(fromBits(codecBytes, outputChunk), offset + paddingStart);
|
|
189
194
|
}
|
|
190
195
|
aesCrypto.pending = subarray(input, offset);
|
|
191
196
|
return output;
|
|
@@ -212,14 +217,14 @@ async function createKeys(target, password, salt) {
|
|
|
212
217
|
const derivedBits = await deriveBits(Object.assign({ salt }, DERIVED_BITS_ALGORITHM), basekey, 8 * ((KEY_LENGTH[target.strength] * 2) + 2));
|
|
213
218
|
const compositeKey = new Uint8Array(derivedBits);
|
|
214
219
|
target.keys = {
|
|
215
|
-
key:
|
|
216
|
-
authentication:
|
|
220
|
+
key: toBits(codecBytes, subarray(compositeKey, 0, KEY_LENGTH[target.strength])),
|
|
221
|
+
authentication: toBits(codecBytes, subarray(compositeKey, KEY_LENGTH[target.strength], KEY_LENGTH[target.strength] * 2)),
|
|
217
222
|
passwordVerification: subarray(compositeKey, KEY_LENGTH[target.strength] * 2)
|
|
218
223
|
};
|
|
219
224
|
}
|
|
220
225
|
|
|
221
226
|
function getRandomValues(array) {
|
|
222
|
-
if (
|
|
227
|
+
if (GET_RANDOM_VALUES_SUPPORTED) {
|
|
223
228
|
return crypto.getRandomValues(array);
|
|
224
229
|
} else {
|
|
225
230
|
return random.getRandomValues(array);
|
|
@@ -227,7 +232,7 @@ function getRandomValues(array) {
|
|
|
227
232
|
}
|
|
228
233
|
|
|
229
234
|
function importKey(format, password, algorithm, extractable, keyUsages) {
|
|
230
|
-
if (
|
|
235
|
+
if (IMPORT_KEY_SUPPORTED) {
|
|
231
236
|
return crypto.subtle.importKey(format, password, algorithm, extractable, keyUsages);
|
|
232
237
|
} else {
|
|
233
238
|
return misc.importKey(password);
|
|
@@ -235,7 +240,7 @@ function importKey(format, password, algorithm, extractable, keyUsages) {
|
|
|
235
240
|
}
|
|
236
241
|
|
|
237
242
|
async function deriveBits(algorithm, baseKey, length) {
|
|
238
|
-
if (
|
|
243
|
+
if (DERIVE_BITS_SUPPORTED) {
|
|
239
244
|
return await crypto.subtle.deriveBits(algorithm, baseKey, length);
|
|
240
245
|
} else {
|
|
241
246
|
return misc.pbkdf2(baseKey, algorithm.salt, DERIVED_BITS_ALGORITHM.iterations, length);
|
|
@@ -263,4 +268,11 @@ function expand(inputArray, length) {
|
|
|
263
268
|
|
|
264
269
|
function subarray(array, begin, end) {
|
|
265
270
|
return array.subarray(begin, end);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function fromBits(codecBytes, chunk) {
|
|
274
|
+
return codecBytes.fromBits(chunk);
|
|
275
|
+
}
|
|
276
|
+
function toBits(codecBytes, chunk) {
|
|
277
|
+
return codecBytes.toBits(chunk);
|
|
266
278
|
}
|
|
@@ -43,13 +43,13 @@ class CodecStream extends TransformStream {
|
|
|
43
43
|
},
|
|
44
44
|
transform(chunk, controller) {
|
|
45
45
|
chunk = this.codec.append(chunk);
|
|
46
|
-
if (chunk) {
|
|
46
|
+
if (chunk && chunk.length) {
|
|
47
47
|
controller.enqueue(chunk);
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
flush(controller) {
|
|
51
51
|
const chunk = this.codec.flush();
|
|
52
|
-
if (chunk) {
|
|
52
|
+
if (chunk && chunk.length) {
|
|
53
53
|
controller.enqueue(chunk);
|
|
54
54
|
}
|
|
55
55
|
}
|
package/lib/core/codecs/codec.js
CHANGED
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
// deno-lint-ignore-file no-this-alias
|
|
31
31
|
|
|
32
32
|
import Crc32Stream from "./crc32-stream.js";
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
33
|
+
import { AESEncryptionStream, AESDecryptionStream, ERR_INVALID_PASSWORD } from "./aes-crypto-stream.js";
|
|
34
|
+
import { ZipCryptoDecryptionStream, ZipCryptoEncryptionStream } from "./zip-crypto-stream.js";
|
|
35
35
|
import CodecStream from "./codec-stream.js";
|
|
36
36
|
|
|
37
37
|
const CODEC_DEFLATE = "deflate";
|
|
@@ -42,6 +42,8 @@ const MESSAGE_START = "start";
|
|
|
42
42
|
const MESSAGE_PULL = "pull";
|
|
43
43
|
const MESSAGE_DATA = "data";
|
|
44
44
|
const MESSAGE_ABORT = "abort";
|
|
45
|
+
const COMPRESSION_FORMAT = "deflate-raw";
|
|
46
|
+
const UNDEFINED_TYPE = "undefined";
|
|
45
47
|
|
|
46
48
|
class Inflate {
|
|
47
49
|
|
|
@@ -64,30 +66,22 @@ class Inflate {
|
|
|
64
66
|
signed,
|
|
65
67
|
compressed,
|
|
66
68
|
zipCrypto,
|
|
67
|
-
stream:
|
|
68
|
-
async pull(controller) {
|
|
69
|
-
const { value, done } = await codec.pull();
|
|
70
|
-
controller.enqueue(value);
|
|
71
|
-
if (done || codec.aborted) {
|
|
72
|
-
controller.close();
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
})
|
|
69
|
+
stream: createReadableStream(codec)
|
|
76
70
|
});
|
|
77
71
|
if (encrypted) {
|
|
78
72
|
if (zipCrypto) {
|
|
79
|
-
codec.stream = codec.stream.pipeThrough(new
|
|
73
|
+
codec.stream = codec.stream.pipeThrough(new ZipCryptoDecryptionStream(password, passwordVerification));
|
|
80
74
|
} else {
|
|
81
|
-
codec.decryptStream = new
|
|
75
|
+
codec.decryptStream = new AESDecryptionStream(password, signed, encryptionStrength);
|
|
82
76
|
codec.stream = codec.stream.pipeThrough(codec.decryptStream);
|
|
83
77
|
}
|
|
84
78
|
}
|
|
85
79
|
if (compressed) {
|
|
86
|
-
if ((useCompressionStream !== undefined && !useCompressionStream) || typeof DecompressionStream ==
|
|
80
|
+
if ((useCompressionStream !== undefined && !useCompressionStream) || typeof DecompressionStream == UNDEFINED_TYPE) {
|
|
87
81
|
pipeCodecStream();
|
|
88
82
|
} else {
|
|
89
83
|
try {
|
|
90
|
-
codec.stream = codec.stream.pipeThrough(new DecompressionStream(
|
|
84
|
+
codec.stream = codec.stream.pipeThrough(new DecompressionStream(COMPRESSION_FORMAT));
|
|
91
85
|
} catch (_error) {
|
|
92
86
|
pipeCodecStream();
|
|
93
87
|
}
|
|
@@ -155,15 +149,7 @@ class Deflate {
|
|
|
155
149
|
signed,
|
|
156
150
|
compressed,
|
|
157
151
|
zipCrypto,
|
|
158
|
-
stream:
|
|
159
|
-
async pull(controller) {
|
|
160
|
-
const { value, done } = await codec.pull();
|
|
161
|
-
controller.enqueue(value);
|
|
162
|
-
if (done || codec.aborted) {
|
|
163
|
-
controller.close();
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
})
|
|
152
|
+
stream: createReadableStream(codec)
|
|
167
153
|
});
|
|
168
154
|
if ((!encrypted || zipCrypto) && signed) {
|
|
169
155
|
const tee = codec.stream.tee();
|
|
@@ -171,11 +157,11 @@ class Deflate {
|
|
|
171
157
|
codec.crc32Stream = tee[1].pipeThrough(new Crc32Stream({ chunkSize }));
|
|
172
158
|
}
|
|
173
159
|
if (compressed) {
|
|
174
|
-
if ((useCompressionStream !== undefined && !useCompressionStream) || typeof CompressionStream ==
|
|
160
|
+
if ((useCompressionStream !== undefined && !useCompressionStream) || typeof CompressionStream == UNDEFINED_TYPE) {
|
|
175
161
|
pipeCodecStream();
|
|
176
162
|
} else {
|
|
177
163
|
try {
|
|
178
|
-
codec.stream = codec.stream.pipeThrough(new CompressionStream(
|
|
164
|
+
codec.stream = codec.stream.pipeThrough(new CompressionStream(COMPRESSION_FORMAT));
|
|
179
165
|
} catch (_error) {
|
|
180
166
|
pipeCodecStream();
|
|
181
167
|
}
|
|
@@ -183,9 +169,9 @@ class Deflate {
|
|
|
183
169
|
}
|
|
184
170
|
if (encrypted) {
|
|
185
171
|
if (zipCrypto) {
|
|
186
|
-
codec.stream = codec.stream.pipeThrough(new
|
|
172
|
+
codec.stream = codec.stream.pipeThrough(new ZipCryptoEncryptionStream(password, passwordVerification));
|
|
187
173
|
} else {
|
|
188
|
-
codec.encryptStream = new
|
|
174
|
+
codec.encryptStream = new AESEncryptionStream(password, encryptionStrength);
|
|
189
175
|
codec.stream = codec.stream.pipeThrough(codec.encryptStream);
|
|
190
176
|
}
|
|
191
177
|
}
|
|
@@ -243,4 +229,18 @@ function createCodec(codecConstructor, options, config) {
|
|
|
243
229
|
} else if (options.codecType.startsWith(CODEC_INFLATE)) {
|
|
244
230
|
return new Inflate(codecConstructor, options, config);
|
|
245
231
|
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function createReadableStream(codec) {
|
|
235
|
+
return new ReadableStream({
|
|
236
|
+
async pull(controller) {
|
|
237
|
+
const { value, done } = await codec.pull();
|
|
238
|
+
if (value) {
|
|
239
|
+
controller.enqueue(value);
|
|
240
|
+
}
|
|
241
|
+
if (done || codec.aborted) {
|
|
242
|
+
controller.close();
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
});
|
|
246
246
|
}
|
|
@@ -34,7 +34,7 @@ import { ERR_INVALID_PASSWORD } from "./aes-crypto-stream.js";
|
|
|
34
34
|
|
|
35
35
|
const HEADER_LENGTH = 12;
|
|
36
36
|
|
|
37
|
-
class
|
|
37
|
+
class ZipCryptoDecryptionStream extends TransformStream {
|
|
38
38
|
|
|
39
39
|
constructor(password, passwordVerification) {
|
|
40
40
|
let stream;
|
|
@@ -68,7 +68,7 @@ class ZipCryptoDecryptStream extends TransformStream {
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
class
|
|
71
|
+
class ZipCryptoEncryptionStream extends TransformStream {
|
|
72
72
|
|
|
73
73
|
constructor(password, passwordVerification) {
|
|
74
74
|
super({
|
|
@@ -106,8 +106,8 @@ class ZipCryptoEncryptStream extends TransformStream {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
export {
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
ZipCryptoDecryptionStream,
|
|
110
|
+
ZipCryptoEncryptionStream,
|
|
111
111
|
ERR_INVALID_PASSWORD
|
|
112
112
|
};
|
|
113
113
|
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
/* global navigator */
|
|
30
30
|
|
|
31
|
+
const MINIMUM_CHUNK_SIZE = 64;
|
|
31
32
|
const DEFAULT_CONFIGURATION = {
|
|
32
33
|
chunkSize: 512 * 1024,
|
|
33
34
|
maxWorkers: (typeof navigator != "undefined" && navigator.hardwareConcurrency) || 2,
|
|
@@ -40,13 +41,18 @@ const config = Object.assign({}, DEFAULT_CONFIGURATION);
|
|
|
40
41
|
|
|
41
42
|
export {
|
|
42
43
|
configure,
|
|
43
|
-
getConfiguration
|
|
44
|
+
getConfiguration,
|
|
45
|
+
getChunkSize
|
|
44
46
|
};
|
|
45
47
|
|
|
46
48
|
function getConfiguration() {
|
|
47
49
|
return config;
|
|
48
50
|
}
|
|
49
51
|
|
|
52
|
+
function getChunkSize(config) {
|
|
53
|
+
return Math.max(config.chunkSize, MINIMUM_CHUNK_SIZE);
|
|
54
|
+
}
|
|
55
|
+
|
|
50
56
|
function configure(configuration) {
|
|
51
57
|
if (configuration.baseURL !== undefined) {
|
|
52
58
|
config.baseURL = configuration.baseURL;
|
package/lib/core/engine.js
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
const MINIMUM_CHUNK_SIZE = 64;
|
|
29
|
+
// const MINIMUM_CHUNK_SIZE = 64;
|
|
30
30
|
const ERR_ABORT = "Abort error";
|
|
31
31
|
|
|
32
32
|
export {
|
|
@@ -34,39 +34,35 @@ export {
|
|
|
34
34
|
processData
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
-
async function processData(codec, reader, writer,
|
|
38
|
-
const chunkSize = Math.max(config.chunkSize, MINIMUM_CHUNK_SIZE);
|
|
39
|
-
const signal = options.signal;
|
|
37
|
+
async function processData(codec, reader, writer, size, { signal, onprogress }) {
|
|
40
38
|
let length = 0;
|
|
41
39
|
let chunkOffset = 0;
|
|
42
40
|
|
|
43
41
|
const result = new Promise((resolve, reject) => {
|
|
44
42
|
codec.pull = async () => {
|
|
45
43
|
testAborted(signal, codec);
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const value = await reader.readUint8Array(currentChunkOffset + offset, Math.min(chunkSize, inputLength - currentChunkOffset));
|
|
50
|
-
const done = chunkOffset > inputLength;
|
|
51
|
-
return { value, done };
|
|
44
|
+
const result = await reader.read();
|
|
45
|
+
chunkOffset += result.length;
|
|
46
|
+
return result;
|
|
52
47
|
};
|
|
53
48
|
codec.ondata = async ({ value, done }) => {
|
|
54
49
|
try {
|
|
55
50
|
testAborted(signal, codec);
|
|
56
|
-
const inputLength = inputLengthGetter();
|
|
57
51
|
const { data, signature } = value;
|
|
58
52
|
if (data && data.length) {
|
|
59
53
|
length += data.length;
|
|
60
|
-
await writer.
|
|
54
|
+
await writer.ready;
|
|
55
|
+
await writer.write(data);
|
|
61
56
|
}
|
|
62
|
-
if (
|
|
57
|
+
if (onprogress) {
|
|
63
58
|
try {
|
|
64
|
-
|
|
59
|
+
onprogress(chunkOffset, size());
|
|
65
60
|
} catch (error) {
|
|
66
61
|
// ignored
|
|
67
62
|
}
|
|
68
63
|
}
|
|
69
64
|
if (done) {
|
|
65
|
+
await writer.ready;
|
|
70
66
|
resolve({ signature, length });
|
|
71
67
|
}
|
|
72
68
|
} catch (error) {
|