/** * Chapter Transition Orchestrator */ import type { ViewerApi } from '../../core/types/viewer-api'; import type { StoryWithDefaults } from './storyLoader'; export type TransitionEventMap = { 'transition:start': { chapterId: string; runId: string; }; 'transition:assetsLoading': { chapterId: string; runId: string; }; 'transition:sourceOpen': { chapterId: string; runId: string; }; 'transition:poseApplied': { chapterId: string; runId: string; }; 'transition:posePainted': { chapterId: string; runId: string; degraded: boolean; }; 'transition:narrationStarted': { chapterId: string; runId: string; }; 'transition:mediaStarted': { chapterId: string; runId: string; }; 'transition:ready': { chapterId: string; runId: string; }; 'transition:cancelled': { chapterId: string; runId: string; }; 'transition:error': { chapterId: string; runId: string; error: Error; }; }; export type TransitionEventHandler = (payload: TransitionEventMap[K]) => void; type TransitionOptions = { autoPlay?: boolean; }; type TransitionGateConfig = { posePaintedTimeoutMs?: number; sourceOpenTimeoutMs?: number; }; /** * Hides or reveals the stage. Called with the ramp length so the consumer can * match its own transition to the wait the orchestrator performs. */ type StageFader = (visible: boolean, durationMs: number) => void; /** * How long the stage takes to fade each way around a source change. * * Deliberately not read from `entryTransition.durationMs`: that field still * carries the legacy `transitionTimeMs`, which is a presentation length * measured in seconds, and ramping opacity over two seconds reads as a fault * rather than a transition. */ export declare const STAGE_CROSSFADE_MS = 260; export type ChapterTransitionOrchestrator = { loadChapter: (index: number, options?: TransitionOptions) => Promise; cancelCurrentTransition: () => void; on: (event: K, handler: TransitionEventHandler) => () => void; off: (event: K, handler: TransitionEventHandler) => void; getCurrentRunId: () => string | null; destroy: () => void; }; type RuntimeDeps = { now?: () => number; setTimeoutFn?: typeof setTimeout; clearTimeoutFn?: typeof clearTimeout; requestAnimationFrame?: (callback: FrameRequestCallback) => number; cancelAnimationFrame?: (handle: number) => void; stageFader?: StageFader; crossfadeMs?: number; }; export declare const createChapterTransitionOrchestrator: (viewer: ViewerApi, story: StoryWithDefaults, deps?: RuntimeDeps & TransitionGateConfig) => ChapterTransitionOrchestrator; export {};