cmpstr 3.2.1 → 3.2.2

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 (150) hide show
  1. package/README.md +24 -18
  2. package/dist/CmpStr.esm.js +485 -220
  3. package/dist/CmpStr.esm.min.js +2 -3
  4. package/dist/CmpStr.umd.js +484 -220
  5. package/dist/CmpStr.umd.min.js +2 -3
  6. package/dist/cjs/CmpStr.cjs +57 -36
  7. package/dist/cjs/CmpStrAsync.cjs +30 -24
  8. package/dist/cjs/index.cjs +1 -2
  9. package/dist/cjs/metric/Cosine.cjs +1 -2
  10. package/dist/cjs/metric/DamerauLevenshtein.cjs +1 -2
  11. package/dist/cjs/metric/DiceSorensen.cjs +1 -2
  12. package/dist/cjs/metric/Hamming.cjs +5 -4
  13. package/dist/cjs/metric/Jaccard.cjs +1 -2
  14. package/dist/cjs/metric/JaroWinkler.cjs +1 -2
  15. package/dist/cjs/metric/LCS.cjs +1 -2
  16. package/dist/cjs/metric/Levenshtein.cjs +1 -2
  17. package/dist/cjs/metric/Metric.cjs +57 -38
  18. package/dist/cjs/metric/NeedlemanWunsch.cjs +1 -2
  19. package/dist/cjs/metric/QGram.cjs +1 -2
  20. package/dist/cjs/metric/SmithWaterman.cjs +1 -2
  21. package/dist/cjs/phonetic/Caverphone.cjs +1 -2
  22. package/dist/cjs/phonetic/Cologne.cjs +1 -2
  23. package/dist/cjs/phonetic/Metaphone.cjs +1 -2
  24. package/dist/cjs/phonetic/Phonetic.cjs +55 -35
  25. package/dist/cjs/phonetic/Soundex.cjs +1 -2
  26. package/dist/cjs/root.cjs +3 -2
  27. package/dist/cjs/utils/DeepMerge.cjs +10 -5
  28. package/dist/cjs/utils/DiffChecker.cjs +1 -2
  29. package/dist/cjs/utils/Errors.cjs +103 -0
  30. package/dist/cjs/utils/Filter.cjs +52 -27
  31. package/dist/cjs/utils/HashTable.cjs +1 -2
  32. package/dist/cjs/utils/Normalizer.cjs +54 -34
  33. package/dist/cjs/utils/Pool.cjs +42 -18
  34. package/dist/cjs/utils/Profiler.cjs +1 -2
  35. package/dist/cjs/utils/Registry.cjs +46 -22
  36. package/dist/cjs/utils/StructuredData.cjs +13 -5
  37. package/dist/cjs/utils/TextAnalyzer.cjs +1 -2
  38. package/dist/esm/CmpStr.mjs +55 -32
  39. package/dist/esm/CmpStrAsync.mjs +26 -20
  40. package/dist/esm/index.mjs +1 -2
  41. package/dist/esm/metric/Cosine.mjs +1 -2
  42. package/dist/esm/metric/DamerauLevenshtein.mjs +1 -2
  43. package/dist/esm/metric/DiceSorensen.mjs +1 -2
  44. package/dist/esm/metric/Hamming.mjs +5 -4
  45. package/dist/esm/metric/Jaccard.mjs +1 -2
  46. package/dist/esm/metric/JaroWinkler.mjs +1 -2
  47. package/dist/esm/metric/LCS.mjs +1 -2
  48. package/dist/esm/metric/Levenshtein.mjs +1 -2
  49. package/dist/esm/metric/Metric.mjs +59 -38
  50. package/dist/esm/metric/NeedlemanWunsch.mjs +1 -2
  51. package/dist/esm/metric/QGram.mjs +1 -2
  52. package/dist/esm/metric/SmithWaterman.mjs +1 -2
  53. package/dist/esm/phonetic/Caverphone.mjs +1 -2
  54. package/dist/esm/phonetic/Cologne.mjs +1 -2
  55. package/dist/esm/phonetic/Metaphone.mjs +1 -2
  56. package/dist/esm/phonetic/Phonetic.mjs +55 -35
  57. package/dist/esm/phonetic/Soundex.mjs +1 -2
  58. package/dist/esm/root.mjs +3 -2
  59. package/dist/esm/utils/DeepMerge.mjs +10 -5
  60. package/dist/esm/utils/DiffChecker.mjs +1 -2
  61. package/dist/esm/utils/Errors.mjs +103 -0
  62. package/dist/esm/utils/Filter.mjs +52 -27
  63. package/dist/esm/utils/HashTable.mjs +1 -2
  64. package/dist/esm/utils/Normalizer.mjs +54 -34
  65. package/dist/esm/utils/Pool.mjs +38 -18
  66. package/dist/esm/utils/Profiler.mjs +1 -2
  67. package/dist/esm/utils/Registry.mjs +46 -22
  68. package/dist/esm/utils/StructuredData.mjs +13 -5
  69. package/dist/esm/utils/TextAnalyzer.mjs +1 -2
  70. package/dist/types/CmpStr.d.ts +5 -1
  71. package/dist/types/CmpStrAsync.d.ts +1 -0
  72. package/dist/types/index.d.ts +3 -2
  73. package/dist/types/metric/Metric.d.ts +6 -5
  74. package/dist/types/phonetic/Phonetic.d.ts +3 -1
  75. package/dist/types/root.d.ts +2 -1
  76. package/dist/types/utils/DeepMerge.d.ts +1 -1
  77. package/dist/types/utils/Errors.d.ts +137 -0
  78. package/dist/types/utils/Filter.d.ts +4 -0
  79. package/dist/types/utils/Normalizer.d.ts +3 -0
  80. package/dist/types/utils/Pool.d.ts +2 -0
  81. package/dist/types/utils/Registry.d.ts +3 -3
  82. package/dist/types/utils/StructuredData.d.ts +3 -1
  83. package/dist/types/utils/Types.d.ts +26 -0
  84. package/package.json +7 -7
  85. package/dist/CmpStr.esm.js.map +0 -1
  86. package/dist/CmpStr.esm.min.js.map +0 -1
  87. package/dist/CmpStr.umd.js.map +0 -1
  88. package/dist/CmpStr.umd.min.js.map +0 -1
  89. package/dist/cjs/CmpStr.cjs.map +0 -1
  90. package/dist/cjs/CmpStrAsync.cjs.map +0 -1
  91. package/dist/cjs/index.cjs.map +0 -1
  92. package/dist/cjs/metric/Cosine.cjs.map +0 -1
  93. package/dist/cjs/metric/DamerauLevenshtein.cjs.map +0 -1
  94. package/dist/cjs/metric/DiceSorensen.cjs.map +0 -1
  95. package/dist/cjs/metric/Hamming.cjs.map +0 -1
  96. package/dist/cjs/metric/Jaccard.cjs.map +0 -1
  97. package/dist/cjs/metric/JaroWinkler.cjs.map +0 -1
  98. package/dist/cjs/metric/LCS.cjs.map +0 -1
  99. package/dist/cjs/metric/Levenshtein.cjs.map +0 -1
  100. package/dist/cjs/metric/Metric.cjs.map +0 -1
  101. package/dist/cjs/metric/NeedlemanWunsch.cjs.map +0 -1
  102. package/dist/cjs/metric/QGram.cjs.map +0 -1
  103. package/dist/cjs/metric/SmithWaterman.cjs.map +0 -1
  104. package/dist/cjs/phonetic/Caverphone.cjs.map +0 -1
  105. package/dist/cjs/phonetic/Cologne.cjs.map +0 -1
  106. package/dist/cjs/phonetic/Metaphone.cjs.map +0 -1
  107. package/dist/cjs/phonetic/Phonetic.cjs.map +0 -1
  108. package/dist/cjs/phonetic/Soundex.cjs.map +0 -1
  109. package/dist/cjs/root.cjs.map +0 -1
  110. package/dist/cjs/utils/DeepMerge.cjs.map +0 -1
  111. package/dist/cjs/utils/DiffChecker.cjs.map +0 -1
  112. package/dist/cjs/utils/Filter.cjs.map +0 -1
  113. package/dist/cjs/utils/HashTable.cjs.map +0 -1
  114. package/dist/cjs/utils/Normalizer.cjs.map +0 -1
  115. package/dist/cjs/utils/Pool.cjs.map +0 -1
  116. package/dist/cjs/utils/Profiler.cjs.map +0 -1
  117. package/dist/cjs/utils/Registry.cjs.map +0 -1
  118. package/dist/cjs/utils/StructuredData.cjs.map +0 -1
  119. package/dist/cjs/utils/TextAnalyzer.cjs.map +0 -1
  120. package/dist/esm/CmpStr.mjs.map +0 -1
  121. package/dist/esm/CmpStrAsync.mjs.map +0 -1
  122. package/dist/esm/index.mjs.map +0 -1
  123. package/dist/esm/metric/Cosine.mjs.map +0 -1
  124. package/dist/esm/metric/DamerauLevenshtein.mjs.map +0 -1
  125. package/dist/esm/metric/DiceSorensen.mjs.map +0 -1
  126. package/dist/esm/metric/Hamming.mjs.map +0 -1
  127. package/dist/esm/metric/Jaccard.mjs.map +0 -1
  128. package/dist/esm/metric/JaroWinkler.mjs.map +0 -1
  129. package/dist/esm/metric/LCS.mjs.map +0 -1
  130. package/dist/esm/metric/Levenshtein.mjs.map +0 -1
  131. package/dist/esm/metric/Metric.mjs.map +0 -1
  132. package/dist/esm/metric/NeedlemanWunsch.mjs.map +0 -1
  133. package/dist/esm/metric/QGram.mjs.map +0 -1
  134. package/dist/esm/metric/SmithWaterman.mjs.map +0 -1
  135. package/dist/esm/phonetic/Caverphone.mjs.map +0 -1
  136. package/dist/esm/phonetic/Cologne.mjs.map +0 -1
  137. package/dist/esm/phonetic/Metaphone.mjs.map +0 -1
  138. package/dist/esm/phonetic/Phonetic.mjs.map +0 -1
  139. package/dist/esm/phonetic/Soundex.mjs.map +0 -1
  140. package/dist/esm/root.mjs.map +0 -1
  141. package/dist/esm/utils/DeepMerge.mjs.map +0 -1
  142. package/dist/esm/utils/DiffChecker.mjs.map +0 -1
  143. package/dist/esm/utils/Filter.mjs.map +0 -1
  144. package/dist/esm/utils/HashTable.mjs.map +0 -1
  145. package/dist/esm/utils/Normalizer.mjs.map +0 -1
  146. package/dist/esm/utils/Pool.mjs.map +0 -1
  147. package/dist/esm/utils/Profiler.mjs.map +0 -1
  148. package/dist/esm/utils/Registry.mjs.map +0 -1
  149. package/dist/esm/utils/StructuredData.mjs.map +0 -1
  150. package/dist/esm/utils/TextAnalyzer.mjs.map +0 -1
