@socketsecurity/lib 1.0.5 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/arrays.d.ts +143 -0
  3. package/dist/arrays.js.map +2 -2
  4. package/dist/fs.d.ts +595 -23
  5. package/dist/fs.js.map +2 -2
  6. package/dist/git.d.ts +488 -41
  7. package/dist/git.js.map +2 -2
  8. package/dist/github.d.ts +361 -12
  9. package/dist/github.js.map +2 -2
  10. package/dist/http-request.d.ts +463 -4
  11. package/dist/http-request.js.map +2 -2
  12. package/dist/json.d.ts +177 -4
  13. package/dist/json.js.map +2 -2
  14. package/dist/logger.d.ts +822 -67
  15. package/dist/logger.js +653 -46
  16. package/dist/logger.js.map +2 -2
  17. package/dist/objects.d.ts +386 -10
  18. package/dist/objects.js.map +2 -2
  19. package/dist/path.d.ts +270 -6
  20. package/dist/path.js.map +2 -2
  21. package/dist/promises.d.ts +432 -27
  22. package/dist/promises.js.map +2 -2
  23. package/dist/spawn.d.ts +239 -12
  24. package/dist/spawn.js.map +2 -2
  25. package/dist/spinner.d.ts +260 -20
  26. package/dist/spinner.js +201 -63
  27. package/dist/spinner.js.map +2 -2
  28. package/dist/stdio/clear.d.ts +130 -9
  29. package/dist/stdio/clear.js.map +2 -2
  30. package/dist/stdio/divider.d.ts +106 -10
  31. package/dist/stdio/divider.js +10 -0
  32. package/dist/stdio/divider.js.map +2 -2
  33. package/dist/stdio/footer.d.ts +70 -3
  34. package/dist/stdio/footer.js.map +2 -2
  35. package/dist/stdio/header.d.ts +93 -12
  36. package/dist/stdio/header.js.map +2 -2
  37. package/dist/stdio/mask.d.ts +82 -14
  38. package/dist/stdio/mask.js +25 -4
  39. package/dist/stdio/mask.js.map +2 -2
  40. package/dist/stdio/progress.d.ts +112 -15
  41. package/dist/stdio/progress.js +43 -3
  42. package/dist/stdio/progress.js.map +2 -2
  43. package/dist/stdio/prompts.d.ts +95 -5
  44. package/dist/stdio/prompts.js.map +2 -2
  45. package/dist/stdio/stderr.d.ts +114 -11
  46. package/dist/stdio/stderr.js.map +2 -2
  47. package/dist/stdio/stdout.d.ts +107 -11
  48. package/dist/stdio/stdout.js.map +2 -2
  49. package/dist/strings.d.ts +357 -28
  50. package/dist/strings.js.map +2 -2
  51. package/dist/validation/json-parser.d.ts +226 -7
  52. package/dist/validation/json-parser.js.map +2 -2
  53. package/dist/validation/types.d.ts +114 -8
  54. package/dist/validation/types.js.map +1 -1
  55. package/package.json +1 -1
@@ -1,67 +1,472 @@
1
+ /**
2
+ * Configuration options for retry behavior with exponential backoff.
3
+ *
4
+ * Controls how failed operations are retried, including timing, backoff strategy,
5
+ * and callback hooks for observing or modifying retry behavior.
6
+ */
1
7
  export interface RetryOptions {
2
- args?: unknown[];
3
- backoffFactor?: number;
4
- baseDelayMs?: number;
5
- factor?: number;
6
- jitter?: boolean;
7
- maxDelayMs?: number;
8
- maxTimeout?: number;
9
- minTimeout?: number;
10
- onRetry?: (attempt: number, error: unknown, delay: number) => boolean | number | undefined;
11
- onRetryCancelOnFalse?: boolean;
12
- onRetryRethrow?: boolean;
13
- retries?: number;
14
- signal?: AbortSignal;
8
+ /**
9
+ * Arguments to pass to the callback function on each attempt.
10
+ *
11
+ * @default []
12
+ */
13
+ args?: unknown[] | undefined;
14
+ /**
15
+ * Multiplier for exponential backoff (e.g., 2 doubles delay each retry).
16
+ * Each retry waits `baseDelayMs * (backoffFactor ** attemptNumber)`.
17
+ *
18
+ * @default 2
19
+ * @example
20
+ * // With backoffFactor: 2, baseDelayMs: 100
21
+ * // Retry 1: 100ms
22
+ * // Retry 2: 200ms
23
+ * // Retry 3: 400ms
24
+ */
25
+ backoffFactor?: number | undefined;
26
+ /**
27
+ * Initial delay before the first retry (in milliseconds).
28
+ * This is the base value for exponential backoff calculations.
29
+ *
30
+ * @default 200
31
+ */
32
+ baseDelayMs?: number | undefined;
33
+ /**
34
+ * Legacy alias for `backoffFactor`. Use `backoffFactor` instead.
35
+ *
36
+ * @deprecated Use `backoffFactor` instead
37
+ * @default 2
38
+ */
39
+ factor?: number | undefined;
40
+ /**
41
+ * Whether to apply randomness to spread out retries and avoid thundering herd.
42
+ * When `true`, adds random delay between 0 and current delay value.
43
+ *
44
+ * @default true
45
+ * @example
46
+ * // With jitter: true, delay: 100ms
47
+ * // Actual wait: 100ms + random(0-100ms) = 100-200ms
48
+ */
49
+ jitter?: boolean | undefined;
50
+ /**
51
+ * Upper limit for any backoff delay (in milliseconds).
52
+ * Prevents exponential backoff from growing unbounded.
53
+ *
54
+ * @default 10000
55
+ */
56
+ maxDelayMs?: number | undefined;
57
+ /**
58
+ * Legacy alias for `maxDelayMs`. Use `maxDelayMs` instead.
59
+ *
60
+ * @deprecated Use `maxDelayMs` instead
61
+ * @default 10000
62
+ */
63
+ maxTimeout?: number | undefined;
64
+ /**
65
+ * Legacy alias for `baseDelayMs`. Use `baseDelayMs` instead.
66
+ *
67
+ * @deprecated Use `baseDelayMs` instead
68
+ * @default 200
69
+ */
70
+ minTimeout?: number | undefined;
71
+ /**
72
+ * Callback invoked on each retry attempt.
73
+ * Can observe errors, customize delays, or cancel retries.
74
+ *
75
+ * @param attempt - The current attempt number (1-based: 1, 2, 3, ...)
76
+ * @param error - The error that triggered this retry
77
+ * @param delay - The calculated delay in milliseconds before next retry
78
+ * @returns `false` to cancel retries (if `onRetryCancelOnFalse` is `true`),
79
+ * a number to override the delay, or `undefined` to use calculated delay
80
+ *
81
+ * @example
82
+ * // Log each retry
83
+ * onRetry: (attempt, error, delay) => {
84
+ * console.log(`Retry ${attempt} after ${delay}ms: ${error}`)
85
+ * }
86
+ *
87
+ * @example
88
+ * // Cancel retries for specific errors
89
+ * onRetry: (attempt, error) => {
90
+ * if (error instanceof ValidationError) return false
91
+ * }
92
+ *
93
+ * @example
94
+ * // Use custom delay
95
+ * onRetry: (attempt) => attempt * 1000 // 1s, 2s, 3s, ...
96
+ */
97
+ onRetry?: ((attempt: number, error: unknown, delay: number) => boolean | number | undefined) | undefined;
98
+ /**
99
+ * Whether `onRetry` can cancel retries by returning `false`.
100
+ * When `true`, returning `false` from `onRetry` stops retry attempts.
101
+ *
102
+ * @default false
103
+ */
104
+ onRetryCancelOnFalse?: boolean | undefined;
105
+ /**
106
+ * Whether errors thrown by `onRetry` should propagate.
107
+ * When `true`, exceptions in `onRetry` terminate the retry loop.
108
+ * When `false`, exceptions in `onRetry` are silently caught.
109
+ *
110
+ * @default false
111
+ */
112
+ onRetryRethrow?: boolean | undefined;
113
+ /**
114
+ * Number of retry attempts (0 = no retries, only initial attempt).
115
+ * The callback is executed `retries + 1` times total (initial + retries).
116
+ *
117
+ * @default 0
118
+ * @example
119
+ * // retries: 0 -> 1 total attempt (no retries)
120
+ * // retries: 3 -> 4 total attempts (1 initial + 3 retries)
121
+ */
122
+ retries?: number | undefined;
123
+ /**
124
+ * AbortSignal to support cancellation of retry operations.
125
+ * When aborted, immediately stops retrying and returns `undefined`.
126
+ *
127
+ * @default process abort signal
128
+ * @example
129
+ * const controller = new AbortController()
130
+ * pRetry(fn, { signal: controller.signal })
131
+ * // Later: controller.abort() to cancel
132
+ */
133
+ signal?: AbortSignal | undefined;
15
134
  }
