import { type KeyValueStorage } from "./keyValueStore.js"; export interface LevelDescriptor { id: string; config: TLevelConfig; } /** A level's star rating, 0 (cleared, no stars) to 3. */ export type LevelStars = 0 | 1 | 2 | 3; /** Persisted per-level outcome: whether it has ever been cleared and the best star rating achieved. */ export interface LevelRecord { cleared: boolean; stars: LevelStars; } export interface LevelSequenceConfig { levels: readonly LevelDescriptor[]; /** Extra attempts granted after the first per level. Defaults to 0 (a single attempt, no retries). */ retriesPerLevel?: number; /** Persistence key for per-level completion/stars. Omit to keep records in-memory only. */ key?: string; /** Storage backend for the records (browser `localStorage` by default when `key` is set); pass `null` for memory-only. */ storage?: KeyValueStorage | null; } export type LevelSequenceStatus = "idle" | "playing" | "cleared" | "failed" | "complete"; export interface CurrentLevel { id: string; index: number; config: TLevelConfig; attempt: number; } export interface LevelSequenceProgress { index: number; total: number; cleared: readonly string[]; } export interface LevelSequence { current(): CurrentLevel | null; status(): LevelSequenceStatus; /** Enters level 0. A no-op on an empty level list, which leaves `status()` at "idle" forever. */ start(): void; /** Marks the current level cleared, recording its best star rating; call `advance()` to move to the next one. */ clear(stars?: LevelStars): void; /** Consumes an attempt on the current level. Returns "retry" while attempts remain, else "failed". */ fail(): "retry" | "failed"; /** Restarts the current level after a "retry"-eligible failure. Returns false if there was nothing to retry. */ retry(): boolean; /** Moves past a cleared level, or to "complete" if it was the last one. Returns false unless status is "cleared". */ advance(): boolean; /** Jumps directly to an unlocked level and starts it. Returns false for an unknown or still-locked level. */ select(level: string): boolean; /** Whether a level can be entered: the first level always, later ones once the preceding level has a cleared record. */ isUnlocked(level: string): boolean; /** The persisted record for a level, or `null` if it has never been cleared. */ record(level: string): LevelRecord | null; /** A snapshot of every persisted level record, keyed by level id. */ records(): Readonly>; reset(): void; /** Wipes all persisted completion/star records (and the frontier), returning to a fresh campaign. */ clearRecords(): void; progress(): LevelSequenceProgress; } /** * A pure, deterministic level campaign: an ordered list of levels, each with its own opaque config, played * through a `start` → (`clear` → `advance`)* → `complete` happy path, with `fail`/`retry` handling per-level * attempts. Mirrors the reducer style of `game/race.ts` and `ai/spawnDirector.ts` — no I/O, no timers, just * state transitions driven by the caller. */ export declare function createLevelSequence(config: LevelSequenceConfig): LevelSequence;