@n8n/utils 1.17.0 → 1.18.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 (55) hide show
  1. package/dist/assert.cjs +7 -5
  2. package/dist/assert.cjs.map +1 -1
  3. package/dist/assert.d.cts +3 -1
  4. package/dist/assert.d.ts +3 -1
  5. package/dist/assert.js +8 -7
  6. package/dist/assert.js.map +1 -1
  7. package/dist/event-bus.cjs +39 -35
  8. package/dist/event-bus.cjs.map +1 -1
  9. package/dist/event-bus.d.cts +9 -9
  10. package/dist/event-bus.d.ts +9 -9
  11. package/dist/event-bus.js +40 -37
  12. package/dist/event-bus.js.map +1 -1
  13. package/dist/event-queue.cjs +36 -25
  14. package/dist/event-queue.cjs.map +1 -1
  15. package/dist/event-queue.d.cts +4 -2
  16. package/dist/event-queue.d.ts +4 -2
  17. package/dist/event-queue.js +37 -27
  18. package/dist/event-queue.js.map +1 -1
  19. package/dist/number/smartDecimal.cjs +7 -10
  20. package/dist/number/smartDecimal.cjs.map +1 -1
  21. package/dist/number/smartDecimal.d.cts +3 -1
  22. package/dist/number/smartDecimal.d.ts +3 -1
  23. package/dist/number/smartDecimal.js +8 -12
  24. package/dist/number/smartDecimal.js.map +1 -1
  25. package/dist/retry.cjs +35 -26
  26. package/dist/retry.cjs.map +1 -1
  27. package/dist/retry.d.cts +3 -1
  28. package/dist/retry.d.ts +3 -1
  29. package/dist/retry.js +36 -28
  30. package/dist/retry.js.map +1 -1
  31. package/dist/search/reRankSearchResults.cjs +15 -17
  32. package/dist/search/reRankSearchResults.cjs.map +1 -1
  33. package/dist/search/reRankSearchResults.d.cts +8 -6
  34. package/dist/search/reRankSearchResults.d.ts +8 -6
  35. package/dist/search/reRankSearchResults.js +16 -19
  36. package/dist/search/reRankSearchResults.js.map +1 -1
  37. package/dist/search/sublimeSearch.cjs +161 -186
  38. package/dist/search/sublimeSearch.cjs.map +1 -1
  39. package/dist/search/sublimeSearch.d.cts +9 -7
  40. package/dist/search/sublimeSearch.d.ts +9 -7
  41. package/dist/search/sublimeSearch.js +160 -187
  42. package/dist/search/sublimeSearch.js.map +1 -1
  43. package/dist/sort/sortByProperty.cjs +9 -8
  44. package/dist/sort/sortByProperty.cjs.map +1 -1
  45. package/dist/sort/sortByProperty.d.cts +3 -1
  46. package/dist/sort/sortByProperty.d.ts +3 -1
  47. package/dist/sort/sortByProperty.js +10 -10
  48. package/dist/sort/sortByProperty.js.map +1 -1
  49. package/dist/string/truncate.cjs +27 -27
  50. package/dist/string/truncate.cjs.map +1 -1
  51. package/dist/string/truncate.d.cts +3 -1
  52. package/dist/string/truncate.d.ts +3 -1
  53. package/dist/string/truncate.js +26 -28
  54. package/dist/string/truncate.js.map +1 -1
  55. package/package.json +8 -8
@@ -1,198 +1,173 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/search/sublimeSearch.ts
2
- var SEQUENTIAL_BONUS = 60;
3
- var SEPARATOR_BONUS = 38;
4
- var CAMEL_BONUS = 30;
5
- var FIRST_LETTER_BONUS = 15;
6
- var LEADING_LETTER_PENALTY = -20;
7
- var MAX_LEADING_LETTER_PENALTY = -200;
8
- var UNMATCHED_LETTER_PENALTY = -5;
9
- var DEFAULT_KEYS = [
10
- { key: "properties.displayName", weight: 1.3 },
11
- { key: "properties.codex.alias", weight: 1 }
12
- ];
1
+
2
+ //#region src/search/sublimeSearch.ts
3
+ const SEQUENTIAL_BONUS = 60;
4
+ const SEPARATOR_BONUS = 38;
5
+ const CAMEL_BONUS = 30;
6
+ const FIRST_LETTER_BONUS = 15;
7
+ const LEADING_LETTER_PENALTY = -20;
8
+ const MAX_LEADING_LETTER_PENALTY = -200;
9
+ const UNMATCHED_LETTER_PENALTY = -5;
10
+ const DEFAULT_KEYS = [{
11
+ key: "properties.displayName",
12
+ weight: 1.3
13
+ }, {
14
+ key: "properties.codex.alias",
15
+ weight: 1
16
+ }];
17
+ /**
18
+ * Returns true if each character in pattern is found sequentially within target
19
+ * @param {*} pattern string
20
+ * @param {*} target string
21
+ */
13
22
  function fuzzyMatchSimple(pattern, target) {
14
- let patternIdx = 0;
15
- let strIdx = 0;
16
- while (patternIdx < pattern.length && strIdx < target.length) {
17
- const patternChar = pattern.charAt(patternIdx).toLowerCase();
18
- const targetChar = target.charAt(strIdx).toLowerCase();
19
- if (patternChar === targetChar) {
20
- patternIdx++;
21
- }
22
- ++strIdx;
23
- }
24
- return pattern.length !== 0 && target.length !== 0 && patternIdx === pattern.length;
23
+ let patternIdx = 0;
24
+ let strIdx = 0;
25
+ while (patternIdx < pattern.length && strIdx < target.length) {
26
+ if (pattern.charAt(patternIdx).toLowerCase() === target.charAt(strIdx).toLowerCase()) patternIdx++;
27
+ ++strIdx;
28
+ }
29
+ return pattern.length !== 0 && target.length !== 0 && patternIdx === pattern.length;
25
30
  }
