/**
* Nexus Streaming SSR — Out-of-order HTML flushing with Suspense boundaries.
*
* How it works:
*
* 1. The route render function returns immediately with the static shell.
* Any Promise in the template becomes a placeholder:
*
*
* 2. The HTTP connection stays OPEN (Transfer-Encoding: chunked).
* The browser receives and paints the static shell instantly.
*
* 3. When each Promise resolves, the server writes two chunks:
* a) The resolved HTML wrapped in a
* b) A tiny inline script that moves the template content
* to the hole's position and removes both elements.
*
* 4. Error boundary: if a Promise rejects, the server writes the
* error.nx fallback HTML instead.
*
* Result: Users see content as it becomes available, not all-at-once.
* The Time-to-First-Byte is the server's fastest possible response.
*
* Wire format (chunks sent over HTTP):
* Chunk 1: Full HTML with placeholders
* Static content
*
*
*
* Chunk 2: Resolved content (arrives async)
* ...
*
*
* Chunk 3: Another resolution or error boundary
* ...
*
*
* Final chunk (closes stream):
*
*/
/**
* Resolved deferred chunk: plain HTML, or body + optional Pretext wire + dev bridge script.
* Pretext wire must be the same string produced by `serialize(ctx.pretext)` for `#__NEXUS_PRETEXT__`.
*/
export type StreamingPromiseValue = string | {
html: string;
pretextWire?: string;
devBridgeScript?: string;
};
export interface StreamingBoundary {
id: string;
/** The promise that will resolve to HTML (or a structured payload for Pretext streaming). */
promise: Promise;
/** Fallback HTML shown while the promise is pending. Injected next to the hole immediately on page paint. */
fallback?: string;
/** Error boundary HTML or factory. Overrides `onError` at the boundary level. */
errorFallback?: string | ((err: unknown) => string);
}
export interface StreamController {
/** Write the initial HTML shell (immediately) */
writeShell: (html: string) => void;
/** Register a deferred content promise */
defer: (boundary: StreamingBoundary) => void;
/** Signal stream completion */
close: () => void;
}
/**
* Creates a streaming SSR response.
* Returns a Web-standard `ReadableStream` for use in any edge runtime.
*/
export declare function createStreamingResponse(renderFn: (ctrl: StreamController) => void | Promise, opts?: {
headers?: HeadersInit;
onError?: (err: unknown) => string;
}): Response;
/**
* Template tag for deferred content in .nx templates.
*
* Usage in template:
* {#await fetchPosts()}
* Loading posts...
* {:then posts}
* {#each posts as p}{p.title}{/each}
* {:catch error}
* {error.message}
* {/await}
*
* Compiled output:
* createSuspenseBoundary(fetchPosts(), {
* fallback: 'Loading posts...
',
* render: (posts) => posts.map(...).join(''),
* })
*/
export declare function createSuspenseBoundary(promise: Promise, opts: {
fallback?: string;
render: (value: T) => string;
errorFallback?: string | ((err: unknown) => string);
}): {
id: string;
placeholder: string;
boundary: StreamingBoundary;
};
/**
* Pipes a streaming response to a Node.js `ServerResponse`.
* Used by the Node.js server adapter.
*/
export declare function pipeToNodeResponse(webResponse: Response, nodeRes: import('node:http').ServerResponse, mergeHeaders?: (h: Record) => Record): Promise;
/** Stable hole id for streaming Pretext (shell + one deferred body chunk). */
export declare function nextStreamBoundaryId(): string;
//# sourceMappingURL=streaming.d.ts.map