@kwiz/common 1.0.69 → 1.0.70
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.
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lock all concurrent calls to a resource to one promise for a set duration of time.
|
|
3
|
+
* @param {string} key - Unique key to identify the promise.
|
|
4
|
+
* @param {() => Promise<T>} promiseFunc - Function that will return the promise to be run only once.
|
|
5
|
+
* @param {number} duration - Duration to hold on to the promise result. (default=1)
|
|
6
|
+
* @returns {Promise<T>} Returns the single promise that will be fullfilled for all promises with the same key.
|
|
7
|
+
* @example
|
|
8
|
+
* // returns Promise<string>
|
|
9
|
+
* var initTests = await promiseLock<string>("initTests", async () => { ... }, 2);
|
|
10
|
+
*/
|
|
11
|
+
export declare function promiseLock<T>(key: string, promiseFunc: () => Promise<T>, duration?: number): Promise<T>;
|
|
1
12
|
/**
|
|
2
13
|
* Ensures that a promise runs only once
|
|
3
14
|
* @param {string} key - Unique key to identify the promise.
|
|
@@ -7,7 +18,7 @@
|
|
|
7
18
|
* @returns {Promise<T>} Returns the single promise that will be fullfilled for all promises with the same key.
|
|
8
19
|
* @example
|
|
9
20
|
* // returns Promise<string>
|
|
10
|
-
*
|
|
21
|
+
* var initTests = await promiseOnce<string>("initTests", async () => { ... });
|
|
11
22
|
*/
|
|
12
23
|
export declare function promiseOnce<T>(key: string, promiseFunc: () => Promise<T>, isValidResult?: (result: T) => Promise<boolean>): Promise<T>;
|
|
13
24
|
/**
|
package/dist/helpers/promises.js
CHANGED
|
@@ -1,11 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.retryAsync = exports.sleepAsync = exports.promiseNParallel = exports.promiseAllSequential = exports.promiseOnce = void 0;
|
|
3
|
+
exports.retryAsync = exports.sleepAsync = exports.promiseNParallel = exports.promiseAllSequential = exports.promiseOnce = exports.promiseLock = void 0;
|
|
4
4
|
const objects_1 = require("./objects");
|
|
5
5
|
const typecheckers_1 = require("./typecheckers");
|
|
6
6
|
let _global = (0, objects_1.getGlobal)("helpers_promises", {
|
|
7
7
|
promises: {}
|
|
8
8
|
});
|
|
9
|
+
/**
|
|
10
|
+
* Lock all concurrent calls to a resource to one promise for a set duration of time.
|
|
11
|
+
* @param {string} key - Unique key to identify the promise.
|
|
12
|
+
* @param {() => Promise<T>} promiseFunc - Function that will return the promise to be run only once.
|
|
13
|
+
* @param {number} duration - Duration to hold on to the promise result. (default=1)
|
|
14
|
+
* @returns {Promise<T>} Returns the single promise that will be fullfilled for all promises with the same key.
|
|
15
|
+
* @example
|
|
16
|
+
* // returns Promise<string>
|
|
17
|
+
* var initTests = await promiseLock<string>("initTests", async () => { ... }, 2);
|
|
18
|
+
*/
|
|
19
|
+
async function promiseLock(key, promiseFunc, duration = 1) {
|
|
20
|
+
return promiseOnce(key, promiseFunc).then((result) => {
|
|
21
|
+
(globalThis || window).setTimeout(() => {
|
|
22
|
+
_deletePromiseByKey(key);
|
|
23
|
+
}, (0, typecheckers_1.isNumber)(duration) && duration >= 1 ? duration : 1);
|
|
24
|
+
return result;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
exports.promiseLock = promiseLock;
|
|
9
28
|
/**
|
|
10
29
|
* Ensures that a promise runs only once
|
|
11
30
|
* @param {string} key - Unique key to identify the promise.
|
|
@@ -15,7 +34,7 @@ let _global = (0, objects_1.getGlobal)("helpers_promises", {
|
|
|
15
34
|
* @returns {Promise<T>} Returns the single promise that will be fullfilled for all promises with the same key.
|
|
16
35
|
* @example
|
|
17
36
|
* // returns Promise<string>
|
|
18
|
-
*
|
|
37
|
+
* var initTests = await promiseOnce<string>("initTests", async () => { ... });
|
|
19
38
|
*/
|
|
20
39
|
async function promiseOnce(key, promiseFunc, isValidResult) {
|
|
21
40
|
let promises = _global.promises;
|
|
@@ -26,8 +45,9 @@ async function promiseOnce(key, promiseFunc, isValidResult) {
|
|
|
26
45
|
queuedResult = await promises[key];
|
|
27
46
|
}
|
|
28
47
|
catch (e) { }
|
|
29
|
-
if ((await isValidResult(queuedResult)) !== true)
|
|
30
|
-
|
|
48
|
+
if ((await isValidResult(queuedResult)) !== true) {
|
|
49
|
+
_deletePromiseByKey(key);
|
|
50
|
+
}
|
|
31
51
|
}
|
|
32
52
|
if (!(0, objects_1.hasOwnProperty)(promises, key)) {
|
|
33
53
|
promises[key] = promiseFunc();
|
|
@@ -93,7 +113,7 @@ exports.promiseNParallel = promiseNParallel;
|
|
|
93
113
|
*/
|
|
94
114
|
function sleepAsync(seconds) {
|
|
95
115
|
return new Promise(resolve => {
|
|
96
|
-
window.setTimeout(() => resolve(), seconds > 0 ? seconds * 1000 : 3000);
|
|
116
|
+
(globalThis || window).setTimeout(() => resolve(), seconds > 0 ? seconds * 1000 : 3000);
|
|
97
117
|
});
|
|
98
118
|
}
|
|
99
119
|
exports.sleepAsync = sleepAsync;
|
|
@@ -121,4 +141,16 @@ async function retryAsync(fn, numberOfRetries, seconds = 1) {
|
|
|
121
141
|
throw new Error(`Failed retrying ${numberOfRetries} times`);
|
|
122
142
|
}
|
|
123
143
|
exports.retryAsync = retryAsync;
|
|
144
|
+
function _deletePromiseByKey(key) {
|
|
145
|
+
let promises = _global.promises;
|
|
146
|
+
if ((0, objects_1.hasOwnProperty)(promises, key)) {
|
|
147
|
+
try {
|
|
148
|
+
delete promises[key];
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
124
156
|
//# sourceMappingURL=promises.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"promises.js","sourceRoot":"","sources":["../../src/helpers/promises.ts"],"names":[],"mappings":";;;AACA,uCAAsD;AACtD,
|
|
1
|
+
{"version":3,"file":"promises.js","sourceRoot":"","sources":["../../src/helpers/promises.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import assert from 'assert/strict';
|
|
2
2
|
import test from 'node:test';
|
|
3
|
-
import { promiseOnce } from './promises';
|
|
3
|
+
import { promiseLock, promiseOnce, sleepAsync } from './promises';
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
test('promiseOnce', async t => {
|
|
7
|
-
|
|
7
|
+
let promiseOnceTester = promiseOnce("promiseOnceTester", async() => {
|
|
8
8
|
return Date.now();
|
|
9
9
|
});
|
|
10
10
|
|
|
@@ -15,4 +15,24 @@ test('promiseOnce', async t => {
|
|
|
15
15
|
await t.test("Second call", t => assert.strictEqual(value === value2, true));
|
|
16
16
|
let value3 = await promiseOnceTester;
|
|
17
17
|
await t.test("Third call", t => assert.strictEqual(value === value3, true));
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('promisLock', async t => {
|
|
21
|
+
|
|
22
|
+
let promiseLockTester = async() => {
|
|
23
|
+
return new Date().getTime();
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
let p1 = promiseLock("promiseLockTest", promiseLockTester);
|
|
27
|
+
let p2 = promiseLock("promiseLockTest", promiseLockTester);
|
|
28
|
+
|
|
29
|
+
let v1 = await p1;
|
|
30
|
+
let v2 = await p2;
|
|
31
|
+
|
|
32
|
+
await sleepAsync(1);
|
|
33
|
+
|
|
34
|
+
let v3 = await promiseLock("promiseLockTest", promiseLockTester);
|
|
35
|
+
|
|
36
|
+
await t.test("During lock", t => assert.strictEqual(v1 === v2, true));
|
|
37
|
+
await t.test("After lock", t => assert.strictEqual(v1 === v3, false));
|
|
18
38
|
});
|
package/src/helpers/promises.ts
CHANGED
|
@@ -1,12 +1,30 @@
|
|
|
1
1
|
import { IDictionary } from "./_dependencies";
|
|
2
2
|
import { getGlobal, hasOwnProperty } from "./objects";
|
|
3
|
-
import { isFunction, isNullOrUndefined } from "./typecheckers";
|
|
3
|
+
import { isFunction, isNullOrUndefined, isNumber } from "./typecheckers";
|
|
4
4
|
|
|
5
5
|
let _global = getGlobal<{ promises: IDictionary<Promise<any>> }>("helpers_promises",
|
|
6
6
|
{
|
|
7
7
|
promises: {}
|
|
8
8
|
});
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Lock all concurrent calls to a resource to one promise for a set duration of time.
|
|
12
|
+
* @param {string} key - Unique key to identify the promise.
|
|
13
|
+
* @param {() => Promise<T>} promiseFunc - Function that will return the promise to be run only once.
|
|
14
|
+
* @param {number} duration - Duration to hold on to the promise result. (default=1)
|
|
15
|
+
* @returns {Promise<T>} Returns the single promise that will be fullfilled for all promises with the same key.
|
|
16
|
+
* @example
|
|
17
|
+
* // returns Promise<string>
|
|
18
|
+
* var initTests = await promiseLock<string>("initTests", async () => { ... }, 2);
|
|
19
|
+
*/
|
|
20
|
+
export async function promiseLock<T>(key: string, promiseFunc: () => Promise<T>, duration = 1): Promise<T> {
|
|
21
|
+
return promiseOnce(key, promiseFunc).then((result) => {
|
|
22
|
+
(globalThis || window).setTimeout(() => {
|
|
23
|
+
_deletePromiseByKey(key);
|
|
24
|
+
}, isNumber(duration) && duration >= 1 ? duration : 1);
|
|
25
|
+
return result;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
10
28
|
/**
|
|
11
29
|
* Ensures that a promise runs only once
|
|
12
30
|
* @param {string} key - Unique key to identify the promise.
|
|
@@ -16,7 +34,7 @@ let _global = getGlobal<{ promises: IDictionary<Promise<any>> }>("helpers_promis
|
|
|
16
34
|
* @returns {Promise<T>} Returns the single promise that will be fullfilled for all promises with the same key.
|
|
17
35
|
* @example
|
|
18
36
|
* // returns Promise<string>
|
|
19
|
-
*
|
|
37
|
+
* var initTests = await promiseOnce<string>("initTests", async () => { ... });
|
|
20
38
|
*/
|
|
21
39
|
export async function promiseOnce<T>(key: string, promiseFunc: () => Promise<T>, isValidResult?: (result: T) => Promise<boolean>): Promise<T> {
|
|
22
40
|
let promises = _global.promises;
|
|
@@ -25,8 +43,9 @@ export async function promiseOnce<T>(key: string, promiseFunc: () => Promise<T>,
|
|
|
25
43
|
//we have en existing pending promise...
|
|
26
44
|
let queuedResult: T = null;
|
|
27
45
|
try { queuedResult = await promises[key]; } catch (e) { }
|
|
28
|
-
if ((await isValidResult(queuedResult)) !== true)
|
|
29
|
-
|
|
46
|
+
if ((await isValidResult(queuedResult)) !== true) {
|
|
47
|
+
_deletePromiseByKey(key);
|
|
48
|
+
}
|
|
30
49
|
}
|
|
31
50
|
|
|
32
51
|
if (!hasOwnProperty(promises, key)) {
|
|
@@ -100,7 +119,7 @@ export function promiseNParallel<T>(asyncFuncs: (() => Promise<T>)[], maxParalle
|
|
|
100
119
|
*/
|
|
101
120
|
export function sleepAsync(seconds?: number): Promise<void> {
|
|
102
121
|
return new Promise(resolve => {
|
|
103
|
-
window.setTimeout(() => resolve(), seconds > 0 ? seconds * 1000 : 3000);
|
|
122
|
+
(globalThis || window).setTimeout(() => resolve(), seconds > 0 ? seconds * 1000 : 3000);
|
|
104
123
|
});
|
|
105
124
|
}
|
|
106
125
|
|
|
@@ -127,4 +146,16 @@ export async function retryAsync<T>(fn: (...args) => Promise<T>, numberOfRetries
|
|
|
127
146
|
throw error;
|
|
128
147
|
}
|
|
129
148
|
throw new Error(`Failed retrying ${numberOfRetries} times`);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function _deletePromiseByKey(key: string) {
|
|
152
|
+
let promises = _global.promises;
|
|
153
|
+
if (hasOwnProperty(promises, key)) {
|
|
154
|
+
try {
|
|
155
|
+
delete promises[key];
|
|
156
|
+
return true;
|
|
157
|
+
} catch {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
130
161
|
}
|