@ddunigma/node 3.1.0 → 5.0.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 (47) hide show
  1. package/README.md +107 -281
  2. package/dist/BrowserAdapter-HORDDCOE.js +2 -0
  3. package/dist/BrowserAdapter-PB4J6FHX.cjs +2 -0
  4. package/dist/NodeAdapter-5FBNCJSG.js +2 -0
  5. package/dist/NodeAdapter-EQ73FGEJ.cjs +2 -0
  6. package/dist/{ObfuscationLayer-D-xl5d7P.d.ts → ObfuscationLayer-BDr-0s1M.d.ts} +31 -15
  7. package/dist/{ObfuscationLayer-DAVKTnHf.d.cts → ObfuscationLayer-BgL73E5F.d.cts} +31 -15
  8. package/dist/browser.cjs +1 -1
  9. package/dist/browser.d.cts +5 -4
  10. package/dist/browser.d.ts +5 -4
  11. package/dist/browser.js +1 -1
  12. package/dist/chunk-5NSHXTMN.cjs +2 -0
  13. package/dist/chunk-7RWUNW5S.js +2 -0
  14. package/dist/chunk-AMOZHHMB.cjs +2 -0
  15. package/dist/chunk-CQATQOBZ.js +2 -0
  16. package/dist/chunk-HTZT725P.js +10 -0
  17. package/dist/chunk-HZJ7PU7X.cjs +2 -0
  18. package/dist/chunk-KS6PRP5Y.js +2 -0
  19. package/dist/chunk-OQXMQIE3.js +2 -0
  20. package/dist/chunk-UMA4JEN4.cjs +10 -0
  21. package/dist/chunk-WCXD5LRF.cjs +2 -0
  22. package/dist/core.cjs +1 -1
  23. package/dist/core.d.cts +40 -1
  24. package/dist/core.d.ts +40 -1
  25. package/dist/core.js +1 -1
  26. package/dist/{core-DYSnygnp.d.cts → errors-DNICpo4L.d.cts} +188 -139
  27. package/dist/{core-DYSnygnp.d.ts → errors-DNICpo4L.d.ts} +188 -139
  28. package/dist/index.cjs +1 -1
  29. package/dist/index.d.cts +23 -8
  30. package/dist/index.d.ts +23 -8
  31. package/dist/index.js +1 -1
  32. package/dist/wasm/codec.wasm +0 -0
  33. package/package.json +46 -5
  34. package/dist/BrowserAdapter-BHHWPUTB.js +0 -2
  35. package/dist/BrowserAdapter-M7PUHVGS.cjs +0 -2
  36. package/dist/NodeAdapter-JB2EZ3T4.js +0 -2
  37. package/dist/NodeAdapter-JRRSYUJT.cjs +0 -2
  38. package/dist/chunk-5RZDTEOZ.js +0 -2
  39. package/dist/chunk-JUBMOKKH.js +0 -2
  40. package/dist/chunk-JZSHJ6KN.cjs +0 -9
  41. package/dist/chunk-KEWLOPEV.js +0 -9
  42. package/dist/chunk-M6LY6DIE.js +0 -2
  43. package/dist/chunk-NFMYVNOG.cjs +0 -2
  44. package/dist/chunk-NY4FGVF3.cjs +0 -2
  45. package/dist/chunk-PHMARSJE.cjs +0 -2
  46. package/dist/chunk-QR43FNIY.js +0 -2
  47. package/dist/chunk-TJTDYO65.cjs +0 -2
package/README.md CHANGED
@@ -17,7 +17,7 @@ V2 추가사항
17
17
 
18
18
  ## Requirements
19
19
 
20
- - **Node.js >= 18.0.0**
20
+ - **Node.js >= 22.0.0**
21
21
 
22
22
  ## Install
23
23
 
