@laisuk/opencc-fmmseg-wasm 0.2.4 → 0.3.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.
package/README.md CHANGED
@@ -24,6 +24,13 @@ Features:
24
24
  * In-memory Office / EPUB document conversion
25
25
  * Zero-dependency Node.js CLI
26
26
 
27
+ Package profile:
28
+
29
+ * 0 runtime dependencies
30
+ * 1 WASM file
31
+ * 18 conversion configs
32
+ * 100% offline
33
+
27
34
  ---
28
35
 
29
36
  ## Installation
@@ -38,7 +45,8 @@ npm install @laisuk/opencc-fmmseg-wasm
38
45
 
39
46
  ```javascript
40
47
  import init, {
41
- OpenccWasm
48
+ OpenccWasm,
49
+ DetofuLevelWasm
42
50
  } from "@laisuk/opencc-fmmseg-wasm";
43
51
 
44
52
  await init();
@@ -47,6 +55,9 @@ const cc = new OpenccWasm("s2t");
47
55
 
48
56
  console.log(cc.convert("汉字", false));
49
57
  // 漢字
58
+
59
+ console.log(cc.convertDetofu("儼驂騑於上路", false, DetofuLevelWasm.ExtB));
60
+ // 俨骖騑于上路
50
61
  ```
51
62
 
52
63
  ---
@@ -54,43 +65,47 @@ console.log(cc.convert("汉字", false));
54
65
  ## Using Config Enums
55
66
 
56
67
  ```javascript
57
- import init, {
58
- OpenccWasm,
59
- OpenccConfigWasm
60
- } from "@laisuk/opencc-fmmseg-wasm";
61
-
62
- await init();
63
-
64
- const cc = OpenccWasm.newWithEnum(
65
- OpenccConfigWasm.S2t
66
- );
68
+ import init, {
69
+ OpenccWasm,
70
+ OpenccConfigWasm
71
+ } from "@laisuk/opencc-fmmseg-wasm";
67
72
 
68
- console.log(cc.convert("汉字", false));
69
- // 漢字
73
+ await init();
74
+
75
+ const cc = OpenccWasm.newWithEnum(
76
+ OpenccConfigWasm.S2hkp
77
+ );
78
+
79
+ console.log(cc.convert("别随便录影侵犯个人隐私权", false));
80
+ // 別隨便錄影侵犯個人私隱權
70
81
  ```
71
82
 
72
83
  ---
73
84
 
74
85
  ## Supported Configs
75
86
 
76
- | Config | Description |
77
- |---------|----------------------------------------------------|
78
- | `s2t` | Simplified Chinese → Traditional Chinese |
79
- | `s2tw` | Simplified Chinese → Taiwan Traditional |
80
- | `s2twp` | Simplified Chinese → Taiwan Traditional (phrases) |
81
- | `s2hk` | Simplified Chinese → Hong Kong Traditional |
82
- | `t2s` | Traditional Chinese → Simplified Chinese |
83
- | `t2tw` | Traditional Chinese → Taiwan Traditional |
84
- | `t2twp` | Traditional Chinese → Taiwan Traditional (phrases) |
85
- | `t2hk` | Traditional Chinese → Hong Kong Traditional |
86
- | `tw2s` | Taiwan Traditional → Simplified Chinese |
87
- | `tw2sp` | Taiwan Traditional → Simplified Chinese (phrases) |
88
- | `tw2t` | Taiwan Traditional → Traditional Chinese |
89
- | `tw2tp` | Taiwan Traditional → Traditional Chinese (phrases) |
90
- | `hk2s` | Hong Kong Traditional → Simplified Chinese |
91
- | `hk2t` | Hong Kong Traditional → Traditional Chinese |
92
- | `jp2t` | Japanese Shinjitai → Traditional Chinese |
93
- | `t2jp` | Traditional Chinese → Japanese Shinjitai |
87
+ | Config | Enum | Description |
88
+ |---------|--------------------------|------------------------------------------------------|
89
+ | `s2t` | `OpenccConfigWasm.S2t` | Simplified Chinese → Traditional Chinese |
90
+ | `s2tw` | `OpenccConfigWasm.S2tw` | Simplified Chinese → Taiwan Traditional |
91
+ | `s2twp` | `OpenccConfigWasm.S2twp` | Simplified Chinese → Taiwan Traditional (phrases) |
92
+ | `s2hk` | `OpenccConfigWasm.S2hk` | Simplified Chinese → Hong Kong Traditional |
93
+ | `s2hkp` | `OpenccConfigWasm.S2hkp` | Simplified Chinese → Hong Kong Traditional (phrases) |
94
+ | `t2s` | `OpenccConfigWasm.T2s` | Traditional Chinese → Simplified Chinese |
95
+ | `t2tw` | `OpenccConfigWasm.T2tw` | Traditional Chinese → Taiwan Traditional |
96
+ | `t2twp` | `OpenccConfigWasm.T2twp` | Traditional Chinese → Taiwan Traditional (phrases) |
97
+ | `t2hk` | `OpenccConfigWasm.T2hk` | Traditional Chinese → Hong Kong Traditional |
98
+ | `tw2s` | `OpenccConfigWasm.Tw2s` | Taiwan Traditional → Simplified Chinese |
99
+ | `tw2sp` | `OpenccConfigWasm.Tw2sp` | Taiwan Traditional → Simplified Chinese (phrases) |
100
+ | `tw2t` | `OpenccConfigWasm.Tw2t` | Taiwan Traditional → Traditional Chinese |
101
+ | `tw2tp` | `OpenccConfigWasm.Tw2tp` | Taiwan Traditional → Traditional Chinese (phrases) |
102
+ | `hk2s` | `OpenccConfigWasm.Hk2s` | Hong Kong Traditional → Simplified Chinese |
103
+ | `hk2sp` | `OpenccConfigWasm.Hk2sp` | Hong Kong Traditional → Simplified Chinese (phrases) |
104
+ | `hk2t` | `OpenccConfigWasm.Hk2t` | Hong Kong Traditional → Traditional Chinese |
105
+ | `jp2t` | `OpenccConfigWasm.Jp2t` | Japanese Shinjitai → Traditional Chinese |
106
+ | `t2jp` | `OpenccConfigWasm.T2jp` | Traditional Chinese → Japanese Shinjitai |
107
+
108
+ The numeric enum values match the vendored Rust backend. Existing values are unchanged; `S2hkp = 17` and `Hk2sp = 18`.
94
109
 