26
31
  function fuzzyMatchRecursive(pattern, target, patternCurIndex, targetCurrIndex, targetMatches, matches, maxMatches, nextMatch, recursionCount, recursionLimit) {
27
- let outScore = 0;
28
- if (++recursionCount >= recursionLimit) {
29
- return { matched: false, outScore };
30
- }
31
- if (patternCurIndex === pattern.length || targetCurrIndex === target.length) {
32
- return { matched: false, outScore };
33
- }
34
- let recursiveMatch = false;
35
- let bestRecursiveMatches = [];
36
- let bestRecursiveScore = 0;
37
- let firstMatch = true;
38
- while (patternCurIndex < pattern.length && targetCurrIndex < target.length) {
39
- if (pattern[patternCurIndex].toLowerCase() === target[targetCurrIndex].toLowerCase()) {
40
- if (nextMatch >= maxMatches) {
41
- return { matched: false, outScore };
42
- }
43
- if (firstMatch && targetMatches) {
44
- matches = [...targetMatches];
45
- firstMatch = false;
46
- }
47
- const recursiveMatches = [];
48
- const recursiveResult = fuzzyMatchRecursive(
49
- pattern,
50
- target,
51
- patternCurIndex,
52
- targetCurrIndex + 1,
53
- matches,
54
- recursiveMatches,
55
- maxMatches,
56
- nextMatch,
57
- recursionCount,
58
- recursionLimit
59
- );
60
- const recursiveScore = recursiveResult.outScore;
61
- if (recursiveResult.matched) {
62
- if (!recursiveMatch || recursiveScore > bestRecursiveScore) {
63
- bestRecursiveMatches = [...recursiveMatches];
64
- bestRecursiveScore = recursiveScore;
65
- }
66
- recursiveMatch = true;
67
- }
68
- matches[nextMatch++] = targetCurrIndex;
69
- ++patternCurIndex;
70
- }
71
- ++targetCurrIndex;
72
- }
73
- const matched = patternCurIndex === pattern.length;
74
- if (matched) {
75
- outScore = 100;
76
- if (!target.toLowerCase().startsWith("n8n")) {
77
- let penalty = LEADING_LETTER_PENALTY * matches[0];
78
- penalty = penalty < MAX_LEADING_LETTER_PENALTY ? MAX_LEADING_LETTER_PENALTY : penalty;
79
- outScore += penalty;
80
- }
81
- const unmatched = target.length - nextMatch;
82
- outScore += UNMATCHED_LETTER_PENALTY * unmatched;
83
- for (let i = 0; i < nextMatch; i++) {
84
- const currIdx = matches[i];
85
- if (i > 0) {
86
- const prevIdx = matches[i - 1];
87
- if (currIdx === prevIdx + 1) {
88
- outScore += SEQUENTIAL_BONUS;
89
- }
90
- }
91
- if (currIdx > 0) {
92
- const neighbor = target[currIdx - 1];
93
- const curr = target[currIdx];
94
- if (neighbor !== neighbor.toUpperCase() && curr !== curr.toLowerCase()) {
95
- outScore += CAMEL_BONUS;
96
- }
97
- const isNeighbourSeparator = neighbor === "_" || neighbor === " ";
98
- if (isNeighbourSeparator) {
99
- outScore += SEPARATOR_BONUS;
100
- }
101
- } else {
102
- outScore += FIRST_LETTER_BONUS;
103
- }
104
- }
105
- if (recursiveMatch && (!matched || bestRecursiveScore > outScore)) {
106
- matches = [...bestRecursiveMatches];
107
- outScore = bestRecursiveScore;
108
- return { matched: true, outScore };
109
- } else if (matched) {
110
- return { matched: true, outScore };
111
- } else {
112
- return { matched: false, outScore };
113
- }
114
- }
115
- return { matched: false, outScore };
32
+ let outScore = 0;
33
+ if (++recursionCount >= recursionLimit) return {
34
+ matched: false,
35
+ outScore
36
+ };
37
+ if (patternCurIndex === pattern.length || targetCurrIndex === target.length) return {
38
+ matched: false,
39
+ outScore
40
+ };
41
+ let recursiveMatch = false;
42
+ let bestRecursiveMatches = [];
43
+ let bestRecursiveScore = 0;
44
+ let firstMatch = true;
45
+ while (patternCurIndex < pattern.length && targetCurrIndex < target.length) {
46
+ if (pattern[patternCurIndex].toLowerCase() === target[targetCurrIndex].toLowerCase()) {
47
+ if (nextMatch >= maxMatches) return {
48
+ matched: false,
49
+ outScore
50
+ };
51
+ if (firstMatch && targetMatches) {
52
+ matches = [...targetMatches];
53
+ firstMatch = false;
54
+ }
55
+ const recursiveMatches = [];
56
+ const recursiveResult = fuzzyMatchRecursive(pattern, target, patternCurIndex, targetCurrIndex + 1, matches, recursiveMatches, maxMatches, nextMatch, recursionCount, recursionLimit);
57
+ const recursiveScore = recursiveResult.outScore;
58
+ if (recursiveResult.matched) {
59
+ if (!recursiveMatch || recursiveScore > bestRecursiveScore) {
60
+ bestRecursiveMatches = [...recursiveMatches];
61
+ bestRecursiveScore = recursiveScore;
62
+ }
63
+ recursiveMatch = true;
64
+ }
65
+ matches[nextMatch++] = targetCurrIndex;
66
+ ++patternCurIndex;
67
+ }
68
+ ++targetCurrIndex;
69
+ }
70
+ const matched = patternCurIndex === pattern.length;
71
+ if (matched) {
72
+ outScore = 100;
73
+ if (!target.toLowerCase().startsWith("n8n")) {
74
+ let penalty = LEADING_LETTER_PENALTY * matches[0];
75
+ penalty = penalty < MAX_LEADING_LETTER_PENALTY ? MAX_LEADING_LETTER_PENALTY : penalty;
76
+ outScore += penalty;
77
+ }
78
+ const unmatched = target.length - nextMatch;
79
+ outScore += UNMATCHED_LETTER_PENALTY * unmatched;
80
+ for (let i = 0; i < nextMatch; i++) {
81
+ const currIdx = matches[i];
82
+ if (i > 0) {
83
+ if (currIdx === matches[i - 1] + 1) outScore += SEQUENTIAL_BONUS;
84
+ }
85
+ if (currIdx > 0) {
86
+ const neighbor = target[currIdx - 1];
87
+ const curr = target[currIdx];
88
+ if (neighbor !== neighbor.toUpperCase() && curr !== curr.toLowerCase()) outScore += CAMEL_BONUS;
89
+ if (neighbor === "_" || neighbor === " ") outScore += SEPARATOR_BONUS;
90
+ } else outScore += FIRST_LETTER_BONUS;
91
+ }
92
+ if (recursiveMatch && (!matched || bestRecursiveScore > outScore)) {
93
+ matches = [...bestRecursiveMatches];
94
+ outScore = bestRecursiveScore;
95
+ return {
96
+ matched: true,
97
+ outScore
98
+ };
99
+ } else if (matched) return {
100
+ matched: true,
101
+ outScore
102
+ };
103
+ else return {
104
+ matched: false,
105
+ outScore
106
+ };
107
+ }
108
+ return {
109
+ matched: false,
110
+ outScore
111
+ };
116
112
  }
