@cj-tech-master/excelts 6.1.1 → 6.1.2

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.
@@ -28,10 +28,11 @@ export declare function inflateRaw(data: Uint8Array): Uint8Array;
28
28
  */
29
29
  export declare function deflateRawStore(data: Uint8Array): Uint8Array;
30
30
  /**
31
- * Compress data using DEFLATE with fixed Huffman codes
31
+ * Compress data using DEFLATE with fixed Huffman codes.
32
32
  *
33
- * This provides real compression using LZ77 + fixed Huffman codes.
34
- * Not as efficient as full DEFLATE but much better than STORE mode.
33
+ * Uses LZ77 with hash chains and lazy matching for significantly better
34
+ * compression than a single-entry hash table. The algorithm is modelled
35
+ * after zlib's "fast" and "slow" deflate strategies.
35
36
  *
36
37
  * @param data - Data to compress
37
38
  * @returns Compressed data in deflate-raw format
@@ -44,7 +45,10 @@ export declare function deflateRawCompressed(data: Uint8Array): Uint8Array;
44
45
  * maintains state across multiple `write()` calls:
45
46
  *
46
47
  * - **LZ77 sliding window**: back-references can span across chunks.
47
- * - **Hash table**: match positions persist across chunks.
48
+ * - **Hash chains**: match positions persist across chunks with typed-array
49
+ * hash tables for fast lookup.
50
+ * - **Lazy matching**: each match is compared with the next position's match
51
+ * to pick the longer one.
48
52
  * - **Bit writer**: bit position is preserved, so consecutive blocks form
49
53
  * a single valid DEFLATE bit-stream without alignment issues.
50
54
  *
@@ -57,13 +61,18 @@ export declare function deflateRawCompressed(data: Uint8Array): Uint8Array;
57
61
  */
58
62
  export declare class SyncDeflater {
59
63
  private _output;
60
- private _hashTable;
64
+ private _head;
65
+ private _prev;
61
66
  /** Sliding window: the last WINDOW_SIZE bytes of uncompressed data. */
62
67
  private _window;
63
68
  /** Number of valid bytes currently in the window. */
64
69
  private _windowLen;
65
70
  /** Total bytes written so far (monotonically increasing; used for hash offsets). */
66
71
  private _totalIn;
72
+ private _hasPrevMatch;
73
+ private _prevMatchLen;
74
+ private _prevMatchDist;
75
+ private _prevLiteral;
67
76
  /**
68
77
  * Compress a chunk and return the compressed bytes produced so far.
69
78
  * The output is a valid prefix of a DEFLATE stream (one or more non-final blocks).
@@ -46,20 +46,32 @@ export declare function createZlibStream(options?: StreamCompressOptions): ZlibS
46
46
  */
47
47
  export declare function createUnzlibStream(_options?: StreamCompressOptions): UnzlibStream;
48
48
  /**
49
- * Node.js synchronous deflater using `deflateRawSync` with `Z_SYNC_FLUSH`.
49
+ * Node.js synchronous deflater that batches small writes for better
50
+ * compression.
50
51
  *
51
- * Each `write()` compresses the chunk independently (no cross-chunk dictionary)
52
- * but uses `Z_SYNC_FLUSH` so the output is byte-aligned and can be concatenated
53
- * into a single valid DEFLATE stream. The final `finish()` emits a proper
54
- * BFINAL=1 block.
52
+ * Previous implementation compressed each `write()` call independently
53
+ * with `deflateRawSync()`, creating a fresh zlib context every time.
54
+ * For streaming workloads that push many small chunks (e.g. WorkbookWriter
55
+ * writing one row at a time), this destroyed the LZ77 dictionary between
56
+ * chunks and caused compression ratios to drop from ~82% to ~58%.
55
57
  *
56
- * This is fast (native C zlib) and produces valid output on all Node.js versions
57
- * (20+). The trade-off is ~2% worse compression ratio vs a stateful context,
58
- * which is acceptable for streaming where memory is the priority.
58
+ * The new implementation accumulates incoming data into an internal buffer
59
+ * and only calls `deflateRawSync()` when the buffer reaches 64 KB (or on
60
+ * `finish()`). Each batch is still compressed independently, but 64 KB
61
+ * is enough for zlib to build a good dictionary — the compression ratio
62
+ * is within ~1% of a single-shot compression of the entire input.
63
+ *
64
+ * The trade-off is slightly higher latency (compressed output is not
65
+ * returned byte-for-byte immediately), but this is acceptable because
66
+ * the ZIP writer buffers output anyway and the streaming contract only
67
+ * requires data to flow *eventually*, not after every single write.
59
68
  */
60
69
  export declare class SyncDeflater implements SyncDeflaterLike {
61
70
  private _level;
71
+ private _pending;
72
+ private _pendingSize;
62
73
  constructor(level?: number);
63
74
  write(data: Uint8Array): Uint8Array;
64
75
  finish(): Uint8Array;
76
+ private _flushBatch;
65
77
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cj-tech-master/excelts",
3
- "version": "6.1.1",
3
+ "version": "6.1.2",
4
4
  "description": "TypeScript Excel Workbook Manager - Read and Write xlsx and csv Files.",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
@@ -197,7 +197,7 @@
197
197
  "benchmark:compress": "rimraf dist && npm run build && node --expose-gc scripts/benchmark-compress.ts",
198
198
  "build:esm": "tsc --project tsconfig.esm.json && node scripts/fix-esm-imports.ts",
199
199
  "build:cjs": "tsc --project tsconfig.cjs.json && node scripts/fix-cjs-imports.ts",
200
- "build:browser": "tsc --project tsconfig.browser.json && node scripts/fix-esm-imports.ts --dist dist/browser && node scripts/fix-browser-imports.ts --dir dist/browser",
200
+ "build:browser": "tsc --project tsconfig.browser.json && node scripts/fix-esm-imports.ts --dist dist/browser --types dist/browser && node scripts/fix-browser-imports.ts --dir dist/browser",
201
201
  "build:browser:bundle": "rolldown -c rolldown.config.ts",
202
202
  "preversion": "npm run lint && npm run type && npm run build && npm run test"
203
203
  }