@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
- * export var initTests = promiseOnce<string>("initTests", async () => { ... });
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
  /**
@@ -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
- * export var initTests = promiseOnce<string>("initTests", async () => { ... });
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
- delete promises[key];
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":"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"}
1
+ {"version":3,"file":"promises.js","sourceRoot":"","sources":["../../src/helpers/promises.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kwiz/common",
3
- "version": "1.0.69",
3
+ "version": "1.0.70",
4
4
  "description": "KWIZ common utilities and helpers for M365 platform",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -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
- var promiseOnceTester = promiseOnce("promiseOnceTester", async () => {
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
  });
@@ -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
- * export var initTests = promiseOnce<string>("initTests", async () => { ... });
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
- delete promises[key];
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
  }