@fluidframework/core-utils 2.0.0-internal.6.3.2 → 2.0.0-internal.6.4.0

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 CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  module.exports = {
7
- extends: [require.resolve("@fluidframework/eslint-config-fluid/minimal"), "prettier"],
7
+ extends: [require.resolve("@fluidframework/eslint-config-fluid"), "prettier"],
8
8
 
9
9
  parserOptions: {
10
10
  project: ["./tsconfig.json", "./src/test/tsconfig.json"],
@@ -12,14 +12,24 @@ module.exports = {
12
12
  rules: {
13
13
  // This library is used in the browser, so we don't want dependencies on most node libraries.
14
14
  "import/no-nodejs-modules": ["error", { allow: ["events"] }],
15
+
16
+ // This has been disabled in the next eslint-config-fluid.
17
+ // Once the dependency here has been updated, this override can be removed.
18
+ "unicorn/numeric-separators-style": "off",
15
19
  },
16
20
  overrides: [
17
21
  {
18
22
  // Rules only for test files
19
- files: ["*.spec.ts", "src/test/**"],
23
+ files: ["*.spec.ts", "*.test.ts", "src/test/**"],
20
24
  rules: {
21
25
  // Test files are run in node only so additional node libraries can be used.
22
- "import/no-nodejs-modules": ["error", { allow: ["assert", "events", "process"] }],
26
+ "import/no-nodejs-modules": [
27
+ "error",
28
+ { allow: ["node:assert", "node:events", "node:process"] },
29
+ ],
30
+
31
+ // Does not work well with describe/it block scoping
32
+ "unicorn/consistent-function-scoping": "off",
23
33
  },
24
34
  },
25
35
  ],
package/.mocharc.js CHANGED
@@ -8,6 +8,6 @@
8
8
  const getFluidTestMochaConfig = require("@fluidframework/mocha-test-setup/mocharc-common");
9
9
 
10
10
  const packageDir = __dirname;
11
- const config = getFluidTestMochaConfig(packageDir, ["source-map-support/register"]);
11
+ const config = getFluidTestMochaConfig(packageDir);
12
12
  config.spec = "dist/test";
13
13
  module.exports = config;
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # @fluidframework/core-utils
2
2
 
3
+ ## 2.0.0-internal.6.4.0
4
+
5
+ Dependency updates only.
6
+
3
7
  ## 2.0.0-internal.6.3.0
4
8
 
5
9
  Dependency updates only.
@@ -1 +1 @@
1
- {"version":3,"file":"compare.js","sourceRoot":"","sources":["../src/compare.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;;;;;;;;GASG;AACI,MAAM,aAAa,GAAG,CAC5B,IAAkB,EAClB,KAAmB,EACnB,aAAoE,CACnE,QAAW,EACX,SAAY,EACX,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,EACzB,EAAE;IACZ,6CAA6C;IAC7C,sCAAsC;IACtC,wDAAwD;IACxD,sEAAsE;IACtE,OAAO,CACN,IAAI,KAAK,KAAK,IAAI,+DAA+D;QACjF,CAAC,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,8DAA8D;YAC9F,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAC5E,CAAC;AACH,CAAC,CAAC;AAjBW,QAAA,aAAa,iBAiBxB","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Compare two arrays. Returns true if their elements are equivalent and in the same order.\n *\n * @internal\n *\n * @param left - The first array to compare\n * @param right - The second array to compare\n * @param comparator - The function used to check if two `T`s are equivalent.\n * Defaults to `Object.is()` equality (a shallow compare where NaN = NaN and -0 ≠ 0)\n */\nexport const compareArrays = <T>(\n\tleft: readonly T[],\n\tright: readonly T[],\n\tcomparator: (leftItem: T, rightItem: T, index: number) => boolean = (\n\t\tleftItem: T,\n\t\trightItem: T,\n\t) => Object.is(leftItem, rightItem),\n): boolean => {\n\t// PERF: 'for-loop' and 'Array.every()' tied.\n\t// '===' and 'Object.is()' tied.\n\t// Trivial acceptance adds no measurable overhead.\n\t// 30% penalty vs. baseline for exported function [node 14 x64].\n\treturn (\n\t\tleft === right || // Trivial acceptance: 'left' and 'right' are the same instance\n\t\t(left.length === right.length && // Trivial rejection: 'left' and 'right' are different lengths\n\t\t\tleft.every((leftItem, index) => comparator(leftItem, right[index], index)))\n\t);\n};\n"]}
1
+ {"version":3,"file":"compare.js","sourceRoot":"","sources":["../src/compare.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;;;;;;;;GASG;AACI,MAAM,aAAa,GAAG,CAC5B,IAAkB,EAClB,KAAmB,EACnB,aAAoE,CACnE,QAAW,EACX,SAAY,EACF,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,EAClC,EAAE;IACZ,6CAA6C;IAC7C,sCAAsC;IACtC,wDAAwD;IACxD,sEAAsE;IACtE,OAAO,CACN,IAAI,KAAK,KAAK,IAAI,+DAA+D;QACjF,CAAC,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,8DAA8D;YAC9F,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAC5E,CAAC;AACH,CAAC,CAAC;AAjBW,QAAA,aAAa,iBAiBxB","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Compare two arrays. Returns true if their elements are equivalent and in the same order.\n *\n * @internal\n *\n * @param left - The first array to compare\n * @param right - The second array to compare\n * @param comparator - The function used to check if two `T`s are equivalent.\n * Defaults to `Object.is()` equality (a shallow compare where NaN = NaN and -0 ≠ 0)\n */\nexport const compareArrays = <T>(\n\tleft: readonly T[],\n\tright: readonly T[],\n\tcomparator: (leftItem: T, rightItem: T, index: number) => boolean = (\n\t\tleftItem: T,\n\t\trightItem: T,\n\t): boolean => Object.is(leftItem, rightItem),\n): boolean => {\n\t// PERF: 'for-loop' and 'Array.every()' tied.\n\t// '===' and 'Object.is()' tied.\n\t// Trivial acceptance adds no measurable overhead.\n\t// 30% penalty vs. baseline for exported function [node 14 x64].\n\treturn (\n\t\tleft === right || // Trivial acceptance: 'left' and 'right' are the same instance\n\t\t(left.length === right.length && // Trivial rejection: 'left' and 'right' are different lengths\n\t\t\tleft.every((leftItem, index) => comparator(leftItem, right[index], index)))\n\t);\n};\n"]}
package/dist/heap.js CHANGED
@@ -84,7 +84,7 @@ class Heap {
84
84
  // Move the node we want to remove to the end of the array
85
85
  const position = node.position;
86
86
  this.swap(node.position, this.L.length - 1);
87
- this.L.splice(this.L.length - 1);
87
+ this.L.splice(-1);
88
88
  // Update the swapped node assuming we didn't remove the end of the list
89
89
  if (position !== this.L.length) {
90
90
  this.update(this.L[position]);
package/dist/heap.js.map CHANGED
@@ -1 +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 */\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 */\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 */\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 */\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> {\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 {\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(this.L.length - 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"]}
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 */\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 */\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 */\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 */\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> {\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 {\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"]}
@@ -1 +1 @@
1
- {"version":3,"file":"lazy.d.ts","sourceRoot":"","sources":["../src/lazy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,qBAAa,IAAI,CAAC,CAAC;IAON,OAAO,CAAC,QAAQ,CAAC,cAAc;IAN3C,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,UAAU,CAAkB;IACpC;;;OAGG;gBAC0B,cAAc,EAAE,MAAM,CAAC;IAEpD;;OAEG;IACH,IAAW,SAAS,IAAI,OAAO,CAE9B;IAED;;OAEG;IACH,IAAW,KAAK,IAAI,CAAC,CAOpB;CACD;AAED;;;;;GAKG;AACH,qBAAa,WAAW,CAAC,CAAC,CAAE,YAAW,OAAO,CAAC,CAAC,CAAC;IAOpC,OAAO,CAAC,QAAQ,CAAC,OAAO;IANpC,IAAW,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,MAAM,CAExC;IAED,OAAO,CAAC,MAAM,CAAyB;gBAEV,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC;IAEzC,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,EAEjF,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,EAEjC,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"}
1
+ {"version":3,"file":"lazy.d.ts","sourceRoot":"","sources":["../src/lazy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;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;;;;;GAKG;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/dist/lazy.js CHANGED
@@ -49,16 +49,19 @@ class LazyPromise {
49
49
  get [Symbol.toStringTag]() {
50
50
  return this.getPromise()[Symbol.toStringTag];
51
51
  }
52
+ // eslint-disable-next-line unicorn/no-thenable
52
53
  async then(
53
54
  // eslint-disable-next-line @rushstack/no-new-null
54
55
  onfulfilled,
55
- // eslint-disable-next-line @rushstack/no-new-null
56
+ // TODO: Use `unknown` instead (API breaking)
57
+ // eslint-disable-next-line @rushstack/no-new-null, @typescript-eslint/no-explicit-any
56
58
  onrejected) {
57
59
  // eslint-disable-next-line prefer-rest-params
58
60
  return this.getPromise().then(...arguments);
59
61
  }
60
62
  async catch(
61
- // eslint-disable-next-line @rushstack/no-new-null
63
+ // TODO: Use `unknown` instead (API breaking)
64
+ // eslint-disable-next-line @rushstack/no-new-null, @typescript-eslint/no-explicit-any
62
65
  onrejected) {
63
66
  // eslint-disable-next-line prefer-rest-params
64
67
  return this.getPromise().catch(...arguments);
package/dist/lazy.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lazy.js","sourceRoot":"","sources":["../src/lazy.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;GAEG;AACH,MAAa,IAAI;IAGhB;;;OAGG;IACH,YAA6B,cAAuB;QAAvB,mBAAc,GAAd,cAAc,CAAS;QAL5C,eAAU,GAAY,KAAK,CAAC;IAKmB,CAAC;IAExD;;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;;;;;GAKG;AACH,MAAa,WAAW;IAOvB,YAA6B,OAAyB;QAAzB,YAAO,GAAP,OAAO,CAAkB;IAAG,CAAC;IAN1D,IAAW,CAAC,MAAM,CAAC,WAAW,CAAC;QAC9B,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC9C,CAAC;IAMM,KAAK,CAAC,IAAI;IAChB,kDAAkD;IAClD,WAAiF;IACjF,kDAAkD;IAClD,UAAmF;QAEnF,8CAA8C;QAC9C,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC,IAAI,CAAqB,GAAG,SAAS,CAAC,CAAC;IACjE,CAAC;IAEM,KAAK,CAAC,KAAK;IACjB,kDAAkD;IAClD,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;AAvCD,kCAuCC","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 */\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\tconstructor(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 */\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\tconstructor(private readonly execute: () => Promise<T>) {}\n\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// eslint-disable-next-line @rushstack/no-new-null\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// eslint-disable-next-line @rushstack/no-new-null\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"]}
1
+ {"version":3,"file":"lazy.js","sourceRoot":"","sources":["../src/lazy.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;GAEG;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;;;;;GAKG;AACH,MAAa,WAAW;IAOvB,YAAoC,OAAyB;QAAzB,YAAO,GAAP,OAAO,CAAkB;IAAG,CAAC;IANjE,IAAW,CAAC,MAAM,CAAC,WAAW,CAAC;QAC9B,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC9C,CAAC;IAMD,+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 */\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 */\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"]}
@@ -18,10 +18,14 @@ export declare type PromiseCacheExpiry = {
18
18
  * Options for configuring the {@link PromiseCache}
19
19
  */
20
20
  export interface PromiseCacheOptions {
21
- /** Common expiration policy for all items added to this cache */
21
+ /**
22
+ * Common expiration policy for all items added to this cache
23
+ */
22
24
  expiry?: PromiseCacheExpiry;
23
- /** If the stored Promise is rejected with a particular error, should the given key be removed? */
24
- removeOnError?: (e: any) => boolean;
25
+ /**
26
+ * If the stored Promise is rejected with a particular error, should the given key be removed?
27
+ */
28
+ removeOnError?: (error: any) => boolean;
25
29
  }
26
30
  /**
27
31
  * A specialized cache for async work, allowing you to safely cache the promised result of some async work
@@ -1 +1 @@
1
- {"version":3,"file":"promiseCache.d.ts","sourceRoot":"","sources":["../src/promiseCache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AACH,oBAAY,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;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,iEAAiE;IACjE,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,kGAAkG;IAClG,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC;CACpC;AAoDD;;;GAGG;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,CAA0B;IAExD;;;;OAIG;gBACS,EACX,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"}
1
+ {"version":3,"file":"promiseCache.d.ts","sourceRoot":"","sources":["../src/promiseCache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AACH,oBAAY,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;;GAEG;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;;;GAGG;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"}
@@ -1 +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 */\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 */\nexport interface PromiseCacheOptions {\n\t/** Common expiration policy for all items added to this cache */\n\texpiry?: PromiseCacheExpiry;\n\t/** If the stored Promise is rejected with a particular error, should the given key be removed? */\n\tremoveOnError?: (e: 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\tconstructor(\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 */\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: any) => 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\tconstructor({\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"]}
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 */\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 */\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 */\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"]}
@@ -1 +1 @@
1
- {"version":3,"file":"promises.d.ts","sourceRoot":"","sources":["../src/promises.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,qBAAa,QAAQ,CAAC,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAa;IAC/B,OAAO,CAAC,GAAG,CAAoD;IAC/D,OAAO,CAAC,GAAG,CAAuC;IAClD,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;IACI,MAAM,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;CAM/B"}
1
+ {"version":3,"file":"promises.d.ts","sourceRoot":"","sources":["../src/promises.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;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"}
package/dist/promises.js CHANGED
@@ -46,6 +46,8 @@ class Deferred {
46
46
  *
47
47
  * @param value - the value to reject the promise with
48
48
  */
49
+ // TODO: Use `unknown` instead (API breaking)
50
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
49
51
  reject(error) {
50
52
  if (this.rej !== undefined) {
51
53
  this.completed = true;
@@ -1 +1 @@
1
- {"version":3,"file":"promises.js","sourceRoot":"","sources":["../src/promises.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;GAEG;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;IACI,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;AAnDD,4BAmDC","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 */\nexport class Deferred<T> {\n\tprivate readonly p: Promise<T>;\n\tprivate res: ((value: T | PromiseLike<T>) => void) | undefined;\n\tprivate rej: ((reason?: any) => void) | undefined;\n\tprivate completed: boolean = false;\n\n\tconstructor() {\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\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"]}
1
+ {"version":3,"file":"promises.js","sourceRoot":"","sources":["../src/promises.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;GAEG;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 */\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"]}
@@ -1 +1 @@
1
- {"version":3,"file":"timer.d.ts","sourceRoot":"","sources":["../src/timer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,WAAW,MAAM;IACtB;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAE3B;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;IAEd;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;CACd;AAsCD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC7B,SAAS,EAAE,MAAM,IAAI,EACrB,SAAS,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,KAAK,IAAI,GACjE,UAAU,CAAC,OAAO,UAAU,CAAC,CAe/B;AAED;;;;;GAKG;AACH,qBAAa,KAAM,YAAW,MAAM;IAWlC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAZhC;;OAEG;IACH,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED,OAAO,CAAC,YAAY,CAAiC;gBAGnC,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,IAAI,EAC1B,cAAc,GAAE,MAAM,MAAiC;IAGzE;;;;OAIG;IACI,KAAK,CACX,EAAE,GAAE,MAA4B,EAChC,OAAO,GAAE,MAAM,IAA0B,GACvC,IAAI;IAIP;;OAEG;IACI,KAAK,IAAI,IAAI;IAQpB;;;;;;;;OAQG;IACI,OAAO,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI;IA+BvD,OAAO,CAAC,SAAS;IAmBjB,OAAO,CAAC,OAAO;IAef,OAAO,CAAC,sBAAsB;CAI9B;AAED,MAAM,WAAW,mBAAmB;IACnC,WAAW,EAAE,SAAS,GAAG,QAAQ,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,WAAW,aAAc,SAAQ,MAAM;IAC5C;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACtC;AAED;;;;;GAKG;AACH,qBAAa,YAAa,YAAW,aAAa;IACjD,OAAO,CAAC,QAAQ,CAAC,CAAgC;IACjD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAE9B;;OAEG;IACH,IAAW,QAAQ,IAAI,OAAO,CAE7B;gBAEW,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,IAAI;IAI9D;;OAEG;IACU,KAAK,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAO5E,KAAK,IAAI,IAAI;IAQpB,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;CAMhD"}
1
+ {"version":3,"file":"timer.d.ts","sourceRoot":"","sources":["../src/timer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,WAAW,MAAM;IACtB;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAE3B;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;IAEd;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;CACd;AAsCD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC7B,SAAS,EAAE,MAAM,IAAI,EACrB,SAAS,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,KAAK,IAAI,GACjE,UAAU,CAAC,OAAO,UAAU,CAAC,CAe/B;AAED;;;;;GAKG;AACH,qBAAa,KAAM,YAAW,MAAM;IAWlC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAZhC;;OAEG;IACH,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED,OAAO,CAAC,YAAY,CAAiC;gBAGnC,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,IAAI,EAC1B,cAAc,GAAE,MAAM,MAAiC;IAGzE;;;;OAIG;IACI,KAAK,CACX,EAAE,GAAE,MAA4B,EAChC,OAAO,GAAE,MAAM,IAA0B,GACvC,IAAI;IAIP;;OAEG;IACI,KAAK,IAAI,IAAI;IAQpB;;;;;;;;OAQG;IACI,OAAO,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI;IA+BvD,OAAO,CAAC,SAAS;IAmBjB,OAAO,CAAC,OAAO;IAef,OAAO,CAAC,sBAAsB;CAI9B;AAED,MAAM,WAAW,mBAAmB;IACnC,WAAW,EAAE,SAAS,GAAG,QAAQ,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,WAAW,aAAc,SAAQ,MAAM;IAC5C;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACtC;AAED;;;;;GAKG;AACH,qBAAa,YAAa,YAAW,aAAa;IACjD,OAAO,CAAC,QAAQ,CAAC,CAAgC;IACjD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAE9B;;OAEG;IACH,IAAW,QAAQ,IAAI,OAAO,CAE7B;gBAEkB,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,IAAI;IAIrE;;OAEG;IACU,KAAK,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAO5E,KAAK,IAAI,IAAI;IAQpB,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;CAMhD"}
package/dist/timer.js CHANGED
@@ -78,11 +78,7 @@ class Timer {
78
78
  * @param handler - overrides previous or default handler
79
79
  */
80
80
  restart(ms, handler) {
81
- if (!this.runningState) {
82
- // If restart is called first, it behaves as a call to start
83
- this.start(ms, handler);
84
- }
85
- else {
81
+ if (this.runningState) {
86
82
  const duration = ms ?? this.runningState.intendedDuration;
87
83
  const handlerToUse = handler ?? this.runningState.restart?.handler ?? this.runningState.handler;
88
84
  const remainingTime = this.calculateRemainingTime(this.runningState);
@@ -107,6 +103,10 @@ class Timer {
107
103
  };
108
104
  }
109
105
  }
106
+ else {
107
+ // If restart is called first, it behaves as a call to start
108
+ this.start(ms, handler);
109
+ }
110
110
  }
111
111
  startCore(duration, handler, intendedDuration) {
112
112
  this.clear();
@@ -125,17 +125,17 @@ class Timer {
125
125
  handler() {
126
126
  (0, assert_1.assert)(!!this.runningState, 0x764 /* Running timer missing handler */);
127
127
  const restart = this.runningState.restart;
128
- if (restart !== undefined) {
129
- // Restart with remaining time
130
- const remainingTime = this.calculateRemainingTime(restart);
131
- this.startCore(remainingTime, () => restart.handler(), restart.duration);
132
- }
133
- else {
128
+ if (restart === undefined) {
134
129
  // Run clear first, in case the handler decides to start again
135
130
  const handler = this.runningState.handler;
136
131
  this.clear();
137
132
  handler();
138
133
  }
134
+ else {
135
+ // Restart with remaining time
136
+ const remainingTime = this.calculateRemainingTime(restart);
137
+ this.startCore(remainingTime, () => restart.handler(), restart.duration);
138
+ }
139
139
  }
140
140
  calculateRemainingTime(runningTimeout) {
141
141
  const elapsedTime = this.getCurrentTick() - runningTimeout.startTick;
package/dist/timer.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"timer.js","sourceRoot":"","sources":["../src/timer.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\nimport { assert } from \"./assert\";\nimport { Deferred } from \"./promises\";\n\nexport interface ITimer {\n\t/**\n\t * True if timer is currently running\n\t */\n\treadonly hasTimer: boolean;\n\n\t/**\n\t * Starts the timer\n\t */\n\tstart(): void;\n\n\t/**\n\t * Cancels the timer if already running\n\t */\n\tclear(): void;\n}\n\ninterface ITimeout {\n\t/**\n\t * Tick that timeout was started.\n\t */\n\tstartTick: number;\n\n\t/**\n\t * Timeout duration in ms.\n\t */\n\tduration: number;\n\n\t/**\n\t * Handler to execute when timeout ends.\n\t */\n\thandler: () => void;\n}\n\ninterface IRunningTimerState extends ITimeout {\n\t/**\n\t * JavaScript Timeout object.\n\t */\n\ttimeout: ReturnType<typeof setTimeout>;\n\n\t/**\n\t * Intended duration in ms.\n\t */\n\tintendedDuration: number;\n\n\t/**\n\t * Intended restart timeout.\n\t */\n\trestart?: ITimeout;\n}\n\nconst maxSetTimeoutMs = 0x7fffffff; // setTimeout limit is MAX_INT32=(2^31-1).\n\n/**\n * Sets timeouts like the setTimeout function allowing timeouts to exceed the setTimeout's max timeout limit.\n * Timeouts may not be exactly accurate due to browser implementations and the OS.\n * https://stackoverflow.com/questions/21097421/what-is-the-reason-javascript-settimeout-is-so-inaccurate\n * @param timeoutFn - Executed when the timeout expires\n * @param timeoutMs - Duration of the timeout in milliseconds\n * @param setTimeoutIdFn - Executed to update the timeout if multiple timeouts are required when\n * timeoutMs greater than maxTimeout\n * @returns The initial timeout\n */\nexport function setLongTimeout(\n\ttimeoutFn: () => void,\n\ttimeoutMs: number,\n\tsetTimeoutIdFn?: (timeoutId: ReturnType<typeof setTimeout>) => void,\n): ReturnType<typeof setTimeout> {\n\t// The setTimeout max is 24.8 days before looping occurs.\n\tlet timeoutId: ReturnType<typeof setTimeout>;\n\tif (timeoutMs > maxSetTimeoutMs) {\n\t\tconst newTimeoutMs = timeoutMs - maxSetTimeoutMs;\n\t\ttimeoutId = setTimeout(\n\t\t\t() => setLongTimeout(timeoutFn, newTimeoutMs, setTimeoutIdFn),\n\t\t\tmaxSetTimeoutMs,\n\t\t);\n\t} else {\n\t\ttimeoutId = setTimeout(() => timeoutFn(), Math.max(timeoutMs, 0));\n\t}\n\n\tsetTimeoutIdFn?.(timeoutId);\n\treturn timeoutId;\n}\n\n/**\n * This class is a thin wrapper over setTimeout and clearTimeout which\n * makes it simpler to keep track of recurring timeouts with the same\n * or similar handlers and timeouts. This class supports long timeouts\n * or timeouts exceeding (2^31)-1 ms or approximately 24.8 days.\n */\nexport class Timer implements ITimer {\n\t/**\n\t * Returns true if the timer is running.\n\t */\n\tpublic get hasTimer(): boolean {\n\t\treturn !!this.runningState;\n\t}\n\n\tprivate runningState: IRunningTimerState | undefined;\n\n\tconstructor(\n\t\tprivate readonly defaultTimeout: number,\n\t\tprivate readonly defaultHandler: () => void,\n\t\tprivate readonly getCurrentTick: () => number = (): number => Date.now(),\n\t) {}\n\n\t/**\n\t * Calls setTimeout and tracks the resulting timeout.\n\t * @param ms - overrides default timeout in ms\n\t * @param handler - overrides default handler\n\t */\n\tpublic start(\n\t\tms: number = this.defaultTimeout,\n\t\thandler: () => void = this.defaultHandler,\n\t): void {\n\t\tthis.startCore(ms, handler, ms);\n\t}\n\n\t/**\n\t * Calls clearTimeout on the underlying timeout if running.\n\t */\n\tpublic clear(): void {\n\t\tif (!this.runningState) {\n\t\t\treturn;\n\t\t}\n\t\tclearTimeout(this.runningState.timeout);\n\t\tthis.runningState = undefined;\n\t}\n\n\t/**\n\t * Restarts the timer with the new handler and duration.\n\t * If a new handler is passed, the original handler may\n\t * never execute.\n\t * This is a potentially more efficient way to clear and start\n\t * a new timer.\n\t * @param ms - overrides previous or default timeout in ms\n\t * @param handler - overrides previous or default handler\n\t */\n\tpublic restart(ms?: number, handler?: () => void): void {\n\t\tif (!this.runningState) {\n\t\t\t// If restart is called first, it behaves as a call to start\n\t\t\tthis.start(ms, handler);\n\t\t} else {\n\t\t\tconst duration = ms ?? this.runningState.intendedDuration;\n\t\t\tconst handlerToUse =\n\t\t\t\thandler ?? this.runningState.restart?.handler ?? this.runningState.handler;\n\t\t\tconst remainingTime = this.calculateRemainingTime(this.runningState);\n\n\t\t\tif (duration < remainingTime) {\n\t\t\t\t// If remaining time exceeds restart duration, do a hard restart.\n\t\t\t\t// The existing timeout time is too long.\n\t\t\t\tthis.start(duration, handlerToUse);\n\t\t\t} else if (duration === remainingTime) {\n\t\t\t\t// The existing timeout time is perfect, just update handler and data.\n\t\t\t\tthis.runningState.handler = handlerToUse;\n\t\t\t\tthis.runningState.restart = undefined;\n\t\t\t\tthis.runningState.intendedDuration = duration;\n\t\t\t} else {\n\t\t\t\t// If restart duration exceeds remaining time, set restart info.\n\t\t\t\t// Existing timeout will start a new timeout for remaining time.\n\t\t\t\tthis.runningState.restart = {\n\t\t\t\t\tstartTick: this.getCurrentTick(),\n\t\t\t\t\tduration,\n\t\t\t\t\thandler: handlerToUse,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate startCore(duration: number, handler: () => void, intendedDuration: number): void {\n\t\tthis.clear();\n\t\tthis.runningState = {\n\t\t\tstartTick: this.getCurrentTick(),\n\t\t\tduration,\n\t\t\tintendedDuration,\n\t\t\thandler,\n\t\t\ttimeout: setLongTimeout(\n\t\t\t\t() => this.handler(),\n\t\t\t\tduration,\n\t\t\t\t(timer: number) => {\n\t\t\t\t\tif (this.runningState !== undefined) {\n\t\t\t\t\t\tthis.runningState.timeout = timer;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t\t};\n\t}\n\n\tprivate handler(): void {\n\t\tassert(!!this.runningState, 0x764 /* Running timer missing handler */);\n\t\tconst restart = this.runningState.restart;\n\t\tif (restart !== undefined) {\n\t\t\t// Restart with remaining time\n\t\t\tconst remainingTime = this.calculateRemainingTime(restart);\n\t\t\tthis.startCore(remainingTime, () => restart.handler(), restart.duration);\n\t\t} else {\n\t\t\t// Run clear first, in case the handler decides to start again\n\t\t\tconst handler = this.runningState.handler;\n\t\t\tthis.clear();\n\t\t\thandler();\n\t\t}\n\t}\n\n\tprivate calculateRemainingTime(runningTimeout: ITimeout): number {\n\t\tconst elapsedTime = this.getCurrentTick() - runningTimeout.startTick;\n\t\treturn runningTimeout.duration - elapsedTime;\n\t}\n}\n\nexport interface IPromiseTimerResult {\n\ttimerResult: \"timeout\" | \"cancel\";\n}\n\n/**\n * Timer which offers a promise that fulfills when the timer\n * completes.\n */\nexport interface IPromiseTimer extends ITimer {\n\t/**\n\t * Starts the timer and returns a promise that\n\t * resolves when the timer times out or is canceled.\n\t */\n\tstart(): Promise<IPromiseTimerResult>;\n}\n\n/**\n * This class is a wrapper over setTimeout and clearTimeout which\n * makes it simpler to keep track of recurring timeouts with the\n * same handlers and timeouts, while also providing a promise that\n * resolves when it times out.\n */\nexport class PromiseTimer implements IPromiseTimer {\n\tprivate deferred?: Deferred<IPromiseTimerResult>;\n\tprivate readonly timer: Timer;\n\n\t/**\n\t * {@inheritDoc Timer.hasTimer}\n\t */\n\tpublic get hasTimer(): boolean {\n\t\treturn this.timer.hasTimer;\n\t}\n\n\tconstructor(defaultTimeout: number, defaultHandler: () => void) {\n\t\tthis.timer = new Timer(defaultTimeout, () => this.wrapHandler(defaultHandler));\n\t}\n\n\t/**\n\t * {@inheritDoc IPromiseTimer.start}\n\t */\n\tpublic async start(ms?: number, handler?: () => void): Promise<IPromiseTimerResult> {\n\t\tthis.clear();\n\t\tthis.deferred = new Deferred<IPromiseTimerResult>();\n\t\tthis.timer.start(ms, handler ? (): void => this.wrapHandler(handler) : undefined);\n\t\treturn this.deferred.promise;\n\t}\n\n\tpublic clear(): void {\n\t\tthis.timer.clear();\n\t\tif (this.deferred) {\n\t\t\tthis.deferred.resolve({ timerResult: \"cancel\" });\n\t\t\tthis.deferred = undefined;\n\t\t}\n\t}\n\n\tprotected wrapHandler(handler: () => void): void {\n\t\thandler();\n\t\tassert(!!this.deferred, 0x765 /* Handler executed without deferred */);\n\t\tthis.deferred.resolve({ timerResult: \"timeout\" });\n\t\tthis.deferred = undefined;\n\t}\n}\n"]}
1
+ {"version":3,"file":"timer.js","sourceRoot":"","sources":["../src/timer.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\nimport { assert } from \"./assert\";\nimport { Deferred } from \"./promises\";\n\nexport interface ITimer {\n\t/**\n\t * True if timer is currently running\n\t */\n\treadonly hasTimer: boolean;\n\n\t/**\n\t * Starts the timer\n\t */\n\tstart(): void;\n\n\t/**\n\t * Cancels the timer if already running\n\t */\n\tclear(): void;\n}\n\ninterface ITimeout {\n\t/**\n\t * Tick that timeout was started.\n\t */\n\tstartTick: number;\n\n\t/**\n\t * Timeout duration in ms.\n\t */\n\tduration: number;\n\n\t/**\n\t * Handler to execute when timeout ends.\n\t */\n\thandler: () => void;\n}\n\ninterface IRunningTimerState extends ITimeout {\n\t/**\n\t * JavaScript Timeout object.\n\t */\n\ttimeout: ReturnType<typeof setTimeout>;\n\n\t/**\n\t * Intended duration in ms.\n\t */\n\tintendedDuration: number;\n\n\t/**\n\t * Intended restart timeout.\n\t */\n\trestart?: ITimeout;\n}\n\nconst maxSetTimeoutMs = 0x7fffffff; // setTimeout limit is MAX_INT32=(2^31-1).\n\n/**\n * Sets timeouts like the setTimeout function allowing timeouts to exceed the setTimeout's max timeout limit.\n * Timeouts may not be exactly accurate due to browser implementations and the OS.\n * https://stackoverflow.com/questions/21097421/what-is-the-reason-javascript-settimeout-is-so-inaccurate\n * @param timeoutFn - Executed when the timeout expires\n * @param timeoutMs - Duration of the timeout in milliseconds\n * @param setTimeoutIdFn - Executed to update the timeout if multiple timeouts are required when\n * timeoutMs greater than maxTimeout\n * @returns The initial timeout\n */\nexport function setLongTimeout(\n\ttimeoutFn: () => void,\n\ttimeoutMs: number,\n\tsetTimeoutIdFn?: (timeoutId: ReturnType<typeof setTimeout>) => void,\n): ReturnType<typeof setTimeout> {\n\t// The setTimeout max is 24.8 days before looping occurs.\n\tlet timeoutId: ReturnType<typeof setTimeout>;\n\tif (timeoutMs > maxSetTimeoutMs) {\n\t\tconst newTimeoutMs = timeoutMs - maxSetTimeoutMs;\n\t\ttimeoutId = setTimeout(\n\t\t\t() => setLongTimeout(timeoutFn, newTimeoutMs, setTimeoutIdFn),\n\t\t\tmaxSetTimeoutMs,\n\t\t);\n\t} else {\n\t\ttimeoutId = setTimeout(() => timeoutFn(), Math.max(timeoutMs, 0));\n\t}\n\n\tsetTimeoutIdFn?.(timeoutId);\n\treturn timeoutId;\n}\n\n/**\n * This class is a thin wrapper over setTimeout and clearTimeout which\n * makes it simpler to keep track of recurring timeouts with the same\n * or similar handlers and timeouts. This class supports long timeouts\n * or timeouts exceeding (2^31)-1 ms or approximately 24.8 days.\n */\nexport class Timer implements ITimer {\n\t/**\n\t * Returns true if the timer is running.\n\t */\n\tpublic get hasTimer(): boolean {\n\t\treturn !!this.runningState;\n\t}\n\n\tprivate runningState: IRunningTimerState | undefined;\n\n\tpublic constructor(\n\t\tprivate readonly defaultTimeout: number,\n\t\tprivate readonly defaultHandler: () => void,\n\t\tprivate readonly getCurrentTick: () => number = (): number => Date.now(),\n\t) {}\n\n\t/**\n\t * Calls setTimeout and tracks the resulting timeout.\n\t * @param ms - overrides default timeout in ms\n\t * @param handler - overrides default handler\n\t */\n\tpublic start(\n\t\tms: number = this.defaultTimeout,\n\t\thandler: () => void = this.defaultHandler,\n\t): void {\n\t\tthis.startCore(ms, handler, ms);\n\t}\n\n\t/**\n\t * Calls clearTimeout on the underlying timeout if running.\n\t */\n\tpublic clear(): void {\n\t\tif (!this.runningState) {\n\t\t\treturn;\n\t\t}\n\t\tclearTimeout(this.runningState.timeout);\n\t\tthis.runningState = undefined;\n\t}\n\n\t/**\n\t * Restarts the timer with the new handler and duration.\n\t * If a new handler is passed, the original handler may\n\t * never execute.\n\t * This is a potentially more efficient way to clear and start\n\t * a new timer.\n\t * @param ms - overrides previous or default timeout in ms\n\t * @param handler - overrides previous or default handler\n\t */\n\tpublic restart(ms?: number, handler?: () => void): void {\n\t\tif (this.runningState) {\n\t\t\tconst duration = ms ?? this.runningState.intendedDuration;\n\t\t\tconst handlerToUse =\n\t\t\t\thandler ?? this.runningState.restart?.handler ?? this.runningState.handler;\n\t\t\tconst remainingTime = this.calculateRemainingTime(this.runningState);\n\n\t\t\tif (duration < remainingTime) {\n\t\t\t\t// If remaining time exceeds restart duration, do a hard restart.\n\t\t\t\t// The existing timeout time is too long.\n\t\t\t\tthis.start(duration, handlerToUse);\n\t\t\t} else if (duration === remainingTime) {\n\t\t\t\t// The existing timeout time is perfect, just update handler and data.\n\t\t\t\tthis.runningState.handler = handlerToUse;\n\t\t\t\tthis.runningState.restart = undefined;\n\t\t\t\tthis.runningState.intendedDuration = duration;\n\t\t\t} else {\n\t\t\t\t// If restart duration exceeds remaining time, set restart info.\n\t\t\t\t// Existing timeout will start a new timeout for remaining time.\n\t\t\t\tthis.runningState.restart = {\n\t\t\t\t\tstartTick: this.getCurrentTick(),\n\t\t\t\t\tduration,\n\t\t\t\t\thandler: handlerToUse,\n\t\t\t\t};\n\t\t\t}\n\t\t} else {\n\t\t\t// If restart is called first, it behaves as a call to start\n\t\t\tthis.start(ms, handler);\n\t\t}\n\t}\n\n\tprivate startCore(duration: number, handler: () => void, intendedDuration: number): void {\n\t\tthis.clear();\n\t\tthis.runningState = {\n\t\t\tstartTick: this.getCurrentTick(),\n\t\t\tduration,\n\t\t\tintendedDuration,\n\t\t\thandler,\n\t\t\ttimeout: setLongTimeout(\n\t\t\t\t() => this.handler(),\n\t\t\t\tduration,\n\t\t\t\t(timer: number) => {\n\t\t\t\t\tif (this.runningState !== undefined) {\n\t\t\t\t\t\tthis.runningState.timeout = timer;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t\t};\n\t}\n\n\tprivate handler(): void {\n\t\tassert(!!this.runningState, 0x764 /* Running timer missing handler */);\n\t\tconst restart = this.runningState.restart;\n\t\tif (restart === undefined) {\n\t\t\t// Run clear first, in case the handler decides to start again\n\t\t\tconst handler = this.runningState.handler;\n\t\t\tthis.clear();\n\t\t\thandler();\n\t\t} else {\n\t\t\t// Restart with remaining time\n\t\t\tconst remainingTime = this.calculateRemainingTime(restart);\n\t\t\tthis.startCore(remainingTime, () => restart.handler(), restart.duration);\n\t\t}\n\t}\n\n\tprivate calculateRemainingTime(runningTimeout: ITimeout): number {\n\t\tconst elapsedTime = this.getCurrentTick() - runningTimeout.startTick;\n\t\treturn runningTimeout.duration - elapsedTime;\n\t}\n}\n\nexport interface IPromiseTimerResult {\n\ttimerResult: \"timeout\" | \"cancel\";\n}\n\n/**\n * Timer which offers a promise that fulfills when the timer\n * completes.\n */\nexport interface IPromiseTimer extends ITimer {\n\t/**\n\t * Starts the timer and returns a promise that\n\t * resolves when the timer times out or is canceled.\n\t */\n\tstart(): Promise<IPromiseTimerResult>;\n}\n\n/**\n * This class is a wrapper over setTimeout and clearTimeout which\n * makes it simpler to keep track of recurring timeouts with the\n * same handlers and timeouts, while also providing a promise that\n * resolves when it times out.\n */\nexport class PromiseTimer implements IPromiseTimer {\n\tprivate deferred?: Deferred<IPromiseTimerResult>;\n\tprivate readonly timer: Timer;\n\n\t/**\n\t * {@inheritDoc Timer.hasTimer}\n\t */\n\tpublic get hasTimer(): boolean {\n\t\treturn this.timer.hasTimer;\n\t}\n\n\tpublic constructor(defaultTimeout: number, defaultHandler: () => void) {\n\t\tthis.timer = new Timer(defaultTimeout, () => this.wrapHandler(defaultHandler));\n\t}\n\n\t/**\n\t * {@inheritDoc IPromiseTimer.start}\n\t */\n\tpublic async start(ms?: number, handler?: () => void): Promise<IPromiseTimerResult> {\n\t\tthis.clear();\n\t\tthis.deferred = new Deferred<IPromiseTimerResult>();\n\t\tthis.timer.start(ms, handler ? (): void => this.wrapHandler(handler) : undefined);\n\t\treturn this.deferred.promise;\n\t}\n\n\tpublic clear(): void {\n\t\tthis.timer.clear();\n\t\tif (this.deferred) {\n\t\t\tthis.deferred.resolve({ timerResult: \"cancel\" });\n\t\t\tthis.deferred = undefined;\n\t\t}\n\t}\n\n\tprotected wrapHandler(handler: () => void): void {\n\t\thandler();\n\t\tassert(!!this.deferred, 0x765 /* Handler executed without deferred */);\n\t\tthis.deferred.resolve({ timerResult: \"timeout\" });\n\t\tthis.deferred = undefined;\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"compare.js","sourceRoot":"","sources":["../src/compare.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAC5B,IAAkB,EAClB,KAAmB,EACnB,aAAoE,CACnE,QAAW,EACX,SAAY,EACX,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,EACzB,EAAE;IACZ,6CAA6C;IAC7C,sCAAsC;IACtC,wDAAwD;IACxD,sEAAsE;IACtE,OAAO,CACN,IAAI,KAAK,KAAK,IAAI,+DAA+D;QACjF,CAAC,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,8DAA8D;YAC9F,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAC5E,CAAC;AACH,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Compare two arrays. Returns true if their elements are equivalent and in the same order.\n *\n * @internal\n *\n * @param left - The first array to compare\n * @param right - The second array to compare\n * @param comparator - The function used to check if two `T`s are equivalent.\n * Defaults to `Object.is()` equality (a shallow compare where NaN = NaN and -0 ≠ 0)\n */\nexport const compareArrays = <T>(\n\tleft: readonly T[],\n\tright: readonly T[],\n\tcomparator: (leftItem: T, rightItem: T, index: number) => boolean = (\n\t\tleftItem: T,\n\t\trightItem: T,\n\t) => Object.is(leftItem, rightItem),\n): boolean => {\n\t// PERF: 'for-loop' and 'Array.every()' tied.\n\t// '===' and 'Object.is()' tied.\n\t// Trivial acceptance adds no measurable overhead.\n\t// 30% penalty vs. baseline for exported function [node 14 x64].\n\treturn (\n\t\tleft === right || // Trivial acceptance: 'left' and 'right' are the same instance\n\t\t(left.length === right.length && // Trivial rejection: 'left' and 'right' are different lengths\n\t\t\tleft.every((leftItem, index) => comparator(leftItem, right[index], index)))\n\t);\n};\n"]}
1
+ {"version":3,"file":"compare.js","sourceRoot":"","sources":["../src/compare.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAC5B,IAAkB,EAClB,KAAmB,EACnB,aAAoE,CACnE,QAAW,EACX,SAAY,EACF,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC,EAClC,EAAE;IACZ,6CAA6C;IAC7C,sCAAsC;IACtC,wDAAwD;IACxD,sEAAsE;IACtE,OAAO,CACN,IAAI,KAAK,KAAK,IAAI,+DAA+D;QACjF,CAAC,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,8DAA8D;YAC9F,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAC5E,CAAC;AACH,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Compare two arrays. Returns true if their elements are equivalent and in the same order.\n *\n * @internal\n *\n * @param left - The first array to compare\n * @param right - The second array to compare\n * @param comparator - The function used to check if two `T`s are equivalent.\n * Defaults to `Object.is()` equality (a shallow compare where NaN = NaN and -0 ≠ 0)\n */\nexport const compareArrays = <T>(\n\tleft: readonly T[],\n\tright: readonly T[],\n\tcomparator: (leftItem: T, rightItem: T, index: number) => boolean = (\n\t\tleftItem: T,\n\t\trightItem: T,\n\t): boolean => Object.is(leftItem, rightItem),\n): boolean => {\n\t// PERF: 'for-loop' and 'Array.every()' tied.\n\t// '===' and 'Object.is()' tied.\n\t// Trivial acceptance adds no measurable overhead.\n\t// 30% penalty vs. baseline for exported function [node 14 x64].\n\treturn (\n\t\tleft === right || // Trivial acceptance: 'left' and 'right' are the same instance\n\t\t(left.length === right.length && // Trivial rejection: 'left' and 'right' are different lengths\n\t\t\tleft.every((leftItem, index) => comparator(leftItem, right[index], index)))\n\t);\n};\n"]}
package/lib/heap.js CHANGED
@@ -81,7 +81,7 @@ export class Heap {
81
81
  // Move the node we want to remove to the end of the array
82
82
  const position = node.position;
83
83
  this.swap(node.position, this.L.length - 1);
84
- this.L.splice(this.L.length - 1);
84
+ this.L.splice(-1);
85
85
  // Update the swapped node assuming we didn't remove the end of the list
86
86
  if (position !== this.L.length) {
87
87
  this.update(this.L[position]);
package/lib/heap.js.map CHANGED
@@ -1 +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 */\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 */\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 */\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 */\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> {\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 {\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(this.L.length - 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"]}
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 */\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 */\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 */\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 */\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> {\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 {\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/lazy.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lazy.d.ts","sourceRoot":"","sources":["../src/lazy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,qBAAa,IAAI,CAAC,CAAC;IAON,OAAO,CAAC,QAAQ,CAAC,cAAc;IAN3C,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,UAAU,CAAkB;IACpC;;;OAGG;gBAC0B,cAAc,EAAE,MAAM,CAAC;IAEpD;;OAEG;IACH,IAAW,SAAS,IAAI,OAAO,CAE9B;IAED;;OAEG;IACH,IAAW,KAAK,IAAI,CAAC,CAOpB;CACD;AAED;;;;;GAKG;AACH,qBAAa,WAAW,CAAC,CAAC,CAAE,YAAW,OAAO,CAAC,CAAC,CAAC;IAOpC,OAAO,CAAC,QAAQ,CAAC,OAAO;IANpC,IAAW,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,MAAM,CAExC;IAED,OAAO,CAAC,MAAM,CAAyB;gBAEV,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC;IAEzC,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,EAEjF,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,EAEjC,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"}
1
+ {"version":3,"file":"lazy.d.ts","sourceRoot":"","sources":["../src/lazy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;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;;;;;GAKG;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 CHANGED
@@ -45,16 +45,19 @@ export class LazyPromise {
45
45
  get [Symbol.toStringTag]() {
46
46
  return this.getPromise()[Symbol.toStringTag];
47
47
  }
48
+ // eslint-disable-next-line unicorn/no-thenable
48
49
  async then(
49
50
  // eslint-disable-next-line @rushstack/no-new-null
50
51
  onfulfilled,
51
- // eslint-disable-next-line @rushstack/no-new-null
52
+ // TODO: Use `unknown` instead (API breaking)
53
+ // eslint-disable-next-line @rushstack/no-new-null, @typescript-eslint/no-explicit-any
52
54
  onrejected) {
53
55
  // eslint-disable-next-line prefer-rest-params
54
56
  return this.getPromise().then(...arguments);
55
57
  }
56
58
  async catch(
57
- // eslint-disable-next-line @rushstack/no-new-null
59
+ // TODO: Use `unknown` instead (API breaking)
60
+ // eslint-disable-next-line @rushstack/no-new-null, @typescript-eslint/no-explicit-any
58
61
  onrejected) {
59
62
  // eslint-disable-next-line prefer-rest-params
60
63
  return this.getPromise().catch(...arguments);
package/lib/lazy.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lazy.js","sourceRoot":"","sources":["../src/lazy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,OAAO,IAAI;IAGhB;;;OAGG;IACH,YAA6B,cAAuB;QAAvB,mBAAc,GAAd,cAAc,CAAS;QAL5C,eAAU,GAAY,KAAK,CAAC;IAKmB,CAAC;IAExD;;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;AAED;;;;;GAKG;AACH,MAAM,OAAO,WAAW;IAOvB,YAA6B,OAAyB;QAAzB,YAAO,GAAP,OAAO,CAAkB;IAAG,CAAC;IAN1D,IAAW,CAAC,MAAM,CAAC,WAAW,CAAC;QAC9B,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC9C,CAAC;IAMM,KAAK,CAAC,IAAI;IAChB,kDAAkD;IAClD,WAAiF;IACjF,kDAAkD;IAClD,UAAmF;QAEnF,8CAA8C;QAC9C,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC,IAAI,CAAqB,GAAG,SAAS,CAAC,CAAC;IACjE,CAAC;IAEM,KAAK,CAAC,KAAK;IACjB,kDAAkD;IAClD,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","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 */\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\tconstructor(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 */\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\tconstructor(private readonly execute: () => Promise<T>) {}\n\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// eslint-disable-next-line @rushstack/no-new-null\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// eslint-disable-next-line @rushstack/no-new-null\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"]}
1
+ {"version":3,"file":"lazy.js","sourceRoot":"","sources":["../src/lazy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,OAAO,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;AAED;;;;;GAKG;AACH,MAAM,OAAO,WAAW;IAOvB,YAAoC,OAAyB;QAAzB,YAAO,GAAP,OAAO,CAAkB;IAAG,CAAC;IANjE,IAAW,CAAC,MAAM,CAAC,WAAW,CAAC;QAC9B,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC9C,CAAC;IAMD,+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","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 */\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 */\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"]}
@@ -18,10 +18,14 @@ export declare type PromiseCacheExpiry = {
18
18
  * Options for configuring the {@link PromiseCache}
19
19
  */
20
20
  export interface PromiseCacheOptions {
21
- /** Common expiration policy for all items added to this cache */
21
+ /**
22
+ * Common expiration policy for all items added to this cache
23
+ */
22
24
  expiry?: PromiseCacheExpiry;
23
- /** If the stored Promise is rejected with a particular error, should the given key be removed? */
24
- removeOnError?: (e: any) => boolean;
25
+ /**
26
+ * If the stored Promise is rejected with a particular error, should the given key be removed?
27
+ */
28
+ removeOnError?: (error: any) => boolean;
25
29
  }
26
30
  /**
27
31
  * A specialized cache for async work, allowing you to safely cache the promised result of some async work
@@ -1 +1 @@
1
- {"version":3,"file":"promiseCache.d.ts","sourceRoot":"","sources":["../src/promiseCache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AACH,oBAAY,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;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,iEAAiE;IACjE,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,kGAAkG;IAClG,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC;CACpC;AAoDD;;;GAGG;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,CAA0B;IAExD;;;;OAIG;gBACS,EACX,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"}
1
+ {"version":3,"file":"promiseCache.d.ts","sourceRoot":"","sources":["../src/promiseCache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;GAKG;AACH,oBAAY,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;;GAEG;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;;;GAGG;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"}
@@ -1 +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 */\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 */\nexport interface PromiseCacheOptions {\n\t/** Common expiration policy for all items added to this cache */\n\texpiry?: PromiseCacheExpiry;\n\t/** If the stored Promise is rejected with a particular error, should the given key be removed? */\n\tremoveOnError?: (e: 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\tconstructor(\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 */\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: any) => 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\tconstructor({\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"]}
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 */\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 */\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 */\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"]}
@@ -1 +1 @@
1
- {"version":3,"file":"promises.d.ts","sourceRoot":"","sources":["../src/promises.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,qBAAa,QAAQ,CAAC,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAa;IAC/B,OAAO,CAAC,GAAG,CAAoD;IAC/D,OAAO,CAAC,GAAG,CAAuC;IAClD,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;IACI,MAAM,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;CAM/B"}
1
+ {"version":3,"file":"promises.d.ts","sourceRoot":"","sources":["../src/promises.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;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"}
package/lib/promises.js CHANGED
@@ -43,6 +43,8 @@ export class Deferred {
43
43
  *
44
44
  * @param value - the value to reject the promise with
45
45
  */
46
+ // TODO: Use `unknown` instead (API breaking)
47
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
46
48
  reject(error) {
47
49
  if (this.rej !== undefined) {
48
50
  this.completed = true;
@@ -1 +1 @@
1
- {"version":3,"file":"promises.js","sourceRoot":"","sources":["../src/promises.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,OAAO,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;IACI,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","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 */\nexport class Deferred<T> {\n\tprivate readonly p: Promise<T>;\n\tprivate res: ((value: T | PromiseLike<T>) => void) | undefined;\n\tprivate rej: ((reason?: any) => void) | undefined;\n\tprivate completed: boolean = false;\n\n\tconstructor() {\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\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"]}
1
+ {"version":3,"file":"promises.js","sourceRoot":"","sources":["../src/promises.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,OAAO,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","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 */\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"]}
@@ -1 +1 @@
1
- {"version":3,"file":"timer.d.ts","sourceRoot":"","sources":["../src/timer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,WAAW,MAAM;IACtB;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAE3B;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;IAEd;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;CACd;AAsCD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC7B,SAAS,EAAE,MAAM,IAAI,EACrB,SAAS,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,KAAK,IAAI,GACjE,UAAU,CAAC,OAAO,UAAU,CAAC,CAe/B;AAED;;;;;GAKG;AACH,qBAAa,KAAM,YAAW,MAAM;IAWlC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAZhC;;OAEG;IACH,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED,OAAO,CAAC,YAAY,CAAiC;gBAGnC,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,IAAI,EAC1B,cAAc,GAAE,MAAM,MAAiC;IAGzE;;;;OAIG;IACI,KAAK,CACX,EAAE,GAAE,MAA4B,EAChC,OAAO,GAAE,MAAM,IAA0B,GACvC,IAAI;IAIP;;OAEG;IACI,KAAK,IAAI,IAAI;IAQpB;;;;;;;;OAQG;IACI,OAAO,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI;IA+BvD,OAAO,CAAC,SAAS;IAmBjB,OAAO,CAAC,OAAO;IAef,OAAO,CAAC,sBAAsB;CAI9B;AAED,MAAM,WAAW,mBAAmB;IACnC,WAAW,EAAE,SAAS,GAAG,QAAQ,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,WAAW,aAAc,SAAQ,MAAM;IAC5C;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACtC;AAED;;;;;GAKG;AACH,qBAAa,YAAa,YAAW,aAAa;IACjD,OAAO,CAAC,QAAQ,CAAC,CAAgC;IACjD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAE9B;;OAEG;IACH,IAAW,QAAQ,IAAI,OAAO,CAE7B;gBAEW,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,IAAI;IAI9D;;OAEG;IACU,KAAK,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAO5E,KAAK,IAAI,IAAI;IAQpB,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;CAMhD"}
1
+ {"version":3,"file":"timer.d.ts","sourceRoot":"","sources":["../src/timer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,WAAW,MAAM;IACtB;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAE3B;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;IAEd;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;CACd;AAsCD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC7B,SAAS,EAAE,MAAM,IAAI,EACrB,SAAS,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,KAAK,IAAI,GACjE,UAAU,CAAC,OAAO,UAAU,CAAC,CAe/B;AAED;;;;;GAKG;AACH,qBAAa,KAAM,YAAW,MAAM;IAWlC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAZhC;;OAEG;IACH,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED,OAAO,CAAC,YAAY,CAAiC;gBAGnC,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,IAAI,EAC1B,cAAc,GAAE,MAAM,MAAiC;IAGzE;;;;OAIG;IACI,KAAK,CACX,EAAE,GAAE,MAA4B,EAChC,OAAO,GAAE,MAAM,IAA0B,GACvC,IAAI;IAIP;;OAEG;IACI,KAAK,IAAI,IAAI;IAQpB;;;;;;;;OAQG;IACI,OAAO,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI;IA+BvD,OAAO,CAAC,SAAS;IAmBjB,OAAO,CAAC,OAAO;IAef,OAAO,CAAC,sBAAsB;CAI9B;AAED,MAAM,WAAW,mBAAmB;IACnC,WAAW,EAAE,SAAS,GAAG,QAAQ,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,WAAW,aAAc,SAAQ,MAAM;IAC5C;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACtC;AAED;;;;;GAKG;AACH,qBAAa,YAAa,YAAW,aAAa;IACjD,OAAO,CAAC,QAAQ,CAAC,CAAgC;IACjD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAE9B;;OAEG;IACH,IAAW,QAAQ,IAAI,OAAO,CAE7B;gBAEkB,cAAc,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,IAAI;IAIrE;;OAEG;IACU,KAAK,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAO5E,KAAK,IAAI,IAAI;IAQpB,SAAS,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;CAMhD"}
package/lib/timer.js CHANGED
@@ -74,11 +74,7 @@ export class Timer {
74
74
  * @param handler - overrides previous or default handler
75
75
  */
76
76
  restart(ms, handler) {
77
- if (!this.runningState) {
78
- // If restart is called first, it behaves as a call to start
79
- this.start(ms, handler);
80
- }
81
- else {
77
+ if (this.runningState) {
82
78
  const duration = ms ?? this.runningState.intendedDuration;
83
79
  const handlerToUse = handler ?? this.runningState.restart?.handler ?? this.runningState.handler;
84
80
  const remainingTime = this.calculateRemainingTime(this.runningState);
@@ -103,6 +99,10 @@ export class Timer {
103
99
  };
104
100
  }
105
101
  }
102
+ else {
103
+ // If restart is called first, it behaves as a call to start
104
+ this.start(ms, handler);
105
+ }
106
106
  }
107
107
  startCore(duration, handler, intendedDuration) {
108
108
  this.clear();
@@ -121,17 +121,17 @@ export class Timer {
121
121
  handler() {
122
122
  assert(!!this.runningState, 0x764 /* Running timer missing handler */);
123
123
  const restart = this.runningState.restart;
124
- if (restart !== undefined) {
125
- // Restart with remaining time
126
- const remainingTime = this.calculateRemainingTime(restart);
127
- this.startCore(remainingTime, () => restart.handler(), restart.duration);
128
- }
129
- else {
124
+ if (restart === undefined) {
130
125
  // Run clear first, in case the handler decides to start again
131
126
  const handler = this.runningState.handler;
132
127
  this.clear();
133
128
  handler();
134
129
  }
130
+ else {
131
+ // Restart with remaining time
132
+ const remainingTime = this.calculateRemainingTime(restart);
133
+ this.startCore(remainingTime, () => restart.handler(), restart.duration);
134
+ }
135
135
  }
136
136
  calculateRemainingTime(runningTimeout) {
137
137
  const elapsedTime = this.getCurrentTick() - runningTimeout.startTick;
package/lib/timer.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"timer.js","sourceRoot":"","sources":["../src/timer.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\nimport { assert } from \"./assert\";\nimport { Deferred } from \"./promises\";\n\nexport interface ITimer {\n\t/**\n\t * True if timer is currently running\n\t */\n\treadonly hasTimer: boolean;\n\n\t/**\n\t * Starts the timer\n\t */\n\tstart(): void;\n\n\t/**\n\t * Cancels the timer if already running\n\t */\n\tclear(): void;\n}\n\ninterface ITimeout {\n\t/**\n\t * Tick that timeout was started.\n\t */\n\tstartTick: number;\n\n\t/**\n\t * Timeout duration in ms.\n\t */\n\tduration: number;\n\n\t/**\n\t * Handler to execute when timeout ends.\n\t */\n\thandler: () => void;\n}\n\ninterface IRunningTimerState extends ITimeout {\n\t/**\n\t * JavaScript Timeout object.\n\t */\n\ttimeout: ReturnType<typeof setTimeout>;\n\n\t/**\n\t * Intended duration in ms.\n\t */\n\tintendedDuration: number;\n\n\t/**\n\t * Intended restart timeout.\n\t */\n\trestart?: ITimeout;\n}\n\nconst maxSetTimeoutMs = 0x7fffffff; // setTimeout limit is MAX_INT32=(2^31-1).\n\n/**\n * Sets timeouts like the setTimeout function allowing timeouts to exceed the setTimeout's max timeout limit.\n * Timeouts may not be exactly accurate due to browser implementations and the OS.\n * https://stackoverflow.com/questions/21097421/what-is-the-reason-javascript-settimeout-is-so-inaccurate\n * @param timeoutFn - Executed when the timeout expires\n * @param timeoutMs - Duration of the timeout in milliseconds\n * @param setTimeoutIdFn - Executed to update the timeout if multiple timeouts are required when\n * timeoutMs greater than maxTimeout\n * @returns The initial timeout\n */\nexport function setLongTimeout(\n\ttimeoutFn: () => void,\n\ttimeoutMs: number,\n\tsetTimeoutIdFn?: (timeoutId: ReturnType<typeof setTimeout>) => void,\n): ReturnType<typeof setTimeout> {\n\t// The setTimeout max is 24.8 days before looping occurs.\n\tlet timeoutId: ReturnType<typeof setTimeout>;\n\tif (timeoutMs > maxSetTimeoutMs) {\n\t\tconst newTimeoutMs = timeoutMs - maxSetTimeoutMs;\n\t\ttimeoutId = setTimeout(\n\t\t\t() => setLongTimeout(timeoutFn, newTimeoutMs, setTimeoutIdFn),\n\t\t\tmaxSetTimeoutMs,\n\t\t);\n\t} else {\n\t\ttimeoutId = setTimeout(() => timeoutFn(), Math.max(timeoutMs, 0));\n\t}\n\n\tsetTimeoutIdFn?.(timeoutId);\n\treturn timeoutId;\n}\n\n/**\n * This class is a thin wrapper over setTimeout and clearTimeout which\n * makes it simpler to keep track of recurring timeouts with the same\n * or similar handlers and timeouts. This class supports long timeouts\n * or timeouts exceeding (2^31)-1 ms or approximately 24.8 days.\n */\nexport class Timer implements ITimer {\n\t/**\n\t * Returns true if the timer is running.\n\t */\n\tpublic get hasTimer(): boolean {\n\t\treturn !!this.runningState;\n\t}\n\n\tprivate runningState: IRunningTimerState | undefined;\n\n\tconstructor(\n\t\tprivate readonly defaultTimeout: number,\n\t\tprivate readonly defaultHandler: () => void,\n\t\tprivate readonly getCurrentTick: () => number = (): number => Date.now(),\n\t) {}\n\n\t/**\n\t * Calls setTimeout and tracks the resulting timeout.\n\t * @param ms - overrides default timeout in ms\n\t * @param handler - overrides default handler\n\t */\n\tpublic start(\n\t\tms: number = this.defaultTimeout,\n\t\thandler: () => void = this.defaultHandler,\n\t): void {\n\t\tthis.startCore(ms, handler, ms);\n\t}\n\n\t/**\n\t * Calls clearTimeout on the underlying timeout if running.\n\t */\n\tpublic clear(): void {\n\t\tif (!this.runningState) {\n\t\t\treturn;\n\t\t}\n\t\tclearTimeout(this.runningState.timeout);\n\t\tthis.runningState = undefined;\n\t}\n\n\t/**\n\t * Restarts the timer with the new handler and duration.\n\t * If a new handler is passed, the original handler may\n\t * never execute.\n\t * This is a potentially more efficient way to clear and start\n\t * a new timer.\n\t * @param ms - overrides previous or default timeout in ms\n\t * @param handler - overrides previous or default handler\n\t */\n\tpublic restart(ms?: number, handler?: () => void): void {\n\t\tif (!this.runningState) {\n\t\t\t// If restart is called first, it behaves as a call to start\n\t\t\tthis.start(ms, handler);\n\t\t} else {\n\t\t\tconst duration = ms ?? this.runningState.intendedDuration;\n\t\t\tconst handlerToUse =\n\t\t\t\thandler ?? this.runningState.restart?.handler ?? this.runningState.handler;\n\t\t\tconst remainingTime = this.calculateRemainingTime(this.runningState);\n\n\t\t\tif (duration < remainingTime) {\n\t\t\t\t// If remaining time exceeds restart duration, do a hard restart.\n\t\t\t\t// The existing timeout time is too long.\n\t\t\t\tthis.start(duration, handlerToUse);\n\t\t\t} else if (duration === remainingTime) {\n\t\t\t\t// The existing timeout time is perfect, just update handler and data.\n\t\t\t\tthis.runningState.handler = handlerToUse;\n\t\t\t\tthis.runningState.restart = undefined;\n\t\t\t\tthis.runningState.intendedDuration = duration;\n\t\t\t} else {\n\t\t\t\t// If restart duration exceeds remaining time, set restart info.\n\t\t\t\t// Existing timeout will start a new timeout for remaining time.\n\t\t\t\tthis.runningState.restart = {\n\t\t\t\t\tstartTick: this.getCurrentTick(),\n\t\t\t\t\tduration,\n\t\t\t\t\thandler: handlerToUse,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate startCore(duration: number, handler: () => void, intendedDuration: number): void {\n\t\tthis.clear();\n\t\tthis.runningState = {\n\t\t\tstartTick: this.getCurrentTick(),\n\t\t\tduration,\n\t\t\tintendedDuration,\n\t\t\thandler,\n\t\t\ttimeout: setLongTimeout(\n\t\t\t\t() => this.handler(),\n\t\t\t\tduration,\n\t\t\t\t(timer: number) => {\n\t\t\t\t\tif (this.runningState !== undefined) {\n\t\t\t\t\t\tthis.runningState.timeout = timer;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t\t};\n\t}\n\n\tprivate handler(): void {\n\t\tassert(!!this.runningState, 0x764 /* Running timer missing handler */);\n\t\tconst restart = this.runningState.restart;\n\t\tif (restart !== undefined) {\n\t\t\t// Restart with remaining time\n\t\t\tconst remainingTime = this.calculateRemainingTime(restart);\n\t\t\tthis.startCore(remainingTime, () => restart.handler(), restart.duration);\n\t\t} else {\n\t\t\t// Run clear first, in case the handler decides to start again\n\t\t\tconst handler = this.runningState.handler;\n\t\t\tthis.clear();\n\t\t\thandler();\n\t\t}\n\t}\n\n\tprivate calculateRemainingTime(runningTimeout: ITimeout): number {\n\t\tconst elapsedTime = this.getCurrentTick() - runningTimeout.startTick;\n\t\treturn runningTimeout.duration - elapsedTime;\n\t}\n}\n\nexport interface IPromiseTimerResult {\n\ttimerResult: \"timeout\" | \"cancel\";\n}\n\n/**\n * Timer which offers a promise that fulfills when the timer\n * completes.\n */\nexport interface IPromiseTimer extends ITimer {\n\t/**\n\t * Starts the timer and returns a promise that\n\t * resolves when the timer times out or is canceled.\n\t */\n\tstart(): Promise<IPromiseTimerResult>;\n}\n\n/**\n * This class is a wrapper over setTimeout and clearTimeout which\n * makes it simpler to keep track of recurring timeouts with the\n * same handlers and timeouts, while also providing a promise that\n * resolves when it times out.\n */\nexport class PromiseTimer implements IPromiseTimer {\n\tprivate deferred?: Deferred<IPromiseTimerResult>;\n\tprivate readonly timer: Timer;\n\n\t/**\n\t * {@inheritDoc Timer.hasTimer}\n\t */\n\tpublic get hasTimer(): boolean {\n\t\treturn this.timer.hasTimer;\n\t}\n\n\tconstructor(defaultTimeout: number, defaultHandler: () => void) {\n\t\tthis.timer = new Timer(defaultTimeout, () => this.wrapHandler(defaultHandler));\n\t}\n\n\t/**\n\t * {@inheritDoc IPromiseTimer.start}\n\t */\n\tpublic async start(ms?: number, handler?: () => void): Promise<IPromiseTimerResult> {\n\t\tthis.clear();\n\t\tthis.deferred = new Deferred<IPromiseTimerResult>();\n\t\tthis.timer.start(ms, handler ? (): void => this.wrapHandler(handler) : undefined);\n\t\treturn this.deferred.promise;\n\t}\n\n\tpublic clear(): void {\n\t\tthis.timer.clear();\n\t\tif (this.deferred) {\n\t\t\tthis.deferred.resolve({ timerResult: \"cancel\" });\n\t\t\tthis.deferred = undefined;\n\t\t}\n\t}\n\n\tprotected wrapHandler(handler: () => void): void {\n\t\thandler();\n\t\tassert(!!this.deferred, 0x765 /* Handler executed without deferred */);\n\t\tthis.deferred.resolve({ timerResult: \"timeout\" });\n\t\tthis.deferred = undefined;\n\t}\n}\n"]}
1
+ {"version":3,"file":"timer.js","sourceRoot":"","sources":["../src/timer.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\nimport { assert } from \"./assert\";\nimport { Deferred } from \"./promises\";\n\nexport interface ITimer {\n\t/**\n\t * True if timer is currently running\n\t */\n\treadonly hasTimer: boolean;\n\n\t/**\n\t * Starts the timer\n\t */\n\tstart(): void;\n\n\t/**\n\t * Cancels the timer if already running\n\t */\n\tclear(): void;\n}\n\ninterface ITimeout {\n\t/**\n\t * Tick that timeout was started.\n\t */\n\tstartTick: number;\n\n\t/**\n\t * Timeout duration in ms.\n\t */\n\tduration: number;\n\n\t/**\n\t * Handler to execute when timeout ends.\n\t */\n\thandler: () => void;\n}\n\ninterface IRunningTimerState extends ITimeout {\n\t/**\n\t * JavaScript Timeout object.\n\t */\n\ttimeout: ReturnType<typeof setTimeout>;\n\n\t/**\n\t * Intended duration in ms.\n\t */\n\tintendedDuration: number;\n\n\t/**\n\t * Intended restart timeout.\n\t */\n\trestart?: ITimeout;\n}\n\nconst maxSetTimeoutMs = 0x7fffffff; // setTimeout limit is MAX_INT32=(2^31-1).\n\n/**\n * Sets timeouts like the setTimeout function allowing timeouts to exceed the setTimeout's max timeout limit.\n * Timeouts may not be exactly accurate due to browser implementations and the OS.\n * https://stackoverflow.com/questions/21097421/what-is-the-reason-javascript-settimeout-is-so-inaccurate\n * @param timeoutFn - Executed when the timeout expires\n * @param timeoutMs - Duration of the timeout in milliseconds\n * @param setTimeoutIdFn - Executed to update the timeout if multiple timeouts are required when\n * timeoutMs greater than maxTimeout\n * @returns The initial timeout\n */\nexport function setLongTimeout(\n\ttimeoutFn: () => void,\n\ttimeoutMs: number,\n\tsetTimeoutIdFn?: (timeoutId: ReturnType<typeof setTimeout>) => void,\n): ReturnType<typeof setTimeout> {\n\t// The setTimeout max is 24.8 days before looping occurs.\n\tlet timeoutId: ReturnType<typeof setTimeout>;\n\tif (timeoutMs > maxSetTimeoutMs) {\n\t\tconst newTimeoutMs = timeoutMs - maxSetTimeoutMs;\n\t\ttimeoutId = setTimeout(\n\t\t\t() => setLongTimeout(timeoutFn, newTimeoutMs, setTimeoutIdFn),\n\t\t\tmaxSetTimeoutMs,\n\t\t);\n\t} else {\n\t\ttimeoutId = setTimeout(() => timeoutFn(), Math.max(timeoutMs, 0));\n\t}\n\n\tsetTimeoutIdFn?.(timeoutId);\n\treturn timeoutId;\n}\n\n/**\n * This class is a thin wrapper over setTimeout and clearTimeout which\n * makes it simpler to keep track of recurring timeouts with the same\n * or similar handlers and timeouts. This class supports long timeouts\n * or timeouts exceeding (2^31)-1 ms or approximately 24.8 days.\n */\nexport class Timer implements ITimer {\n\t/**\n\t * Returns true if the timer is running.\n\t */\n\tpublic get hasTimer(): boolean {\n\t\treturn !!this.runningState;\n\t}\n\n\tprivate runningState: IRunningTimerState | undefined;\n\n\tpublic constructor(\n\t\tprivate readonly defaultTimeout: number,\n\t\tprivate readonly defaultHandler: () => void,\n\t\tprivate readonly getCurrentTick: () => number = (): number => Date.now(),\n\t) {}\n\n\t/**\n\t * Calls setTimeout and tracks the resulting timeout.\n\t * @param ms - overrides default timeout in ms\n\t * @param handler - overrides default handler\n\t */\n\tpublic start(\n\t\tms: number = this.defaultTimeout,\n\t\thandler: () => void = this.defaultHandler,\n\t): void {\n\t\tthis.startCore(ms, handler, ms);\n\t}\n\n\t/**\n\t * Calls clearTimeout on the underlying timeout if running.\n\t */\n\tpublic clear(): void {\n\t\tif (!this.runningState) {\n\t\t\treturn;\n\t\t}\n\t\tclearTimeout(this.runningState.timeout);\n\t\tthis.runningState = undefined;\n\t}\n\n\t/**\n\t * Restarts the timer with the new handler and duration.\n\t * If a new handler is passed, the original handler may\n\t * never execute.\n\t * This is a potentially more efficient way to clear and start\n\t * a new timer.\n\t * @param ms - overrides previous or default timeout in ms\n\t * @param handler - overrides previous or default handler\n\t */\n\tpublic restart(ms?: number, handler?: () => void): void {\n\t\tif (this.runningState) {\n\t\t\tconst duration = ms ?? this.runningState.intendedDuration;\n\t\t\tconst handlerToUse =\n\t\t\t\thandler ?? this.runningState.restart?.handler ?? this.runningState.handler;\n\t\t\tconst remainingTime = this.calculateRemainingTime(this.runningState);\n\n\t\t\tif (duration < remainingTime) {\n\t\t\t\t// If remaining time exceeds restart duration, do a hard restart.\n\t\t\t\t// The existing timeout time is too long.\n\t\t\t\tthis.start(duration, handlerToUse);\n\t\t\t} else if (duration === remainingTime) {\n\t\t\t\t// The existing timeout time is perfect, just update handler and data.\n\t\t\t\tthis.runningState.handler = handlerToUse;\n\t\t\t\tthis.runningState.restart = undefined;\n\t\t\t\tthis.runningState.intendedDuration = duration;\n\t\t\t} else {\n\t\t\t\t// If restart duration exceeds remaining time, set restart info.\n\t\t\t\t// Existing timeout will start a new timeout for remaining time.\n\t\t\t\tthis.runningState.restart = {\n\t\t\t\t\tstartTick: this.getCurrentTick(),\n\t\t\t\t\tduration,\n\t\t\t\t\thandler: handlerToUse,\n\t\t\t\t};\n\t\t\t}\n\t\t} else {\n\t\t\t// If restart is called first, it behaves as a call to start\n\t\t\tthis.start(ms, handler);\n\t\t}\n\t}\n\n\tprivate startCore(duration: number, handler: () => void, intendedDuration: number): void {\n\t\tthis.clear();\n\t\tthis.runningState = {\n\t\t\tstartTick: this.getCurrentTick(),\n\t\t\tduration,\n\t\t\tintendedDuration,\n\t\t\thandler,\n\t\t\ttimeout: setLongTimeout(\n\t\t\t\t() => this.handler(),\n\t\t\t\tduration,\n\t\t\t\t(timer: number) => {\n\t\t\t\t\tif (this.runningState !== undefined) {\n\t\t\t\t\t\tthis.runningState.timeout = timer;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t\t};\n\t}\n\n\tprivate handler(): void {\n\t\tassert(!!this.runningState, 0x764 /* Running timer missing handler */);\n\t\tconst restart = this.runningState.restart;\n\t\tif (restart === undefined) {\n\t\t\t// Run clear first, in case the handler decides to start again\n\t\t\tconst handler = this.runningState.handler;\n\t\t\tthis.clear();\n\t\t\thandler();\n\t\t} else {\n\t\t\t// Restart with remaining time\n\t\t\tconst remainingTime = this.calculateRemainingTime(restart);\n\t\t\tthis.startCore(remainingTime, () => restart.handler(), restart.duration);\n\t\t}\n\t}\n\n\tprivate calculateRemainingTime(runningTimeout: ITimeout): number {\n\t\tconst elapsedTime = this.getCurrentTick() - runningTimeout.startTick;\n\t\treturn runningTimeout.duration - elapsedTime;\n\t}\n}\n\nexport interface IPromiseTimerResult {\n\ttimerResult: \"timeout\" | \"cancel\";\n}\n\n/**\n * Timer which offers a promise that fulfills when the timer\n * completes.\n */\nexport interface IPromiseTimer extends ITimer {\n\t/**\n\t * Starts the timer and returns a promise that\n\t * resolves when the timer times out or is canceled.\n\t */\n\tstart(): Promise<IPromiseTimerResult>;\n}\n\n/**\n * This class is a wrapper over setTimeout and clearTimeout which\n * makes it simpler to keep track of recurring timeouts with the\n * same handlers and timeouts, while also providing a promise that\n * resolves when it times out.\n */\nexport class PromiseTimer implements IPromiseTimer {\n\tprivate deferred?: Deferred<IPromiseTimerResult>;\n\tprivate readonly timer: Timer;\n\n\t/**\n\t * {@inheritDoc Timer.hasTimer}\n\t */\n\tpublic get hasTimer(): boolean {\n\t\treturn this.timer.hasTimer;\n\t}\n\n\tpublic constructor(defaultTimeout: number, defaultHandler: () => void) {\n\t\tthis.timer = new Timer(defaultTimeout, () => this.wrapHandler(defaultHandler));\n\t}\n\n\t/**\n\t * {@inheritDoc IPromiseTimer.start}\n\t */\n\tpublic async start(ms?: number, handler?: () => void): Promise<IPromiseTimerResult> {\n\t\tthis.clear();\n\t\tthis.deferred = new Deferred<IPromiseTimerResult>();\n\t\tthis.timer.start(ms, handler ? (): void => this.wrapHandler(handler) : undefined);\n\t\treturn this.deferred.promise;\n\t}\n\n\tpublic clear(): void {\n\t\tthis.timer.clear();\n\t\tif (this.deferred) {\n\t\t\tthis.deferred.resolve({ timerResult: \"cancel\" });\n\t\t\tthis.deferred = undefined;\n\t\t}\n\t}\n\n\tprotected wrapHandler(handler: () => void): void {\n\t\thandler();\n\t\tassert(!!this.deferred, 0x765 /* Handler executed without deferred */);\n\t\tthis.deferred.resolve({ timerResult: \"timeout\" });\n\t\tthis.deferred = undefined;\n\t}\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/core-utils",
3
- "version": "2.0.0-internal.6.3.2",
3
+ "version": "2.0.0-internal.6.4.0",
4
4
  "description": "Not intended for use outside the Fluid client repo.",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -40,7 +40,7 @@
40
40
  "@fluidframework/build-common": "^2.0.0",
41
41
  "@fluidframework/build-tools": "^0.22.0",
42
42
  "@fluidframework/eslint-config-fluid": "^2.1.0",
43
- "@fluidframework/mocha-test-setup": ">=2.0.0-internal.6.3.2 <2.0.0-internal.6.4.0",
43
+ "@fluidframework/mocha-test-setup": ">=2.0.0-internal.6.4.0 <2.0.0-internal.6.5.0",
44
44
  "@microsoft/api-extractor": "^7.34.4",
45
45
  "@types/mocha": "^9.1.1",
46
46
  "@types/node": "^16.18.38",
@@ -57,7 +57,6 @@
57
57
  "prettier": "~2.6.2",
58
58
  "rimraf": "^4.4.0",
59
59
  "sinon": "^7.4.2",
60
- "source-map-support": "^0.5.16",
61
60
  "typescript": "~4.5.5"
62
61
  },
63
62
  "typeValidation": {
package/src/compare.ts CHANGED
@@ -19,7 +19,7 @@ export const compareArrays = <T>(
19
19
  comparator: (leftItem: T, rightItem: T, index: number) => boolean = (
20
20
  leftItem: T,
21
21
  rightItem: T,
22
- ) => Object.is(leftItem, rightItem),
22
+ ): boolean => Object.is(leftItem, rightItem),
23
23
  ): boolean => {
24
24
  // PERF: 'for-loop' and 'Array.every()' tied.
25
25
  // '===' and 'Object.is()' tied.
package/src/heap.ts CHANGED
@@ -115,7 +115,7 @@ export class Heap<T> {
115
115
  // Move the node we want to remove to the end of the array
116
116
  const position = node.position;
117
117
  this.swap(node.position, this.L.length - 1);
118
- this.L.splice(this.L.length - 1);
118
+ this.L.splice(-1);
119
119
 
120
120
  // Update the swapped node assuming we didn't remove the end of the list
121
121
  if (position !== this.L.length) {
package/src/lazy.ts CHANGED
@@ -13,7 +13,7 @@ export class Lazy<T> {
13
13
  * Instantiates an instance of Lazy<T>.
14
14
  * @param valueGenerator - The function that will generate the value when value is accessed the first time.
15
15
  */
16
- constructor(private readonly valueGenerator: () => T) {}
16
+ public constructor(private readonly valueGenerator: () => T) {}
17
17
 
18
18
  /**
19
19
  * Return true if the value as been generated, otherwise false.
@@ -48,12 +48,14 @@ export class LazyPromise<T> implements Promise<T> {
48
48
 
49
49
  private result: Promise<T> | undefined;
50
50
 
51
- constructor(private readonly execute: () => Promise<T>) {}
51
+ public constructor(private readonly execute: () => Promise<T>) {}
52
52
 
53
+ // eslint-disable-next-line unicorn/no-thenable
53
54
  public async then<TResult1 = T, TResult2 = never>(
54
55
  // eslint-disable-next-line @rushstack/no-new-null
55
56
  onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null | undefined,
56
- // eslint-disable-next-line @rushstack/no-new-null
57
+ // TODO: Use `unknown` instead (API breaking)
58
+ // eslint-disable-next-line @rushstack/no-new-null, @typescript-eslint/no-explicit-any
57
59
  onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined,
58
60
  ): Promise<TResult1 | TResult2> {
59
61
  // eslint-disable-next-line prefer-rest-params
@@ -61,7 +63,8 @@ export class LazyPromise<T> implements Promise<T> {
61
63
  }
62
64
 
63
65
  public async catch<TResult = never>(
64
- // eslint-disable-next-line @rushstack/no-new-null
66
+ // TODO: Use `unknown` instead (API breaking)
67
+ // eslint-disable-next-line @rushstack/no-new-null, @typescript-eslint/no-explicit-any
65
68
  onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null | undefined,
66
69
  ): Promise<T | TResult> {
67
70
  // eslint-disable-next-line prefer-rest-params
@@ -22,10 +22,16 @@ export type PromiseCacheExpiry =
22
22
  * Options for configuring the {@link PromiseCache}
23
23
  */
24
24
  export interface PromiseCacheOptions {
25
- /** Common expiration policy for all items added to this cache */
25
+ /**
26
+ * Common expiration policy for all items added to this cache
27
+ */
26
28
  expiry?: PromiseCacheExpiry;
27
- /** If the stored Promise is rejected with a particular error, should the given key be removed? */
28
- removeOnError?: (e: any) => boolean;
29
+ /**
30
+ * If the stored Promise is rejected with a particular error, should the given key be removed?
31
+ */
32
+ // TODO: Use `unknown` instead (API breaking)
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+ removeOnError?: (error: any) => boolean;
29
35
  }
30
36
 
31
37
  /**
@@ -35,7 +41,7 @@ export interface PromiseCacheOptions {
35
41
  class GarbageCollector<TKey> {
36
42
  private readonly gcTimeouts = new Map<TKey, ReturnType<typeof setTimeout>>();
37
43
 
38
- constructor(
44
+ public constructor(
39
45
  private readonly expiry: PromiseCacheExpiry,
40
46
  private readonly cleanup: (key: TKey) => void,
41
47
  ) {}
@@ -86,14 +92,14 @@ export class PromiseCache<TKey, TResult> {
86
92
  private readonly cache = new Map<TKey, Promise<TResult>>();
87
93
  private readonly gc: GarbageCollector<TKey>;
88
94
 
89
- private readonly removeOnError: (error: any) => boolean;
95
+ private readonly removeOnError: (error: unknown) => boolean;
90
96
 
91
97
  /**
92
98
  * Create the PromiseCache with the given options, with the following defaults:
93
99
  *
94
100
  * expiry: indefinite, removeOnError: true for all errors
95
101
  */
96
- constructor({
102
+ public constructor({
97
103
  expiry = { policy: "indefinite" },
98
104
  removeOnError = (): boolean => true,
99
105
  }: PromiseCacheOptions = {}) {
package/src/promises.ts CHANGED
@@ -9,10 +9,10 @@
9
9
  export class Deferred<T> {
10
10
  private readonly p: Promise<T>;
11
11
  private res: ((value: T | PromiseLike<T>) => void) | undefined;
12
- private rej: ((reason?: any) => void) | undefined;
12
+ private rej: ((reason?: unknown) => void) | undefined;
13
13
  private completed: boolean = false;
14
14
 
15
- constructor() {
15
+ public constructor() {
16
16
  this.p = new Promise<T>((resolve, reject) => {
17
17
  this.res = resolve;
18
18
  this.rej = reject;
@@ -51,6 +51,8 @@ export class Deferred<T> {
51
51
  *
52
52
  * @param value - the value to reject the promise with
53
53
  */
54
+ // TODO: Use `unknown` instead (API breaking)
55
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
54
56
  public reject(error: any): void {
55
57
  if (this.rej !== undefined) {
56
58
  this.completed = true;
package/src/timer.ts CHANGED
@@ -106,7 +106,7 @@ export class Timer implements ITimer {
106
106
 
107
107
  private runningState: IRunningTimerState | undefined;
108
108
 
109
- constructor(
109
+ public constructor(
110
110
  private readonly defaultTimeout: number,
111
111
  private readonly defaultHandler: () => void,
112
112
  private readonly getCurrentTick: () => number = (): number => Date.now(),
@@ -145,10 +145,7 @@ export class Timer implements ITimer {
145
145
  * @param handler - overrides previous or default handler
146
146
  */
147
147
  public restart(ms?: number, handler?: () => void): void {
148
- if (!this.runningState) {
149
- // If restart is called first, it behaves as a call to start
150
- this.start(ms, handler);
151
- } else {
148
+ if (this.runningState) {
152
149
  const duration = ms ?? this.runningState.intendedDuration;
153
150
  const handlerToUse =
154
151
  handler ?? this.runningState.restart?.handler ?? this.runningState.handler;
@@ -172,6 +169,9 @@ export class Timer implements ITimer {
172
169
  handler: handlerToUse,
173
170
  };
174
171
  }
172
+ } else {
173
+ // If restart is called first, it behaves as a call to start
174
+ this.start(ms, handler);
175
175
  }
176
176
  }
177
177
 
@@ -197,15 +197,15 @@ export class Timer implements ITimer {
197
197
  private handler(): void {
198
198
  assert(!!this.runningState, 0x764 /* Running timer missing handler */);
199
199
  const restart = this.runningState.restart;
200
- if (restart !== undefined) {
201
- // Restart with remaining time
202
- const remainingTime = this.calculateRemainingTime(restart);
203
- this.startCore(remainingTime, () => restart.handler(), restart.duration);
204
- } else {
200
+ if (restart === undefined) {
205
201
  // Run clear first, in case the handler decides to start again
206
202
  const handler = this.runningState.handler;
207
203
  this.clear();
208
204
  handler();
205
+ } else {
206
+ // Restart with remaining time
207
+ const remainingTime = this.calculateRemainingTime(restart);
208
+ this.startCore(remainingTime, () => restart.handler(), restart.duration);
209
209
  }
210
210
  }
211
211
 
@@ -248,7 +248,7 @@ export class PromiseTimer implements IPromiseTimer {
248
248
  return this.timer.hasTimer;
249
249
  }
250
250
 
251
- constructor(defaultTimeout: number, defaultHandler: () => void) {
251
+ public constructor(defaultTimeout: number, defaultHandler: () => void) {
252
252
  this.timer = new Timer(defaultTimeout, () => this.wrapHandler(defaultHandler));
253
253
  }
254
254