@gukhanmun/wasm 0.4.0-dev.236 → 0.4.0-dev.245

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/dist/index.d.ts CHANGED
@@ -1,687 +1,4 @@
1
- //#region ../types/dist/index.d.ts
2
- //#region index.d.ts
3
- /**
4
- * Canonical TypeScript API contract for Gukhanmun.
5
- *
6
- * This package contains only TypeScript type declarations and carries no
7
- * runtime code. Both `@gukhanmun/wasm` and `@gukhanmun/napi` satisfy this
8
- * contract structurally. All TSDoc lives here as the single source of
9
- * truth for the JavaScript API.
10
- *
11
- * @module @gukhanmun/types
12
- */
13
- /**
14
- * Named configuration preset that sets orthographic and lexical defaults.
15
- *
16
- * - `"ko-kr"` — South Korean orthography: dictionary-driven readings, the
17
- * initial sound law applied to fallback fragments, per-block homophone
18
- * disambiguation, and the bundled *Standard Korean Language Dictionary*
19
- * (標準國語大辭典). Corresponds to Rust `Preset::KoKr`.
20
- * - `"ko-kp"` — North Korean orthography: no initial sound law (래일,
21
- * 류행, 녀자), no bundled dictionary data. Corresponds to Rust `Preset::KoKp`.
22
- *
23
- * Both presets default `rendering` to `"hangul-only"` and `segmentation` to
24
- * `"lattice"`. Individual options passed to {@link GukhanmunOptions} override
25
- * the preset.
26
- */
27
- type Preset = "ko-kr" | "ko-kp";
28
- /**
29
- * Controls how the renderer expands each converted hanja annotation into
30
- * output text or markup. Corresponds to Rust `RenderMode`.
31
- *
32
- * - `"hangul-only"` — Emit only the hangul reading. When `homophone` or
33
- * `require_hanja` is set on an annotation the reading is followed by the
34
- * original hanja in parentheses: `한글(漢字)`. Corresponds to Rust
35
- * `RenderMode::HangulOnly`.
36
- * - `"hangul-hanja-parens"` — Always emit `한글(漢字)`. Corresponds to
37
- * Rust `RenderMode::HangulHanjaParens`.
38
- * - `"hanja-hangul-parens"` — Always emit `漢字(한글)`. Useful for
39
- * academic and historical-document styles. Corresponds to Rust
40
- * `RenderMode::HanjaHangulParens`.
41
- * - `"ruby-on-hangul"` — Emit `<ruby>한글<rt>漢字</rt></ruby>`. Falls
42
- * back to parentheses when the current scope does not permit inline markup
43
- * (e.g., inside `<pre>`). Corresponds to Rust
44
- * `RenderMode::Ruby(RubyBase::OnHangul)`.
45
- * - `"ruby-on-hanja"` — Emit `<ruby>漢字<rt>한글</rt></ruby>`.
46
- * Corresponds to Rust `RenderMode::Ruby(RubyBase::OnHanja)`.
47
- * - `"original"` — Keep the original mixed-script form; only annotations
48
- * with `require_hangul` or a user directive receive a hangul gloss, which
49
- * appears either in parentheses or as a ruby element depending on
50
- * {@link GukhanmunOptions.originalGloss}. Corresponds to Rust
51
- * `RenderMode::Original`.
52
- */
53
- type RenderMode = "hangul-only" | "hangul-hanja-parens" | "hanja-hangul-parens" | "ruby-on-hangul" | "ruby-on-hanja" | "original";
54
- /** The hanja variant set applied after dictionary recognition. */
55
- type HanjaVariantSet = "as-dictionary" | "shinjitai" | "kanxi" | "simplified" | "asahimoji";
56
- /**
57
- * Selects how glosses are rendered when {@link RenderMode} is `"original"`.
58
- *
59
- * - `"parens"` — Wrap the gloss in parentheses: `漢字(한글)` (default).
60
- * Corresponds to Rust `OriginalGloss::Parens`.
61
- * - `"ruby"` — Wrap the gloss in a `<ruby>` element. Falls back to
62
- * parentheses in scopes that do not permit inline markup. Corresponds to
63
- * Rust `OriginalGloss::Ruby`.
64
- *
65
- * This option is ignored when `rendering` is not `"original"`.
66
- */
67
- type OriginalGloss = "parens" | "ruby";
68
- /**
69
- * Controls how the engine segments a hanja-containing span into dictionary
70
- * words and fallback fragments. Corresponds to Rust `SegmentationStrategy`.
71
- *
72
- * - `"lattice"` — Dynamic programming over all possible dictionary matches
73
- * at each position; selects the segmentation that maximises dictionary
74
- * coverage and then prefers fewer segments. This is the default and
75
- * produces better results than greedy approaches when a longer prefix
76
- * would leave a suffix uncovered by the dictionary. Corresponds to Rust
77
- * `SegmentationStrategy::Lattice`.
78
- * - `"eager"` — Left-to-right longest-match (greedy). Lower overhead per
79
- * span at the cost of occasional mis-segmentation. Corresponds to Rust
80
- * `SegmentationStrategy::Eager`.
81
- */
82
- type Segmentation = "lattice" | "eager";
83
- /**
84
- * Controls how runs of hanja numerals are converted. Corresponds to Rust
85
- * `NumeralStrategy`.
86
- *
87
- * | Strategy | `二〇一六年` | `十一月` | `一千二百三十四` |
88
- * | --------------------- | ------------ | -------- | ---------------- |
89
- * | `"hangul-phonetic"` | 이공일륙년 | 십일월 | 일천이백삼십사 |
90
- * | `"positional-arabic"` | 2016년 | (n/a) | (n/a) |
91
- * | `"additive-arabic"` | (n/a) | 11월 | 1234 |
92
- * | `"smart"` | 2016년 | 11월 | 1234 |
93
- *
94
- * - `"hangul-phonetic"` — Read every digit character-by-character in
95
- * Korean phonetics. This is Seonbi's behaviour and the preset default.
96
- * Corresponds to Rust `NumeralStrategy::HangulPhonetic`.
97
- * - `"positional-arabic"` — Treat a run of digit-only hanja
98
- * (`〇一二三四五六七八九` and variants) as positional (place-value)
99
- * notation and convert to Arabic. Corresponds to Rust
100
- * `NumeralStrategy::PositionalArabic`.
101
- * - `"additive-arabic"` — Parse sequences containing place markers
102
- * (`十百千萬億兆京`) using stack-based accumulation and produce Arabic,
103
- * respecting the Korean convention that bare `十` means 10 not `一十`.
104
- * Corresponds to Rust `NumeralStrategy::AdditiveArabic`.
105
- * - `"smart"` — Uses `"additive-arabic"` for additive numerals that
106
- * begin with a digit, and for small-place-marker starts (`十`, `百`,
107
- * `千`) unless the next character is an ambiguous non-unit hanja word
108
- * character; uses `"positional-arabic"` for pure-digit runs of four or
109
- * more characters (year convention) or when a unit hanja follows the
110
- * digit run (`年月日時分秒號世紀` and others); otherwise falls back to
111
- * `"hangul-phonetic"`. Corresponds to Rust `NumeralStrategy::Smart`.
112
- */
113
- type NumeralStrategy = "hangul-phonetic" | "positional-arabic" | "additive-arabic" | "smart";
114
- /**
115
- * Defines the scope within which the homophone marker and first-occurrence
116
- * filter track previously seen readings. Corresponds to Rust `ContextWindow`.
117
- *
118
- * - `"off"` — Disable the corresponding middleware entirely.
119
- * - `"per-block"` — Reset at each block boundary (paragraph, list item,
120
- * heading, …). This is the default for both homophone marking and first-
121
- * occurrence filtering. In plain text, which has no block scopes, `per-block`
122
- * is document-wide.
123
- * - `"per-section"` — Reset at each heading boundary (HTML `<h1>`–`<h6>`,
124
- * Markdown ATX/setext headings).
125
- * - `"per-document"` — Track across the entire document. This buffers the
126
- * entire token stream and is appropriate only for small inputs or when full
127
- * accuracy matters more than latency.
128
- */
129
- type ContextWindow = "off" | "per-block" | "per-section" | "per-document";
130
- /**
131
- * Selects how the homophone marker decides that a reading needs its hanja shown
132
- * in `rendering: "hangul-only"`. Corresponds to Rust `HomophoneDetection`.
133
- *
134
- * - `"context-local"` — Gloss a reading only when a different-meaning homophone
135
- * actually appears within the {@link ContextWindow}. This keeps hangul-only
136
- * output clean and is the default.
137
- * - `"dictionary-wide"` — Also gloss readings shared by other hanja forms
138
- * anywhere in the dictionary, even when no homophone appears in the text.
139
- * With a large reference dictionary this glosses most Sino-Korean words; words
140
- * that should always be glossed are better expressed with `requireHanja`.
141
- */
142
- type HomophoneDetection = "context-local" | "dictionary-wide";
143
- /**
144
- * Controls how the pipeline handles reader errors encountered during HTML
145
- * scanning. Corresponds to Rust `Recovery`.
146
- *
147
- * - `"strict"` — Propagate the error and stop (default).
148
- * - `"lenient"` — Log the error via `tracing` and emit a verbatim token for
149
- * the unrecognised region so that downstream tokens continue to flow.
150
- *
151
- * This option is meaningful only for `format: "html"`. Markdown parsing does
152
- * not produce recoverable errors, so this option is ignored for Markdown input.
153
- */
154
- type Recovery = "strict" | "lenient";
155
- /**
156
- * A single dictionary entry: a hanja key with one hangul reading.
157
- *
158
- * Callers pass these in {@link MapDictionarySource.entries} to build a
159
- * dictionary at runtime. Fields mirror the Rust `ReadingCandidate` type plus
160
- * the hanja key.
161
- */
162
- interface DictionaryEntry {
163
- /** The hanja form (dictionary key), e.g. `"漢字"`. */
164
- readonly hanja: string;
165
- /** The word-initial hangul reading, e.g. `"한자"`. */
166
- readonly reading: string;
167
- /**
168
- * The reading used when the match is not word-initial, when it differs from
169
- * {@link reading}. For example a `年代` entry with `reading: "연대"` and
170
- * `suffixReading: "년대"` reads `1990年代` as `1990년대` but `年代` alone as
171
- * `연대`.
172
- *
173
- * Corresponds to Rust `ReadingCandidate::suffix_reading`.
174
- */
175
- readonly suffixReading?: string;
176
- /**
177
- * Relative default preference for this reading within its hanja key, a
178
- * non-negative integer. Larger values win, so an entry listed twice with
179
- * different preferences keeps competing readings and uses the higher one by
180
- * default. Absent means `0`.
181
- *
182
- * List order never selects the default: when two readings share a preference
183
- * the tie is broken by reading spelling. Set distinct preferences to choose
184
- * a default deliberately.
185
- *
186
- * Corresponds to Rust `ReadingCandidate::preference`.
187
- */
188
- readonly preference?: number;
189
- /**
190
- * When `true`, the renderer should always show the original hanja
191
- * alongside the hangul reading, regardless of ambiguity.
192
- *
193
- * Corresponds to Rust `MatchMark::require_hanja`.
194
- */
195
- readonly requireHanja?: boolean;
196
- /**
197
- * When `true`, the renderer should always show a hangul gloss alongside
198
- * the original hanja (used with `rendering: "original"`).
199
- *
200
- * Corresponds to Rust `MatchMark::require_hangul`.
201
- */
202
- readonly requireHangul?: boolean;
203
- }
204
- /**
205
- * Specifies a dictionary loaded from a binary file or URL.
206
- *
207
- * The `data` field accepts:
208
- * - A `BufferSource` (`ArrayBuffer` or `ArrayBufferView`) — supported in all
209
- * environments.
210
- * - A `URL` — resolved via `fetch` in browsers; via `node:fs/promises`
211
- * in Node.js, Deno 2.0+, and Bun.
212
- * - A `string` — treated as a filesystem path; supported in Node.js,
213
- * Deno 2.0+, and Bun only. Throws in browser environments.
214
- *
215
- * At runtime, a `FileDictionarySource` is distinguished from other values by
216
- * the absence of an `entries` property (`"entries" in source` selects a
217
- * {@link MapDictionarySource}).
218
- */
219
- interface FileDictionarySource {
220
- /**
221
- * The binary dictionary data or a reference to where it can be loaded.
222
- *
223
- * Pass a `BufferSource` for data already in memory, a `URL` for a remote
224
- * or local URL (resolved via `fetch` or `readFile`), or a path `string`
225
- * for filesystem paths (Node.js / Deno 2.0+ / Bun only).
226
- */
227
- readonly data: ArrayBuffer | ArrayBufferView | URL | string;
228
- /**
229
- * The on-disk format of the dictionary file.
230
- *
231
- * - `"fst"` — Gukhanmun FST file (`*.gukfst`); preferred for small
232
- * WebAssembly bundles. Supported in all runtimes.
233
- * - `"cdb"` — Gukhanmun CDB-trie file (`*.gukcdb`); preferred when code
234
- * auditability or trivial mmap support matters. Requires a filesystem
235
- * or in-memory bytes; supported in Node-API and (with `from_bytes`) in
236
- * WASM builds that include the `cdb` feature.
237
- *
238
- * The `"tsv"` format is reserved and never accepted. Pass entries in memory
239
- * through {@link MapDictionarySource} instead of compiling a table.
240
- */
241
- readonly format: "fst" | "cdb";
242
- }
243
- /**
244
- * A dictionary built from entries computed at runtime, such as per-document
245
- * reading overrides.
246
- *
247
- * Use this instead of compiling a TSV file with `gukhanmun-mkdict` when the
248
- * entries do not exist on disk, for example in a browser, an edge runtime, or a
249
- * site generator that derives entries per document.
250
- *
251
- * A source is distinguished from a {@link FileDictionarySource} by the presence
252
- * of an `entries` property.
253
- *
254
- * @example
255
- * ```ts
256
- * import { stdictFst } from "@gukhanmun/stdict-fst";
257
- * const g = await load({
258
- * dictionaries: [
259
- * {
260
- * entries: [
261
- * { hanja: "高橋", reading: "다카하시" },
262
- * { hanja: "東京", reading: "도쿄", preference: 10 },
263
- * { hanja: "年代", reading: "연대", suffixReading: "년대" },
264
- * ],
265
- * },
266
- * await stdictFst(),
267
- * ],
268
- * });
269
- * ```
270
- */
271
- interface MapDictionarySource {
272
- /**
273
- * The entries of this dictionary.
274
- *
275
- * Repeated `hanja` keys append competing readings instead of replacing each
276
- * other, and {@link DictionaryEntry.preference} decides which reading is the
277
- * context-free default. Several readings for one key also let the engine
278
- * pick a reading from a following particle (`東京을` versus `東京를`).
279
- *
280
- * An empty list contributes nothing, which is a convenient way to express
281
- * "this document has no overrides".
282
- */
283
- readonly entries: readonly DictionaryEntry[];
284
- }
285
- /**
286
- * A dictionary source accepted by {@link GukhanmunOptions.dictionaries}.
287
- *
288
- * Sources are tried in array order; the first match for a hanja key wins, and
289
- * every source listed before a compiled dictionary overrides that dictionary
290
- * for the keys it carries.
291
- *
292
- * @example
293
- * ```ts
294
- * import { stdictFst } from "@gukhanmun/stdict-fst";
295
- * const g = await load({ dictionaries: [await stdictFst()] });
296
- * ```
297
- */
298
- type DictionarySource = FileDictionarySource | MapDictionarySource;
299
- /**
300
- * Fine-grained HTML preservation rules passed in
301
- * {@link GukhanmunOptions.html}.
302
- *
303
- * These are additive: a scope is preserved when *any* rule matches. They
304
- * correspond to the CLI flags `--html-preserve-class` and
305
- * `--html-preserve-attr`, and to the Rust `Builder::html_preserve_when`
306
- * predicate.
307
- */
308
- interface HtmlOptions {
309
- /**
310
- * Class names whose containing element (and all descendants) should be
311
- * treated as a preserved region—the engine skips their text content.
312
- *
313
- * Equivalent to passing `--html-preserve-class NAME` to the CLI one or
314
- * more times.
315
- */
316
- readonly preserveClasses?: readonly string[];
317
- /**
318
- * Attribute matchers; an element is preserved when it carries a matching
319
- * attribute. Each entry is either:
320
- * - A bare string — preserve any element that has the attribute, regardless
321
- * of value (e.g. `"data-no-translate"`).
322
- * - An object `{ name, value? }` — preserve elements where the attribute
323
- * equals `value`, or has the attribute when `value` is omitted.
324
- *
325
- * Equivalent to `--html-preserve-attr KEY[=VALUE]` on the CLI.
326
- */
327
- readonly preserveAttributes?: readonly (string | {
328
- readonly name: string;
329
- readonly value?: string;
330
- })[];
331
- }
332
- /**
333
- * Per-hanja rendering directives that override the dictionary's own marks.
334
- *
335
- * Each list contains hanja forms (exact string matches, e.g. `"漢字"`).
336
- * JavaScript bindings expose only the literal-set form; glob and predicate
337
- * variants are available in the Rust API only.
338
- *
339
- * Corresponds to Rust `UserDirectives` with `DirectiveAction::RequireHanja`,
340
- * `DirectiveAction::RequireHangul`, and `DirectiveAction::SkipAnnotation`.
341
- */
342
- interface Directives {
343
- /**
344
- * Hanja forms that must always be shown with their original hanja
345
- * alongside the hangul reading, as if `requireHanja` were set in the
346
- * dictionary.
347
- */
348
- readonly requireHanja?: readonly string[];
349
- /**
350
- * Hanja forms that must always be shown with a hangul gloss alongside the
351
- * original hanja (relevant for `rendering: "original"`).
352
- */
353
- readonly requireHangul?: readonly string[];
354
- /**
355
- * Hanja forms whose annotation should be suppressed entirely; the renderer
356
- * emits only the primary plain text form (hangul or hanja depending on
357
- * `rendering`).
358
- */
359
- readonly skipAnnotation?: readonly string[];
360
- }
361
- /** Policy for ordinary spaces following an eligible stop. */
362
- type SpaceAfter = "preserve" | "remove" | "single";
363
- /** Built-in output style; input recognition is independent of this choice. */
364
- type PunctuationPreset = "preserve" | "modern" | "traditional" | "traditional-vertical";
365
- /** A single Unicode scalar and its following U+0020 policy. */
366
- interface StopStyle {
367
- /** One Unicode scalar, validated by the shared profile resolver. */
368
- readonly mark: string;
369
- /** Policy applied only to U+0020 following this stop. */
370
- readonly after: SpaceAfter;
371
- }
372
- /** Opening and closing Unicode punctuation scalars. */
373
- interface DelimiterStyle {
374
- /** Opening scalar with Unicode category Ps or Pi. */
375
- readonly open: string;
376
- /** Closing scalar with Unicode category Pe or Pf. */
377
- readonly close: string;
378
- }
379
- /** Partial overrides; omitted roles inherit, null preserves the role. */
380
- interface CustomPunctuationProfile {
381
- /** Inherited preset, defaulting to preserve. */
382
- readonly base?: PunctuationPreset;
383
- /** Comma style; omitted inherits, null preserves. */
384
- readonly comma?: StopStyle | null;
385
- /** Period style; omitted inherits, null preserves. */
386
- readonly period?: StopStyle | null;
387
- /** Single delimiters; omitted inherits, null preserves. */
388
- readonly single?: DelimiterStyle | null;
389
- /** Double delimiters; omitted inherits, null preserves. */
390
- readonly double?: DelimiterStyle | null;
391
- }
392
- /** Fully resolved styles, copied and deeply frozen by each binding. */
393
- interface ResolvedPunctuationProfile {
394
- /** Comma style, or null for preservation. */
395
- readonly comma: StopStyle | null;
396
- /** Period style, or null for preservation. */
397
- readonly period: StopStyle | null;
398
- /** Single delimiters, or null for preservation. */
399
- readonly single: DelimiterStyle | null;
400
- /** Double delimiters, or null for preservation. */
401
- readonly double: DelimiterStyle | null;
402
- }
403
- /**
404
- * Full set of options passed to {@link GukhanmunFactory.load} (or the
405
- * top-level `load` function) to configure a {@link Gukhanmun} instance.
406
- *
407
- * All fields are optional. When a `preset` is specified it supplies
408
- * defaults; individual fields override those defaults. When no preset is
409
- * given, `"ko-kr"` is implicitly used.
410
- */
411
- interface GukhanmunOptions {
412
- /** Independent output punctuation policy. Defaults to preserve. */
413
- readonly punctuation?: PunctuationPreset | CustomPunctuationProfile;
414
- /**
415
- * Named configuration preset. Defaults to `"ko-kr"`.
416
- *
417
- * @see {@link Preset}
418
- */
419
- readonly preset?: Preset;
420
- /**
421
- * How annotations are rendered into output text or markup. Defaults to
422
- * `"hangul-only"`.
423
- *
424
- * @see {@link RenderMode}
425
- */
426
- readonly rendering?: RenderMode;
427
- /**
428
- * How glosses are rendered when `rendering` is `"original"`. Ignored for
429
- * all other render modes. Defaults to `"parens"`.
430
- *
431
- * @see {@link OriginalGloss}
432
- */
433
- readonly originalGloss?: OriginalGloss;
434
- /** The hanja variant set. Defaults to `"as-dictionary"`. */
435
- readonly hanjaVariantSet?: HanjaVariantSet;
436
- /**
437
- * Hanja-span segmentation algorithm. Defaults to `"lattice"`.
438
- *
439
- * @see {@link Segmentation}
440
- */
441
- readonly segmentation?: Segmentation;
442
- /**
443
- * How runs of hanja numerals are converted. Defaults to
444
- * `"hangul-phonetic"`.
445
- *
446
- * @see {@link NumeralStrategy}
447
- */
448
- readonly numerals?: NumeralStrategy;
449
- /**
450
- * Whether to apply the Korean initial sound law (頭音法則) to fallback
451
- * phonetic readings. Defaults to `true` for `"ko-kr"` and `false` for
452
- * `"ko-kp"`.
453
- *
454
- * Note: dictionary entries are assumed to encode the correct reading
455
- * already; this flag only affects the character-by-character fallback path.
456
- */
457
- readonly initialSoundLaw?: boolean;
458
- /**
459
- * Context window for homophone disambiguation. The `HomophoneMarker`
460
- * middleware sets `homophone = true` on annotations whose hangul reading
461
- * collides within this window. Defaults to `"per-block"`.
462
- *
463
- * @see {@link ContextWindow}
464
- */
465
- readonly homophoneWindow?: ContextWindow;
466
- /**
467
- * Strategy that decides which readings count as homophones needing a hanja
468
- * gloss. Defaults to `"context-local"`, which glosses a reading only when a
469
- * different-meaning homophone appears within {@link homophoneWindow}. Use
470
- * `"dictionary-wide"` to also gloss readings shared by other dictionary
471
- * entries.
472
- *
473
- * @see {@link HomophoneDetection}
474
- */
475
- readonly homophoneDetection?: HomophoneDetection;
476
- /**
477
- * Context window for first-occurrence filtering. The
478
- * `FirstOccurrenceFilter` middleware clears `requireHanja` /
479
- * `requireHangul` on repeated occurrences of the same word within this
480
- * window, so the gloss appears only the first time. Defaults to `"off"`
481
- * (filter disabled) in both presets.
482
- *
483
- * @see {@link ContextWindow}
484
- */
485
- readonly firstOccurrenceWindow?: ContextWindow;
486
- /**
487
- * Whether to collapse redundant parenthetical reading annotations. Defaults
488
- * to `true`.
489
- *
490
- * When enabled, an explicit gloss such as `庫間(곳간)` or `곳간(庫間)` is
491
- * recognised, the redundant parenthetical is removed, and the annotation is
492
- * shown in both scripts in every render mode. A parenthetical that pins an
493
- * alternative reading (for example `數字(수자)`) overrides the dictionary
494
- * reading for that occurrence. A parenthetical that is a definition rather
495
- * than a reading (for example `庫間(물건을 간직하여 두는 곳)`) is left
496
- * untouched.
497
- */
498
- readonly collapseRedundantParens?: boolean;
499
- /**
500
- * Error recovery policy for HTML scanning. Defaults to `"strict"`.
501
- * Ignored for non-HTML input formats.
502
- *
503
- * @see {@link Recovery}
504
- */
505
- readonly recovery?: Recovery;
506
- /**
507
- * Ordered list of dictionary sources. Sources are queried in order;
508
- * earlier entries take precedence. When omitted (or empty), only the
509
- * fallback Unihan character map is used (no bundled dictionaries).
510
- *
511
- * JavaScript presets do **not**
512
- * automatically include bundled dictionary data. To use the *Standard
513
- * Korean Language Dictionary*, add `@gukhanmun/stdict-fst` or
514
- * `@gukhanmun/stdict-cdb` explicitly. To use Open Korean Dictionary
515
- * categories, add `@gukhanmun/opendict-fst` or
516
- * `@gukhanmun/opendict-cdb` explicitly. For NIKL loanword examples, load
517
- * `@gukhanmun/loanwords-fst` or `@gukhanmun/loanwords-cdb`. Put user
518
- * dictionaries first, then loanwords, then the preset dictionaries.
519
- *
520
- * Entries computed at runtime need no package and no `gukhanmun-mkdict` run:
521
- * pass {@link MapDictionarySource} (`{ entries: [...] }`) at the position
522
- * where those overrides should take precedence.
523
- *
524
- * @see {@link DictionarySource}
525
- */
526
- readonly dictionaries?: readonly DictionarySource[];
527
- /**
528
- * Per-hanja rendering directives that override dictionary marks.
529
- *
530
- * @see {@link Directives}
531
- */
532
- readonly directives?: Directives;
533
- /**
534
- * HTML-specific preservation rules. Ignored for non-HTML input formats.
535
- *
536
- * @see {@link HtmlOptions}
537
- */
538
- readonly html?: HtmlOptions;
539
- }
540
- /**
541
- * Input / output format for {@link Gukhanmun.convert} and
542
- * {@link Gukhanmun.stream}.
543
- *
544
- * - `"text"` — Plain text (default). No markup interpretation; ruby
545
- * rendering falls back to parentheses.
546
- * - `"html"` — HTML fragment. The scanner is fragment-oriented and recovers
547
- * from minor malformations.
548
- * - `"markdown"` — CommonMark Markdown (GFM disabled by default).
549
- * - `{ format: "markdown"; gfm?: boolean }` — Markdown with optional GFM
550
- * extensions. Set `gfm: true` to enable GitHub Flavored Markdown tables,
551
- * strikethrough, and task lists.
552
- *
553
- * The object form `{ format: "markdown" }` is equivalent to the string
554
- * `"markdown"`.
555
- */
556
- type Format = "text" | "html" | "markdown" | {
557
- readonly format: "markdown";
558
- readonly gfm?: boolean;
559
- };
560
- /**
561
- * A configured hanja-to-hangul converter. Created by calling
562
- * {@link GukhanmunFactory.load} (or the top-level `load` function).
563
- *
564
- * The instance is immutable after creation; call `load` again to obtain a
565
- * converter with different options.
566
- */
567
- interface Gukhanmun {
568
- /**
569
- * Converts `source` to hangul in one shot. Buffers the entire input
570
- * before returning.
571
- *
572
- * @param source - The text to convert.
573
- * @param format - Input / output format. Defaults to `"text"`.
574
- * @returns The converted text.
575
- * @throws {@link GukhanmunError} on conversion failure.
576
- */
577
- convert(source: string, format?: Format): string;
578
- /**
579
- * Returns a `TransformStream<string, string>` that converts chunks
580
- * incrementally. Chunks are JavaScript strings; byte-level encoding is
581
- * the caller's responsibility (`TextDecoderStream` / `TextEncoderStream`).
582
- *
583
- * The stream guarantees that the concatenated output equals the result of
584
- * calling `convert` on the concatenated input, regardless of chunk
585
- * boundaries. Document-wide middlewares (e.g., homophone marking with
586
- * `homophoneWindow: "per-document"`) buffer until the writable side is
587
- * closed.
588
- *
589
- * @param format - Input / output format. Defaults to `"text"`.
590
- * @returns A platform `TransformStream<string, string>`.
591
- * @throws {@link GukhanmunError} on initialisation failure (not on chunk
592
- * errors; those are signalled via the stream's error channel).
593
- */
594
- stream(format?: Format): TransformStream<string, string>;
595
- /**
596
- * Read-only view of the resolved options (after preset defaults are
597
- * applied). Excludes `dictionaries`, `directives`, `html`, and
598
- * `originalGloss`, which are not meaningfully representable as plain
599
- * values.
600
- */
601
- readonly options: Readonly<Required<Omit<GukhanmunOptions, "dictionaries" | "directives" | "html" | "originalGloss" | "punctuation">> & {
602
- readonly punctuation: ResolvedPunctuationProfile;
603
- }>;
604
- }
605
- /**
606
- * Factory interface satisfied by both `@gukhanmun/wasm` and
607
- * `@gukhanmun/napi`.
608
- *
609
- * @example
610
- * ```ts
611
- * import { load } from "@gukhanmun/wasm";
612
- * import { stdictFst } from "@gukhanmun/stdict-fst";
613
- *
614
- * const g = await load({
615
- * preset: "ko-kr",
616
- * dictionaries: [await stdictFst()],
617
- * });
618
- * console.log(g.convert("漢字를 한글로"));
619
- * ```
620
- */
621
- interface GukhanmunFactory {
622
- /**
623
- * Loads and initialises a {@link Gukhanmun} converter with the given
624
- * options.
625
- *
626
- * In the WASM implementation this involves asynchronous `.wasm` binary
627
- * initialisation; in the Node-API implementation the native addon is
628
- * synchronously ready but still returns a `Promise` for API uniformity.
629
- * Dictionary sources with `URL` or string `data` are fetched / read during
630
- * this call.
631
- *
632
- * @param options - Conversion options. All fields are optional; unset
633
- * fields inherit defaults from the selected `preset` (or `"ko-kr"` when
634
- * no preset is given).
635
- * @returns A ready-to-use {@link Gukhanmun} instance.
636
- * @throws {@link GukhanmunError} when an option value is unrecognised
637
- * (`code: "invalid-input"`) or a dictionary fails to load
638
- * (`code: "dictionary-load"`).
639
- */
640
- load(options?: GukhanmunOptions): Promise<Gukhanmun>;
641
- }
642
- /**
643
- * Top-level entry point exported by both `@gukhanmun/wasm` and
644
- * `@gukhanmun/napi` as a named export.
645
- *
646
- * Equivalent to `new GukhanmunFactory().load(options)`. Declared here so
647
- * that code that `import { load }` from either implementation package
648
- * type-checks against the same signature.
649
- */
650
-
651
- /**
652
- * Discriminant code carried by every {@link GukhanmunError}.
653
- *
654
- * - `"dictionary-load"` — A dictionary file could not be opened, read, or
655
- * decoded.
656
- * - `"segmentation"` — The lattice segmenter encountered an internal
657
- * inconsistency.
658
- * - `"invalid-reading"` — A dictionary entry's hangul reading is not valid
659
- * hangul.
660
- * - `"html-scan"` — The HTML scanner encountered an unrecoverable error.
661
- * - `"html-malformed-attr"` — An HTML attribute string could not be parsed.
662
- * - `"markdown"` — The Markdown adapter encountered a parsing error.
663
- * - `"unsupported-content-type"` — An unrecognised format string was passed
664
- * to `convert` or `stream`.
665
- * - `"invalid-input"` — An option value is not in the expected set (e.g. an
666
- * unrecognised preset or render mode string).
667
- * - `"io"` — An I/O error occurred (file read, network, …).
668
- * - `"internal"` — An internal invariant was violated; this is a bug.
669
- * - `"other"` — Any other error not covered by the above codes.
670
- */
671
- type ErrorCode = "dictionary-load" | "segmentation" | "invalid-reading" | "html-scan" | "html-malformed-attr" | "markdown" | "unsupported-content-type" | "invalid-input" | "io" | "internal" | "other";
672
- /**
673
- * Error class thrown by all Gukhanmun operations.
674
- *
675
- * Declared here as a `declare class` so this package remains purely
676
- * type-level. The actual class (with identical shape) is provided by each
677
- * runtime package (`@gukhanmun/wasm` and `@gukhanmun/napi`).
678
- *
679
- * The `chain` property exposes the Rust `Error::source()` chain materialised
680
- * at the FFI boundary, allowing callers to inspect underlying causes without
681
- * additional FFI calls.
682
- */
683
- //#endregion
684
- //#region index.d.ts
1
+ import { ContextWindow, CustomPunctuationProfile, DelimiterStyle, DictionaryEntry, DictionarySource, Directives, ErrorCode, ErrorCode as ErrorCode$1, FileDictionarySource, Format, Gukhanmun, Gukhanmun as Gukhanmun$1, GukhanmunFactory, GukhanmunOptions, GukhanmunOptions as GukhanmunOptions$1, HanjaVariantSet, HomophoneDetection, HtmlOptions, MapDictionarySource, NumeralStrategy, OriginalGloss, Preset, PunctuationPreset, Recovery, RenderMode, ResolvedPunctuationProfile, Segmentation, SpaceAfter, StopStyle } from "@gukhanmun/types";
685
2
  /**
686
3
  * Error thrown by `{@link load}`, `{@link Gukhanmun.convert}`, and
687
4
  * `{@link Gukhanmun.stream}` when the Rust engine reports a failure.
@@ -690,20 +7,20 @@ type ErrorCode = "dictionary-load" | "segmentation" | "invalid-reading" | "html-
690
7
  * materialised at the FFI boundary so callers do not need additional round
691
8
  * trips.
692
9
  */
