morphex 0.0.0-stage → 1.0.1

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.
@@ -0,0 +1,257 @@
1
+ /**
2
+ * Public type surface for morphex.
3
+ *
4
+ * The shapes mirror the Java library's `Inflection`, `DecisionSource`, `Countability`,
5
+ * `CasePolicy`, `Mode` and `UppercasePolicy`, adapted to TypeScript idioms.
6
+ */
7
+ /** Stable decision stages, in precedence order. */
8
+ declare const INFLECTION_SOURCES: readonly ["OVERRIDE", "LEXICON", "INFERRED", "COMPOUND", "RULE", "FALLBACK"];
9
+ /** Where the reported plural came from. Ordered by precedence. */
10
+ type InflectionSource = (typeof INFLECTION_SOURCES)[number];
11
+ /** Countability metadata for a noun lemma. */
12
+ declare const COUNTABILITIES: readonly ["COUNTABLE", "MASS", "MIXED", "PLURAL_ONLY", "UNKNOWN"];
13
+ type Countability = (typeof COUNTABILITIES)[number];
14
+ /** Preferred-form mode for lemmas with both an anglicized and a classical plural. */
15
+ type Mode = 'ANGLICIZED' | 'CLASSICAL';
16
+ /** Output casing policy. */
17
+ type CasePolicy = 'PRESERVE' | 'LOWERCASE' | 'UPPERCASE';
18
+ /** How an unknown all-uppercase token is interpreted. */
19
+ type UppercasePolicy = 'INFER_INITIALISM' | 'LITERAL';
20
+ /**
21
+ * Diagnostic result of `analyze()`.
22
+ *
23
+ * `stage` is the decision stage (the Java `DecisionSource`); `source` is the stable identifier
24
+ * for the entry or rule that won (the Java `Inflection.id()`), e.g. `lex:child` or
25
+ * `rule:default-s`. Every field is always present: a build without full lexical diagnostics
26
+ * reports `diagnostics: false` and leaves `countability` at `UNKNOWN` rather than `undefined`.
27
+ */
28
+ interface Inflection {
29
+ /** The caller's exact input spelling. */
30
+ readonly input: string;
31
+ /** The selected plural. */
32
+ readonly plural: string;
33
+ /** Other accepted plural forms known for this lemma, in artifact order. */
34
+ readonly alternatives: readonly string[];
35
+ /**
36
+ * True when the spelling alone cannot select one form, for example `die` (game piece versus
37
+ * stamping tool). The selected plural is still returned.
38
+ */
39
+ readonly ambiguous: boolean;
40
+ /** Decision stage that produced the plural. */
41
+ readonly stage: InflectionSource;
42
+ /** Stable identifier of the winning entry or rule. */
43
+ readonly source: string;
44
+ readonly countability: Countability;
45
+ /** True when singular and plural are identical (`sheep`). */
46
+ readonly invariant: boolean;
47
+ /** Human-readable explanation of the decision. Empty when there is none. */
48
+ readonly note: string;
49
+ /**
50
+ * True when the backing lexicon supplies complete diagnostics (a full artifact or a
51
+ * caller-supplied lexicon). False for the bundled delta lexicon and rules-only builds, where
52
+ * metadata for lemmas outside the shipped delta may be absent.
53
+ */
54
+ readonly diagnostics: boolean;
55
+ /** True when `form` is the selected plural or one of the accepted alternatives. */
56
+ isAccepted(form: string): boolean;
57
+ }
58
+ /** A single lexical entry as seen by the engine. */
59
+ interface LexiconEntry {
60
+ /** The artifact's exact lemma spelling (case-sensitive entries rely on this). */
61
+ readonly lemma: string;
62
+ /** The lower-cased lookup key. */
63
+ readonly key: string;
64
+ /** The lower-cased preferred plural. */
65
+ readonly plural: string;
66
+ /** An attested classical plural, or `null` when the entry has none. */
67
+ readonly classical: string | null;
68
+ /** Other accepted plural forms, in artifact order. */
69
+ readonly alternatives: readonly string[];
70
+ readonly countability: Countability;
71
+ readonly invariant: boolean;
72
+ readonly initialism: boolean;
73
+ readonly caseSensitive: boolean;
74
+ readonly ambiguous: boolean;
75
+ }
76
+ /** Caller-supplied lexicon entry; missing fields take the documented defaults. */
77
+ interface LexiconEntryInput {
78
+ readonly lemma: string;
79
+ readonly plural: string;
80
+ readonly classical?: string | null;
81
+ readonly alternatives?: readonly string[];
82
+ readonly countability?: Countability;
83
+ readonly invariant?: boolean;
84
+ readonly initialism?: boolean;
85
+ readonly caseSensitive?: boolean;
86
+ readonly ambiguous?: boolean;
87
+ }
88
+ /**
89
+ * A pluggable lexicon. The bundled delta artifact, the opt-in full artifact, rules-only mode and
90
+ * caller-supplied data all implement this interface.
91
+ */
92
+ interface LexiconProvider {
93
+ readonly kind: 'rules-only' | 'delta' | 'full' | 'custom';
94
+ /** Number of entries visible to the engine. */
95
+ readonly size: number;
96
+ /** True when entries carry complete diagnostics (alternatives, countability, notes). */
97
+ readonly diagnostics: boolean;
98
+ /** Returns the entry for a lower-cased key, or `undefined`. */
99
+ lookup(lower: string): LexiconEntry | undefined;
100
+ /**
101
+ * Membership evidence for ordinary-word checks. `undefined` means the provider has no
102
+ * membership table, which disables uppercase-initialism inference exactly as the Java
103
+ * rules-only instance does.
104
+ */
105
+ isOrdinaryWord(lower: string): boolean | undefined;
106
+ }
107
+ /** A membership table for lower-cased lemmas, independent of the exception artifact. */
108
+ interface MembershipTable {
109
+ readonly size: number;
110
+ contains(lower: string): boolean;
111
+ }
112
+
113
+ /**
114
+ * Immutable English noun pluralizer, a TypeScript port of the Java `EnglishInflector`.
115
+ *
116
+ * Resolution order is fixed: caller override, exact lexical entry, caller-declared initialism,
117
+ * supported compound, productive spelling rule, then the documented fallback that returns the
118
+ * input unchanged. Instances are immutable and stateless.
119
+ */
120
+
121
+ interface Config {
122
+ readonly mode: Mode;
123
+ readonly casePolicy: CasePolicy;
124
+ readonly overrides: ReadonlyMap<string, string>;
125
+ readonly initialisms: ReadonlySet<string>;
126
+ readonly uppercasePolicy: UppercasePolicy;
127
+ readonly lexicon: LexiconProvider;
128
+ }
129
+ declare class EnglishInflector {
130
+ #private;
131
+ /** @internal Instances are created through `standard()` or `builder()`. */
132
+ constructor(config: Config);
133
+ /** Shared default instance: anglicized mode, `PRESERVE` casing, bundled delta lexicon. */
134
+ static standard(): EnglishInflector;
135
+ static builder(): Builder;
136
+ get mode(): Mode;
137
+ get casePolicy(): CasePolicy;
138
+ get uppercasePolicy(): UppercasePolicy;
139
+ /** Number of lexical entries visible to this instance (0 for a rules-only build). */
140
+ get lexiconSize(): number;
141
+ /**
142
+ * Returns the plural of a singular noun. With a `count`, returns `noun` unchanged when
143
+ * `count === 1` and the plural otherwise. This is deliberately a plain count test, not an
144
+ * absolute-value or locale rule.
145
+ */
146
+ pluralize(noun: string, count?: number): string;
147
+ /** Returns a full diagnostic result. The chosen form is identical to `pluralize(noun)`. */
148
+ analyze(noun: string): Inflection;
149
+ }
150
+ /** Immutable configuration builder. Every setter returns the builder. */
151
+ declare class Builder {
152
+ #private;
153
+ withMode(mode: Mode): this;
154
+ withCasePolicy(casePolicy: CasePolicy): this;
155
+ withUppercasePolicy(uppercasePolicy: UppercasePolicy): this;
156
+ /** Adds an exact, case-sensitive replacement for the whole input spelling. */
157
+ withOverride(noun: string, plural: string): this;
158
+ withOverrides(replacements: Readonly<Record<string, string>>): this;
159
+ /** Declares a token an initialism: it appends `s`, or `es` after a final s. */
160
+ withInitialism(token: string): this;
161
+ withInitialisms(tokens: Iterable<string>): this;
162
+ /** Replaces the bundled lexicon with caller-supplied or custom data. */
163
+ withLexicon(lexicon: LexiconProvider): this;
164
+ /** Builds a rules-only instance (no bundled lexicon). */
165
+ withoutBundledLexicon(): this;
166
+ build(): EnglishInflector;
167
+ }
168
+
169
+ /**
170
+ * Lexicon providers: the packed delta artifact, the packed full artifact, rules-only mode and
171
+ * caller-supplied data all implement the same `LexiconProvider` interface.
172
+ *
173
+ * Two packed formats are emitted, both line-oriented so they can be reviewed in a diff.
174
+ *
175
+ * Full artifact (`morphex-lexicon-v1`):
176
+ *
177
+ * morphex-lexicon-v1<TAB>full<TAB><count>
178
+ * <lemma><TAB><cut><TAB><append><TAB><classicalCut|-><TAB><classicalAppend|-><TAB><alternatives|-><TAB><countability><TAB><flags>
179
+ *
180
+ * Delta artifact (`morphex-delta-v1`): a small table of entries whose edit differs from the
181
+ * productive rules, followed by sorted key lists for the mass, plural-only and invariant nouns
182
+ * whose pluralize() answer is "return the input unchanged". Those identity nouns are 90k of the
183
+ * 147k artifact entries, and a key list stores them without a redundant record per noun.
184
+ *
185
+ * morphex-delta-v1<TAB><edits><TAB><mass><TAB><pluralOnly><TAB><invariant>
186
+ * <edit record, full format minus the leading kind>
187
+ * <lower-case key> (mass)
188
+ * <lower-case key> (plural-only)
189
+ * <lower-case key> (invariant)
190
+ *
191
+ * Both loaders reject a malformed artifact, an unsorted file, a duplicate key or a bad flag
192
+ * instead of guessing.
193
+ */
194
+
195
+ /** Computes the end-of-token edit that turns `lemma` into `plural` (longest common prefix). */
196
+ declare function deriveEdit(lemma: string, plural: string): readonly [cut: number, append: string];
197
+ /** Rules-only provider: no entries, no membership evidence, no data. */
198
+ declare const RULES_ONLY_LEXICON: LexiconProvider;
199
+ /** Parses the full packed artifact. Throws on malformed, unsorted or duplicate data. */
200
+ declare function parseFullLexicon(packed: string): readonly LexiconEntry[];
201
+ /** Builds the opt-in full provider from a packed full artifact. */
202
+ declare function createFullLexicon(packed: string, membership?: MembershipTable): LexiconProvider;
203
+ /** Builds the bundled delta provider. `pluralize()` needs nothing else. */
204
+ declare function createDeltaLexicon(packed: string, membership?: MembershipTable): LexiconProvider;
205
+ /**
206
+ * Builds a provider from caller-supplied entries. Duplicate lookup keys are rejected, matching
207
+ * the bundled-artifact loader.
208
+ */
209
+ declare function createLexicon(entries: Iterable<LexiconEntryInput>, membership?: MembershipTable): LexiconProvider;
210
+ /** FNV-1a 64-bit, low 32 bits only: identical to the Java membership hash truncated. */
211
+ declare function fnv1aLow32(value: string): number;
212
+ /** Decodes standard base64 without depending on `atob` or Node-specific APIs. */
213
+ declare function decodeBase64(value: string): Uint8Array;
214
+ /** Wraps a base64-encoded, sorted, little-endian `uint32` hash table as a membership table. */
215
+ declare function createMembershipTable(base64: string): MembershipTable;
216
+
217
+ /**
218
+ * Default bundled lexicon. The generated module contains the delta artifact: only the entries
219
+ * whose true answer differs from the three productive rules, plus entries that carry metadata
220
+ * which changes a decision. `pluralize()` needs nothing else.
221
+ *
222
+ * The `morphex/rules` build replaces this module with an empty artifact, so that entry ships no
223
+ * lexicon data at all.
224
+ */
225
+
226
+ declare function defaultLexiconProvider(): LexiconProvider;
227
+
228
+ /**
229
+ * Bounded, documented compound support, ported from the Java `CompoundTable`.
230
+ *
231
+ * Deliberately small: a suffix match is not proof of a morpheme boundary, so only structures that
232
+ * were individually reviewed are recognised. A malformed table entry fails fast at module load.
233
+ */
234
+ /** Whole compound (lower case) to whole plural (lower case). */
235
+ declare const COMPOUND_EXACT: {
236
+ readonly 'passer-by': "passers-by";
237
+ readonly 'hanger-on': "hangers-on";
238
+ readonly 'looker-on': "lookers-on";
239
+ readonly 'runner-up': "runners-up";
240
+ readonly 'stand-in': "stand-ins";
241
+ readonly 'drive-by': "drive-bys";
242
+ readonly 'tie-in': "tie-ins";
243
+ readonly 'close-up': "close-ups";
244
+ readonly 'grown-up': "grown-ups";
245
+ readonly 'go-between': "go-betweens";
246
+ readonly 'forget-me-not': "forget-me-nots";
247
+ readonly 'jack-in-the-box': "jack-in-the-boxes";
248
+ readonly 'man-of-war': "men-of-war";
249
+ readonly 'major general': "major generals";
250
+ };
251
+ /**
252
+ * Validates every table entry. A typo (upper case, missing separator, duplicate membership)
253
+ * throws, so a malformed table fails the build and the test run instead of silently misfiring.
254
+ */
255
+ declare function validateCompoundTable(): void;
256
+
257
+ export { Builder, COMPOUND_EXACT, COUNTABILITIES, type CasePolicy, type Countability, EnglishInflector, INFLECTION_SOURCES, type Inflection, type InflectionSource, type LexiconEntry, type LexiconEntryInput, type LexiconProvider, type MembershipTable, type Mode, RULES_ONLY_LEXICON, type UppercasePolicy, createDeltaLexicon, createFullLexicon, createLexicon, createMembershipTable, decodeBase64, defaultLexiconProvider, deriveEdit, fnv1aLow32, parseFullLexicon, validateCompoundTable };
@@ -0,0 +1,257 @@
1
+ /**
2
+ * Public type surface for morphex.
3
+ *
4
+ * The shapes mirror the Java library's `Inflection`, `DecisionSource`, `Countability`,
5
+ * `CasePolicy`, `Mode` and `UppercasePolicy`, adapted to TypeScript idioms.
6
+ */
7
+ /** Stable decision stages, in precedence order. */
8
+ declare const INFLECTION_SOURCES: readonly ["OVERRIDE", "LEXICON", "INFERRED", "COMPOUND", "RULE", "FALLBACK"];
9
+ /** Where the reported plural came from. Ordered by precedence. */
10
+ type InflectionSource = (typeof INFLECTION_SOURCES)[number];
11
+ /** Countability metadata for a noun lemma. */
12
+ declare const COUNTABILITIES: readonly ["COUNTABLE", "MASS", "MIXED", "PLURAL_ONLY", "UNKNOWN"];
13
+ type Countability = (typeof COUNTABILITIES)[number];
14
+ /** Preferred-form mode for lemmas with both an anglicized and a classical plural. */
15
+ type Mode = 'ANGLICIZED' | 'CLASSICAL';
16
+ /** Output casing policy. */
17
+ type CasePolicy = 'PRESERVE' | 'LOWERCASE' | 'UPPERCASE';
18
+ /** How an unknown all-uppercase token is interpreted. */
19
+ type UppercasePolicy = 'INFER_INITIALISM' | 'LITERAL';
20
+ /**
21
+ * Diagnostic result of `analyze()`.
22
+ *
23
+ * `stage` is the decision stage (the Java `DecisionSource`); `source` is the stable identifier
24
+ * for the entry or rule that won (the Java `Inflection.id()`), e.g. `lex:child` or
25
+ * `rule:default-s`. Every field is always present: a build without full lexical diagnostics
26
+ * reports `diagnostics: false` and leaves `countability` at `UNKNOWN` rather than `undefined`.
27
+ */
28
+ interface Inflection {
29
+ /** The caller's exact input spelling. */
30
+ readonly input: string;
31
+ /** The selected plural. */
32
+ readonly plural: string;
33
+ /** Other accepted plural forms known for this lemma, in artifact order. */
34
+ readonly alternatives: readonly string[];
35
+ /**
36
+ * True when the spelling alone cannot select one form, for example `die` (game piece versus
37
+ * stamping tool). The selected plural is still returned.
38
+ */
39
+ readonly ambiguous: boolean;
40
+ /** Decision stage that produced the plural. */
41
+ readonly stage: InflectionSource;
42
+ /** Stable identifier of the winning entry or rule. */
43
+ readonly source: string;
44
+ readonly countability: Countability;
45
+ /** True when singular and plural are identical (`sheep`). */
46
+ readonly invariant: boolean;
47
+ /** Human-readable explanation of the decision. Empty when there is none. */
48
+ readonly note: string;
49
+ /**
50
+ * True when the backing lexicon supplies complete diagnostics (a full artifact or a
51
+ * caller-supplied lexicon). False for the bundled delta lexicon and rules-only builds, where
52
+ * metadata for lemmas outside the shipped delta may be absent.
53
+ */
54
+ readonly diagnostics: boolean;
55
+ /** True when `form` is the selected plural or one of the accepted alternatives. */
56
+ isAccepted(form: string): boolean;
57
+ }
58
+ /** A single lexical entry as seen by the engine. */
59
+ interface LexiconEntry {
60
+ /** The artifact's exact lemma spelling (case-sensitive entries rely on this). */
61
+ readonly lemma: string;
62
+ /** The lower-cased lookup key. */
63
+ readonly key: string;
64
+ /** The lower-cased preferred plural. */
65
+ readonly plural: string;
66
+ /** An attested classical plural, or `null` when the entry has none. */
67
+ readonly classical: string | null;
68
+ /** Other accepted plural forms, in artifact order. */
69
+ readonly alternatives: readonly string[];
70
+ readonly countability: Countability;
71
+ readonly invariant: boolean;
72
+ readonly initialism: boolean;
73
+ readonly caseSensitive: boolean;
74
+ readonly ambiguous: boolean;
75
+ }
76
+ /** Caller-supplied lexicon entry; missing fields take the documented defaults. */
77
+ interface LexiconEntryInput {
78
+ readonly lemma: string;
79
+ readonly plural: string;
80
+ readonly classical?: string | null;
81
+ readonly alternatives?: readonly string[];
82
+ readonly countability?: Countability;
83
+ readonly invariant?: boolean;
84
+ readonly initialism?: boolean;
85
+ readonly caseSensitive?: boolean;
86
+ readonly ambiguous?: boolean;
87
+ }
88
+ /**
89
+ * A pluggable lexicon. The bundled delta artifact, the opt-in full artifact, rules-only mode and
90
+ * caller-supplied data all implement this interface.
91
+ */
92
+ interface LexiconProvider {
93
+ readonly kind: 'rules-only' | 'delta' | 'full' | 'custom';
94
+ /** Number of entries visible to the engine. */
95
+ readonly size: number;
96
+ /** True when entries carry complete diagnostics (alternatives, countability, notes). */
97
+ readonly diagnostics: boolean;
98
+ /** Returns the entry for a lower-cased key, or `undefined`. */
99
+ lookup(lower: string): LexiconEntry | undefined;
100
+ /**
101
+ * Membership evidence for ordinary-word checks. `undefined` means the provider has no
102
+ * membership table, which disables uppercase-initialism inference exactly as the Java
103
+ * rules-only instance does.
104
+ */
105
+ isOrdinaryWord(lower: string): boolean | undefined;
106
+ }
107
+ /** A membership table for lower-cased lemmas, independent of the exception artifact. */
108
+ interface MembershipTable {
109
+ readonly size: number;
110
+ contains(lower: string): boolean;
111
+ }
112
+
113
+ /**
114
+ * Immutable English noun pluralizer, a TypeScript port of the Java `EnglishInflector`.
115
+ *
116
+ * Resolution order is fixed: caller override, exact lexical entry, caller-declared initialism,
117
+ * supported compound, productive spelling rule, then the documented fallback that returns the
118
+ * input unchanged. Instances are immutable and stateless.
119
+ */
120
+
121
+ interface Config {
122
+ readonly mode: Mode;
123
+ readonly casePolicy: CasePolicy;
124
+ readonly overrides: ReadonlyMap<string, string>;
125
+ readonly initialisms: ReadonlySet<string>;
126
+ readonly uppercasePolicy: UppercasePolicy;
127
+ readonly lexicon: LexiconProvider;
128
+ }
129
+ declare class EnglishInflector {
130
+ #private;
131
+ /** @internal Instances are created through `standard()` or `builder()`. */
132
+ constructor(config: Config);
133
+ /** Shared default instance: anglicized mode, `PRESERVE` casing, bundled delta lexicon. */
134
+ static standard(): EnglishInflector;
135
+ static builder(): Builder;
136
+ get mode(): Mode;
137
+ get casePolicy(): CasePolicy;
138
+ get uppercasePolicy(): UppercasePolicy;
139
+ /** Number of lexical entries visible to this instance (0 for a rules-only build). */
140
+ get lexiconSize(): number;
141
+ /**
142
+ * Returns the plural of a singular noun. With a `count`, returns `noun` unchanged when
143
+ * `count === 1` and the plural otherwise. This is deliberately a plain count test, not an
144
+ * absolute-value or locale rule.
145
+ */
146
+ pluralize(noun: string, count?: number): string;
147
+ /** Returns a full diagnostic result. The chosen form is identical to `pluralize(noun)`. */
148
+ analyze(noun: string): Inflection;
149
+ }
150
+ /** Immutable configuration builder. Every setter returns the builder. */
151
+ declare class Builder {
152
+ #private;
153
+ withMode(mode: Mode): this;
154
+ withCasePolicy(casePolicy: CasePolicy): this;
155
+ withUppercasePolicy(uppercasePolicy: UppercasePolicy): this;
156
+ /** Adds an exact, case-sensitive replacement for the whole input spelling. */
157
+ withOverride(noun: string, plural: string): this;
158
+ withOverrides(replacements: Readonly<Record<string, string>>): this;
159
+ /** Declares a token an initialism: it appends `s`, or `es` after a final s. */
160
+ withInitialism(token: string): this;
161
+ withInitialisms(tokens: Iterable<string>): this;
162
+ /** Replaces the bundled lexicon with caller-supplied or custom data. */
163
+ withLexicon(lexicon: LexiconProvider): this;
164
+ /** Builds a rules-only instance (no bundled lexicon). */
165
+ withoutBundledLexicon(): this;
166
+ build(): EnglishInflector;
167
+ }
168
+
169
+ /**
170
+ * Lexicon providers: the packed delta artifact, the packed full artifact, rules-only mode and
171
+ * caller-supplied data all implement the same `LexiconProvider` interface.
172
+ *
173
+ * Two packed formats are emitted, both line-oriented so they can be reviewed in a diff.
174
+ *
175
+ * Full artifact (`morphex-lexicon-v1`):
176
+ *
177
+ * morphex-lexicon-v1<TAB>full<TAB><count>
178
+ * <lemma><TAB><cut><TAB><append><TAB><classicalCut|-><TAB><classicalAppend|-><TAB><alternatives|-><TAB><countability><TAB><flags>
179
+ *
180
+ * Delta artifact (`morphex-delta-v1`): a small table of entries whose edit differs from the
181
+ * productive rules, followed by sorted key lists for the mass, plural-only and invariant nouns
182
+ * whose pluralize() answer is "return the input unchanged". Those identity nouns are 90k of the
183
+ * 147k artifact entries, and a key list stores them without a redundant record per noun.
184
+ *
185
+ * morphex-delta-v1<TAB><edits><TAB><mass><TAB><pluralOnly><TAB><invariant>
186
+ * <edit record, full format minus the leading kind>
187
+ * <lower-case key> (mass)
188
+ * <lower-case key> (plural-only)
189
+ * <lower-case key> (invariant)
190
+ *
191
+ * Both loaders reject a malformed artifact, an unsorted file, a duplicate key or a bad flag
192
+ * instead of guessing.
193
+ */
194
+
195
+ /** Computes the end-of-token edit that turns `lemma` into `plural` (longest common prefix). */
196
+ declare function deriveEdit(lemma: string, plural: string): readonly [cut: number, append: string];
197
+ /** Rules-only provider: no entries, no membership evidence, no data. */
198
+ declare const RULES_ONLY_LEXICON: LexiconProvider;
199
+ /** Parses the full packed artifact. Throws on malformed, unsorted or duplicate data. */
200
+ declare function parseFullLexicon(packed: string): readonly LexiconEntry[];
201
+ /** Builds the opt-in full provider from a packed full artifact. */
202
+ declare function createFullLexicon(packed: string, membership?: MembershipTable): LexiconProvider;
203
+ /** Builds the bundled delta provider. `pluralize()` needs nothing else. */
204
+ declare function createDeltaLexicon(packed: string, membership?: MembershipTable): LexiconProvider;
205
+ /**
206
+ * Builds a provider from caller-supplied entries. Duplicate lookup keys are rejected, matching
207
+ * the bundled-artifact loader.
208
+ */
209
+ declare function createLexicon(entries: Iterable<LexiconEntryInput>, membership?: MembershipTable): LexiconProvider;
210
+ /** FNV-1a 64-bit, low 32 bits only: identical to the Java membership hash truncated. */
211
+ declare function fnv1aLow32(value: string): number;
212
+ /** Decodes standard base64 without depending on `atob` or Node-specific APIs. */
213
+ declare function decodeBase64(value: string): Uint8Array;
214
+ /** Wraps a base64-encoded, sorted, little-endian `uint32` hash table as a membership table. */
215
+ declare function createMembershipTable(base64: string): MembershipTable;
216
+
217
+ /**
218
+ * Default bundled lexicon. The generated module contains the delta artifact: only the entries
219
+ * whose true answer differs from the three productive rules, plus entries that carry metadata
220
+ * which changes a decision. `pluralize()` needs nothing else.
221
+ *
222
+ * The `morphex/rules` build replaces this module with an empty artifact, so that entry ships no
223
+ * lexicon data at all.
224
+ */
225
+
226
+ declare function defaultLexiconProvider(): LexiconProvider;
227
+
228
+ /**
229
+ * Bounded, documented compound support, ported from the Java `CompoundTable`.
230
+ *
231
+ * Deliberately small: a suffix match is not proof of a morpheme boundary, so only structures that
232
+ * were individually reviewed are recognised. A malformed table entry fails fast at module load.
233
+ */
234
+ /** Whole compound (lower case) to whole plural (lower case). */
235
+ declare const COMPOUND_EXACT: {
236
+ readonly 'passer-by': "passers-by";
237
+ readonly 'hanger-on': "hangers-on";
238
+ readonly 'looker-on': "lookers-on";
239
+ readonly 'runner-up': "runners-up";
240
+ readonly 'stand-in': "stand-ins";
241
+ readonly 'drive-by': "drive-bys";
242
+ readonly 'tie-in': "tie-ins";
243
+ readonly 'close-up': "close-ups";
244
+ readonly 'grown-up': "grown-ups";
245
+ readonly 'go-between': "go-betweens";
246
+ readonly 'forget-me-not': "forget-me-nots";
247
+ readonly 'jack-in-the-box': "jack-in-the-boxes";
248
+ readonly 'man-of-war': "men-of-war";
249
+ readonly 'major general': "major generals";
250
+ };
251
+ /**
252
+ * Validates every table entry. A typo (upper case, missing separator, duplicate membership)
253
+ * throws, so a malformed table fails the build and the test run instead of silently misfiring.
254
+ */
255
+ declare function validateCompoundTable(): void;
256
+
257
+ export { Builder, COMPOUND_EXACT, COUNTABILITIES, type CasePolicy, type Countability, EnglishInflector, INFLECTION_SOURCES, type Inflection, type InflectionSource, type LexiconEntry, type LexiconEntryInput, type LexiconProvider, type MembershipTable, type Mode, RULES_ONLY_LEXICON, type UppercasePolicy, createDeltaLexicon, createFullLexicon, createLexicon, createMembershipTable, decodeBase64, defaultLexiconProvider, deriveEdit, fnv1aLow32, parseFullLexicon, validateCompoundTable };