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