113
+ /**
114
+ * Does a fuzzy search to find pattern inside a string.
115
+ * @param {*} pattern string pattern to search for
116
+ * @param {*} target string string which is being searched
117
+ * @returns [boolean, number] a boolean which tells if pattern was
118
+ * found or not and a search score
119
+ */
117
120
  function fuzzyMatch(pattern, target) {
118
- const recursionCount = 0;
119
- const recursionLimit = 5;
120
- const matches = [];
121
- const maxMatches = 256;
122
- return fuzzyMatchRecursive(
123
- pattern,
124
- target,
125
- 0,
126
- 0,
127
- null,
128
- matches,
129
- maxMatches,
130
- 0,
131
- recursionCount,
132
- recursionLimit
133
- );
121
+ return fuzzyMatchRecursive(pattern, target, 0, 0, null, [], 256, 0, 0, 5);
134
122
  }
135
123
  function getValue(obj, prop) {
136
- if (obj.hasOwnProperty(prop)) {
137
- return obj[prop];
138
- }
139
- const segments = prop.split(".");
140
- let result = obj;
141
- let i = 0;
142
- while (result && i < segments.length) {
143
- const key = segments[i];
144
- result = result[key];
145
- i++;
146
- }
147
- return result;
124
+ if (obj.hasOwnProperty(prop)) return obj[prop];
125
+ const segments = prop.split(".");
126
+ let result = obj;
127
+ let i = 0;
128
+ while (result && i < segments.length) {
129
+ const key = segments[i];
130
+ result = result[key];
131
+ i++;
132
+ }
133
+ return result;
148
134
  }
