@exactjs/server
v0.7.0
Published
Transport-neutral server runtime for eXact operations, refreshes, patches, and server components.
Maintainers
Readme
@exactjs/server
Transport-neutral server runtime for eXact operations, refreshes, patches, and server components.
Overview
handleExactRequest() validates the endpoint, request envelope, operation allowlist,
authorization, CSRF policy, payload limits, batching, cancellation, and response shape. Platform
adapters translate their native request objects into this shared runtime.
Fetch-compatible adapters pass the native request stream through to the runtime. The runtime
enforces limits.maxRequestBytes while reading and cancels the stream on overflow, so an oversized
body is rejected before it can be fully buffered.
Adapter authors should use handleExactFetchRequest() for the canonical Fetch-to-eXact request
translation and exactResponseToFetchResponse() for the portable response path. Bun keeps its
specialized Blob-backed response conversion while sharing the request translation.
Most applications compose a runtime through @exactjs/ssr and connect it with the adapter for
Fetch, Node, Express, Fastify, Hapi, Koa, Bun, Deno, Cloudflare, or a serverless host.
SSR may return an eXact-owned ordered-chunk response body. Platform adapters should consume it through
their native integration when available; its ReadableStream compatibility view is constructed
only when a Web-stream host requests it. Response bodies are single-consumer values.
Custom synchronous producers that already know their complete UTF-8 body size can call
environment?.setBodyByteLength?.(bytes) after their final write. Include every output span;
otherwise omit the hint and let the adapter count. See SSR output accounting.
A binding gateway forwards original payload bytes and credentials after request authentication.
Each service owns its operation policy. Add agreed service headers with transformForwardedRequest;
keep gateway endpoints ahead of JSON body-parsing middleware.
Security model
Dispatch only compiler-generated contracts. Component labels, module names, debug identifiers, and client payloads are not operation authority. Keep application services, private captures, request resources, and secrets in trusted server context.
Register a payload decoder for every manual operation that accepts client data. It runs before
authorizeOperation and the handler. Request-level authorize and validateCsrf run before body parsing. Manual replacement/list HTML must be wrapped with
unsafeExactHtml(); raw strings are rejected, while compiler/SSR output retains framework-owned
provenance. The unsafe constructor is an explicit audit capability, not an escaping function.
Optional DevTools access uses the same endpoint but requires explicit allowDebug authorization
for origin-less clients and server-owned inspection catalogs. Same-origin development browsers may
use the catalog-based default. Runtime observations are bounded to one authorized operation
request, returned with that response, and disposed at response completion; the browser DevTools
runtime owns all cross-request history and subscriptions.
SSR response factories expose an explicit buffered or produced body. Pass the complete response
to the platform adapter. Only buffered bodies support synchronous text/blob collection; progressive
bodies require asynchronous consumption. Direct stream responses omit the text body field.
See server components and eXact DevTools.
Documentation | Source on GitHub
Task progress
Browser-initiated tasks can deliver optional progress over Fetch/NDJSON. On a buffering
deployment, set progress: { supported: false, reason: "deployment buffers responses" } in the
server context. Tasks still run once and return their ordinary result, with an attributed warning.
See streaming deployment requirements.
