@xlsxflow/core 1.1.5 → 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/README.md +27 -7
- package/dist/index.cjs +21 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +21 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -3
package/dist/index.mjs
CHANGED
|
@@ -11,6 +11,15 @@ const CRC_TABLE = (() => {
|
|
|
11
11
|
function crc32(bytes) {
|
|
12
12
|
return (crc32Update(0xffffffff, bytes) ^ 0xffffffff) >>> 0;
|
|
13
13
|
}
|
|
14
|
+
// Older runtimes lack CompressionStream or its 'deflate-raw' format; say what is needed instead of a bare ReferenceError
|
|
15
|
+
function deflateRaw(kind) {
|
|
16
|
+
try {
|
|
17
|
+
return (kind === 'compress' ? new CompressionStream('deflate-raw') : new DecompressionStream('deflate-raw'));
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
throw new Error(`XlsxFlow needs ${kind === 'compress' ? 'CompressionStream' : 'DecompressionStream'} with 'deflate-raw': Chrome 103+, Firefox 113+, Safari 16.4+, Node 20.12+, Deno, Bun or Cloudflare Workers`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
14
23
|
// Running CRC-32 over chunks: start at 0xffffffff, finish with (crc ^ 0xffffffff) >>> 0
|
|
15
24
|
function crc32Update(crc, bytes) {
|
|
16
25
|
for (let i = 0; i < bytes.length; i++)
|
|
@@ -56,13 +65,15 @@ class ZipStreamWriter {
|
|
|
56
65
|
// Stream data, tracking sizes and CRC32
|
|
57
66
|
let uncompressedSize = 0;
|
|
58
67
|
let crc = 0xffffffff;
|
|
59
|
-
const compressor =
|
|
68
|
+
const compressor = deflateRaw('compress');
|
|
60
69
|
const writer = compressor.writable.getWriter();
|
|
61
70
|
const reader = compressor.readable.getReader();
|
|
62
71
|
const input = inputStream.getReader();
|
|
63
|
-
// Node's and Bun's CompressionStream accept thousands of writes without backpressure, so
|
|
64
|
-
//
|
|
72
|
+
// Node's and Bun's CompressionStream accept thousands of writes without backpressure, so only a few
|
|
73
|
+
// chunks are fed ahead: a write resolves once the chunk is compressed, which waits while nobody reads
|
|
65
74
|
// the output. Rows are then only pulled as fast as the ZIP is consumed.
|
|
75
|
+
// A few writes in flight keep the compressor busy while the next chunk is built
|
|
76
|
+
const inFlight = [];
|
|
66
77
|
const feed = (async () => {
|
|
67
78
|
try {
|
|
68
79
|
while (true) {
|
|
@@ -72,8 +83,13 @@ class ZipStreamWriter {
|
|
|
72
83
|
await this.roomInQueue();
|
|
73
84
|
uncompressedSize += value.length;
|
|
74
85
|
crc = crc32Update(crc, value);
|
|
75
|
-
|
|
86
|
+
const written = writer.write(value);
|
|
87
|
+
written.catch(() => { }); // after a failure, writes nobody awaits any more must not go unhandled
|
|
88
|
+
inFlight.push(written);
|
|
89
|
+
if (inFlight.length >= 4)
|
|
90
|
+
await inFlight.shift();
|
|
76
91
|
}
|
|
92
|
+
await Promise.all(inFlight);
|
|
77
93
|
await writer.close();
|
|
78
94
|
}
|
|
79
95
|
catch (err) {
|
|
@@ -496,7 +512,7 @@ class ZipRandomAccessParser {
|
|
|
496
512
|
}
|
|
497
513
|
const stream = await this.extractRawStream(filename);
|
|
498
514
|
const data = record.compressionMethod === 0 ? stream
|
|
499
|
-
: stream.pipeThrough(
|
|
515
|
+
: stream.pipeThrough(deflateRaw('decompress'));
|
|
500
516
|
// Node reports bad deflate data as a bare TypeError; name the entry instead
|
|
501
517
|
const inflated = data.getReader();
|
|
502
518
|
let total = 0;
|