149
135
  function sublimeSearch(filter, data, keys = DEFAULT_KEYS) {
150
- const results = data.reduce((accu, item) => {
151
- let values = [];
152
- keys.forEach(({ key, weight }) => {
153
- const value = getValue(item, key);
154
- if (Array.isArray(value)) {
155
- values = values.concat(value.map((v) => ({ value: v, weight })));
156
- } else if (typeof value === "string") {
157
- values.push({
158
- value,
159
- weight
160
- });
161
- }
162
- });
163
- const itemMatch = values.reduce(
164
- (result, { value, weight }) => {
165
- if (!fuzzyMatchSimple(filter, value)) {
166
- return result;
167
- }
168
- const match = fuzzyMatch(filter, value);
169
- match.outScore *= weight;
170
- const { matched, outScore } = match;
171
- if (!result && matched) {
172
- return match;
173
- }
174
- if (matched && result && outScore > result.outScore) {
175
- return match;
176
- }
177
- return result;
178
- },
179
- null
180
- );
181
- if (itemMatch) {
182
- accu.push({
183
- score: itemMatch.outScore,
184
- item
185
- });
186
- }
187
- return accu;
188
- }, []);
189
- results.sort((a, b) => {
190
- return b.score - a.score;
191
- });
192
- return results;
136
+ const results = data.reduce((accu, item) => {
137
+ let values = [];
138
+ keys.forEach(({ key, weight }) => {
139
+ const value = getValue(item, key);
140
+ if (Array.isArray(value)) values = values.concat(value.map((v) => ({
141
+ value: v,
142
+ weight
143
+ })));
144
+ else if (typeof value === "string") values.push({
145
+ value,
146
+ weight
147
+ });
148
+ });
149
+ const itemMatch = values.reduce((result, { value, weight }) => {
150
+ if (!fuzzyMatchSimple(filter, value)) return result;
151
+ const match = fuzzyMatch(filter, value);
152
+ match.outScore *= weight;
153
+ const { matched, outScore } = match;
154
+ if (!result && matched) return match;
155
+ if (matched && result && outScore > result.outScore) return match;
156
+ return result;
157
+ }, null);
158
+ if (itemMatch) accu.push({
159
+ score: itemMatch.outScore,
160
+ item
161
+ });
162
+ return accu;
163
+ }, []);
164
+ results.sort((a, b) => {
165
+ return b.score - a.score;
166
+ });
167
+ return results;
193
168
  }
194
169
 
