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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/.eslintrc.js +36 -0
  2. package/.mocharc.js +13 -0
  3. package/CHANGELOG.md +81 -0
  4. package/LICENSE +21 -0
  5. package/README.md +75 -0
  6. package/api-extractor-lint.json +4 -0
  7. package/api-extractor.json +4 -0
  8. package/api-report/core-utils.api.md +147 -0
  9. package/dist/assert.d.ts +17 -0
  10. package/dist/assert.d.ts.map +1 -0
  11. package/dist/assert.js +25 -0
  12. package/dist/assert.js.map +1 -0
  13. package/dist/compare.d.ts +16 -0
  14. package/dist/compare.d.ts.map +1 -0
  15. package/dist/compare.js +28 -0
  16. package/dist/compare.js.map +1 -0
  17. package/dist/core-utils-alpha.d.ts +191 -0
  18. package/dist/core-utils-beta.d.ts +41 -0
  19. package/dist/core-utils-public.d.ts +41 -0
  20. package/dist/core-utils-untrimmed.d.ts +414 -0
  21. package/dist/delay.d.ts +11 -0
  22. package/dist/delay.d.ts.map +1 -0
  23. package/dist/delay.js +15 -0
  24. package/dist/delay.js.map +1 -0
  25. package/dist/heap.d.ts +86 -0
  26. package/dist/heap.d.ts.map +1 -0
  27. package/dist/heap.js +144 -0
  28. package/dist/heap.js.map +1 -0
  29. package/dist/index.d.ts +14 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +30 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/lazy.d.ts +44 -0
  34. package/dist/lazy.d.ts.map +1 -0
  35. package/dist/lazy.js +84 -0
  36. package/dist/lazy.js.map +1 -0
  37. package/dist/promiseCache.d.ts +89 -0
  38. package/dist/promiseCache.d.ts.map +1 -0
  39. package/dist/promiseCache.js +148 -0
  40. package/dist/promiseCache.js.map +1 -0
  41. package/dist/promises.d.ts +38 -0
  42. package/dist/promises.d.ts.map +1 -0
  43. package/dist/promises.js +60 -0
  44. package/dist/promises.js.map +1 -0
  45. package/dist/timer.d.ts +115 -0
  46. package/dist/timer.d.ts.map +1 -0
  47. package/dist/timer.js +189 -0
  48. package/dist/timer.js.map +1 -0
  49. package/dist/tsdoc-metadata.json +11 -0
  50. package/dist/unreachable.d.ts +22 -0
  51. package/dist/unreachable.d.ts.map +1 -0
  52. package/dist/unreachable.js +28 -0
  53. package/dist/unreachable.js.map +1 -0
  54. package/lib/assert.d.ts +17 -0
  55. package/lib/assert.d.ts.map +1 -0
  56. package/lib/assert.js +25 -0
  57. package/lib/assert.js.map +1 -0
  58. package/lib/compare.d.ts +16 -0
  59. package/lib/compare.d.ts.map +1 -0
  60. package/lib/compare.js +28 -0
  61. package/lib/compare.js.map +1 -0
  62. package/lib/core-utils-alpha.d.ts +191 -0
  63. package/lib/core-utils-beta.d.ts +41 -0
  64. package/lib/core-utils-public.d.ts +41 -0
  65. package/lib/core-utils-untrimmed.d.ts +414 -0
  66. package/lib/delay.d.ts +11 -0
  67. package/lib/delay.d.ts.map +1 -0
  68. package/lib/delay.js +15 -0
  69. package/lib/delay.js.map +1 -0
  70. package/lib/heap.d.ts +86 -0
  71. package/lib/heap.d.ts.map +1 -0
  72. package/lib/heap.js +144 -0
  73. package/lib/heap.js.map +1 -0
  74. package/lib/index.d.ts +14 -0
  75. package/lib/index.d.ts.map +1 -0
  76. package/lib/index.js +30 -0
  77. package/lib/index.js.map +1 -0
  78. package/lib/lazy.d.ts +44 -0
  79. package/lib/lazy.d.ts.map +1 -0
  80. package/lib/lazy.js +84 -0
  81. package/lib/lazy.js.map +1 -0
  82. package/lib/promiseCache.d.ts +89 -0
  83. package/lib/promiseCache.d.ts.map +1 -0
  84. package/lib/promiseCache.js +148 -0
  85. package/lib/promiseCache.js.map +1 -0
  86. package/lib/promises.d.ts +38 -0
  87. package/lib/promises.d.ts.map +1 -0
  88. package/lib/promises.js +60 -0
  89. package/lib/promises.js.map +1 -0
  90. package/lib/timer.d.ts +115 -0
  91. package/lib/timer.d.ts.map +1 -0
  92. package/lib/timer.js +189 -0
  93. package/lib/timer.js.map +1 -0
  94. package/lib/unreachable.d.ts +22 -0
  95. package/lib/unreachable.d.ts.map +1 -0
  96. package/lib/unreachable.js +28 -0
  97. package/lib/unreachable.js.map +1 -0
  98. package/package.json +111 -0
  99. package/prettier.config.cjs +8 -0
  100. package/src/assert.ts +23 -0
  101. package/src/compare.ts +33 -0
  102. package/src/delay.ts +12 -0
  103. package/src/heap.ts +182 -0
  104. package/src/index.ts +21 -0
  105. package/src/lazy.ts +88 -0
  106. package/src/promiseCache.ts +205 -0
  107. package/src/promises.ts +63 -0
  108. package/src/timer.ts +289 -0
  109. package/src/unreachable.ts +24 -0
  110. package/tsconfig.esnext.json +6 -0
  111. package/tsconfig.json +12 -0
