first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -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.