195
-
196
-
197
- exports.DEFAULT_KEYS = DEFAULT_KEYS; exports.sublimeSearch = sublimeSearch;
170
+ //#endregion
171
+ exports.DEFAULT_KEYS = DEFAULT_KEYS;
172
+ exports.sublimeSearch = sublimeSearch;
198
173
  //# sourceMappingURL=sublimeSearch.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/n8n/n8n/packages/@n8n/utils/dist/search/sublimeSearch.cjs","../../src/search/sublimeSearch.ts"],"names":[],"mappings":"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","file":"/home/runner/work/n8n/n8n/packages/@n8n/utils/dist/search/sublimeSearch.cjs","sourcesContent":[null,"/*\n * Constants and utility functions used for searching for node types in node creator component\n * based on https://github.com/forrestthewoods/lib_fts/blob/master/code/fts_fuzzy_match.js\n */\n\nconst SEQUENTIAL_BONUS = 60; // bonus for adjacent matches\nconst SEPARATOR_BONUS = 38; // bonus if match occurs after a separator\nconst CAMEL_BONUS = 30; // bonus if match is uppercase and prev is lower\nconst FIRST_LETTER_BONUS = 15; // bonus if the first letter is matched\n\nconst LEADING_LETTER_PENALTY = -20; // penalty applied for every letter in str before the first match\nconst MAX_LEADING_LETTER_PENALTY = -200; // maximum penalty for leading letters\nconst UNMATCHED_LETTER_PENALTY = -5;\n\nexport const DEFAULT_KEYS = [\n\t{ key: 'properties.displayName', weight: 1.3 },\n\t{ key: 'properties.codex.alias', weight: 1 },\n];\n\n/**\n * Returns true if each character in pattern is found sequentially within target\n * @param {*} pattern string\n * @param {*} target string\n */\nfunction fuzzyMatchSimple(pattern: string, target: string): boolean {\n\tlet patternIdx = 0;\n\tlet strIdx = 0;\n\n\twhile (patternIdx < pattern.length && strIdx < target.length) {\n\t\tconst patternChar = pattern.charAt(patternIdx).toLowerCase();\n\t\tconst targetChar = target.charAt(strIdx).toLowerCase();\n\t\tif (patternChar === targetChar) {\n\t\t\tpatternIdx++;\n\t\t}\n\t\t++strIdx;\n\t}\n\n\treturn pattern.length !== 0 && target.length !== 0 && patternIdx === pattern.length;\n}\n\nfunction fuzzyMatchRecursive(\n\tpattern: string,\n\ttarget: string,\n\tpatternCurIndex: number,\n\ttargetCurrIndex: number,\n\ttargetMatches: null | number[],\n\tmatches: number[],\n\tmaxMatches: number,\n\tnextMatch: number,\n\trecursionCount: number,\n\trecursionLimit: number,\n): { matched: boolean; outScore: number } {\n\tlet outScore = 0;\n\n\t// Return if recursion limit is reached.\n\tif (++recursionCount >= recursionLimit) {\n\t\treturn { matched: false, outScore };\n\t}\n\n\t// Return if we reached ends of strings.\n\tif (patternCurIndex === pattern.length || targetCurrIndex === target.length) {\n\t\treturn { matched: false, outScore };\n\t}\n\n\t// Recursion params\n\tlet recursiveMatch = false;\n\tlet bestRecursiveMatches: number[] = [];\n\tlet bestRecursiveScore = 0;\n\n\t// Loop through pattern and str looking for a match.\n\tlet firstMatch = true;\n\twhile (patternCurIndex < pattern.length && targetCurrIndex < target.length) {\n\t\t// Match found.\n\t\tif (pattern[patternCurIndex].toLowerCase() === target[targetCurrIndex].toLowerCase()) {\n\t\t\tif (nextMatch >= maxMatches) {\n\t\t\t\treturn { matched: false, outScore };\n\t\t\t}\n\n\t\t\tif (firstMatch && targetMatches) {\n\t\t\t\tmatches = [...targetMatches];\n\t\t\t\tfirstMatch = false;\n\t\t\t}\n\n\t\t\tconst recursiveMatches: number[] = [];\n\t\t\tconst recursiveResult = fuzzyMatchRecursive(\n\t\t\t\tpattern,\n\t\t\t\ttarget,\n\t\t\t\tpatternCurIndex,\n\t\t\t\ttargetCurrIndex + 1,\n\t\t\t\tmatches,\n\t\t\t\trecursiveMatches,\n\t\t\t\tmaxMatches,\n\t\t\t\tnextMatch,\n\t\t\t\trecursionCount,\n\t\t\t\trecursionLimit,\n\t\t\t);\n\n\t\t\tconst recursiveScore = recursiveResult.outScore;\n\t\t\tif (recursiveResult.matched) {\n\t\t\t\t// Pick best recursive score.\n\t\t\t\tif (!recursiveMatch || recursiveScore > bestRecursiveScore) {\n\t\t\t\t\tbestRecursiveMatches = [...recursiveMatches];\n\t\t\t\t\tbestRecursiveScore = recursiveScore;\n\t\t\t\t}\n\t\t\t\trecursiveMatch = true;\n\t\t\t}\n\n\t\t\tmatches[nextMatch++] = targetCurrIndex;\n\t\t\t++patternCurIndex;\n\t\t}\n\t\t++targetCurrIndex;\n\t}\n\n\tconst matched = patternCurIndex === pattern.length;\n\n\tif (matched) {\n\t\toutScore = 100;\n\n\t\t// Apply leading letter penalty (if not n8n-prefixed)\n\t\tif (!target.toLowerCase().startsWith('n8n')) {\n\t\t\tlet penalty = LEADING_LETTER_PENALTY * matches[0];\n\t\t\tpenalty = penalty < MAX_LEADING_LETTER_PENALTY ? MAX_LEADING_LETTER_PENALTY : penalty;\n\t\t\toutScore += penalty;\n\t\t}\n\n\t\t//Apply unmatched penalty\n\t\tconst unmatched = target.length - nextMatch;\n\t\toutScore += UNMATCHED_LETTER_PENALTY * unmatched;\n\n\t\t// Apply ordering bonuses\n\t\tfor (let i = 0; i < nextMatch; i++) {\n\t\t\tconst currIdx = matches[i];\n\n\t\t\tif (i > 0) {\n\t\t\t\tconst prevIdx = matches[i - 1];\n\t\t\t\tif (currIdx === prevIdx + 1) {\n\t\t\t\t\toutScore += SEQUENTIAL_BONUS;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check for bonuses based on neighbor character value.\n\t\t\tif (currIdx > 0) {\n\t\t\t\t// Camel case\n\t\t\t\tconst neighbor = target[currIdx - 1];\n\t\t\t\tconst curr = target[currIdx];\n\t\t\t\tif (neighbor !== neighbor.toUpperCase() && curr !== curr.toLowerCase()) {\n\t\t\t\t\toutScore += CAMEL_BONUS;\n\t\t\t\t}\n\t\t\t\tconst isNeighbourSeparator = neighbor === '_' || neighbor === ' ';\n\t\t\t\tif (isNeighbourSeparator) {\n\t\t\t\t\toutScore += SEPARATOR_BONUS;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// First letter\n\t\t\t\toutScore += FIRST_LETTER_BONUS;\n\t\t\t}\n\t\t}\n\n\t\t// Return best result\n\t\tif (recursiveMatch && (!matched || bestRecursiveScore > outScore)) {\n\t\t\t// Recursive score is better than \"this\"\n\t\t\tmatches = [...bestRecursiveMatches];\n\t\t\toutScore = bestRecursiveScore;\n\t\t\treturn { matched: true, outScore };\n\t\t} else if (matched) {\n\t\t\t// \"this\" score is better than recursive\n\t\t\treturn { matched: true, outScore };\n\t\t} else {\n\t\t\treturn { matched: false, outScore };\n\t\t}\n\t}\n\treturn { matched: false, outScore };\n}\n\n/**\n * Does a fuzzy search to find pattern inside a string.\n * @param {*} pattern string pattern to search for\n * @param {*} target string string which is being searched\n * @returns [boolean, number] a boolean which tells if pattern was\n * found or not and a search score\n */\nfunction fuzzyMatch(pattern: string, target: string): { matched: boolean; outScore: number } {\n\tconst recursionCount = 0;\n\tconst recursionLimit = 5;\n\tconst matches: number[] = [];\n\tconst maxMatches = 256;\n\n\treturn fuzzyMatchRecursive(\n\t\tpattern,\n\t\ttarget,\n\t\t0 /* patternCurIndex */,\n\t\t0 /* strCurrIndex */,\n\t\tnull /* srcMatces */,\n\t\tmatches,\n\t\tmaxMatches,\n\t\t0 /* nextMatch */,\n\t\trecursionCount,\n\t\trecursionLimit,\n\t);\n}\n\n// prop = 'key'\n// prop = 'key1.key2'\n// prop = ['key1', 'key2']\nfunction getValue<T extends object>(obj: T, prop: string): unknown {\n\tif (obj.hasOwnProperty(prop)) {\n\t\treturn obj[prop as keyof T];\n\t}\n\n\tconst segments = prop.split('.');\n\n\tlet result = obj;\n\tlet i = 0;\n\twhile (result && i < segments.length) {\n\t\tconst key = segments[i] as keyof T;\n\t\tresult = result[key] as T;\n\t\ti++;\n\t}\n\treturn result;\n}\n\nexport function sublimeSearch<T extends object>(\n\tfilter: string,\n\tdata: readonly T[],\n\tkeys: Array<{ key: string; weight: number }> = DEFAULT_KEYS,\n): Array<{ score: number; item: T }> {\n\tconst results = data.reduce((accu: Array<{ score: number; item: T }>, item: T) => {\n\t\tlet values: Array<{ value: string; weight: number }> = [];\n\t\tkeys.forEach(({ key, weight }) => {\n\t\t\tconst value = getValue(item, key);\n\t\t\tif (Array.isArray(value)) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\t\tvalues = values.concat(value.map((v) => ({ value: v, weight })));\n\t\t\t} else if (typeof value === 'string') {\n\t\t\t\tvalues.push({\n\t\t\t\t\tvalue,\n\t\t\t\t\tweight,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// for each item, check every key and get maximum score\n\t\tconst itemMatch = values.reduce(\n\t\t\t(\n\t\t\t\tresult: null | { matched: boolean; outScore: number },\n\t\t\t\t{ value, weight }: { value: string; weight: number },\n\t\t\t) => {\n\t\t\t\tif (!fuzzyMatchSimple(filter, value)) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tconst match = fuzzyMatch(filter, value);\n\t\t\t\tmatch.outScore *= weight;\n\n\t\t\t\tconst { matched, outScore } = match;\n\t\t\t\tif (!result && matched) {\n\t\t\t\t\treturn match;\n\t\t\t\t}\n\t\t\t\tif (matched && result && outScore > result.outScore) {\n\t\t\t\t\treturn match;\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t},\n\t\t\tnull,\n\t\t);\n\n\t\tif (itemMatch) {\n\t\t\taccu.push({\n\t\t\t\tscore: itemMatch.outScore,\n\t\t\t\titem,\n\t\t\t});\n\t\t}\n\n\t\treturn accu;\n\t}, []);\n\n\tresults.sort((a, b) => {\n\t\treturn b.score - a.score;\n\t});\n\n\treturn results;\n}\n"]}
