import { type HandlerResult, type PlainRender, type ResponseResult } from "./runtime-core.js"; import type { CtxSet } from "./server.js"; import { type StaticResponseHeaders } from "./static-headers.js"; /** * What {@link Server.resolveNode} returns: either a plain-data render the `@nifrajs/node` adapter writes * to the socket directly (`kind: "json"` - status + headers + cookies + a pre-stringified body, **no** * undici `Response` built or drained), a marked buffered response body (`kind: "body"` - e.g. * @nifrajs/web's non-deferred SSR HTML), or a `Response` (`kind: "response"`) for everything else * (redirects, 404/405/errors, unmarked or streaming bodies). Internal to the nifra<->node bridge. */ export type NodeServeOutcome = { readonly kind: "response"; readonly response: Response; } | { readonly kind: "json"; readonly status: number; /** Header record after native hooks; repeated values are retained as arrays. */ readonly headers: Readonly> | undefined; /** Queued `Set-Cookie` lines, or `undefined`; the adapter emits one header line each. */ readonly cookies: readonly string[] | undefined; /** The JSON body already stringified, or `null` for an empty (204) response. */ readonly body: string | null; } | { readonly kind: "body"; readonly status: number; readonly headers: Readonly> | undefined; readonly body: string | Uint8Array; }; /** * `finalize` for the node-direct path - mirror of `toResponse` that skips the `Response` build: * a plain value becomes pre-stringified JSON primitives (the adapter `JSON.stringify`s once, here, not * via `Response.json` + a body drain); a handler-returned `Response` is wrapped as-is, with queued * cookies appended exactly as `toResponse` does (so the set-cookie-then-`redirect()` pattern still * works on Node). */ export declare function toNodeOutcome(result: HandlerResult, set: CtxSet): NodeServeOutcome; /** * A `status(...)` (or any other {@link PlainRender} carrier) on the node lane: the same `kind: "json"` * outcome a handler's plain return produces, so an early exit is written to the socket by the same * direct writer, with a `content-length`, and never builds a `Response`. */ export declare function plainNodeOutcome(plain: PlainRender, set: CtxSet): NodeServeOutcome; /** * Materialize a buffered node outcome only when a Web `onResponse` hook needs to see a real * `Response`. The marker lets an in-place hook (`response.headers.set(...); return response`) go back * to the direct socket writer without draining the body through a Web stream. A hook that replaces, * consumes, or otherwise changes the response naturally loses the marker and stays on the portable * response path. */ export declare function nodeOutcomeToResponse(outcome: NodeServeOutcome): Response; /** * Fold declared static headers into a resolved outcome, ONCE, before any native response hook runs - * so a header or body twin sees the declared values through its view exactly as it would see values * a hook had written, and so the no-hook direct-writer path (which never calls the finish step) still * ships them. * * The record handed over is always a fresh copy: the Node writers mutate the outcome's record in * place (content-type, content-length, cookies), and the static record is shared by every request. * Its names are already lowercase, so the writer's all-lowercase fast path still holds. * * `markLowercase` publishes that fast path as a proof on the record instead of leaving each reader to * re-derive it. This stage can answer it for free - the static names were lowercased at registration * and the merge lowercases every own name anyway - and it runs BEFORE the response hooks, so it * covers the hookless lane too, which never reaches the native walk that would otherwise mark. The * caller passes `false` for an app carrying a raw `onNodeResponse` twin: that twin writes the record * directly, past the case-normalizing view, after this point. */ export declare function withStaticNodeHeaders(outcome: NodeServeOutcome, statics: StaticResponseHeaders, markLowercase?: boolean): NodeServeOutcome; /** * The node lane's `wrapResponse`: what an early exit built OUTSIDE the handler's finalizer renders as * - an `onRequest` hook's `Response`, a mount's, and every framework error render. * * A plain-data carrier ({@link plainError}, `status(...)`) takes the same `kind: "json"` lane a * handler's plain return takes: no `Response` built, and none drained. `EMPTY_RESPONSE_CONTROLS` * rather than the request's `c.set` on purpose - these renders happen where no context exists (before * routing, or after it was abandoned), which is exactly why they are wrapped rather than finalized. */ export declare function nodeOutcomeFromResponse(result: Response | ResponseResult): NodeServeOutcome; //# sourceMappingURL=node-outcome.d.ts.map