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.
- package/README.md +24 -18
- package/dist/CmpStr.esm.js +1904 -1211
- package/dist/CmpStr.esm.min.js +2 -3
- package/dist/CmpStr.umd.js +1924 -1236
- package/dist/CmpStr.umd.min.js +2 -3
- package/dist/cjs/CmpStr.cjs +134 -64
- package/dist/cjs/CmpStrAsync.cjs +60 -37
- package/dist/cjs/index.cjs +1 -2
- package/dist/cjs/metric/Cosine.cjs +1 -2
- package/dist/cjs/metric/DamerauLevenshtein.cjs +1 -2
- package/dist/cjs/metric/DiceSorensen.cjs +1 -2
- package/dist/cjs/metric/Hamming.cjs +5 -4
- package/dist/cjs/metric/Jaccard.cjs +1 -2
- package/dist/cjs/metric/JaroWinkler.cjs +1 -2
- package/dist/cjs/metric/LCS.cjs +1 -2
- package/dist/cjs/metric/Levenshtein.cjs +1 -2
- package/dist/cjs/metric/Metric.cjs +90 -53
- package/dist/cjs/metric/NeedlemanWunsch.cjs +1 -2
- package/dist/cjs/metric/QGram.cjs +1 -2
- package/dist/cjs/metric/SmithWaterman.cjs +1 -2
- package/dist/cjs/phonetic/Caverphone.cjs +1 -2
- package/dist/cjs/phonetic/Cologne.cjs +1 -2
- package/dist/cjs/phonetic/Metaphone.cjs +1 -2
- package/dist/cjs/phonetic/Phonetic.cjs +80 -48
- package/dist/cjs/phonetic/Soundex.cjs +1 -2
- package/dist/cjs/root.cjs +6 -3
- package/dist/cjs/utils/DeepMerge.cjs +109 -99
- package/dist/cjs/utils/DiffChecker.cjs +1 -2
- package/dist/cjs/utils/Errors.cjs +106 -0
- package/dist/cjs/utils/Filter.cjs +97 -37
- package/dist/cjs/utils/HashTable.cjs +44 -30
- package/dist/cjs/utils/Normalizer.cjs +84 -35
- package/dist/cjs/utils/OptionsValidator.cjs +211 -0
- package/dist/cjs/utils/Pool.cjs +57 -19
- package/dist/cjs/utils/Profiler.cjs +41 -28
- package/dist/cjs/utils/Registry.cjs +48 -24
- package/dist/cjs/utils/StructuredData.cjs +95 -57
- package/dist/cjs/utils/TextAnalyzer.cjs +1 -2
- package/dist/esm/CmpStr.mjs +133 -61
- package/dist/esm/CmpStrAsync.mjs +56 -33
- package/dist/esm/index.mjs +1 -2
- package/dist/esm/metric/Cosine.mjs +1 -2
- package/dist/esm/metric/DamerauLevenshtein.mjs +1 -2
- package/dist/esm/metric/DiceSorensen.mjs +1 -2
- package/dist/esm/metric/Hamming.mjs +5 -4
- package/dist/esm/metric/Jaccard.mjs +1 -2
- package/dist/esm/metric/JaroWinkler.mjs +1 -2
- package/dist/esm/metric/LCS.mjs +1 -2
- package/dist/esm/metric/Levenshtein.mjs +1 -2
- package/dist/esm/metric/Metric.mjs +92 -53
- package/dist/esm/metric/NeedlemanWunsch.mjs +1 -2
- package/dist/esm/metric/QGram.mjs +1 -2
- package/dist/esm/metric/SmithWaterman.mjs +1 -2
- package/dist/esm/phonetic/Caverphone.mjs +1 -2
- package/dist/esm/phonetic/Cologne.mjs +1 -2
- package/dist/esm/phonetic/Metaphone.mjs +1 -2
- package/dist/esm/phonetic/Phonetic.mjs +83 -48
- package/dist/esm/phonetic/Soundex.mjs +1 -2
- package/dist/esm/root.mjs +5 -4
- package/dist/esm/utils/DeepMerge.mjs +109 -95
- package/dist/esm/utils/DiffChecker.mjs +1 -2
- package/dist/esm/utils/Errors.mjs +106 -0
- package/dist/esm/utils/Filter.mjs +97 -37
- package/dist/esm/utils/HashTable.mjs +44 -30
- package/dist/esm/utils/Normalizer.mjs +84 -35
- package/dist/esm/utils/OptionsValidator.mjs +210 -0
- package/dist/esm/utils/Pool.mjs +53 -19
- package/dist/esm/utils/Profiler.mjs +41 -28
- package/dist/esm/utils/Registry.mjs +48 -24
- package/dist/esm/utils/StructuredData.mjs +95 -57
- package/dist/esm/utils/TextAnalyzer.mjs +1 -2
- package/dist/types/CmpStr.d.ts +25 -14
- package/dist/types/CmpStrAsync.d.ts +4 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/metric/Metric.d.ts +15 -14
- package/dist/types/phonetic/Phonetic.d.ts +7 -4
- package/dist/types/root.d.ts +4 -2
- package/dist/types/utils/DeepMerge.d.ts +80 -58
- package/dist/types/utils/Errors.d.ts +154 -0
- package/dist/types/utils/Filter.d.ts +8 -1
- package/dist/types/utils/HashTable.d.ts +12 -11
- package/dist/types/utils/Normalizer.d.ts +5 -1
- package/dist/types/utils/OptionsValidator.d.ts +193 -0
- package/dist/types/utils/Pool.d.ts +2 -0
- package/dist/types/utils/Profiler.d.ts +9 -28
- package/dist/types/utils/Registry.d.ts +3 -3
- package/dist/types/utils/StructuredData.d.ts +6 -1
- package/dist/types/utils/Types.d.ts +39 -1
- package/package.json +20 -11
- package/dist/CmpStr.esm.js.map +0 -1
- package/dist/CmpStr.esm.min.js.map +0 -1
- package/dist/CmpStr.umd.js.map +0 -1
- package/dist/CmpStr.umd.min.js.map +0 -1
- package/dist/cjs/CmpStr.cjs.map +0 -1
- package/dist/cjs/CmpStrAsync.cjs.map +0 -1
- package/dist/cjs/index.cjs.map +0 -1
- package/dist/cjs/metric/Cosine.cjs.map +0 -1
- package/dist/cjs/metric/DamerauLevenshtein.cjs.map +0 -1
- package/dist/cjs/metric/DiceSorensen.cjs.map +0 -1
- package/dist/cjs/metric/Hamming.cjs.map +0 -1
- package/dist/cjs/metric/Jaccard.cjs.map +0 -1
- package/dist/cjs/metric/JaroWinkler.cjs.map +0 -1
- package/dist/cjs/metric/LCS.cjs.map +0 -1
- package/dist/cjs/metric/Levenshtein.cjs.map +0 -1
- package/dist/cjs/metric/Metric.cjs.map +0 -1
- package/dist/cjs/metric/NeedlemanWunsch.cjs.map +0 -1
- package/dist/cjs/metric/QGram.cjs.map +0 -1
- package/dist/cjs/metric/SmithWaterman.cjs.map +0 -1
- package/dist/cjs/phonetic/Caverphone.cjs.map +0 -1
- package/dist/cjs/phonetic/Cologne.cjs.map +0 -1
- package/dist/cjs/phonetic/Metaphone.cjs.map +0 -1
- package/dist/cjs/phonetic/Phonetic.cjs.map +0 -1
- package/dist/cjs/phonetic/Soundex.cjs.map +0 -1
- package/dist/cjs/root.cjs.map +0 -1
- package/dist/cjs/utils/DeepMerge.cjs.map +0 -1
- package/dist/cjs/utils/DiffChecker.cjs.map +0 -1
- package/dist/cjs/utils/Filter.cjs.map +0 -1
- package/dist/cjs/utils/HashTable.cjs.map +0 -1
- package/dist/cjs/utils/Normalizer.cjs.map +0 -1
- package/dist/cjs/utils/Pool.cjs.map +0 -1
- package/dist/cjs/utils/Profiler.cjs.map +0 -1
- package/dist/cjs/utils/Registry.cjs.map +0 -1
- package/dist/cjs/utils/StructuredData.cjs.map +0 -1
- package/dist/cjs/utils/TextAnalyzer.cjs.map +0 -1
- package/dist/esm/CmpStr.mjs.map +0 -1
- package/dist/esm/CmpStrAsync.mjs.map +0 -1
- package/dist/esm/index.mjs.map +0 -1
- package/dist/esm/metric/Cosine.mjs.map +0 -1
- package/dist/esm/metric/DamerauLevenshtein.mjs.map +0 -1
- package/dist/esm/metric/DiceSorensen.mjs.map +0 -1
- package/dist/esm/metric/Hamming.mjs.map +0 -1
- package/dist/esm/metric/Jaccard.mjs.map +0 -1
- package/dist/esm/metric/JaroWinkler.mjs.map +0 -1
- package/dist/esm/metric/LCS.mjs.map +0 -1
- package/dist/esm/metric/Levenshtein.mjs.map +0 -1
- package/dist/esm/metric/Metric.mjs.map +0 -1
- package/dist/esm/metric/NeedlemanWunsch.mjs.map +0 -1
- package/dist/esm/metric/QGram.mjs.map +0 -1
- package/dist/esm/metric/SmithWaterman.mjs.map +0 -1
- package/dist/esm/phonetic/Caverphone.mjs.map +0 -1
- package/dist/esm/phonetic/Cologne.mjs.map +0 -1
- package/dist/esm/phonetic/Metaphone.mjs.map +0 -1
- package/dist/esm/phonetic/Phonetic.mjs.map +0 -1
- package/dist/esm/phonetic/Soundex.mjs.map +0 -1
- package/dist/esm/root.mjs.map +0 -1
- package/dist/esm/utils/DeepMerge.mjs.map +0 -1
- package/dist/esm/utils/DiffChecker.mjs.map +0 -1
- package/dist/esm/utils/Filter.mjs.map +0 -1
- package/dist/esm/utils/HashTable.mjs.map +0 -1
- package/dist/esm/utils/Normalizer.mjs.map +0 -1
- package/dist/esm/utils/Pool.mjs.map +0 -1
- package/dist/esm/utils/Profiler.mjs.map +0 -1
- package/dist/esm/utils/Registry.mjs.map +0 -1
- package/dist/esm/utils/StructuredData.mjs.map +0 -1
- package/dist/esm/utils/TextAnalyzer.mjs.map +0 -1
package/dist/cjs/utils/Pool.cjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
// CmpStr v3.
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
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
|
-
|
|
91
|
-
|
|
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.
|
|
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 =
|
|
10
|
+
store = [];
|
|
11
|
+
last;
|
|
11
12
|
totalTime = 0;
|
|
12
13
|
totalMem = 0;
|
|
13
14
|
static detectEnv() {
|
|
14
|
-
if (typeof process !== 'undefined'
|
|
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())
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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.
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
33
|
-
|
|
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
|
|
44
|
-
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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.
|
|
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
|
|
18
|
-
|
|
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] =
|
|
24
|
+
result[i] = val != null ? String(val) : '';
|
|
21
25
|
}
|
|
22
26
|
return result;
|
|
23
27
|
}
|
|
24
|
-
extract
|
|
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
|
|
43
|
-
if (this.isMetricResult(first))
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
|
69
|
+
return out;
|
|
57
70
|
}
|
|
58
71
|
rebuild(results, sourceData, extractedStrings, removeZero, objectsOnly) {
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
-
|
|
99
|
-
|
|
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
|
|
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
|
|
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.
|
|
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
|