@fluidframework/core-utils 2.0.0-internal.6.1.1 → 2.0.0-internal.6.3.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.
Files changed (67) hide show
  1. package/.eslintrc.js +1 -1
  2. package/CHANGELOG.md +8 -0
  3. package/README.md +32 -6
  4. package/dist/assert.d.ts +16 -0
  5. package/dist/assert.d.ts.map +1 -0
  6. package/dist/assert.js +24 -0
  7. package/dist/assert.js.map +1 -0
  8. package/dist/delay.d.ts +10 -0
  9. package/dist/delay.d.ts.map +1 -0
  10. package/dist/delay.js +14 -0
  11. package/dist/delay.js.map +1 -0
  12. package/dist/heap.d.ts +82 -0
  13. package/dist/heap.d.ts.map +1 -0
  14. package/dist/heap.js +139 -0
  15. package/dist/heap.js.map +1 -0
  16. package/dist/index.d.ts +6 -0
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +16 -1
  19. package/dist/index.js.map +1 -1
  20. package/dist/promises.d.ts +37 -0
  21. package/dist/promises.d.ts.map +1 -0
  22. package/dist/promises.js +57 -0
  23. package/dist/promises.js.map +1 -0
  24. package/dist/timer.d.ts +105 -0
  25. package/dist/timer.d.ts.map +1 -0
  26. package/dist/timer.js +186 -0
  27. package/dist/timer.js.map +1 -0
  28. package/dist/unreachable.d.ts +21 -0
  29. package/dist/unreachable.d.ts.map +1 -0
  30. package/dist/unreachable.js +27 -0
  31. package/dist/unreachable.js.map +1 -0
  32. package/lib/assert.d.ts +16 -0
  33. package/lib/assert.d.ts.map +1 -0
  34. package/lib/assert.js +20 -0
  35. package/lib/assert.js.map +1 -0
  36. package/lib/delay.d.ts +10 -0
  37. package/lib/delay.d.ts.map +1 -0
  38. package/lib/delay.js +10 -0
  39. package/lib/delay.js.map +1 -0
  40. package/lib/heap.d.ts +82 -0
  41. package/lib/heap.d.ts.map +1 -0
  42. package/lib/heap.js +135 -0
  43. package/lib/heap.js.map +1 -0
  44. package/lib/index.d.ts +6 -0
  45. package/lib/index.d.ts.map +1 -1
  46. package/lib/index.js +6 -0
  47. package/lib/index.js.map +1 -1
  48. package/lib/promises.d.ts +37 -0
  49. package/lib/promises.d.ts.map +1 -0
  50. package/lib/promises.js +53 -0
  51. package/lib/promises.js.map +1 -0
  52. package/lib/timer.d.ts +105 -0
  53. package/lib/timer.d.ts.map +1 -0
  54. package/lib/timer.js +180 -0
  55. package/lib/timer.js.map +1 -0
  56. package/lib/unreachable.d.ts +21 -0
  57. package/lib/unreachable.d.ts.map +1 -0
  58. package/lib/unreachable.js +23 -0
  59. package/lib/unreachable.js.map +1 -0
  60. package/package.json +7 -9
  61. package/src/assert.ts +22 -0
  62. package/src/delay.ts +11 -0
  63. package/src/heap.ts +174 -0
  64. package/src/index.ts +13 -0
  65. package/src/promises.ts +60 -0
  66. package/src/timer.ts +279 -0
  67. package/src/unreachable.ts +23 -0
