Response API
primate/response exports server response helpers and the types used by custom
response functions and frontend integrations.
import response from "primate/response";
import type {
Deferred,
ResponseFunction,
ServeApp,
ViewResponse,
} from "primate/response";Helpers return ResponseFunction values that Primate
executes with the current serving app and request. See the
Responses guide for implicit response conversion and
walkthroughs.
response.text()
text(body: string, init?: ResponseInit): ResponseFunction<never>;Returns a plain-text response function. The default status is 200, and
Content-Type is set to text/plain.
response.json()
json<T>(body: T, init?: ResponseInit): ResponseFunction<never, T>;Serializes body with JSON.stringify when the response function executes.
The default status is 200, and Content-Type is set to
application/json. Serialization errors propagate through request error
handling. The second type parameter retains T for route-client inference.
response.binary()
binary(
source: Streamable,
init?: ResponseInit,
): ResponseFunction<never>;Streams a Blob, readable stream, or @rcompat/fs streamable source. It defaults
to application/octet-stream and an attachment filename of default.bin.
Named sources use their sanitized, length-limited name in Content-Disposition.
Blobs also set Content-Length and use their non-empty MIME type.
response.redirect()
redirect(
target: RedirectTarget,
statusOrInit?: Redirection | RedirectInit,
): ResponseFunction<never>;Redirects to a string or structured same-origin target. The status defaults to
302; the second argument may be a redirect status number or options object.
The response has an empty body, Content-Length: 0, and
Cache-Control: no-cache.
During client navigation, Primate returns 204 and carries the destination and
original redirect status in Primate headers. Ordinary requests receive the
configured status and Location header.
Throws: For invalid origin-form paths, control characters, backslashes, non-HTTP(S) protocols, unapproved external origins, invalid byte limits, or a location larger than the configured limit.
RedirectTarget
type RedirectTarget = string | {
pathname: string;
query?: Record<
string,
boolean | null | number | string | undefined
>;
};Structured pathname must start with one /, cannot start with //, and
cannot contain a backslash. Path segments and query values are URL-encoded;
nullish query values are omitted.
RedirectInit
type RedirectInit = Omit<ResponseInit, "headers" | "status"> & {
headers?: HeadersInit;
status?: 300 | 301 | 302 | 303 | 304 | 307 | 308;
allowExternal?: boolean;
base?: string | URL;
maxLocationBytes?: number;
};allowExternal defaults to false, base defaults to the request URL, and
maxLocationBytes defaults to 2048. Generated redirect headers replace any
caller-provided values with the same names.
response.view()
function view(
component: abstract new (...args: any[]) => any,
props?: Dict,
options?: ViewOptions,
): ResponseFunction<Dict>;
function view<Props>(
component: unknown,
props: Props,
options?: ViewOptions,
): ResponseFunction<Props>;
function view(
component: unknown,
props?: Dict,
options?: ViewOptions,
): ResponseFunction<Dict>;
function view<Props extends Dict>(
name: string,
props?: Props,
options?: ViewOptions,
): ResponseFunction<Props>;Renders a component reference or registered view name. Props default to an empty object. Primate selects the frontend integration from the component or filename extension and throws a missing-frontend diagnostic when none matches.
response.page()
page<Props extends Dict>(
props?: Props,
options?: ViewOptions,
): ResponseFunction<Props>;Renders the component collocated with the current route or layout. Props default to an empty object. Calling the returned function outside a matched route/layout context throws a page-context diagnostic.
ViewOptions
Supporting options accepted by response.view() and response.page(); this
type is not a named export from primate/response.
interface ViewOptions extends ResponseInit {
csp?: {
script_src?: string[];
style_src?: string[];
};
head?: string;
template?: string;
partial?: boolean;
placeholders?: Omit<Dict, "body" | "head">;
}template selects an HTML template, head adds markup to its head placeholder,
and partial: true omits the enclosing template. placeholders cannot replace
the reserved body and head entries.
response.error()
error(options?: {
body?: string;
template?: string;
status?: ValidStatus;
}): ResponseFunction<never>;Renders an error HTML page. Defaults are body "Not Found", template
"error.html", and status 404. Development responses also inject the live
reload listener. This is an ordinary response and does not throw.
response.abort()
abort(response: Response): never;
abort(options: AbortOptions): never;
type AbortOptions = Omit<ResponseInit, "status"> & {
body?: BodyInit | null;
status: ValidStatus;
};Throws an internal control-flow value carrying a native response. body
defaults to null; status is required. Primate handles it without invoking
the error route, error logger, or module error observers. A HEAD request keeps
status and headers but strips the body. Call response.abort(...) directly;
do not prefix it with throw.
response.null()
null(): ResponseFunction<never>;Returns a response function producing an empty 204 response.
response.defer()
defer<T>(value: T | PromiseLike<T>): Deferred<Awaited<T>>;Wraps the input in a branded promise used for direct page and layout props. Initial document rendering awaits it. Client navigation sends immediate props first and resolves or rejects the deferred prop through the streamed navigation response. The wrapper observes rejection early without changing the promise consumed by rendering.
Deferred
Named type export representing the server-rendered or client-navigation form of a deferred value.
type Deferred<T> = T | Promise<T>;
response.sse()
sse(
body: (source: SSESource) => void | (() => void),
init?: ResponseInit,
): ResponseFunction<never>;Creates a text/event-stream response. The setup callback runs when the stream
starts and may return cleanup, which runs once on server close or client
disconnect.
SSESource
type SSESource = {
close(): void;
send(data: string): void;
send(name: string, data: unknown): void;
};send(data) emits the default event; send(name, data) emits a named event.
Data is JSON-serialized. Event names must be non-empty and contain no control
characters. Sends after close are ignored; close() is idempotent.
response.ws()
ws(actions: Actions): ResponseFunction<never>;Upgrades the original request with the @rcompat/http WebSocket actions
object. Runtime support and action examples are in the
Responses guide.
ResponseFunction
Named type export implemented by every helper result.
type ResponseFunction<Props = never, Result = never> = {
(
app: ServeApp,
transfer: Dict,
request: RequestFacade,
): MaybePromise<View | null | Response | undefined>;
readonly _props?: Props;
readonly _result?: Result;
};_props and _result are optional inference properties and do not contain
runtime values. Custom response functions may use the serving context and
request to return a native response, rendered view, null, or undefined.
ServeApp
Named type export for the first ResponseFunction
argument. It is the full serving application class; response authors most
commonly use this response-related subset:
interface ServeApp {
respond(body: BodyInit | null, init?: ResponseInit): Response;
media(contentType: string, init?: ResponseInit): ResponseInit;
view(options: FullViewOptions): Response;
page(pathname: string): string;
upgrade(request: Request, actions: Actions): Response | null;
}The interface above is a focused view, not a separate exported declaration.
respond() applies response defaults and content length, while media() sets
the requested content type and defaults the status to 200.
ViewResponse
Named type export used by frontend modules to register view response factories.
type ViewResponse = (
name: string,
props?: Dict,
options?: ViewOptions,
) => ResponseFunction;
Browser availability
Response construction is server-side. Browser builds replace helpers with
throwing stubs; response.page is not present in the browser runtime object.
Do not call response helpers from frontend code.