/** * The three-blocks dev overlay: a Logo chip that expands into a live status * panel (worker lifecycle, shader precompile state, assets, text, HMR feed). * * Injected by `three-blocks/vite` into dev-server HTML only — it never ships in * a production bundle. Self-contained on purpose: no runtime imports, plain DOM * inside a shadow root, and every read of app state is defensive so the overlay * can never take the page down. Data sources: * - the compile-time client config (passed by the injected boot module), * - `window.__threeBlocksSmoke` (the public lifecycle bridge, polled), * - Vite HMR events + `three-blocks:*` server pushes (wired by the boot module). * * Brand rules: the mark's yellow/red/blue stay inside the mark; lime #d4ff47 is * the "live" signal, gold marks attention, red marks errors, accent is action. */ import { type ThreeBlocksAssetBuildConfig, type ThreeBlocksClientConfig, type ThreeBlocksShaderBuildConfig, type ThreeBlocksTextBuildConfig } from '../vite/types.js'; export type ThreeBlocksOverlayPosition = 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right'; export interface ThreeBlocksOverlayOptions { readonly config: ThreeBlocksClientConfig; readonly position?: ThreeBlocksOverlayPosition; /** Showcase mode removes development-only HMR guidance. */ readonly mode?: 'dev' | 'showcase'; } export interface ThreeBlocksProjectStateEvent { readonly shaders: ThreeBlocksShaderBuildConfig; readonly text: ThreeBlocksTextBuildConfig; readonly assets?: ThreeBlocksAssetBuildConfig; } export interface ThreeBlocksCaptureStateEvent { readonly stage?: 'idle' | 'starting' | 'building' | 'settling' | 'hidden' | 'writing' | 'complete' | 'cancelled' | 'error'; readonly scene?: string; readonly active?: boolean; readonly pipelines?: number; readonly error?: string; readonly stats?: { readonly registeredBuilds?: number; readonly buildMs?: number; }; } export interface ThreeBlocksDevOverlay { hotUpdate(kind: 'pending' | 'updated' | 'error', payload: unknown): void; workerRestart(payload: unknown): void; projectState(payload: ThreeBlocksProjectStateEvent): void; captureState(payload: ThreeBlocksCaptureStateEvent): void; dispose(): void; } /** * Mount the overlay once per page. Returns null when the page opted out with * `?tbOverlay=0` or an overlay is already live (the existing handle is reused). */ export declare function mountThreeBlocksDevOverlay(options: ThreeBlocksOverlayOptions): ThreeBlocksDevOverlay | null;