@cj-tech-master/excelts 4.2.1 → 4.2.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.
Files changed (311) hide show
  1. package/THIRD_PARTY_NOTICES.md +0 -31
  2. package/dist/browser/index.browser.d.ts +1 -0
  3. package/dist/browser/index.browser.js +12 -0
  4. package/dist/{esm/modules/archive → browser/modules/archive/compression}/compress.base.js +1 -1
  5. package/dist/{types/modules/archive → browser/modules/archive/compression}/compress.browser.d.ts +2 -8
  6. package/dist/browser/modules/archive/{compress.browser.js → compression/compress.browser.js} +3 -11
  7. package/dist/browser/modules/archive/{compress.d.ts → compression/compress.d.ts} +2 -2
  8. package/dist/{esm/modules/archive → browser/modules/archive/compression}/compress.js +1 -1
  9. package/dist/browser/modules/archive/{crc32.browser.d.ts → compression/crc32.browser.d.ts} +1 -1
  10. package/dist/browser/modules/archive/{crc32.d.ts → compression/crc32.d.ts} +1 -1
  11. package/dist/browser/modules/archive/{crc32.js → compression/crc32.js} +1 -1
  12. package/dist/browser/modules/archive/{deflate-fallback.js → compression/deflate-fallback.js} +1 -1
  13. package/dist/browser/modules/archive/{streaming-compress.browser.d.ts → compression/streaming-compress.browser.d.ts} +2 -2
  14. package/dist/browser/modules/archive/{streaming-compress.browser.js → compression/streaming-compress.browser.js} +3 -3
  15. package/dist/browser/modules/archive/{streaming-compress.d.ts → compression/streaming-compress.d.ts} +2 -2
  16. package/dist/browser/modules/archive/{streaming-compress.js → compression/streaming-compress.js} +2 -2
  17. package/dist/browser/modules/archive/defaults.d.ts +1 -0
  18. package/dist/browser/modules/archive/defaults.js +6 -3
  19. package/dist/browser/modules/archive/index.base.d.ts +4 -4
  20. package/dist/browser/modules/archive/index.base.js +3 -6
  21. package/dist/browser/modules/archive/index.browser.d.ts +3 -4
  22. package/dist/browser/modules/archive/index.browser.js +3 -7
  23. package/dist/browser/modules/archive/index.d.ts +3 -4
  24. package/dist/browser/modules/archive/index.js +3 -5
  25. package/dist/browser/modules/archive/internal/byte-queue.d.ts +33 -0
  26. package/dist/browser/modules/archive/internal/byte-queue.js +407 -0
  27. package/dist/browser/modules/archive/io/archive-sink.d.ts +8 -0
  28. package/dist/browser/modules/archive/io/archive-sink.js +45 -0
  29. package/dist/browser/modules/archive/io/archive-source.d.ts +6 -0
  30. package/dist/browser/modules/archive/io/archive-source.js +100 -0
  31. package/dist/browser/modules/archive/{extract.d.ts → unzip/extract.d.ts} +2 -2
  32. package/dist/browser/modules/archive/unzip/index.d.ts +40 -0
  33. package/dist/browser/modules/archive/unzip/index.js +164 -0
  34. package/dist/browser/modules/archive/{parse.base.d.ts → unzip/stream.base.d.ts} +36 -2
  35. package/dist/browser/modules/archive/unzip/stream.base.js +1022 -0
  36. package/dist/browser/modules/archive/{parse.browser.d.ts → unzip/stream.browser.d.ts} +1 -1
  37. package/dist/browser/modules/archive/{parse.browser.js → unzip/stream.browser.js} +371 -110
  38. package/dist/browser/modules/archive/{parse.d.ts → unzip/stream.d.ts} +2 -2
  39. package/dist/{esm/modules/archive/parse.js → browser/modules/archive/unzip/stream.js} +6 -5
  40. package/dist/browser/modules/archive/{zip-parser.d.ts → unzip/zip-parser.d.ts} +1 -1
  41. package/dist/{esm/modules/archive → browser/modules/archive/unzip}/zip-parser.js +38 -24
  42. package/dist/browser/modules/archive/utils/async-queue.d.ts +7 -0
  43. package/dist/browser/modules/archive/utils/async-queue.js +103 -0
  44. package/dist/browser/modules/archive/utils/bytes.js +16 -16
  45. package/dist/browser/modules/archive/utils/compressibility.d.ts +10 -0
  46. package/dist/browser/modules/archive/utils/compressibility.js +57 -0
  47. package/dist/browser/modules/archive/utils/parse-buffer.js +21 -23
  48. package/dist/browser/modules/archive/utils/pattern-scanner.d.ts +21 -0
  49. package/dist/browser/modules/archive/utils/pattern-scanner.js +27 -0
  50. package/dist/browser/modules/archive/utils/timestamps.js +62 -1
  51. package/dist/browser/modules/archive/utils/zip-extra-fields.d.ts +1 -1
  52. package/dist/browser/modules/archive/utils/zip-extra-fields.js +26 -14
  53. package/dist/browser/modules/archive/zip/index.d.ts +42 -0
  54. package/dist/browser/modules/archive/zip/index.js +157 -0
  55. package/dist/browser/modules/archive/{streaming-zip.d.ts → zip/stream.d.ts} +28 -5
  56. package/dist/browser/modules/archive/{streaming-zip.js → zip/stream.js} +192 -48
  57. package/dist/browser/modules/archive/zip/zip-bytes.d.ts +73 -0
  58. package/dist/browser/modules/archive/zip/zip-bytes.js +239 -0
  59. package/dist/{esm/modules/archive → browser/modules/archive/zip}/zip-entry-metadata.js +3 -3
  60. package/dist/browser/modules/archive/{zip-records.d.ts → zip-spec/zip-records.d.ts} +20 -0
  61. package/dist/browser/modules/archive/zip-spec/zip-records.js +126 -0
  62. package/dist/browser/modules/excel/stream/workbook-reader.browser.js +1 -1
  63. package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +1 -1
  64. package/dist/browser/modules/excel/stream/workbook-writer.browser.js +1 -1
  65. package/dist/browser/modules/excel/utils/ooxml-validator.d.ts +48 -0
  66. package/dist/browser/modules/excel/utils/ooxml-validator.js +469 -0
  67. package/dist/browser/modules/excel/worksheet.js +5 -2
  68. package/dist/browser/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.d.ts +1 -0
  69. package/dist/browser/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.js +13 -1
  70. package/dist/browser/modules/excel/xlsx/xform/drawing/sp-xform.d.ts +18 -0
  71. package/dist/browser/modules/excel/xlsx/xform/drawing/sp-xform.js +112 -0
  72. package/dist/browser/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.d.ts +6 -1
  73. package/dist/browser/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +30 -2
  74. package/dist/browser/modules/excel/xlsx/xform/drawing/vml-drawing-xform.js +11 -0
  75. package/dist/browser/modules/excel/xlsx/xform/sheet/page-setup-xform.d.ts +1 -0
  76. package/dist/browser/modules/excel/xlsx/xform/sheet/page-setup-xform.js +16 -2
  77. package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +110 -12
  78. package/dist/browser/modules/excel/xlsx/xlsx.browser.js +3 -6
  79. package/dist/browser/modules/excel/xlsx/xlsx.js +1 -1
  80. package/dist/browser/modules/stream/base-transform.d.ts +3 -0
  81. package/dist/browser/modules/stream/base-transform.js +34 -20
  82. package/dist/browser/modules/stream/buffered-stream.d.ts +2 -12
  83. package/dist/browser/modules/stream/chunked-builder.js +4 -4
  84. package/dist/browser/modules/stream/index.browser.d.ts +13 -19
  85. package/dist/browser/modules/stream/index.browser.js +10 -22
  86. package/dist/browser/modules/stream/index.d.ts +18 -41
  87. package/dist/browser/modules/stream/index.js +15 -44
  88. package/dist/browser/modules/stream/internal/event-utils.d.ts +17 -0
  89. package/dist/browser/modules/stream/internal/event-utils.js +40 -0
  90. package/dist/browser/modules/stream/internal/type-guards.d.ts +9 -0
  91. package/dist/browser/modules/stream/internal/type-guards.js +24 -0
  92. package/dist/browser/modules/stream/pull-stream.d.ts +5 -6
  93. package/dist/browser/modules/stream/pull-stream.js +107 -43
  94. package/dist/browser/modules/stream/shared.d.ts +1 -1
  95. package/dist/browser/modules/stream/shared.js +7 -4
  96. package/dist/browser/modules/stream/streams.browser.d.ts +32 -44
  97. package/dist/browser/modules/stream/streams.browser.js +921 -836
  98. package/dist/browser/modules/stream/streams.d.ts +4 -20
  99. package/dist/browser/modules/stream/streams.js +146 -95
  100. package/dist/browser/modules/stream/utils.js +5 -38
  101. package/dist/cjs/modules/archive/{compress.base.js → compression/compress.base.js} +1 -1
  102. package/dist/cjs/modules/archive/{compress.browser.js → compression/compress.browser.js} +3 -11
  103. package/dist/cjs/modules/archive/{compress.js → compression/compress.js} +1 -1
  104. package/dist/cjs/modules/archive/{crc32.js → compression/crc32.js} +1 -1
  105. package/dist/cjs/modules/archive/{deflate-fallback.js → compression/deflate-fallback.js} +1 -1
  106. package/dist/cjs/modules/archive/{streaming-compress.browser.js → compression/streaming-compress.browser.js} +3 -3
  107. package/dist/cjs/modules/archive/{streaming-compress.js → compression/streaming-compress.js} +2 -2
  108. package/dist/cjs/modules/archive/defaults.js +7 -4
  109. package/dist/cjs/modules/archive/index.base.js +9 -19
  110. package/dist/cjs/modules/archive/index.browser.js +4 -10
  111. package/dist/cjs/modules/archive/index.js +4 -8
  112. package/dist/cjs/modules/archive/internal/byte-queue.js +411 -0
  113. package/dist/cjs/modules/archive/io/archive-sink.js +49 -0
  114. package/dist/cjs/modules/archive/io/archive-source.js +105 -0
  115. package/dist/cjs/modules/archive/unzip/index.js +170 -0
  116. package/dist/cjs/modules/archive/unzip/stream.base.js +1044 -0
  117. package/dist/cjs/modules/archive/{parse.browser.js → unzip/stream.browser.js} +372 -111
  118. package/dist/cjs/modules/archive/{parse.js → unzip/stream.js} +9 -8
  119. package/dist/cjs/modules/archive/{zip-parser.js → unzip/zip-parser.js} +47 -33
  120. package/dist/cjs/modules/archive/utils/async-queue.js +106 -0
  121. package/dist/cjs/modules/archive/utils/bytes.js +16 -16
  122. package/dist/cjs/modules/archive/utils/compressibility.js +60 -0
  123. package/dist/cjs/modules/archive/utils/parse-buffer.js +21 -23
  124. package/dist/cjs/modules/archive/utils/pattern-scanner.js +31 -0
  125. package/dist/cjs/modules/archive/utils/timestamps.js +64 -3
  126. package/dist/cjs/modules/archive/utils/zip-extra-fields.js +26 -14
  127. package/dist/cjs/modules/archive/zip/index.js +162 -0
  128. package/dist/cjs/modules/archive/{streaming-zip.js → zip/stream.js} +194 -50
  129. package/dist/cjs/modules/archive/zip/zip-bytes.js +242 -0
  130. package/dist/cjs/modules/archive/{zip-entry-metadata.js → zip/zip-entry-metadata.js} +5 -5
  131. package/dist/cjs/modules/archive/zip-spec/zip-records.js +136 -0
  132. package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +2 -2
  133. package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +4 -4
  134. package/dist/cjs/modules/excel/utils/ooxml-validator.js +475 -0
  135. package/dist/cjs/modules/excel/worksheet.js +5 -2
  136. package/dist/cjs/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.js +13 -1
  137. package/dist/cjs/modules/excel/xlsx/xform/drawing/sp-xform.js +115 -0
  138. package/dist/cjs/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +30 -2
  139. package/dist/cjs/modules/excel/xlsx/xform/drawing/vml-drawing-xform.js +11 -0
  140. package/dist/cjs/modules/excel/xlsx/xform/sheet/page-setup-xform.js +16 -2
  141. package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +110 -12
  142. package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +6 -9
  143. package/dist/cjs/modules/excel/xlsx/xlsx.js +2 -2
  144. package/dist/cjs/modules/stream/base-transform.js +34 -20
  145. package/dist/cjs/modules/stream/chunked-builder.js +4 -4
  146. package/dist/cjs/modules/stream/index.browser.js +10 -17
  147. package/dist/cjs/modules/stream/index.js +15 -39
  148. package/dist/cjs/modules/stream/internal/event-utils.js +43 -0
  149. package/dist/cjs/modules/stream/internal/type-guards.js +30 -0
  150. package/dist/cjs/modules/stream/pull-stream.js +107 -43
  151. package/dist/cjs/modules/stream/shared.js +7 -4
  152. package/dist/cjs/modules/stream/streams.browser.js +927 -847
  153. package/dist/cjs/modules/stream/streams.js +156 -107
  154. package/dist/cjs/modules/stream/utils.js +3 -36
  155. package/dist/esm/index.browser.js +12 -0
  156. package/dist/{browser/modules/archive → esm/modules/archive/compression}/compress.base.js +1 -1
  157. package/dist/esm/modules/archive/{compress.browser.js → compression/compress.browser.js} +3 -11
  158. package/dist/{browser/modules/archive → esm/modules/archive/compression}/compress.js +1 -1
  159. package/dist/esm/modules/archive/{crc32.js → compression/crc32.js} +1 -1
  160. package/dist/esm/modules/archive/{deflate-fallback.js → compression/deflate-fallback.js} +1 -1
  161. package/dist/esm/modules/archive/{streaming-compress.browser.js → compression/streaming-compress.browser.js} +3 -3
  162. package/dist/esm/modules/archive/{streaming-compress.js → compression/streaming-compress.js} +2 -2
  163. package/dist/esm/modules/archive/defaults.js +6 -3
  164. package/dist/esm/modules/archive/index.base.js +3 -6
  165. package/dist/esm/modules/archive/index.browser.js +3 -7
  166. package/dist/esm/modules/archive/index.js +3 -5
  167. package/dist/esm/modules/archive/internal/byte-queue.js +407 -0
  168. package/dist/esm/modules/archive/io/archive-sink.js +45 -0
  169. package/dist/esm/modules/archive/io/archive-source.js +100 -0
  170. package/dist/esm/modules/archive/unzip/index.js +164 -0
  171. package/dist/esm/modules/archive/unzip/stream.base.js +1022 -0
  172. package/dist/esm/modules/archive/{parse.browser.js → unzip/stream.browser.js} +371 -110
  173. package/dist/{browser/modules/archive/parse.js → esm/modules/archive/unzip/stream.js} +6 -5
  174. package/dist/{browser/modules/archive → esm/modules/archive/unzip}/zip-parser.js +38 -24
  175. package/dist/esm/modules/archive/utils/async-queue.js +103 -0
  176. package/dist/esm/modules/archive/utils/bytes.js +16 -16
  177. package/dist/esm/modules/archive/utils/compressibility.js +57 -0
  178. package/dist/esm/modules/archive/utils/parse-buffer.js +21 -23
  179. package/dist/esm/modules/archive/utils/pattern-scanner.js +27 -0
  180. package/dist/esm/modules/archive/utils/timestamps.js +62 -1
  181. package/dist/esm/modules/archive/utils/zip-extra-fields.js +26 -14
  182. package/dist/esm/modules/archive/zip/index.js +157 -0
  183. package/dist/esm/modules/archive/{streaming-zip.js → zip/stream.js} +192 -48
  184. package/dist/esm/modules/archive/zip/zip-bytes.js +239 -0
  185. package/dist/{browser/modules/archive → esm/modules/archive/zip}/zip-entry-metadata.js +3 -3
  186. package/dist/esm/modules/archive/zip-spec/zip-records.js +126 -0
  187. package/dist/esm/modules/excel/stream/workbook-reader.browser.js +1 -1
  188. package/dist/esm/modules/excel/stream/workbook-writer.browser.js +1 -1
  189. package/dist/esm/modules/excel/utils/ooxml-validator.js +469 -0
  190. package/dist/esm/modules/excel/worksheet.js +5 -2
  191. package/dist/esm/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.js +13 -1
  192. package/dist/esm/modules/excel/xlsx/xform/drawing/sp-xform.js +112 -0
  193. package/dist/esm/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +30 -2
  194. package/dist/esm/modules/excel/xlsx/xform/drawing/vml-drawing-xform.js +11 -0
  195. package/dist/esm/modules/excel/xlsx/xform/sheet/page-setup-xform.js +16 -2
  196. package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +110 -12
  197. package/dist/esm/modules/excel/xlsx/xlsx.browser.js +3 -6
  198. package/dist/esm/modules/excel/xlsx/xlsx.js +1 -1
  199. package/dist/esm/modules/stream/base-transform.js +34 -20
  200. package/dist/esm/modules/stream/chunked-builder.js +4 -4
  201. package/dist/esm/modules/stream/index.browser.js +10 -22
  202. package/dist/esm/modules/stream/index.js +15 -44
  203. package/dist/esm/modules/stream/internal/event-utils.js +40 -0
  204. package/dist/esm/modules/stream/internal/type-guards.js +24 -0
  205. package/dist/esm/modules/stream/pull-stream.js +107 -43
  206. package/dist/esm/modules/stream/shared.js +7 -4
  207. package/dist/esm/modules/stream/streams.browser.js +921 -836
  208. package/dist/esm/modules/stream/streams.js +146 -95
  209. package/dist/esm/modules/stream/utils.js +5 -38
  210. package/dist/iife/THIRD_PARTY_NOTICES.md +0 -31
  211. package/dist/iife/excelts.iife.js +6495 -4440
  212. package/dist/iife/excelts.iife.js.map +1 -1
  213. package/dist/iife/excelts.iife.min.js +103 -31
  214. package/dist/types/index.browser.d.ts +1 -0
  215. package/dist/{browser/modules/archive → types/modules/archive/compression}/compress.browser.d.ts +2 -8
  216. package/dist/types/modules/archive/{streaming-compress.browser.d.ts → compression/streaming-compress.browser.d.ts} +1 -1
  217. package/dist/types/modules/archive/defaults.d.ts +1 -0
  218. package/dist/types/modules/archive/index.base.d.ts +4 -4
  219. package/dist/types/modules/archive/index.browser.d.ts +3 -4
  220. package/dist/types/modules/archive/index.d.ts +3 -4
  221. package/dist/types/modules/archive/internal/byte-queue.d.ts +33 -0
  222. package/dist/types/modules/archive/io/archive-sink.d.ts +8 -0
  223. package/dist/types/modules/archive/io/archive-source.d.ts +6 -0
  224. package/dist/types/modules/archive/unzip/index.d.ts +40 -0
  225. package/dist/types/modules/archive/{parse.base.d.ts → unzip/stream.base.d.ts} +38 -4
  226. package/dist/types/modules/archive/{parse.browser.d.ts → unzip/stream.browser.d.ts} +2 -2
  227. package/dist/types/modules/archive/{parse.d.ts → unzip/stream.d.ts} +3 -3
  228. package/dist/types/modules/archive/{zip-parser.d.ts → unzip/zip-parser.d.ts} +1 -1
  229. package/dist/types/modules/archive/utils/async-queue.d.ts +7 -0
  230. package/dist/types/modules/archive/utils/compressibility.d.ts +10 -0
  231. package/dist/types/modules/archive/utils/pattern-scanner.d.ts +21 -0
  232. package/dist/types/modules/archive/utils/zip-extra-fields.d.ts +1 -1
  233. package/dist/types/modules/archive/zip/index.d.ts +42 -0
  234. package/dist/types/modules/archive/{streaming-zip.d.ts → zip/stream.d.ts} +29 -6
  235. package/dist/types/modules/archive/zip/zip-bytes.d.ts +73 -0
  236. package/dist/types/modules/archive/{zip-entry-metadata.d.ts → zip/zip-entry-metadata.d.ts} +1 -1
  237. package/dist/types/modules/archive/{zip-records.d.ts → zip-spec/zip-records.d.ts} +20 -0
  238. package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +1 -1
  239. package/dist/types/modules/excel/utils/ooxml-validator.d.ts +48 -0
  240. package/dist/types/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.d.ts +1 -0
  241. package/dist/types/modules/excel/xlsx/xform/drawing/sp-xform.d.ts +18 -0
  242. package/dist/types/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.d.ts +6 -1
  243. package/dist/types/modules/excel/xlsx/xform/sheet/page-setup-xform.d.ts +1 -0
  244. package/dist/types/modules/stream/base-transform.d.ts +3 -0
  245. package/dist/types/modules/stream/buffered-stream.d.ts +2 -12
  246. package/dist/types/modules/stream/index.browser.d.ts +13 -19
  247. package/dist/types/modules/stream/index.d.ts +18 -41
  248. package/dist/types/modules/stream/internal/event-utils.d.ts +17 -0
  249. package/dist/types/modules/stream/internal/type-guards.d.ts +9 -0
  250. package/dist/types/modules/stream/pull-stream.d.ts +5 -6
  251. package/dist/types/modules/stream/shared.d.ts +1 -1
  252. package/dist/types/modules/stream/streams.browser.d.ts +32 -44
  253. package/dist/types/modules/stream/streams.d.ts +4 -20
  254. package/package.json +14 -10
  255. package/dist/browser/modules/archive/byte-queue.d.ts +0 -18
  256. package/dist/browser/modules/archive/byte-queue.js +0 -125
  257. package/dist/browser/modules/archive/parse.base.js +0 -644
  258. package/dist/browser/modules/archive/utils/zip-extra.d.ts +0 -18
  259. package/dist/browser/modules/archive/utils/zip-extra.js +0 -68
  260. package/dist/browser/modules/archive/zip-builder.d.ts +0 -117
  261. package/dist/browser/modules/archive/zip-builder.js +0 -292
  262. package/dist/browser/modules/archive/zip-constants.d.ts +0 -18
  263. package/dist/browser/modules/archive/zip-constants.js +0 -23
  264. package/dist/browser/modules/archive/zip-records.js +0 -84
  265. package/dist/cjs/modules/archive/byte-queue.js +0 -129
  266. package/dist/cjs/modules/archive/parse.base.js +0 -666
  267. package/dist/cjs/modules/archive/utils/zip-extra.js +0 -74
  268. package/dist/cjs/modules/archive/zip-builder.js +0 -297
  269. package/dist/cjs/modules/archive/zip-constants.js +0 -26
  270. package/dist/cjs/modules/archive/zip-records.js +0 -90
  271. package/dist/esm/modules/archive/byte-queue.js +0 -125
  272. package/dist/esm/modules/archive/parse.base.js +0 -644
  273. package/dist/esm/modules/archive/utils/zip-extra.js +0 -68
  274. package/dist/esm/modules/archive/zip-builder.js +0 -292
  275. package/dist/esm/modules/archive/zip-constants.js +0 -23
  276. package/dist/esm/modules/archive/zip-records.js +0 -84
  277. package/dist/types/modules/archive/byte-queue.d.ts +0 -18
  278. package/dist/types/modules/archive/utils/zip-extra.d.ts +0 -18
  279. package/dist/types/modules/archive/zip-builder.d.ts +0 -117
  280. package/dist/types/modules/archive/zip-constants.d.ts +0 -18
  281. /package/dist/browser/modules/archive/{compress.base.d.ts → compression/compress.base.d.ts} +0 -0
  282. /package/dist/browser/modules/archive/{crc32.base.d.ts → compression/crc32.base.d.ts} +0 -0
  283. /package/dist/browser/modules/archive/{crc32.base.js → compression/crc32.base.js} +0 -0
  284. /package/dist/browser/modules/archive/{crc32.browser.js → compression/crc32.browser.js} +0 -0
  285. /package/dist/browser/modules/archive/{deflate-fallback.d.ts → compression/deflate-fallback.d.ts} +0 -0
  286. /package/dist/browser/modules/archive/{streaming-compress.base.d.ts → compression/streaming-compress.base.d.ts} +0 -0
  287. /package/dist/browser/modules/archive/{streaming-compress.base.js → compression/streaming-compress.base.js} +0 -0
  288. /package/dist/browser/modules/archive/{extract.js → unzip/extract.js} +0 -0
  289. /package/dist/browser/modules/archive/{zip-entry-metadata.d.ts → zip/zip-entry-metadata.d.ts} +0 -0
  290. /package/dist/browser/modules/archive/{zip-entry-info.d.ts → zip-spec/zip-entry-info.d.ts} +0 -0
  291. /package/dist/browser/modules/archive/{zip-entry-info.js → zip-spec/zip-entry-info.js} +0 -0
  292. /package/dist/cjs/modules/archive/{crc32.base.js → compression/crc32.base.js} +0 -0
  293. /package/dist/cjs/modules/archive/{crc32.browser.js → compression/crc32.browser.js} +0 -0
  294. /package/dist/cjs/modules/archive/{streaming-compress.base.js → compression/streaming-compress.base.js} +0 -0
  295. /package/dist/cjs/modules/archive/{extract.js → unzip/extract.js} +0 -0
  296. /package/dist/cjs/modules/archive/{zip-entry-info.js → zip-spec/zip-entry-info.js} +0 -0
  297. /package/dist/esm/modules/archive/{crc32.base.js → compression/crc32.base.js} +0 -0
  298. /package/dist/esm/modules/archive/{crc32.browser.js → compression/crc32.browser.js} +0 -0
  299. /package/dist/esm/modules/archive/{streaming-compress.base.js → compression/streaming-compress.base.js} +0 -0
  300. /package/dist/esm/modules/archive/{extract.js → unzip/extract.js} +0 -0
  301. /package/dist/esm/modules/archive/{zip-entry-info.js → zip-spec/zip-entry-info.js} +0 -0
  302. /package/dist/types/modules/archive/{compress.base.d.ts → compression/compress.base.d.ts} +0 -0
  303. /package/dist/types/modules/archive/{compress.d.ts → compression/compress.d.ts} +0 -0
  304. /package/dist/types/modules/archive/{crc32.base.d.ts → compression/crc32.base.d.ts} +0 -0
  305. /package/dist/types/modules/archive/{crc32.browser.d.ts → compression/crc32.browser.d.ts} +0 -0
  306. /package/dist/types/modules/archive/{crc32.d.ts → compression/crc32.d.ts} +0 -0
  307. /package/dist/types/modules/archive/{deflate-fallback.d.ts → compression/deflate-fallback.d.ts} +0 -0
  308. /package/dist/types/modules/archive/{streaming-compress.base.d.ts → compression/streaming-compress.base.d.ts} +0 -0
  309. /package/dist/types/modules/archive/{streaming-compress.d.ts → compression/streaming-compress.d.ts} +0 -0
  310. /package/dist/types/modules/archive/{extract.d.ts → unzip/extract.d.ts} +0 -0
  311. /package/dist/types/modules/archive/{zip-entry-info.d.ts → zip-spec/zip-entry-info.d.ts} +0 -0