@@ -43,369 +43,195 @@ dduV1.decode(".우땨땨이?땨뜌.이.뜌이?이!.우우땨이?우뜌.우땨뜌
43
43
 
44
44
  ---
45
45
 
46
- ## Binary Data
46
+ ## 5.0.0 사용법
47
+
48
+ ### 문자열과 바이너리
47
49
 
48
50
  ```typescript
51
+ import { Ddu64 } from "@ddunigma/node";
52
+
49
53
  const ddu = new Ddu64();
50
- const input = new Uint8Array([0, 1, 127, 128, 255]);
51
54
 
52
- const encoded = ddu.encode(input);
53
- const bytes = ddu.decodeToUint8Array(encoded);
54
- const buffer = ddu.decodeToBuffer(encoded); // Node.js entry only
55
+ const encodedText = ddu.encode("안녕하세요");
56
+ const decodedText = ddu.decode(encodedText);
57
+
58
+ const encodedBytes = ddu.encode(new Uint8Array([0, 1, 127, 128, 255]));
59
+ const decodedBytes = ddu.decodeToUint8Array(encodedBytes);
60
+ const decodedBuffer = ddu.decodeToBuffer(encodedBytes); // Node.js 전용
55
61
  ```
56
62
 
57
- ## Presets
63
+ ### 프리셋
58
64
 
59
65
  ```typescript
60
66
  import { Ddu64, DduSetSymbol } from "@ddunigma/node";
61
67
 
62
- // 기본값 - 한글 종성 결합 64문자
63
- new Ddu64();
64
-
65
- // 구버전 호환 8문자 (아래 두 방법 모두 사용가능)
66
- new Ddu64({ dduSetSymbol: DduSetSymbol.DDU_V1 });
67
- new Ddu64(undefined, undefined, { dduSetSymbol: DduSetSymbol.DDU_V1 });
68
-
69
- // 영문+숫자 64문자 (아래 두 방법 모두 사용가능)
70
- new Ddu64({ dduSetSymbol: DduSetSymbol.ONECHARSET });
71
- new Ddu64(undefined, undefined, { dduSetSymbol: DduSetSymbol.ONECHARSET });
68
+ const ddu = new Ddu64();
69
+ const legacy = new Ddu64({ dduSetSymbol: DduSetSymbol.DDU_V1 });
70
+ const oneCharset = new Ddu64({ dduSetSymbol: DduSetSymbol.ONECHARSET });
72
71
  ```
73
72
 
74
- | Symbol | 문자 수 | 설명 |
75
- | ------------ | ------: | ---------------------------------- |
76
- | `DDU` | 64 | 한글 기본 문자 8개 × 종성 8개 조합 |
77
- | `DDU_V1` | 8 | 기존 8문자 쌍 방식 (하위 호환) |
78
- | `ONECHARSET` | 64 | 영문, 숫자, 일부 특수문자 |
79
-
80
- ## Custom Charset
73
+ ### 커스텀 charset
81
74
 
82
75
  ```typescript
83
- // 문자열로 직접 지정
84
- const base64Like = new Ddu64(
85
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
86
- "=",
87
- );
88
-
89
- // 한글 종성 조합으로 커스텀 charset 생성
90
- const hangulCoda = new Ddu64(["가", "나", "다", "라"], "뭐", {
76
+ import { Ddu64 } from "@ddunigma/node";
77
+
78
+ const base64 = new Ddu64("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "=");
79
+
80
+ const hangul = new Ddu64(["가", "나", "다", "라"], "뭐", {
91
81
  codaChar: ["", "ㄱ", "ㄲ", "ㄷ"],
92
82
  });
93
- // → 가, 각, 갂, 갇, 나, 낙, 낚, 낟, 다, 닥, 닦, 닫, 라, 락, 랔, 랗 (16문자)
94
83
  ```
95
84
 
96
- ## CharsetBuilder
97
-
98
- ```typescript
99
- import { CharsetBuilder, Ddu64 } from "@ddunigma/node";
85
+ charset 문자와 `paddingChar`는 각각 단일 UTF-16 코드 유닛이어야 합니다.
100
86
 
101
- // Base64에서 혼동 문자 제거 후 2의 제곱수로 맞추기
102
- const { charset, padding } = CharsetBuilder.base64()
103
- .excludeConfusing()
104
- .limitToPowerOfTwo()
105
- .buildWithPadding();
87
+ ### 사용 가능한 옵션
106
88
 
107
- const ddu = new Ddu64(charset, padding);
89
+ 생성자 옵션은 인스턴스의 기본값으로 적용됩니다. `encode`, `decode`, `getStats` 계열 메서드에
90
+ 같은 옵션을 전달하면 해당 호출에서만 기본값을 덮어씁니다.
108
91
 
109
- // 유니코드 범위에서 생성
110
- const chars = CharsetBuilder.fromUnicodeRange(0x4e00, 0x4e3f)
111
- .shuffle(12345)
112
- .limitToPowerOfTwo()
113
- .build();
114
- ```
92
+ #### 공통 옵션
115
93
 
116
- ## Compression
94
+ | 옵션 | 타입 | 기본값 | 용도 |
95
+ | ---------------------- | --------------------------------- | ----------- | ---------------------------------- |
96
+ | `compress` | `boolean` | `false` | 압축 사용 |
97
+ | `compressionAlgorithm` | `"deflate" \| "brotli"` | `"deflate"` | 압축 알고리즘 |
98
+ | `compressionLevel` | `number` | `6` | 압축 레벨 |
99
+ | `checksum` | `boolean` | `false` | CRC32 체크섬 추가 및 검증 |
100
+ | `checksumScope` | `"plaintext" \| "output"` | `"output"` | CRC32 계산 범위 |
101
+ | `chunkSize` | `number` | 미사용 | 출력 문자열 분할 크기 |
102
+ | `chunkSeparator` | `string` | `"\n"` | 청크 구분자 |
103
+ | `maxDecodedBytes` | `number` | `67108864` | 최대 디코딩 바이트 수 |
104
+ | `maxDecompressedBytes` | `number` | `67108864` | 최대 압축 해제 바이트 수 |
105
+ | `obfuscate` | `boolean` | `false` | 암호화된 출력을 한글 음절로 난독화 |
106
+ | `onProgress` | `(info: DduProgressInfo) => void` | 미사용 | 처리 진행률 콜백 |
117
107
 
118
- ```typescript
119
- const ddu = new Ddu64({
120
- compress: true, // 압축 활성화
121
- compressionAlgorithm: "deflate", // "deflate" | "brotli"
122
- compressionLevel: 6, // deflate: 0-9, brotli: 0-11
123
- });
108
+ #### 생성자 전용 옵션
124
109
 
125
- const encoded = ddu.encode("A".repeat(1000)); // 압축되어 짧아짐
126
- const decoded = ddu.decode(encoded);
127
- ```
110
+ | 옵션 | 타입 | 기본값 | 용도 |
111
+ | ------------------ | ---------------------- | ----------- | ----------------------------------- |
112
+ | `dduSetSymbol` | `DduSetSymbol` | `DDU` | 기본 charset 프리셋 선택 |
113
+ | `dduChar` | `string \| string[]` | 프리셋 사용 | 커스텀 charset |
114
+ | `codaChar` | `string[]` | 미사용 | 기본 문자와 조합할 한글 종성 |
115
+ | `paddingChar` | `string` | 프리셋 사용 | 커스텀 패딩 문자 |
116
+ | `requiredLength` | `number` | `64` | 필요한 charset 문자 수 |
117
+ | `usePowerOfTwo` | `boolean` | 자동 결정 | 2의 제곱수 charset 직접 인덱스 모드 |
118
+ | `useRepeatPadding` | `boolean` | 프리셋 설정 | 반복 패딩 방식 사용 |
119
+ | `throwOnError` | `boolean` | `true` | 잘못된 charset 설정에서 예외 발생 |
120
+ | `urlSafe` | `boolean` | `false` | URL-Safe 출력 변환 |
121
+ | `encryptionKey` | `string` | 미사용 | AES-256-GCM 암호화 키 |
122
+ | `keyDerivation` | `KeyDerivationOptions` | `pbkdf2` | 암호화 키 파생 방식 |
123
+ | `adapter` | `PlatformAdapter` | 진입점 설정 | 플랫폼 어댑터 직접 주입 |
124
+ | `wasmThreshold` | `number` | `16384` | WASM 사용을 시작할 입력 크기 |
128
125
 
129
- 압축은 원본보다 작아질 때만 적용됩니다. 압축 결과가 크면 비압축으로 저장됩니다.
130
- 브라우저 진입점은 `deflate-raw`를 지원하는 CompressionStream/DecompressionStream 런타임에서 압축을 사용합니다.
131
- 브라우저 Brotli는 런타임 지원 여부를 feature detection으로 확인하며, Web API 특성상 `compressionLevel`은 적용되지 않을 수 있습니다.
126
+ `encoding`은 레거시 타입 호환을 위해서만 남아 있으며 런타임 문자열 처리는 항상 UTF-8입니다.
127
+ `encrypt`와 `omitFooter`는 스트림 내부 파이프라인 제어용이므로 일반 사용에서는 지정하지 않습니다.
132
128
 
133
- ## Encryption
129
+ ### 압축, 암호화, 체크섬
134
130
 
135
131
  ```typescript
136
- // SHA-256 파생 (기본)
132
+ import { Ddu64 } from "@ddunigma/node";
133
+
137
134
  const ddu = new Ddu64({
135
+ compress: true,
136
+ compressionAlgorithm: "deflate",
137
+ compressionLevel: 6,
138
138
  encryptionKey: "my-secret-key",
139
- });
140
-
141
- const encoded = ddu.encode("secret message");
142
- const decoded = ddu.decode(encoded); // 같은 키로만 복호화 가능
143
-
144
- // PBKDF2 키 파생
145
- const dduPbkdf2 = new Ddu64({
146
- encryptionKey: "user password",
147
139
  keyDerivation: {
148
140
  algorithm: "pbkdf2",
149
- salt: "app-specific-salt",
141
+ salt: "my-application-salt",
150
142
  iterations: 210_000,
151
- hash: "SHA-256",
152
143
  },
144
+ checksum: true,
153
145
  });
154
- ```
155
146
 
156
- PBKDF2 `iterations`는 기본값이 `210_000`이며, `10_000` 미만의 양수는 `10_000`으로 보정됩니다.
157
- 0 이하 또는 유한하지 않은 값은 기본값으로 대체됩니다.
147
+ const encoded = ddu.encode("보호할 데이터");
148
+ const decoded = ddu.decode(encoded);
149
+ ```
158
150
 
159
- ## Checksum
151
+ 복호화할 때는 인코딩에 사용한 `encryptionKey`와 키 파생 설정을 동일하게 사용해야 합니다.
152
+ 체크섬을 호출별 옵션으로 사용한 경우 디코딩에도 `checksum: true`를 지정합니다.
160
153
 
161
154
  ```typescript
162
- const ddu = new Ddu64({ checksum: true });
163
-
164
- const encoded = ddu.encode("data"); // CRC32 체크섬 포함
165
- const decoded = ddu.decode(encoded); // 무결성 검증 후 반환
155
+ const encoded = ddu.encode("data", { checksum: true });
156
+ const decoded = ddu.decode(encoded, { checksum: true });
166
157
  ```
167
158
 
168
- ## URL-Safe
159
+ ### URL-Safe와 청크 분할
169
160
 
170
161
  ```typescript
171
162
  const ddu = new Ddu64("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "=", {
172
163
  urlSafe: true,
173
- });
174
-
175
- // +→- /→_ =→. 로 자동 변환
176
- const encoded = ddu.encode("URL safe text");
177
- ```
178
-
179
- ## Chunking
180
-
181
- ```typescript
182
- const ddu = new Ddu64({
183
164
  chunkSize: 76,
184
165
  chunkSeparator: "\n",
185
166
  });