693
- declare class GukhanmunError extends Error {
10
+ export declare class GukhanmunError extends Error {
694
11
  /**
695
12
  * Machine-readable error code.
696
13
  *
697
14
  * @see {@link ErrorCode}
698
15
  */
699
- readonly code: ErrorCode;
16
+ readonly code: ErrorCode$1;
700
17
  /**
701
18
  * Full causal chain from the Rust `Error::source()` traversal, materialised
702
19
  * at the FFI boundary. The first element is the root cause; the last is
703
20
  * the immediate error.
704
21
  */
705
22
  readonly chain: readonly {
706
- readonly code: ErrorCode;
23
+ readonly code: ErrorCode$1;
707
24
  readonly message: string;
708
25
  }[];
709
26
  /**
@@ -713,8 +30,8 @@ declare class GukhanmunError extends Error {
713
30
  * @param message - Human-readable description.
714
31
  * @param chain - Optional causal chain.
715
32
  */
716
- constructor(code: ErrorCode, message: string, chain?: readonly {
717
- code: ErrorCode;
33
+ constructor(code: ErrorCode$1, message: string, chain?: readonly {
34
+ code: ErrorCode$1;
718
35
  message: string;
719
36
  }[]);
720
37
  }
@@ -736,6 +53,5 @@ declare class GukhanmunError extends Error {
736
53
  * @returns A `{@link Gukhanmun}` instance.
737
54
  * @throws {@link GukhanmunError} on invalid options or dictionary load failure.
738
55
  */
739
- declare function load(options?: GukhanmunOptions): Promise<Gukhanmun>;
740
- //#endregion
741
- export { type ContextWindow, type CustomPunctuationProfile, type DelimiterStyle, type DictionaryEntry, type DictionarySource, type Directives, type ErrorCode, type FileDictionarySource, type Format, type Gukhanmun, GukhanmunError, type GukhanmunFactory, type GukhanmunOptions, type HanjaVariantSet, type HomophoneDetection, type HtmlOptions, type MapDictionarySource, type NumeralStrategy, type OriginalGloss, type Preset, type PunctuationPreset, type Recovery, type RenderMode, type ResolvedPunctuationProfile, type Segmentation, type SpaceAfter, type StopStyle, load };
56
+ export declare function load(options?: GukhanmunOptions$1): Promise<Gukhanmun$1>;
57
+ export type { ContextWindow, CustomPunctuationProfile, DelimiterStyle, DictionaryEntry, DictionarySource, Directives, ErrorCode, FileDictionarySource, Format, Gukhanmun, GukhanmunFactory, GukhanmunOptions, HanjaVariantSet, HomophoneDetection, HtmlOptions, MapDictionarySource, NumeralStrategy, OriginalGloss, Preset, PunctuationPreset, Recovery, RenderMode, ResolvedPunctuationProfile, Segmentation, SpaceAfter, StopStyle };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- //#region index.ts
1
+ // index.ts
2
2
  function isNodeLike() {
3
3
  return typeof globalThis.process?.versions?.node === "string";
4
4
  }
@@ -345,5 +345,4 @@ function punctuationJson(value) {
345
345
  throw new GukhanmunError("invalid-input", error instanceof Error ? error.message : String(error));
346
346
  }
347
347
  }
348
- //#endregion
349
348
  export { GukhanmunError, load };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gukhanmun/wasm",
3
- "version": "0.4.0-dev.236",
3
+ "version": "0.4.0-dev.245",
4
4
  "description": "WebAssembly implementation of the Gukhanmun hanja-to-hangul converter.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -54,7 +54,7 @@
54
54
  "@gukhanmun/types": "*"
55
55
  },
56
56
  "devDependencies": {
57
- "@gukhanmun/types": "0.4.0-dev.236+75afc34"
57
+ "@gukhanmun/types": "0.4.0-dev.245+223a736"
58
58
  },
59
59
  "scripts": {
60
60
  "build": "tsdown && node -e \"const fs=require('node:fs'),p=require('node:path');fs.cpSync('wasm','dist/wasm',{recursive:true,force:true,filter:(s)=>p.basename(s)!=='.gitignore'})\""