@atom8n/utils 1.21.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 (106) hide show
  1. package/README.md +25 -0
  2. package/dist/assert.cjs +3 -0
  3. package/dist/assert.d.cts +2 -0
  4. package/dist/assert.d.mts +2 -0
  5. package/dist/assert.mjs +3 -0
  6. package/dist/assert2.cjs +17 -0
  7. package/dist/assert2.cjs.map +1 -0
  8. package/dist/assert2.d.cts +5 -0
  9. package/dist/assert2.d.mts +5 -0
  10. package/dist/assert2.mjs +11 -0
  11. package/dist/assert2.mjs.map +1 -0
  12. package/dist/event-bus.cjs +3 -0
  13. package/dist/event-bus.d.cts +2 -0
  14. package/dist/event-bus.d.mts +2 -0
  15. package/dist/event-bus.mjs +3 -0
  16. package/dist/event-bus2.cjs +49 -0
  17. package/dist/event-bus2.cjs.map +1 -0
  18. package/dist/event-bus2.d.cts +14 -0
  19. package/dist/event-bus2.d.mts +14 -0
  20. package/dist/event-bus2.mjs +43 -0
  21. package/dist/event-bus2.mjs.map +1 -0
  22. package/dist/event-queue.cjs +3 -0
  23. package/dist/event-queue.d.cts +2 -0
  24. package/dist/event-queue.d.mts +2 -0
  25. package/dist/event-queue.mjs +3 -0
  26. package/dist/event-queue2.cjs +46 -0
  27. package/dist/event-queue2.cjs.map +1 -0
  28. package/dist/event-queue2.d.cts +7 -0
  29. package/dist/event-queue2.d.mts +7 -0
  30. package/dist/event-queue2.mjs +40 -0
  31. package/dist/event-queue2.mjs.map +1 -0
  32. package/dist/files/sanitize.cjs +3 -0
  33. package/dist/files/sanitize.d.cts +2 -0
  34. package/dist/files/sanitize.d.mts +2 -0
  35. package/dist/files/sanitize.mjs +3 -0
  36. package/dist/index.cjs +23 -0
  37. package/dist/index.d.cts +11 -0
  38. package/dist/index.d.mts +11 -0
  39. package/dist/index.mjs +12 -0
  40. package/dist/number/smartDecimal.cjs +3 -0
  41. package/dist/number/smartDecimal.d.cts +2 -0
  42. package/dist/number/smartDecimal.d.mts +2 -0
  43. package/dist/number/smartDecimal.mjs +3 -0
  44. package/dist/reRankSearchResults.cjs +25 -0
  45. package/dist/reRankSearchResults.cjs.map +1 -0
  46. package/dist/reRankSearchResults.d.cts +13 -0
  47. package/dist/reRankSearchResults.d.mts +13 -0
  48. package/dist/reRankSearchResults.mjs +19 -0
  49. package/dist/reRankSearchResults.mjs.map +1 -0
  50. package/dist/retry.cjs +3 -0
  51. package/dist/retry.d.cts +2 -0
  52. package/dist/retry.d.mts +2 -0
  53. package/dist/retry.mjs +3 -0
  54. package/dist/retry2.cjs +45 -0
  55. package/dist/retry2.cjs.map +1 -0
  56. package/dist/retry2.d.cts +6 -0
  57. package/dist/retry2.d.mts +6 -0
  58. package/dist/retry2.mjs +39 -0
  59. package/dist/retry2.mjs.map +1 -0
  60. package/dist/sanitize.cjs +67 -0
  61. package/dist/sanitize.cjs.map +1 -0
  62. package/dist/sanitize.d.cts +5 -0
  63. package/dist/sanitize.d.mts +5 -0
  64. package/dist/sanitize.mjs +61 -0
  65. package/dist/sanitize.mjs.map +1 -0
  66. package/dist/search/reRankSearchResults.cjs +3 -0
  67. package/dist/search/reRankSearchResults.d.cts +2 -0
  68. package/dist/search/reRankSearchResults.d.mts +2 -0
  69. package/dist/search/reRankSearchResults.mjs +3 -0
  70. package/dist/search/sublimeSearch.cjs +4 -0
  71. package/dist/search/sublimeSearch.d.cts +2 -0
  72. package/dist/search/sublimeSearch.d.mts +2 -0
  73. package/dist/search/sublimeSearch.mjs +3 -0
  74. package/dist/smartDecimal.cjs +16 -0
  75. package/dist/smartDecimal.cjs.map +1 -0
  76. package/dist/smartDecimal.d.cts +5 -0
  77. package/dist/smartDecimal.d.mts +5 -0
  78. package/dist/smartDecimal.mjs +10 -0
  79. package/dist/smartDecimal.mjs.map +1 -0
  80. package/dist/sort/sortByProperty.cjs +3 -0
  81. package/dist/sort/sortByProperty.d.cts +2 -0
  82. package/dist/sort/sortByProperty.d.mts +2 -0
  83. package/dist/sort/sortByProperty.mjs +3 -0
  84. package/dist/sortByProperty.cjs +18 -0
  85. package/dist/sortByProperty.cjs.map +1 -0
  86. package/dist/sortByProperty.d.cts +5 -0
  87. package/dist/sortByProperty.d.mts +5 -0
  88. package/dist/sortByProperty.mjs +12 -0
  89. package/dist/sortByProperty.mjs.map +1 -0
  90. package/dist/string/truncate.cjs +4 -0
  91. package/dist/string/truncate.d.cts +2 -0
  92. package/dist/string/truncate.d.mts +2 -0
  93. package/dist/string/truncate.mjs +3 -0
  94. package/dist/sublimeSearch.cjs +183 -0
  95. package/dist/sublimeSearch.cjs.map +1 -0
  96. package/dist/sublimeSearch.d.cts +15 -0
  97. package/dist/sublimeSearch.d.mts +15 -0
  98. package/dist/sublimeSearch.mjs +171 -0
  99. package/dist/sublimeSearch.mjs.map +1 -0
  100. package/dist/truncate.cjs +42 -0
  101. package/dist/truncate.cjs.map +1 -0
  102. package/dist/truncate.d.cts +6 -0
  103. package/dist/truncate.d.mts +6 -0
  104. package/dist/truncate.mjs +30 -0
  105. package/dist/truncate.mjs.map +1 -0
  106. package/package.json +53 -0