186
167
 
187
- const encoded = ddu.encode("long data ".repeat(100));
188
- // 76자마다 줄바꿈 삽입
168
+ const encoded = ddu.encode("long data");
169
+ const decoded = ddu.decode(encoded);
189
170
  ```
190
171
 
191
- ## Obfuscation (한글 난독화)
172
+ ### 한글 난독화
192
173
 
193
174
  ```typescript
194
175
  const ddu = new Ddu64({
195
- encryptionKey: "secret",
196
- obfuscate: true, // 암호화 필수
176
+ encryptionKey: "my-secret-key",
177
+ obfuscate: true,
197
178
  });
198
179
 
199
- const encoded = ddu.encode("hello");
200
- // 출력이 한글 음절 블록(U+AC00–U+D7A3)으로 변환됨
201
- ```
202
-
203
- ## Async (브라우저 호환)
204
-
205
- ```typescript
206
- // 브라우저에서는 async 메서드 사용
207
- import { Ddu64 } from "@ddunigma/node/browser";
208
-
209
- const ddu = new Ddu64();
210
- const encoded = await ddu.encodeAsync("browser text");
211
- const decoded = await ddu.decodeAsync(encoded);
180
+ const encoded = ddu.encode("secret");
181
+ const decoded = ddu.decode(encoded);
212
182
  ```
213
183
 
214
- Node.js에서도 async 메서드를 사용할 있습니다. 브라우저 진입점(`@ddunigma/node/browser`)은 Node.js 내장 모듈을 임포트하지 않습니다.
215
- 코어 진입점(`@ddunigma/node/core`)은 기본 인코딩/디코딩만 포함하며, 압축/암호화가 필요하면 명시적으로 어댑터를 전달하세요.
184
+ 난독화에는 암호화 키가 필요하며 `obfuscate: true`와 `encrypt: false`를 함께 사용할 없습니다.
216
185
 
217
- ## Web Streams
186
+ ### 브라우저와 Workers
218
187
 
219
188
  ```typescript