@@ -0,0 +1,157 @@
1
+ import { DEFAULT_ZIP_LEVEL, DEFAULT_ZIP_TIMESTAMPS } from "../defaults.js";
2
+ import { ZipDeflateFile, StreamingZip } from "./stream.js";
3
+ import { createZip, createZipSync } from "./zip-bytes.js";
4
+ import { collect, pipeIterableToSink } from "../io/archive-sink.js";
5
+ import { toAsyncIterable, toUint8Array, toUint8ArraySync } from "../io/archive-source.js";
6
+ import { createAsyncQueue } from "../utils/async-queue.js";
7
+ const REPRODUCIBLE_ZIP_MOD_TIME = new Date(1980, 0, 1, 0, 0, 0);
8
+ export class ZipArchive {
9
+ constructor(options = {}) {
10
+ this._entries = [];
11
+ this._sealed = false;
12
+ const reproducible = options.reproducible ?? false;
13
+ this._options = {
14
+ level: options.level ?? DEFAULT_ZIP_LEVEL,
15
+ timestamps: options.timestamps ?? (reproducible ? "dos" : DEFAULT_ZIP_TIMESTAMPS),
16
+ comment: options.comment,
17
+ modTime: options.modTime ?? (reproducible ? REPRODUCIBLE_ZIP_MOD_TIME : new Date()),
18
+ smartStore: options.smartStore ?? true
19
+ };
20
+ }
21
+ add(name, source, options) {
22
+ if (this._sealed) {
23
+ throw new Error("Cannot add entries after output has started");
24
+ }
25
+ if (!name) {
26
+ throw new Error("Entry name is required");
27
+ }
28
+ this._entries.push({ name, source, options });
29
+ return this;
30
+ }
31
+ stream() {
32
+ this._sealed = true;
33
+ const queue = createAsyncQueue();
34
+ const zip = new StreamingZip((err, data, final) => {
35
+ if (err) {
36
+ queue.fail(err);
37
+ return;
38
+ }
39
+ if (data.length) {
40
+ queue.push(data);
41
+ }
42
+ if (final) {
43
+ queue.close();
44
+ }
45
+ }, { comment: this._options.comment });
46
+ (async () => {
47
+ try {
48
+ for (const entry of this._entries) {
49
+ const level = entry.options?.level ?? this._options.level;
50
+ const file = new ZipDeflateFile(entry.name, {
51
+ level,
52
+ modTime: entry.options?.modTime ?? this._options.modTime,
53
+ timestamps: this._options.timestamps,
54
+ comment: entry.options?.comment,
55
+ smartStore: this._options.smartStore
56
+ });
57
+ zip.add(file);
58
+ // Feed data
59
+ if (entry.source instanceof Uint8Array ||
60
+ entry.source instanceof ArrayBuffer ||
61
+ typeof entry.source === "string" ||
62
+ (typeof Blob !== "undefined" && entry.source instanceof Blob)) {
63
+ const bytes = await toUint8Array(entry.source);
64
+ await file.push(bytes, true);
65
+ }
66
+ else {
67
+ for await (const chunk of toAsyncIterable(entry.source)) {
68
+ await file.push(chunk, false);
69
+ }
70
+ await file.push(new Uint8Array(0), true);
71
+ }
72
+ await file.complete();
73
+ }
74
+ zip.end();
75
+ }
76
+ catch (e) {
77
+ queue.fail(e instanceof Error ? e : new Error(String(e)));
78
+ }
79
+ })();
80
+ return queue.iterable;
81
+ }
82
+ async bytes() {
83
+ this._sealed = true;
84
+ const allSourcesInMemory = this._entries.every(e => e.source instanceof Uint8Array ||
85
+ e.source instanceof ArrayBuffer ||
86
+ typeof e.source === "string" ||
87
+ (typeof Blob !== "undefined" && e.source instanceof Blob));
88
+ const hasBlobSource = this._entries.some(e => typeof Blob !== "undefined" && e.source instanceof Blob);
89
+ // Fast-path: when all sources are already in memory and there are no
90
+ // per-entry compression overrides, use the single-buffer ZIP builder.
91
+ // This avoids the overhead of chunking + collecting from the streaming writer.
92
+ if (allSourcesInMemory) {
93
+ // Prefer the sync builder when possible (Node.js hot path): it avoids
94
+ // async/Promise overhead and uses zlib sync fast paths.
95
+ if (!hasBlobSource) {
96
+ const entries = this._entries.map(e => ({
97
+ name: e.name,
98
+ data: toUint8ArraySync(e.source),
99
+ level: e.options?.level,
100
+ modTime: e.options?.modTime,
101
+ comment: e.options?.comment
102
+ }));
103
+ return createZipSync(entries, {
104
+ level: this._options.level,
105
+ timestamps: this._options.timestamps,
106
+ modTime: this._options.modTime,
107
+ comment: this._options.comment,
108
+ smartStore: this._options.smartStore
109
+ });
110
+ }
111
+ const entries = await Promise.all(this._entries.map(async (e) => ({
112
+ name: e.name,
113
+ data: await toUint8Array(e.source),
114
+ level: e.options?.level,
115
+ modTime: e.options?.modTime,
116
+ comment: e.options?.comment
117
+ })));
118
+ return createZip(entries, {
119
+ level: this._options.level,
120
+ timestamps: this._options.timestamps,
121
+ modTime: this._options.modTime,
122
+ comment: this._options.comment,
123
+ smartStore: this._options.smartStore
124
+ });
125
+ }
126
+ return collect(this.stream());
127
+ }
128
+ bytesSync() {
129
+ this._sealed = true;
130
+ const entries = this._entries.map(e => {
131
+ if (!(e.source instanceof Uint8Array) &&
132
+ !(e.source instanceof ArrayBuffer) &&
133
+ typeof e.source !== "string") {
134
+ throw new Error("bytesSync() only supports Uint8Array/ArrayBuffer/string sources");
135
+ }
136
+ return {
137
+ name: e.name,
138
+ data: toUint8ArraySync(e.source),
139
+ modTime: e.options?.modTime,
140
+ comment: e.options?.comment
141
+ };
142
+ });
143
+ return createZipSync(entries, {
144
+ level: this._options.level,
145
+ timestamps: this._options.timestamps,
146
+ modTime: this._options.modTime,
147
+ comment: this._options.comment,
148
+ smartStore: this._options.smartStore
149
+ });
150
+ }
151
+ async pipeTo(sink) {
152
+ await pipeIterableToSink(this.stream(), sink);
153
+ }
154
+ }
155
+ export function zip(options) {
156
+ return new ZipArchive(options);
157
+ }
@@ -2,15 +2,16 @@
2
2
  * True Streaming ZIP creator - shared implementation.
