first commit
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
# `streaming`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
This module marshals binary `ReadableStream<Uint8Array>` bodies between
|
||||
the main and worker processes by piggy-backing on `@suaveplan/api-worker-
|
||||
rpc`'s `stream-chunk` / `stream-end` / `stream-ack` frames. It implements
|
||||
the producer (`sendStream`) and consumer (`receiveStream`) halves of a
|
||||
single body transfer keyed on a numeric `streamId` (the same id baked
|
||||
into the body descriptor on the request or response envelope).
|
||||
|
||||
## Features
|
||||
|
||||
- Window-based back-pressure: the producer stalls after `DEFAULT_STREAM_
|
||||
WINDOW` (16) outbound chunks until the consumer sends a matching
|
||||
`stream-ack`, preventing unbounded buffering across the port.
|
||||
- Reuses the wire frame shape of `api-worker-rpc` so a single port can
|
||||
multiplex RPC and bridge streams interchangeably.
|
||||
- Producer errors are forwarded via `errorToEnvelope`; consumer rehydrates
|
||||
via `envelopeToError`, preserving the `SuaveplanError` code chain.
|
||||
- Defensive enqueue: non-binary chunks fail with `ROUTER_BRIDGE.STREAM_
|
||||
INTERRUPTED` so misuse is loud rather than silently corrupting the body.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import {
|
||||
sendStream,
|
||||
receiveStream,
|
||||
} from "@suaveplan/api-router-worker-bridge/streaming";
|
||||
|
||||
const stream = receiveStream(port, 1);
|
||||
// consume `stream` like any ReadableStream
|
||||
await sendStream(port, 1, sourceStream);
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
Tune the back-pressure window for a high-throughput download path:
|
||||
|
||||
```ts
|
||||
import { sendStream } from "@suaveplan/api-router-worker-bridge/streaming";
|
||||
|
||||
await sendStream(port, streamId, hugeAttachment.body!, { window: 64 });
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `sendStream(port, streamId, stream, options?) → Promise<void>`.
|
||||
- `receiveStream(port, streamId, options?) → ReadableStream<Uint8Array>`.
|
||||
- `DEFAULT_STREAM_WINDOW = 16`.
|
||||
- `StreamOptions { window?: number }`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The producer's ack listener is registered for the entire pump lifetime and
|
||||
torn down in `finally` so a crash in the source stream cannot leak a
|
||||
listener. `receiveStream` issues a `stream-ack` whenever its locally-
|
||||
buffered count reaches the window, not after every chunk — this matches
|
||||
the producer's pause threshold so throughput is steady rather than
|
||||
sawtoothed. `ArrayBuffer` payloads are coerced to `Uint8Array` to absorb
|
||||
runtime variation in how `MessagePort` surfaces transfers.
|
||||
Reference in New Issue
Block a user