import { type RoutePreviewArtifactBundleV2 } from './routePreviewArtifactV2.js'; import { type RoutePreviewArtifactBundleV3, type RoutePreviewArtifactV3Diagnostic, type RoutePreviewArtifactV3Status } from './routePreviewArtifactV3.js'; import type { StoryboardEnvironment } from './designImport.js'; import type { PreviewArtifactLatestRequest, RoutePreviewFrameRecipe } from './previewBootstrap.js'; import { type InstanceResolver } from './fiberMap.js'; import { type StateSwitchMetrics } from './stateSwitchMetrics.js'; import { type EditorDeclarations } from './declarations.js'; type SlotRelease = () => void; export interface RoutePreviewRecipe { namespace?: string; previewRevision?: string; route: string; width: number; height: number; environment?: unknown; preset?: unknown; desiredState?: unknown; interactions?: unknown; assertions?: unknown; } export interface RoutePreviewArtifactBundleV1 { version: 1; namespace: string; /** Source SHA at the time of creation. It must match the value before the first ':' of runtime previewRevision. */ sourceRevision?: string; snapshots: Record; } export type RoutePreviewArtifactBundle = RoutePreviewArtifactBundleV1 | RoutePreviewArtifactBundleV2 | RoutePreviewArtifactBundleV3; export interface RoutePreviewArtifactOutcome { status: RoutePreviewArtifactV3Status; diagnostics: readonly RoutePreviewArtifactV3Diagnostic[]; /** The snapshot is a last-known preview shown while an exact revision is loading. */ stale?: boolean; screenshot: { mediaType: 'image/png' | 'image/webp'; width: number; height: number; dataUrl: string; } | null; } export interface RoutePreviewShadowArtifact { bodyHtml: string; bodyAttributes: string; htmlAttributes: string; sharedStylesheets: readonly { key: string; cssText: string; }[]; stylesheetLinksHtml: string; } export interface RoutePreviewArtifactPage { canonicalId: string; route: string; previewRoute?: string; /** What this page's capture must have come from. Compared per frame. */ fingerprint?: string; width?: number; height?: number; environment?: StoryboardEnvironment; preset?: unknown; desiredState?: unknown; interactions?: unknown; assertions?: unknown; } export interface RoutePreviewArtifactSeedResult { accepted: number; rejected: number; reason?: 'invalid-bundle' | 'namespace-mismatch' | 'revision-mismatch'; } export interface RoutePreviewArtifactFrameIdentity { id: string; fingerprint?: string; /** Capture recipe identity without its source dependency digest. */ recipeFingerprint?: string; /** * The recipe the fingerprint stands for, carried so a generator can reproduce * it. Without this a host can only re-capture what it declared for the id and * label it with the requested fingerprint — the frame then answers "exact" * with the screen the axis was supposed to change. */ recipe?: RoutePreviewFrameRecipe; } /** Lifecycle of resolving one frame against an exact artifact endpoint. */ export type RoutePreviewArtifactResolution = { status: 'idle'; } | { status: 'checking'; } | { status: 'outdated'; message?: string; } | { status: 'generating'; } | { status: 'error'; reason: 'unavailable' | 'rejected' | 'not-prepared'; message: string; } | { status: 'exact'; }; export type RoutePreviewArtifactFrameRequestResult = { status: 'accepted'; } | { status: 'superseded'; } | { status: 'unavailable'; message?: string; notPrepared?: boolean; absent?: readonly string[]; } | { status: 'rejected'; message: string; }; export type RoutePreviewState = 'hydrating' | 'live' | 'cached' | 'detailed' | 'placeholder'; export declare function resolveRoutePreviewState(input: { hasRoute: boolean; layersImported: boolean; cacheHydrated: boolean; hasSnapshot: boolean; liveGranted: boolean; }): RoutePreviewState; export declare function routePreviewRetryDelay(failedAttempt: number, options?: { maxAttempts?: number; baseDelayMs?: number; }): number | null; export interface RoutePreviewPersistentRecord { version: number; key: string; namespace: string; snapshot: string; bytes: number; lastAccess: number; } export interface RoutePreviewPersistence { read(key: string): Promise; readMany?(keys: readonly string[]): Promise>; write(record: RoutePreviewPersistentRecord): Promise; remove(key: string): Promise; clear(namespace?: string): Promise; } export interface RoutePreviewSlotTicket { promise: Promise; cancel: () => void; updatePriority: (priority: number) => void; } export declare function recommendedRoutePreviewConcurrency(capabilities?: { hardwareConcurrency?: number; deviceMemory?: number; }): number; /** * Persistent cache identity excluding random mirror ports. * By normalizing the object key order, the same screen recipe always uses the same key. */ export interface RoutePreviewFrameRequestOptions { /** Where the capture queues among others; see PREVIEW_CAPTURE_PRIORITY. */ priority?: number; latestRequest?: PreviewArtifactLatestRequest; } type RoutePreviewFrameRequester = (frames: readonly RoutePreviewArtifactFrameIdentity[], options?: RoutePreviewFrameRequestOptions) => RoutePreviewArtifactFrameRequestResult | Promise | void; /** The ids a probe found current, and the ids it got no answer for. */ export interface RoutePreviewFrameProbeAnswer { exact: readonly string[]; unanswered?: readonly string[]; } /** * Asks the artifact endpoint which frames already hold a current capture, * without generating one or downloading its payload. Null when the endpoint * answered for none of them. */ export type RoutePreviewFrameProber = (frames: readonly RoutePreviewArtifactFrameIdentity[], options: { signal: AbortSignal; }) => Promise; /** A persisted exact frozen snapshot already satisfies the active editor frame. */ export declare function shouldRequestRoutePreviewArtifactFrame({ cacheHydrated, detailActive, hasRoute, layersImported, hasExactArtifact, hasExactSnapshot, hasFingerprint, }: { cacheHydrated: boolean; detailActive: boolean; hasRoute: boolean; layersImported: boolean; hasExactArtifact: boolean; hasExactSnapshot: boolean; hasFingerprint: boolean; }): boolean; export declare function routePreviewPruneKeys(records: readonly Pick[]): string[]; /** Maps live elements to their source metadata for stamping (docs/perf-contracts.md). */ export interface RoutePreviewSourceAnnotator { /** Resolves the registry component instance rooted at an element. */ resolveInstance?: InstanceResolver; /** Resolves the `file#localName` CSS-module source of an element. */ resolveStyle?: (el: Element) => string | null; } export interface SerializeRoutePreviewOptions { annotate?: RoutePreviewSourceAnnotator; } export declare function waitForRoutePreviewSettle(ms?: number): Promise; /** * The per-runtime preview cache: snapshots and their persistence, artifact * frames and outcomes, capture slots and the layer-capture queue, the frame * requester, and the per-key invalidation channels components subscribe to. * The bodies below are the former module-level functions, closed over * instance state instead of module state. */ export interface RoutePreviewCacheOptions { /** Where producer decisions are counted; the runtime passes its own metrics. */ metrics?: Pick; /** The host declarations this cache keys and installs against; the runtime passes its own. */ declarations?: EditorDeclarations; } export declare function createRoutePreviewCache(options?: RoutePreviewCacheOptions): { beginSnapshotNotificationBatch: () => void; endSnapshotNotificationBatch: () => void; subscribeRoutePreviewSnapshots: (listener: () => void) => () => void; getRoutePreviewSnapshotRevision: () => number; subscribeRoutePreviewSnapshotKey: (key: string, listener: () => void) => () => void; getRoutePreviewSnapshotKeyVersion: (key: string) => number; subscribeRoutePreviewArtifactKey: (cacheKey: string, listener: () => void) => () => void; getRoutePreviewArtifactKeyVersion: (cacheKey: string) => number; subscribeRoutePreviewArtifactIdentity: (id: string, fingerprint: string | undefined, listener: () => void) => () => void; getRoutePreviewArtifactIdentityVersion: (id: string, fingerprint?: string) => number; subscribeRoutePreviewSlotCount: (listener: () => void) => () => void; getActiveRoutePreviewCount: () => number; hasRoutePreviewSnapshot: (key: string) => boolean; hasExactRoutePreviewSnapshot: (key: string) => boolean; getRoutePreviewArtifactOutcome: (key: string) => RoutePreviewArtifactOutcome | null; getRoutePreviewArtifactRevision: () => number; subscribeRoutePreviewArtifacts: (listener: () => void) => () => void; getRoutePreviewArtifactResolution: (id: string, fingerprint?: string) => RoutePreviewArtifactResolution; setRoutePreviewArtifactResolution: (frames: readonly RoutePreviewArtifactFrameIdentity[], resolution: RoutePreviewArtifactResolution) => void; isRoutePreviewSnapshotHydrated: (key: string) => boolean; setRoutePreviewArtifactFrameRequester: (requester: RoutePreviewFrameRequester | null) => () => void; setRoutePreviewArtifactFrameProber: (prober: RoutePreviewFrameProber | null) => () => void; subscribeRoutePreviewArtifactFrameProber: (listener: () => void) => () => void; probeRoutePreviewArtifactFrames: (frames: readonly RoutePreviewArtifactFrameIdentity[], options: { signal: AbortSignal; }) => Promise | null; setRoutePreviewArtifactEndpointConfigured: (configured: boolean) => void; isRoutePreviewArtifactEndpointConfigured: () => boolean; shouldStartRoutePreviewProducer: ({ detailActive, previewIntended, }: { detailActive: boolean; previewIntended: boolean; }) => boolean; requestRoutePreviewArtifactFrame: (id: string, fingerprint?: string, options?: { retry?: boolean; recipeFingerprint?: string; recipe?: RoutePreviewFrameRecipe; priority?: number; }) => Promise | null; requestRoutePreviewArtifactFrames: (frames: readonly RoutePreviewArtifactFrameIdentity[], options?: RoutePreviewFrameRequestOptions & { retry?: boolean; }) => Promise | null; createRoutePreviewRecipeKey: (recipe: RoutePreviewRecipe) => string; getRoutePreviewShadowArtifact: (key: string) => RoutePreviewShadowArtifact | null; routePreviewSourceRevision: (previewRevision: string) => string; seedRoutePreviewArtifacts: (bundle: RoutePreviewArtifactBundle | null | undefined, options: { namespace: string; previewRevision: string; appOrigin: string; baselineEnvironment?: StoryboardEnvironment; allowStaleIdentity?: boolean; /** Endpoint-validated v3 subsets may prove freshness by frame fingerprint. */ allowMatchingFrameIdentity?: boolean; pages: readonly RoutePreviewArtifactPage[]; }) => RoutePreviewArtifactSeedResult; setRoutePreviewCacheNamespace: (namespace: string | null | undefined) => void; getRoutePreviewCacheNamespace: () => string; setRoutePreviewPersistenceForTests: (persistence: RoutePreviewPersistence | null | undefined) => void; scheduleRouteLayerCapture: (key: string, priority: number, task: () => Promise) => Promise; acquireRoutePreviewSlot: (priority?: number) => RoutePreviewSlotTicket; setRoutePreviewConcurrency: (value: number) => void; getRoutePreviewSnapshot: (key: string) => string | null; setRoutePreviewSnapshot: (key: string, snapshot: string) => boolean; hydrateRoutePreviewSnapshot: (key: string) => Promise; prehydrateRoutePreviewSnapshots: (keys: readonly string[]) => Promise>; clearRoutePreviewSnapshots: (namespace?: string) => void; scheduleRoutePreviewTask: (key: string, priority: number, task: () => Promise) => Promise; scheduleRoutePreviewSnapshot: (key: string, priority: number, task: () => Promise, runtimeKey?: string) => Promise; serializeRoutePreview: (iframe: HTMLIFrameElement, fallbackUrl: string, options?: SerializeRoutePreviewOptions) => string | null; serializeRoutePreviewShadow: (iframe: HTMLIFrameElement, fallbackUrl: string) => RoutePreviewShadowArtifact | null; }; export type RoutePreviewCache = ReturnType; export {};