@pawells/typescript-common 1.3.1 → 2.0.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 (149) hide show
  1. package/README.md +69 -15
  2. package/build/array/array-chunk.d.ts +1 -1
  3. package/build/array/array-chunk.d.ts.map +1 -1
  4. package/build/array/array-chunk.js.map +1 -1
  5. package/build/array/array-contains.d.ts +4 -1
  6. package/build/array/array-contains.d.ts.map +1 -1
  7. package/build/array/array-contains.js +4 -0
  8. package/build/array/array-contains.js.map +1 -1
  9. package/build/array/array-count-by.d.ts +3 -1
  10. package/build/array/array-count-by.d.ts.map +1 -1
  11. package/build/array/array-count-by.js +4 -1
  12. package/build/array/array-count-by.js.map +1 -1
  13. package/build/array/array-difference.d.ts +20 -9
  14. package/build/array/array-difference.d.ts.map +1 -1
  15. package/build/array/array-difference.js +25 -8
  16. package/build/array/array-difference.js.map +1 -1
  17. package/build/array/array-filter.d.ts +3 -1
  18. package/build/array/array-filter.d.ts.map +1 -1
  19. package/build/array/array-filter.js +4 -1
  20. package/build/array/array-filter.js.map +1 -1
  21. package/build/array/array-flatten.d.ts +1 -1
  22. package/build/array/array-flatten.d.ts.map +1 -1
  23. package/build/array/array-flatten.js.map +1 -1
  24. package/build/array/array-group-by.d.ts +3 -1
  25. package/build/array/array-group-by.d.ts.map +1 -1
  26. package/build/array/array-group-by.js +4 -1
  27. package/build/array/array-group-by.js.map +1 -1
  28. package/build/array/array-intersection.d.ts +20 -9
  29. package/build/array/array-intersection.d.ts.map +1 -1
  30. package/build/array/array-intersection.js +30 -12
  31. package/build/array/array-intersection.js.map +1 -1
  32. package/build/array/array-partition.d.ts +3 -1
  33. package/build/array/array-partition.d.ts.map +1 -1
  34. package/build/array/array-partition.js +4 -1
  35. package/build/array/array-partition.js.map +1 -1
  36. package/build/array/array-sample.d.ts +6 -2
  37. package/build/array/array-sample.d.ts.map +1 -1
  38. package/build/array/array-sample.js +8 -6
  39. package/build/array/array-sample.js.map +1 -1
  40. package/build/array/array-shuffle.d.ts +4 -2
  41. package/build/array/array-shuffle.d.ts.map +1 -1
  42. package/build/array/array-shuffle.js +6 -3
  43. package/build/array/array-shuffle.js.map +1 -1
  44. package/build/array/array-sort-by.d.ts +1 -1
  45. package/build/array/array-sort-by.d.ts.map +1 -1
  46. package/build/array/array-sort-by.js.map +1 -1
  47. package/build/array/assert.d.ts +22 -18
  48. package/build/array/assert.d.ts.map +1 -1
  49. package/build/array/assert.js +27 -23
  50. package/build/array/assert.js.map +1 -1
  51. package/build/array/types.d.ts +11 -0
  52. package/build/array/types.d.ts.map +1 -1
  53. package/build/array/unique.d.ts +3 -1
  54. package/build/array/unique.d.ts.map +1 -1
  55. package/build/array/unique.js +4 -1
  56. package/build/array/unique.js.map +1 -1
  57. package/build/asserts/generic.d.ts +9 -0
  58. package/build/asserts/generic.d.ts.map +1 -1
  59. package/build/asserts/generic.js +30 -8
  60. package/build/asserts/generic.js.map +1 -1
  61. package/build/asserts/utils.d.ts +32 -0
  62. package/build/asserts/utils.d.ts.map +1 -1
  63. package/build/asserts/utils.js +79 -0
  64. package/build/asserts/utils.js.map +1 -1
  65. package/build/boolean/assert.d.ts.map +1 -1
  66. package/build/boolean/assert.js +2 -5
  67. package/build/boolean/assert.js.map +1 -1
  68. package/build/function/compose.d.ts +3 -2
  69. package/build/function/compose.d.ts.map +1 -1
  70. package/build/function/compose.js.map +1 -1
  71. package/build/function/debounce.d.ts +2 -1
  72. package/build/function/debounce.d.ts.map +1 -1
  73. package/build/function/debounce.js.map +1 -1
  74. package/build/function/once.d.ts +1 -0
  75. package/build/function/once.d.ts.map +1 -1
  76. package/build/function/once.js +1 -0
  77. package/build/function/once.js.map +1 -1
  78. package/build/function/throttle.d.ts +2 -1
  79. package/build/function/throttle.d.ts.map +1 -1
  80. package/build/function/throttle.js.map +1 -1
  81. package/build/index.d.ts +2 -2
  82. package/build/index.d.ts.map +1 -1
  83. package/build/index.js +1 -1
  84. package/build/index.js.map +1 -1
  85. package/build/number/assert.d.ts.map +1 -1
  86. package/build/number/assert.js +38 -42
  87. package/build/number/assert.js.map +1 -1
  88. package/build/object/clone.d.ts.map +1 -1
  89. package/build/object/clone.js +3 -0
  90. package/build/object/clone.js.map +1 -1
  91. package/build/object/equals.d.ts +1 -1
  92. package/build/object/equals.d.ts.map +1 -1
  93. package/build/object/equals.js +14 -7
  94. package/build/object/equals.js.map +1 -1
  95. package/build/object/filter-cached.js.map +1 -1
  96. package/build/object/filter.d.ts +7 -1
  97. package/build/object/filter.d.ts.map +1 -1
  98. package/build/object/filter.js +36 -61
  99. package/build/object/filter.js.map +1 -1
  100. package/build/object/hash.d.ts +1 -1
  101. package/build/object/hash.d.ts.map +1 -1
  102. package/build/object/hash.js +1 -0
  103. package/build/object/hash.js.map +1 -1
  104. package/build/object/key-value-pairs.d.ts +1 -1
  105. package/build/object/key-value-pairs.d.ts.map +1 -1
  106. package/build/object/key-value-pairs.js.map +1 -1
  107. package/build/object/omit.d.ts +1 -1
  108. package/build/object/omit.d.ts.map +1 -1
  109. package/build/object/omit.js.map +1 -1
  110. package/build/object/pick.d.ts +1 -1
  111. package/build/object/pick.d.ts.map +1 -1
  112. package/build/object/pick.js.map +1 -1
  113. package/build/object/property-paths.d.ts +2 -2
  114. package/build/object/property-paths.d.ts.map +1 -1
  115. package/build/object/property-paths.js +7 -2
  116. package/build/object/property-paths.js.map +1 -1
  117. package/build/object/security-utils.d.ts +2 -2
  118. package/build/object/security-utils.d.ts.map +1 -1
  119. package/build/object/security-utils.js.map +1 -1
  120. package/build/object/types.d.ts +1 -1
  121. package/build/object/types.d.ts.map +1 -1
  122. package/build/string/assert.d.ts.map +1 -1
  123. package/build/string/assert.js +3 -9
  124. package/build/string/assert.js.map +1 -1
  125. package/build/string/case-conversion.d.ts +53 -24
  126. package/build/string/case-conversion.d.ts.map +1 -1
  127. package/build/string/case-conversion.js +59 -29
  128. package/build/string/case-conversion.js.map +1 -1
  129. package/build/string/comparison.d.ts +20 -0
  130. package/build/string/comparison.d.ts.map +1 -0
  131. package/build/string/comparison.js +25 -0
  132. package/build/string/comparison.js.map +1 -0
  133. package/build/string/formatting.d.ts +35 -22
  134. package/build/string/formatting.d.ts.map +1 -1
  135. package/build/string/formatting.js +35 -22
  136. package/build/string/formatting.js.map +1 -1
  137. package/build/string/index.d.ts +1 -0
  138. package/build/string/index.d.ts.map +1 -1
  139. package/build/string/index.js +1 -0
  140. package/build/string/index.js.map +1 -1
  141. package/build/string/transformation.d.ts +19 -9
  142. package/build/string/transformation.d.ts.map +1 -1
  143. package/build/string/transformation.js +21 -10
  144. package/build/string/transformation.js.map +1 -1
  145. package/build/string/validation.d.ts +21 -9
  146. package/build/string/validation.d.ts.map +1 -1
  147. package/build/string/validation.js +23 -10
  148. package/build/string/validation.js.map +1 -1
  149. package/package.json +2 -2
