import { ShaderCache } from './registry.cjs';
import { type BuilderStateTuple, type PrecompiledManifest, type ShaderBuildKind, type ShaderBuildState, type ShaderCompatibility, type ShaderNodeBuilderStateConstructor, type ShaderProviderHook, type ShaderRenderObjectLike, type ShaderRuntimeStats } from './types.cjs';
export type ShaderRuntimeLogger = (level: 'info' | 'warn' | 'error', message: string) => void;
export declare class ShaderHydrationError extends Error {
readonly scene: string;
readonly key: string;
readonly kind: ShaderBuildKind;
readonly causeValue: unknown;
constructor(scene: string, key: string, kind: ShaderBuildKind, causeValue: unknown);
}
export declare class ShaderProviderInstallError extends Error {
readonly state: ShaderBuildState['state'];
readonly causeValue: unknown;
constructor(state: ShaderBuildState['state'], reason: string, causeValue?: unknown);
}
export interface ShaderCacheProviderOptions {
readonly manifest: PrecompiledManifest;
readonly renderer: object;
readonly cache?: ShaderCache;
readonly compatibility: ShaderCompatibility;
readonly logger?: ShaderRuntimeLogger;
/**
* Throw {@link ShaderHydrationError} into the renderer when a manifest state fails
* to hydrate. Off by default: production applications log the failure once and
* fall back to live TSL compilation for that key instead of breaking rendering.
*/
readonly strict?: boolean;
}
/**
* Provider consulted on renderer cache misses by the version-gated Vite hook.
*
* State hydration failures throw only in strict mode; otherwise the failure is
* logged once per key and that key permanently falls back to live compilation,
* so a bad manifest can never break production rendering.
*/
export declare class ShaderCacheProvider implements ShaderProviderHook {
#private;
constructor(options: ShaderCacheProviderOptions);
get manifest(): PrecompiledManifest;
get stats(): ShaderRuntimeStats;
invalidateKey(key: string, reason?: string): void;
invalidateScene(reason?: string): void;
getForRender(renderObject: ShaderRenderObjectLike): BuilderStateTuple | null;
getForRender(renderObject: ShaderRenderObjectLike, NodeBuilderState: ShaderNodeBuilderStateConstructor, prepareForHydration?: () => void): object | null;
getForCompute(computeNode: object): BuilderStateTuple | null;
getForCompute(computeNode: object, NodeBuilderState: ShaderNodeBuilderStateConstructor, prepareForHydration?: () => void): object | null;
}
export interface InstallShaderCacheOptions {
readonly renderer: object;
readonly scene: string;
readonly state: ShaderBuildState;
/**
* Loads the scene's manifest, for example a lazily imported module. Without it the manifest
* is fetched from `three-blocks/shaders/..json`, where both a capture at
* build and a committed capture's public twin are served.
*/
readonly loadManifest?: (scene: string, backend: 'webgpu' | 'webgl') => unknown | PromiseLike;
/** Public path the application is served under (the bundler's `base`). Defaults to `/`. */
readonly base?: string;
readonly compatibility: ShaderCompatibility;
readonly cache?: ShaderCache;
readonly logger?: ShaderRuntimeLogger;
}
export interface ShaderProviderInstallation {
readonly scene: string;
readonly mode: 'precompiled' | 'live';
readonly state: ShaderBuildState['state'];
readonly reason: string;
readonly provider?: ShaderCacheProvider;
/** Dynamic counters for either a precompiled provider or an observed live fallback. */
readonly runtimeStats?: ShaderRuntimeStats;
dispose(): void;
}
/** Where a built application serves one scene's manifest; `base` is the bundler's public path. */
export declare function shaderManifestUrl(scene: string, backend: 'webgpu' | 'webgl', base?: string): string;
/** The capture runtime of this realm; a capture lane has no manifest to load by definition. */
export declare function shaderCaptureHost(): object | undefined;
/**
* Hand the renderer to a capture host living in this realm. Only the Node capture driver
* defines that runtime (as an init script), which is what lets one production bundle be
* captured and observed without a second, instrumented build. In a browser it is absent and
* this is one symbol lookup.
*
* Call it once the provider decision is made: capture replaces or wraps
* `renderer.nodeBuilderStateProvider`, so it must have the last word. Builds that ran
* earlier are invisible to capture exactly as they are to hydration.
*/
export declare function offerRendererToShaderCapture(renderer: object): void;
/**
* Load and install only the active scene's provider. Stale/invalid/missing states never
* call the manifest loader, so old lazy chunks cannot accidentally inject.
*/
export declare function installShaderCache(options: InstallShaderCacheOptions): Promise;