@catbee/utils 0.0.1 → 0.0.3

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 (197) hide show
  1. package/README.md +303 -107
  2. package/build/esm/config.d.ts +13 -1
  3. package/build/esm/config.js +16 -4
  4. package/build/esm/config.js.map +1 -1
  5. package/build/esm/index.d.ts +20 -18
  6. package/build/esm/index.js +20 -18
  7. package/build/esm/index.js.map +1 -1
  8. package/build/esm/types/api-response.d.ts +83 -1
  9. package/build/esm/types/api-response.js.map +1 -1
  10. package/build/esm/utils/array.utils.d.ts +65 -2
  11. package/build/esm/utils/array.utils.js +147 -20
  12. package/build/esm/utils/array.utils.js.map +1 -1
  13. package/build/esm/utils/async.utils.d.ts +56 -1
  14. package/build/esm/utils/async.utils.js +166 -11
  15. package/build/esm/utils/async.utils.js.map +1 -1
  16. package/build/esm/utils/cache.utils.d.ts +67 -4
  17. package/build/esm/utils/cache.utils.js +210 -28
  18. package/build/esm/utils/cache.utils.js.map +1 -1
  19. package/build/esm/utils/context-store.utils.d.ts +102 -1
  20. package/build/esm/utils/context-store.utils.js +185 -3
  21. package/build/esm/utils/context-store.utils.js.map +1 -1
  22. package/build/esm/utils/crypto.utils.d.ts +110 -8
  23. package/build/esm/utils/crypto.utils.js +298 -23
  24. package/build/esm/utils/crypto.utils.js.map +1 -1
  25. package/build/esm/utils/decorators.utils.d.ts +40 -0
  26. package/build/esm/utils/decorators.utils.js +312 -0
  27. package/build/esm/utils/decorators.utils.js.map +1 -0
  28. package/build/esm/utils/dir.utils.d.ts +122 -1
  29. package/build/esm/utils/dir.utils.js +578 -3
  30. package/build/esm/utils/dir.utils.js.map +1 -1
  31. package/build/esm/utils/env.utils.d.ts +83 -0
  32. package/build/esm/utils/env.utils.js +235 -6
  33. package/build/esm/utils/env.utils.js.map +1 -1
  34. package/build/esm/utils/exception.utils.d.ts +117 -1
  35. package/build/esm/utils/exception.utils.js +331 -12
  36. package/build/esm/utils/exception.utils.js.map +1 -1
  37. package/build/esm/utils/fs.utils.d.ts +132 -0
  38. package/build/esm/utils/fs.utils.js +421 -4
  39. package/build/esm/utils/fs.utils.js.map +1 -1
  40. package/build/esm/utils/http-status-codes.d.ts +87 -178
  41. package/build/esm/utils/http-status-codes.js +92 -178
  42. package/build/esm/utils/http-status-codes.js.map +1 -1
  43. package/build/esm/utils/id.utils.d.ts +11 -10
  44. package/build/esm/utils/id.utils.js +30 -21
  45. package/build/esm/utils/id.utils.js.map +1 -1
  46. package/build/esm/utils/logger.utils.d.ts +35 -2
  47. package/build/esm/utils/logger.utils.js +68 -14
  48. package/build/esm/utils/logger.utils.js.map +1 -1
  49. package/build/esm/utils/middleware.utils.d.ts +73 -0
  50. package/build/esm/utils/middleware.utils.js +158 -0
  51. package/build/esm/utils/middleware.utils.js.map +1 -0
  52. package/build/esm/utils/obj.utils.d.ts +65 -3
  53. package/build/esm/utils/obj.utils.js +206 -18
  54. package/build/esm/utils/obj.utils.js.map +1 -1
  55. package/build/esm/utils/response.utils.d.ts +103 -2
  56. package/build/esm/utils/response.utils.js +156 -3
  57. package/build/esm/utils/response.utils.js.map +1 -1
  58. package/build/esm/utils/string.utils.d.ts +61 -5
  59. package/build/esm/utils/string.utils.js +109 -19
  60. package/build/esm/utils/string.utils.js.map +1 -1
  61. package/build/esm/utils/url.utils.d.ts +117 -0
  62. package/build/esm/utils/url.utils.js +287 -2
  63. package/build/esm/utils/url.utils.js.map +1 -1
  64. package/build/esm/utils/validate.utils.d.ts +110 -0
  65. package/build/esm/utils/validate.utils.js +190 -8
  66. package/build/esm/utils/validate.utils.js.map +1 -1
  67. package/build/esnext/config.d.ts +13 -1
  68. package/build/esnext/config.js +16 -4
  69. package/build/esnext/config.js.map +1 -1
  70. package/build/esnext/index.d.ts +20 -18
  71. package/build/esnext/index.js +20 -18
  72. package/build/esnext/index.js.map +1 -1
  73. package/build/esnext/types/api-response.d.ts +83 -1
  74. package/build/esnext/types/api-response.js.map +1 -1
  75. package/build/esnext/utils/array.utils.d.ts +65 -2
  76. package/build/esnext/utils/array.utils.js +140 -21
  77. package/build/esnext/utils/array.utils.js.map +1 -1
  78. package/build/esnext/utils/async.utils.d.ts +56 -1
  79. package/build/esnext/utils/async.utils.js +130 -14
  80. package/build/esnext/utils/async.utils.js.map +1 -1
  81. package/build/esnext/utils/cache.utils.d.ts +67 -4
  82. package/build/esnext/utils/cache.utils.js +137 -9
  83. package/build/esnext/utils/cache.utils.js.map +1 -1
  84. package/build/esnext/utils/context-store.utils.d.ts +102 -1
  85. package/build/esnext/utils/context-store.utils.js +171 -3
  86. package/build/esnext/utils/context-store.utils.js.map +1 -1
  87. package/build/esnext/utils/crypto.utils.d.ts +110 -8
  88. package/build/esnext/utils/crypto.utils.js +199 -19
  89. package/build/esnext/utils/crypto.utils.js.map +1 -1
  90. package/build/esnext/utils/decorators.utils.d.ts +40 -0
  91. package/build/esnext/utils/decorators.utils.js +155 -0
  92. package/build/esnext/utils/decorators.utils.js.map +1 -0
  93. package/build/esnext/utils/dir.utils.d.ts +122 -1
  94. package/build/esnext/utils/dir.utils.js +307 -3
  95. package/build/esnext/utils/dir.utils.js.map +1 -1
  96. package/build/esnext/utils/env.utils.d.ts +83 -0
  97. package/build/esnext/utils/env.utils.js +191 -8
  98. package/build/esnext/utils/env.utils.js.map +1 -1
  99. package/build/esnext/utils/exception.utils.d.ts +117 -1
  100. package/build/esnext/utils/exception.utils.js +222 -12
  101. package/build/esnext/utils/exception.utils.js.map +1 -1
  102. package/build/esnext/utils/fs.utils.d.ts +132 -0
  103. package/build/esnext/utils/fs.utils.js +268 -4
  104. package/build/esnext/utils/fs.utils.js.map +1 -1
  105. package/build/esnext/utils/http-status-codes.d.ts +87 -178
  106. package/build/esnext/utils/http-status-codes.js +92 -178
  107. package/build/esnext/utils/http-status-codes.js.map +1 -1
  108. package/build/esnext/utils/id.utils.d.ts +11 -10
  109. package/build/esnext/utils/id.utils.js +28 -20
  110. package/build/esnext/utils/id.utils.js.map +1 -1
  111. package/build/esnext/utils/logger.utils.d.ts +35 -2
  112. package/build/esnext/utils/logger.utils.js +56 -14
  113. package/build/esnext/utils/logger.utils.js.map +1 -1
  114. package/build/esnext/utils/middleware.utils.d.ts +73 -0
  115. package/build/esnext/utils/middleware.utils.js +157 -0
  116. package/build/esnext/utils/middleware.utils.js.map +1 -0
  117. package/build/esnext/utils/obj.utils.d.ts +65 -3
  118. package/build/esnext/utils/obj.utils.js +169 -14
  119. package/build/esnext/utils/obj.utils.js.map +1 -1
  120. package/build/esnext/utils/response.utils.d.ts +103 -2
  121. package/build/esnext/utils/response.utils.js +141 -3
  122. package/build/esnext/utils/response.utils.js.map +1 -1
  123. package/build/esnext/utils/string.utils.d.ts +61 -5
  124. package/build/esnext/utils/string.utils.js +110 -14
  125. package/build/esnext/utils/string.utils.js.map +1 -1
  126. package/build/esnext/utils/url.utils.d.ts +117 -0
  127. package/build/esnext/utils/url.utils.js +248 -2
  128. package/build/esnext/utils/url.utils.js.map +1 -1
  129. package/build/esnext/utils/validate.utils.d.ts +110 -0
  130. package/build/esnext/utils/validate.utils.js +190 -8
  131. package/build/esnext/utils/validate.utils.js.map +1 -1
  132. package/build/src/config.d.ts +13 -1
  133. package/build/src/config.js +15 -3
  134. package/build/src/config.js.map +1 -1
  135. package/build/src/index.d.ts +20 -18
  136. package/build/src/index.js +2 -0
  137. package/build/src/index.js.map +1 -1
  138. package/build/src/types/api-response.d.ts +83 -1
  139. package/build/src/types/api-response.js.map +1 -1
  140. package/build/src/utils/array.utils.d.ts +65 -2
  141. package/build/src/utils/array.utils.js +147 -22
  142. package/build/src/utils/array.utils.js.map +1 -1
  143. package/build/src/utils/async.utils.d.ts +56 -1
  144. package/build/src/utils/async.utils.js +137 -17
  145. package/build/src/utils/async.utils.js.map +1 -1
  146. package/build/src/utils/cache.utils.d.ts +67 -4
  147. package/build/src/utils/cache.utils.js +137 -9
  148. package/build/src/utils/cache.utils.js.map +1 -1
  149. package/build/src/utils/context-store.utils.d.ts +102 -1
  150. package/build/src/utils/context-store.utils.js +173 -3
  151. package/build/src/utils/context-store.utils.js.map +1 -1
  152. package/build/src/utils/crypto.utils.d.ts +110 -8
  153. package/build/src/utils/crypto.utils.js +214 -27
  154. package/build/src/utils/crypto.utils.js.map +1 -1
  155. package/build/src/utils/decorators.utils.d.ts +40 -0
  156. package/build/src/utils/decorators.utils.js +165 -0
  157. package/build/src/utils/decorators.utils.js.map +1 -0
  158. package/build/src/utils/dir.utils.d.ts +122 -1
  159. package/build/src/utils/dir.utils.js +314 -0
  160. package/build/src/utils/dir.utils.js.map +1 -1
  161. package/build/src/utils/env.utils.d.ts +83 -0
  162. package/build/src/utils/env.utils.js +192 -9
  163. package/build/src/utils/env.utils.js.map +1 -1
  164. package/build/src/utils/exception.utils.d.ts +117 -1
  165. package/build/src/utils/exception.utils.js +233 -11
  166. package/build/src/utils/exception.utils.js.map +1 -1
  167. package/build/src/utils/fs.utils.d.ts +132 -0
  168. package/build/src/utils/fs.utils.js +281 -3
  169. package/build/src/utils/fs.utils.js.map +1 -1
  170. package/build/src/utils/http-status-codes.d.ts +87 -178
  171. package/build/src/utils/http-status-codes.js +92 -178
  172. package/build/src/utils/http-status-codes.js.map +1 -1
  173. package/build/src/utils/id.utils.d.ts +11 -10
  174. package/build/src/utils/id.utils.js +28 -20
  175. package/build/src/utils/id.utils.js.map +1 -1
  176. package/build/src/utils/logger.utils.d.ts +35 -2
  177. package/build/src/utils/logger.utils.js +56 -11
  178. package/build/src/utils/logger.utils.js.map +1 -1
  179. package/build/src/utils/middleware.utils.d.ts +73 -0
  180. package/build/src/utils/middleware.utils.js +163 -0
  181. package/build/src/utils/middleware.utils.js.map +1 -0
  182. package/build/src/utils/obj.utils.d.ts +65 -3
  183. package/build/src/utils/obj.utils.js +179 -18
  184. package/build/src/utils/obj.utils.js.map +1 -1
  185. package/build/src/utils/response.utils.d.ts +103 -2
  186. package/build/src/utils/response.utils.js +147 -2
  187. package/build/src/utils/response.utils.js.map +1 -1
  188. package/build/src/utils/string.utils.d.ts +61 -5
  189. package/build/src/utils/string.utils.js +122 -20
  190. package/build/src/utils/string.utils.js.map +1 -1
  191. package/build/src/utils/url.utils.d.ts +117 -0
  192. package/build/src/utils/url.utils.js +256 -1
  193. package/build/src/utils/url.utils.js.map +1 -1
  194. package/build/src/utils/validate.utils.d.ts +110 -0
  195. package/build/src/utils/validate.utils.js +204 -8
  196. package/build/src/utils/validate.utils.js.map +1 -1
  197. package/package.json +20 -12
