@dr.pogodin/js-utils 0.0.7 → 0.0.8

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
@@ -33,10 +33,6 @@ The library currently exports (links below lead to [React Utils] docs,
33
33
  but the same stuff can be imported from this `@dr.pogodin/js-utils`,
34
34
  and used in the same way):
35
35
 
36
- [Barrier]: https://dr.pogodin.studio/docs/react-utils/docs/api/classes/Barrier
37
- [Promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
38
- [timer]: https://dr.pogodin.studio/docs/react-utils/docs/api/utils/time#timer
39
-
40
36
  ### Constants
41
37
  - [SEC_MS](https://dr.pogodin.studio/docs/react-utils/docs/api/utils/time#sec_ms)
42
38
  — One second expressed in milliseconds.
@@ -50,8 +46,8 @@ and used in the same way):
50
46
  — One year expressed in milliseconds.
51
47
 
52
48
  ### Functions
53
- - [timer]
54
- — Creates a [Barrier] which resolves after the specified timeout.
49
+ - [timer()] — Creates a [Barrier] which resolves after the specified timeout.
50
+ - [withRetries()] — Attempts a given action multiple times until its succeeds.
55
51
 
56
52
  ### Classes
57
53
  - [Barrier] — A [Promise] with **resolve()** and **reject()** exposed as
@@ -60,5 +56,12 @@ and used in the same way):
60
56
  — Simple listeneable data emitter.