@@ -0,0 +1,45 @@
1
+
2
+ //#region src/retry.ts
3
+ /**
4
+ * A utility that retries a function every `interval` milliseconds
5
+ * until the function returns true or the maximum number of retries is reached.
6
+ *
7
+ * @param fn - A function that returns a boolean or a Promise resolving to a boolean.
8
+ * @param interval - The time interval (in milliseconds) between each retry. Defaults to 1000.
9
+ * @param maxRetries - The maximum number of retry attempts. Defaults to 3.
10
+ * @param backoff - The backoff strategy to use: 'linear', 'exponential', or null.
11
+ * @returns {Promise<boolean>} - A promise that resolves to:
12
+ * - true: If the function returns true before reaching maxRetries.
13
+ * - false: If the function never returns true or if an error occurs.
14
+ */
15
+ async function retry(fn, interval = 1e3, maxRetries = 3, backoff = "linear") {
16
+ let attempt = 0;
17
+ while (attempt < maxRetries) {
18
+ attempt++;
19
+ try {
20
+ if (await fn()) return true;
21
+ } catch (error) {
22
+ console.error("Error during retry:", error);
23
+ throw error;
24
+ }
25
+ if (attempt < maxRetries) {
26
+ let computedInterval = interval;
27
+ if (backoff === "linear") computedInterval = interval * attempt;
28
+ else if (backoff === "exponential") {
29
+ computedInterval = Math.pow(2, attempt - 1) * interval;
30
+ computedInterval = Math.min(computedInterval, 3e4);
31
+ }
32
+ await new Promise((resolve) => setTimeout(resolve, computedInterval));
33
+ }
34
+ }
35
+ return false;
36
+ }
37
+
38
+ //#endregion
39
+ Object.defineProperty(exports, 'retry', {
40
+ enumerable: true,
41
+ get: function () {
42
+ return retry;
43
+ }
44
+ });
45
+ //# sourceMappingURL=retry2.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry2.cjs","names":[],"sources":["../src/retry.ts"],"sourcesContent":["type RetryFn = () => boolean | Promise<boolean>;\n\n/**\n * A utility that retries a function every `interval` milliseconds\n * until the function returns true or the maximum number of retries is reached.\n *\n * @param fn - A function that returns a boolean or a Promise resolving to a boolean.\n * @param interval - The time interval (in milliseconds) between each retry. Defaults to 1000.\n * @param maxRetries - The maximum number of retry attempts. Defaults to 3.\n * @param backoff - The backoff strategy to use: 'linear', 'exponential', or null.\n * @returns {Promise<boolean>} - A promise that resolves to:\n * - true: If the function returns true before reaching maxRetries.\n * - false: If the function never returns true or if an error occurs.\n */\nexport async function retry(\n\tfn: RetryFn,\n\tinterval: number = 1000,\n\tmaxRetries: number = 3,\n\tbackoff: 'exponential' | 'linear' | null = 'linear',\n): Promise<boolean> {\n\tlet attempt = 0;\n\n\twhile (attempt < maxRetries) {\n\t\tattempt++;\n\t\ttry {\n\t\t\tconst result = await fn();\n\t\t\tif (result) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error('Error during retry:', error);\n\t\t\tthrow error;\n\t\t}\n\n\t\t// Wait for the specified interval before the next attempt, if any attempts remain.\n\t\tif (attempt < maxRetries) {\n\t\t\tlet computedInterval = interval;\n\n\t\t\tif (backoff === 'linear') {\n\t\t\t\tcomputedInterval = interval * attempt;\n\t\t\t} else if (backoff === 'exponential') {\n\t\t\t\tcomputedInterval = Math.pow(2, attempt - 1) * interval;\n\t\t\t\tcomputedInterval = Math.min(computedInterval, 30000); // Cap the maximum interval to 30 seconds\n\t\t\t}\n\n\t\t\tawait new Promise<void>((resolve) => setTimeout(resolve, computedInterval));\n\t\t}\n\t}\n\n\treturn false;\n}\n"],"mappings":";;;;;;;;;;;;;;AAcA,eAAsB,MACrB,IACA,WAAmB,KACnB,aAAqB,GACrB,UAA2C,UACxB;CACnB,IAAI,UAAU;AAEd,QAAO,UAAU,YAAY;AAC5B;AACA,MAAI;AAEH,OADe,MAAM,IAAI,CAExB,QAAO;WAEA,OAAO;AACf,WAAQ,MAAM,uBAAuB,MAAM;AAC3C,SAAM;;AAIP,MAAI,UAAU,YAAY;GACzB,IAAI,mBAAmB;AAEvB,OAAI,YAAY,SACf,oBAAmB,WAAW;YACpB,YAAY,eAAe;AACrC,uBAAmB,KAAK,IAAI,GAAG,UAAU,EAAE,GAAG;AAC9C,uBAAmB,KAAK,IAAI,kBAAkB,IAAM;;AAGrD,SAAM,IAAI,SAAe,YAAY,WAAW,SAAS,iBAAiB,CAAC;;;AAI7E,QAAO"}
@@ -0,0 +1,6 @@
1
+ //#region src/retry.d.ts
2
+ type RetryFn = () => boolean | Promise<boolean>;
3
+ declare function retry(fn: RetryFn, interval?: number, maxRetries?: number, backoff?: 'exponential' | 'linear' | null): Promise<boolean>;
4
+ //#endregion
5
+ export { retry as t };
6
+ //# sourceMappingURL=retry2.d.cts.map
@@ -0,0 +1,6 @@
1
+ //#region src/retry.d.ts
2
+ type RetryFn = () => boolean | Promise<boolean>;
3
+ declare function retry(fn: RetryFn, interval?: number, maxRetries?: number, backoff?: 'exponential' | 'linear' | null): Promise<boolean>;
4
+ //#endregion
5
+ export { retry as t };
6
+ //# sourceMappingURL=retry2.d.mts.map
@@ -0,0 +1,39 @@
1
+ //#region src/retry.ts
2
+ /**
3
+ * A utility that retries a function every `interval` milliseconds
4
+ * until the function returns true or the maximum number of retries is reached.
5
+ *
6
+ * @param fn - A function that returns a boolean or a Promise resolving to a boolean.
7
+ * @param interval - The time interval (in milliseconds) between each retry. Defaults to 1000.
8
+ * @param maxRetries - The maximum number of retry attempts. Defaults to 3.
9
+ * @param backoff - The backoff strategy to use: 'linear', 'exponential', or null.
10
+ * @returns {Promise<boolean>} - A promise that resolves to:
11
+ * - true: If the function returns true before reaching maxRetries.
12
+ * - false: If the function never returns true or if an error occurs.
13
+ */
14
+ async function retry(fn, interval = 1e3, maxRetries = 3, backoff = "linear") {
15
+ let attempt = 0;
16
+ while (attempt < maxRetries) {
17
+ attempt++;
18
+ try {
19
+ if (await fn()) return true;
20
+ } catch (error) {
21
+ console.error("Error during retry:", error);
22
+ throw error;
23
+ }
24
+ if (attempt < maxRetries) {
25
+ let computedInterval = interval;
26
+ if (backoff === "linear") computedInterval = interval * attempt;
27
+ else if (backoff === "exponential") {
28
+ computedInterval = Math.pow(2, attempt - 1) * interval;
29
+ computedInterval = Math.min(computedInterval, 3e4);
30
+ }
31
+ await new Promise((resolve) => setTimeout(resolve, computedInterval));
32
+ }
33
+ }
34
+ return false;
35
+ }
36
+
37
+ //#endregion
38
+ export { retry as t };
39
+ //# sourceMappingURL=retry2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry2.mjs","names":[],"sources":["../src/retry.ts"],"sourcesContent":["type RetryFn = () => boolean | Promise<boolean>;\n\n/**\n * A utility that retries a function every `interval` milliseconds\n * until the function returns true or the maximum number of retries is reached.\n *\n * @param fn - A function that returns a boolean or a Promise resolving to a boolean.\n * @param interval - The time interval (in milliseconds) between each retry. Defaults to 1000.\n * @param maxRetries - The maximum number of retry attempts. Defaults to 3.\n * @param backoff - The backoff strategy to use: 'linear', 'exponential', or null.\n * @returns {Promise<boolean>} - A promise that resolves to:\n * - true: If the function returns true before reaching maxRetries.\n * - false: If the function never returns true or if an error occurs.\n */\nexport async function retry(\n\tfn: RetryFn,\n\tinterval: number = 1000,\n\tmaxRetries: number = 3,\n\tbackoff: 'exponential' | 'linear' | null = 'linear',\n): Promise<boolean> {\n\tlet attempt = 0;\n\n\twhile (attempt < maxRetries) {\n\t\tattempt++;\n\t\ttry {\n\t\t\tconst result = await fn();\n\t\t\tif (result) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error('Error during retry:', error);\n\t\t\tthrow error;\n\t\t}\n\n\t\t// Wait for the specified interval before the next attempt, if any attempts remain.\n\t\tif (attempt < maxRetries) {\n\t\t\tlet computedInterval = interval;\n\n\t\t\tif (backoff === 'linear') {\n\t\t\t\tcomputedInterval = interval * attempt;\n\t\t\t} else if (backoff === 'exponential') {\n\t\t\t\tcomputedInterval = Math.pow(2, attempt - 1) * interval;\n\t\t\t\tcomputedInterval = Math.min(computedInterval, 30000); // Cap the maximum interval to 30 seconds\n\t\t\t}\n\n\t\t\tawait new Promise<void>((resolve) => setTimeout(resolve, computedInterval));\n\t\t}\n\t}\n\n\treturn false;\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,eAAsB,MACrB,IACA,WAAmB,KACnB,aAAqB,GACrB,UAA2C,UACxB;CACnB,IAAI,UAAU;AAEd,QAAO,UAAU,YAAY;AAC5B;AACA,MAAI;AAEH,OADe,MAAM,IAAI,CAExB,QAAO;WAEA,OAAO;AACf,WAAQ,MAAM,uBAAuB,MAAM;AAC3C,SAAM;;AAIP,MAAI,UAAU,YAAY;GACzB,IAAI,mBAAmB;AAEvB,OAAI,YAAY,SACf,oBAAmB,WAAW;YACpB,YAAY,eAAe;AACrC,uBAAmB,KAAK,IAAI,GAAG,UAAU,EAAE,GAAG;AAC9C,uBAAmB,KAAK,IAAI,kBAAkB,IAAM;;AAGrD,SAAM,IAAI,SAAe,YAAY,WAAW,SAAS,iBAAiB,CAAC;;;AAI7E,QAAO"}
@@ -0,0 +1,67 @@
1
+
2
+ //#region src/files/sanitize.ts
3
+ const INVALID_CHARS_REGEX = /[<>:"/\\|?*\u0000-\u001F\u007F-\u009F]/g;
4
+ const ZERO_WIDTH_CHARS_REGEX = /[\u200B-\u200D\u2060\uFEFF]/g;
5
+ const UNICODE_SPACES_REGEX = /[\u00A0\u2000-\u200A]/g;
6
+ const LEADING_TRAILING_DOTS_SPACES_REGEX = /^[\s.]+|[\s.]+$/g;
7
+ const WINDOWS_RESERVED_NAMES = new Set([
8
+ "CON",
9
+ "PRN",
10
+ "AUX",
11
+ "NUL",
12
+ "COM1",
13
+ "COM2",
14
+ "COM3",
15
+ "COM4",
16
+ "COM5",
17
+ "COM6",
18
+ "COM7",
19
+ "COM8",
20
+ "COM9",
21
+ "LPT1",
22
+ "LPT2",
23
+ "LPT3",
24
+ "LPT4",
25
+ "LPT5",
26
+ "LPT6",
27
+ "LPT7",
28
+ "LPT8",
29
+ "LPT9"
30
+ ]);
31
+ const DEFAULT_FALLBACK_NAME = "untitled";
32
+ const MAX_FILENAME_LENGTH = 200;
33
+ /**
34
+ * Sanitizes a filename to be compatible with Mac, Linux, and Windows file systems
35
+ *
36
+ * Main features:
37
+ * - Replace invalid characters (e.g. ":" in hello:world)
38
+ * - Handle Windows reserved names
39
+ * - Limit filename length
40
+ * - Normalize Unicode characters
41
+ *
42
+ * @param filename - The filename to sanitize (without extension)
43
+ * @param maxLength - Maximum filename length (default: 200)
44
+ * @returns A sanitized filename (without extension)
45
+ *
46
+ * @example
47
+ * sanitizeFilename('hello:world') // returns 'hello_world'
48
+ * sanitizeFilename('CON') // returns '_CON'
49
+ * sanitizeFilename('') // returns 'untitled'
50
+ */
51
+ const sanitizeFilename = (filename, maxLength = MAX_FILENAME_LENGTH) => {
52
+ if (!filename) return DEFAULT_FALLBACK_NAME;
53
+ let baseName = filename.trim().replace(INVALID_CHARS_REGEX, "_").replace(ZERO_WIDTH_CHARS_REGEX, "").replace(UNICODE_SPACES_REGEX, " ").replace(LEADING_TRAILING_DOTS_SPACES_REGEX, "");
54
+ if (!baseName) baseName = DEFAULT_FALLBACK_NAME;
55
+ if (WINDOWS_RESERVED_NAMES.has(baseName.toUpperCase())) baseName = `_${baseName}`;
56
+ if (baseName.length > maxLength) baseName = baseName.slice(0, maxLength);
57
+ return baseName;
58
+ };
59
+
60
+ //#endregion
61
+ Object.defineProperty(exports, 'sanitizeFilename', {
62
+ enumerable: true,
63
+ get: function () {
64
+ return sanitizeFilename;
65
+ }
66
+ });
67
+ //# sourceMappingURL=sanitize.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.cjs","names":[],"sources":["../src/files/sanitize.ts"],"sourcesContent":["// Constants definition\n/* eslint-disable no-control-regex */\nconst INVALID_CHARS_REGEX = /[<>:\"/\\\\|?*\\u0000-\\u001F\\u007F-\\u009F]/g;\nconst ZERO_WIDTH_CHARS_REGEX = /[\\u200B-\\u200D\\u2060\\uFEFF]/g;\nconst UNICODE_SPACES_REGEX = /[\\u00A0\\u2000-\\u200A]/g;\nconst LEADING_TRAILING_DOTS_SPACES_REGEX = /^[\\s.]+|[\\s.]+$/g;\n/* eslint-enable no-control-regex */\n\nconst WINDOWS_RESERVED_NAMES = new Set([\n\t'CON',\n\t'PRN',\n\t'AUX',\n\t'NUL',\n\t'COM1',\n\t'COM2',\n\t'COM3',\n\t'COM4',\n\t'COM5',\n\t'COM6',\n\t'COM7',\n\t'COM8',\n\t'COM9',\n\t'LPT1',\n\t'LPT2',\n\t'LPT3',\n\t'LPT4',\n\t'LPT5',\n\t'LPT6',\n\t'LPT7',\n\t'LPT8',\n\t'LPT9',\n]);\n\nconst DEFAULT_FALLBACK_NAME = 'untitled';\nconst MAX_FILENAME_LENGTH = 200;\n\n/**\n * Sanitizes a filename to be compatible with Mac, Linux, and Windows file systems\n *\n * Main features:\n * - Replace invalid characters (e.g. \":\" in hello:world)\n * - Handle Windows reserved names\n * - Limit filename length\n * - Normalize Unicode characters\n *\n * @param filename - The filename to sanitize (without extension)\n * @param maxLength - Maximum filename length (default: 200)\n * @returns A sanitized filename (without extension)\n *\n * @example\n * sanitizeFilename('hello:world') // returns 'hello_world'\n * sanitizeFilename('CON') // returns '_CON'\n * sanitizeFilename('') // returns 'untitled'\n */\nexport const sanitizeFilename = (\n\tfilename: string,\n\tmaxLength: number = MAX_FILENAME_LENGTH,\n): string => {\n\t// Input validation\n\tif (!filename) {\n\t\treturn DEFAULT_FALLBACK_NAME;\n\t}\n\n\tlet baseName = filename\n\t\t.trim()\n\t\t.replace(INVALID_CHARS_REGEX, '_')\n\t\t.replace(ZERO_WIDTH_CHARS_REGEX, '')\n\t\t.replace(UNICODE_SPACES_REGEX, ' ')\n\t\t.replace(LEADING_TRAILING_DOTS_SPACES_REGEX, '');\n\n\t// Handle empty or invalid filenames after cleaning\n\tif (!baseName) {\n\t\tbaseName = DEFAULT_FALLBACK_NAME;\n\t}\n\n\t// Handle Windows reserved names\n\tif (WINDOWS_RESERVED_NAMES.has(baseName.toUpperCase())) {\n\t\tbaseName = `_${baseName}`;\n\t}\n\n\t// Truncate if too long\n\tif (baseName.length > maxLength) {\n\t\tbaseName = baseName.slice(0, maxLength);\n\t}\n\n\treturn baseName;\n};\n"],"mappings":";;AAEA,MAAM,sBAAsB;AAC5B,MAAM,yBAAyB;AAC/B,MAAM,uBAAuB;AAC7B,MAAM,qCAAqC;AAG3C,MAAM,yBAAyB,IAAI,IAAI;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,CAAC;AAEF,MAAM,wBAAwB;AAC9B,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;AAoB5B,MAAa,oBACZ,UACA,YAAoB,wBACR;AAEZ,KAAI,CAAC,SACJ,QAAO;CAGR,IAAI,WAAW,SACb,MAAM,CACN,QAAQ,qBAAqB,IAAI,CACjC,QAAQ,wBAAwB,GAAG,CACnC,QAAQ,sBAAsB,IAAI,CAClC,QAAQ,oCAAoC,GAAG;AAGjD,KAAI,CAAC,SACJ,YAAW;AAIZ,KAAI,uBAAuB,IAAI,SAAS,aAAa,CAAC,CACrD,YAAW,IAAI;AAIhB,KAAI,SAAS,SAAS,UACrB,YAAW,SAAS,MAAM,GAAG,UAAU;AAGxC,QAAO"}
@@ -0,0 +1,5 @@
1
+ //#region src/files/sanitize.d.ts
2
+ declare const sanitizeFilename: (filename: string, maxLength?: number) => string;
3
+ //#endregion
4
+ export { sanitizeFilename as t };
5
+ //# sourceMappingURL=sanitize.d.cts.map
@@ -0,0 +1,5 @@
1
+ //#region src/files/sanitize.d.ts
2
+ declare const sanitizeFilename: (filename: string, maxLength?: number) => string;
3
+ //#endregion
4
+ export { sanitizeFilename as t };
5
+ //# sourceMappingURL=sanitize.d.mts.map
@@ -0,0 +1,61 @@
1
+ //#region src/files/sanitize.ts
2
+ const INVALID_CHARS_REGEX = /[<>:"/\\|?*\u0000-\u001F\u007F-\u009F]/g;
3
+ const ZERO_WIDTH_CHARS_REGEX = /[\u200B-\u200D\u2060\uFEFF]/g;
4
+ const UNICODE_SPACES_REGEX = /[\u00A0\u2000-\u200A]/g;
5
+ const LEADING_TRAILING_DOTS_SPACES_REGEX = /^[\s.]+|[\s.]+$/g;
6
+ const WINDOWS_RESERVED_NAMES = new Set([
7
+ "CON",
8
+ "PRN",
9
+ "AUX",
10
+ "NUL",
11
+ "COM1",
12
+ "COM2",
13
+ "COM3",
14
+ "COM4",
15
+ "COM5",
16
+ "COM6",
17
+ "COM7",
18
+ "COM8",
19
+ "COM9",
20
+ "LPT1",
21
+ "LPT2",
22
+ "LPT3",
23
+ "LPT4",
24
+ "LPT5",
25
+ "LPT6",
26
+ "LPT7",
27
+ "LPT8",
28
+ "LPT9"
29
+ ]);
30
+ const DEFAULT_FALLBACK_NAME = "untitled";
31
+ const MAX_FILENAME_LENGTH = 200;
32
+ /**
33
+ * Sanitizes a filename to be compatible with Mac, Linux, and Windows file systems
34
+ *
35
+ * Main features:
36
+ * - Replace invalid characters (e.g. ":" in hello:world)
37
+ * - Handle Windows reserved names
38
+ * - Limit filename length
39
+ * - Normalize Unicode characters
40
+ *
41
+ * @param filename - The filename to sanitize (without extension)
42
+ * @param maxLength - Maximum filename length (default: 200)
43
+ * @returns A sanitized filename (without extension)
44
+ *
45
+ * @example
46
+ * sanitizeFilename('hello:world') // returns 'hello_world'
47
+ * sanitizeFilename('CON') // returns '_CON'
48
+ * sanitizeFilename('') // returns 'untitled'
49
+ */
50
+ const sanitizeFilename = (filename, maxLength = MAX_FILENAME_LENGTH) => {
51
+ if (!filename) return DEFAULT_FALLBACK_NAME;
52
+ let baseName = filename.trim().replace(INVALID_CHARS_REGEX, "_").replace(ZERO_WIDTH_CHARS_REGEX, "").replace(UNICODE_SPACES_REGEX, " ").replace(LEADING_TRAILING_DOTS_SPACES_REGEX, "");
53
+ if (!baseName) baseName = DEFAULT_FALLBACK_NAME;
54
+ if (WINDOWS_RESERVED_NAMES.has(baseName.toUpperCase())) baseName = `_${baseName}`;
55
+ if (baseName.length > maxLength) baseName = baseName.slice(0, maxLength);
56
+ return baseName;
57
+ };
58
+
59
+ //#endregion
60
+ export { sanitizeFilename as t };
61
+ //# sourceMappingURL=sanitize.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.mjs","names":[],"sources":["../src/files/sanitize.ts"],"sourcesContent":["// Constants definition\n/* eslint-disable no-control-regex */\nconst INVALID_CHARS_REGEX = /[<>:\"/\\\\|?*\\u0000-\\u001F\\u007F-\\u009F]/g;\nconst ZERO_WIDTH_CHARS_REGEX = /[\\u200B-\\u200D\\u2060\\uFEFF]/g;\nconst UNICODE_SPACES_REGEX = /[\\u00A0\\u2000-\\u200A]/g;\nconst LEADING_TRAILING_DOTS_SPACES_REGEX = /^[\\s.]+|[\\s.]+$/g;\n/* eslint-enable no-control-regex */\n\nconst WINDOWS_RESERVED_NAMES = new Set([\n\t'CON',\n\t'PRN',\n\t'AUX',\n\t'NUL',\n\t'COM1',\n\t'COM2',\n\t'COM3',\n\t'COM4',\n\t'COM5',\n\t'COM6',\n\t'COM7',\n\t'COM8',\n\t'COM9',\n\t'LPT1',\n\t'LPT2',\n\t'LPT3',\n\t'LPT4',\n\t'LPT5',\n\t'LPT6',\n\t'LPT7',\n\t'LPT8',\n\t'LPT9',\n]);\n\nconst DEFAULT_FALLBACK_NAME = 'untitled';\nconst MAX_FILENAME_LENGTH = 200;\n\n/**\n * Sanitizes a filename to be compatible with Mac, Linux, and Windows file systems\n *\n * Main features:\n * - Replace invalid characters (e.g. \":\" in hello:world)\n * - Handle Windows reserved names\n * - Limit filename length\n * - Normalize Unicode characters\n *\n * @param filename - The filename to sanitize (without extension)\n * @param maxLength - Maximum filename length (default: 200)\n * @returns A sanitized filename (without extension)\n *\n * @example\n * sanitizeFilename('hello:world') // returns 'hello_world'\n * sanitizeFilename('CON') // returns '_CON'\n * sanitizeFilename('') // returns 'untitled'\n */\nexport const sanitizeFilename = (\n\tfilename: string,\n\tmaxLength: number = MAX_FILENAME_LENGTH,\n): string => {\n\t// Input validation\n\tif (!filename) {\n\t\treturn DEFAULT_FALLBACK_NAME;\n\t}\n\n\tlet baseName = filename\n\t\t.trim()\n\t\t.replace(INVALID_CHARS_REGEX, '_')\n\t\t.replace(ZERO_WIDTH_CHARS_REGEX, '')\n\t\t.replace(UNICODE_SPACES_REGEX, ' ')\n\t\t.replace(LEADING_TRAILING_DOTS_SPACES_REGEX, '');\n\n\t// Handle empty or invalid filenames after cleaning\n\tif (!baseName) {\n\t\tbaseName = DEFAULT_FALLBACK_NAME;\n\t}\n\n\t// Handle Windows reserved names\n\tif (WINDOWS_RESERVED_NAMES.has(baseName.toUpperCase())) {\n\t\tbaseName = `_${baseName}`;\n\t}\n\n\t// Truncate if too long\n\tif (baseName.length > maxLength) {\n\t\tbaseName = baseName.slice(0, maxLength);\n\t}\n\n\treturn baseName;\n};\n"],"mappings":";AAEA,MAAM,sBAAsB;AAC5B,MAAM,yBAAyB;AAC/B,MAAM,uBAAuB;AAC7B,MAAM,qCAAqC;AAG3C,MAAM,yBAAyB,IAAI,IAAI;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,CAAC;AAEF,MAAM,wBAAwB;AAC9B,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;AAoB5B,MAAa,oBACZ,UACA,YAAoB,wBACR;AAEZ,KAAI,CAAC,SACJ,QAAO;CAGR,IAAI,WAAW,SACb,MAAM,CACN,QAAQ,qBAAqB,IAAI,CACjC,QAAQ,wBAAwB,GAAG,CACnC,QAAQ,sBAAsB,IAAI,CAClC,QAAQ,oCAAoC,GAAG;AAGjD,KAAI,CAAC,SACJ,YAAW;AAIZ,KAAI,uBAAuB,IAAI,SAAS,aAAa,CAAC,CACrD,YAAW,IAAI;AAIhB,KAAI,SAAS,SAAS,UACrB,YAAW,SAAS,MAAM,GAAG,UAAU;AAGxC,QAAO"}
@@ -0,0 +1,3 @@
1
+ const require_reRankSearchResults = require('../reRankSearchResults.cjs');
2
+
3
+ exports.reRankSearchResults = require_reRankSearchResults.reRankSearchResults;
@@ -0,0 +1,2 @@
1
+ import { t as reRankSearchResults } from "../reRankSearchResults.cjs";
2
+ export { reRankSearchResults };
@@ -0,0 +1,2 @@
1
+ import { t as reRankSearchResults } from "../reRankSearchResults.mjs";
2
+ export { reRankSearchResults };
@@ -0,0 +1,3 @@
1
+ import { t as reRankSearchResults } from "../reRankSearchResults.mjs";
2
+
3
+ export { reRankSearchResults };
@@ -0,0 +1,4 @@
1
+ const require_sublimeSearch = require('../sublimeSearch.cjs');
2
+
3
+ exports.DEFAULT_KEYS = require_sublimeSearch.DEFAULT_KEYS;
4
+ exports.sublimeSearch = require_sublimeSearch.sublimeSearch;
@@ -0,0 +1,2 @@
1
+ import { n as sublimeSearch, t as DEFAULT_KEYS } from "../sublimeSearch.cjs";
2
+ export { DEFAULT_KEYS, sublimeSearch };
@@ -0,0 +1,2 @@
1
+ import { n as sublimeSearch, t as DEFAULT_KEYS } from "../sublimeSearch.mjs";
2
+ export { DEFAULT_KEYS, sublimeSearch };
@@ -0,0 +1,3 @@
1
+ import { n as sublimeSearch, t as DEFAULT_KEYS } from "../sublimeSearch.mjs";
2
+
3
+ export { DEFAULT_KEYS, sublimeSearch };
@@ -0,0 +1,16 @@
1
+
2
+ //#region src/number/smartDecimal.ts
3
+ const smartDecimal = (value, decimals = 2) => {
4
+ if (Number.isInteger(value)) return value;
5
+ if (value.toString().split(".")[1].length <= decimals) return value;
6
+ return Number(value.toFixed(decimals));
7
+ };
8
+
9
+ //#endregion
10
+ Object.defineProperty(exports, 'smartDecimal', {
11
+ enumerable: true,
12
+ get: function () {
13
+ return smartDecimal;
14
+ }
15
+ });
16
+ //# sourceMappingURL=smartDecimal.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smartDecimal.cjs","names":[],"sources":["../src/number/smartDecimal.ts"],"sourcesContent":["export const smartDecimal = (value: number, decimals = 2): number => {\n\t// Check if integer\n\tif (Number.isInteger(value)) {\n\t\treturn value;\n\t}\n\n\t// Check if it has only one decimal place\n\tif (value.toString().split('.')[1].length <= decimals) {\n\t\treturn value;\n\t}\n\n\treturn Number(value.toFixed(decimals));\n};\n"],"mappings":";;AAAA,MAAa,gBAAgB,OAAe,WAAW,MAAc;AAEpE,KAAI,OAAO,UAAU,MAAM,CAC1B,QAAO;AAIR,KAAI,MAAM,UAAU,CAAC,MAAM,IAAI,CAAC,GAAG,UAAU,SAC5C,QAAO;AAGR,QAAO,OAAO,MAAM,QAAQ,SAAS,CAAC"}
@@ -0,0 +1,5 @@
1
+ //#region src/number/smartDecimal.d.ts
2
+ declare const smartDecimal: (value: number, decimals?: number) => number;
3
+ //#endregion
4
+ export { smartDecimal as t };
5
+ //# sourceMappingURL=smartDecimal.d.cts.map
@@ -0,0 +1,5 @@
1
+ //#region src/number/smartDecimal.d.ts
2
+ declare const smartDecimal: (value: number, decimals?: number) => number;
3
+ //#endregion
4
+ export { smartDecimal as t };
5
+ //# sourceMappingURL=smartDecimal.d.mts.map
@@ -0,0 +1,10 @@
1
+ //#region src/number/smartDecimal.ts
2
+ const smartDecimal = (value, decimals = 2) => {
3
+ if (Number.isInteger(value)) return value;
4
+ if (value.toString().split(".")[1].length <= decimals) return value;
5
+ return Number(value.toFixed(decimals));
6
+ };
7
+
8
+ //#endregion
9
+ export { smartDecimal as t };
10
+ //# sourceMappingURL=smartDecimal.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smartDecimal.mjs","names":[],"sources":["../src/number/smartDecimal.ts"],"sourcesContent":["export const smartDecimal = (value: number, decimals = 2): number => {\n\t// Check if integer\n\tif (Number.isInteger(value)) {\n\t\treturn value;\n\t}\n\n\t// Check if it has only one decimal place\n\tif (value.toString().split('.')[1].length <= decimals) {\n\t\treturn value;\n\t}\n\n\treturn Number(value.toFixed(decimals));\n};\n"],"mappings":";AAAA,MAAa,gBAAgB,OAAe,WAAW,MAAc;AAEpE,KAAI,OAAO,UAAU,MAAM,CAC1B,QAAO;AAIR,KAAI,MAAM,UAAU,CAAC,MAAM,IAAI,CAAC,GAAG,UAAU,SAC5C,QAAO;AAGR,QAAO,OAAO,MAAM,QAAQ,SAAS,CAAC"}
@@ -0,0 +1,3 @@
1
+ const require_sortByProperty = require('../sortByProperty.cjs');
2
+
3
+ exports.sortByProperty = require_sortByProperty.sortByProperty;
@@ -0,0 +1,2 @@
1
+ import { t as sortByProperty } from "../sortByProperty.cjs";
2
+ export { sortByProperty };
@@ -0,0 +1,2 @@
1
+ import { t as sortByProperty } from "../sortByProperty.mjs";
2
+ export { sortByProperty };
@@ -0,0 +1,3 @@
1
+ import { t as sortByProperty } from "../sortByProperty.mjs";
2
+
3
+ export { sortByProperty };
@@ -0,0 +1,18 @@
1
+
2
+ //#region src/sort/sortByProperty.ts
3
+ const sortByProperty = (property, arr, order = "asc") => arr.sort((a, b) => {
4
+ const result = String(a[property]).localeCompare(String(b[property]), void 0, {
5
+ numeric: true,
6
+ sensitivity: "base"
7
+ });
8
+ return order === "asc" ? result : -result;
9
+ });
10
+
11
+ //#endregion
12
+ Object.defineProperty(exports, 'sortByProperty', {
13
+ enumerable: true,
14
+ get: function () {
15
+ return sortByProperty;
16
+ }
17
+ });
18
+ //# sourceMappingURL=sortByProperty.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sortByProperty.cjs","names":[],"sources":["../src/sort/sortByProperty.ts"],"sourcesContent":["export const sortByProperty = <T>(\n\tproperty: keyof T,\n\tarr: T[],\n\torder: 'asc' | 'desc' = 'asc',\n): T[] =>\n\tarr.sort((a, b) => {\n\t\tconst result = String(a[property]).localeCompare(String(b[property]), undefined, {\n\t\t\tnumeric: true,\n\t\t\tsensitivity: 'base',\n\t\t});\n\t\treturn order === 'asc' ? result : -result;\n\t});\n"],"mappings":";;AAAA,MAAa,kBACZ,UACA,KACA,QAAwB,UAExB,IAAI,MAAM,GAAG,MAAM;CAClB,MAAM,SAAS,OAAO,EAAE,UAAU,CAAC,cAAc,OAAO,EAAE,UAAU,EAAE,QAAW;EAChF,SAAS;EACT,aAAa;EACb,CAAC;AACF,QAAO,UAAU,QAAQ,SAAS,CAAC;EAClC"}
@@ -0,0 +1,5 @@
1
+ //#region src/sort/sortByProperty.d.ts
2
+ declare const sortByProperty: <T>(property: keyof T, arr: T[], order?: "asc" | "desc") => T[];
3
+ //#endregion
4
+ export { sortByProperty as t };
5
+ //# sourceMappingURL=sortByProperty.d.cts.map
@@ -0,0 +1,5 @@
1
+ //#region src/sort/sortByProperty.d.ts
2
+ declare const sortByProperty: <T>(property: keyof T, arr: T[], order?: "asc" | "desc") => T[];
3
+ //#endregion
4
+ export { sortByProperty as t };
5
+ //# sourceMappingURL=sortByProperty.d.mts.map
@@ -0,0 +1,12 @@
1
+ //#region src/sort/sortByProperty.ts
2
+ const sortByProperty = (property, arr, order = "asc") => arr.sort((a, b) => {
3
+ const result = String(a[property]).localeCompare(String(b[property]), void 0, {
4
+ numeric: true,
5
+ sensitivity: "base"
6
+ });
7
+ return order === "asc" ? result : -result;
8
+ });
9
+
10
+ //#endregion
11
+ export { sortByProperty as t };
12
+ //# sourceMappingURL=sortByProperty.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sortByProperty.mjs","names":[],"sources":["../src/sort/sortByProperty.ts"],"sourcesContent":["export const sortByProperty = <T>(\n\tproperty: keyof T,\n\tarr: T[],\n\torder: 'asc' | 'desc' = 'asc',\n): T[] =>\n\tarr.sort((a, b) => {\n\t\tconst result = String(a[property]).localeCompare(String(b[property]), undefined, {\n\t\t\tnumeric: true,\n\t\t\tsensitivity: 'base',\n\t\t});\n\t\treturn order === 'asc' ? result : -result;\n\t});\n"],"mappings":";AAAA,MAAa,kBACZ,UACA,KACA,QAAwB,UAExB,IAAI,MAAM,GAAG,MAAM;CAClB,MAAM,SAAS,OAAO,EAAE,UAAU,CAAC,cAAc,OAAO,EAAE,UAAU,EAAE,QAAW;EAChF,SAAS;EACT,aAAa;EACb,CAAC;AACF,QAAO,UAAU,QAAQ,SAAS,CAAC;EAClC"}
@@ -0,0 +1,4 @@
1
+ const require_truncate = require('../truncate.cjs');
2
+
3
+ exports.truncate = require_truncate.truncate;
4
+ exports.truncateBeforeLast = require_truncate.truncateBeforeLast;
@@ -0,0 +1,2 @@
1
+ import { n as truncateBeforeLast, t as truncate } from "../truncate.cjs";
2
+ export { truncate, truncateBeforeLast };
@@ -0,0 +1,2 @@
1
+ import { n as truncateBeforeLast, t as truncate } from "../truncate.mjs";
2
+ export { truncate, truncateBeforeLast };
@@ -0,0 +1,3 @@
1
+ import { n as truncateBeforeLast, t as truncate } from "../truncate.mjs";
2
+
3
+ export { truncate, truncateBeforeLast };
@@ -0,0 +1,183 @@
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
+ */
22
+ function fuzzyMatchSimple(pattern, target) {
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;
30
+ }
31
+ function fuzzyMatchRecursive(pattern, target, patternCurIndex, targetCurrIndex, targetMatches, matches, maxMatches, nextMatch, recursionCount, recursionLimit) {
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
+ };
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
+ */
120
+ function fuzzyMatch(pattern, target) {
121
+ return fuzzyMatchRecursive(pattern, target, 0, 0, null, [], 256, 0, 0, 5);
122
+ }
123
+ function getValue(obj, prop) {
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;
134
+ }
135
+ function sublimeSearch(filter, data, keys = DEFAULT_KEYS) {
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;
168
+ }
169
+
170
+ //#endregion
171
+ Object.defineProperty(exports, 'DEFAULT_KEYS', {
172
+ enumerable: true,
173
+ get: function () {
174
+ return DEFAULT_KEYS;
175
+ }
176
+ });
177
+ Object.defineProperty(exports, 'sublimeSearch', {
178
+ enumerable: true,
179
+ get: function () {
180
+ return sublimeSearch;
181
+ }
182
+ });
183
+ //# sourceMappingURL=sublimeSearch.cjs.map