package/README.md CHANGED
@@ -36,7 +36,60 @@ BooleanUtils.AssertBoolean(value); // throws if not a boolean
36
36
  NumberUtils.AssertNumber(value, { gte: 0, integer: true });
37
37
 
38
38
  // Direct named import (tree-shakeable)
39
- import { ArrayChunk, ObjectPick, CamelCase, Sleep, AssertString, LRUCache } from '@pawells/typescript-common';
39
+ import { ArrayChunk, ObjectPick, KebabCase, Sleep, AssertString, LRUCache } from '@pawells/typescript-common';
40
+ ```
41
+
42
+ ## Features & Patterns
43
+
44
+ ### Readonly Array Support
45
+
46
+ All array utilities accept `readonly T[]` arrays, enabling zero-copy usage with frozen constants:
47
+
48
+ ```typescript
49
+ const colors = Object.freeze(['red', 'green', 'blue']); // readonly string[]
50
+ ArrayChunk(colors, 2); // Works without casting!
51
+ ArrayFilter(colors, c => c.length > 3); // ✓ No type errors
52
+ ```
53
+
54
+ ### Custom RNG for Deterministic Testing
55
+
56
+ `ArraySample` and `ArrayShuffle` accept an optional custom RNG function for reproducible randomization:
57
+
58
+ ```typescript
59
+ const seededRng = Mulberry32(42); // Your seeded PRNG
60
+ ArrayShuffle([1, 2, 3], seededRng); // Same output every time
61
+ ArraySample([1, 2, 3], 2, seededRng); // Deterministic sampling
62
+
63
+ // Without RNG, defaults to Math.random() for normal usage
64
+ ArrayShuffle([1, 2, 3]); // Random shuffle
65
+ ```
66
+
67
+ ### Predicate Functions in ObjectFilter
68
+
69
+ Filter by predicate functions in addition to equality checks:
70
+
71
+ ```typescript
72
+ const user = { name: 'John', age: 30, active: true };
73
+
74
+ // Basic equality filtering
75
+ ObjectFilter(user, { name: 'John' }); // true
76
+
77
+ // Predicate functions as filter values
78
+ ObjectFilter(user, { age: (v) => v > 18 }); // true
79
+ ObjectFilter(user, { age: (v) => v < 18 }); // false
80
+
81
+ // Mix predicates and values
82
+ ObjectFilter(user, {
83
+ active: true,
84
+ age: (v) => v >= 21
85
+ }); // true
86
+
87
+ // Supports dot notation with predicates
88
+ const order = { user: { age: 25 }, total: 100 };
89
+ ObjectFilter(order, {
90
+ 'user.age': (v) => v >= 21,
91
+ 'total': (v) => v > 50
92
+ }); // true
40
93
  ```
41
94
 
42
95
  ## API
@@ -50,7 +103,8 @@ import { ArrayChunk, ObjectPick, CamelCase, Sleep, AssertString, LRUCache } from
50
103
  | `ArrayFilter(array, predicate)` | Type-safe array filter |
51
104
  | `ArrayGroupBy(array, keyFn)` | Group array elements by a key function |
52
105
  | `ArrayIntersection(a, b)` | Return elements present in both arrays |
53
- | `ArrayShuffle(array)` | Return a shuffled copy of an array |
106
+ | `ArrayShuffle(array, rng?)` | Return a shuffled copy of an array (optional custom RNG for deterministic results) |
107
+ | `ArraySample(array, n?, rng?)` | Random element or `n` random elements (optional custom RNG for deterministic results) |
54
108
  | `Unique(array)` | Remove duplicate values |
55
109
  | `ArrayDifference(a, b)` | Elements in `a` not present in `b` |
56
110
  | `ArrayFlatten(array, depth?)` | Flatten a nested array to a given depth |
@@ -60,7 +114,6 @@ import { ArrayChunk, ObjectPick, CamelCase, Sleep, AssertString, LRUCache } from
60
114
  | `ArrayRange(start, end, step?)` | Generate a numeric sequence |
61
115
  | `ArraySortBy(array, keyFn, direction?)` | Immutable sort by a computed key |
62
116
  | `ArrayCountBy(array, keyFn)` | Count elements per group key |
63
- | `ArraySample(array, n?)` | Random element or `n` random elements |
64
117
  | `AssertArray(value, args?, exception?)` | Assert value is an array (with optional size constraints) |
65
118
  | `AssertArray2D(value, args?, exception?)` | Assert value is a rectangular 2D array |
66
119
  | `AssertArrayNotEmpty(value, exception?)` | Assert array has at least one element |
@@ -86,14 +139,14 @@ import { ArrayChunk, ObjectPick, CamelCase, Sleep, AssertString, LRUCache } from
86
139
  | `IsObject(value)` | Type-guard: returns `true` if value is a non-null, non-array object |
87
140
  | `ObjectClone(obj)` | Deep-clone an object |
88
141
  | `ObjectEquals(a, b)` | Deep equality check |
89
- | `ObjectFilter(obj, predicate)` | Filter object entries by predicate |
90
- | `ObjectFilterCached(obj, predicate)` | Cached filter for repeated operations |
142
+ | `ObjectFilter(obj, filter, options?)` | Filter object by property values or predicate functions (supports dot notation, deep equality, case-insensitive matching, and predicate functions) |
143
+ | `ObjectFilterCached(options?)` | Returns a cached filter function for repeated filtering operations with optional deep equality and case-insensitive matching |
91
144
  | `FilterObject(obj, keys)` | Keep only specified keys |
92
145
  | `ObjectPick(obj, keys)` | Pick a subset of keys |
93
146
  | `ObjectOmit(obj, keys)` | Omit specified keys |
94
147
  | `ObjectMerge(target, ...sources)` | Deep merge objects |
95
148
  | `MapObject(obj, fn)` | Map over object values |
96
- | `MapObjectCached(obj, fn)` | Cached map for repeated operations |
149
+ | `MapObjectCached(options?)` | Returns a cached map function for repeated mapping operations with optional async support |
97
150
  | `TransformObject(obj, fn)` | Transform object entries |
98
151
  | `ObjectHash(obj)` | Compute a stable hash of an object |
99
152
  | `ObjectSortKeys(obj)` | Return object with keys sorted |
@@ -116,11 +169,11 @@ import { ArrayChunk, ObjectPick, CamelCase, Sleep, AssertString, LRUCache } from
116
169
  | Export | Description |
117
170
  |--------|-------------|
118
171
  | `CamelCase(str)` | Convert a string to camelCase |
119
- | `CAPITALIZE(str)` | Capitalize the first letter of a string |
120
- | `PASCAL_CASE(str)` | Convert a string to PascalCase |
121
- | `KEBAB_CASE(str)` | Convert a string to kebab-case |
122
- | `SNAKE_CASE(str)` | Convert a string to snake_case |
123
- | `SCREAMING_SNAKE_CASE(str)` | Convert a string to SCREAMING_SNAKE_CASE |
172
+ | `Capitalize(str)` | Capitalize the first letter of a string |
173
+ | `PascalCase(str)` | Convert a string to PascalCase |
174
+ | `KebabCase(str)` | Convert a string to kebab-case |
175
+ | `SnakeCase(str)` | Convert a string to snake_case |
176
+ | `ScreamingSnakeCase(str)` | Convert a string to SCREAMING_SNAKE_CASE |
124
177
  | `FormatString(template, values)` | Simple string template formatting |
125
178
  | `TruncateString(str, maxLength, ellipsis?)` | Truncate a string with ellipsis |
126
179
  | `PadString(str, length, char?, padEnd?)` | Pad a string to a specified length |
@@ -129,10 +182,11 @@ import { ArrayChunk, ObjectPick, CamelCase, Sleep, AssertString, LRUCache } from
129
182
  | `Pluralize(word, count, plural?)` | Return singular or plural form based on count |
130
183
  | `WordCount(str)` | Count the number of words in a string |
131
184
  | `CountOccurrences(str, substr)` | Count non-overlapping occurrences of a substring |
132
- | `REVERSE_STRING(str)` | Reverse a string |
133
- | `SLUGIFY(str)` | Convert a string to a URL-friendly slug |
134
- | `IS_BLANK_STRING(str)` | Check if a string is empty or whitespace-only |
135
- | `IS_HEX_STRING(str)` | Check if a string is a valid hexadecimal value |
185
+ | `ReverseString(str)` | Reverse a string |
186
+ | `Slugify(str)` | Convert a string to a URL-friendly slug |
187
+ | `IsBlankString(str)` | Check if a string is empty or whitespace-only |
188
+ | `IsHexString(str)` | Check if a string is a valid hexadecimal value |
189
+ | `StringEquals(a, b, caseInsensitive?)` | Compare two strings with optional case-insensitive matching |
136
190
  | `AssertString(value, exception?)` | Assert value is a string primitive |
137
191
  | `AssertStringNotEmpty(value, exception?)` | Assert value is a non-empty, non-whitespace string |
138
192
  | `AssertStringMatches(value, regex, exception?)` | Assert string matches a regular expression |
@@ -12,5 +12,5 @@
12
12
  * ArrayChunk(['a', 'b', 'c'], 2); // [['a', 'b'], ['c']]
13
13
  * ```
