cmpstr 3.2.1 → 3.3.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 (155) hide show
  1. package/README.md +24 -18
  2. package/dist/CmpStr.esm.js +1904 -1211
  3. package/dist/CmpStr.esm.min.js +2 -3
  4. package/dist/CmpStr.umd.js +1924 -1236
  5. package/dist/CmpStr.umd.min.js +2 -3
  6. package/dist/cjs/CmpStr.cjs +134 -64
  7. package/dist/cjs/CmpStrAsync.cjs +60 -37
  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 +90 -53
  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 +80 -48
  25. package/dist/cjs/phonetic/Soundex.cjs +1 -2
  26. package/dist/cjs/root.cjs +6 -3
  27. package/dist/cjs/utils/DeepMerge.cjs +109 -99
  28. package/dist/cjs/utils/DiffChecker.cjs +1 -2
  29. package/dist/cjs/utils/Errors.cjs +106 -0
  30. package/dist/cjs/utils/Filter.cjs +97 -37
  31. package/dist/cjs/utils/HashTable.cjs +44 -30
  32. package/dist/cjs/utils/Normalizer.cjs +84 -35
  33. package/dist/cjs/utils/OptionsValidator.cjs +211 -0
  34. package/dist/cjs/utils/Pool.cjs +57 -19
  35. package/dist/cjs/utils/Profiler.cjs +41 -28
  36. package/dist/cjs/utils/Registry.cjs +48 -24
  37. package/dist/cjs/utils/StructuredData.cjs +95 -57
  38. package/dist/cjs/utils/TextAnalyzer.cjs +1 -2
  39. package/dist/esm/CmpStr.mjs +133 -61
  40. package/dist/esm/CmpStrAsync.mjs +56 -33
  41. package/dist/esm/index.mjs +1 -2
  42. package/dist/esm/metric/Cosine.mjs +1 -2
  43. package/dist/esm/metric/DamerauLevenshtein.mjs +1 -2
  44. package/dist/esm/metric/DiceSorensen.mjs +1 -2
  45. package/dist/esm/metric/Hamming.mjs +5 -4
  46. package/dist/esm/metric/Jaccard.mjs +1 -2
  47. package/dist/esm/metric/JaroWinkler.mjs +1 -2
  48. package/dist/esm/metric/LCS.mjs +1 -2
  49. package/dist/esm/metric/Levenshtein.mjs +1 -2
  50. package/dist/esm/metric/Metric.mjs +92 -53
  51. package/dist/esm/metric/NeedlemanWunsch.mjs +1 -2
  52. package/dist/esm/metric/QGram.mjs +1 -2
  53. package/dist/esm/metric/SmithWaterman.mjs +1 -2
  54. package/dist/esm/phonetic/Caverphone.mjs +1 -2
  55. package/dist/esm/phonetic/Cologne.mjs +1 -2
  56. package/dist/esm/phonetic/Metaphone.mjs +1 -2
  57. package/dist/esm/phonetic/Phonetic.mjs +83 -48
  58. package/dist/esm/phonetic/Soundex.mjs +1 -2
  59. package/dist/esm/root.mjs +5 -4
  60. package/dist/esm/utils/DeepMerge.mjs +109 -95
  61. package/dist/esm/utils/DiffChecker.mjs +1 -2
  62. package/dist/esm/utils/Errors.mjs +106 -0
  63. package/dist/esm/utils/Filter.mjs +97 -37
  64. package/dist/esm/utils/HashTable.mjs +44 -30
  65. package/dist/esm/utils/Normalizer.mjs +84 -35
  66. package/dist/esm/utils/OptionsValidator.mjs +210 -0
  67. package/dist/esm/utils/Pool.mjs +53 -19
  68. package/dist/esm/utils/Profiler.mjs +41 -28
  69. package/dist/esm/utils/Registry.mjs +48 -24
  70. package/dist/esm/utils/StructuredData.mjs +95 -57
  71. package/dist/esm/utils/TextAnalyzer.mjs +1 -2
  72. package/dist/types/CmpStr.d.ts +25 -14
  73. package/dist/types/CmpStrAsync.d.ts +4 -0
  74. package/dist/types/index.d.ts +3 -2
  75. package/dist/types/metric/Metric.d.ts +15 -14
  76. package/dist/types/phonetic/Phonetic.d.ts +7 -4
  77. package/dist/types/root.d.ts +4 -2
  78. package/dist/types/utils/DeepMerge.d.ts +80 -58
  79. package/dist/types/utils/Errors.d.ts +154 -0
  80. package/dist/types/utils/Filter.d.ts +8 -1
  81. package/dist/types/utils/HashTable.d.ts +12 -11
  82. package/dist/types/utils/Normalizer.d.ts +5 -1
  83. package/dist/types/utils/OptionsValidator.d.ts +193 -0
  84. package/dist/types/utils/Pool.d.ts +2 -0
  85. package/dist/types/utils/Profiler.d.ts +9 -28
  86. package/dist/types/utils/Registry.d.ts +3 -3
  87. package/dist/types/utils/StructuredData.d.ts +6 -1
  88. package/dist/types/utils/Types.d.ts +39 -1
  89. package/package.json +20 -11
  90. package/dist/CmpStr.esm.js.map +0 -1
  91. package/dist/CmpStr.esm.min.js.map +0 -1
  92. package/dist/CmpStr.umd.js.map +0 -1
  93. package/dist/CmpStr.umd.min.js.map +0 -1
  94. package/dist/cjs/CmpStr.cjs.map +0 -1
  95. package/dist/cjs/CmpStrAsync.cjs.map +0 -1
  96. package/dist/cjs/index.cjs.map +0 -1
  97. package/dist/cjs/metric/Cosine.cjs.map +0 -1
  98. package/dist/cjs/metric/DamerauLevenshtein.cjs.map +0 -1
  99. package/dist/cjs/metric/DiceSorensen.cjs.map +0 -1
  100. package/dist/cjs/metric/Hamming.cjs.map +0 -1
  101. package/dist/cjs/metric/Jaccard.cjs.map +0 -1
  102. package/dist/cjs/metric/JaroWinkler.cjs.map +0 -1
  103. package/dist/cjs/metric/LCS.cjs.map +0 -1
  104. package/dist/cjs/metric/Levenshtein.cjs.map +0 -1
  105. package/dist/cjs/metric/Metric.cjs.map +0 -1
  106. package/dist/cjs/metric/NeedlemanWunsch.cjs.map +0 -1
  107. package/dist/cjs/metric/QGram.cjs.map +0 -1
  108. package/dist/cjs/metric/SmithWaterman.cjs.map +0 -1
  109. package/dist/cjs/phonetic/Caverphone.cjs.map +0 -1
  110. package/dist/cjs/phonetic/Cologne.cjs.map +0 -1
  111. package/dist/cjs/phonetic/Metaphone.cjs.map +0 -1
  112. package/dist/cjs/phonetic/Phonetic.cjs.map +0 -1
  113. package/dist/cjs/phonetic/Soundex.cjs.map +0 -1
  114. package/dist/cjs/root.cjs.map +0 -1
  115. package/dist/cjs/utils/DeepMerge.cjs.map +0 -1
  116. package/dist/cjs/utils/DiffChecker.cjs.map +0 -1
  117. package/dist/cjs/utils/Filter.cjs.map +0 -1
  118. package/dist/cjs/utils/HashTable.cjs.map +0 -1
  119. package/dist/cjs/utils/Normalizer.cjs.map +0 -1
  120. package/dist/cjs/utils/Pool.cjs.map +0 -1
  121. package/dist/cjs/utils/Profiler.cjs.map +0 -1
  122. package/dist/cjs/utils/Registry.cjs.map +0 -1
  123. package/dist/cjs/utils/StructuredData.cjs.map +0 -1
  124. package/dist/cjs/utils/TextAnalyzer.cjs.map +0 -1
  125. package/dist/esm/CmpStr.mjs.map +0 -1
  126. package/dist/esm/CmpStrAsync.mjs.map +0 -1
  127. package/dist/esm/index.mjs.map +0 -1
  128. package/dist/esm/metric/Cosine.mjs.map +0 -1
  129. package/dist/esm/metric/DamerauLevenshtein.mjs.map +0 -1
  130. package/dist/esm/metric/DiceSorensen.mjs.map +0 -1
  131. package/dist/esm/metric/Hamming.mjs.map +0 -1
  132. package/dist/esm/metric/Jaccard.mjs.map +0 -1
  133. package/dist/esm/metric/JaroWinkler.mjs.map +0 -1
  134. package/dist/esm/metric/LCS.mjs.map +0 -1
  135. package/dist/esm/metric/Levenshtein.mjs.map +0 -1
  136. package/dist/esm/metric/Metric.mjs.map +0 -1
  137. package/dist/esm/metric/NeedlemanWunsch.mjs.map +0 -1
  138. package/dist/esm/metric/QGram.mjs.map +0 -1
  139. package/dist/esm/metric/SmithWaterman.mjs.map +0 -1
  140. package/dist/esm/phonetic/Caverphone.mjs.map +0 -1
  141. package/dist/esm/phonetic/Cologne.mjs.map +0 -1
  142. package/dist/esm/phonetic/Metaphone.mjs.map +0 -1
  143. package/dist/esm/phonetic/Phonetic.mjs.map +0 -1
  144. package/dist/esm/phonetic/Soundex.mjs.map +0 -1
  145. package/dist/esm/root.mjs.map +0 -1
  146. package/dist/esm/utils/DeepMerge.mjs.map +0 -1
  147. package/dist/esm/utils/DiffChecker.mjs.map +0 -1
  148. package/dist/esm/utils/Filter.mjs.map +0 -1
  149. package/dist/esm/utils/HashTable.mjs.map +0 -1
  150. package/dist/esm/utils/Normalizer.mjs.map +0 -1
  151. package/dist/esm/utils/Pool.mjs.map +0 -1
  152. package/dist/esm/utils/Profiler.mjs.map +0 -1
  153. package/dist/esm/utils/Registry.mjs.map +0 -1
  154. package/dist/esm/utils/StructuredData.mjs.map +0 -1
  155. package/dist/esm/utils/TextAnalyzer.mjs.map +0 -1