package/lib/heap.js ADDED
@@ -0,0 +1,135 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ /**
6
+ * A comparer for numbers.
7
+ */
8
+ export const NumberComparer = {
9
+ /**
10
+ * The compare function for numbers.
11
+ * @returns The difference of the two numbers.
12
+ */
13
+ compare: (a, b) => a - b,
14
+ /**
15
+ * The minimum value of a JavaScript number, which is `Number.MIN_VALUE`.
16
+ */
17
+ min: Number.MIN_VALUE,
18
+ };
19
+ /**
20
+ * Ordered {@link https://en.wikipedia.org/wiki/Heap_(data_structure) | Heap} data structure implementation.
21
+ */
22
+ export class Heap {
23
+ /**
24
+ * Creates an instance of `Heap` with comparer.
25
+ * @param comp - A comparer that specify how elements are ordered.
26
+ */
27
+ constructor(comp) {
28
+ this.comp = comp;
29
+ this.L = [{ value: comp.min, position: 0 }];
30
+ }
31
+ /**
32
+ * Return the smallest element in the heap as determined by the order of the comparer
33
+ *
34
+ * @returns Heap node containing the smallest element
35
+ */
36
+ peek() {
37
+ return this.L[1];
38
+ }
39
+ /**
40
+ * Get and remove the smallest element in the heap as determined by the order of the comparer
41
+ *
42
+ * @returns The smallest value in the heap
43
+ */
44
+ get() {
45
+ this.swap(1, this.count());
46
+ const x = this.L.pop();
47
+ this.fixdown(1);
48
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
49
+ return x.value;
50
+ }
51
+ /**
52
+ * Add a value to the heap
53
+ *
54
+ * @param x - value to add
55
+ * @returns The heap node that contains the value
56
+ */
57
+ add(x) {
58
+ const node = { value: x, position: this.L.length };
59
+ this.L.push(node);
60
+ this.fixup(this.count());
61
+ return node;
62
+ }
63
+ /**
64
+ * Allows for the Heap to be updated after a node's value changes.
65
+ */
66
+ update(node) {
67
+ const k = node.position;
68
+ if (this.isGreaterThanParent(k)) {
69
+ this.fixup(k);
70
+ }
71
+ else {
72
+ this.fixdown(k);
73
+ }
74
+ }
75
+ /**
76
+ * Removes the given node from the heap.
77
+ *
78
+ * @param node - The node to remove from the heap.
79
+ */
80
+ remove(node) {
81
+ // Move the node we want to remove to the end of the array
82
+ const position = node.position;
83
+ this.swap(node.position, this.L.length - 1);
84
+ this.L.splice(this.L.length - 1);
85
+ // Update the swapped node assuming we didn't remove the end of the list
86
+ if (position !== this.L.length) {
87
+ this.update(this.L[position]);
88
+ }
89
+ }
90
+ /**
91
+ * Get the number of elements in the Heap.
92
+ *
93
+ * @returns The number of elements in the Heap.
94
+ */
95
+ count() {
96
+ return this.L.length - 1;
97
+ }
98
+ fixup(pos) {
99
+ let k = pos;
100
+ while (this.isGreaterThanParent(k)) {
101
+ // eslint-disable-next-line no-bitwise
102
+ const parent = k >> 1;
103
+ this.swap(k, parent);
104
+ k = parent;
105
+ }
106
+ }
107
+ isGreaterThanParent(k) {
108
+ // eslint-disable-next-line no-bitwise
109
+ return k > 1 && this.comp.compare(this.L[k >> 1].value, this.L[k].value) > 0;
110
+ }
111
+ fixdown(pos) {
112
+ let k = pos;
113
+ // eslint-disable-next-line no-bitwise
114
+ while (k << 1 <= this.count()) {
115
+ // eslint-disable-next-line no-bitwise
116
+ let j = k << 1;
117
+ if (j < this.count() && this.comp.compare(this.L[j].value, this.L[j + 1].value) > 0) {
118
+ j++;
119
+ }
120
+ if (this.comp.compare(this.L[k].value, this.L[j].value) <= 0) {
121
+ break;
122
+ }
123
+ this.swap(k, j);
124
+ k = j;
125
+ }
126
+ }
127
+ swap(k, j) {
128
+ const tmp = this.L[k];
129
+ this.L[k] = this.L[j];
130
+ this.L[k].position = k;
131
+ this.L[j] = tmp;
132
+ this.L[j].position = j;
133
+ }
134
+ }
135
+ //# sourceMappingURL=heap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heap.js","sourceRoot":"","sources":["../src/heap.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Interface for a comparer.\n */\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"]}
package/lib/index.d.ts CHANGED
@@ -2,7 +2,13 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+ export { assert } from "./assert";
5
6
  export { compareArrays } from "./compare";
7
+ export { delay } from "./delay";
8
+ export { Heap, IComparer, IHeapNode, NumberComparer } from "./heap";
6
9
  export { Lazy, LazyPromise } from "./lazy";
7
10
  export { PromiseCache, PromiseCacheExpiry, PromiseCacheOptions } from "./promiseCache";
