@gukhanmun/wasm 0.1.0-dev.15 → 0.1.0-dev.18

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
@@ -123,6 +123,19 @@ type NumeralStrategy = "hangul-phonetic" | "positional-arabic" | "additive-arabi
123
123
  * accuracy matters more than latency.
124
124
  */
125
125
  type ContextWindow = "off" | "per-block" | "per-section" | "per-document";
126
+ /**
127
+ * Selects how the homophone marker decides that a reading needs its hanja shown
128
+ * in `rendering: "hangul-only"`. Corresponds to Rust `HomophoneDetection`.
129
+ *
130
+ * - `"context-local"` — Gloss a reading only when a different-meaning homophone
131
+ * actually appears within the {@link ContextWindow}. This keeps hangul-only
132
+ * output clean and is the default.
133
+ * - `"dictionary-wide"` — Also gloss readings shared by other hanja forms
134
+ * anywhere in the dictionary, even when no homophone appears in the text.
135
+ * With a large reference dictionary this glosses most Sino-Korean words; words
136
+ * that should always be glossed are better expressed with `requireHanja`.
137
+ */
138
+ type HomophoneDetection = "context-local" | "dictionary-wide";
126
139
  /**
127
140
  * Controls how the pipeline handles reader errors encountered during HTML
128
141
  * scanning. Corresponds to Rust `Recovery`.
@@ -324,13 +337,22 @@ interface GukhanmunOptions {
324
337
  readonly initialSoundLaw?: boolean;
325
338
  /**
326
339
  * Context window for homophone disambiguation. The `HomophoneMarker`
327
- * middleware sets `homophone = true` on annotations whose hangul reading is
328
- * shared by another hanja form within this window. Defaults to
329
- * `"per-block"`.
340
+ * middleware sets `homophone = true` on annotations whose hangul reading
341
+ * collides within this window. Defaults to `"per-block"`.
330
342
  *
331
343
  * @see {@link ContextWindow}
332
344
  */
333
345
  readonly homophoneWindow?: ContextWindow;
346
+ /**
347
+ * Strategy that decides which readings count as homophones needing a hanja
348
+ * gloss. Defaults to `"context-local"`, which glosses a reading only when a
349
+ * different-meaning homophone appears within {@link homophoneWindow}. Use
350
+ * `"dictionary-wide"` to also gloss readings shared by other dictionary
351
+ * entries.
352
+ *
353
+ * @see {@link HomophoneDetection}
354
+ */
355
+ readonly homophoneDetection?: HomophoneDetection;
334
356
  /**
335
357
  * Context window for first-occurrence filtering. The
336
358
  * `FirstOccurrenceFilter` middleware clears `requireHanja` /
@@ -572,4 +594,4 @@ declare class GukhanmunError extends Error {
572
594
  */
573
595
  declare function load(options?: GukhanmunOptions): Promise<Gukhanmun>;
574
596
  //#endregion
575
- export { type ContextWindow, type DictionaryEntry, type DictionarySource, type Directives, type ErrorCode, type FileDictionarySource, type Format, type Gukhanmun, GukhanmunError, type GukhanmunFactory, type GukhanmunOptions, type HtmlOptions, type NumeralStrategy, type OriginalGloss, type Preset, type Recovery, type RenderMode, type Segmentation, load };
597
+ export { type ContextWindow, type DictionaryEntry, type DictionarySource, type Directives, type ErrorCode, type FileDictionarySource, type Format, type Gukhanmun, GukhanmunError, type GukhanmunFactory, type GukhanmunOptions, type HomophoneDetection, type HtmlOptions, type NumeralStrategy, type OriginalGloss, type Preset, type Recovery, type RenderMode, type Segmentation, load };
package/dist/index.js CHANGED
@@ -42,22 +42,36 @@ let wasmInit;
42
42
  * Loads and caches the WASM module. The module URL is resolved relative to
43
43
  * this source file so it works with Deno's module graph and `import.meta.url`.
44
44
  *
45
- * Node.js `fetch()` does not support `file://` URLs, so on Node.js the WASM
46
- * binary is read via `node:fs/promises` and passed directly as a `Uint8Array`
47
- * to the web-target init function, bypassing the streaming-fetch path.
48
- * Deno and Bun support `fetch()` for `file://` URLs and use the default path.
45
+ * Node.js `fetch()` does not support `file://` URLs, so when the binary is a
46
+ * `file:` URL on Node.js it is read via `node:fs/promises` and passed directly
47
+ * as a `Uint8Array` to the web-target init function, bypassing the
48
+ * streaming-fetch path. Every other case uses `fetch`: Deno and Bun support
49
+ * `fetch()` for `file://` URLs, and a non-`file:` URL (such as the `https:`
50
+ * URL of a JSR install run on Deno, where `process.versions.node` is also
51
+ * defined) must be fetched since `node:fs` would reject it.
49
52
  */
