/** * FrameBudget -- rAF priority lanes for frame budget management. * * Tracks remaining frame budget per animation frame and * schedules work by priority: `critical > high > low > idle`. * * Hot path methods (remaining, canRun, scheduleSync) are plain JS. * Effect is used only for resource lifecycle (rAF cleanup) and * backwards-compatible schedule() wrapper. * * @module */ import type { Scope } from 'effect'; import { Effect } from 'effect'; import { type Clock } from './clock.js'; /** * Frame-budget priority lane in descending urgency. `critical` always runs; * `high` / `low` / `idle` gate based on the milliseconds remaining in the * current frame. */ export type Priority = 'critical' | 'high' | 'low' | 'idle'; interface FrameBudgetShape { remaining(): number; canRun(priority: Priority): boolean; /** Synchronous scheduler for hot paths — no Effect overhead. */ scheduleSync(priority: Priority, task: () => A): A | null; schedule(priority: Priority, task: Effect.Effect): Effect.Effect; readonly fps: Effect.Effect; /** Synchronous FPS accessor for hot paths. */ readonly fpsSync: number; } /** * Creates a FrameBudget tracker tied to rAF, with priority-based scheduling. * Critical tasks always run; lower priorities are deferred if budget is exhausted. * * @example * ```ts * const program = Effect.scoped(Effect.gen(function* () { * const budget = yield* FrameBudget.make({ targetFps: 60 }); * const remaining = budget.remaining(); // ms left in this frame * const canAnimate = budget.canRun('high'); // true if enough budget * const result = yield* budget.schedule('low', Effect.succeed('done')); * // result is 'done' if budget permits, null otherwise * })); * ``` */ declare function _make(config?: { targetFps?: number; clock?: Clock; }): Effect.Effect; /** * FrameBudget -- rAF-based frame budget manager with priority lanes. * Tracks remaining time per animation frame and gates work by priority: * `critical` (always runs) `> high > low > idle`. * * @example * ```ts * const program = Effect.scoped(Effect.gen(function* () { * const budget = yield* FrameBudget.make({ targetFps: 60 }); * if (budget.canRun('high')) { * yield* budget.schedule('high', Effect.succeed('rendered')); * } * const fps = yield* budget.fps; // current measured FPS * })); * ``` */ export declare const FrameBudget: { make: typeof _make; }; export declare namespace FrameBudget { /** Structural shape of a {@link FrameBudget} instance — `canRun`, `schedule`, `remaining`, `fps`. */ type Shape = FrameBudgetShape; } export {}; //# sourceMappingURL=frame-budget.d.ts.map