@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,12 +1,14 @@
|
|
|
1
1
|
import zlib from "zlib";
|
|
2
|
-
import {
|
|
2
|
+
import { writeUint32LE } from "./utils/binary.js";
|
|
3
|
+
import { PullStream, runParseLoop, streamUntilValidatedDataDescriptor } from "./parse.base.js";
|
|
4
|
+
import { DATA_DESCRIPTOR_SIG } from "./zip-constants.js";
|
|
3
5
|
/**
|
|
4
6
|
* Creates an InflateRaw stream using Node.js native zlib.
|
|
5
7
|
*/
|
|
6
8
|
function createInflateRaw() {
|
|
7
9
|
return zlib.createInflateRaw();
|
|
8
10
|
}
|
|
9
|
-
const dataDescriptorSignature =
|
|
11
|
+
const dataDescriptorSignature = writeUint32LE(DATA_DESCRIPTOR_SIG);
|
|
10
12
|
export function createParseClass(createInflateRawFn) {
|
|
11
13
|
return class Parse extends PullStream {
|
|
12
14
|
constructor(opts = {}) {
|
|
@@ -61,12 +63,9 @@ export function createParseClass(createInflateRawFn) {
|
|
|
61
63
|
_streamUntilValidatedDataDescriptor() {
|
|
62
64
|
return streamUntilValidatedDataDescriptor({
|
|
63
65
|
source: {
|
|
66
|
+
getView: () => this._queue.view(),
|
|
64
67
|
getLength: () => this._queue.length,
|
|
65
68
|
read: (length) => this._queue.read(length),
|
|
66
|
-
peekChunks: (length) => this._queue.peekChunks(length),
|
|
67
|
-
discard: (length) => this._queue.discard(length),
|
|
68
|
-
indexOfPattern: (pattern, startIndex) => this._queue.indexOfPattern(pattern, startIndex),
|
|
69
|
-
peekUint32LE: (offset) => this._queue.peekUint32LE(offset),
|
|
70
69
|
isFinished: () => this.finished,
|
|
71
70
|
onDataAvailable: (cb) => {
|
|
72
71
|
this.on("chunk", cb);
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
*
|
|
7
7
|
* API compatible with Node.js version - supports .on("data"), .on("end"), .write(callback), .end()
|
|
8
8
|
*/
|
|
9
|
-
export type {
|
|
10
|
-
import { type DeflateStream, type InflateStream, type StreamCompressOptions } from "@archive/
|
|
9
|
+
export type { StreamCompressOptions } from "@archive/streaming-compress.base";
|
|
10
|
+
import { type DeflateStream, type InflateStream, type StreamCompressOptions } from "@archive/streaming-compress.base";
|
|
11
11
|
/**
|
|
12
12
|
* Check if deflate-raw streaming compression is supported by this library.
|
|
13
13
|
*
|
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
*
|
|
7
7
|
* API compatible with Node.js version - supports .on("data"), .on("end"), .write(callback), .end()
|
|
8
8
|
*/
|
|
9
|
-
import { EventEmitter } from "
|
|
9
|
+
import { EventEmitter } from "../stream/index.browser.js";
|
|
10
10
|
import { deflateRawCompressed, inflateRaw } from "./deflate-fallback.js";
|
|
11
11
|
import { hasDeflateRawWebStreams } from "./compress.base.js";
|
|
12
|
-
import { concatUint8Arrays } from "
|
|
13
|
-
import { DEFAULT_COMPRESS_LEVEL } from "
|
|
12
|
+
import { concatUint8Arrays } from "./utils/bytes.js";
|
|
13
|
+
import { DEFAULT_COMPRESS_LEVEL } from "./defaults.js";
|
|
14
14
|
import { asError } from "./streaming-compress.base.js";
|
|
15
15
|
/**
|
|
16
16
|
* Check if deflate-raw streaming compression is supported by this library.
|
package/dist/browser/modules/archive/{compression/streaming-compress.d.ts → streaming-compress.d.ts}
RENAMED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Uses zlib.createDeflateRaw() with explicit flush() calls for real chunk-by-chunk streaming.
|
|
5
5
|
* Each write() immediately produces compressed output without waiting for end().
|
|
6
6
|
*/
|
|
7
|
-
export type { DeflateStream, InflateStream, StreamCompressOptions, StreamingCodec } from "@archive/
|
|
8
|
-
import type { DeflateStream, InflateStream, StreamCompressOptions } from "@archive/
|
|
7
|
+
export type { DeflateStream, InflateStream, StreamCompressOptions, StreamingCodec } from "@archive/streaming-compress.base";
|
|
8
|
+
import type { DeflateStream, InflateStream, StreamCompressOptions } from "@archive/streaming-compress.base";
|
|
9
9
|
/**
|
|
10
10
|
* Create a true streaming DEFLATE compressor
|
|
11
11
|
* Returns a Transform stream that emits compressed data immediately after each write
|
package/dist/browser/modules/archive/{compression/streaming-compress.js → streaming-compress.js}
RENAMED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* Each write() immediately produces compressed output without waiting for end().
|
|
6
6
|
*/
|
|
7
7
|
import { createDeflateRaw, createInflateRaw, constants } from "zlib";
|
|
8
|
-
import { Transform } from "
|
|
9
|
-
import { DEFAULT_COMPRESS_LEVEL } from "
|
|
8
|
+
import { Transform } from "../stream/index.browser.js";
|
|
9
|
+
import { DEFAULT_COMPRESS_LEVEL } from "./defaults.js";
|
|
10
10
|
/**
|
|
11
11
|
* Wrapper around zlib DeflateRaw that flushes after every write
|
|
12
12
|
* This ensures true streaming behavior - data is emitted immediately, not buffered
|
|
@@ -2,18 +2,17 @@
|
|
|
2
2
|
* True Streaming ZIP creator - shared implementation.
|
|
3
3
|
*
|
|
4
4
|
* This module is intentionally platform-agnostic.
|
|
5
|
-
* - In Node builds it uses `./
|
|
5
|
+
* - In Node builds it uses `./crc32` + `./streaming-compress` (zlib-backed).
|
|
6
6
|
* - In browser builds the bundler aliases those imports to their browser variants.
|
|
7
7
|
*/
|
|
8
8
|
import type { ZipTimestampMode } from "@archive/utils/timestamps";
|
|
9
|
-
import type { ZipEntryInfo as UnzipZipEntryInfo } from "@archive/zip-
|
|
9
|
+
import type { ZipEntryInfo as UnzipZipEntryInfo } from "@archive/zip-entry-info";
|
|
10
10
|
/**
|
|
11
11
|
* Internal entry info for central directory
|
|
12
12
|
*/
|
|
13
13
|
interface ZipEntryInfo {
|
|
14
14
|
name: Uint8Array;
|
|
15
15
|
extraField: Uint8Array;
|
|
16
|
-
comment: Uint8Array;
|
|
17
16
|
flags: number;
|
|
18
17
|
crc: number;
|
|
19
18
|
compressedSize: number;
|
|
@@ -35,62 +34,43 @@ export declare class ZipDeflateFile {
|
|
|
35
34
|
private _finalized;
|
|
36
35
|
private _headerEmitted;
|
|
37
36
|
private _ondata;
|
|
38
|
-
private _onerror;
|
|
39
37
|
private _centralDirEntryInfo;
|
|
40
38
|
private _pendingEnd;
|
|
41
39
|
private _emittedDataDescriptor;
|
|
42
40
|
private _localHeader;
|
|
43
|
-
private _deflateWanted;
|
|
44
|
-
private _pendingChunks;
|
|
45
|
-
private _sampleBuffer;
|
|
46
|
-
private _sampleLen;
|
|
47
|
-
private _smartStore;
|
|
48
41
|
private _completeResolve;
|
|
49
42
|
private _completeReject;
|
|
50
43
|
private _completePromise;
|
|
51
44
|
private _completeError;
|
|
52
45
|
private _dataQueue;
|
|
53
46
|
private _finalQueued;
|
|
54
|
-
private _pushChain;
|
|
55
47
|
readonly name: string;
|
|
56
48
|
readonly level: number;
|
|
57
49
|
readonly nameBytes: Uint8Array;
|
|
58
|
-
readonly commentBytes: Uint8Array;
|
|
59
50
|
readonly dosTime: number;
|
|
60
51
|
readonly dosDate: number;
|
|
61
52
|
readonly extraField: Uint8Array;
|
|
62
53
|
private readonly _flags;
|
|
63
|
-
private _compressionMethod;
|
|
54
|
+
private readonly _compressionMethod;
|
|
64
55
|
private readonly _modTime;
|
|
65
56
|
constructor(name: string, options?: {
|
|
66
57
|
level?: number;
|
|
67
58
|
modTime?: Date;
|
|
68
59
|
timestamps?: ZipTimestampMode;
|
|
69
|
-
comment?: string;
|
|
70
|
-
smartStore?: boolean;
|
|
71
60
|
});
|
|
72
|
-
private _buildCompressionMethod;
|
|
73
|
-
private _initDeflateStream;
|
|
74
61
|
private _buildLocalHeader;
|
|
75
|
-
private _accumulateSample;
|
|
76
|
-
private _shouldDecide;
|
|
77
|
-
private _decideCompressionIfNeeded;
|
|
78
|
-
private _emitHeaderIfNeeded;
|
|
79
|
-
private _flushPendingChunks;
|
|
80
62
|
private _enqueueData;
|
|
81
63
|
private _flushQueue;
|
|
82
64
|
get ondata(): ((data: Uint8Array, final: boolean) => void) | undefined;
|
|
83
65
|
set ondata(cb: (data: Uint8Array, final: boolean) => void);
|
|
84
|
-
get onerror(): ((err: Error) => void) | undefined;
|
|
85
|
-
set onerror(cb: (err: Error) => void);
|
|
86
66
|
private _resolveComplete;
|
|
87
67
|
private _rejectComplete;
|
|
88
68
|
private _ensureCompletePromise;
|
|
89
69
|
private _tapCallback;
|
|
70
|
+
private _emitHeaderIfNeeded;
|
|
90
71
|
private _writeData;
|
|
91
72
|
private _endDeflateAndWait;
|
|
92
73
|
private _finalizeAfterWrite;
|
|
93
|
-
private _pushUnchained;
|
|
94
74
|
/**
|
|
95
75
|
* Push data - immediately compresses and outputs
|
|
96
76
|
* Returns a Promise that resolves when the write is complete.
|
|
@@ -128,13 +108,10 @@ export declare class StreamingZip {
|
|
|
128
108
|
private currentOffset;
|
|
129
109
|
private ended;
|
|
130
110
|
private endPending;
|
|
131
|
-
private zipComment;
|
|
132
111
|
private fileQueue;
|
|
133
112
|
private fileQueueIndex;
|
|
134
113
|
private activeFile;
|
|
135
|
-
constructor(callback: (err: Error | null, data: Uint8Array, final: boolean) => void
|
|
136
|
-
comment?: string;
|
|
137
|
-
});
|
|
114
|
+
constructor(callback: (err: Error | null, data: Uint8Array, final: boolean) => void);
|
|
138
115
|
add(file: ZipDeflateFile): void;
|
|
139
116
|
private _processNextFile;
|
|
140
117
|
private _finalize;
|
|
@@ -2,16 +2,15 @@
|
|
|
2
2
|
* True Streaming ZIP creator - shared implementation.
|
|
3
3
|
*
|
|
4
4
|
* This module is intentionally platform-agnostic.
|
|
5
|
-
* - In Node builds it uses `./
|
|
5
|
+
* - In Node builds it uses `./crc32` + `./streaming-compress` (zlib-backed).
|
|
6
6
|
* - In browser builds the bundler aliases those imports to their browser variants.
|
|
7
7
|
*/
|
|
8
|
-
import { crc32Update, crc32Finalize } from "
|
|
9
|
-
import { createDeflateStream } from "
|
|
10
|
-
import { DEFAULT_ZIP_LEVEL, DEFAULT_ZIP_TIMESTAMPS } from "
|
|
11
|
-
import { buildZipEntryMetadata
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { buildCentralDirectoryHeader, buildDataDescriptor, buildEndOfCentralDirectory, buildLocalFileHeader, VERSION_MADE_BY, VERSION_NEEDED } from "../zip-spec/zip-records.js";
|
|
8
|
+
import { crc32Update, crc32Finalize } from "./crc32.browser.js";
|
|
9
|
+
import { createDeflateStream } from "./streaming-compress.browser.js";
|
|
10
|
+
import { DEFAULT_ZIP_LEVEL, DEFAULT_ZIP_TIMESTAMPS } from "./defaults.js";
|
|
11
|
+
import { buildZipEntryMetadata } from "./zip-entry-metadata.js";
|
|
12
|
+
import { buildCentralDirectoryHeader, buildDataDescriptor, buildEndOfCentralDirectory, buildLocalFileHeader } from "./zip-records.js";
|
|
13
|
+
import { VERSION_MADE_BY, VERSION_NEEDED } from "./zip-constants.js";
|
|
15
14
|
/**
|
|
16
15
|
* True Streaming ZIP File - compresses chunk by chunk
|
|
17
16
|
*/
|
|
@@ -24,15 +23,9 @@ export class ZipDeflateFile {
|
|
|
24
23
|
this._finalized = false;
|
|
25
24
|
this._headerEmitted = false;
|
|
26
25
|
this._ondata = null;
|
|
27
|
-
this._onerror = null;
|
|
28
26
|
this._centralDirEntryInfo = null;
|
|
29
27
|
this._pendingEnd = false;
|
|
30
28
|
this._emittedDataDescriptor = false;
|
|
31
|
-
this._localHeader = null;
|
|
32
|
-
// Smart STORE: delay method selection until we sample data.
|
|
33
|
-
this._deflateWanted = null;
|
|
34
|
-
this._pendingChunks = [];
|
|
35
|
-
this._sampleLen = 0;
|
|
36
29
|
// Promise resolution for completion (including data descriptor)
|
|
37
30
|
this._completeResolve = null;
|
|
38
31
|
this._completeReject = null;
|
|
@@ -41,70 +34,46 @@ export class ZipDeflateFile {
|
|
|
41
34
|
// Queue for incoming data before ondata is set
|
|
42
35
|
this._dataQueue = [];
|
|
43
36
|
this._finalQueued = false;
|
|
44
|
-
// Serialize push() calls so callers don't need to await to preserve ordering.
|
|
45
|
-
this._pushChain = Promise.resolve();
|
|
46
37
|
this.name = name;
|
|
47
38
|
const modTime = options?.modTime ?? new Date();
|
|
48
39
|
this._modTime = modTime;
|
|
49
40
|
this.level = options?.level ?? DEFAULT_ZIP_LEVEL;
|
|
50
|
-
this._smartStore = options?.smartStore ?? true;
|
|
51
|
-
this._sampleBuffer = this._smartStore ? new Uint8Array(64 * 1024) : new Uint8Array(0);
|
|
52
41
|
const metadata = buildZipEntryMetadata({
|
|
53
42
|
name,
|
|
54
|
-
comment:
|
|
43
|
+
comment: "",
|
|
55
44
|
modTime,
|
|
56
45
|
timestamps: options?.timestamps ?? DEFAULT_ZIP_TIMESTAMPS,
|
|
57
46
|
useDataDescriptor: true,
|
|
58
|
-
deflate:
|
|
47
|
+
deflate: this.level > 0
|
|
59
48
|
});
|
|
60
49
|
this.nameBytes = metadata.nameBytes;
|
|
61
|
-
this.commentBytes = metadata.commentBytes;
|
|
62
50
|
this.dosTime = metadata.dosTime;
|
|
63
51
|
this.dosDate = metadata.dosDate;
|
|
64
52
|
this.extraField = metadata.extraField;
|
|
65
53
|
this._flags = metadata.flags;
|
|
66
54
|
this._compressionMethod = metadata.compressionMethod;
|
|
67
|
-
//
|
|
68
|
-
if (
|
|
69
|
-
|
|
70
|
-
this.
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if (this._deflate) {
|
|
88
|
-
return;
|
|
55
|
+
// Create deflate stream for compression
|
|
56
|
+
if (this.level > 0) {
|
|
57
|
+
this._deflate = createDeflateStream({ level: this.level });
|
|
58
|
+
this._deflate.on("error", (err) => {
|
|
59
|
+
this._rejectComplete(err);
|
|
60
|
+
});
|
|
61
|
+
// Handle compressed output - this is true streaming!
|
|
62
|
+
this._deflate.on("data", (chunk) => {
|
|
63
|
+
this._compressedSize += chunk.length;
|
|
64
|
+
this._enqueueData(chunk, false);
|
|
65
|
+
});
|
|
66
|
+
// Handle end - emit data descriptor
|
|
67
|
+
// IMPORTANT: Only use 'end' event, NOT 'finish'!
|
|
68
|
+
// Node.js zlib emits events in order: finish -> data -> end
|
|
69
|
+
this._deflate.on("end", () => {
|
|
70
|
+
if (this._pendingEnd && !this._emittedDataDescriptor) {
|
|
71
|
+
this._emittedDataDescriptor = true;
|
|
72
|
+
this._emitDataDescriptor();
|
|
73
|
+
}
|
|
74
|
+
});
|
|
89
75
|
}
|
|
90
|
-
this.
|
|
91
|
-
this._deflate.on("error", (err) => {
|
|
92
|
-
this._rejectComplete(err);
|
|
93
|
-
});
|
|
94
|
-
// Handle compressed output - this is true streaming!
|
|
95
|
-
this._deflate.on("data", (chunk) => {
|
|
96
|
-
this._compressedSize += chunk.length;
|
|
97
|
-
this._enqueueData(chunk, false);
|
|
98
|
-
});
|
|
99
|
-
// Handle end - emit data descriptor
|
|
100
|
-
// IMPORTANT: Only use 'end' event, NOT 'finish'!
|
|
101
|
-
// Node.js zlib emits events in order: finish -> data -> end
|
|
102
|
-
this._deflate.on("end", () => {
|
|
103
|
-
if (this._pendingEnd && !this._emittedDataDescriptor) {
|
|
104
|
-
this._emittedDataDescriptor = true;
|
|
105
|
-
this._emitDataDescriptor();
|
|
106
|
-
}
|
|
107
|
-
});
|
|
76
|
+
this._localHeader = this._buildLocalHeader();
|
|
108
77
|
}
|
|
109
78
|
_buildLocalHeader() {
|
|
110
79
|
// CRC + sizes are written via data descriptor for true streaming.
|
|
@@ -121,63 +90,6 @@ export class ZipDeflateFile {
|
|
|
121
90
|
versionNeeded: VERSION_NEEDED
|
|
122
91
|
});
|
|
123
92
|
}
|
|
124
|
-
_accumulateSample(data) {
|
|
125
|
-
if (this._deflateWanted !== null) {
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
if (this._sampleLen >= this._sampleBuffer.length) {
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
const take = Math.min(this._sampleBuffer.length - this._sampleLen, data.length);
|
|
132
|
-
if (take <= 0) {
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
this._sampleBuffer.set(data.subarray(0, take), this._sampleLen);
|
|
136
|
-
this._sampleLen += take;
|
|
137
|
-
}
|
|
138
|
-
_shouldDecide(final) {
|
|
139
|
-
if (this._deflateWanted !== null) {
|
|
140
|
-
return false;
|
|
141
|
-
}
|
|
142
|
-
return final || this._sampleLen >= 16 * 1024;
|
|
143
|
-
}
|
|
144
|
-
_decideCompressionIfNeeded(final) {
|
|
145
|
-
if (this._deflateWanted !== null) {
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
// Match non-streaming builder semantics: empty files never need DEFLATE.
|
|
149
|
-
if (final && this._sampleLen === 0) {
|
|
150
|
-
this._deflateWanted = false;
|
|
151
|
-
this._compressionMethod = this._buildCompressionMethod(false);
|
|
152
|
-
this._localHeader = null;
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
// Default to DEFLATE unless heuristic says STORE.
|
|
156
|
-
const sample = this._sampleBuffer.subarray(0, this._sampleLen);
|
|
157
|
-
const store = isProbablyIncompressible(sample);
|
|
158
|
-
this._deflateWanted = !store;
|
|
159
|
-
this._compressionMethod = this._buildCompressionMethod(this._deflateWanted);
|
|
160
|
-
this._localHeader = null;
|
|
161
|
-
if (this._deflateWanted) {
|
|
162
|
-
this._initDeflateStream();
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
_emitHeaderIfNeeded() {
|
|
166
|
-
if (this._headerEmitted) {
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
this._emitHeader();
|
|
170
|
-
this._headerEmitted = true;
|
|
171
|
-
}
|
|
172
|
-
async _flushPendingChunks() {
|
|
173
|
-
if (this._pendingChunks.length === 0) {
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
for (const chunk of this._pendingChunks) {
|
|
177
|
-
await this._writeData(chunk);
|
|
178
|
-
}
|
|
179
|
-
this._pendingChunks = [];
|
|
180
|
-
}
|
|
181
93
|
_enqueueData(data, final) {
|
|
182
94
|
if (this._ondata) {
|
|
183
95
|
this._ondata(data, final);
|
|
@@ -209,29 +121,13 @@ export class ZipDeflateFile {
|
|
|
209
121
|
// Flush any queued data
|
|
210
122
|
this._flushQueue();
|
|
211
123
|
}
|
|
212
|
-
get onerror() {
|
|
213
|
-
return this._onerror ?? undefined;
|
|
214
|
-
}
|
|
215
|
-
set onerror(cb) {
|
|
216
|
-
this._onerror = cb;
|
|
217
|
-
// If an error already occurred, surface it immediately.
|
|
218
|
-
if (this._completeError) {
|
|
219
|
-
cb(this._completeError);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
124
|
_resolveComplete() {
|
|
223
125
|
if (this._completeResolve) {
|
|
224
126
|
this._completeResolve();
|
|
225
127
|
}
|
|
226
128
|
}
|
|
227
129
|
_rejectComplete(err) {
|
|
228
|
-
if (this._completeError) {
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
130
|
this._completeError = err;
|
|
232
|
-
if (this._onerror) {
|
|
233
|
-
this._onerror(err);
|
|
234
|
-
}
|
|
235
131
|
if (this._completeReject) {
|
|
236
132
|
this._completeReject(err);
|
|
237
133
|
}
|
|
@@ -257,6 +153,13 @@ export class ZipDeflateFile {
|
|
|
257
153
|
}
|
|
258
154
|
promise.then(() => callback()).catch(err => callback(err));
|
|
259
155
|
}
|
|
156
|
+
_emitHeaderIfNeeded() {
|
|
157
|
+
if (this._headerEmitted) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
this._emitHeader();
|
|
161
|
+
this._headerEmitted = true;
|
|
162
|
+
}
|
|
260
163
|
_writeData(data) {
|
|
261
164
|
if (data.length === 0) {
|
|
262
165
|
return Promise.resolve();
|
|
@@ -314,60 +217,27 @@ export class ZipDeflateFile {
|
|
|
314
217
|
this._emitDataDescriptor();
|
|
315
218
|
return completePromise;
|
|
316
219
|
}
|
|
317
|
-
|
|
220
|
+
/**
|
|
221
|
+
* Push data - immediately compresses and outputs
|
|
222
|
+
* Returns a Promise that resolves when the write is complete.
|
|
223
|
+
* If final=true, it resolves after the data descriptor is emitted.
|
|
224
|
+
*/
|
|
225
|
+
push(data, final = false, callback) {
|
|
318
226
|
if (this._finalized) {
|
|
319
227
|
const promise = Promise.reject(new Error("Cannot push to finalized ZipDeflateFile"));
|
|
320
228
|
this._tapCallback(promise, callback);
|
|
321
229
|
return promise;
|
|
322
230
|
}
|
|
323
|
-
if (this._deflateWanted === null) {
|
|
324
|
-
this._accumulateSample(data);
|
|
325
|
-
if (!this._shouldDecide(final)) {
|
|
326
|
-
if (data.length > 0) {
|
|
327
|
-
this._pendingChunks.push(data);
|
|
328
|
-
}
|
|
329
|
-
const promise = Promise.resolve();
|
|
330
|
-
this._tapCallback(promise, callback);
|
|
331
|
-
return promise;
|
|
332
|
-
}
|
|
333
|
-
this._decideCompressionIfNeeded(final);
|
|
334
|
-
this._emitHeaderIfNeeded();
|
|
335
|
-
const hadPendingChunks = this._pendingChunks.length > 0;
|
|
336
|
-
const flushPromise = this._flushPendingChunks();
|
|
337
|
-
let writePromise = flushPromise;
|
|
338
|
-
if (data.length > 0) {
|
|
339
|
-
writePromise = hadPendingChunks
|
|
340
|
-
? flushPromise.then(() => this._writeData(data))
|
|
341
|
-
: this._writeData(data);
|
|
342
|
-
}
|
|
343
|
-
const promise = final ? this._finalizeAfterWrite(writePromise) : writePromise;
|
|
344
|
-
this._tapCallback(promise, callback);
|
|
345
|
-
return promise;
|
|
346
|
-
}
|
|
347
231
|
this._emitHeaderIfNeeded();
|
|
348
232
|
const writePromise = this._writeData(data);
|
|
349
233
|
const promise = final ? this._finalizeAfterWrite(writePromise) : writePromise;
|
|
350
234
|
this._tapCallback(promise, callback);
|
|
351
235
|
return promise;
|
|
352
236
|
}
|
|
353
|
-
/**
|
|
354
|
-
* Push data - immediately compresses and outputs
|
|
355
|
-
* Returns a Promise that resolves when the write is complete.
|
|
356
|
-
* If final=true, it resolves after the data descriptor is emitted.
|
|
357
|
-
*/
|
|
358
|
-
push(data, final = false, callback) {
|
|
359
|
-
const promise = (this._pushChain = this._pushChain.then(() => this._pushUnchained(data, final, callback)));
|
|
360
|
-
// Prevent unhandled rejection when callers intentionally ignore the Promise.
|
|
361
|
-
promise.catch(() => { });
|
|
362
|
-
return promise;
|
|
363
|
-
}
|
|
364
237
|
/**
|
|
365
238
|
* Emit local file header with Data Descriptor flag
|
|
366
239
|
*/
|
|
367
240
|
_emitHeader() {
|
|
368
|
-
if (!this._localHeader) {
|
|
369
|
-
this._localHeader = this._buildLocalHeader();
|
|
370
|
-
}
|
|
371
241
|
this._enqueueData(this._localHeader, false);
|
|
372
242
|
}
|
|
373
243
|
/**
|
|
@@ -380,7 +250,6 @@ export class ZipDeflateFile {
|
|
|
380
250
|
this._centralDirEntryInfo = {
|
|
381
251
|
name: this.nameBytes,
|
|
382
252
|
extraField: this.extraField,
|
|
383
|
-
comment: this.commentBytes,
|
|
384
253
|
flags: this._flags,
|
|
385
254
|
crc: crcValue,
|
|
386
255
|
compressedSize: this._compressedSize,
|
|
@@ -419,7 +288,7 @@ export class ZipDeflateFile {
|
|
|
419
288
|
crc32: this._centralDirEntryInfo.crc,
|
|
420
289
|
lastModified: this._modTime,
|
|
421
290
|
localHeaderOffset: this._centralDirEntryInfo.offset,
|
|
422
|
-
comment:
|
|
291
|
+
comment: "",
|
|
423
292
|
externalAttributes: 0,
|
|
424
293
|
isEncrypted: false
|
|
425
294
|
};
|
|
@@ -436,7 +305,7 @@ export class ZipDeflateFile {
|
|
|
436
305
|
* Streaming ZIP Creator - processes files sequentially
|
|
437
306
|
*/
|
|
438
307
|
export class StreamingZip {
|
|
439
|
-
constructor(callback
|
|
308
|
+
constructor(callback) {
|
|
440
309
|
this.entries = [];
|
|
441
310
|
this.currentOffset = 0;
|
|
442
311
|
this.ended = false;
|
|
@@ -446,12 +315,10 @@ export class StreamingZip {
|
|
|
446
315
|
this.fileQueueIndex = 0;
|
|
447
316
|
this.activeFile = null;
|
|
448
317
|
this.callback = callback;
|
|
449
|
-
// Avoid per-instance TextEncoder allocations.
|
|
450
|
-
this.zipComment = options?.comment ? encodeUtf8(options.comment) : new Uint8Array(0);
|
|
451
318
|
}
|
|
452
319
|
add(file) {
|
|
453
320
|
if (this.ended) {
|
|
454
|
-
throw new Error("Cannot add files after calling end()
|
|
321
|
+
throw new Error("Cannot add files after calling end()");
|
|
455
322
|
}
|
|
456
323
|
this.fileQueue.push(file);
|
|
457
324
|
// If no active file, process this one
|
|
@@ -474,18 +341,7 @@ export class StreamingZip {
|
|
|
474
341
|
const file = this.fileQueue[this.fileQueueIndex++];
|
|
475
342
|
this.activeFile = file;
|
|
476
343
|
const startOffset = this.currentOffset;
|
|
477
|
-
const empty = new Uint8Array(0);
|
|
478
|
-
file.onerror = (err) => {
|
|
479
|
-
if (this.ended) {
|
|
480
|
-
return;
|
|
481
|
-
}
|
|
482
|
-
this.ended = true;
|
|
483
|
-
this.callback(err, empty, true);
|
|
484
|
-
};
|
|
485
344
|
file.ondata = (data, final) => {
|
|
486
|
-
if (this.ended) {
|
|
487
|
-
return;
|
|
488
|
-
}
|
|
489
345
|
this.currentOffset += data.length;
|
|
490
346
|
this.callback(null, data, false);
|
|
491
347
|
if (final) {
|
|
@@ -511,7 +367,7 @@ export class StreamingZip {
|
|
|
511
367
|
const header = buildCentralDirectoryHeader({
|
|
512
368
|
fileName: entry.name,
|
|
513
369
|
extraField: entry.extraField,
|
|
514
|
-
comment:
|
|
370
|
+
comment: empty,
|
|
515
371
|
flags: entry.flags,
|
|
516
372
|
compressionMethod: entry.compressionMethod,
|
|
517
373
|
dosTime: entry.dosTime,
|
|
@@ -530,7 +386,7 @@ export class StreamingZip {
|
|
|
530
386
|
entryCount: this.entries.length,
|
|
531
387
|
centralDirSize,
|
|
532
388
|
centralDirOffset,
|
|
533
|
-
comment:
|
|
389
|
+
comment: empty
|
|
534
390
|
});
|
|
535
391
|
this.callback(null, eocd, true);
|
|
536
392
|
}
|
|
@@ -45,18 +45,21 @@ export function indexOfUint8ArrayPattern(buffer, pattern, startIndex = 0) {
|
|
|
45
45
|
}
|
|
46
46
|
// Fast paths for small patterns (very common in ZIP parsing: 2/3/4-byte signatures).
|
|
47
47
|
if (patLen === 1) {
|
|
48
|
-
|
|
48
|
+
const p0 = pattern[0];
|
|
49
|
+
for (let i = start; i < bufLen; i++) {
|
|
50
|
+
if (buffer[i] === p0) {
|
|
51
|
+
return i;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return -1;
|
|
49
55
|
}
|
|
50
56
|
if (patLen === 2) {
|
|
51
57
|
const p0 = pattern[0];
|
|
52
58
|
const p1 = pattern[1];
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
while (i !== -1 && i <= last) {
|
|
56
|
-
if (buffer[i + 1] === p1) {
|
|
59
|
+
for (let i = start; i <= bufLen - 2; i++) {
|
|
60
|
+
if (buffer[i] === p0 && buffer[i + 1] === p1) {
|
|
57
61
|
return i;
|
|
58
62
|
}
|
|
59
|
-
i = buffer.indexOf(p0, i + 1);
|
|
60
63
|
}
|
|
61
64
|
return -1;
|
|
62
65
|
}
|
|
@@ -64,13 +67,10 @@ export function indexOfUint8ArrayPattern(buffer, pattern, startIndex = 0) {
|
|
|
64
67
|
const p0 = pattern[0];
|
|
65
68
|
const p1 = pattern[1];
|
|
66
69
|
const p2 = pattern[2];
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
while (i !== -1 && i <= last) {
|
|
70
|
-
if (buffer[i + 1] === p1 && buffer[i + 2] === p2) {
|
|
70
|
+
for (let i = start; i <= bufLen - 3; i++) {
|
|
71
|
+
if (buffer[i] === p0 && buffer[i + 1] === p1 && buffer[i + 2] === p2) {
|
|
71
72
|
return i;
|
|
72
73
|
}
|
|
73
|
-
i = buffer.indexOf(p0, i + 1);
|
|
74
74
|
}
|
|
75
75
|
return -1;
|
|
76
76
|
}
|
|
@@ -79,13 +79,13 @@ export function indexOfUint8ArrayPattern(buffer, pattern, startIndex = 0) {
|
|
|
79
79
|
const p1 = pattern[1];
|
|
80
80
|
const p2 = pattern[2];
|
|
81
81
|
const p3 = pattern[3];
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
for (let i = start; i <= bufLen - 4; i++) {
|
|
83
|
+
if (buffer[i] === p0 &&
|
|
84
|
+
buffer[i + 1] === p1 &&
|
|
85
|
+
buffer[i + 2] === p2 &&
|
|
86
|
+
buffer[i + 3] === p3) {
|
|
86
87
|
return i;
|
|
87
88
|
}
|
|
88
|
-
i = buffer.indexOf(p0, i + 1);
|
|
89
89
|
}
|
|
90
90
|
return -1;
|
|
91
91
|
}
|