135
+ /**
136
+ * Configuration options for iteration functions with concurrency control.
137
+ *
138
+ * Controls how array operations are parallelized and retried.
139
+ */
16
140
  export interface IterationOptions {
17
- concurrency?: number;
18
- retries?: number | RetryOptions;
19
- signal?: AbortSignal;
141
+ /**
142
+ * The number of concurrent executions performed at one time.
143
+ * Higher values increase parallelism but may overwhelm resources.
144
+ *
145
+ * @default 1
146
+ * @example
147
+ * // Process 5 items at a time
148
+ * await pEach(items, processItem, { concurrency: 5 })
149
+ */
150
+ concurrency?: number | undefined;
151
+ /**
152
+ * Retry configuration as a number (retry count) or full options object.
153
+ * Applied to each individual item's callback execution.
154
+ *
155
+ * @default 0 (no retries)
156
+ * @example
157
+ * // Simple: retry each item up to 3 times
158
+ * await pEach(items, fetchItem, { retries: 3 })
159
+ *
160
+ * @example
161
+ * // Advanced: custom backoff for each item
162
+ * await pEach(items, fetchItem, {
163
+ * retries: {
164
+ * retries: 3,
165
+ * baseDelayMs: 1000,
166
+ * backoffFactor: 2
167
+ * }
168
+ * })
169
+ */
170
+ retries?: number | RetryOptions | undefined;
171
+ /**
172
+ * AbortSignal to support cancellation of the entire iteration.
173
+ * When aborted, stops processing remaining items.
174
+ *
175
+ * @default process abort signal
176
+ */
177
+ signal?: AbortSignal | undefined;
20
178
  }
21
179
  /**
22
180
  * Normalize options for iteration functions.
181
+ *
182
+ * Converts various option formats into a consistent structure with defaults applied.
183
+ * Handles number shorthand for concurrency and ensures minimum values.
184
+ *
185
+ * @param options - Concurrency as number, or full options object, or undefined
186
+ * @returns Normalized options with concurrency, retries, and signal
187
+ *
188
+ * @example
189
+ * // Number shorthand for concurrency
190
+ * normalizeIterationOptions(5)
191
+ * // => { concurrency: 5, retries: {...}, signal: AbortSignal }
192
+ *
193
+ * @example
194
+ * // Full options
195
+ * normalizeIterationOptions({ concurrency: 3, retries: 2 })
196
+ * // => { concurrency: 3, retries: {...}, signal: AbortSignal }
23
197
  */
24
198
  /*@__NO_SIDE_EFFECTS__*/
