@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.
Files changed (232) hide show
  1. package/THIRD_PARTY_NOTICES.md +31 -0
  2. package/dist/browser/index.browser.d.ts +0 -1
  3. package/dist/browser/index.browser.js +0 -12
  4. package/dist/browser/modules/archive/byte-queue.d.ts +18 -0
  5. package/dist/browser/modules/archive/byte-queue.js +125 -0
  6. package/dist/browser/modules/archive/{compression/compress.base.js → compress.base.js} +1 -1
  7. package/dist/browser/modules/archive/{compression/compress.browser.d.ts → compress.browser.d.ts} +8 -2
  8. package/dist/{esm/modules/archive/compression → browser/modules/archive}/compress.browser.js +11 -3
  9. package/dist/browser/modules/archive/{compression/compress.d.ts → compress.d.ts} +2 -2
  10. package/dist/{esm/modules/archive/compression → browser/modules/archive}/compress.js +1 -1
  11. package/dist/browser/modules/archive/{compression/crc32.browser.d.ts → crc32.browser.d.ts} +1 -1
  12. package/dist/browser/modules/archive/{compression/crc32.d.ts → crc32.d.ts} +1 -1
  13. package/dist/browser/modules/archive/{compression/crc32.js → crc32.js} +1 -1
  14. package/dist/browser/modules/archive/defaults.d.ts +0 -1
  15. package/dist/browser/modules/archive/defaults.js +3 -6
  16. package/dist/browser/modules/archive/{compression/deflate-fallback.js → deflate-fallback.js} +1 -1
  17. package/dist/browser/modules/archive/{unzip/extract.d.ts → extract.d.ts} +2 -2
  18. package/dist/browser/modules/archive/index.base.d.ts +4 -4
  19. package/dist/browser/modules/archive/index.base.js +6 -3
  20. package/dist/browser/modules/archive/index.browser.d.ts +4 -3
  21. package/dist/browser/modules/archive/index.browser.js +7 -3
  22. package/dist/browser/modules/archive/index.d.ts +4 -3
  23. package/dist/browser/modules/archive/index.js +5 -3
  24. package/dist/browser/modules/archive/{unzip/stream.base.d.ts → parse.base.d.ts} +2 -36
  25. package/dist/browser/modules/archive/parse.base.js +644 -0
  26. package/dist/browser/modules/archive/{unzip/stream.browser.d.ts → parse.browser.d.ts} +1 -1
  27. package/dist/{esm/modules/archive/unzip/stream.browser.js → browser/modules/archive/parse.browser.js} +110 -371
  28. package/dist/browser/modules/archive/{unzip/stream.d.ts → parse.d.ts} +2 -2
  29. package/dist/{esm/modules/archive/unzip/stream.js → browser/modules/archive/parse.js} +5 -6
  30. package/dist/browser/modules/archive/{compression/streaming-compress.browser.d.ts → streaming-compress.browser.d.ts} +2 -2
  31. package/dist/browser/modules/archive/{compression/streaming-compress.browser.js → streaming-compress.browser.js} +3 -3
  32. package/dist/browser/modules/archive/{compression/streaming-compress.d.ts → streaming-compress.d.ts} +2 -2
  33. package/dist/browser/modules/archive/{compression/streaming-compress.js → streaming-compress.js} +2 -2
  34. package/dist/browser/modules/archive/{zip/stream.d.ts → streaming-zip.d.ts} +5 -28
  35. package/dist/{esm/modules/archive/zip/stream.js → browser/modules/archive/streaming-zip.js} +48 -192
  36. package/dist/browser/modules/archive/utils/bytes.js +16 -16
  37. package/dist/browser/modules/archive/utils/parse-buffer.js +23 -21
  38. package/dist/browser/modules/archive/utils/timestamps.js +1 -62
  39. package/dist/browser/modules/archive/utils/zip-extra-fields.d.ts +1 -1
  40. package/dist/browser/modules/archive/utils/zip-extra-fields.js +14 -26
  41. package/dist/browser/modules/archive/utils/zip-extra.d.ts +18 -0
  42. package/dist/browser/modules/archive/utils/zip-extra.js +68 -0
  43. package/dist/browser/modules/archive/zip-builder.d.ts +117 -0
  44. package/dist/browser/modules/archive/zip-builder.js +292 -0
  45. package/dist/browser/modules/archive/zip-constants.d.ts +18 -0
  46. package/dist/browser/modules/archive/zip-constants.js +23 -0
  47. package/dist/{esm/modules/archive/zip → browser/modules/archive}/zip-entry-metadata.js +3 -3
  48. package/dist/{types/modules/archive/unzip → browser/modules/archive}/zip-parser.d.ts +1 -1
  49. package/dist/{esm/modules/archive/unzip → browser/modules/archive}/zip-parser.js +24 -38
  50. package/dist/browser/modules/archive/{zip-spec/zip-records.d.ts → zip-records.d.ts} +0 -20
  51. package/dist/browser/modules/archive/zip-records.js +84 -0
  52. package/dist/browser/modules/excel/stream/workbook-reader.browser.js +1 -1
  53. package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +1 -1
  54. package/dist/browser/modules/excel/stream/workbook-writer.browser.js +1 -1
  55. package/dist/browser/modules/excel/xlsx/xlsx.browser.js +6 -3
  56. package/dist/browser/modules/excel/xlsx/xlsx.js +1 -1
  57. package/dist/browser/modules/stream/streams.browser.d.ts +30 -28
  58. package/dist/browser/modules/stream/streams.browser.js +710 -830
  59. package/dist/browser/modules/stream/streams.js +58 -140
  60. package/dist/cjs/modules/archive/byte-queue.js +129 -0
  61. package/dist/cjs/modules/archive/{compression/compress.base.js → compress.base.js} +1 -1
  62. package/dist/cjs/modules/archive/{compression/compress.browser.js → compress.browser.js} +11 -3
  63. package/dist/cjs/modules/archive/{compression/compress.js → compress.js} +1 -1
  64. package/dist/cjs/modules/archive/{compression/crc32.js → crc32.js} +1 -1
  65. package/dist/cjs/modules/archive/defaults.js +4 -7
  66. package/dist/cjs/modules/archive/{compression/deflate-fallback.js → deflate-fallback.js} +1 -1
  67. package/dist/cjs/modules/archive/index.base.js +19 -9
  68. package/dist/cjs/modules/archive/index.browser.js +10 -4
  69. package/dist/cjs/modules/archive/index.js +8 -4
  70. package/dist/cjs/modules/archive/parse.base.js +666 -0
  71. package/dist/cjs/modules/archive/{unzip/stream.browser.js → parse.browser.js} +111 -372
  72. package/dist/cjs/modules/archive/{unzip/stream.js → parse.js} +8 -9
  73. package/dist/cjs/modules/archive/{compression/streaming-compress.browser.js → streaming-compress.browser.js} +3 -3
  74. package/dist/cjs/modules/archive/{compression/streaming-compress.js → streaming-compress.js} +2 -2
  75. package/dist/cjs/modules/archive/{zip/stream.js → streaming-zip.js} +50 -194
  76. package/dist/cjs/modules/archive/utils/bytes.js +16 -16
  77. package/dist/cjs/modules/archive/utils/parse-buffer.js +23 -21
  78. package/dist/cjs/modules/archive/utils/timestamps.js +3 -64
  79. package/dist/cjs/modules/archive/utils/zip-extra-fields.js +14 -26
  80. package/dist/cjs/modules/archive/utils/zip-extra.js +74 -0
  81. package/dist/cjs/modules/archive/zip-builder.js +297 -0
  82. package/dist/cjs/modules/archive/zip-constants.js +26 -0
  83. package/dist/cjs/modules/archive/{zip/zip-entry-metadata.js → zip-entry-metadata.js} +5 -5
  84. package/dist/cjs/modules/archive/{unzip/zip-parser.js → zip-parser.js} +33 -47
  85. package/dist/cjs/modules/archive/zip-records.js +90 -0
  86. package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +2 -2
  87. package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +4 -4
  88. package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +9 -6
  89. package/dist/cjs/modules/excel/xlsx/xlsx.js +2 -2
  90. package/dist/cjs/modules/stream/streams.browser.js +710 -830
  91. package/dist/cjs/modules/stream/streams.js +58 -140
  92. package/dist/esm/index.browser.js +0 -12
  93. package/dist/esm/modules/archive/byte-queue.js +125 -0
  94. package/dist/esm/modules/archive/{compression/compress.base.js → compress.base.js} +1 -1
  95. package/dist/{browser/modules/archive/compression → esm/modules/archive}/compress.browser.js +11 -3
  96. package/dist/{browser/modules/archive/compression → esm/modules/archive}/compress.js +1 -1
  97. package/dist/esm/modules/archive/{compression/crc32.js → crc32.js} +1 -1
  98. package/dist/esm/modules/archive/defaults.js +3 -6
  99. package/dist/esm/modules/archive/{compression/deflate-fallback.js → deflate-fallback.js} +1 -1
  100. package/dist/esm/modules/archive/index.base.js +6 -3
  101. package/dist/esm/modules/archive/index.browser.js +7 -3
  102. package/dist/esm/modules/archive/index.js +5 -3
  103. package/dist/esm/modules/archive/parse.base.js +644 -0
  104. package/dist/{browser/modules/archive/unzip/stream.browser.js → esm/modules/archive/parse.browser.js} +110 -371
  105. package/dist/{browser/modules/archive/unzip/stream.js → esm/modules/archive/parse.js} +5 -6
  106. package/dist/esm/modules/archive/{compression/streaming-compress.browser.js → streaming-compress.browser.js} +3 -3
  107. package/dist/esm/modules/archive/{compression/streaming-compress.js → streaming-compress.js} +2 -2
  108. package/dist/{browser/modules/archive/zip/stream.js → esm/modules/archive/streaming-zip.js} +48 -192
  109. package/dist/esm/modules/archive/utils/bytes.js +16 -16
  110. package/dist/esm/modules/archive/utils/parse-buffer.js +23 -21
  111. package/dist/esm/modules/archive/utils/timestamps.js +1 -62
  112. package/dist/esm/modules/archive/utils/zip-extra-fields.js +14 -26
  113. package/dist/esm/modules/archive/utils/zip-extra.js +68 -0
  114. package/dist/esm/modules/archive/zip-builder.js +292 -0
  115. package/dist/esm/modules/archive/zip-constants.js +23 -0
  116. package/dist/{browser/modules/archive/zip → esm/modules/archive}/zip-entry-metadata.js +3 -3
  117. package/dist/{browser/modules/archive/unzip → esm/modules/archive}/zip-parser.js +24 -38
  118. package/dist/esm/modules/archive/zip-records.js +84 -0
  119. package/dist/esm/modules/excel/stream/workbook-reader.browser.js +1 -1
  120. package/dist/esm/modules/excel/stream/workbook-writer.browser.js +1 -1
  121. package/dist/esm/modules/excel/xlsx/xlsx.browser.js +6 -3
  122. package/dist/esm/modules/excel/xlsx/xlsx.js +1 -1
  123. package/dist/esm/modules/stream/streams.browser.js +710 -830
  124. package/dist/esm/modules/stream/streams.js +58 -140
  125. package/dist/iife/THIRD_PARTY_NOTICES.md +31 -0
  126. package/dist/iife/excelts.iife.js +4425 -6215
  127. package/dist/iife/excelts.iife.js.map +1 -1
  128. package/dist/iife/excelts.iife.min.js +31 -103
  129. package/dist/types/index.browser.d.ts +0 -1
  130. package/dist/types/modules/archive/byte-queue.d.ts +18 -0
  131. package/dist/types/modules/archive/{compression/compress.browser.d.ts → compress.browser.d.ts} +8 -2
  132. package/dist/types/modules/archive/defaults.d.ts +0 -1
  133. package/dist/types/modules/archive/index.base.d.ts +4 -4
  134. package/dist/types/modules/archive/index.browser.d.ts +4 -3
  135. package/dist/types/modules/archive/index.d.ts +4 -3
  136. package/dist/types/modules/archive/{unzip/stream.base.d.ts → parse.base.d.ts} +4 -38
  137. package/dist/types/modules/archive/{unzip/stream.browser.d.ts → parse.browser.d.ts} +2 -2
  138. package/dist/types/modules/archive/{unzip/stream.d.ts → parse.d.ts} +3 -3
  139. package/dist/types/modules/archive/{compression/streaming-compress.browser.d.ts → streaming-compress.browser.d.ts} +1 -1
  140. package/dist/types/modules/archive/{zip/stream.d.ts → streaming-zip.d.ts} +6 -29
  141. package/dist/types/modules/archive/utils/zip-extra-fields.d.ts +1 -1
  142. package/dist/types/modules/archive/utils/zip-extra.d.ts +18 -0
  143. package/dist/types/modules/archive/zip-builder.d.ts +117 -0
  144. package/dist/types/modules/archive/zip-constants.d.ts +18 -0
  145. package/dist/types/modules/archive/{zip/zip-entry-metadata.d.ts → zip-entry-metadata.d.ts} +1 -1
  146. package/dist/{browser/modules/archive/unzip → types/modules/archive}/zip-parser.d.ts +1 -1
  147. package/dist/types/modules/archive/{zip-spec/zip-records.d.ts → zip-records.d.ts} +0 -20
  148. package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +1 -1
  149. package/dist/types/modules/stream/streams.browser.d.ts +30 -28
  150. package/package.json +1 -5
  151. package/dist/browser/modules/archive/internal/byte-queue.d.ts +0 -33
  152. package/dist/browser/modules/archive/internal/byte-queue.js +0 -407
  153. package/dist/browser/modules/archive/io/archive-sink.d.ts +0 -9
  154. package/dist/browser/modules/archive/io/archive-sink.js +0 -77
  155. package/dist/browser/modules/archive/io/archive-source.d.ts +0 -8
  156. package/dist/browser/modules/archive/io/archive-source.js +0 -107
  157. package/dist/browser/modules/archive/unzip/index.d.ts +0 -40
  158. package/dist/browser/modules/archive/unzip/index.js +0 -164
  159. package/dist/browser/modules/archive/unzip/stream.base.js +0 -1022
  160. package/dist/browser/modules/archive/utils/async-queue.d.ts +0 -7
  161. package/dist/browser/modules/archive/utils/async-queue.js +0 -103
  162. package/dist/browser/modules/archive/utils/compressibility.d.ts +0 -10
  163. package/dist/browser/modules/archive/utils/compressibility.js +0 -57
  164. package/dist/browser/modules/archive/utils/pattern-scanner.d.ts +0 -21
  165. package/dist/browser/modules/archive/utils/pattern-scanner.js +0 -27
  166. package/dist/browser/modules/archive/zip/index.d.ts +0 -42
  167. package/dist/browser/modules/archive/zip/index.js +0 -157
  168. package/dist/browser/modules/archive/zip/zip-bytes.d.ts +0 -73
  169. package/dist/browser/modules/archive/zip/zip-bytes.js +0 -239
  170. package/dist/browser/modules/archive/zip-spec/zip-records.js +0 -126
  171. package/dist/cjs/modules/archive/internal/byte-queue.js +0 -411
  172. package/dist/cjs/modules/archive/io/archive-sink.js +0 -82
  173. package/dist/cjs/modules/archive/io/archive-source.js +0 -114
  174. package/dist/cjs/modules/archive/unzip/index.js +0 -170
  175. package/dist/cjs/modules/archive/unzip/stream.base.js +0 -1044
  176. package/dist/cjs/modules/archive/utils/async-queue.js +0 -106
  177. package/dist/cjs/modules/archive/utils/compressibility.js +0 -60
  178. package/dist/cjs/modules/archive/utils/pattern-scanner.js +0 -31
  179. package/dist/cjs/modules/archive/zip/index.js +0 -162
  180. package/dist/cjs/modules/archive/zip/zip-bytes.js +0 -242
  181. package/dist/cjs/modules/archive/zip-spec/zip-records.js +0 -136
  182. package/dist/esm/modules/archive/internal/byte-queue.js +0 -407
  183. package/dist/esm/modules/archive/io/archive-sink.js +0 -77
  184. package/dist/esm/modules/archive/io/archive-source.js +0 -107
  185. package/dist/esm/modules/archive/unzip/index.js +0 -164
  186. package/dist/esm/modules/archive/unzip/stream.base.js +0 -1022
  187. package/dist/esm/modules/archive/utils/async-queue.js +0 -103
  188. package/dist/esm/modules/archive/utils/compressibility.js +0 -57
  189. package/dist/esm/modules/archive/utils/pattern-scanner.js +0 -27
  190. package/dist/esm/modules/archive/zip/index.js +0 -157
  191. package/dist/esm/modules/archive/zip/zip-bytes.js +0 -239
  192. package/dist/esm/modules/archive/zip-spec/zip-records.js +0 -126
  193. package/dist/types/modules/archive/internal/byte-queue.d.ts +0 -33
  194. package/dist/types/modules/archive/io/archive-sink.d.ts +0 -9
  195. package/dist/types/modules/archive/io/archive-source.d.ts +0 -8
  196. package/dist/types/modules/archive/unzip/index.d.ts +0 -40
  197. package/dist/types/modules/archive/utils/async-queue.d.ts +0 -7
  198. package/dist/types/modules/archive/utils/compressibility.d.ts +0 -10
  199. package/dist/types/modules/archive/utils/pattern-scanner.d.ts +0 -21
  200. package/dist/types/modules/archive/zip/index.d.ts +0 -42
  201. package/dist/types/modules/archive/zip/zip-bytes.d.ts +0 -73
  202. /package/dist/browser/modules/archive/{compression/compress.base.d.ts → compress.base.d.ts} +0 -0
  203. /package/dist/browser/modules/archive/{compression/crc32.base.d.ts → crc32.base.d.ts} +0 -0
  204. /package/dist/browser/modules/archive/{compression/crc32.base.js → crc32.base.js} +0 -0
  205. /package/dist/browser/modules/archive/{compression/crc32.browser.js → crc32.browser.js} +0 -0
  206. /package/dist/browser/modules/archive/{compression/deflate-fallback.d.ts → deflate-fallback.d.ts} +0 -0
  207. /package/dist/browser/modules/archive/{unzip/extract.js → extract.js} +0 -0
  208. /package/dist/browser/modules/archive/{compression/streaming-compress.base.d.ts → streaming-compress.base.d.ts} +0 -0
  209. /package/dist/browser/modules/archive/{compression/streaming-compress.base.js → streaming-compress.base.js} +0 -0
  210. /package/dist/browser/modules/archive/{zip-spec/zip-entry-info.d.ts → zip-entry-info.d.ts} +0 -0
  211. /package/dist/browser/modules/archive/{zip-spec/zip-entry-info.js → zip-entry-info.js} +0 -0
  212. /package/dist/browser/modules/archive/{zip/zip-entry-metadata.d.ts → zip-entry-metadata.d.ts} +0 -0
  213. /package/dist/cjs/modules/archive/{compression/crc32.base.js → crc32.base.js} +0 -0
  214. /package/dist/cjs/modules/archive/{compression/crc32.browser.js → crc32.browser.js} +0 -0
  215. /package/dist/cjs/modules/archive/{unzip/extract.js → extract.js} +0 -0
  216. /package/dist/cjs/modules/archive/{compression/streaming-compress.base.js → streaming-compress.base.js} +0 -0
  217. /package/dist/cjs/modules/archive/{zip-spec/zip-entry-info.js → zip-entry-info.js} +0 -0
  218. /package/dist/esm/modules/archive/{compression/crc32.base.js → crc32.base.js} +0 -0
  219. /package/dist/esm/modules/archive/{compression/crc32.browser.js → crc32.browser.js} +0 -0
  220. /package/dist/esm/modules/archive/{unzip/extract.js → extract.js} +0 -0
  221. /package/dist/esm/modules/archive/{compression/streaming-compress.base.js → streaming-compress.base.js} +0 -0
  222. /package/dist/esm/modules/archive/{zip-spec/zip-entry-info.js → zip-entry-info.js} +0 -0
  223. /package/dist/types/modules/archive/{compression/compress.base.d.ts → compress.base.d.ts} +0 -0
  224. /package/dist/types/modules/archive/{compression/compress.d.ts → compress.d.ts} +0 -0
  225. /package/dist/types/modules/archive/{compression/crc32.base.d.ts → crc32.base.d.ts} +0 -0
  226. /package/dist/types/modules/archive/{compression/crc32.browser.d.ts → crc32.browser.d.ts} +0 -0
  227. /package/dist/types/modules/archive/{compression/crc32.d.ts → crc32.d.ts} +0 -0
  228. /package/dist/types/modules/archive/{compression/deflate-fallback.d.ts → deflate-fallback.d.ts} +0 -0
  229. /package/dist/types/modules/archive/{unzip/extract.d.ts → extract.d.ts} +0 -0
  230. /package/dist/types/modules/archive/{compression/streaming-compress.base.d.ts → streaming-compress.base.d.ts} +0 -0
  231. /package/dist/types/modules/archive/{compression/streaming-compress.d.ts → streaming-compress.d.ts} +0 -0
  232. /package/dist/types/modules/archive/{zip-spec/zip-entry-info.d.ts → zip-entry-info.d.ts} +0 -0
