cspell-trie-lib 7.0.0-alpha.2 → 7.0.0

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.
Files changed (153) hide show
  1. package/dist/lib/Builder/BuilderCursor.d.ts +7 -0
  2. package/dist/lib/Builder/BuilderCursor.js +1 -0
  3. package/dist/lib/Builder/TrieBuilder.d.ts +9 -0
  4. package/dist/lib/Builder/TrieBuilder.js +1 -0
  5. package/dist/lib/Builder/cursor-util.d.ts +3 -0
  6. package/dist/lib/Builder/cursor-util.js +21 -0
  7. package/dist/lib/Builder/index.d.ts +4 -0
  8. package/dist/lib/Builder/index.js +1 -0
  9. package/dist/lib/ITrie.d.ts +164 -0
  10. package/dist/lib/ITrie.js +176 -0
  11. package/dist/lib/ITrieNode/CompoundModes.d.ts +15 -0
  12. package/dist/lib/ITrieNode/CompoundModes.js +4 -0
  13. package/dist/lib/ITrieNode/FindOptions.d.ts +12 -0
  14. package/dist/lib/ITrieNode/FindOptions.js +1 -0
  15. package/dist/lib/ITrieNode/ITrieNode.d.ts +42 -0
  16. package/dist/lib/ITrieNode/ITrieNode.js +1 -0
  17. package/dist/lib/ITrieNode/TrieInfo.d.ts +9 -0
  18. package/dist/lib/ITrieNode/TrieInfo.js +1 -0
  19. package/dist/lib/ITrieNode/find.d.ts +48 -0
  20. package/dist/lib/ITrieNode/find.js +289 -0
  21. package/dist/lib/ITrieNode/index.d.ts +3 -0
  22. package/dist/lib/ITrieNode/index.js +1 -0
  23. package/dist/lib/ITrieNode/trie-util.d.ts +17 -0
  24. package/dist/lib/ITrieNode/trie-util.js +62 -0
  25. package/dist/lib/ITrieNode/walker/hintedWalker.d.ts +23 -0
  26. package/dist/lib/ITrieNode/walker/hintedWalker.js +138 -0
  27. package/dist/lib/ITrieNode/walker/index.d.ts +5 -0
  28. package/dist/lib/ITrieNode/walker/index.js +3 -0
  29. package/dist/lib/ITrieNode/walker/walker.d.ts +10 -0
  30. package/dist/lib/ITrieNode/walker/walker.js +122 -0
  31. package/dist/lib/ITrieNode/walker/walkerTypes.d.ts +14 -0
  32. package/dist/lib/ITrieNode/walker/walkerTypes.js +1 -0
  33. package/dist/lib/SimpleDictionaryParser.d.ts +5 -2
  34. package/dist/lib/SimpleDictionaryParser.js +15 -2
  35. package/dist/lib/TrieBlob/FastTrieBlob.d.ts +39 -0
  36. package/dist/lib/TrieBlob/FastTrieBlob.js +173 -0
  37. package/dist/lib/TrieBlob/FastTrieBlobBitMaskInfo.d.ts +7 -0
  38. package/dist/lib/TrieBlob/FastTrieBlobBitMaskInfo.js +8 -0
  39. package/dist/lib/TrieBlob/FastTrieBlobBuilder.d.ts +34 -0
  40. package/dist/lib/TrieBlob/FastTrieBlobBuilder.js +271 -0
  41. package/dist/lib/TrieBlob/FastTrieBlobIRoot.d.ts +32 -0
  42. package/dist/lib/TrieBlob/FastTrieBlobIRoot.js +92 -0
  43. package/dist/lib/TrieBlob/FastTrieBlobInternals.d.ts +11 -0
  44. package/dist/lib/TrieBlob/FastTrieBlobInternals.js +11 -0
  45. package/dist/lib/TrieBlob/TrieBlob.d.ts +34 -1
  46. package/dist/lib/TrieBlob/TrieBlob.js +234 -0
  47. package/dist/lib/TrieBlob/TrieBlobIRoot.d.ts +46 -0
  48. package/dist/lib/TrieBlob/TrieBlobIRoot.js +103 -0
  49. package/dist/lib/TrieBlob/createTrieBlob.d.ts +8 -0
  50. package/dist/lib/TrieBlob/createTrieBlob.js +63 -0
  51. package/dist/lib/TrieBlob/resolveMap.d.ts +2 -0
  52. package/dist/lib/TrieBlob/resolveMap.js +8 -0
  53. package/dist/lib/TrieBuilder.d.ts +10 -1
  54. package/dist/lib/TrieBuilder.js +99 -23
  55. package/dist/lib/TrieCursor/TrieCursor.d.ts +9 -0
  56. package/dist/lib/TrieCursor/TrieCursor.js +1 -0
  57. package/dist/lib/TrieCursor/index.d.ts +2 -0
  58. package/dist/lib/TrieCursor/index.js +1 -0
  59. package/dist/lib/TrieData.d.ts +13 -0
  60. package/dist/lib/TrieData.js +1 -0
  61. package/dist/lib/TrieNode/TrieNode.d.ts +11 -0
  62. package/dist/lib/TrieNode/TrieNodeBuilder.d.ts +14 -0
  63. package/dist/lib/TrieNode/TrieNodeBuilder.js +98 -0
  64. package/dist/lib/TrieNode/TrieNodeTrie.d.ts +22 -0
  65. package/dist/lib/TrieNode/TrieNodeTrie.js +45 -0
  66. package/dist/lib/{compoundWalker.d.ts → TrieNode/compoundWalker.d.ts} +1 -1
  67. package/dist/lib/{find.d.ts → TrieNode/find.d.ts} +1 -1
  68. package/dist/lib/{find.js → TrieNode/find.js} +3 -3
  69. package/dist/lib/TrieNode/trie-util.d.ts +47 -0
  70. package/dist/lib/{trie-util.js → TrieNode/trie-util.js} +51 -30
  71. package/dist/lib/TrieNode/trie.d.ts +5 -0
  72. package/dist/lib/TrieNode/trie.js +84 -0
  73. package/dist/lib/buildITrie.d.ts +4 -0
  74. package/dist/lib/buildITrie.js +7 -0
  75. package/dist/lib/consolidate.d.ts +1 -1
  76. package/dist/lib/consolidate.js +6 -3
  77. package/dist/lib/constants.d.ts +2 -2
  78. package/dist/lib/constants.js +2 -1
  79. package/dist/lib/convertToTrieRefNodes.d.ts +1 -1
  80. package/dist/lib/convertToTrieRefNodes.js +1 -1
  81. package/dist/lib/decodeTrie.d.ts +4 -0
  82. package/dist/lib/decodeTrie.js +6 -0
  83. package/dist/lib/distance/distance.d.ts +0 -1
  84. package/dist/lib/distance/distanceAStarWeighted.d.ts +2 -2
  85. package/dist/lib/distance/distanceAStarWeighted.js +4 -2
  86. package/dist/lib/distance/formatResultEx.d.ts +1 -1
  87. package/dist/lib/distance/formatResultEx.js +4 -2
  88. package/dist/lib/distance/index.d.ts +1 -1
  89. package/dist/lib/distance/levenshtein.d.ts +5 -0
  90. package/dist/lib/distance/levenshtein.js +95 -5
  91. package/dist/lib/distance/weightedMaps.d.ts +13 -1
  92. package/dist/lib/distance/weightedMaps.js +17 -12
  93. package/dist/lib/flatten.d.ts +1 -1
  94. package/dist/lib/index.d.ts +11 -5
  95. package/dist/lib/index.js +9 -4
  96. package/dist/lib/io/constants.d.ts +17 -0
  97. package/dist/lib/io/constants.js +16 -0
  98. package/dist/lib/io/decode.d.ts +4 -0
  99. package/dist/lib/io/decode.js +50 -0
  100. package/dist/lib/io/importExport.d.ts +3 -4
  101. package/dist/lib/io/importExport.js +19 -14
  102. package/dist/lib/io/importExportV1.d.ts +1 -1
  103. package/dist/lib/io/importExportV1.js +3 -3
  104. package/dist/lib/io/importExportV2.d.ts +1 -1
  105. package/dist/lib/io/importExportV2.js +3 -3
  106. package/dist/lib/io/importExportV3.d.ts +3 -4
  107. package/dist/lib/io/importExportV3.js +10 -155
  108. package/dist/lib/io/importExportV4.d.ts +2 -3
  109. package/dist/lib/io/importExportV4.js +6 -16
  110. package/dist/lib/io/importV3.d.ts +6 -0
  111. package/dist/lib/io/importV3.js +157 -0
  112. package/dist/lib/io/importV3FastBlob.d.ts +3 -0
  113. package/dist/lib/io/importV3FastBlob.js +5 -0
  114. package/dist/lib/io/index.d.ts +2 -0
  115. package/dist/lib/io/index.js +1 -0
  116. package/dist/lib/suggestCollector.d.ts +2 -1
  117. package/dist/lib/suggestions/SuggestionTypes.d.ts +39 -0
  118. package/dist/lib/suggestions/SuggestionTypes.js +1 -0
  119. package/dist/lib/suggestions/collectSuggestions.d.ts +3 -0
  120. package/dist/lib/suggestions/collectSuggestions.js +31 -0
  121. package/dist/lib/suggestions/constants.d.ts +10 -0
  122. package/dist/lib/suggestions/constants.js +10 -0
  123. package/dist/lib/suggestions/genSuggestionsOptions.d.ts +1 -1
  124. package/dist/lib/suggestions/orthography.js +1 -1
  125. package/dist/lib/suggestions/suggest.d.ts +2 -2
  126. package/dist/lib/suggestions/suggest.js +8 -9
  127. package/dist/lib/suggestions/suggestAStar.d.ts +48 -6
  128. package/dist/lib/suggestions/suggestAStar.js +303 -376
  129. package/dist/lib/suggestions/suggestCollector.d.ts +1 -38
  130. package/dist/lib/suggestions/suggestCollector.js +6 -5
  131. package/dist/lib/suggestions/suggestTrieData.d.ts +2 -0
  132. package/dist/lib/suggestions/suggestTrieData.js +1 -0
  133. package/dist/lib/trie.d.ts +8 -25
  134. package/dist/lib/trie.js +6 -32
  135. package/dist/lib/utils/PairingHeap.d.ts +8 -0
  136. package/dist/lib/utils/PairingHeap.js +10 -0
  137. package/dist/lib/utils/assert.d.ts +2 -0
  138. package/dist/lib/utils/assert.js +5 -0
  139. package/dist/lib/utils/mergeDefaults.d.ts +1 -1
  140. package/dist/lib/utils/mergeOptionalWithDefaults.d.ts +4 -2
  141. package/dist/lib/utils/mergeOptionalWithDefaults.js +3 -3
  142. package/dist/lib/utils/secondChanceCache.js +1 -1
  143. package/dist/lib/utils/timer.d.ts +23 -7
  144. package/dist/lib/utils/timer.js +112 -18
  145. package/dist/lib/walker/hintedWalker.d.ts +1 -1
  146. package/dist/lib/walker/walker.d.ts +8 -4
  147. package/dist/lib/walker/walker.js +148 -12
  148. package/dist/lib/walker/walkerTypes.d.ts +1 -1
  149. package/package.json +12 -7
  150. package/dist/lib/TrieNode.d.ts +0 -17
  151. package/dist/lib/trie-util.d.ts +0 -27
  152. /package/dist/lib/{TrieNode.js → TrieNode/TrieNode.js} +0 -0
  153. /package/dist/lib/{compoundWalker.js → TrieNode/compoundWalker.js} +0 -0
