@oscarpalmer/atoms 0.218.0 → 0.220.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 (54) hide show
  1. package/dist/array/filter.d.mts +38 -4
  2. package/dist/array/find.d.mts +34 -0
  3. package/dist/array/first.d.mts +40 -4
  4. package/dist/array/last.d.mts +46 -10
  5. package/dist/array/partition.d.mts +24 -8
  6. package/dist/array/reverse.d.mts +6 -0
  7. package/dist/array/reverse.mjs +6 -0
  8. package/dist/array/select.d.mts +97 -116
  9. package/dist/array/select.mjs +19 -15
  10. package/dist/array/single.d.mts +22 -0
  11. package/dist/array/single.mjs +1 -1
  12. package/dist/array/sort.d.mts +54 -0
  13. package/dist/color/space/hex.d.mts +8 -0
  14. package/dist/color/space/hex.mjs +8 -0
  15. package/dist/index.d.mts +764 -189
  16. package/dist/index.mjs +508 -207
  17. package/dist/internal/array/callbacks.mjs +1 -1
  18. package/dist/internal/array/find.d.mts +3 -3
  19. package/dist/internal/array/find.mjs +71 -52
  20. package/dist/internal/array/shuffle.d.mts +5 -0
  21. package/dist/internal/array/shuffle.mjs +5 -0
  22. package/dist/internal/math/aggregate.d.mts +69 -21
  23. package/dist/internal/math/misc.d.mts +14 -0
  24. package/dist/internal/math/misc.mjs +14 -0
  25. package/dist/internal/number.d.mts +18 -0
  26. package/dist/internal/number.mjs +18 -0
  27. package/dist/internal/string/case.d.mts +63 -0
  28. package/dist/internal/string/case.mjs +63 -0
  29. package/dist/internal/string/misc.d.mts +20 -0
  30. package/dist/internal/string/misc.mjs +20 -0
  31. package/dist/logger.d.mts +12 -0
  32. package/dist/logger.mjs +12 -0
  33. package/dist/math.d.mts +90 -0
  34. package/dist/math.mjs +7 -0
  35. package/dist/models/array/array.find.model.d.mts +26 -0
  36. package/dist/models/array/array.misc.model.d.mts +2 -4
  37. package/dist/models/index.d.mts +1 -1
  38. package/dist/models/string/string.fuzzy.model.d.mts +46 -18
  39. package/dist/models/string/string.fuzzy.model.mjs +3 -1
  40. package/dist/models/value/value.merge.model.d.mts +3 -3
  41. package/dist/promise/misc.d.mts +6 -0
  42. package/dist/promise/misc.mjs +6 -0
  43. package/dist/promise/timed.d.mts +3 -0
  44. package/dist/promise/timed.mjs +3 -0
  45. package/dist/queue.d.mts +0 -1
  46. package/dist/queue.mjs +1 -1
  47. package/dist/string/fuzzy.d.mts +3 -3
  48. package/dist/string/fuzzy.mjs +171 -97
  49. package/dist/string/index.d.mts +15 -1
  50. package/dist/string/index.mjs +15 -1
  51. package/dist/string/match.d.mts +24 -0
  52. package/dist/string/match.mjs +24 -0
  53. package/dist/string/template.d.mts +4 -0
  54. package/package.json +1 -1
