@fluidframework/core-utils 2.0.0-dev-rc.1.0.0.224419

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.
Files changed (111) hide show
  1. package/.eslintrc.js +36 -0
  2. package/.mocharc.js +13 -0
  3. package/CHANGELOG.md +81 -0
  4. package/LICENSE +21 -0
  5. package/README.md +75 -0
  6. package/api-extractor-lint.json +4 -0
  7. package/api-extractor.json +4 -0
  8. package/api-report/core-utils.api.md +147 -0
  9. package/dist/assert.d.ts +17 -0
  10. package/dist/assert.d.ts.map +1 -0
  11. package/dist/assert.js +25 -0
  12. package/dist/assert.js.map +1 -0
  13. package/dist/compare.d.ts +16 -0
  14. package/dist/compare.d.ts.map +1 -0
  15. package/dist/compare.js +28 -0
  16. package/dist/compare.js.map +1 -0
  17. package/dist/core-utils-alpha.d.ts +191 -0
  18. package/dist/core-utils-beta.d.ts +41 -0
  19. package/dist/core-utils-public.d.ts +41 -0
  20. package/dist/core-utils-untrimmed.d.ts +414 -0
  21. package/dist/delay.d.ts +11 -0
  22. package/dist/delay.d.ts.map +1 -0
  23. package/dist/delay.js +15 -0
  24. package/dist/delay.js.map +1 -0
  25. package/dist/heap.d.ts +86 -0
  26. package/dist/heap.d.ts.map +1 -0
  27. package/dist/heap.js +144 -0
  28. package/dist/heap.js.map +1 -0
  29. package/dist/index.d.ts +14 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +30 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/lazy.d.ts +44 -0
  34. package/dist/lazy.d.ts.map +1 -0
  35. package/dist/lazy.js +84 -0
  36. package/dist/lazy.js.map +1 -0
  37. package/dist/promiseCache.d.ts +89 -0
  38. package/dist/promiseCache.d.ts.map +1 -0
  39. package/dist/promiseCache.js +148 -0
  40. package/dist/promiseCache.js.map +1 -0
  41. package/dist/promises.d.ts +38 -0
  42. package/dist/promises.d.ts.map +1 -0
  43. package/dist/promises.js +60 -0
  44. package/dist/promises.js.map +1 -0
  45. package/dist/timer.d.ts +115 -0
  46. package/dist/timer.d.ts.map +1 -0
  47. package/dist/timer.js +189 -0
  48. package/dist/timer.js.map +1 -0
  49. package/dist/tsdoc-metadata.json +11 -0
  50. package/dist/unreachable.d.ts +22 -0
  51. package/dist/unreachable.d.ts.map +1 -0
  52. package/dist/unreachable.js +28 -0
  53. package/dist/unreachable.js.map +1 -0
  54. package/lib/assert.d.ts +17 -0
  55. package/lib/assert.d.ts.map +1 -0
  56. package/lib/assert.js +25 -0
  57. package/lib/assert.js.map +1 -0
  58. package/lib/compare.d.ts +16 -0
  59. package/lib/compare.d.ts.map +1 -0
  60. package/lib/compare.js +28 -0
  61. package/lib/compare.js.map +1 -0
  62. package/lib/core-utils-alpha.d.ts +191 -0
  63. package/lib/core-utils-beta.d.ts +41 -0
  64. package/lib/core-utils-public.d.ts +41 -0
  65. package/lib/core-utils-untrimmed.d.ts +414 -0
  66. package/lib/delay.d.ts +11 -0
  67. package/lib/delay.d.ts.map +1 -0
  68. package/lib/delay.js +15 -0
  69. package/lib/delay.js.map +1 -0
  70. package/lib/heap.d.ts +86 -0
  71. package/lib/heap.d.ts.map +1 -0
  72. package/lib/heap.js +144 -0
  73. package/lib/heap.js.map +1 -0
  74. package/lib/index.d.ts +14 -0
  75. package/lib/index.d.ts.map +1 -0
  76. package/lib/index.js +30 -0
  77. package/lib/index.js.map +1 -0
  78. package/lib/lazy.d.ts +44 -0
  79. package/lib/lazy.d.ts.map +1 -0
  80. package/lib/lazy.js +84 -0
  81. package/lib/lazy.js.map +1 -0
  82. package/lib/promiseCache.d.ts +89 -0
  83. package/lib/promiseCache.d.ts.map +1 -0
  84. package/lib/promiseCache.js +148 -0
  85. package/lib/promiseCache.js.map +1 -0
  86. package/lib/promises.d.ts +38 -0
  87. package/lib/promises.d.ts.map +1 -0
  88. package/lib/promises.js +60 -0
  89. package/lib/promises.js.map +1 -0
  90. package/lib/timer.d.ts +115 -0
  91. package/lib/timer.d.ts.map +1 -0
  92. package/lib/timer.js +189 -0
  93. package/lib/timer.js.map +1 -0
  94. package/lib/unreachable.d.ts +22 -0
  95. package/lib/unreachable.d.ts.map +1 -0
  96. package/lib/unreachable.js +28 -0
  97. package/lib/unreachable.js.map +1 -0
  98. package/package.json +111 -0
  99. package/prettier.config.cjs +8 -0
  100. package/src/assert.ts +23 -0
  101. package/src/compare.ts +33 -0
  102. package/src/delay.ts +12 -0
  103. package/src/heap.ts +182 -0
  104. package/src/index.ts +21 -0
  105. package/src/lazy.ts +88 -0
  106. package/src/promiseCache.ts +205 -0
  107. package/src/promises.ts +63 -0
  108. package/src/timer.ts +289 -0
  109. package/src/unreachable.ts +24 -0
  110. package/tsconfig.esnext.json +6 -0
  111. package/tsconfig.json +12 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heap.js","sourceRoot":"","sources":["../src/heap.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Interface for a comparer.\n * @internal\n */\nexport interface IComparer<T> {\n\t/**\n\t * The minimum value of type T.\n\t */\n\tmin: T;\n\n\t/**\n\t * Compare the two value\n\t *\n\t * @returns 0 if the value is equal, negative number if a is smaller then b, positive number otherwise\n\t */\n\tcompare(a: T, b: T): number;\n}\n\n/**\n * A comparer for numbers.\n * @internal\n */\nexport const NumberComparer: IComparer<number> = {\n\t/**\n\t * The compare function for numbers.\n\t * @returns The difference of the two numbers.\n\t */\n\tcompare: (a, b): number => a - b,\n\n\t/**\n\t * The minimum value of a JavaScript number, which is `Number.MIN_VALUE`.\n\t */\n\tmin: Number.MIN_VALUE,\n};\n\n/**\n * Interface to a node in {@link Heap}.\n * @internal\n */\nexport interface IHeapNode<T> {\n\tvalue: T;\n\tposition: number;\n}\n\n/**\n * Ordered {@link https://en.wikipedia.org/wiki/Heap_(data_structure) | Heap} data structure implementation.\n * @internal\n */\nexport class Heap<T> {\n\tprivate L: IHeapNode<T>[];\n\n\t/**\n\t * Creates an instance of `Heap` with comparer.\n\t * @param comp - A comparer that specify how elements are ordered.\n\t */\n\tconstructor(public comp: IComparer<T>) {\n\t\tthis.L = [{ value: comp.min, position: 0 }];\n\t}\n\n\t/**\n\t * Return the smallest element in the heap as determined by the order of the comparer\n\t *\n\t * @returns Heap node containing the smallest element\n\t */\n\tpublic peek(): IHeapNode<T> | undefined {\n\t\treturn this.L[1];\n\t}\n\n\t/**\n\t * Get and remove the smallest element in the heap as determined by the order of the comparer\n\t *\n\t * @returns The smallest value in the heap\n\t */\n\tpublic get(): T | undefined {\n\t\tif (this.L.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tthis.swap(1, this.count());\n\t\tconst x = this.L.pop();\n\t\tthis.fixdown(1);\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\treturn x!.value;\n\t}\n\n\t/**\n\t * Add a value to the heap\n\t *\n\t * @param x - value to add\n\t * @returns The heap node that contains the value\n\t */\n\tpublic add(x: T): IHeapNode<T> {\n\t\tconst node = { value: x, position: this.L.length };\n\t\tthis.L.push(node);\n\t\tthis.fixup(this.count());\n\n\t\treturn node;\n\t}\n\n\t/**\n\t * Allows for the Heap to be updated after a node's value changes.\n\t */\n\tpublic update(node: IHeapNode<T>): void {\n\t\tconst k = node.position;\n\t\tif (this.isGreaterThanParent(k)) {\n\t\t\tthis.fixup(k);\n\t\t} else {\n\t\t\tthis.fixdown(k);\n\t\t}\n\t}\n\n\t/**\n\t * Removes the given node from the heap.\n\t *\n\t * @param node - The node to remove from the heap.\n\t */\n\tpublic remove(node: IHeapNode<T>): void {\n\t\t// Move the node we want to remove to the end of the array\n\t\tconst position = node.position;\n\t\tthis.swap(node.position, this.L.length - 1);\n\t\tthis.L.splice(-1);\n\n\t\t// Update the swapped node assuming we didn't remove the end of the list\n\t\tif (position !== this.L.length) {\n\t\t\tthis.update(this.L[position]);\n\t\t}\n\t}\n\n\t/**\n\t * Get the number of elements in the Heap.\n\t *\n\t * @returns The number of elements in the Heap.\n\t */\n\tpublic count(): number {\n\t\treturn this.L.length - 1;\n\t}\n\n\tprivate fixup(pos: number): void {\n\t\tlet k = pos;\n\t\twhile (this.isGreaterThanParent(k)) {\n\t\t\t// eslint-disable-next-line no-bitwise\n\t\t\tconst parent = k >> 1;\n\t\t\tthis.swap(k, parent);\n\t\t\tk = parent;\n\t\t}\n\t}\n\n\tprivate isGreaterThanParent(k: number): boolean {\n\t\t// eslint-disable-next-line no-bitwise\n\t\treturn k > 1 && this.comp.compare(this.L[k >> 1].value, this.L[k].value) > 0;\n\t}\n\n\tprivate fixdown(pos: number): void {\n\t\tlet k = pos;\n\t\t// eslint-disable-next-line no-bitwise\n\t\twhile (k << 1 <= this.count()) {\n\t\t\t// eslint-disable-next-line no-bitwise\n\t\t\tlet j = k << 1;\n\t\t\tif (j < this.count() && this.comp.compare(this.L[j].value, this.L[j + 1].value) > 0) {\n\t\t\t\tj++;\n\t\t\t}\n\t\t\tif (this.comp.compare(this.L[k].value, this.L[j].value) <= 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tthis.swap(k, j);\n\t\t\tk = j;\n\t\t}\n\t}\n\n\tprivate swap(k: number, j: number): void {\n\t\tconst tmp = this.L[k];\n\t\tthis.L[k] = this.L[j];\n\t\tthis.L[k].position = k;\n\t\tthis.L[j] = tmp;\n\t\tthis.L[j].position = j;\n\t}\n}\n"]}
package/lib/index.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ export { assert } from "./assert";
6
+ export { compareArrays } from "./compare";
7
+ export { delay } from "./delay";
8
+ export { Heap, IComparer, IHeapNode, NumberComparer } from "./heap";
9
+ export { Lazy, LazyPromise } from "./lazy";
10
+ export { PromiseCache, PromiseCacheExpiry, PromiseCacheOptions } from "./promiseCache";
11
+ export { Deferred } from "./promises";
12
+ export { IPromiseTimer, IPromiseTimerResult, ITimer, PromiseTimer, setLongTimeout, Timer, } from "./timer";
13
+ export { unreachableCase } from "./unreachable";
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AACpE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACvF,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EACN,aAAa,EACb,mBAAmB,EACnB,MAAM,EACN,YAAY,EACZ,cAAc,EACd,KAAK,GACL,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
package/lib/index.js ADDED
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.unreachableCase = exports.Timer = exports.setLongTimeout = exports.PromiseTimer = exports.Deferred = exports.PromiseCache = exports.LazyPromise = exports.Lazy = exports.NumberComparer = exports.Heap = exports.delay = exports.compareArrays = exports.assert = void 0;
8
+ var assert_1 = require("./assert");
9
+ Object.defineProperty(exports, "assert", { enumerable: true, get: function () { return assert_1.assert; } });
10
+ var compare_1 = require("./compare");
11
+ Object.defineProperty(exports, "compareArrays", { enumerable: true, get: function () { return compare_1.compareArrays; } });
12
+ var delay_1 = require("./delay");
13
+ Object.defineProperty(exports, "delay", { enumerable: true, get: function () { return delay_1.delay; } });
14
+ var heap_1 = require("./heap");
15
+ Object.defineProperty(exports, "Heap", { enumerable: true, get: function () { return heap_1.Heap; } });
16
+ Object.defineProperty(exports, "NumberComparer", { enumerable: true, get: function () { return heap_1.NumberComparer; } });
17
+ var lazy_1 = require("./lazy");
18
+ Object.defineProperty(exports, "Lazy", { enumerable: true, get: function () { return lazy_1.Lazy; } });
19
+ Object.defineProperty(exports, "LazyPromise", { enumerable: true, get: function () { return lazy_1.LazyPromise; } });
20
+ var promiseCache_1 = require("./promiseCache");
21
+ Object.defineProperty(exports, "PromiseCache", { enumerable: true, get: function () { return promiseCache_1.PromiseCache; } });
22
+ var promises_1 = require("./promises");
23
+ Object.defineProperty(exports, "Deferred", { enumerable: true, get: function () { return promises_1.Deferred; } });
24
+ var timer_1 = require("./timer");
25
+ Object.defineProperty(exports, "PromiseTimer", { enumerable: true, get: function () { return timer_1.PromiseTimer; } });
26
+ Object.defineProperty(exports, "setLongTimeout", { enumerable: true, get: function () { return timer_1.setLongTimeout; } });
27
+ Object.defineProperty(exports, "Timer", { enumerable: true, get: function () { return timer_1.Timer; } });
28
+ var unreachable_1 = require("./unreachable");
29
+ Object.defineProperty(exports, "unreachableCase", { enumerable: true, get: function () { return unreachable_1.unreachableCase; } });
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,mCAAkC;AAAzB,gGAAA,MAAM,OAAA;AACf,qCAA0C;AAAjC,wGAAA,aAAa,OAAA;AACtB,iCAAgC;AAAvB,8FAAA,KAAK,OAAA;AACd,+BAAoE;AAA3D,4FAAA,IAAI,OAAA;AAAwB,sGAAA,cAAc,OAAA;AACnD,+BAA2C;AAAlC,4FAAA,IAAI,OAAA;AAAE,mGAAA,WAAW,OAAA;AAC1B,+CAAuF;AAA9E,4GAAA,YAAY,OAAA;AACrB,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA;AACjB,iCAOiB;AAHhB,qGAAA,YAAY,OAAA;AACZ,uGAAA,cAAc,OAAA;AACd,8FAAA,KAAK,OAAA;AAEN,6CAAgD;AAAvC,8GAAA,eAAe,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { assert } from \"./assert\";\nexport { compareArrays } from \"./compare\";\nexport { delay } from \"./delay\";\nexport { Heap, IComparer, IHeapNode, NumberComparer } from \"./heap\";\nexport { Lazy, LazyPromise } from \"./lazy\";\nexport { PromiseCache, PromiseCacheExpiry, PromiseCacheOptions } from \"./promiseCache\";\nexport { Deferred } from \"./promises\";\nexport {\n\tIPromiseTimer,\n\tIPromiseTimerResult,\n\tITimer,\n\tPromiseTimer,\n\tsetLongTimeout,\n\tTimer,\n} from \"./timer\";\nexport { unreachableCase } from \"./unreachable\";\n"]}
package/lib/lazy.d.ts ADDED
@@ -0,0 +1,44 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ /**
6
+ * Helper class for lazy initialized values. Ensures the value is only generated once, and remain immutable.
7
+ * @internal
8
+ */
9
+ export declare class Lazy<T> {
10
+ private readonly valueGenerator;
11
+ private _value;
12
+ private _evaluated;
13
+ /**
14
+ * Instantiates an instance of Lazy<T>.
15
+ * @param valueGenerator - The function that will generate the value when value is accessed the first time.
16
+ */
17
+ constructor(valueGenerator: () => T);
18
+ /**
19
+ * Return true if the value as been generated, otherwise false.
20
+ */
21
+ get evaluated(): boolean;
22
+ /**
23
+ * Get the value. If this is the first call the value will be generated.
24
+ */
25
+ get value(): T;
26
+ }
27
+ /**
28
+ * A lazy evaluated promise. The execute function is delayed until
29
+ * the promise is used, e.g. await, then, catch ...
30
+ * The execute function is only called once.
31
+ * All calls are then proxied to the promise returned by the execute method.
32
+ * @alpha
33
+ */
34
+ export declare class LazyPromise<T> implements Promise<T> {
35
+ private readonly execute;
36
+ get [Symbol.toStringTag](): string;
37
+ private result;
38
+ constructor(execute: () => Promise<T>);
39
+ then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined): Promise<TResult1 | TResult2>;
40
+ catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null | undefined): Promise<T | TResult>;
41
+ finally(onfinally?: (() => void) | null | undefined): Promise<T>;
42
+ private getPromise;
43
+ }
44
+ //# sourceMappingURL=lazy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lazy.d.ts","sourceRoot":"","sources":["../src/lazy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,qBAAa,IAAI,CAAC,CAAC;IAOC,OAAO,CAAC,QAAQ,CAAC,cAAc;IANlD,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,UAAU,CAAkB;IACpC;;;OAGG;gBACiC,cAAc,EAAE,MAAM,CAAC;IAE3D;;OAEG;IACH,IAAW,SAAS,IAAI,OAAO,CAE9B;IAED;;OAEG;IACH,IAAW,KAAK,IAAI,CAAC,CAOpB;CACD;AAED;;;;;;GAMG;AACH,qBAAa,WAAW,CAAC,CAAC,CAAE,YAAW,OAAO,CAAC,CAAC,CAAC;IAO7B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAN3C,IAAW,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,MAAM,CAExC;IAED,OAAO,CAAC,MAAM,CAAyB;gBAEH,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC;IAGhD,IAAI,CAAC,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,KAAK,EAE/C,WAAW,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,EAGjF,UAAU,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,GAAG,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,GACjF,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAKlB,KAAK,CAAC,OAAO,GAAG,KAAK,EAGjC,UAAU,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,GAAG,KAAK,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,GAC/E,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC;IAMV,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC;YAK/D,UAAU;CAMxB"}
package/lib/lazy.js ADDED
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.LazyPromise = exports.Lazy = void 0;
8
+ /**
9
+ * Helper class for lazy initialized values. Ensures the value is only generated once, and remain immutable.
10
+ * @internal
11
+ */
12
+ class Lazy {
13
+ /**
14
+ * Instantiates an instance of Lazy<T>.
15
+ * @param valueGenerator - The function that will generate the value when value is accessed the first time.
16
+ */
17
+ constructor(valueGenerator) {
18
+ this.valueGenerator = valueGenerator;
19
+ this._evaluated = false;
20
+ }
21
+ /**
22
+ * Return true if the value as been generated, otherwise false.
23
+ */
24
+ get evaluated() {
25
+ return this._evaluated;
26
+ }
27
+ /**
28
+ * Get the value. If this is the first call the value will be generated.
29
+ */
30
+ get value() {
31
+ if (!this._evaluated) {
32
+ this._evaluated = true;
33
+ this._value = this.valueGenerator();
34
+ }
35
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
36
+ return this._value;
37
+ }
38
+ }
39
+ exports.Lazy = Lazy;
40
+ /**
41
+ * A lazy evaluated promise. The execute function is delayed until
42
+ * the promise is used, e.g. await, then, catch ...
43
+ * The execute function is only called once.
44
+ * All calls are then proxied to the promise returned by the execute method.
45
+ * @alpha
46
+ */
47
+ class LazyPromise {
48
+ get [Symbol.toStringTag]() {
49
+ return this.getPromise()[Symbol.toStringTag];
50
+ }
51
+ constructor(execute) {
52
+ this.execute = execute;
53
+ }
54
+ // eslint-disable-next-line unicorn/no-thenable
55
+ async then(
56
+ // eslint-disable-next-line @rushstack/no-new-null
57
+ onfulfilled,
58
+ // TODO: Use `unknown` instead (API breaking)
59
+ // eslint-disable-next-line @rushstack/no-new-null, @typescript-eslint/no-explicit-any
60
+ onrejected) {
61
+ // eslint-disable-next-line prefer-rest-params
62
+ return this.getPromise().then(...arguments);
63
+ }
64
+ async catch(
65
+ // TODO: Use `unknown` instead (API breaking)
66
+ // eslint-disable-next-line @rushstack/no-new-null, @typescript-eslint/no-explicit-any
67
+ onrejected) {
68
+ // eslint-disable-next-line prefer-rest-params
69
+ return this.getPromise().catch(...arguments);
70
+ }
71
+ // eslint-disable-next-line @rushstack/no-new-null
72
+ async finally(onfinally) {
73
+ // eslint-disable-next-line prefer-rest-params
74
+ return this.getPromise().finally(...arguments);
75
+ }
76
+ async getPromise() {
77
+ if (this.result === undefined) {
78
+ this.result = this.execute();
79
+ }
80
+ return this.result;
81
+ }
82
+ }
83
+ exports.LazyPromise = LazyPromise;
84
+ //# sourceMappingURL=lazy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lazy.js","sourceRoot":"","sources":["../src/lazy.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;;GAGG;AACH,MAAa,IAAI;IAGhB;;;OAGG;IACH,YAAoC,cAAuB;QAAvB,mBAAc,GAAd,cAAc,CAAS;QALnD,eAAU,GAAY,KAAK,CAAC;IAK0B,CAAC;IAE/D;;OAEG;IACH,IAAW,SAAS;QACnB,OAAO,IAAI,CAAC,UAAU,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,IAAW,KAAK;QACf,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;YACrB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACvB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;SACpC;QACD,oEAAoE;QACpE,OAAO,IAAI,CAAC,MAAO,CAAC;IACrB,CAAC;CACD;AA3BD,oBA2BC;AAED;;;;;;GAMG;AACH,MAAa,WAAW;IACvB,IAAW,CAAC,MAAM,CAAC,WAAW,CAAC;QAC9B,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC9C,CAAC;IAID,YAAoC,OAAyB;QAAzB,YAAO,GAAP,OAAO,CAAkB;IAAG,CAAC;IAEjE,+CAA+C;IACxC,KAAK,CAAC,IAAI;IAChB,kDAAkD;IAClD,WAAiF;IACjF,6CAA6C;IAC7C,sFAAsF;IACtF,UAAmF;QAEnF,8CAA8C;QAC9C,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC,IAAI,CAAqB,GAAG,SAAS,CAAC,CAAC;IACjE,CAAC;IAEM,KAAK,CAAC,KAAK;IACjB,6CAA6C;IAC7C,sFAAsF;IACtF,UAAiF;QAEjF,8CAA8C;QAC9C,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC,KAAK,CAAU,GAAG,SAAS,CAAC,CAAC;IACvD,CAAC;IAED,kDAAkD;IAC3C,KAAK,CAAC,OAAO,CAAC,SAA2C;QAC/D,8CAA8C;QAC9C,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;IAChD,CAAC;IAEO,KAAK,CAAC,UAAU;QACvB,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE;YAC9B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;SAC7B;QACD,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;CACD;AA1CD,kCA0CC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Helper class for lazy initialized values. Ensures the value is only generated once, and remain immutable.\n * @internal\n */\nexport class Lazy<T> {\n\tprivate _value: T | undefined;\n\tprivate _evaluated: boolean = false;\n\t/**\n\t * Instantiates an instance of Lazy<T>.\n\t * @param valueGenerator - The function that will generate the value when value is accessed the first time.\n\t */\n\tpublic constructor(private readonly valueGenerator: () => T) {}\n\n\t/**\n\t * Return true if the value as been generated, otherwise false.\n\t */\n\tpublic get evaluated(): boolean {\n\t\treturn this._evaluated;\n\t}\n\n\t/**\n\t * Get the value. If this is the first call the value will be generated.\n\t */\n\tpublic get value(): T {\n\t\tif (!this._evaluated) {\n\t\t\tthis._evaluated = true;\n\t\t\tthis._value = this.valueGenerator();\n\t\t}\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\treturn this._value!;\n\t}\n}\n\n/**\n * A lazy evaluated promise. The execute function is delayed until\n * the promise is used, e.g. await, then, catch ...\n * The execute function is only called once.\n * All calls are then proxied to the promise returned by the execute method.\n * @alpha\n */\nexport class LazyPromise<T> implements Promise<T> {\n\tpublic get [Symbol.toStringTag](): string {\n\t\treturn this.getPromise()[Symbol.toStringTag];\n\t}\n\n\tprivate result: Promise<T> | undefined;\n\n\tpublic constructor(private readonly execute: () => Promise<T>) {}\n\n\t// eslint-disable-next-line unicorn/no-thenable\n\tpublic async then<TResult1 = T, TResult2 = never>(\n\t\t// eslint-disable-next-line @rushstack/no-new-null\n\t\tonfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null | undefined,\n\t\t// TODO: Use `unknown` instead (API breaking)\n\t\t// eslint-disable-next-line @rushstack/no-new-null, @typescript-eslint/no-explicit-any\n\t\tonrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined,\n\t): Promise<TResult1 | TResult2> {\n\t\t// eslint-disable-next-line prefer-rest-params\n\t\treturn this.getPromise().then<TResult1, TResult2>(...arguments);\n\t}\n\n\tpublic async catch<TResult = never>(\n\t\t// TODO: Use `unknown` instead (API breaking)\n\t\t// eslint-disable-next-line @rushstack/no-new-null, @typescript-eslint/no-explicit-any\n\t\tonrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null | undefined,\n\t): Promise<T | TResult> {\n\t\t// eslint-disable-next-line prefer-rest-params\n\t\treturn this.getPromise().catch<TResult>(...arguments);\n\t}\n\n\t// eslint-disable-next-line @rushstack/no-new-null\n\tpublic async finally(onfinally?: (() => void) | null | undefined): Promise<T> {\n\t\t// eslint-disable-next-line prefer-rest-params\n\t\treturn this.getPromise().finally(...arguments);\n\t}\n\n\tprivate async getPromise(): Promise<T> {\n\t\tif (this.result === undefined) {\n\t\t\tthis.result = this.execute();\n\t\t}\n\t\treturn this.result;\n\t}\n}\n"]}
@@ -0,0 +1,89 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ /**
6
+ * Three supported expiry policies:
7
+ * - indefinite: entries don't expire and must be explicitly removed
8
+ * - absolute: entries expire after the given duration in MS, even if accessed multiple times in the mean time
9
+ * - sliding: entries expire after the given duration in MS of inactivity (i.e. get resets the clock)
10
+ * @alpha
11
+ */
12
+ export type PromiseCacheExpiry = {
13
+ policy: "indefinite";
14
+ } | {
15
+ policy: "absolute" | "sliding";
16
+ durationMs: number;
17
+ };
18
+ /**
19
+ * Options for configuring the {@link PromiseCache}
20
+ * @alpha
21
+ */
22
+ export interface PromiseCacheOptions {
23
+ /**
24
+ * Common expiration policy for all items added to this cache
25
+ */
26
+ expiry?: PromiseCacheExpiry;
27
+ /**
28
+ * If the stored Promise is rejected with a particular error, should the given key be removed?
29
+ */
30
+ removeOnError?: (error: any) => boolean;
31
+ }
32
+ /**
33
+ * A specialized cache for async work, allowing you to safely cache the promised result of some async work
34
+ * without fear of running it multiple times or losing track of errors.
35
+ * @alpha
36
+ */
37
+ export declare class PromiseCache<TKey, TResult> {
38
+ private readonly cache;
39
+ private readonly gc;
40
+ private readonly removeOnError;
41
+ /**
42
+ * Create the PromiseCache with the given options, with the following defaults:
43
+ *
44
+ * expiry: indefinite, removeOnError: true for all errors
45
+ */
46
+ constructor({ expiry, removeOnError, }?: PromiseCacheOptions);
47
+ /**
48
+ * Check if there's anything cached at the given key
49
+ */
50
+ has(key: TKey): boolean;
51
+ /**
52
+ * Get the Promise for the given key, or undefined if it's not found.
53
+ * Extend expiry if applicable.
54
+ */
55
+ get(key: TKey): Promise<TResult> | undefined;
56
+ /**
57
+ * Remove the Promise for the given key, returning true if it was found and removed
58
+ */
59
+ remove(key: TKey): boolean;
60
+ /**
61
+ * Try to add the result of the given asyncFn, without overwriting an existing cache entry at that key.
62
+ * Returns a Promise for the added or existing async work being done at that key.
63
+ * @param key - key name where to store the async work
64
+ * @param asyncFn - the async work to do and store, if not already in progress under the given key
65
+ */
66
+ addOrGet(key: TKey, asyncFn: () => Promise<TResult>): Promise<TResult>;
67
+ /**
68
+ * Try to add the result of the given asyncFn, without overwriting an existing cache entry at that key.
69
+ * Returns false if the cache already contained an entry at that key, and true otherwise.
70
+ * @param key - key name where to store the async work
71
+ * @param asyncFn - the async work to do and store, if not already in progress under the given key
72
+ */
73
+ add(key: TKey, asyncFn: () => Promise<TResult>): boolean;
74
+ /**
75
+ * Try to add the given value, without overwriting an existing cache entry at that key.
76
+ * Returns a Promise for the added or existing async work being done at that key.
77
+ * @param key - key name where to store the async work
78
+ * @param value - value to store
79
+ */
80
+ addValueOrGet(key: TKey, value: TResult): Promise<TResult>;
81
+ /**
82
+ * Try to add the given value, without overwriting an existing cache entry at that key.
83
+ * Returns false if the cache already contained an entry at that key, and true otherwise.
84
+ * @param key - key name where to store the value
85
+ * @param value - value to store
86
+ */
87
+ addValue(key: TKey, value: TResult): boolean;
88
+ }
89
+ //# sourceMappingURL=promiseCache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promiseCache.d.ts","sourceRoot":"","sources":["../src/promiseCache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAC3B;IACA,MAAM,EAAE,YAAY,CAAC;CACpB,GACD;IACA,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;CAClB,CAAC;AAEL;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IACnC;;OAEG;IACH,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B;;OAEG;IAGH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC;CACxC;AAoDD;;;;GAIG;AACH,qBAAa,YAAY,CAAC,IAAI,EAAE,OAAO;IACtC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqC;IAC3D,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAyB;IAE5C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA8B;IAE5D;;;;OAIG;gBACgB,EAClB,MAAiC,EACjC,aAAmC,GACnC,GAAE,mBAAwB;IAK3B;;OAEG;IACI,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO;IAI9B;;;OAGG;IACI,GAAG,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,SAAS;IAOnD;;OAEG;IACI,MAAM,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO;IAKjC;;;;;OAKG;IACU,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAyBnF;;;;;OAKG;IACI,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO;IAU/D;;;;;OAKG;IACU,aAAa,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAIvE;;;;;OAKG;IACI,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO;CAGnD"}
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.PromiseCache = void 0;
8
+ /**
9
+ * Handles garbage collection of expiring cache entries.
10
+ * Not exported.
11
+ */
12
+ class GarbageCollector {
13
+ constructor(expiry, cleanup) {
14
+ this.expiry = expiry;
15
+ this.cleanup = cleanup;
16
+ this.gcTimeouts = new Map();
17
+ }
18
+ /**
19
+ * Schedule GC for the given key, as applicable
20
+ */
21
+ schedule(key) {
22
+ if (this.expiry.policy !== "indefinite") {
23
+ this.gcTimeouts.set(key, setTimeout(() => {
24
+ this.cleanup(key);
25
+ this.cancel(key);
26
+ }, this.expiry.durationMs));
27
+ }
28
+ }
29
+ /**
30
+ * Cancel any pending GC for the given key
31
+ */
32
+ cancel(key) {
33
+ const timeout = this.gcTimeouts.get(key);
34
+ if (timeout !== undefined) {
35
+ clearTimeout(timeout);
36
+ this.gcTimeouts.delete(key);
37
+ }
38
+ }
39
+ /**
40
+ * Update any pending GC for the given key, as applicable
41
+ */
42
+ update(key) {
43
+ // Cancel/reschedule new GC if the policy is sliding
44
+ if (this.expiry.policy === "sliding") {
45
+ this.cancel(key);
46
+ this.schedule(key);
47
+ }
48
+ }
49
+ }
50
+ /**
51
+ * A specialized cache for async work, allowing you to safely cache the promised result of some async work
52
+ * without fear of running it multiple times or losing track of errors.
53
+ * @alpha
54
+ */
55
+ class PromiseCache {
56
+ /**
57
+ * Create the PromiseCache with the given options, with the following defaults:
58
+ *
59
+ * expiry: indefinite, removeOnError: true for all errors
60
+ */
61
+ constructor({ expiry = { policy: "indefinite" }, removeOnError = () => true, } = {}) {
62
+ this.cache = new Map();
63
+ this.removeOnError = removeOnError;
64
+ this.gc = new GarbageCollector(expiry, (key) => this.remove(key));
65
+ }
66
+ /**
67
+ * Check if there's anything cached at the given key
68
+ */
69
+ has(key) {
70
+ return this.cache.has(key);
71
+ }
72
+ /**
73
+ * Get the Promise for the given key, or undefined if it's not found.
74
+ * Extend expiry if applicable.
75
+ */
76
+ get(key) {
77
+ if (this.has(key)) {
78
+ this.gc.update(key);
79
+ }
80
+ return this.cache.get(key);
81
+ }
82
+ /**
83
+ * Remove the Promise for the given key, returning true if it was found and removed
84
+ */
85
+ remove(key) {
86
+ this.gc.cancel(key);
87
+ return this.cache.delete(key);
88
+ }
89
+ /**
90
+ * Try to add the result of the given asyncFn, without overwriting an existing cache entry at that key.
91
+ * Returns a Promise for the added or existing async work being done at that key.
92
+ * @param key - key name where to store the async work
93
+ * @param asyncFn - the async work to do and store, if not already in progress under the given key
94
+ */
95
+ async addOrGet(key, asyncFn) {
96
+ // NOTE: Do not await the Promise returned by asyncFn!
97
+ // Let the caller do so once we return or after a subsequent call to get
98
+ let promise = this.get(key);
99
+ if (promise === undefined) {
100
+ // Wrap in an async lambda in case asyncFn disabled @typescript-eslint/promise-function-async
101
+ const safeAsyncFn = async () => asyncFn();
102
+ // Start the async work and put the Promise in the cache
103
+ promise = safeAsyncFn();
104
+ this.cache.set(key, promise);
105
+ // If asyncFn throws, we may remove the Promise from the cache
106
+ promise.catch((error) => {
107
+ if (this.removeOnError(error)) {
108
+ this.remove(key);
109
+ }
110
+ });
111
+ this.gc.schedule(key);
112
+ }
113
+ return promise;
114
+ }
115
+ /**
116
+ * Try to add the result of the given asyncFn, without overwriting an existing cache entry at that key.
117
+ * Returns false if the cache already contained an entry at that key, and true otherwise.
118
+ * @param key - key name where to store the async work
119
+ * @param asyncFn - the async work to do and store, if not already in progress under the given key
120
+ */
121
+ add(key, asyncFn) {
122
+ const alreadyPresent = this.has(key);
123
+ // We are blindly adding the Promise to the cache here, which introduces a Promise in this scope.
124
+ // Swallow Promise rejections here, since whoever gets this out of the cache to use it will await/catch.
125
+ this.addOrGet(key, asyncFn).catch(() => { });
126
+ return !alreadyPresent;
127
+ }
128
+ /**
129
+ * Try to add the given value, without overwriting an existing cache entry at that key.
130
+ * Returns a Promise for the added or existing async work being done at that key.
131
+ * @param key - key name where to store the async work
132
+ * @param value - value to store
133
+ */
134
+ async addValueOrGet(key, value) {
135
+ return this.addOrGet(key, async () => value);
136
+ }
137
+ /**
138
+ * Try to add the given value, without overwriting an existing cache entry at that key.
139
+ * Returns false if the cache already contained an entry at that key, and true otherwise.
140
+ * @param key - key name where to store the value
141
+ * @param value - value to store
142
+ */
143
+ addValue(key, value) {
144
+ return this.add(key, async () => value);
145
+ }
146
+ }
147
+ exports.PromiseCache = PromiseCache;
148
+ //# sourceMappingURL=promiseCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promiseCache.js","sourceRoot":"","sources":["../src/promiseCache.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Three supported expiry policies:\n * - indefinite: entries don't expire and must be explicitly removed\n * - absolute: entries expire after the given duration in MS, even if accessed multiple times in the mean time\n * - sliding: entries expire after the given duration in MS of inactivity (i.e. get resets the clock)\n * @alpha\n */\nexport type PromiseCacheExpiry =\n\t| {\n\t\t\tpolicy: \"indefinite\";\n\t }\n\t| {\n\t\t\tpolicy: \"absolute\" | \"sliding\";\n\t\t\tdurationMs: number;\n\t };\n\n/**\n * Options for configuring the {@link PromiseCache}\n * @alpha\n */\nexport interface PromiseCacheOptions {\n\t/**\n\t * Common expiration policy for all items added to this cache\n\t */\n\texpiry?: PromiseCacheExpiry;\n\t/**\n\t * If the stored Promise is rejected with a particular error, should the given key be removed?\n\t */\n\t// TODO: Use `unknown` instead (API breaking)\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tremoveOnError?: (error: any) => boolean;\n}\n\n/**\n * Handles garbage collection of expiring cache entries.\n * Not exported.\n */\nclass GarbageCollector<TKey> {\n\tprivate readonly gcTimeouts = new Map<TKey, ReturnType<typeof setTimeout>>();\n\n\tpublic constructor(\n\t\tprivate readonly expiry: PromiseCacheExpiry,\n\t\tprivate readonly cleanup: (key: TKey) => void,\n\t) {}\n\n\t/**\n\t * Schedule GC for the given key, as applicable\n\t */\n\tpublic schedule(key: TKey): void {\n\t\tif (this.expiry.policy !== \"indefinite\") {\n\t\t\tthis.gcTimeouts.set(\n\t\t\t\tkey,\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tthis.cleanup(key);\n\t\t\t\t\tthis.cancel(key);\n\t\t\t\t}, this.expiry.durationMs),\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Cancel any pending GC for the given key\n\t */\n\tpublic cancel(key: TKey): void {\n\t\tconst timeout = this.gcTimeouts.get(key);\n\t\tif (timeout !== undefined) {\n\t\t\tclearTimeout(timeout);\n\t\t\tthis.gcTimeouts.delete(key);\n\t\t}\n\t}\n\n\t/**\n\t * Update any pending GC for the given key, as applicable\n\t */\n\tpublic update(key: TKey): void {\n\t\t// Cancel/reschedule new GC if the policy is sliding\n\t\tif (this.expiry.policy === \"sliding\") {\n\t\t\tthis.cancel(key);\n\t\t\tthis.schedule(key);\n\t\t}\n\t}\n}\n\n/**\n * A specialized cache for async work, allowing you to safely cache the promised result of some async work\n * without fear of running it multiple times or losing track of errors.\n * @alpha\n */\nexport class PromiseCache<TKey, TResult> {\n\tprivate readonly cache = new Map<TKey, Promise<TResult>>();\n\tprivate readonly gc: GarbageCollector<TKey>;\n\n\tprivate readonly removeOnError: (error: unknown) => boolean;\n\n\t/**\n\t * Create the PromiseCache with the given options, with the following defaults:\n\t *\n\t * expiry: indefinite, removeOnError: true for all errors\n\t */\n\tpublic constructor({\n\t\texpiry = { policy: \"indefinite\" },\n\t\tremoveOnError = (): boolean => true,\n\t}: PromiseCacheOptions = {}) {\n\t\tthis.removeOnError = removeOnError;\n\t\tthis.gc = new GarbageCollector<TKey>(expiry, (key) => this.remove(key));\n\t}\n\n\t/**\n\t * Check if there's anything cached at the given key\n\t */\n\tpublic has(key: TKey): boolean {\n\t\treturn this.cache.has(key);\n\t}\n\n\t/**\n\t * Get the Promise for the given key, or undefined if it's not found.\n\t * Extend expiry if applicable.\n\t */\n\tpublic get(key: TKey): Promise<TResult> | undefined {\n\t\tif (this.has(key)) {\n\t\t\tthis.gc.update(key);\n\t\t}\n\t\treturn this.cache.get(key);\n\t}\n\n\t/**\n\t * Remove the Promise for the given key, returning true if it was found and removed\n\t */\n\tpublic remove(key: TKey): boolean {\n\t\tthis.gc.cancel(key);\n\t\treturn this.cache.delete(key);\n\t}\n\n\t/**\n\t * Try to add the result of the given asyncFn, without overwriting an existing cache entry at that key.\n\t * Returns a Promise for the added or existing async work being done at that key.\n\t * @param key - key name where to store the async work\n\t * @param asyncFn - the async work to do and store, if not already in progress under the given key\n\t */\n\tpublic async addOrGet(key: TKey, asyncFn: () => Promise<TResult>): Promise<TResult> {\n\t\t// NOTE: Do not await the Promise returned by asyncFn!\n\t\t// Let the caller do so once we return or after a subsequent call to get\n\t\tlet promise = this.get(key);\n\t\tif (promise === undefined) {\n\t\t\t// Wrap in an async lambda in case asyncFn disabled @typescript-eslint/promise-function-async\n\t\t\tconst safeAsyncFn = async (): Promise<TResult> => asyncFn();\n\n\t\t\t// Start the async work and put the Promise in the cache\n\t\t\tpromise = safeAsyncFn();\n\t\t\tthis.cache.set(key, promise);\n\n\t\t\t// If asyncFn throws, we may remove the Promise from the cache\n\t\t\tpromise.catch((error) => {\n\t\t\t\tif (this.removeOnError(error)) {\n\t\t\t\t\tthis.remove(key);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.gc.schedule(key);\n\t\t}\n\n\t\treturn promise;\n\t}\n\n\t/**\n\t * Try to add the result of the given asyncFn, without overwriting an existing cache entry at that key.\n\t * Returns false if the cache already contained an entry at that key, and true otherwise.\n\t * @param key - key name where to store the async work\n\t * @param asyncFn - the async work to do and store, if not already in progress under the given key\n\t */\n\tpublic add(key: TKey, asyncFn: () => Promise<TResult>): boolean {\n\t\tconst alreadyPresent = this.has(key);\n\n\t\t// We are blindly adding the Promise to the cache here, which introduces a Promise in this scope.\n\t\t// Swallow Promise rejections here, since whoever gets this out of the cache to use it will await/catch.\n\t\tthis.addOrGet(key, asyncFn).catch(() => {});\n\n\t\treturn !alreadyPresent;\n\t}\n\n\t/**\n\t * Try to add the given value, without overwriting an existing cache entry at that key.\n\t * Returns a Promise for the added or existing async work being done at that key.\n\t * @param key - key name where to store the async work\n\t * @param value - value to store\n\t */\n\tpublic async addValueOrGet(key: TKey, value: TResult): Promise<TResult> {\n\t\treturn this.addOrGet(key, async () => value);\n\t}\n\n\t/**\n\t * Try to add the given value, without overwriting an existing cache entry at that key.\n\t * Returns false if the cache already contained an entry at that key, and true otherwise.\n\t * @param key - key name where to store the value\n\t * @param value - value to store\n\t */\n\tpublic addValue(key: TKey, value: TResult): boolean {\n\t\treturn this.add(key, async () => value);\n\t}\n}\n"]}
@@ -0,0 +1,38 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ /**
6
+ * A deferred creates a promise and the ability to resolve or reject it
7
+ * @alpha
8
+ */
9
+ export declare class Deferred<T> {
10
+ private readonly p;
11
+ private res;
12
+ private rej;
13
+ private completed;
14
+ constructor();
15
+ /**
16
+ * Returns whether the underlying promise has been completed
17
+ */
18
+ get isCompleted(): boolean;
19
+ /**
20
+ * Retrieves the underlying promise for the deferred
21
+ *
22
+ * @returns the underlying promise
23
+ */
24
+ get promise(): Promise<T>;
25
+ /**
26
+ * Resolves the promise
27
+ *
28
+ * @param value - the value to resolve the promise with
29
+ */
30
+ resolve(value: T | PromiseLike<T>): void;
31
+ /**
32
+ * Rejects the promise
33
+ *
34
+ * @param value - the value to reject the promise with
35
+ */
36
+ reject(error: any): void;
37
+ }
38
+ //# sourceMappingURL=promises.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promises.d.ts","sourceRoot":"","sources":["../src/promises.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,qBAAa,QAAQ,CAAC,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAa;IAC/B,OAAO,CAAC,GAAG,CAAoD;IAC/D,OAAO,CAAC,GAAG,CAA2C;IACtD,OAAO,CAAC,SAAS,CAAkB;;IAQnC;;OAEG;IACH,IAAW,WAAW,IAAI,OAAO,CAEhC;IAED;;;;OAIG;IACH,IAAW,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,CAE/B;IAED;;;;OAIG;IACI,OAAO,CAAC,KAAK,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI;IAO/C;;;;OAIG;IAGI,MAAM,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;CAM/B"}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.Deferred = void 0;
8
+ /**
9
+ * A deferred creates a promise and the ability to resolve or reject it
10
+ * @alpha
11
+ */
12
+ class Deferred {
13
+ constructor() {
14
+ this.completed = false;
15
+ this.p = new Promise((resolve, reject) => {
16
+ this.res = resolve;
17
+ this.rej = reject;
18
+ });
19
+ }
20
+ /**
21
+ * Returns whether the underlying promise has been completed
22
+ */
23
+ get isCompleted() {
24
+ return this.completed;
25
+ }
26
+ /**
27
+ * Retrieves the underlying promise for the deferred
28
+ *
29
+ * @returns the underlying promise
30
+ */
31
+ get promise() {
32
+ return this.p;
33
+ }
34
+ /**
35
+ * Resolves the promise
36
+ *
37
+ * @param value - the value to resolve the promise with
38
+ */
39
+ resolve(value) {
40
+ if (this.res !== undefined) {
41
+ this.completed = true;
42
+ this.res(value);
43
+ }
44
+ }
45
+ /**
46
+ * Rejects the promise
47
+ *
48
+ * @param value - the value to reject the promise with
49
+ */
50
+ // TODO: Use `unknown` instead (API breaking)
51
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
52
+ reject(error) {
53
+ if (this.rej !== undefined) {
54
+ this.completed = true;
55
+ this.rej(error);
56
+ }
57
+ }
58
+ }
59
+ exports.Deferred = Deferred;
60
+ //# sourceMappingURL=promises.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promises.js","sourceRoot":"","sources":["../src/promises.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;;GAGG;AACH,MAAa,QAAQ;IAMpB;QAFQ,cAAS,GAAY,KAAK,CAAC;QAGlC,IAAI,CAAC,CAAC,GAAG,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC;YACnB,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC;QACnB,CAAC,CAAC,CAAC;IACJ,CAAC;IACD;;OAEG;IACH,IAAW,WAAW;QACrB,OAAO,IAAI,CAAC,SAAS,CAAC;IACvB,CAAC;IAED;;;;OAIG;IACH,IAAW,OAAO;QACjB,OAAO,IAAI,CAAC,CAAC,CAAC;IACf,CAAC;IAED;;;;OAIG;IACI,OAAO,CAAC,KAAyB;QACvC,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,EAAE;YAC3B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;SAChB;IACF,CAAC;IAED;;;;OAIG;IACH,6CAA6C;IAC7C,iHAAiH;IAC1G,MAAM,CAAC,KAAU;QACvB,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,EAAE;YAC3B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;SAChB;IACF,CAAC;CACD;AArDD,4BAqDC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * A deferred creates a promise and the ability to resolve or reject it\n * @alpha\n */\nexport class Deferred<T> {\n\tprivate readonly p: Promise<T>;\n\tprivate res: ((value: T | PromiseLike<T>) => void) | undefined;\n\tprivate rej: ((reason?: unknown) => void) | undefined;\n\tprivate completed: boolean = false;\n\n\tpublic constructor() {\n\t\tthis.p = new Promise<T>((resolve, reject) => {\n\t\t\tthis.res = resolve;\n\t\t\tthis.rej = reject;\n\t\t});\n\t}\n\t/**\n\t * Returns whether the underlying promise has been completed\n\t */\n\tpublic get isCompleted(): boolean {\n\t\treturn this.completed;\n\t}\n\n\t/**\n\t * Retrieves the underlying promise for the deferred\n\t *\n\t * @returns the underlying promise\n\t */\n\tpublic get promise(): Promise<T> {\n\t\treturn this.p;\n\t}\n\n\t/**\n\t * Resolves the promise\n\t *\n\t * @param value - the value to resolve the promise with\n\t */\n\tpublic resolve(value: T | PromiseLike<T>): void {\n\t\tif (this.res !== undefined) {\n\t\t\tthis.completed = true;\n\t\t\tthis.res(value);\n\t\t}\n\t}\n\n\t/**\n\t * Rejects the promise\n\t *\n\t * @param value - the value to reject the promise with\n\t */\n\t// TODO: Use `unknown` instead (API breaking)\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types\n\tpublic reject(error: any): void {\n\t\tif (this.rej !== undefined) {\n\t\t\tthis.completed = true;\n\t\t\tthis.rej(error);\n\t\t}\n\t}\n}\n"]}