@zip.js/zip.js 2.7.73 → 2.8.1
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/deno.json +2 -4
- package/dist/README.md +7 -25
- package/dist/zip-core.js +5961 -0
- package/dist/zip-core.min.js +1 -0
- package/dist/{zip-full.js → zip-fs-core.js} +4160 -7358
- package/dist/zip-fs-core.min.js +1 -0
- package/dist/zip-fs.js +4355 -2542
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-module.wasm +0 -0
- package/dist/zip-web-worker.js +1 -0
- package/dist/zip.js +2647 -2466
- package/dist/zip.min.js +1 -1
- package/index.cjs +4624 -8659
- package/index.d.ts +27 -176
- package/index.js +2 -63
- package/index.min.js +1 -1
- package/lib/core/codec-pool.js +6 -4
- package/lib/core/codec-worker.js +37 -20
- package/lib/core/configuration.js +16 -37
- package/lib/core/io.js +3 -8
- package/lib/core/streams/aes-crypto-stream.js +1 -0
- package/lib/core/streams/zip-entry-stream.js +19 -11
- package/lib/core/streams/zlib/README.md +1 -0
- package/lib/core/streams/{stream-adapter.js → zlib/zlib-streams-loader.js} +54 -25
- package/lib/core/streams/zlib/zlib-streams.js +184 -0
- package/lib/core/streams/zlib/zlib-streams.wasm +0 -0
- package/lib/core/util/decode-text.js +1 -1
- package/lib/core/util/encode-text.js +1 -0
- package/lib/core/util/mini-lz.js +198 -0
- package/lib/{z-worker.js → core/web-worker-inline-template.js} +10 -9
- package/lib/core/web-worker-inline.js +1 -0
- package/lib/core/{z-worker-core.js → web-worker.js} +17 -36
- package/lib/core/zip-entry.js +3 -7
- package/lib/core/zip-reader.js +11 -4
- package/lib/core/zip-writer.js +11 -13
- package/lib/{z-worker-bootstrap-pako.js → core/zlib-streams-inline-template.js} +8 -10
- package/lib/core/zlib-streams-inline.js +1 -0
- package/{index-fflate.js → lib/zip-core.js} +43 -22
- package/lib/{z-worker-fflate.js → zip-fs-core.js} +5 -15
- package/lib/zip-fs.js +7 -24
- package/lib/zip.js +6 -23
- package/package.json +13 -33
- package/dist/z-worker-fflate.js +0 -1
- package/dist/z-worker-pako.js +0 -1
- package/dist/z-worker.js +0 -1
- package/dist/zip-fs-full.js +0 -12536
- package/dist/zip-fs-full.min.js +0 -1
- package/dist/zip-full.min.js +0 -1
- package/dist/zip-no-worker-deflate.min.js +0 -1
- package/dist/zip-no-worker-inflate.min.js +0 -1
- package/dist/zip-no-worker.min.js +0 -1
- package/lib/core/streams/codecs/deflate.js +0 -2059
- package/lib/core/streams/codecs/inflate.js +0 -2163
- package/lib/core/util/stream-codec-shim.js +0 -91
- package/lib/z-worker-bootstrap-fflate.js +0 -40
- package/lib/z-worker-inline-template.js +0 -42
- package/lib/z-worker-inline.js +0 -1
- package/lib/zip-data-uri.js +0 -56
- package/lib/zip-fflate-shim.js +0 -37
- package/lib/zip-full-fflate.js +0 -54
- package/lib/zip-full.js +0 -55
- package/lib/zip-no-worker-deflate.js +0 -42
- package/lib/zip-no-worker-fflate-deflate.js +0 -42
- package/lib/zip-no-worker-fflate-inflate.js +0 -42
- package/lib/zip-no-worker-fflate.js +0 -43
- package/lib/zip-no-worker-inflate.js +0 -42
- package/lib/zip-no-worker.js +0 -44
- /package/lib/core/util/{cp437-decode.js → decode-cp437.js} +0 -0
- /package/lib/core/{zip-fs-core.js → zip-fs.js} +0 -0
package/lib/core/codec-pool.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Copyright (c)
|
|
2
|
+
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
3
3
|
|
|
4
4
|
Redistribution and use in source and binary forms, with or without
|
|
5
5
|
modification, are permitted provided that the following conditions are met:
|
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
ERR_ABORT_CHECK_PASSWORD
|
|
39
39
|
} from "./streams/codec-stream.js";
|
|
40
40
|
import { CodecWorker } from "./codec-worker.js";
|
|
41
|
+
import { resetWasmModule } from "./streams/zlib/zlib-streams-loader.js";
|
|
41
42
|
|
|
42
43
|
let pool = [];
|
|
43
44
|
const pendingRequests = [];
|
|
@@ -57,12 +58,12 @@ let indexWorker = 0;
|
|
|
57
58
|
|
|
58
59
|
async function runWorker(stream, workerOptions) {
|
|
59
60
|
const { options, config } = workerOptions;
|
|
60
|
-
const { transferStreams, useWebWorkers, useCompressionStream,
|
|
61
|
-
const {
|
|
61
|
+
const { transferStreams, useWebWorkers, useCompressionStream, compressed, signed, encrypted } = options;
|
|
62
|
+
const { workerURI, maxWorkers } = config;
|
|
62
63
|
workerOptions.transferStreams = transferStreams || transferStreams === UNDEFINED_VALUE;
|
|
63
64
|
const streamCopy = !compressed && !signed && !encrypted && !workerOptions.transferStreams;
|
|
64
65
|
workerOptions.useWebWorkers = !streamCopy && (useWebWorkers || (useWebWorkers === UNDEFINED_VALUE && config.useWebWorkers));
|
|
65
|
-
workerOptions.
|
|
66
|
+
workerOptions.workerURI = workerOptions.useWebWorkers && workerURI ? workerURI : UNDEFINED_VALUE;
|
|
66
67
|
options.useCompressionStream = useCompressionStream || (useCompressionStream === UNDEFINED_VALUE && config.useCompressionStream);
|
|
67
68
|
return (await getWorker()).run();
|
|
68
69
|
|
|
@@ -128,4 +129,5 @@ async function terminateWorkers() {
|
|
|
128
129
|
clearTerminateTimeout(workerData);
|
|
129
130
|
return workerData.terminate();
|
|
130
131
|
}));
|
|
132
|
+
resetWasmModule();
|
|
131
133
|
}
|
package/lib/core/codec-worker.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Copyright (c)
|
|
2
|
+
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
3
3
|
|
|
4
4
|
Redistribution and use in source and binary forms, with or without
|
|
5
5
|
modification, are permitted provided that the following conditions are met:
|
|
@@ -42,7 +42,12 @@ import {
|
|
|
42
42
|
MESSAGE_ACK_DATA,
|
|
43
43
|
MESSAGE_CLOSE
|
|
44
44
|
} from "./streams/codec-stream.js";
|
|
45
|
+
import {
|
|
46
|
+
initModule,
|
|
47
|
+
initializedModule
|
|
48
|
+
} from "./streams/zlib/zlib-streams-loader.js";
|
|
45
49
|
|
|
50
|
+
// deno-lint-ignore valid-typeof
|
|
46
51
|
let WEB_WORKERS_SUPPORTED = typeof Worker != UNDEFINED_TYPE;
|
|
47
52
|
|
|
48
53
|
export {
|
|
@@ -51,7 +56,7 @@ export {
|
|
|
51
56
|
|
|
52
57
|
class CodecWorker {
|
|
53
58
|
|
|
54
|
-
constructor(workerData, { readable, writable }, { options, config, streamOptions, useWebWorkers, transferStreams,
|
|
59
|
+
constructor(workerData, { readable, writable }, { options, config, streamOptions, useWebWorkers, transferStreams, workerURI }, onTaskFinished) {
|
|
55
60
|
const { signal } = streamOptions;
|
|
56
61
|
Object.assign(workerData, {
|
|
57
62
|
busy: true,
|
|
@@ -60,7 +65,7 @@ class CodecWorker {
|
|
|
60
65
|
.pipeThrough(new ProgressWatcherStream(streamOptions), { signal }),
|
|
61
66
|
writable,
|
|
62
67
|
options: Object.assign({}, options),
|
|
63
|
-
|
|
68
|
+
workerURI,
|
|
64
69
|
transferStreams,
|
|
65
70
|
terminate() {
|
|
66
71
|
return new Promise(resolve => {
|
|
@@ -136,11 +141,17 @@ function createWorkerInterface(workerData, config) {
|
|
|
136
141
|
}
|
|
137
142
|
|
|
138
143
|
function createWebWorkerInterface(workerData, config) {
|
|
139
|
-
const {
|
|
144
|
+
const { baseURI, chunkSize } = config;
|
|
145
|
+
let { wasmURI } = config;
|
|
146
|
+
|
|
140
147
|
if (!workerData.interface) {
|
|
148
|
+
// deno-lint-ignore valid-typeof
|
|
149
|
+
if (typeof wasmURI == FUNCTION_TYPE) {
|
|
150
|
+
wasmURI = wasmURI();
|
|
151
|
+
}
|
|
141
152
|
let worker;
|
|
142
153
|
try {
|
|
143
|
-
worker = getWebWorker(workerData.
|
|
154
|
+
worker = getWebWorker(workerData.workerURI, baseURI, workerData);
|
|
144
155
|
// eslint-disable-next-line no-unused-vars
|
|
145
156
|
} catch (_) {
|
|
146
157
|
WEB_WORKERS_SUPPORTED = false;
|
|
@@ -149,7 +160,7 @@ function createWebWorkerInterface(workerData, config) {
|
|
|
149
160
|
Object.assign(workerData, {
|
|
150
161
|
worker,
|
|
151
162
|
interface: {
|
|
152
|
-
run: () => runWebWorker(workerData, { chunkSize })
|
|
163
|
+
run: () => runWebWorker(workerData, { chunkSize, wasmURI, baseURI })
|
|
153
164
|
}
|
|
154
165
|
});
|
|
155
166
|
}
|
|
@@ -159,6 +170,14 @@ function createWebWorkerInterface(workerData, config) {
|
|
|
159
170
|
async function runWorker({ options, readable, writable, onTaskFinished }, config) {
|
|
160
171
|
let codecStream;
|
|
161
172
|
try {
|
|
173
|
+
if (!options.useCompressionStream && !initializedModule) {
|
|
174
|
+
let { wasmURI } = config;
|
|
175
|
+
// deno-lint-ignore valid-typeof
|
|
176
|
+
if (typeof wasmURI == FUNCTION_TYPE) {
|
|
177
|
+
wasmURI = wasmURI();
|
|
178
|
+
}
|
|
179
|
+
await initModule(wasmURI, config);
|
|
180
|
+
}
|
|
162
181
|
codecStream = new CodecStream(options, config);
|
|
163
182
|
await readable.pipeThrough(codecStream).pipeTo(writable, { preventClose: true, preventAbort: true });
|
|
164
183
|
const {
|
|
@@ -194,11 +213,10 @@ async function runWebWorker(workerData, config) {
|
|
|
194
213
|
rejectResult,
|
|
195
214
|
result
|
|
196
215
|
});
|
|
197
|
-
const { readable, options
|
|
216
|
+
const { readable, options } = workerData;
|
|
198
217
|
const { writable, closed } = watchClosedStream(workerData.writable);
|
|
199
218
|
const streamsTransferred = sendMessage({
|
|
200
219
|
type: MESSAGE_START,
|
|
201
|
-
scripts: scripts.slice(1),
|
|
202
220
|
options,
|
|
203
221
|
config,
|
|
204
222
|
readable,
|
|
@@ -239,30 +257,29 @@ function watchClosedStream(writableSource) {
|
|
|
239
257
|
return { writable, closed };
|
|
240
258
|
}
|
|
241
259
|
|
|
242
|
-
let classicWorkersSupported = true;
|
|
243
260
|
let transferStreamsSupported = true;
|
|
244
261
|
|
|
245
|
-
function getWebWorker(url,
|
|
262
|
+
function getWebWorker(url, baseURI, workerData) {
|
|
246
263
|
const workerOptions = { type: "module" };
|
|
247
264
|
let scriptUrl, worker;
|
|
265
|
+
// deno-lint-ignore valid-typeof
|
|
248
266
|
if (typeof url == FUNCTION_TYPE) {
|
|
249
267
|
url = url();
|
|
250
268
|
}
|
|
251
|
-
|
|
252
|
-
scriptUrl = new URL(url, baseURL);
|
|
253
|
-
// eslint-disable-next-line no-unused-vars
|
|
254
|
-
} catch (_) {
|
|
255
|
-
scriptUrl = url;
|
|
256
|
-
}
|
|
257
|
-
if (classicWorkersSupported) {
|
|
269
|
+
if (url.startsWith("data:") || url.startsWith("blob:")) {
|
|
258
270
|
try {
|
|
259
|
-
worker = new Worker(
|
|
271
|
+
worker = new Worker(url);
|
|
260
272
|
// eslint-disable-next-line no-unused-vars
|
|
261
273
|
} catch (_) {
|
|
262
|
-
|
|
263
|
-
worker = new Worker(scriptUrl, workerOptions);
|
|
274
|
+
worker = new Worker(url, workerOptions);
|
|
264
275
|
}
|
|
265
276
|
} else {
|
|
277
|
+
try {
|
|
278
|
+
scriptUrl = new URL(url, baseURI);
|
|
279
|
+
// eslint-disable-next-line no-unused-vars
|
|
280
|
+
} catch (_) {
|
|
281
|
+
scriptUrl = url;
|
|
282
|
+
}
|
|
266
283
|
worker = new Worker(scriptUrl, workerOptions);
|
|
267
284
|
}
|
|
268
285
|
worker.addEventListener(MESSAGE_EVENT_TYPE, event => onMessage(event, workerData));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Copyright (c)
|
|
2
|
+
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
3
3
|
|
|
4
4
|
Redistribution and use in source and binary forms, with or without
|
|
5
5
|
modification, are permitted provided that the following conditions are met:
|
|
@@ -32,7 +32,6 @@ import {
|
|
|
32
32
|
UNDEFINED_VALUE,
|
|
33
33
|
UNDEFINED_TYPE
|
|
34
34
|
} from "./constants.js";
|
|
35
|
-
import { StreamAdapter } from "./streams/stream-adapter.js";
|
|
36
35
|
|
|
37
36
|
const MINIMUM_CHUNK_SIZE = 64;
|
|
38
37
|
let maxWorkers = 2;
|
|
@@ -45,14 +44,15 @@ try {
|
|
|
45
44
|
// ignored
|
|
46
45
|
}
|
|
47
46
|
const DEFAULT_CONFIGURATION = {
|
|
48
|
-
|
|
47
|
+
workerURI: "./core/web-worker.js",
|
|
48
|
+
wasmURI: "./core/streams/zlib/zlib-streams.wasm",
|
|
49
|
+
chunkSize: 64 * 1024,
|
|
49
50
|
maxWorkers,
|
|
50
51
|
terminateWorkerTimeout: 5000,
|
|
51
52
|
useWebWorkers: true,
|
|
52
53
|
useCompressionStream: true,
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
DecompressionStreamNative: typeof DecompressionStream != UNDEFINED_TYPE && DecompressionStream
|
|
54
|
+
CompressionStream: typeof CompressionStream != UNDEFINED_TYPE && CompressionStream,
|
|
55
|
+
DecompressionStream: typeof DecompressionStream != UNDEFINED_TYPE && DecompressionStream
|
|
56
56
|
};
|
|
57
57
|
|
|
58
58
|
const config = Object.assign({}, DEFAULT_CONFIGURATION);
|
|
@@ -73,52 +73,31 @@ function getChunkSize(config) {
|
|
|
73
73
|
|
|
74
74
|
function configure(configuration) {
|
|
75
75
|
const {
|
|
76
|
-
|
|
76
|
+
baseURI,
|
|
77
77
|
chunkSize,
|
|
78
78
|
maxWorkers,
|
|
79
79
|
terminateWorkerTimeout,
|
|
80
80
|
useCompressionStream,
|
|
81
81
|
useWebWorkers,
|
|
82
|
-
Deflate,
|
|
83
|
-
Inflate,
|
|
84
82
|
CompressionStream,
|
|
85
83
|
DecompressionStream,
|
|
86
|
-
|
|
84
|
+
CompressionStreamZlib,
|
|
85
|
+
DecompressionStreamZlib,
|
|
86
|
+
workerURI,
|
|
87
|
+
wasmURI
|
|
87
88
|
} = configuration;
|
|
88
|
-
setIfDefined("
|
|
89
|
+
setIfDefined("baseURI", baseURI);
|
|
90
|
+
setIfDefined("wasmURI", wasmURI);
|
|
91
|
+
setIfDefined("workerURI", workerURI);
|
|
89
92
|
setIfDefined("chunkSize", chunkSize);
|
|
90
93
|
setIfDefined("maxWorkers", maxWorkers);
|
|
91
94
|
setIfDefined("terminateWorkerTimeout", terminateWorkerTimeout);
|
|
92
95
|
setIfDefined("useCompressionStream", useCompressionStream);
|
|
93
96
|
setIfDefined("useWebWorkers", useWebWorkers);
|
|
94
|
-
if (Deflate) {
|
|
95
|
-
config.CompressionStream = new StreamAdapter(Deflate);
|
|
96
|
-
}
|
|
97
|
-
if (Inflate) {
|
|
98
|
-
config.DecompressionStream = new StreamAdapter(Inflate);
|
|
99
|
-
}
|
|
100
97
|
setIfDefined("CompressionStream", CompressionStream);
|
|
101
98
|
setIfDefined("DecompressionStream", DecompressionStream);
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (deflate || inflate) {
|
|
105
|
-
if (!config.workerScripts) {
|
|
106
|
-
config.workerScripts = {};
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
if (deflate) {
|
|
110
|
-
if (!Array.isArray(deflate)) {
|
|
111
|
-
throw new Error("workerScripts.deflate must be an array");
|
|
112
|
-
}
|
|
113
|
-
config.workerScripts.deflate = deflate;
|
|
114
|
-
}
|
|
115
|
-
if (inflate) {
|
|
116
|
-
if (!Array.isArray(inflate)) {
|
|
117
|
-
throw new Error("workerScripts.inflate must be an array");
|
|
118
|
-
}
|
|
119
|
-
config.workerScripts.inflate = inflate;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
99
|
+
setIfDefined("CompressionStreamZlib", CompressionStreamZlib);
|
|
100
|
+
setIfDefined("DecompressionStreamZlib", DecompressionStreamZlib);
|
|
122
101
|
}
|
|
123
102
|
|
|
124
103
|
function setIfDefined(propertyName, propertyValue) {
|
package/lib/core/io.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Copyright (c)
|
|
2
|
+
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
3
3
|
|
|
4
4
|
Redistribution and use in source and binary forms, with or without
|
|
5
5
|
modification, are permitted provided that the following conditions are met:
|
|
@@ -738,8 +738,8 @@ class GenericWriter {
|
|
|
738
738
|
}
|
|
739
739
|
|
|
740
740
|
function isHttpFamily(url) {
|
|
741
|
-
const {
|
|
742
|
-
const { protocol } = new URL(url,
|
|
741
|
+
const { baseURI } = getConfiguration();
|
|
742
|
+
const { protocol } = new URL(url, baseURI);
|
|
743
743
|
return protocol == "http:" || protocol == "https:";
|
|
744
744
|
}
|
|
745
745
|
|
|
@@ -755,9 +755,6 @@ function readUint8Array(reader, offset, size, diskNumber) {
|
|
|
755
755
|
return reader.readUint8Array(offset, size, diskNumber);
|
|
756
756
|
}
|
|
757
757
|
|
|
758
|
-
const SplitZipReader = SplitDataReader;
|
|
759
|
-
const SplitZipWriter = SplitDataWriter;
|
|
760
|
-
|
|
761
758
|
export {
|
|
762
759
|
initStream,
|
|
763
760
|
GenericReader,
|
|
@@ -775,8 +772,6 @@ export {
|
|
|
775
772
|
Uint8ArrayWriter,
|
|
776
773
|
HttpReader,
|
|
777
774
|
HttpRangeReader,
|
|
778
|
-
SplitZipReader,
|
|
779
|
-
SplitZipWriter,
|
|
780
775
|
SplitDataReader,
|
|
781
776
|
SplitDataWriter,
|
|
782
777
|
ERR_HTTP_RANGE,
|
|
@@ -56,6 +56,7 @@ const SALT_LENGTH = [8, 12, 16];
|
|
|
56
56
|
const KEY_LENGTH = [16, 24, 32];
|
|
57
57
|
const SIGNATURE_LENGTH = 10;
|
|
58
58
|
const COUNTER_DEFAULT_VALUE = [0, 0, 0, 0];
|
|
59
|
+
// deno-lint-ignore valid-typeof
|
|
59
60
|
const CRYPTO_API_SUPPORTED = typeof crypto != UNDEFINED_TYPE;
|
|
60
61
|
const subtle = CRYPTO_API_SUPPORTED && crypto.subtle;
|
|
61
62
|
const SUBTLE_API_SUPPORTED = CRYPTO_API_SUPPORTED && typeof subtle != UNDEFINED_TYPE;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Copyright (c)
|
|
2
|
+
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
3
3
|
|
|
4
4
|
Redistribution and use in source and binary forms, with or without
|
|
5
5
|
modification, are permitted provided that the following conditions are met:
|
|
@@ -45,11 +45,12 @@ import {
|
|
|
45
45
|
} from "./common-crypto.js";
|
|
46
46
|
|
|
47
47
|
const ERR_INVALID_UNCOMPRESSED_SIZE = "Invalid uncompressed size";
|
|
48
|
-
const
|
|
48
|
+
const FORMAT_DEFLATE_RAW = "deflate-raw";
|
|
49
|
+
const FORMAT_DEFLATE64_RAW = "deflate64-raw";
|
|
49
50
|
|
|
50
51
|
class DeflateStream extends TransformStream {
|
|
51
52
|
|
|
52
|
-
constructor(options, { chunkSize,
|
|
53
|
+
constructor(options, { chunkSize, CompressionStreamZlib, CompressionStream }) {
|
|
53
54
|
super({});
|
|
54
55
|
const { compressed, encrypted, useCompressionStream, zipCrypto, signed, level } = options;
|
|
55
56
|
const stream = this;
|
|
@@ -60,7 +61,7 @@ class DeflateStream extends TransformStream {
|
|
|
60
61
|
readable = pipeThrough(readable, crc32Stream);
|
|
61
62
|
}
|
|
62
63
|
if (compressed) {
|
|
63
|
-
readable = pipeThroughCommpressionStream(readable, useCompressionStream, { level, chunkSize },
|
|
64
|
+
readable = pipeThroughCommpressionStream(readable, useCompressionStream, { level, chunkSize }, CompressionStream, CompressionStreamZlib, CompressionStream);
|
|
64
65
|
}
|
|
65
66
|
if (encrypted) {
|
|
66
67
|
if (zipCrypto) {
|
|
@@ -85,9 +86,9 @@ class DeflateStream extends TransformStream {
|
|
|
85
86
|
|
|
86
87
|
class InflateStream extends TransformStream {
|
|
87
88
|
|
|
88
|
-
constructor(options, { chunkSize,
|
|
89
|
+
constructor(options, { chunkSize, DecompressionStreamZlib, DecompressionStream }) {
|
|
89
90
|
super({});
|
|
90
|
-
const { zipCrypto, encrypted, signed, signature, compressed, useCompressionStream } = options;
|
|
91
|
+
const { zipCrypto, encrypted, signed, signature, compressed, useCompressionStream, deflate64 } = options;
|
|
91
92
|
let crc32Stream, decryptionStream;
|
|
92
93
|
let readable = super.readable;
|
|
93
94
|
if (encrypted) {
|
|
@@ -99,7 +100,7 @@ class InflateStream extends TransformStream {
|
|
|
99
100
|
}
|
|
100
101
|
}
|
|
101
102
|
if (compressed) {
|
|
102
|
-
readable = pipeThroughCommpressionStream(readable, useCompressionStream, { chunkSize },
|
|
103
|
+
readable = pipeThroughCommpressionStream(readable, useCompressionStream, { chunkSize, deflate64 }, DecompressionStream, DecompressionStreamZlib, DecompressionStream);
|
|
103
104
|
}
|
|
104
105
|
if ((!encrypted || zipCrypto) && signed) {
|
|
105
106
|
crc32Stream = new Crc32Stream();
|
|
@@ -134,13 +135,20 @@ function setReadable(stream, readable, flush) {
|
|
|
134
135
|
});
|
|
135
136
|
}
|
|
136
137
|
|
|
137
|
-
function pipeThroughCommpressionStream(readable, useCompressionStream, options,
|
|
138
|
+
function pipeThroughCommpressionStream(readable, useCompressionStream, options, CompressionStreamNative, CompressionStreamZlib, CompressionStream) {
|
|
139
|
+
const Stream = useCompressionStream && CompressionStreamNative ? CompressionStreamNative : CompressionStreamZlib || CompressionStream;
|
|
140
|
+
const format = options.deflate64 ? FORMAT_DEFLATE64_RAW : FORMAT_DEFLATE_RAW;
|
|
138
141
|
try {
|
|
139
|
-
|
|
140
|
-
readable = pipeThrough(readable, new CompressionStream(COMPRESSION_FORMAT, options));
|
|
142
|
+
readable = pipeThrough(readable, new Stream(format, options));
|
|
141
143
|
} catch (error) {
|
|
142
144
|
if (useCompressionStream) {
|
|
143
|
-
|
|
145
|
+
if (CompressionStreamZlib) {
|
|
146
|
+
readable = pipeThrough(readable, new CompressionStreamZlib(format, options));
|
|
147
|
+
} else if (CompressionStream) {
|
|
148
|
+
readable = pipeThrough(readable, new CompressionStream(format, options));
|
|
149
|
+
} else {
|
|
150
|
+
throw error;
|
|
151
|
+
}
|
|
144
152
|
} else {
|
|
145
153
|
throw error;
|
|
146
154
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
See https://github.com/gildas-lormeau/zlib-streams/tree/main/dist
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
Copyright (c)
|
|
2
|
+
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
3
3
|
|
|
4
4
|
Redistribution and use in source and binary forms, with or without
|
|
5
5
|
modification, are permitted provided that the following conditions are met:
|
|
@@ -26,30 +26,59 @@
|
|
|
26
26
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
/* global
|
|
29
|
+
/* global WebAssembly, URL, fetch, atob */
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
},
|
|
45
|
-
flush(controller) {
|
|
46
|
-
const chunk = codec.flush();
|
|
47
|
-
if (chunk) {
|
|
48
|
-
controller.enqueue(chunk);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
});
|
|
31
|
+
import { setWasmExports } from "./zlib-streams.js";
|
|
32
|
+
|
|
33
|
+
let initializedModule = false;
|
|
34
|
+
|
|
35
|
+
async function initModule(wasmURI, { baseURI }) {
|
|
36
|
+
if (!initializedModule) {
|
|
37
|
+
let arrayBuffer, uri;
|
|
38
|
+
try {
|
|
39
|
+
try {
|
|
40
|
+
uri = new URL(wasmURI, baseURI);
|
|
41
|
+
// eslint-disable-next-line no-unused-vars
|
|
42
|
+
} catch (_) {
|
|
43
|
+
// ignored
|
|
52
44
|
}
|
|
53
|
-
|
|
45
|
+
const response = await fetch(uri);
|
|
46
|
+
arrayBuffer = await response.arrayBuffer();
|
|
47
|
+
} catch (error) {
|
|
48
|
+
if (wasmURI.startsWith("data:application/wasm;base64,")) {
|
|
49
|
+
arrayBuffer = arrayBufferFromDataURI(wasmURI);
|
|
50
|
+
} else {
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const wasmInstance = await WebAssembly.instantiate(arrayBuffer);
|
|
55
|
+
setWasmExports(wasmInstance.instance.exports);
|
|
56
|
+
initializedModule = true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function resetWasmModule() {
|
|
61
|
+
initializedModule = false;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function arrayBufferFromDataURI(dataURI) {
|
|
65
|
+
const base64 = dataURI.split(",")[1];
|
|
66
|
+
const binary = atob(base64);
|
|
67
|
+
const len = binary.length;
|
|
68
|
+
const bytes = new Uint8Array(len);
|
|
69
|
+
for (let i = 0; i < len; ++i) {
|
|
70
|
+
bytes[i] = binary.charCodeAt(i);
|
|
54
71
|
}
|
|
55
|
-
|
|
72
|
+
return bytes.buffer;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export {
|
|
76
|
+
setWasmExports,
|
|
77
|
+
CompressionStreamZlib,
|
|
78
|
+
DecompressionStreamZlib
|
|
79
|
+
} from "./zlib-streams.js";
|
|
80
|
+
export {
|
|
81
|
+
initModule,
|
|
82
|
+
resetWasmModule,
|
|
83
|
+
initializedModule
|
|
84
|
+
};
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2025 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 TransformStream */
|
|
30
|
+
|
|
31
|
+
let wasm, malloc, free, memory;
|
|
32
|
+
|
|
33
|
+
export function setWasmExports(wasmAPI) {
|
|
34
|
+
wasm = wasmAPI;
|
|
35
|
+
({ malloc, free, memory } = wasm);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function _make(isCompress, type, options = {}) {
|
|
39
|
+
const level = (typeof options.level === "number") ? options.level : -1;
|
|
40
|
+
const outBufferSize = (typeof options.outBuffer === "number") ? options.outBuffer : 64 * 1024;
|
|
41
|
+
const inBufferSize = (typeof options.inBufferSize === "number") ? options.inBufferSize : 64 * 1024;
|
|
42
|
+
|
|
43
|
+
return new TransformStream({
|
|
44
|
+
start() {
|
|
45
|
+
let result;
|
|
46
|
+
this.out = malloc(outBufferSize);
|
|
47
|
+
this.in = malloc(inBufferSize);
|
|
48
|
+
this.inBufferSize = inBufferSize;
|
|
49
|
+
this._scratch = new Uint8Array(outBufferSize);
|
|
50
|
+
if (isCompress) {
|
|
51
|
+
this._process = wasm.deflate_process;
|
|
52
|
+
this._last_consumed = wasm.deflate_last_consumed;
|
|
53
|
+
this._end = wasm.deflate_end;
|
|
54
|
+
this.streamHandle = wasm.deflate_new();
|
|
55
|
+
if (type === "gzip") {
|
|
56
|
+
result = wasm.deflate_init_gzip(this.streamHandle, level);
|
|
57
|
+
} else if (type === "deflate-raw") {
|
|
58
|
+
result = wasm.deflate_init_raw(this.streamHandle, level);
|
|
59
|
+
} else {
|
|
60
|
+
result = wasm.deflate_init(this.streamHandle, level);
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
if (type === "deflate64-raw") {
|
|
64
|
+
this._process = wasm.inflate9_process;
|
|
65
|
+
this._last_consumed = wasm.inflate9_last_consumed;
|
|
66
|
+
this._end = wasm.inflate9_end;
|
|
67
|
+
this.streamHandle = wasm.inflate9_new();
|
|
68
|
+
result = wasm.inflate9_init_raw(this.streamHandle);
|
|
69
|
+
} else {
|
|
70
|
+
this._process = wasm.inflate_process;
|
|
71
|
+
this._last_consumed = wasm.inflate_last_consumed;
|
|
72
|
+
this._end = wasm.inflate_end;
|
|
73
|
+
this.streamHandle = wasm.inflate_new();
|
|
74
|
+
if (type === "deflate-raw") {
|
|
75
|
+
result = wasm.inflate_init_raw(this.streamHandle);
|
|
76
|
+
} else if (type === "gzip") {
|
|
77
|
+
result = wasm.inflate_init_gzip(this.streamHandle);
|
|
78
|
+
} else {
|
|
79
|
+
result = wasm.inflate_init(this.streamHandle);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (result !== 0) {
|
|
84
|
+
throw new Error("init failed:" + result);
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
transform(chunk, controller) {
|
|
88
|
+
try {
|
|
89
|
+
const buffer = chunk;
|
|
90
|
+
const heap = new Uint8Array(memory.buffer);
|
|
91
|
+
const process = this._process;
|
|
92
|
+
const last_consumed = this._last_consumed;
|
|
93
|
+
const out = this.out;
|
|
94
|
+
const scratch = this._scratch;
|
|
95
|
+
let offset = 0;
|
|
96
|
+
while (offset < buffer.length) {
|
|
97
|
+
const toRead = Math.min(buffer.length - offset, 32 * 1024);
|
|
98
|
+
if (!this.in || this.inBufferSize < toRead) {
|
|
99
|
+
if (this.in && free) {
|
|
100
|
+
free(this.in);
|
|
101
|
+
}
|
|
102
|
+
this.in = malloc(toRead);
|
|
103
|
+
this.inBufferSize = toRead;
|
|
104
|
+
}
|
|
105
|
+
heap.set(buffer.subarray(offset, offset + toRead), this.in);
|
|
106
|
+
const result = process(this.streamHandle, this.in, toRead, out, outBufferSize, 0);
|
|
107
|
+
if (!isCompress && result < 0) {
|
|
108
|
+
throw new Error("process error:" + result);
|
|
109
|
+
}
|
|
110
|
+
const prod = result & 0x00ffffff;
|
|
111
|
+
if (prod) {
|
|
112
|
+
scratch.set(heap.subarray(out, out + prod), 0);
|
|
113
|
+
controller.enqueue(scratch.slice(0, prod));
|
|
114
|
+
}
|
|
115
|
+
const consumed = last_consumed(this.streamHandle);
|
|
116
|
+
if (consumed === 0) {
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
offset += consumed;
|
|
120
|
+
}
|
|
121
|
+
} catch (error) {
|
|
122
|
+
if (this._end && this.streamHandle) {
|
|
123
|
+
this._end(this.streamHandle);
|
|
124
|
+
}
|
|
125
|
+
if (this.in && free) {
|
|
126
|
+
free(this.in);
|
|
127
|
+
}
|
|
128
|
+
if (this.out && free) {
|
|
129
|
+
free(this.out);
|
|
130
|
+
}
|
|
131
|
+
controller.error(error);
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
flush(controller) {
|
|
135
|
+
try {
|
|
136
|
+
const heap = new Uint8Array(memory.buffer);
|
|
137
|
+
const process = this._process;
|
|
138
|
+
const out = this.out;
|
|
139
|
+
const scratch = this._scratch;
|
|
140
|
+
while (true) {
|
|
141
|
+
const result = process(this.streamHandle, 0, 0, out, outBufferSize, 4);
|
|
142
|
+
if (!isCompress && result < 0) {
|
|
143
|
+
throw new Error("process error:" + result);
|
|
144
|
+
}
|
|
145
|
+
const produced = result & 0x00ffffff;
|
|
146
|
+
const code = (result >> 24) & 0xff;
|
|
147
|
+
if (produced) {
|
|
148
|
+
scratch.set(heap.subarray(out, out + produced), 0);
|
|
149
|
+
controller.enqueue(scratch.slice(0, produced));
|
|
150
|
+
}
|
|
151
|
+
if (code === 1 || produced === 0) {
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
} catch (error) {
|
|
156
|
+
controller.error(error);
|
|
157
|
+
} finally {
|
|
158
|
+
if (this._end && this.streamHandle) {
|
|
159
|
+
const result = this._end(this.streamHandle);
|
|
160
|
+
if (result !== 0) {
|
|
161
|
+
controller.error(new Error("end error:" + result));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (this.in && free) {
|
|
165
|
+
free(this.in);
|
|
166
|
+
}
|
|
167
|
+
if (this.out && free) {
|
|
168
|
+
free(this.out);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export class CompressionStreamZlib {
|
|
176
|
+
constructor(type = "deflate", options) {
|
|
177
|
+
return _make(true, type, options);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
export class DecompressionStreamZlib {
|
|
181
|
+
constructor(type = "deflate", options) {
|
|
182
|
+
return _make(false, type, options);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
Binary file
|