cspell-dictionary 6.29.2 → 6.30.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.
@@ -1,5 +1,5 @@
1
1
  import type { CacheStats } from '../util/AutoCache.js';
2
- import type { SearchOptions, SpellingDictionary } from './SpellingDictionary.js';
2
+ import type { PreferredSuggestion, SearchOptions, SpellingDictionary } from './SpellingDictionary.js';
3
3
  import type { SpellingDictionaryCollection } from './SpellingDictionaryCollection.js';
4
4
  interface CallStats {
5
5
  name: string;
@@ -7,6 +7,7 @@ interface CallStats {
7
7
  has: CacheStats;
8
8
  isNoSuggestWord: CacheStats;
9
9
  isForbidden: CacheStats;
10
+ getPreferredSuggestions: CacheStats;
10
11
  }
11
12
  /**
12
13
  * Caching Dictionary remembers method calls to increase performance.
@@ -18,6 +19,7 @@ export interface CachingDictionary {
18
19
  isNoSuggestWord(word: string): boolean;
19
20
  isForbidden(word: string): boolean;
20
21
  stats(): CallStats;
22
+ getPreferredSuggestions(word: string): PreferredSuggestion[] | undefined;
21
23
  }
22
24
  /**
23
25
  * create a caching dictionary
@@ -4,14 +4,16 @@ exports.createCachingDictionary = void 0;
4
4
  const AutoCache_js_1 = require("../util/AutoCache.js");
5
5
  const SpellingDictionaryMethods_js_1 = require("./SpellingDictionaryMethods.js");
6
6
  let dictionaryCounter = 0;
7
+ const DefaultAutoCacheSize = 1000;
7
8
  class CachedDict {
8
9
  constructor(dict, options) {
9
10
  this.dict = dict;
10
11
  this.options = options;
11
12
  this.id = ++dictionaryCounter;
12
- this.has = (0, AutoCache_js_1.autoCache)((word) => this.dict.has(word, this.options));
13
- this.isNoSuggestWord = (0, AutoCache_js_1.autoCache)((word) => this.dict.isNoSuggestWord(word, this.options));
14
- this.isForbidden = (0, AutoCache_js_1.autoCache)((word) => this.dict.isForbidden(word));
13
+ this.has = (0, AutoCache_js_1.autoCache)((word) => this.dict.has(word, this.options), DefaultAutoCacheSize);
14
+ this.isNoSuggestWord = (0, AutoCache_js_1.autoCache)((word) => this.dict.isNoSuggestWord(word, this.options), DefaultAutoCacheSize);
15
+ this.isForbidden = (0, AutoCache_js_1.autoCache)((word) => this.dict.isForbidden(word), DefaultAutoCacheSize);
16
+ this.getPreferredSuggestions = (0, AutoCache_js_1.autoCache)((word) => this.dict.getPreferredSuggestions?.(word), DefaultAutoCacheSize);
15
17
  this.name = dict.name;
16
18
  // console.log(`CachedDict for ${this.name}`);
17
19
  }
@@ -22,6 +24,7 @@ class CachedDict {
22
24
  has: (0, AutoCache_js_1.extractStats)(this.has),
23
25
  isNoSuggestWord: (0, AutoCache_js_1.extractStats)(this.isNoSuggestWord),
24
26
  isForbidden: (0, AutoCache_js_1.extractStats)(this.isForbidden),
27
+ getPreferredSuggestions: (0, AutoCache_js_1.extractStats)(this.getPreferredSuggestions),
25
28
  };
26
29
  }
27
30
  }
@@ -107,6 +107,9 @@ class FlagWordsDictionary {
107
107
  const suggestOptions = (0, SpellingDictionaryMethods_js_1.suggestArgsToSuggestOptions)(args);
108
108
  return this.dictTypos.suggest(word, suggestOptions);
109
109
  }
110
+ getPreferredSuggestions(word) {
111
+ return this.dictTypos.getPreferredSuggestions(word);
112
+ }
110
113
  genSuggestions() {
111
114
  return;
112
115
  }
@@ -45,6 +45,13 @@ export interface SuggestOptions {
45
45
  timeout?: number | undefined;
46
46
  }
47
47
  export type FindOptions = SearchOptions;
48
+ export interface Suggestion {
49
+ word: string;
50
+ isPreferred?: boolean | undefined;
51
+ }
52
+ export interface PreferredSuggestion extends Suggestion {
53
+ isPreferred: true;
54
+ }
48
55
  export interface FindResult {
49
56
  /** the text found, otherwise `false` */
50
57
  found: string | false;
@@ -132,6 +139,7 @@ export interface SpellingDictionary extends DictionaryInfo {
132
139
  * @param suggestOptions - options
133
140
  */
134
141
  suggest(word: string, suggestOptions: SuggestOptions): SuggestionResult[];
142
+ getPreferredSuggestions?: (word: string) => PreferredSuggestion[];
135
143
  genSuggestions(collector: SuggestionCollector, suggestOptions: SuggestOptions): void;
136
144
  mapWord(word: string): string;
137
145
  /**
@@ -88,11 +88,23 @@ class SpellingDictionaryCollectionImpl {
88
88
  };
89
89
  const collector = (0, SpellingDictionaryMethods_js_1.suggestionCollector)(word, collectorOptions);
90
90
  this.genSuggestions(collector, suggestOptions);
91
- return collector.suggestions.map((r) => ({ ...r, word: r.word }));
91
+ return collector.suggestions;
92
92
  }
93
93
  get size() {
94
94
  return this.dictionaries.reduce((a, b) => a + b.size, 0);
95
95
  }
96
+ getPreferredSuggestions(word) {
97
+ const sugs = this.dictionaries.flatMap((dict) => dict.getPreferredSuggestions?.(word)).filter(util_js_1.isDefined);
98
+ if (sugs.length <= 1)
99
+ return sugs;
100
+ const unique = new Set();
101
+ return sugs.filter((sug) => {
102
+ if (unique.has(sug.word))
103
+ return false;
104
+ unique.add(sug.word);
105
+ return true;
106
+ });
107
+ }
96
108
  genSuggestions(collector, suggestOptions) {
97
109
  const _suggestOptions = { ...suggestOptions };
98
110
  const { compoundMethod = SpellingDictionary_js_1.CompoundWordsMethod.SEPARATE_WORDS } = suggestOptions;
@@ -1,6 +1,7 @@
1
- import type { IgnoreCaseOption, SpellingDictionary } from './SpellingDictionary.js';
1
+ import type { IgnoreCaseOption, PreferredSuggestion, SpellingDictionary } from './SpellingDictionary.js';
2
2
  import { type TypoEntry, type TyposDef } from './Typos/index.js';
3
3
  export interface SuggestDictionary extends SpellingDictionary {
4
+ getPreferredSuggestions: (word: string) => PreferredSuggestion[];
4
5
  /**
5
6
  * Determine if the word can appear in a list of suggestions.
6
7
  * @param word - word
@@ -76,7 +76,7 @@ class SuggestDictionaryImpl {
76
76
  return ignoreCaseAndAccents && (this.suggestions.has(lcWord) || this.suggestionsLower.has(lcWord));
77
77
  }
78
78
  suggest(word) {
79
- return this._suggest(word) || this._suggest(word.toLowerCase()) || [];
79
+ return this.getPreferredSuggestions(word);
80
80
  }
81
81
  _suggest(word) {
82
82
  if (!(word in this.typosDef))
@@ -96,6 +96,9 @@ class SuggestDictionaryImpl {
96
96
  }
97
97
  return sug.map((word, index) => ({ word, cost: index + 1, isPreferred }));
98
98
  }
99
+ getPreferredSuggestions(word) {
100
+ return this._suggest(word) || this._suggest(word.toLowerCase()) || [];
101
+ }
99
102
  genSuggestions(collector) {
100
103
  const sugs = this.suggest(collector.word);
101
104
  sugs.forEach((result) => collector.add(result));
@@ -1,6 +1,7 @@
1
- import type { IgnoreCaseOption, SpellingDictionary } from './SpellingDictionary.js';
1
+ import type { IgnoreCaseOption, PreferredSuggestion, SpellingDictionary } from './SpellingDictionary.js';
2
2
  import { type TypoEntry, type TyposDef } from './Typos/index.js';
3
3
  export interface TyposDictionary extends SpellingDictionary {
4
+ getPreferredSuggestions: (word: string) => PreferredSuggestion[];
4
5
  isForbidden(word: string, ignoreCaseAndAccents?: IgnoreCaseOption): boolean;
5
6
  /**
6
7
  * Determine if the word can appear in a list of suggestions.
@@ -106,7 +106,7 @@ class TyposDictionaryImpl {
106
106
  return ignoreCaseAndAccents && (this.suggestions.has(lcWord) || this.suggestionsLower.has(lcWord));
107
107
  }
108
108
  suggest(word) {
109
- return this._suggest(word) || this._suggest(word.toLowerCase()) || [];
109
+ return this.getPreferredSuggestions(word);
110
110
  }
111
111
  _suggest(word) {
112
112
  if (this.ignoreWords.has(word))
@@ -132,6 +132,9 @@ class TyposDictionaryImpl {
132
132
  const sugs = this.suggest(collector.word);
133
133
  sugs.forEach((result) => collector.add(result));
134
134
  }
135
+ getPreferredSuggestions(word) {
136
+ return this._suggest(word) || this._suggest(word.toLowerCase()) || [];
137
+ }
135
138
  mapWord(word) {
136
139
  return word;
137
140
  }
@@ -1,5 +1,5 @@
1
1
  import type { CacheStats } from '../util/AutoCache.mjs';
2
- import type { SearchOptions, SpellingDictionary } from './SpellingDictionary.mjs';
2
+ import type { PreferredSuggestion, SearchOptions, SpellingDictionary } from './SpellingDictionary.mjs';
3
3
  import type { SpellingDictionaryCollection } from './SpellingDictionaryCollection.mjs';
4
4
  interface CallStats {
5
5
  name: string;
@@ -7,6 +7,7 @@ interface CallStats {
7
7
  has: CacheStats;
8
8
  isNoSuggestWord: CacheStats;
9
9
  isForbidden: CacheStats;
10
+ getPreferredSuggestions: CacheStats;
10
11
  }
11
12
  /**
12
13
  * Caching Dictionary remembers method calls to increase performance.
@@ -18,6 +19,7 @@ export interface CachingDictionary {
18
19
  isNoSuggestWord(word: string): boolean;
19
20
  isForbidden(word: string): boolean;
20
21
  stats(): CallStats;
22
+ getPreferredSuggestions(word: string): PreferredSuggestion[] | undefined;
21
23
  }
22
24
  /**
23
25
  * create a caching dictionary
@@ -1,14 +1,16 @@
1
1
  import { autoCache, extractStats } from '../util/AutoCache.mjs';
2
2
  import { canonicalSearchOptions } from './SpellingDictionaryMethods.mjs';
3
3
  let dictionaryCounter = 0;
4
+ const DefaultAutoCacheSize = 1000;
4
5
  class CachedDict {
5
6
  constructor(dict, options) {
6
7
  this.dict = dict;
7
8
  this.options = options;
8
9
  this.id = ++dictionaryCounter;
9
- this.has = autoCache((word) => this.dict.has(word, this.options));
10
- this.isNoSuggestWord = autoCache((word) => this.dict.isNoSuggestWord(word, this.options));
11
- this.isForbidden = autoCache((word) => this.dict.isForbidden(word));
10
+ this.has = autoCache((word) => this.dict.has(word, this.options), DefaultAutoCacheSize);
11
+ this.isNoSuggestWord = autoCache((word) => this.dict.isNoSuggestWord(word, this.options), DefaultAutoCacheSize);
12
+ this.isForbidden = autoCache((word) => this.dict.isForbidden(word), DefaultAutoCacheSize);
13
+ this.getPreferredSuggestions = autoCache((word) => this.dict.getPreferredSuggestions?.(word), DefaultAutoCacheSize);
12
14
  this.name = dict.name;
13
15
  // console.log(`CachedDict for ${this.name}`);
14
16
  }
@@ -19,6 +21,7 @@ class CachedDict {
19
21
  has: extractStats(this.has),
20
22
  isNoSuggestWord: extractStats(this.isNoSuggestWord),
21
23
  isForbidden: extractStats(this.isForbidden),
24
+ getPreferredSuggestions: extractStats(this.getPreferredSuggestions),
22
25
  };
23
26
  }
24
27
  }
@@ -81,6 +81,9 @@ class FlagWordsDictionary {
81
81
  const suggestOptions = suggestArgsToSuggestOptions(args);
82
82
  return this.dictTypos.suggest(word, suggestOptions);
83
83
  }
84
+ getPreferredSuggestions(word) {
85
+ return this.dictTypos.getPreferredSuggestions(word);
86
+ }
84
87
  genSuggestions() {
85
88
  return;
86
89
  }
@@ -45,6 +45,13 @@ export interface SuggestOptions {
45
45
  timeout?: number | undefined;
46
46
  }
47
47
  export type FindOptions = SearchOptions;
48
+ export interface Suggestion {
49
+ word: string;
50
+ isPreferred?: boolean | undefined;
51
+ }
52
+ export interface PreferredSuggestion extends Suggestion {
53
+ isPreferred: true;
54
+ }
48
55
  export interface FindResult {
49
56
  /** the text found, otherwise `false` */
50
57
  found: string | false;
@@ -132,6 +139,7 @@ export interface SpellingDictionary extends DictionaryInfo {
132
139
  * @param suggestOptions - options
133
140
  */
134
141
  suggest(word: string, suggestOptions: SuggestOptions): SuggestionResult[];
142
+ getPreferredSuggestions?: (word: string) => PreferredSuggestion[];
135
143
  genSuggestions(collector: SuggestionCollector, suggestOptions: SuggestOptions): void;
136
144
  mapWord(word: string): string;
137
145
  /**
@@ -62,11 +62,23 @@ class SpellingDictionaryCollectionImpl {
62
62
  };
63
63
  const collector = suggestionCollector(word, collectorOptions);
64
64
  this.genSuggestions(collector, suggestOptions);
65
- return collector.suggestions.map((r) => ({ ...r, word: r.word }));
65
+ return collector.suggestions;
66
66
  }
67
67
  get size() {
68
68
  return this.dictionaries.reduce((a, b) => a + b.size, 0);
69
69
  }
70
+ getPreferredSuggestions(word) {
71
+ const sugs = this.dictionaries.flatMap((dict) => dict.getPreferredSuggestions?.(word)).filter(isDefined);
72
+ if (sugs.length <= 1)
73
+ return sugs;
74
+ const unique = new Set();
75
+ return sugs.filter((sug) => {
76
+ if (unique.has(sug.word))
77
+ return false;
78
+ unique.add(sug.word);
79
+ return true;
80
+ });
81
+ }
70
82
  genSuggestions(collector, suggestOptions) {
71
83
  const _suggestOptions = { ...suggestOptions };
72
84
  const { compoundMethod = CompoundWordsMethod.SEPARATE_WORDS } = suggestOptions;
@@ -1,6 +1,7 @@
1
- import type { IgnoreCaseOption, SpellingDictionary } from './SpellingDictionary.mjs';
1
+ import type { IgnoreCaseOption, PreferredSuggestion, SpellingDictionary } from './SpellingDictionary.mjs';
2
2
  import { type TypoEntry, type TyposDef } from './Typos/index.mjs';
3
3
  export interface SuggestDictionary extends SpellingDictionary {
4
+ getPreferredSuggestions: (word: string) => PreferredSuggestion[];
4
5
  /**
5
6
  * Determine if the word can appear in a list of suggestions.
6
7
  * @param word - word
@@ -50,7 +50,7 @@ class SuggestDictionaryImpl {
50
50
  return ignoreCaseAndAccents && (this.suggestions.has(lcWord) || this.suggestionsLower.has(lcWord));
51
51
  }
52
52
  suggest(word) {
53
- return this._suggest(word) || this._suggest(word.toLowerCase()) || [];
53
+ return this.getPreferredSuggestions(word);
54
54
  }
55
55
  _suggest(word) {
56
56
  if (!(word in this.typosDef))
@@ -70,6 +70,9 @@ class SuggestDictionaryImpl {
70
70
  }
71
71
  return sug.map((word, index) => ({ word, cost: index + 1, isPreferred }));
72
72
  }
73
+ getPreferredSuggestions(word) {
74
+ return this._suggest(word) || this._suggest(word.toLowerCase()) || [];
75
+ }
73
76
  genSuggestions(collector) {
74
77
  const sugs = this.suggest(collector.word);
75
78
  sugs.forEach((result) => collector.add(result));
@@ -1,6 +1,7 @@
1
- import type { IgnoreCaseOption, SpellingDictionary } from './SpellingDictionary.mjs';
1
+ import type { IgnoreCaseOption, PreferredSuggestion, SpellingDictionary } from './SpellingDictionary.mjs';
2
2
  import { type TypoEntry, type TyposDef } from './Typos/index.mjs';
3
3
  export interface TyposDictionary extends SpellingDictionary {
4
+ getPreferredSuggestions: (word: string) => PreferredSuggestion[];
4
5
  isForbidden(word: string, ignoreCaseAndAccents?: IgnoreCaseOption): boolean;
5
6
  /**
6
7
  * Determine if the word can appear in a list of suggestions.
@@ -80,7 +80,7 @@ class TyposDictionaryImpl {
80
80
  return ignoreCaseAndAccents && (this.suggestions.has(lcWord) || this.suggestionsLower.has(lcWord));
81
81
  }
82
82
  suggest(word) {
83
- return this._suggest(word) || this._suggest(word.toLowerCase()) || [];
83
+ return this.getPreferredSuggestions(word);
84
84
  }
85
85
  _suggest(word) {
86
86
  if (this.ignoreWords.has(word))
@@ -106,6 +106,9 @@ class TyposDictionaryImpl {
106
106
  const sugs = this.suggest(collector.word);
107
107
  sugs.forEach((result) => collector.add(result));
108
108
  }
109
+ getPreferredSuggestions(word) {
110
+ return this._suggest(word) || this._suggest(word.toLowerCase()) || [];
111
+ }
109
112
  mapWord(word) {
110
113
  return word;
111
114
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cspell-dictionary",
3
- "version": "6.29.2",
3
+ "version": "6.30.0",
4
4
  "description": "A spelling dictionary library useful for checking words and getting suggestions.",
5
5
  "type": "commonjs",
6
6
  "main": "dist/cjs/index.js",
@@ -52,11 +52,11 @@
52
52
  "node": ">=14"
53
53
  },
54
54
  "dependencies": {
55
- "@cspell/cspell-pipe": "6.29.2",
56
- "@cspell/cspell-types": "6.29.2",
57
- "cspell-trie-lib": "6.29.2",
55
+ "@cspell/cspell-pipe": "6.30.0",
56
+ "@cspell/cspell-types": "6.30.0",
57
+ "cspell-trie-lib": "6.30.0",
58
58
  "fast-equals": "^4.0.3",
59
59
  "gensequence": "^5.0.2"
60
60
  },
61
- "gitHead": "fae497508ec03795dfe0e0b70ea80cdf3d7be5a5"
61
+ "gitHead": "9af8c211fdeeb58e2d7a2be0e72405a23fe954cc"
62
62
  }