1
+ {"version":3,"file":"sublimeSearch.cjs","names":["bestRecursiveMatches: number[]","recursiveMatches: number[]","values: Array<{ value: string; weight: number }>"],"sources":["../../src/search/sublimeSearch.ts"],"sourcesContent":["/*\n * Constants and utility functions used for searching for node types in node creator component\n * based on https://github.com/forrestthewoods/lib_fts/blob/master/code/fts_fuzzy_match.js\n */\n\nconst SEQUENTIAL_BONUS = 60; // bonus for adjacent matches\nconst SEPARATOR_BONUS = 38; // bonus if match occurs after a separator\nconst CAMEL_BONUS = 30; // bonus if match is uppercase and prev is lower\nconst FIRST_LETTER_BONUS = 15; // bonus if the first letter is matched\n\nconst LEADING_LETTER_PENALTY = -20; // penalty applied for every letter in str before the first match\nconst MAX_LEADING_LETTER_PENALTY = -200; // maximum penalty for leading letters\nconst UNMATCHED_LETTER_PENALTY = -5;\n\nexport const DEFAULT_KEYS = [\n\t{ key: 'properties.displayName', weight: 1.3 },\n\t{ key: 'properties.codex.alias', weight: 1 },\n];\n\n/**\n * Returns true if each character in pattern is found sequentially within target\n * @param {*} pattern string\n * @param {*} target string\n */\nfunction fuzzyMatchSimple(pattern: string, target: string): boolean {\n\tlet patternIdx = 0;\n\tlet strIdx = 0;\n\n\twhile (patternIdx < pattern.length && strIdx < target.length) {\n\t\tconst patternChar = pattern.charAt(patternIdx).toLowerCase();\n\t\tconst targetChar = target.charAt(strIdx).toLowerCase();\n\t\tif (patternChar === targetChar) {\n\t\t\tpatternIdx++;\n\t\t}\n\t\t++strIdx;\n\t}\n\n\treturn pattern.length !== 0 && target.length !== 0 && patternIdx === pattern.length;\n}\n\nfunction fuzzyMatchRecursive(\n\tpattern: string,\n\ttarget: string,\n\tpatternCurIndex: number,\n\ttargetCurrIndex: number,\n\ttargetMatches: null | number[],\n\tmatches: number[],\n\tmaxMatches: number,\n\tnextMatch: number,\n\trecursionCount: number,\n\trecursionLimit: number,\n): { matched: boolean; outScore: number } {\n\tlet outScore = 0;\n\n\t// Return if recursion limit is reached.\n\tif (++recursionCount >= recursionLimit) {\n\t\treturn { matched: false, outScore };\n\t}\n\n\t// Return if we reached ends of strings.\n\tif (patternCurIndex === pattern.length || targetCurrIndex === target.length) {\n\t\treturn { matched: false, outScore };\n\t}\n\n\t// Recursion params\n\tlet recursiveMatch = false;\n\tlet bestRecursiveMatches: number[] = [];\n\tlet bestRecursiveScore = 0;\n\n\t// Loop through pattern and str looking for a match.\n\tlet firstMatch = true;\n\twhile (patternCurIndex < pattern.length && targetCurrIndex < target.length) {\n\t\t// Match found.\n\t\tif (pattern[patternCurIndex].toLowerCase() === target[targetCurrIndex].toLowerCase()) {\n\t\t\tif (nextMatch >= maxMatches) {\n\t\t\t\treturn { matched: false, outScore };\n\t\t\t}\n\n\t\t\tif (firstMatch && targetMatches) {\n\t\t\t\tmatches = [...targetMatches];\n\t\t\t\tfirstMatch = false;\n\t\t\t}\n\n\t\t\tconst recursiveMatches: number[] = [];\n\t\t\tconst recursiveResult = fuzzyMatchRecursive(\n\t\t\t\tpattern,\n\t\t\t\ttarget,\n\t\t\t\tpatternCurIndex,\n\t\t\t\ttargetCurrIndex + 1,\n\t\t\t\tmatches,\n\t\t\t\trecursiveMatches,\n\t\t\t\tmaxMatches,\n\t\t\t\tnextMatch,\n\t\t\t\trecursionCount,\n\t\t\t\trecursionLimit,\n\t\t\t);\n\n\t\t\tconst recursiveScore = recursiveResult.outScore;\n\t\t\tif (recursiveResult.matched) {\n\t\t\t\t// Pick best recursive score.\n\t\t\t\tif (!recursiveMatch || recursiveScore > bestRecursiveScore) {\n\t\t\t\t\tbestRecursiveMatches = [...recursiveMatches];\n\t\t\t\t\tbestRecursiveScore = recursiveScore;\n\t\t\t\t}\n\t\t\t\trecursiveMatch = true;\n\t\t\t}\n\n\t\t\tmatches[nextMatch++] = targetCurrIndex;\n\t\t\t++patternCurIndex;\n\t\t}\n\t\t++targetCurrIndex;\n\t}\n\n\tconst matched = patternCurIndex === pattern.length;\n\n\tif (matched) {\n\t\toutScore = 100;\n\n\t\t// Apply leading letter penalty (if not n8n-prefixed)\n\t\tif (!target.toLowerCase().startsWith('n8n')) {\n\t\t\tlet penalty = LEADING_LETTER_PENALTY * matches[0];\n\t\t\tpenalty = penalty < MAX_LEADING_LETTER_PENALTY ? MAX_LEADING_LETTER_PENALTY : penalty;\n\t\t\toutScore += penalty;\n\t\t}\n\n\t\t//Apply unmatched penalty\n\t\tconst unmatched = target.length - nextMatch;\n\t\toutScore += UNMATCHED_LETTER_PENALTY * unmatched;\n\n\t\t// Apply ordering bonuses\n\t\tfor (let i = 0; i < nextMatch; i++) {\n\t\t\tconst currIdx = matches[i];\n\n\t\t\tif (i > 0) {\n\t\t\t\tconst prevIdx = matches[i - 1];\n\t\t\t\tif (currIdx === prevIdx + 1) {\n\t\t\t\t\toutScore += SEQUENTIAL_BONUS;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check for bonuses based on neighbor character value.\n\t\t\tif (currIdx > 0) {\n\t\t\t\t// Camel case\n\t\t\t\tconst neighbor = target[currIdx - 1];\n\t\t\t\tconst curr = target[currIdx];\n\t\t\t\tif (neighbor !== neighbor.toUpperCase() && curr !== curr.toLowerCase()) {\n\t\t\t\t\toutScore += CAMEL_BONUS;\n\t\t\t\t}\n\t\t\t\tconst isNeighbourSeparator = neighbor === '_' || neighbor === ' ';\n\t\t\t\tif (isNeighbourSeparator) {\n\t\t\t\t\toutScore += SEPARATOR_BONUS;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// First letter\n\t\t\t\toutScore += FIRST_LETTER_BONUS;\n\t\t\t}\n\t\t}\n\n\t\t// Return best result\n\t\tif (recursiveMatch && (!matched || bestRecursiveScore > outScore)) {\n\t\t\t// Recursive score is better than \"this\"\n\t\t\tmatches = [...bestRecursiveMatches];\n\t\t\toutScore = bestRecursiveScore;\n\t\t\treturn { matched: true, outScore };\n\t\t} else if (matched) {\n\t\t\t// \"this\" score is better than recursive\n\t\t\treturn { matched: true, outScore };\n\t\t} else {\n\t\t\treturn { matched: false, outScore };\n\t\t}\n\t}\n\treturn { matched: false, outScore };\n}\n\n/**\n * Does a fuzzy search to find pattern inside a string.\n * @param {*} pattern string pattern to search for\n * @param {*} target string string which is being searched\n * @returns [boolean, number] a boolean which tells if pattern was\n * found or not and a search score\n */\nfunction fuzzyMatch(pattern: string, target: string): { matched: boolean; outScore: number } {\n\tconst recursionCount = 0;\n\tconst recursionLimit = 5;\n\tconst matches: number[] = [];\n\tconst maxMatches = 256;\n\n\treturn fuzzyMatchRecursive(\n\t\tpattern,\n\t\ttarget,\n\t\t0 /* patternCurIndex */,\n\t\t0 /* strCurrIndex */,\n\t\tnull /* srcMatces */,\n\t\tmatches,\n\t\tmaxMatches,\n\t\t0 /* nextMatch */,\n\t\trecursionCount,\n\t\trecursionLimit,\n\t);\n}\n\n// prop = 'key'\n// prop = 'key1.key2'\n// prop = ['key1', 'key2']\nfunction getValue<T extends object>(obj: T, prop: string): unknown {\n\tif (obj.hasOwnProperty(prop)) {\n\t\treturn obj[prop as keyof T];\n\t}\n\n\tconst segments = prop.split('.');\n\n\tlet result = obj;\n\tlet i = 0;\n\twhile (result && i < segments.length) {\n\t\tconst key = segments[i] as keyof T;\n\t\tresult = result[key] as T;\n\t\ti++;\n\t}\n\treturn result;\n}\n\nexport function sublimeSearch<T extends object>(\n\tfilter: string,\n\tdata: readonly T[],\n\tkeys: Array<{ key: string; weight: number }> = DEFAULT_KEYS,\n): Array<{ score: number; item: T }> {\n\tconst results = data.reduce((accu: Array<{ score: number; item: T }>, item: T) => {\n\t\tlet values: Array<{ value: string; weight: number }> = [];\n\t\tkeys.forEach(({ key, weight }) => {\n\t\t\tconst value = getValue(item, key);\n\t\t\tif (Array.isArray(value)) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\t\tvalues = values.concat(value.map((v) => ({ value: v, weight })));\n\t\t\t} else if (typeof value === 'string') {\n\t\t\t\tvalues.push({\n\t\t\t\t\tvalue,\n\t\t\t\t\tweight,\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t// for each item, check every key and get maximum score\n\t\tconst itemMatch = values.reduce(\n\t\t\t(\n\t\t\t\tresult: null | { matched: boolean; outScore: number },\n\t\t\t\t{ value, weight }: { value: string; weight: number },\n\t\t\t) => {\n\t\t\t\tif (!fuzzyMatchSimple(filter, value)) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tconst match = fuzzyMatch(filter, value);\n\t\t\t\tmatch.outScore *= weight;\n\n\t\t\t\tconst { matched, outScore } = match;\n\t\t\t\tif (!result && matched) {\n\t\t\t\t\treturn match;\n\t\t\t\t}\n\t\t\t\tif (matched && result && outScore > result.outScore) {\n\t\t\t\t\treturn match;\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t},\n\t\t\tnull,\n\t\t);\n\n\t\tif (itemMatch) {\n\t\t\taccu.push({\n\t\t\t\tscore: itemMatch.outScore,\n\t\t\t\titem,\n\t\t\t});\n\t\t}\n\n\t\treturn accu;\n\t}, []);\n\n\tresults.sort((a, b) => {\n\t\treturn b.score - a.score;\n\t});\n\n\treturn results;\n}\n"],"mappings":"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"}
@@ -1,13 +1,15 @@
1
+ //#region src/search/sublimeSearch.d.ts
1
2
  declare const DEFAULT_KEYS: {
2
- key: string;
3
- weight: number;
3
+ key: string;
4
+ weight: number;
4
5
  }[];