95
110
  ---
96
111
 
@@ -113,6 +128,15 @@ Example:
113
128
  const cc = new OpenccWasm("t2s");
114
129
  ```
115
130
 
131
+ Hong Kong phrase config example:
132
+
133
+ ```javascript
134
+ const cc = new OpenccWasm("s2hkp");
135
+
136
+ cc.convert("别随便录影侵犯个人隐私权", false);
137
+ // 別隨便錄影侵犯個人私隱權
138
+ ```
139
+
116
140
  ---
117
141
 
118
142
  ### convert
@@ -138,6 +162,85 @@ cc.convert("汉字", false);
138
162
 
139
163
  ---
140
164
 
165
+ ### detofu
166
+
167
+ Replace tofu-risk rare CJK extension characters with display-compatible fallbacks.
168
+
169
+ ```javascript
170
+ cc.detofu(text, level)
171
+ ```
172
+
173
+ Parameters:
174
+
175
+ * `text`: input string
176
+ * `level`: `DetofuLevelWasm` threshold for the CJK extension ranges to replace
177
+
178
+ Returns:
179
+
180
+ * detofu-safe string
181
+
182
+ Supported levels:
183
+
184
+ | Enum | CLI value |
185
+ |------------------------|-----------|
186
+ | `DetofuLevelWasm.ExtB` | `ext-b` |
187
+ | `DetofuLevelWasm.ExtC` | `ext-c` |
188
+ | `DetofuLevelWasm.ExtD` | `ext-d` |
189
+ | `DetofuLevelWasm.ExtE` | `ext-e` |
190
+ | `DetofuLevelWasm.ExtF` | `ext-f` |
191
+ | `DetofuLevelWasm.ExtG` | `ext-g` |
192
+ | `DetofuLevelWasm.ExtH` | `ext-h` |
193
+ | `DetofuLevelWasm.ExtI` | `ext-i` |
194
+
195
+ Example:
196
+
197
+ ```javascript
198
+ import init, {
199
+ OpenccWasm,
200
+ DetofuLevelWasm
201
+ } from "@laisuk/opencc-fmmseg-wasm";
202
+
203
+ await init();
204
+
205
+ const cc = new OpenccWasm("t2s");
206
+ const converted = cc.convert("儼驂騑於上路", false);
207
+
208
+ console.log(converted);
209
+ // 俨骖𬴂于上路
210
+
211
+ console.log(cc.detofu(converted, DetofuLevelWasm.ExtB));
212
+ // 俨骖騑于上路
213
+ ```
214
+
215
+ ---
216
+
217
+ ### convertDetofu
218
+
219
+ Convert text and apply detofu in one call.
220
+
221
+ ```javascript
222
+ cc.convertDetofu(text, punctuation, level)
223
+ ```
224
+
225
+ Parameters:
226
+
227
+ * `text`: input string
228
+ * `punctuation`: whether to convert punctuation variants
229
+ * `level`: `DetofuLevelWasm` threshold for the CJK extension ranges to replace
230
+
231
+ Returns:
232
+
233
+ * converted detofu-safe string
234
+
235
+ Example:
236
+
237
+ ```javascript
238
+ cc.convertDetofu("儼驂騑於上路", false, DetofuLevelWasm.ExtB);
239
+ // 俨骖騑于上路
240
+ ```
241
+
242
+ ---
243
+
141
244
  ### setConfig
142
245
 
143
246
  ```javascript
@@ -177,6 +280,8 @@ OpenccWasm.getSupportedConfigs();
177
280
 
178
281
  Returns all supported config strings.
179
282
 
283
+ Includes `s2hkp` and `hk2sp`.
284
+
180
285
  ---
181
286
 
182
287
  ### zhoCheck
@@ -197,6 +302,137 @@ Returns:
197
302
 
198
303
  ---
199
304
 
