MCPcopy
hub / github.com/statelyai/xstate / SimulatedClock

Class SimulatedClock

packages/core/src/SimulatedClock.ts:16–85  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

14}
15// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
16export class SimulatedClock implements SimulatedClock {
17 private timeouts: Map<number, SimulatedTimeout> = new Map();
18 private _now: number = 0;
19 private _id: number = 0;
20 private _flushing = false;
21 private _flushingInvalidated = false;
22
23 public now() {
24 return this._now;
25 }
26 private getId() {
27 return this._id++;
28 }
29 public setTimeout(fn: (...args: any[]) => void, timeout: number) {
30 this._flushingInvalidated = this._flushing;
31 const id = this.getId();
32 this.timeouts.set(id, {
33 start: this.now(),
34 timeout,
35 fn
36 });
37 return id;
38 }
39 public clearTimeout(id: number) {
40 this._flushingInvalidated = this._flushing;
41 this.timeouts.delete(id);
42 }
43 public set(time: number) {
44 if (this._now > time) {
45 throw new Error('Unable to travel back in time');
46 }
47
48 this._now = time;
49 this.flushTimeouts();
50 }
51 private flushTimeouts() {
52 if (this._flushing) {
53 this._flushingInvalidated = true;
54 return;
55 }
56 this._flushing = true;
57
58 const sorted = [...this.timeouts].sort(
59 ([_idA, timeoutA], [_idB, timeoutB]) => {
60 const endA = timeoutA.start + timeoutA.timeout;
61 const endB = timeoutB.start + timeoutB.timeout;
62 return endB > endA ? -1 : 1;
63 }
64 );
65
66 for (const [id, timeout] of sorted) {
67 if (this._flushingInvalidated) {
68 this._flushingInvalidated = false;
69 this._flushing = false;
70 this.flushTimeouts();
71 return;
72 }
73 if (this.now() - timeout.start >= timeout.timeout) {

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected