Files
suaveplan/openspec/archive/2026-05-23-enterprise-react-audio-stream-transports/proposal.md
2026-05-27 23:29:53 +01:00

2.8 KiB
Raw Blame History

@suaveplan/react-audio-stream — transports (chunk B)

  • Target path: packages/ui/react/react-audio-stream/
  • Tier: browser/react
  • Date: 2026-05-23
  • Status: PROPOSED — chunk B of the 4-chunk enterprise-react-audio-stream split.

Why

The session-core chunk (A) declares a structural StreamTransportAdapter contract that StreamSession accepts via constructor injection. This chunk lands three concrete adapters that implement that contract: WebRTC (default, low-latency), WebSocket (fallback for corporate NATs), and Trystero (serverless WebRTC over BitTorrent/Nostr/MQTT/IPFS). Each lives behind its own subpath so consumers only bundle what they import.

What changes

  1. WebRTC adapter — src/transports/webrtc/webrtc-transport.ts. Uses RTCPeerConnection, ICE configuration via supplied STUN/TURN list (no embedded defaults — caller MUST provide for security), MediaStream send/receive, signalling driven through an injected SignallingChannel shape (this chunk does NOT implement a signalling server, only the adapter side that an external signalling channel feeds).
  2. WebSocket adapter — src/transports/websocket/websocket-transport.ts. Wraps @suaveplan/network-transport-websockets; frames PCM (raw or Opus-encoded when @suaveplan/audio-codec-ffmpeg-wasm is available); fallback path for NAT'd peers.
  3. Trystero adapter — src/transports/trystero/trystero-transport.ts. Optional peer dep on @suaveplan/network-discovery-trystero. Only this subpath imports trystero — the other transports do not transitively pull it.
  4. Shared transport types — src/transports/transport.types.ts defines StreamTransportAdapter (the contract chunk A's session accepts), SignallingChannel, IceConfig, TransportEvent union.
  5. RTT probes — every adapter implements getRtt(): Promise<number> for the telemetry histogram registered in chunk A.
  6. Subpath gating — package.json adds ./transports/webrtc, ./transports/websocket, ./transports/trystero exports. Trystero is optional via optionalDependencies + lazy import().
  7. Bundle-size test — tests/bundle-size/webrtc-only.size.test.ts asserts a WebRTC-only consumer's tree-shaken bundle has zero bytes from @suaveplan/network-discovery-trystero.

Requirements landed by this chunk

From the original spec:

  • Subpath exports per surface — completes the ./transports/* subpaths
  • Bundle-size purity for trystero gating

Impact

  • ~20 files (3 adapters × 5 sibling files + shared types + bundle-size test + config touches).
  • Imports StreamTransportAdapter, ReactAudioStreamError, InterruptionClassifier from chunk A — declare those as local-mirror types in this chunk's tests/fixtures/ if chunk A hasn't merged yet.
  • No spec fold or archive — that happens after chunk D.