@@ -1,4 +1,4 @@
1
- import { getValueByPath } from "./obj.utils";
1
+ import { getValueByPath } from './obj.utils';
2
2
  /**
3
3
  * Splits an array into chunks of the specified size.
4
4
  *
@@ -9,15 +9,15 @@ import { getValueByPath } from "./obj.utils";
9
9
  * @throws {TypeError} If array is not an array.
10
10
  * @throws {Error} If chunk size is not a positive integer.
11
11
  */
12
- export const chunk = (array, size) => {
12
+ export function chunk(array, size) {
13
13
  if (!Array.isArray(array))
14
- throw new TypeError("Expected an array");
14
+ throw new TypeError('Expected an array');
15
15
  if (!array.length)
16
16
  return [];
17
17
  if (!Number.isInteger(size) || size <= 0)
18
- throw new Error("Chunk size must be a positive integer");
18
+ throw new Error('Chunk size must be a positive integer');
19
19
  return Array.from({ length: Math.ceil(array.length / size) }, (_, i) => array.slice(i * size, i * size + size));
20
- };
20
+ }
21
21
  /**
22
22
  * Removes duplicate values from an array.
23
23
  * Optionally enforces uniqueness by a key function.
@@ -33,7 +33,7 @@ export function unique(array, keyFn) {
33
33
  if (!keyFn)
34
34
  return Array.from(new Set(array));
35
35
  const seen = new Set();
36
- return array.filter((item) => {
36
+ return array.filter(item => {
37
37
  const key = keyFn(item);
38
38
  if (seen.has(key))
39
39
  return false;
@@ -76,9 +76,7 @@ export function random(array) {
76
76
  export function groupBy(array, keyOrFn) {
77
77
  if (!Array.isArray(array) || array.length === 0)
78
78
  return {};
79
- const keyFn = typeof keyOrFn === "function"
80
- ? keyOrFn
81
- : (item) => item[keyOrFn];
79
+ const keyFn = typeof keyOrFn === 'function' ? keyOrFn : (item) => item[keyOrFn];
82
80
  return array.reduce((acc, item) => {
83
81
  const key = keyFn(item);
84
82
  if (!acc[key])
@@ -98,7 +96,7 @@ export function groupBy(array, keyOrFn) {
98
96
  */
