export type { PresetConfig, ComponentConfig } from '../core'; export interface ShaderOptions { colorSpace?: 'p3-linear' | 'srgb'; toneMapping?: 'linear' | 'reinhard' | 'cineon' | 'aces' | 'agx' | 'neutral' | 'hable' | 'unreal'; disableTelemetry?: boolean; enablePerformanceTracking?: boolean; isPreview?: boolean; onReady?: () => void; /** * Fires when something goes wrong with the GPU. Two flavours: * * **Recoverable** — the device was lost (Chrome evicting a backgrounded tab's * WebGPU device, an OS-level GPU reset, a driver crash). By the time this runs * the instance has already started rebuilding itself transparently against the * same canvas and preset; your existing `update / pause / resume / resize / * destroy` references keep working once the rebuild completes. Informational — * surface a toast, write a log, no action required. `reason` is a best-effort * string from the underlying API. * * **Terminal** — the shader will never draw and has released everything. The * canvas is left as-is (transparent, if it never rendered). This is the moment * to swap in a static fallback. `reason` is one of: * * - `'unsupported'` — the browser has no WebGPU at all * - `'no-adapter'` — WebGPU exists but no GPU adapter was granted * - `'no-device'` — an adapter exists but the device request failed * - `'init-failed'` — start-up threw for some other reason * - `'device-lost'` — lost with no recovery possible * - `'out-of-memory'` — the GPU refused an allocation * - `'gpu-error'` — sustained device errors; the GPU is not usable * - `'render-failed'` — repeated exceptions while composing or drawing * - `'limit-exceeded'` — the composition needs more of some GPU resource than this device * allows (today: more uniform bytes than a single binding permits). * Unlike the others this is about the CONTENT — fewer layers would run * - `'unrecoverable'` — too many device losses in a row; we stopped retrying * - `'rebuild_failed'` — a device-loss rebuild itself failed * * A terminal reason is reported exactly once. Check {@link isWebGPUSupported} or * `getWebGPUSupport()` before mounting if you'd rather not create the shader at * all on an unsupported browser. */ onError?: (reason: string) => void; /** When false, disables automatic ResizeObserver and IntersectionObserver. * Use resize() for manual sizing and pause()/resume() for animation control. * Defaults to true. * * @example * ```js * const shader = await createShader(canvas, preset, { * observeElement: false * }) * * // Pause when the shader is off-screen or hidden * shader.pause() * * // Resume when it's visible again * shader.resume() * * // Resize after changing the canvas size (debounce as you see fit) * onZoomEnd(() => { * const rect = canvas.getBoundingClientRect() * shader.resize(rect.width, rect.height) * }) * ``` */ observeElement?: boolean; /** Optional shared WebGPU device + adapter, created via `createSharedDevice()`. * When multiple `createShader` calls receive the same `gpu` object, all instances * share one WebGPU device — pipelines are compiled once and cached across instances, * GPU resources pool, and submission overhead drops. Only worth using if a page * loads several shader instances at once. Pass nothing for the default per-instance * device. */ gpu?: { device: GPUDevice; adapter: GPUAdapter; }; } export interface KeyPropTarget { component_id: string; prop: string; } export interface KeyProp { label: string; type: 'color' | 'range' | 'logo' | 'image'; category?: string; targets: KeyPropTarget[]; } export interface PreviewOptions { shader?: string; presetId?: string; apiBaseUrl?: string; /** * Map of camelCase key_prop identifier → user value, layered on top of the * preset's authored defaults. Identifiers are derived from `key_prop.label` * via the same slugify rules the Pro Framer exporter uses, so identifiers * generated by codegen and identifiers expected here always match. * * Only applies on the `presetId` path — `shader` token previews don't carry * key_props and silently ignore this option. */ configuration?: Record; /** * Lock the preview to a specific snapshot of the preset, addressed by * content hash. Customized snippets pin a version so subsequent upstream * edits don't silently break the configuration. Server falls back to * latest with the `X-Shaders-Version-Fallback` header when the requested * snapshot is missing. Only meaningful on the `presetId` path. */ version?: string; } export interface PreviewInstance extends ShaderInstance { /** Replace the active configuration. Re-applies values to the live shader without refetching. */ setConfiguration(configuration: Record): void; } export interface ShaderInstance { /** * Why the shader gave up, or `null` while it is healthy. Non-null means the canvas will * never draw and every GPU resource has been released — `update / resize / pause / resume` * become safe no-ops from that point on. * * The same value is delivered to {@link ShaderOptions.onError} the moment it happens; this * is the pull-based equivalent, for code that runs later and just wants to ask (a fallback * component mounting after the shader, a health check, a test). */ getFailureReason(): string | null; update(componentId: string, props: Record): void; /** * Sync the renderer to the canvas's current dimensions. * Call this after changing canvas.style.width/height or the width/height attributes. * Optionally pass explicit pixel dimensions to force a specific size. */ resize(width?: number, height?: number): void; /** Stop the animation loop. The last rendered frame is preserved on the canvas. */ pause(): void; /** Restart the animation loop after a pause(). */ resume(): void; destroy(): void; } //# sourceMappingURL=types.d.ts.map