11
+ export { Deferred } from "./promises";
12
+ export { IPromiseTimer, IPromiseTimerResult, ITimer, PromiseTimer, setLongTimeout, Timer, } from "./timer";
13
+ export { unreachableCase } from "./unreachable";
8
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AACpE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACvF,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EACN,aAAa,EACb,mBAAmB,EACnB,MAAM,EACN,YAAY,EACZ,cAAc,EACd,KAAK,GACL,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
package/lib/index.js CHANGED
@@ -2,7 +2,13 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
+ export { assert } from "./assert";
5
6
  export { compareArrays } from "./compare";
7
+ export { delay } from "./delay";
8
+ export { Heap, NumberComparer } from "./heap";
6
9
  export { Lazy, LazyPromise } from "./lazy";
7
10
  export { PromiseCache } from "./promiseCache";
11
+ export { Deferred } from "./promises";
12
+ export { PromiseTimer, setLongTimeout, Timer, } from "./timer";
13
+ export { unreachableCase } from "./unreachable";
8
14
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAE,YAAY,EAA2C,MAAM,gBAAgB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { compareArrays } from \"./compare\";\nexport { Lazy, LazyPromise } from \"./lazy\";\nexport { PromiseCache, PromiseCacheExpiry, PromiseCacheOptions } from \"./promiseCache\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,IAAI,EAAwB,cAAc,EAAE,MAAM,QAAQ,CAAC;AACpE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAE,YAAY,EAA2C,MAAM,gBAAgB,CAAC;AACvF,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAIN,YAAY,EACZ,cAAc,EACd,KAAK,GACL,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport { assert } from \"./assert\";\nexport { compareArrays } from \"./compare\";\nexport { delay } from \"./delay\";\nexport { Heap, IComparer, IHeapNode, NumberComparer } from \"./heap\";\nexport { Lazy, LazyPromise } from \"./lazy\";\nexport { PromiseCache, PromiseCacheExpiry, PromiseCacheOptions } from \"./promiseCache\";\nexport { Deferred } from \"./promises\";\nexport {\n\tIPromiseTimer,\n\tIPromiseTimerResult,\n\tITimer,\n\tPromiseTimer,\n\tsetLongTimeout,\n\tTimer,\n} from \"./timer\";\nexport { unreachableCase } from \"./unreachable\";\n"]}
@@ -0,0 +1,37 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ /**
6
+ * A deferred creates a promise and the ability to resolve or reject it
7
+ */
8
+ export declare class Deferred<T> {
9
+ private readonly p;
10
+ private res;
11
+ private rej;
12
+ private completed;
13
+ constructor();
14
+ /**
15
+ * Returns whether the underlying promise has been completed
16
+ */
17
+ get isCompleted(): boolean;
18
+ /**
19
+ * Retrieves the underlying promise for the deferred
20
+ *
21
+ * @returns the underlying promise
22
+ */
23
+ get promise(): Promise<T>;
24
+ /**
25
+ * Resolves the promise
26
+ *
27
+ * @param value - the value to resolve the promise with
28
+ */
29
+ resolve(value: T | PromiseLike<T>): void;
30
+ /**
31
+ * Rejects the promise
32
+ *
33
+ * @param value - the value to reject the promise with
34
+ */
35
+ reject(error: any): void;
36
+ }
37
+ //# sourceMappingURL=promises.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promises.d.ts","sourceRoot":"","sources":["../src/promises.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;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"}
@@ -0,0 +1,53 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ /**
6
+ * A deferred creates a promise and the ability to resolve or reject it
7
+ */
8
+ export class Deferred {
9
+ constructor() {
10
+ this.completed = false;
11
+ this.p = new Promise((resolve, reject) => {
12
+ this.res = resolve;
13
+ this.rej = reject;
14
+ });
15
+ }
16
+ /**
17
+ * Returns whether the underlying promise has been completed
18
+ */
19
+ get isCompleted() {
20
+ return this.completed;
21
+ }
22
+ /**
23
+ * Retrieves the underlying promise for the deferred
24
+ *
25
+ * @returns the underlying promise
26
+ */
27
+ get promise() {
28
+ return this.p;
29
+ }
30
+ /**
31
+ * Resolves the promise
32
+ *
33
+ * @param value - the value to resolve the promise with
34
+ */
35
+ resolve(value) {
36
+ if (this.res !== undefined) {
37
+ this.completed = true;
38
+ this.res(value);
39
+ }
40
+ }
41
+ /**
42
+ * Rejects the promise
43
+ *
44
+ * @param value - the value to reject the promise with
45
+ */
46
+ reject(error) {
47
+ if (this.rej !== undefined) {
48
+ this.completed = true;
49
+ this.rej(error);
50
+ }
51
+ }
52
+ }
53
+ //# sourceMappingURL=promises.js.map
@@ -0,0 +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"]}
package/lib/timer.d.ts ADDED
@@ -0,0 +1,105 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ export interface ITimer {
6
+ /**
7
+ * True if timer is currently running
8
+ */
9
+ readonly hasTimer: boolean;
10
+ /**
11
+ * Starts the timer
12
+ */
13
+ start(): void;
14
+ /**
15
+ * Cancels the timer if already running
16
+ */
17
+ clear(): void;
18
+ }
19
+ /**
20
+ * Sets timeouts like the setTimeout function allowing timeouts to exceed the setTimeout's max timeout limit.
21
+ * Timeouts may not be exactly accurate due to browser implementations and the OS.
22
+ * https://stackoverflow.com/questions/21097421/what-is-the-reason-javascript-settimeout-is-so-inaccurate
23
+ * @param timeoutFn - Executed when the timeout expires
24
+ * @param timeoutMs - Duration of the timeout in milliseconds
25
+ * @param setTimeoutIdFn - Executed to update the timeout if multiple timeouts are required when
26
+ * timeoutMs greater than maxTimeout
27
+ * @returns The initial timeout
28
+ */
29
+ export declare function setLongTimeout(timeoutFn: () => void, timeoutMs: number, setTimeoutIdFn?: (timeoutId: ReturnType<typeof setTimeout>) => void): ReturnType<typeof setTimeout>;
30
+ /**
31
+ * This class is a thin wrapper over setTimeout and clearTimeout which
32
+ * makes it simpler to keep track of recurring timeouts with the same
33
+ * or similar handlers and timeouts. This class supports long timeouts
34
+ * or timeouts exceeding (2^31)-1 ms or approximately 24.8 days.
35
+ */
36
+ export declare class Timer implements ITimer {
37
+ private readonly defaultTimeout;
38
+ private readonly defaultHandler;
39
+ private readonly getCurrentTick;
40
+ /**
41
+ * Returns true if the timer is running.
42
+ */
43
+ get hasTimer(): boolean;
44
+ private runningState;
45
+ constructor(defaultTimeout: number, defaultHandler: () => void, getCurrentTick?: () => number);
46
+ /**
47
+ * Calls setTimeout and tracks the resulting timeout.
48
+ * @param ms - overrides default timeout in ms
49
+ * @param handler - overrides default handler
50
+ */
51
+ start(ms?: number, handler?: () => void): void;
52
+ /**
53
+ * Calls clearTimeout on the underlying timeout if running.
54
+ */
55
+ clear(): void;
56
+ /**
57
+ * Restarts the timer with the new handler and duration.
58
+ * If a new handler is passed, the original handler may
59
+ * never execute.
60
+ * This is a potentially more efficient way to clear and start
61
+ * a new timer.
62
+ * @param ms - overrides previous or default timeout in ms
63
+ * @param handler - overrides previous or default handler
64
+ */
65
+ restart(ms?: number, handler?: () => void): void;
66
+ private startCore;
67
+ private handler;
68
+ private calculateRemainingTime;
69
+ }
70
+ export interface IPromiseTimerResult {
71
+ timerResult: "timeout" | "cancel";
72
+ }
73
+ /**
74
+ * Timer which offers a promise that fulfills when the timer
75
+ * completes.
76
+ */
77
+ export interface IPromiseTimer extends ITimer {
78
+ /**
79
+ * Starts the timer and returns a promise that
80
+ * resolves when the timer times out or is canceled.
81
+ */
82
+ start(): Promise<IPromiseTimerResult>;
83
+ }
84
+ /**
85
+ * This class is a wrapper over setTimeout and clearTimeout which
86
+ * makes it simpler to keep track of recurring timeouts with the
87
+ * same handlers and timeouts, while also providing a promise that
88
+ * resolves when it times out.
89
+ */
90
+ export declare class PromiseTimer implements IPromiseTimer {
91
+ private deferred?;
92
+ private readonly timer;
93
+ /**
94
+ * {@inheritDoc Timer.hasTimer}
95
+ */
96
+ get hasTimer(): boolean;
97
+ constructor(defaultTimeout: number, defaultHandler: () => void);
98
+ /**
99
+ * {@inheritDoc IPromiseTimer.start}
100
+ */
101
+ start(ms?: number, handler?: () => void): Promise<IPromiseTimerResult>;
102
+ clear(): void;
103
+ protected wrapHandler(handler: () => void): void;
104
+ }
105
+ //# sourceMappingURL=timer.d.ts.map
@@ -0,0 +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"}
package/lib/timer.js ADDED
@@ -0,0 +1,180 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { assert } from "./assert";
6
+ import { Deferred } from "./promises";
7
+ const maxSetTimeoutMs = 0x7fffffff; // setTimeout limit is MAX_INT32=(2^31-1).
8
+ /**
9
+ * Sets timeouts like the setTimeout function allowing timeouts to exceed the setTimeout's max timeout limit.
10
+ * Timeouts may not be exactly accurate due to browser implementations and the OS.
11
+ * https://stackoverflow.com/questions/21097421/what-is-the-reason-javascript-settimeout-is-so-inaccurate
12
+ * @param timeoutFn - Executed when the timeout expires
13
+ * @param timeoutMs - Duration of the timeout in milliseconds
14
+ * @param setTimeoutIdFn - Executed to update the timeout if multiple timeouts are required when
15
+ * timeoutMs greater than maxTimeout
16
+ * @returns The initial timeout
17
+ */
18
+ export function setLongTimeout(timeoutFn, timeoutMs, setTimeoutIdFn) {
19
+ // The setTimeout max is 24.8 days before looping occurs.
20
+ let timeoutId;
21
+ if (timeoutMs > maxSetTimeoutMs) {
22
+ const newTimeoutMs = timeoutMs - maxSetTimeoutMs;
23
+ timeoutId = setTimeout(() => setLongTimeout(timeoutFn, newTimeoutMs, setTimeoutIdFn), maxSetTimeoutMs);
24
+ }
25
+ else {
26
+ timeoutId = setTimeout(() => timeoutFn(), Math.max(timeoutMs, 0));
27
+ }
28
+ setTimeoutIdFn?.(timeoutId);
29
+ return timeoutId;
30
+ }
31
+ /**
32
+ * This class is a thin wrapper over setTimeout and clearTimeout which
33
+ * makes it simpler to keep track of recurring timeouts with the same
34
+ * or similar handlers and timeouts. This class supports long timeouts
35
+ * or timeouts exceeding (2^31)-1 ms or approximately 24.8 days.
36
+ */
37
+ export class Timer {
38
+ constructor(defaultTimeout, defaultHandler, getCurrentTick = () => Date.now()) {
39
+ this.defaultTimeout = defaultTimeout;
40
+ this.defaultHandler = defaultHandler;
41
+ this.getCurrentTick = getCurrentTick;
42
+ }
43
+ /**
44
+ * Returns true if the timer is running.
45
+ */
46
+ get hasTimer() {
47
+ return !!this.runningState;
48
+ }
49
+ /**
50
+ * Calls setTimeout and tracks the resulting timeout.
51
+ * @param ms - overrides default timeout in ms
52
+ * @param handler - overrides default handler
53
+ */
54
+ start(ms = this.defaultTimeout, handler = this.defaultHandler) {
55
+ this.startCore(ms, handler, ms);
56
+ }
57
+ /**
58
+ * Calls clearTimeout on the underlying timeout if running.
59
+ */
60
+ clear() {
61
+ if (!this.runningState) {
62
+ return;
63
+ }
64
+ clearTimeout(this.runningState.timeout);
65
+ this.runningState = undefined;
66
+ }
67
+ /**
68
+ * Restarts the timer with the new handler and duration.
69
+ * If a new handler is passed, the original handler may
70
+ * never execute.
71
+ * This is a potentially more efficient way to clear and start
72
+ * a new timer.
73
+ * @param ms - overrides previous or default timeout in ms
74
+ * @param handler - overrides previous or default handler
75
+ */
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 {
82
+ const duration = ms ?? this.runningState.intendedDuration;
83
+ const handlerToUse = handler ?? this.runningState.restart?.handler ?? this.runningState.handler;
84
+ const remainingTime = this.calculateRemainingTime(this.runningState);
85
+ if (duration < remainingTime) {
86
+ // If remaining time exceeds restart duration, do a hard restart.
87
+ // The existing timeout time is too long.
88
+ this.start(duration, handlerToUse);
89
+ }
90
+ else if (duration === remainingTime) {
91
+ // The existing timeout time is perfect, just update handler and data.
92
+ this.runningState.handler = handlerToUse;
93
+ this.runningState.restart = undefined;
94
+ this.runningState.intendedDuration = duration;
95
+ }
96
+ else {
97
+ // If restart duration exceeds remaining time, set restart info.
98
+ // Existing timeout will start a new timeout for remaining time.
99
+ this.runningState.restart = {
100
+ startTick: this.getCurrentTick(),
101
+ duration,
102
+ handler: handlerToUse,
103
+ };
104
+ }
105
+ }
106
+ }
107
+ startCore(duration, handler, intendedDuration) {
108
+ this.clear();
109
+ this.runningState = {
110
+ startTick: this.getCurrentTick(),
111
+ duration,
112
+ intendedDuration,
113
+ handler,
114
+ timeout: setLongTimeout(() => this.handler(), duration, (timer) => {
115
+ if (this.runningState !== undefined) {
116
+ this.runningState.timeout = timer;
117
+ }
118
+ }),
119
+ };
120
+ }
121
+ handler() {
122
+ assert(!!this.runningState, 0x764 /* Running timer missing handler */);
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 {
130
+ // Run clear first, in case the handler decides to start again
131
+ const handler = this.runningState.handler;
132
+ this.clear();
133
+ handler();
134
+ }
135
+ }
136
+ calculateRemainingTime(runningTimeout) {
137
+ const elapsedTime = this.getCurrentTick() - runningTimeout.startTick;
138
+ return runningTimeout.duration - elapsedTime;
139
+ }
140
+ }
141
+ /**
142
+ * This class is a wrapper over setTimeout and clearTimeout which
143
+ * makes it simpler to keep track of recurring timeouts with the
144
+ * same handlers and timeouts, while also providing a promise that
145
+ * resolves when it times out.
146
+ */
147
+ export class PromiseTimer {
148
+ constructor(defaultTimeout, defaultHandler) {
149
+ this.timer = new Timer(defaultTimeout, () => this.wrapHandler(defaultHandler));
150
+ }
151
+ /**
152
+ * {@inheritDoc Timer.hasTimer}
153
+ */
154
+ get hasTimer() {
155
+ return this.timer.hasTimer;
156
+ }
157
+ /**
158
+ * {@inheritDoc IPromiseTimer.start}
159
+ */
160
+ async start(ms, handler) {
161
+ this.clear();
162
+ this.deferred = new Deferred();
163
+ this.timer.start(ms, handler ? () => this.wrapHandler(handler) : undefined);
164
+ return this.deferred.promise;
165
+ }
166
+ clear() {
167
+ this.timer.clear();
168
+ if (this.deferred) {
169
+ this.deferred.resolve({ timerResult: "cancel" });
170
+ this.deferred = undefined;
171
+ }
172
+ }
173
+ wrapHandler(handler) {
174
+ handler();
175
+ assert(!!this.deferred, 0x765 /* Handler executed without deferred */);
176
+ this.deferred.resolve({ timerResult: "timeout" });
177
+ this.deferred = undefined;
178
+ }
179
+ }
180
+ //# sourceMappingURL=timer.js.map
@@ -0,0 +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"]}
@@ -0,0 +1,21 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ /**
6
+ * This function can be used to assert at compile time that a given value has type never.
7
+ * One common usage is in the default case of a switch block,
8
+ * to ensure that all cases are explicitly handled.
9
+ *
10
+ * Example:
11
+ * ```typescript
12
+ * const bool: true | false = ...;
13
+ * switch(bool) {
14
+ * case true: {...}
15
+ * case false: {...}
16
+ * default: unreachableCase(bool);
17
+ * }
18
+ * ```
19
+ */
20
+ export declare function unreachableCase(_: never, message?: string): never;
21
+ //# sourceMappingURL=unreachable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unreachable.d.ts","sourceRoot":"","sources":["../src/unreachable.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,SAAqB,GAAG,KAAK,CAE7E"}