@gukhanmun/wasm 0.3.1 → 0.4.0-dev.236
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 +88 -13
- package/dist/index.js +51 -3
- package/dist/wasm/deno/gukhanmun_wasm.js +4 -0
- package/dist/wasm/deno/gukhanmun_wasm_bg.wasm +0 -0
- package/dist/wasm/nodejs/gukhanmun_wasm.js +4 -0
- package/dist/wasm/nodejs/gukhanmun_wasm_bg.wasm +0 -0
- package/dist/wasm/nodejs/package.json +1 -1
- package/dist/wasm/web/gukhanmun_wasm.js +4 -0
- package/dist/wasm/web/gukhanmun_wasm_bg.wasm +0 -0
- package/dist/wasm/web/package.json +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -153,13 +153,39 @@ type HomophoneDetection = "context-local" | "dictionary-wide";
|
|
|
153
153
|
*/
|
|
154
154
|
type Recovery = "strict" | "lenient";
|
|
155
155
|
/**
|
|
156
|
-
* A single dictionary entry
|
|
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.
|
|
157
161
|
*/
|
|
158
162
|
interface DictionaryEntry {
|
|
159
|
-
/** The hanja form (key), e.g. `"漢字"`. */
|
|
163
|
+
/** The hanja form (dictionary key), e.g. `"漢字"`. */
|
|
160
164
|
readonly hanja: string;
|
|
161
|
-
/** The hangul reading, e.g. `"한자"`. */
|
|
165
|
+
/** The word-initial hangul reading, e.g. `"한자"`. */
|
|
162
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;
|
|
163
189
|
/**
|
|
164
190
|
* When `true`, the renderer should always show the original hanja
|
|
165
191
|
* alongside the hangul reading, regardless of ambiguity.
|
|
@@ -187,7 +213,8 @@ interface DictionaryEntry {
|
|
|
187
213
|
* Deno 2.0+, and Bun only. Throws in browser environments.
|
|
188
214
|
*
|
|
189
215
|
* At runtime, a `FileDictionarySource` is distinguished from other values by
|
|
190
|
-
* the
|
|
216
|
+
* the absence of an `entries` property (`"entries" in source` selects a
|
|
217
|
+
* {@link MapDictionarySource}).
|
|
191
218
|
*/
|
|
192
219
|
interface FileDictionarySource {
|
|
193
220
|
/**
|
|
@@ -208,16 +235,59 @@ interface FileDictionarySource {
|
|
|
208
235
|
* or in-memory bytes; supported in Node-API and (with `from_bytes`) in
|
|
209
236
|
* WASM builds that include the `cdb` feature.
|
|
210
237
|
*
|
|
211
|
-
* The `"tsv"` format is reserved
|
|
212
|
-
*
|
|
238
|
+
* The `"tsv"` format is reserved and never accepted. Pass entries in memory
|
|
239
|
+
* through {@link MapDictionarySource} instead of compiling a table.
|
|
213
240
|
*/
|
|
214
241
|
readonly format: "fst" | "cdb";
|
|
215
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
|
+
}
|
|
216
285
|
/**
|
|
217
286
|
* A dictionary source accepted by {@link GukhanmunOptions.dictionaries}.
|
|
218
287
|
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
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.
|
|
221
291
|
*
|
|
222
292
|
* @example
|
|
223
293
|
* ```ts
|
|
@@ -225,7 +295,7 @@ interface FileDictionarySource {
|
|
|
225
295
|
* const g = await load({ dictionaries: [await stdictFst()] });
|
|
226
296
|
* ```
|
|
227
297
|
*/
|
|
228
|
-
type DictionarySource = FileDictionarySource;
|
|
298
|
+
type DictionarySource = FileDictionarySource | MapDictionarySource;
|
|
229
299
|
/**
|
|
230
300
|
* Fine-grained HTML preservation rules passed in
|
|
231
301
|
* {@link GukhanmunOptions.html}.
|
|
@@ -447,6 +517,10 @@ interface GukhanmunOptions {
|
|
|
447
517
|
* `@gukhanmun/loanwords-fst` or `@gukhanmun/loanwords-cdb`. Put user
|
|
448
518
|
* dictionaries first, then loanwords, then the preset dictionaries.
|
|
449
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
|
+
*
|
|
450
524
|
* @see {@link DictionarySource}
|
|
451
525
|
*/
|
|
452
526
|
readonly dictionaries?: readonly DictionarySource[];
|
|
@@ -648,9 +722,10 @@ declare class GukhanmunError extends Error {
|
|
|
648
722
|
* Creates a Gukhanmun converter with the given options.
|
|
649
723
|
*
|
|
650
724
|
* Initialises the WASM module on the first call (subsequent calls reuse the
|
|
651
|
-
* cached module).
|
|
652
|
-
* `{@link GukhanmunOptions.dictionaries}` are fetched
|
|
653
|
-
*
|
|
725
|
+
* cached module). Compiled dictionaries supplied via
|
|
726
|
+
* `{@link GukhanmunOptions.dictionaries}` are fetched, while
|
|
727
|
+
* `{@link MapDictionarySource}` entry lists are serialised and built in memory
|
|
728
|
+
* as Rust `MapDictionary` values.
|
|
654
729
|
*
|
|
655
730
|
* Note: unlike the Rust `ko-kr` preset, the JavaScript preset never includes a
|
|
656
731
|
* bundled dictionary. Pass `dictionaries: [await stdictFst()]` to include the
|
|
@@ -663,4 +738,4 @@ declare class GukhanmunError extends Error {
|
|
|
663
738
|
*/
|
|
664
739
|
declare function load(options?: GukhanmunOptions): Promise<Gukhanmun>;
|
|
665
740
|
//#endregion
|
|
666
|
-
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 NumeralStrategy, type OriginalGloss, type Preset, type PunctuationPreset, type Recovery, type RenderMode, type ResolvedPunctuationProfile, type Segmentation, type SpaceAfter, type StopStyle, load };
|
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -77,7 +77,54 @@ function ensureWasm() {
|
|
|
77
77
|
}
|
|
78
78
|
return wasmInit;
|
|
79
79
|
}
|
|
80
|
+
/** Rejects a source that is not an object before any property is read. */
|
|
81
|
+
function isRecord(value) {
|
|
82
|
+
return typeof value === "object" && value !== null;
|
|
83
|
+
}
|
|
84
|
+
/** The entry fields {@link DictionaryEntry} declares, in serialisation order. */
|
|
85
|
+
const DICTIONARY_ENTRY_FIELDS = [
|
|
86
|
+
"hanja",
|
|
87
|
+
"reading",
|
|
88
|
+
"suffixReading",
|
|
89
|
+
"preference",
|
|
90
|
+
"requireHanja",
|
|
91
|
+
"requireHangul"
|
|
92
|
+
];
|
|
93
|
+
/**
|
|
94
|
+
* Encodes runtime dictionary entries for the WASM boundary.
|
|
95
|
+
*
|
|
96
|
+
* Each entry is copied field by field, so a class instance exposing its
|
|
97
|
+
* properties through getters serialises the same values it presents, and any
|
|
98
|
+
* extra property a caller carries is dropped rather than rejected. The copy
|
|
99
|
+
* also keeps `NaN` and `±Infinity` preferences visible: `JSON.stringify` would
|
|
100
|
+
* erase them to `null`, which the Rust side reads as "absent".
|
|
101
|
+
*/
|
|
102
|
+
function encodeEntries(entries) {
|
|
103
|
+
if (!Array.isArray(entries)) throw new GukhanmunError("invalid-input", "Dictionary 'entries' must be an array");
|
|
104
|
+
const records = [];
|
|
105
|
+
for (const [index, entry] of entries.entries()) {
|
|
106
|
+
if (!isRecord(entry)) {
|
|
107
|
+
records.push(entry);
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
const record = {};
|
|
111
|
+
for (const field of DICTIONARY_ENTRY_FIELDS) record[field] = entry[field];
|
|
112
|
+
const preference = record["preference"];
|
|
113
|
+
if (preference != null && !Number.isInteger(preference)) throw new GukhanmunError("invalid-input", `dictionary entry ${index} has a non-integer \`preference\`: ${String(preference)}`);
|
|
114
|
+
records.push(record);
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
return JSON.stringify(records);
|
|
118
|
+
} catch (e) {
|
|
119
|
+
throw new GukhanmunError("invalid-input", `Dictionary entries are not serialisable: ${e instanceof Error ? e.message : String(e)}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
80
122
|
async function resolveDictionary(source) {
|
|
123
|
+
if (typeof source !== "object" || source === null) throw new GukhanmunError("invalid-input", "Each dictionary must be an object");
|
|
124
|
+
if ("entries" in source) {
|
|
125
|
+
if ("format" in source || "data" in source) throw new GukhanmunError("invalid-input", "A dictionary must not combine 'entries' with 'format' or 'data'");
|
|
126
|
+
return { entriesJson: encodeEntries(source.entries) };
|
|
127
|
+
}
|
|
81
128
|
if (source.data instanceof ArrayBuffer) return {
|
|
82
129
|
format: source.format,
|
|
83
130
|
bytes: new Uint8Array(source.data)
|
|
@@ -223,9 +270,10 @@ function resolveOptions(opts = {}) {
|
|
|
223
270
|
* Creates a Gukhanmun converter with the given options.
|
|
224
271
|
*
|
|
225
272
|
* Initialises the WASM module on the first call (subsequent calls reuse the
|
|
226
|
-
* cached module).
|
|
227
|
-
* `{@link GukhanmunOptions.dictionaries}` are fetched
|
|
228
|
-
*
|
|
273
|
+
* cached module). Compiled dictionaries supplied via
|
|
274
|
+
* `{@link GukhanmunOptions.dictionaries}` are fetched, while
|
|
275
|
+
* `{@link MapDictionarySource}` entry lists are serialised and built in memory
|
|
276
|
+
* as Rust `MapDictionary` values.
|
|
229
277
|
*
|
|
230
278
|
* Note: unlike the Rust `ko-kr` preset, the JavaScript preset never includes a
|
|
231
279
|
* bundled dictionary. Pass `dictionaries: [await stdictFst()]` to include the
|
|
@@ -301,6 +301,10 @@ function __wbg_get_imports() {
|
|
|
301
301
|
const ret = arg0[arg1];
|
|
302
302
|
return ret;
|
|
303
303
|
},
|
|
304
|
+
__wbg_has_73740b27f436fed3: function() { return handleError(function (arg0, arg1) {
|
|
305
|
+
const ret = Reflect.has(arg0, arg1);
|
|
306
|
+
return ret;
|
|
307
|
+
}, arguments); },
|
|
304
308
|
__wbg_instanceof_ArrayBuffer_8f49811467741499: function(arg0) {
|
|
305
309
|
let result;
|
|
306
310
|
try {
|
|
Binary file
|
|
@@ -303,6 +303,10 @@ function __wbg_get_imports() {
|
|
|
303
303
|
const ret = arg0[arg1];
|
|
304
304
|
return ret;
|
|
305
305
|
},
|
|
306
|
+
__wbg_has_73740b27f436fed3: function() { return handleError(function (arg0, arg1) {
|
|
307
|
+
const ret = Reflect.has(arg0, arg1);
|
|
308
|
+
return ret;
|
|
309
|
+
}, arguments); },
|
|
306
310
|
__wbg_instanceof_ArrayBuffer_8f49811467741499: function(arg0) {
|
|
307
311
|
let result;
|
|
308
312
|
try {
|
|
Binary file
|
|
@@ -301,6 +301,10 @@ function __wbg_get_imports() {
|
|
|
301
301
|
const ret = arg0[arg1];
|
|
302
302
|
return ret;
|
|
303
303
|
},
|
|
304
|
+
__wbg_has_73740b27f436fed3: function() { return handleError(function (arg0, arg1) {
|
|
305
|
+
const ret = Reflect.has(arg0, arg1);
|
|
306
|
+
return ret;
|
|
307
|
+
}, arguments); },
|
|
304
308
|
__wbg_instanceof_ArrayBuffer_8f49811467741499: function(arg0) {
|
|
305
309
|
let result;
|
|
306
310
|
try {
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gukhanmun/wasm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0-dev.236",
|
|
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.
|
|
57
|
+
"@gukhanmun/types": "0.4.0-dev.236+75afc34"
|
|
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'})\""
|