5
6
  declare function sublimeSearch<T extends object>(filter: string, data: readonly T[], keys?: Array<{
6
- key: string;
7
- weight: number;
7
+ key: string;
8
+ weight: number;
8
9
  }>): Array<{
9
- score: number;
10
- item: T;
10
+ score: number;
11
+ item: T;
11
12
  }>;
12
-
13
+ //#endregion
13
14
  export { DEFAULT_KEYS, sublimeSearch };
15
+ //# sourceMappingURL=sublimeSearch.d.cts.map
@@ -1,13 +1,15 @@
1
+ //#region src/search/sublimeSearch.d.ts
1
2
  declare const DEFAULT_KEYS: {
2
- key: string;
3
- weight: number;
3
+ key: string;
4
+ weight: number;
4
5
  }[];
5
6
  declare function sublimeSearch<T extends object>(filter: string, data: readonly T[], keys?: Array<{
6
- key: string;
7
- weight: number;
7
+ key: string;
8
+ weight: number;
8
9
  }>): Array<{
9
- score: number;
10
- item: T;
10
+ score: number;
11
+ item: T;
11
12
  }>;
12
-
13
+ //#endregion
13
14
  export { DEFAULT_KEYS, sublimeSearch };
15
+ //# sourceMappingURL=sublimeSearch.d.ts.map