@sha1n/about-time 0.0.1 → 0.0.2

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
@@ -7,7 +7,7 @@
7
7
 
8
8
  # About-Time
9
9
 
10
- A set of essential time related utilities.
10
+ A collection of essential time related utilities.
11
11
 
12
12
  - [About-Time](#about-time)
13
13
  - [Install](#install)
@@ -78,20 +78,27 @@ const retryPolicy = fixedRetryPolicy([3, 10, 50, 100], TimeUnit.Milliseconds);
78
78
  ```
79
79
 
80
80
  #### Exponential backoff retry policy
81
+ Exponential backoff formula based retry policy with optional custom exponent base and a limit.
82
+ The optional `limit` provides control over maximum pause intervals, so they don't soar beyond reasonable values.
83
+
84
+ **The formula used by this implementation is the following:**
85
+
86
+ interval<sub>i</sub> = min(limit, (exponential<sup>i</sup> - 1) / 2)
87
+
81
88
  ```ts
82
- // 10 retries, starting with 10 milliseconds and then exponentially increases the delay based on the default power value without a limit.
83
89
  const retryPolicy = exponentialBackoffRetryPolicy(/* count = */10, /* opts?: { exponential?: number, limit?: number, units?: TimeUnit }*/);
84
90
  ```
85
91
 
86
92
  ### RetryAround
87
- Executes the given function with the retries based on the specified policy.
93
+ Executes the given function with retries based on the specified policy and *optional* predicate.
94
+ The predicate provides control over which errors we want to retry on.
88
95
  ```ts
89
- const result = await retryAround(action, retryPolicy);
96
+ const result = await retryAround(action, retryPolicy, predicate);
90
97
  ```
91
98
 
92
99
  ### Retriable
93
- Wraps a given function with `retryAround` with the specified policy.
100
+ Wraps a given function with `retryAround` with the specified arguments.
94
101
  ```ts
95
- const retriableAction = retriable(action, retryPolicy);
102
+ const retriableAction = retriable(action, retryPolicy, predicate);
96
103
  const result = await retriableAction();
97
104
  ```
package/dist/lib/retry.js CHANGED
@@ -61,7 +61,7 @@ function exponentialBackoffRetryPolicy(count, opts) {
61
61
  return Object.freeze(new ExponentialBackoffRetryPolicy(count, opts === null || opts === void 0 ? void 0 : opts.exponential, opts === null || opts === void 0 ? void 0 : opts.limit, opts === null || opts === void 0 ? void 0 : opts.units));
62
62
  }
63
63
  exports.exponentialBackoffRetryPolicy = exponentialBackoffRetryPolicy;
64
- async function retryAround(action, policy) {
64
+ async function retryAround(action, policy, predicate = () => true) {
65
65
  let next;
66
66
  const intervals = policy.intervals()[Symbol.iterator]();
67
67
  do {
@@ -70,7 +70,7 @@ async function retryAround(action, policy) {
70
70
  }
71
71
  catch (e) {
72
72
  next = intervals.next();
73
- if (next.done) {
73
+ if (next.done || !predicate(e)) {
74
74
  throw e;
75
75
  }
76
76
  await (0, utilities_1.sleep)(next.value);
@@ -79,9 +79,9 @@ async function retryAround(action, policy) {
79
79
  throw new Error('Unexpected error. This is most likely a bug.');
80
80
  }
81
81
  exports.retryAround = retryAround;
82
- function retriable(action, policy) {
82
+ function retriable(action, policy, predicate = () => true) {
83
83
  return () => {
84
- return retryAround(action, policy);
84
+ return retryAround(action, policy, predicate);
85
85
  };
86
86
  }
87
87
  exports.retriable = retriable;
@@ -10,7 +10,7 @@ const timeunit_1 = require("./timeunit");
10
10
  * @returns a promise that resolves when the specified time has elapsed.
11
11
  */
12
12
  function sleep(time, units) {
13
- return new Promise((resolve) => {
13
+ return new Promise(resolve => {
14
14
  setTimeout(resolve, (0, timeunit_1.toMilliseconds)(time, units));
15
15
  });
16
16
  }
@@ -53,12 +53,8 @@ async function until(condition, opts) {
53
53
  return;
54
54
  }
55
55
  const defaultInterval = 50;
56
- const deadline = opts
57
- ? Date.now() + (0, timeunit_1.toMilliseconds)(opts.timeout, opts.units)
58
- : Number.MAX_VALUE;
59
- const interval = (opts === null || opts === void 0 ? void 0 : opts.interval)
60
- ? (0, timeunit_1.toMilliseconds)(opts.interval, opts.units)
61
- : defaultInterval;
56
+ const deadline = opts ? Date.now() + (0, timeunit_1.toMilliseconds)(opts.timeout, opts.units) : Number.MAX_VALUE;
57
+ const interval = (opts === null || opts === void 0 ? void 0 : opts.interval) ? (0, timeunit_1.toMilliseconds)(opts.interval, opts.units) : defaultInterval;
62
58
  return new Promise((resolve, reject) => {
63
59
  const handle = setInterval(() => {
64
60
  if (Date.now() > deadline) {
@@ -13,6 +13,6 @@ declare function exponentialBackoffRetryPolicy(count: number, opts?: {
13
13
  limit?: number;
14
14
  units?: TimeUnit;
15
15
  }): RetryPolicy;
16
- declare function retryAround<T>(action: () => T | Promise<T>, policy: RetryPolicy): Promise<T>;
17
- declare function retriable<T>(action: () => T | Promise<T>, policy: RetryPolicy): () => Promise<T>;
16
+ declare function retryAround<T>(action: () => T | Promise<T>, policy: RetryPolicy, predicate?: (e: Error) => boolean): Promise<T>;
17
+ declare function retriable<T>(action: () => T | Promise<T>, policy: RetryPolicy, predicate?: (e: Error) => boolean): () => Promise<T>;
18
18
  export { RetryPolicy, retryAround, retriable, fixedRetryPolicy, simpleRetryPolicy, exponentialBackoffRetryPolicy };
package/lib/retry.ts CHANGED
@@ -8,11 +8,7 @@ interface RetryPolicy {
8
8
  class SimpleRetryPolicy implements RetryPolicy {
9
9
  private readonly interval: number;
10
10
 
11
- constructor(
12
- private readonly count: number,
13
- interval: number,
14
- units?: TimeUnit
15
- ) {
11
+ constructor(private readonly count: number, interval: number, units?: TimeUnit) {
16
12
  this.interval = toMilliseconds(interval, units);
17
13
  }
18
14
 
@@ -68,18 +64,11 @@ class FixedRetryPolicy implements RetryPolicy {
68
64
  }
69
65
  }
70
66
 
71
- function simpleRetryPolicy(
72
- count: number,
73
- interval: number,
74
- opts?: { units?: TimeUnit }
75
- ): RetryPolicy {
67
+ function simpleRetryPolicy(count: number, interval: number, opts?: { units?: TimeUnit }): RetryPolicy {
76
68
  return Object.freeze(new SimpleRetryPolicy(count, interval, opts?.units));
77
69
  }
78
70
 
79
- function fixedRetryPolicy(
80
- intervals: number[],
81
- opts?: { units?: TimeUnit }
82
- ): RetryPolicy {
71
+ function fixedRetryPolicy(intervals: number[], opts?: { units?: TimeUnit }): RetryPolicy {
83
72
  return Object.freeze(new FixedRetryPolicy(intervals, opts?.units));
84
73
  }
85
74
 
@@ -87,19 +76,13 @@ function exponentialBackoffRetryPolicy(
87
76
  count: number,
88
77
  opts?: { exponential?: number; limit?: number; units?: TimeUnit }
89
78
  ): RetryPolicy {
90
- return Object.freeze(
91
- new ExponentialBackoffRetryPolicy(
92
- count,
93
- opts?.exponential,
94
- opts?.limit,
95
- opts?.units
96
- )
97
- );
79
+ return Object.freeze(new ExponentialBackoffRetryPolicy(count, opts?.exponential, opts?.limit, opts?.units));
98
80
  }
99
81
 
100
82
  async function retryAround<T>(
101
83
  action: () => T | Promise<T>,
102
- policy: RetryPolicy
84
+ policy: RetryPolicy,
85
+ predicate: (e: Error) => boolean = () => true
103
86
  ): Promise<T> {
104
87
  let next: IteratorResult<number, undefined>;
105
88
  const intervals = policy.intervals()[Symbol.iterator]();
@@ -109,7 +92,7 @@ async function retryAround<T>(
109
92
  } catch (e) {
110
93
  next = intervals.next();
111
94
 
112
- if (next.done) {
95
+ if (next.done || !predicate(e)) {
113
96
  throw e;
114
97
  }
115
98
 
@@ -122,18 +105,12 @@ async function retryAround<T>(
122
105
 
123
106
  function retriable<T>(
124
107
  action: () => T | Promise<T>,
125
- policy: RetryPolicy
108
+ policy: RetryPolicy,
109
+ predicate: (e: Error) => boolean = () => true
126
110
  ): () => Promise<T> {
127
111
  return () => {
128
- return retryAround(action, policy);
112
+ return retryAround(action, policy, predicate);
129
113
  };
130
114
  }
131
115
 
132
- export {
133
- RetryPolicy,
134
- retryAround,
135
- retriable,
136
- fixedRetryPolicy,
137
- simpleRetryPolicy,
138
- exponentialBackoffRetryPolicy
139
- };
116
+ export { RetryPolicy, retryAround, retriable, fixedRetryPolicy, simpleRetryPolicy, exponentialBackoffRetryPolicy };
package/lib/utilities.ts CHANGED
@@ -8,7 +8,7 @@ import { TimeUnit, toMilliseconds } from './timeunit';
8
8
  * @returns a promise that resolves when the specified time has elapsed.
9
9
  */
10
10
  function sleep(time: number, units?: TimeUnit): Promise<void> {
11
- return new Promise((resolve) => {
11
+ return new Promise(resolve => {
12
12
  setTimeout(resolve, toMilliseconds(time, units));
13
13
  });
14
14
  }
@@ -21,11 +21,7 @@ function sleep(time: number, units?: TimeUnit): Promise<void> {
21
21
  * @param units the units on time
22
22
  * @returns a promise that resolves when the specified time has elapsed.
23
23
  */
24
- function delay<T>(
25
- action: () => T | Promise<T>,
26
- time: number,
27
- units?: TimeUnit
28
- ): Promise<T> {
24
+ function delay<T>(action: () => T | Promise<T>, time: number, units?: TimeUnit): Promise<T> {
29
25
  const delayMs = toMilliseconds(time, units);
30
26
  return new Promise((resolve, reject) => {
31
27
  setTimeout(() => Promise.resolve(action()).then(resolve, reject), delayMs);
@@ -60,12 +56,8 @@ async function until(
60
56
  }
61
57
 
62
58
  const defaultInterval = 50;
63
- const deadline = opts
64
- ? Date.now() + toMilliseconds(opts.timeout, opts.units)
65
- : Number.MAX_VALUE;
66
- const interval = opts?.interval
67
- ? toMilliseconds(opts.interval, opts.units)
68
- : defaultInterval;
59
+ const deadline = opts ? Date.now() + toMilliseconds(opts.timeout, opts.units) : Number.MAX_VALUE;
60
+ const interval = opts?.interval ? toMilliseconds(opts.interval, opts.units) : defaultInterval;
69
61
 
70
62
  return new Promise<void>((resolve, reject) => {
71
63
  const handle = setInterval(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sha1n/about-time",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "A set of essential time related utilities",
5
5
  "repository": "https://github.com/sha1n/about-time",
6
6
  "author": "Shai Nagar",