220
- import { Ddu64, createReadableEncodeStream, createReadableDecodeStream } from "@ddunigma/node";
189
+ import { Ddu64 } from "@ddunigma/node/browser";
221
190
 
222
191
  const ddu = new Ddu64({
223
192
  compress: true,
224
- encryptionKey: "stream-key",
225
- });
226
-
227
- const encodedStream = readableByteStream.pipeThrough(
228
- createReadableEncodeStream(ddu, { compress: true }),
229
- );
230
-
231
- const decodedStream = encodedStream.pipeThrough(createReadableDecodeStream(ddu));
232
- ```
233
-
234
- ## WASM Acceleration
235
-
236
- ```typescript
237
- import { Ddu64, preloadWasm } from "@ddunigma/node";
238
-
239
- await preloadWasm(); // 동기 encode/decode hot path에서 WASM을 쓰려면 먼저 완료되어야 함
240
-
241
- const ddu = new Ddu64({
242
- wasmThreshold: 4096, // 이 크기 이상일 때 WASM 사용
193
+ checksum: true,
243
194
  });
244
195
 
245
- const encoded = ddu.encode(new Uint8Array(1024 * 1024));
196
+ const encoded = await ddu.encodeAsync("browser data");
197
+ const decoded = await ddu.decodeAsync(encoded);
198
+ const bytes = await ddu.decodeToUint8ArrayAsync(encoded);
246
199
  ```
247
200
 
248
- `encode()`/`decode()`의 동기 hot path는 이미 로드된 WASM만 사용합니다.
249
- `preloadWasm()`이 완료되지 않았거나 WASM을 사용할 수 없으면 JavaScript로 폴백됩니다.
201
+ 브라우저 압축은 실행 환경의 `CompressionStream`과 `DecompressionStream` 지원 여부에 따라 사용할
202
+ 있습니다.
250
203
 
251
- ## Progress Callback
204
+ ### 인코딩 통계
252
205
 
253
206
  ```typescript
