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