50
53
  function ensureWasm() {
51
54
  if (!wasmInit) {
52
55
  const glueHref = new URL("./wasm/web/gukhanmun_wasm.js", import.meta.url).href;
53
56
  wasmInit = (async () => {
54
- const mod = await import(glueHref);
55
- if (isNodeLike()) {
56
- const wasmUrl = new URL("./wasm/web/gukhanmun_wasm_bg.wasm", import.meta.url);
57
- const buf = await (await import("node:fs/promises")).readFile(wasmUrl);
57
+ const mod = await import(
58
+ /* webpackIgnore: true */
59
+ glueHref
60
+ );
61
+ const wasmUrl = new URL("./wasm/web/gukhanmun_wasm_bg.wasm", import.meta.url);
62
+ if (isNodeLike() && wasmUrl.protocol === "file:") {
63
+ const buf = await (await import(
64
+ /* webpackIgnore: true */
65
+ "node:fs/promises"
66
+ )).readFile(wasmUrl);
58
67
  const bytes = new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
59
68
  await mod.default({ module_or_path: bytes });
60
- } else await mod.default();
69
+ } else {
70
+ const response = await fetch(wasmUrl);
71
+ if (!response.ok) throw new Error(`Failed to fetch WASM binary: HTTP ${response.status}`);
72
+ const bytes = new Uint8Array(await response.arrayBuffer());
73
+ await mod.default({ module_or_path: bytes });
74
+ }
61
75
  return mod;
62
76
  })();
63
77
  }
@@ -80,11 +94,17 @@ async function resolveDictionary(source) {
80
94
  else {
81
95
  const str = String(source.data);
82
96
  if (str.includes("://")) url = new URL(str);
83
- else if (isNodeLike()) url = (await import("node:url")).pathToFileURL(str);
97
+ else if (isNodeLike()) url = (await import(
98
+ /* webpackIgnore: true */
99
+ "node:url"
100
+ )).pathToFileURL(str);
84
101
  else throw new GukhanmunError("invalid-input", "File path strings require a Node.js environment; use URL or ArrayBuffer in browsers");
85
102
  }
86
103
  if (isNodeLike() && url.protocol === "file:") {
87
- const fs = await import("node:fs/promises");
104
+ const fs = await import(
105
+ /* webpackIgnore: true */
106
+ "node:fs/promises"
107
+ );
88
108
  let buf;
89
109
  try {
90
110
  buf = await fs.readFile(url);
@@ -186,6 +206,7 @@ function resolveOptions(opts = {}) {
186
206
  numerals: opts.numerals ?? "hangul-phonetic",
187
207
  initialSoundLaw: opts.initialSoundLaw ?? (koKp ? false : true),
188
208
  homophoneWindow: opts.homophoneWindow ?? (koKp ? "off" : "per-block"),
209
+ homophoneDetection: opts.homophoneDetection ?? "context-local",
189
210
  firstOccurrenceWindow: opts.firstOccurrenceWindow ?? "off",
190
211
  recovery: opts.recovery ?? "strict"
191
212
  };
@@ -229,6 +250,7 @@ function buildRawOptions(opts, resolved) {
229
250
  numerals: resolved.numerals,
230
251
  initialSoundLaw: resolved.initialSoundLaw,
231
252
  homophoneWindow: resolved.homophoneWindow,
253
+ homophoneDetection: resolved.homophoneDetection,
232
254
  firstOccurrenceWindow: resolved.firstOccurrenceWindow,
233
255
  recovery: resolved.recovery
234
256
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gukhanmun/wasm",
3
- "version": "0.1.0-dev.15",
3
+ "version": "0.1.0-dev.18",
4
4
  "description": "WebAssembly implementation of the Gukhanmun hanja-to-hangul converter.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -45,7 +45,7 @@
45
45
  "@gukhanmun/types": "*"
46
46
  },
47
47
  "devDependencies": {
48
- "@gukhanmun/types": "0.1.0-dev.15+3fd33cbb18850ceb854950ab7837d01d307ba573"
48
+ "@gukhanmun/types": "0.1.0-dev.18+25611433dc656544ad355f3b96f45650c351cab9"
49
49
  },
50
50
  "scripts": {
51
51
  "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'})\""