61
57
  - [Semaphore](https://dr.pogodin.studio/docs/react-utils/docs/api/classes/Semaphore)
62
58
  — Synchronization primitive.
63
- - `Timer` — The core implementation of [timer] functionality, allowing
59
+ - `Timer` — The core implementation of [timer()] functionality, allowing
64
60
  to create further customized timer objects. _To be documented_.
61
+
62
+ <!-- References -->
63
+
64
+ [Barrier]: https://dr.pogodin.studio/docs/react-utils/docs/api/classes/Barrier
65
+ [Promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
66
+ [timer()]: https://dr.pogodin.studio/docs/react-utils/docs/api/utils/time#timer
67
+ [withRetries()]: https://dr.pogodin.studio/docs/react-utils/docs/api/functions/withretries
package/build/index.d.ts CHANGED
@@ -2,3 +2,4 @@ export { default as Barrier } from './Barrier';
2
2
  export { default as Emitter } from './Emitter';
3
3
  export { default as Semaphore } from './Semaphore';
4
4
  export * from './time';
5
+ export { default as withRetries } from './withRetries';
package/build/index.js CHANGED
@@ -17,7 +17,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
17
17
  return (mod && mod.__esModule) ? mod : { "default": mod };
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.Semaphore = exports.Emitter = exports.Barrier = void 0;
20
+ exports.withRetries = exports.Semaphore = exports.Emitter = exports.Barrier = void 0;
21
21
  var Barrier_1 = require("./Barrier");
22
22
  Object.defineProperty(exports, "Barrier", { enumerable: true, get: function () { return __importDefault(Barrier_1).default; } });
23
23
  var Emitter_1 = require("./Emitter");
@@ -25,3 +25,5 @@ Object.defineProperty(exports, "Emitter", { enumerable: true, get: function () {
25
25
  var Semaphore_1 = require("./Semaphore");
26
26
  Object.defineProperty(exports, "Semaphore", { enumerable: true, get: function () { return __importDefault(Semaphore_1).default; } });
27
27
  __exportStar(require("./time"), exports);
28
+ var withRetries_1 = require("./withRetries");
29
+ Object.defineProperty(exports, "withRetries", { enumerable: true, get: function () { return __importDefault(withRetries_1).default; } });
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Attempts to perform the given async `action` up to `maxRetries` times with
3
+ * the specified `interval`, stopping at the first successful (non-throwing)
4
+ * execution.
5
+ * @param action
6
+ * @param maxRetries Optional. The maximum number of re-tries. Defaults 3.
7
+ * @param interval Optional. The interval between re-tries (in milliseconds).
8
+ * Defaults to 300ms.
9
+ * @returns Resolves to the result of the successful `action` execution;
10
+ * or rejects with the error from the last faileda attempt.
11
+ */
12
+ export default function withRetries(action: () => unknown, maxRetries?: number, interval?: number): Promise<any>;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const time_1 = require("./time");
13
+ /**
14
+ * Attempts to perform the given async `action` up to `maxRetries` times with
15
+ * the specified `interval`, stopping at the first successful (non-throwing)
16
+ * execution.
17
+ * @param action
18
+ * @param maxRetries Optional. The maximum number of re-tries. Defaults 3.
19
+ * @param interval Optional. The interval between re-tries (in milliseconds).
20
+ * Defaults to 300ms.
21
+ * @returns Resolves to the result of the successful `action` execution;
22
+ * or rejects with the error from the last faileda attempt.
23
+ */
24
+ function withRetries(action, maxRetries = 3, interval = 300) {
25
+ return __awaiter(this, void 0, void 0, function* () {
26
+ /* eslint-disable no-await-in-loop */
27
+ for (let n = 1;; ++n) {
28
+ try {
29
+ const res = action();
30
+ return res instanceof Promise ? yield res : res;
31
+ }
32
+ catch (error) {
33
+ if (n < maxRetries)
34
+ yield (0, time_1.timer)(interval);
35
+ else
36
+ throw error;
37
+ }
38
+ }
39
+ /* eslint-enable no-await-in-loop */
40
+ });
41
+ }
42
+ exports.default = withRetries;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dr.pogodin/js-utils",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "Collection of JavaScript (TypeScript) utilities.",
5
5
  "main": "build/index",
6
6
  "react-native": "src/index",
@@ -31,14 +31,14 @@
31
31
  },
32
32
  "homepage": "https://github.com/birdofpreyru/js-utils#readme",
33
33
  "devDependencies": {
34
- "@babel/core": "^7.23.7",
35
- "@babel/preset-env": "^7.23.8",
34
+ "@babel/core": "^7.23.9",
35
+ "@babel/preset-env": "^7.23.9",
36
36
  "@babel/preset-typescript": "^7.23.3",
37
37
  "@tsconfig/recommended": "^1.0.3",
38
38
  "@tsd/typescript": "^5.3.3",
39
- "@types/jest": "^29.5.11",
40
- "@typescript-eslint/eslint-plugin": "^6.19.0",
41
- "@typescript-eslint/parser": "^6.19.0",
39
+ "@types/jest": "^29.5.12",
40
+ "@typescript-eslint/eslint-plugin": "^6.21.0",
41
+ "@typescript-eslint/parser": "^6.21.0",
42
42
  "babel-jest": "^29.7.0",
43
43
  "eslint": "^8.56.0",
44
44
  "eslint-config-airbnb-base": "^15.0.0",
package/src/index.ts CHANGED
@@ -2,3 +2,4 @@ export { default as Barrier } from './Barrier';
2
2
  export { default as Emitter } from './Emitter';
3
3
  export { default as Semaphore } from './Semaphore';
4
4
  export * from './time';
5
+ export { default as withRetries } from './withRetries';
@@ -0,0 +1,30 @@
1
+ import { timer } from './time';
2
+
3
+ /**
4
+ * Attempts to perform the given async `action` up to `maxRetries` times with
5
+ * the specified `interval`, stopping at the first successful (non-throwing)
6
+ * execution.
7
+ * @param action
8
+ * @param maxRetries Optional. The maximum number of re-tries. Defaults 3.
9
+ * @param interval Optional. The interval between re-tries (in milliseconds).
10
+ * Defaults to 300ms.
11
+ * @returns Resolves to the result of the successful `action` execution;
12
+ * or rejects with the error from the last faileda attempt.
13
+ */
14
+ export default async function withRetries(
15
+ action: () => unknown,
16
+ maxRetries = 3,
17
+ interval = 300,
18
+ ) {
19
+ /* eslint-disable no-await-in-loop */
20
+ for (let n = 1; ; ++n) {
21
+ try {
22
+ const res = action();
23
+ return res instanceof Promise ? await res : res;
24
+ } catch (error) {
25
+ if (n < maxRetries) await timer(interval);
26
+ else throw error;
27
+ }
28
+ }
29
+ /* eslint-enable no-await-in-loop */
30
+ }