/** * The grammatical feature model. * * A small, closed vocabulary shared by every language pack, modeled after * Apple Foundation's `Morphology`. Languages consume the features they * understand and ignore the rest (with a warning, so typos surface in dev). */ /** Part-of-speech hint for the phrase head. */ type PartOfSpeech = "noun" | "properNoun" | "adjective" | "determiner" | "numeral" | "pronoun" | "particle"; /** Grammatical number of the phrase head. */ type GrammaticalNumber = "singular" | "plural"; /** Grammatical gender (Indo-European three-way system plus "common"). */ type GrammaticalGender = "masculine" | "feminine" | "neuter" | "common"; /** * Grammatical case. * * The union covers the pan-European core, the full Hungarian oblique set and * the Korean particle semantics (topic/comitative are modeled as cases so a * single `case:` template key works across languages). */ type GrammaticalCase = "nominative" | "accusative" | "dative" | "genitive" | "instrumental" | "vocative" | "inessive" | "elative" | "illative" | "superessive" | "delative" | "sublative" | "adessive" | "ablative" | "allative" | "translative" | "causalFinal" | "terminative" | "essiveFormal" | "topic" | "comitative"; /** Definiteness of the noun phrase (drives article agreement). */ type Definiteness = "definite" | "indefinite" | "none"; /** Grammatical person. */ type GrammaticalPerson = "first" | "second" | "third"; /** Explicit request to prepend (or normalize) an article on the phrase. */ type ArticleRequest = "definite" | "indefinite" | "none"; /** * Word formation rather than inflection: make a different word out of this * one. `"relational"` is the adjective meaning "belonging to / coming from" * — Hungarian Budapest → budapesti, German Wien → Wiener. */ type Derivation = "relational"; /** * A bundle of grammatical features to apply to a phrase. * * Every field is optional; a pack applies what it understands. This is the * programmatic mirror of the `^[...](key: value)` template annotations. */ interface GrammaticalFeatures { /** Part of speech of the phrase head (default: noun). */ partOfSpeech?: PartOfSpeech; /** Target grammatical number. */ number?: GrammaticalNumber; /** Target grammatical case (or particle role for Korean). */ case?: GrammaticalCase; /** Grammatical gender of the head — required for correct German articles. */ gender?: GrammaticalGender; /** Definiteness used when agreeing an article already present in the text. */ definiteness?: Definiteness; /** Grammatical person (reserved for future verb agreement). */ person?: GrammaticalPerson; /** Request to prepend/normalize an article on the phrase. */ article?: ArticleRequest; /** Derive a different word before applying any of the above. */ derivation?: Derivation; /** * Mark the noun as possessed by someone: Hungarian `ház` → `házam` (my * house), `házunk` (our house). `number` keeps its usual meaning — how * many things are possessed — so `{ possessor: "first", number: "plural" }` * is "my houses". */ possessor?: GrammaticalPerson; /** Whether the possessor is plural: our house rather than my house. */ possessorNumber?: GrammaticalNumber; } /** Callback used to surface ignored template feature keys/values. */ type FeatureWarning = (kind: "unknown-feature-key" | "unknown-feature-value", detail: string) => void; /** * Default mapping from raw template annotations (`case: instrumental`) to * {@link GrammaticalFeatures}. Language packs may refine it via * `LanguagePack.normalizeFeatures` (e.g. to accept locale-specific aliases). * * Unknown keys and values are ignored and reported through `warn` — a * malformed annotation must never break formatting. */ declare function normalizeFeatures(raw: Record, warn?: FeatureWarning): GrammaticalFeatures; /** * Warning channel. * * `inflect()`/`format()` never throw on bad input — they degrade gracefully * and report what they ignored through this hook, so problems surface in * development without breaking production rendering. */ /** Machine-readable warning categories. */ type WarningCode = "unknown-locale" | "unknown-feature-key" | "unknown-feature-value" | "missing-argument" | "malformed-template" | "missing-gender" | "fallback-error" | "fallback-rejected" | "low-confidence"; /** A single reported warning. */ interface InflectWarning { code: WarningCode; /** Resolved language subtag, when the warning is locale-specific. */ locale?: string; /** Human-readable detail (offending key, span, argument name, …). */ detail: string; } /** Handler installed via {@link onWarning}. */ type WarningHandler = (warning: InflectWarning) => void; /** * Install a global warning handler (pass `undefined` to remove). * * Typical development setup: `onWarning(w => console.warn("[i18n-inflect]", w))`. * No handler is installed by default — production stays silent. */ declare function onWarning(next: WarningHandler | undefined): void; /** * A single word-level inflection request that rules could not answer with * certainty — the unit of work handed to a registered fallback (typically * the neural module). */ interface FallbackRequest { /** The surface word to inflect (post-interpolation, as seen in the text). */ lemma: string; /** * UniMorph-style tag bundle identifying the requested form, e.g. * `"N;INS;SG"`. Each pack owns its own tag mapping; core treats the tag as * an opaque cache-key component. */ tag: string; } /** * Capabilities the engine hands to a pack for one `inflectPhrase` run. * * This is the pack's only side channel: packs must stay pure, deterministic * functions of `(phrase, features, lookup results)` — the property the * engine's two-pass async design relies on. */ interface InflectionContext { /** Resolved primary language subtag ("hu", "de", …). */ readonly locale: string; /** * Synchronously consult the shared oracle cache (earlier neural answers). * Returns the cached inflected form, or `undefined` on a miss. */ lookup(request: FallbackRequest): string | undefined; /** * Record that `lookup` missed and a fallback answer would improve the * result. The async engine batches these, resolves them via the registered * fallback, fills the cache and re-runs the pack. */ requestFallback(request: FallbackRequest): void; /** Report a degradation (unknown feature, missing gender, …). */ warn(code: WarningCode, detail: string): void; } /** Outcome of a phrase inflection. */ interface InflectionResult { /** The inflected phrase. */ text: string; /** * `"high"` — rules/lexicon were sufficient; `"low"` — a heuristic guess * was involved and an async fallback pass may improve the result. */ confidence: "high" | "low"; } /** * The contract a language module implements. * * A pack works on a whole noun phrase: it tokenizes, inflects the head, * agrees articles/adjectives or attaches particles — whatever the language * needs. Packs are registered via `registerLanguage`, which importing the * language subpath (`import "i18n-inflect/hu"`) does as a side effect. */ interface LanguagePack { /** Primary language subtag this pack serves ("hu", "de", …). */ readonly locale: string; /** * Inflect a phrase according to `features`. * * Must be pure and synchronous; use `ctx.lookup`/`ctx.requestFallback` * for anything beyond deterministic rules. */ inflectPhrase(phrase: string, features: GrammaticalFeatures, ctx: InflectionContext): InflectionResult; /** * Optional locale-specific mapping of raw template annotations to * {@link GrammaticalFeatures}; defaults to the shared `normalizeFeatures`. */ normalizeFeatures?(raw: Record, warn: (kind: "unknown-feature-key" | "unknown-feature-value", detail: string) => void): GrammaticalFeatures; /** * Optional plausibility check for a fallback's answer, called before it * enters the shared cache. * * A fallback is a statistical model asked about words it may never have * seen; without a check, one implausible answer would be cached and then * served to every later synchronous call. Return `false` to discard it * and keep the rule-based form. Core applies generic sanity checks * (non-empty, sane length) regardless. */ acceptFallback?(request: FallbackRequest, answer: string): boolean; } /** * A pluggable oracle that can answer {@link FallbackRequest}s asynchronously — * in practice the `@i18n-inflect/neural` seq2seq module, but any * implementation (server API, bigger dictionary, …) fits. */ interface InflectionFallback { /** Primary language subtag this fallback serves. */ readonly locale: string; /** * Resolve a batch of requests. Must return one answer per request, in * order. Individual answers may be empty strings to signal "no answer". */ predict(requests: readonly FallbackRequest[]): Promise; /** Optional warm-up (e.g. create the inference session, load weights). */ preload?(): Promise; } export { type ArticleRequest as A, type Definiteness as D, type FallbackRequest as F, type GrammaticalFeatures as G, type InflectionFallback as I, type LanguagePack as L, type PartOfSpeech as P, type WarningCode as W, type Derivation as a, type GrammaticalCase as b, type GrammaticalGender as c, type GrammaticalNumber as d, type GrammaticalPerson as e, type InflectWarning as f, type InflectionContext as g, type InflectionResult as h, type WarningHandler as i, normalizeFeatures as n, onWarning as o };