@handy-common-utils/promise-utils 1.4.1 → 1.6.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.
package/README.md CHANGED
@@ -1,7 +1,18 @@
1
1
  # @handy-common-utils/promise-utils
2
2
 
3
- These Promise related utilities have 100% test coverage. The package is tiny because there is no dependency on any other package.
4
- Functions provided are `repeat`, `withRetry`, `inParallel`, `delayedResolve`, `delayedReject`, `timeoutResolve`, `timeoutReject`, `promiseState`, `synchronized`, etc.
3
+ These Promise-related utilities boast 100% test coverage, ensuring robust reliability.
4
+ The package, free of external dependencies, offers essential functions such as:
5
+
6
+ - `repeat`: Executes an operation repeatedly, very useful to collect all results through pagination.
7
+ - `withRetry`: Retries an operation until a specified condition is met.
8
+ - `withConcurrency`: Executes multiple operations with specified level of concurrency, and abort remaining operations when an error happens.
9
+ - `inParallel`: Executes multiple operations with specified level of concurrency, all operations are guaranteed to be executed regardless of any possible error.
10
+ - `delayedResolve`: Creates a Promise that resolves after a specified delay.
11
+ - `delayedReject`: Creates a Promise that rejects after a specified delay.
12
+ - `timeoutResolve`: Applies a timeout to a Promise and resolves with a specified result if the timeout occurs.
13
+ - `timeoutReject`: Applies a timeout to a Promise and rejects with a specified error/reason if the timeout occurs.
14
+ - `promiseState`: Retrieves the state of a Promise.
15
+ - `synchronized`: Provides mutual exclusion for concurrent operations using a lock mechanism, similar to `synchronized` in Java.
5
16
 
