@zip.js/zip.js 2.5.13 → 2.5.16
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/cli-deno/mc-zip.js +21 -19
- 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 +139 -142
- package/dist/zip-fs-full.min.js +1 -1
- package/dist/zip-fs.js +137 -140
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-full.js +139 -142
- 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 +137 -140
- package/dist/zip.min.js +1 -1
- package/index.d.ts +6 -2
- package/lib/core/codec-pool-worker.js +45 -33
- package/lib/core/codec-pool.js +11 -8
- package/lib/core/configuration.js +40 -28
- package/lib/core/io.js +21 -35
- package/lib/core/streams/aes-crypto-stream.js +5 -5
- package/lib/core/streams/codecs/deflate.js +1 -1
- package/lib/core/streams/codecs/inflate.js +1 -1
- package/lib/core/util/decode-text.js +1 -8
- package/lib/core/util/stream-codec-shim.js +2 -2
- package/lib/core/z-worker-core.js +10 -8
- package/lib/core/zip-writer.js +12 -21
- package/lib/z-worker-inline.js +1 -1
- package/package.json +1 -1
- package/rollup-fflate.config.dev.js +1 -1
- package/rollup-fflate.config.js +2 -2
- package/rollup.config.dev.js +1 -1
- package/rollup.config.js +2 -2
- package/tests/all/test-abort-signal-read.js +4 -2
|
@@ -97,14 +97,15 @@ async function callHandler(handler, ...parameters) {
|
|
|
97
97
|
|
|
98
98
|
function createWorkerInterface(workerData, config) {
|
|
99
99
|
const interfaceCodec = createCodec(workerData.codecConstructor, workerData.readable, workerData.writable, workerData.options, config);
|
|
100
|
+
const { onTaskFinished } = workerData;
|
|
100
101
|
const codec = {
|
|
101
102
|
abort() {
|
|
102
103
|
interfaceCodec.abort();
|
|
103
|
-
|
|
104
|
+
onTaskFinished();
|
|
104
105
|
},
|
|
105
|
-
run() {
|
|
106
|
-
const result = interfaceCodec.run();
|
|
107
|
-
|
|
106
|
+
async run() {
|
|
107
|
+
const result = await interfaceCodec.run();
|
|
108
|
+
onTaskFinished();
|
|
108
109
|
return result;
|
|
109
110
|
}
|
|
110
111
|
};
|
|
@@ -113,11 +114,15 @@ function createWorkerInterface(workerData, config) {
|
|
|
113
114
|
|
|
114
115
|
function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
|
|
115
116
|
const workerOptions = { type: "module" };
|
|
116
|
-
|
|
117
|
-
workerData
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
const { readable, writable } = workerData;
|
|
118
|
+
Object.assign(workerData, {
|
|
119
|
+
reader: readable.getReader(),
|
|
120
|
+
writer: writable.getWriter(),
|
|
121
|
+
result: new Promise((resolve, reject) => {
|
|
122
|
+
workerData.resolveResult = resolve;
|
|
123
|
+
workerData.rejectResult = reject;
|
|
124
|
+
}),
|
|
125
|
+
aborted: false
|
|
121
126
|
});
|
|
122
127
|
if (!workerData.interface) {
|
|
123
128
|
if (!classicWorkersSupported) {
|
|
@@ -133,6 +138,7 @@ function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
|
|
|
133
138
|
workerData.worker.addEventListener(MESSAGE_EVENT_TYPE, onMessage, false);
|
|
134
139
|
workerData.interface = {
|
|
135
140
|
abort() {
|
|
141
|
+
workerData.aborted = true;
|
|
136
142
|
sendMessage({ type: MESSAGE_ABORT });
|
|
137
143
|
workerData.writer.releaseLock();
|
|
138
144
|
workerData.onTaskFinished();
|
|
@@ -162,12 +168,13 @@ function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
|
|
|
162
168
|
}
|
|
163
169
|
|
|
164
170
|
function sendMessage(message) {
|
|
165
|
-
const { worker } = workerData;
|
|
171
|
+
const { worker, writer, onTaskFinished } = workerData;
|
|
166
172
|
try {
|
|
167
173
|
let { data } = message;
|
|
168
174
|
if (data) {
|
|
169
175
|
try {
|
|
170
|
-
|
|
176
|
+
const { buffer, length } = data;
|
|
177
|
+
if (length != buffer.byteLength) {
|
|
171
178
|
data = new Uint8Array(data);
|
|
172
179
|
}
|
|
173
180
|
message.data = data.buffer;
|
|
@@ -179,43 +186,48 @@ function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
|
|
|
179
186
|
worker.postMessage(message);
|
|
180
187
|
}
|
|
181
188
|
} catch (error) {
|
|
182
|
-
|
|
183
|
-
|
|
189
|
+
writer.releaseLock();
|
|
190
|
+
onTaskFinished();
|
|
184
191
|
throw error;
|
|
185
192
|
}
|
|
186
193
|
}
|
|
187
194
|
|
|
188
195
|
async function onMessage(event) {
|
|
189
196
|
const message = event.data;
|
|
197
|
+
const { reader, writer, resolveResult, rejectResult, onTaskFinished } = workerData;
|
|
198
|
+
const { type, data, messageId, result } = message;
|
|
190
199
|
const reponseError = message.error;
|
|
191
200
|
try {
|
|
192
201
|
if (reponseError) {
|
|
193
|
-
const
|
|
194
|
-
error
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
workerData.onTaskFinished();
|
|
202
|
+
const { message, stack } = reponseError;
|
|
203
|
+
const error = new Error(message);
|
|
204
|
+
error.stack = stack;
|
|
205
|
+
close(error);
|
|
198
206
|
} else {
|
|
199
|
-
if (
|
|
200
|
-
const { value, done } = await
|
|
201
|
-
sendMessage({ type: MESSAGE_DATA, data: value, done, messageId
|
|
207
|
+
if (type == MESSAGE_PULL) {
|
|
208
|
+
const { value, done } = await reader.read();
|
|
209
|
+
sendMessage({ type: MESSAGE_DATA, data: value, done, messageId });
|
|
202
210
|
}
|
|
203
|
-
if (
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
await workerData.writer.ready;
|
|
207
|
-
await workerData.writer.write(data);
|
|
211
|
+
if (type == MESSAGE_DATA) {
|
|
212
|
+
await writer.ready;
|
|
213
|
+
await writer.write(new Uint8Array(data));
|
|
208
214
|
}
|
|
209
|
-
if (
|
|
210
|
-
|
|
211
|
-
workerData.writer.releaseLock();
|
|
212
|
-
workerData.onTaskFinished();
|
|
215
|
+
if (type == MESSAGE_CLOSE) {
|
|
216
|
+
close(null, result);
|
|
213
217
|
}
|
|
214
218
|
}
|
|
215
219
|
} catch (error) {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
220
|
+
close(error);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function close(error, result) {
|
|
224
|
+
if (error && !workerData.aborted) {
|
|
225
|
+
rejectResult(error);
|
|
226
|
+
} else {
|
|
227
|
+
resolveResult(result);
|
|
228
|
+
}
|
|
229
|
+
writer.releaseLock();
|
|
230
|
+
onTaskFinished();
|
|
219
231
|
}
|
|
220
232
|
}
|
|
221
233
|
}
|
package/lib/core/codec-pool.js
CHANGED
|
@@ -55,11 +55,12 @@ let indexWorker = 0;
|
|
|
55
55
|
async function runWorker(stream, workerOptions) {
|
|
56
56
|
const { options, config, streamOptions } = workerOptions;
|
|
57
57
|
const streamCopy = !options.compressed && !options.signed && !options.encrypted;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
const { useWebWorkers, useCompressionStream, codecType } = options;
|
|
59
|
+
const { workerScripts } = config;
|
|
60
|
+
workerOptions.webWorker = !streamCopy && (useWebWorkers || (useWebWorkers === undefined && config.useWebWorkers));
|
|
61
|
+
workerOptions.scripts = workerOptions.webWorker && workerScripts ? workerScripts[codecType] : [];
|
|
62
|
+
options.useCompressionStream = useCompressionStream === undefined ? config.useCompressionStream : useCompressionStream;
|
|
61
63
|
let codec;
|
|
62
|
-
|
|
63
64
|
if (pool.length < config.maxWorkers) {
|
|
64
65
|
const workerData = { indexWorker };
|
|
65
66
|
indexWorker++;
|
|
@@ -91,12 +92,13 @@ async function runWorker(stream, workerOptions) {
|
|
|
91
92
|
const [{ resolve, stream, workerOptions }] = pendingRequests.splice(0, 1);
|
|
92
93
|
resolve(getWorker(workerData, stream, workerOptions, onTaskFinished));
|
|
93
94
|
} else if (workerData.worker) {
|
|
95
|
+
const { terminateWorkerTimeout } = config;
|
|
94
96
|
clearTerminateTimeout(workerData);
|
|
95
|
-
if (Number.isFinite(
|
|
97
|
+
if (Number.isFinite(terminateWorkerTimeout) && terminateWorkerTimeout >= 0) {
|
|
96
98
|
workerData.terminateTimeout = setTimeout(() => {
|
|
97
99
|
pool = pool.filter(data => data != workerData);
|
|
98
100
|
workerData.terminate();
|
|
99
|
-
},
|
|
101
|
+
}, terminateWorkerTimeout);
|
|
100
102
|
}
|
|
101
103
|
} else {
|
|
102
104
|
pool = pool.filter(data => data != workerData);
|
|
@@ -105,8 +107,9 @@ async function runWorker(stream, workerOptions) {
|
|
|
105
107
|
}
|
|
106
108
|
|
|
107
109
|
function clearTerminateTimeout(workerData) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
+
const { terminateTimeout } = workerData;
|
|
111
|
+
if (terminateTimeout) {
|
|
112
|
+
clearTimeout(terminateTimeout);
|
|
110
113
|
workerData.terminateTimeout = null;
|
|
111
114
|
}
|
|
112
115
|
}
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
/* global navigator */
|
|
30
30
|
|
|
31
31
|
const MINIMUM_CHUNK_SIZE = 64;
|
|
32
|
+
const UNDEFINED_TYPE = undefined;
|
|
32
33
|
const DEFAULT_CONFIGURATION = {
|
|
33
34
|
chunkSize: 512 * 1024,
|
|
34
35
|
maxWorkers: (typeof navigator != "undefined" && navigator.hardwareConcurrency) || 2,
|
|
@@ -54,48 +55,59 @@ function getChunkSize(config) {
|
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
function configure(configuration) {
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
const {
|
|
59
|
+
baseURL,
|
|
60
|
+
chunkSize,
|
|
61
|
+
maxWorkers,
|
|
62
|
+
terminateWorkerTimeout,
|
|
63
|
+
useCompressionStream,
|
|
64
|
+
useWebWorkers,
|
|
65
|
+
Deflate,
|
|
66
|
+
Inflate,
|
|
67
|
+
workerScripts
|
|
68
|
+
} = configuration;
|
|
69
|
+
if (baseURL !== UNDEFINED_TYPE) {
|
|
70
|
+
config.baseURL = baseURL;
|
|
59
71
|
}
|
|
60
|
-
if (
|
|
61
|
-
config.chunkSize =
|
|
72
|
+
if (chunkSize !== UNDEFINED_TYPE) {
|
|
73
|
+
config.chunkSize = chunkSize;
|
|
62
74
|
}
|
|
63
|
-
if (
|
|
64
|
-
config.maxWorkers =
|
|
75
|
+
if (maxWorkers !== UNDEFINED_TYPE) {
|
|
76
|
+
config.maxWorkers = maxWorkers;
|
|
65
77
|
}
|
|
66
|
-
if (
|
|
67
|
-
config.terminateWorkerTimeout =
|
|
78
|
+
if (terminateWorkerTimeout !== UNDEFINED_TYPE) {
|
|
79
|
+
config.terminateWorkerTimeout = terminateWorkerTimeout;
|
|
68
80
|
}
|
|
69
|
-
if (
|
|
70
|
-
config.useCompressionStream =
|
|
81
|
+
if (useCompressionStream !== UNDEFINED_TYPE) {
|
|
82
|
+
config.useCompressionStream = useCompressionStream;
|
|
71
83
|
}
|
|
72
|
-
if (
|
|
73
|
-
config.useWebWorkers =
|
|
84
|
+
if (useWebWorkers !== UNDEFINED_TYPE) {
|
|
85
|
+
config.useWebWorkers = useWebWorkers;
|
|
74
86
|
}
|
|
75
|
-
if (
|
|
76
|
-
config.Deflate =
|
|
87
|
+
if (Deflate !== UNDEFINED_TYPE) {
|
|
88
|
+
config.Deflate = Deflate;
|
|
77
89
|
}
|
|
78
|
-
if (
|
|
79
|
-
config.Inflate =
|
|
90
|
+
if (Inflate !== UNDEFINED_TYPE) {
|
|
91
|
+
config.Inflate = Inflate;
|
|
80
92
|
}
|
|
81
|
-
if (
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
throw new Error("workerScripts.deflate must be an array");
|
|
85
|
-
}
|
|
93
|
+
if (workerScripts !== UNDEFINED_TYPE) {
|
|
94
|
+
const { deflate, inflate } = workerScripts;
|
|
95
|
+
if (deflate || inflate) {
|
|
86
96
|
if (!config.workerScripts) {
|
|
87
97
|
config.workerScripts = {};
|
|
88
98
|
}
|
|
89
|
-
config.workerScripts.deflate = configuration.workerScripts.deflate;
|
|
90
99
|
}
|
|
91
|
-
if (
|
|
92
|
-
if (!Array.isArray(
|
|
93
|
-
throw new Error("workerScripts.
|
|
100
|
+
if (deflate) {
|
|
101
|
+
if (!Array.isArray(deflate)) {
|
|
102
|
+
throw new Error("workerScripts.deflate must be an array");
|
|
94
103
|
}
|
|
95
|
-
|
|
96
|
-
|
|
104
|
+
config.workerScripts.deflate = deflate;
|
|
105
|
+
}
|
|
106
|
+
if (inflate) {
|
|
107
|
+
if (!Array.isArray(inflate)) {
|
|
108
|
+
throw new Error("workerScripts.inflate must be an array");
|
|
97
109
|
}
|
|
98
|
-
config.workerScripts.inflate =
|
|
110
|
+
config.workerScripts.inflate = inflate;
|
|
99
111
|
}
|
|
100
112
|
}
|
|
101
113
|
}
|
package/lib/core/io.js
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
/* global Blob,
|
|
29
|
+
/* global Blob, atob, btoa, XMLHttpRequest, document, fetch, ReadableStream, WritableStream, TransformStream */
|
|
30
30
|
|
|
31
31
|
const ERR_HTTP_STATUS = "HTTP error ";
|
|
32
32
|
const ERR_HTTP_RANGE = "HTTP Range not supported";
|
|
@@ -127,16 +127,7 @@ class TextWriter extends Writer {
|
|
|
127
127
|
|
|
128
128
|
getData() {
|
|
129
129
|
const writer = this;
|
|
130
|
-
|
|
131
|
-
return writer.blob.text();
|
|
132
|
-
} else {
|
|
133
|
-
const reader = new FileReader();
|
|
134
|
-
return new Promise((resolve, reject) => {
|
|
135
|
-
reader.onload = event => resolve(event.target.result);
|
|
136
|
-
reader.onerror = () => reject(reader.error);
|
|
137
|
-
reader.readAsText(writer.blob, writer.encoding);
|
|
138
|
-
});
|
|
139
|
-
}
|
|
130
|
+
return writer.blob.text();
|
|
140
131
|
}
|
|
141
132
|
}
|
|
142
133
|
|
|
@@ -210,16 +201,7 @@ class BlobReader extends Reader {
|
|
|
210
201
|
|
|
211
202
|
async readUint8Array(offset, length) {
|
|
212
203
|
const reader = this;
|
|
213
|
-
|
|
214
|
-
return new Uint8Array(await reader.blob.slice(offset, offset + length).arrayBuffer());
|
|
215
|
-
} else {
|
|
216
|
-
const reader = new FileReader();
|
|
217
|
-
return new Promise((resolve, reject) => {
|
|
218
|
-
reader.onload = event => resolve(new Uint8Array(event.target.result));
|
|
219
|
-
reader.onerror = () => reject(reader.error);
|
|
220
|
-
reader.readAsArrayBuffer(reader.blob.slice(offset, offset + length));
|
|
221
|
-
});
|
|
222
|
-
}
|
|
204
|
+
return new Uint8Array(await reader.blob.slice(offset, offset + length).arrayBuffer());
|
|
223
205
|
}
|
|
224
206
|
}
|
|
225
207
|
|
|
@@ -267,9 +249,12 @@ function flushArrayBuffers(blobWriter) {
|
|
|
267
249
|
|
|
268
250
|
class ReadableStreamReader {
|
|
269
251
|
|
|
270
|
-
constructor(
|
|
252
|
+
constructor(readable) {
|
|
271
253
|
const reader = this;
|
|
272
|
-
|
|
254
|
+
if (!readable) {
|
|
255
|
+
readable = new ReadableStream({});
|
|
256
|
+
}
|
|
257
|
+
reader.readable = readable.pipeThrough(new TransformStream({
|
|
273
258
|
transform(chunk, controller) {
|
|
274
259
|
if (chunk) {
|
|
275
260
|
reader.size += chunk.length;
|
|
@@ -285,14 +270,18 @@ class ReadableStreamReader {
|
|
|
285
270
|
}
|
|
286
271
|
|
|
287
272
|
getReadable() {
|
|
288
|
-
return this.
|
|
273
|
+
return this.readable;
|
|
289
274
|
}
|
|
290
275
|
}
|
|
291
276
|
|
|
292
277
|
class WritableStreamWriter extends Writer {
|
|
293
278
|
|
|
294
|
-
constructor(writable) {
|
|
279
|
+
constructor(writable, { preventClose } = {}) {
|
|
295
280
|
super();
|
|
281
|
+
this.preventClose = preventClose;
|
|
282
|
+
if (!writable) {
|
|
283
|
+
writable = new WritableStream({});
|
|
284
|
+
}
|
|
296
285
|
Object.defineProperty(this, "writable", {
|
|
297
286
|
get() {
|
|
298
287
|
return writable;
|
|
@@ -300,16 +289,13 @@ class WritableStreamWriter extends Writer {
|
|
|
300
289
|
});
|
|
301
290
|
}
|
|
302
291
|
|
|
303
|
-
async writeUint8Array(array) {
|
|
304
|
-
await this.writer.ready;
|
|
305
|
-
const writer = this.writable.getWriter();
|
|
306
|
-
await writer.write(array);
|
|
307
|
-
writer.releaseLock();
|
|
308
|
-
}
|
|
309
|
-
|
|
310
292
|
async getData() {
|
|
311
|
-
|
|
312
|
-
|
|
293
|
+
const writer = this;
|
|
294
|
+
const { writable } = writer;
|
|
295
|
+
if (!writer.preventClose) {
|
|
296
|
+
await writable.getWriter().close();
|
|
297
|
+
}
|
|
298
|
+
return writable;
|
|
313
299
|
}
|
|
314
300
|
}
|
|
315
301
|
|
|
@@ -543,7 +529,7 @@ class Uint8ArrayWriter extends Writer {
|
|
|
543
529
|
|
|
544
530
|
constructor() {
|
|
545
531
|
super();
|
|
546
|
-
this.array = new Uint8Array(
|
|
532
|
+
this.array = new Uint8Array();
|
|
547
533
|
}
|
|
548
534
|
|
|
549
535
|
writeUint8Array(array) {
|
|
@@ -74,7 +74,7 @@ class AESDecryptionStream extends TransformStream {
|
|
|
74
74
|
password,
|
|
75
75
|
signed,
|
|
76
76
|
strength: strength - 1,
|
|
77
|
-
pending: new Uint8Array(
|
|
77
|
+
pending: new Uint8Array()
|
|
78
78
|
});
|
|
79
79
|
},
|
|
80
80
|
async transform(chunk, controller) {
|
|
@@ -100,7 +100,7 @@ class AESDecryptionStream extends TransformStream {
|
|
|
100
100
|
const pending = aesCrypto.pending;
|
|
101
101
|
const chunkToDecrypt = subarray(pending, 0, pending.length - SIGNATURE_LENGTH);
|
|
102
102
|
const originalSignature = subarray(pending, pending.length - SIGNATURE_LENGTH);
|
|
103
|
-
let decryptedChunkArray = new Uint8Array(
|
|
103
|
+
let decryptedChunkArray = new Uint8Array();
|
|
104
104
|
if (chunkToDecrypt.length) {
|
|
105
105
|
const encryptedChunk = toBits(codecBytes, chunkToDecrypt);
|
|
106
106
|
aesCrypto.hmac.update(encryptedChunk);
|
|
@@ -133,12 +133,12 @@ class AESEncryptionStream extends TransformStream {
|
|
|
133
133
|
ready: new Promise(resolve => this.resolveReady = resolve),
|
|
134
134
|
password,
|
|
135
135
|
strength: strength - 1,
|
|
136
|
-
pending: new Uint8Array(
|
|
136
|
+
pending: new Uint8Array()
|
|
137
137
|
});
|
|
138
138
|
},
|
|
139
139
|
async transform(chunk, controller) {
|
|
140
140
|
const aesCrypto = this;
|
|
141
|
-
let preamble = new Uint8Array(
|
|
141
|
+
let preamble = new Uint8Array();
|
|
142
142
|
if (aesCrypto.password) {
|
|
143
143
|
const password = aesCrypto.password;
|
|
144
144
|
aesCrypto.password = null;
|
|
@@ -156,7 +156,7 @@ class AESEncryptionStream extends TransformStream {
|
|
|
156
156
|
async flush(controller) {
|
|
157
157
|
const aesCrypto = this;
|
|
158
158
|
await aesCrypto.ready;
|
|
159
|
-
let encryptedChunkArray = new Uint8Array(
|
|
159
|
+
let encryptedChunkArray = new Uint8Array();
|
|
160
160
|
if (aesCrypto.pending.length) {
|
|
161
161
|
const encryptedChunk = aesCrypto.ctr.update(toBits(codecBytes, aesCrypto.pending));
|
|
162
162
|
aesCrypto.hmac.update(encryptedChunk);
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
/* global TextDecoder
|
|
29
|
+
/* global TextDecoder */
|
|
30
30
|
|
|
31
31
|
import decodeCP437 from "./cp437-decode.js";
|
|
32
32
|
|
|
@@ -35,13 +35,6 @@ export default decodeText;
|
|
|
35
35
|
function decodeText(value, encoding) {
|
|
36
36
|
if (encoding && encoding.trim().toLowerCase() == "cp437") {
|
|
37
37
|
return decodeCP437(value);
|
|
38
|
-
} else if (typeof TextDecoder == "undefined") {
|
|
39
|
-
const fileReader = new FileReader();
|
|
40
|
-
return new Promise((resolve, reject) => {
|
|
41
|
-
fileReader.onload = event => resolve(event.target.result);
|
|
42
|
-
fileReader.onerror = () => reject(fileReader.error);
|
|
43
|
-
fileReader.readAsText(new Blob([value]));
|
|
44
|
-
});
|
|
45
38
|
} else {
|
|
46
39
|
return new TextDecoder(encoding).decode(value);
|
|
47
40
|
}
|
|
@@ -61,7 +61,7 @@ function createCodecClass(constructor, constructorOptions, registerDataHandler)
|
|
|
61
61
|
return getResponse(this);
|
|
62
62
|
}
|
|
63
63
|
flush() {
|
|
64
|
-
this.codec.push(new Uint8Array(
|
|
64
|
+
this.codec.push(new Uint8Array(), true);
|
|
65
65
|
return getResponse(this);
|
|
66
66
|
}
|
|
67
67
|
};
|
|
@@ -72,7 +72,7 @@ function createCodecClass(constructor, constructorOptions, registerDataHandler)
|
|
|
72
72
|
codec.pendingData = null;
|
|
73
73
|
return output;
|
|
74
74
|
} else {
|
|
75
|
-
return new Uint8Array(
|
|
75
|
+
return new Uint8Array();
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
}
|
|
@@ -66,20 +66,21 @@ addEventListener(MESSAGE_EVENT_TYPE, async event => {
|
|
|
66
66
|
|
|
67
67
|
async function init(message) {
|
|
68
68
|
try {
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
const { options, scripts, config } = message;
|
|
70
|
+
const { codecType } = options;
|
|
71
|
+
if (scripts && scripts.length) {
|
|
72
|
+
importScripts.apply(undefined, scripts);
|
|
71
73
|
}
|
|
72
|
-
const options = message.options;
|
|
73
74
|
if (self.initCodec) {
|
|
74
75
|
self.initCodec();
|
|
75
76
|
}
|
|
76
77
|
let codecConstructor;
|
|
77
|
-
if (
|
|
78
|
+
if (codecType.startsWith(CODEC_DEFLATE)) {
|
|
78
79
|
codecConstructor = self.Deflate;
|
|
79
|
-
} else if (
|
|
80
|
+
} else if (codecType.startsWith(CODEC_INFLATE)) {
|
|
80
81
|
codecConstructor = self.Inflate;
|
|
81
82
|
}
|
|
82
|
-
const strategy = { highWaterMark: 1, size: () =>
|
|
83
|
+
const strategy = { highWaterMark: 1, size: () => config.chunkSize };
|
|
83
84
|
const readable = new ReadableStream({
|
|
84
85
|
async pull(controller) {
|
|
85
86
|
let result = new Promise((resolve, reject) => pendingMessages.set(messageId, { resolve, reject }));
|
|
@@ -97,12 +98,13 @@ async function init(message) {
|
|
|
97
98
|
sendMessage({ type: MESSAGE_DATA, data });
|
|
98
99
|
}
|
|
99
100
|
}, strategy);
|
|
100
|
-
codec = createCodec(codecConstructor, readable, writable, options,
|
|
101
|
+
codec = createCodec(codecConstructor, readable, writable, options, config);
|
|
101
102
|
const result = await codec.run();
|
|
102
103
|
sendMessage({ type: MESSAGE_CLOSE, result });
|
|
103
104
|
|
|
104
105
|
} catch (error) {
|
|
105
|
-
|
|
106
|
+
const { message, stack } = error;
|
|
107
|
+
postMessage({ error: { message, stack } });
|
|
106
108
|
}
|
|
107
109
|
}
|
|
108
110
|
|
package/lib/core/zip-writer.js
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
/* global BigInt
|
|
29
|
+
/* global BigInt */
|
|
30
30
|
|
|
31
31
|
import {
|
|
32
32
|
MAX_32_BITS,
|
|
@@ -125,7 +125,7 @@ class ZipWriter {
|
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
async close(comment = new Uint8Array(
|
|
128
|
+
async close(comment = new Uint8Array(), options = {}) {
|
|
129
129
|
while (this.pendingAddFileCalls.size) {
|
|
130
130
|
await Promise.all(Array.from(this.pendingAddFileCalls));
|
|
131
131
|
}
|
|
@@ -183,7 +183,7 @@ async function addFile(zipWriter, name, reader, options) {
|
|
|
183
183
|
if (password !== undefined && encryptionStrength !== undefined && (encryptionStrength < 1 || encryptionStrength > 3)) {
|
|
184
184
|
throw new Error(ERR_INVALID_ENCRYPTION_STRENGTH);
|
|
185
185
|
}
|
|
186
|
-
let rawExtraField = new Uint8Array(
|
|
186
|
+
let rawExtraField = new Uint8Array();
|
|
187
187
|
const { extraField } = options;
|
|
188
188
|
if (extraField) {
|
|
189
189
|
let extraFieldSize = 0;
|
|
@@ -410,7 +410,7 @@ async function createFileEntry(reader, writable, config, options) {
|
|
|
410
410
|
arraySet(rawExtraFieldAES, EXTRAFIELD_DATA_AES, 2);
|
|
411
411
|
setUint8(extraFieldAESView, 8, encryptionStrength);
|
|
412
412
|
} else {
|
|
413
|
-
rawExtraFieldAES = new Uint8Array(
|
|
413
|
+
rawExtraFieldAES = new Uint8Array();
|
|
414
414
|
}
|
|
415
415
|
let rawExtraFieldNTFS;
|
|
416
416
|
let rawExtraFieldExtendedTimestamp;
|
|
@@ -440,10 +440,10 @@ async function createFileEntry(reader, writable, config, options) {
|
|
|
440
440
|
setBigUint64(extraFieldNTFSView, 20, getTimeNTFS(lastAccessDate) || lastModTimeNTFS);
|
|
441
441
|
setBigUint64(extraFieldNTFSView, 28, getTimeNTFS(creationDate) || lastModTimeNTFS);
|
|
442
442
|
} catch (_error) {
|
|
443
|
-
rawExtraFieldNTFS = new Uint8Array(
|
|
443
|
+
rawExtraFieldNTFS = new Uint8Array();
|
|
444
444
|
}
|
|
445
445
|
} else {
|
|
446
|
-
rawExtraFieldNTFS = rawExtraFieldExtendedTimestamp = new Uint8Array(
|
|
446
|
+
rawExtraFieldNTFS = rawExtraFieldExtendedTimestamp = new Uint8Array();
|
|
447
447
|
}
|
|
448
448
|
const fileEntry = {
|
|
449
449
|
version: version || VERSION_DEFLATE,
|
|
@@ -454,7 +454,7 @@ async function createFileEntry(reader, writable, config, options) {
|
|
|
454
454
|
rawFilename,
|
|
455
455
|
commentUTF8: true,
|
|
456
456
|
rawComment,
|
|
457
|
-
rawExtraFieldZip64: zip64 ? new Uint8Array(EXTRAFIELD_LENGTH_ZIP64 + 4) : new Uint8Array(
|
|
457
|
+
rawExtraFieldZip64: zip64 ? new Uint8Array(EXTRAFIELD_LENGTH_ZIP64 + 4) : new Uint8Array(),
|
|
458
458
|
rawExtraFieldExtendedTimestamp,
|
|
459
459
|
rawExtraFieldNTFS,
|
|
460
460
|
rawExtraFieldAES,
|
|
@@ -550,7 +550,7 @@ async function createFileEntry(reader, writable, config, options) {
|
|
|
550
550
|
await writeUint8Array(writable, localHeaderArray);
|
|
551
551
|
fileEntry.dataWritten = true;
|
|
552
552
|
}
|
|
553
|
-
let dataDescriptorArray = new Uint8Array(
|
|
553
|
+
let dataDescriptorArray = new Uint8Array();
|
|
554
554
|
let dataDescriptorView, dataDescriptorOffset = 0;
|
|
555
555
|
if (dataDescriptor) {
|
|
556
556
|
dataDescriptorArray = new Uint8Array(zip64 ? (dataDescriptorSignature ? 24 : 20) : (dataDescriptorSignature ? 16 : 12));
|
|
@@ -657,7 +657,7 @@ async function closeFile(zipWriter, comment, options) {
|
|
|
657
657
|
setUint8(extraFieldExtendedTimestampView, 4, 0x1);
|
|
658
658
|
setUint32(extraFieldExtendedTimestampView, 5, Math.floor(fileEntry.lastModDate.getTime() / 1000));
|
|
659
659
|
} else {
|
|
660
|
-
rawExtraFieldNTFS = rawExtraFieldExtendedTimestamp = new Uint8Array(
|
|
660
|
+
rawExtraFieldNTFS = rawExtraFieldExtendedTimestamp = new Uint8Array();
|
|
661
661
|
}
|
|
662
662
|
const extraFieldLength = rawExtraFieldZip64.length + rawExtraFieldAES.length + rawExtraFieldExtendedTimestamp.length + rawExtraFieldNTFS.length + rawExtraField.length;
|
|
663
663
|
setUint32(directoryView, offset, CENTRAL_FILE_HEADER_SIGNATURE);
|
|
@@ -722,19 +722,10 @@ async function closeFile(zipWriter, comment, options) {
|
|
|
722
722
|
}
|
|
723
723
|
|
|
724
724
|
function sliceAsArrayBuffer(blob, start, end) {
|
|
725
|
-
if (
|
|
726
|
-
|
|
727
|
-
return blob.slice(start, end).arrayBuffer();
|
|
728
|
-
} else {
|
|
729
|
-
return blob.arrayBuffer();
|
|
730
|
-
}
|
|
725
|
+
if (start || end) {
|
|
726
|
+
return blob.slice(start, end).arrayBuffer();
|
|
731
727
|
} else {
|
|
732
|
-
|
|
733
|
-
return new Promise((resolve, reject) => {
|
|
734
|
-
fileReader.onload = event => resolve(event.target.result);
|
|
735
|
-
fileReader.onerror = () => reject(fileReader.error);
|
|
736
|
-
fileReader.readAsArrayBuffer(start || end ? blob.slice(start, end) : blob);
|
|
737
|
-
});
|
|
728
|
+
return blob.arrayBuffer();
|
|
738
729
|
}
|
|
739
730
|
}
|
|
740
731
|
|