@cj-tech-master/excelts 4.2.1-canary.20260111102127.f808a37 → 4.2.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/THIRD_PARTY_NOTICES.md +31 -0
- package/dist/browser/index.browser.d.ts +0 -1
- package/dist/browser/index.browser.js +0 -12
- package/dist/browser/modules/archive/byte-queue.d.ts +18 -0
- package/dist/browser/modules/archive/byte-queue.js +125 -0
- package/dist/browser/modules/archive/{compression/compress.base.js → compress.base.js} +1 -1
- package/dist/browser/modules/archive/{compression/compress.browser.d.ts → compress.browser.d.ts} +8 -2
- package/dist/{esm/modules/archive/compression → browser/modules/archive}/compress.browser.js +11 -3
- package/dist/browser/modules/archive/{compression/compress.d.ts → compress.d.ts} +2 -2
- package/dist/{esm/modules/archive/compression → browser/modules/archive}/compress.js +1 -1
- package/dist/browser/modules/archive/{compression/crc32.browser.d.ts → crc32.browser.d.ts} +1 -1
- package/dist/browser/modules/archive/{compression/crc32.d.ts → crc32.d.ts} +1 -1
- package/dist/browser/modules/archive/{compression/crc32.js → crc32.js} +1 -1
- package/dist/browser/modules/archive/defaults.d.ts +0 -1
- package/dist/browser/modules/archive/defaults.js +3 -6
- package/dist/browser/modules/archive/{compression/deflate-fallback.js → deflate-fallback.js} +1 -1
- package/dist/browser/modules/archive/{unzip/extract.d.ts → extract.d.ts} +2 -2
- package/dist/browser/modules/archive/index.base.d.ts +4 -4
- package/dist/browser/modules/archive/index.base.js +6 -3
- package/dist/browser/modules/archive/index.browser.d.ts +4 -3
- package/dist/browser/modules/archive/index.browser.js +7 -3
- package/dist/browser/modules/archive/index.d.ts +4 -3
- package/dist/browser/modules/archive/index.js +5 -3
- package/dist/browser/modules/archive/{unzip/stream.base.d.ts → parse.base.d.ts} +2 -36
- package/dist/browser/modules/archive/parse.base.js +644 -0
- package/dist/browser/modules/archive/{unzip/stream.browser.d.ts → parse.browser.d.ts} +1 -1
- package/dist/{esm/modules/archive/unzip/stream.browser.js → browser/modules/archive/parse.browser.js} +110 -371
- package/dist/browser/modules/archive/{unzip/stream.d.ts → parse.d.ts} +2 -2
- package/dist/{esm/modules/archive/unzip/stream.js → browser/modules/archive/parse.js} +5 -6
- package/dist/browser/modules/archive/{compression/streaming-compress.browser.d.ts → streaming-compress.browser.d.ts} +2 -2
- package/dist/browser/modules/archive/{compression/streaming-compress.browser.js → streaming-compress.browser.js} +3 -3
- package/dist/browser/modules/archive/{compression/streaming-compress.d.ts → streaming-compress.d.ts} +2 -2
- package/dist/browser/modules/archive/{compression/streaming-compress.js → streaming-compress.js} +2 -2
- package/dist/browser/modules/archive/{zip/stream.d.ts → streaming-zip.d.ts} +5 -28
- package/dist/{esm/modules/archive/zip/stream.js → browser/modules/archive/streaming-zip.js} +48 -192
- package/dist/browser/modules/archive/utils/bytes.js +16 -16
- package/dist/browser/modules/archive/utils/parse-buffer.js +23 -21
- package/dist/browser/modules/archive/utils/timestamps.js +1 -62
- package/dist/browser/modules/archive/utils/zip-extra-fields.d.ts +1 -1
- package/dist/browser/modules/archive/utils/zip-extra-fields.js +14 -26
- package/dist/browser/modules/archive/utils/zip-extra.d.ts +18 -0
- package/dist/browser/modules/archive/utils/zip-extra.js +68 -0
- package/dist/browser/modules/archive/zip-builder.d.ts +117 -0
- package/dist/browser/modules/archive/zip-builder.js +292 -0
- package/dist/browser/modules/archive/zip-constants.d.ts +18 -0
- package/dist/browser/modules/archive/zip-constants.js +23 -0
- package/dist/{esm/modules/archive/zip → browser/modules/archive}/zip-entry-metadata.js +3 -3
- package/dist/{types/modules/archive/unzip → browser/modules/archive}/zip-parser.d.ts +1 -1
- package/dist/{esm/modules/archive/unzip → browser/modules/archive}/zip-parser.js +24 -38
- package/dist/browser/modules/archive/{zip-spec/zip-records.d.ts → zip-records.d.ts} +0 -20
- package/dist/browser/modules/archive/zip-records.js +84 -0
- package/dist/browser/modules/excel/stream/workbook-reader.browser.js +1 -1
- package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +1 -1
- package/dist/browser/modules/excel/stream/workbook-writer.browser.js +1 -1
- package/dist/browser/modules/excel/xlsx/xlsx.browser.js +6 -3
- package/dist/browser/modules/excel/xlsx/xlsx.js +1 -1
- package/dist/browser/modules/stream/streams.browser.d.ts +30 -28
- package/dist/browser/modules/stream/streams.browser.js +710 -830
- package/dist/browser/modules/stream/streams.js +58 -140
- package/dist/cjs/modules/archive/byte-queue.js +129 -0
- package/dist/cjs/modules/archive/{compression/compress.base.js → compress.base.js} +1 -1
- package/dist/cjs/modules/archive/{compression/compress.browser.js → compress.browser.js} +11 -3
- package/dist/cjs/modules/archive/{compression/compress.js → compress.js} +1 -1
- package/dist/cjs/modules/archive/{compression/crc32.js → crc32.js} +1 -1
- package/dist/cjs/modules/archive/defaults.js +4 -7
- package/dist/cjs/modules/archive/{compression/deflate-fallback.js → deflate-fallback.js} +1 -1
- package/dist/cjs/modules/archive/index.base.js +19 -9
- package/dist/cjs/modules/archive/index.browser.js +10 -4
- package/dist/cjs/modules/archive/index.js +8 -4
- package/dist/cjs/modules/archive/parse.base.js +666 -0
- package/dist/cjs/modules/archive/{unzip/stream.browser.js → parse.browser.js} +111 -372
- package/dist/cjs/modules/archive/{unzip/stream.js → parse.js} +8 -9
- package/dist/cjs/modules/archive/{compression/streaming-compress.browser.js → streaming-compress.browser.js} +3 -3
- package/dist/cjs/modules/archive/{compression/streaming-compress.js → streaming-compress.js} +2 -2
- package/dist/cjs/modules/archive/{zip/stream.js → streaming-zip.js} +50 -194
- package/dist/cjs/modules/archive/utils/bytes.js +16 -16
- package/dist/cjs/modules/archive/utils/parse-buffer.js +23 -21
- package/dist/cjs/modules/archive/utils/timestamps.js +3 -64
- package/dist/cjs/modules/archive/utils/zip-extra-fields.js +14 -26
- package/dist/cjs/modules/archive/utils/zip-extra.js +74 -0
- package/dist/cjs/modules/archive/zip-builder.js +297 -0
- package/dist/cjs/modules/archive/zip-constants.js +26 -0
- package/dist/cjs/modules/archive/{zip/zip-entry-metadata.js → zip-entry-metadata.js} +5 -5
- package/dist/cjs/modules/archive/{unzip/zip-parser.js → zip-parser.js} +33 -47
- package/dist/cjs/modules/archive/zip-records.js +90 -0
- package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +2 -2
- package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +4 -4
- package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +9 -6
- package/dist/cjs/modules/excel/xlsx/xlsx.js +2 -2
- package/dist/cjs/modules/stream/streams.browser.js +710 -830
- package/dist/cjs/modules/stream/streams.js +58 -140
- package/dist/esm/index.browser.js +0 -12
- package/dist/esm/modules/archive/byte-queue.js +125 -0
- package/dist/esm/modules/archive/{compression/compress.base.js → compress.base.js} +1 -1
- package/dist/{browser/modules/archive/compression → esm/modules/archive}/compress.browser.js +11 -3
- package/dist/{browser/modules/archive/compression → esm/modules/archive}/compress.js +1 -1
- package/dist/esm/modules/archive/{compression/crc32.js → crc32.js} +1 -1
- package/dist/esm/modules/archive/defaults.js +3 -6
- package/dist/esm/modules/archive/{compression/deflate-fallback.js → deflate-fallback.js} +1 -1
- package/dist/esm/modules/archive/index.base.js +6 -3
- package/dist/esm/modules/archive/index.browser.js +7 -3
- package/dist/esm/modules/archive/index.js +5 -3
- package/dist/esm/modules/archive/parse.base.js +644 -0
- package/dist/{browser/modules/archive/unzip/stream.browser.js → esm/modules/archive/parse.browser.js} +110 -371
- package/dist/{browser/modules/archive/unzip/stream.js → esm/modules/archive/parse.js} +5 -6
- package/dist/esm/modules/archive/{compression/streaming-compress.browser.js → streaming-compress.browser.js} +3 -3
- package/dist/esm/modules/archive/{compression/streaming-compress.js → streaming-compress.js} +2 -2
- package/dist/{browser/modules/archive/zip/stream.js → esm/modules/archive/streaming-zip.js} +48 -192
- package/dist/esm/modules/archive/utils/bytes.js +16 -16
- package/dist/esm/modules/archive/utils/parse-buffer.js +23 -21
- package/dist/esm/modules/archive/utils/timestamps.js +1 -62
- package/dist/esm/modules/archive/utils/zip-extra-fields.js +14 -26
- package/dist/esm/modules/archive/utils/zip-extra.js +68 -0
- package/dist/esm/modules/archive/zip-builder.js +292 -0
- package/dist/esm/modules/archive/zip-constants.js +23 -0
- package/dist/{browser/modules/archive/zip → esm/modules/archive}/zip-entry-metadata.js +3 -3
- package/dist/{browser/modules/archive/unzip → esm/modules/archive}/zip-parser.js +24 -38
- package/dist/esm/modules/archive/zip-records.js +84 -0
- package/dist/esm/modules/excel/stream/workbook-reader.browser.js +1 -1
- package/dist/esm/modules/excel/stream/workbook-writer.browser.js +1 -1
- package/dist/esm/modules/excel/xlsx/xlsx.browser.js +6 -3
- package/dist/esm/modules/excel/xlsx/xlsx.js +1 -1
- package/dist/esm/modules/stream/streams.browser.js +710 -830
- package/dist/esm/modules/stream/streams.js +58 -140
- package/dist/iife/THIRD_PARTY_NOTICES.md +31 -0
- package/dist/iife/excelts.iife.js +4425 -6215
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +31 -103
- package/dist/types/index.browser.d.ts +0 -1
- package/dist/types/modules/archive/byte-queue.d.ts +18 -0
- package/dist/types/modules/archive/{compression/compress.browser.d.ts → compress.browser.d.ts} +8 -2
- package/dist/types/modules/archive/defaults.d.ts +0 -1
- package/dist/types/modules/archive/index.base.d.ts +4 -4
- package/dist/types/modules/archive/index.browser.d.ts +4 -3
- package/dist/types/modules/archive/index.d.ts +4 -3
- package/dist/types/modules/archive/{unzip/stream.base.d.ts → parse.base.d.ts} +4 -38
- package/dist/types/modules/archive/{unzip/stream.browser.d.ts → parse.browser.d.ts} +2 -2
- package/dist/types/modules/archive/{unzip/stream.d.ts → parse.d.ts} +3 -3
- package/dist/types/modules/archive/{compression/streaming-compress.browser.d.ts → streaming-compress.browser.d.ts} +1 -1
- package/dist/types/modules/archive/{zip/stream.d.ts → streaming-zip.d.ts} +6 -29
- package/dist/types/modules/archive/utils/zip-extra-fields.d.ts +1 -1
- package/dist/types/modules/archive/utils/zip-extra.d.ts +18 -0
- package/dist/types/modules/archive/zip-builder.d.ts +117 -0
- package/dist/types/modules/archive/zip-constants.d.ts +18 -0
- package/dist/types/modules/archive/{zip/zip-entry-metadata.d.ts → zip-entry-metadata.d.ts} +1 -1
- package/dist/{browser/modules/archive/unzip → types/modules/archive}/zip-parser.d.ts +1 -1
- package/dist/types/modules/archive/{zip-spec/zip-records.d.ts → zip-records.d.ts} +0 -20
- package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +1 -1
- package/dist/types/modules/stream/streams.browser.d.ts +30 -28
- package/package.json +1 -5
- package/dist/browser/modules/archive/internal/byte-queue.d.ts +0 -33
- package/dist/browser/modules/archive/internal/byte-queue.js +0 -407
- package/dist/browser/modules/archive/io/archive-sink.d.ts +0 -9
- package/dist/browser/modules/archive/io/archive-sink.js +0 -77
- package/dist/browser/modules/archive/io/archive-source.d.ts +0 -8
- package/dist/browser/modules/archive/io/archive-source.js +0 -107
- package/dist/browser/modules/archive/unzip/index.d.ts +0 -40
- package/dist/browser/modules/archive/unzip/index.js +0 -164
- package/dist/browser/modules/archive/unzip/stream.base.js +0 -1022
- package/dist/browser/modules/archive/utils/async-queue.d.ts +0 -7
- package/dist/browser/modules/archive/utils/async-queue.js +0 -103
- package/dist/browser/modules/archive/utils/compressibility.d.ts +0 -10
- package/dist/browser/modules/archive/utils/compressibility.js +0 -57
- package/dist/browser/modules/archive/utils/pattern-scanner.d.ts +0 -21
- package/dist/browser/modules/archive/utils/pattern-scanner.js +0 -27
- package/dist/browser/modules/archive/zip/index.d.ts +0 -42
- package/dist/browser/modules/archive/zip/index.js +0 -157
- package/dist/browser/modules/archive/zip/zip-bytes.d.ts +0 -73
- package/dist/browser/modules/archive/zip/zip-bytes.js +0 -239
- package/dist/browser/modules/archive/zip-spec/zip-records.js +0 -126
- package/dist/cjs/modules/archive/internal/byte-queue.js +0 -411
- package/dist/cjs/modules/archive/io/archive-sink.js +0 -82
- package/dist/cjs/modules/archive/io/archive-source.js +0 -114
- package/dist/cjs/modules/archive/unzip/index.js +0 -170
- package/dist/cjs/modules/archive/unzip/stream.base.js +0 -1044
- package/dist/cjs/modules/archive/utils/async-queue.js +0 -106
- package/dist/cjs/modules/archive/utils/compressibility.js +0 -60
- package/dist/cjs/modules/archive/utils/pattern-scanner.js +0 -31
- package/dist/cjs/modules/archive/zip/index.js +0 -162
- package/dist/cjs/modules/archive/zip/zip-bytes.js +0 -242
- package/dist/cjs/modules/archive/zip-spec/zip-records.js +0 -136
- package/dist/esm/modules/archive/internal/byte-queue.js +0 -407
- package/dist/esm/modules/archive/io/archive-sink.js +0 -77
- package/dist/esm/modules/archive/io/archive-source.js +0 -107
- package/dist/esm/modules/archive/unzip/index.js +0 -164
- package/dist/esm/modules/archive/unzip/stream.base.js +0 -1022
- package/dist/esm/modules/archive/utils/async-queue.js +0 -103
- package/dist/esm/modules/archive/utils/compressibility.js +0 -57
- package/dist/esm/modules/archive/utils/pattern-scanner.js +0 -27
- package/dist/esm/modules/archive/zip/index.js +0 -157
- package/dist/esm/modules/archive/zip/zip-bytes.js +0 -239
- package/dist/esm/modules/archive/zip-spec/zip-records.js +0 -126
- package/dist/types/modules/archive/internal/byte-queue.d.ts +0 -33
- package/dist/types/modules/archive/io/archive-sink.d.ts +0 -9
- package/dist/types/modules/archive/io/archive-source.d.ts +0 -8
- package/dist/types/modules/archive/unzip/index.d.ts +0 -40
- package/dist/types/modules/archive/utils/async-queue.d.ts +0 -7
- package/dist/types/modules/archive/utils/compressibility.d.ts +0 -10
- package/dist/types/modules/archive/utils/pattern-scanner.d.ts +0 -21
- package/dist/types/modules/archive/zip/index.d.ts +0 -42
- package/dist/types/modules/archive/zip/zip-bytes.d.ts +0 -73
- /package/dist/browser/modules/archive/{compression/compress.base.d.ts → compress.base.d.ts} +0 -0
- /package/dist/browser/modules/archive/{compression/crc32.base.d.ts → crc32.base.d.ts} +0 -0
- /package/dist/browser/modules/archive/{compression/crc32.base.js → crc32.base.js} +0 -0
- /package/dist/browser/modules/archive/{compression/crc32.browser.js → crc32.browser.js} +0 -0
- /package/dist/browser/modules/archive/{compression/deflate-fallback.d.ts → deflate-fallback.d.ts} +0 -0
- /package/dist/browser/modules/archive/{unzip/extract.js → extract.js} +0 -0
- /package/dist/browser/modules/archive/{compression/streaming-compress.base.d.ts → streaming-compress.base.d.ts} +0 -0
- /package/dist/browser/modules/archive/{compression/streaming-compress.base.js → streaming-compress.base.js} +0 -0
- /package/dist/browser/modules/archive/{zip-spec/zip-entry-info.d.ts → zip-entry-info.d.ts} +0 -0
- /package/dist/browser/modules/archive/{zip-spec/zip-entry-info.js → zip-entry-info.js} +0 -0
- /package/dist/browser/modules/archive/{zip/zip-entry-metadata.d.ts → zip-entry-metadata.d.ts} +0 -0
- /package/dist/cjs/modules/archive/{compression/crc32.base.js → crc32.base.js} +0 -0
- /package/dist/cjs/modules/archive/{compression/crc32.browser.js → crc32.browser.js} +0 -0
- /package/dist/cjs/modules/archive/{unzip/extract.js → extract.js} +0 -0
- /package/dist/cjs/modules/archive/{compression/streaming-compress.base.js → streaming-compress.base.js} +0 -0
- /package/dist/cjs/modules/archive/{zip-spec/zip-entry-info.js → zip-entry-info.js} +0 -0
- /package/dist/esm/modules/archive/{compression/crc32.base.js → crc32.base.js} +0 -0
- /package/dist/esm/modules/archive/{compression/crc32.browser.js → crc32.browser.js} +0 -0
- /package/dist/esm/modules/archive/{unzip/extract.js → extract.js} +0 -0
- /package/dist/esm/modules/archive/{compression/streaming-compress.base.js → streaming-compress.base.js} +0 -0
- /package/dist/esm/modules/archive/{zip-spec/zip-entry-info.js → zip-entry-info.js} +0 -0
- /package/dist/types/modules/archive/{compression/compress.base.d.ts → compress.base.d.ts} +0 -0
- /package/dist/types/modules/archive/{compression/compress.d.ts → compress.d.ts} +0 -0
- /package/dist/types/modules/archive/{compression/crc32.base.d.ts → crc32.base.d.ts} +0 -0
- /package/dist/types/modules/archive/{compression/crc32.browser.d.ts → crc32.browser.d.ts} +0 -0
- /package/dist/types/modules/archive/{compression/crc32.d.ts → crc32.d.ts} +0 -0
- /package/dist/types/modules/archive/{compression/deflate-fallback.d.ts → deflate-fallback.d.ts} +0 -0
- /package/dist/types/modules/archive/{unzip/extract.d.ts → extract.d.ts} +0 -0
- /package/dist/types/modules/archive/{compression/streaming-compress.base.d.ts → streaming-compress.base.d.ts} +0 -0
- /package/dist/types/modules/archive/{compression/streaming-compress.d.ts → streaming-compress.d.ts} +0 -0
- /package/dist/types/modules/archive/{zip-spec/zip-entry-info.d.ts → zip-entry-info.d.ts} +0 -0
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
export function createAsyncQueue() {
|
|
2
|
-
const values = [];
|
|
3
|
-
let valuesHead = 0;
|
|
4
|
-
const waiters = [];
|
|
5
|
-
let waitersHead = 0;
|
|
6
|
-
let done = false;
|
|
7
|
-
let error = null;
|
|
8
|
-
const maybeCompact = () => {
|
|
9
|
-
// Prevent unbounded growth of the underlying arrays.
|
|
10
|
-
if (valuesHead > 1024 && valuesHead * 2 > values.length) {
|
|
11
|
-
values.splice(0, valuesHead);
|
|
12
|
-
valuesHead = 0;
|
|
13
|
-
}
|
|
14
|
-
if (waitersHead > 1024 && waitersHead * 2 > waiters.length) {
|
|
15
|
-
waiters.splice(0, waitersHead);
|
|
16
|
-
waitersHead = 0;
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
const shiftWaiter = () => {
|
|
20
|
-
while (waitersHead < waiters.length) {
|
|
21
|
-
const w = waiters[waitersHead];
|
|
22
|
-
waiters[waitersHead] = undefined;
|
|
23
|
-
waitersHead++;
|
|
24
|
-
if (w) {
|
|
25
|
-
maybeCompact();
|
|
26
|
-
return w;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
maybeCompact();
|
|
30
|
-
return undefined;
|
|
31
|
-
};
|
|
32
|
-
const shiftValue = () => {
|
|
33
|
-
while (valuesHead < values.length) {
|
|
34
|
-
const v = values[valuesHead];
|
|
35
|
-
values[valuesHead] = undefined;
|
|
36
|
-
valuesHead++;
|
|
37
|
-
if (v !== undefined) {
|
|
38
|
-
maybeCompact();
|
|
39
|
-
return v;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
maybeCompact();
|
|
43
|
-
return undefined;
|
|
44
|
-
};
|
|
45
|
-
const push = (value) => {
|
|
46
|
-
if (done || error) {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
const waiter = shiftWaiter();
|
|
50
|
-
if (waiter) {
|
|
51
|
-
waiter.resolve({ value, done: false });
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
values.push(value);
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
const fail = (err) => {
|
|
58
|
-
if (done || error) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
error = err;
|
|
62
|
-
while (true) {
|
|
63
|
-
const waiter = shiftWaiter();
|
|
64
|
-
if (!waiter) {
|
|
65
|
-
break;
|
|
66
|
-
}
|
|
67
|
-
waiter.reject(err);
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
const close = () => {
|
|
71
|
-
if (done || error) {
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
done = true;
|
|
75
|
-
while (true) {
|
|
76
|
-
const waiter = shiftWaiter();
|
|
77
|
-
if (!waiter) {
|
|
78
|
-
break;
|
|
79
|
-
}
|
|
80
|
-
waiter.resolve({ value: undefined, done: true });
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
const iterable = {
|
|
84
|
-
[Symbol.asyncIterator]() {
|
|
85
|
-
return {
|
|
86
|
-
next() {
|
|
87
|
-
if (error) {
|
|
88
|
-
return Promise.reject(error);
|
|
89
|
-
}
|
|
90
|
-
const value = shiftValue();
|
|
91
|
-
if (value !== undefined) {
|
|
92
|
-
return Promise.resolve({ value, done: false });
|
|
93
|
-
}
|
|
94
|
-
if (done) {
|
|
95
|
-
return Promise.resolve({ value: undefined, done: true });
|
|
96
|
-
}
|
|
97
|
-
return new Promise((resolve, reject) => waiters.push({ resolve, reject }));
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
return { push, fail, close, iterable };
|
|
103
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
const DEFAULT_SAMPLE_BYTES = 64 * 1024;
|
|
2
|
-
const MIN_DECISION_BYTES = 16 * 1024;
|
|
3
|
-
function log2(x) {
|
|
4
|
-
return Math.log(x) / Math.LN2;
|
|
5
|
-
}
|
|
6
|
-
function shannonEntropy(bytes) {
|
|
7
|
-
const counts = new Uint32Array(256);
|
|
8
|
-
for (let i = 0; i < bytes.length; i++) {
|
|
9
|
-
counts[bytes[i]] += 1;
|
|
10
|
-
}
|
|
11
|
-
let entropy = 0;
|
|
12
|
-
const total = bytes.length;
|
|
13
|
-
for (let i = 0; i < 256; i++) {
|
|
14
|
-
const count = counts[i];
|
|
15
|
-
if (count === 0) {
|
|
16
|
-
continue;
|
|
17
|
-
}
|
|
18
|
-
const p = count / total;
|
|
19
|
-
entropy -= p * log2(p);
|
|
20
|
-
}
|
|
21
|
-
return entropy;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Heuristic: detect incompressible (high-entropy) data.
|
|
25
|
-
*
|
|
26
|
-
* This is a performance optimization: if data looks random, DEFLATE usually
|
|
27
|
-
* wastes CPU and may even produce slightly larger output.
|
|
28
|
-
*/
|
|
29
|
-
export function isProbablyIncompressible(data, options = {}) {
|
|
30
|
-
const sampleBytes = options.sampleBytes ?? DEFAULT_SAMPLE_BYTES;
|
|
31
|
-
const minDecisionBytes = options.minDecisionBytes ?? MIN_DECISION_BYTES;
|
|
32
|
-
const len = Math.min(data.length, sampleBytes);
|
|
33
|
-
if (len < minDecisionBytes) {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
const sample = data.subarray(0, len);
|
|
37
|
-
// Fast-ish early filter: if there are too few unique bytes, it's probably compressible.
|
|
38
|
-
// (e.g. text, repeated patterns)
|
|
39
|
-
const seen = new Uint8Array(256);
|
|
40
|
-
let unique = 0;
|
|
41
|
-
for (let i = 0; i < sample.length; i++) {
|
|
42
|
-
const b = sample[i];
|
|
43
|
-
if (seen[b] === 0) {
|
|
44
|
-
seen[b] = 1;
|
|
45
|
-
unique += 1;
|
|
46
|
-
if (unique >= 200) {
|
|
47
|
-
break;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
if (unique < 200) {
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
// Shannon entropy in bits/byte; random tends to ~8.
|
|
55
|
-
// Threshold picked to be conservative.
|
|
56
|
-
return shannonEntropy(sample) >= 7.95;
|
|
57
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Stateful helper for incremental pattern scanning in growing buffers.
|
|
3
|
-
*
|
|
4
|
-
* The scanner tracks a `searchFrom` cursor and an `overlap` region so callers
|
|
5
|
-
* can avoid rescanning bytes that cannot start a match.
|
|
6
|
-
*/
|
|
7
|
-
export class PatternScanner {
|
|
8
|
-
constructor(pattern) {
|
|
9
|
-
this.searchFrom = 0;
|
|
10
|
-
this.pattern = pattern;
|
|
11
|
-
this.overlap = Math.max(0, pattern.length - 1);
|
|
12
|
-
}
|
|
13
|
-
/** Find the next match index starting at the current `searchFrom`. */
|
|
14
|
-
find(target) {
|
|
15
|
-
return target.indexOfPattern(this.pattern, this.searchFrom);
|
|
16
|
-
}
|
|
17
|
-
/** Update `searchFrom` after consuming `consumed` bytes from the front. */
|
|
18
|
-
onConsume(consumed) {
|
|
19
|
-
if (consumed > 0) {
|
|
20
|
-
this.searchFrom = Math.max(0, this.searchFrom - consumed);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
/** Update `searchFrom` after a no-match scan on a buffer of length `bufferLength`. */
|
|
24
|
-
onNoMatch(bufferLength) {
|
|
25
|
-
this.searchFrom = Math.max(this.searchFrom, Math.max(0, bufferLength - this.overlap));
|
|
26
|
-
}
|
|
27
|
-
}
|
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import { DEFAULT_ZIP_LEVEL, DEFAULT_ZIP_TIMESTAMPS } from "../defaults.js";
|
|
2
|
-
import { ZipDeflateFile, StreamingZip } from "./stream.js";
|
|
3
|
-
import { createZip, createZipSync } from "./zip-bytes.js";
|
|
4
|
-
import { collect, pipeIterableToSink } from "../io/archive-sink.js";
|
|
5
|
-
import { toAsyncIterable, toUint8Array, toUint8ArraySync } from "../io/archive-source.js";
|
|
6
|
-
import { createAsyncQueue } from "../utils/async-queue.js";
|
|
7
|
-
const REPRODUCIBLE_ZIP_MOD_TIME = new Date(1980, 0, 1, 0, 0, 0);
|
|
8
|
-
export class ZipArchive {
|
|
9
|
-
constructor(options = {}) {
|
|
10
|
-
this._entries = [];
|
|
11
|
-
this._sealed = false;
|
|
12
|
-
const reproducible = options.reproducible ?? false;
|
|
13
|
-
this._options = {
|
|
14
|
-
level: options.level ?? DEFAULT_ZIP_LEVEL,
|
|
15
|
-
timestamps: options.timestamps ?? (reproducible ? "dos" : DEFAULT_ZIP_TIMESTAMPS),
|
|
16
|
-
comment: options.comment,
|
|
17
|
-
modTime: options.modTime ?? (reproducible ? REPRODUCIBLE_ZIP_MOD_TIME : new Date()),
|
|
18
|
-
smartStore: options.smartStore ?? true
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
add(name, source, options) {
|
|
22
|
-
if (this._sealed) {
|
|
23
|
-
throw new Error("Cannot add entries after output has started");
|
|
24
|
-
}
|
|
25
|
-
if (!name) {
|
|
26
|
-
throw new Error("Entry name is required");
|
|
27
|
-
}
|
|
28
|
-
this._entries.push({ name, source, options });
|
|
29
|
-
return this;
|
|
30
|
-
}
|
|
31
|
-
stream() {
|
|
32
|
-
this._sealed = true;
|
|
33
|
-
const queue = createAsyncQueue();
|
|
34
|
-
const zip = new StreamingZip((err, data, final) => {
|
|
35
|
-
if (err) {
|
|
36
|
-
queue.fail(err);
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
if (data.length) {
|
|
40
|
-
queue.push(data);
|
|
41
|
-
}
|
|
42
|
-
if (final) {
|
|
43
|
-
queue.close();
|
|
44
|
-
}
|
|
45
|
-
}, { comment: this._options.comment });
|
|
46
|
-
(async () => {
|
|
47
|
-
try {
|
|
48
|
-
for (const entry of this._entries) {
|
|
49
|
-
const level = entry.options?.level ?? this._options.level;
|
|
50
|
-
const file = new ZipDeflateFile(entry.name, {
|
|
51
|
-
level,
|
|
52
|
-
modTime: entry.options?.modTime ?? this._options.modTime,
|
|
53
|
-
timestamps: this._options.timestamps,
|
|
54
|
-
comment: entry.options?.comment,
|
|
55
|
-
smartStore: this._options.smartStore
|
|
56
|
-
});
|
|
57
|
-
zip.add(file);
|
|
58
|
-
// Feed data
|
|
59
|
-
if (entry.source instanceof Uint8Array ||
|
|
60
|
-
entry.source instanceof ArrayBuffer ||
|
|
61
|
-
typeof entry.source === "string" ||
|
|
62
|
-
(typeof Blob !== "undefined" && entry.source instanceof Blob)) {
|
|
63
|
-
const bytes = await toUint8Array(entry.source);
|
|
64
|
-
await file.push(bytes, true);
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
for await (const chunk of toAsyncIterable(entry.source)) {
|
|
68
|
-
await file.push(chunk, false);
|
|
69
|
-
}
|
|
70
|
-
await file.push(new Uint8Array(0), true);
|
|
71
|
-
}
|
|
72
|
-
await file.complete();
|
|
73
|
-
}
|
|
74
|
-
zip.end();
|
|
75
|
-
}
|
|
76
|
-
catch (e) {
|
|
77
|
-
queue.fail(e instanceof Error ? e : new Error(String(e)));
|
|
78
|
-
}
|
|
79
|
-
})();
|
|
80
|
-
return queue.iterable;
|
|
81
|
-
}
|
|
82
|
-
async bytes() {
|
|
83
|
-
this._sealed = true;
|
|
84
|
-
const allSourcesInMemory = this._entries.every(e => e.source instanceof Uint8Array ||
|
|
85
|
-
e.source instanceof ArrayBuffer ||
|
|
86
|
-
typeof e.source === "string" ||
|
|
87
|
-
(typeof Blob !== "undefined" && e.source instanceof Blob));
|
|
88
|
-
const hasBlobSource = this._entries.some(e => typeof Blob !== "undefined" && e.source instanceof Blob);
|
|
89
|
-
// Fast-path: when all sources are already in memory and there are no
|
|
90
|
-
// per-entry compression overrides, use the single-buffer ZIP builder.
|
|
91
|
-
// This avoids the overhead of chunking + collecting from the streaming writer.
|
|
92
|
-
if (allSourcesInMemory) {
|
|
93
|
-
// Prefer the sync builder when possible (Node.js hot path): it avoids
|
|
94
|
-
// async/Promise overhead and uses zlib sync fast paths.
|
|
95
|
-
if (!hasBlobSource) {
|
|
96
|
-
const entries = this._entries.map(e => ({
|
|
97
|
-
name: e.name,
|
|
98
|
-
data: toUint8ArraySync(e.source),
|
|
99
|
-
level: e.options?.level,
|
|
100
|
-
modTime: e.options?.modTime,
|
|
101
|
-
comment: e.options?.comment
|
|
102
|
-
}));
|
|
103
|
-
return createZipSync(entries, {
|
|
104
|
-
level: this._options.level,
|
|
105
|
-
timestamps: this._options.timestamps,
|
|
106
|
-
modTime: this._options.modTime,
|
|
107
|
-
comment: this._options.comment,
|
|
108
|
-
smartStore: this._options.smartStore
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
const entries = await Promise.all(this._entries.map(async (e) => ({
|
|
112
|
-
name: e.name,
|
|
113
|
-
data: await toUint8Array(e.source),
|
|
114
|
-
level: e.options?.level,
|
|
115
|
-
modTime: e.options?.modTime,
|
|
116
|
-
comment: e.options?.comment
|
|
117
|
-
})));
|
|
118
|
-
return createZip(entries, {
|
|
119
|
-
level: this._options.level,
|
|
120
|
-
timestamps: this._options.timestamps,
|
|
121
|
-
modTime: this._options.modTime,
|
|
122
|
-
comment: this._options.comment,
|
|
123
|
-
smartStore: this._options.smartStore
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
return collect(this.stream());
|
|
127
|
-
}
|
|
128
|
-
bytesSync() {
|
|
129
|
-
this._sealed = true;
|
|
130
|
-
const entries = this._entries.map(e => {
|
|
131
|
-
if (!(e.source instanceof Uint8Array) &&
|
|
132
|
-
!(e.source instanceof ArrayBuffer) &&
|
|
133
|
-
typeof e.source !== "string") {
|
|
134
|
-
throw new Error("bytesSync() only supports Uint8Array/ArrayBuffer/string sources");
|
|
135
|
-
}
|
|
136
|
-
return {
|
|
137
|
-
name: e.name,
|
|
138
|
-
data: toUint8ArraySync(e.source),
|
|
139
|
-
modTime: e.options?.modTime,
|
|
140
|
-
comment: e.options?.comment
|
|
141
|
-
};
|
|
142
|
-
});
|
|
143
|
-
return createZipSync(entries, {
|
|
144
|
-
level: this._options.level,
|
|
145
|
-
timestamps: this._options.timestamps,
|
|
146
|
-
modTime: this._options.modTime,
|
|
147
|
-
comment: this._options.comment,
|
|
148
|
-
smartStore: this._options.smartStore
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
async pipeTo(sink) {
|
|
152
|
-
await pipeIterableToSink(this.stream(), sink);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
export function zip(options) {
|
|
156
|
-
return new ZipArchive(options);
|
|
157
|
-
}
|
|
@@ -1,239 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ZIP file format encoder (single-buffer output)
|
|
3
|
-
*
|
|
4
|
-
* Implements ZIP file structure according to PKWARE's APPNOTE.TXT specification
|
|
5
|
-
* https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
|
|
6
|
-
*
|
|
7
|
-
* This module focuses on producing a complete ZIP as a single Uint8Array.
|
|
8
|
-
* For true streaming (push chunks while reading sources), use `zip()` / `ZipArchive.stream()`.
|
|
9
|
-
*/
|
|
10
|
-
import { compress, compressSync } from "../compression/compress.js";
|
|
11
|
-
import { crc32 } from "../compression/crc32.js";
|
|
12
|
-
import { DEFAULT_ZIP_LEVEL, DEFAULT_ZIP_TIMESTAMPS } from "../defaults.js";
|
|
13
|
-
import { isProbablyIncompressible } from "../utils/compressibility.js";
|
|
14
|
-
import { encodeUtf8 } from "../utils/text.js";
|
|
15
|
-
import {} from "../utils/timestamps.js";
|
|
16
|
-
import { buildZipEntryMetadata, resolveZipCompressionMethod } from "./zip-entry-metadata.js";
|
|
17
|
-
import { FLAG_UTF8, ZIP_CENTRAL_DIR_HEADER_FIXED_SIZE, ZIP_END_OF_CENTRAL_DIR_FIXED_SIZE, ZIP_LOCAL_FILE_HEADER_FIXED_SIZE, writeCentralDirectoryHeaderInto, writeEndOfCentralDirectoryInto, writeLocalFileHeaderInto } from "../zip-spec/zip-records.js";
|
|
18
|
-
const REPRODUCIBLE_ZIP_MOD_TIME = new Date(1980, 0, 1, 0, 0, 0);
|
|
19
|
-
function encodeZipComment(comment) {
|
|
20
|
-
// Keep empty comment as empty bytes (no encoding surprises).
|
|
21
|
-
return comment ? encodeUtf8(comment) : new Uint8Array(0);
|
|
22
|
-
}
|
|
23
|
-
function shouldDeflate(level, data) {
|
|
24
|
-
return level > 0 && data.length > 0;
|
|
25
|
-
}
|
|
26
|
-
async function compressEntryMaybe(entry, level, compressOptions, smartStore) {
|
|
27
|
-
if (!shouldDeflate(level, entry.data)) {
|
|
28
|
-
return { compressedData: entry.data, deflate: false };
|
|
29
|
-
}
|
|
30
|
-
if (!smartStore) {
|
|
31
|
-
const compressed = await compress(entry.data, compressOptions);
|
|
32
|
-
return { compressedData: compressed, deflate: true };
|
|
33
|
-
}
|
|
34
|
-
// Heuristic: skip deflate for high-entropy inputs.
|
|
35
|
-
if (isProbablyIncompressible(entry.data)) {
|
|
36
|
-
return { compressedData: entry.data, deflate: false };
|
|
37
|
-
}
|
|
38
|
-
const compressed = await compress(entry.data, compressOptions);
|
|
39
|
-
if (compressed.length >= entry.data.length) {
|
|
40
|
-
return { compressedData: entry.data, deflate: false };
|
|
41
|
-
}
|
|
42
|
-
return { compressedData: compressed, deflate: true };
|
|
43
|
-
}
|
|
44
|
-
function compressEntryMaybeSync(entry, level, compressOptions, smartStore) {
|
|
45
|
-
if (!shouldDeflate(level, entry.data)) {
|
|
46
|
-
return { compressedData: entry.data, deflate: false };
|
|
47
|
-
}
|
|
48
|
-
if (!smartStore) {
|
|
49
|
-
const compressed = compressSync(entry.data, compressOptions);
|
|
50
|
-
return { compressedData: compressed, deflate: true };
|
|
51
|
-
}
|
|
52
|
-
if (isProbablyIncompressible(entry.data)) {
|
|
53
|
-
return { compressedData: entry.data, deflate: false };
|
|
54
|
-
}
|
|
55
|
-
const compressed = compressSync(entry.data, compressOptions);
|
|
56
|
-
if (compressed.length >= entry.data.length) {
|
|
57
|
-
return { compressedData: entry.data, deflate: false };
|
|
58
|
-
}
|
|
59
|
-
return { compressedData: compressed, deflate: true };
|
|
60
|
-
}
|
|
61
|
-
function computeLocalRecordSize(entry) {
|
|
62
|
-
return (ZIP_LOCAL_FILE_HEADER_FIXED_SIZE +
|
|
63
|
-
entry.name.length +
|
|
64
|
-
entry.extraField.length +
|
|
65
|
-
entry.compressedData.length);
|
|
66
|
-
}
|
|
67
|
-
function computeCentralDirHeaderSize(entry) {
|
|
68
|
-
return (ZIP_CENTRAL_DIR_HEADER_FIXED_SIZE +
|
|
69
|
-
entry.name.length +
|
|
70
|
-
entry.extraField.length +
|
|
71
|
-
entry.comment.length);
|
|
72
|
-
}
|
|
73
|
-
function buildProcessedEntry(entry, offset, settings, compressedData, deflate) {
|
|
74
|
-
const modDate = entry.modTime ?? settings.defaultModTime;
|
|
75
|
-
const metadata = buildZipEntryMetadata({
|
|
76
|
-
name: entry.name,
|
|
77
|
-
comment: entry.comment,
|
|
78
|
-
modTime: modDate,
|
|
79
|
-
timestamps: settings.timestamps,
|
|
80
|
-
useDataDescriptor: false,
|
|
81
|
-
deflate
|
|
82
|
-
});
|
|
83
|
-
return {
|
|
84
|
-
name: metadata.nameBytes,
|
|
85
|
-
uncompressedSize: entry.data.length,
|
|
86
|
-
compressedData,
|
|
87
|
-
crc: crc32(entry.data),
|
|
88
|
-
compressionMethod: resolveZipCompressionMethod(deflate),
|
|
89
|
-
modTime: metadata.dosTime,
|
|
90
|
-
modDate: metadata.dosDate,
|
|
91
|
-
extraField: metadata.extraField,
|
|
92
|
-
comment: metadata.commentBytes,
|
|
93
|
-
offset
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
function appendProcessedEntry(processedEntries, entry, compressedData, deflate, currentOffset, settings) {
|
|
97
|
-
const processedEntry = buildProcessedEntry(entry, currentOffset, settings, compressedData, deflate);
|
|
98
|
-
processedEntries.push(processedEntry);
|
|
99
|
-
return {
|
|
100
|
-
processedEntry,
|
|
101
|
-
nextOffset: currentOffset + computeLocalRecordSize(processedEntry)
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
function finalizeZip(processedEntries, zipComment) {
|
|
105
|
-
// Assemble ZIP into a single buffer to reduce allocations and copying.
|
|
106
|
-
let localSectionSize = 0;
|
|
107
|
-
let centralDirSize = 0;
|
|
108
|
-
for (const entry of processedEntries) {
|
|
109
|
-
localSectionSize += computeLocalRecordSize(entry);
|
|
110
|
-
centralDirSize += computeCentralDirHeaderSize(entry);
|
|
111
|
-
}
|
|
112
|
-
// The central directory should start immediately after local section.
|
|
113
|
-
const centralDirOffset = localSectionSize;
|
|
114
|
-
const totalSize = localSectionSize + centralDirSize + ZIP_END_OF_CENTRAL_DIR_FIXED_SIZE + zipComment.length;
|
|
115
|
-
const out = new Uint8Array(totalSize);
|
|
116
|
-
const view = new DataView(out.buffer, out.byteOffset, out.byteLength);
|
|
117
|
-
let offset = 0;
|
|
118
|
-
// Local file headers and data
|
|
119
|
-
for (const entry of processedEntries) {
|
|
120
|
-
offset += writeLocalFileHeaderInto(out, view, offset, {
|
|
121
|
-
fileName: entry.name,
|
|
122
|
-
extraField: entry.extraField,
|
|
123
|
-
flags: FLAG_UTF8,
|
|
124
|
-
compressionMethod: entry.compressionMethod,
|
|
125
|
-
dosTime: entry.modTime,
|
|
126
|
-
dosDate: entry.modDate,
|
|
127
|
-
crc32: entry.crc,
|
|
128
|
-
compressedSize: entry.compressedData.length,
|
|
129
|
-
uncompressedSize: entry.uncompressedSize
|
|
130
|
-
});
|
|
131
|
-
out.set(entry.compressedData, offset);
|
|
132
|
-
offset += entry.compressedData.length;
|
|
133
|
-
}
|
|
134
|
-
// Central directory headers
|
|
135
|
-
for (const entry of processedEntries) {
|
|
136
|
-
offset += writeCentralDirectoryHeaderInto(out, view, offset, {
|
|
137
|
-
fileName: entry.name,
|
|
138
|
-
extraField: entry.extraField,
|
|
139
|
-
comment: entry.comment,
|
|
140
|
-
flags: FLAG_UTF8,
|
|
141
|
-
compressionMethod: entry.compressionMethod,
|
|
142
|
-
dosTime: entry.modTime,
|
|
143
|
-
dosDate: entry.modDate,
|
|
144
|
-
crc32: entry.crc,
|
|
145
|
-
compressedSize: entry.compressedData.length,
|
|
146
|
-
uncompressedSize: entry.uncompressedSize,
|
|
147
|
-
localHeaderOffset: entry.offset
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
// End of central directory
|
|
151
|
-
writeEndOfCentralDirectoryInto(out, view, offset, {
|
|
152
|
-
entryCount: processedEntries.length,
|
|
153
|
-
centralDirSize,
|
|
154
|
-
centralDirOffset,
|
|
155
|
-
comment: zipComment
|
|
156
|
-
});
|
|
157
|
-
return out;
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* Create a ZIP file from entries (async)
|
|
161
|
-
*/
|
|
162
|
-
export async function createZip(entries, options = {}) {
|
|
163
|
-
const reproducible = options.reproducible ?? false;
|
|
164
|
-
const level = options.level ?? DEFAULT_ZIP_LEVEL;
|
|
165
|
-
const smartStore = options.smartStore ?? true;
|
|
166
|
-
const concurrency = options.concurrency ?? 4;
|
|
167
|
-
const timestamps = options.timestamps ?? (reproducible ? "dos" : DEFAULT_ZIP_TIMESTAMPS);
|
|
168
|
-
const zipComment = encodeZipComment(options.comment);
|
|
169
|
-
const defaultModTime = options.modTime ?? (reproducible ? REPRODUCIBLE_ZIP_MOD_TIME : new Date());
|
|
170
|
-
const settings = {
|
|
171
|
-
level,
|
|
172
|
-
timestamps,
|
|
173
|
-
defaultModTime
|
|
174
|
-
};
|
|
175
|
-
const thresholdBytes = options.thresholdBytes;
|
|
176
|
-
const limit = Math.max(1, Math.floor(concurrency));
|
|
177
|
-
const processedEntries = new Array(entries.length);
|
|
178
|
-
if (entries.length > 0) {
|
|
179
|
-
let nextIndex = 0;
|
|
180
|
-
const workerCount = Math.min(limit, entries.length);
|
|
181
|
-
const workers = Array.from({ length: workerCount }, async () => {
|
|
182
|
-
while (true) {
|
|
183
|
-
const idx = nextIndex++;
|
|
184
|
-
if (idx >= entries.length) {
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
const entry = entries[idx];
|
|
188
|
-
const entryLevel = entry.level ?? level;
|
|
189
|
-
const compressOptions = {
|
|
190
|
-
level: entryLevel,
|
|
191
|
-
thresholdBytes
|
|
192
|
-
};
|
|
193
|
-
const { compressedData, deflate } = await compressEntryMaybe(entry, entryLevel, compressOptions, smartStore);
|
|
194
|
-
processedEntries[idx] = buildProcessedEntry(entry, 0, settings, compressedData, deflate);
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
await Promise.all(workers);
|
|
198
|
-
}
|
|
199
|
-
// Compute offsets in original order.
|
|
200
|
-
let currentOffset = 0;
|
|
201
|
-
for (let i = 0; i < processedEntries.length; i++) {
|
|
202
|
-
const processedEntry = processedEntries[i];
|
|
203
|
-
processedEntry.offset = currentOffset;
|
|
204
|
-
currentOffset += computeLocalRecordSize(processedEntry);
|
|
205
|
-
}
|
|
206
|
-
return finalizeZip(processedEntries, zipComment);
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* Create a ZIP file from entries (sync)
|
|
210
|
-
*
|
|
211
|
-
* This is supported in both Node.js and browser builds.
|
|
212
|
-
*/
|
|
213
|
-
export function createZipSync(entries, options = {}) {
|
|
214
|
-
const reproducible = options.reproducible ?? false;
|
|
215
|
-
const level = options.level ?? DEFAULT_ZIP_LEVEL;
|
|
216
|
-
const smartStore = options.smartStore ?? true;
|
|
217
|
-
const timestamps = options.timestamps ?? (reproducible ? "dos" : DEFAULT_ZIP_TIMESTAMPS);
|
|
218
|
-
const zipComment = encodeZipComment(options.comment);
|
|
219
|
-
const defaultModTime = options.modTime ?? (reproducible ? REPRODUCIBLE_ZIP_MOD_TIME : new Date());
|
|
220
|
-
const settings = {
|
|
221
|
-
level,
|
|
222
|
-
timestamps,
|
|
223
|
-
defaultModTime
|
|
224
|
-
};
|
|
225
|
-
const thresholdBytes = options.thresholdBytes;
|
|
226
|
-
const processedEntries = [];
|
|
227
|
-
let currentOffset = 0;
|
|
228
|
-
for (const entry of entries) {
|
|
229
|
-
const entryLevel = entry.level ?? level;
|
|
230
|
-
const compressOptions = {
|
|
231
|
-
level: entryLevel,
|
|
232
|
-
thresholdBytes
|
|
233
|
-
};
|
|
234
|
-
const { compressedData, deflate } = compressEntryMaybeSync(entry, entryLevel, compressOptions, smartStore);
|
|
235
|
-
const result = appendProcessedEntry(processedEntries, entry, compressedData, deflate, currentOffset, settings);
|
|
236
|
-
currentOffset = result.nextOffset;
|
|
237
|
-
}
|
|
238
|
-
return finalizeZip(processedEntries, zipComment);
|
|
239
|
-
}
|