@ledgerhq/live-promise 0.0.1

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/.eslintrc.js ADDED
@@ -0,0 +1,57 @@
1
+ module.exports = {
2
+ parser: "@typescript-eslint/parser",
3
+ env: {
4
+ browser: true,
5
+ es6: true,
6
+ node: true,
7
+ jest: true,
8
+ },
9
+ extends: [
10
+ "eslint:recommended",
11
+ "plugin:@typescript-eslint/eslint-recommended",
12
+ "plugin:@typescript-eslint/recommended",
13
+ "prettier",
14
+ ],
15
+ globals: {
16
+ Atomics: "readonly",
17
+ SharedArrayBuffer: "readonly",
18
+ },
19
+ plugins: ["@typescript-eslint", "prettier"],
20
+ rules: {
21
+ "no-console": ["error", { allow: ["warn", "error"] }],
22
+ "linebreak-style": ["error", "unix"],
23
+ semi: ["error", "always"],
24
+ "no-unused-vars": "off",
25
+ "import/prefer-default-export": 0,
26
+ "no-plusplus": 0,
27
+ "no-underscore-dangle": 0,
28
+ "prefer-template": 0,
29
+ "no-await-in-loop": 0,
30
+ "no-restricted-syntax": 0,
31
+ "consistent-return": 0,
32
+ "no-lonely-if": 0,
33
+ "no-use-before-define": 0,
34
+ "no-nested-ternary": 0,
35
+ "import/no-cycle": 0,
36
+ "no-multi-assign": 0,
37
+ "guard-for-in": 0,
38
+ "no-continue": 0,
39
+ "lines-between-class-members": 0,
40
+ "prefer-destructuring": 0,
41
+ "prettier/prettier": "error",
42
+ "@typescript-eslint/no-use-before-define": "off",
43
+ "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
44
+ "@typescript-eslint/no-empty-function": "off",
45
+ "@typescript-eslint/no-namespace": ["error", { allowDeclarations: true }],
46
+ "@typescript-eslint/no-explicit-any": 0,
47
+ "@typescript-eslint/ban-types": [
48
+ "error",
49
+ {
50
+ extendDefaults: true,
51
+ types: {
52
+ "{}": false,
53
+ },
54
+ },
55
+ ],
56
+ },
57
+ };
@@ -0,0 +1,4 @@
1
+
2
+ > @ledgerhq/live-promise@0.0.1 build /home/runner/work/ledger-live/ledger-live/libs/promise
3
+ > tsc && tsc -m ES6 --outDir lib-es
4
+
package/jest.config.js ADDED
@@ -0,0 +1,10 @@
1
+ /** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
2
+ module.exports = {
3
+ preset: 'ts-jest',
4
+ testEnvironment: 'node',
5
+ testPathIgnorePatterns: [
6
+ "lib/",
7
+ "lib-es/"
8
+ ]
9
+ };
10
+
package/lib/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./promise";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC"}
package/lib/index.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ exports.__esModule = true;
17
+ __exportStar(require("./promise"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4CAA0B"}
@@ -0,0 +1,21 @@
1
+ export declare const delay: (ms: number) => Promise<void>;
2
+ declare const defaults: {
3
+ maxRetry: number;
4
+ interval: number;
5
+ intervalMultiplicator: number;
6
+ context: string;
7
+ };
8
+ export declare function retry<A>(f: () => Promise<A>, options?: Partial<typeof defaults>): Promise<A>;
9
+ type Job<R, A extends Array<any>> = (...args: A) => Promise<R>;
10
+ export declare const atomicQueue: <R, A extends any[]>(job: Job<R, A>, queueIdentifier?: (...args: A) => string) => Job<R, A>;
11
+ export declare function execAndWaitAtLeast<A>(ms: number, cb: () => Promise<A>): Promise<A>;
12
+ /**
13
+ * promiseAllBatched(n, items, i => f(i))
14
+ * is essentially like
15
+ * Promise.all(items.map(i => f(i)))
16
+ * but with a guarantee that it will not create more than n concurrent call to f
17
+ * where f is a function that returns a promise
18
+ */
19
+ export declare function promiseAllBatched<A, B>(batch: number, items: Array<A>, fn: (arg0: A, arg1: number) => Promise<B>): Promise<B[]>;
20
+ export {};
21
+ //# sourceMappingURL=promise.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promise.d.ts","sourceRoot":"","sources":["../src/promise.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,KAAK,OAAQ,MAAM,KAAG,QAAQ,IAAI,CACR,CAAC;AACxC,QAAA,MAAM,QAAQ;;;;;CAKb,CAAC;AACF,wBAAgB,KAAK,CAAC,CAAC,EACrB,CAAC,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACnB,OAAO,CAAC,EAAE,OAAO,CAAC,OAAO,QAAQ,CAAC,GACjC,OAAO,CAAC,CAAC,CAAC,CA0BZ;AACD,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;AAC/D,eAAO,MAAM,WAAW,yEAEW,MAAM,cAUxC,CAAC;AACF,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAOZ;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAC1C,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EACf,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GACxC,OAAO,CAAC,CAAC,EAAE,CAAC,CAwBd"}
package/lib/promise.js ADDED
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ var __read = (this && this.__read) || function (o, n) {
50
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
51
+ if (!m) return o;
52
+ var i = m.call(o), r, ar = [], e;
53
+ try {
54
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
55
+ }
56
+ catch (error) { e = { error: error }; }
57
+ finally {
58
+ try {
59
+ if (r && !r.done && (m = i["return"])) m.call(i);
60
+ }
61
+ finally { if (e) throw e.error; }
62
+ }
63
+ return ar;
64
+ };
65
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
66
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
67
+ if (ar || !(i in from)) {
68
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
69
+ ar[i] = from[i];
70
+ }
71
+ }
72
+ return to.concat(ar || Array.prototype.slice.call(from));
73
+ };
74
+ exports.__esModule = true;
75
+ exports.promiseAllBatched = exports.execAndWaitAtLeast = exports.atomicQueue = exports.retry = exports.delay = void 0;
76
+ var logs_1 = require("@ledgerhq/logs");
77
+ var delay = function (ms) {
78
+ return new Promise(function (f) { return setTimeout(f, ms); });
79
+ };
80
+ exports.delay = delay;
81
+ var defaults = {
82
+ maxRetry: 4,
83
+ interval: 300,
84
+ intervalMultiplicator: 1.5,
85
+ context: ""
86
+ };
87
+ function retry(f, options) {
88
+ var _a = __assign(__assign({}, defaults), options), maxRetry = _a.maxRetry, interval = _a.interval, intervalMultiplicator = _a.intervalMultiplicator, context = _a.context;
89
+ function rec(remainingTry, i) {
90
+ var result = f();
91
+ if (remainingTry <= 0) {
92
+ return result;
93
+ }
94
+ // In case of failure, wait the interval, retry the action
95
+ return result["catch"](function (e) {
96
+ (0, logs_1.log)("promise-retry", context + " failed. " + remainingTry + " retry remain. " + String(e));
97
+ return (0, exports.delay)(i).then(function () {
98
+ return rec(remainingTry - 1, i * intervalMultiplicator);
99
+ });
100
+ });
101
+ }
102
+ return rec(maxRetry, interval);
103
+ }
104
+ exports.retry = retry;
105
+ var atomicQueue = function (job, queueIdentifier) {
106
+ if (queueIdentifier === void 0) { queueIdentifier = function () { return ""; }; }
107
+ var queues = {};
108
+ return function () {
109
+ var args = [];
110
+ for (var _i = 0; _i < arguments.length; _i++) {
111
+ args[_i] = arguments[_i];
112
+ }
113
+ var id = queueIdentifier.apply(void 0, __spreadArray([], __read(args), false));
114
+ var queue = queues[id] || Promise.resolve();
115
+ var p = queue.then(function () { return job.apply(void 0, __spreadArray([], __read(args), false)); });
116
+ queues[id] = p["catch"](function () { });
117
+ return p;
118
+ };
119
+ };
120
+ exports.atomicQueue = atomicQueue;
121
+ function execAndWaitAtLeast(ms, cb) {
122
+ var startTime = Date.now();
123
+ return cb().then(function (r) {
124
+ var remaining = ms - (Date.now() - startTime);
125
+ if (remaining <= 0)
126
+ return r;
127
+ return (0, exports.delay)(remaining).then(function () { return r; });
128
+ });
129
+ }
130
+ exports.execAndWaitAtLeast = execAndWaitAtLeast;
131
+ /**
132
+ * promiseAllBatched(n, items, i => f(i))
133
+ * is essentially like
134
+ * Promise.all(items.map(i => f(i)))
135
+ * but with a guarantee that it will not create more than n concurrent call to f
136
+ * where f is a function that returns a promise
137
+ */
138
+ function promiseAllBatched(batch, items, fn) {
139
+ return __awaiter(this, void 0, void 0, function () {
140
+ function step() {
141
+ return __awaiter(this, void 0, void 0, function () {
142
+ var first, item, index, _a, _b;
143
+ return __generator(this, function (_c) {
144
+ switch (_c.label) {
145
+ case 0:
146
+ if (queue.length === 0)
147
+ return [2 /*return*/];
148
+ first = queue.shift();
149
+ if (!first) return [3 /*break*/, 2];
150
+ item = first.item, index = first.index;
151
+ _a = data;
152
+ _b = index;
153
+ return [4 /*yield*/, fn(item, index)];
154
+ case 1:
155
+ _a[_b] = _c.sent();
156
+ _c.label = 2;
157
+ case 2: return [4 /*yield*/, step()];
158
+ case 3:
159
+ _c.sent(); // each time an item redeem, we schedule another one
160
+ return [2 /*return*/];
161
+ }
162
+ });
163
+ });
164
+ }
165
+ var data, queue;
166
+ return __generator(this, function (_a) {
167
+ switch (_a.label) {
168
+ case 0:
169
+ data = Array(items.length);
170
+ queue = items.map(function (item, index) { return ({
171
+ item: item,
172
+ index: index
173
+ }); });
174
+ // initially, we schedule <batch> items in parallel
175
+ return [4 /*yield*/, Promise.all(Array(Math.min(batch, items.length))
176
+ .fill(function () { return undefined; })
177
+ .map(step))];
178
+ case 1:
179
+ // initially, we schedule <batch> items in parallel
180
+ _a.sent();
181
+ return [2 /*return*/, data];
182
+ }
183
+ });
184
+ });
185
+ }
186
+ exports.promiseAllBatched = promiseAllBatched;
187
+ //# sourceMappingURL=promise.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promise.js","sourceRoot":"","sources":["../src/promise.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=promise.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promise.test.d.ts","sourceRoot":"","sources":["../src/promise.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,72 @@
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
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ exports.__esModule = true;
39
+ var promise_1 = require("./promise");
40
+ test("promiseAllBatched", function () { return __awaiter(void 0, void 0, void 0, function () {
41
+ var promisifyIdPlusOne, p, _a, _b, _c, _d, _e;
42
+ return __generator(this, function (_f) {
43
+ switch (_f.label) {
44
+ case 0:
45
+ promisifyIdPlusOne = function (a) { return Promise.resolve(a + 1); };
46
+ p = (0, promise_1.promiseAllBatched)(5, [], promisifyIdPlusOne);
47
+ expect(typeof p.then).toBe("function");
48
+ _a = expect;
49
+ return [4 /*yield*/, p];
50
+ case 1:
51
+ _a.apply(void 0, [_f.sent()]).toEqual([]);
52
+ _b = expect;
53
+ return [4 /*yield*/, (0, promise_1.promiseAllBatched)(5, [1, 2, 3, 4, 5, 6, 7, 8], promisifyIdPlusOne)];
54
+ case 2:
55
+ _b.apply(void 0, [_f.sent()]).toEqual([2, 3, 4, 5, 6, 7, 8, 9]);
56
+ _c = expect;
57
+ return [4 /*yield*/, (0, promise_1.promiseAllBatched)(1, [1, 2, 3, 4, 5, 6, 7, 8], promisifyIdPlusOne)];
58
+ case 3:
59
+ _c.apply(void 0, [_f.sent()]).toEqual([2, 3, 4, 5, 6, 7, 8, 9]);
60
+ _d = expect;
61
+ return [4 /*yield*/, (0, promise_1.promiseAllBatched)(10, [1, 2, 3, 4, 5, 6, 7, 8], promisifyIdPlusOne)];
62
+ case 4:
63
+ _d.apply(void 0, [_f.sent()]).toEqual([2, 3, 4, 5, 6, 7, 8, 9]);
64
+ _e = expect;
65
+ return [4 /*yield*/, (0, promise_1.promiseAllBatched)(2, Array(6).fill(0), function (_, i) { return Promise.resolve(i); })];
66
+ case 5:
67
+ _e.apply(void 0, [_f.sent()]).toEqual([0, 1, 2, 3, 4, 5]);
68
+ return [2 /*return*/];
69
+ }
70
+ });
71
+ }); });
72
+ //# sourceMappingURL=promise.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promise.test.js","sourceRoot":"","sources":["../src/promise.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAA8C;AAC9C,IAAI,CAAC,mBAAmB,EAAE;;;;;gBAClB,kBAAkB,GAAG,UAAC,CAAS,IAAK,OAAA,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,EAAtB,CAAsB,CAAC;gBAE3D,CAAC,GAAG,IAAA,2BAAiB,EAAC,CAAC,EAAE,EAAE,EAAE,kBAAkB,CAAC,CAAC;gBACvD,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACvC,KAAA,MAAM,CAAA;gBAAC,qBAAM,CAAC,EAAA;;gBAAd,kBAAO,SAAO,EAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBAC5B,KAAA,MAAM,CAAA;gBACJ,qBAAM,IAAA,2BAAiB,EAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,kBAAkB,CAAC,EAAA;;gBAD1E,kBACE,SAAwE,EACzE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBACpC,KAAA,MAAM,CAAA;gBACJ,qBAAM,IAAA,2BAAiB,EAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,kBAAkB,CAAC,EAAA;;gBAD1E,kBACE,SAAwE,EACzE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBACpC,KAAA,MAAM,CAAA;gBACJ,qBAAM,IAAA,2BAAiB,EAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,kBAAkB,CAAC,EAAA;;gBAD3E,kBACE,SAAyE,EAC1E,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBACpC,KAAA,MAAM,CAAA;gBACJ,qBAAM,IAAA,2BAAiB,EAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,UAAC,CAAC,EAAE,CAAC,IAAK,OAAA,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAlB,CAAkB,CAAC,EAAA;;gBAD5E,kBACE,SAA0E,EAC3E,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;;;;KAC/B,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./promise";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./promise";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC"}
@@ -0,0 +1,21 @@
1
+ export declare const delay: (ms: number) => Promise<void>;
2
+ declare const defaults: {
3
+ maxRetry: number;
4
+ interval: number;
5
+ intervalMultiplicator: number;
6
+ context: string;
7
+ };
8
+ export declare function retry<A>(f: () => Promise<A>, options?: Partial<typeof defaults>): Promise<A>;
9
+ type Job<R, A extends Array<any>> = (...args: A) => Promise<R>;
10
+ export declare const atomicQueue: <R, A extends any[]>(job: Job<R, A>, queueIdentifier?: (...args: A) => string) => Job<R, A>;
11
+ export declare function execAndWaitAtLeast<A>(ms: number, cb: () => Promise<A>): Promise<A>;
12
+ /**
13
+ * promiseAllBatched(n, items, i => f(i))
14
+ * is essentially like
15
+ * Promise.all(items.map(i => f(i)))
16
+ * but with a guarantee that it will not create more than n concurrent call to f
17
+ * where f is a function that returns a promise
18
+ */
19
+ export declare function promiseAllBatched<A, B>(batch: number, items: Array<A>, fn: (arg0: A, arg1: number) => Promise<B>): Promise<B[]>;
20
+ export {};
21
+ //# sourceMappingURL=promise.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promise.d.ts","sourceRoot":"","sources":["../src/promise.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,KAAK,OAAQ,MAAM,KAAG,QAAQ,IAAI,CACR,CAAC;AACxC,QAAA,MAAM,QAAQ;;;;;CAKb,CAAC;AACF,wBAAgB,KAAK,CAAC,CAAC,EACrB,CAAC,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACnB,OAAO,CAAC,EAAE,OAAO,CAAC,OAAO,QAAQ,CAAC,GACjC,OAAO,CAAC,CAAC,CAAC,CA0BZ;AACD,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;AAC/D,eAAO,MAAM,WAAW,yEAEW,MAAM,cAUxC,CAAC;AACF,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAOZ;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAC1C,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EACf,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GACxC,OAAO,CAAC,CAAC,EAAE,CAAC,CAwBd"}
@@ -0,0 +1,179 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
13
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
14
+ return new (P || (P = Promise))(function (resolve, reject) {
15
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
18
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
19
+ });
20
+ };
21
+ var __generator = (this && this.__generator) || function (thisArg, body) {
22
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
23
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24
+ function verb(n) { return function (v) { return step([n, v]); }; }
25
+ function step(op) {
26
+ if (f) throw new TypeError("Generator is already executing.");
27
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
28
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
29
+ if (y = 0, t) op = [op[0] & 2, t.value];
30
+ switch (op[0]) {
31
+ case 0: case 1: t = op; break;
32
+ case 4: _.label++; return { value: op[1], done: false };
33
+ case 5: _.label++; y = op[1]; op = [0]; continue;
34
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
35
+ default:
36
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40
+ if (t[2]) _.ops.pop();
41
+ _.trys.pop(); continue;
42
+ }
43
+ op = body.call(thisArg, _);
44
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46
+ }
47
+ };
48
+ var __read = (this && this.__read) || function (o, n) {
49
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
50
+ if (!m) return o;
51
+ var i = m.call(o), r, ar = [], e;
52
+ try {
53
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
54
+ }
55
+ catch (error) { e = { error: error }; }
56
+ finally {
57
+ try {
58
+ if (r && !r.done && (m = i["return"])) m.call(i);
59
+ }
60
+ finally { if (e) throw e.error; }
61
+ }
62
+ return ar;
63
+ };
64
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
65
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
66
+ if (ar || !(i in from)) {
67
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
68
+ ar[i] = from[i];
69
+ }
70
+ }
71
+ return to.concat(ar || Array.prototype.slice.call(from));
72
+ };
73
+ import { log } from "@ledgerhq/logs";
74
+ export var delay = function (ms) {
75
+ return new Promise(function (f) { return setTimeout(f, ms); });
76
+ };
77
+ var defaults = {
78
+ maxRetry: 4,
79
+ interval: 300,
80
+ intervalMultiplicator: 1.5,
81
+ context: ""
82
+ };
83
+ export function retry(f, options) {
84
+ var _a = __assign(__assign({}, defaults), options), maxRetry = _a.maxRetry, interval = _a.interval, intervalMultiplicator = _a.intervalMultiplicator, context = _a.context;
85
+ function rec(remainingTry, i) {
86
+ var result = f();
87
+ if (remainingTry <= 0) {
88
+ return result;
89
+ }
90
+ // In case of failure, wait the interval, retry the action
91
+ return result["catch"](function (e) {
92
+ log("promise-retry", context + " failed. " + remainingTry + " retry remain. " + String(e));
93
+ return delay(i).then(function () {
94
+ return rec(remainingTry - 1, i * intervalMultiplicator);
95
+ });
96
+ });
97
+ }
98
+ return rec(maxRetry, interval);
99
+ }
100
+ export var atomicQueue = function (job, queueIdentifier) {
101
+ if (queueIdentifier === void 0) { queueIdentifier = function () { return ""; }; }
102
+ var queues = {};
103
+ return function () {
104
+ var args = [];
105
+ for (var _i = 0; _i < arguments.length; _i++) {
106
+ args[_i] = arguments[_i];
107
+ }
108
+ var id = queueIdentifier.apply(void 0, __spreadArray([], __read(args), false));
109
+ var queue = queues[id] || Promise.resolve();
110
+ var p = queue.then(function () { return job.apply(void 0, __spreadArray([], __read(args), false)); });
111
+ queues[id] = p["catch"](function () { });
112
+ return p;
113
+ };
114
+ };
115
+ export function execAndWaitAtLeast(ms, cb) {
116
+ var startTime = Date.now();
117
+ return cb().then(function (r) {
118
+ var remaining = ms - (Date.now() - startTime);
119
+ if (remaining <= 0)
120
+ return r;
121
+ return delay(remaining).then(function () { return r; });
122
+ });
123
+ }
124
+ /**
125
+ * promiseAllBatched(n, items, i => f(i))
126
+ * is essentially like
127
+ * Promise.all(items.map(i => f(i)))
128
+ * but with a guarantee that it will not create more than n concurrent call to f
129
+ * where f is a function that returns a promise
130
+ */
131
+ export function promiseAllBatched(batch, items, fn) {
132
+ return __awaiter(this, void 0, void 0, function () {
133
+ function step() {
134
+ return __awaiter(this, void 0, void 0, function () {
135
+ var first, item, index, _a, _b;
136
+ return __generator(this, function (_c) {
137
+ switch (_c.label) {
138
+ case 0:
139
+ if (queue.length === 0)
140
+ return [2 /*return*/];
141
+ first = queue.shift();
142
+ if (!first) return [3 /*break*/, 2];
143
+ item = first.item, index = first.index;
144
+ _a = data;
145
+ _b = index;
146
+ return [4 /*yield*/, fn(item, index)];
147
+ case 1:
148
+ _a[_b] = _c.sent();
149
+ _c.label = 2;
150
+ case 2: return [4 /*yield*/, step()];
151
+ case 3:
152
+ _c.sent(); // each time an item redeem, we schedule another one
153
+ return [2 /*return*/];
154
+ }
155
+ });
156
+ });
157
+ }
158
+ var data, queue;
159
+ return __generator(this, function (_a) {
160
+ switch (_a.label) {
161
+ case 0:
162
+ data = Array(items.length);
163
+ queue = items.map(function (item, index) { return ({
164
+ item: item,
165
+ index: index
166
+ }); });
167
+ // initially, we schedule <batch> items in parallel
168
+ return [4 /*yield*/, Promise.all(Array(Math.min(batch, items.length))
169
+ .fill(function () { return undefined; })
170
+ .map(step))];
171
+ case 1:
172
+ // initially, we schedule <batch> items in parallel
173
+ _a.sent();
174
+ return [2 /*return*/, data];
175
+ }
176
+ });
177
+ });
178
+ }
179
+ //# sourceMappingURL=promise.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promise.js","sourceRoot":"","sources":["../src/promise.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=promise.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promise.test.d.ts","sourceRoot":"","sources":["../src/promise.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,70 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ var __generator = (this && this.__generator) || function (thisArg, body) {
11
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
12
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
13
+ function verb(n) { return function (v) { return step([n, v]); }; }
14
+ function step(op) {
15
+ if (f) throw new TypeError("Generator is already executing.");
16
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
17
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
18
+ if (y = 0, t) op = [op[0] & 2, t.value];
19
+ switch (op[0]) {
20
+ case 0: case 1: t = op; break;
21
+ case 4: _.label++; return { value: op[1], done: false };
22
+ case 5: _.label++; y = op[1]; op = [0]; continue;
23
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
24
+ default:
25
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
26
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
27
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
28
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
29
+ if (t[2]) _.ops.pop();
30
+ _.trys.pop(); continue;
31
+ }
32
+ op = body.call(thisArg, _);
33
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
34
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
+ }
36
+ };
37
+ import { promiseAllBatched } from "./promise";
38
+ test("promiseAllBatched", function () { return __awaiter(void 0, void 0, void 0, function () {
39
+ var promisifyIdPlusOne, p, _a, _b, _c, _d, _e;
40
+ return __generator(this, function (_f) {
41
+ switch (_f.label) {
42
+ case 0:
43
+ promisifyIdPlusOne = function (a) { return Promise.resolve(a + 1); };
44
+ p = promiseAllBatched(5, [], promisifyIdPlusOne);
45
+ expect(typeof p.then).toBe("function");
46
+ _a = expect;
47
+ return [4 /*yield*/, p];
48
+ case 1:
49
+ _a.apply(void 0, [_f.sent()]).toEqual([]);
50
+ _b = expect;
51
+ return [4 /*yield*/, promiseAllBatched(5, [1, 2, 3, 4, 5, 6, 7, 8], promisifyIdPlusOne)];
52
+ case 2:
53
+ _b.apply(void 0, [_f.sent()]).toEqual([2, 3, 4, 5, 6, 7, 8, 9]);
54
+ _c = expect;
55
+ return [4 /*yield*/, promiseAllBatched(1, [1, 2, 3, 4, 5, 6, 7, 8], promisifyIdPlusOne)];
56
+ case 3:
57
+ _c.apply(void 0, [_f.sent()]).toEqual([2, 3, 4, 5, 6, 7, 8, 9]);
58
+ _d = expect;
59
+ return [4 /*yield*/, promiseAllBatched(10, [1, 2, 3, 4, 5, 6, 7, 8], promisifyIdPlusOne)];
60
+ case 4:
61
+ _d.apply(void 0, [_f.sent()]).toEqual([2, 3, 4, 5, 6, 7, 8, 9]);
62
+ _e = expect;
63
+ return [4 /*yield*/, promiseAllBatched(2, Array(6).fill(0), function (_, i) { return Promise.resolve(i); })];
64
+ case 5:
65
+ _e.apply(void 0, [_f.sent()]).toEqual([0, 1, 2, 3, 4, 5]);
66
+ return [2 /*return*/];
67
+ }
68
+ });
69
+ }); });
70
+ //# sourceMappingURL=promise.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promise.test.js","sourceRoot":"","sources":["../src/promise.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,IAAI,CAAC,mBAAmB,EAAE;;;;;gBAClB,kBAAkB,GAAG,UAAC,CAAS,IAAK,OAAA,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,EAAtB,CAAsB,CAAC;gBAE3D,CAAC,GAAG,iBAAiB,CAAC,CAAC,EAAE,EAAE,EAAE,kBAAkB,CAAC,CAAC;gBACvD,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACvC,KAAA,MAAM,CAAA;gBAAC,qBAAM,CAAC,EAAA;;gBAAd,kBAAO,SAAO,EAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBAC5B,KAAA,MAAM,CAAA;gBACJ,qBAAM,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,kBAAkB,CAAC,EAAA;;gBAD1E,kBACE,SAAwE,EACzE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBACpC,KAAA,MAAM,CAAA;gBACJ,qBAAM,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,kBAAkB,CAAC,EAAA;;gBAD1E,kBACE,SAAwE,EACzE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBACpC,KAAA,MAAM,CAAA;gBACJ,qBAAM,iBAAiB,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,kBAAkB,CAAC,EAAA;;gBAD3E,kBACE,SAAyE,EAC1E,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBACpC,KAAA,MAAM,CAAA;gBACJ,qBAAM,iBAAiB,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,UAAC,CAAC,EAAE,CAAC,IAAK,OAAA,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAlB,CAAkB,CAAC,EAAA;;gBAD5E,kBACE,SAA0E,EAC3E,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;;;;KAC/B,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@ledgerhq/live-promise",
3
+ "version": "0.0.1",
4
+ "description": "Ledger Live Promise utilities",
5
+ "keywords": [
6
+ "Ledger"
7
+ ],
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/LedgerHQ/ledger-live.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/LedgerHQ/ledger-live/issues"
14
+ },
15
+ "homepage": "https://github.com/LedgerHQ/ledger-live/tree/develop/libs/promise",
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "main": "lib/index.js",
20
+ "module": "lib-es/index.js",
21
+ "types": "lib/index.d.ts",
22
+ "license": "Apache-2.0",
23
+ "dependencies": {
24
+ "@ledgerhq/logs": "^6.10.1"
25
+ },
26
+ "devDependencies": {
27
+ "@types/jest": "^29.2.4",
28
+ "@typescript-eslint/eslint-plugin": "^5.46.1",
29
+ "@typescript-eslint/parser": "^5.46.1",
30
+ "eslint": "^7.32.0",
31
+ "eslint-config-prettier": "^8.3.0",
32
+ "eslint-config-typescript": "^3.0.0",
33
+ "eslint-formatter-pretty": "^3.0.1",
34
+ "eslint-plugin-prettier": "^3.4.0",
35
+ "eslint-plugin-typescript": "^0.14.0",
36
+ "jest": "^28.1.1",
37
+ "prettier": "^2.8.1",
38
+ "ts-jest": "^28.0.5",
39
+ "typescript": "^4.9.4"
40
+ },
41
+ "scripts": {
42
+ "clean": "rimraf lib lib-es",
43
+ "build": "tsc && tsc -m ES6 --outDir lib-es",
44
+ "prewatch": "pnpm build",
45
+ "watch": "tsc --watch",
46
+ "lint": "eslint ./src --no-error-on-unmatched-pattern --ext .ts,.tsx",
47
+ "lint:fix": "pnpm lint --fix",
48
+ "test": "jest"
49
+ }
50
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./promise";
@@ -0,0 +1,20 @@
1
+ import { promiseAllBatched } from "./promise";
2
+ test("promiseAllBatched", async () => {
3
+ const promisifyIdPlusOne = (a: number) => Promise.resolve(a + 1);
4
+
5
+ const p = promiseAllBatched(5, [], promisifyIdPlusOne);
6
+ expect(typeof p.then).toBe("function");
7
+ expect(await p).toEqual([]);
8
+ expect(
9
+ await promiseAllBatched(5, [1, 2, 3, 4, 5, 6, 7, 8], promisifyIdPlusOne)
10
+ ).toEqual([2, 3, 4, 5, 6, 7, 8, 9]);
11
+ expect(
12
+ await promiseAllBatched(1, [1, 2, 3, 4, 5, 6, 7, 8], promisifyIdPlusOne)
13
+ ).toEqual([2, 3, 4, 5, 6, 7, 8, 9]);
14
+ expect(
15
+ await promiseAllBatched(10, [1, 2, 3, 4, 5, 6, 7, 8], promisifyIdPlusOne)
16
+ ).toEqual([2, 3, 4, 5, 6, 7, 8, 9]);
17
+ expect(
18
+ await promiseAllBatched(2, Array(6).fill(0), (_, i) => Promise.resolve(i))
19
+ ).toEqual([0, 1, 2, 3, 4, 5]);
20
+ });
package/src/promise.ts ADDED
@@ -0,0 +1,101 @@
1
+ import { log } from "@ledgerhq/logs";
2
+ export const delay = (ms: number): Promise<void> =>
3
+ new Promise((f) => setTimeout(f, ms));
4
+ const defaults = {
5
+ maxRetry: 4,
6
+ interval: 300,
7
+ intervalMultiplicator: 1.5,
8
+ context: "",
9
+ };
10
+ export function retry<A>(
11
+ f: () => Promise<A>,
12
+ options?: Partial<typeof defaults>
13
+ ): Promise<A> {
14
+ const { maxRetry, interval, intervalMultiplicator, context } = {
15
+ ...defaults,
16
+ ...options,
17
+ };
18
+
19
+ function rec(remainingTry: number, i: number): Promise<A> {
20
+ const result = f();
21
+
22
+ if (remainingTry <= 0) {
23
+ return result;
24
+ }
25
+
26
+ // In case of failure, wait the interval, retry the action
27
+ return result.catch((e) => {
28
+ log(
29
+ "promise-retry",
30
+ context + " failed. " + remainingTry + " retry remain. " + String(e)
31
+ );
32
+ return delay(i).then(() =>
33
+ rec(remainingTry - 1, i * intervalMultiplicator)
34
+ );
35
+ });
36
+ }
37
+
38
+ return rec(maxRetry, interval);
39
+ }
40
+ type Job<R, A extends Array<any>> = (...args: A) => Promise<R>;
41
+ export const atomicQueue = <R, A extends Array<any>>(
42
+ job: Job<R, A>,
43
+ queueIdentifier: (...args: A) => string = () => ""
44
+ ): Job<R, A> => {
45
+ const queues: Record<string, any> = {};
46
+ return (...args) => {
47
+ const id = queueIdentifier(...args);
48
+ const queue = queues[id] || Promise.resolve();
49
+ const p = queue.then(() => job(...args));
50
+ queues[id] = p.catch(() => {});
51
+ return p;
52
+ };
53
+ };
54
+ export function execAndWaitAtLeast<A>(
55
+ ms: number,
56
+ cb: () => Promise<A>
57
+ ): Promise<A> {
58
+ const startTime = Date.now();
59
+ return cb().then((r) => {
60
+ const remaining = ms - (Date.now() - startTime);
61
+ if (remaining <= 0) return r;
62
+ return delay(remaining).then(() => r);
63
+ });
64
+ }
65
+
66
+ /**
67
+ * promiseAllBatched(n, items, i => f(i))
68
+ * is essentially like
69
+ * Promise.all(items.map(i => f(i)))
70
+ * but with a guarantee that it will not create more than n concurrent call to f
71
+ * where f is a function that returns a promise
72
+ */
73
+ export async function promiseAllBatched<A, B>(
74
+ batch: number,
75
+ items: Array<A>,
76
+ fn: (arg0: A, arg1: number) => Promise<B>
77
+ ): Promise<B[]> {
78
+ const data = Array(items.length);
79
+ const queue = items.map((item, index) => ({
80
+ item,
81
+ index,
82
+ }));
83
+
84
+ async function step() {
85
+ if (queue.length === 0) return;
86
+ const first = queue.shift();
87
+ if (first) {
88
+ const { item, index } = first;
89
+ data[index] = await fn(item, index);
90
+ }
91
+ await step(); // each time an item redeem, we schedule another one
92
+ }
93
+
94
+ // initially, we schedule <batch> items in parallel
95
+ await Promise.all(
96
+ Array(Math.min(batch, items.length))
97
+ .fill(() => undefined)
98
+ .map(step)
99
+ );
100
+ return data;
101
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "declaration": true,
4
+ "declarationMap": true,
5
+ "sourceMap": true,
6
+ "strict": true,
7
+ "noImplicitAny": false,
8
+ "noImplicitThis": false,
9
+ "allowSyntheticDefaultImports": true,
10
+ "esModuleInterop": true,
11
+ "skipLibCheck": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "moduleResolution": "node",
14
+ "downlevelIteration": true,
15
+ "resolveJsonModule": true,
16
+ "lib": ["es2020", "dom"],
17
+ "outDir": "lib"
18
+ },
19
+ "include": ["src/**/*"]
20
+ }