6
17
  [![Version](https://img.shields.io/npm/v/@handy-common-utils/promise-utils.svg)](https://npmjs.org/package/@handy-common-utils/promise-utils)
7
18
  [![Downloads/week](https://img.shields.io/npm/dw/@handy-common-utils/promise-utils.svg)](https://npmjs.org/package/@handy-common-utils/promise-utils)
@@ -59,7 +70,6 @@ const result2 = await withRetry(() => doSomething(), Array.from({length: 10}, (_
59
70
  const result3 = await withRetry(() => doSomething(), attempt => attempt <= 8 ? 1000 * Math.min(EXPONENTIAL_SEQUENCE[attempt - 1], 10) : undefined, err => err.statusCode === 429);
60
71
  statusCode === 429);
61
72
 
62
- // inParallel(...)
63
73
  // Capture errors in the returned array
64
74
  const attributesAndPossibleErrors = await PromiseUtils.inParallel(5, topicArns, async (topicArn) => {
65
75
  const topicAttributes = (await sns.getTopicAttributes({ TopicArn: topicArn }).promise()).Attributes!;
@@ -69,7 +79,7 @@ const attributesAndPossibleErrors = await PromiseUtils.inParallel(5, topicArns,
69
79
  // Abort on the first error
70
80
  let results: Array<JobResult>;
71
81
  try {
72
- results = await PromiseUtils.inParallel(100, jobs, async (job) => processor.process(job), { abortOnError: true });
82
+ results = await PromiseUtils.withConcurrency(100, jobs, async (job) => processor.process(job));
73
83
  } catch (error) {
74
84
  // handle the error
75
85
  }
@@ -135,7 +145,7 @@ PromiseUtils.withRetry(() => doSomething(), FIBONACCI_SEQUENCE.slice(0, 5).map(n
135
145
 
136
146
  #### delayedReject
137
147
 
138
- ▸ **delayedReject**<`T`, `R`\>(`ms`, `reason`): `Promise`<`T`\>
148
+ ▸ **delayedReject**\<`T`, `R`\>(`ms`, `reason`): `Promise`\<`T`\>
139
149
 
140
150
  See [delayedReject](#delayedreject) for full documentation.
141
151
 
@@ -151,17 +161,17 @@ See [delayedReject](#delayedreject) for full documentation.
151
161
  | Name | Type |
152
162
  | :------ | :------ |
153
163
  | `ms` | `number` |
154
- | `reason` | `R` \| `PromiseLike`<`R`\> \| () => `R` \| `PromiseLike`<`R`\> |
164
+ | `reason` | `R` \| `PromiseLike`\<`R`\> \| () => `R` \| `PromiseLike`\<`R`\> |
155
165
 
156
166
  ##### Returns
157
167
 
158
- `Promise`<`T`\>
168
+ `Promise`\<`T`\>
159
169
 
160
170
  ___
161
171
 
162
172
  #### delayedResolve
163
173
 
164
- ▸ **delayedResolve**<`T`\>(`ms`, `result?`): `Promise`<`T`\>
174
+ ▸ **delayedResolve**\<`T`\>(`ms`, `result?`): `Promise`\<`T`\>
165
175
 
166
176
  See [delayedResolve](#delayedresolve) for full documentation.
167
177
 
@@ -176,17 +186,17 @@ See [delayedResolve](#delayedresolve) for full documentation.
176
186
  | Name | Type |
177
187
  | :------ | :------ |
178
188
  | `ms` | `number` |
179
- | `result?` | `T` \| `PromiseLike`<`T`\> \| () => `T` \| `PromiseLike`<`T`\> |
189
+ | `result?` | `T` \| `PromiseLike`\<`T`\> \| () => `T` \| `PromiseLike`\<`T`\> |
180
190
 
181
191
  ##### Returns
182
192
 
183
- `Promise`<`T`\>
193
+ `Promise`\<`T`\>
184
194
 
185
195
  ___
186
196
 
187
197
  #### inParallel
188
198
 
189
- ▸ **inParallel**<`Data`, `Result`, `TError`\>(`parallelism`, `jobs`, `operation`, `options?`): `Promise`<(`Result` \| `TError`)[]\>
199
+ ▸ **inParallel**\<`Data`, `Result`, `TError`\>(`parallelism`, `jobs`, `operation`, `options?`): `Promise`\<(`Result` \| `TError`)[]\>
190
200
 
191
201
  See [inParallel](#inparallel) for full documentation.
192
202
 
@@ -203,20 +213,20 @@ See [inParallel](#inparallel) for full documentation.
203
213
  | Name | Type |
204
214
  | :------ | :------ |
205
215
  | `parallelism` | `number` |
206
- | `jobs` | `Iterable`<`Data`\> |
207
- | `operation` | (`job`: `Data`, `index`: `number`) => `Promise`<`Result`\> |
216
+ | `jobs` | `Iterable`\<`Data`\> |
217
+ | `operation` | (`job`: `Data`, `index`: `number`) => `Promise`\<`Result`\> |
208
218
  | `options?` | `Object` |
209
219
  | `options.abortOnError` | `boolean` |
210
220
 
211
221
  ##### Returns
212
222
 
213
- `Promise`<(`Result` \| `TError`)[]\>
223
+ `Promise`\<(`Result` \| `TError`)[]\>
214
224
 
215
225
  ___
216
226
 
217
227
  #### promiseState
218
228
 
219
- ▸ **promiseState**(`p`): `Promise`<[`PromiseState`](#enumspromisestatemd)\>
229
+ ▸ **promiseState**(`p`): `Promise`\<[`PromiseState`](#enumspromisestatemd)\>
220
230
 
221
231
  See [promiseState](#promisestate) for full documentation.
222
232
 
@@ -224,17 +234,17 @@ See [promiseState](#promisestate) for full documentation.
224
234
 
225
235
  | Name | Type |
226
236
  | :------ | :------ |
227
- | `p` | `Promise`<`any`\> |
237
+ | `p` | `Promise`\<`any`\> |
228
238
 
229
239
  ##### Returns
230
240
 
231
- `Promise`<[`PromiseState`](#enumspromisestatemd)\>
241
+ `Promise`\<[`PromiseState`](#enumspromisestatemd)\>
232
242
 
233
243
  ___
234
244
 
235
245
  #### repeat
236
246
 
237
- ▸ **repeat**<`Result`, `Param`, `Collection`\>(`operation`, `nextParameter`, `collect`, `initialCollection`, `initialParameter?`): `Promise`<`Collection`\>
247
+ ▸ **repeat**\<`Result`, `Param`, `Collection`\>(`operation`, `nextParameter`, `collect`, `initialCollection`, `initialParameter?`): `Promise`\<`Collection`\>
238
248
 
239
249
  See [repeat](#repeat) for full documentation.
240
250
 
@@ -250,21 +260,21 @@ See [repeat](#repeat) for full documentation.
250
260
 
251
261
  | Name | Type |
252
262
  | :------ | :------ |
253
- | `operation` | (`parameter`: `Partial`<`Param`\>) => `Promise`<`Result`\> |
254
- | `nextParameter` | (`response`: `Result`) => ``null`` \| `Partial`<`Param`\> \| `Promise`<`Partial`<`Param`\>\> |
263
+ | `operation` | (`parameter`: `Partial`\<`Param`\>) => `Promise`\<`Result`\> |
264
+ | `nextParameter` | (`response`: `Result`) => ``null`` \| `Partial`\<`Param`\> \| `Promise`\<`Partial`\<`Param`\>\> |
255
265
  | `collect` | (`collection`: `Collection`, `result`: `Result`) => `Collection` |
256
266
  | `initialCollection` | `Collection` |
257
- | `initialParameter` | `Partial`<`Param`\> |
267
+ | `initialParameter` | `Partial`\<`Param`\> |
258
268
 
259
269
  ##### Returns
260
270
 
261
- `Promise`<`Collection`\>
271
+ `Promise`\<`Collection`\>
262
272
 
263
273
  ___
264
274
 
265
275
  #### synchronised
266
276
 
267
- ▸ **synchronised**<`T`\>(`lock`, `operation`): `Promise`<`T`\>
277
+ ▸ **synchronised**\<`T`\>(`lock`, `operation`): `Promise`\<`T`\>
268
278
 
269
279
  See [synchronised](#synchronised) for full documentation.
270
280
 
@@ -278,18 +288,18 @@ See [synchronised](#synchronised) for full documentation.
278
288
 
279
289
  | Name | Type |
280
290
  | :------ | :------ |
281
- | `lock` | `unknown` |
282
- | `operation` | (`previousState`: `undefined` \| [`PromiseState`](#enumspromisestatemd), `previousSettledState`: `undefined` \| [`PromiseState`](#enumspromisestatemd), `previousResult`: `any`) => `Promise`<`T`\> |
291
+ | `lock` | `any` |
292
+ | `operation` | (`previousState`: `undefined` \| [`PromiseState`](#enumspromisestatemd), `previousSettledState`: `undefined` \| [`PromiseState`](#enumspromisestatemd), `previousResult`: `any`) => `Promise`\<`T`\> |
283
293
 
284
294
  ##### Returns
285
295
 
286
- `Promise`<`T`\>
296
+ `Promise`\<`T`\>
287
297
 
288
298
  ___
289
299
 
290
300
  #### synchronized
291
301
 
292
- ▸ **synchronized**<`T`\>(`lock`, `operation`): `Promise`<`T`\>
302
+ ▸ **synchronized**\<`T`\>(`lock`, `operation`): `Promise`\<`T`\>
293
303
 
294
304
  See [synchronized](#synchronized) for full documentation.
295
305
 
@@ -303,18 +313,18 @@ See [synchronized](#synchronized) for full documentation.
303
313
 
304
314
  | Name | Type |
305
315
  | :------ | :------ |
306
- | `lock` | `unknown` |
307
- | `operation` | (`previousState`: `undefined` \| [`PromiseState`](#enumspromisestatemd), `previousSettledState`: `undefined` \| [`PromiseState`](#enumspromisestatemd), `previousResult`: `any`) => `Promise`<`T`\> |
316
+ | `lock` | `any` |
317
+ | `operation` | (`previousState`: `undefined` \| [`PromiseState`](#enumspromisestatemd), `previousSettledState`: `undefined` \| [`PromiseState`](#enumspromisestatemd), `previousResult`: `any`) => `Promise`\<`T`\> |
308
318
 
309
319
  ##### Returns
310
320
 
311
- `Promise`<`T`\>
321
+ `Promise`\<`T`\>
312
322
 
313
323
  ___
314
324
 
315
325
  #### timeoutReject
316
326
 
317
- ▸ **timeoutReject**<`T`, `R`\>(`operation`, `ms`, `rejectReason`): `Promise`<`T`\>
327
+ ▸ **timeoutReject**\<`T`, `R`\>(`operation`, `ms`, `rejectReason`): `Promise`\<`T`\>
318
328
 
319
329
  See [timeoutReject](#timeoutreject) for full documentation.
320
330
 
@@ -329,19 +339,19 @@ See [timeoutReject](#timeoutreject) for full documentation.
329
339
 
330
340
  | Name | Type |
331
341
  | :------ | :------ |
332
- | `operation` | `Promise`<`T`\> \| () => `Promise`<`T`\> |
342
+ | `operation` | `Promise`\<`T`\> \| () => `Promise`\<`T`\> |
333
343
  | `ms` | `number` |
334
- | `rejectReason` | `R` \| `PromiseLike`<`R`\> \| () => `R` \| `PromiseLike`<`R`\> |
344
+ | `rejectReason` | `R` \| `PromiseLike`\<`R`\> \| () => `R` \| `PromiseLike`\<`R`\> |
335
345
 
336
346
  ##### Returns
337
347
 
338
- `Promise`<`T`\>
348
+ `Promise`\<`T`\>
339
349
 
340
350
  ___
341
351
 
342
352
  #### timeoutResolve
343
353
 
344
- ▸ **timeoutResolve**<`T`\>(`operation`, `ms`, `result?`): `Promise`<`T`\>
354
+ ▸ **timeoutResolve**\<`T`\>(`operation`, `ms`, `result?`): `Promise`\<`T`\>
345
355
 
346
356
  See [timeoutResolve](#timeoutresolve) for full documentation.
347
357
 
@@ -355,19 +365,46 @@ See [timeoutResolve](#timeoutresolve) for full documentation.
355
365
 
356
366
  | Name | Type |
357
367
  | :------ | :------ |
358
- | `operation` | `Promise`<`T`\> \| () => `Promise`<`T`\> |
368
+ | `operation` | `Promise`\<`T`\> \| () => `Promise`\<`T`\> |
359
369
  | `ms` | `number` |
360
- | `result?` | `T` \| `PromiseLike`<`T`\> \| () => `T` \| `PromiseLike`<`T`\> |
370
+ | `result?` | `T` \| `PromiseLike`\<`T`\> \| () => `T` \| `PromiseLike`\<`T`\> |
361
371
 
362
372
  ##### Returns
363
373
 
364
- `Promise`<`T`\>
374
+ `Promise`\<`T`\>
375
+
376
+ ___
377
+
378
+ #### withConcurrency
379
+
380
+ ▸ **withConcurrency**\<`Data`, `Result`\>(`concurrency`, `jobs`, `operation`): `Promise`\<`Result`[]\>
381
+
382
+ See [withConcurrency](#withconcurrency) for full documentation.
383
+
384
+ ##### Type parameters
385
+
386
+ | Name |
387
+ | :------ |
388
+ | `Data` |
389
+ | `Result` |
390
+
391
+ ##### Parameters
392
+
393
+ | Name | Type |
394
+ | :------ | :------ |
395
+ | `concurrency` | `number` |
396
+ | `jobs` | `Iterable`\<`Data`\> |
397
+ | `operation` | (`job`: `Data`, `index`: `number`) => `Promise`\<`Result`\> |
398
+
399
+ ##### Returns
400
+
401
+ `Promise`\<`Result`[]\>
365
402
 
366
403
  ___
367
404
 
368
405
  #### withRetry
369
406
 
370
- ▸ **withRetry**<`Result`, `TError`\>(`operation`, `backoff`, `shouldRetry?`): `Promise`<`Result`\>
407
+ ▸ **withRetry**\<`Result`, `TError`\>(`operation`, `backoff`, `shouldRetry?`): `Promise`\<`Result`\>
371
408
 
372
409
  See [withRetry](#withretry) for full documentation.
373
410
 
@@ -382,13 +419,13 @@ See [withRetry](#withretry) for full documentation.
382
419
 
383
420
  | Name | Type |
384
421
  | :------ | :------ |
385
- | `operation` | (`attempt`: `number`, `previousResult`: `undefined` \| `Result`, `previousError`: `undefined` \| `TError`) => `Promise`<`Result`\> |
422
+ | `operation` | (`attempt`: `number`, `previousResult`: `undefined` \| `Result`, `previousError`: `undefined` \| `TError`) => `Promise`\<`Result`\> |
386
423
  | `backoff` | `number`[] \| (`attempt`: `number`, `previousResult`: `undefined` \| `Result`, `previousError`: `undefined` \| `TError`) => `undefined` \| `number` |
387
424
  | `shouldRetry` | (`previousError`: `undefined` \| `TError`, `previousResult`: `undefined` \| `Result`, `attempt`: `number`) => `boolean` |
388
425
 
389
426
  ##### Returns
390
427
 
391
- `Promise`<`Result`\>
428
+ `Promise`\<`Result`\>
392
429
 
393
430
  ## Classes
394
431
 
@@ -407,9 +444,9 @@ See [withRetry](#withretry) for full documentation.
407
444
 
408
445
  ##### delayedReject
409
446
 
410
- ▸ `Static` **delayedReject**<`T`, `R`\>(`ms`, `reason`): `Promise`<`T`\>
447
+ ▸ `Static` **delayedReject**\<`T`, `R`\>(`ms`, `reason`): `Promise`\<`T`\>
411
448
 
412
- Create a Promise that rejects after number of milliseconds specified.
449
+ Creates a Promise that rejects after a specified number of milliseconds.
413
450
 
414
451
  ###### Type parameters
415
452
 
@@ -422,22 +459,22 @@ Create a Promise that rejects after number of milliseconds specified.
422
459
 
423
460
  | Name | Type | Description |
424
461
  | :------ | :------ | :------ |
425
- | `ms` | `number` | number of milliseconds after which the created Promise would reject |
426
- | `reason` | `R` \| `PromiseLike`<`R`\> \| () => `R` \| `PromiseLike`<`R`\> | the reason of the rejection for the Promise, or a function that supplies the reason. If the reason ends up to be a rejected Promise, then the outcome (could be fulfilled or rejected) of it will be the reject reason of the Promise returned. |
462
+ | `ms` | `number` | The number of milliseconds after which the created Promise will reject. |
463
+ | `reason` | `R` \| `PromiseLike`\<`R`\> \| () => `R` \| `PromiseLike`\<`R`\> | The reason for the rejection, or a function that supplies the reason. If the reason is a rejected Promise, the outcome of it will be the rejection reason of the returned Promise. |
427
464
 
428
465
  ###### Returns
429
466
 
430
- `Promise`<`T`\>
467
+ `Promise`\<`T`\>
431
468
 
432
- the new Promise created
469
+ A new Promise that rejects with the specified reason after the specified delay.
433
470
 
434
471
  ___
435
472
 
436
473
  ##### delayedResolve
437
474
 
438
- ▸ `Static` **delayedResolve**<`T`\>(`ms`, `result?`): `Promise`<`T`\>
475
+ ▸ `Static` **delayedResolve**\<`T`\>(`ms`, `result?`): `Promise`\<`T`\>
439
476
 
440
- Create a Promise that resolves after number of milliseconds specified
477
+ Creates a Promise that resolves after a specified number of milliseconds.
441
478
 
442
479
  ###### Type parameters
443
480
 
@@ -449,61 +486,62 @@ Create a Promise that resolves after number of milliseconds specified
449
486
 
450
487
  | Name | Type | Description |
451
488
  | :------ | :------ | :------ |
452
- | `ms` | `number` | number of milliseconds after which the created Promise would resolve |
453
- | `result?` | `T` \| `PromiseLike`<`T`\> \| () => `T` \| `PromiseLike`<`T`\> | the result to be resolved for the Promise, or a function that supplies the result. |
489
+ | `ms` | `number` | The number of milliseconds after which the created Promise will resolve. |
490
+ | `result?` | `T` \| `PromiseLike`\<`T`\> \| () => `T` \| `PromiseLike`\<`T`\> | The result to be resolved by the Promise, or a function that supplies the result. |
454
491
 
455
492
  ###### Returns
456
493
 
457
- `Promise`<`T`\>
494
+ `Promise`\<`T`\>
458
495
 
459
- the new Promise created
496
+ A new Promise that resolves with the specified result after the specified delay.
460
497
 
461
498
  ___
462
499
 
463
500
  ##### inParallel
464
501
 
465
- ▸ `Static` **inParallel**<`Data`, `Result`, `TError`\>(`parallelism`, `jobs`, `operation`, `options?`): `Promise`<(`Result` \| `TError`)[]\>
502
+ ▸ `Static` **inParallel**\<`Data`, `Result`, `TError`\>(`parallelism`, `jobs`, `operation`, `options?`): `Promise`\<(`Result` \| `TError`)[]\>
466
503
 
467
- Run multiple jobs/operations in parallel.
504
+ Executes multiple jobs/operations in parallel. By default, all operations are executed regardless of any failures.
505
+ In most cases, using [withConcurrency](#withconcurrency) might be more convenient.
468
506
 
469
- By default this function does not throw / reject with error when any of the job/operation fails.
470
- Operation errors are returned together with operation results in the same returned array.
471
- That also means this function only returns when all the jobs/operations settle (either resolve or reject).
507
+ By default, this function does not throw or reject an error when any job/operation fails.
508
+ Errors from operations are returned alongside results in the returned array.
509
+ This function only resolves when all jobs/operations are settled (either resolved or rejected).
472
510
 
473
- However, if options.abortOnError is true, this function throws / rejects with error when any of the job/operation fails.
474
- That also means, some of the jobs/operations may not get the chance to be executed if one of them fails.
511
+ If `options.abortOnError` is set to true, this function throws (or rejects with) an error immediately when any job/operation fails.
512
+ In this mode, some jobs/operations may not be executed if one fails.
475
513
 
476
514
  ###### Type parameters
477
515
 
478
516
  | Name | Type | Description |
479
517
  | :------ | :------ | :------ |
480
- | `Data` | `Data` | Type of the job data, usually it would be an Array |
481
- | `Result` | `Result` | Type of the return value of the operation function |
482
- | `TError` | `Result` | - |
518
+ | `Data` | `Data` | The type of the job data, typically an Array. |
519
+ | `Result` | `Result` | The type of the return value from the operation function. |
520
+ | `TError` | `Result` | The type for the error that could be thrown from the operation function, defaults to `Result`. |
483
521
 
484
522
  ###### Parameters
485
523
 
486
524
  | Name | Type | Description |
487
525
  | :------ | :------ | :------ |
488
- | `parallelism` | `number` | how many jobs/operations can be running at the same time |
489
- | `jobs` | `Iterable`<`Data`\> | job data which will be the input to operation function. This function is safe when there are infinite unknown number of elements in the job data. |
490
- | `operation` | (`job`: `Data`, `index`: `number`) => `Promise`<`Result`\> | the function that turns job data into result asynchronously |
491
- | `options?` | `Object` | Options for controlling the behavior of this function. |
492
- | `options.abortOnError` | `boolean` | - |
526
+ | `parallelism` | `number` | The number of jobs/operations to run concurrently. |
527
+ | `jobs` | `Iterable`\<`Data`\> | The job data to be processed. This function can safely handle an infinite or unknown number of elements. |
528
+ | `operation` | (`job`: `Data`, `index`: `number`) => `Promise`\<`Result`\> | The function that processes job data asynchronously. |
529
+ | `options?` | `Object` | Options to control the function's behavior. |
530
+ | `options.abortOnError` | `boolean` | If true, the function aborts and throws an error on the first failed operation. |
493
531
 
494
532
  ###### Returns
495
533
 
496
- `Promise`<(`Result` \| `TError`)[]\>
534
+ `Promise`\<(`Result` \| `TError`)[]\>
497
535
 
498
- Promise of void if the operation function does not return a value,
499
- or promise of an array containing outcomes from the operation function.
500
- In the returned array containing outcomes, each element is either the fulfilled result, or the rejected error/reason.
536
+ A promise that resolves to an array containing the results of the operations.
537
+ Each element is either a fulfilled result or a rejected error/reason.
538
+ The results or errors in the returned array are in the same order as the corresponding elements in the jobs array.
501
539
 
502
540
  **`Example`**
503
541
 
504
542
  ```ts
505
543
  // Capture errors in the returned array
506
- const attributesAndPossibleErrors = await PromiseUtils.inParallel(5, topicArns, async (topicArn) => {
544
+ const attributesAndPossibleErrors: Array<JobResult|JobError> = await PromiseUtils.inParallel(5, topicArns, async (topicArn) => {
507
545
  const topicAttributes = (await sns.getTopicAttributes({ TopicArn: topicArn }).promise()).Attributes!;
508
546
  return topicAttributes;
509
547
  });
@@ -521,55 +559,55 @@ ___
521
559
 
522
560
  ##### promiseState
523
561
 
524
- ▸ `Static` **promiseState**(`p`): `Promise`<[`PromiseState`](#enumspromisestatemd)\>
562
+ ▸ `Static` **promiseState**(`p`): `Promise`\<[`PromiseState`](#enumspromisestatemd)\>
525
563
 
526
- Get the state of the Promise.
527
- Please note that the returned value is a Promise, although it resolves immediately.
564
+ Retrieves the state of the specified Promise.
565
+ Note: The returned value is a Promise that resolves immediately.
528
566
 
529
567
  ###### Parameters
530
568
 
531
569
  | Name | Type | Description |
532
570
  | :------ | :------ | :------ |
533
- | `p` | `Promise`<`any`\> | the Promise for which we would like to know its state |
571
+ | `p` | `Promise`\<`any`\> | The Promise whose state is to be determined. |
534
572
 
535
573
  ###### Returns
536
574
 
537
- `Promise`<[`PromiseState`](#enumspromisestatemd)\>
575
+ `Promise`\<[`PromiseState`](#enumspromisestatemd)\>
538
576
 
539
- A Promise that resolves immediately containing the state of the input Promise
577
+ A Promise that resolves immediately with the state of the input Promise.
540
578
 
541
579
  ___
542
580
 
543
581
  ##### repeat
544
582
 
545
- ▸ `Static` **repeat**<`Result`, `Param`, `Collection`\>(`operation`, `nextParameter`, `collect`, `initialCollection`, `initialParameter?`): `Promise`<`Collection`\>
583
+ ▸ `Static` **repeat**\<`Result`, `Param`, `Collection`\>(`operation`, `nextParameter`, `collect`, `initialCollection`, `initialParameter?`): `Promise`\<`Collection`\>
546
584
 
547
- Do an operation repeatedly and collect all the results.
548
- This function is useful for client side pagination.
585
+ Executes an operation repeatedly and collects all the results.
586
+ This function is very useful for many scenarios, such like client-side pagination.
549
587
 
550
588
  ###### Type parameters
551
589
 
552
590
  | Name | Description |
553
591
  | :------ | :------ |
554
- | `Result` | type of the operation result |
555
- | `Param` | type of the input to the operation, normally the input is a paging parameter |
556
- | `Collection` | type of the returned value of this function |
592
+ | `Result` | The type of the operation result. |
593
+ | `Param` | The type of the input to the operation, typically a paging parameter. |
594
+ | `Collection` | The type of the collection returned by this function. |
557
595
 
558
596
  ###### Parameters
559
597
 
560
598
  | Name | Type | Description |
561
599
  | :------ | :------ | :------ |
562
- | `operation` | (`parameter`: `Partial`<`Param`\>) => `Promise`<`Result`\> | a function that takes paging parameter as input and outputs a result, normally the operation supports paging |
563
- | `nextParameter` | (`response`: `Result`) => ``null`` \| `Partial`<`Param`\> \| `Promise`<`Partial`<`Param`\>\> | The function for calculating next parameter from the operation result. Normally the parameter controls paging, This function should return null when next invocation of the operation function is not desired. If next invocation is desired, the return value of this function can be a Promise or not a Promise. |
564
- | `collect` | (`collection`: `Collection`, `result`: `Result`) => `Collection` | the function for merging operation result into the collection |
565
- | `initialCollection` | `Collection` | initial collection which would be the first argument passed into the first invocation of the collect function |
566
- | `initialParameter` | `Partial`<`Param`\> | the parameter for the first operation |
600
+ | `operation` | (`parameter`: `Partial`\<`Param`\>) => `Promise`\<`Result`\> | A function that takes a parameter as input and returns a result. Typically, the parameter has optional fields to control paging. |
601
+ | `nextParameter` | (`response`: `Result`) => ``null`` \| `Partial`\<`Param`\> \| `Promise`\<`Partial`\<`Param`\>\> | A function for calculating the next parameter from the operation result. Normally, this parameter controls paging. This function should return null when no further invocation of the operation function is desired. If further invocation is desired, the return value of this function can be a Promise or a non-Promise value. |
602
+ | `collect` | (`collection`: `Collection`, `result`: `Result`) => `Collection` | A function for merging the operation result into the collection. |
603
+ | `initialCollection` | `Collection` | The initial collection, which will be the first argument passed to the first invocation of the collect function. |
604
+ | `initialParameter` | `Partial`\<`Param`\> | The parameter for the first operation. |
567
605
 
568
606
  ###### Returns
569
607
 
570
- `Promise`<`Collection`\>
608
+ `Promise`\<`Collection`\>
571
609
 
572
- Promise of collection of all the results returned by the operation function
610
+ A promise that resolves to a collection of all the results returned by the operation function.
573
611
 
574
612
  **`Example`**
575
613
 
@@ -586,7 +624,7 @@ ___
586
624
 
587
625
  ##### synchronised
588
626
 
589
- ▸ `Static` **synchronised**<`T`\>(`lock`, `operation`): `Promise`<`T`\>
627
+ ▸ `Static` **synchronised**\<`T`\>(`lock`, `operation`): `Promise`\<`T`\>
590
628
 
591
629
  This is just another spelling of [synchronized](#synchronized).
592
630
 
@@ -600,26 +638,27 @@ This is just another spelling of [synchronized](#synchronized).
600
638
 
601
639
  | Name | Type | Description |
602
640
  | :------ | :------ | :------ |
603
- | `lock` | `unknown` | the object (could be a string, a number, or `this` in a class) that is used to apply the lock |
604
- | `operation` | (`previousState`: `undefined` \| [`PromiseState`](#enumspromisestatemd), `previousSettledState`: `undefined` \| [`PromiseState`](#enumspromisestatemd), `previousResult`: `any`) => `Promise`<`T`\> | function for doing the computation and returning a Promise |
641
+ | `lock` | `any` | The object (such as a string, a number, or `this` in a class) used to identify the lock. |
642
+ | `operation` | (`previousState`: `undefined` \| [`PromiseState`](#enumspromisestatemd), `previousSettledState`: `undefined` \| [`PromiseState`](#enumspromisestatemd), `previousResult`: `any`) => `Promise`\<`T`\> | The function that performs the computation and returns a Promise. |
605
643
 
606
644
  ###### Returns
607
645
 
608
- `Promise`<`T`\>
646
+ `Promise`\<`T`\>
609
647
 
610
- the result of the operation function
648
+ The result of the operation function.
611
649
 
612
650
  ___
613
651
 
614
652
  ##### synchronized
615
653
 
616
- ▸ `Static` **synchronized**<`T`\>(`lock`, `operation`): `Promise`<`T`\>
654
+ ▸ `Static` **synchronized**\<`T`\>(`lock`, `operation`): `Promise`\<`T`\>
617
655
 
618
- Equivalent of `synchronized` in Java.
619
- In any situation there's no concurrent execution of any operation function associated with the same lock.
620
- The operation function has access to the state (when `synchronized` is called), settledState (when the operation function is called),
621
- and result (could be the fulfilled result or the rejected reason) of the previous operation.
622
- In case there is no previous invocation, state, settledState and result would all be undefined.
656
+ Provides mutual exclusion similar to `synchronized` in Java.
657
+ Ensures no concurrent execution of any operation function associated with the same lock.
658
+ The operation function has access to the state (when `synchronized` is called),
659
+ settledState (when the operation function is called),
660
+ and result (either the fulfilled result or the rejected reason) of the previous operation.
661
+ If there is no previous invocation, state, settledState, and result will all be undefined.
623
662
 
624
663
  ###### Type parameters
625
664
 
@@ -631,26 +670,26 @@ In case there is no previous invocation, state, settledState and result would al
631
670
 
632
671
  | Name | Type | Description |
633
672
  | :------ | :------ | :------ |
634
- | `lock` | `unknown` | the object (could be a string, a number, or `this` in a class) that is used to apply the lock |
635
- | `operation` | (`previousState`: `undefined` \| [`PromiseState`](#enumspromisestatemd), `previousSettledState`: `undefined` \| [`PromiseState`](#enumspromisestatemd), `previousResult`: `any`) => `Promise`<`T`\> | function for doing the computation and returning a Promise |
673
+ | `lock` | `any` | The object (such as a string, a number, or `this` in a class) used to identify the lock. |
674
+ | `operation` | (`previousState`: `undefined` \| [`PromiseState`](#enumspromisestatemd), `previousSettledState`: `undefined` \| [`PromiseState`](#enumspromisestatemd), `previousResult`: `any`) => `Promise`\<`T`\> | The function that performs the computation and returns a Promise. |
636
675
 
637
676
  ###### Returns
638
677
 
639
- `Promise`<`T`\>
678
+ `Promise`\<`T`\>
640
679
 
641
- the result of the operation function
680
+ The result of the operation function.
642
681
 
643
682
  ___
644
683
 
645
684
  ##### timeoutReject
646
685
 
647
- ▸ `Static` **timeoutReject**<`T`, `R`\>(`operation`, `ms`, `rejectReason`): `Promise`<`T`\>
686
+ ▸ `Static` **timeoutReject**\<`T`, `R`\>(`operation`, `ms`, `rejectReason`): `Promise`\<`T`\>
648
687
 
649
688
  Applies a timeout to a Promise or a function that returns a Promise.
650
- If the timeout occurs, rejects with the specified reason.
651
- If the timeout doesn't occur, the resolved result or rejection reason of the original Promise will be the outcome of the Promise returned from this function.
652
- If the 'reason' parameter is a function and timeout doesn't occur, the function won't be called.
653
- The rejection of the 'operation' parameter is not handled by this function, you may want to handle it outside of this function to avoid warnings like "(node:4330) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously".
689
+ If the timeout occurs, the returned Promise rejects with the specified reason.
690
+ If the timeout does not occur, the returned Promise resolves or rejects based on the outcome of the original Promise.
691
+ If the `rejectReason` parameter is a function and the timeout does not occur, the function will not be called.
692
+ Note: The rejection of the `operation` parameter is not handled by this function. You may want to handle it outside this function to avoid warnings like "(node:4330) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously."
654
693
 
655
694
  ###### Type parameters
656
695
 
@@ -663,13 +702,13 @@ The rejection of the 'operation' parameter is not handled by this function, you
663
702
 
664
703
  | Name | Type | Description |
665
704
  | :------ | :------ | :------ |
666
- | `operation` | `Promise`<`T`\> \| () => `Promise`<`T`\> | The original Promise or a function that returns a Promise for which the timeout will be applied. |
705
+ | `operation` | `Promise`\<`T`\> \| () => `Promise`\<`T`\> | The original Promise or a function that returns a Promise to which the timeout will be applied. |
667
706
  | `ms` | `number` | The number of milliseconds for the timeout. |
668
- | `rejectReason` | `R` \| `PromiseLike`<`R`\> \| () => `R` \| `PromiseLike`<`R`\> | The reason to reject with if the timeout occurs, or a function that supplies the reason. |
707
+ | `rejectReason` | `R` \| `PromiseLike`\<`R`\> \| () => `R` \| `PromiseLike`\<`R`\> | The reason to reject with if the timeout occurs, or a function that supplies the reason. |
669
708
 
670
709
  ###### Returns
671
710
 
672
- `Promise`<`T`\>
711
+ `Promise`\<`T`\>
673
712
 
674
713
  A new Promise that rejects with the specified reason if the timeout occurs.
675
714
 
@@ -677,13 +716,14 @@ ___
677
716
 
678
717
  ##### timeoutResolve
679
718
 
680
- ▸ `Static` **timeoutResolve**<`T`\>(`operation`, `ms`, `result?`): `Promise`<`T`\>
719
+ ▸ `Static` **timeoutResolve**\<`T`\>(`operation`, `ms`, `result?`): `Promise`\<`T`\>
681
720
 
682
721
  Applies a timeout to a Promise or a function that returns a Promise.
683
- If the timeout occurs, resolves to the specified result.
684
- If the timeout doesn't occur, the resolved result or rejection reason of the original Promise will be the outcome of the Promise returned from this function.
685
- If the 'result' parameter is a function and timeout doesn't occur, the function won't be called.
686
- The rejection of the 'operation' parameter is not handled by this function, you may want to handle it outside of this function to avoid warnings like "(node:4330) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously".
722
+ If the timeout occurs, the returned Promise resolves to the specified result.
723
+ If the timeout does not occur, the returned Promise resolves or rejects based on the outcome of the original Promise.
724
+ If the `result` parameter is a function and the timeout does not occur, the function will not be called.
725
+ Note: The rejection of the `operation` parameter is not handled by this function.
726
+ You may want to handle it outside this function to avoid warnings like "(node:4330) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously."
687
727
 
688
728
  ###### Type parameters
689
729
 
@@ -695,44 +735,88 @@ The rejection of the 'operation' parameter is not handled by this function, you
695
735
 
696
736
  | Name | Type | Description |
697
737
  | :------ | :------ | :------ |
698
- | `operation` | `Promise`<`T`\> \| () => `Promise`<`T`\> | The original Promise or a function that returns a Promise for which the timeout will be applied. |
738
+ | `operation` | `Promise`\<`T`\> \| () => `Promise`\<`T`\> | The original Promise or a function that returns a Promise to which the timeout will be applied. |
699
739
  | `ms` | `number` | The number of milliseconds for the timeout. |
700
- | `result?` | `T` \| `PromiseLike`<`T`\> \| () => `T` \| `PromiseLike`<`T`\> | The result to be resolved with if the timeout occurs, or a function that supplies the result. |
740
+ | `result?` | `T` \| `PromiseLike`\<`T`\> \| () => `T` \| `PromiseLike`\<`T`\> | The result to resolve with if the timeout occurs, or a function that supplies the result. |
701
741
 
702
742
  ###### Returns
703
743
 
704
- `Promise`<`T`\>
744
+ `Promise`\<`T`\>
705
745
 
706
746
  A new Promise that resolves to the specified result if the timeout occurs.
707
747
 
708
748
  ___
709
749
 
750
+ ##### withConcurrency
751
+
752
+ ▸ `Static` **withConcurrency**\<`Data`, `Result`\>(`concurrency`, `jobs`, `operation`): `Promise`\<`Result`[]\>
753
+
754
+ Executes multiple jobs/operations with a specified level of concurrency.
755
+
756
+ Unlike `inParallel(...)`, this function may throw or reject an error when a job/operation fails.
757
+ When an error is re-thrown, remaining operations will not be executed.
758
+ If you want all the operations to always be executed, use [inParallel](#inparallel) instead.
759
+
760
+ ###### Type parameters
761
+
762
+ | Name | Description |
763
+ | :------ | :------ |
764
+ | `Data` | The type of the job data, typically an Array. |
765
+ | `Result` | The type of the return value from the operation function. |
766
+
767
+ ###### Parameters
768
+
769
+ | Name | Type | Description |
770
+ | :------ | :------ | :------ |
771
+ | `concurrency` | `number` | The number of jobs/operations to run concurrently. |
772
+ | `jobs` | `Iterable`\<`Data`\> | The job data to be processed. This function can handle an infinite or unknown number of elements safely. |
773
+ | `operation` | (`job`: `Data`, `index`: `number`) => `Promise`\<`Result`\> | The function that processes job data asynchronously. |
774
+
775
+ ###### Returns
776
+
777
+ `Promise`\<`Result`[]\>
778
+
779
+ A promise that resolves to an array containing the results from the operation function.
780
+ The results in the returned array are in the same order as the corresponding elements in the jobs array.
781
+
782
+ **`Example`**
783
+
784
+ ```ts
785
+ // At any time, there would be no more than 5 concurrency API calls. Error would be re-thrown immediately when it occurs.
786
+ const attributes = await PromiseUtils.withConcurrency(5, topicArns, async (topicArn) => {
787
+ const topicAttributes = (await sns.getTopicAttributes({ TopicArn: topicArn }).promise()).Attributes!;
788
+ return topicAttributes;
789
+ });
790
+ ```
791
+
792
+ ___
793
+
710
794
  ##### withRetry
711
795
 
712
- ▸ `Static` **withRetry**<`Result`, `TError`\>(`operation`, `backoff`, `shouldRetry?`): `Promise`<`Result`\>
796
+ ▸ `Static` **withRetry**\<`Result`, `TError`\>(`operation`, `backoff`, `shouldRetry?`): `Promise`\<`Result`\>
713
797
 
714
- Do an operation repeatedly until a criteria is met.
798
+ Repeatedly performs an operation until a specified criteria is met.
715
799
 
716
800
  ###### Type parameters
717
801
 
718
802
  | Name | Type | Description |
719
803
  | :------ | :------ | :------ |
720
- | `Result` | `Result` | type of the operation result |
721
- | `TError` | `any` | type of the possible error that could be generated by the operation |
804
+ | `Result` | `Result` | Type of the operation result. |
805
+ | `TError` | `any` | Type of the possible error that could be generated by the operation. |
722
806
 
723
807
  ###### Parameters
724
808
 
725
809
  | Name | Type | Description |
726
810
  | :------ | :------ | :------ |
727
- | `operation` | (`attempt`: `number`, `previousResult`: `undefined` \| `Result`, `previousError`: `undefined` \| `TError`) => `Promise`<`Result`\> | a function that outputs a Promise result, normally the operation does not use its arguments |
728
- | `backoff` | `number`[] \| (`attempt`: `number`, `previousResult`: `undefined` \| `Result`, `previousError`: `undefined` \| `TError`) => `undefined` \| `number` | Array of retry backoff periods (unit: milliseconds) or function for calculating them. If retry is desired, before making next call to the operation the desired backoff period would be waited. If the array runs out of elements or the function returns `undefined` or either the array or the function returns a negative number, there would be no further call to the operation. The `attempt` argument passed into backoff function starts from 1 because the function is called right after the first attempt and before the first retry. |
729
- | `shouldRetry` | (`previousError`: `undefined` \| `TError`, `previousResult`: `undefined` \| `Result`, `attempt`: `number`) => `boolean` | Predicate function for deciding whether another call to the operation should happen. If this argument is not defined, retry would happen whenever the operation rejects with an error. `shouldRetry` would be evaluated before `backoff`. The `attempt` argument passed into shouldRetry function starts from 1. |
811
+ | `operation` | (`attempt`: `number`, `previousResult`: `undefined` \| `Result`, `previousError`: `undefined` \| `TError`) => `Promise`\<`Result`\> | A function that outputs a Promise result. Typically, the operation does not use its arguments. |
812
+ | `backoff` | `number`[] \| (`attempt`: `number`, `previousResult`: `undefined` \| `Result`, `previousError`: `undefined` \| `TError`) => `undefined` \| `number` | An array of retry backoff periods (in milliseconds) or a function for calculating them. If retry is desired, the specified backoff period is waited before the next call to the operation. If the array runs out of elements or the function returns `undefined` or a negative number, no further calls to the operation will be made. The `attempt` argument passed to the backoff function starts from 1, as it is called immediately after the first attempt and before the first retry. |
813
+ | `shouldRetry` | (`previousError`: `undefined` \| `TError`, `previousResult`: `undefined` \| `Result`, `attempt`: `number`) => `boolean` | A predicate function for deciding whether another call to the operation should occur. If this argument is not defined, a retry will occur whenever the operation rejects with an error. The `shouldRetry` function is evaluated before the `backoff`. The `attempt` argument passed to the shouldRetry function starts from 1. |
730
814
 
731
815
  ###### Returns
732
816
 
733
- `Promise`<`Result`\>
817
+ `Promise`\<`Result`\>
734
818
 
735
- Promise of the operation result potentially with retries already applied
819
+ A promise of the operation result, potentially with retries applied.
736
820
 
737
821
  **`Example`**
738
822