@zip.js/zip.js 2.6.33 → 2.6.35
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 +2483 -2364
- package/dist/zip-fs-full.min.js +1 -1
- package/dist/zip-fs.js +1241 -1122
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-full.js +1238 -1119
- 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 +1242 -1123
- package/dist/zip.min.js +1 -1
- package/index-fflate.js +3 -1
- package/index.cjs +2483 -2364
- package/index.d.ts +51 -6
- package/index.js +3 -1
- package/lib/core/codec-pool.js +2 -2
- package/lib/core/codec-worker.js +321 -0
- package/lib/core/configuration.js +3 -3
- package/lib/core/constants.js +6 -5
- package/lib/core/io.js +68 -1
- package/lib/core/streams/aes-crypto-stream.js +2 -0
- package/lib/core/streams/codec-stream.js +60 -13
- package/lib/core/streams/codecs/sjcl.js +1 -1
- package/lib/core/streams/stream-adapter.js +55 -0
- package/lib/core/streams/zip-crypto-stream.js +1 -0
- package/lib/core/streams/zip-entry-stream.js +1 -0
- package/lib/core/util/stream-codec-shim.js +2 -0
- package/lib/core/z-worker-core.js +21 -11
- package/lib/core/zip-entry.js +2 -1
- package/lib/core/zip-fs-core.js +1 -0
- package/lib/core/zip-reader.js +7 -5
- package/lib/core/zip-writer.js +88 -42
- package/lib/z-worker-inline.js +1 -1
- package/lib/zip.js +1 -1
- package/package.json +5 -5
- package/tests/all/test-http-split-zip.js +37 -0
- package/tests/all/test-split-zip.js +25 -22
- package/tests/tests-data.js +2 -1
- package/lib/core/codec-interface.js +0 -115
- package/lib/core/codec-pool-worker.js +0 -293
package/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ declare global {
|
|
|
7
7
|
*
|
|
8
8
|
* @see {@link https://wicg.github.io/entries-api/#api-entry|specification}
|
|
9
9
|
*/
|
|
10
|
+
// deno-lint-ignore no-empty-interface
|
|
10
11
|
interface FileSystemEntry { }
|
|
11
12
|
}
|
|
12
13
|
|
|
@@ -141,6 +142,7 @@ interface WorkerConfiguration {
|
|
|
141
142
|
* @param registerDataHandler The function called to handle the `data` events triggered by a third-party codec implementation.
|
|
142
143
|
* @returns An instance containing classes compatible with `ZipDeflate` and `ZipInflate`.
|
|
143
144
|
*/
|
|
145
|
+
// deno-lint-ignore no-explicit-any
|
|
144
146
|
export function initShimAsyncCodec(library: EventBasedZipLibrary, constructorOptions: any | null, registerDataHandler: registerDataHandler): ZipLibrary
|
|
145
147
|
|
|
146
148
|
/**
|
|
@@ -270,7 +272,7 @@ export function getMimeType(fileExtension: string): string
|
|
|
270
272
|
* zip.js can handle multiple types of data thanks to a generic API. This feature is based on 2 abstract constructors: `Reader` and `Writer`.
|
|
271
273
|
* The classes inheriting from `Reader` help to read data from a source of data. The classes inheriting from `Writer` help to write data into a destination.
|
|
272
274
|
*/
|
|
273
|
-
interface
|
|
275
|
+
interface Initializable {
|
|
274
276
|
/**
|
|
275
277
|
* Initializes the instance asynchronously
|
|
276
278
|
*/
|
|
@@ -315,7 +317,7 @@ interface ReadableReader {
|
|
|
315
317
|
* }
|
|
316
318
|
* ```
|
|
317
319
|
*/
|
|
318
|
-
export class Reader<Type> implements
|
|
320
|
+
export class Reader<Type> implements Initializable, ReadableReader {
|
|
319
321
|
/**
|
|
320
322
|
* Creates the `Reader` instance
|
|
321
323
|
*
|
|
@@ -367,11 +369,13 @@ export class Uint8ArrayReader extends Reader<Uint8Array> { }
|
|
|
367
369
|
/**
|
|
368
370
|
* Represents a `Reader` instance used to read data provided as an array of `Reader` instances (i.e. split zip files).
|
|
369
371
|
*/
|
|
372
|
+
// deno-lint-ignore no-explicit-any
|
|
370
373
|
export class SplitZipReader extends Reader<Reader<any>[] | ReadableReader[] | ReadableStream[]> { }
|
|
371
374
|
|
|
372
375
|
/**
|
|
373
376
|
* Represents a URL stored into a `string`.
|
|
374
377
|
*/
|
|
378
|
+
// deno-lint-ignore no-empty-interface
|
|
375
379
|
interface URLString extends String { }
|
|
376
380
|
|
|
377
381
|
/**
|
|
@@ -475,7 +479,7 @@ interface WritableWriter {
|
|
|
475
479
|
* }
|
|
476
480
|
* ```
|
|
477
481
|
*/
|
|
478
|
-
export class Writer<Type> implements
|
|
482
|
+
export class Writer<Type> implements Initializable, WritableWriter {
|
|
479
483
|
/**
|
|
480
484
|
* The `WritableStream` instance.
|
|
481
485
|
*/
|
|
@@ -517,13 +521,27 @@ export class TextWriter extends Writer<string> {
|
|
|
517
521
|
/**
|
|
518
522
|
* Represents a `Writer` instance used to retrieve the written data as a `Blob` instance.
|
|
519
523
|
*/
|
|
520
|
-
export class BlobWriter
|
|
524
|
+
export class BlobWriter implements Initializable, WritableWriter {
|
|
525
|
+
/**
|
|
526
|
+
* The `WritableStream` instance.
|
|
527
|
+
*/
|
|
528
|
+
writable: WritableStream
|
|
529
|
+
/**
|
|
530
|
+
* Initializes the instance asynchronously
|
|
531
|
+
*/
|
|
532
|
+
init(): Promise<void>
|
|
521
533
|
/**
|
|
522
534
|
* Creates the `BlobWriter` instance
|
|
523
535
|
*
|
|
524
536
|
* @param mimeString The MIME type of the content.
|
|
525
537
|
*/
|
|
526
538
|
constructor(mimeString?: string)
|
|
539
|
+
/**
|
|
540
|
+
* Retrieves all the written data
|
|
541
|
+
*
|
|
542
|
+
* @returns A promise resolving to the written data.
|
|
543
|
+
*/
|
|
544
|
+
getData(): Promise<Blob>
|
|
527
545
|
}
|
|
528
546
|
|
|
529
547
|
/**
|
|
@@ -538,6 +556,27 @@ export class Data64URIWriter extends Writer<string> {
|
|
|
538
556
|
constructor(mimeString?: string)
|
|
539
557
|
}
|
|
540
558
|
|
|
559
|
+
/**
|
|
560
|
+
* Represents a `Writer` instance used to retrieve the written data from a generator of `Writer` instances (i.e. split zip files).
|
|
561
|
+
*/
|
|
562
|
+
export class SplitZipWriter implements Initializable, WritableWriter {
|
|
563
|
+
/**
|
|
564
|
+
* The `WritableStream` instance.
|
|
565
|
+
*/
|
|
566
|
+
writable: WritableStream
|
|
567
|
+
/**
|
|
568
|
+
* Initializes the instance asynchronously
|
|
569
|
+
*/
|
|
570
|
+
init(): Promise<void>
|
|
571
|
+
/**
|
|
572
|
+
* Creates the `SplitZipWriter` instance
|
|
573
|
+
*
|
|
574
|
+
* @param writerGenerator The MIME type of the content.
|
|
575
|
+
* @param maxSize The maximum size of the data written into `Writer` instances (default: 4GB).
|
|
576
|
+
*/
|
|
577
|
+
constructor(writerGenerator: AsyncGenerator<Writer<any> | WritableWriter | WritableStream, boolean>, maxSize?: number)
|
|
578
|
+
}
|
|
579
|
+
|
|
541
580
|
/**
|
|
542
581
|
* Represents a `Writer` instance used to retrieve the written data as a `Uint8Array` instance.
|
|
543
582
|
*/
|
|
@@ -582,6 +621,7 @@ export class ZipReader<Type> {
|
|
|
582
621
|
* @param reader The `Reader` instance used to read data.
|
|
583
622
|
* @param options The options.
|
|
584
623
|
*/
|
|
624
|
+
// deno-lint-ignore no-explicit-any
|
|
585
625
|
constructor(reader: Reader<Type> | ReadableReader | ReadableStream | Reader<any>[] | ReadableReader[] | ReadableStream[], options?: ZipReaderConstructorOptions)
|
|
586
626
|
/**
|
|
587
627
|
* The global comment of the zip file.
|
|
@@ -792,6 +832,10 @@ export interface Entry {
|
|
|
792
832
|
* The external file attribute (raw).
|
|
793
833
|
*/
|
|
794
834
|
externalFileAttribute: number
|
|
835
|
+
/**
|
|
836
|
+
* The number of the disk where the entry data starts.
|
|
837
|
+
*/
|
|
838
|
+
diskNumberStart: number
|
|
795
839
|
/**
|
|
796
840
|
* Returns the content of the entry
|
|
797
841
|
*
|
|
@@ -834,7 +878,7 @@ export class ZipWriter<Type> {
|
|
|
834
878
|
* @param writer The `Writer` instance where the zip content will be written.
|
|
835
879
|
* @param options The options.
|
|
836
880
|
*/
|
|
837
|
-
constructor(writer: Writer<Type> | WritableWriter | WritableStream, options?: ZipWriterConstructorOptions)
|
|
881
|
+
constructor(writer: Writer<Type> | WritableWriter | WritableStream | SplitZipWriter | AsyncGenerator<Writer<any> | WritableWriter | WritableStream, boolean>, options?: ZipWriterConstructorOptions)
|
|
838
882
|
/**
|
|
839
883
|
* `true` if the zip contains at least one entry that has been partially written.
|
|
840
884
|
*/
|
|
@@ -1444,4 +1488,5 @@ export const ERR_INVALID_EXTRAFIELD_TYPE: string
|
|
|
1444
1488
|
export const ERR_INVALID_EXTRAFIELD_DATA: string
|
|
1445
1489
|
export const ERR_INVALID_ENCRYPTION_STRENGTH: string
|
|
1446
1490
|
export const ERR_UNSUPPORTED_FORMAT: string
|
|
1447
|
-
export const ERR_SPLIT_ZIP_FILE: string
|
|
1491
|
+
export const ERR_SPLIT_ZIP_FILE: string
|
|
1492
|
+
export const ERR_ITERATOR_COMPLETED_TOO_SOON: string
|
package/index.js
CHANGED
|
@@ -55,6 +55,7 @@ export {
|
|
|
55
55
|
Uint8ArrayWriter,
|
|
56
56
|
Uint8ArrayReader,
|
|
57
57
|
SplitZipReader,
|
|
58
|
+
SplitZipWriter,
|
|
58
59
|
ERR_HTTP_RANGE,
|
|
59
60
|
ERR_BAD_FORMAT,
|
|
60
61
|
ERR_EOCDR_NOT_FOUND,
|
|
@@ -77,6 +78,7 @@ export {
|
|
|
77
78
|
ERR_INVALID_EXTRAFIELD_DATA,
|
|
78
79
|
ERR_INVALID_ENCRYPTION_STRENGTH,
|
|
79
80
|
ERR_UNSUPPORTED_FORMAT,
|
|
80
|
-
ERR_SPLIT_ZIP_FILE
|
|
81
|
+
ERR_SPLIT_ZIP_FILE,
|
|
82
|
+
ERR_ITERATOR_COMPLETED_TOO_SOON
|
|
81
83
|
} from "./lib/zip-fs.js";
|
|
82
84
|
export { getMimeType, terminateWorkers };
|
package/lib/core/codec-pool.js
CHANGED
|
@@ -34,8 +34,8 @@ import {
|
|
|
34
34
|
CODEC_DEFLATE,
|
|
35
35
|
ERR_INVALID_SIGNATURE,
|
|
36
36
|
ERR_INVALID_PASSWORD
|
|
37
|
-
} from "./codec-
|
|
38
|
-
import { CodecWorker } from "./codec-
|
|
37
|
+
} from "./streams/codec-stream.js";
|
|
38
|
+
import { CodecWorker } from "./codec-worker.js";
|
|
39
39
|
|
|
40
40
|
let pool = [];
|
|
41
41
|
const pendingRequests = [];
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2022 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 Worker, URL, TransformStream, WritableStream */
|
|
30
|
+
|
|
31
|
+
import {
|
|
32
|
+
UNDEFINED_TYPE,
|
|
33
|
+
FUNCTION_TYPE
|
|
34
|
+
} from "./constants.js";
|
|
35
|
+
import {
|
|
36
|
+
CodecStream,
|
|
37
|
+
MESSAGE_EVENT_TYPE,
|
|
38
|
+
MESSAGE_START,
|
|
39
|
+
MESSAGE_PULL,
|
|
40
|
+
MESSAGE_DATA,
|
|
41
|
+
MESSAGE_ACK_DATA,
|
|
42
|
+
MESSAGE_CLOSE
|
|
43
|
+
} from "./streams/codec-stream.js";
|
|
44
|
+
|
|
45
|
+
// deno-lint-ignore valid-typeof
|
|
46
|
+
const WEB_WORKERS_SUPPORTED = typeof Worker != UNDEFINED_TYPE;
|
|
47
|
+
|
|
48
|
+
export {
|
|
49
|
+
CodecWorker
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
class CodecWorker {
|
|
53
|
+
|
|
54
|
+
constructor(workerData, stream, workerOptions, onTaskFinished) {
|
|
55
|
+
const { readable, writable } = stream;
|
|
56
|
+
const { options, config, streamOptions, useWebWorkers, transferStreams, scripts } = workerOptions;
|
|
57
|
+
const { signal } = streamOptions;
|
|
58
|
+
Object.assign(workerData, {
|
|
59
|
+
busy: true,
|
|
60
|
+
readable: readable.pipeThrough(new ReadableStreamHooks(readable, streamOptions, config), { signal }),
|
|
61
|
+
writable,
|
|
62
|
+
options: Object.assign({}, options),
|
|
63
|
+
scripts,
|
|
64
|
+
transferStreams,
|
|
65
|
+
terminate() {
|
|
66
|
+
const { worker, busy } = workerData;
|
|
67
|
+
if (worker && !busy) {
|
|
68
|
+
worker.terminate();
|
|
69
|
+
workerData.interface = null;
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
onTaskFinished() {
|
|
73
|
+
workerData.busy = false;
|
|
74
|
+
onTaskFinished(workerData);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
return (useWebWorkers && WEB_WORKERS_SUPPORTED ? createWebWorkerInterface : createWorkerInterface)(workerData, config);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
class ReadableStreamHooks extends TransformStream {
|
|
82
|
+
|
|
83
|
+
constructor(readableSource, { onstart, onprogress, size, onend }, { chunkSize }) {
|
|
84
|
+
let chunkOffset = 0;
|
|
85
|
+
super({
|
|
86
|
+
start() {
|
|
87
|
+
if (onstart) {
|
|
88
|
+
callHandler(onstart, size);
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
async transform(chunk, controller) {
|
|
92
|
+
chunkOffset += chunk.length;
|
|
93
|
+
if (onprogress) {
|
|
94
|
+
await callHandler(onprogress, chunkOffset, size);
|
|
95
|
+
}
|
|
96
|
+
controller.enqueue(chunk);
|
|
97
|
+
},
|
|
98
|
+
flush() {
|
|
99
|
+
readableSource.size = chunkOffset;
|
|
100
|
+
if (onend) {
|
|
101
|
+
callHandler(onend, chunkOffset);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}, { highWaterMark: 1, size: () => chunkSize });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async function callHandler(handler, ...parameters) {
|
|
109
|
+
try {
|
|
110
|
+
await handler(...parameters);
|
|
111
|
+
} catch (_error) {
|
|
112
|
+
// ignored
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function createWorkerInterface(workerData, config) {
|
|
117
|
+
return {
|
|
118
|
+
run: () => runWorker(workerData, config)
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function createWebWorkerInterface(workerData, { baseURL, chunkSize }) {
|
|
123
|
+
if (!workerData.interface) {
|
|
124
|
+
Object.assign(workerData, {
|
|
125
|
+
worker: getWebWorker(workerData.scripts[0], baseURL, workerData),
|
|
126
|
+
interface: {
|
|
127
|
+
run: () => runWebWorker(workerData, { chunkSize })
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return workerData.interface;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async function runWorker({ options, readable, writable, onTaskFinished }, config) {
|
|
135
|
+
const codecStream = new CodecStream(options, config);
|
|
136
|
+
try {
|
|
137
|
+
await readable.pipeThrough(codecStream).pipeTo(writable, { preventClose: true, preventAbort: true });
|
|
138
|
+
const {
|
|
139
|
+
signature,
|
|
140
|
+
size
|
|
141
|
+
} = codecStream;
|
|
142
|
+
return {
|
|
143
|
+
signature,
|
|
144
|
+
size
|
|
145
|
+
};
|
|
146
|
+
} finally {
|
|
147
|
+
onTaskFinished();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async function runWebWorker(workerData, config) {
|
|
152
|
+
let resolveResult, rejectResult;
|
|
153
|
+
const result = new Promise((resolve, reject) => {
|
|
154
|
+
resolveResult = resolve;
|
|
155
|
+
rejectResult = reject;
|
|
156
|
+
});
|
|
157
|
+
Object.assign(workerData, {
|
|
158
|
+
reader: null,
|
|
159
|
+
writer: null,
|
|
160
|
+
resolveResult,
|
|
161
|
+
rejectResult,
|
|
162
|
+
result
|
|
163
|
+
});
|
|
164
|
+
const { readable, options } = workerData;
|
|
165
|
+
const { writable, closed } = detectClosedStream(workerData.writable);
|
|
166
|
+
const streamsTransferred = sendMessage({
|
|
167
|
+
type: MESSAGE_START,
|
|
168
|
+
scripts: workerData.scripts.slice(1),
|
|
169
|
+
options,
|
|
170
|
+
config,
|
|
171
|
+
readable,
|
|
172
|
+
writable
|
|
173
|
+
}, workerData);
|
|
174
|
+
if (!streamsTransferred) {
|
|
175
|
+
Object.assign(workerData, {
|
|
176
|
+
reader: readable.getReader(),
|
|
177
|
+
writer: writable.getWriter()
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
const resultValue = await result;
|
|
181
|
+
try {
|
|
182
|
+
await writable.close();
|
|
183
|
+
} catch (_error) {
|
|
184
|
+
// ignored
|
|
185
|
+
}
|
|
186
|
+
await closed;
|
|
187
|
+
return resultValue;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function detectClosedStream(writableSource) {
|
|
191
|
+
const writer = writableSource.getWriter();
|
|
192
|
+
let resolveStreamClosed;
|
|
193
|
+
const closed = new Promise(resolve => resolveStreamClosed = resolve);
|
|
194
|
+
const writable = new WritableStream({
|
|
195
|
+
async write(chunk) {
|
|
196
|
+
await writer.ready;
|
|
197
|
+
await writer.write(chunk);
|
|
198
|
+
},
|
|
199
|
+
close() {
|
|
200
|
+
writer.releaseLock();
|
|
201
|
+
resolveStreamClosed();
|
|
202
|
+
},
|
|
203
|
+
abort(reason) {
|
|
204
|
+
writer.abort(reason);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
return { writable, closed };
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
let classicWorkersSupported = true;
|
|
211
|
+
let transferStreamsSupported = true;
|
|
212
|
+
|
|
213
|
+
function getWebWorker(url, baseURL, workerData) {
|
|
214
|
+
const workerOptions = { type: "module" };
|
|
215
|
+
let scriptUrl, worker;
|
|
216
|
+
if (typeof url == FUNCTION_TYPE) {
|
|
217
|
+
url = url();
|
|
218
|
+
}
|
|
219
|
+
try {
|
|
220
|
+
scriptUrl = new URL(url, baseURL);
|
|
221
|
+
} catch (_error) {
|
|
222
|
+
scriptUrl = url;
|
|
223
|
+
}
|
|
224
|
+
if (classicWorkersSupported) {
|
|
225
|
+
try {
|
|
226
|
+
worker = new Worker(scriptUrl);
|
|
227
|
+
} catch (_error) {
|
|
228
|
+
classicWorkersSupported = false;
|
|
229
|
+
worker = new Worker(scriptUrl, workerOptions);
|
|
230
|
+
}
|
|
231
|
+
} else {
|
|
232
|
+
worker = new Worker(scriptUrl, workerOptions);
|
|
233
|
+
}
|
|
234
|
+
worker.addEventListener(MESSAGE_EVENT_TYPE, event => onMessage(event, workerData));
|
|
235
|
+
return worker;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function sendMessage(message, { worker, writer, onTaskFinished, transferStreams }) {
|
|
239
|
+
try {
|
|
240
|
+
let { data, readable, writable } = message;
|
|
241
|
+
const transferrables = [];
|
|
242
|
+
if (data) {
|
|
243
|
+
const { buffer, length } = data;
|
|
244
|
+
if (length != buffer.byteLength) {
|
|
245
|
+
data = new Uint8Array(data);
|
|
246
|
+
}
|
|
247
|
+
message.data = data.buffer;
|
|
248
|
+
transferrables.push(message.data);
|
|
249
|
+
}
|
|
250
|
+
if (transferStreams && transferStreamsSupported) {
|
|
251
|
+
if (readable) {
|
|
252
|
+
transferrables.push(readable);
|
|
253
|
+
}
|
|
254
|
+
if (writable) {
|
|
255
|
+
transferrables.push(writable);
|
|
256
|
+
}
|
|
257
|
+
} else {
|
|
258
|
+
message.readable = message.writable = null;
|
|
259
|
+
}
|
|
260
|
+
if (transferrables.length) {
|
|
261
|
+
try {
|
|
262
|
+
worker.postMessage(message, transferrables);
|
|
263
|
+
return true;
|
|
264
|
+
} catch (_error) {
|
|
265
|
+
transferStreamsSupported = false;
|
|
266
|
+
message.readable = message.writable = null;
|
|
267
|
+
worker.postMessage(message);
|
|
268
|
+
}
|
|
269
|
+
} else {
|
|
270
|
+
worker.postMessage(message);
|
|
271
|
+
}
|
|
272
|
+
} catch (error) {
|
|
273
|
+
if (writer) {
|
|
274
|
+
writer.releaseLock();
|
|
275
|
+
}
|
|
276
|
+
onTaskFinished();
|
|
277
|
+
throw error;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
async function onMessage(event, workerData) {
|
|
282
|
+
const message = event.data;
|
|
283
|
+
const { reader, writer, resolveResult, rejectResult, onTaskFinished } = workerData;
|
|
284
|
+
const { type, data, messageId, result } = message;
|
|
285
|
+
const reponseError = message.error;
|
|
286
|
+
try {
|
|
287
|
+
if (reponseError) {
|
|
288
|
+
const { message, stack, code, name } = reponseError;
|
|
289
|
+
const error = new Error(message);
|
|
290
|
+
Object.assign(error, { stack, code, name });
|
|
291
|
+
close(error);
|
|
292
|
+
} else {
|
|
293
|
+
if (type == MESSAGE_PULL) {
|
|
294
|
+
const { value, done } = await reader.read();
|
|
295
|
+
sendMessage({ type: MESSAGE_DATA, data: value, done, messageId }, workerData);
|
|
296
|
+
}
|
|
297
|
+
if (type == MESSAGE_DATA) {
|
|
298
|
+
await writer.ready;
|
|
299
|
+
await writer.write(new Uint8Array(data));
|
|
300
|
+
sendMessage({ type: MESSAGE_ACK_DATA, messageId }, workerData);
|
|
301
|
+
}
|
|
302
|
+
if (type == MESSAGE_CLOSE) {
|
|
303
|
+
close(null, result);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
} catch (error) {
|
|
307
|
+
close(error);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
function close(error, result) {
|
|
311
|
+
if (error) {
|
|
312
|
+
rejectResult(error);
|
|
313
|
+
} else {
|
|
314
|
+
resolveResult(result);
|
|
315
|
+
}
|
|
316
|
+
if (writer) {
|
|
317
|
+
writer.releaseLock();
|
|
318
|
+
}
|
|
319
|
+
onTaskFinished();
|
|
320
|
+
}
|
|
321
|
+
}
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
|
|
29
29
|
/* global navigator, CompressionStream, DecompressionStream */
|
|
30
30
|
|
|
31
|
-
import { getCodecStreamClass } from "./codec-interface.js";
|
|
32
31
|
import {
|
|
33
32
|
UNDEFINED_VALUE,
|
|
34
33
|
UNDEFINED_TYPE
|
|
35
34
|
} from "./constants.js";
|
|
35
|
+
import { StreamAdapter } from "./streams/stream-adapter.js";
|
|
36
36
|
|
|
37
37
|
const MINIMUM_CHUNK_SIZE = 64;
|
|
38
38
|
let maxWorkers = 2;
|
|
@@ -91,10 +91,10 @@ function configure(configuration) {
|
|
|
91
91
|
setIfDefined("useCompressionStream", useCompressionStream);
|
|
92
92
|
setIfDefined("useWebWorkers", useWebWorkers);
|
|
93
93
|
if (Deflate) {
|
|
94
|
-
config.CompressionStream =
|
|
94
|
+
config.CompressionStream = new StreamAdapter(Deflate);
|
|
95
95
|
}
|
|
96
96
|
if (Inflate) {
|
|
97
|
-
config.DecompressionStream =
|
|
97
|
+
config.DecompressionStream = new StreamAdapter(Inflate);
|
|
98
98
|
}
|
|
99
99
|
setIfDefined("CompressionStream", CompressionStream);
|
|
100
100
|
setIfDefined("DecompressionStream", DecompressionStream);
|
package/lib/core/constants.js
CHANGED
|
@@ -33,7 +33,8 @@ const COMPRESSION_METHOD_STORE = 0x00;
|
|
|
33
33
|
const COMPRESSION_METHOD_AES = 0x63;
|
|
34
34
|
|
|
35
35
|
const LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50;
|
|
36
|
-
const
|
|
36
|
+
const SPLIT_ZIP_FILE_SIGNATURE = 0x08074b50;
|
|
37
|
+
const DATA_DESCRIPTOR_RECORD_SIGNATURE = SPLIT_ZIP_FILE_SIGNATURE;
|
|
37
38
|
const CENTRAL_FILE_HEADER_SIGNATURE = 0x02014b50;
|
|
38
39
|
const END_OF_CENTRAL_DIR_SIGNATURE = 0x06054b50;
|
|
39
40
|
const ZIP64_END_OF_CENTRAL_DIR_SIGNATURE = 0x06064b50;
|
|
@@ -43,8 +44,6 @@ const ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH = 20;
|
|
|
43
44
|
const ZIP64_END_OF_CENTRAL_DIR_LENGTH = 56;
|
|
44
45
|
const ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH = END_OF_CENTRAL_DIR_LENGTH + ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH + ZIP64_END_OF_CENTRAL_DIR_LENGTH;
|
|
45
46
|
|
|
46
|
-
const ZIP64_TOTAL_NUMBER_OF_DISKS = 1;
|
|
47
|
-
|
|
48
47
|
const EXTRAFIELD_TYPE_ZIP64 = 0x0001;
|
|
49
48
|
const EXTRAFIELD_TYPE_AES = 0x9901;
|
|
50
49
|
const EXTRAFIELD_TYPE_NTFS = 0x000a;
|
|
@@ -70,6 +69,7 @@ const MIN_DATE = new Date(1980, 0, 1);
|
|
|
70
69
|
|
|
71
70
|
const UNDEFINED_VALUE = undefined;
|
|
72
71
|
const UNDEFINED_TYPE = "undefined";
|
|
72
|
+
const FUNCTION_TYPE = "function";
|
|
73
73
|
|
|
74
74
|
export {
|
|
75
75
|
MAX_32_BITS,
|
|
@@ -77,6 +77,7 @@ export {
|
|
|
77
77
|
COMPRESSION_METHOD_DEFLATE,
|
|
78
78
|
COMPRESSION_METHOD_STORE,
|
|
79
79
|
COMPRESSION_METHOD_AES,
|
|
80
|
+
SPLIT_ZIP_FILE_SIGNATURE,
|
|
80
81
|
LOCAL_FILE_HEADER_SIGNATURE,
|
|
81
82
|
DATA_DESCRIPTOR_RECORD_SIGNATURE,
|
|
82
83
|
CENTRAL_FILE_HEADER_SIGNATURE,
|
|
@@ -94,7 +95,6 @@ export {
|
|
|
94
95
|
ZIP64_END_OF_CENTRAL_DIR_LOCATOR_LENGTH,
|
|
95
96
|
ZIP64_END_OF_CENTRAL_DIR_LENGTH,
|
|
96
97
|
ZIP64_END_OF_CENTRAL_DIR_TOTAL_LENGTH,
|
|
97
|
-
ZIP64_TOTAL_NUMBER_OF_DISKS,
|
|
98
98
|
BITFLAG_ENCRYPTED,
|
|
99
99
|
BITFLAG_LEVEL,
|
|
100
100
|
BITFLAG_DATA_DESCRIPTOR,
|
|
@@ -107,5 +107,6 @@ export {
|
|
|
107
107
|
MIN_DATE,
|
|
108
108
|
MAX_DATE,
|
|
109
109
|
UNDEFINED_VALUE,
|
|
110
|
-
UNDEFINED_TYPE
|
|
110
|
+
UNDEFINED_TYPE,
|
|
111
|
+
FUNCTION_TYPE
|
|
111
112
|
};
|
package/lib/core/io.js
CHANGED
|
@@ -27,9 +27,11 @@
|
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
29
|
/* global Blob, atob, btoa, XMLHttpRequest, URL, fetch, ReadableStream, WritableStream, FileReader, TransformStream, Response */
|
|
30
|
+
// deno-lint-ignore-file no-this-alias
|
|
30
31
|
|
|
31
32
|
const ERR_HTTP_STATUS = "HTTP error ";
|
|
32
33
|
const ERR_HTTP_RANGE = "HTTP Range not supported";
|
|
34
|
+
const ERR_ITERATOR_COMPLETED_TOO_SOON = "Writer iterator completed too soon";
|
|
33
35
|
|
|
34
36
|
const CONTENT_TYPE_TEXT_PLAIN = "text/plain";
|
|
35
37
|
const HTTP_HEADER_CONTENT_LENGTH = "Content-Length";
|
|
@@ -565,6 +567,69 @@ class SplitZipReader extends Reader {
|
|
|
565
567
|
}
|
|
566
568
|
}
|
|
567
569
|
|
|
570
|
+
class SplitZipWriter extends Stream {
|
|
571
|
+
|
|
572
|
+
constructor(writerGenerator, maxSize = 4294967296) {
|
|
573
|
+
super();
|
|
574
|
+
const zipWriter = this;
|
|
575
|
+
Object.assign(zipWriter, {
|
|
576
|
+
diskNumber: 0,
|
|
577
|
+
diskOffset: 0,
|
|
578
|
+
size: 0,
|
|
579
|
+
availableSize: maxSize
|
|
580
|
+
});
|
|
581
|
+
let diskSourceWriter, diskWritable, diskWriter;
|
|
582
|
+
const writable = new WritableStream({
|
|
583
|
+
async write(chunk) {
|
|
584
|
+
if (!diskWriter) {
|
|
585
|
+
const { value, done } = await writerGenerator.next();
|
|
586
|
+
if (done && !value) {
|
|
587
|
+
throw new Error(ERR_ITERATOR_COMPLETED_TOO_SOON);
|
|
588
|
+
} else {
|
|
589
|
+
diskSourceWriter = value;
|
|
590
|
+
diskSourceWriter.size = 0;
|
|
591
|
+
diskWritable = value.writable;
|
|
592
|
+
diskWriter = diskWritable.getWriter();
|
|
593
|
+
}
|
|
594
|
+
await this.write(chunk);
|
|
595
|
+
} else if (diskSourceWriter.size + chunk.length >= maxSize) {
|
|
596
|
+
const chunkLength = maxSize - diskSourceWriter.size;
|
|
597
|
+
await writeChunk(chunk.slice(0, chunkLength));
|
|
598
|
+
await closeDisk();
|
|
599
|
+
zipWriter.diskOffset += diskSourceWriter.size;
|
|
600
|
+
zipWriter.diskNumber++;
|
|
601
|
+
diskWriter = null;
|
|
602
|
+
await this.write(chunk.slice(chunkLength));
|
|
603
|
+
} else if (chunk.length) {
|
|
604
|
+
await writeChunk(chunk);
|
|
605
|
+
}
|
|
606
|
+
zipWriter.availableSize = maxSize - diskSourceWriter.size;
|
|
607
|
+
},
|
|
608
|
+
async close() {
|
|
609
|
+
await diskWriter.ready;
|
|
610
|
+
await closeDisk();
|
|
611
|
+
}
|
|
612
|
+
});
|
|
613
|
+
Object.defineProperty(zipWriter, PROPERTY_NAME_WRITABLE, {
|
|
614
|
+
get() {
|
|
615
|
+
return writable;
|
|
616
|
+
}
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
async function writeChunk(chunk) {
|
|
620
|
+
await diskWriter.ready;
|
|
621
|
+
await diskWriter.write(chunk);
|
|
622
|
+
diskSourceWriter.size += chunk.length;
|
|
623
|
+
zipWriter.size += chunk.length;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
async function closeDisk() {
|
|
627
|
+
diskWritable.size = diskSourceWriter.size;
|
|
628
|
+
await diskWriter.close();
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
568
633
|
function isHttpFamily(url) {
|
|
569
634
|
const { baseURL } = getConfiguration();
|
|
570
635
|
const { protocol } = new URL(url, baseURL);
|
|
@@ -597,5 +662,7 @@ export {
|
|
|
597
662
|
HttpReader,
|
|
598
663
|
HttpRangeReader,
|
|
599
664
|
SplitZipReader,
|
|
600
|
-
|
|
665
|
+
SplitZipWriter,
|
|
666
|
+
ERR_HTTP_RANGE,
|
|
667
|
+
ERR_ITERATOR_COMPLETED_TOO_SOON
|
|
601
668
|
};
|
|
@@ -56,6 +56,7 @@ const SIGNATURE_LENGTH = 10;
|
|
|
56
56
|
const COUNTER_DEFAULT_VALUE = [0, 0, 0, 0];
|
|
57
57
|
const UNDEFINED_TYPE = "undefined";
|
|
58
58
|
const FUNCTION_TYPE = "function";
|
|
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;
|
|
@@ -132,6 +133,7 @@ class AESDecryptionStream extends TransformStream {
|
|
|
132
133
|
class AESEncryptionStream extends TransformStream {
|
|
133
134
|
|
|
134
135
|
constructor(password, strength) {
|
|
136
|
+
// deno-lint-ignore prefer-const
|
|
135
137
|
let stream;
|
|
136
138
|
super({
|
|
137
139
|
start() {
|