package/lib/timer.d.ts ADDED
@@ -0,0 +1,115 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ /**
6
+ * @internal
7
+ */
8
+ export interface ITimer {
9
+ /**
10
+ * True if timer is currently running
11
+ */
12
+ readonly hasTimer: boolean;
13
+ /**
14
+ * Starts the timer
15
+ */
16
+ start(): void;
17
+ /**
18
+ * Cancels the timer if already running
19
+ */
20
+ clear(): void;
21
+ }
22
+ /**
23
+ * Sets timeouts like the setTimeout function allowing timeouts to exceed the setTimeout's max timeout limit.
24
+ * Timeouts may not be exactly accurate due to browser implementations and the OS.
25
+ * https://stackoverflow.com/questions/21097421/what-is-the-reason-javascript-settimeout-is-so-inaccurate
26
+ * @param timeoutFn - Executed when the timeout expires
27
+ * @param timeoutMs - Duration of the timeout in milliseconds
28
+ * @param setTimeoutIdFn - Executed to update the timeout if multiple timeouts are required when
29
+ * timeoutMs greater than maxTimeout
30
+ * @returns The initial timeout
31
+ * @internal
32
+ */
33
+ export declare function setLongTimeout(timeoutFn: () => void, timeoutMs: number, setTimeoutIdFn?: (timeoutId: ReturnType<typeof setTimeout>) => void): ReturnType<typeof setTimeout>;
34
+ /**
35
+ * This class is a thin wrapper over setTimeout and clearTimeout which
36
+ * makes it simpler to keep track of recurring timeouts with the same
37
+ * or similar handlers and timeouts. This class supports long timeouts
38
+ * or timeouts exceeding (2^31)-1 ms or approximately 24.8 days.
39
+ * @internal
40
+ */
41
+ export declare class Timer implements ITimer {
42
+ private readonly defaultTimeout;
43
+ private readonly defaultHandler;
44
+ private readonly getCurrentTick;
45
+ /**
46
+ * Returns true if the timer is running.
47
+ */
48
+ get hasTimer(): boolean;
49
+ private runningState;
50
+ constructor(defaultTimeout: number, defaultHandler: () => void, getCurrentTick?: () => number);
51
+ /**
52
+ * Calls setTimeout and tracks the resulting timeout.
53
+ * @param ms - overrides default timeout in ms
54
+ * @param handler - overrides default handler
55
+ */
56
+ start(ms?: number, handler?: () => void): void;
57
+ /**
58
+ * Calls clearTimeout on the underlying timeout if running.
59
+ */
60
+ clear(): void;
61
+ /**
62
+ * Restarts the timer with the new handler and duration.
63
+ * If a new handler is passed, the original handler may
64
+ * never execute.
65
+ * This is a potentially more efficient way to clear and start
66
+ * a new timer.
67
+ * @param ms - overrides previous or default timeout in ms
68
+ * @param handler - overrides previous or default handler
69
+ */
70
+ restart(ms?: number, handler?: () => void): void;
71
+ private startCore;
72
+ private handler;
73
+ private calculateRemainingTime;
74
+ }
75
+ /**
76
+ * @internal
77
+ */
78
+ export interface IPromiseTimerResult {
79
+ timerResult: "timeout" | "cancel";
80
+ }
81
+ /**
82
+ * Timer which offers a promise that fulfills when the timer
83
+ * completes.
84
+ * @internal
85
+ */
86
+ export interface IPromiseTimer extends ITimer {
87
+ /**
88
+ * Starts the timer and returns a promise that
89
+ * resolves when the timer times out or is canceled.
90
+ */
91
+ start(): Promise<IPromiseTimerResult>;
92
+ }
93
+ /**
94
+ * This class is a wrapper over setTimeout and clearTimeout which
95
+ * makes it simpler to keep track of recurring timeouts with the
96
+ * same handlers and timeouts, while also providing a promise that
97
+ * resolves when it times out.
98
+ * @internal
99
+ */
100
+ export declare class PromiseTimer implements IPromiseTimer {
101
+ private deferred?;
102
+ private readonly timer;
103
+ /**
104
+ * {@inheritDoc Timer.hasTimer}
105
+ */
106
+ get hasTimer(): boolean;
107
+ constructor(defaultTimeout: number, defaultHandler: () => void);
108
+ /**
109
+ * {@inheritDoc IPromiseTimer.start}
110
+ */
111
+ start(ms?: number, handler?: () => void): Promise<IPromiseTimerResult>;
112
+ clear(): void;
113
+ protected wrapHandler(handler: () => void): void;
114
+ }
115
+ //# 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;;GAEG;AACH,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;;;;;;;;;;GAUG;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;;;;;;GAMG;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;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC,WAAW,EAAE,SAAS,GAAG,QAAQ,CAAC;CAClC;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAc,SAAQ,MAAM;IAC5C;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACtC;AAED;;;;;;GAMG;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 ADDED
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.PromiseTimer = exports.Timer = exports.setLongTimeout = void 0;
8
+ const assert_1 = require("./assert");
9
+ const promises_1 = require("./promises");
10
+ const maxSetTimeoutMs = 0x7fffffff; // setTimeout limit is MAX_INT32=(2^31-1).
11
+ /**
12
+ * Sets timeouts like the setTimeout function allowing timeouts to exceed the setTimeout's max timeout limit.
13
+ * Timeouts may not be exactly accurate due to browser implementations and the OS.
14
+ * https://stackoverflow.com/questions/21097421/what-is-the-reason-javascript-settimeout-is-so-inaccurate
15
+ * @param timeoutFn - Executed when the timeout expires
16
+ * @param timeoutMs - Duration of the timeout in milliseconds
17
+ * @param setTimeoutIdFn - Executed to update the timeout if multiple timeouts are required when
18
+ * timeoutMs greater than maxTimeout
19
+ * @returns The initial timeout
20
+ * @internal
21
+ */
22
+ function setLongTimeout(timeoutFn, timeoutMs, setTimeoutIdFn) {
23
+ // The setTimeout max is 24.8 days before looping occurs.
24
+ let timeoutId;
25
+ if (timeoutMs > maxSetTimeoutMs) {
26
+ const newTimeoutMs = timeoutMs - maxSetTimeoutMs;
27
+ timeoutId = setTimeout(() => setLongTimeout(timeoutFn, newTimeoutMs, setTimeoutIdFn), maxSetTimeoutMs);
28
+ }
29
+ else {
30
+ timeoutId = setTimeout(() => timeoutFn(), Math.max(timeoutMs, 0));
31
+ }
32
+ setTimeoutIdFn?.(timeoutId);
33
+ return timeoutId;
34
+ }
35
+ exports.setLongTimeout = setLongTimeout;
36
+ /**
37
+ * This class is a thin wrapper over setTimeout and clearTimeout which
38
+ * makes it simpler to keep track of recurring timeouts with the same
39
+ * or similar handlers and timeouts. This class supports long timeouts
40
+ * or timeouts exceeding (2^31)-1 ms or approximately 24.8 days.
41
+ * @internal
42
+ */
43
+ class Timer {
44
+ /**
45
+ * Returns true if the timer is running.
46
+ */
47
+ get hasTimer() {
48
+ return !!this.runningState;
49
+ }
50
+ constructor(defaultTimeout, defaultHandler, getCurrentTick = () => Date.now()) {
51
+ this.defaultTimeout = defaultTimeout;
52
+ this.defaultHandler = defaultHandler;
53
+ this.getCurrentTick = getCurrentTick;
54
+ }
55
+ /**
56
+ * Calls setTimeout and tracks the resulting timeout.
57
+ * @param ms - overrides default timeout in ms
58
+ * @param handler - overrides default handler
59
+ */
60
+ start(ms = this.defaultTimeout, handler = this.defaultHandler) {
61
+ this.startCore(ms, handler, ms);
62
+ }
63
+ /**
64
+ * Calls clearTimeout on the underlying timeout if running.
65
+ */
66
+ clear() {
67
+ if (!this.runningState) {
68
+ return;
69
+ }
70
+ clearTimeout(this.runningState.timeout);
71
+ this.runningState = undefined;
72
+ }
73
+ /**
74
+ * Restarts the timer with the new handler and duration.
75
+ * If a new handler is passed, the original handler may
76
+ * never execute.
77
+ * This is a potentially more efficient way to clear and start
78
+ * a new timer.
79
+ * @param ms - overrides previous or default timeout in ms
80
+ * @param handler - overrides previous or default handler
81
+ */
82
+ restart(ms, handler) {
83
+ if (this.runningState) {
84
+ const duration = ms ?? this.runningState.intendedDuration;
85
+ const handlerToUse = handler ?? this.runningState.restart?.handler ?? this.runningState.handler;
86
+ const remainingTime = this.calculateRemainingTime(this.runningState);
87
+ if (duration < remainingTime) {
88
+ // If remaining time exceeds restart duration, do a hard restart.
89
+ // The existing timeout time is too long.
90
+ this.start(duration, handlerToUse);
91
+ }
92
+ else if (duration === remainingTime) {
93
+ // The existing timeout time is perfect, just update handler and data.
94
+ this.runningState.handler = handlerToUse;
95
+ this.runningState.restart = undefined;
96
+ this.runningState.intendedDuration = duration;
97
+ }
98
+ else {
99
+ // If restart duration exceeds remaining time, set restart info.
100
+ // Existing timeout will start a new timeout for remaining time.
101
+ this.runningState.restart = {
102
+ startTick: this.getCurrentTick(),
103
+ duration,
104
+ handler: handlerToUse,
105
+ };
106
+ }
107
+ }
108
+ else {
109
+ // If restart is called first, it behaves as a call to start
110
+ this.start(ms, handler);
111
+ }
112
+ }
113
+ startCore(duration, handler, intendedDuration) {
114
+ this.clear();
115
+ this.runningState = {
116
+ startTick: this.getCurrentTick(),
117
+ duration,
118
+ intendedDuration,
119
+ handler,
120
+ timeout: setLongTimeout(() => this.handler(), duration, (timer) => {
121
+ if (this.runningState !== undefined) {
122
+ this.runningState.timeout = timer;
123
+ }
124
+ }),
125
+ };
126
+ }
127
+ handler() {
128
+ (0, assert_1.assert)(!!this.runningState, 0x764 /* Running timer missing handler */);
129
+ const restart = this.runningState.restart;
130
+ if (restart === undefined) {
131
+ // Run clear first, in case the handler decides to start again
132
+ const handler = this.runningState.handler;
133
+ this.clear();
134
+ handler();
135
+ }
136
+ else {
137
+ // Restart with remaining time
138
+ const remainingTime = this.calculateRemainingTime(restart);
139
+ this.startCore(remainingTime, () => restart.handler(), restart.duration);
140
+ }
141
+ }
142
+ calculateRemainingTime(runningTimeout) {
143
+ const elapsedTime = this.getCurrentTick() - runningTimeout.startTick;
144
+ return runningTimeout.duration - elapsedTime;
145
+ }
146
+ }
147
+ exports.Timer = Timer;
148
+ /**
149
+ * This class is a wrapper over setTimeout and clearTimeout which
150
+ * makes it simpler to keep track of recurring timeouts with the
151
+ * same handlers and timeouts, while also providing a promise that
152
+ * resolves when it times out.
153
+ * @internal
154
+ */
155
+ class PromiseTimer {
156
+ /**
157
+ * {@inheritDoc Timer.hasTimer}
158
+ */
159
+ get hasTimer() {
160
+ return this.timer.hasTimer;
161
+ }
162
+ constructor(defaultTimeout, defaultHandler) {
163
+ this.timer = new Timer(defaultTimeout, () => this.wrapHandler(defaultHandler));
164
+ }
165
+ /**
166
+ * {@inheritDoc IPromiseTimer.start}
167
+ */
168
+ async start(ms, handler) {
169
+ this.clear();
170
+ this.deferred = new promises_1.Deferred();
171
+ this.timer.start(ms, handler ? () => this.wrapHandler(handler) : undefined);
172
+ return this.deferred.promise;
173
+ }
174
+ clear() {
175
+ this.timer.clear();
176
+ if (this.deferred) {
177
+ this.deferred.resolve({ timerResult: "cancel" });
178
+ this.deferred = undefined;
179
+ }
180
+ }
181
+ wrapHandler(handler) {
182
+ handler();
183
+ (0, assert_1.assert)(!!this.deferred, 0x765 /* Handler executed without deferred */);
184
+ this.deferred.resolve({ timerResult: "timeout" });
185
+ this.deferred = undefined;
186
+ }
187
+ }
188
+ exports.PromiseTimer = PromiseTimer;
189
+ //# 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\n/**\n * @internal\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 * @internal\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 * @internal\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\n/**\n * @internal\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 * @internal\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 * @internal\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"]}
@@ -0,0 +1,22 @@
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
+ * @internal
20
+ */
21
+ export declare function unreachableCase(_: never, message?: string): never;
22
+ //# 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;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,SAAqB,GAAG,KAAK,CAE7E"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.unreachableCase = void 0;
8
+ /**
9
+ * This function can be used to assert at compile time that a given value has type never.
10
+ * One common usage is in the default case of a switch block,
11
+ * to ensure that all cases are explicitly handled.
12
+ *
13
+ * Example:
14
+ * ```typescript
15
+ * const bool: true | false = ...;
16
+ * switch(bool) {
17
+ * case true: {...}
18
+ * case false: {...}
19
+ * default: unreachableCase(bool);
20
+ * }
21
+ * ```
22
+ * @internal
23
+ */
24
+ function unreachableCase(_, message = "Unreachable Case") {
25
+ throw new Error(message);
26
+ }
27
+ exports.unreachableCase = unreachableCase;
28
+ //# sourceMappingURL=unreachable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unreachable.js","sourceRoot":"","sources":["../src/unreachable.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,eAAe,CAAC,CAAQ,EAAE,OAAO,GAAG,kBAAkB;IACrE,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AAC1B,CAAC;AAFD,0CAEC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * This function can be used to assert at compile time that a given value has type never.\n * One common usage is in the default case of a switch block,\n * to ensure that all cases are explicitly handled.\n *\n * Example:\n * ```typescript\n * const bool: true | false = ...;\n * switch(bool) {\n * case true: {...}\n * case false: {...}\n * default: unreachableCase(bool);\n * }\n * ```\n * @internal\n */\nexport function unreachableCase(_: never, message = \"Unreachable Case\"): never {\n\tthrow new Error(message);\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,111 @@
1
+ {
2
+ "name": "@fluidframework/core-utils",
3
+ "version": "2.0.0-dev-rc.1.0.0.224419",
4
+ "description": "Not intended for use outside the Fluid client repo.",
5
+ "homepage": "https://fluidframework.com",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/microsoft/FluidFramework.git",
9
+ "directory": "packages/common/core-utils"
10
+ },
11
+ "license": "MIT",
12
+ "author": "Microsoft and contributors",
13
+ "sideEffects": false,
14
+ "main": "dist/index.js",
15
+ "module": "lib/index.js",
16
+ "types": "dist/index.d.ts",
17
+ "c8": {
18
+ "all": true,
19
+ "cache-dir": "nyc/.cache",
20
+ "exclude": [
21
+ "src/test/**/*.*ts",
22
+ "dist/test/**/*.*js"
23
+ ],
24
+ "exclude-after-remap": false,
25
+ "include": [
26
+ "src/**/*.*ts",
27
+ "dist/**/*.*js"
28
+ ],
29
+ "report-dir": "nyc/report",
30
+ "reporter": [
31
+ "cobertura",
32
+ "html",
33
+ "text"
34
+ ],
35
+ "temp-directory": "nyc/.nyc_output"
36
+ },
37
+ "devDependencies": {
38
+ "@arethetypeswrong/cli": "^0.13.3",
39
+ "@fluid-tools/benchmark": "^0.47.0",
40
+ "@fluid-tools/build-cli": "0.29.0-222379",
41
+ "@fluidframework/build-common": "^2.0.3",
42
+ "@fluidframework/build-tools": "0.29.0-222379",
43
+ "@fluidframework/eslint-config-fluid": "^3.1.0",
44
+ "@fluidframework/mocha-test-setup": "2.0.0-dev-rc.1.0.0.224419",
45
+ "@microsoft/api-extractor": "^7.38.3",
46
+ "@types/mocha": "^9.1.1",
47
+ "@types/node": "^18.19.0",
48
+ "@types/sinon": "^7.0.13",
49
+ "c8": "^7.7.1",
50
+ "copyfiles": "^2.4.1",
51
+ "cross-env": "^7.0.3",
52
+ "eslint": "~8.50.0",
53
+ "eslint-config-prettier": "~9.0.0",
54
+ "mocha": "^10.2.0",
55
+ "mocha-json-output-reporter": "^2.0.1",
56
+ "mocha-multi-reporters": "^1.5.1",
57
+ "moment": "^2.21.0",
58
+ "prettier": "~3.0.3",
59
+ "rimraf": "^4.4.0",
60
+ "sinon": "^7.4.2",
61
+ "typescript": "~5.1.6"
62
+ },
63
+ "fluidBuild": {
64
+ "tasks": {
65
+ "build:docs": {
66
+ "dependsOn": [
67
+ "...",
68
+ "api-extractor:commonjs",
69
+ "api-extractor:esnext"
70
+ ],
71
+ "script": false
72
+ }
73
+ }
74
+ },
75
+ "typeValidation": {
76
+ "disabled": true,
77
+ "broken": {}
78
+ },
79
+ "scripts": {
80
+ "api": "fluid-build . --task api",
81
+ "api-extractor:commonjs": "api-extractor run --local",
82
+ "api-extractor:esnext": "copyfiles -u 1 \"dist/**/*-@(alpha|beta|public|untrimmed).d.ts\" lib",
83
+ "bench": "mocha --timeout 999999 --perfMode --parentProcess --fgrep @Benchmark --reporter @fluid-tools/benchmark/dist/MochaReporter.js",
84
+ "bench:profile": "mocha --v8-prof --v8-logfile=profile.log --v8-no-logfile-per-isolate --timeout 999999 --perfMode --fgrep @Benchmark --reporter @fluid-tools/benchmark/dist/MochaReporter.js && node --prof-process profile.log > profile.txt && rimraf profile.log && echo See results in profile.txt",
85
+ "build": "fluid-build . --task build",
86
+ "build:commonjs": "fluid-build . --task commonjs",
87
+ "build:compile": "fluid-build . --task compile",
88
+ "build:docs": "fluid-build . --task api",
89
+ "build:esnext": "tsc --project ./tsconfig.esnext.json",
90
+ "build:test": "tsc --project ./src/test/tsconfig.json",
91
+ "check:are-the-types-wrong": "attw --pack",
92
+ "check:release-tags": "api-extractor run --local --config ./api-extractor-lint.json",
93
+ "ci:build:docs": "api-extractor run",
94
+ "clean": "rimraf --glob dist lib \"**/*.tsbuildinfo\" \"**/*.build.log\" _api-extractor-temp nyc",
95
+ "eslint": "eslint --format stylish src",
96
+ "eslint:fix": "eslint --format stylish src --fix --fix-type problem,suggestion,layout",
97
+ "format": "npm run prettier:fix",
98
+ "lint": "npm run prettier && npm run check:release-tags && npm run eslint",
99
+ "lint:fix": "npm run prettier:fix && npm run eslint:fix",
100
+ "prettier": "prettier --check . --cache --ignore-path ../../../.prettierignore",
101
+ "prettier:fix": "prettier --write . --cache --ignore-path ../../../.prettierignore",
102
+ "test": "npm run test:mocha",
103
+ "test:benchmark:report": "mocha --node-option unhandled-rejections=strict,expose-gc --exit --perfMode --fgrep @Benchmark --reporter @fluid-tools/benchmark/dist/MochaReporter.js --timeout 60000",
104
+ "test:coverage": "c8 npm test",
105
+ "test:mocha": "mocha",
106
+ "test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
107
+ "tsc": "tsc",
108
+ "typetests:gen": "fluid-type-test-generator",
109
+ "typetests:prepare": "flub typetests --dir . --reset --previous --normalize"
110
+ }
111
+ }
@@ -0,0 +1,8 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ module.exports = {
7
+ ...require("@fluidframework/build-common/prettier.config.cjs"),
8
+ };
package/src/assert.ts ADDED
@@ -0,0 +1,23 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ /**
7
+ * A browser friendly assert library.
8
+ * Use this instead of the 'assert' package, which has a big impact on bundle sizes.
9
+ * @param condition - The condition that should be true, if the condition is false an error will be thrown.
10
+ * Only use this API when `false` indicates a logic error in the problem and thus a bug that should be fixed.
11
+ * @param message - The message to include in the error when the condition does not hold.
12
+ * A number should not be specified manually: use a string.
13
+ * Before a release, policy-check should be run, which will convert any asserts still using strings to
14
+ * use numbered error codes instead.
15
+ * @alpha
16
+ */
17
+ export function assert(condition: boolean, message: string | number): asserts condition {
18
+ if (!condition) {
19
+ throw new Error(
20
+ typeof message === "number" ? `0x${message.toString(16).padStart(3, "0")}` : message,
21
+ );
22
+ }
23
+ }
package/src/compare.ts ADDED
@@ -0,0 +1,33 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ /**
7
+ * Compare two arrays. Returns true if their elements are equivalent and in the same order.
8
+ *
9
+ * @alpha
10
+ *
11
+ * @param left - The first array to compare
12
+ * @param right - The second array to compare
13
+ * @param comparator - The function used to check if two `T`s are equivalent.
14
+ * Defaults to `Object.is()` equality (a shallow compare where NaN = NaN and -0 ≠ 0)
15
+ */
16
+ export const compareArrays = <T>(
17
+ left: readonly T[],
18
+ right: readonly T[],
19
+ comparator: (leftItem: T, rightItem: T, index: number) => boolean = (
20
+ leftItem: T,
21
+ rightItem: T,
22
+ ): boolean => Object.is(leftItem, rightItem),
23
+ ): boolean => {
24
+ // PERF: 'for-loop' and 'Array.every()' tied.
25
+ // '===' and 'Object.is()' tied.
26
+ // Trivial acceptance adds no measurable overhead.
27
+ // 30% penalty vs. baseline for exported function [node 14 x64].
28
+ return (
29
+ left === right || // Trivial acceptance: 'left' and 'right' are the same instance
30
+ (left.length === right.length && // Trivial rejection: 'left' and 'right' are different lengths
31
+ left.every((leftItem, index) => comparator(leftItem, right[index], index)))
32
+ );
33
+ };
package/src/delay.ts ADDED
@@ -0,0 +1,12 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+
6
+ /**
7
+ * Returns a promise that resolves after `timeMs`.
8
+ * @param timeMs - Time in milliseconds to wait.
9
+ * @internal
10
+ */
11
+ export const delay = async (timeMs: number): Promise<void> =>
12
+ new Promise((resolve) => setTimeout(() => resolve(), timeMs));