305
+ ### newWithCustomDicts
306
+
307
+ Construct a converter with in-memory custom dictionary pairs.
308
+
309
+ ```javascript
310
+ const cc = OpenccWasm.newWithCustomDicts(config, specs);
311
+ ```
312
+
313
+ Parameters:
314
+
315
+ * `config`: OpenCC config string, such as `"s2t"`
316
+ * `specs`: array of custom dictionary specs
317
+
318
+ TypeScript-style spec shape:
319
+
320
+ ```typescript
321
+ type WasmCustomDictSpec = {
322
+ slot: string;
323
+ mode?: "Append" | "Override";
324
+ pairs: Array<[string, string]>;
325
+ };
326
+ ```
327
+
328
+ `mode` defaults to `"Append"` when omitted.
329
+
330
+ Each `pairs` entry is a `[source, target]` string tuple for the selected slot.
331
+
332
+ TypeScript example:
333
+
334
+ ```typescript
335
+ import init, {OpenccWasm} from "@laisuk/opencc-fmmseg-wasm";
336
+
337
+ await init();
338
+
339
+ const specs: WasmCustomDictSpec[] = [
340
+ {
341
+ slot: "STPhrases",
342
+ pairs: [
343
+ ["云端", "雲端"]
344
+ ]
345
+ }
346
+ ];
347
+
348
+ const cc = OpenccWasm.newWithCustomDicts("s2t", specs);
349
+ ```
350
+
351
+ Practical example:
352
+
353
+ ```javascript
354
+ import init, {OpenccWasm} from "@laisuk/opencc-fmmseg-wasm";
355
+
356
+ await init();
357
+
358
+ const cc = OpenccWasm.newWithCustomDicts("s2t", [
359
+ {
360
+ slot: "STPhrases",
361
+ mode: "Append",
362
+ pairs: [
363
+ ["帕兰蒂尔", "柏蘭蒂爾"],
364
+ ["软件", "軟體"]
365
+ ]
366
+ }
367
+ ]);
368
+
369
+ console.log(cc.convert("帕兰蒂尔软件", false));
370
+ // 柏蘭蒂爾軟體
371
+ ```
372
+
373
+ Override example:
374
+
375
+ ```javascript
376
+ const cc = OpenccWasm.newWithCustomDicts("s2t", [
377
+ {
378
+ slot: "STPhrases",
379
+ mode: "Override",
380
+ pairs: [
381
+ ["软件", "軟體"]
382
+ ]
383
+ }
384
+ ]);
385
+ ```
386
+
387
+ `Override` replaces the selected slot before inserting the provided pairs. It is powerful and should be used only when
388
+ the caller intentionally wants to discard built-in entries for that slot.
389
+
390
+ Custom dictionary specs use strict canonical `DictSlot` names:
391
+
392
+ ```text
393
+ STPhrases
394
+ TSPhrases
395
+ STCharacters
396
+ TSCharacters
397
+ TWPhrases
398
+ TWPhrasesRev
399
+ HKPhrases
400
+ HKPhrasesRev
401
+ TWVariants
402
+ TWVariantsPhrases
403
+ TWVariantsRev
404
+ TWVariantsRevPhrases
405
+ HKVariants
406
+ HKVariantsPhrases
407
+ HKVariantsRev
408
+ HKVariantsRevPhrases
409
+ JPShinjitaiCharacters
410
+ JPShinjitaiPhrases
411
+ JPVariants
412
+ JPVariantsRev
413
+ STPunctuations
414
+ TSPunctuations
415
+ ```
416
+
417
+ Suffixes such as `.txt` are not accepted. Use `"STPhrases"`, not `"STPhrases.txt"`.
418
+
419
+ Merge contract:
420
+
421
+ * Custom dictionaries are loaded from in-memory pairs only; no file I/O is involved.
422
+ * The embedded compressed CBOR dictionary is loaded first.
423
+ * Custom specs are applied to `DictionaryMaxlength` before `OpenCC::from_dictionary(...)`.
424
+ * Conversion hot paths remain immutable after construction.
425
+ * `Append` mode merges into the selected slot.
426
+ * Duplicate or conflicting keys use last-wins semantics.
427
+ * `Override` mode clears the selected slot first, then inserts the provided custom pairs.
428
+ * Multiple specs are applied in array order.
429
+
430
+ This API is useful for browser apps, user-defined terminology, database-loaded terms, generated dictionaries,
431
+ `localStorage` or `IndexedDB` terms, testing, and embedded WASM environments. Customization happens at construction
432
+ time, not during conversion.
433
+
434
+ ---
435
+
200
436
  ## Office / EPUB Conversion
201
437
 
202
438
  Office and EPUB conversion runs fully locally in the browser or Node.js. Files are passed in and returned as bytes;
@@ -308,6 +544,26 @@ fs.writeFileSync("output.docx", outputBytes);
308
544
  </html>
309
545
  ```
310
546
 
547
+ > **Note**
548
+ >
549
+ > The npm package automatically loads the bundled WebAssembly module when
550
+ > installed normally via npm.
551
+ >
552
+ > If you are running examples directly from a local repository checkout,
553
+ > you may need to initialize using explicit WASM bytes:
554
+ >
555
+ > ```javascript
556
+ > import fs from "fs";
557
+ > import init from "../pkg/opencc_fmmseg_wasm.js";
558
+ >
559
+ > const wasmBytes = fs.readFileSync(
560
+ > "../pkg/opencc_fmmseg_wasm_bg.wasm"
561
+ > );
562
+ >
563
+ > await init({ module: wasmBytes });
564
+ > ```
565
+ >
566
+
311
567
  ---
312
568
 
313
569
  ## Node.js CLI
@@ -316,6 +572,8 @@ The package includes a zero-dependency Node.js CLI:
316
572
 
317
573
  ```bash
