clock.js (1425B)
1 // Active-time deadline: input/step/idle pauses are excluded. Long delays are 2 // chunked to fit the browser's signed 32-bit timer range. 3 export class ActiveClock { 4 expire; 5 now; 6 schedule; 7 cancel; 8 remaining = Infinity; 9 since; 10 timer; 11 constructor(expire, now = () => performance.now(), schedule = (handler, delay, ...args) => globalThis.setTimeout(handler, delay, ...args), cancel = id => globalThis.clearTimeout(id)) { 12 this.expire = expire; 13 this.now = now; 14 this.schedule = schedule; 15 this.cancel = cancel; 16 } 17 reset(milliseconds) { 18 if (milliseconds !== Infinity && (!Number.isSafeInteger(milliseconds) || milliseconds < 1)) 19 throw new Error('Invalid active deadline'); 20 this.pause(); 21 this.remaining = milliseconds; 22 } 23 start() { 24 if (this.since !== undefined || this.remaining === Infinity) 25 return; 26 this.since = this.now(); 27 this.timer = this.schedule(() => { 28 this.pause(); 29 if (this.remaining <= 0) 30 this.expire(); 31 else 32 this.start(); 33 }, Math.min(2_147_483_647, Math.max(0, this.remaining))); 34 } 35 pause() { 36 this.cancel(this.timer); 37 if (this.since !== undefined) 38 this.remaining -= this.now() - this.since; 39 this.since = undefined; 40 this.timer = undefined; 41 } 42 }