@@ -1,4 +1,4 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.2.2 build-bb61120-260311 by Paul Köhler @komed3 / MIT License
2
2
  import { Pool } from '../utils/Pool.mjs';
3
3
  import { MetricRegistry, Metric } from './Metric.mjs';
4
4
 
@@ -34,4 +34,3 @@ class LCSMetric extends Metric {
34
34
  MetricRegistry.add('lcs', LCSMetric);
35
35
 
36
36
  export { LCSMetric };
37
- //# sourceMappingURL=LCS.mjs.map
@@ -1,4 +1,4 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.2.2 build-bb61120-260311 by Paul Köhler @komed3 / MIT License
2
2
  import { Pool } from '../utils/Pool.mjs';
3
3
  import { MetricRegistry, Metric } from './Metric.mjs';
4
4
 
@@ -34,4 +34,3 @@ class LevenshteinDistance extends Metric {
34
34
  MetricRegistry.add('levenshtein', LevenshteinDistance);
35
35
 
36
36
  export { LevenshteinDistance };
37
- //# sourceMappingURL=Levenshtein.mjs.map
@@ -1,4 +1,9 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.2.2 build-bb61120-260311 by Paul Köhler @komed3 / MIT License
2
+ import {
3
+ ErrorUtil,
4
+ CmpStrInternalError,
5
+ CmpStrUsageError
6
+ } from '../utils/Errors.mjs';
2
7
  import { HashTable, Hasher } from '../utils/HashTable.mjs';
3
8
  import { Profiler } from '../utils/Profiler.mjs';
4
9
  import { Registry } from '../utils/Registry.mjs';
@@ -22,8 +27,11 @@ class Metric {
22
27
  this.metric = metric;
23
28
  this.a = Array.isArray(a) ? a : [a];
24
29
  this.b = Array.isArray(b) ? b : [b];
25
- if (this.a.length === 0 || this.b.length === 0)
26
- throw new Error(`Inputs <a> and <b> must not be empty`);
30
+ ErrorUtil.assert(
31
+ this.a.length > 0 && this.b.length > 0,
32
+ `Inputs <a> and <b> must not be empty`,
33
+ { a: this.a, b: this.b }
34
+ );
27
35
  this.options = opt;
28
36
  this.optKey = Hasher.fastFNV1a(
29
37
  JSON.stringify(opt, Object.keys(opt).sort())
@@ -36,37 +44,46 @@ class Metric {
36
44
  return undefined;
37
45
  }
38
46
  compute(a, b, m, n, maxLen) {
39
- throw new Error(`Method compute() must be overridden in a subclass`);
47
+ throw new CmpStrInternalError(
48
+ `Method compute() must be overridden in a subclass`
49
+ );
40
50
  }
41
51
  runSingle(i, j) {
42
- let a = String(this.a[i]),
43
- A = a;
44
- let b = String(this.b[j]),
45
- B = b;
46
- let m = A.length,
47
- n = B.length;
48
- let result = this.preCompute(A, B, m, n);
49
- if (!result) {
50
- result = profiler.run(() => {
51
- if (this.symmetric) [A, B, m, n] = Metric.swap(A, B, m, n);
52
- const key =
53
- Metric.cache.key(this.metric, [A, B], this.symmetric) + this.optKey;
54
- return (
55
- Metric.cache.get(key || '') ??
56
- (() => {
57
- const res = this.compute(A, B, m, n, Math.max(m, n));
58
- if (key) Metric.cache.set(key, res);
59
- return res;
60
- })()
61
- );
62
- });
63
- }
64
- return {
65
- metric: this.metric,
66
- a: this.origA[i] ?? a,
67
- b: this.origB[j] ?? b,
68
- ...result
69
- };
52
+ return ErrorUtil.wrap(
53
+ () => {
54
+ let a = String(this.a[i]),
55
+ A = a;
56
+ let b = String(this.b[j]),
57
+ B = b;
58
+ let m = A.length,
59
+ n = B.length;
60
+ let result = this.preCompute(A, B, m, n);
61
+ if (!result) {
62
+ result = profiler.run(() => {
63
+ if (this.symmetric) [A, B, m, n] = Metric.swap(A, B, m, n);
64
+ const key =
65
+ Metric.cache.key(this.metric, [A, B], this.symmetric) +
66
+ this.optKey;
67
+ return (
68
+ Metric.cache.get(key || '') ??
69
+ (() => {
70
+ const res = this.compute(A, B, m, n, Math.max(m, n));
71
+ if (key) Metric.cache.set(key, res);
72
+ return res;
73
+ })()
74
+ );
75
+ });
76
+ }
77
+ return {
78
+ metric: this.metric,
79
+ a: this.origA[i] ?? a,
80
+ b: this.origB[j] ?? b,
81
+ ...result
82
+ };
83
+ },
84
+ `Failed to compute metric for inputs at indices a[${i}] and b[${j}]`,
85
+ { i, j }
86
+ );
70
87
  }
71
88
  async runSingleAsync(i, j) {
72
89
  return Promise.resolve(this.runSingle(i, j));
@@ -108,7 +125,10 @@ class Metric {
108
125
  ? true
109
126
  : !safe &&
110
127
  (() => {
111
- throw new Error(`Mode <pairwise> requires arrays of equal length`);
128
+ throw new CmpStrUsageError(
129
+ `Mode <pairwise> requires arrays of equal length`,
130
+ { a: this.a, b: this.b }
131
+ );
112
132
  })();
113
133
  }
114
134
  isSymmetrical = () => this.symmetric;
@@ -132,7 +152,7 @@ class Metric {
132
152
  if (this.isPairwise()) this.runPairwise();
133
153
  break;
134
154
  default:
135
- throw new Error(`Unsupported mode <${mode}>`);
155
+ throw new CmpStrInternalError(`Unsupported mode <${mode}>`);
136
156
  }
137
157
  }
138
158
  async runAsync(mode, clear = true) {
@@ -153,17 +173,18 @@ class Metric {
153
173
  if (this.isPairwise()) await this.runPairwiseAsync();
154
174
  break;
155
175
  default:
156
- throw new Error(`Unsupported async mode <${mode}>`);
176
+ throw new CmpStrInternalError(`Unsupported async mode <${mode}>`);
157
177
  }
158
178
  }
159
179
  getMetricName = () => this.metric;
160
180
  getResults() {
161
- if (this.results === undefined)
162
- throw new Error(`run() must be called before getResult()`);
181
+ ErrorUtil.assert(
182
+ this.results !== undefined,
183
+ `run() must be called before getResults()`
184
+ );
163
185
  return this.results;
164
186
  }
165
187
  }
166
188
  const MetricRegistry = Registry('metric', Metric);
167
189
 
168
190
  export { Metric, MetricRegistry };
169
- //# sourceMappingURL=Metric.mjs.map
@@ -1,4 +1,4 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.2.2 build-bb61120-260311 by Paul Köhler @komed3 / MIT License
2
2
  import { Pool } from '../utils/Pool.mjs';
3
3
  import { MetricRegistry, Metric } from './Metric.mjs';
4
4
 
@@ -41,4 +41,3 @@ class NeedlemanWunschDistance extends Metric {
41
41
  MetricRegistry.add('needlemanWunsch', NeedlemanWunschDistance);
42
42
 
43
43
  export { NeedlemanWunschDistance };
44
- //# sourceMappingURL=NeedlemanWunsch.mjs.map
@@ -1,4 +1,4 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.2.2 build-bb61120-260311 by Paul Köhler @komed3 / MIT License
2
2
  import { Pool } from '../utils/Pool.mjs';
3
3
  import { MetricRegistry, Metric } from './Metric.mjs';
4
4
 
@@ -35,4 +35,3 @@ class QGramSimilarity extends Metric {
35
35
  MetricRegistry.add('qGram', QGramSimilarity);
36
36
 
37
37
  export { QGramSimilarity };
38
- //# sourceMappingURL=QGram.mjs.map
@@ -1,4 +1,4 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.2.2 build-bb61120-260311 by Paul Köhler @komed3 / MIT License
2
2
  import { Pool } from '../utils/Pool.mjs';
3
3
  import { MetricRegistry, Metric } from './Metric.mjs';
4
4
 
@@ -42,4 +42,3 @@ class SmithWatermanDistance extends Metric {
42
42
  MetricRegistry.add('smithWaterman', SmithWatermanDistance);
43
43
 
44
44
  export { SmithWatermanDistance };
45
- //# sourceMappingURL=SmithWaterman.mjs.map
@@ -1,4 +1,4 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.2.2 build-bb61120-260311 by Paul Köhler @komed3 / MIT License
2
2
  import {
3
3
  PhoneticRegistry,
4
4
  PhoneticMappingRegistry,
@@ -118,4 +118,3 @@ PhoneticMappingRegistry.add('caverphone', 'en2', {
118
118
  });
119
119
 
120
120
  export { Caverphone };
121
- //# sourceMappingURL=Caverphone.mjs.map
@@ -1,4 +1,4 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.2.2 build-bb61120-260311 by Paul Köhler @komed3 / MIT License
2
2
  import {
3
3
  PhoneticRegistry,
4
4
  PhoneticMappingRegistry,
@@ -69,4 +69,3 @@ PhoneticMappingRegistry.add('cologne', 'default', {
69
69
  });
70
70
 
71
71
  export { Cologne };
72
- //# sourceMappingURL=Cologne.mjs.map
@@ -1,4 +1,4 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.2.2 build-bb61120-260311 by Paul Köhler @komed3 / MIT License
2
2
  import {
3
3
  PhoneticRegistry,
4
4
  PhoneticMappingRegistry,
@@ -99,4 +99,3 @@ PhoneticMappingRegistry.add('metaphone', 'en90', {
99
99
  });
100
100
 
101
101
  export { Metaphone };
102
- //# sourceMappingURL=Metaphone.mjs.map
@@ -1,5 +1,6 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.2.2 build-bb61120-260311 by Paul Köhler @komed3 / MIT License
2
2
  import { merge } from '../utils/DeepMerge.mjs';
3
+ import { CmpStrNotFoundError, ErrorUtil } from '../utils/Errors.mjs';
3
4
  import { HashTable, Hasher } from '../utils/HashTable.mjs';
4
5
  import { Profiler } from '../utils/Profiler.mjs';
5
6
  import { Registry } from '../utils/Registry.mjs';
@@ -16,10 +17,17 @@ class Phonetic {
16
17
  constructor(algo, opt = {}) {
17
18
  const defaults = this.constructor.default ?? {};
18
19
  const mapId = opt.map ?? defaults.map;
19
- if (!mapId) throw new Error(`No mapping specified for phonetic algorithm`);
20
+ if (!mapId)
21
+ throw new CmpStrNotFoundError(
22
+ `No mapping specified for phonetic algorithm`,
23
+ { algo }
24
+ );
20
25
  const map = PhoneticMappingRegistry.get(algo, mapId);
21
26
  if (map === undefined)
22
- throw new Error(`Requested mapping <${mapId}> is not declared`);
27
+ throw new CmpStrNotFoundError(
28
+ `Requested mapping <${mapId}> is not declared`,
29
+ { algo, mapId }
30
+ );
23
31
  this.options = merge(merge(defaults, map.options ?? {}), opt);
24
32
  this.optKey = Hasher.fastFNV1a(
25
33
  JSON.stringify(this.options, Object.keys(this.options).sort())
@@ -109,35 +117,47 @@ class Phonetic {
109
117
  return code;
110
118
  }
111
119
  loop(words) {
112
- const index = [];
113
- for (const word of words) {
114
- const key = Phonetic.cache.key(this.algo, [word]) + this.optKey;
115
- const code =
116
- Phonetic.cache.get(key || '') ??
117
- (() => {
118
- const res = this.encode(word);
119
- if (key) Phonetic.cache.set(key, res);
120
- return res;
121
- })();
122
- if (code && code.length) index.push(this.equalLen(code));
123
- }
124
- return index;
120
+ return ErrorUtil.wrap(
121
+ () => {
122
+ const index = [];
123
+ for (const word of words) {
124
+ const key = Phonetic.cache.key(this.algo, [word]) + this.optKey;
125
+ const code =
126
+ Phonetic.cache.get(key || '') ??
127
+ (() => {
128
+ const res = this.encode(word);
129
+ if (key) Phonetic.cache.set(key, res);
130
+ return res;
131
+ })();
132
+ if (code && code.length) index.push(this.equalLen(code));
133
+ }
134
+ return index;
135
+ },
136
+ `Failed to generate phonetic index`,
137
+ { algo: this.algo, words }
138
+ );
125
139
  }
126
140
  async loopAsync(words) {
127
- const index = [];
128
- for (const word of words) {
129
- const key = Phonetic.cache.key(this.algo, [word]) + this.optKey;
130
- const code = await Promise.resolve(
131
- Phonetic.cache.get(key || '') ??
132
- (() => {
133
- const res = this.encode(word);
134
- if (key) Phonetic.cache.set(key, res);
135
- return res;
136
- })()
137
- );
138
- if (code && code.length) index.push(this.equalLen(code));
139
- }
140
- return index;
141
+ return ErrorUtil.wrapAsync(
142
+ async () => {
143
+ const index = [];
144
+ for (const word of words) {
145
+ const key = Phonetic.cache.key(this.algo, [word]) + this.optKey;
146
+ const code = await Promise.resolve(
147
+ Phonetic.cache.get(key || '') ??
148
+ (() => {
149
+ const res = this.encode(word);
150
+ if (key) Phonetic.cache.set(key, res);
151
+ return res;
152
+ })()
153
+ );
154
+ if (code && code.length) index.push(this.equalLen(code));
155
+ }
156
+ return index;
157
+ },
158
+ `Failed to generate phonetic index asynchronously`,
159
+ { algo: this.algo, words }
160
+ );
141
161
  }
142
162
  getAlgoName = () => this.algo;
143
163
  getIndex(input) {
@@ -162,10 +182,11 @@ const PhoneticMappingRegistry = (() => {
162
182
  return Object.freeze({
163
183
  add(algo, id, map, update = false) {
164
184
  const mappings = maps(algo);
165
- if (!update && id in mappings)
166
- throw new Error(
167
- `Entry <${id}> already exists / use <update=true> to overwrite`
168
- );
185
+ ErrorUtil.assert(
186
+ !(!id || id in mappings) || update,
187
+ `Entry <${id}> already exists / use <update=true> to overwrite`,
188
+ { algo, id }
189
+ );
169
190
  mappings[id] = map;
170
191
  },
171
192
  remove(algo, id) {
@@ -184,4 +205,3 @@ const PhoneticMappingRegistry = (() => {
184
205
  })();
185
206
 
186
207
  export { Phonetic, PhoneticMappingRegistry, PhoneticRegistry };
187
- //# sourceMappingURL=Phonetic.mjs.map
@@ -1,4 +1,4 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.2.2 build-bb61120-260311 by Paul Köhler @komed3 / MIT License
2
2
  import {
3
3
  PhoneticRegistry,
4
4
  PhoneticMappingRegistry,
@@ -88,4 +88,3 @@ PhoneticMappingRegistry.add('soundex', 'de', {
88
88
  });
89
89
 
90
90
  export { Soundex };
91
- //# sourceMappingURL=Soundex.mjs.map
package/dist/esm/root.mjs CHANGED
@@ -1,4 +1,4 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.2.2 build-bb61120-260311 by Paul Köhler @komed3 / MIT License
2
2
  export { CmpStr } from './CmpStr.mjs';
3
3
  export { CmpStrAsync } from './CmpStrAsync.mjs';
4
4
  export { DiffChecker } from './utils/DiffChecker.mjs';
@@ -27,9 +27,10 @@ export {
27
27
  } from './phonetic/Phonetic.mjs';
28
28
  import * as DeepMerge from './utils/DeepMerge.mjs';
29
29
  export { DeepMerge };
30
+ import * as Errors from './utils/Errors.mjs';
31
+ export { Errors as CmpStrError };
30
32
  export { Filter } from './utils/Filter.mjs';
31
33
  export { HashTable, Hasher } from './utils/HashTable.mjs';
32
34
  export { Pool } from './utils/Pool.mjs';
33
35
  export { Profiler } from './utils/Profiler.mjs';
34
36
  export { StructuredData } from './utils/StructuredData.mjs';
35
- //# sourceMappingURL=root.mjs.map
@@ -1,4 +1,6 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.2.2 build-bb61120-260311 by Paul Köhler @komed3 / MIT License
2
+ import { CmpStrUsageError } from './Errors.mjs';
3
+
2
4
  const BRACKET_PATTERN = /\[(\d+)]/g;
3
5
  const PATH_CACHE = new Map();
4
6
  function parse(p) {
@@ -34,15 +36,19 @@ function set(t, path, value) {
34
36
  if (path === '') return value;
35
37
  const keys = parse(path);
36
38
  if (t !== undefined && (typeof t !== 'object' || t === null))
37
- throw Error(`Cannot set property <${keys[0]}> of <${JSON.stringify(t)}>`);
39
+ throw new CmpStrUsageError(
40
+ `Cannot set property <${keys[0]}> of <${JSON.stringify(t)}>`,
41
+ { path: keys[0], target: t }
42
+ );
38
43
  const root = t ?? (typeof keys[0] === 'number' ? [] : Object.create(null));
39
44
  let cur = root;
40
45
  for (let i = 0; i < keys.length - 1; i++) {
41
46
  const k = keys[i];
42
47
  let n = cur[k];
43
48
  if (n != null && typeof n !== 'object')
44
- throw Error(
45
- `Cannot set property <${keys[i + 1]}> of <${JSON.stringify(n)}>`
49
+ throw new CmpStrUsageError(
50
+ `Cannot set property <${keys[i + 1]}> of <${JSON.stringify(n)}>`,
51
+ { path: keys.slice(0, i + 2), value: n }
46
52
  );
47
53
  if (n == null)
48
54
  n = cur[k] = typeof keys[i + 1] === 'number' ? [] : Object.create(null);
@@ -99,4 +105,3 @@ function rmv(t, path, preserveEmpty = false) {
99
105
  }
100
106
 
101
107
  export { get, has, merge, rmv, set };
102
- //# sourceMappingURL=DeepMerge.mjs.map
@@ -1,4 +1,4 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.2.2 build-bb61120-260311 by Paul Köhler @komed3 / MIT License
2
2
  class DiffChecker {
3
3
  a;
4
4
  b;
@@ -295,4 +295,3 @@ class DiffChecker {
295
295
  }
296
296
 
297
297
  export { DiffChecker };
298
- //# sourceMappingURL=DiffChecker.mjs.map
@@ -0,0 +1,103 @@
1
+ // CmpStr v3.2.2 build-bb61120-260311 by Paul Köhler @komed3 / MIT License
2
+ class CmpStrError extends Error {
3
+ code;
4
+ meta;
5
+ cause;
6
+ when = new Date().toISOString();
7
+ constructor(code, message, meta, cause) {
8
+ super(message);
9
+ this.name = this.constructor.name;
10
+ this.code = code;
11
+ this.meta = meta;
12
+ this.cause = cause;
13
+ if (typeof Error.captureStackTrace === 'function') {
14
+ Error.captureStackTrace(this, this.constructor);
15
+ }
16
+ }
17
+ toJSON() {
18
+ return {
19
+ name: this.name,
20
+ code: this.code,
21
+ message: this.message,
22
+ meta: this.meta,
23
+ when: this.when,
24
+ cause:
25
+ this.cause instanceof Error
26
+ ? {
27
+ name: this.cause.name,
28
+ message: this.cause.message,
29
+ stack: this.cause.stack
30
+ }
31
+ : this.cause
32
+ };
33
+ }
34
+ toString(stack = false) {
35
+ const parts = [`${this.name} [${this.code}]`, this.message];
36
+ if (this.meta && Object.keys(this.meta).length) {
37
+ try {
38
+ parts.push(JSON.stringify(this.meta));
39
+ } catch {}
40
+ }
41
+ return (
42
+ parts.join(' - ') +
43
+ (stack && this.stack ? `\nStack Trace:\n${this.stack}` : '')
44
+ );
45
+ }
46
+ }
47
+ class CmpStrValidationError extends CmpStrError {
48
+ constructor(message, meta, cause) {
49
+ super('E_VALIDATION', message, meta, cause);
50
+ }
51
+ }
52
+ class CmpStrNotFoundError extends CmpStrError {
53
+ constructor(message, meta, cause) {
54
+ super('E_NOT_FOUND', message, meta, cause);
55
+ }
56
+ }
57
+ class CmpStrUsageError extends CmpStrError {
58
+ constructor(message, meta, cause) {
59
+ super('E_USAGE', message, meta, cause);
60
+ }
61
+ }
62
+ class CmpStrInternalError extends CmpStrError {
63
+ constructor(message, meta, cause) {
64
+ super('E_INTERNAL', message, meta, cause);
65
+ }
66
+ }
67
+ class ErrorUtil {
68
+ static assert(condition, message, meta) {
69
+ if (!condition) throw new CmpStrUsageError(message, meta);
70
+ }
71
+ static create(err, message, meta) {
72
+ if (err instanceof CmpStrError) throw err;
73
+ throw new CmpStrInternalError(message, meta, err);
74
+ }
75
+ static format(err) {
76
+ if (err instanceof CmpStrError) return err.toString();
77
+ if (err instanceof Error) return `${err.name}: ${err.message}`;
78
+ return String(err);
79
+ }
80
+ static wrap(fn, message, meta) {
81
+ try {
82
+ return fn();
83
+ } catch (err) {
84
+ throw new CmpStrInternalError(message, meta, err);
85
+ }
86
+ }
87
+ static async wrapAsync(fn, message, meta) {
88
+ try {
89
+ return await fn();
90
+ } catch (err) {
91
+ throw new CmpStrInternalError(message, meta, err);
92
+ }
93
+ }
94
+ }
95
+
96
+ export {
97
+ CmpStrError,
98
+ CmpStrInternalError,
99
+ CmpStrNotFoundError,
100
+ CmpStrUsageError,
101
+ CmpStrValidationError,
102
+ ErrorUtil
103
+ };
@@ -1,32 +1,46 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.2.2 build-bb61120-260311 by Paul Köhler @komed3 / MIT License
2
+ import { ErrorUtil } from './Errors.mjs';
3
+
2
4
  class Filter {
3
5
  static filters = new Map();
4
6
  static pipeline = new Map();
5
7
  static getPipeline(hook) {
6
- const cached = Filter.pipeline.get(hook);
7
- if (cached) return cached;
8
- const filter = Filter.filters.get(hook);
9
- if (!filter) return (s) => s;
10
- const pipeline = Array.from(filter.values())
11
- .filter((f) => f.active)
12
- .sort((a, b) => a.priority - b.priority)
13
- .map((f) => f.fn);
14
- const fn = (input) => pipeline.reduce((v, f) => f(v), input);
15
- Filter.pipeline.set(hook, fn);
16
- return fn;
8
+ return ErrorUtil.wrap(
9
+ () => {
10
+ const cached = Filter.pipeline.get(hook);
11
+ if (cached) return cached;
12
+ const filter = Filter.filters.get(hook);
13
+ if (!filter) return (s) => s;
14
+ const pipeline = Array.from(filter.values())
15
+ .filter((f) => f.active)
16
+ .sort((a, b) => a.priority - b.priority)
17
+ .map((f) => f.fn);
18
+ const fn = (input) => pipeline.reduce((v, f) => f(v), input);
19
+ Filter.pipeline.set(hook, fn);
20
+ return fn;
21
+ },
22
+ `Error compiling filter pipeline for hook <${hook}>`,
23
+ { hook }
24
+ );
17
25
  }
18
26
  static has(hook, id) {
19
27
  return !!Filter.filters.get(hook)?.has(id);
20
28
  }
21
29
  static add(hook, id, fn, opt = {}) {
22
- const { priority = 10, active = true, overrideable = true } = opt;
23
- const filter = Filter.filters.get(hook) ?? new Map();
24
- const index = filter.get(id);
25
- if (index && !index.overrideable) return false;
26
- filter.set(id, { id, fn, priority, active, overrideable });
27
- Filter.filters.set(hook, filter);
28
- Filter.pipeline.delete(hook);
29
- return true;
30
+ return ErrorUtil.wrap(
31
+ () => {
32
+ const { priority = 10, active = true, overrideable = true } = opt;
33
+ const filter = Filter.filters.get(hook) ?? new Map();
34
+ const index = filter.get(id);
35
+ if (index && !index.overrideable) return false;
36
+ filter.set(id, { id, fn, priority, active, overrideable });
37
+ Filter.filters.set(hook, filter);
38
+ Filter.pipeline.delete(hook);
39
+ return true;
40
+ },
41
+ `Error adding filter <${id}> to hook <${hook}>`,
42
+ { hook, id, opt }
43
+ );
30
44
  }
31
45
  static remove(hook, id) {
32
46
  Filter.pipeline.delete(hook);
@@ -51,14 +65,26 @@ class Filter {
51
65
  return out;
52
66
  }
53
67
  static apply(hook, input) {
54
- const fn = Filter.getPipeline(hook);
55
- return Array.isArray(input) ? input.map(fn) : fn(input);
68
+ return ErrorUtil.wrap(
69
+ () => {
70
+ const fn = Filter.getPipeline(hook);
71
+ return Array.isArray(input) ? input.map(fn) : fn(input);
72
+ },
73
+ `Error applying filters for hook <${hook}>`,
74
+ { hook, input }
75
+ );
56
76
  }
57
77
  static async applyAsync(hook, input) {
58
- const fn = Filter.getPipeline(hook);
59
- return Array.isArray(input)
60
- ? Promise.all(input.map(fn))
61
- : Promise.resolve(fn(input));
78
+ return ErrorUtil.wrapAsync(
79
+ async () => {
80
+ const fn = Filter.getPipeline(hook);
81
+ return Array.isArray(input)
82
+ ? Promise.all(input.map(fn))
83
+ : Promise.resolve(fn(input));
84
+ },
85
+ `Error applying filters for hook <${hook}>`,
86
+ { hook, input }
87
+ );
62
88
  }
63
89
  static clear(hook) {
64
90
  Filter.pipeline.clear();
@@ -71,4 +97,3 @@ class Filter {
71
97
  }
72
98
 
73
99
  export { Filter };
74
- //# sourceMappingURL=Filter.mjs.map
@@ -1,4 +1,4 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.2.2 build-bb61120-260311 by Paul Köhler @komed3 / MIT License
2
2
  class Hasher {
3
3
  static FNV_PRIME = 0x01000193;
4
4
  static HASH_OFFSET = 0x811c9dc5;
@@ -62,4 +62,3 @@ class HashTable {
62
62
  }
63
63
 
64
64
  export { HashTable, Hasher };
65
- //# sourceMappingURL=HashTable.mjs.map