254
- const ddu = new Ddu64({ compress: true });
255
-
256
- ddu.encode("data", {
257
- onProgress: ({ percent, stage }) => {
258
- console.log(`${stage}: ${percent}%`);
259
- // stage: start → compress → encrypt → encode → done
260
- },
261
- });
207
+ const stats = ddu.getStats("payload");
208
+ const asyncStats = await ddu.getStatsAsync("payload", { compress: true });
262
209
  ```
263
210
 
264
- ## Stats
211
+ 브라우저에서 압축 통계를 계산할 때는 `getStatsAsync`를 사용합니다.
265
212
 
266
- ```typescript
267
- const ddu = new Ddu64({ compress: true });
268
- const stats = ddu.getStats("A".repeat(1000));
213
+ ### WASM 가속
269
214
 
270
- // { originalSize, encodedSize, compressedSize, compressionRatio, expansionRatio, charsetSize, bitLength }
271
- ```
215
+ ```typescript
216
+ import { Ddu64, preloadWasm } from "@ddunigma/node";
272
217
 
273
- ## Size Limits
218
+ await preloadWasm();
274
219
 
275
- ```typescript
276
220
  const ddu = new Ddu64({
277
- maxDecodedBytes: 10 * 1024 * 1024, // 디코딩 최대 크기 (기본 64MB)
278
- maxDecompressedBytes: 50 * 1024 * 1024, // 압축해제 최대 크기 (기본 64MB)
221
+ wasmThreshold: 16 * 1024,
279
222
  });
280
223
  ```
281
224
 
282
- ---
225
+ `wasmThreshold: Infinity`를 지정하면 WASM 사용을 비활성화할 수 있습니다.
283
226
 
284
- ## API
285
-
286
- ### Node Entry
227
+ ### 진입점
287
228
 
288
229
  ```typescript
289
- class Ddu64 {
290
- encode(data: string | Uint8Array, options?: DduOptions): string;
291
- decode(encoded: string, options?: DduOptions): string;
292
- decodeToUint8Array(encoded: string, options?: DduOptions): Uint8Array;
293
- decodeToBuffer(encoded: string, options?: DduOptions): Buffer;
294
-
295
- encodeAsync(data: string | Uint8Array, options?: DduOptions): Promise<string>;
296
- decodeAsync(encoded: string, options?: DduOptions): Promise<string>;
297
- decodeToUint8ArrayAsync(encoded: string, options?: DduOptions): Promise<Uint8Array>;
298
- decodeToBufferAsync(encoded: string, options?: DduOptions): Promise<Buffer>;
299
-
300
- getStats(data: string | Uint8Array, options?: DduOptions): DduEncodeStats;
301
- getCharSetInfo(): CharSetInfo;
302
- }
303
- ```
304
-
305
- ### Browser Entry
230
+ import { Ddu64 as NodeDdu64 } from "@ddunigma/node";
231
+ import { Ddu64 as BrowserDdu64 } from "@ddunigma/node/browser";
232
+ import { Ddu64 as CoreDdu64 } from "@ddunigma/node/core";
306
233
 
307
- ```typescript
308
- class Ddu64 {
309
- encode(data: string | Uint8Array, options?: DduOptions): string;
310
- decode(encoded: string, options?: DduOptions): string;
311
- decodeToUint8Array(encoded: string, options?: DduOptions): Uint8Array;
312
-
313
- encodeAsync(data: string | Uint8Array, options?: DduOptions): Promise<string>;
314
- decodeAsync(encoded: string, options?: DduOptions): Promise<string>;
315
- decodeToUint8ArrayAsync(encoded: string, options?: DduOptions): Promise<Uint8Array>;
316
-
317
- getStats(data: string | Uint8Array, options?: DduOptions): DduEncodeStats;
318
- getCharSetInfo(): CharSetInfo;
319
- }
234
+ const nodeEncoder = new NodeDdu64();
235
+ const browserEncoder = new BrowserDdu64();
236
+ const coreEncoder = new CoreDdu64();
320
237
  ```
