@zip.js/zip.js 2.7.32 → 2.7.33
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 +133 -42
- package/dist/zip-fs-full.min.js +1 -1
- package/dist/zip-fs.js +133 -42
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-full.js +133 -42
- 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 +133 -42
- package/dist/zip.min.js +1 -1
- package/index.cjs +133 -42
- package/index.d.ts +2 -2
- package/index.min.js +1 -1
- package/lib/core/codec-pool.js +16 -8
- package/lib/core/codec-worker.js +47 -16
- package/lib/core/streams/codec-stream.js +53 -6
- package/lib/core/streams/zip-entry-stream.js +6 -2
- package/lib/core/z-worker-core.js +33 -7
- package/lib/core/zip-writer.js +13 -10
- package/lib/z-worker-inline.js +1 -1
- package/package.json +4 -4
package/lib/core/codec-pool.js
CHANGED
|
@@ -84,10 +84,18 @@ async function runWorker(stream, workerOptions) {
|
|
|
84
84
|
} else if (workerData.worker) {
|
|
85
85
|
clearTerminateTimeout(workerData);
|
|
86
86
|
if (Number.isFinite(terminateWorkerTimeout) && terminateWorkerTimeout >= 0) {
|
|
87
|
-
workerData.
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
if (workerData.terminated) {
|
|
88
|
+
workerData.terminated = false;
|
|
89
|
+
} else {
|
|
90
|
+
workerData.terminateTimeout = setTimeout(async () => {
|
|
91
|
+
pool = pool.filter(data => data != workerData);
|
|
92
|
+
try {
|
|
93
|
+
await workerData.terminate();
|
|
94
|
+
} catch (_error) {
|
|
95
|
+
// ignored
|
|
96
|
+
}
|
|
97
|
+
}, terminateWorkerTimeout);
|
|
98
|
+
}
|
|
91
99
|
}
|
|
92
100
|
} else {
|
|
93
101
|
pool = pool.filter(data => data != workerData);
|
|
@@ -103,9 +111,9 @@ function clearTerminateTimeout(workerData) {
|
|
|
103
111
|
}
|
|
104
112
|
}
|
|
105
113
|
|
|
106
|
-
function terminateWorkers() {
|
|
107
|
-
pool.
|
|
114
|
+
async function terminateWorkers() {
|
|
115
|
+
await Promise.allSettled(pool.map(workerData => {
|
|
108
116
|
clearTerminateTimeout(workerData);
|
|
109
|
-
workerData.terminate();
|
|
110
|
-
});
|
|
117
|
+
return workerData.terminate();
|
|
118
|
+
}));
|
|
111
119
|
}
|
package/lib/core/codec-worker.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
worker
|
|
67
|
-
|
|
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,7 +97,7 @@ class CodecWorker {
|
|
|
78
97
|
|
|
79
98
|
class ProgressWatcherStream extends TransformStream {
|
|
80
99
|
|
|
81
|
-
constructor(readableSource, { onstart, onprogress, size, onend }
|
|
100
|
+
constructor(readableSource, { onstart, onprogress, size, onend }) {
|
|
82
101
|
let chunkOffset = 0;
|
|
83
102
|
super({
|
|
84
103
|
start() {
|
|
@@ -99,7 +118,7 @@ class ProgressWatcherStream extends TransformStream {
|
|
|
99
118
|
callHandler(onend, chunkOffset);
|
|
100
119
|
}
|
|
101
120
|
}
|
|
102
|
-
}
|
|
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,
|
|
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
|
|
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
|
-
|
|
165
|
+
inputSize,
|
|
166
|
+
outputSize
|
|
139
167
|
} = codecStream;
|
|
140
168
|
return {
|
|
141
169
|
signature,
|
|
142
|
-
|
|
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
|
|
|
@@ -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
|
|
84
|
+
let outputSize = 0;
|
|
85
|
+
let inputSize = 0;
|
|
84
86
|
const stream = new Stream(options, config);
|
|
85
87
|
const readable = super.readable;
|
|
86
|
-
const
|
|
88
|
+
const inputSizeStream = new TransformStream({
|
|
87
89
|
transform(chunk, controller) {
|
|
88
90
|
if (chunk && chunk.length) {
|
|
89
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
}
|
|
@@ -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
|
-
|
|
151
|
+
try {
|
|
152
|
+
readable = pipeThrough(readable, new CodecStream(COMPRESSION_FORMAT, options));
|
|
153
|
+
} catch (error) {
|
|
154
|
+
return readable;
|
|
155
|
+
}
|
|
152
156
|
} else {
|
|
153
|
-
|
|
157
|
+
return readable;
|
|
154
158
|
}
|
|
155
159
|
}
|
|
156
160
|
return readable;
|
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
136
|
+
inputSize,
|
|
137
|
+
outputSize
|
|
119
138
|
} = codecStream;
|
|
120
139
|
sendMessage({
|
|
121
140
|
type: MESSAGE_CLOSE,
|
|
122
141
|
result: {
|
|
123
142
|
signature,
|
|
124
|
-
|
|
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) {
|
package/lib/core/zip-writer.js
CHANGED
|
@@ -164,7 +164,7 @@ class ZipWriter {
|
|
|
164
164
|
const { pendingAddFileCalls, writer } = this;
|
|
165
165
|
const { writable } = writer;
|
|
166
166
|
while (pendingAddFileCalls.size) {
|
|
167
|
-
await Promise.
|
|
167
|
+
await Promise.allSettled(Array.from(pendingAddFileCalls));
|
|
168
168
|
}
|
|
169
169
|
await closeFile(this, comment, options);
|
|
170
170
|
const preventClose = getOptionValue(zipWriter, options, "preventClose");
|
|
@@ -420,7 +420,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
420
420
|
} else if (fileEntry.offset >= MAX_32_BITS) {
|
|
421
421
|
throw new Error(ERR_UNSUPPORTED_FORMAT);
|
|
422
422
|
}
|
|
423
|
-
zipWriter.offset += fileEntry.
|
|
423
|
+
zipWriter.offset += fileEntry.size;
|
|
424
424
|
return fileEntry;
|
|
425
425
|
} catch (error) {
|
|
426
426
|
if ((bufferedWrite && writingBufferedEntryData) || (!bufferedWrite && writingEntryData)) {
|
|
@@ -571,10 +571,10 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
571
571
|
streamOptions: { signal, size, onstart, onprogress, onend }
|
|
572
572
|
};
|
|
573
573
|
const result = await runWorker({ readable, writable }, workerOptions);
|
|
574
|
-
|
|
574
|
+
uncompressedSize = result.inputSize;
|
|
575
|
+
compressedSize = result.outputSize;
|
|
575
576
|
signature = result.signature;
|
|
576
|
-
|
|
577
|
-
compressedSize = result.size;
|
|
577
|
+
writable.size += uncompressedSize;
|
|
578
578
|
} else {
|
|
579
579
|
await writeData(writable, localHeaderArray);
|
|
580
580
|
}
|
|
@@ -616,7 +616,7 @@ async function createFileEntry(reader, writer, { diskNumberStart, lock }, entryI
|
|
|
616
616
|
creationDate,
|
|
617
617
|
lastAccessDate,
|
|
618
618
|
encrypted,
|
|
619
|
-
|
|
619
|
+
size: metadataSize + compressedSize,
|
|
620
620
|
compressionMethod,
|
|
621
621
|
version,
|
|
622
622
|
headerArray,
|
|
@@ -1088,10 +1088,13 @@ async function closeFile(zipWriter, comment, options) {
|
|
|
1088
1088
|
|
|
1089
1089
|
async function writeData(writable, array) {
|
|
1090
1090
|
const streamWriter = writable.getWriter();
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1091
|
+
try {
|
|
1092
|
+
await streamWriter.ready;
|
|
1093
|
+
writable.size += getLength(array);
|
|
1094
|
+
await streamWriter.write(array);
|
|
1095
|
+
} finally {
|
|
1096
|
+
streamWriter.releaseLock();
|
|
1097
|
+
}
|
|
1095
1098
|
}
|
|
1096
1099
|
|
|
1097
1100
|
function getTimeNTFS(date) {
|