@handy-common-utils/promise-utils 1.2.3 → 1.2.6

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
@@ -51,11 +51,13 @@ You can either import and use the [PromiseUtils class](#classespromiseutilsmd) a
51
51
  or you can import its re-exported functions directly like below:
52
52
 
53
53
  ```javascript
54
- import { withRetry, inParallel } from '@handy-common-utils/promise-utils';
54
+ import { withRetry, inParallel, FIBONACCI_SEQUENCE, EXPONENTIAL_SEQUENCE } from '@handy-common-utils/promise-utils';
55
55
 
56
56
  // withRetry(...)
57
- const result = await PromiseUtils.withRetry(() => doSomething(), [100, 200, 300, 500, 800, 1000]);
58
- const result2 = await PromiseUtils.withRetry(() => doSomething(), PromiseUtils.FIBONACCI_SEQUENCE, err => err.statusCode === 429);
57
+ const result = await withRetry(() => doSomething(), [100, 200, 300, 500, 800, 1000]);
58
+ const result2 = await withRetry(() => doSomething(), Array.from({length: 10}, (_v, i) => Math.min(FIBONACCI_SEQUENCE[i], 10)), err => err.statusCode === 429);
59
+ const result3 = await withRetry(() => doSomething(), attempt => attempt <= 8 ? 1000 * Math.min(EXPONENTIAL_SEQUENCE[attempt - 1], 10) : undefined, err => err.statusCode === 429);
60
+ statusCode === 429);
59
61
 
60
62
  // inParallel(...)
61
63
  const topicArns = topics.map(topic => topic.TopicArn!);
@@ -90,9 +92,62 @@ await inParallel(5, topicArns, async topicArn => {
90
92
 
91
93
  #### Variables
92
94
 
95
+ - [EXPONENTIAL\_SEQUENCE](#exponential_sequence)
93
96
  - [FIBONACCI\_SEQUENCE](#fibonacci_sequence)
94
97
 
95
- ### Classes
98
+ #### Functions
99
+
100
+ - [delayedReject](#delayedreject)
101
+ - [delayedResolve](#delayedresolve)
102
+ - [inParallel](#inparallel)
103
+ - [promiseState](#promisestate)
104
+ - [repeat](#repeat)
105
+ - [synchronised](#synchronised)
106
+ - [synchronized](#synchronized)
107
+ - [timeoutReject](#timeoutreject)
108
+ - [timeoutResolve](#timeoutresolve)
109
+ - [withRetry](#withretry)
110
+
111
+ ### Variables
112
+
113
+ #### EXPONENTIAL\_SEQUENCE
114
+
115
+ • `Const` **EXPONENTIAL\_SEQUENCE**: `number`[]
116
+
117
+ Array of 25 exponential numbers starting from 1 up to 33554432.
118
+ It can be used to form your own backoff interval array.
119
+
120
+ **`example`**
121
+ ```javascript
122
+
123
+ // 1ms, 2ms, 4ms, 8ms, 16ms, 32ms
124
+ PromiseUtils.withRetry(() => doSomething(), EXPONENTIAL_SEQUENCE.slice(0, 5), err => err.statusCode === 429);
125
+ // 1s, 2s, 4s, 8s, 10s, 10s, 10s, 10s, 10s, 10s
126
+ PromiseUtils.withRetry(() => doSomething(), Array.from({length: 10}, (_v, i) => 1000 * Math.min(EXPONENTIAL_SEQUENCE[i], 10)), err => err.statusCode === 429);
127
+ // with +-10% randomness: 1s, 2s, 4s, 8s
128
+ PromiseUtils.withRetry(() => doSomething(), FIBONACCI_SEQUENCE.slice(0, 4).map(n => 1000 * n * (1 + (Math.random() - 0.5) / 5)), err => err.statusCode === 429);
129
+
130
+ ___
131
+
132
+ ```
133
+ #### FIBONACCI\_SEQUENCE
134
+
135
+ • `Const` **FIBONACCI\_SEQUENCE**: `number`[]
136
+
137
+ Array of 25 Fibonacci numbers starting from 1 up to 317811.
138
+ It can be used to form your own backoff interval array.
139
+
140
+ **`example`**
141
+ ```javascript
142
+
143
+ // 1ms, 2ms, 3ms, 5ms, 8ms, 13ms
144
+ PromiseUtils.withRetry(() => doSomething(), FIBONACCI_SEQUENCE.slice(0, 5), err => err.statusCode === 429);
145
+ // 1s, 2s, 3s, 4s, 8s, 10s, 10s, 10s, 10s, 10s
146
+ PromiseUtils.withRetry(() => doSomething(), Array.from({length: 10}, (_v, i) => 1000 * Math.min(FIBONACCI_SEQUENCE[i], 10)), err => err.statusCode === 429);
147
+ // with +-10% randomness: 1s, 2s, 3s, 5s, 8s, 13s
148
+ PromiseUtils.withRetry(() => doSomething(), FIBONACCI_SEQUENCE.slice(0, 5).map(n => 1000 * n * (1 + (Math.random() - 0.5) / 5)), err => err.statusCode === 429);
149
+
150
+ ```## Classes
96
151
 
97
152
 
98
153
  <a name="classespromiseutilsmd"></a>
@@ -426,7 +481,8 @@ Do an operation repeatedly until a criteria is met.
426
481
  ```javascript
427
482
 
428
483
  const result = await PromiseUtils.withRetry(() => doSomething(), [100, 200, 300, 500, 800, 1000]);
429
- const result2 = await PromiseUtils.withRetry(() => doSomething(), PromiseUtils.FIBONACCI_SEQUENCE, err => err.statusCode === 429);
484
+ const result2 = await PromiseUtils.withRetry(() => doSomething(), Array.from({length: 10}, (_v, i) => Math.min(FIBONACCI_SEQUENCE[i], 10), err => err.statusCode === 429);
485
+ const result3 = await PromiseUtils.withRetry(() => doSomething(), attempt => attempt <= 8 ? 1000 * Math.min(FIBONACCI_SEQUENCE[attempt - 1], 10) : undefined, err => err.statusCode === 429);
430
486
 
431
487
  ```
432
488
  ###### Type parameters
@@ -441,7 +497,7 @@ const result2 = await PromiseUtils.withRetry(() => doSomething(), PromiseUtils.F
441
497
  | Name | Type | Description |
442
498
  | :------ | :------ | :------ |
443
499
  | `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 |
444
- | `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 2 because only retries need to backoff, so the first retry is the second attempt. |
500
+ | `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. |
445
501
  | `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. |
446
502
 
447
503
  ###### Returns
@@ -459,7 +515,7 @@ Promise of the operation result potentially with retries already applied
459
515
 
460
516
  ### Enumeration: PromiseState
461
517
 
462
- The state of a Promise can only be on of: Pending, Fulfilled, and Rejected.
518
+ The state of a Promise can only be one of: Pending, Fulfilled, and Rejected.
463
519
 
464
520
  #### Table of contents
465
521
 
@@ -1,9 +1,29 @@
1
1
  /**
2
- * Array of Fibonacci numbers starting from 1 up to 317811.
2
+ * Array of 25 Fibonacci numbers starting from 1 up to 317811.
3
+ * It can be used to form your own backoff interval array.
4
+ * @example
5
+ * // 1ms, 2ms, 3ms, 5ms, 8ms, 13ms
6
+ * PromiseUtils.withRetry(() => doSomething(), FIBONACCI_SEQUENCE.slice(0, 5), err => err.statusCode === 429);
7
+ * // 1s, 2s, 3s, 4s, 8s, 10s, 10s, 10s, 10s, 10s
8
+ * PromiseUtils.withRetry(() => doSomething(), Array.from({length: 10}, (_v, i) => 1000 * Math.min(FIBONACCI_SEQUENCE[i], 10)), err => err.statusCode === 429);
9
+ * // with +-10% randomness: 1s, 2s, 3s, 5s, 8s, 13s
10
+ * PromiseUtils.withRetry(() => doSomething(), FIBONACCI_SEQUENCE.slice(0, 5).map(n => 1000 * n * (1 + (Math.random() - 0.5) / 5)), err => err.statusCode === 429);
3
11
  */
4
12
  export declare const FIBONACCI_SEQUENCE: number[];
5
13
  /**
6
- * The state of a Promise can only be on of: Pending, Fulfilled, and Rejected.
14
+ * Array of 25 exponential numbers starting from 1 up to 33554432.
15
+ * It can be used to form your own backoff interval array.
16
+ * @example
17
+ * // 1ms, 2ms, 4ms, 8ms, 16ms, 32ms
18
+ * PromiseUtils.withRetry(() => doSomething(), EXPONENTIAL_SEQUENCE.slice(0, 5), err => err.statusCode === 429);
19
+ * // 1s, 2s, 4s, 8s, 10s, 10s, 10s, 10s, 10s, 10s
20
+ * PromiseUtils.withRetry(() => doSomething(), Array.from({length: 10}, (_v, i) => 1000 * Math.min(EXPONENTIAL_SEQUENCE[i], 10)), err => err.statusCode === 429);
21
+ * // with +-10% randomness: 1s, 2s, 4s, 8s
22
+ * PromiseUtils.withRetry(() => doSomething(), FIBONACCI_SEQUENCE.slice(0, 4).map(n => 1000 * n * (1 + (Math.random() - 0.5) / 5)), err => err.statusCode === 429);
23
+ */
24
+ export declare const EXPONENTIAL_SEQUENCE: number[];
25
+ /**
26
+ * The state of a Promise can only be one of: Pending, Fulfilled, and Rejected.
7
27
  */
8
28
  export declare enum PromiseState {
9
29
  Pending = "Pending",
@@ -44,7 +64,8 @@ export declare abstract class PromiseUtils {
44
64
  *
45
65
  * @example
46
66
  * const result = await PromiseUtils.withRetry(() => doSomething(), [100, 200, 300, 500, 800, 1000]);
47
- * const result2 = await PromiseUtils.withRetry(() => doSomething(), PromiseUtils.FIBONACCI_SEQUENCE, err => err.statusCode === 429);
67
+ * const result2 = await PromiseUtils.withRetry(() => doSomething(), Array.from({length: 10}, (_v, i) => Math.min(FIBONACCI_SEQUENCE[i], 10), err => err.statusCode === 429);
68
+ * const result3 = await PromiseUtils.withRetry(() => doSomething(), attempt => attempt <= 8 ? 1000 * Math.min(FIBONACCI_SEQUENCE[attempt - 1], 10) : undefined, err => err.statusCode === 429);
48
69
  *
49
70
  * @template Result type of the operation result
50
71
  * @template TError type of the possible error that could be generated by the operation
@@ -54,8 +75,7 @@ export declare abstract class PromiseUtils {
54
75
  * If retry is desired, before making next call to the operation the desired backoff period would be waited.
55
76
  * If the array runs out of elements or the function returns `undefined` or either the array or the function returns a negative number,
56
77
  * there would be no further call to the operation.
57
- * The `attempt` argument passed into backoff function starts from 2 because only retries need to backoff,
58
- * so the first retry is the second attempt.
78
+ * 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.
59
79
  * @param shouldRetry Predicate function for deciding whether another call to the operation should happen.
60
80
  * If this argument is not defined, retry would happen whenever the operation rejects with an error.
61
81
  * `shouldRetry` would be evaluated before `backoff`.
@@ -1 +1 @@
1
- {"version":3,"file":"promise-utils.d.ts","sourceRoot":"","sources":["../src/promise-utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"promise-utils.d.ts","sourceRoot":"","sources":["../src/promise-utils.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,32 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.promiseState = exports.synchronised = exports.synchronized = exports.timeoutReject = exports.timeoutResolve = exports.delayedReject = exports.delayedResolve = exports.inParallel = exports.withRetry = exports.repeat = exports.PromiseUtils = exports.PromiseState = exports.FIBONACCI_SEQUENCE = void 0;
3
+ exports.promiseState = exports.synchronised = exports.synchronized = exports.timeoutReject = exports.timeoutResolve = exports.delayedReject = exports.delayedResolve = exports.inParallel = exports.withRetry = exports.repeat = exports.PromiseUtils = exports.PromiseState = exports.EXPONENTIAL_SEQUENCE = exports.FIBONACCI_SEQUENCE = void 0;
4
4
  /**
5
- * Array of Fibonacci numbers starting from 1 up to 317811.
5
+ * Array of 25 Fibonacci numbers starting from 1 up to 317811.
6
+ * It can be used to form your own backoff interval array.
7
+ * @example
8
+ * // 1ms, 2ms, 3ms, 5ms, 8ms, 13ms
9
+ * PromiseUtils.withRetry(() => doSomething(), FIBONACCI_SEQUENCE.slice(0, 5), err => err.statusCode === 429);
10
+ * // 1s, 2s, 3s, 4s, 8s, 10s, 10s, 10s, 10s, 10s
11
+ * PromiseUtils.withRetry(() => doSomething(), Array.from({length: 10}, (_v, i) => 1000 * Math.min(FIBONACCI_SEQUENCE[i], 10)), err => err.statusCode === 429);
12
+ * // with +-10% randomness: 1s, 2s, 3s, 5s, 8s, 13s
13
+ * PromiseUtils.withRetry(() => doSomething(), FIBONACCI_SEQUENCE.slice(0, 5).map(n => 1000 * n * (1 + (Math.random() - 0.5) / 5)), err => err.statusCode === 429);
6
14
  */
7
15
  exports.FIBONACCI_SEQUENCE = [1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811];
8
16
  /**
9
- * The state of a Promise can only be on of: Pending, Fulfilled, and Rejected.
17
+ * Array of 25 exponential numbers starting from 1 up to 33554432.
18
+ * It can be used to form your own backoff interval array.
19
+ * @example
20
+ * // 1ms, 2ms, 4ms, 8ms, 16ms, 32ms
21
+ * PromiseUtils.withRetry(() => doSomething(), EXPONENTIAL_SEQUENCE.slice(0, 5), err => err.statusCode === 429);
22
+ * // 1s, 2s, 4s, 8s, 10s, 10s, 10s, 10s, 10s, 10s
23
+ * PromiseUtils.withRetry(() => doSomething(), Array.from({length: 10}, (_v, i) => 1000 * Math.min(EXPONENTIAL_SEQUENCE[i], 10)), err => err.statusCode === 429);
24
+ * // with +-10% randomness: 1s, 2s, 4s, 8s
25
+ * PromiseUtils.withRetry(() => doSomething(), FIBONACCI_SEQUENCE.slice(0, 4).map(n => 1000 * n * (1 + (Math.random() - 0.5) / 5)), err => err.statusCode === 429);
26
+ */
27
+ exports.EXPONENTIAL_SEQUENCE = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 1597, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432];
28
+ /**
29
+ * The state of a Promise can only be one of: Pending, Fulfilled, and Rejected.
10
30
  */
11
31
  var PromiseState;
12
32
  (function (PromiseState) {
@@ -61,7 +81,8 @@ class PromiseUtils {
61
81
  *
62
82
  * @example
63
83
  * const result = await PromiseUtils.withRetry(() => doSomething(), [100, 200, 300, 500, 800, 1000]);
64
- * const result2 = await PromiseUtils.withRetry(() => doSomething(), PromiseUtils.FIBONACCI_SEQUENCE, err => err.statusCode === 429);
84
+ * const result2 = await PromiseUtils.withRetry(() => doSomething(), Array.from({length: 10}, (_v, i) => Math.min(FIBONACCI_SEQUENCE[i], 10), err => err.statusCode === 429);
85
+ * const result3 = await PromiseUtils.withRetry(() => doSomething(), attempt => attempt <= 8 ? 1000 * Math.min(FIBONACCI_SEQUENCE[attempt - 1], 10) : undefined, err => err.statusCode === 429);
65
86
  *
66
87
  * @template Result type of the operation result
67
88
  * @template TError type of the possible error that could be generated by the operation
@@ -71,8 +92,7 @@ class PromiseUtils {
71
92
  * If retry is desired, before making next call to the operation the desired backoff period would be waited.
72
93
  * If the array runs out of elements or the function returns `undefined` or either the array or the function returns a negative number,
73
94
  * there would be no further call to the operation.
74
- * The `attempt` argument passed into backoff function starts from 2 because only retries need to backoff,
75
- * so the first retry is the second attempt.
95
+ * 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.
76
96
  * @param shouldRetry Predicate function for deciding whether another call to the operation should happen.
77
97
  * If this argument is not defined, retry would happen whenever the operation rejects with an error.
78
98
  * `shouldRetry` would be evaluated before `backoff`.
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@handy-common-utils/promise-utils",
3
- "version": "1.2.3",
3
+ "version": "1.2.6",
4
4
  "description": "Promise related utilities",
5
5
  "scripts": {
6
6
  "pretest": "eslint . --ext .ts",
7
7
  "test": "nyc mocha",
8
8
  "prepare": "shx rm -rf dist && tsc && es-check",
9
- "preversion": "generate-api-docs-and-update-readme && replace-in-file README.md '### Functions[\\s\\S]*?## Classes' '## Classes' && git add README.md"
9
+ "preversion": "generate-api-docs-and-update-readme && replace-in-file README.md '[^#]### Functions[\\s\\S]*?## Classes' '## Classes' && git add README.md"
10
10
  },
11
11
  "files": [
12
12
  "package.json",
@@ -19,7 +19,8 @@
19
19
  "@handy-common-utils/dev-dependencies": "^1.0.31",
20
20
  "@types/chai-as-promised": "^7.1.3",
21
21
  "chai-as-promised": "^7.1.1",
22
- "es-check": "^5.2.3"
22
+ "es-check": "^5.2.3",
23
+ "eslint": "^7.32.0"
23
24
  },
24
25
  "publishConfig": {
25
26
  "access": "public"
@@ -38,5 +39,8 @@
38
39
  "utilities"
39
40
  ],
40
41
  "author": "James Hu",
41
- "license": "Apache-2.0"
42
+ "license": "Apache-2.0",
43
+ "dependencies": {
44
+ "-": "^0.0.1"
45
+ }
42
46
  }