321
-
322
- 브라우저 진입점(`@ddunigma/node/browser`)은 `Buffer` API를 노출하지 않습니다.
323
-
324
- ### Core Entry
325
-
326
- ```typescript
327
- class Ddu64 {
328
- encode(data: string | Uint8Array, options?: DduOptions): string;
329
- decode(encoded: string, options?: DduOptions): string;
330
- decodeToUint8Array(encoded: string, options?: DduOptions): Uint8Array;
331
-
332
- encodeAsync(data: string | Uint8Array, options?: DduOptions): Promise<string>;
333
- decodeAsync(encoded: string, options?: DduOptions): Promise<string>;
334
- decodeToUint8ArrayAsync(encoded: string, options?: DduOptions): Promise<Uint8Array>;
335
-
336
- getStats(data: string | Uint8Array, options?: DduOptions): DduEncodeStats;
337
- getCharSetInfo(): CharSetInfo;
338
- }
339
- ```
340
-
341
- 코어 진입점(`@ddunigma/node/core`)은 플랫폼 어댑터를 자동 로드하지 않습니다.
342
- 압축 또는 암호화가 필요한 async 호출에는 `adapter`를 명시적으로 전달하세요.
343
-
344
- ## Constructor Options
345
-
346
- ```typescript
347
- // 옵션만 전달 (권장)
348
- new Ddu64(options?);
349
-
350
- // charset 직접 지정
351
- new Ddu64(dduChar, paddingChar, options?);
352
- ```
353
-
354
- | Option | Type | Default | 설명 |
355
- | ---------------------- | ----------------------- | ----------- | --------------------- |
356
- | `dduSetSymbol` | `DduSetSymbol` | `DDU` | 프리셋 선택 |
357
- | `dduChar` | `string \| string[]` | - | 커스텀 charset |
358
- | `paddingChar` | `string` | - | 패딩 문자 |
359
- | `codaChar` | `string[]` | - | 종성 조합 문자 |
360
- | `compress` | `boolean` | `false` | 압축 활성화 |
361
- | `compressionAlgorithm` | `"deflate" \| "brotli"` | `"deflate"` | 압축 알고리즘 |
362
- | `compressionLevel` | `number` | `6` | 압축 레벨 |
363
- | `encryptionKey` | `string` | - | AES-256-GCM 암호화 키 |
364
- | `keyDerivation` | `KeyDerivationOptions` | `sha256` | 키 파생 방식 |
365
- | `checksum` | `boolean` | `false` | CRC32 체크섬 |
366
- | `urlSafe` | `boolean` | `false` | URL-Safe 변환 |
367
- | `obfuscate` | `boolean` | `false` | 한글 난독화 |
368
- | `chunkSize` | `number` | - | 청크 분할 크기 |
369
- | `chunkSeparator` | `string` | `"\n"` | 청크 구분자 |
370
- | `maxDecodedBytes` | `number` | `67108864` | 디코딩 크기 제한 |
371
- | `maxDecompressedBytes` | `number` | `67108864` | 압축해제 크기 제한 |
372
- | `wasmThreshold` | `number` | `4096` | WASM 사용 임계값 |
373
- | `throwOnError` | `boolean` | `false` | 초기화 에러 시 throw |
374
-
375
- ## Per-Call Options
376
-
377
- `encode`, `decode`, `encodeAsync`, `decodeAsync` 등에서 호출별로 오버라이드 가능:
378
-
379
- | Option | Type | 설명 |
380
- | ---------------------- | ----------------------- | ------------------ |
381
- | `compress` | `boolean` | 압축 사용 여부 |
382
- | `compressionAlgorithm` | `"deflate" \| "brotli"` | 압축 알고리즘 |
383
- | `compressionLevel` | `number` | 압축 레벨 |
384
- | `encrypt` | `boolean` | 암호화 사용 여부 |
385
- | `checksum` | `boolean` | 체크섬 사용 여부 |
386
- | `obfuscate` | `boolean` | 난독화 사용 여부 |
387
- | `chunkSize` | `number` | 청크 크기 |
388
- | `maxDecodedBytes` | `number` | 디코딩 크기 제한 |
389
- | `maxDecompressedBytes` | `number` | 압축해제 크기 제한 |
390
- | `onProgress` | `(info) => void` | 진행률 콜백 |
391
-
392
- ## Entry Points
393
-
394
- | Import Path | 용도 |
395
- | ------------------------ | ------------------------------------- |
396
- | `@ddunigma/node` | Node.js 전체 기능 (동기+비동기) |
397
- | `@ddunigma/node/browser` | 브라우저 최적화 (BrowserAdapter 기본) |
398
- | `@ddunigma/node/core` | 최소 코어 (인코딩/디코딩만) |
399
-
400
- ## Build & Test
401
-
402
- ```bash
403
- pnpm test
404
- pnpm build
405
- pnpm lint
406
- pnpm bench
407
- ```
408
-
409
- ## License
410
-
411
- BSD-2-Clause
@@ -0,0 +1,2 @@
1
+ export{a as BrowserAdapter}from'./chunk-CQATQOBZ.js';import'./chunk-OQXMQIE3.js';//# sourceMappingURL=BrowserAdapter-HORDDCOE.js.map
2
+ //# sourceMappingURL=BrowserAdapter-HORDDCOE.js.map
@@ -0,0 +1,2 @@
1
+ 'use strict';var chunkAMOZHHMB_cjs=require('./chunk-AMOZHHMB.cjs');require('./chunk-5NSHXTMN.cjs');Object.defineProperty(exports,"BrowserAdapter",{enumerable:true,get:function(){return chunkAMOZHHMB_cjs.a}});//# sourceMappingURL=BrowserAdapter-PB4J6FHX.cjs.map
2
+ //# sourceMappingURL=BrowserAdapter-PB4J6FHX.cjs.map
@@ -0,0 +1,2 @@
1
+ export{a as NodeAdapter}from'./chunk-7RWUNW5S.js';import'./chunk-OQXMQIE3.js';//# sourceMappingURL=NodeAdapter-5FBNCJSG.js.map
2
+ //# sourceMappingURL=NodeAdapter-5FBNCJSG.js.map
@@ -0,0 +1,2 @@
1
+ 'use strict';var chunkHZJ7PU7X_cjs=require('./chunk-HZJ7PU7X.cjs');require('./chunk-5NSHXTMN.cjs');Object.defineProperty(exports,"NodeAdapter",{enumerable:true,get:function(){return chunkHZJ7PU7X_cjs.a}});//# sourceMappingURL=NodeAdapter-EQ73FGEJ.cjs.map
2
+ //# sourceMappingURL=NodeAdapter-EQ73FGEJ.cjs.map
@@ -1,4 +1,4 @@
1
- import { P as PlatformAdapter, i as KeyDerivationOptions, D as Ddu64Core, e as DduOptions, O as ObfuscationLayer } from './core-DYSnygnp.js';
1
+ import { P as PlatformAdapter, y as KeyDerivationOptions, D as Ddu64Core, u as DduOptions, O as ObfuscationLayer } from './errors-DNICpo4L.js';
2
2
 
