JavaScript API
The JavaScript bindings are distributed as @odict/node on npm. They are native extensions built with NAPI-RS and also support the browser via WASI.
Installation
Section titled “Installation”npm install @odict/nodeRequires Node.js 12+. Native binaries are included for all major platforms (macOS, Linux, Windows, ARM64, WASI).
Quick example
Section titled “Quick example”import { readFile } from "node:fs/promises";import { compile, OpenDictionary } from "@odict/node";
// Compile XML to a bufferconst xml = await readFile("my-dictionary.xml", "utf-8");const data = compile(xml);const dictionary = new OpenDictionary(data);
const results = dictionary.lookup("hello");console.log(results[0].entry.term); // "hello"Functions
Section titled “Functions”compile(xml: string): Buffer
Section titled “compile(xml: string): Buffer”Compiles an ODXML string into binary .odict data. Returns a Buffer that can be passed to new OpenDictionary().
import { compile } from "@odict/node";
const data = compile(` <dictionary> <entry term="hi"> <ety><sense><definition value="greeting"/></sense></ety> </entry> </dictionary>`);OpenDictionary
Section titled “OpenDictionary”The main class for working with compiled dictionaries.
Constructors
Section titled “Constructors”new OpenDictionary(data: Buffer | string)
Section titled “new OpenDictionary(data: Buffer | string)”Creates a dictionary from compiled binary data (as returned by compile()) or directly from an XML string.
import { compile, OpenDictionary } from "@odict/node";
// From compiled bufferconst data = compile(xmlString);const dictionary = new OpenDictionary(data);
// Directly from XML stringconst dictionary = new OpenDictionary(xmlString);OpenDictionary.load(dictionary: string, options?: LoadOptions): Promise<OpenDictionary>
Section titled “OpenDictionary.load(dictionary: string, options?: LoadOptions): Promise<OpenDictionary>”Loads a dictionary from a file path or remote identifier. Returns a Promise.
- If
dictionaryis a path to a.odictfile, it loads from disk. - If it matches the format
org/lang(e.g.wiktionary/eng), it downloads from the remote registry.
import { OpenDictionary } from "@odict/node";
// Load from fileconst dictionary = await OpenDictionary.load("./my-dictionary.odict");
// Load from remote registryconst dictionary = await OpenDictionary.load("wiktionary/eng");
// Load with optionsconst dictionary = await OpenDictionary.load("wiktionary/eng", { configDir: "./config", remote: { caching: true, retries: 3 },});Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
minRank | number | null | The minimum rank value across all entries, or null if no entries have ranks |
maxRank | number | null | The maximum rank value across all entries, or null if no entries have ranks |
Methods
Section titled “Methods”save(path: string, options?: SaveOptions): void
Section titled “save(path: string, options?: SaveOptions): void”Saves the dictionary to disk as a .odict file.
dictionary.save("output.odict");dictionary.save("output.odict", { compress: { quality: 11, windowSize: 22 },});lookup(query: string | string[], options?: LookupOptions): LookupResult[]
Section titled “lookup(query: string | string[], options?: LookupOptions): LookupResult[]”Looks up one or more terms by exact match.
| Parameter | Type | Default | Description |
|---|---|---|---|
query | string | string[] | — | Term(s) to look up |
options.split | number | — | Minimum word length for compound splitting |
options.follow | boolean | — | Follow see cross-references until an entry with etymologies is found |
options.insensitive | boolean | — | Enable case-insensitive matching |
// Simple lookupconst results = dictionary.lookup("cat");
// Multiple termsconst results = dictionary.lookup(["cat", "dog"]);
// Follow cross-references, case-insensitiveconst results = dictionary.lookup("RaN", { follow: true, insensitive: true,});// results[0].entry.term === "run"// results[0].directedFrom?.term === "ran"
// Compound word splittingconst results = dictionary.lookup("catdog", { split: 3 });split(query: string | string[], options?: SplitOptions): LookupResult[]
Section titled “split(query: string | string[], options?: SplitOptions): LookupResult[]”Splits one or more compound terms into component dictionary entries. Unlike lookup(query, { split }), this does not try the whole query first.
| Parameter | Type | Default | Description |
|---|---|---|---|
query | string | string[] | — | Term(s) to split |
options.minLength | number | — | Minimum character length for each segment |
options.follow | boolean | — | Follow see cross-references |
options.insensitive | boolean | — | Enable case-insensitive matching |
const splitResults = dictionary.split("catdog", { minLength: 3 });const insensitiveResults = dictionary.split("CATdog", { minLength: 3, insensitive: true,});lexicon(): string[]
Section titled “lexicon(): string[]”Returns all terms defined in the dictionary, sorted alphabetically.
const words = dictionary.lexicon();// ["cat", "dog", "run", ...]index(options?: IndexOptions): void
Section titled “index(options?: IndexOptions): void”Creates a full-text search index for the dictionary.
dictionary.index();dictionary.index({ overwrite: true, memory: 50_000_000 });search(query: string, options?: SearchOptions): Entry[]
Section titled “search(query: string, options?: SearchOptions): Entry[]”Runs a full-text search. Requires an index (call index() first).
dictionary.index();
const results = dictionary.search("domesticated mammal");const results = dictionary.search("greeting", { limit: 5 });tokenize(text: string, options?: TokenizeOptions): Token[]
Section titled “tokenize(text: string, options?: TokenizeOptions): Token[]”Tokenizes text and matches each token against the dictionary. Supports Chinese, Japanese, Korean, Thai, Khmer, German, Swedish, and Latin-script languages.
const tokens = dictionary.tokenize("the cat ran");for (const token of tokens) { console.log(token.lemma, token.entries);}
// With optionsconst tokens = dictionary.tokenize("DOG cat", { insensitive: true, follow: true,});LookupResult
Section titled “LookupResult”interface LookupResult { entry: Entry; directedFrom?: Entry;}interface Entry { term: string; rank?: number; seeAlso?: string; etymologies: Etymology[]; media: MediaURL[];}Etymology
Section titled “Etymology”interface Etymology { id?: string; pronunciations: Pronunciation[]; description?: string; senses: Sense[];}interface Sense { pos: EnumWrapper; lemma?: string; definitions: Array<Definition | Group>; tags: string[]; translations: Translation[]; forms: Form[];}Definition
Section titled “Definition”interface Definition { id?: string; value: string; examples: Example[]; notes: Note[];}interface Group { id?: string; description: string; definitions: Definition[];}Example
Section titled “Example”interface Example { value: string; translations: Translation[]; pronunciations: Pronunciation[];}interface Note { id?: string; value: string; examples: Example[];}Pronunciation
Section titled “Pronunciation”interface Pronunciation { kind?: EnumWrapper; value: string; media: MediaUrl[];}MediaUrl
Section titled “MediaUrl”interface MediaUrl { src: string; mimeType?: string; description?: string;}interface Token { lemma: string; language?: string; entries: LookupResult[]; kind: string; script: string; start: number; end: number;}EnumWrapper
Section titled “EnumWrapper”interface EnumWrapper { name: string; variant: string; value: string;}Options
Section titled “Options”interface LoadOptions { configDir?: string; remote?: RemoteLoadOptions;}
interface RemoteLoadOptions { outDir?: string; caching?: boolean; retries?: number;}
interface SaveOptions { compress?: CompressOptions;}
interface CompressOptions { quality?: number; windowSize?: number;}
interface LookupOptions { split?: number; follow?: boolean; insensitive?: boolean;}
interface IndexOptions { directory?: string; memory?: number; overwrite?: boolean;}
interface SearchOptions { directory?: string; threshold?: number; autoindex?: boolean; limit?: number;}
interface TokenizeOptions { follow?: boolean; allowList?: string[]; insensitive?: boolean;}Browser support
Section titled “Browser support”The @odict/node package also supports browser environments via WASI. Import from the browser entry point:
import { compile, OpenDictionary } from "@odict/node/browser";