@@ -0,0 +1,7 @@
1
+ export interface BuilderCursor {
2
+ insertChar(char: string): void;
3
+ markEOW(): void;
4
+ reference(nodeIdx: number): void;
5
+ backStep(num: number): void;
6
+ }
7
+ //# sourceMappingURL=BuilderCursor.d.ts.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ import type { PartialTrieOptions, TrieOptions } from '../trie.js';
2
+ import type { TrieData } from '../TrieData.js';
3
+ import type { BuilderCursor } from './BuilderCursor.js';
4
+ export interface TrieBuilder<T extends TrieData> {
5
+ getCursor(): BuilderCursor;
6
+ build(): T;
7
+ setOptions(options: Readonly<PartialTrieOptions>): Readonly<TrieOptions>;
8
+ }
9
+ //# sourceMappingURL=TrieBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { BuilderCursor } from './BuilderCursor.js';
2
+ export declare function insertWordsAtCursor(cursor: BuilderCursor, words: Iterable<string>): void;
3
+ //# sourceMappingURL=cursor-util.d.ts.map
@@ -0,0 +1,21 @@
1
+ export function insertWordsAtCursor(cursor, words) {
2
+ let prevWord = '';
3
+ for (const word of words) {
4
+ const pLen = commonPrefixLen(prevWord, word);
5
+ const stepBack = prevWord.length - pLen;
6
+ cursor.backStep(stepBack);
7
+ for (let i = pLen; i < word.length; ++i) {
8
+ cursor.insertChar(word[i]);
9
+ }
10
+ cursor.markEOW();
11
+ prevWord = word;
12
+ }
13
+ cursor.backStep(prevWord.length);
14
+ }
15
+ function commonPrefixLen(a, b) {
16
+ let i = 0;
17
+ for (i = 0; i < a.length && a[i] === b[i]; ++i) {
18
+ /* empty */
19
+ }
20
+ return i;
21
+ }
@@ -0,0 +1,4 @@
1
+ export type { BuilderCursor } from './BuilderCursor.js';
2
+ export { insertWordsAtCursor } from './cursor-util.js';
3
+ export type { TrieBuilder } from './TrieBuilder.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ export { insertWordsAtCursor } from './cursor-util.js';
@@ -0,0 +1,164 @@
1
+ import type { WeightMap } from './distance/index.js';
2
+ import type { FindFullResult } from './ITrieNode/find.js';
3
+ import type { ITrieNode } from './ITrieNode/index.js';
4
+ import type { PartialTrieInfo, TrieInfo } from './ITrieNode/TrieInfo.js';
5
+ import type { CompoundWordsMethod, WalkerIterator } from './ITrieNode/walker/walkerTypes.js';
6
+ import type { SuggestionCollector, SuggestionResult } from './suggestCollector.js';
7
+ import { type SuggestionOptions } from './suggestions/genSuggestionsOptions.js';
8
+ import type { TrieData } from './TrieData.js';
9
+ export interface ITrie {
10
+ readonly data: TrieData;
11
+ /**
12
+ * Approximate number of words in the Trie, the first call to this method might be expensive.
13
+ * Use `size` to get the number of nodes.
14
+ *
15
+ * It does NOT count natural compound words. Natural compounds are words that are composed of appending
16
+ * multiple words to make a new word. This is common in languages like German and Dutch.
17
+ */
18
+ numWords(): number;
19
+ /**
20
+ * Used to check if the number of words has been calculated.
21
+ */
22
+ isNumWordsKnown(): boolean;
23
+ /**
24
+ * The number of nodes in the Trie. There is a rough corelation between the size and the number of words.
25
+ */
26
+ readonly size: number;
27
+ readonly info: Readonly<TrieInfo>;
28
+ /**
29
+ * @param text - text to find in the Trie
30
+ */
31
+ find(text: string): ITrieNode | undefined;
32
+ has(word: string): boolean;
33
+ has(word: string, minLegacyCompoundLength: boolean | number): boolean;
34
+ /**
35
+ * Determine if a word is in the dictionary.
36
+ * @param word - the exact word to search for - must be normalized.
37
+ * @param caseSensitive - false means also searching a dictionary where the words were normalized to lower case and accents removed.
38
+ * @returns true if the word was found and is not forbidden.
39
+ */
40
+ hasWord(word: string, caseSensitive: boolean): boolean;
41
+ findWord(word: string, options?: FindWordOptions): FindFullResult;
42
+ /**
43
+ * Determine if a word is in the forbidden word list.
44
+ * @param word the word to lookup.
45
+ */
46
+ isForbiddenWord(word: string): boolean;
47
+ /**
48
+ * Provides an ordered sequence of words with the prefix of text.
49
+ */
50
+ completeWord(text: string): Iterable<string>;
51
+ /**
52
+ * Suggest spellings for `text`. The results are sorted by edit distance with changes near the beginning of a word having a greater impact.
53
+ * @param text - the text to search for
54
+ * @param options - Controls the generated suggestions:
55
+ * - ignoreCase - Ignore Case and Accents
56
+ * - numSuggestions - the maximum number of suggestions to return.
57
+ * - compoundMethod - Use to control splitting words.
58
+ * - changeLimit - the maximum number of changes allowed to text. This is an approximate value, since some changes cost less than others.
59
+ * the lower the value, the faster results are returned. Values less than 4 are best.
60
+ */
61
+ suggest(text: string, options: SuggestionOptions): string[];
62
+ /**
63
+ * Suggest spellings for `text`. The results are sorted by edit distance with changes near the beginning of a word having a greater impact.
64
+ * The results include the word and adjusted edit cost. This is useful for merging results from multiple tries.
65
+ */
66
+ suggestWithCost(text: string, options: SuggestionOptions): SuggestionResult[];
67
+ /**
68
+ * genSuggestions will generate suggestions and send them to `collector`. `collector` is responsible for returning the max acceptable cost.
69
+ * Costs are measured in weighted changes. A cost of 100 is the same as 1 edit. Some edits are considered cheaper.
70
+ * Returning a MaxCost < 0 will effectively cause the search for suggestions to stop.
71
+ */
72
+ genSuggestions(collector: SuggestionCollector, compoundMethod?: CompoundWordsMethod): void;
73
+ /**
74
+ * Returns an iterator that can be used to get all words in the trie. For some dictionaries, this can result in millions of words.
75
+ */
76
+ words(): Iterable<string>;
77
+ /**
78
+ * Allows iteration over the entire tree.
79
+ * On the returned Iterator, calling .next(goDeeper: boolean), allows for controlling the depth.
80
+ */
81
+ iterate(): WalkerIterator;
82
+ weightMap: WeightMap | undefined;
83
+ get isCaseAware(): boolean;
84
+ }
85
+ export declare class ITrieImpl implements ITrie {
86
+ readonly data: TrieData;
87
+ private numNodes?;
88
+ private _info;
89
+ private _findOptionsDefaults;
90
+ private hasForbidden;
91
+ private root;
92
+ private count?;
93
+ weightMap: WeightMap | undefined;
94
+ constructor(data: TrieData, numNodes?: number | undefined);
95
+ /**
96
+ * Number of words in the Trie, the first call to this method might be expensive.
97
+ * Use `size` to get the number of nodes.
98
+ */
99
+ numWords(): number;
100
+ isNumWordsKnown(): boolean;
101
+ get size(): number;
102
+ get info(): Readonly<TrieInfo>;
103
+ get isCaseAware(): boolean;
104
+ /**
105
+ * @param text - text to find in the Trie
106
+ */
107
+ find(text: string): ITrieNode | undefined;
108
+ has(word: string, minLegacyCompoundLength?: boolean | number): boolean;
109
+ /**
110
+ * Determine if a word is in the dictionary.
111
+ * @param word - the exact word to search for - must be normalized.
112
+ * @param caseSensitive - false means also searching a dictionary where the words were normalized to lower case and accents removed.
113
+ * @returns true if the word was found and is not forbidden.
114
+ */
115
+ hasWord(word: string, caseSensitive: boolean): boolean;
116
+ findWord(word: string, options?: FindWordOptions): FindFullResult;
117
+ /**
118
+ * Determine if a word is in the forbidden word list.
119
+ * @param word the word to lookup.
120
+ */
121
+ isForbiddenWord(word: string): boolean;
122
+ /**
123
+ * Provides an ordered sequence of words with the prefix of text.
124
+ */
125
+ completeWord(text: string): Iterable<string>;
126
+ /**
127
+ * Suggest spellings for `text`. The results are sorted by edit distance with changes near the beginning of a word having a greater impact.
128
+ * @param text - the text to search for
129
+ * @param maxNumSuggestions - the maximum number of suggestions to return.
130
+ * @param compoundMethod - Use to control splitting words.
131
+ * @param numChanges - the maximum number of changes allowed to text. This is an approximate value, since some changes cost less than others.
132
+ * the lower the value, the faster results are returned. Values less than 4 are best.
133
+ */
134
+ suggest(text: string, options: SuggestionOptions): string[];
135
+ /**
136
+ * Suggest spellings for `text`. The results are sorted by edit distance with changes near the beginning of a word having a greater impact.
137
+ * The results include the word and adjusted edit cost. This is useful for merging results from multiple tries.
138
+ */
139
+ suggestWithCost(text: string, options: SuggestionOptions): SuggestionResult[];
140
+ /**
141
+ * genSuggestions will generate suggestions and send them to `collector`. `collector` is responsible for returning the max acceptable cost.
142
+ * Costs are measured in weighted changes. A cost of 100 is the same as 1 edit. Some edits are considered cheaper.
143
+ * Returning a MaxCost < 0 will effectively cause the search for suggestions to stop.
144
+ */
145
+ genSuggestions(collector: SuggestionCollector, compoundMethod?: CompoundWordsMethod): void;
146
+ /**
147
+ * Returns an iterator that can be used to get all words in the trie. For some dictionaries, this can result in millions of words.
148
+ */
149
+ words(): Iterable<string>;
150
+ /**
151
+ * Allows iteration over the entire tree.
152
+ * On the returned Iterator, calling .next(goDeeper: boolean), allows for controlling the depth.
153
+ */
154
+ iterate(): WalkerIterator;
155
+ static create(words: Iterable<string> | IterableIterator<string>, info?: PartialTrieInfo): ITrie;
156
+ private createFindOptions;
157
+ private lastCreateFindOptionsMatchCaseMap;
158
+ private createFindOptionsMatchCase;
159
+ }
160
+ export interface FindWordOptions {
161
+ caseSensitive?: boolean;
162
+ useLegacyWordCompounds?: boolean | number;
163
+ }
164
+ //# sourceMappingURL=ITrie.d.ts.map
@@ -0,0 +1,176 @@
1
+ import { opAppend, opFilter, opMap, pipe } from '@cspell/cspell-pipe/sync';
2
+ import { createFindOptions, findLegacyCompound, findWord, findWordNode, isForbiddenWord } from './ITrieNode/find.js';
3
+ import { countWords, iteratorTrieWords } from './ITrieNode/trie-util.js';
4
+ import { walker } from './ITrieNode/walker/walker.js';
5
+ import { createSuggestionOptions } from './suggestions/genSuggestionsOptions.js';
6
+ import { genSuggestions, suggest } from './suggestions/suggestTrieData.js';
7
+ import { FastTrieBlobBuilder } from './TrieBlob/FastTrieBlobBuilder.js';
8
+ import { clean } from './utils/clean.js';
9
+ import { mergeOptionalWithDefaults } from './utils/mergeOptionalWithDefaults.js';
10
+ import { replaceAllFactory } from './utils/util.js';
11
+ const defaultLegacyMinCompoundLength = 3;
12
+ export class ITrieImpl {
13
+ constructor(data, numNodes) {
14
+ this.data = data;
15
+ this.numNodes = numNodes;
16
+ this.lastCreateFindOptionsMatchCaseMap = new Map();
17
+ this.root = data.getRoot();
18
+ this._info = mergeOptionalWithDefaults(data.info);
19
+ this.hasForbidden = data.hasForbiddenWords();
20
+ this._findOptionsDefaults = {
21
+ caseInsensitivePrefix: this._info.stripCaseAndAccentsPrefix,
22
+ compoundFix: this._info.compoundCharacter,
23
+ forbidPrefix: this._info.forbiddenWordPrefix,
24
+ };
25
+ }
26
+ /**
27
+ * Number of words in the Trie, the first call to this method might be expensive.
28
+ * Use `size` to get the number of nodes.
29
+ */
30
+ numWords() {
31
+ this.count ??= countWords(this.root);
32
+ return this.count;
33
+ }
34
+ isNumWordsKnown() {
35
+ return this.count !== undefined;
36
+ }
37
+ get size() {
38
+ return this.data.size;
39
+ }
40
+ get info() {
41
+ return this._info;
42
+ }
43
+ get isCaseAware() {
44
+ return this.info.isCaseAware ?? true;
45
+ }
46
+ /**
47
+ * @param text - text to find in the Trie
48
+ */
49
+ find(text) {
50
+ const options = this.createFindOptions({ compoundMode: 'compound' });
51
+ return findWordNode(this.data.getRoot(), text, options).node;
52
+ }
53
+ has(word, minLegacyCompoundLength) {
54
+ if (this.hasWord(word, false))
55
+ return true;
56
+ if (minLegacyCompoundLength) {
57
+ const f = this.findWord(word, { useLegacyWordCompounds: minLegacyCompoundLength });
58
+ return !!f.found;
59
+ }
60
+ return false;
61
+ }
62
+ /**
63
+ * Determine if a word is in the dictionary.
64
+ * @param word - the exact word to search for - must be normalized.
65
+ * @param caseSensitive - false means also searching a dictionary where the words were normalized to lower case and accents removed.
66
+ * @returns true if the word was found and is not forbidden.
67
+ */
68
+ hasWord(word, caseSensitive) {
69
+ const f = this.findWord(word, { caseSensitive });
70
+ return !!f.found && !f.forbidden;
71
+ }
72
+ findWord(word, options) {
73
+ if (options?.useLegacyWordCompounds) {
74
+ const len = options.useLegacyWordCompounds !== true
75
+ ? options.useLegacyWordCompounds
76
+ : defaultLegacyMinCompoundLength;
77
+ const findOptions = this.createFindOptions({
78
+ legacyMinCompoundLength: len,
79
+ matchCase: options.caseSensitive,
80
+ });
81
+ return findLegacyCompound(this.root, word, findOptions);
82
+ }
83
+ const findOptions = this.createFindOptionsMatchCase(options?.caseSensitive);
84
+ return findWord(this.root, word, findOptions);
85
+ }
86
+ /**
87
+ * Determine if a word is in the forbidden word list.
88
+ * @param word the word to lookup.
89
+ */
90
+ isForbiddenWord(word) {
91
+ return this.hasForbidden && isForbiddenWord(this.root, word, this.info.forbiddenWordPrefix);
92
+ }
93
+ /**
94
+ * Provides an ordered sequence of words with the prefix of text.
95
+ */
96
+ completeWord(text) {
97
+ const n = this.find(text);
98
+ const compoundChar = this.info.compoundCharacter;
99
+ const subNodes = pipe(n ? iteratorTrieWords(n) : [], opFilter((w) => w[w.length - 1] !== compoundChar), opMap((suffix) => text + suffix));
100
+ return pipe(n && n.eow ? [text] : [], opAppend(subNodes));
101
+ }
102
+ /**
103
+ * Suggest spellings for `text`. The results are sorted by edit distance with changes near the beginning of a word having a greater impact.
104
+ * @param text - the text to search for
105
+ * @param maxNumSuggestions - the maximum number of suggestions to return.
106
+ * @param compoundMethod - Use to control splitting words.
107
+ * @param numChanges - the maximum number of changes allowed to text. This is an approximate value, since some changes cost less than others.
108
+ * the lower the value, the faster results are returned. Values less than 4 are best.
109
+ */
110
+ suggest(text, options) {
111
+ return this.suggestWithCost(text, options).map((a) => a.word);
112
+ }
113
+ /**
114
+ * Suggest spellings for `text`. The results are sorted by edit distance with changes near the beginning of a word having a greater impact.
115
+ * The results include the word and adjusted edit cost. This is useful for merging results from multiple tries.
116
+ */
117
+ suggestWithCost(text, options) {
118
+ const sep = options.compoundSeparator;
119
+ const weightMap = options.weightMap || this.weightMap;
120
+ const adjWord = sep ? replaceAllFactory(sep, '') : (a) => a;
121
+ const optFilter = options.filter;
122
+ const filter = optFilter
123
+ ? (word, cost) => {
124
+ const w = adjWord(word);
125
+ return !this.isForbiddenWord(w) && optFilter(w, cost);
126
+ }
127
+ : (word) => !this.isForbiddenWord(adjWord(word));
128
+ const opts = { ...options, filter, weightMap };
129
+ return suggest(this.data, text, opts);
130
+ }
131
+ /**
132
+ * genSuggestions will generate suggestions and send them to `collector`. `collector` is responsible for returning the max acceptable cost.
133
+ * Costs are measured in weighted changes. A cost of 100 is the same as 1 edit. Some edits are considered cheaper.
134
+ * Returning a MaxCost < 0 will effectively cause the search for suggestions to stop.
135
+ */
136
+ genSuggestions(collector, compoundMethod) {
137
+ const filter = (word) => !this.isForbiddenWord(word);
138
+ const options = createSuggestionOptions(clean({ compoundMethod, ...collector.genSuggestionOptions }));
139
+ const suggestions = genSuggestions(this.data, collector.word, options);
140
+ collector.collect(suggestions, undefined, filter);
141
+ }
142
+ /**
143
+ * Returns an iterator that can be used to get all words in the trie. For some dictionaries, this can result in millions of words.
144
+ */
145
+ words() {
146
+ return iteratorTrieWords(this.root);
147
+ }
148
+ /**
149
+ * Allows iteration over the entire tree.
150
+ * On the returned Iterator, calling .next(goDeeper: boolean), allows for controlling the depth.
151
+ */
152
+ iterate() {
153
+ return walker(this.root);
154
+ }
155
+ static create(words, info) {
156
+ const builder = new FastTrieBlobBuilder(info);
157
+ builder.insert(words);
158
+ const root = builder.build();
159
+ return new ITrieImpl(root, undefined);
160
+ }
161
+ createFindOptions(options = {}) {
162
+ const findOptions = createFindOptions({
163
+ ...this._findOptionsDefaults,
164
+ ...options,
165
+ });
166
+ return findOptions;
167
+ }
168
+ createFindOptionsMatchCase(matchCase) {
169
+ const f = this.lastCreateFindOptionsMatchCaseMap.get(matchCase);
170
+ if (f !== undefined)
171
+ return f;
172
+ const findOptions = this.createFindOptions({ matchCase });
173
+ this.lastCreateFindOptionsMatchCaseMap.set(matchCase, findOptions);
174
+ return findOptions;
175
+ }
176
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * No compounding allowed.
3
+ */
4
+ export type CompoundModeNone = 'none';
5
+ /**
6
+ * Allow natural compounding in the dictionary
7
+ * using compound prefixes
8
+ */
9
+ export type CompoundModesCompound = 'compound';
10
+ /**
11
+ * Allow all possible compounds -- Very slow.
12
+ */
13
+ export type CompoundModesLegacy = 'legacy';
14
+ export type CompoundModes = CompoundModeNone | CompoundModesCompound | CompoundModesLegacy;
15
+ //# sourceMappingURL=CompoundModes.d.ts.map
@@ -0,0 +1,4 @@
1
+ /**
2
+ * No compounding allowed.
3
+ */
4
+ export {};
@@ -0,0 +1,12 @@
1
+ import type { PartialWithUndefined } from '../types.js';
2
+ import type { CompoundModes } from './CompoundModes.js';
3
+ export interface FindOptions {
4
+ matchCase: boolean;
5
+ compoundMode: CompoundModes;
6
+ forbidPrefix: string;
7
+ compoundFix: string;
8
+ caseInsensitivePrefix: string;
9
+ legacyMinCompoundLength: number;
10
+ }
11
+ export type PartialFindOptions = PartialWithUndefined<FindOptions> | undefined;
12
+ //# sourceMappingURL=FindOptions.d.ts.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,42 @@
1
+ import type { TrieInfo } from './TrieInfo.js';
2
+ export type ITrieNodeId = object | number | string;
3
+ type Entry = readonly [string, ITrieNode];
4
+ export interface ITrieNode {
5
+ /**
6
+ * ITrieNode instances are not unique. It is possible for multiple ITrieNode instances to
7
+ * represent the same node.
8
+ * `id` is used to see if two instances refer to the same node.
9
+ * The type is obscured because it is up the the backing structure to provide the best value.
10
+ * Note, only nodes from the same root are guaranteed to be unique. It is possible for two
11
+ * different ITrieNode instances to have the same `id` value if they come from different roots.
12
+ */
13
+ readonly id: ITrieNodeId;
14
+ /** flag End of Word */
15
+ readonly eow: boolean;
16
+ /** number of children */
17
+ readonly size: number;
18
+ /** get keys to children */
19
+ keys(): readonly string[];
20
+ /** get keys to children */
21
+ values(): readonly ITrieNode[];
22
+ /** get the children as key value pairs */
23
+ entries(): readonly Entry[];
24
+ /** get child ITrieNode */
25
+ get(char: string): ITrieNode | undefined;
26
+ /** get a child by the key index */
27
+ child(idx: number): ITrieNode;
28
+ /** has child */
29
+ has(char: string): boolean;
30
+ /** `true` iff this node has children */
31
+ hasChildren(): boolean;
32
+ }
33
+ export interface ITrieNodeRoot extends ITrieNode {
34
+ info: Readonly<TrieInfo>;
35
+ /**
36
+ * converts an `id` into a node.
37
+ * @param id an of a ITrieNode in this Trie
38
+ */
39
+ resolveId(id: ITrieNodeId): ITrieNode;
40
+ }
41
+ export {};
42
+ //# sourceMappingURL=ITrieNode.d.ts.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ import type { PartialWithUndefined } from '../types.js';
2
+ export interface TrieInfo {
3
+ compoundCharacter: string;
4
+ stripCaseAndAccentsPrefix: string;
5
+ forbiddenWordPrefix: string;
6
+ isCaseAware: boolean;
7
+ }
8
+ export type PartialTrieInfo = PartialWithUndefined<TrieInfo> | undefined;
9
+ //# sourceMappingURL=TrieInfo.d.ts.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,48 @@
1
+ import type { FindOptions, PartialFindOptions } from './FindOptions.js';
2
+ import type { ITrieNode, ITrieNodeRoot } from './ITrieNode.js';
3
+ type Root = ITrieNodeRoot;
4
+ export interface FindNodeResult {
5
+ node: ITrieNode | undefined;
6
+ }
7
+ export interface FindResult {
8
+ found: string | false;
9
+ compoundUsed: boolean;
10
+ caseMatched: boolean;
11
+ }
12
+ export interface FindFullResult extends FindResult {
13
+ /**
14
+ * Is the word explicitly forbidden.
15
+ * - `true` - word is in the forbidden list.
16
+ * - `false` - word is not in the forbidden list.
17
+ * - `undefined` - unknown - was not checked.
18
+ * */
19
+ forbidden: boolean | undefined;
20
+ }
21
+ export interface FindFullNodeResult extends FindNodeResult, FindFullResult {
22
+ }
23
+ /**
24
+ *
25
+ * @param root Trie root node. root.c contains the compound root and forbidden root.
26
+ * @param word A pre normalized word use `normalizeWord` or `normalizeWordToLowercase`
27
+ * @param options
28
+ */
29
+ export declare function findWord(root: Root, word: string, options?: PartialFindOptions): FindFullResult;
30
+ /**
31
+ *
32
+ * @param root Trie root node. root.c contains the compound root and forbidden root.
33
+ * @param word A pre normalized word use `normalizeWord` or `normalizeWordToLowercase`
34
+ * @param options
35
+ */
36
+ export declare function findWordNode(root: Root, word: string, options?: PartialFindOptions): FindFullNodeResult;
37
+ export declare function findLegacyCompound(root: Root, word: string, options: FindOptions): FindFullNodeResult;
38
+ export declare function findCompoundNode(root: Root | undefined, word: string, compoundCharacter: string, ignoreCasePrefix: string): FindFullNodeResult;
39
+ export declare function findWordExact(root: Root | ITrieNode | undefined, word: string): boolean;
40
+ export declare function isEndOfWordNode(n: ITrieNode | undefined): boolean;
41
+ declare function findLegacyCompoundWord(roots: (ITrieNode | undefined)[], word: string, minCompoundLength: number): FindResult;
42
+ export declare function isForbiddenWord(root: Root | ITrieNode | undefined, word: string, forbiddenPrefix: string): boolean;
43
+ export declare const createFindOptions: (p: PartialFindOptions) => FindOptions;
44
+ export declare const __testing__: {
45
+ findLegacyCompoundWord: typeof findLegacyCompoundWord;
46
+ };
47
+ export {};
48
+ //# sourceMappingURL=find.d.ts.map