79 lines
4.8 KiB
Markdown
79 lines
4.8 KiB
Markdown
# @suaveplan/api-router-worker-bridge — HTTP Request/Response marshalling across the worker boundary. Pairs a main-side and worker-side bridge over @suaveplan/api-worker-rpc, transporting fetch-compatible Request and Response objects (including ReadableStream bodies via streaming frames) without exposing the raw Request to worker code.
|
|
|
|
Stage-3 HTTP bridge that marshals Fetch `Request` and `Response` objects
|
|
across the worker boundary. Pairs a main-side `dispatch` with a worker-
|
|
side handler over a single `MessagePort`, transporting bodies either
|
|
inline (small payloads) or via the `@suaveplan/api-worker-rpc` streaming
|
|
frames (large payloads, with back-pressure).
|
|
|
|
The raw `Request` instance is **never** placed on the wire. Only the
|
|
method, URL, allow-listed headers, and body descriptor cross the port;
|
|
worker code reconstructs a fresh `Request` from those fields and can
|
|
neither read the original socket nor inspect headers on the deny-list
|
|
(`Authorization`, `Cookie`, `Set-Cookie`, `X-CSRF-Token`,
|
|
`Proxy-Authorization` by default).
|
|
|
|
<!-- begin:auto-docs -->
|
|
## Documentation tree
|
|
|
|
- [bridge](./src/bridge/bridge.md) — This module ties `marshal-request`, `marshal-response`, and `streaming` together into the two halves of a working Fetch…
|
|
- [bridge](./src/bridge/bridge.md) — This module ties `marshal-request`, `marshal-response`, and `streaming` together into the two halves of a working Fetch…
|
|
- [error-codes](./src/error-codes/error-codes.md) — This module owns the stable error-code registry for `@suaveplan/api-router-worker-bridge`. Every failure path that aris…
|
|
- [error-codes](./src/error-codes/error-codes.md) — This module owns the stable error-code registry for `@suaveplan/api-router-worker-bridge`. Every failure path that aris…
|
|
- [marshal-request](./src/marshal-request/marshal-request.md) — This module converts a Fetch `Request` into a plain `SerializedRequest` object that is safe to ship across a `MessagePo…
|
|
- [marshal-request](./src/marshal-request/marshal-request.md) — This module converts a Fetch `Request` into a plain `SerializedRequest` object that is safe to ship across a `MessagePo…
|
|
- [marshal-response](./src/marshal-response/marshal-response.md) — This module is the response-side counterpart to `marshal-request`. It converts a Fetch `Response` produced by a worker-…
|
|
- [marshal-response](./src/marshal-response/marshal-response.md) — This module is the response-side counterpart to `marshal-request`. It converts a Fetch `Response` produced by a worker-…
|
|
- [streaming](./src/streaming/streaming.md) — This module marshals binary `ReadableStream<Uint8Array>` bodies between the main and worker processes by piggy-backing…
|
|
- [streaming](./src/streaming/streaming.md) — This module marshals binary `ReadableStream<Uint8Array>` bodies between the main and worker processes by piggy-backing…
|
|
- [testing](./src/testing/testing.md) — This module hands consumers the in-process scaffolding needed to exercise the worker bridge under a real `MessageChanne…
|
|
- [testing](./src/testing/testing.md) — This module hands consumers the in-process scaffolding needed to exercise the worker bridge under a real `MessageChanne…
|
|
<!-- end:auto-docs -->
|
|
|
|
## Modules
|
|
|
|
- [`marshal-request`](src/marshal-request/marshal-request.md) —
|
|
`Request` ↔ `SerializedRequest` round-trip.
|
|
- [`marshal-response`](src/marshal-response/marshal-response.md) —
|
|
`Response` ↔ `SerializedResponse` round-trip.
|
|
- [`streaming`](src/streaming/streaming.md) — `ReadableStream<Uint8Array>`
|
|
transport via `stream-chunk` / `stream-end` / `stream-ack` frames.
|
|
- [`bridge`](src/bridge/bridge.md) — main + worker bridge factories.
|
|
- [`error-codes`](src/error-codes/error-codes.md) — frozen
|
|
`ROUTER_BRIDGE.*` registry.
|
|
- [`testing`](src/testing/testing.md) — in-process bridge + conformance
|
|
harness.
|
|
|
|
## No-raw-Request invariant
|
|
|
|
`marshalRequest` returns a plain, structured-clone-safe object. Inspection
|
|
of the wire envelope yields exactly: `method`, `url`, `headers`,
|
|
`body { kind, ... }`. There is no `Request` reference and no way for
|
|
worker code to call `request.clone()` on the original — the deny-list
|
|
strips credentials before serialisation and the `Headers` instance handed
|
|
to worker code is freshly constructed from the allow-listed tuples only.
|
|
|
|
## Install
|
|
|
|
```bash
|
|
bun add @suaveplan/api-router-worker-bridge
|
|
```
|
|
|
|
## Quickstart
|
|
|
|
```ts
|
|
import {
|
|
createMainBridge,
|
|
createWorkerBridge,
|
|
} from "@suaveplan/api-router-worker-bridge/bridge";
|
|
|
|
const channel = new MessageChannel();
|
|
createWorkerBridge(channel.port2 as never, async (req) =>
|
|
new Response(`hi ${new URL(req.url).pathname}`)
|
|
);
|
|
const { dispatch } = createMainBridge(channel.port1 as never);
|
|
const res = await dispatch(new Request("https://api.local/world"));
|
|
console.log(await res.text()); // "hi /world"
|
|
```
|
|
|