@@ -7,6 +7,14 @@ import { STRING_CASE_CAMEL, STRING_CASE_KEBAB, STRING_CASE_PASCAL, STRING_CASE_S
7
7
  *
8
8
  * @param value String to convert
9
9
  * @returns Camel-cased string
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * camelCase('this is camel case'); // => 'thisIsCamelCase'
14
+ * camelCase('ThisIsCamelCase'); // => 'thisIsCamelCase'
15
+ * camelCase('this-is-camel-case'); // => 'thisIsCamelCase'
16
+ * camelCase('this_is_camel_case'); // => 'thisIsCamelCase'
17
+ * ```
10
18
  */
11
19
  function camelCase(value) {
12
20
  return toCase(STRING_CASE_CAMEL, value, true, false);
@@ -16,6 +24,14 @@ function camelCase(value) {
16
24
  *
17
25
  * @param value String to capitalize
18
26
  * @returns Capitalized string
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * capitalize('this is a test'); // => 'This is a test'
31
+ * capitalize('This Is A Test'); // => 'This is a test'
32
+ * capitalize('t'); // => 'T'
33
+ * capitalize(''); // => ''
34
+ * ```
19
35
  */
20
36
  function capitalize(value) {
21
37
  if (typeof value !== "string" || value.length === 0) return "";
@@ -27,6 +43,14 @@ function capitalize(value) {
27
43
  *
28
44
  * @param value String to convert
29
45
  * @returns Kebab-cased string
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * kebabCase('this is kebab case'); // => 'this-is-kebab-case'
50
+ * kebabCase('ThisIsKebabCase'); // => 'this-is-kebab-case'
51
+ * kebabCase('this-is-kebab-case'); // => 'this-is-kebab-case'
52
+ * kebabCase('this_is_kebab_case'); // => 'this-is-kebab-case'
53
+ * ```
30
54
  */
31
55
  function kebabCase(value) {
32
56
  return toCase(STRING_CASE_KEBAB, value, false, false);
@@ -36,6 +60,13 @@ function kebabCase(value) {
36
60
  *
37
61
  * @param value String to convert
38
62
  * @returns Lower-cased string
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * lowerCase('THIS IS A TEST'); // => 'this is a test'
67
+ * lowerCase('this is a test'); // => 'this is a test'
68
+ * lowerCase('t'); // => 't'
69
+ * ```
39
70
  */
40
71
  function lowerCase(value) {
41
72
  if (typeof value !== "string") return "";
@@ -47,6 +78,14 @@ function lowerCase(value) {
47
78
  *
48
79
  * @param value String to convert
49
80
  * @returns Pascal-cased string
81
+ *
82
+ * @example
83
+ * ```typescript
84
+ * pascalCase('this is pascal case'); // => 'ThisIsPascalCase'
85
+ * pascalCase('ThisIsPascalCase'); // => 'ThisIsPascalCase'
86
+ * pascalCase('this-is-pascal-case'); // => 'ThisIsPascalCase'
87
+ * pascalCase('this_is_pascal_case'); // => 'ThisIsPascalCase'
88
+ * ```
50
89
  */
51
90
  function pascalCase(value) {
52
91
  return toCase(STRING_CASE_PASCAL, value, true, true);
@@ -56,6 +95,14 @@ function pascalCase(value) {
56
95
  *
57
96
  * @param value String to convert
58
97
  * @returns Snake-cased string
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * snakeCase('this is snake case'); // => 'this_is_snake_case'
102
+ * snakeCase('ThisIsSnakeCase'); // => 'this_is_snake_case'
103
+ * snakeCase('this-is-snake-case'); // => 'this_is_snake_case'
104
+ * snakeCase('this_is_snake_case'); // => 'this_is_snake_case'
105
+ * ```
59
106
  */
60
107
  function snakeCase(value) {
61
108
  return toCase(STRING_CASE_SNAKE, value, false, false);
@@ -65,6 +112,14 @@ function snakeCase(value) {
65
112
  *
66
113
  * @param value String to convert
67
114
  * @returns Title-cased string
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * titleCase('this is a test'); // => 'This Is A Test'
119
+ * titleCase('This Is A Test'); // => 'This Is A Test'
120
+ * titleCase('t'); // => 'T'
121
+ * titleCase(''); // => ''
122
+ * ```
68
123
  */
69
124
  function titleCase(value) {
70
125
  if (typeof value !== "string" || value.length === 0) return "";
@@ -107,6 +162,14 @@ function toCaseCallback(value) {
107
162
  *
108
163
  * @param value String to convert
109
164
  * @returns Upper-cased string
165
+ *
166
+ * @example
167
+ * ```typescript
168
+ * upperCase('this is a test'); // => 'THIS IS A TEST'
169
+ * upperCase('This Is A Test'); // => 'THIS IS A TEST'
170
+ * upperCase('t'); // => 'T'
171
+ * upperCase(''); // => ''
172
+ * ```
110
173
  */
111
174
  function upperCase(value) {
112
175
  if (typeof value !== "string" || value.length === 0) return "";
@@ -17,7 +17,13 @@
17
17
  * ```
18
18
  */
19
19
  export declare function getString(value: unknown): string;
20
+ /**
21
+ * @internal
22
+ */
20
23
  export declare function ignoreKey(key: string): boolean;
24
+ /**
25
+ * @internal
26
+ */
21
27
  export declare function interpolate(strings: TemplateStringsArray, values: unknown[]): string;
22
28
  /**
23
29
  * Join an array of values into a string _(while ignoring empty values)_
@@ -27,9 +33,23 @@ export declare function interpolate(strings: TemplateStringsArray, values: unkno
27
33
  * @param array Array of values
28
34
  * @param delimiter Delimiter to use between values
29
35
  * @returns Joined string
36
+ * @example
37
+ * ```typescript
38
+ * join(['a', 'b', 'c']); // => 'abc'
39
+ * join(['a', 'b', 'c'], ', '); // => 'a, b, c'
40
+ * join(['a', '', 'c']); // => 'ac'
41
+ * join([null, 'b', undefined]); // => 'b'
42
+ * join([]); // => ''
43
+ * ```
30
44
  */
31
45
  export declare function join(array: unknown[], delimiter?: string): string;
46
+ /**
47
+ * @internal
48
+ */
32
49
  export declare function tryDecode(value: string): string;
50
+ /**
51
+ * @internal
52
+ */
33
53
  export declare function tryEncode(value: boolean | number | string): unknown;
34
54
  /**
35
55
  * Split a string into words _(and other readable parts)_
@@ -27,9 +27,15 @@ function getString(value) {
27
27
  const asString = String(value.valueOf?.() ?? value);
28
28
  return asString.startsWith("[object ") ? JSON.stringify(value) : asString;
29
29
  }
30
+ /**
31
+ * @internal
32
+ */
30
33
  function ignoreKey(key) {
31
34
  return STRING_EXPRESSION_IGNORED.test(key);
32
35
  }
36
+ /**
37
+ * @internal
38
+ */
33
39
  function interpolate(strings, values) {
34
40
  const { length } = strings;
35
41
  let interpolated = "";
@@ -47,6 +53,14 @@ function interpolate(strings, values) {
47
53
  * @param array Array of values
48
54
  * @param delimiter Delimiter to use between values
49
55
  * @returns Joined string
56
+ * @example
57
+ * ```typescript
58
+ * join(['a', 'b', 'c']); // => 'abc'
59
+ * join(['a', 'b', 'c'], ', '); // => 'a, b, c'
60
+ * join(['a', '', 'c']); // => 'ac'
61
+ * join([null, 'b', undefined]); // => 'b'
62
+ * join([]); // => ''
63
+ * ```
50
64
  */
51
65
  function join(array, delimiter) {
52
66
  if (!Array.isArray(array)) return "";
@@ -62,9 +76,15 @@ function join(array, delimiter) {
62
76
  function tryCallback(value, callback) {
63
77
  return unwrap(attempt(() => callback(value)), value);
64
78
  }
79
+ /**
80
+ * @internal
81
+ */
65
82
  function tryDecode(value) {
66
83
  return tryCallback(value, decodeURIComponent);
67
84
  }
85
+ /**
86
+ * @internal
87
+ */
68
88
  function tryEncode(value) {
69
89
  return tryCallback(value, encodeURIComponent);
70
90
  }
package/dist/logger.d.mts CHANGED
@@ -1,7 +1,19 @@
1
1
  import { Lumberjack, TimeLogger } from "./models/logger.model.mjs";
2
2
  //#region src/logger.d.ts
3
3
  declare function TimeLogger(this: any, label: string): void;
4
+ /**
5
+ * Is the value a _Logger_?
6
+ *
7
+ * @param value Value to check
8
+ * @returns `true` if the value is a _Logger_, otherwise `false`
9
+ */
4
10
  declare function isLogger(value: unknown): value is Lumberjack;
11
+ /**
12
+ * Is the value a _TimeLogger_?
13
+ *
14
+ * @param value Value to check
15
+ * @returns `true` if the value is a _TimeLogger_, otherwise `false`
16
+ */
5
17
  declare function isTimeLogger(value: unknown): value is TimeLogger;
6
18
  /**
7
19
  * A logger that can be used to log messages to the console
package/dist/logger.mjs CHANGED
@@ -64,12 +64,24 @@ function getTimeLoggerStop() {
64
64
  }
65
65
  return noop;
66
66
  }
67
+ /**
68
+ * Is the value a _Logger_?
69
+ *
70
+ * @param value Value to check
71
+ * @returns `true` if the value is a _Logger_, otherwise `false`
72
+ */
67
73
  function isLogger(value) {
68
74
  return isLoggerInstance(LOGGER_NAME, value);
69
75
  }
70
76
  function isLoggerInstance(name, value) {
71
77
  return typeof value === "object" && value !== null && "$logger" in value && value["$logger"] === name;
72
78
  }
79
+ /**
80
+ * Is the value a _TimeLogger_?
81
+ *
82
+ * @param value Value to check
83
+ * @returns `true` if the value is a _TimeLogger_, otherwise `false`
84
+ */
73
85
  function isTimeLogger(value) {
74
86
  return isLoggerInstance(LOGGER_NAME_TIMED, value);
75
87
  }
package/dist/math.d.mts CHANGED
@@ -8,6 +8,16 @@ import { floor, round } from "./internal/math/misc.mjs";
8
8
  * @param items List of items
9
9
  * @param callback Callback to get an item's value
10
10
  * @returns Average value, or `Number.NaN` if no average can be calculated
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * average([
15
+ * {value: 1},
16
+ * {value: 2},
17
+ * {value: 3},
18
+ * ], item => item.value); // => 2
19
+ * average([{value: 1}], item => item.nope); // => Number.NaN
20
+ * ```
11
21
  */
12
22
  export declare function average<Item>(items: Item[], callback: (item: Item, index: number, array: Item[]) => number): number;
13
23
  /**
@@ -16,6 +26,12 @@ export declare function average<Item>(items: Item[], callback: (item: Item, inde
16
26
  * @param items List of items
17
27
  * @param key Key to use for value
18
28
  * @returns Average value, or `Number.NaN` if no average can be calculated
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * average([{value: 1}, {value: 2}, {value: 3}], 'value'); // => 2
33
+ * average([{value: 1}], 'nope'); // => Number.NaN
34
+ * ```
19
35
  */
20
36
  export declare function average<Item extends PlainObject>(items: Item[], key: keyof NumericalValues<Item>): number;
21
37
  /**
@@ -23,6 +39,12 @@ export declare function average<Item extends PlainObject>(items: Item[], key: ke
23
39
  *
24
40
  * @param numbers List of numbers
25
41
  * @returns Average value, or `Number.NaN` if no average can be calculated
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * average([1, 2, 3, 4, 5]); // => 3
46
+ * average([]); // => Number.NaN
47
+ * ```
26
48
  */
27
49
  export declare function average(numbers: number[]): number;
28
50
  /**
@@ -31,6 +53,13 @@ export declare function average(numbers: number[]): number;
31
53
  * @param value Number to round up
32
54
  * @param decimals Number of decimal places to round to _(defaults to `0`)_
33
55
  * @returns Rounded number, or `Number.NaN` if the value if unable to be rounded
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * ceil(1.234, 2); // => 1.24
60
+ * ceil(1.234); // => 2
61
+ * ceil('abc'); // => Number.NaN
62
+ * ```
34
63
  */
35
64
  export declare function ceil(value: number, decimals?: number): number;
36
65
  /**
@@ -40,6 +69,14 @@ export declare function ceil(value: number, decimals?: number): number;
40
69
  * @param callback Callback to get an item's value
41
70
  * @param value Value to match and count
42
71
  * @returns Number of items that match the condition, or `Number.NaN` if no count can be calculated
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * count([1, 2, 3, 2], (item) => item, 2); // => 2
76
+ * count([{value: 1}, {value: 2}, {value: 3}], 'value', 2); // => 1
77
+ * count([1, 2, 3], (item) => item, 4); // => 0
78
+ * count([], (item) => item, 1); // => Number.NaN
79
+ * ```
43
80
  */
44
81
  export declare function count<Item>(array: Item[], callback: (item: Item, index: number, array: Item[]) => unknown, value: unknown): number;
45
82
  /**
@@ -49,6 +86,12 @@ export declare function count<Item>(array: Item[], callback: (item: Item, index:
49
86
  * @param key Key to use for value
50
87
  * @param value Value to match and count
51
88
  * @returns Number of items with the specified key value, or `Number.NaN` if no count can be calculated
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * count([{value: 1}, {value: 2}, {value: 3}], 'value', 2); // => 1
93
+ * count([{value: 1}], 'nope', 1); // => Number.NaN
94
+ * ```
52
95
  */
53
96
  export declare function count<Item extends PlainObject, ItemKey extends keyof Item>(array: Item[], key: ItemKey, value: Item[ItemKey]): number;
54
97
  /**
@@ -56,6 +99,12 @@ export declare function count<Item extends PlainObject, ItemKey extends keyof It
56
99
  *
57
100
  * @param values Array to count for
58
101
  * @returns Number of items, or `Number.NaN` if no count can be calculated
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * count([1, 2, 3]); // => 3
106
+ * count([]); // => Number.NaN
107
+ * ```
59
108
  */
60
109
  export declare function count(values: unknown[]): number;
61
110
  /**
@@ -64,6 +113,13 @@ export declare function count(values: unknown[]): number;
64
113
  * @param array List of items
65
114
  * @param callback Callback to get an item's value
66
115
  * @returns Median value, or `Number.NaN` if no median can be calculated
116
+ *
117
+ * @example
118
+ * ```typescript
119
+ * median([1, 2, 3, 4, 5]); // => 3
120
+ * median([1, 2, 3, 4]); // => 2.5
121
+ * median([]); // => Number.NaN
122
+ * ```
67
123
  */
68
124
  export declare function median<Item>(array: Item[], callback: (item: Item, index: number, array: Item[]) => number): number;
69
125
  /**
@@ -72,6 +128,13 @@ export declare function median<Item>(array: Item[], callback: (item: Item, index
72
128
  * @param array List of items
73
129
  * @param key Key to use for value
74
130
  * @returns Median value, or `Number.NaN` if no median can be calculated
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * median([{value: 1}, {value: 2}, {value: 3}], 'value'); // => 2
135
+ * median([{value: 1}, {value: 2}, {value: 3}, {value: 4}], 'value'); // => 2.5
136
+ * median([], 'value'); // => Number.NaN
137
+ * ```
75
138
  */
76
139
  export declare function median<Item extends PlainObject>(array: Item[], key: keyof NumericalValues<Item>): number;
77
140
  /**
@@ -79,6 +142,13 @@ export declare function median<Item extends PlainObject>(array: Item[], key: key
79
142
  *
80
143
  * @param array List of numbers
81
144
  * @returns Median value, or `Number.NaN` if no median can be calculated
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * median([1, 2, 3, 4, 5]); // => 3
149
+ * median([1, 2, 3, 4]); // => 2.5
150
+ * median([]); // => Number.NaN
151
+ * ```
82
152
  */
83
153
  export declare function median(array: number[]): number;
84
154
  /**
@@ -87,6 +157,13 @@ export declare function median(array: number[]): number;
87
157
  * @param items List of items
88
158
  * @param callback Callback to get an item's value
89
159
  * @returns Sum of the values, or `Number.NaN` if no sum can be calculated
160
+ *
161
+ * @example
162
+ * ```typescript
163
+ * sum([{value: 1}, {value: 2}, {value: 3}], 'value'); // => 6
164
+ * sum([{value: 1}, {value: 2}, {value: 3}], item => item.value); // => 6
165
+ * sum([]); // => Number.NaN
166
+ * ```
90
167
  */
91
168
  export declare function sum<Item>(items: Item[], callback: (item: Item, index: number, array: Item[]) => number): number;
92
169
  /**
@@ -95,6 +172,13 @@ export declare function sum<Item>(items: Item[], callback: (item: Item, index: n
95
172
  * @param items List of items
96
173
  * @param key Key to use for value
97
174
  * @returns Sum of the values, or `Number.NaN` if no sum can be calculated
175
+ *
176
+ * @example
177
+ * ```typescript
178
+ * sum([{value: 1}, {value: 2}, {value: 3}], 'value'); // => 6
179
+ * sum([{value: 1}, {value: 2}, {value: 3}], item => item.value); // => 6
180
+ * sum([]); // => Number.NaN
181
+ * ```
98
182
  */
99
183
  export declare function sum<Item extends PlainObject>(items: Item[], key: keyof NumericalValues<Item>): number;
100
184
  /**
@@ -102,6 +186,12 @@ export declare function sum<Item extends PlainObject>(items: Item[], key: keyof
102
186
  *
103
187
  * @param values List of numbers
104
188
  * @returns Sum of the numbers, or `Number.NaN` if no sum can be calculated
189
+ *
190
+ * @example
191
+ * ```typescript
192
+ * sum([1, 2, 3]); // => 6
193
+ * sum([]); // => Number.NaN
194
+ * ```
105
195
  */
106
196
  export declare function sum(values: number[]): number;
107
197
  //#endregion
package/dist/math.mjs CHANGED
@@ -13,6 +13,13 @@ function average(array, key) {
13
13
  * @param value Number to round up
14
14
  * @param decimals Number of decimal places to round to _(defaults to `0`)_
15
15
  * @returns Rounded number, or `Number.NaN` if the value if unable to be rounded
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * ceil(1.234, 2); // => 1.24
20
+ * ceil(1.234); // => 2
21
+ * ceil('abc'); // => Number.NaN
22
+ * ```
16
23
  */
17
24
  function ceil(value, decimals) {
18
25
  return roundNumber(Math.ceil, value, decimals);
@@ -1,8 +1,34 @@
1
+ import { GenericCallback } from "../index.mjs";
1
2
  //#region src/models/array/array.find.model.d.ts
3
+ export type ArrayFindLimitOptions = {
4
+ limit?: number;
5
+ map?: never;
6
+ };
7
+ export type ArrayFindMapOptions = {
8
+ limit?: never;
9
+ map?: ArrayFindMapper;
10
+ };
2
11
  export type ArrayFindMapper = {
3
12
  callback: unknown;
13
+ flat: boolean;
4
14
  reverse: boolean;
5
15
  };
16
+ export type ArrayFindOptions = ArrayFindMapOptions | ArrayFindLimitOptions;
17
+ export type ArrayFindParameters = {
18
+ array: unknown[];
19
+ arrayLength: number;
20
+ callback?: GenericCallback;
21
+ flat: boolean;
22
+ limit: number;
23
+ map?: ArrayFindParametersMap;
24
+ result: ArrayFindValuesResult;
25
+ type: ArrayFindValuesType;
26
+ value: unknown;
27
+ };
28
+ export type ArrayFindParametersMap = {
29
+ after?: GenericCallback;
30
+ before?: GenericCallback;
31
+ };
6
32
  export type ArrayFindValueType = "index" | "item";
7
33
  export type ArrayFindValuesResult = {
8
34
  matched: unknown[];
@@ -1,4 +1,4 @@
1
- import { GenericCallback, PlainObject } from "../index.mjs";
1
+ import { GenericCallback } from "../index.mjs";
2
2
  //#region src/models/array/array.misc.model.d.ts
3
3
  export type ArrayCompareSetsType = "difference" | "intersection" | "union";
4
4
  /**
@@ -6,6 +6,7 @@ export type ArrayCompareSetsType = "difference" | "intersection" | "union";
6
6
  */
7
7
  export type ArrayComparison = "end" | "inside" | "invalid" | "outside" | "same" | "start";
8
8
  export type ArrayExtractType = "drop" | "take";
9
+ export type ArrayFlattened<Value> = Value extends ReadonlyArray<infer Inner> ? Inner : Value;
9
10
  export type ArrayGetCallbacks = {
10
11
  bool?: GenericCallback;
11
12
  keyed?: GenericCallback;
@@ -16,9 +17,6 @@ export type ArrayOverlapItem = {
16
17
  array: unknown[];
17
18
  index: number;
18
19
  };
19
- export type ArrayMapKeyOrCallback<Item> = ((item: Item, index: number, array: Item[]) => unknown) | (Item extends PlainObject ? keyof Item : never);
20
- export type ArrayMapped<Item, Map extends ArrayMapKeyOrCallback<Item>> = Map extends ((item: Item, index: number, array: Item[]) => unknown) ? ReturnType<Map> : Map extends keyof Item ? Item[Map] : never;
21
- export type ArrayObjectKeysOf<Item> = { [Key in keyof Item]: Item[Key] extends PlainObject ? Key : never; }[keyof Item];
22
20
  export type ArrayOverlapResult = {
23
21
  first: ArrayOverlapItem;
24
22
  second: ArrayOverlapItem;
@@ -49,7 +49,7 @@ export type KeyOrCallbackValue<Item, Arg extends KeyOrCallback<Item>> = Arg exte
49
49
  /**
50
50
  * A nested array
51
51
  */
52
- export type NestedArray<Value> = Value extends Array<infer NestedValue> ? NestedArray<NestedValue> : Value;
52
+ export type NestedArray<Value> = Value extends ReadonlyArray<infer NestedValue> ? NestedArray<NestedValue> : Value;
53
53
  /**
54
54
  * All nested keys of an object as dot notation strings _(up to 5 levels deep)_
55
55
  */
@@ -27,26 +27,28 @@ export type Fuzzy<Item> = {
27
27
  *
28
28
  * @param value Value to search for
29
29
  * @param options Search options
30
- * @returns Search results, with exact matches _(ordered)_ and similar matches _(ordered by relevance)_
30
+ * @returns Search results, with exact, included, and similar matches
31
31
  */
32
32
  search(value: string, options?: FuzzyOptions): FuzzyResult<Item>;
33
33
  /**
34
34
  * Search for items matching the given value
35
35
  *
36
36
  * @param value Value to search for
37
- * @param limit Maximum number of combined items to return in `exact` and `similar`
38
- * @returns Search results, with exact matches _(ordered)_ and similar matches _(ordered by relevance)_
37
+ * @param limit Maximum number of combined items to return in `exact`, `included`, and `similar`
38
+ * @returns Search results, with exact, included, and similar matches
39
39
  */
40
40
  search(value: string, limit: number): FuzzyResult<Item>;
41
41
  };
42
42
  export type FuzzyConfiguration<Item> = {
43
+ handler?: (item: Item) => string;
43
44
  /**
44
- * Handler to stringify items
45
+ * Function to compare the stringified items for results _(defaults to `Intl.Collator().compare`)_
45
46
  *
46
- * - May be a function that takes an item and returns a string, or if items are plain objects, a key of the item to use to grab a string value from
47
- * - Defaults to `getString`
47
+ * @param first First string to compare
48
+ * @param second Second string to compare
49
+ * @returns Comparison result, similar to `Array.prototype.sort` callback
48
50
  */
49
- handler?: (item: Item) => string;
51
+ compare?: (first: string, second: string) => number;
50
52
  } & (Item extends PlainObject ? {
51
53
  /**
52
54
  * Key to use to stringify items
@@ -55,13 +57,13 @@ export type FuzzyConfiguration<Item> = {
55
57
  */
56
58
  key?: keyof Item;
57
59
  } : {}) & FuzzyOptions;
58
- export type FuzzyItem<Item> = {
59
- item: Item;
60
- haystack: string;
60
+ export type FuzzyItem<Data> = {
61
+ data: Data;
62
+ string: FuzzyString;
61
63
  };
62
64
  export type FuzzyOptions = {
63
65
  /**
64
- * Maximum number of combined items to return in `exact` and `similar` _(defaults to all matches)_
66
+ * Maximum number of combined items to return in `exact`, `included`, and `similar` _(defaults to all matches)_
65
67
  */
66
68
  limit?: number;
67
69
  /**
@@ -72,16 +74,27 @@ export type FuzzyOptions = {
72
74
  */
73
75
  tolerance?: number;
74
76
  };
77
+ export type FuzzyRanked<Data> = {
78
+ position: number;
79
+ /**
80
+ * `0` for starting with the value, `1` for the value starting a word, `2` for anything else
81
+ */
82
+ rank: number;
83
+ } & FuzzyItem<Data>;
75
84
  /**
76
- * Search results from a fuzzy search, with exact and similar matches
85
+ * Search results from a fuzzy search, with exact, included, and similar matches
77
86
  */
78
87
  export type FuzzyResult<Item> = {
79
88
  /**
80
- * Ordered items that exactly match the search value
89
+ * Items whose strings exactly match the search value, ordered alphabetically
81
90
  */
82
91
  exact: Item[];
83
92
  /**
84
- * Ordered items that are similar to the search value, ranked by relevance
93
+ * Items whose strings contain the search value, ordered alphabetically
94
+ */
95
+ included: Item[];
96
+ /**
97
+ * Items whose strings are similar to the search value, ranked by relevance, sorted by score, and ordered alphabetically within the same score
85
98
  */
86
99
  similar: Item[];
87
100
  };
@@ -90,19 +103,34 @@ export type FuzzyResult<Item> = {
90
103
  */
91
104
  export type FuzzySearchOptions = { [Key in keyof FuzzyOptions]: FuzzyOptions[Key]; };
92
105
  export type FuzzyState<Item> = {
106
+ compare: FuzzyStateCompare<Item>;
93
107
  handler(item: Item): string;
94
- items: Item[];
95
- limit?: number;
96
- strings: string[];
108
+ items: FuzzyStateItems<Item>;
109
+ limit: number;
97
110
  tolerance: number;
98
111
  };
112
+ type FuzzyStateCompare<Item = unknown> = {
113
+ item: (first: FuzzyItem<Item>, second: FuzzyItem<Item>) => number;
114
+ ranked: (first: FuzzyRanked<Item>, second: FuzzyRanked<Item>) => number;
115
+ };
116
+ type FuzzyStateItems<Item> = {
117
+ original: Array<FuzzyItem<Item>>;
118
+ sorted?: Array<FuzzyItem<Item>>;
119
+ };
120
+ export type FuzzyString = {
121
+ lowercase: string;
122
+ original: string;
123
+ };
99
124
  export type InternalFuzzy<Item = unknown> = {
100
125
  [FUZZY_SYMBOL]: FuzzyState<Item>;
101
126
  } & Fuzzy<Item>;
127
+ export declare const FUZZY_BOUNDARY_BONUS = 2;
128
+ export declare const FUZZY_BOUNDARY_SEPARATOR: RegExp;
102
129
  export declare const FUZZY_LENGTH_DIVISOR = 3;
103
130
  export declare const FUZZY_MESSAGE_ARRAY = "Fuzzy requires an array of items";
104
131
  export declare const FUZZY_MESSAGE_HANDLER = "Fuzzy requires a key or function to stringify items";
105
132
  export declare const FUZZY_PROPERTY = "$fuzzy";
106
133
  export declare const FUZZY_PROXIMITY_THRESHOLD = 5;
107
134
  export declare const FUZZY_SYMBOL: unique symbol;
108
- //#endregion
135
+ //#endregion
136
+ export {};
@@ -1,4 +1,6 @@
1
1
  //#region src/models/string/string.fuzzy.model.ts
2
+ const FUZZY_BOUNDARY_BONUS = 2;
3
+ const FUZZY_BOUNDARY_SEPARATOR = /[\s./:\\_-]/;
2
4
  const FUZZY_LENGTH_DIVISOR = 3;
3
5
  const FUZZY_MESSAGE_ARRAY = "Fuzzy requires an array of items";
4
6
  const FUZZY_MESSAGE_HANDLER = "Fuzzy requires a key or function to stringify items";
@@ -6,4 +8,4 @@ const FUZZY_PROPERTY = "$fuzzy";
6
8
  const FUZZY_PROXIMITY_THRESHOLD = 5;
7
9
  const FUZZY_SYMBOL = Symbol(FUZZY_PROPERTY);
8
10
  //#endregion
9
- export { FUZZY_LENGTH_DIVISOR, FUZZY_MESSAGE_ARRAY, FUZZY_MESSAGE_HANDLER, FUZZY_PROPERTY, FUZZY_PROXIMITY_THRESHOLD, FUZZY_SYMBOL };
11
+ export { FUZZY_BOUNDARY_BONUS, FUZZY_BOUNDARY_SEPARATOR, FUZZY_LENGTH_DIVISOR, FUZZY_MESSAGE_ARRAY, FUZZY_MESSAGE_HANDLER, FUZZY_PROPERTY, FUZZY_PROXIMITY_THRESHOLD, FUZZY_SYMBOL };
@@ -8,7 +8,7 @@ type BaseOptions = {
8
8
  /**
9
9
  * Key _(or key epxressions)_ for values that should be replaced
10
10
  *
11
- * ```ts
11
+ * ```typescript
12
12
  * merge([{items: [1, 2, 3]}, {items: [99]}]); // => {items: [99]}
13
13
  * ```
14
14
  */
@@ -16,7 +16,7 @@ type BaseOptions = {
16
16
  /**
17
17
  * Skip nullable values when merging objects?
18
18
  *
19
- * ```ts
19
+ * ```typescript
20
20
  * merge({a: 1, b: 2}, {b: null, c: 3}, {d: null}); // => {a: 1, b: 2, c: 3}
21
21
  * ```
22
22
  */
@@ -24,7 +24,7 @@ type BaseOptions = {
24
24
  /**
25
25
  * Skip nullable values when merging arrays?
26
26
  *
27
- * ```ts
27
+ * ```typescript
28
28
  * merge([1, 2, 3], [null, null, 99]); // => [1, 2, 99]
29
29
  * ```
30
30
  */