3
3
  *
4
4
  * This module is intentionally platform-agnostic.
5
- * - In Node builds it uses `./crc32` + `./streaming-compress` (zlib-backed).
5
+ * - In Node builds it uses `./compression/crc32` + `./compression/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 "./crc32.js";
9
- import { createDeflateStream } from "./streaming-compress.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";
8
+ import { crc32Update, crc32Finalize } from "../compression/crc32.js";
9
+ import { createDeflateStream } from "../compression/streaming-compress.js";
10
+ import { DEFAULT_ZIP_LEVEL, DEFAULT_ZIP_TIMESTAMPS } from "../defaults.js";
11
+ import { buildZipEntryMetadata, resolveZipCompressionMethod } from "./zip-entry-metadata.js";
12
+ import { decodeUtf8, encodeUtf8 } from "../utils/text.js";
13
+ import { isProbablyIncompressible } from "../utils/compressibility.js";
14
+ import { buildCentralDirectoryHeader, buildDataDescriptor, buildEndOfCentralDirectory, buildLocalFileHeader, VERSION_MADE_BY, VERSION_NEEDED } from "../zip-spec/zip-records.js";
14
15
  /**
15
16
  * True Streaming ZIP File - compresses chunk by chunk
16
17
  */
@@ -23,9 +24,15 @@ export class ZipDeflateFile {
23
24
  this._finalized = false;
24
25
  this._headerEmitted = false;
25
26
  this._ondata = null;
27
+ this._onerror = null;
26
28
  this._centralDirEntryInfo = null;
27
29
  this._pendingEnd = false;
28
30
  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;
29
36
  // Promise resolution for completion (including data descriptor)
30
37
  this._completeResolve = null;
31
38
  this._completeReject = null;
@@ -34,46 +41,70 @@ export class ZipDeflateFile {
34
41
  // Queue for incoming data before ondata is set
35
42
  this._dataQueue = [];
36
43
  this._finalQueued = false;
44
+ // Serialize push() calls so callers don't need to await to preserve ordering.
45
+ this._pushChain = Promise.resolve();
37
46
  this.name = name;
38
47
  const modTime = options?.modTime ?? new Date();
39
48
  this._modTime = modTime;
40
49
  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);
41
52
  const metadata = buildZipEntryMetadata({
42
53
  name,
43
- comment: "",
54
+ comment: options?.comment ?? "",
44
55
  modTime,
45
56
  timestamps: options?.timestamps ?? DEFAULT_ZIP_TIMESTAMPS,
46
57
  useDataDescriptor: true,
47
- deflate: this.level > 0
58
+ deflate: false
48
59
  });
49
60
  this.nameBytes = metadata.nameBytes;
61
+ this.commentBytes = metadata.commentBytes;
50
62
  this.dosTime = metadata.dosTime;
51
63
  this.dosDate = metadata.dosDate;
52
64
  this.extraField = metadata.extraField;
53
65
  this._flags = metadata.flags;
54
66
  this._compressionMethod = metadata.compressionMethod;
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
- });
67
+ // If smart store is disabled, decide method upfront and keep true streaming semantics.
68
+ if (!this._smartStore) {
69
+ const deflate = this.level > 0;
70
+ this._deflateWanted = deflate;
71
+ this._compressionMethod = this._buildCompressionMethod(deflate);
72
+ if (deflate) {
73
+ this._initDeflateStream();
74
+ }
75
+ return;
75
76
  }
76
- this._localHeader = this._buildLocalHeader();
77
+ // Level 0: always STORE.
78
+ if (this.level === 0) {
79
+ this._deflateWanted = false;
80
+ this._compressionMethod = this._buildCompressionMethod(false);
81
+ }
82
+ }
83
+ _buildCompressionMethod(deflate) {
84
+ return resolveZipCompressionMethod(deflate);
85
+ }
86
+ _initDeflateStream() {
87
+ if (this._deflate) {
88
+ return;
89
+ }
90
+ this._deflate = createDeflateStream({ level: this.level });
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
+ });
77
108
  }
78
109
  _buildLocalHeader() {
79
110
  // CRC + sizes are written via data descriptor for true streaming.
@@ -90,6 +121,63 @@ export class ZipDeflateFile {
90
121
  versionNeeded: VERSION_NEEDED
91
122
  });
92
123
  }
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
+ }
93
181
  _enqueueData(data, final) {
94
182
  if (this._ondata) {
95
183
  this._ondata(data, final);
@@ -121,13 +209,29 @@ export class ZipDeflateFile {
121
209
  // Flush any queued data
122
210
  this._flushQueue();
123
211
  }
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
+ }
124
222
  _resolveComplete() {
125
223
  if (this._completeResolve) {
126
224
  this._completeResolve();
127
225
  }
128
226
  }
129
227
  _rejectComplete(err) {
228
+ if (this._completeError) {
229
+ return;
230
+ }
130
231
  this._completeError = err;
232
+ if (this._onerror) {
233
+ this._onerror(err);
234
+ }
131
235
  if (this._completeReject) {
132
236
  this._completeReject(err);
133
237
  }
@@ -153,13 +257,6 @@ export class ZipDeflateFile {
153
257
  }
154
258
  promise.then(() => callback()).catch(err => callback(err));
155
259
  }
156
- _emitHeaderIfNeeded() {
157
- if (this._headerEmitted) {
158
- return;
159
- }
160
- this._emitHeader();
161
- this._headerEmitted = true;
162
- }
163
260
  _writeData(data) {
164
261
  if (data.length === 0) {
165
262
  return Promise.resolve();
@@ -217,27 +314,60 @@ export class ZipDeflateFile {
217
314
  this._emitDataDescriptor();
218
315
  return completePromise;
219
316
  }
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) {
317
+ _pushUnchained(data, final, callback) {
226
318
  if (this._finalized) {
227
319
  const promise = Promise.reject(new Error("Cannot push to finalized ZipDeflateFile"));
228
320
  this._tapCallback(promise, callback);
229
321
  return promise;
230
322
  }
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
+ }
231
347
  this._emitHeaderIfNeeded();
232
348
  const writePromise = this._writeData(data);
233
349
  const promise = final ? this._finalizeAfterWrite(writePromise) : writePromise;
234
350
  this._tapCallback(promise, callback);
235
351
  return promise;
236
352
  }
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
+ }
237
364
  /**
238
365
  * Emit local file header with Data Descriptor flag
239
366
  */
240
367
  _emitHeader() {
368
+ if (!this._localHeader) {
369
+ this._localHeader = this._buildLocalHeader();
370
+ }
241
371
  this._enqueueData(this._localHeader, false);
242
372
  }
243
373
  /**
@@ -250,6 +380,7 @@ export class ZipDeflateFile {
250
380
  this._centralDirEntryInfo = {
251
381
  name: this.nameBytes,
252
382
  extraField: this.extraField,
383
+ comment: this.commentBytes,
253
384
  flags: this._flags,
254
385
  crc: crcValue,
255
386
  compressedSize: this._compressedSize,
@@ -288,7 +419,7 @@ export class ZipDeflateFile {
288
419
  crc32: this._centralDirEntryInfo.crc,
289
420
  lastModified: this._modTime,
290
421
  localHeaderOffset: this._centralDirEntryInfo.offset,
291
- comment: "",
422
+ comment: decodeUtf8(this._centralDirEntryInfo.comment),
292
423
  externalAttributes: 0,
293
424
  isEncrypted: false
294
425
  };
@@ -305,7 +436,7 @@ export class ZipDeflateFile {
305
436
  * Streaming ZIP Creator - processes files sequentially
306
437
  */
307
438
  export class StreamingZip {
308
- constructor(callback) {
439
+ constructor(callback, options) {
309
440
  this.entries = [];
310
441
  this.currentOffset = 0;
311
442
  this.ended = false;
@@ -315,10 +446,12 @@ export class StreamingZip {
315
446
  this.fileQueueIndex = 0;
316
447
  this.activeFile = null;
317
448
  this.callback = callback;
449
+ // Avoid per-instance TextEncoder allocations.
450
+ this.zipComment = options?.comment ? encodeUtf8(options.comment) : new Uint8Array(0);
318
451
  }
319
452
  add(file) {
320
453
  if (this.ended) {
321
- throw new Error("Cannot add files after calling end()");
454
+ throw new Error("Cannot add files after calling end() ");
322
455
  }
323
456
  this.fileQueue.push(file);
324
457
  // If no active file, process this one
@@ -341,7 +474,18 @@ export class StreamingZip {
341
474
  const file = this.fileQueue[this.fileQueueIndex++];
342
475
  this.activeFile = file;
343
476
  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
+ };
344
485
  file.ondata = (data, final) => {
486
+ if (this.ended) {
487
+ return;
488
+ }
345
489
  this.currentOffset += data.length;
346
490
  this.callback(null, data, false);
347
491
  if (final) {
@@ -367,7 +511,7 @@ export class StreamingZip {
367
511
  const header = buildCentralDirectoryHeader({
368
512
  fileName: entry.name,
369
513
  extraField: entry.extraField,
370
- comment: empty,
514
+ comment: entry.comment ?? empty,
371
515
  flags: entry.flags,
372
516
  compressionMethod: entry.compressionMethod,
373
517
  dosTime: entry.dosTime,
@@ -386,7 +530,7 @@ export class StreamingZip {
386
530
  entryCount: this.entries.length,
387
531
  centralDirSize,
388
532
  centralDirOffset,
389
- comment: empty
533
+ comment: this.zipComment
390
534
  });
391
535
  this.callback(null, eocd, true);
392
536
  }