@@ -1,6 +1,8 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.3.0 build-3699f85-260318 by Paul Köhler @komed3 / MIT License
2
2
  'use strict';
3
3
 
4
+ var Errors = require('./Errors.cjs');
5
+
4
6
  class RingPool {
5
7
  maxSize;
6
8
  buffers = [];
@@ -9,22 +11,39 @@ class RingPool {
9
11
  this.maxSize = maxSize;
10
12
  }
11
13
  acquire(minSize, allowOversize) {
12
- const len = this.buffers.length;
13
- for (let i = 0; i < len; i++) {
14
- const idx = (this.pointer + i) & (len - 1);
15
- const item = this.buffers[idx];
16
- if (item.size >= minSize && (allowOversize || item.size === minSize)) {
17
- this.pointer = (idx + 1) & (len - 1);
18
- return item;
19
- }
20
- }
21
- return null;
14
+ return Errors.ErrorUtil.wrap(
15
+ () => {
16
+ const buffers = this.buffers;
17
+ const len = buffers.length;
18
+ for (let i = 0; i < len; i++) {
19
+ const idx = (this.pointer + i) % len;
20
+ const item = buffers[idx];
21
+ const size = item.size;
22
+ if (size >= minSize && (allowOversize || size === minSize)) {
23
+ this.pointer = (idx + 1) % len;
24
+ return item;
25
+ }
26
+ }
27
+ return null;
28
+ },
29
+ `Failed to acquire buffer of size >= ${minSize} from pool`,
30
+ { minSize, allowOversize }
31
+ );
22
32
  }
23
33
  release(item) {
24
- if (this.buffers.length < this.maxSize)
25
- return void [this.buffers.push(item)];
26
- this.buffers[this.pointer] = item;
27
- this.pointer = (this.pointer + 1) % this.maxSize;
34
+ Errors.ErrorUtil.wrap(
35
+ () => {
36
+ const buffers = this.buffers;
37
+ if (buffers.length < this.maxSize) {
38
+ buffers.push(item);
39
+ return;
40
+ }
41
+ buffers[this.pointer] = item;
42
+ this.pointer = (this.pointer + 1) % this.maxSize;
43
+ },
44
+ `Failed to release buffer back to pool`,
45
+ { item }
46
+ );
28
47
  }
29
48
  clear() {
30
49
  this.buffers = [];
@@ -39,6 +58,12 @@ class Pool {
39
58
  maxItemSize: 2048,
40
59
  allowOversize: true
41
60
  },
61
+ 'arr[]': {
62
+ type: 'arr[]',
63
+ maxSize: 4,
64
+ maxItemSize: 1024,
65
+ allowOversize: false
66
+ },
42
67
  'number[]': {
43
68
  type: 'number[]',
44
69
  maxSize: 16,
@@ -56,6 +81,7 @@ class Pool {
56
81
  };
57
82
  static POOLS = {
58
83
  int32: new RingPool(64),
84
+ 'arr[]': new RingPool(4),
59
85
  'number[]': new RingPool(16),
60
86
  'string[]': new RingPool(2),
61
87
  set: new RingPool(8),
@@ -65,6 +91,8 @@ class Pool {
65
91
  switch (type) {
66
92
  case 'int32':
67
93
  return new Int32Array(size);
94
+ case 'arr[]':
95
+ return new Array(size);
68
96
  case 'number[]':
69
97
  return new Float64Array(size);
70
98
  case 'string[]':
@@ -77,6 +105,10 @@ class Pool {
77
105
  }
78
106
  static acquire(type, size) {
79
107
  const CONFIG = this.CONFIG[type];
108
+ if (!CONFIG)
109
+ throw new Errors.CmpStrUsageError(`Unsupported pool type <${type}>`, {
110
+ type
111
+ });
80
112
  if (size > CONFIG.maxItemSize) return this.allocate(type, size);
81
113
  const item = this.POOLS[type].acquire(size, CONFIG.allowOversize);
82
114
  if (item)
@@ -84,13 +116,19 @@ class Pool {
84
116
  return this.allocate(type, size);
85
117
  }
86
118
  static acquireMany(type, sizes) {
87
- return sizes.map((size) => this.acquire(type, size));
119
+ const out = new Array(sizes.length);
120
+ for (let i = 0; i < sizes.length; i++)
121
+ out[i] = this.acquire(type, sizes[i]);
122
+ return out;
88
123
  }
89
124
  static release(type, buffer, size) {
90
- if (size <= this.CONFIG[type].maxItemSize)
91
- this.POOLS[type].release({ buffer, size });
125
+ const CONFIG = this.CONFIG[type];
126
+ if (!CONFIG)
127
+ throw new Errors.CmpStrUsageError(`Unsupported pool type <${type}>`, {
128
+ type
129
+ });
130
+ if (size <= CONFIG.maxItemSize) this.POOLS[type].release({ buffer, size });
92
131
  }
93
132
  }
94
133
 
95
134
  exports.Pool = Pool;
96
- //# sourceMappingURL=Pool.cjs.map
@@ -1,4 +1,4 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.3.0 build-3699f85-260318 by Paul Köhler @komed3 / MIT License
2
2
  'use strict';
3
3
 
4
4
  class Profiler {
@@ -7,11 +7,13 @@ class Profiler {
7
7
  static instance;
8
8
  nowFn;
9
9
  memFn;
10
- store = new Set();
10
+ store = [];
11
+ last;
11
12
  totalTime = 0;
12
13
  totalMem = 0;
13
14
  static detectEnv() {
14
- if (typeof process !== 'undefined') Profiler.ENV = 'nodejs';
15
+ if (typeof process !== 'undefined' && process.versions?.node)
16
+ Profiler.ENV = 'nodejs';
15
17
  else if (typeof performance !== 'undefined') Profiler.ENV = 'browser';
16
18
  else Profiler.ENV = 'unknown';
17
19
  }
@@ -23,7 +25,7 @@ class Profiler {
23
25
  this.active = active;
24
26
  switch (Profiler.ENV) {
25
27
  case 'nodejs':
26
- this.nowFn = () => Number(process.hrtime.bigint()) / 1e6;
28
+ this.nowFn = () => Number(process.hrtime.bigint()) * 1e-6;
27
29
  this.memFn = () => process.memoryUsage().heapUsed;
28
30
  break;
29
31
  case 'browser':
@@ -36,40 +38,52 @@ class Profiler {
36
38
  break;
37
39
  }
38
40
  }
39
- now = () => this.nowFn();
40
- mem = () => this.memFn();
41
- profile(fn, meta) {
42
- const startTime = this.now(),
43
- startMem = this.mem();
44
- const res = fn();
45
- const deltaTime = this.now() - startTime,
46
- deltaMem = this.mem() - startMem;
47
- this.store.add({ time: deltaTime, mem: deltaMem, res, meta });
48
- ((this.totalTime += deltaTime), (this.totalMem += deltaMem));
49
- return res;
41
+ storeRes(entry) {
42
+ this.store.push((this.last = entry));
43
+ this.totalTime += entry.time;
44
+ this.totalMem += entry.mem;
50
45
  }
51
- enable = () => {
46
+ enable() {
52
47
  this.active = true;
53
- };
54
- disable = () => {
48
+ }
49
+ disable() {
55
50
  this.active = false;
56
- };
51
+ }
57
52
  clear() {
58
- this.store.clear();
53
+ this.store.length = 0;
54
+ this.last = undefined;
59
55
  this.totalTime = 0;
60
56
  this.totalMem = 0;
61
57
  }
62
58
  run(fn, meta = {}) {
63
- return this.active ? this.profile(fn, meta) : fn();
59
+ if (!this.active) return fn();
60
+ const startTime = this.nowFn(),
61
+ startMem = this.memFn();
62
+ const res = fn();
63
+ const deltaTime = this.nowFn() - startTime,
64
+ deltaMem = this.memFn() - startMem;
65
+ this.storeRes({ time: deltaTime, mem: deltaMem, res, meta });
66
+ return res;
64
67
  }
65
68
  async runAsync(fn, meta = {}) {
66
- return this.active
67
- ? this.profile(async () => await fn(), meta)
68
- : await fn();
69
+ if (!this.active) return fn();
70
+ const startTime = this.nowFn(),
71
+ startMem = this.memFn();
72
+ const res = await fn();
73
+ const deltaTime = this.nowFn() - startTime,
74
+ deltaMem = this.memFn() - startMem;
75
+ this.storeRes({ time: deltaTime, mem: deltaMem, res, meta });
76
+ return res;
77
+ }
78
+ getAll() {
79
+ return [...this.store];
80
+ }
81
+ getLast() {
82
+ return this.last;
83
+ }
84
+ getTotal() {
85
+ return { time: this.totalTime, mem: this.totalMem };
69
86
  }
70
- getAll = () => [...this.store];
71
- getLast = () => this.getAll().pop();
72
- getTotal = () => ({ time: this.totalTime, mem: this.totalMem });
73
87
  services = Object.freeze({
74
88
  enable: this.enable.bind(this),
75
89
  disable: this.disable.bind(this),
@@ -81,4 +95,3 @@ class Profiler {
81
95
  }
82
96
 
83
97
  exports.Profiler = Profiler;
84
- //# sourceMappingURL=Profiler.cjs.map
@@ -1,22 +1,39 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.3.0 build-3699f85-260318 by Paul Köhler @komed3 / MIT License
2
2
  'use strict';
3
3
 
4
+ var Errors = require('./Errors.cjs');
5
+
4
6
  const registry = Object.create(null);
5
7
  const factory = Object.create(null);
6
8
  function Registry(reg, ctor) {
7
- if (reg in registry || reg in factory)
8
- throw new Error(
9
- `Registry <${reg}> already exists / overwriting is forbidden`
10
- );
9
+ Errors.ErrorUtil.assert(
10
+ !(reg in registry || reg in factory),
11
+ `Registry <${reg}> already exists / overwriting is forbidden`,
12
+ { registry: reg }
13
+ );
11
14
  const classes = Object.create(null);
12
15
  const service = Object.freeze({
13
16
  add(name, cls, update = false) {
14
- if (!(cls.prototype instanceof ctor))
15
- throw new TypeError(`Class must extend <${reg}>`);
16
- if (!update && name in classes)
17
- throw new Error(
18
- `Entry <${name}> already exists / use <update=true> to overwrite`
19
- );
17
+ Errors.ErrorUtil.assert(
18
+ typeof name === 'string' && name.length > 0,
19
+ `Class name must be a non-empty string`,
20
+ { registry: reg, name }
21
+ );
22
+ Errors.ErrorUtil.assert(
23
+ typeof cls === 'function',
24
+ `Class must be a constructor function`,
25
+ { registry: reg, class: cls }
26
+ );
27
+ Errors.ErrorUtil.assert(
28
+ cls.prototype instanceof ctor,
29
+ `Class must extend <${reg}>`,
30
+ { registry: reg, class: cls }
31
+ );
32
+ Errors.ErrorUtil.assert(
33
+ update || !(name in classes),
34
+ `Class <${name}> already exists / use <update=true> to overwrite`,
35
+ { registry: reg, name }
36
+ );
20
37
  classes[name] = cls;
21
38
  },
22
39
  remove(name) {
@@ -29,8 +46,16 @@ function Registry(reg, ctor) {
29
46
  return Object.keys(classes);
30
47
  },
31
48
  get(name) {
32
- if (!(name in classes))
33
- throw new Error(`Class <${name}> not registered for <${reg}>`);
49
+ Errors.ErrorUtil.assert(
50
+ typeof name === 'string' && name.length > 0,
51
+ `Class name must be a non-empty string`,
52
+ { registry: reg, name }
53
+ );
54
+ Errors.ErrorUtil.assert(
55
+ name in classes,
56
+ `Class <${name}> not registered for <${reg}>`,
57
+ { registry: reg, name }
58
+ );
34
59
  return classes[name];
35
60
  }
36
61
  });
@@ -40,18 +65,18 @@ function Registry(reg, ctor) {
40
65
  }
41
66
  function resolveCls(reg, cls) {
42
67
  if (!(reg in registry))
43
- throw new ReferenceError(`Registry <${reg}> does not exist`);
44
- return typeof cls === 'string' ? registry[reg]?.get(cls) : cls;
68
+ throw new Errors.CmpStrNotFoundError(`Registry <${reg}> does not exist`, {
69
+ registry: reg
70
+ });
71
+ return typeof cls === 'string' ? registry[reg].get(cls) : cls;
45
72
  }
46
73
  function createFromRegistry(reg, cls, ...args) {
47
- cls = resolveCls(reg, cls);
48
- try {
49
- return new cls(...args);
50
- } catch (err) {
51
- throw new Error(`Cannot instantiate class <${cls.name ?? cls}>`, {
52
- cause: err
53
- });
54
- }
74
+ const ctor = resolveCls(reg, cls);
75
+ return Errors.ErrorUtil.wrap(
76
+ () => new ctor(...args),
77
+ `Failed to create instance of class <${ctor.name ?? cls}> from registry <${reg}>`,
78
+ { registry: reg, class: cls, args }
79
+ );
55
80
  }
56
81
 
57
82
  exports.Registry = Registry;
@@ -59,4 +84,3 @@ exports.createFromRegistry = createFromRegistry;
59
84
  exports.factory = factory;
60
85
  exports.registry = registry;
61
86
  exports.resolveCls = resolveCls;
62
- //# sourceMappingURL=Registry.cjs.map
@@ -1,11 +1,14 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.3.0 build-3699f85-260318 by Paul Köhler @komed3 / MIT License
2
2
  'use strict';
3
3
 
4
+ var Errors = require('./Errors.cjs');
4
5
  var Pool = require('./Pool.cjs');
5
6
 
6
7
  class StructuredData {
7
8
  data;
8
9
  key;
10
+ static SORT_ASC = (a, b) => a.res - b.res;
11
+ static SORT_DESC = (a, b) => b.res - a.res;
9
12
  static create(data, key) {
10
13
  return new StructuredData(data, key);
11
14
  }
@@ -14,14 +17,17 @@ class StructuredData {
14
17
  this.key = key;
15
18
  }
16
19
  extractFrom(arr, key) {
17
- const result = Pool.Pool.acquire('string[]', arr.length);
18
- for (let i = 0; i < arr.length; i++) {
20
+ const n = arr.length;
21
+ const result = new Array(n);
22
+ for (let i = 0; i < n; i++) {
19
23
  const val = arr[i][key];
20
- result[i] = typeof val === 'string' ? val : String(val ?? '');
24
+ result[i] = val != null ? String(val) : '';
21
25
  }
22
26
  return result;
23
27
  }
24
- extract = () => this.extractFrom(this.data, this.key);
28
+ extract() {
29
+ return this.extractFrom(this.data, this.key);
30
+ }
25
31
  isMetricResult(v) {
26
32
  return (
27
33
  typeof v === 'object' && v !== null && 'a' in v && 'b' in v && 'res' in v
@@ -39,64 +45,89 @@ class StructuredData {
39
45
  normalizeResults(results) {
40
46
  if (!Array.isArray(results) || results.length === 0) return [];
41
47
  const first = results[0];
42
- let normalized = [];
43
- if (this.isMetricResult(first)) normalized = results;
44
- else if (this.isCmpStrResult(first))
45
- normalized = results.map((r) => ({
46
- metric: 'unknown',
47
- a: r.source,
48
- b: r.target,
49
- res: r.match,
50
- raw: r.raw
51
- }));
52
- else
53
- throw new TypeError(
48
+ let out = new Array(results.length);
49
+ if (this.isMetricResult(first)) {
50
+ const src = results;
51
+ for (let i = 0; i < src.length; i++) out[i] = { ...src[i], __idx: i };
52
+ } else if (this.isCmpStrResult(first)) {
53
+ const src = results;
54
+ for (let i = 0; i < src.length; i++) {
55
+ const r = src[i];
56
+ out[i] = {
57
+ metric: 'unknown',
58
+ a: r.source,
59
+ b: r.target,
60
+ res: r.match,
61
+ raw: r.raw,
62
+ __idx: i
63
+ };
64
+ }
65
+ } else
66
+ throw new Errors.CmpStrValidationError(
54
67
  'Unsupported result format for StructuredData normalization.'
55
68
  );
56
- return normalized.map((r, idx) => ({ ...r, __idx: idx }));
69
+ return out;
57
70
  }
58
71
  rebuild(results, sourceData, extractedStrings, removeZero, objectsOnly) {
59
- const stringToIndices = new Map();
60
- for (let i = 0; i < extractedStrings.length; i++) {
61
- const str = extractedStrings[i];
62
- if (!stringToIndices.has(str)) stringToIndices.set(str, []);
63
- stringToIndices.get(str).push(i);
64
- }
65
- const output = new Array(results.length);
66
- const occurrenceCount = new Map();
67
- let out = 0;
68
- for (let i = 0; i < results.length; i++) {
69
- const result = results[i];
70
- if (removeZero && result.res === 0) continue;
71
- const targetStr = result.b || '';
72
- const indices = stringToIndices.get(targetStr);
73
- let dataIndex;
74
- if (indices && indices.length > 0) {
75
- const occurrence = occurrenceCount.get(targetStr) ?? 0;
76
- occurrenceCount.set(targetStr, occurrence + 1);
77
- dataIndex = indices[occurrence % indices.length];
78
- } else {
79
- dataIndex = result.__idx ?? i;
72
+ const m = extractedStrings.length,
73
+ n = results.length;
74
+ const stringToIndices = Pool.Pool.acquire('map', m);
75
+ const occurrenceCount = Pool.Pool.acquire('map', n);
76
+ const output = new Array(n);
77
+ stringToIndices.clear();
78
+ occurrenceCount.clear();
79
+ try {
80
+ for (let i = 0; i < m; i++) {
81
+ const str = extractedStrings[i];
82
+ let arr = stringToIndices.get(str);
83
+ if (!arr) {
84
+ arr = [];
85
+ stringToIndices.set(str, arr);
86
+ }
87
+ arr.push(i);
80
88
  }
81
- if (dataIndex < 0 || dataIndex >= sourceData.length) continue;
82
- const sourceObj = sourceData[dataIndex];
83
- const mappedTarget = extractedStrings[dataIndex] || targetStr;
84
- if (objectsOnly) output[out++] = sourceObj;
85
- else
86
- output[out++] = {
87
- obj: sourceObj,
88
- key: this.key,
89
- result: { source: result.a, target: mappedTarget, match: result.res },
90
- ...(result.raw ? { raw: result.raw } : null)
91
- };
89
+ let out = 0;
90
+ for (let i = 0; i < n; i++) {
91
+ const result = results[i];
92
+ if (removeZero && result.res === 0) continue;
93
+ const targetStr = result.b || '';
94
+ const indices = stringToIndices.get(targetStr);
95
+ let dataIndex;
96
+ if (indices && indices.length > 0) {
97
+ const occurrence = occurrenceCount.get(targetStr) ?? 0;
98
+ occurrenceCount.set(targetStr, occurrence + 1);
99
+ dataIndex = indices[occurrence % indices.length];
100
+ } else {
101
+ dataIndex = result.__idx ?? i;
102
+ }
103
+ if (dataIndex < 0 || dataIndex >= sourceData.length) continue;
104
+ const sourceObj = sourceData[dataIndex];
105
+ const mappedTarget = extractedStrings[dataIndex] || targetStr;
106
+ if (objectsOnly) output[out++] = sourceObj;
107
+ else
108
+ output[out++] = {
109
+ obj: sourceObj,
110
+ key: this.key,
111
+ result: {
112
+ source: result.a,
113
+ target: mappedTarget,
114
+ match: result.res
115
+ },
116
+ ...(result.raw ? { raw: result.raw } : null)
117
+ };
118
+ }
119
+ output.length = out;
120
+ return output;
121
+ } finally {
122
+ Pool.Pool.release('map', stringToIndices, m);
123
+ Pool.Pool.release('map', occurrenceCount, n);
92
124
  }
93
- output.length = out;
94
- return output;
95
125
  }
96
126
  sort(results, sort) {
97
127
  if (!sort || results.length <= 1) return results;
98
- const asc = sort === 'asc';
99
- return results.sort((a, b) => (asc ? a.res - b.res : b.res - a.res));
128
+ return results.sort(
129
+ sort === 'asc' ? StructuredData.SORT_ASC : StructuredData.SORT_DESC
130
+ );
100
131
  }
101
132
  finalizeLookup(results, extractedStrings, opt) {
102
133
  return this.rebuild(
@@ -108,10 +139,18 @@ class StructuredData {
108
139
  );
109
140
  }
110
141
  performLookup(fn, extractedStrings, opt) {
111
- return this.finalizeLookup(fn(), extractedStrings, opt);
142
+ return Errors.ErrorUtil.wrap(
143
+ () => this.finalizeLookup(fn(), extractedStrings, opt),
144
+ 'StructuredData lookup failed',
145
+ { key: this.key }
146
+ );
112
147
  }
113
148
  async performLookupAsync(fn, extractedStrings, opt) {
114
- return this.finalizeLookup(await fn(), extractedStrings, opt);
149
+ return await Errors.ErrorUtil.wrapAsync(
150
+ async () => this.finalizeLookup(await fn(), extractedStrings, opt),
151
+ 'StructuredData async lookup failed',
152
+ { key: this.key }
153
+ );
115
154
  }
116
155
  lookup(fn, query, opt) {
117
156
  const b = this.extract();
@@ -152,4 +191,3 @@ class StructuredData {
152
191
  }
153
192
 
154
193
  exports.StructuredData = StructuredData;
155
- //# sourceMappingURL=StructuredData.cjs.map
@@ -1,4 +1,4 @@
1
- // CmpStr v3.2.1 build-3439ccb-260130 by Paul Köhler @komed3 / MIT License
1
+ // CmpStr v3.3.0 build-3699f85-260318 by Paul Köhler @komed3 / MIT License
2
2
  'use strict';
3
3
 
4
4
  class TextAnalyzer {
@@ -196,4 +196,3 @@ class TextAnalyzer {
196
196
  }
197
197
 
198
198
  exports.TextAnalyzer = TextAnalyzer;
199
- //# sourceMappingURL=TextAnalyzer.cjs.map