25
- export declare function normalizeIterationOptions(options?: number | IterationOptions): {
199
+ export declare function normalizeIterationOptions(options?: number | IterationOptions | undefined): {
26
200
  concurrency: number;
27
201
  retries: RetryOptions;
28
202
  signal: AbortSignal;
29
203
  };
30
204
  /**
31
205
  * Normalize options for retry functionality.
206
+ *
207
+ * Converts various retry option formats into a complete configuration with all defaults.
208
+ * Handles legacy property names (`factor`, `minTimeout`, `maxTimeout`) and merges them
209
+ * with modern equivalents.
210
+ *
211
+ * @param options - Retry count as number, or full options object, or undefined
212
+ * @returns Normalized retry options with all properties set
213
+ *
214
+ * @example
215
+ * // Number shorthand
216
+ * normalizeRetryOptions(3)
217
+ * // => { retries: 3, baseDelayMs: 200, backoffFactor: 2, ... }
218
+ *
219
+ * @example
220
+ * // Full options with defaults filled in
221
+ * normalizeRetryOptions({ retries: 5, baseDelayMs: 500 })
222
+ * // => { retries: 5, baseDelayMs: 500, backoffFactor: 2, jitter: true, ... }
32
223
  */
33
224
  /*@__NO_SIDE_EFFECTS__*/
34
- export declare function normalizeRetryOptions(options?: number | RetryOptions): RetryOptions;
225
+ export declare function normalizeRetryOptions(options?: number | RetryOptions | undefined): RetryOptions;
35
226
  /**
36
227
  * Resolve retry options from various input formats.
228
+ *
229
+ * Converts shorthand and partial options into a base configuration that can be
230
+ * further normalized. This is an internal helper for option processing.
231
+ *
232
+ * @param options - Retry count as number, or partial options object, or undefined
233
+ * @returns Resolved retry options with defaults for basic properties
234
+ *
235
+ * @example
236
+ * resolveRetryOptions(3)
237
+ * // => { retries: 3, minTimeout: 200, maxTimeout: 10000, factor: 2 }
238
+ *
239
+ * @example
240
+ * resolveRetryOptions({ retries: 5, maxTimeout: 5000 })
241
+ * // => { retries: 5, minTimeout: 200, maxTimeout: 5000, factor: 2 }
37
242
  */
38
243
  /*@__NO_SIDE_EFFECTS__*/
39
- export declare function resolveRetryOptions(options?: number | RetryOptions): RetryOptions;
244
+ export declare function resolveRetryOptions(options?: number | RetryOptions | undefined): RetryOptions;
40
245
  /**
41
246
  * Execute an async function for each array element with concurrency control.
247
+ *
248
+ * Processes array items in parallel batches (chunks) with configurable concurrency.
249
+ * Each item's callback can be retried independently on failure. Similar to
250
+ * `Promise.all(array.map(fn))` but with controlled parallelism.
251
+ *
252
+ * @template T - The type of array elements
253
+ * @param array - The array to iterate over
254
+ * @param callbackFn - Async function to execute for each item
255
+ * @param options - Concurrency as number, or full iteration options, or undefined
256
+ * @returns Promise that resolves when all items are processed
257
+ *
258
+ * @example
259
+ * // Process items serially (concurrency: 1)
260
+ * await pEach(urls, async (url) => {
261
+ * await fetch(url)
262
+ * })
263
+ *
264
+ * @example
265
+ * // Process 5 items at a time
266
+ * await pEach(files, async (file) => {
267
+ * await processFile(file)
268
+ * }, 5)
269
+ *
270
+ * @example
271
+ * // With retries and cancellation
272
+ * const controller = new AbortController()
273
+ * await pEach(tasks, async (task) => {
274
+ * await executeTask(task)
275
+ * }, {
276
+ * concurrency: 3,
277
+ * retries: 2,
278
+ * signal: controller.signal
279
+ * })
42
280
  */
43
281
  /*@__NO_SIDE_EFFECTS__*/
44
- export declare function pEach<T>(array: T[], callbackFn: (item: T) => Promise<unknown>, options?: number | IterationOptions): Promise<void>;
282
+ export declare function pEach<T>(array: T[], callbackFn: (item: T) => Promise<unknown>, options?: number | IterationOptions | undefined): Promise<void>;
45
283
  /**
46
284
  * Filter an array asynchronously with concurrency control.
285
+ *
286
+ * Tests each element with an async predicate function, processing items in parallel
287
+ * batches. Returns a new array with only items that pass the test. Similar to
288
+ * `array.filter()` but for async predicates with controlled concurrency.
289
+ *
290
+ * @template T - The type of array elements
291
+ * @param array - The array to filter
292
+ * @param callbackFn - Async predicate function returning true to keep item
293
+ * @param options - Concurrency as number, or full iteration options, or undefined
294
+ * @returns Promise resolving to filtered array
295
+ *
296
+ * @example
297
+ * // Filter serially
298
+ * const activeUsers = await pFilter(users, async (user) => {
299
+ * return await isUserActive(user.id)
300
+ * })
301
+ *
302
+ * @example
303
+ * // Filter with concurrency
304
+ * const validFiles = await pFilter(filePaths, async (path) => {
305
+ * try {
306
+ * await fs.access(path)
307
+ * return true
308
+ * } catch {
309
+ * return false
310
+ * }
311
+ * }, 10)
312
+ *
313
+ * @example
314
+ * // With retries for flaky checks
315
+ * const reachable = await pFilter(endpoints, async (url) => {
316
+ * const response = await fetch(url)
317
+ * return response.ok
318
+ * }, {
319
+ * concurrency: 5,
320
+ * retries: 2
321
+ * })
47
322
  */
48
323
  /*@__NO_SIDE_EFFECTS__*/
49
- export declare function pFilter<T>(array: T[], callbackFn: (item: T) => Promise<boolean>, options?: number | IterationOptions): Promise<T[]>;
324
+ export declare function pFilter<T>(array: T[], callbackFn: (item: T) => Promise<boolean>, options?: number | IterationOptions | undefined): Promise<T[]>;
50
325
  /**
51
326
  * Process array in chunks with an async callback.
327
+ *
328
+ * Divides the array into fixed-size chunks and processes each chunk sequentially
329
+ * with the callback. Useful for batch operations like bulk database inserts or
330
+ * API calls with payload size limits.
331
+ *
332
+ * @template T - The type of array elements
333
+ * @param array - The array to process in chunks
334
+ * @param callbackFn - Async function to execute for each chunk
335
+ * @param options - Chunk size and retry options
336
+ * @returns Promise that resolves when all chunks are processed
337
+ *
338
+ * @example
339
+ * // Insert records in batches of 100
340
+ * await pEachChunk(records, async (chunk) => {
341
+ * await db.batchInsert(chunk)
342
+ * }, { chunkSize: 100 })
343
+ *
344
+ * @example
345
+ * // Upload files in batches with retries
346
+ * await pEachChunk(files, async (batch) => {
347
+ * await uploadBatch(batch)
348
+ * }, {
349
+ * chunkSize: 50,
350
+ * retries: 3,
351
+ * baseDelayMs: 1000
352
+ * })
353
+ *
354
+ * @example
355
+ * // Process with cancellation support
356
+ * const controller = new AbortController()
357
+ * await pEachChunk(items, async (chunk) => {
358
+ * await processChunk(chunk)
359
+ * }, {
360
+ * chunkSize: 25,
361
+ * signal: controller.signal
362
+ * })
52
363
  */
53
364
  /*@__NO_SIDE_EFFECTS__*/
54
- export declare function pEachChunk<T>(array: T[], callbackFn: (chunk: T[]) => Promise<unknown>, options?: RetryOptions & {
55
- chunkSize?: number;
56
- }): Promise<void>;
365
+ export declare function pEachChunk<T>(array: T[], callbackFn: (chunk: T[]) => Promise<unknown>, options?: (RetryOptions & {
366
+ chunkSize?: number | undefined;
367
+ }) | undefined): Promise<void>;
57
368
  /**
58
369
  * Filter chunked arrays with an async predicate.
370
+ *
371
+ * Internal helper for `pFilter`. Processes pre-chunked arrays, applying the
372
+ * predicate to each element within each chunk with retry support.
373
+ *
374
+ * @template T - The type of array elements
375
+ * @param chunks - Pre-chunked array (array of arrays)
376
+ * @param callbackFn - Async predicate function
377
+ * @param options - Retry count as number, or full retry options, or undefined
378
+ * @returns Promise resolving to array of filtered chunks
379
+ *
380
+ * @example
381
+ * const chunks = [[1, 2], [3, 4], [5, 6]]
382
+ * const filtered = await pFilterChunk(chunks, async (n) => n % 2 === 0)
383
+ * // => [[2], [4], [6]]
59
384
  */
60
385
  /*@__NO_SIDE_EFFECTS__*/
61
- export declare function pFilterChunk<T>(chunks: T[][], callbackFn: (value: T) => Promise<boolean>, options?: number | RetryOptions): Promise<T[][]>;
386
+ export declare function pFilterChunk<T>(chunks: T[][], callbackFn: (value: T) => Promise<boolean>, options?: number | RetryOptions | undefined): Promise<T[][]>;
62
387
  /**
63
388
  * Retry an async function with exponential backoff.
64
- * @throws {Error} The last error if all retries fail.
389
+ *
390
+ * Attempts to execute a function multiple times with increasing delays between attempts.
391
+ * Implements exponential backoff with optional jitter to prevent thundering herd problems.
392
+ * Supports custom retry logic via `onRetry` callback.
393
+ *
394
+ * The delay calculation follows: `min(baseDelayMs * (backoffFactor ** attempt), maxDelayMs)`
395
+ * With jitter: adds random value between 0 and calculated delay.
396
+ *
397
+ * @template T - The return type of the callback function
398
+ * @param callbackFn - Async function to retry
399
+ * @param options - Retry count as number, or full retry options, or undefined
400
+ * @returns Promise resolving to callback result, or `undefined` if aborted
401
+ *
402
+ * @throws {Error} The last error if all retry attempts fail
403
+ *
404
+ * @example
405
+ * // Simple retry: 3 attempts with default backoff
406
+ * const data = await pRetry(async () => {
407
+ * return await fetchData()
408
+ * }, 3)
409
+ *
410
+ * @example
411
+ * // Custom backoff strategy
412
+ * const result = await pRetry(async () => {
413
+ * return await unreliableOperation()
414
+ * }, {
415
+ * retries: 5,
416
+ * baseDelayMs: 1000, // Start at 1 second
417
+ * backoffFactor: 2, // Double each time
418
+ * maxDelayMs: 30000, // Cap at 30 seconds
419
+ * jitter: true // Add randomness
420
+ * })
421
+ * // Delays: ~1s, ~2s, ~4s, ~8s, ~16s (each ± random jitter)
422
+ *
423
+ * @example
424
+ * // With custom retry logic
425
+ * const data = await pRetry(async () => {
426
+ * return await apiCall()
427
+ * }, {
428
+ * retries: 3,
429
+ * onRetry: (attempt, error, delay) => {
430
+ * console.log(`Attempt ${attempt} failed: ${error}`)
431
+ * console.log(`Waiting ${delay}ms before retry...`)
432
+ *
433
+ * // Cancel retries for client errors (4xx)
434
+ * if (error.statusCode >= 400 && error.statusCode < 500) {
435
+ * return false
436
+ * }
437
+ *
438
+ * // Use longer delay for rate limit errors
439
+ * if (error.statusCode === 429) {
440
+ * return 60000 // Wait 1 minute
441
+ * }
442
+ * },
443
+ * onRetryCancelOnFalse: true
444
+ * })
445
+ *
446
+ * @example
447
+ * // With cancellation support
448
+ * const controller = new AbortController()
449
+ * setTimeout(() => controller.abort(), 5000) // Cancel after 5s
450
+ *
451
+ * const result = await pRetry(async ({ signal }) => {
452
+ * return await longRunningTask(signal)
453
+ * }, {
454
+ * retries: 10,
455
+ * signal: controller.signal
456
+ * })
457
+ * // Returns undefined if aborted
458
+ *
459
+ * @example
460
+ * // Pass arguments to callback
461
+ * const result = await pRetry(
462
+ * async (url, options) => {
463
+ * return await fetch(url, options)
464
+ * },
465
+ * {
466
+ * retries: 3,
467
+ * args: ['https://api.example.com', { method: 'POST' }]
468
+ * }
469
+ * )
65
470
  */
66
471
  /*@__NO_SIDE_EFFECTS__*/
67
- export declare function pRetry<T>(callbackFn: (...args: unknown[]) => Promise<T>, options?: number | RetryOptions): Promise<T | undefined>;
472
+ export declare function pRetry<T>(callbackFn: (...args: unknown[]) => Promise<T>, options?: number | RetryOptions | undefined): Promise<T | undefined>;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/promises.ts"],
4
- "sourcesContent": ["/**\n * @fileoverview Promise utilities including chunked iteration and timers.\n * Provides async control flow helpers and promise-based timing functions.\n */\n\nimport { UNDEFINED_TOKEN } from '#constants/core'\nimport { getAbortSignal } from '#constants/process'\n\nimport { arrayChunk } from './arrays'\n\nconst abortSignal = getAbortSignal()\n\nexport interface RetryOptions {\n args?: unknown[]\n backoffFactor?: number\n baseDelayMs?: number\n factor?: number\n jitter?: boolean\n maxDelayMs?: number\n maxTimeout?: number\n minTimeout?: number\n onRetry?: (\n attempt: number,\n error: unknown,\n delay: number,\n ) => boolean | number | undefined\n onRetryCancelOnFalse?: boolean\n onRetryRethrow?: boolean\n retries?: number\n signal?: AbortSignal\n}\n\nexport interface IterationOptions {\n concurrency?: number\n retries?: number | RetryOptions\n signal?: AbortSignal\n}\n\nlet _timers: typeof import('node:timers/promises') | undefined\n/**\n * Get the timers/promises module.\n * @private\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getTimers() {\n if (_timers === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _timers = /*@__PURE__*/ require('node:timers/promises')\n }\n return _timers as typeof import('node:timers/promises')\n}\n\n/**\n * Normalize options for iteration functions.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function normalizeIterationOptions(\n options?: number | IterationOptions,\n): { concurrency: number; retries: RetryOptions; signal: AbortSignal } {\n // Handle number as concurrency shorthand\n const opts = typeof options === 'number' ? { concurrency: options } : options\n\n const {\n // The number of concurrent executions performed at one time.\n concurrency = 1,\n // Retries as a number or options object.\n retries,\n // AbortSignal used to support cancellation.\n signal = abortSignal,\n } = { __proto__: null, ...opts } as IterationOptions\n\n // Ensure concurrency is at least 1\n const normalizedConcurrency = Math.max(1, concurrency)\n const retryOpts = resolveRetryOptions(retries)\n return {\n __proto__: null,\n concurrency: normalizedConcurrency,\n retries: normalizeRetryOptions({ signal, ...retryOpts }),\n signal,\n } as { concurrency: number; retries: RetryOptions; signal: AbortSignal }\n}\n\n/**\n * Normalize options for retry functionality.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function normalizeRetryOptions(\n options?: number | RetryOptions,\n): RetryOptions {\n const resolved = resolveRetryOptions(options)\n const {\n // Arguments to pass to the callback function.\n args = [],\n // Multiplier for exponential backoff (e.g., 2 doubles delay each retry).\n backoffFactor = resolved.factor || 2,\n // Initial delay before the first retry (in milliseconds).\n baseDelayMs = resolved.minTimeout || 200,\n // Whether to apply randomness to spread out retries.\n jitter = true,\n // Upper limit for any backoff delay (in milliseconds).\n maxDelayMs = resolved.maxTimeout || 10_000,\n // Optional callback invoked on each retry attempt:\n // (attempt: number, error: unknown, delay: number) => void\n onRetry,\n // Whether onRetry can cancel retries by returning `false`.\n onRetryCancelOnFalse = false,\n // Whether onRetry will rethrow errors.\n onRetryRethrow = false,\n // Number of retry attempts (0 = no retries, only initial attempt).\n retries = resolved.retries || 0,\n // AbortSignal used to support cancellation.\n signal = abortSignal,\n } = resolved\n return {\n args,\n backoffFactor,\n baseDelayMs,\n jitter,\n maxDelayMs,\n minTimeout: baseDelayMs,\n maxTimeout: maxDelayMs,\n onRetry,\n onRetryCancelOnFalse,\n onRetryRethrow,\n retries,\n signal,\n } as RetryOptions\n}\n\n/**\n * Resolve retry options from various input formats.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function resolveRetryOptions(\n options?: number | RetryOptions,\n): RetryOptions {\n const defaults = {\n __proto__: null,\n retries: 0,\n minTimeout: 200,\n maxTimeout: 10_000,\n factor: 2,\n }\n\n if (typeof options === 'number') {\n return { ...defaults, retries: options }\n }\n\n return options ? { ...defaults, ...options } : defaults\n}\n\n/**\n * Execute an async function for each array element with concurrency control.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pEach<T>(\n array: T[],\n callbackFn: (item: T) => Promise<unknown>,\n options?: number | IterationOptions,\n): Promise<void> {\n const iterOpts = normalizeIterationOptions(options)\n const { concurrency, retries, signal } = iterOpts\n\n // Process items with concurrency control.\n const chunks = arrayChunk(array, concurrency)\n for (const chunk of chunks) {\n if (signal?.aborted) {\n return\n }\n // Process each item in the chunk concurrently.\n // eslint-disable-next-line no-await-in-loop\n await Promise.all(\n chunk.map((item: T) =>\n pRetry((...args: unknown[]) => callbackFn(args[0] as T), {\n ...retries,\n args: [item],\n signal,\n }),\n ),\n )\n }\n}\n\n/**\n * Filter an array asynchronously with concurrency control.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pFilter<T>(\n array: T[],\n callbackFn: (item: T) => Promise<boolean>,\n options?: number | IterationOptions,\n): Promise<T[]> {\n const iterOpts = normalizeIterationOptions(options)\n return (\n await pFilterChunk(\n arrayChunk(array, iterOpts.concurrency),\n callbackFn,\n iterOpts.retries,\n )\n ).flat()\n}\n\n/**\n * Process array in chunks with an async callback.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pEachChunk<T>(\n array: T[],\n callbackFn: (chunk: T[]) => Promise<unknown>,\n options?: RetryOptions & { chunkSize?: number },\n): Promise<void> {\n const { chunkSize = 100, ...retryOpts } = options || {}\n const chunks = arrayChunk(array, chunkSize)\n const normalizedRetryOpts = normalizeRetryOptions(retryOpts)\n const { signal } = normalizedRetryOpts\n for (const chunk of chunks) {\n if (signal?.aborted) {\n return\n }\n // eslint-disable-next-line no-await-in-loop\n await pRetry((...args: unknown[]) => callbackFn(args[0] as T[]), {\n ...normalizedRetryOpts,\n args: [chunk],\n })\n }\n}\n\n/**\n * Filter chunked arrays with an async predicate.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pFilterChunk<T>(\n chunks: T[][],\n callbackFn: (value: T) => Promise<boolean>,\n options?: number | RetryOptions,\n): Promise<T[][]> {\n const retryOpts = normalizeRetryOptions(options)\n const { signal } = retryOpts\n const { length } = chunks\n const filteredChunks = Array(length)\n for (let i = 0; i < length; i += 1) {\n // Process each chunk, filtering based on the callback function.\n if (signal?.aborted) {\n filteredChunks[i] = []\n } else {\n const chunk = chunks[i] as T[]\n // eslint-disable-next-line no-await-in-loop\n const predicateResults = await Promise.all(\n chunk.map(value =>\n pRetry((...args: unknown[]) => callbackFn(args[0] as T), {\n ...retryOpts,\n args: [value],\n }),\n ),\n )\n filteredChunks[i] = chunk.filter((_v, i) => predicateResults[i])\n }\n }\n return filteredChunks\n}\n\n/**\n * Retry an async function with exponential backoff.\n * @throws {Error} The last error if all retries fail.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pRetry<T>(\n callbackFn: (...args: unknown[]) => Promise<T>,\n options?: number | RetryOptions,\n): Promise<T | undefined> {\n const {\n args,\n backoffFactor,\n baseDelayMs,\n jitter,\n maxDelayMs,\n onRetry,\n onRetryCancelOnFalse,\n onRetryRethrow,\n retries,\n signal,\n } = normalizeRetryOptions(options)\n if (signal?.aborted) {\n return undefined\n }\n if (retries === 0) {\n return await callbackFn(...(args || []), { signal })\n }\n\n const timers = getTimers()\n\n let attempts = retries as number\n let delay = baseDelayMs as number\n let error: unknown = UNDEFINED_TOKEN\n\n while (attempts-- >= 0) {\n // Check abort before attempt.\n if (signal?.aborted) {\n return undefined\n }\n\n try {\n // eslint-disable-next-line no-await-in-loop\n return await callbackFn(...(args || []), { signal })\n } catch (e) {\n if (error === UNDEFINED_TOKEN) {\n error = e\n }\n if (attempts < 0) {\n break\n }\n let waitTime = delay\n if (jitter) {\n // Add randomness: Pick a value between 0 and `delay`.\n waitTime += Math.floor(Math.random() * delay)\n }\n // Clamp wait time to max delay.\n waitTime = Math.min(waitTime, maxDelayMs as number)\n if (typeof onRetry === 'function') {\n try {\n const result = onRetry((retries as number) - attempts, e, waitTime)\n if (result === false && onRetryCancelOnFalse) {\n break\n }\n // If onRetry returns a number, use it as the custom delay.\n if (typeof result === 'number' && result >= 0) {\n waitTime = Math.min(result, maxDelayMs as number)\n }\n } catch (e) {\n if (onRetryRethrow) {\n throw e\n }\n }\n }\n\n try {\n // eslint-disable-next-line no-await-in-loop\n await timers.setTimeout(waitTime, undefined, { signal })\n } catch {\n // setTimeout was aborted.\n return undefined\n }\n\n // Check abort again after delay.\n if (signal?.aborted) {\n return undefined\n }\n\n // Exponentially increase the delay for the next attempt, capping at maxDelayMs.\n delay = Math.min(delay * (backoffFactor as number), maxDelayMs as number)\n }\n }\n if (error !== UNDEFINED_TOKEN) {\n throw error\n }\n return undefined\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * @fileoverview Promise utilities including chunked iteration and timers.\n * Provides async control flow helpers and promise-based timing functions.\n */\n\nimport { UNDEFINED_TOKEN } from '#constants/core'\nimport { getAbortSignal } from '#constants/process'\n\nimport { arrayChunk } from './arrays'\n\nconst abortSignal = getAbortSignal()\n\n/**\n * Configuration options for retry behavior with exponential backoff.\n *\n * Controls how failed operations are retried, including timing, backoff strategy,\n * and callback hooks for observing or modifying retry behavior.\n */\nexport interface RetryOptions {\n /**\n * Arguments to pass to the callback function on each attempt.\n *\n * @default []\n */\n args?: unknown[] | undefined\n\n /**\n * Multiplier for exponential backoff (e.g., 2 doubles delay each retry).\n * Each retry waits `baseDelayMs * (backoffFactor ** attemptNumber)`.\n *\n * @default 2\n * @example\n * // With backoffFactor: 2, baseDelayMs: 100\n * // Retry 1: 100ms\n * // Retry 2: 200ms\n * // Retry 3: 400ms\n */\n backoffFactor?: number | undefined\n\n /**\n * Initial delay before the first retry (in milliseconds).\n * This is the base value for exponential backoff calculations.\n *\n * @default 200\n */\n baseDelayMs?: number | undefined\n\n /**\n * Legacy alias for `backoffFactor`. Use `backoffFactor` instead.\n *\n * @deprecated Use `backoffFactor` instead\n * @default 2\n */\n factor?: number | undefined\n\n /**\n * Whether to apply randomness to spread out retries and avoid thundering herd.\n * When `true`, adds random delay between 0 and current delay value.\n *\n * @default true\n * @example\n * // With jitter: true, delay: 100ms\n * // Actual wait: 100ms + random(0-100ms) = 100-200ms\n */\n jitter?: boolean | undefined\n\n /**\n * Upper limit for any backoff delay (in milliseconds).\n * Prevents exponential backoff from growing unbounded.\n *\n * @default 10000\n */\n maxDelayMs?: number | undefined\n\n /**\n * Legacy alias for `maxDelayMs`. Use `maxDelayMs` instead.\n *\n * @deprecated Use `maxDelayMs` instead\n * @default 10000\n */\n maxTimeout?: number | undefined\n\n /**\n * Legacy alias for `baseDelayMs`. Use `baseDelayMs` instead.\n *\n * @deprecated Use `baseDelayMs` instead\n * @default 200\n */\n minTimeout?: number | undefined\n\n /**\n * Callback invoked on each retry attempt.\n * Can observe errors, customize delays, or cancel retries.\n *\n * @param attempt - The current attempt number (1-based: 1, 2, 3, ...)\n * @param error - The error that triggered this retry\n * @param delay - The calculated delay in milliseconds before next retry\n * @returns `false` to cancel retries (if `onRetryCancelOnFalse` is `true`),\n * a number to override the delay, or `undefined` to use calculated delay\n *\n * @example\n * // Log each retry\n * onRetry: (attempt, error, delay) => {\n * console.log(`Retry ${attempt} after ${delay}ms: ${error}`)\n * }\n *\n * @example\n * // Cancel retries for specific errors\n * onRetry: (attempt, error) => {\n * if (error instanceof ValidationError) return false\n * }\n *\n * @example\n * // Use custom delay\n * onRetry: (attempt) => attempt * 1000 // 1s, 2s, 3s, ...\n */\n onRetry?:\n | ((\n attempt: number,\n error: unknown,\n delay: number,\n ) => boolean | number | undefined)\n | undefined\n\n /**\n * Whether `onRetry` can cancel retries by returning `false`.\n * When `true`, returning `false` from `onRetry` stops retry attempts.\n *\n * @default false\n */\n onRetryCancelOnFalse?: boolean | undefined\n\n /**\n * Whether errors thrown by `onRetry` should propagate.\n * When `true`, exceptions in `onRetry` terminate the retry loop.\n * When `false`, exceptions in `onRetry` are silently caught.\n *\n * @default false\n */\n onRetryRethrow?: boolean | undefined\n\n /**\n * Number of retry attempts (0 = no retries, only initial attempt).\n * The callback is executed `retries + 1` times total (initial + retries).\n *\n * @default 0\n * @example\n * // retries: 0 -> 1 total attempt (no retries)\n * // retries: 3 -> 4 total attempts (1 initial + 3 retries)\n */\n retries?: number | undefined\n\n /**\n * AbortSignal to support cancellation of retry operations.\n * When aborted, immediately stops retrying and returns `undefined`.\n *\n * @default process abort signal\n * @example\n * const controller = new AbortController()\n * pRetry(fn, { signal: controller.signal })\n * // Later: controller.abort() to cancel\n */\n signal?: AbortSignal | undefined\n}\n\n/**\n * Configuration options for iteration functions with concurrency control.\n *\n * Controls how array operations are parallelized and retried.\n */\nexport interface IterationOptions {\n /**\n * The number of concurrent executions performed at one time.\n * Higher values increase parallelism but may overwhelm resources.\n *\n * @default 1\n * @example\n * // Process 5 items at a time\n * await pEach(items, processItem, { concurrency: 5 })\n */\n concurrency?: number | undefined\n\n /**\n * Retry configuration as a number (retry count) or full options object.\n * Applied to each individual item's callback execution.\n *\n * @default 0 (no retries)\n * @example\n * // Simple: retry each item up to 3 times\n * await pEach(items, fetchItem, { retries: 3 })\n *\n * @example\n * // Advanced: custom backoff for each item\n * await pEach(items, fetchItem, {\n * retries: {\n * retries: 3,\n * baseDelayMs: 1000,\n * backoffFactor: 2\n * }\n * })\n */\n retries?: number | RetryOptions | undefined\n\n /**\n * AbortSignal to support cancellation of the entire iteration.\n * When aborted, stops processing remaining items.\n *\n * @default process abort signal\n */\n signal?: AbortSignal | undefined\n}\n\nlet _timers: typeof import('node:timers/promises') | undefined\n/**\n * Get the timers/promises module.\n * Uses lazy loading to avoid Webpack bundling issues.\n *\n * @private\n * @returns The Node.js timers/promises module\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getTimers() {\n if (_timers === undefined) {\n // Use non-'node:' prefixed require to avoid Webpack errors.\n\n _timers = /*@__PURE__*/ require('node:timers/promises')\n }\n return _timers as typeof import('node:timers/promises')\n}\n\n/**\n * Normalize options for iteration functions.\n *\n * Converts various option formats into a consistent structure with defaults applied.\n * Handles number shorthand for concurrency and ensures minimum values.\n *\n * @param options - Concurrency as number, or full options object, or undefined\n * @returns Normalized options with concurrency, retries, and signal\n *\n * @example\n * // Number shorthand for concurrency\n * normalizeIterationOptions(5)\n * // => { concurrency: 5, retries: {...}, signal: AbortSignal }\n *\n * @example\n * // Full options\n * normalizeIterationOptions({ concurrency: 3, retries: 2 })\n * // => { concurrency: 3, retries: {...}, signal: AbortSignal }\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function normalizeIterationOptions(\n options?: number | IterationOptions | undefined,\n): { concurrency: number; retries: RetryOptions; signal: AbortSignal } {\n // Handle number as concurrency shorthand\n const opts = typeof options === 'number' ? { concurrency: options } : options\n\n const {\n // The number of concurrent executions performed at one time.\n concurrency = 1,\n // Retries as a number or options object.\n retries,\n // AbortSignal used to support cancellation.\n signal = abortSignal,\n } = { __proto__: null, ...opts } as IterationOptions\n\n // Ensure concurrency is at least 1\n const normalizedConcurrency = Math.max(1, concurrency)\n const retryOpts = resolveRetryOptions(retries)\n return {\n __proto__: null,\n concurrency: normalizedConcurrency,\n retries: normalizeRetryOptions({ signal, ...retryOpts }),\n signal,\n } as { concurrency: number; retries: RetryOptions; signal: AbortSignal }\n}\n\n/**\n * Normalize options for retry functionality.\n *\n * Converts various retry option formats into a complete configuration with all defaults.\n * Handles legacy property names (`factor`, `minTimeout`, `maxTimeout`) and merges them\n * with modern equivalents.\n *\n * @param options - Retry count as number, or full options object, or undefined\n * @returns Normalized retry options with all properties set\n *\n * @example\n * // Number shorthand\n * normalizeRetryOptions(3)\n * // => { retries: 3, baseDelayMs: 200, backoffFactor: 2, ... }\n *\n * @example\n * // Full options with defaults filled in\n * normalizeRetryOptions({ retries: 5, baseDelayMs: 500 })\n * // => { retries: 5, baseDelayMs: 500, backoffFactor: 2, jitter: true, ... }\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function normalizeRetryOptions(\n options?: number | RetryOptions | undefined,\n): RetryOptions {\n const resolved = resolveRetryOptions(options)\n const {\n // Arguments to pass to the callback function.\n args = [],\n // Multiplier for exponential backoff (e.g., 2 doubles delay each retry).\n backoffFactor = resolved.factor || 2,\n // Initial delay before the first retry (in milliseconds).\n baseDelayMs = resolved.minTimeout || 200,\n // Whether to apply randomness to spread out retries.\n jitter = true,\n // Upper limit for any backoff delay (in milliseconds).\n maxDelayMs = resolved.maxTimeout || 10_000,\n // Optional callback invoked on each retry attempt:\n // (attempt: number, error: unknown, delay: number) => void\n onRetry,\n // Whether onRetry can cancel retries by returning `false`.\n onRetryCancelOnFalse = false,\n // Whether onRetry will rethrow errors.\n onRetryRethrow = false,\n // Number of retry attempts (0 = no retries, only initial attempt).\n retries = resolved.retries || 0,\n // AbortSignal used to support cancellation.\n signal = abortSignal,\n } = resolved\n return {\n args,\n backoffFactor,\n baseDelayMs,\n jitter,\n maxDelayMs,\n minTimeout: baseDelayMs,\n maxTimeout: maxDelayMs,\n onRetry,\n onRetryCancelOnFalse,\n onRetryRethrow,\n retries,\n signal,\n } as RetryOptions\n}\n\n/**\n * Resolve retry options from various input formats.\n *\n * Converts shorthand and partial options into a base configuration that can be\n * further normalized. This is an internal helper for option processing.\n *\n * @param options - Retry count as number, or partial options object, or undefined\n * @returns Resolved retry options with defaults for basic properties\n *\n * @example\n * resolveRetryOptions(3)\n * // => { retries: 3, minTimeout: 200, maxTimeout: 10000, factor: 2 }\n *\n * @example\n * resolveRetryOptions({ retries: 5, maxTimeout: 5000 })\n * // => { retries: 5, minTimeout: 200, maxTimeout: 5000, factor: 2 }\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function resolveRetryOptions(\n options?: number | RetryOptions | undefined,\n): RetryOptions {\n const defaults = {\n __proto__: null,\n retries: 0,\n minTimeout: 200,\n maxTimeout: 10_000,\n factor: 2,\n }\n\n if (typeof options === 'number') {\n return { ...defaults, retries: options }\n }\n\n return options ? { ...defaults, ...options } : defaults\n}\n\n/**\n * Execute an async function for each array element with concurrency control.\n *\n * Processes array items in parallel batches (chunks) with configurable concurrency.\n * Each item's callback can be retried independently on failure. Similar to\n * `Promise.all(array.map(fn))` but with controlled parallelism.\n *\n * @template T - The type of array elements\n * @param array - The array to iterate over\n * @param callbackFn - Async function to execute for each item\n * @param options - Concurrency as number, or full iteration options, or undefined\n * @returns Promise that resolves when all items are processed\n *\n * @example\n * // Process items serially (concurrency: 1)\n * await pEach(urls, async (url) => {\n * await fetch(url)\n * })\n *\n * @example\n * // Process 5 items at a time\n * await pEach(files, async (file) => {\n * await processFile(file)\n * }, 5)\n *\n * @example\n * // With retries and cancellation\n * const controller = new AbortController()\n * await pEach(tasks, async (task) => {\n * await executeTask(task)\n * }, {\n * concurrency: 3,\n * retries: 2,\n * signal: controller.signal\n * })\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pEach<T>(\n array: T[],\n callbackFn: (item: T) => Promise<unknown>,\n options?: number | IterationOptions | undefined,\n): Promise<void> {\n const iterOpts = normalizeIterationOptions(options)\n const { concurrency, retries, signal } = iterOpts\n\n // Process items with concurrency control.\n const chunks = arrayChunk(array, concurrency)\n for (const chunk of chunks) {\n if (signal?.aborted) {\n return\n }\n // Process each item in the chunk concurrently.\n // eslint-disable-next-line no-await-in-loop\n await Promise.all(\n chunk.map((item: T) =>\n pRetry((...args: unknown[]) => callbackFn(args[0] as T), {\n ...retries,\n args: [item],\n signal,\n }),\n ),\n )\n }\n}\n\n/**\n * Filter an array asynchronously with concurrency control.\n *\n * Tests each element with an async predicate function, processing items in parallel\n * batches. Returns a new array with only items that pass the test. Similar to\n * `array.filter()` but for async predicates with controlled concurrency.\n *\n * @template T - The type of array elements\n * @param array - The array to filter\n * @param callbackFn - Async predicate function returning true to keep item\n * @param options - Concurrency as number, or full iteration options, or undefined\n * @returns Promise resolving to filtered array\n *\n * @example\n * // Filter serially\n * const activeUsers = await pFilter(users, async (user) => {\n * return await isUserActive(user.id)\n * })\n *\n * @example\n * // Filter with concurrency\n * const validFiles = await pFilter(filePaths, async (path) => {\n * try {\n * await fs.access(path)\n * return true\n * } catch {\n * return false\n * }\n * }, 10)\n *\n * @example\n * // With retries for flaky checks\n * const reachable = await pFilter(endpoints, async (url) => {\n * const response = await fetch(url)\n * return response.ok\n * }, {\n * concurrency: 5,\n * retries: 2\n * })\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pFilter<T>(\n array: T[],\n callbackFn: (item: T) => Promise<boolean>,\n options?: number | IterationOptions | undefined,\n): Promise<T[]> {\n const iterOpts = normalizeIterationOptions(options)\n return (\n await pFilterChunk(\n arrayChunk(array, iterOpts.concurrency),\n callbackFn,\n iterOpts.retries,\n )\n ).flat()\n}\n\n/**\n * Process array in chunks with an async callback.\n *\n * Divides the array into fixed-size chunks and processes each chunk sequentially\n * with the callback. Useful for batch operations like bulk database inserts or\n * API calls with payload size limits.\n *\n * @template T - The type of array elements\n * @param array - The array to process in chunks\n * @param callbackFn - Async function to execute for each chunk\n * @param options - Chunk size and retry options\n * @returns Promise that resolves when all chunks are processed\n *\n * @example\n * // Insert records in batches of 100\n * await pEachChunk(records, async (chunk) => {\n * await db.batchInsert(chunk)\n * }, { chunkSize: 100 })\n *\n * @example\n * // Upload files in batches with retries\n * await pEachChunk(files, async (batch) => {\n * await uploadBatch(batch)\n * }, {\n * chunkSize: 50,\n * retries: 3,\n * baseDelayMs: 1000\n * })\n *\n * @example\n * // Process with cancellation support\n * const controller = new AbortController()\n * await pEachChunk(items, async (chunk) => {\n * await processChunk(chunk)\n * }, {\n * chunkSize: 25,\n * signal: controller.signal\n * })\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pEachChunk<T>(\n array: T[],\n callbackFn: (chunk: T[]) => Promise<unknown>,\n options?: (RetryOptions & { chunkSize?: number | undefined }) | undefined,\n): Promise<void> {\n const { chunkSize = 100, ...retryOpts } = options || {}\n const chunks = arrayChunk(array, chunkSize)\n const normalizedRetryOpts = normalizeRetryOptions(retryOpts)\n const { signal } = normalizedRetryOpts\n for (const chunk of chunks) {\n if (signal?.aborted) {\n return\n }\n // eslint-disable-next-line no-await-in-loop\n await pRetry((...args: unknown[]) => callbackFn(args[0] as T[]), {\n ...normalizedRetryOpts,\n args: [chunk],\n })\n }\n}\n\n/**\n * Filter chunked arrays with an async predicate.\n *\n * Internal helper for `pFilter`. Processes pre-chunked arrays, applying the\n * predicate to each element within each chunk with retry support.\n *\n * @template T - The type of array elements\n * @param chunks - Pre-chunked array (array of arrays)\n * @param callbackFn - Async predicate function\n * @param options - Retry count as number, or full retry options, or undefined\n * @returns Promise resolving to array of filtered chunks\n *\n * @example\n * const chunks = [[1, 2], [3, 4], [5, 6]]\n * const filtered = await pFilterChunk(chunks, async (n) => n % 2 === 0)\n * // => [[2], [4], [6]]\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pFilterChunk<T>(\n chunks: T[][],\n callbackFn: (value: T) => Promise<boolean>,\n options?: number | RetryOptions | undefined,\n): Promise<T[][]> {\n const retryOpts = normalizeRetryOptions(options)\n const { signal } = retryOpts\n const { length } = chunks\n const filteredChunks = Array(length)\n for (let i = 0; i < length; i += 1) {\n // Process each chunk, filtering based on the callback function.\n if (signal?.aborted) {\n filteredChunks[i] = []\n } else {\n const chunk = chunks[i] as T[]\n // eslint-disable-next-line no-await-in-loop\n const predicateResults = await Promise.all(\n chunk.map(value =>\n pRetry((...args: unknown[]) => callbackFn(args[0] as T), {\n ...retryOpts,\n args: [value],\n }),\n ),\n )\n filteredChunks[i] = chunk.filter((_v, i) => predicateResults[i])\n }\n }\n return filteredChunks\n}\n\n/**\n * Retry an async function with exponential backoff.\n *\n * Attempts to execute a function multiple times with increasing delays between attempts.\n * Implements exponential backoff with optional jitter to prevent thundering herd problems.\n * Supports custom retry logic via `onRetry` callback.\n *\n * The delay calculation follows: `min(baseDelayMs * (backoffFactor ** attempt), maxDelayMs)`\n * With jitter: adds random value between 0 and calculated delay.\n *\n * @template T - The return type of the callback function\n * @param callbackFn - Async function to retry\n * @param options - Retry count as number, or full retry options, or undefined\n * @returns Promise resolving to callback result, or `undefined` if aborted\n *\n * @throws {Error} The last error if all retry attempts fail\n *\n * @example\n * // Simple retry: 3 attempts with default backoff\n * const data = await pRetry(async () => {\n * return await fetchData()\n * }, 3)\n *\n * @example\n * // Custom backoff strategy\n * const result = await pRetry(async () => {\n * return await unreliableOperation()\n * }, {\n * retries: 5,\n * baseDelayMs: 1000, // Start at 1 second\n * backoffFactor: 2, // Double each time\n * maxDelayMs: 30000, // Cap at 30 seconds\n * jitter: true // Add randomness\n * })\n * // Delays: ~1s, ~2s, ~4s, ~8s, ~16s (each \u00B1 random jitter)\n *\n * @example\n * // With custom retry logic\n * const data = await pRetry(async () => {\n * return await apiCall()\n * }, {\n * retries: 3,\n * onRetry: (attempt, error, delay) => {\n * console.log(`Attempt ${attempt} failed: ${error}`)\n * console.log(`Waiting ${delay}ms before retry...`)\n *\n * // Cancel retries for client errors (4xx)\n * if (error.statusCode >= 400 && error.statusCode < 500) {\n * return false\n * }\n *\n * // Use longer delay for rate limit errors\n * if (error.statusCode === 429) {\n * return 60000 // Wait 1 minute\n * }\n * },\n * onRetryCancelOnFalse: true\n * })\n *\n * @example\n * // With cancellation support\n * const controller = new AbortController()\n * setTimeout(() => controller.abort(), 5000) // Cancel after 5s\n *\n * const result = await pRetry(async ({ signal }) => {\n * return await longRunningTask(signal)\n * }, {\n * retries: 10,\n * signal: controller.signal\n * })\n * // Returns undefined if aborted\n *\n * @example\n * // Pass arguments to callback\n * const result = await pRetry(\n * async (url, options) => {\n * return await fetch(url, options)\n * },\n * {\n * retries: 3,\n * args: ['https://api.example.com', { method: 'POST' }]\n * }\n * )\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport async function pRetry<T>(\n callbackFn: (...args: unknown[]) => Promise<T>,\n options?: number | RetryOptions | undefined,\n): Promise<T | undefined> {\n const {\n args,\n backoffFactor,\n baseDelayMs,\n jitter,\n maxDelayMs,\n onRetry,\n onRetryCancelOnFalse,\n onRetryRethrow,\n retries,\n signal,\n } = normalizeRetryOptions(options)\n if (signal?.aborted) {\n return undefined\n }\n if (retries === 0) {\n return await callbackFn(...(args || []), { signal })\n }\n\n const timers = getTimers()\n\n let attempts = retries as number\n let delay = baseDelayMs as number\n let error: unknown = UNDEFINED_TOKEN\n\n while (attempts-- >= 0) {\n // Check abort before attempt.\n if (signal?.aborted) {\n return undefined\n }\n\n try {\n // eslint-disable-next-line no-await-in-loop\n return await callbackFn(...(args || []), { signal })\n } catch (e) {\n if (error === UNDEFINED_TOKEN) {\n error = e\n }\n if (attempts < 0) {\n break\n }\n let waitTime = delay\n if (jitter) {\n // Add randomness: Pick a value between 0 and `delay`.\n waitTime += Math.floor(Math.random() * delay)\n }\n // Clamp wait time to max delay.\n waitTime = Math.min(waitTime, maxDelayMs as number)\n if (typeof onRetry === 'function') {\n try {\n const result = onRetry((retries as number) - attempts, e, waitTime)\n if (result === false && onRetryCancelOnFalse) {\n break\n }\n // If onRetry returns a number, use it as the custom delay.\n if (typeof result === 'number' && result >= 0) {\n waitTime = Math.min(result, maxDelayMs as number)\n }\n } catch (e) {\n if (onRetryRethrow) {\n throw e\n }\n }\n }\n\n try {\n // eslint-disable-next-line no-await-in-loop\n await timers.setTimeout(waitTime, undefined, { signal })\n } catch {\n // setTimeout was aborted.\n return undefined\n }\n\n // Check abort again after delay.\n if (signal?.aborted) {\n return undefined\n }\n\n // Exponentially increase the delay for the next attempt, capping at maxDelayMs.\n delay = Math.min(delay * (backoffFactor as number), maxDelayMs as number)\n }\n }\n if (error !== UNDEFINED_TOKEN) {\n throw error\n }\n return undefined\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["i", "e"]
7
7
  }