@@ -5,13 +5,14 @@
5
5
  * Falls back to pure JavaScript implementation for older browsers.
6
6
  * Uses the browser Duplex stream implementation for compatibility.
7
7
  */
8
- import { Duplex, PassThrough, concatUint8Arrays } from "../../stream/index.browser.js";
9
- import { DATA_DESCRIPTOR_SIGNATURE_BYTES, runParseLoop, streamUntilValidatedDataDescriptor } from "./stream.base.js";
10
- import { PatternScanner } from "../utils/pattern-scanner.js";
11
- import { inflateRaw as fallbackInflateRaw } from "../compression/deflate-fallback.js";
12
- import { ByteQueue } from "../internal/byte-queue.js";
13
- import { hasDeflateRawDecompressionStream } from "../compression/compress.base.js";
14
- const DEFAULT_UNZIP_STREAM_HIGH_WATER_MARK = 256 * 1024;
8
+ import { Duplex, PassThrough, concatUint8Arrays } from "../stream/index.js";
9
+ import { writeUint32LE } from "./utils/binary.js";
10
+ import { indexOfUint8ArrayPattern } from "./utils/bytes.js";
11
+ import { runParseLoop, streamUntilValidatedDataDescriptor } from "./parse.base.js";
12
+ import { inflateRaw as fallbackInflateRaw } from "./deflate-fallback.js";
13
+ import { ByteQueue } from "./byte-queue.js";
14
+ import { DATA_DESCRIPTOR_SIG } from "./zip-constants.js";
15
+ import { hasDeflateRawDecompressionStream } from "./compress.base.js";
15
16
  // =============================================================================