3
3
  /**
4
4
  * 브라우저 플랫폼 어댑터 구현.
@@ -21,8 +21,9 @@ import { P as PlatformAdapter, i as KeyDerivationOptions, D as Ddu64Core, e as D
21
21
  declare class BrowserAdapter implements PlatformAdapter {
22
22
  readonly supportsSyncCrypto = false;
23
23
  readonly supportsSyncCompression = false;
24
- readonly supportsBrotli: boolean;
25
- readonly runtime: "browser";
24
+ readonly runtime: "browser" | "edge" | "deno" | "bun";
25
+ constructor(runtime?: "browser" | "edge" | "deno" | "bun");
26
+ get supportsBrotli(): boolean;
26
27
  /**
27
28
  * UTF-8 키 문자열에서 SHA-256을 통해 256비트 키를 파생합니다.
28
29
  * UTF-8 인코딩된 키에 SubtleCrypto.digest('SHA-256', ...)를 사용합니다.
@@ -35,13 +36,13 @@ declare class BrowserAdapter implements PlatformAdapter {
35
36
  * 참고: Web Crypto는 authTag를 암호문에 추가하므로,
36
37
  * 마지막 16바이트를 authTag로 추출하고 와이어 포맷에 맞게 재배치합니다.
37
38
  */
38
- encrypt(data: Uint8Array, keyHash: Uint8Array): Promise<Uint8Array>;
39
+ encrypt(data: Uint8Array, keyHash: Uint8Array, aad?: Uint8Array): Promise<Uint8Array>;
39
40
  /**
40
41
  * AES-256-GCM 페이로드를 복호화합니다.
41
42
  * 와이어 포맷 기대: IV(12바이트) + authTag(16바이트) + 암호문.
42
43
  * 복호화 전에 Web Crypto 형식(암호문 + authTag)으로 재구성합니다.
43
44
  */
44
- decrypt(data: Uint8Array, keyHash: Uint8Array): Promise<Uint8Array>;
45
+ decrypt(data: Uint8Array, keyHash: Uint8Array, aad?: Uint8Array): Promise<Uint8Array>;
45
46
  /**
46
47
  * 암호학적으로 안전한 랜덤 바이트를 생성합니다.
47
48
  */
@@ -97,8 +98,8 @@ declare function detectRuntime(): RuntimeId;
97
98
  * 모든 최신 브라우저와 Node.js에서 사용 가능합니다.
98
99
  *
99
100
  * 스트리밍 모드:
100
- * - 압축/암호화/체크섬 비활성화 + 2의 제곱수 charset: 진정한 청크 단위 스트리밍
101
- * - 외: 전체 축적 일괄 처리 (알고리즘/와이어 포맷 제약)
101
+ * - 인코딩: 압축/암호화/체크섬 비활성화 + 2의 제곱수 charset에서 청크 단위 출력
102
+ * - 디코딩: footer의 압축/암호화 마커를 최종 신뢰하기 위해 payload를 축적 후 처리
102
103
  *
103
104
  * 스트림 헤더 형식: [pad]DDS1[D|B|N][1|0][pad]
104
105
  * D=deflate, B=brotli, N=없음 (압축), 1/0 (암호화).
@@ -122,11 +123,8 @@ declare function createReadableEncodeStream(encoder: Ddu64Core, options?: DduOpt
122
123
  * charset 인코딩 문자열을 바이너리 데이터로 역변환하는
123
124
  * Web Streams API TransformStream을 생성합니다.
124
125
  *
125
- * 스트림은 DDS1 스트림 헤더를 파싱하여 압축 암호화 설정을 감지한 후
126
- * 페이로드를 그에 맞게 디코딩합니다.
127
- *
128
- * 압축/암호화/체크섬이 없고 charset이 2의 제곱수인 스트림은 헤더 파싱 후 각 청크를 즉시 디코딩합니다.
129
- * 그 외에는 전체 페이로드를 축적 후 일괄 디코딩합니다.
126
+ * 스트림은 DDS1 스트림 헤더를 조기 검증하되, 헤더만으로 복호화/압축해제를 비활성화하지 않습니다.
127
+ * footer가 최종 wire metadata이므로 전체 페이로드를 축적 일괄 디코딩합니다.
130
128
  *
131
129
  * @param encoder - 디코딩에 사용할 Ddu64Core 인스턴스
132
130
  * @param options - 디코딩 옵션
@@ -193,13 +191,31 @@ declare class HangulObfuscationLayer implements ObfuscationLayer {
193
191
  /**
194
192
  * 주어진 charset 설정에 대한 ObfuscationLayer를 생성합니다.
195
193
  *
196
- * charset 문자와 패딩 문자로부터 완전한 알파벳을 구성한
197
- * 한글 난독화 레이어를 생성합니다.
194
+ * @deprecated 인코더 출력과 호환되지 않습니다(charset/패딩만 포함, footer 마커·숫자 미포함).
195
+ * 인코더 출력을 deobfuscate하려면 `createEncoderObfuscationLayer`를, 일반 난독화는 `Ddu64`의
196
+ * `obfuscate` 옵션을 사용하세요. 이 함수는 다음 메이저에서 제거될 수 있습니다.
197
+ *
198
+ * charset 문자와 패딩 문자로부터 알파벳을 구성한 후 한글 난독화 레이어를 생성합니다.
198
199
  *
199
200
  * @param charSet - 인코딩에 사용되는 charset 문자
200
201
  * @param paddingChar - 패딩 문자
201
202
  * @returns ObfuscationLayer 인스턴스
202
203
  */
203
204
  declare function createObfuscationLayer(charSet: string[], paddingChar: string): ObfuscationLayer;
205
+ /**
206
+ * Ddu64 인코더 출력과 호환되는 ObfuscationLayer를 생성합니다.
207
+ *
208
+ * `createObfuscationLayer`와 달리 charset/패딩 외에 footer 마커
209
+ * (ELYSIA/GRISEO/ENC/V3/V4)와 숫자(0-9)까지 알파벳에 포함하므로, 압축/암호화/파이프라인
210
+ * 마커가 붙은 실제 인코더 출력도 안전하게 deobfuscate할 수 있습니다.
211
+ *
212
+ * 일반적으로는 `Ddu64`의 `obfuscate` 옵션을 쓰는 것으로 충분하며, 이 헬퍼는 인코더와
213
+ * 동일한 난독화 매핑을 외부에서 재현해야 할 때 사용합니다.
214
+ *
215
+ * @param charSet - 인코딩에 사용되는 charset 문자
216
+ * @param paddingChar - 패딩 문자
217
+ * @returns 인코더 호환 ObfuscationLayer 인스턴스
218
+ */
219
+ declare function createEncoderObfuscationLayer(charSet: string[], paddingChar: string): ObfuscationLayer;
204
220
 
205
- export { BrowserAdapter as B, HangulObfuscationLayer as H, createReadableDecodeStream as a, createReadableEncodeStream as b, createObfuscationLayer as c, detectRuntime as d };
221
+ export { BrowserAdapter as B, HangulObfuscationLayer as H, createObfuscationLayer as a, createReadableDecodeStream as b, createEncoderObfuscationLayer as c, createReadableEncodeStream as d, detectRuntime as e };