@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
@@ -1,103 +0,0 @@
1
- export function createAsyncQueue() {
2
- const values = [];
3
- let valuesHead = 0;
4
- const waiters = [];
5
- let waitersHead = 0;
6
- let done = false;
7
- let error = null;
8
- const maybeCompact = () => {
9
- // Prevent unbounded growth of the underlying arrays.
10
- if (valuesHead > 1024 && valuesHead * 2 > values.length) {
11
- values.splice(0, valuesHead);
12
- valuesHead = 0;
13
- }
14
- if (waitersHead > 1024 && waitersHead * 2 > waiters.length) {
15
- waiters.splice(0, waitersHead);
16
- waitersHead = 0;
17
- }
18
- };
19
- const shiftWaiter = () => {
20
- while (waitersHead < waiters.length) {
21
- const w = waiters[waitersHead];
22
- waiters[waitersHead] = undefined;
23
- waitersHead++;
24
- if (w) {
25
- maybeCompact();
26
- return w;
27
- }
28
- }
29
- maybeCompact();
30
- return undefined;
31
- };
32
- const shiftValue = () => {
33
- while (valuesHead < values.length) {
34
- const v = values[valuesHead];
35
- values[valuesHead] = undefined;
36
- valuesHead++;
37
- if (v !== undefined) {
38
- maybeCompact();
39
- return v;
40
- }
41
- }
42
- maybeCompact();
43
- return undefined;
44
- };
45
- const push = (value) => {
46
- if (done || error) {
47
- return;
48
- }
49
- const waiter = shiftWaiter();
50
- if (waiter) {
51
- waiter.resolve({ value, done: false });
52
- }
53
- else {
54
- values.push(value);
55
- }
56
- };
57
- const fail = (err) => {
58
- if (done || error) {
59
- return;
60
- }
61
- error = err;
62
- while (true) {
63
- const waiter = shiftWaiter();
64
- if (!waiter) {
65
- break;
66
- }
67
- waiter.reject(err);
68
- }
69
- };
70
- const close = () => {
71
- if (done || error) {
72
- return;
73
- }
74
- done = true;
75
- while (true) {
76
- const waiter = shiftWaiter();
77
- if (!waiter) {
78
- break;
79
- }
80
- waiter.resolve({ value: undefined, done: true });
81
- }
82
- };
83
- const iterable = {
84
- [Symbol.asyncIterator]() {
85
- return {
86
- next() {
87
- if (error) {
88
- return Promise.reject(error);
89
- }
90
- const value = shiftValue();
91
- if (value !== undefined) {
92
- return Promise.resolve({ value, done: false });
93
- }
94
- if (done) {
95
- return Promise.resolve({ value: undefined, done: true });
96
- }
97
- return new Promise((resolve, reject) => waiters.push({ resolve, reject }));
98
- }
99
- };
100
- }
101
- };
102
- return { push, fail, close, iterable };
103
- }
@@ -1,57 +0,0 @@
1
- const DEFAULT_SAMPLE_BYTES = 64 * 1024;
2
- const MIN_DECISION_BYTES = 16 * 1024;
3
- function log2(x) {
4
- return Math.log(x) / Math.LN2;
5
- }
6
- function shannonEntropy(bytes) {
7
- const counts = new Uint32Array(256);
8
- for (let i = 0; i < bytes.length; i++) {
9
- counts[bytes[i]] += 1;
10
- }
11
- let entropy = 0;
12
- const total = bytes.length;
13
- for (let i = 0; i < 256; i++) {
14
- const count = counts[i];
15
- if (count === 0) {
16
- continue;
17
- }
18
- const p = count / total;
19
- entropy -= p * log2(p);
20
- }
21
- return entropy;
22
- }
23
- /**
24
- * Heuristic: detect incompressible (high-entropy) data.
25
- *
26
- * This is a performance optimization: if data looks random, DEFLATE usually
27
- * wastes CPU and may even produce slightly larger output.
28
- */
29
- export function isProbablyIncompressible(data, options = {}) {
30
- const sampleBytes = options.sampleBytes ?? DEFAULT_SAMPLE_BYTES;
31
- const minDecisionBytes = options.minDecisionBytes ?? MIN_DECISION_BYTES;
32
- const len = Math.min(data.length, sampleBytes);
33
- if (len < minDecisionBytes) {
34
- return false;
35
- }
36
- const sample = data.subarray(0, len);
37
- // Fast-ish early filter: if there are too few unique bytes, it's probably compressible.
38
- // (e.g. text, repeated patterns)
39
- const seen = new Uint8Array(256);
40
- let unique = 0;
41
- for (let i = 0; i < sample.length; i++) {
42
- const b = sample[i];
43
- if (seen[b] === 0) {
44
- seen[b] = 1;
45
- unique += 1;
46
- if (unique >= 200) {
47
- break;
48
- }
49
- }
50
- }
51
- if (unique < 200) {
52
- return false;
53
- }
54
- // Shannon entropy in bits/byte; random tends to ~8.
55
- // Threshold picked to be conservative.
56
- return shannonEntropy(sample) >= 7.95;
57
- }
@@ -1,27 +0,0 @@
1
- /**
2
- * Stateful helper for incremental pattern scanning in growing buffers.
3
- *
4
- * The scanner tracks a `searchFrom` cursor and an `overlap` region so callers
5
- * can avoid rescanning bytes that cannot start a match.
6
- */
7
- export class PatternScanner {
8
- constructor(pattern) {
9
- this.searchFrom = 0;
10
- this.pattern = pattern;
11
- this.overlap = Math.max(0, pattern.length - 1);
12
- }
13
- /** Find the next match index starting at the current `searchFrom`. */
14
- find(target) {
15
- return target.indexOfPattern(this.pattern, this.searchFrom);
16
- }
17
- /** Update `searchFrom` after consuming `consumed` bytes from the front. */
18
- onConsume(consumed) {
19
- if (consumed > 0) {
20
- this.searchFrom = Math.max(0, this.searchFrom - consumed);
21
- }
22
- }
23
- /** Update `searchFrom` after a no-match scan on a buffer of length `bufferLength`. */
24
- onNoMatch(bufferLength) {
25
- this.searchFrom = Math.max(this.searchFrom, Math.max(0, bufferLength - this.overlap));
26
- }
27
- }
@@ -1,157 +0,0 @@
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
- }
@@ -1,239 +0,0 @@
1
- /**
2
- * ZIP file format encoder (single-buffer output)
3
- *
4
- * Implements ZIP file structure according to PKWARE's APPNOTE.TXT specification
5
- * https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
6
- *
7
- * This module focuses on producing a complete ZIP as a single Uint8Array.
8
- * For true streaming (push chunks while reading sources), use `zip()` / `ZipArchive.stream()`.
9
- */
10
- import { compress, compressSync } from "../compression/compress.js";
11
- import { crc32 } from "../compression/crc32.js";
12
- import { DEFAULT_ZIP_LEVEL, DEFAULT_ZIP_TIMESTAMPS } from "../defaults.js";
13
- import { isProbablyIncompressible } from "../utils/compressibility.js";
14
- import { encodeUtf8 } from "../utils/text.js";
15
- import {} from "../utils/timestamps.js";
16
- import { buildZipEntryMetadata, resolveZipCompressionMethod } from "./zip-entry-metadata.js";
17
- import { FLAG_UTF8, ZIP_CENTRAL_DIR_HEADER_FIXED_SIZE, ZIP_END_OF_CENTRAL_DIR_FIXED_SIZE, ZIP_LOCAL_FILE_HEADER_FIXED_SIZE, writeCentralDirectoryHeaderInto, writeEndOfCentralDirectoryInto, writeLocalFileHeaderInto } from "../zip-spec/zip-records.js";
18
- const REPRODUCIBLE_ZIP_MOD_TIME = new Date(1980, 0, 1, 0, 0, 0);
19
- function encodeZipComment(comment) {
20
- // Keep empty comment as empty bytes (no encoding surprises).
21
- return comment ? encodeUtf8(comment) : new Uint8Array(0);
22
- }
23
- function shouldDeflate(level, data) {
24
- return level > 0 && data.length > 0;
25
- }
26
- async function compressEntryMaybe(entry, level, compressOptions, smartStore) {
27
- if (!shouldDeflate(level, entry.data)) {
28
- return { compressedData: entry.data, deflate: false };
29
- }
30
- if (!smartStore) {
31
- const compressed = await compress(entry.data, compressOptions);
32
- return { compressedData: compressed, deflate: true };
33
- }
34
- // Heuristic: skip deflate for high-entropy inputs.
35
- if (isProbablyIncompressible(entry.data)) {
36
- return { compressedData: entry.data, deflate: false };
37
- }
38
- const compressed = await compress(entry.data, compressOptions);
39
- if (compressed.length >= entry.data.length) {
40
- return { compressedData: entry.data, deflate: false };
41
- }
42
- return { compressedData: compressed, deflate: true };
43
- }
44
- function compressEntryMaybeSync(entry, level, compressOptions, smartStore) {
45
- if (!shouldDeflate(level, entry.data)) {
46
- return { compressedData: entry.data, deflate: false };
47
- }
48
- if (!smartStore) {
49
- const compressed = compressSync(entry.data, compressOptions);
50
- return { compressedData: compressed, deflate: true };
51
- }
52
- if (isProbablyIncompressible(entry.data)) {
53
- return { compressedData: entry.data, deflate: false };
54
- }
55
- const compressed = compressSync(entry.data, compressOptions);
56
- if (compressed.length >= entry.data.length) {
57
- return { compressedData: entry.data, deflate: false };
58
- }
59
- return { compressedData: compressed, deflate: true };
60
- }
61
- function computeLocalRecordSize(entry) {
62
- return (ZIP_LOCAL_FILE_HEADER_FIXED_SIZE +
63
- entry.name.length +
64
- entry.extraField.length +
65
- entry.compressedData.length);
66
- }
67
- function computeCentralDirHeaderSize(entry) {
68
- return (ZIP_CENTRAL_DIR_HEADER_FIXED_SIZE +
69
- entry.name.length +
70
- entry.extraField.length +
71
- entry.comment.length);
72
- }
73
- function buildProcessedEntry(entry, offset, settings, compressedData, deflate) {
74
- const modDate = entry.modTime ?? settings.defaultModTime;
75
- const metadata = buildZipEntryMetadata({
76
- name: entry.name,
77
- comment: entry.comment,
78
- modTime: modDate,
79
- timestamps: settings.timestamps,
80
- useDataDescriptor: false,
81
- deflate
82
- });
83
- return {
84
- name: metadata.nameBytes,
85
- uncompressedSize: entry.data.length,
86
- compressedData,
87
- crc: crc32(entry.data),
88
- compressionMethod: resolveZipCompressionMethod(deflate),
89
- modTime: metadata.dosTime,
90
- modDate: metadata.dosDate,
91
- extraField: metadata.extraField,
92
- comment: metadata.commentBytes,
93
- offset
94
- };
95
- }
96
- function appendProcessedEntry(processedEntries, entry, compressedData, deflate, currentOffset, settings) {
97
- const processedEntry = buildProcessedEntry(entry, currentOffset, settings, compressedData, deflate);
98
- processedEntries.push(processedEntry);
99
- return {
100
- processedEntry,
101
- nextOffset: currentOffset + computeLocalRecordSize(processedEntry)
102
- };
103
- }
104
- function finalizeZip(processedEntries, zipComment) {
105
- // Assemble ZIP into a single buffer to reduce allocations and copying.
106
- let localSectionSize = 0;
107
- let centralDirSize = 0;
108
- for (const entry of processedEntries) {
109
- localSectionSize += computeLocalRecordSize(entry);
110
- centralDirSize += computeCentralDirHeaderSize(entry);
111
- }
112
- // The central directory should start immediately after local section.
113
- const centralDirOffset = localSectionSize;
114
- const totalSize = localSectionSize + centralDirSize + ZIP_END_OF_CENTRAL_DIR_FIXED_SIZE + zipComment.length;
115
- const out = new Uint8Array(totalSize);
116
- const view = new DataView(out.buffer, out.byteOffset, out.byteLength);
117
- let offset = 0;
118
- // Local file headers and data
119
- for (const entry of processedEntries) {
120
- offset += writeLocalFileHeaderInto(out, view, offset, {
121
- fileName: entry.name,
122
- extraField: entry.extraField,
123
- flags: FLAG_UTF8,
124
- compressionMethod: entry.compressionMethod,
125
- dosTime: entry.modTime,
126
- dosDate: entry.modDate,
127
- crc32: entry.crc,
128
- compressedSize: entry.compressedData.length,
129
- uncompressedSize: entry.uncompressedSize
130
- });
131
- out.set(entry.compressedData, offset);
132
- offset += entry.compressedData.length;
133
- }
134
- // Central directory headers
135
- for (const entry of processedEntries) {
136
- offset += writeCentralDirectoryHeaderInto(out, view, offset, {
137
- fileName: entry.name,
138
- extraField: entry.extraField,
139
- comment: entry.comment,
140
- flags: FLAG_UTF8,
141
- compressionMethod: entry.compressionMethod,
142
- dosTime: entry.modTime,
143
- dosDate: entry.modDate,
144
- crc32: entry.crc,
145
- compressedSize: entry.compressedData.length,
146
- uncompressedSize: entry.uncompressedSize,
147
- localHeaderOffset: entry.offset
148
- });
149
- }
150
- // End of central directory
151
- writeEndOfCentralDirectoryInto(out, view, offset, {
152
- entryCount: processedEntries.length,
153
- centralDirSize,
154
- centralDirOffset,
155
- comment: zipComment
156
- });
157
- return out;
158
- }
159
- /**
160
- * Create a ZIP file from entries (async)
161
- */
162
- export async function createZip(entries, options = {}) {
163
- const reproducible = options.reproducible ?? false;
164
- const level = options.level ?? DEFAULT_ZIP_LEVEL;
165
- const smartStore = options.smartStore ?? true;
166
- const concurrency = options.concurrency ?? 4;
167
- const timestamps = options.timestamps ?? (reproducible ? "dos" : DEFAULT_ZIP_TIMESTAMPS);
168
- const zipComment = encodeZipComment(options.comment);
169
- const defaultModTime = options.modTime ?? (reproducible ? REPRODUCIBLE_ZIP_MOD_TIME : new Date());
170
- const settings = {
171
- level,
172
- timestamps,
173
- defaultModTime
174
- };
175
- const thresholdBytes = options.thresholdBytes;
176
- const limit = Math.max(1, Math.floor(concurrency));
177
- const processedEntries = new Array(entries.length);
178
- if (entries.length > 0) {
179
- let nextIndex = 0;
180
- const workerCount = Math.min(limit, entries.length);
181
- const workers = Array.from({ length: workerCount }, async () => {
182
- while (true) {
183
- const idx = nextIndex++;
184
- if (idx >= entries.length) {
185
- return;
186
- }
187
- const entry = entries[idx];
188
- const entryLevel = entry.level ?? level;
189
- const compressOptions = {
190
- level: entryLevel,
191
- thresholdBytes
192
- };
193
- const { compressedData, deflate } = await compressEntryMaybe(entry, entryLevel, compressOptions, smartStore);
194
- processedEntries[idx] = buildProcessedEntry(entry, 0, settings, compressedData, deflate);
195
- }
196
- });
197
- await Promise.all(workers);
198
- }
199
- // Compute offsets in original order.
200
- let currentOffset = 0;
201
- for (let i = 0; i < processedEntries.length; i++) {
202
- const processedEntry = processedEntries[i];
203
- processedEntry.offset = currentOffset;
204
- currentOffset += computeLocalRecordSize(processedEntry);
205
- }
206
- return finalizeZip(processedEntries, zipComment);
207
- }
208
- /**
209
- * Create a ZIP file from entries (sync)
210
- *
211
- * This is supported in both Node.js and browser builds.
212
- */
213
- export function createZipSync(entries, options = {}) {
214
- const reproducible = options.reproducible ?? false;
215
- const level = options.level ?? DEFAULT_ZIP_LEVEL;
216
- const smartStore = options.smartStore ?? true;
217
- const timestamps = options.timestamps ?? (reproducible ? "dos" : DEFAULT_ZIP_TIMESTAMPS);
218
- const zipComment = encodeZipComment(options.comment);
219
- const defaultModTime = options.modTime ?? (reproducible ? REPRODUCIBLE_ZIP_MOD_TIME : new Date());
220
- const settings = {
221
- level,
222
- timestamps,
223
- defaultModTime
224
- };
225
- const thresholdBytes = options.thresholdBytes;
226
- const processedEntries = [];
227
- let currentOffset = 0;
228
- for (const entry of entries) {
229
- const entryLevel = entry.level ?? level;
230
- const compressOptions = {
231
- level: entryLevel,
232
- thresholdBytes
233
- };
234
- const { compressedData, deflate } = compressEntryMaybeSync(entry, entryLevel, compressOptions, smartStore);
235
- const result = appendProcessedEntry(processedEntries, entry, compressedData, deflate, currentOffset, settings);
236
- currentOffset = result.nextOffset;
237
- }
238
- return finalizeZip(processedEntries, zipComment);
239
- }