16
17
  // Browser InflateRaw using DecompressionStream
17
18
  // =============================================================================
@@ -28,9 +29,6 @@ class BrowserInflateRaw extends Duplex {
28
29
  // Pass write handler to Duplex so pipe() calls our write method
29
30
  // Also pass final handler to close the DecompressionStream when _writable ends
30
31
  super({
31
- // Keep the internal buffer bounded; this stream is used in tight parse loops.
32
- writableHighWaterMark: 512 * 1024,
33
- readableHighWaterMark: 512 * 1024,
34
32
  write: (chunk, _encoding, callback) => {
35
33
  this._doWrite(chunk, callback);
36
34
  },
@@ -139,6 +137,47 @@ class BrowserInflateRaw extends Duplex {
139
137
  this.push(null);
140
138
  }
141
139
  }
140
+ // Override write to feed data into DecompressionStream
141
+ write(chunk, encodingOrCallback, callback) {
142
+ // Handle overload
143
+ let cb;
144
+ if (typeof encodingOrCallback === "function") {
145
+ cb = encodingOrCallback;
146
+ }
147
+ else {
148
+ cb = callback;
149
+ }
150
+ this._doWrite(chunk, cb);
151
+ return true;
152
+ }
153
+ // Override end to close the DecompressionStream writer
154
+ end(chunkOrCallback, encodingOrCallback, callback) {
155
+ // Handle overloads
156
+ let chunk;
157
+ let cb;
158
+ if (typeof chunkOrCallback === "function") {
159
+ cb = chunkOrCallback;
160
+ }
161
+ else if (chunkOrCallback !== undefined) {
162
+ chunk = chunkOrCallback;
163
+ if (typeof encodingOrCallback === "function") {
164
+ cb = encodingOrCallback;
165
+ }
166
+ else {
167
+ cb = callback;
168
+ }
169
+ }
170
+ // Write final chunk if provided
171
+ if (chunk) {
172
+ this.write(chunk, () => {
173
+ this._closeWriter(cb);
174
+ });
175
+ }
176
+ else {
177
+ this._closeWriter(cb);
178
+ }
179
+ return this;
180
+ }
142
181
  _closeWriter(callback) {
143
182
  if (this.writeClosed) {
144
183
  this._readingDonePromise.then(() => {
@@ -166,6 +205,7 @@ class BrowserInflateRaw extends Duplex {
166
205
  if (callback) {
167
206
  callback();
168
207
  }
208
+ this.emit("finish");
169
209
  });
170
210
  });
171
211
  }
@@ -178,225 +218,6 @@ class BrowserInflateRaw extends Duplex {
178
218
  }
179
219
  }
180
220
  // =============================================================================
181
- // Worker-based InflateRaw (optional)
182
- // =============================================================================
183
- let _inflateWorkerUrl = null;
184
- function getInflateWorkerUrl(customUrl) {
185
- if (typeof customUrl === "string" && customUrl.length > 0) {
186
- return customUrl;
187
- }
188
- if (_inflateWorkerUrl) {
189
- return _inflateWorkerUrl;
190
- }
191
- // Inline worker to avoid bundler-specific worker loaders.
192
- // It streams deflate-raw through DecompressionStream and posts decompressed chunks back.
193
- const code = `
194
- let ds;
195
- let writer;
196
- let reader;
197
- let junkError = false;
198
- let pendingWrites = 0;
199
-
200
- function isJunkErrorMessage(msg) {
201
- return typeof msg === 'string' && (msg.includes('Junk') || msg.includes('junk'));
202
- }
203
-
204
- async function ensureStarted() {
205
- if (ds) return;
206
- ds = new DecompressionStream('deflate-raw');
207
- writer = ds.writable.getWriter();
208
- reader = ds.readable.getReader();
209
-
210
- (async () => {
211
- try {
212
- while (true) {
213
- const r = await reader.read();
214
- if (r.done) break;
215
- const chunk = r.value;
216
- postMessage({ t: 'data', chunk }, [chunk.buffer]);
217
- }
218
- postMessage({ t: 'end' });
219
- } catch (e) {
220
- const msg = e && e.message ? e.message : String(e);
221
- if (isJunkErrorMessage(msg)) {
222
- junkError = true;
223
- postMessage({ t: 'end' });
224
- } else {
225
- postMessage({ t: 'error', message: msg });
226
- }
227
- }
228
- })();
229
- }
230
-
231
- onmessage = async (ev) => {
232
- const msg = ev.data;
233
- try {
234
- await ensureStarted();
235
- if (msg.t === 'write') {
236
- if (junkError) {
237
- postMessage({ t: 'ack', id: msg.id });
238
- return;
239
- }
240
- pendingWrites++;
241
- await writer.write(msg.chunk);
242
- pendingWrites--;
243
- postMessage({ t: 'ack', id: msg.id });
244
- return;
245
- }
246
- if (msg.t === 'close') {
247
- // Wait for in-flight writes to finish (best-effort).
248
- while (pendingWrites > 0) {
249
- await new Promise(r => setTimeout(r, 0));
250
- }
251
- try { await writer.close(); } catch (_) {}
252
- postMessage({ t: 'closed' });
253
- return;
254
- }
255
- if (msg.t === 'abort') {
256
- try { await writer.abort(); } catch (_) {}
257
- postMessage({ t: 'aborted' });
258
- return;
259
- }
260
- } catch (e) {
261
- const m = e && e.message ? e.message : String(e);
262
- postMessage({ t: 'error', message: m, id: msg && msg.id });
263
- }
264
- };
265
- `;
266
- const blob = new Blob([code], { type: "text/javascript" });
267
- _inflateWorkerUrl = URL.createObjectURL(blob);
268
- return _inflateWorkerUrl;
269
- }
270
- class WorkerInflateRaw extends Duplex {
271
- constructor(workerUrl) {
272
- super({
273
- write: (chunk, _encoding, callback) => {
274
- this._doWrite(chunk, callback);
275
- },
276
- final: (callback) => {
277
- this._doClose(callback);
278
- }
279
- });
280
- this._nextId = 1;
281
- this._pendingAcks = new Map();
282
- this._closed = false;
283
- this._junkError = false;
284
- this._terminated = false;
285
- const url = getInflateWorkerUrl(workerUrl);
286
- this.worker = new Worker(url);
287
- this.worker.onmessage = (ev) => {
288
- const msg = ev.data;
289
- if (!msg || typeof msg.t !== "string") {
290
- return;
291
- }
292
- if (msg.t === "data") {
293
- const chunk = msg.chunk;
294
- this.push(chunk);
295
- return;
296
- }
297
- if (msg.t === "end") {
298
- this.push(null);
299
- this._terminateWorker();
300
- return;
301
- }
302
- if (msg.t === "aborted") {
303
- this._terminateWorker();
304
- return;
305
- }
306
- if (msg.t === "ack") {
307
- const id = msg.id;
308
- const cb = this._pendingAcks.get(id);
309
- if (cb) {
310
- this._pendingAcks.delete(id);
311
- cb();
312
- }
313
- return;
314
- }
315
- if (msg.t === "error") {
316
- const message = typeof msg.message === "string" ? msg.message : "Worker inflate error";
317
- if (message.includes("Junk") || message.includes("junk")) {
318
- this._junkError = true;
319
- // Treat as end-of-stream.
320
- this.push(null);
321
- this._terminateWorker();
322
- // Resolve any pending writes.
323
- for (const cb of this._pendingAcks.values()) {
324
- cb();
325
- }
326
- this._pendingAcks.clear();
327
- return;
328
- }
329
- const err = new Error(message);
330
- // Fail any pending writes.
331
- for (const cb of this._pendingAcks.values()) {
332
- cb(err);
333
- }
334
- this._pendingAcks.clear();
335
- this.emit("error", err);
336
- this._terminateWorker();
337
- return;
338
- }
339
- };
340
- this.worker.onerror = (e) => {
341
- const err = new Error(e.message || "Worker error");
342
- for (const cb of this._pendingAcks.values()) {
343
- cb(err);
344
- }
345
- this._pendingAcks.clear();
346
- this.emit("error", err);
347
- this._terminateWorker();
348
- };
349
- }
350
- _terminateWorker() {
351
- if (this._terminated) {
352
- return;
353
- }
354
- this._terminated = true;
355
- try {
356
- this.worker.terminate();
357
- }
358
- catch {
359
- // ignore
360
- }
361
- }
362
- _doWrite(chunk, callback) {
363
- if (this._closed || this._junkError) {
364
- callback();
365
- return;
366
- }
367
- const id = this._nextId++;
368
- this._pendingAcks.set(id, callback);
369
- // Transfer the underlying ArrayBuffer to reduce copies.
370
- // If chunk is a view into a larger buffer, slice to avoid transferring unrelated bytes.
371
- const transferable = chunk.byteOffset === 0 && chunk.byteLength === chunk.buffer.byteLength
372
- ? chunk
373
- : chunk.slice();
374
- this.worker.postMessage({ t: "write", id, chunk: transferable }, [transferable.buffer]);
375
- }
376
- _doClose(callback) {
377
- if (this._closed) {
378
- callback();
379
- return;
380
- }
381
- this._closed = true;
382
- this.worker.postMessage({ t: "close" });
383
- callback();
384
- }
385
- destroy(error) {
386
- if (!this._closed) {
387
- this._closed = true;
388
- try {
389
- this.worker.postMessage({ t: "abort" });
390
- }
391
- catch {
392
- // ignore
393
- }
394
- }
395
- this._terminateWorker();
396
- return super.destroy(error);
397
- }
398
- }
399
- // =============================================================================
400
221
  // Fallback InflateRaw for browsers without DecompressionStream
401
222
  // =============================================================================
402
223
  /**
@@ -456,7 +277,7 @@ function createInflateRaw() {
456
277
  // =============================================================================
457
278
  // Utilities
458
279
  // =============================================================================
459
- const dataDescriptorSignature = DATA_DESCRIPTOR_SIGNATURE_BYTES;
280
+ const dataDescriptorSignature = writeUint32LE(DATA_DESCRIPTOR_SIG);
460
281
  export function createParseClass(createInflateRawFn) {
461
282
  /**
462
283
  * ZIP Stream Parser for browsers.
@@ -470,11 +291,11 @@ export function createParseClass(createInflateRawFn) {
470
291
  super({
471
292
  objectMode: true,
472
293
  write: (chunk, _encoding, callback) => {
473
- this._handleWrite(chunk, callback);
294
+ this._handleWrite(chunk);
295
+ callback();
474
296
  },
475
297
  final: (callback) => {
476
298
  this.finished = true;
477
- this._maybeReleaseWriteCallback();
478
299
  this._wakeUp();
479
300
  this.emit("data-available");
480
301
  this.emit("chunk", false);
@@ -486,12 +307,6 @@ export function createParseClass(createInflateRawFn) {
486
307
  this._driverState = {};
487
308
  this._parsingDone = Promise.resolve();
488
309
  this._opts = opts;
489
- // Default values are intentionally conservative to avoid memory spikes
490
- // when parsing large archives under slow consumers.
491
- const hi = Math.max(64 * 1024, opts.inputHighWaterMarkBytes ?? 2 * 1024 * 1024);
492
- const lo = Math.max(32 * 1024, opts.inputLowWaterMarkBytes ?? Math.floor(hi / 4));
493
- this._inputHighWaterMarkBytes = hi;
494
- this._inputLowWaterMarkBytes = Math.min(lo, hi);
495
310
  const io = {
496
311
  pull: (length) => this.pull(length),
497
312
  pullUntil: (pattern, includeEof) => this.pullUntil(pattern, includeEof),
@@ -519,12 +334,6 @@ export function createParseClass(createInflateRawFn) {
519
334
  },
520
335
  emitError: (err) => {
521
336
  this.__emittedError = err;
522
- // Ensure upstream writers don't hang waiting for a deferred write callback.
523
- if (this._writeCb) {
524
- const cb = this._writeCb;
525
- this._writeCb = undefined;
526
- cb(err);
527
- }
528
337
  this.emit("error", err);
529
338
  },
530
339
  emitClose: () => {
@@ -535,22 +344,7 @@ export function createParseClass(createInflateRawFn) {
535
344
  // NOTE: We intentionally do NOT pass inflateRawSync to runParseLoop in browser.
536
345
  // Browser's native DecompressionStream is faster than our pure-JS fallback,
537
346
  // so we always use the streaming path for decompression in browsers.
538
- const inflateFactory = () => {
539
- if (this._opts.useWorkerInflate && typeof Worker !== "undefined") {
540
- // Worker path requires DecompressionStream support.
541
- if (hasDeflateRawDecompressionStream()) {
542
- try {
543
- return new WorkerInflateRaw(this._opts.workerInflateUrl);
544
- }
545
- catch {
546
- // If Worker construction fails (e.g. CSP/CORS), fall back.
547
- return createInflateRawFn();
548
- }
549
- }
550
- }
551
- return createInflateRawFn();
552
- };
553
- this._parsingDone = runParseLoop(this._opts, io, emitter, inflateFactory, this._driverState
347
+ this._parsingDone = runParseLoop(this._opts, io, emitter, () => createInflateRawFn(), this._driverState
554
348
  // No inflateRawSync - always use streaming DecompressionStream in browser
555
349
  );
556
350
  this._parsingDone.catch((e) => {
@@ -562,16 +356,8 @@ export function createParseClass(createInflateRawFn) {
562
356
  });
563
357
  });
564
358
  }
565
- _handleWrite(chunk, callback) {
359
+ _handleWrite(chunk) {
566
360
  this._buffer.append(chunk);
567
- // Apply writable backpressure by deferring the callback when the input buffer is large.
568
- // The callback will be released once the parser drains the buffer.
569
- if (this._buffer.length >= this._inputHighWaterMarkBytes) {
570
- this._writeCb = callback;
571
- }
572
- else {
573
- callback();
574
- }
575
361
  this._wakeUp();
576
362
  this.emit("data-available");
577
363
  this.emit("chunk");
@@ -582,6 +368,13 @@ export function createParseClass(createInflateRawFn) {
582
368
  set buffer(value) {
583
369
  this._buffer.reset(value);
584
370
  }
371
+ _maybeReleaseWriteCallback() {
372
+ if (typeof this.cb === "function") {
373
+ const callback = this.cb;
374
+ this.cb = undefined;
375
+ callback();
376
+ }
377
+ }
585
378
  _wakeUp() {
586
379
  if (this._pendingResolve) {
587
380
  const resolve = this._pendingResolve;
@@ -589,17 +382,6 @@ export function createParseClass(createInflateRawFn) {
589
382
  resolve();
590
383
  }
591
384
  }
592
- _maybeReleaseWriteCallback() {
593
- if (!this._writeCb) {
594
- return;
595
- }
596
- if (this._buffer.length > this._inputLowWaterMarkBytes) {
597
- return;
598
- }
599
- const cb = this._writeCb;
600
- this._writeCb = undefined;
601
- cb();
602
- }
603
385
  _waitForData() {
604
386
  return new Promise(resolve => {
605
387
  this._pendingResolve = resolve;
@@ -613,76 +395,60 @@ export function createParseClass(createInflateRawFn) {
613
395
  if (this.finished) {
614
396
  if (this._buffer.length > 0) {
615
397
  const data = this._buffer.read(this._buffer.length);
616
- this._maybeReleaseWriteCallback();
617
398
  return data;
618
399
  }
619
400
  throw new Error("FILE_ENDED");
620
401
  }
621
402
  await this._waitForData();
622
403
  }
623
- const out = this._buffer.read(length);
624
- this._maybeReleaseWriteCallback();
625
- return out;
404
+ return this._buffer.read(length);
626
405
  }
627
406
  async _pullUntilInternal(pattern, includeEof = false) {
628
407
  const chunks = [];
629
- const scanner = new PatternScanner(pattern);
408
+ let searchFrom = 0;
409
+ const overlap = Math.max(0, pattern.length - 1);
630
410
  while (true) {
631
- const bufLen = this._buffer.length;
632
- const match = scanner.find(this._buffer);
411
+ const view = this._buffer.view();
412
+ const match = indexOfUint8ArrayPattern(view, pattern, searchFrom);
633
413
  if (match !== -1) {
634
414
  this.match = match;
635
415
  const toRead = match + (includeEof ? pattern.length : 0);
636
416
  if (toRead > 0) {
637
417
  chunks.push(this._buffer.read(toRead));
638
- this._maybeReleaseWriteCallback();
639
418
  }
640
- return chunks.length === 1 ? chunks[0] : concatUint8Arrays(chunks);
419
+ return concatUint8Arrays(chunks);
641
420
  }
642
421
  // No match yet. Avoid rescanning bytes that can't start a match.
643
- scanner.onNoMatch(bufLen);
422
+ searchFrom = Math.max(searchFrom, Math.max(0, view.length - overlap));
644
423
  if (this.finished) {
645
424
  throw new Error("FILE_ENDED");
646
425
  }
647
426
  const safeLen = Math.max(0, this._buffer.length - pattern.length);
648
427
  if (safeLen > 0) {
649
428
  chunks.push(this._buffer.read(safeLen));
650
- scanner.onConsume(safeLen);
651
- this._maybeReleaseWriteCallback();
429
+ searchFrom = Math.max(0, searchFrom - safeLen);
652
430
  }
653
431
  await this._waitForData();
654
432
  }
655
433
  }
656
434
  _streamFixedLength(length) {
657
- const output = new PassThrough({ highWaterMark: DEFAULT_UNZIP_STREAM_HIGH_WATER_MARK });
435
+ const output = new PassThrough();
658
436
  let remaining = length;
659
437
  let done = false;
660
- let waitingDrain = false;
661
438
  const pull = () => {
662
439
  if (done) {
663
440
  return;
664
441
  }
665
- if (waitingDrain) {
666
- return;
667
- }
668
442
  while (remaining > 0 && this._buffer.length > 0) {
669
443
  const toRead = Math.min(remaining, this._buffer.length);
670
444
  const chunk = this._buffer.read(toRead);
671
445
  remaining -= toRead;
672
- const ok = output.write(chunk);
673
- this._maybeReleaseWriteCallback();
674
- if (!ok) {
675
- waitingDrain = true;
676
- output.once("drain", () => {
677
- waitingDrain = false;
678
- pull();
679
- });
680
- return;
681
- }
446
+ output.write(chunk);
682
447
  }
683
448
  if (remaining === 0) {
684
449
  done = true;
685
450
  this.removeListener("data-available", pull);
451
+ this._maybeReleaseWriteCallback();
686
452
  output.end();
687
453
  }
688
454
  else if (this.finished) {
@@ -696,69 +462,42 @@ export function createParseClass(createInflateRawFn) {
696
462
  return output;
697
463
  }
698
464
  _streamUntilPattern(pattern, includeEof = false) {
699
- const output = new PassThrough({ highWaterMark: DEFAULT_UNZIP_STREAM_HIGH_WATER_MARK });
465
+ const output = new PassThrough();
700
466
  let done = false;
701
- const patternLen = pattern.length;
702
- const scanner = new PatternScanner(pattern);
703
- let waitingDrain = false;
467
+ let searchFrom = 0;
468
+ const overlap = Math.max(0, pattern.length - 1);
704
469
  const pull = () => {
705
- if (done || waitingDrain) {
470
+ if (done) {
706
471
  return;
707
472
  }
708
- while (true) {
709
- if (this._buffer.length <= 0) {
710
- break;
711
- }
712
- const bufLen = this._buffer.length;
713
- const match = scanner.find(this._buffer);
714
- if (match !== -1) {
715
- this.match = match;
716
- const endIndex = includeEof ? match + patternLen : match;
717
- if (endIndex > 0) {
718
- const ok = output.write(this._buffer.read(endIndex));
719
- scanner.onConsume(endIndex);
720
- this._maybeReleaseWriteCallback();
721
- if (!ok) {
722
- waitingDrain = true;
723
- output.once("drain", () => {
724
- waitingDrain = false;
725
- pull();
726
- });
727
- return;
728
- }
729
- }
730
- done = true;
731
- this.removeListener("data-available", pull);
732
- output.end();
733
- return;
734
- }
735
- // No match yet. Avoid rescanning bytes that can't start a match.
736
- scanner.onNoMatch(bufLen);
737
- if (this.finished) {
738
- done = true;
739
- this.removeListener("data-available", pull);
740
- output.destroy(new Error("FILE_ENDED"));
741
- return;
742
- }
743
- const safeLen = bufLen - patternLen;
744
- if (safeLen <= 0) {
745
- // Keep enough bytes to detect a split signature.
746
- if (this._buffer.length <= patternLen) {
747
- this._maybeReleaseWriteCallback();
748
- }
749
- break;
473
+ const view = this._buffer.view();
474
+ const match = indexOfUint8ArrayPattern(view, pattern, searchFrom);
475
+ if (match !== -1) {
476
+ this.match = match;
477
+ const endIndex = includeEof ? match + pattern.length : match;
478
+ if (endIndex > 0) {
479
+ output.write(this._buffer.read(endIndex));
750
480
  }
751
- const ok = output.write(this._buffer.read(safeLen));
752
- scanner.onConsume(safeLen);
481
+ done = true;
482
+ this.removeListener("data-available", pull);
483
+ this._maybeReleaseWriteCallback();
484
+ output.end();
485
+ return;
486
+ }
487
+ // No match yet. Avoid rescanning bytes that can't start a match.
488
+ searchFrom = Math.max(searchFrom, Math.max(0, view.length - overlap));
489
+ if (this.finished) {
490
+ done = true;
491
+ this.removeListener("data-available", pull);
492
+ this._maybeReleaseWriteCallback();
493
+ output.destroy(new Error("FILE_ENDED"));
494
+ return;
495
+ }
496
+ const safeLen = Math.max(0, this._buffer.length - pattern.length);
497
+ if (safeLen > 0) {
498
+ output.write(this._buffer.read(safeLen));
499
+ searchFrom = Math.max(0, searchFrom - safeLen);
753
500
  this._maybeReleaseWriteCallback();
754
- if (!ok) {
755
- waitingDrain = true;
756
- output.once("drain", () => {
757
- waitingDrain = false;
758
- pull();
759
- });
760
- return;
761
- }
762
501
  }
763
502
  };
764
503
  this.on("data-available", pull);
@@ -781,7 +520,11 @@ export function createParseClass(createInflateRawFn) {
781
520
  return Promise.reject(new Error("FILE_ENDED"));
782
521
  }
783
522
  if (this._buffer.length >= eof) {
784
- return Promise.resolve(this._buffer.read(eof));
523
+ const data = this._buffer.read(eof);
524
+ if (this._buffer.length === 0) {
525
+ this._maybeReleaseWriteCallback();
526
+ }
527
+ return Promise.resolve(data);
785
528
  }
786
529
  return this._pullInternal(eof);
787
530
  }
@@ -797,18 +540,14 @@ export function createParseClass(createInflateRawFn) {
797
540
  _streamUntilDataDescriptor() {
798
541
  return streamUntilValidatedDataDescriptor({
799
542
  source: {
543
+ getView: () => this._buffer.view(),
800
544
  getLength: () => this._buffer.length,
801
545
  read: (length) => this._buffer.read(length),
802
- peekChunks: (length) => this._buffer.peekChunks(length),
803
- discard: (length) => this._buffer.discard(length),
804
- indexOfPattern: (pattern, startIndex) => this._buffer.indexOfPattern(pattern, startIndex),
805
- peekUint32LE: (offset) => this._buffer.peekUint32LE(offset),
806
546
  isFinished: () => this.finished,
807
547
  onDataAvailable: (cb) => {
808
548
  this.on("data-available", cb);
809
549
  return () => this.removeListener("data-available", cb);
810
- },
811
- maybeReleaseWriteCallback: () => this._maybeReleaseWriteCallback()
550
+ }
812
551
  },
813
552
  dataDescriptorSignature
814
553
  });
@@ -1,12 +1,14 @@
1
1
  import zlib from "zlib";
2
- import { DATA_DESCRIPTOR_SIGNATURE_BYTES, PullStream, runParseLoop, streamUntilValidatedDataDescriptor } from "./stream.base.js";
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 = DATA_DESCRIPTOR_SIGNATURE_BYTES;
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);