318
574
  opencc-fmmseg convert -i input.txt -o output.txt -c s2t -p
575
+ opencc-fmmseg convert -i input.txt -o output.txt -c t2s -p --detofu all
576
+ echo "别随便录影侵犯个人隐私权" | opencc-fmmseg convert -c s2hkp
319
577
  ```
320
578
 
321
579
  ```bash
@@ -329,10 +587,20 @@ opencc-fmmseg office -i input.docx -o output.docx -c s2t -p --keep-font
329
587
  -o, --output <file> Output text file
330
588
  -c, --config <conversion> Conversion config
331
589
  -p, --punct Enable punctuation conversion
590
+ --detofu [level] Replace tofu-risk rare CJK extension chars after conversion
591
+ level: all | ext-b | ext-c | ext-d | ext-e | ext-f | ext-g | ext-h | ext-i
592
+ default when omitted value: all
332
593
  --in-enc <encoding> Input encoding
333
594
  --out-enc <encoding> Output encoding
334
595
  ```
335
596
 
597
+ Supported conversion configs:
598
+
599
+ ```text
600
+ s2t, s2tw, s2twp, s2hk, s2hkp, t2s, t2tw, t2twp, t2hk,
601
+ tw2s, tw2sp, tw2t, tw2tp, hk2s, hk2sp, hk2t, jp2t, t2jp
602
+ ```
603
+
336
604
  ### Office / EPUB Options
337
605
 
338
606
  ```text
@@ -356,13 +624,16 @@ If `-o, --output` is omitted, `office` writes:
356
624
 
357
625
  ---
358
626
 
359
- ## TypeScript Support
360
-
361
- The package includes generated TypeScript definitions from `wasm-bindgen`.
362
-
363
- The WASM-facing enum is exported as `OpenccConfigWasm`, alongside `OpenccWasm`.
364
-
365
- ---
627
+ ## TypeScript Support
628
+
629
+ The package includes generated TypeScript definitions from `wasm-bindgen`.
630
+
631
+ The WASM-facing enum is exported as `OpenccConfigWasm`, alongside `OpenccWasm`.
632
+
633
+ `OpenccConfigWasm.S2hkp` and `OpenccConfigWasm.Hk2sp` are available for Hong Kong phrase conversions and map to backend
634
+ config IDs `17` and `18`.
635
+
636
+ ---
366
637
 
367
638
  ## Performance Notes
368
639
 
package/bin/opencc.js CHANGED
@@ -6,6 +6,7 @@ import process from "process";
6
6
 
7
7
  import init, {
8
8
  OpenccWasm,
9
+ DetofuLevelWasm,
9
10
  convert_office_bytes
10
11
  } from "../opencc_fmmseg_wasm.js";
11
12
 
@@ -53,9 +54,16 @@ Convert options:
53
54
  -o, --output <file> Output text file; stdout if omitted
54
55
  -c, --config <conversion> Conversion config (default: s2t)
55
56
  -p, --punct Enable punctuation conversion
57
+ --detofu [level] Replace tofu-risk rare CJK extension chars after conversion
58
+ level: all | ext-b | ext-c | ext-d | ext-e | ext-f | ext-g | ext-h | ext-i
59
+ default when omitted value: all
56
60
  --in-enc <encoding> Input encoding (default: utf8)
57
61
  --out-enc <encoding> Output encoding (default: utf8)
58
62
 
63
+ Supported configs:
64
+ s2t, s2tw, s2twp, s2hk, s2hkp, t2s, t2tw, t2twp, t2hk,
65
+ tw2s, tw2sp, tw2t, tw2tp, hk2s, hk2sp, hk2t, jp2t, t2jp
66
+
59
67
  Office options:
60
68
  -i, --input <file> Input Office / EPUB file
61
69
  -o, --output <file> Output file
@@ -73,6 +81,9 @@ Examples:
73
81
  npx opencc-fmmseg convert -i a.txt -o b.txt -c s2t
74
82
  npx opencc-fmmseg convert -i a.txt -o b.txt -c s2tw -p
75
83
  cat a.txt | npx opencc-fmmseg convert -c t2s
84
+ echo "别随便录影侵犯个人隐私权" | npx opencc-fmmseg convert -c s2hkp
85
+ npx opencc-fmmseg convert -i a.txt -o b.txt -c t2s --detofu
86
+ npx opencc-fmmseg convert -i a.txt -o b.txt -c t2s --detofu ext-c
76
87
 
77
88
  npx opencc-fmmseg office -i a.docx -o b.docx -c s2t -p
78
89
  npx opencc-fmmseg office -i a.epub -c s2tw --auto-ext
@@ -179,6 +190,56 @@ function applyAutoExt(outputFile, officeFormat, autoExt) {
179
190
  return `${outputFile}.${officeFormat}`;
180
191
  }
181
192
 
