@ddunigma/node 2.1.1 → 2.2.0

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 (70) hide show
  1. package/README.md +101 -11
  2. package/dist/DduStream-KO75MEEM.js +2 -0
  3. package/dist/chunk-CZMUPXSK.js +5 -0
  4. package/dist/index.cjs +8 -0
  5. package/dist/index.d.cts +813 -0
  6. package/dist/index.d.ts +813 -0
  7. package/dist/index.js +5 -0
  8. package/package.json +33 -15
  9. package/dist/cjs/base/BaseDdu.d.ts +0 -53
  10. package/dist/cjs/base/BaseDdu.js +0 -29
  11. package/dist/cjs/base/index.d.ts +0 -1
  12. package/dist/cjs/base/index.js +0 -5
  13. package/dist/cjs/charSets/index.d.ts +0 -18
  14. package/dist/cjs/charSets/index.js +0 -4385
  15. package/dist/cjs/encoders/Ddu64.d.ts +0 -302
  16. package/dist/cjs/encoders/Ddu64.js +0 -1308
  17. package/dist/cjs/encoders/index.d.ts +0 -1
  18. package/dist/cjs/encoders/index.js +0 -5
  19. package/dist/cjs/index.d.ts +0 -5
  20. package/dist/cjs/index.js +0 -16
  21. package/dist/cjs/package.json +0 -3
  22. package/dist/cjs/types/DduDefaultTypes.d.ts +0 -3
  23. package/dist/cjs/types/DduDefaultTypes.js +0 -17
  24. package/dist/cjs/types/DduEnums.d.ts +0 -6
  25. package/dist/cjs/types/DduEnums.js +0 -10
  26. package/dist/cjs/types/DduInterface.d.ts +0 -91
  27. package/dist/cjs/types/DduInterface.js +0 -2
  28. package/dist/cjs/types/index.d.ts +0 -3
  29. package/dist/cjs/types/index.js +0 -19
  30. package/dist/cjs/utils/CharsetBuilder.d.ts +0 -129
  31. package/dist/cjs/utils/CharsetBuilder.js +0 -246
  32. package/dist/cjs/utils/DduPipeline.d.ts +0 -114
  33. package/dist/cjs/utils/DduPipeline.js +0 -229
  34. package/dist/cjs/utils/DduStream.d.ts +0 -64
  35. package/dist/cjs/utils/DduStream.js +0 -221
  36. package/dist/cjs/utils/crypto.d.ts +0 -30
  37. package/dist/cjs/utils/crypto.js +0 -84
  38. package/dist/cjs/utils/index.d.ts +0 -3
  39. package/dist/cjs/utils/index.js +0 -12
  40. package/dist/mjs/base/BaseDdu.d.ts +0 -53
  41. package/dist/mjs/base/BaseDdu.js +0 -23
  42. package/dist/mjs/base/index.d.ts +0 -1
  43. package/dist/mjs/base/index.js +0 -1
  44. package/dist/mjs/charSets/index.d.ts +0 -18
  45. package/dist/mjs/charSets/index.js +0 -4380
  46. package/dist/mjs/encoders/Ddu64.d.ts +0 -302
  47. package/dist/mjs/encoders/Ddu64.js +0 -1343
  48. package/dist/mjs/encoders/index.d.ts +0 -1
  49. package/dist/mjs/encoders/index.js +0 -1
  50. package/dist/mjs/index.d.ts +0 -5
  51. package/dist/mjs/index.js +0 -4
  52. package/dist/mjs/package.json +0 -3
  53. package/dist/mjs/types/DduDefaultTypes.d.ts +0 -3
  54. package/dist/mjs/types/DduDefaultTypes.js +0 -14
  55. package/dist/mjs/types/DduEnums.d.ts +0 -6
  56. package/dist/mjs/types/DduEnums.js +0 -7
  57. package/dist/mjs/types/DduInterface.d.ts +0 -91
  58. package/dist/mjs/types/DduInterface.js +0 -1
  59. package/dist/mjs/types/index.d.ts +0 -3
  60. package/dist/mjs/types/index.js +0 -3
  61. package/dist/mjs/utils/CharsetBuilder.d.ts +0 -129
  62. package/dist/mjs/utils/CharsetBuilder.js +0 -241
  63. package/dist/mjs/utils/DduPipeline.d.ts +0 -114
  64. package/dist/mjs/utils/DduPipeline.js +0 -223
  65. package/dist/mjs/utils/DduStream.d.ts +0 -64
  66. package/dist/mjs/utils/DduStream.js +0 -225
  67. package/dist/mjs/utils/crypto.d.ts +0 -30
  68. package/dist/mjs/utils/crypto.js +0 -78
  69. package/dist/mjs/utils/index.d.ts +0 -3
  70. package/dist/mjs/utils/index.js +0 -3
