UNPKG

tempus

Version:
149 lines (148 loc) 4.38 kB
// packages/core/src/uid.ts var index = 0; function getUID() { return index++; } // packages/core/src/tempus.ts var isClient = typeof window !== "undefined"; var originalRAF = isClient && window.requestAnimationFrame; var originalCancelRAF = isClient && window.cancelAnimationFrame; var Framerate = class { callbacks = []; fps; time = 0; lastTickDate = performance.now(); framesCount = 0; constructor(fps = Number.POSITIVE_INFINITY) { this.fps = fps; } get isRelativeFps() { return typeof this.fps === "string" && this.fps.endsWith("%"); } get maxFramesCount() { if (!this.isRelativeFps) return 1; return Math.max(1, Math.round(100 / Number(this.fps.replace("%", "")))); } get executionTime() { if (this.isRelativeFps) return 0; return 1e3 / this.fps; } dispatch(time, deltaTime) { for (let i = 0; i < this.callbacks.length; i++) { const now = performance.now(); this.callbacks[i]?.callback(time, deltaTime); const duration = performance.now() - now; this.callbacks[i].samples?.push(duration); this.callbacks[i].samples = this.callbacks[i].samples?.slice(-9); } } raf(time, deltaTime) { this.time += deltaTime; if (this.isRelativeFps) { if (this.framesCount === 0) { this.dispatch(time, deltaTime); } this.framesCount++; this.framesCount %= this.maxFramesCount; } else { if (this.fps === Number.POSITIVE_INFINITY) { this.dispatch(time, deltaTime); } else if (this.time >= this.executionTime) { this.time = this.time % this.executionTime; const deltaTime2 = time - this.lastTickDate; this.lastTickDate = time; this.dispatch(time, deltaTime2); } } } add({ callback, priority, label }) { if (typeof callback !== "function") { console.warn("Tempus.add: callback is not a function"); return; } const uid = getUID(); this.callbacks.push({ callback, priority, uid, label, samples: [] }); this.callbacks.sort((a, b) => a.priority - b.priority); return () => this.remove(uid); } remove(uid) { this.callbacks = this.callbacks.filter(({ uid: u }) => uid !== u); } }; var TempusImpl = class { framerates; time; fps; usage; constructor() { this.framerates = {}; this.time = isClient ? performance.now() : 0; this.usage = 0; if (!isClient) return; requestAnimationFrame(this.raf); } add(callback, { priority = 0, fps = Number.POSITIVE_INFINITY, label = "" } = {}) { if (!isClient) return; if (typeof fps === "number" || typeof fps === "string" && fps.endsWith("%")) { if (!this.framerates[fps]) this.framerates[fps] = new Framerate(fps); return this.framerates[fps].add({ callback, priority, label }); } console.warn('Tempus.add: fps is not a number or a string ending with "%"'); } raf = (time) => { if (!isClient) return; const deltaTime = time - this.time; this.time = time; this.fps = 1e3 / deltaTime; const now = performance.now(); for (const framerate of Object.values(this.framerates)) { framerate.raf(time, deltaTime); } const duration = performance.now() - now; this.usage = duration / deltaTime; requestAnimationFrame(this.raf); }; patch() { if (!isClient) return; window.requestAnimationFrame = (callback, { priority = 0, fps = Number.POSITIVE_INFINITY } = {}) => { if (callback === this.raf || !callback.toString().includes("requestAnimationFrame(")) { return originalRAF(callback); } if (!callback.__tempusPatched) { console.log("patching", callback.name, callback); callback.__tempusPatched = true; callback.__tempusUnsubscribe = this.add(callback, { priority, fps, label: callback.name }); } return callback.__tempusUnsubscribe; }; window.cancelAnimationFrame = (callback) => { if (typeof callback === "function") { callback?.(); return; } return originalCancelRAF(callback); }; } unpatch() { if (!isClient) return; window.requestAnimationFrame = originalRAF; window.cancelAnimationFrame = originalCancelRAF; } }; var Tempus = new TempusImpl(); export { Tempus as default }; //# sourceMappingURL=tempus.mjs.map