import { SSRStyleRegistrationValidation, SSRPortalState, DocumentRenderer, DeferredBoundaryRegistration, DocumentRenderContext, RouteAuthOptions, RouteRegistry, RouteHandler, SSRData, DocumentRenderArgs, Route, RouteRecord, ServerQueryRegistry, CoreTelemetry, AccessDenyDecision, QueryPrefetchContext, SSRStyleRegistration, DataRuntime, AccessRedirectDecision, } from '../core.js'; import { JSXElement, Props } from '../elements.js'; import { AuthContext } from '../peer-types.js'; declare const PAGE_RENDER_ENVELOPE_VERSION: 1; interface PageRenderEnvelope { readonly version: typeof PAGE_RENDER_ENVELOPE_VERSION; readonly resources: Readonly>; readonly route: unknown; readonly framework: Readonly>; } /** * Common call contracts: SSR error types */ declare class SSRDataMissingError extends Error { readonly code = 'SSR_DATA_MISSING'; constructor(message?: string); } /** * Thrown by synchronous route SSR (`renderToString()`/`renderToStream()`) when * route auth or a policy redirects or denies the request. Nothing is rendered; * send `decision` as the HTTP response (for example a 302 to `decision.to`, or * `decision.status`). */ declare class SSRAccessDecisionError extends Error { readonly code = 'SSR_ACCESS_DECISION'; readonly decision: AccessRedirectDecision | AccessDenyDecision; constructor(decision: AccessRedirectDecision | AccessDenyDecision); } interface RenderContext { url: string; seed: number; data?: SSRData; params?: Record; routes?: readonly Route[]; routeAuth?: RouteAuthOptions; basePath?: string; authContext?: AuthContext; signal?: AbortSignal; dataRuntime?: unknown; queryCache?: Map; resourceDataProvided: boolean; mode?: 'ssr' | 'spa'; queryPrefetch?: QueryPrefetchContext; ssrCleanupFns: Array<() => void>; keyCounter: number; renderData: PageRenderEnvelope | null; hydrationData: PageRenderEnvelope | null; deferredBoundaries: DeferredBoundaryRegistration[]; ssrStyles: Map; ssrPortals: SSRPortalState; cspNonce?: string; } /** Build a fresh SSR render context (data cache, routes, seed) for a render pass. */ declare function createRenderContext( seed?: number, opts?: { url?: string; data?: SSRData; params?: Record; routes?: readonly Route[]; routeAuth?: RouteAuthOptions; authContext?: AuthContext; basePath?: string; signal?: AbortSignal; dataRuntime?: unknown; mode?: 'ssr' | 'spa'; queryPrefetch?: QueryPrefetchContext; framework?: Readonly>; envelope?: PageRenderEnvelope; cspNonce?: string; } ): RenderContext; /** * Run a function with the given render context. * Concurrency-safe in Node.js via AsyncLocalStorage. */ declare function withRenderContext(ctx: RenderContext, fn: () => T): T; /** Run `fn` with `ctx` as the active SSR render context, using async-local storage. */ declare function withRenderContextAsync( ctx: RenderContext, fn: () => T | PromiseLike ): Promise; /** * Get the current render context. * Returns null if not inside a render. */ declare function getRenderContext(): RenderContext | null; /** A single path-to-handler route binding accepted by low-level SSR route rendering. */ type SSRRoute = { path: string; handler: RouteHandler; namespace?: string; }; type SSRRouteSource = { registry: RouteRegistry; }; type RouteRenderOptions = SSRRouteSource & { url: string; auth?: RouteAuthOptions; authContext?: AuthContext; signal?: AbortSignal; seed?: number; data?: SSRData; document?: DocumentRenderer; request?: Request; dataRuntime?: DataRuntime; queryPrefetch?: QueryPrefetchContext; telemetry?: Pick; /** @internal Precomposed page state used by hydration verification. */ envelope?: PageRenderEnvelope; cspNonce?: string; /** Diagnose document renderers that omit request-local SSR style registrations. */ styleRegistrationValidation?: SSRStyleRegistrationValidation; }; type RouteStreamOptions = RouteRenderOptions & { onChunk(html: string): void; onComplete(): void; }; /** VNode representation for SSR rendering */ type VNode = { type: string | SSRComponent | symbol; props?: Props; children?: unknown[]; key?: string | number | null; }; /** * Component function signature for SSR. * Components receive props and an optional context with signal and SSR context. */ type SSRComponent = ( props: Props, context?: { signal?: AbortSignal; ssr?: RenderContext; } ) => VNode | JSXElement | string | number | boolean | null | undefined; /** Synchronously render a component to an HTML string, without route resolution. */ declare function renderToStringSync( component: ( props?: Record ) => VNode | JSXElement | string | number | boolean | null | undefined, props?: Record, options?: { seed?: number; data?: SSRData; /** @internal A composed page render envelope. */ envelope?: PageRenderEnvelope; cspNonce?: string; /** @internal Request-local authentication for deferred SSR passes. */ authContext?: AuthContext; /** @internal Capture request-local registrations produced by this pass. */ onContext?: (ctx: RenderContext) => void; } ): string; /** Options for {@link renderRouteRequest} and {@link renderRouteRequestToString}. */ interface RenderRouteRequestOptions { url: string; registry: RouteRegistry; auth?: RouteAuthOptions; authContext?: AuthContext; request?: Request; signal?: AbortSignal; seed?: number; data?: SSRData; /** Askr-owned state retained independently from route loader output. */ framework?: Readonly>; dataRuntime?: DataRuntime; queryPrefetch?: QueryPrefetchContext; queryRegistry?: ServerQueryRegistry; telemetry?: CoreTelemetry; cspNonce?: string; } /** Outcome of rendering a route request for SSR: a render, redirect, deny, or no-match. */ type RenderRouteRequestResult = | { kind: 'render'; html: string; stream?: ReadableStream; styles: readonly SSRStyleRegistration[]; params: Record; record?: RouteRecord; } | AccessRedirectDecision | AccessDenyDecision | { kind: 'no-match'; }; /** Resolve and render a route request for SSR, streaming the body when possible. */ declare function renderRouteRequest( options: RenderRouteRequestOptions ): Promise; /** Resolve and render a route request for SSR, always fully buffering the HTML. */ declare function renderRouteRequestToString( options: RenderRouteRequestOptions ): Promise; /** * Render a component or route request to a complete HTML string, synchronously. */ declare function renderToString( component: ( props?: Record ) => VNode | JSXElement | string | number | null ): string; declare function renderToString(opts: RouteRenderOptions): string; /** * Escape a string for interpolation into a hand-written HTML document template, * either as text content or inside a quoted attribute value. Replaces `&`, `<`, * `>`, `"` and `'` with character references. Use it for every request-derived * value a `document` renderer interpolates, such as `context.pathname`, * `context.params` or loader data. Do not use it for `appHtml`, which is * already rendered markup, or inside `