193
+ function parseDetofuLevel(value) {
194
+ if (value === null || value === undefined || value === true) {
195
+ return DetofuLevelWasm.ExtB; // "all"
196
+ }
197
+
198
+ const normalized = String(value).trim().toLowerCase();
199
+
200
+ switch (normalized) {
201
+ case "":
202
+ case "all":
203
+ case "ext-b":
204
+ case "extb":
205
+ case "b":
206
+ return DetofuLevelWasm.ExtB;
207
+ case "ext-c":
208
+ case "extc":
209
+ case "c":
210
+ return DetofuLevelWasm.ExtC;
211
+ case "ext-d":
212
+ case "extd":
213
+ case "d":
214
+ return DetofuLevelWasm.ExtD;
215
+ case "ext-e":
216
+ case "exte":
217
+ case "e":
218
+ return DetofuLevelWasm.ExtE;
219
+ case "ext-f":
220
+ case "extf":
221
+ case "f":
222
+ return DetofuLevelWasm.ExtF;
223
+ case "ext-g":
224
+ case "extg":
225
+ case "g":
226
+ return DetofuLevelWasm.ExtG;
227
+ case "ext-h":
228
+ case "exth":
229
+ case "h":
230
+ return DetofuLevelWasm.ExtH;
231
+ case "ext-i":
232
+ case "exti":
233
+ case "i":
234
+ return DetofuLevelWasm.ExtI;
235
+ default:
236
+ throw new Error(
237
+ `Invalid detofu level: ${value}. ` +
238
+ `Valid values: all | ext-b | ext-c | ext-d | ext-e | ext-f | ext-g | ext-h | ext-i`
239
+ );
240
+ }
241
+ }
242
+
182
243
  async function runConvert(args) {
183
244
  const input = getArg(args, "-i", "--input");
184
245
  const output = getArg(args, "-o", "--output");
@@ -187,6 +248,20 @@ async function runConvert(args) {
187
248
  const outEnc = getArg(args, null, "--out-enc", "utf8");
188
249
  const punct = hasFlag(args, "-p", "--punct");
189
250
 
251
+ const detofuIndex = args.indexOf("--detofu");
252
+ const detofuEnabled = detofuIndex !== -1;
253
+ let detofuLevel = null;
254
+
255
+ if (detofuEnabled) {
256
+ const next = args[detofuIndex + 1];
257
+
258
+ if (!next || next.startsWith("-")) {
259
+ detofuLevel = parseDetofuLevel("all");
260
+ } else {
261
+ detofuLevel = parseDetofuLevel(next);
262
+ }
263
+ }
264
+
190
265
  await ensureWasmInitialized();
191
266
 
192
267
  const cc = new OpenccWasm(config);
@@ -197,7 +272,11 @@ async function runConvert(args) {
197
272
  }
198
273
 
199
274
  const inputText = readInputText(input, inEnc);
200
- const outputText = cc.convert(inputText, punct);
275
+ let outputText = cc.convert(inputText, punct);
276
+
277
+ if (detofuEnabled) {
278
+ outputText = cc.detofu(outputText, detofuLevel);
279
+ }
201
280
 
202
281
  writeOutputText(output, outputText, outEnc);
203
282
 
@@ -209,7 +288,8 @@ async function runConvert(args) {
209
288
  console.error();
210
289
  }
211
290
 
212
- console.error(`Conversion completed (${config}): ${inFrom} -> ${outTo}`);
291
+ const suffix = detofuEnabled ? ", detofu" : "";
292
+ console.error(`Conversion completed (${config}${suffix}): ${inFrom} -> ${outTo}`);
213
293
  }
214
294
  }
215
295
 
@@ -1,6 +1,17 @@
1
1
  /* tslint:disable */
2
2
  /* eslint-disable */
3
3
 
