Size / Priority
Rationale
If #147 (Streams DSL subset) ships, interop with the Reactive Streams spec makes our hubs interoperable with:
- Node's
stream/web (ReadableStream / WritableStream).
- Bun's
ReadableStream (same spec).
- Any RxJS observable (via
from(publisher)).
- Any
@nodejs/streams-based code.
The Spec is small (4 interfaces). Adapters are ~200 lines.
Depends on #147: without the Streams DSL, there's nothing to wrap.
Design sketch
// src/streams/interop/ReactiveStreams.ts (new)
import type { Publisher, Subscriber, Subscription } from './reactive-streams-types.js';
import type { SourceQueue, BroadcastHubSource } from '../Streams.js';
/** Wrap our SourceQueue as a Reactive Streams Publisher. */
export function toPublisher<T>(queue: SourceQueue<T>): Publisher<T>;
/** Wrap a Reactive Streams Publisher as our Source. */
export function fromPublisher<T>(publisher: Publisher<T>): SourceQueue<T>;
/** Web Streams interop. */
export function toReadableStream<T>(queue: SourceQueue<T>): ReadableStream<T>;
export function fromReadableStream<T>(stream: ReadableStream<T>): SourceQueue<T>;
Integration
Out of scope / non-goals
- RxJS-specific — RxJS observables are interop-compatible via
Publisher; no special wrapper.
Open design questions
- Buffer policy when bridging RS Publisher with infinite demand vs our bounded SourceQueue. Recommend: respect our queue's overflow strategy.
- Async error propagation: both sides have error channels; map cleanly.
Test plan
- Pipe Node
Readable → fromReadableStream → Source → consumer; no data loss.
- Pipe our
Source → toReadableStream → Node Writable; works.
- Backpressure: slow consumer → publisher slows.
- Error propagation in both directions.
Acceptance criteria
Size / Priority
stream/web.Rationale
If #147 (Streams DSL subset) ships, interop with the Reactive Streams spec makes our hubs interoperable with:
stream/web(ReadableStream/WritableStream).ReadableStream(same spec).from(publisher)).@nodejs/streams-based code.The Spec is small (4 interfaces). Adapters are ~200 lines.
Depends on #147: without the Streams DSL, there's nothing to wrap.
Design sketch
Integration
request(n)maps to ouroffersemantics.Out of scope / non-goals
Publisher; no special wrapper.Open design questions
Test plan
Readable→fromReadableStream→Source→ consumer; no data loss.Source→toReadableStream→ NodeWritable; works.Acceptance criteria
toPublisher/fromPublisheradapters.toReadableStream/fromReadableStreamfor Web Streams.