14
14
  */
15
- export declare function ArrayChunk<T>(array: T[], size: number): T[][];
15
+ export declare function ArrayChunk<T>(array: readonly T[], size: number): T[][];
16
16
  //# sourceMappingURL=array-chunk.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"array-chunk.d.ts","sourceRoot":"","sources":["../../src/array/array-chunk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,EAAE,CAY7D"}
1
+ {"version":3,"file":"array-chunk.d.ts","sourceRoot":"","sources":["../../src/array/array-chunk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,EAAE,EAAE,CAYtE"}
@@ -1 +1 @@
1
- {"version":3,"file":"array-chunk.js","sourceRoot":"","sources":["../../src/array/array-chunk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,UAAU,CAAI,KAAU,EAAE,IAAY;IACrD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC;QAC1D,OAAO,EAAE,CAAC;IACX,CAAC;IAED,MAAM,MAAM,GAAU,EAAE,CAAC;IAEzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,MAAM,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"array-chunk.js","sourceRoot":"","sources":["../../src/array/array-chunk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,UAAU,CAAI,KAAmB,EAAE,IAAY;IAC9D,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC;QAC1D,OAAO,EAAE,CAAC;IACX,CAAC;IAED,MAAM,MAAM,GAAU,EAAE,CAAC;IAEzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,MAAM,CAAC;AACf,CAAC"}
@@ -2,6 +2,9 @@ import type { TPredicate } from './types.js';
2
2
  /**
3
3
  * Checks if an array contains at least one element that passes a predicate test.
4
4
  *
5
+ * Uses `array.some()` to check if any element satisfies the predicate condition.
6
+ * Returns false if the array is null, undefined, or empty.
7
+ *
5
8
  * @template T - The type of array elements
6
9
  * @param array - The array to check
7
10
  * @param predicate - A function that tests each element; returns `true` to signal a match
@@ -13,5 +16,5 @@ import type { TPredicate } from './types.js';
13
16
  * ArrayContains([1, 2, 3], (n) => n > 10); // false
14
17
  * ```
15
18
  */
16
- export declare function ArrayContains<T>(array: T[], predicate: TPredicate<T>): boolean;
19
+ export declare function ArrayContains<T>(array: readonly T[], predicate: TPredicate<T>): boolean;
17
20
  //# sourceMappingURL=array-contains.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"array-contains.d.ts","sourceRoot":"","sources":["../../src/array/array-contains.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAM9E"}
1
+ {"version":3,"file":"array-contains.d.ts","sourceRoot":"","sources":["../../src/array/array-contains.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAOvF"}
@@ -1,6 +1,9 @@
1
1
  /**
2
2
  * Checks if an array contains at least one element that passes a predicate test.
3
3
  *
4
+ * Uses `array.some()` to check if any element satisfies the predicate condition.
5
+ * Returns false if the array is null, undefined, or empty.
6
+ *
4
7
  * @template T - The type of array elements
5
8
  * @param array - The array to check
6
9
  * @param predicate - A function that tests each element; returns `true` to signal a match
@@ -13,6 +16,7 @@
13
16
  * ```
14
17
  */
15
18
  export function ArrayContains(array, predicate) {
19
+ // Predicate functions use array.some() / array.every() for consistency
16
20
  if (!array || array.length === 0) {
17
21
  return false;
18
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"array-contains.js","sourceRoot":"","sources":["../../src/array/array-contains.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,aAAa,CAAI,KAAU,EAAE,SAAwB;IACpE,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"array-contains.js","sourceRoot":"","sources":["../../src/array/array-contains.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,aAAa,CAAI,KAAmB,EAAE,SAAwB;IAC7E,uEAAuE;IACvE,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAC9B,CAAC"}
@@ -2,6 +2,8 @@ import type { TTransform } from './types.js';
2
2
  /**
3
3
  * Counts how many elements fall into each group defined by `keyFn`.
4
4
  *
5
+ * Returns empty object if array is null, undefined, or empty.
6
+ *
5
7
  * @template T - The type of array elements
6
8
  * @template K - The key type (string, number, or symbol)
7
9
  * @param array - The array to count
@@ -17,5 +19,5 @@ import type { TTransform } from './types.js';
17
19
  * // { admin: 3, member: 12, guest: 1 }
18
20
  * ```
19
21
  */
20
- export declare function ArrayCountBy<T, K extends string | number | symbol>(array: T[], keyFn: TTransform<T, K>): Record<K, number>;
22
+ export declare function ArrayCountBy<T, K extends string | number | symbol>(array: readonly T[], keyFn: TTransform<T, K>): Record<K, number>;
21
23
  //# sourceMappingURL=array-count-by.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"array-count-by.d.ts","sourceRoot":"","sources":["../../src/array/array-count-by.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,EACjE,KAAK,EAAE,CAAC,EAAE,EACV,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,GACrB,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAWnB"}
1
+ {"version":3,"file":"array-count-by.d.ts","sourceRoot":"","sources":["../../src/array/array-count-by.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,EACjE,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,GACrB,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAYnB"}
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * Counts how many elements fall into each group defined by `keyFn`.
3
3
  *
4
+ * Returns empty object if array is null, undefined, or empty.
5
+ *
4
6
  * @template T - The type of array elements
5
7
  * @template K - The key type (string, number, or symbol)
6
8
  * @param array - The array to count
@@ -17,7 +19,8 @@
17
19
  * ```
18
20
  */
19
21
  export function ArrayCountBy(array, keyFn) {
20
- if (array === null || array === undefined)
22
+ // Consistent null-check: early return for null/undefined arrays
23
+ if (!array)
21
24
  return {};
22
25
  const result = {};
23
26
  for (const item of array) {
@@ -1 +1 @@
1
- {"version":3,"file":"array-count-by.js","sourceRoot":"","sources":["../../src/array/array-count-by.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,YAAY,CAC3B,KAAU,EACV,KAAuB;IAEvB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAuB,CAAC;IAE1E,MAAM,MAAM,GAAG,EAAuB,CAAC;IAEvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QACxB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAE,MAAM,CAAC,GAAG,CAAwB,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO,MAAM,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"array-count-by.js","sourceRoot":"","sources":["../../src/array/array-count-by.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,YAAY,CAC3B,KAAmB,EACnB,KAAuB;IAEvB,gEAAgE;IAChE,IAAI,CAAC,KAAK;QAAE,OAAO,EAAuB,CAAC;IAE3C,MAAM,MAAM,GAAG,EAAuB,CAAC;IAEvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QACxB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAE,MAAM,CAAC,GAAG,CAAwB,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO,MAAM,CAAC;AACf,CAAC"}
@@ -1,25 +1,36 @@
1
- import type { TEqualityComparator } from './types.js';
1
+ import type { TArrayComparisonOptions } from './types.js';
2
2
  /**
3
3
  * Returns elements present in the first array but not in the second (set difference).
4
4
  * Optimised O(n+m) using a Set when no custom comparator is provided.
5
+ * Supports custom comparators for advanced comparison logic, or deep equality checking.
5
6
  *
6
7
  * @template T - The type of array elements
7
8
  * @param array1 - The source array
8
9
  * @param array2 - Elements to exclude
9
- * @param comparator - Optional custom equality comparator
10
+ * @param options - Optional configuration
11
+ * @param options.comparator - Custom function to determine if elements are equal (optional)
12
+ * @param options.useDeepEqual - Use deep equality for comparison instead of custom comparator (optional)
10
13
  * @returns Array of elements in `array1` that are not in `array2`
11
14
  *
12
15
  * @example
13
16
  * ```typescript
17
+ * // Basic difference with primitives
14
18
  * ArrayDifference([1, 2, 3, 4], [2, 4]); // [1, 3]
15
- * ArrayDifference(
16
- * [{ id: 1 }, { id: 2 }],
17
- * [{ id: 2 }],
18
- * (a, b) => a.id === b.id,
19
- * ); // [{ id: 1 }]
19
+ *
20
+ * // Deep equality comparison with objects
21
+ * const arr1 = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }];
22
+ * const arr2 = [{ id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' }];
23
+ * ArrayDifference(arr1, arr2, { useDeepEqual: true });
24
+ * // [{ id: 1, name: 'Alice' }]
25
+ *
26
+ * // Custom comparator
27
+ * ArrayDifference(arr1, arr2, {
28
+ * comparator: (a, b) => a.id === b.id
29
+ * });
30
+ * // [{ id: 1, name: 'Alice' }]
20
31
  * ```
21
32
  *
22
- * @complexity O(n+m) for primitive values, O(n*m) when a comparator is provided
33
+ * @complexity O(n+m) for primitive values, O(n*m) when a comparator or deep equality is provided
23
34
  */
24
- export declare function ArrayDifference<T>(array1: T[], array2: T[], comparator?: TEqualityComparator<T>): T[];
35
+ export declare function ArrayDifference<T>(array1: readonly T[], array2: readonly T[], options?: TArrayComparisonOptions<T>): T[];
25
36
  //# sourceMappingURL=array-difference.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"array-difference.d.ts","sourceRoot":"","sources":["../../src/array/array-difference.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAChC,MAAM,EAAE,CAAC,EAAE,EACX,MAAM,EAAE,CAAC,EAAE,EACX,UAAU,CAAC,EAAE,mBAAmB,CAAC,CAAC,CAAC,GACjC,CAAC,EAAE,CAUL"}
1
+ {"version":3,"file":"array-difference.d.ts","sourceRoot":"","sources":["../../src/array/array-difference.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAG1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAChC,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,OAAO,CAAC,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAClC,CAAC,EAAE,CAiBL"}
@@ -1,33 +1,50 @@
1
+ import { ObjectEquals } from '../object/equals.js';
1
2
  /**
2
3
  * Returns elements present in the first array but not in the second (set difference).
3
4
  * Optimised O(n+m) using a Set when no custom comparator is provided.
5
+ * Supports custom comparators for advanced comparison logic, or deep equality checking.
4
6
  *
5
7
  * @template T - The type of array elements
6
8
  * @param array1 - The source array
7
9
  * @param array2 - Elements to exclude
8
- * @param comparator - Optional custom equality comparator
10
+ * @param options - Optional configuration
11
+ * @param options.comparator - Custom function to determine if elements are equal (optional)
12
+ * @param options.useDeepEqual - Use deep equality for comparison instead of custom comparator (optional)
9
13
  * @returns Array of elements in `array1` that are not in `array2`
10
14
  *
11
15
  * @example
12
16
  * ```typescript
17
+ * // Basic difference with primitives
13
18
  * ArrayDifference([1, 2, 3, 4], [2, 4]); // [1, 3]
14
- * ArrayDifference(
15
- * [{ id: 1 }, { id: 2 }],
16
- * [{ id: 2 }],
17
- * (a, b) => a.id === b.id,
18
- * ); // [{ id: 1 }]
19
+ *
20
+ * // Deep equality comparison with objects
21
+ * const arr1 = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }];
22
+ * const arr2 = [{ id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' }];
23
+ * ArrayDifference(arr1, arr2, { useDeepEqual: true });
24
+ * // [{ id: 1, name: 'Alice' }]
25
+ *
26
+ * // Custom comparator
27
+ * ArrayDifference(arr1, arr2, {
28
+ * comparator: (a, b) => a.id === b.id
29
+ * });
30
+ * // [{ id: 1, name: 'Alice' }]
19
31
  * ```
20
32
  *
21
- * @complexity O(n+m) for primitive values, O(n*m) when a comparator is provided
33
+ * @complexity O(n+m) for primitive values, O(n*m) when a comparator or deep equality is provided
22
34
  */
23
- export function ArrayDifference(array1, array2, comparator) {
35
+ export function ArrayDifference(array1, array2, options) {
24
36
  if (!array1)
25
37
  return [];
26
38
  if (!array2 || array2.length === 0)
27
39
  return [...array1];
40
+ const opts = options ?? {};
41
+ const { comparator, useDeepEqual = false } = opts;
28
42
  if (comparator) {
29
43
  return array1.filter((item) => !array2.some((other) => comparator(item, other)));
30
44
  }
45
+ if (useDeepEqual) {
46
+ return array1.filter((item) => !array2.some((other) => ObjectEquals(item, other)));
47
+ }
31
48
  const set2 = new Set(array2);
32
49
  return array1.filter((item) => !set2.has(item));
33
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"array-difference.js","sourceRoot":"","sources":["../../src/array/array-difference.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,eAAe,CAC9B,MAAW,EACX,MAAW,EACX,UAAmC;IAEnC,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IACvB,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC;IAEvD,IAAI,UAAU,EAAE,CAAC;QAChB,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAClF,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACjD,CAAC"}
1
+ {"version":3,"file":"array-difference.js","sourceRoot":"","sources":["../../src/array/array-difference.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,UAAU,eAAe,CAC9B,MAAoB,EACpB,MAAoB,EACpB,OAAoC;IAEpC,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IACvB,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC;IAEvD,MAAM,IAAI,GAAI,OAAe,IAAI,EAAE,CAAC;IACpC,MAAM,EAAE,UAAU,EAAE,YAAY,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC;IAElD,IAAI,UAAU,EAAE,CAAC;QAChB,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAClF,CAAC;IAED,IAAI,YAAY,EAAE,CAAC;QAClB,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACjD,CAAC"}
@@ -3,6 +3,8 @@ import type { TPredicate } from './types.js';
3
3
  * Filters an array based on criteria that can be an object filter or a predicate function.
4
4
  * Supports nested property filtering with dot notation and array property filtering.
5
5
  *
6
+ * Returns empty array if input is null, undefined, or empty.
7
+ *
6
8
  * @param array - The array to filter
7
9
  * @param criteria - Either an object with filter criteria or a predicate function
8
10
  * @returns A new array containing only items that match the criteria
@@ -33,5 +35,5 @@ import type { TPredicate } from './types.js';
33
35
  * const numbers = [1, 2, 3, 4, 5];
34
36
  * ArrayFilter(numbers, (n) => n > 3); // [4, 5]
35
37
  */
36
- export declare function ArrayFilter<T>(array: T[], criteria: Partial<Record<string, unknown>> | TPredicate<T>): T[];
38
+ export declare function ArrayFilter<T>(array: readonly T[], criteria: Partial<Record<string, unknown>> | TPredicate<T>): T[];
37
39
  //# sourceMappingURL=array-filter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"array-filter.d.ts","sourceRoot":"","sources":["../../src/array/array-filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAsC7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC5B,KAAK,EAAE,CAAC,EAAE,EACV,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GACxD,CAAC,EAAE,CAeL"}
1
+ {"version":3,"file":"array-filter.d.ts","sourceRoot":"","sources":["../../src/array/array-filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAsC7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC5B,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,GACxD,CAAC,EAAE,CAgBL"}
@@ -35,6 +35,8 @@ function matchesValue(value, filterValue) {
35
35
  * Filters an array based on criteria that can be an object filter or a predicate function.
36
36
  * Supports nested property filtering with dot notation and array property filtering.
37
37
  *
38
+ * Returns empty array if input is null, undefined, or empty.
39
+ *
38
40
  * @param array - The array to filter
39
41
  * @param criteria - Either an object with filter criteria or a predicate function
40
42
  * @returns A new array containing only items that match the criteria
@@ -66,7 +68,8 @@ function matchesValue(value, filterValue) {
66
68
  * ArrayFilter(numbers, (n) => n > 3); // [4, 5]
67
69
  */
68
70
  export function ArrayFilter(array, criteria) {
69
- if (array === null || array === undefined)
71
+ // Consistent null-check: early return for null/undefined arrays
72
+ if (!array)
70
73
  return [];
71
74
  // If criteria is a function, use it as predicate
72
75
  if (typeof criteria === 'function') {
@@ -1 +1 @@
1
- {"version":3,"file":"array-filter.js","sourceRoot":"","sources":["../../src/array/array-filter.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,SAAS,cAAc,CAAC,GAAY,EAAE,IAAY;IACjD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,OAAO,GAAQ,GAAG,CAAC;IAEvB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAChE,kCAAkC;QAClC,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,aAAa,IAAI,GAAG,KAAK,WAAW;YAAE,OAAO,SAAS,CAAC;QAC1F,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,OAAO,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,SAAS,YAAY,CAAC,KAAc,EAAE,WAAoB;IACzD,8DAA8D;IAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IACpC,CAAC;IAED,wBAAwB;IACxB,OAAO,KAAK,KAAK,WAAW,CAAC;AAC9B,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,UAAU,WAAW,CAC1B,KAAU,EACV,QAA0D;IAE1D,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IAErD,iDAAiD;IACjD,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAED,6CAA6C;IAC7C,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QAC5B,OAAO,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,EAAE;YAC5D,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YAC5C,OAAO,YAAY,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"array-filter.js","sourceRoot":"","sources":["../../src/array/array-filter.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,SAAS,cAAc,CAAC,GAAY,EAAE,IAAY;IACjD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,OAAO,GAAQ,GAAG,CAAC;IAEvB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAChE,kCAAkC;QAClC,IAAI,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,aAAa,IAAI,GAAG,KAAK,WAAW;YAAE,OAAO,SAAS,CAAC;QAC1F,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,OAAO,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,SAAS,YAAY,CAAC,KAAc,EAAE,WAAoB;IACzD,8DAA8D;IAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IACpC,CAAC;IAED,wBAAwB;IACxB,OAAO,KAAK,KAAK,WAAW,CAAC;AAC9B,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,UAAU,WAAW,CAC1B,KAAmB,EACnB,QAA0D;IAE1D,gEAAgE;IAChE,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IAEtB,iDAAiD;IACjD,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAED,6CAA6C;IAC7C,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QAC5B,OAAO,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,EAAE;YAC5D,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YAC5C,OAAO,YAAY,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC"}
@@ -12,5 +12,5 @@
12
12
  * ArrayFlatten([1, [2, [3]]], 1); // [1, 2, [3]]
13
13
  * ```
14
14
  */
15
- export declare function ArrayFlatten<T = unknown>(array: any[], depth?: number): T[];
15
+ export declare function ArrayFlatten<T = unknown>(array: readonly any[], depth?: number): T[];
16
16
  //# sourceMappingURL=array-flatten.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"array-flatten.d.ts","sourceRoot":"","sources":["../../src/array/array-flatten.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,CAG3E"}
1
+ {"version":3,"file":"array-flatten.d.ts","sourceRoot":"","sources":["../../src/array/array-flatten.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,SAAS,GAAG,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE,CAGpF"}
@@ -1 +1 @@
1
- {"version":3,"file":"array-flatten.js","sourceRoot":"","sources":["../../src/array/array-flatten.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,YAAY,CAAc,KAAY,EAAE,KAAc;IACrE,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACrD,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAQ,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"array-flatten.js","sourceRoot":"","sources":["../../src/array/array-flatten.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,YAAY,CAAc,KAAqB,EAAE,KAAc;IAC9E,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACrD,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAQ,CAAC;AAC7C,CAAC"}
@@ -2,6 +2,8 @@ import type { TTransform } from './types.js';
2
2
  /**
3
3
  * Groups array elements by a key generated by a provided function.
4
4
  *
5
+ * Returns empty object if array is null, undefined, or empty.
6
+ *
5
7
  * @template T - The type of array elements
6
8
  * @template K - The key type (string, number, or symbol)
7
9
  * @param array - The array to group
@@ -18,5 +20,5 @@ import type { TTransform } from './types.js';
18
20
  * // { 3: ['one', 'two'], 5: ['three'] }
19
21
  * ```
20
22
  */
21
- export declare function ArrayGroupBy<T, K extends string | number | symbol>(array: T[], keyFn: TTransform<T, K>): Record<K, T[]>;
23
+ export declare function ArrayGroupBy<T, K extends string | number | symbol>(array: readonly T[], keyFn: TTransform<T, K>): Record<K, T[]>;
22
24
  //# sourceMappingURL=array-group-by.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"array-group-by.d.ts","sourceRoot":"","sources":["../../src/array/array-group-by.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAavH"}
1
+ {"version":3,"file":"array-group-by.d.ts","sourceRoot":"","sources":["../../src/array/array-group-by.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAchI"}
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * Groups array elements by a key generated by a provided function.
3
3
  *
4
+ * Returns empty object if array is null, undefined, or empty.
5
+ *
4
6
  * @template T - The type of array elements
5
7
  * @template K - The key type (string, number, or symbol)
6
8
  * @param array - The array to group
@@ -18,7 +20,8 @@
18
20
  * ```
19
21
  */
20
22
  export function ArrayGroupBy(array, keyFn) {
21
- if (array === null || array === undefined) {
23
+ // Consistent null-check: early return for null/undefined arrays
24
+ if (!array) {
22
25
  return {};
23
26
  }
24
27
  return array.reduce((acc, item) => {
@@ -1 +1 @@
1
- {"version":3,"file":"array-group-by.js","sourceRoot":"","sources":["../../src/array/array-group-by.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,YAAY,CAAwC,KAAU,EAAE,KAAuB;IACtG,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC3C,OAAO,EAAoB,CAAC;IAC7B,CAAC;IAED,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;QACjC,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACf,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;QACf,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,OAAO,GAAG,CAAC;IACZ,CAAC,EAAE,EAAoB,CAAC,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"array-group-by.js","sourceRoot":"","sources":["../../src/array/array-group-by.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,YAAY,CAAwC,KAAmB,EAAE,KAAuB;IAC/G,gEAAgE;IAChE,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,OAAO,EAAoB,CAAC;IAC7B,CAAC;IAED,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;QACjC,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACf,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;QACf,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,OAAO,GAAG,CAAC;IACZ,CAAC,EAAE,EAAoB,CAAC,CAAC;AAC1B,CAAC"}
@@ -1,25 +1,36 @@
1
- import type { TEqualityComparator } from './types.js';
1
+ import type { TArrayComparisonOptions } from './types.js';
2
2
  /**
3
3
  * Returns the intersection of two arrays (elements present in both)
4
- * Optimized O(n+m) complexity using Set-based approach
4
+ * Optimized O(n+m) complexity using Set-based approach.
5
+ * Supports custom comparators for advanced comparison logic, or deep equality checking.
5
6
  *
6
7
  * @template T - The type of array elements
7
8
  * @param array1 - First array
8
9
  * @param array2 - Second array
9
- * @param comparator - Optional custom equality comparator
10
+ * @param options - Optional configuration
11
+ * @param options.comparator - Custom function to determine if elements are equal (optional)
12
+ * @param options.useDeepEqual - Use deep equality for comparison instead of custom comparator (optional)
10
13
  * @returns Array containing elements present in both arrays
11
14
  *
12
15
  * @example
13
16
  * ```typescript
17
+ * // Basic intersection with primitives
14
18
  * ArrayIntersection([1, 2, 3], [2, 3, 4]); // [2, 3]
15
- * ArrayIntersection(
16
- * [{id: 1}, {id: 2}],
17
- * [{id: 2}, {id: 3}],
18
- * (a, b) => a.id === b.id
19
- * ); // [{id: 2}]
19
+ *
20
+ * // Deep equality comparison with objects
21
+ * const arr1 = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }];
22
+ * const arr2 = [{ id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' }];
23
+ * ArrayIntersection(arr1, arr2, { useDeepEqual: true });
24
+ * // [{ id: 2, name: 'Bob' }]
25
+ *
26
+ * // Custom comparator
27
+ * ArrayIntersection(arr1, arr2, {
28
+ * comparator: (a, b) => a.id === b.id
29
+ * });
30
+ * // [{ id: 2, name: 'Bob' }]
20
31
  * ```
21
32
  *
22
33
  * @complexity O(n+m) where n and m are array lengths
23
34
  */
24
- export declare function ArrayIntersection<T>(array1: T[], array2: T[], comparator?: TEqualityComparator<T>): T[];
35
+ export declare function ArrayIntersection<T>(array1: readonly T[], array2: readonly T[], options?: TArrayComparisonOptions<T>): T[];
25
36
  //# sourceMappingURL=array-intersection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"array-intersection.d.ts","sourceRoot":"","sources":["../../src/array/array-intersection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAClC,MAAM,EAAE,CAAC,EAAE,EACX,MAAM,EAAE,CAAC,EAAE,EACX,UAAU,CAAC,EAAE,mBAAmB,CAAC,CAAC,CAAC,GACjC,CAAC,EAAE,CAoBL"}
1
+ {"version":3,"file":"array-intersection.d.ts","sourceRoot":"","sources":["../../src/array/array-intersection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAG1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAClC,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,OAAO,CAAC,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAClC,CAAC,EAAE,CA8BL"}
@@ -1,39 +1,57 @@
1
+ import { ObjectEquals } from '../object/equals.js';
1
2
  /**
2
3
  * Returns the intersection of two arrays (elements present in both)
3
- * Optimized O(n+m) complexity using Set-based approach
4
+ * Optimized O(n+m) complexity using Set-based approach.
5
+ * Supports custom comparators for advanced comparison logic, or deep equality checking.
4
6
  *
5
7
  * @template T - The type of array elements
6
8
  * @param array1 - First array
7
9
  * @param array2 - Second array
8
- * @param comparator - Optional custom equality comparator
10
+ * @param options - Optional configuration
11
+ * @param options.comparator - Custom function to determine if elements are equal (optional)
12
+ * @param options.useDeepEqual - Use deep equality for comparison instead of custom comparator (optional)
9
13
  * @returns Array containing elements present in both arrays
10
14
  *
11
15
  * @example
12
16
  * ```typescript
17
+ * // Basic intersection with primitives
13
18
  * ArrayIntersection([1, 2, 3], [2, 3, 4]); // [2, 3]
14
- * ArrayIntersection(
15
- * [{id: 1}, {id: 2}],
16
- * [{id: 2}, {id: 3}],
17
- * (a, b) => a.id === b.id
18
- * ); // [{id: 2}]
19
+ *
20
+ * // Deep equality comparison with objects
21
+ * const arr1 = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }];
22
+ * const arr2 = [{ id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' }];
23
+ * ArrayIntersection(arr1, arr2, { useDeepEqual: true });
24
+ * // [{ id: 2, name: 'Bob' }]
25
+ *
26
+ * // Custom comparator
27
+ * ArrayIntersection(arr1, arr2, {
28
+ * comparator: (a, b) => a.id === b.id
29
+ * });
30
+ * // [{ id: 2, name: 'Bob' }]
19
31
  * ```
20
32
  *
21
33
  * @complexity O(n+m) where n and m are array lengths
22
34
  */
23
- export function ArrayIntersection(array1, array2, comparator) {
35
+ export function ArrayIntersection(array1, array2, options) {
24
36
  if (!array1 || !array2) {
25
37
  return [];
26
38
  }
27
- // If no custom comparator, use Set for O(n+m) performance
28
- if (!comparator) {
39
+ const opts = options ?? {};
40
+ const { comparator, useDeepEqual = false } = opts;
41
+ // If no custom comparator and no deep equality, use Set for O(n+m) performance
42
+ if (!comparator && !useDeepEqual) {
29
43
  const set2 = new Set(array2);
30
44
  return array1.filter(item => set2.has(item));
31
45
  }
32
- // With custom comparator, still optimize by checking smaller array
46
+ // With custom comparator or deep equality, optimize by checking smaller array
33
47
  // This reduces comparisons from n*m to min(n,m)*max(n,m)
34
48
  const [smaller, larger] = array1.length <= array2.length
35
49
  ? [array1, array2]
36
50
  : [array2, array1];
37
- return smaller.filter(item => larger.some(otherItem => comparator(item, otherItem)));
51
+ if (comparator) {
52
+ return smaller.filter(item => larger.some(otherItem => comparator(item, otherItem)));
53
+ }
54
+ // Use deep equality
55
+ return smaller.filter(item => larger.some(otherItem => ObjectEquals(item, otherItem)));
38
56
  }
39
57
  //# sourceMappingURL=array-intersection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"array-intersection.js","sourceRoot":"","sources":["../../src/array/array-intersection.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,iBAAiB,CAChC,MAAW,EACX,MAAW,EACX,UAAmC;IAEnC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACX,CAAC;IAED,0DAA0D;IAC1D,IAAI,CAAC,UAAU,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QAC7B,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED,mEAAmE;IACnE,yDAAyD;IACzD,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM;QACvD,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC;QAClB,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEpB,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAC5B,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CACrD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"array-intersection.js","sourceRoot":"","sources":["../../src/array/array-intersection.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,UAAU,iBAAiB,CAChC,MAAoB,EACpB,MAAoB,EACpB,OAAoC;IAEpC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACX,CAAC;IAED,MAAM,IAAI,GAAI,OAAe,IAAI,EAAE,CAAC;IACpC,MAAM,EAAE,UAAU,EAAE,YAAY,GAAG,KAAK,EAAE,GAAG,IAAI,CAAC;IAElD,+EAA+E;IAC/E,IAAI,CAAC,UAAU,IAAI,CAAC,YAAY,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QAC7B,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED,8EAA8E;IAC9E,yDAAyD;IACzD,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM;QACvD,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC;QAClB,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEpB,IAAI,UAAU,EAAE,CAAC;QAChB,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAC5B,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CACrD,CAAC;IACH,CAAC;IAED,oBAAoB;IACpB,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAC5B,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CACvD,CAAC;AACH,CAAC"}