/**
* 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