@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.
- 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 +470 -499
- package/dist/zip-fs-full.min.js +1 -1
- package/dist/zip-fs.js +470 -499
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-full.js +470 -499
- 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 +470 -499
- package/dist/zip.min.js +1 -1
- package/index-fflate.js +1 -1
- package/index.d.ts +1 -1
- package/index.js +3 -3
- package/lib/core/{engine.js → codec-interface.js} +52 -50
- package/lib/core/{codecs/codec-pool-worker.js → codec-pool-worker.js} +55 -29
- package/lib/core/{codecs/codec-pool.js → codec-pool.js} +28 -9
- package/lib/core/configuration.js +10 -1
- package/lib/core/io.js +102 -100
- package/lib/core/{codecs → streams}/aes-crypto-stream.js +68 -54
- package/lib/core/{codecs → streams}/codec-stream.js +6 -6
- package/lib/core/{codecs → streams/codecs}/crc32.js +0 -0
- package/lib/core/{codecs → streams/codecs}/deflate.js +0 -0
- package/lib/core/{codecs → streams/codecs}/inflate.js +0 -0
- package/lib/core/{codecs → streams/codecs}/sjcl.js +0 -0
- package/lib/core/{codecs → streams}/crc32-stream.js +3 -4
- package/lib/core/{codecs → streams}/zip-crypto-stream.js +28 -32
- package/lib/core/streams/zip-entry-stream.js +185 -0
- package/lib/core/z-worker-core.js +30 -15
- package/lib/core/zip-fs-core.js +1 -1
- package/lib/core/zip-reader.js +21 -12
- package/lib/core/zip-writer.js +33 -25
- package/lib/z-worker-fflate.js +4 -1
- package/lib/z-worker-inline.js +1 -1
- package/lib/z-worker.js +2 -2
- package/lib/zip-fflate-shim.js +4 -1
- package/lib/zip-fs.js +6 -2
- package/lib/zip-full-fflate.js +6 -3
- package/lib/zip-full.js +8 -5
- package/lib/zip-no-worker-deflate.js +7 -3
- package/lib/zip-no-worker-fflate-deflate.js +6 -2
- package/lib/zip-no-worker-fflate-inflate.js +6 -3
- package/lib/zip-no-worker-fflate.js +6 -3
- package/lib/zip-no-worker-inflate.js +7 -4
- package/lib/zip-no-worker.js +8 -5
- package/lib/zip.js +6 -3
- package/package.json +2 -8
- package/lib/core/codecs/codec.js +0 -246
|
@@ -26,62 +26,64 @@
|
|
|
26
26
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
/* global AbortController */
|
|
30
|
+
// deno-lint-ignore-file no-this-alias
|
|
31
|
+
|
|
32
|
+
import {
|
|
33
|
+
InflateStream,
|
|
34
|
+
DeflateStream,
|
|
35
|
+
ERR_INVALID_PASSWORD,
|
|
36
|
+
ERR_INVALID_SIGNATURE
|
|
37
|
+
} from "./streams/zip-entry-stream.js";
|
|
38
|
+
|
|
39
|
+
const CODEC_DEFLATE = "deflate";
|
|
40
|
+
const CODEC_INFLATE = "inflate";
|
|
41
|
+
const MESSAGE_EVENT_TYPE = "message";
|
|
42
|
+
const MESSAGE_START = "start";
|
|
43
|
+
const MESSAGE_PULL = "pull";
|
|
44
|
+
const MESSAGE_DATA = "data";
|
|
45
|
+
const MESSAGE_ABORT = "abort";
|
|
46
|
+
const MESSAGE_CLOSE = "close";
|
|
47
|
+
const ERR_ABORT = "AbortError";
|
|
31
48
|
|
|
32
49
|
export {
|
|
33
|
-
|
|
34
|
-
|
|
50
|
+
createCodec,
|
|
51
|
+
CODEC_DEFLATE,
|
|
52
|
+
CODEC_INFLATE,
|
|
53
|
+
ERR_INVALID_SIGNATURE,
|
|
54
|
+
ERR_INVALID_PASSWORD,
|
|
55
|
+
MESSAGE_EVENT_TYPE,
|
|
56
|
+
MESSAGE_START,
|
|
57
|
+
MESSAGE_PULL,
|
|
58
|
+
MESSAGE_DATA,
|
|
59
|
+
MESSAGE_ABORT,
|
|
60
|
+
MESSAGE_CLOSE,
|
|
61
|
+
ERR_ABORT
|
|
35
62
|
};
|
|
36
63
|
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
const signal =
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
codec.pull = async () => {
|
|
45
|
-
testAborted(signal, codec);
|
|
46
|
-
const inputLength = inputLengthGetter();
|
|
47
|
-
let currentChunkOffset = chunkOffset;
|
|
48
|
-
chunkOffset += chunkSize;
|
|
49
|
-
const value = await reader.readUint8Array(currentChunkOffset + offset, Math.min(chunkSize, inputLength - currentChunkOffset));
|
|
50
|
-
const done = chunkOffset > inputLength;
|
|
51
|
-
return { value, done };
|
|
64
|
+
function createCodec(codecConstructor, readable, writable, options, config) {
|
|
65
|
+
const controller = new AbortController();
|
|
66
|
+
const { signal } = controller;
|
|
67
|
+
if (options.codecType.startsWith(CODEC_DEFLATE)) {
|
|
68
|
+
return {
|
|
69
|
+
run: () => run(DeflateStream),
|
|
70
|
+
abort
|
|
52
71
|
};
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const { data, signature } = value;
|
|
58
|
-
if (data && data.length) {
|
|
59
|
-
length += data.length;
|
|
60
|
-
await writer.writeUint8Array(data);
|
|
61
|
-
}
|
|
62
|
-
if (options.onprogress) {
|
|
63
|
-
try {
|
|
64
|
-
options.onprogress(chunkOffset, inputLength);
|
|
65
|
-
} catch (error) {
|
|
66
|
-
// ignored
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
if (done) {
|
|
70
|
-
resolve({ signature, length });
|
|
71
|
-
}
|
|
72
|
-
} catch (error) {
|
|
73
|
-
reject(error);
|
|
74
|
-
}
|
|
72
|
+
} else if (options.codecType.startsWith(CODEC_INFLATE)) {
|
|
73
|
+
return {
|
|
74
|
+
run: () => run(InflateStream),
|
|
75
|
+
abort
|
|
75
76
|
};
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function run(StreamConstructor) {
|
|
80
|
+
const stream = new StreamConstructor(codecConstructor, options, config);
|
|
81
|
+
await readable.pipeThrough(stream, { signal }).pipeTo(writable);
|
|
82
|
+
const { length, signature } = stream;
|
|
83
|
+
return { length, signature };
|
|
84
|
+
}
|
|
81
85
|
|
|
82
|
-
function
|
|
83
|
-
|
|
84
|
-
codec.abort();
|
|
85
|
-
throw new Error(ERR_ABORT);
|
|
86
|
+
function abort() {
|
|
87
|
+
controller.abort();
|
|
86
88
|
}
|
|
87
89
|
}
|
|
@@ -26,9 +26,17 @@
|
|
|
26
26
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
/* global Worker, URL */
|
|
30
|
-
|
|
31
|
-
import {
|
|
29
|
+
/* global Worker, URL, TransformStream */
|
|
30
|
+
|
|
31
|
+
import {
|
|
32
|
+
createCodec,
|
|
33
|
+
MESSAGE_EVENT_TYPE,
|
|
34
|
+
MESSAGE_START,
|
|
35
|
+
MESSAGE_PULL,
|
|
36
|
+
MESSAGE_DATA,
|
|
37
|
+
MESSAGE_ABORT,
|
|
38
|
+
MESSAGE_CLOSE
|
|
39
|
+
} from "./codec-interface.js";
|
|
32
40
|
|
|
33
41
|
let classicWorkersSupported = true;
|
|
34
42
|
|
|
@@ -36,10 +44,12 @@ export {
|
|
|
36
44
|
getWorker
|
|
37
45
|
};
|
|
38
46
|
|
|
39
|
-
function getWorker(workerData, codecConstructor, options, config, onTaskFinished, webWorker, scripts) {
|
|
47
|
+
function getWorker(workerData, codecConstructor, readable, writable, options, config, streamOptions, onTaskFinished, webWorker, scripts) {
|
|
40
48
|
Object.assign(workerData, {
|
|
41
49
|
busy: true,
|
|
42
50
|
codecConstructor,
|
|
51
|
+
readable,
|
|
52
|
+
writable,
|
|
43
53
|
options: Object.assign({}, options),
|
|
44
54
|
scripts,
|
|
45
55
|
terminate() {
|
|
@@ -53,27 +63,50 @@ function getWorker(workerData, codecConstructor, options, config, onTaskFinished
|
|
|
53
63
|
onTaskFinished(workerData);
|
|
54
64
|
}
|
|
55
65
|
});
|
|
66
|
+
const { signal, onprogress, size } = streamOptions;
|
|
67
|
+
if (signal || onprogress) {
|
|
68
|
+
let chunkOffset = 0;
|
|
69
|
+
const transformer = {};
|
|
70
|
+
if (onprogress) {
|
|
71
|
+
transformer.transform = (chunk, controller) => {
|
|
72
|
+
chunkOffset += chunk.length;
|
|
73
|
+
try {
|
|
74
|
+
onprogress(chunkOffset, size());
|
|
75
|
+
} catch (_error) {
|
|
76
|
+
// ignored
|
|
77
|
+
}
|
|
78
|
+
controller.enqueue(chunk);
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
workerData.readable = readable.pipeThrough(new TransformStream(transformer), { signal });
|
|
82
|
+
}
|
|
56
83
|
return webWorker ? createWebWorkerInterface(workerData, config) : createWorkerInterface(workerData, config);
|
|
57
84
|
}
|
|
58
85
|
|
|
59
86
|
function createWorkerInterface(workerData, config) {
|
|
60
|
-
const interfaceCodec = createCodec(workerData.codecConstructor, workerData.options, config);
|
|
87
|
+
const interfaceCodec = createCodec(workerData.codecConstructor, workerData.readable, workerData.writable, workerData.options, config);
|
|
61
88
|
const codec = {
|
|
62
89
|
abort() {
|
|
63
90
|
interfaceCodec.abort();
|
|
64
91
|
workerData.onTaskFinished();
|
|
65
92
|
},
|
|
66
|
-
|
|
67
|
-
|
|
93
|
+
run() {
|
|
94
|
+
const result = interfaceCodec.run();
|
|
95
|
+
workerData.onTaskFinished();
|
|
96
|
+
return result;
|
|
68
97
|
}
|
|
69
98
|
};
|
|
70
|
-
interfaceCodec.pull = () => codec.pull();
|
|
71
|
-
interfaceCodec.ondata = data => ondata(workerData, codec, data);
|
|
72
99
|
return codec;
|
|
73
100
|
}
|
|
74
101
|
|
|
75
102
|
function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
|
|
76
103
|
const workerOptions = { type: "module" };
|
|
104
|
+
workerData.reader = workerData.readable.getReader();
|
|
105
|
+
workerData.writer = workerData.writable.getWriter();
|
|
106
|
+
workerData.result = new Promise((resolve, reject) => {
|
|
107
|
+
workerData.resolveResult = resolve;
|
|
108
|
+
workerData.rejectResult = reject;
|
|
109
|
+
});
|
|
77
110
|
if (!workerData.interface) {
|
|
78
111
|
if (!classicWorkersSupported) {
|
|
79
112
|
workerData.worker = getWorker(workerOptions);
|
|
@@ -91,10 +124,11 @@ function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
|
|
|
91
124
|
sendMessage({ type: MESSAGE_ABORT });
|
|
92
125
|
workerData.onTaskFinished();
|
|
93
126
|
},
|
|
94
|
-
|
|
127
|
+
run() {
|
|
95
128
|
const options = workerData.options;
|
|
96
129
|
const scripts = workerData.scripts.slice(1);
|
|
97
130
|
sendMessage({ type: MESSAGE_START, scripts, options, config: { chunkSize } });
|
|
131
|
+
return workerData.result;
|
|
98
132
|
}
|
|
99
133
|
};
|
|
100
134
|
}
|
|
@@ -136,39 +170,31 @@ function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
|
|
|
136
170
|
async function onMessage(event) {
|
|
137
171
|
const message = event.data;
|
|
138
172
|
const reponseError = message.error;
|
|
139
|
-
const codec = workerData.interface;
|
|
140
173
|
try {
|
|
141
174
|
if (reponseError) {
|
|
142
175
|
const error = new Error(reponseError.message);
|
|
143
176
|
error.stack = reponseError.stack;
|
|
144
|
-
|
|
177
|
+
workerData.rejectResult(error);
|
|
145
178
|
workerData.onTaskFinished();
|
|
146
179
|
} else {
|
|
147
180
|
if (message.type == MESSAGE_PULL) {
|
|
148
|
-
const { value, done } = await
|
|
181
|
+
const { value, done } = await workerData.reader.read();
|
|
149
182
|
sendMessage({ type: MESSAGE_DATA, data: value, done, messageId: message.messageId });
|
|
150
183
|
}
|
|
151
184
|
if (message.type == MESSAGE_DATA) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
185
|
+
let { data } = message;
|
|
186
|
+
data = new Uint8Array(data);
|
|
187
|
+
await workerData.writer.ready;
|
|
188
|
+
workerData.writer.write(data);
|
|
189
|
+
}
|
|
190
|
+
if (message.type == MESSAGE_CLOSE) {
|
|
191
|
+
workerData.resolveResult(message.result);
|
|
192
|
+
workerData.onTaskFinished();
|
|
157
193
|
}
|
|
158
194
|
}
|
|
159
195
|
} catch (error) {
|
|
160
|
-
|
|
196
|
+
workerData.rejectResult(error);
|
|
161
197
|
workerData.onTaskFinished();
|
|
162
198
|
}
|
|
163
199
|
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
async function ondata(workerData, codec, data) {
|
|
167
|
-
let { value, done } = data;
|
|
168
|
-
if (done) {
|
|
169
|
-
await codec.ondata({ value: { data: value.data, signature: value.signature }, done });
|
|
170
|
-
workerData.onTaskFinished();
|
|
171
|
-
} else if (value.data) {
|
|
172
|
-
await codec.ondata({ value: { data: value.data } });
|
|
173
|
-
}
|
|
174
200
|
}
|
|
@@ -28,47 +28,66 @@
|
|
|
28
28
|
|
|
29
29
|
/* global setTimeout, clearTimeout */
|
|
30
30
|
|
|
31
|
-
import {
|
|
31
|
+
import {
|
|
32
|
+
CODEC_INFLATE,
|
|
33
|
+
CODEC_DEFLATE,
|
|
34
|
+
ERR_INVALID_SIGNATURE,
|
|
35
|
+
ERR_INVALID_PASSWORD,
|
|
36
|
+
ERR_ABORT
|
|
37
|
+
} from "./codec-interface.js";
|
|
32
38
|
import { getWorker } from "./codec-pool-worker.js";
|
|
33
39
|
|
|
34
40
|
let pool = [];
|
|
35
41
|
const pendingRequests = [];
|
|
36
42
|
|
|
37
43
|
export {
|
|
38
|
-
|
|
44
|
+
runCodec,
|
|
39
45
|
terminateWorkers,
|
|
40
46
|
CODEC_DEFLATE,
|
|
41
47
|
CODEC_INFLATE,
|
|
42
48
|
ERR_INVALID_SIGNATURE,
|
|
43
|
-
ERR_INVALID_PASSWORD
|
|
49
|
+
ERR_INVALID_PASSWORD,
|
|
50
|
+
ERR_ABORT
|
|
44
51
|
};
|
|
45
52
|
|
|
46
53
|
let indexWorker = 0;
|
|
47
54
|
|
|
48
|
-
function
|
|
55
|
+
async function runCodec(codecConstructor, readable, writable, options, config, streamOptions) {
|
|
49
56
|
const streamCopy = !options.compressed && !options.signed && !options.encrypted;
|
|
50
57
|
const webWorker = !streamCopy && (options.useWebWorkers || (options.useWebWorkers === undefined && config.useWebWorkers));
|
|
51
58
|
const scripts = webWorker && config.workerScripts ? config.workerScripts[options.codecType] : [];
|
|
52
59
|
options.useCompressionStream = options.useCompressionStream === undefined ? config.useCompressionStream : options.useCompressionStream;
|
|
60
|
+
let codec;
|
|
53
61
|
if (pool.length < config.maxWorkers) {
|
|
54
62
|
const workerData = { indexWorker };
|
|
55
63
|
indexWorker++;
|
|
56
64
|
pool.push(workerData);
|
|
57
|
-
|
|
65
|
+
codec = getWorker(workerData, codecConstructor, readable, writable, options, config, streamOptions, onTaskFinished, webWorker, scripts);
|
|
58
66
|
} else {
|
|
59
67
|
const workerData = pool.find(workerData => !workerData.busy);
|
|
60
68
|
if (workerData) {
|
|
61
69
|
clearTerminateTimeout(workerData);
|
|
62
|
-
|
|
70
|
+
codec = getWorker(workerData, codecConstructor, readable, writable, options, config, streamOptions, onTaskFinished, webWorker, scripts);
|
|
71
|
+
} else {
|
|
72
|
+
codec = await new Promise(resolve => pendingRequests.push({ resolve, codecConstructor, readable, writable, options, webWorker, scripts }));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const { signal } = streamOptions;
|
|
76
|
+
try {
|
|
77
|
+
return await codec.run(signal);
|
|
78
|
+
} catch (error) {
|
|
79
|
+
if (signal && signal.aborted && (signal.reason == error || error.name == ERR_ABORT)) {
|
|
80
|
+
codec.abort();
|
|
81
|
+
throw new Error(ERR_ABORT);
|
|
63
82
|
} else {
|
|
64
|
-
|
|
83
|
+
throw error;
|
|
65
84
|
}
|
|
66
85
|
}
|
|
67
86
|
|
|
68
87
|
function onTaskFinished(workerData) {
|
|
69
88
|
if (pendingRequests.length) {
|
|
70
|
-
const [{ resolve, codecConstructor, options, webWorker, scripts }] = pendingRequests.splice(0, 1);
|
|
71
|
-
resolve(getWorker(workerData, codecConstructor, options, config, onTaskFinished, webWorker, scripts));
|
|
89
|
+
const [{ resolve, codecConstructor, readable, writable, options, webWorker, scripts }] = pendingRequests.splice(0, 1);
|
|
90
|
+
resolve(getWorker(workerData, codecConstructor, readable, writable, options, config, streamOptions, onTaskFinished, webWorker, scripts));
|
|
72
91
|
} else if (workerData.worker) {
|
|
73
92
|
clearTerminateTimeout(workerData);
|
|
74
93
|
if (Number.isFinite(config.terminateWorkerTimeout) && config.terminateWorkerTimeout >= 0) {
|
|
@@ -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;
|
|
@@ -60,6 +66,9 @@ function configure(configuration) {
|
|
|
60
66
|
if (configuration.terminateWorkerTimeout !== undefined) {
|
|
61
67
|
config.terminateWorkerTimeout = configuration.terminateWorkerTimeout;
|
|
62
68
|
}
|
|
69
|
+
if (configuration.useCompressionStream !== undefined) {
|
|
70
|
+
config.useCompressionStream = configuration.useCompressionStream;
|
|
71
|
+
}
|
|
63
72
|
if (configuration.useWebWorkers !== undefined) {
|
|
64
73
|
config.useWebWorkers = configuration.useWebWorkers;
|
|
65
74
|
}
|