99
97
  export function shuffle(array) {
100
98
  if (!Array.isArray(array))
101
- throw new TypeError("Expected an array");
99
+ throw new TypeError('Expected an array');
102
100
  const copy = array.slice();
103
101
  for (let i = copy.length - 1; i > 0; i--) {
104
102
  const j = Math.floor(Math.random() * (i + 1));
@@ -118,7 +116,7 @@ export function shuffle(array) {
118
116
  export function pluck(array, key) {
119
117
  if (!Array.isArray(array))
120
118
  return [];
121
- return array.map((item) => item[key]);
119
+ return array.map(item => item[key]);
122
120
  }
123
121
  /**
124
122
  * Returns values in array A that are not in array B.
@@ -132,7 +130,7 @@ export function difference(a, b) {
132
130
  if (!Array.isArray(a) || !Array.isArray(b))
133
131
  return [];
134
132
  const setB = new Set(b);
135
- return a.filter((item) => !setB.has(item));
133
+ return a.filter(item => !setB.has(item));
136
134
  }
137
135
  /**
138
136
  * Returns common values between arrays A and B.
@@ -146,7 +144,7 @@ export function intersect(a, b) {
146
144
  if (!Array.isArray(a) || !Array.isArray(b))
147
145
  return [];
148
146
  const setB = new Set(b);
149
- return a.filter((item) => setB.has(item));
147
+ return a.filter(item => setB.has(item));
150
148
  }
151
149
  /**
152
150
  * Sorts an array of objects by a nested key using Merge Sort (O(n log n)).
@@ -159,14 +157,12 @@ export function intersect(a, b) {
159
157
  * @returns {T[]} A new sorted array.
160
158
  * @throws {TypeError} If array is not an array.
161
159
  */
162
- export function mergeSort(array, key, direction = "asc") {
160
+ export function mergeSort(array, key, direction = 'asc') {
163
161
  if (!Array.isArray(array))
164
- throw new TypeError("Expected array");
162
+ throw new TypeError('Expected array');
165
163
  if (array.length <= 1)
166
164
  return array.slice();
167
- const keyFn = typeof key === "function"
168
- ? key
169
- : (item) => getValueByPath(item, key);
165
+ const keyFn = typeof key === 'function' ? key : (item) => getValueByPath(item, key);
170
166
  const compare = (a, b) => {
171
167
  const aVal = keyFn(a);
172
168
  const bVal = keyFn(b);
@@ -174,10 +170,10 @@ export function mergeSort(array, key, direction = "asc") {
174
170
  if (aVal === bVal)
175
171
  return 0;
176
172
  if (aVal == null)
177
- return direction === "asc" ? 1 : -1;
173
+ return direction === 'asc' ? 1 : -1;
178
174
  if (bVal == null)
179
- return direction === "asc" ? -1 : 1;
180
- return direction === "asc" ? (aVal < bVal ? -1 : 1) : aVal > bVal ? -1 : 1;
175
+ return direction === 'asc' ? -1 : 1;
176
+ return direction === 'asc' ? (aVal < bVal ? -1 : 1) : aVal > bVal ? -1 : 1;
181
177
  };
182
178
  const merge = (left, right) => {
183
179
  const result = [];
@@ -200,4 +196,127 @@ export function mergeSort(array, key, direction = "asc") {
200
196
  };
201
197
  return sort(array);
202
198
  }
199
+ /**
200
+ * Combines multiple arrays into a single array of grouped elements.
201
+ * Output array length equals the length of the shortest input array.
202
+ *
203
+ * @example zip([1, 2], ['a', 'b']) => [[1, 'a'], [2, 'b']]
204
+ * @param {...Array<T>[]} arrays - Two or more arrays to zip together.
205
+ * @returns {Array<T[]>} Array of grouped elements.
206
+ */
207
+ export function zip(...arrays) {
208
+ if (arrays.length === 0)
209
+ return [];
210
+ if (arrays.some(arr => !Array.isArray(arr))) {
211
+ throw new TypeError('All arguments must be arrays');
212
+ }
213
+ const minLength = Math.min(...arrays.map(arr => arr.length));
214
+ const result = [];
215
+ for (let i = 0; i < minLength; i++) {
216
+ result.push(arrays.map(arr => arr[i]));
217
+ }
218
+ return result;
219
+ }
220
+ /**
221
+ * Splits an array into two arrays based on a predicate function.
222
+ *
223
+ * @template T The type of array elements.
224
+ * @param {T[]} array - The input array.
225
+ * @param {(item: T, index: number, array: T[]) => boolean} predicate - Function to test each element.
226
+ * @returns {[T[], T[]]} A tuple of two arrays: [matched, unmatched].
227
+ */
228
+ export function partition(array, predicate) {
229
+ if (!Array.isArray(array))
230
+ return [[], []];
231
+ return array.reduce(([pass, fail], item, index) => {
232
+ return predicate(item, index, array) ? [[...pass, item], fail] : [pass, [...fail, item]];
233
+ }, [[], []]);
234
+ }
235
+ /**
236
+ * Generates an array of numbers within a specified range.
237
+ *
238
+ * @param {number} start - Start of range (inclusive).
239
+ * @param {number} end - End of range (exclusive).
240
+ * @param {number} [step=1] - Step between numbers.
241
+ * @returns {number[]} Array of numbers in range.
242
+ */
243
+ export function range(start, end, step = 1) {
244
+ if (!Number.isFinite(start) || !Number.isFinite(end) || !Number.isFinite(step)) {
245
+ throw new TypeError('Arguments must be finite numbers');
246
+ }
247
+ if (step === 0)
248
+ throw new Error('Step cannot be zero');
249
+ const isAscending = step > 0;
250
+ if ((isAscending && start >= end) || (!isAscending && start <= end)) {
251
+ return [];
252
+ }
253
+ const length = Math.max(Math.ceil((end - start) / step), 0);
254
+ const result = new Array(length);
255
+ for (let i = 0, value = start; i < length; i++, value += step) {
256
+ result[i] = value;
257
+ }
258
+ return result;
259
+ }
260
+ /**
261
+ * Returns the first n elements of an array.
262
+ *
263
+ * @template T The type of array elements.
264
+ * @param {T[]} array - The input array.
265
+ * @param {number} [n=1] - Number of elements to take.
266
+ * @returns {T[]} New array with first n elements.
267
+ */
268
+ export function take(array, n = 1) {
269
+ if (!Array.isArray(array) || n <= 0)
270
+ return [];
271
+ return array.slice(0, n);
272
+ }
273
+ /**
274
+ * Takes elements from the array while predicate returns true.
275
+ *
276
+ * @template T The type of array elements.
277
+ * @param {T[]} array - The input array.
278
+ * @param {(item: T, index: number) => boolean} predicate - Function to test each element.
279
+ * @returns {T[]} New array with taken elements.
280
+ */
281
+ export function takeWhile(array, predicate) {
282
+ if (!Array.isArray(array))
283
+ return [];
284
+ const result = [];
285
+ for (let i = 0; i < array.length; i++) {
286
+ if (!predicate(array[i], i))
287
+ break;
288
+ result.push(array[i]);
289
+ }
290
+ return result;
291
+ }
292
+ /**
293
+ * Removes all falsy values from an array.
294
+ * False, null, 0, "", undefined, and NaN are falsy.
295
+ *
296
+ * @template T The type of array elements.
297
+ * @param {T[]} array - The input array.
298
+ * @returns {NonNullable<T>[]} New array with falsy values removed.
299
+ */
300
+ export function compact(array) {
301
+ if (!Array.isArray(array))
302
+ return [];
303
+ return array.filter(Boolean);
304
+ }
305
+ /**
306
+ * Counts array elements by a key function.
307
+ *
308
+ * @template T The type of array elements.
309
+ * @param {T[]} array - The input array.
310
+ * @param {(item: T) => string | number | symbol} keyFn - Function to generate count key.
311
+ * @returns {Record<string, number>} Object with counts by key.
312
+ */
313
+ export function countBy(array, keyFn) {
314
+ if (!Array.isArray(array))
315
+ return {};
316
+ return array.reduce((acc, item) => {
317
+ const key = String(keyFn(item));
318
+ acc[key] = (acc[key] || 0) + 1;
319
+ return acc;
320
+ }, {});
321
+ }
203
322
  //# sourceMappingURL=array.utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"array.utils.js","sourceRoot":"","sources":["../../../src/utils/array.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { getValueByPath } from \"./obj.utils\";\n\n/**\n * Splits an array into chunks of the specified size.\n *\n * @template T The type of array elements.\n * @param {T[]} array - The array to split into chunks.\n * @param {number} size - The number of elements per chunk.\n * @returns {T[][]} A new array containing chunked arrays.\n * @throws {TypeError} If array is not an array.\n * @throws {Error} If chunk size is not a positive integer.\n */\nexport const chunk = <T>(array: T[], size: number): T[][] => {\n if (!Array.isArray(array)) throw new TypeError(\"Expected an array\");\n if (!array.length) return [];\n if (!Number.isInteger(size) || size <= 0)\n throw new Error(\"Chunk size must be a positive integer\");\n return Array.from({ length: Math.ceil(array.length / size) }, (_, i) =>\n array.slice(i * size, i * size + size),\n );\n};\n\n/**\n * Removes duplicate values from an array.\n * Optionally enforces uniqueness by a key function.\n *\n * @template T The type of array elements.\n * @param {T[]} array - The input array.\n * @param {(item: T) => unknown} [keyFn] - Optional function to determine uniqueness by key.\n * @returns {T[]} A new array with unique values.\n */\nexport function unique<T>(array: T[], keyFn?: (item: T) => unknown): T[] {\n if (!Array.isArray(array) || array.length === 0) return [];\n if (!keyFn) return Array.from(new Set(array));\n const seen = new Set<unknown>();\n return array.filter((item) => {\n const key = keyFn(item);\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\n/**\n * Deeply flattens a nested array to a single-level array.\n *\n * @template T The leaf type of array elements.\n * @param {any[]} array - The (possibly deeply nested) input array.\n * @returns {T[]} A deeply flattened array.\n */\nexport function flattenDeep<T>(array: any[]): T[] {\n if (!Array.isArray(array)) return [];\n return array.reduce<T[]>((acc, val) => {\n if (Array.isArray(val)) {\n acc.push(...flattenDeep<T>(val));\n } else {\n acc.push(val);\n }\n return acc;\n }, []);\n}\n\n/**\n * Returns a random element from an array, or undefined if empty.\n *\n * @template T The type of array elements.\n * @param {T[]} array - The input array.\n * @returns {T | undefined} A randomly selected item, or undefined if array is empty or not an array.\n */\nexport function random<T>(array: T[]): T | undefined {\n if (!Array.isArray(array) || array.length === 0) return undefined;\n return array[Math.floor(Math.random() * array.length)];\n}\n\n/* eslint-disable no-redeclare */\n/**\n * Groups items in an array by a key or key function.\n *\n * @template T The type of array elements.\n * @overload\n * @param {T[]} array - The array to group.\n * @param {keyof T} key - Property key to group by.\n * @returns {Record<string, T[]>}\n * @overload\n * @param {T[]} array - The array to group.\n * @param {(item: T) => string | number | symbol} keyFn - Function to generate group key from item.\n * @returns {Record<K, T[]>}\n * @param {T[]} array - The array to group.\n * @param {keyof T | ((item: T) => string | number | symbol)} keyOrFn - Property key or key-generating function.\n * @returns {Record<string | number | symbol, T[]>} An object mapping group keys to item arrays.\n */\nexport function groupBy<T>(array: T[], key: keyof T): Record<string, T[]>;\nexport function groupBy<T, K extends string | number | symbol>(\n array: T[],\n keyFn: (item: T) => K,\n): Record<K, T[]>;\nexport function groupBy<T>(\n array: T[],\n keyOrFn: keyof T | ((item: T) => string | number | symbol),\n): Record<string | number | symbol, T[]> {\n if (!Array.isArray(array) || array.length === 0) return {};\n const keyFn =\n typeof keyOrFn === \"function\"\n ? keyOrFn\n : (item: T) => item[keyOrFn as keyof T];\n return array.reduce(\n (acc, item) => {\n const key = keyFn(item) as string | number | symbol;\n if (!acc[key]) acc[key] = [];\n acc[key].push(item);\n return acc;\n },\n {} as Record<string | number | symbol, T[]>,\n );\n}\n/* eslint-enable no-redeclare */\n\n/**\n * Shuffles an array using the Fisher-Yates algorithm.\n *\n * @template T The type of array elements.\n * @param {T[]} array - The input array.\n * @returns {T[]} A new shuffled array.\n * @throws {TypeError} If array is not an array.\n */\nexport function shuffle<T>(array: T[]): T[] {\n if (!Array.isArray(array)) throw new TypeError(\"Expected an array\");\n const copy = array.slice();\n for (let i = copy.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [copy[i], copy[j]] = [copy[j], copy[i]];\n }\n return copy;\n}\n\n/**\n * Returns an array of property values from an array of objects.\n *\n * @template T The type of array elements.\n * @template K The object property to pluck.\n * @param {T[]} array - The input array.\n * @param {K} key - The property name to pluck.\n * @returns {T[K][]} Array of property values.\n */\nexport function pluck<T, K extends keyof T>(array: T[], key: K): T[K][] {\n if (!Array.isArray(array)) return [];\n return array.map((item) => item[key]);\n}\n\n/**\n * Returns values in array A that are not in array B.\n *\n * @template T The type of array elements.\n * @param {T[]} a - First array.\n * @param {T[]} b - Second array.\n * @returns {T[]} Elements in A that are not in B.\n */\nexport function difference<T>(a: T[], b: T[]): T[] {\n if (!Array.isArray(a) || !Array.isArray(b)) return [];\n const setB = new Set(b);\n return a.filter((item) => !setB.has(item));\n}\n\n/**\n * Returns common values between arrays A and B.\n *\n * @template T The type of array elements.\n * @param {T[]} a - First array.\n * @param {T[]} b - Second array.\n * @returns {T[]} Elements that exist in both arrays.\n */\nexport function intersect<T>(a: T[], b: T[]): T[] {\n if (!Array.isArray(a) || !Array.isArray(b)) return [];\n const setB = new Set(b);\n return a.filter((item) => setB.has(item));\n}\n\n/**\n * Sorts an array of objects by a nested key using Merge Sort (O(n log n)).\n * Missing/undefined keys are sorted to the \"end\" (asc) or \"start\" (desc).\n *\n * @template T The type of array elements (objects).\n * @param {T[]} array - Array of objects to sort.\n * @param {string | ((item: T) => any)} key - Dot-notated key (e.g., \"profile.age\") or function.\n * @param {\"asc\" | \"desc\"} [direction=\"asc\"] - Sort direction: 'asc' or 'desc'.\n * @returns {T[]} A new sorted array.\n * @throws {TypeError} If array is not an array.\n */\nexport function mergeSort<T>(\n array: T[],\n key: string | ((item: T) => any),\n direction: \"asc\" | \"desc\" = \"asc\",\n): T[] {\n if (!Array.isArray(array)) throw new TypeError(\"Expected array\");\n if (array.length <= 1) return array.slice();\n\n const keyFn =\n typeof key === \"function\"\n ? key\n : (item: T) => getValueByPath(item as object, key);\n\n const compare = (a: T, b: T) => {\n const aVal = keyFn(a);\n const bVal = keyFn(b);\n // Sorts undefined/null last for \"asc\", first for \"desc\"\n if (aVal === bVal) return 0;\n if (aVal == null) return direction === \"asc\" ? 1 : -1;\n if (bVal == null) return direction === \"asc\" ? -1 : 1;\n return direction === \"asc\" ? (aVal < bVal ? -1 : 1) : aVal > bVal ? -1 : 1;\n };\n\n const merge = (left: T[], right: T[]): T[] => {\n const result: T[] = [];\n let i = 0,\n j = 0;\n while (i < left.length && j < right.length) {\n if (compare(left[i], right[j]) <= 0) result.push(left[i++]);\n else result.push(right[j++]);\n }\n return result.concat(left.slice(i)).concat(right.slice(j));\n };\n\n const sort = (arr: T[]): T[] => {\n if (arr.length <= 1) return arr;\n const mid = Math.floor(arr.length / 2);\n const left = sort(arr.slice(0, mid));\n const right = sort(arr.slice(mid));\n return merge(left, right);\n };\n return sort(array);\n}\n"]}
1
+ {"version":3,"file":"array.utils.js","sourceRoot":"","sources":["../../../src/utils/array.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { getValueByPath } from './obj.utils';\n\n/**\n * Splits an array into chunks of the specified size.\n *\n * @template T The type of array elements.\n * @param {T[]} array - The array to split into chunks.\n * @param {number} size - The number of elements per chunk.\n * @returns {T[][]} A new array containing chunked arrays.\n * @throws {TypeError} If array is not an array.\n * @throws {Error} If chunk size is not a positive integer.\n */\nexport function chunk<T>(array: T[], size: number): T[][] {\n if (!Array.isArray(array)) throw new TypeError('Expected an array');\n if (!array.length) return [];\n if (!Number.isInteger(size) || size <= 0) throw new Error('Chunk size must be a positive integer');\n return Array.from({ length: Math.ceil(array.length / size) }, (_, i) => array.slice(i * size, i * size + size));\n}\n\n/**\n * Removes duplicate values from an array.\n * Optionally enforces uniqueness by a key function.\n *\n * @template T The type of array elements.\n * @param {T[]} array - The input array.\n * @param {(item: T) => unknown} [keyFn] - Optional function to determine uniqueness by key.\n * @returns {T[]} A new array with unique values.\n */\nexport function unique<T>(array: T[], keyFn?: (item: T) => unknown): T[] {\n if (!Array.isArray(array) || array.length === 0) return [];\n if (!keyFn) return Array.from(new Set(array));\n const seen = new Set<unknown>();\n return array.filter(item => {\n const key = keyFn(item);\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\n/**\n * Deeply flattens a nested array to a single-level array.\n *\n * @template T The leaf type of array elements.\n * @param {any[]} array - The (possibly deeply nested) input array.\n * @returns {T[]} A deeply flattened array.\n */\nexport function flattenDeep<T>(array: any[]): T[] {\n if (!Array.isArray(array)) return [];\n return array.reduce<T[]>((acc, val) => {\n if (Array.isArray(val)) {\n acc.push(...flattenDeep<T>(val));\n } else {\n acc.push(val);\n }\n return acc;\n }, []);\n}\n\n/**\n * Returns a random element from an array, or undefined if empty.\n *\n * @template T The type of array elements.\n * @param {T[]} array - The input array.\n * @returns {T | undefined} A randomly selected item, or undefined if array is empty or not an array.\n */\nexport function random<T>(array: T[]): T | undefined {\n if (!Array.isArray(array) || array.length === 0) return undefined;\n return array[Math.floor(Math.random() * array.length)];\n}\n\n/* eslint-disable no-redeclare */\n/**\n * Groups items in an array by a key or key function.\n *\n * @template T The type of array elements.\n * @overload\n * @param {T[]} array - The array to group.\n * @param {keyof T} key - Property key to group by.\n * @returns {Record<string, T[]>}\n * @overload\n * @param {T[]} array - The array to group.\n * @param {(item: T) => string | number | symbol} keyFn - Function to generate group key from item.\n * @returns {Record<K, T[]>}\n * @param {T[]} array - The array to group.\n * @param {keyof T | ((item: T) => string | number | symbol)} keyOrFn - Property key or key-generating function.\n * @returns {Record<string | number | symbol, T[]>} An object mapping group keys to item arrays.\n */\nexport function groupBy<T>(array: T[], key: keyof T): Record<string, T[]>;\nexport function groupBy<T, K extends string | number | symbol>(array: T[], keyFn: (item: T) => K): Record<K, T[]>;\nexport function groupBy<T>(\n array: T[],\n keyOrFn: keyof T | ((item: T) => string | number | symbol)\n): Record<string | number | symbol, T[]> {\n if (!Array.isArray(array) || array.length === 0) return {};\n const keyFn = typeof keyOrFn === 'function' ? keyOrFn : (item: T) => item[keyOrFn as keyof T];\n return array.reduce(\n (acc, item) => {\n const key = keyFn(item) as string | number | symbol;\n if (!acc[key]) acc[key] = [];\n acc[key].push(item);\n return acc;\n },\n {} as Record<string | number | symbol, T[]>\n );\n}\n/* eslint-enable no-redeclare */\n\n/**\n * Shuffles an array using the Fisher-Yates algorithm.\n *\n * @template T The type of array elements.\n * @param {T[]} array - The input array.\n * @returns {T[]} A new shuffled array.\n * @throws {TypeError} If array is not an array.\n */\nexport function shuffle<T>(array: T[]): T[] {\n if (!Array.isArray(array)) throw new TypeError('Expected an array');\n const copy = array.slice();\n for (let i = copy.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [copy[i], copy[j]] = [copy[j], copy[i]];\n }\n return copy;\n}\n\n/**\n * Returns an array of property values from an array of objects.\n *\n * @template T The type of array elements.\n * @template K The object property to pluck.\n * @param {T[]} array - The input array.\n * @param {K} key - The property name to pluck.\n * @returns {T[K][]} Array of property values.\n */\nexport function pluck<T, K extends keyof T>(array: T[], key: K): T[K][] {\n if (!Array.isArray(array)) return [];\n return array.map(item => item[key]);\n}\n\n/**\n * Returns values in array A that are not in array B.\n *\n * @template T The type of array elements.\n * @param {T[]} a - First array.\n * @param {T[]} b - Second array.\n * @returns {T[]} Elements in A that are not in B.\n */\nexport function difference<T>(a: T[], b: T[]): T[] {\n if (!Array.isArray(a) || !Array.isArray(b)) return [];\n const setB = new Set(b);\n return a.filter(item => !setB.has(item));\n}\n\n/**\n * Returns common values between arrays A and B.\n *\n * @template T The type of array elements.\n * @param {T[]} a - First array.\n * @param {T[]} b - Second array.\n * @returns {T[]} Elements that exist in both arrays.\n */\nexport function intersect<T>(a: T[], b: T[]): T[] {\n if (!Array.isArray(a) || !Array.isArray(b)) return [];\n const setB = new Set(b);\n return a.filter(item => setB.has(item));\n}\n\n/**\n * Sorts an array of objects by a nested key using Merge Sort (O(n log n)).\n * Missing/undefined keys are sorted to the \"end\" (asc) or \"start\" (desc).\n *\n * @template T The type of array elements (objects).\n * @param {T[]} array - Array of objects to sort.\n * @param {string | ((item: T) => any)} key - Dot-notated key (e.g., \"profile.age\") or function.\n * @param {\"asc\" | \"desc\"} [direction=\"asc\"] - Sort direction: 'asc' or 'desc'.\n * @returns {T[]} A new sorted array.\n * @throws {TypeError} If array is not an array.\n */\nexport function mergeSort<T>(array: T[], key: string | ((item: T) => any), direction: 'asc' | 'desc' = 'asc'): T[] {\n if (!Array.isArray(array)) throw new TypeError('Expected array');\n if (array.length <= 1) return array.slice();\n\n const keyFn = typeof key === 'function' ? key : (item: T) => getValueByPath(item as object, key);\n\n const compare = (a: T, b: T) => {\n const aVal = keyFn(a);\n const bVal = keyFn(b);\n // Sorts undefined/null last for \"asc\", first for \"desc\"\n if (aVal === bVal) return 0;\n if (aVal == null) return direction === 'asc' ? 1 : -1;\n if (bVal == null) return direction === 'asc' ? -1 : 1;\n return direction === 'asc' ? (aVal < bVal ? -1 : 1) : aVal > bVal ? -1 : 1;\n };\n\n const merge = (left: T[], right: T[]): T[] => {\n const result: T[] = [];\n let i = 0,\n j = 0;\n while (i < left.length && j < right.length) {\n if (compare(left[i], right[j]) <= 0) result.push(left[i++]);\n else result.push(right[j++]);\n }\n return result.concat(left.slice(i)).concat(right.slice(j));\n };\n\n const sort = (arr: T[]): T[] => {\n if (arr.length <= 1) return arr;\n const mid = Math.floor(arr.length / 2);\n const left = sort(arr.slice(0, mid));\n const right = sort(arr.slice(mid));\n return merge(left, right);\n };\n return sort(array);\n}\n\n/**\n * Combines multiple arrays into a single array of grouped elements.\n * Output array length equals the length of the shortest input array.\n *\n * @example zip([1, 2], ['a', 'b']) => [[1, 'a'], [2, 'b']]\n * @param {...Array<T>[]} arrays - Two or more arrays to zip together.\n * @returns {Array<T[]>} Array of grouped elements.\n */\nexport function zip<T>(...arrays: T[][]): T[][] {\n if (arrays.length === 0) return [];\n if (arrays.some(arr => !Array.isArray(arr))) {\n throw new TypeError('All arguments must be arrays');\n }\n\n const minLength = Math.min(...arrays.map(arr => arr.length));\n const result: T[][] = [];\n\n for (let i = 0; i < minLength; i++) {\n result.push(arrays.map(arr => arr[i]));\n }\n\n return result;\n}\n\n/**\n * Splits an array into two arrays based on a predicate function.\n *\n * @template T The type of array elements.\n * @param {T[]} array - The input array.\n * @param {(item: T, index: number, array: T[]) => boolean} predicate - Function to test each element.\n * @returns {[T[], T[]]} A tuple of two arrays: [matched, unmatched].\n */\nexport function partition<T>(array: T[], predicate: (item: T, index: number, array: T[]) => boolean): [T[], T[]] {\n if (!Array.isArray(array)) return [[], []];\n\n return array.reduce(\n ([pass, fail], item, index) => {\n return predicate(item, index, array) ? [[...pass, item], fail] : [pass, [...fail, item]];\n },\n [[] as T[], [] as T[]]\n );\n}\n\n/**\n * Generates an array of numbers within a specified range.\n *\n * @param {number} start - Start of range (inclusive).\n * @param {number} end - End of range (exclusive).\n * @param {number} [step=1] - Step between numbers.\n * @returns {number[]} Array of numbers in range.\n */\nexport function range(start: number, end: number, step: number = 1): number[] {\n if (!Number.isFinite(start) || !Number.isFinite(end) || !Number.isFinite(step)) {\n throw new TypeError('Arguments must be finite numbers');\n }\n if (step === 0) throw new Error('Step cannot be zero');\n\n const isAscending = step > 0;\n if ((isAscending && start >= end) || (!isAscending && start <= end)) {\n return [];\n }\n\n const length = Math.max(Math.ceil((end - start) / step), 0);\n const result = new Array(length);\n\n for (let i = 0, value = start; i < length; i++, value += step) {\n result[i] = value;\n }\n\n return result;\n}\n\n/**\n * Returns the first n elements of an array.\n *\n * @template T The type of array elements.\n * @param {T[]} array - The input array.\n * @param {number} [n=1] - Number of elements to take.\n * @returns {T[]} New array with first n elements.\n */\nexport function take<T>(array: T[], n: number = 1): T[] {\n if (!Array.isArray(array) || n <= 0) return [];\n return array.slice(0, n);\n}\n\n/**\n * Takes elements from the array while predicate returns true.\n *\n * @template T The type of array elements.\n * @param {T[]} array - The input array.\n * @param {(item: T, index: number) => boolean} predicate - Function to test each element.\n * @returns {T[]} New array with taken elements.\n */\nexport function takeWhile<T>(array: T[], predicate: (item: T, index: number) => boolean): T[] {\n if (!Array.isArray(array)) return [];\n\n const result: T[] = [];\n for (let i = 0; i < array.length; i++) {\n if (!predicate(array[i], i)) break;\n result.push(array[i]);\n }\n\n return result;\n}\n\n/**\n * Removes all falsy values from an array.\n * False, null, 0, \"\", undefined, and NaN are falsy.\n *\n * @template T The type of array elements.\n * @param {T[]} array - The input array.\n * @returns {NonNullable<T>[]} New array with falsy values removed.\n */\nexport function compact<T>(array: T[]): NonNullable<T>[] {\n if (!Array.isArray(array)) return [];\n return array.filter(Boolean) as NonNullable<T>[];\n}\n\n/**\n * Counts array elements by a key function.\n *\n * @template T The type of array elements.\n * @param {T[]} array - The input array.\n * @param {(item: T) => string | number | symbol} keyFn - Function to generate count key.\n * @returns {Record<string, number>} Object with counts by key.\n */\nexport function countBy<T>(array: T[], keyFn: (item: T) => string | number | symbol): Record<string, number> {\n if (!Array.isArray(array)) return {};\n\n return array.reduce(\n (acc, item) => {\n const key = String(keyFn(item));\n acc[key] = (acc[key] || 0) + 1;\n return acc;\n },\n {} as Record<string, number>\n );\n}\n"]}
@@ -4,7 +4,7 @@
4
4
  * @param {number} ms - The number of milliseconds to sleep.
5
5
  * @returns {Promise<void>} A Promise that resolves after the given time.
6
6
  */
7
- export declare const sleep: (ms: number) => Promise<void>;
7
+ export declare function sleep(ms: number): Promise<void>;
8
8
  /**
9
9
  * Creates a debounced version of a function that delays its execution.
10
10
  * Provides `.cancel()` and `.flush()` methods.
@@ -116,4 +116,59 @@ export declare function createTaskQueue(limit: number): TaskQueue;
116
116
  * @returns {Promise<T[]>} Array of resolved values.
117
117
  */
118
118
  export declare function runInSeries<T>(tasks: (() => Promise<T>)[]): Promise<T[]>;
119
+ /**
120
+ * Memoizes an async function, caching results for repeated calls with identical arguments.
121
+ * Optional TTL (time-to-live) for cached entries.
122
+ *
123
+ * @template T Function return type
124
+ * @template Args Function arguments types
125
+ * @param {(...args: Args) => Promise<T>} fn - The async function to memoize
126
+ * @param {object} [options] - Memoization options
127
+ * @param {number} [options.ttl] - Cache TTL in milliseconds (optional)
128
+ * @param {(args: Args) => string} [options.keyFn] - Custom key generator function
129
+ * @returns {(...args: Args) => Promise<T>} Memoized function
130
+ */
131
+ export declare function memoizeAsync<T, Args extends any[]>(fn: (...args: Args) => Promise<T>, options?: {
132
+ ttl?: number;
133
+ keyFn?: (args: Args) => string;
134
+ }): (...args: Args) => Promise<T>;
135
+ /**
136
+ * Creates an abortable version of a promise that can be cancelled using an AbortController.
137
+ *
138
+ * @template T
139
+ * @param {Promise<T>} promise - The promise to make abortable
140
+ * @param {AbortSignal} signal - AbortSignal from AbortController
141
+ * @param {any} [abortValue] - Value to use when rejecting on abort
142
+ * @returns {Promise<T>} Promise that rejects if the signal is aborted
143
+ */
144
+ export declare function abortable<T>(promise: Promise<T>, signal: AbortSignal, abortValue?: any): Promise<T>;
145
+ /**
146
+ * Creates a promise with external resolve/reject functions.
147
+ * Useful for creating promises that can be resolved or rejected from outside.
148
+ *
149
+ * @template T
150
+ * @returns {[Promise<T>, (value: T | PromiseLike<T>) => void, (reason?: any) => void]}
151
+ * Tuple of [promise, resolve, reject]
152
+ */
153
+ export declare function createDeferred<T>(): [Promise<T>, (value: T | PromiseLike<T>) => void, (reason?: any) => void];
154
+ /**
155
+ * Chains a series of async functions, passing the result of each to the next.
156
+ * Similar to function composition but for async functions.
157
+ *
158
+ * @template T
159
+ * @param {Array<(input: any) => Promise<any>>} fns - Array of async functions to compose
160
+ * @returns {(input: any) => Promise<T>} Composed function
161
+ */
162
+ export declare function waterfall<T>(fns: Array<(input: any) => Promise<any>>): (initialValue: any) => Promise<T>;
163
+ /**
164
+ * Creates a rate limiter that ensures functions aren't called more than
165
+ * a specified number of times per interval.
166
+ *
167
+ * @template T
168
+ * @param {(...args: any[]) => Promise<T>} fn - Function to rate limit
169
+ * @param {number} maxCalls - Maximum calls allowed per interval
170
+ * @param {number} interval - Time interval in milliseconds
171
+ * @returns {(...args: any[]) => Promise<T>} Rate limited function
172
+ */
173
+ export declare function rateLimit<T>(fn: (...args: any[]) => Promise<T>, maxCalls: number, interval: number): (...args: any[]) => Promise<T>;
119
174
  //# sourceMappingURL=async.utils.d.ts.map
@@ -4,7 +4,9 @@
4
4
  * @param {number} ms - The number of milliseconds to sleep.
5
5
  * @returns {Promise<void>} A Promise that resolves after the given time.
6
6
  */
7
- export const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
7
+ export function sleep(ms) {
8
+ return new Promise(resolve => setTimeout(resolve, ms));
9
+ }
8
10
  /**
9
11
  * Creates a debounced version of a function that delays its execution.
10
12
  * Provides `.cancel()` and `.flush()` methods.
@@ -54,7 +56,7 @@ export function debounce(fn, delay) {
54
56
  */
55
57
  export function throttle(fn, limit, opts = {
56
58
  leading: true,
57
- trailing: false,
59
+ trailing: false
58
60
  }) {
59
61
  let lastCall = 0;
60
62
  let timer = null;
@@ -111,7 +113,7 @@ export async function retry(fn, retries = 3, delay = 500, backoff = false, onRet
111
113
  await sleep(backoff ? delay * Math.pow(2, i) : delay);
112
114
  }
113
115
  }
114
- throw new Error("Retry failed"); // should never reach here
116
+ throw new Error('Retry failed'); // should never reach here
115
117
  }
116
118
  /**
117
119
  * Wraps a promise and rejects it if it doesn't resolve within the specified timeout.
@@ -122,15 +124,15 @@ export async function retry(fn, retries = 3, delay = 500, backoff = false, onRet
122
124
  * @param {string} [message="Operation timed out"] - Optional timeout message.
123
125
  * @returns {Promise<T>} A promise that resolves or rejects within the timeout.
124
126
  */
125
- export function withTimeout(promise, ms, message = "Operation timed out") {
127
+ export function withTimeout(promise, ms, message = 'Operation timed out') {
126
128
  return new Promise((resolve, reject) => {
127
129
  const timeoutHandle = setTimeout(() => reject(new Error(message)), ms);
128
130
  promise
129
- .then((result) => {
131
+ .then(result => {
130
132
  clearTimeout(timeoutHandle);
131
133
  resolve(result);
132
134
  })
133
- .catch((err) => {
135
+ .catch(err => {
134
136
  clearTimeout(timeoutHandle);
135
137
  reject(err);
136
138
  });
@@ -151,7 +153,7 @@ export async function runInBatches(tasks, limit) {
151
153
  const results = [];
152
154
  for (let i = 0; i < tasks.length; i += limit) {
153
155
  const batch = tasks.slice(i, i + limit);
154
- const batchResults = await Promise.all(batch.map((fn) => fn()));
156
+ const batchResults = await Promise.all(batch.map(fn => fn()));
155
157
  results.push(...batchResults);
156
158
  }
157
159
  return results;
@@ -176,7 +178,7 @@ export function singletonAsync(fn, drop = false) {
176
178
  });
177
179
  }
178
180
  else if (drop) {
179
- return Promise.reject(new Error("Busy: function already running"));
181
+ return Promise.reject(new Error('Busy: function already running'));
180
182
  }
181
183
  return promise;
182
184
  };
@@ -189,7 +191,7 @@ export function singletonAsync(fn, drop = false) {
189
191
  * @returns {Promise<PromiseSettledResult<T>[]>} Results including status and value/reason.
190
192
  */
191
193
  export async function settleAll(tasks) {
192
- return Promise.allSettled(tasks.map((task) => task()));
194
+ return Promise.allSettled(tasks.map(task => task()));
193
195
  }
194
196
  /**
195
197
  * A simple task queue that executes async tasks with a concurrency limit.
@@ -230,7 +232,7 @@ export function createTaskQueue(limit) {
230
232
  */
231
233
  get isPaused() {
232
234
  return paused;
233
- },
235
+ }
234
236
  };
235
237
  const next = () => {
236
238
  if (paused || queue.length === 0 || activeCount >= limit)
@@ -265,11 +267,11 @@ export function createTaskQueue(limit) {
265
267
  };
266
268
  enqueue.pause = state.pause;
267
269
  enqueue.resume = state.resume;
268
- Object.defineProperty(enqueue, "length", {
269
- get: () => queue.length,
270
+ Object.defineProperty(enqueue, 'length', {
271
+ get: () => queue.length
270
272
  });
271
- Object.defineProperty(enqueue, "isPaused", {
272
- get: () => paused,
273
+ Object.defineProperty(enqueue, 'isPaused', {
274
+ get: () => paused
273
275
  });
274
276
  return enqueue;
275
277
  }
@@ -288,4 +290,118 @@ export async function runInSeries(tasks) {
288
290
  }
289
291
  return results;
290
292
  }
293
+ /**
294
+ * Memoizes an async function, caching results for repeated calls with identical arguments.
295
+ * Optional TTL (time-to-live) for cached entries.
296
+ *
297
+ * @template T Function return type
298
+ * @template Args Function arguments types
299
+ * @param {(...args: Args) => Promise<T>} fn - The async function to memoize
300
+ * @param {object} [options] - Memoization options
301
+ * @param {number} [options.ttl] - Cache TTL in milliseconds (optional)
302
+ * @param {(args: Args) => string} [options.keyFn] - Custom key generator function
303
+ * @returns {(...args: Args) => Promise<T>} Memoized function
304
+ */
305
+ export function memoizeAsync(fn, options = {}) {
306
+ const cache = new Map();
307
+ const { ttl, keyFn = JSON.stringify } = options;
308
+ return async function (...args) {
309
+ const key = keyFn(args);
310
+ const cached = cache.get(key);
311
+ if (cached && (!ttl || Date.now() < cached.expires)) {
312
+ return cached.value;
313
+ }
314
+ const result = await fn(...args);
315
+ cache.set(key, {
316
+ value: result,
317
+ expires: ttl ? Date.now() + ttl : Infinity
318
+ });
319
+ return result;
320
+ };
321
+ }
322
+ /**
323
+ * Creates an abortable version of a promise that can be cancelled using an AbortController.
324
+ *
325
+ * @template T
326
+ * @param {Promise<T>} promise - The promise to make abortable
327
+ * @param {AbortSignal} signal - AbortSignal from AbortController
328
+ * @param {any} [abortValue] - Value to use when rejecting on abort
329
+ * @returns {Promise<T>} Promise that rejects if the signal is aborted
330
+ */
331
+ export function abortable(promise, signal, abortValue = new Error('Operation aborted')) {
332
+ if (signal.aborted) {
333
+ return Promise.reject(abortValue);
334
+ }
335
+ return Promise.race([
336
+ promise,
337
+ new Promise((_, reject) => {
338
+ const abort = () => reject(abortValue);
339
+ signal.addEventListener('abort', abort, { once: true });
340
+ promise.finally(() => signal.removeEventListener('abort', abort));
341
+ })
342
+ ]);
343
+ }
344
+ /**
345
+ * Creates a promise with external resolve/reject functions.
346
+ * Useful for creating promises that can be resolved or rejected from outside.
347
+ *
348
+ * @template T
349
+ * @returns {[Promise<T>, (value: T | PromiseLike<T>) => void, (reason?: any) => void]}
350
+ * Tuple of [promise, resolve, reject]
351
+ */
352
+ export function createDeferred() {
353
+ let resolve;
354
+ let reject;
355
+ const promise = new Promise((res, rej) => {
356
+ resolve = res;
357
+ reject = rej;
358
+ });
359
+ return [promise, resolve, reject];
360
+ }
361
+ /**
362
+ * Chains a series of async functions, passing the result of each to the next.
363
+ * Similar to function composition but for async functions.
364
+ *
365
+ * @template T
366
+ * @param {Array<(input: any) => Promise<any>>} fns - Array of async functions to compose
367
+ * @returns {(input: any) => Promise<T>} Composed function
368
+ */
369
+ export function waterfall(fns) {
370
+ return async (initialValue) => {
371
+ return fns.reduce(async (acc, fn) => fn(await acc), Promise.resolve(initialValue));
372
+ };
373
+ }
374
+ /**
375
+ * Creates a rate limiter that ensures functions aren't called more than
376
+ * a specified number of times per interval.
377
+ *
378
+ * @template T
379
+ * @param {(...args: any[]) => Promise<T>} fn - Function to rate limit
380
+ * @param {number} maxCalls - Maximum calls allowed per interval
381
+ * @param {number} interval - Time interval in milliseconds
382
+ * @returns {(...args: any[]) => Promise<T>} Rate limited function
383
+ */
384
+ export function rateLimit(fn, maxCalls, interval) {
385
+ const calls = [];
386
+ return async function (...args) {
387
+ const now = Date.now();
388
+ calls.splice(0, calls.length, ...calls.filter(time => now - time < interval));
389
+ if (calls.length >= maxCalls) {
390
+ const oldestCall = calls[0];
391
+ const delay = interval - (now - oldestCall);
392
+ await sleep(Math.max(1, delay));
393
+ // Remove potentially stale entries after sleep
394
+ const currentTime = Date.now();
395
+ calls.splice(0, calls.length, ...calls.filter(time => currentTime - time < interval));
396
+ // If still at limit after sleep, wait for another cycle
397
+ if (calls.length >= maxCalls) {
398
+ const nextDelay = interval - (currentTime - calls[0]);
399
+ await sleep(Math.max(1, nextDelay));
400
+ calls.splice(0, calls.length, ...calls.filter(time => Date.now() - time < interval));
401
+ }
402
+ }
403
+ calls.push(Date.now());
404
+ return fn(...args);
405
+ };
406
+ }
291
407
  //# sourceMappingURL=async.utils.js.map