package/README.md CHANGED
@@ -8,6 +8,12 @@ Node.js implementation of [ddunigma](https://github.com/i3l3/ddunigma) (Python o
8
8
 
9
9
  커스텀 charset을 사용하는 Base64 스타일 인코더/디코더 라이브러리입니다.
10
10
 
11
+ ## Documents
12
+
13
+ - `README.md`: 설치, 사용법, 공개 API 요약
14
+ - `CHANGELOG.md`: 공개 변경 이력
15
+ - `RELEASE.md`: 배포 체크리스트와 릴리즈 기준
16
+
11
17
  ### Credits
12
18
 
13
19
  - Original Python Implementation by:
@@ -17,7 +23,8 @@ Node.js implementation of [ddunigma](https://github.com/i3l3/ddunigma) (Python o
17
23
 
18
24
  ## Requirements
19
25
 
20
- - **Node.js >= 14.0.0**
26
+ - **Node.js >= 18.0.0**
27
+ - 라이브러리는 `ES2022` 타깃으로 빌드되며, 현재 스트림 암호화/압축 조합은 Node 18+ 기준으로 검증됩니다.
21
28
 
22
29
  ## Install
23
30
 
@@ -92,10 +99,11 @@ const decoded = encoder.decode(encoded); // 자동으로 압축 해제
92
99
  ### URL-Safe 인코딩
93
100
 
94
101
  ```typescript
95
- import { Ddu64 } from "@ddunigma/node";
102
+ import { CharsetBuilder, Ddu64 } from "@ddunigma/node";
96
103
 
97
- const encoder = new Ddu64(undefined, undefined, {
98
- dduSetSymbol: DduSetSymbol.ONECHARSET,
104
+ const { charset, padding } = CharsetBuilder.base64().buildWithPadding("=");
105
+
106
+ const encoder = new Ddu64(charset, padding, {
99
107
  urlSafe: true, // +, /, = 를 URL 안전 문자로 변환
100
108
  });
101
109
 
@@ -103,6 +111,8 @@ const encoded = encoder.encode("Hello World!");
103
111
  // URL에서 안전하게 사용 가능한 문자열 반환
104
112
  ```
105
113
 
114
+ `urlSafe` 는 charset/padding이 `-`, `_`, `.` 를 포함하지 않을 때만 활성화됩니다. 또한 chunk 정규화를 위해 custom charset/padding에는 `\r`, `\n` 을 사용할 수 없습니다.
115
+
106
116
  ### 체크섬 (무결성 검증)
107
117
 
108
118
  ```typescript
@@ -153,12 +163,14 @@ import { Ddu64 } from "@ddunigma/node";
153
163
 
154
164
  const encoder = new Ddu64();
155
165
 
156
- // 비동기 인코딩 (이벤트 루프 블로킹 방지)
166
+ // 비동기 인코딩
157
167
  const encoded = await encoder.encodeAsync(largeData);
158
168
  const decoded = await encoder.decodeAsync(encoded);
159
169
  const buffer = await encoder.decodeToBufferAsync(encoded);
160
170
  ```
161
171
 
172
+ 큰 입력에서 기본 경로는 이벤트 루프에 양보하면서 처리합니다. 다만 압축, 암호화, 체크섬, URL-safe 같은 옵션이 함께 켜진 복합 경로는 안전성을 위해 전체 payload 기준 fallback을 사용할 수 있습니다.
173
+
162
174
  ### 진행률 콜백
163
175
 
164
176
  ```typescript
@@ -253,7 +265,7 @@ const encoder = new Ddu64();
253
265
 
254
266
  // 압축 → 암호화 → 인코딩 파이프라인
255
267
  const pipeline = new DduPipeline()
256
- .compress()
268
+ .compress(6, "brotli")
257
269
  .encrypt("my-secret-key")
258
270
  .encode(encoder);
259
271
 
@@ -286,6 +298,48 @@ fs.createReadStream("output.txt")
286
298
  .pipe(fs.createWriteStream("restored.bin"));
287
299
  ```
288
300
 
301
+ 압축과 암호화를 함께 사용하는 스트림도 바로 연결할 수 있습니다.
302
+
303
+ ```typescript
304
+ import { Ddu64, DduSetSymbol, createEncodeStream, createDecodeStream } from "@ddunigma/node";
305
+ import fs from "fs";
306
+
307
+ const encoder = new Ddu64(undefined, undefined, {
308
+ dduSetSymbol: DduSetSymbol.ONECHARSET,
309
+ compress: true,
310
+ compressionAlgorithm: "brotli",
311
+ encryptionKey: "stream-secret-key",
312
+ });
313
+
314
+ fs.createReadStream("input.log")
315
+ .pipe(createEncodeStream(encoder))
316
+ .pipe(fs.createWriteStream("input.log.ddu"));
317
+
318
+ fs.createReadStream("input.log.ddu")
319
+ .pipe(createDecodeStream(encoder))
320
+ .pipe(fs.createWriteStream("input-restored.log"));
321
+ ```
322
+
323
+ 기본 `createEncodeStream()` 은 작은 스트림 헤더를 함께 기록하고, 기본 `createDecodeStream()` 은 이 헤더를 읽어 압축/암호화 설정을 초기에 auto-detect 합니다. 그래서 기본 경로도 조기 스트리밍 복원이 가능합니다. 암호화된 payload는 동일한 `encryptionKey`가 필요합니다.
324
+
325
+ 기존 footer-only 스트림 payload도 계속 디코드됩니다. 다만 과거 포맷은 디코드 쪽에서 전체 payload를 버퍼링할 수 있습니다.
326
+
327
+ 헤더 없이 명시적 설정만으로 encode/decode 하려면 양쪽 모두에서 `streamAutoDetect: false` 와 함께 동일한 `compress`, `compressionAlgorithm`, `encryptionKey` 설정을 맞춰 주세요.
328
+
329
+ ---
330
+
331
+ ## Benchmark
332
+
333
+ 대표 시나리오 기준으로 인코딩/디코딩 시간과 샘플링 기반 peak heap 변화를 확인할 수 있습니다.
334
+
335
+ ```bash
336
+ pnpm bench
337
+ ```
338
+
339
+ 벤치마크는 `--expose-gc`로 실행되며, 일반 인코딩, 청크 인코딩, 압축, 암호화 비동기 경로, 공개 스트림 API 조합을 함께 측정합니다.
340
+
341
+ 샘플링 기반 측정이므로 profiler 수준의 정확한 peak memory는 아니며, 긴 동기 CPU 구간에서는 실제 피크보다 낮게 보일 수 있습니다.
342
+
289
343
  ---
290
344
 
291
345
  ## API Reference
@@ -310,7 +364,10 @@ fs.createReadStream("output.txt")
310
364
  | `encoding` | `BufferEncoding` | `'utf-8'` | 문자열 인코딩 |
311
365
  | `usePowerOfTwo` | `boolean` | `true` | 2의 제곱수 강제 여부 |
312
366
  | `useBuildErrorReturn` | `boolean` | `false` | 에러 발생 시 throw 여부 |
367
+ | `throwOnError` | `boolean` | `false` | 초기화 오류 시 throw 여부 |
313
368
  | `compress` | `boolean` | `false` | 기본 압축 활성화 |
369
+ | `compressionAlgorithm` | `"deflate" \| "brotli"` | `'deflate'` | 기본 압축 알고리즘 |
370
+ | `compressionLevel` | `number` | `6` | 압축 레벨 |
314
371
  | `maxDecodedBytes` | `number` | `67108864` | 최대 디코딩 바이트 (64MB) |
315
372
  | `maxDecompressedBytes` | `number` | `67108864` | 최대 압축해제 바이트 (64MB) |
316
373
  | `urlSafe` | `boolean` | `false` | URL-Safe 모드 |
@@ -319,20 +376,29 @@ fs.createReadStream("output.txt")
319
376
  | `chunkSize` | `number` | `undefined` | 청크 분할 크기 |
320
377
  | `chunkSeparator` | `string` | `'\n'` | 청크 구분자 |
321
378
 
379
+ `urlSafe` 는 charset/padding이 `-`, `_`, `.` 를 포함하지 않을 때만 켜집니다. 기본 chunk 정규화와 충돌하므로 custom `charset` 과 `paddingChar` 에는 `\r`, `\n` 을 사용할 수 없습니다.
380
+
322
381
  ### `encode(data, options?): string`
323
382
 
324
383
  데이터를 인코딩합니다.
325
384
 
326
385
  **DduOptions:**
327
386
 
328
- | Option | Type | Description |
329
- | ---------------- | ---------- | ---------------- |
330
- | `compress` | `boolean` | 압축 사용 여부 |
331
- | `checksum` | `boolean` | 체크섬 추가 여부 |
332
- | `chunkSize` | `number` | 청크 분할 크기 |
387
+ | Option | Type | Description |
388
+ | ------ | ---- | ----------- |
389
+ | `compress` | `boolean` | 압축 사용 여부 |
390
+ | `streamAutoDetect` | `boolean` | 기본 스트림 헤더 기반 auto-detect 사용 여부 (`false`이면 footer-only 명시 설정 모드) |
391
+ | `compressionAlgorithm` | `"deflate" \| "brotli"` | 압축 알고리즘 |
392
+ | `compressionLevel` | `number` | 압축 레벨 |
393
+ | `checksum` | `boolean` | 체크섬 추가 여부 |
394
+ | `maxDecodedBytes` | `number` | 최대 디코딩 바이트 |
395
+ | `maxDecompressedBytes` | `number` | 최대 압축해제 바이트 |
396
+ | `chunkSize` | `number` | 청크 분할 크기 |
333
397
  | `chunkSeparator` | `string` | 청크 구분자 |
334
398
  | `onProgress` | `function` | 진행률 콜백 |
335
399
 
400
+ `encrypt` 와 `omitFooter` 는 스트림 내부 파이프라인 제어용 옵션이며 일반적인 공개 사용 시에는 직접 지정할 필요가 없습니다.
401
+
336
402
  ### `decode(encoded, options?): string`
337
403
 
338
404
  인코딩된 문자열을 디코딩합니다.
@@ -386,6 +452,30 @@ fs.createReadStream("output.txt")
386
452
 
387
453
  ---
388
454
 
455
+ ## Testing
456
+
457
+ This project uses [Vitest](https://vitest.dev/) for testing.
458
+
459
+ ```bash
460
+ # Run all tests
461
+ pnpm test
462
+
463
+ # Run tests in watch mode
464
+ pnpm test:watch
465
+ ```
466
+
467
+ ## Verification
468
+
469
+ ```bash
470
+ pnpm lint
471
+ pnpm build
472
+ pnpm test
473
+ pnpm pack:check
474
+ pnpm bench
475
+ ```
476
+
477
+ ---
478
+
389
479
  ## License
390
480
 
391
481
  BSD-2-Clause
@@ -0,0 +1,2 @@
1
+ export{m as DduDecodeStream,l as DduEncodeStream,o as createDecodeStream,n as createEncodeStream}from'./chunk-CZMUPXSK.js';//# sourceMappingURL=DduStream-KO75MEEM.js.map
2
+ //# sourceMappingURL=DduStream-KO75MEEM.js.map
@@ -0,0 +1,5 @@
1
+ import {Transform,PassThrough}from'stream';import {createBrotliCompress,constants,createDeflate,createBrotliDecompress,createInflate}from'zlib';var R={"-":"+",_:"/",".":"="},T=(()=>{let n=new Uint32Array(256);for(let e=0;e<256;e++){let r=e;for(let t=0;t<8;t++)r=r>>>1^(r&1?3988292384:0);n[e]=r;}return n})(),_="ELYSIA",P="GRISEO",b="CHK",N="ENC";function W(n){if(n.length===0)return n;let e=new Array(n.length);for(let r=0;r<n.length;r++){let t=n[r];t==="+"?e[r]="-":t==="/"?e[r]="_":t==="="?e[r]=".":e[r]=t;}return e.join("")}function H(n){if(n.length===0)return n;let e=new Array(n.length);for(let r=0;r<n.length;r++){let t=n[r];t==="-"?e[r]="+":t==="_"?e[r]="/":t==="."?e[r]="=":e[r]=t;}return e.join("")}function K(n,e,r){if(e<=0||n.length<=e)return n;let t=Math.ceil(n.length/e),i=new Array(t*2-1),s=0;for(let o=0;o<n.length;o+=e)i[s++]=n.slice(o,o+e),o+e<n.length&&(i[s++]=r);return i.join("")}function h(n,e){if(n.length===0)return n;let r=e&&e!==`
2
+ `&&e!==`\r
3
+ `&&e!=="\r"?e:"",t=r.length,i="";for(let s=0;s<n.length;s++){let o=n[s];if(!(o===`
4
+ `||o==="\r")){if(t>0&&o===r[0]&&n.startsWith(r,s)){s+=t-1;continue}i+=o;}}return i}function j(n){let e=4294967295;for(let r=0;r<n.length;r++)e=e>>>8^T[(e^n[r])&255];return ((e^4294967295)>>>0).toString(16).padStart(8,"0")}function F(n){let e=n.lastIndexOf(b);if(e===-1)return {data:n,checksum:null};let r=n.slice(e+b.length);return r.length!==8||!/^[0-9a-f]+$/i.test(r)?{data:n,checksum:null}:{data:n.slice(0,e),checksum:r.toLowerCase()}}var c="DDS1";function I(n,e){let t=n===void 0||!Number.isFinite(n)?6:Math.floor(n);return Math.min(e==="brotli"?11:9,Math.max(0,t))}function C(n){return n.length*2+c.length+2}function k(n,e){let r=e.compressionAlgorithm==="brotli"?"B":e.compressionAlgorithm==="deflate"?"D":"N",t=e.encrypted?"1":"0";return `${n}${c}${r}${t}${n}`}function D(n,e){let r=C(e);if(n.length<r||!n.startsWith(e))return null;let t=e.length;if(n.slice(t,t+c.length)!==c)throw new Error("[DduStream decode] Invalid stream header magic");let s=n[t+c.length],o=n[t+c.length+1];if(n.slice(r-e.length,r)!==e)throw new Error("[DduStream decode] Invalid stream header terminator");let a=s==="B"?"brotli":s==="D"?"deflate":s==="N"?void 0:null;if(a===null)throw new Error("[DduStream decode] Invalid stream header compression flag");if(o!=="0"&&o!=="1")throw new Error("[DduStream decode] Invalid stream header encryption flag");return {compressionAlgorithm:a,encrypted:o==="1"}}var m=class extends Transform{prefix;emittedPrefix=false;constructor(e){super(),this.prefix=e;}_transform(e,r,t){try{this.emittedPrefix||(this.push(this.prefix),this.emittedPrefix=!0),this.push(e),t();}catch(i){t(i);}}};function L(n,e){let r=new PassThrough,t=r.write.bind(r);return r.write=function(i,s,o){return typeof s=="function"?n.write(i,s):n.write(i,s,o)},r.end=function(i,s,o){return typeof i=="function"?n.end(i):typeof s=="function"?n.end(i,s):n.end(i,s,o)},e.on("data",i=>t(i)),e.on("end",()=>r.push(null)),e.on("error",i=>r.destroy(i)),n.on("error",i=>r.destroy(i)),r}function v(n){if(n.length===0)return new PassThrough;for(let r=0;r<n.length-1;r++)n[r].pipe(n[r+1]);let e=L(n[0],n[n.length-1]);for(let r of n)r.on("error",t=>{e.destroy(t);});return e}var p=class extends Transform{encoder;buffers;bufferOffset;totalLength;chunkSize;footerCompressionAlgorithm;footerEncrypted;constructor(e,r){super({...r,readableObjectMode:false,writableObjectMode:false}),this.encoder=e;let t=e.getCharSetInfo();this.buffers=[],this.bufferOffset=0,this.totalLength=0,this.footerCompressionAlgorithm=r?.compress??t.defaultCompress?r?.compressionAlgorithm??t.defaultCompressionAlgorithm:void 0,this.footerEncrypted=(r?.encrypt??true)&&t.hasEncryptionKey,this.chunkSize=this.calculateChunkSize(t.bitLength);}calculateChunkSize(e){let r=(s,o)=>o===0?s:r(o,s%o),t=8*e/r(8,e),i=Math.max(1,Math.floor(4096/t));return t*i}_transform(e,r,t){try{for(this.buffers.push(e),this.totalLength+=e.length;this.totalLength>=this.chunkSize;){let i=this.readBytes(this.chunkSize),s=this.encodeChunk(i,!1);this.push(s);}t();}catch(i){t(i);}}_flush(e){try{if(this.totalLength>0){let r=this.readBytes(this.totalLength),t=this.encodeChunk(r,!0);this.push(t);}e();}catch(r){e(r);}}encodeChunk(e,r){return this.encoder.encodeRawBuffer(e,{compressionAlgorithm:r?this.footerCompressionAlgorithm:void 0,encrypted:r?this.footerEncrypted:false,omitFooter:!r})}readBytes(e){if(e<=0||this.totalLength<e)return Buffer.alloc(0);let r=this.buffers[0];if(this.buffers.length===1&&r&&this.bufferOffset===0&&r.length===e)return this.buffers=[],this.totalLength=0,r;let t=Buffer.allocUnsafe(e),i=0;for(;i<e&&this.buffers.length>0;){let s=this.buffers[0],o=s.length-this.bufferOffset,f=Math.min(e-i,o);s.copy(t,i,this.bufferOffset,this.bufferOffset+f),i+=f,this.bufferOffset+=f,this.bufferOffset>=s.length&&(this.buffers.shift(),this.bufferOffset=0);}return this.totalLength-=e,t}},g=class extends Transform{encoder;options;normalizedBuffer;charLength;chunkSize;chunkSeparator;separatorTail;constructor(e,r){super({...r,readableObjectMode:false,writableObjectMode:false}),this.encoder=e,this.options={...r,compress:false,checksum:false,encrypt:false},this.normalizedBuffer="";let t=e.getCharSetInfo();this.charLength=t.charLength,this.chunkSeparator=r?.chunkSeparator??t.defaultChunkSeparator,this.separatorTail="",this.chunkSize=this.calculateChunkSize(t.charLength);}calculateChunkSize(e){return e*1024}_transform(e,r,t){try{this.appendNormalizedChunk(e.toString("utf-8"));let i=100;for(;this.normalizedBuffer.length>=this.chunkSize+i;){let s=this.normalizedBuffer.slice(0,this.chunkSize);this.normalizedBuffer=this.normalizedBuffer.slice(this.chunkSize);let o=this.encoder.decodeToBuffer(s,this.options);this.push(o);}t();}catch(i){t(i);}}_flush(e){try{if(this.separatorTail.length>0&&(this.normalizedBuffer+=h(this.separatorTail,this.chunkSeparator),this.separatorTail=""),this.normalizedBuffer.length>0){let r=this.encoder.decodeStreamToBuffer(this.normalizedBuffer,this.options);this.push(r),this.normalizedBuffer="";}e();}catch(r){e(r);}}appendNormalizedChunk(e){if(e.length===0)return;let r=Math.max(0,this.chunkSeparator.length-1);if(r===0){this.normalizedBuffer+=h(e,this.chunkSeparator);return}let t=this.separatorTail+e;if(t.length<=r){this.separatorTail=t;return}let i=t.length-r,s=t.slice(0,i);this.separatorTail=t.slice(i),this.normalizedBuffer+=h(s,this.chunkSeparator);}},y=class extends Transform{encoder;options;normalizedBuffer;chunkSeparator;separatorTail;paddingChar;headerLength;mode;innerStream;constructor(e,r){super({...r,readableObjectMode:false,writableObjectMode:false}),this.encoder=e,this.options={...r},this.normalizedBuffer="";let t=e.getCharSetInfo();this.paddingChar=t.paddingChar,this.headerLength=C(t.paddingChar),this.chunkSeparator=r?.chunkSeparator??t.defaultChunkSeparator,this.separatorTail="",this.mode="pending",this.innerStream=null;}_transform(e,r,t){try{if(this.appendNormalizedChunk(e.toString("utf-8")),this.maybeInitializeMode(!1),this.mode==="pipeline"){this.flushBufferedToInner(t);return}t();}catch(i){t(i);}}_flush(e){try{if(this.separatorTail.length>0&&(this.normalizedBuffer+=h(this.separatorTail,this.chunkSeparator),this.separatorTail=""),this.maybeInitializeMode(!0),this.mode==="pipeline"){this.finishInnerPipeline(e);return}if(this.normalizedBuffer.length>0){let r=this.encoder.decodeStreamToBuffer(this.normalizedBuffer,this.options);this.push(r),this.normalizedBuffer="";}e();}catch(r){e(r);}}appendNormalizedChunk(e){if(e.length===0)return;let r=Math.max(0,this.chunkSeparator.length-1);if(r===0){this.normalizedBuffer+=h(e,this.chunkSeparator);return}let t=this.separatorTail+e;if(t.length<=r){this.separatorTail=t;return}let i=t.length-r,s=t.slice(0,i);this.separatorTail=t.slice(i),this.normalizedBuffer+=h(s,this.chunkSeparator);}maybeInitializeMode(e){if(this.mode!=="pending")return;let r=this.paddingChar.length;if(this.normalizedBuffer.length<r){e&&this.normalizedBuffer.length>0&&(this.mode="legacy");return}if(!this.normalizedBuffer.startsWith(this.paddingChar)){this.mode="legacy";return}if(this.normalizedBuffer.length<this.headerLength){if(e)throw new Error("[DduStream decode] Incomplete stream header");return}let t=this.normalizedBuffer.slice(0,this.headerLength),i=D(t,this.paddingChar);if(!i){this.mode="legacy";return}this.mode="pipeline",this.normalizedBuffer=this.normalizedBuffer.slice(this.headerLength),this.initializeInnerPipeline(i);}initializeInnerPipeline(e){if(e.encrypted&&!this.encoder.getCharSetInfo().hasEncryptionKey)throw new Error("[DduStream decode] Encrypted stream requires an encryptionKey");let r=O(this.encoder,{...this.options,streamAutoDetect:false,compress:!!e.compressionAlgorithm,compressionAlgorithm:e.compressionAlgorithm,encrypt:e.encrypted});r.on("data",t=>{this.push(t);}),r.on("error",t=>{this.destroy(t);}),this.innerStream=r;}flushBufferedToInner(e){if(!this.innerStream||this.normalizedBuffer.length===0){e();return}let r=this.normalizedBuffer;if(this.normalizedBuffer="",!this.innerStream.write(Buffer.from(r,"utf-8"))){this.innerStream.once("drain",()=>e());return}e();}finishInnerPipeline(e){if(!this.innerStream){e();return}let r=this.innerStream,t=()=>{r.once("end",()=>e()),r.end();};if(this.normalizedBuffer.length>0){let i=this.normalizedBuffer;if(this.normalizedBuffer="",!r.write(Buffer.from(i,"utf-8"))){r.once("drain",t);return}}t();}};function Q(n,e){let r=n.getCharSetInfo(),t=e?.compress??r.defaultCompress,i=(e?.encrypt??true)&&r.hasEncryptionKey,s=e?.streamAutoDetect!==false,o=t?e?.compressionAlgorithm??r.defaultCompressionAlgorithm:void 0,f=new p(n,e),a=[];if(t){let l=o??r.defaultCompressionAlgorithm,u=l==="brotli",S=I(e?.compressionLevel??r.defaultCompressionLevel,l),E=u?createBrotliCompress({params:{[constants.BROTLI_PARAM_QUALITY]:Math.min(11,Math.max(0,S))}}):createDeflate({level:Math.min(9,Math.max(0,S))});a.push(E);}if(i){let l=n.createEncryptionStream();l&&a.push(l);}return a.push(f),s&&a.push(new m(k(r.paddingChar,{compressionAlgorithm:o,encrypted:i}))),a.length===1?f:v(a)}function O(n,e){if(e?.streamAutoDetect??true)return new y(n,e);let t=n.getCharSetInfo(),i=e?.compress??t.defaultCompress,s=(e?.encrypt??true)&&t.hasEncryptionKey,o=new g(n,e),f=[o];if(s){let a=n.createDecryptionStream();a&&f.push(a);}if(i){let u=(e?.compressionAlgorithm??t.defaultCompressionAlgorithm)==="brotli"?createBrotliDecompress():createInflate();f.push(u);}return f.length===1?o:v(f)}export{R as a,_ as b,P as c,b as d,N as e,W as f,H as g,K as h,h as i,j,F as k,p as l,g as m,Q as n,O as o};//# sourceMappingURL=chunk-CZMUPXSK.js.map
5
+ //# sourceMappingURL=chunk-CZMUPXSK.js.map