/** * Runtime-core: the small primitives shared across the server's request/response modules - the context * symbols, the `ResponseResult` marker, the lazy never-abort signal / unbounded budget singletons, and * the request-source accessors. Kept in one leaf (it only type-imports the server's spine types, never * its values) so `request-context`, `respond`, `node-outcome`, and the kernel form a cycle-free graph. */ import { type RequestBudget } from "../budget.js"; import type { CtxSet, RequestSource } from "./server.js"; /** A handler returns a `Response` (used as-is) or any value (serialized to JSON). */ export type HandlerResult = Response | unknown; export declare const RESPONSE_RESULT: unique symbol; export declare const CONTEXT_SET: unique symbol; export declare const CONTEXT_SEARCH: unique symbol; /** * A transport codec (or other pre-parsing hook) that already decoded the body stashes the value * here on the replacement `RequestSource`; the JSON body lane takes it verbatim instead of * parsing again. Boxed so a decoded `undefined` stays distinguishable from "not present". The * stasher owns the poisoning guard for what it stashes - the body lane's own guard only covers * text the lane itself parses. */ export declare const PRE_DECODED_BODY: unique symbol; /** The stash shape under {@link PRE_DECODED_BODY}. */ export interface PreDecodedBody { readonly value: unknown; } /** * A response described as plain data - the status, any headers of its own, and a body still in value * form. A `ResponseResult` carrying one is rendered on the SAME lane a handler's plain return takes: * `JSON.stringify` straight into the node writer's `kind: "json"` outcome, or the web lane's prebuilt * JSON init. No `Response` is constructed anywhere on the node path. * * That matters because building one is the dominant cost of answering early. Measured on the rig, one * server per shape, all five answering the same 401: `c.set.status` + a plain object 82802 req/s, * `beforeHandle` returning that same object 81819, `return new Response(...)` 49668, `throw new * Response(...)` 47505, the same throw from a `derive` 48746. The `Response` costs 40%; the throw * around it costs another 4%; unwinding a lifecycle stage instead of a handler costs nothing * measurable. So the fix for a slow rejection is not a faster throw - it is not allocating the * `Response`. */ export interface PlainRender { readonly status: number; /** Headers belonging to this render. They win over anything the request left in `c.set.headers`. */ readonly headers?: Readonly>; /** The body as a value, serialized by the lane that renders it. `undefined` means no body. */ readonly body: unknown; } export interface ResponseResult { readonly [RESPONSE_RESULT]: true; toResponse(): Response; toNodeBody?(): { readonly status: number; readonly headers: Readonly> | undefined; readonly body: string | Uint8Array; }; /** Present when this result can be rendered as plain data - see {@link PlainRender}. Every lane * checks it before `toNodeBody`/`toResponse`, so a carrier that has one never builds a `Response`. */ readonly plain?: PlainRender; } /** * Type-only metadata carried by {@link status}. The symbol is declared, not created, so this brand * adds no runtime property and no per-response allocation. It lets the registry distinguish a typed * early response from an ordinary handler value while preserving the existing ResponseResult marker. */ export declare const STATUS_RESPONSE_TYPE: unique symbol; /** A status-bearing response whose code and body remain visible to TypeScript. */ export interface StatusResponse extends ResponseResult { readonly [STATUS_RESPONSE_TYPE]: { readonly code: Code; readonly body: Body; }; } export declare function isResponseResult(value: unknown): value is ResponseResult; /** * The headers a plain render ships: its own on top of whatever the request left in `c.set.headers`, * so an ambient header (a request id, say) survives an early exit the way it survives an ordinary * return, and a header named at the exit site still wins. * * Always a fresh object when the render has headers of its own: the node writers mutate the record * they are handed (content-type, content-length, cookies), and a `status(...)` value is commonly * hoisted to module scope and answered from on every request. */ export declare function plainRenderHeaders(plain: PlainRender, set: CtxSet): Record | undefined; /** * Finish the request here, with this status and body, without building a `Response`. * * Returned or thrown, from a handler or from any lifecycle stage: * * ```ts * app.derive((c) => { * const user = sessionOf(c) * if (user === undefined) return status(401, { error: "unauthorized" }) * return { user } * }) * ``` * * A `derive` is the reason this exists as a value rather than as a rule about `beforeHandle`: a * `beforeHandle` already short-circuits by returning a value, but a `derive`'s return IS the context * extension, so before this its only exit was `throw new Response(...)` - the most expensive way to * say 401 (see {@link PlainRender} for the measurements). Returning it is preferred; throwing it * carries the same cost as any other throw and stays supported so a guard helper called for effect * (`requireSession(c)`) can still end the request from inside a call it makes. * * The body is serialized by the lane that renders it, exactly like a handler's plain return, so the * response carries a `content-length` rather than falling to chunked, and queued cookies still apply. */ export declare function status(code: Code, body?: undefined, init?: { readonly headers?: Readonly>; }): StatusResponse; export declare function status(code: Code, body: Body, init?: { readonly headers?: Readonly>; }): StatusResponse; /** The concrete `Request` for a source - itself when a real `Request` was passed (the Web path), or the * lazily-built one (the Node adapter). A real `Request` IS a `RequestSource`, so no wrapper is allocated * on the Web hot path. */ export declare function requestOf(source: RequestSource): Request; /** Read one request header. `header()` answers authoritatively when the source implements it - its * `null` means ABSENT, not "ask `headers` instead". Falling through on `null` would materialize the * lazy sources' full `Headers` object on every absent-header probe (measured at ~4% of request CPU * on the Node POST lane, which checks `transfer-encoding` on every request). */ export declare function headerOf(source: RequestSource, name: string): string | null; /** Off-edge `waitUntil`: run the background work fire-and-forget, never leaking an unhandled * rejection. Edge runtimes pass their own (Workers `ctx.waitUntil`) via the platform arg. */ export declare const fallbackWaitUntil: (promise: Promise) => void; export declare const EMPTY_RESPONSE_CONTROLS: CtxSet; export declare const TEXT_DECODER: TextDecoder; export declare const getNeverAbortSignal: () => AbortSignal; export declare const getUnboundedRequestBudget: () => RequestBudget; //# sourceMappingURL=runtime-core.d.ts.map