4
+ export enum DetofuLevelWasm {
5
+ ExtB = 2,
6
+ ExtC = 3,
7
+ ExtD = 4,
8
+ ExtE = 5,
9
+ ExtF = 6,
10
+ ExtG = 7,
11
+ ExtH = 8,
12
+ ExtI = 9,
13
+ }
14
+
4
15
  export enum OpenccConfigWasm {
5
16
  S2t = 1,
6
17
  S2tw = 2,
@@ -18,18 +29,23 @@ export enum OpenccConfigWasm {
18
29
  Hk2t = 14,
19
30
  Jp2t = 15,
20
31
  T2jp = 16,
32
+ S2hkp = 17,
33
+ Hk2sp = 18,
21
34
  }
22
35
 
23
36
  export class OpenccWasm {
24
37
  free(): void;
25
38
  [Symbol.dispose](): void;
26
39
  convert(text: string, punctuation: boolean): string;
40
+ convertDetofu(text: string, punctuation: boolean, level: DetofuLevelWasm): string;
27
41
  debugPing(): string;
42
+ detofu(text: string, level: DetofuLevelWasm): string;
28
43
  getConfig(): string;
29
44
  getConfigId(): number;
30
45
  static getSupportedConfigs(): string[];
31
46
  static isValidConfig(config: string): boolean;
32
47
  constructor(config?: string | null);
48
+ static newWithCustomDicts(config: string | null | undefined, specs: any): OpenccWasm;
33
49
  static newWithEnum(config?: OpenccConfigWasm | null): OpenccWasm;
34
50
  setConfig(config: string): boolean;
35
51
  setConfigEnum(config: OpenccConfigWasm): void;
@@ -45,19 +61,24 @@ export interface InitOutput {
45
61
  readonly __wbg_openccwasm_free: (a: number, b: number) => void;
46
62
  readonly convert_office_bytes: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => [number, number, number, number];
47
63
  readonly openccwasm_convert: (a: number, b: number, c: number, d: number) => [number, number];
64
+ readonly openccwasm_convertDetofu: (a: number, b: number, c: number, d: number, e: number) => [number, number];
48
65
  readonly openccwasm_debugPing: (a: number) => [number, number];
66
+ readonly openccwasm_detofu: (a: number, b: number, c: number, d: number) => [number, number];
49
67
  readonly openccwasm_getConfig: (a: number) => [number, number];
50
68
  readonly openccwasm_getConfigId: (a: number) => number;
51
69
  readonly openccwasm_getSupportedConfigs: () => [number, number];
52
70
  readonly openccwasm_isValidConfig: (a: number, b: number) => number;
53
71
  readonly openccwasm_new: (a: number, b: number) => [number, number, number];
72
+ readonly openccwasm_newWithCustomDicts: (a: number, b: number, c: any) => [number, number, number];
54
73
  readonly openccwasm_newWithEnum: (a: number) => [number, number, number];
55
74
  readonly openccwasm_setConfig: (a: number, b: number, c: number) => number;
56
75
  readonly openccwasm_setConfigEnum: (a: number, b: number) => void;
57
76
  readonly openccwasm_zhoCheck: (a: number, b: number, c: number) => number;
58
- readonly __wbindgen_externrefs: WebAssembly.Table;
59
77
  readonly __wbindgen_malloc: (a: number, b: number) => number;
60
78
  readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
79
+ readonly __wbindgen_exn_store: (a: number) => void;
80
+ readonly __externref_table_alloc: () => number;
81
+ readonly __wbindgen_externrefs: WebAssembly.Table;
61
82
  readonly __externref_table_dealloc: (a: number) => void;
62
83
  readonly __wbindgen_free: (a: number, b: number, c: number) => void;
63
84
  readonly __externref_drop_slice: (a: number, b: number) => void;
@@ -1,7 +1,21 @@
1
1
  /* @ts-self-types="./opencc_fmmseg_wasm.d.ts" */
2
2
 
3
3
  /**
4
- * @enum {1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16}
4
+ * @enum {2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}
5
+ */
6
+ export const DetofuLevelWasm = Object.freeze({
7
+ ExtB: 2, "2": "ExtB",
8
+ ExtC: 3, "3": "ExtC",
9
+ ExtD: 4, "4": "ExtD",
10
+ ExtE: 5, "5": "ExtE",
11
+ ExtF: 6, "6": "ExtF",
12
+ ExtG: 7, "7": "ExtG",
13
+ ExtH: 8, "8": "ExtH",
14
+ ExtI: 9, "9": "ExtI",
15
+ });
16
+
17
+ /**
18
+ * @enum {1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18}
5
19
  */
6
20
  export const OpenccConfigWasm = Object.freeze({
7
21
  S2t: 1, "1": "S2t",
@@ -20,6 +34,8 @@ export const OpenccConfigWasm = Object.freeze({
20
34
  Hk2t: 14, "14": "Hk2t",
21
35
  Jp2t: 15, "15": "Jp2t",
22
36
  T2jp: 16, "16": "T2jp",
37
+ S2hkp: 17, "17": "S2hkp",
38
+ Hk2sp: 18, "18": "Hk2sp",
23
39
  });
24
40
 
25
41
  export class OpenccWasm {
@@ -58,6 +74,26 @@ export class OpenccWasm {
58
74
  wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
59
75
  }
60
76
  }
77
+ /**
78
+ * @param {string} text
79
+ * @param {boolean} punctuation
80
+ * @param {DetofuLevelWasm} level
81
+ * @returns {string}
82
+ */
83
+ convertDetofu(text, punctuation, level) {
84
+ let deferred2_0;
85
+ let deferred2_1;
86
+ try {
87
+ const ptr0 = passStringToWasm0(text, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
88
+ const len0 = WASM_VECTOR_LEN;
89
+ const ret = wasm.openccwasm_convertDetofu(this.__wbg_ptr, ptr0, len0, punctuation, level);
90
+ deferred2_0 = ret[0];
91
+ deferred2_1 = ret[1];
92
+ return getStringFromWasm0(ret[0], ret[1]);
93
+ } finally {
94
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
95
+ }
96
+ }
61
97
  /**
62
98
  * @returns {string}
63
99
  */
@@ -73,6 +109,25 @@ export class OpenccWasm {
73
109
  wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
74
110
  }
75
111
  }
112
+ /**
113
+ * @param {string} text
114
+ * @param {DetofuLevelWasm} level
115
+ * @returns {string}
116
+ */
117
+ detofu(text, level) {
118
+ let deferred2_0;
119
+ let deferred2_1;
120
+ try {
121
+ const ptr0 = passStringToWasm0(text, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
122
+ const len0 = WASM_VECTOR_LEN;
123
+ const ret = wasm.openccwasm_detofu(this.__wbg_ptr, ptr0, len0, level);
124
+ deferred2_0 = ret[0];
125
+ deferred2_1 = ret[1];
126
+ return getStringFromWasm0(ret[0], ret[1]);
127
+ } finally {
128
+ wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
129
+ }
130
+ }
76
131
  /**
77
132
  * @returns {string}
78
133
  */
@@ -128,6 +183,20 @@ export class OpenccWasm {
128
183
  OpenccWasmFinalization.register(this, this.__wbg_ptr, this);
129
184
  return this;
130
185
  }
186
+ /**
187
+ * @param {string | null | undefined} config
188
+ * @param {any} specs
189
+ * @returns {OpenccWasm}
190
+ */
191
+ static newWithCustomDicts(config, specs) {
192
+ var ptr0 = isLikeNone(config) ? 0 : passStringToWasm0(config, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
193
+ var len0 = WASM_VECTOR_LEN;
194
+ const ret = wasm.openccwasm_newWithCustomDicts(ptr0, len0, specs);
195
+ if (ret[2]) {
196
+ throw takeFromExternrefTable0(ret[1]);
197
+ }
198
+ return OpenccWasm.__wrap(ret[0]);
199
+ }
131
200
  /**
132
201
  * @param {OpenccConfigWasm | null} [config]
133
202
  * @returns {OpenccWasm}
@@ -194,9 +263,142 @@ export function convert_office_bytes(input, format, config, punctuation, keep_fo
194
263
  function __wbg_get_imports() {
195
264
  const import0 = {
196
265
  __proto__: null,
266
+ __wbg_Error_ef53bc310eb298a0: function(arg0, arg1) {
267
+ const ret = Error(getStringFromWasm0(arg0, arg1));
268
+ return ret;
269
+ },
270
+ __wbg_String_8564e559799eccda: function(arg0, arg1) {
271
+ const ret = String(arg1);
272
+ const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
273
+ const len1 = WASM_VECTOR_LEN;
274
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
275
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
276
+ },
277
+ __wbg___wbindgen_boolean_get_1a45e2c38d4d41b9: function(arg0) {
278
+ const v = arg0;
279
+ const ret = typeof(v) === 'boolean' ? v : undefined;
280
+ return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;
281
+ },
282
+ __wbg___wbindgen_debug_string_0accd80f45e5faa2: function(arg0, arg1) {
283
+ const ret = debugString(arg1);
284
+ const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
285
+ const len1 = WASM_VECTOR_LEN;
286
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
287
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
288
+ },
289
+ __wbg___wbindgen_in_70a403a56e771704: function(arg0, arg1) {
290
+ const ret = arg0 in arg1;
291
+ return ret;
292
+ },
293
+ __wbg___wbindgen_is_function_754e9f305ff6029e: function(arg0) {
294
+ const ret = typeof(arg0) === 'function';
295
+ return ret;
296
+ },
297
+ __wbg___wbindgen_is_object_56732c2bc353f41d: function(arg0) {
298
+ const val = arg0;
299
+ const ret = typeof(val) === 'object' && val !== null;
300
+ return ret;
301
+ },
302
+ __wbg___wbindgen_is_undefined_67b456be8673d3d7: function(arg0) {
303
+ const ret = arg0 === undefined;
304
+ return ret;
305
+ },
306
+ __wbg___wbindgen_jsval_loose_eq_2c56564c75129511: function(arg0, arg1) {
307
+ const ret = arg0 == arg1;
308
+ return ret;
309
+ },
310
+ __wbg___wbindgen_number_get_9bb1761122181af2: function(arg0, arg1) {
311
+ const obj = arg1;
312
+ const ret = typeof(obj) === 'number' ? obj : undefined;
313
+ getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true);
314
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);
315
+ },
316
+ __wbg___wbindgen_string_get_72bdf95d3ae505b1: function(arg0, arg1) {
317
+ const obj = arg1;
318
+ const ret = typeof(obj) === 'string' ? obj : undefined;
319
+ var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
320
+ var len1 = WASM_VECTOR_LEN;
321
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
322
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
323
+ },
197
324
  __wbg___wbindgen_throw_1506f2235d1bdba0: function(arg0, arg1) {
198
325
  throw new Error(getStringFromWasm0(arg0, arg1));
199
326
  },
327
+ __wbg_call_8a89609d89f6608a: function() { return handleError(function (arg0, arg1) {
328
+ const ret = arg0.call(arg1);
329
+ return ret;
330
+ }, arguments); },
331
+ __wbg_done_60cf307fcc680536: function(arg0) {
332
+ const ret = arg0.done;
333
+ return ret;
334
+ },
335
+ __wbg_get_1f8f054ddbaa7db2: function() { return handleError(function (arg0, arg1) {
336
+ const ret = Reflect.get(arg0, arg1);
337
+ return ret;
338
+ }, arguments); },
339
+ __wbg_get_unchecked_33f6e5c9e2f2d6b2: function(arg0, arg1) {
340
+ const ret = arg0[arg1 >>> 0];
341
+ return ret;
342
+ },
343
+ __wbg_get_with_ref_key_6412cf3094599694: function(arg0, arg1) {
344
+ const ret = arg0[arg1];
345
+ return ret;
346
+ },
347
+ __wbg_instanceof_ArrayBuffer_8f49811467741499: function(arg0) {
348
+ let result;
349
+ try {
350
+ result = arg0 instanceof ArrayBuffer;
351
+ } catch (_) {
352
+ result = false;
353
+ }
354
+ const ret = result;
355
+ return ret;
356
+ },
357
+ __wbg_instanceof_Uint8Array_86f30649f63ef9c2: function(arg0) {
358
+ let result;
359
+ try {
360
+ result = arg0 instanceof Uint8Array;
361
+ } catch (_) {
362
+ result = false;
363
+ }
364
+ const ret = result;
365
+ return ret;
366
+ },
367
+ __wbg_isArray_67c2c9c4313f4448: function(arg0) {
368
+ const ret = Array.isArray(arg0);
369
+ return ret;
370
+ },
371
+ __wbg_iterator_8732428d309e270e: function() {
372
+ const ret = Symbol.iterator;
373
+ return ret;
374
+ },
375
+ __wbg_length_4a591ecaa01354d9: function(arg0) {
376
+ const ret = arg0.length;
377
+ return ret;
378
+ },
379
+ __wbg_length_66f1a4b2e9026940: function(arg0) {
380
+ const ret = arg0.length;
381
+ return ret;
382
+ },
383
+ __wbg_new_578aeef4b6b94378: function(arg0) {
384
+ const ret = new Uint8Array(arg0);
385
+ return ret;
386
+ },
387
+ __wbg_next_9e03acdf51c4960d: function(arg0) {
388
+ const ret = arg0.next;
389
+ return ret;
390
+ },
391
+ __wbg_next_eb8ca7351fa27906: function() { return handleError(function (arg0) {
392
+ const ret = arg0.next();
393
+ return ret;
394
+ }, arguments); },
395
+ __wbg_prototypesetcall_3249fc62a0fafa30: function(arg0, arg1, arg2) {
396
+ Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), arg2);
397
+ },
398
+ __wbg_value_f3625092ee4b37f4: function(arg0) {
399
+ const ret = arg0.value;
400
+ return ret;
401
+ },
200
402
  __wbindgen_cast_0000000000000001: function(arg0, arg1) {
201
403
  // Cast intrinsic for `Ref(String) -> Externref`.
202
404
  const ret = getStringFromWasm0(arg0, arg1);
@@ -222,6 +424,77 @@ const OpenccWasmFinalization = (typeof FinalizationRegistry === 'undefined')
222
424
  ? { register: () => {}, unregister: () => {} }
223
425
  : new FinalizationRegistry(ptr => wasm.__wbg_openccwasm_free(ptr, 1));
224
426
 
427
+ function addToExternrefTable0(obj) {
428
+ const idx = wasm.__externref_table_alloc();
429
+ wasm.__wbindgen_externrefs.set(idx, obj);
430
+ return idx;
431
+ }
432
+
433
+ function debugString(val) {
434
+ // primitive types
435
+ const type = typeof val;
436
+ if (type == 'number' || type == 'boolean' || val == null) {
437
+ return `${val}`;
438
+ }
439
+ if (type == 'string') {
440
+ return `"${val}"`;
441
+ }
442
+ if (type == 'symbol') {
443
+ const description = val.description;
444
+ if (description == null) {
445
+ return 'Symbol';
446
+ } else {
447
+ return `Symbol(${description})`;
448
+ }
449
+ }
450
+ if (type == 'function') {
451
+ const name = val.name;
452
+ if (typeof name == 'string' && name.length > 0) {
453
+ return `Function(${name})`;
454
+ } else {
455
+ return 'Function';
456
+ }
457
+ }
458
+ // objects
459
+ if (Array.isArray(val)) {
460
+ const length = val.length;
461
+ let debug = '[';
462
+ if (length > 0) {
463
+ debug += debugString(val[0]);
464
+ }
465
+ for(let i = 1; i < length; i++) {
466
+ debug += ', ' + debugString(val[i]);
467
+ }
468
+ debug += ']';
469
+ return debug;
470
+ }
471
+ // Test for built-in
472
+ const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
473
+ let className;
474
+ if (builtInMatches && builtInMatches.length > 1) {
475
+ className = builtInMatches[1];
476
+ } else {
477
+ // Failed to match the standard '[object ClassName]'
478
+ return toString.call(val);
479
+ }
480
+ if (className == 'Object') {
481
+ // we're a user defined class or Object
482
+ // JSON.stringify avoids problems with cycles, and is generally much
483
+ // easier than looping through ownProperties of `val`.
484
+ try {
485
+ return 'Object(' + JSON.stringify(val) + ')';
486
+ } catch (_) {
487
+ return 'Object';
488
+ }
489
+ }
490
+ // errors
491
+ if (val instanceof Error) {
492
+ return `${val.name}: ${val.message}\n${val.stack}`;
493
+ }
494
+ // TODO we could test for more things here, like `Set`s and `Map`s.
495
+ return className;
496
+ }
497
+
225
498
  function getArrayJsValueFromWasm0(ptr, len) {
226
499
  ptr = ptr >>> 0;
227
500
  const mem = getDataViewMemory0();
@@ -258,6 +531,15 @@ function getUint8ArrayMemory0() {
258
531
  return cachedUint8ArrayMemory0;
259
532
  }
260
533
 
534
+ function handleError(f, args) {
535
+ try {
536
+ return f.apply(this, args);
537
+ } catch (e) {
538
+ const idx = addToExternrefTable0(e);
539
+ wasm.__wbindgen_exn_store(idx);
540
+ }
541
+ }
542
+
261
543
  function isLikeNone(x) {
262
544
  return x === undefined || x === null;
263
545
  }
Binary file
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@laisuk/opencc-fmmseg-wasm",
3
3
  "type": "module",
4
4
  "description": "WebAssembly bindings for opencc-fmmseg, a high-performance OpenCC-compatible Simplified/Traditional Chinese converter.",
5
- "version": "0.2.4",
5
+ "version": "0.3.0",
6
6
  "license": "MIT",
7
7
  "repository": {
8
8
  "type": "git",