# @suaveplan/react-audio-stream - Stream-tier React surface for the Suaveplan audio family — session-core foundation (chunk A). Provides StreamSession (FSM lifecycle), InterruptionClassifier, StreamSourcePlugin, error codes, and OTel instruments. Transports, hooks, components, and transport-share land in chunks B/C/D. React 19 surface for live audio streaming sessions: a Provider, six hooks, and four accessible components. Chunk C of the four-chunk `enterprise-react-audio-stream` split. > Chunks A (session-core) and B (transports) deliver the headless engine. Chunk D > delivers `useTransportShare` and its banner. This chunk delivers the React surface > consumers actually touch. ## Documentation tree - [shared-transport-indicator](./src/components/shared-transport-indicator/shared-transport-indicator.md) — `SharedTransportIndicator` renders the spec-mandated "Shared transport active" badge whenever the local peer is in `'re… - [shared-transport-indicator](./src/components/shared-transport-indicator/shared-transport-indicator.md) — `SharedTransportIndicator` renders the spec-mandated "Shared transport active" badge whenever the local peer is in `'re… - [stream-mixer](./src/components/stream-mixer/stream-mixer.md) — `` renders one strip per remote peer, each with a volume range slider, a mute toggle, a solo toggle, and a… - [stream-mixer](./src/components/stream-mixer/stream-mixer.md) — `` renders one strip per remote peer, each with a volume range slider, a mute toggle, a solo toggle, and a… - [stream-permissions-banner](./src/components/stream-permissions-banner/stream-permissions-banner.md) — `` is the visible counterpart to `useStreamPermissions()`. It renders a `role="status"` ARIA-l… - [stream-permissions-banner](./src/components/stream-permissions-banner/stream-permissions-banner.md) — `` is the visible counterpart to `useStreamPermissions()`. It renders a `role="status"` ARIA-l… - [stream-recorder](./src/components/stream-recorder/stream-recorder.md) — `` is a record/stop control with a live duration display. It delegates recording lifecycle to `useStrea… - [stream-recorder](./src/components/stream-recorder/stream-recorder.md) — `` is a record/stop control with a live duration display. It delegates recording lifecycle to `useStrea… - [stream-room](./src/components/stream-room/stream-room.md) — `` is the headless layout primitive for the room scope. It renders no markup of its own — instead it expose… - [stream-room](./src/components/stream-room/stream-room.md) — `` is the headless layout primitive for the room scope. It renders no markup of its own — instead it expose… - [error-codes](./src/error-codes/error-codes.md) — The error-codes module is the canonical source of truth for every failure mode published by `@suaveplan/react-audio-str… - [error-codes](./src/error-codes/error-codes.md) — The error-codes module is the canonical source of truth for every failure mode published by `@suaveplan/react-audio-str… - [internal](./src/hooks/internal/use-stream-context.md) — Internal helper consumed by every public chunk-C hook. It reads the `StreamReactContext`, returns the non-null `{ sessi… - [use-stream-context](./src/hooks/internal/use-stream-context.md) — Internal helper consumed by every public chunk-C hook. It reads the `StreamReactContext`, returns the non-null `{ sessi… - [use-stream-levels](./src/hooks/use-stream-levels/use-stream-levels.md) — `useStreamLevels` projects realtime peak/RMS samples out of the session. Called without an argument it returns the loca… - [use-stream-levels](./src/hooks/use-stream-levels/use-stream-levels.md) — `useStreamLevels` projects realtime peak/RMS samples out of the session. Called without an argument it returns the loca… - [use-stream-mixer](./src/hooks/use-stream-mixer/use-stream-mixer.md) — `useStreamMixer` exposes per-peer mixer controls — level, mute, solo, and the per-peer FX slot count — and implements D… - [use-stream-mixer](./src/hooks/use-stream-mixer/use-stream-mixer.md) — `useStreamMixer` exposes per-peer mixer controls — level, mute, solo, and the per-peer FX slot count — and implements D… - [use-stream-peers](./src/hooks/use-stream-peers/use-stream-peers.md) — `useStreamPeers` returns the live remote-peer roster as a stable `readonly Peer[]`. Each peer entry carries the partici… - [use-stream-peers](./src/hooks/use-stream-peers/use-stream-peers.md) — `useStreamPeers` returns the live remote-peer roster as a stable `readonly Peer[]`. Each peer entry carries the partici… - [use-stream-permissions](./src/hooks/use-stream-permissions/use-stream-permissions.md) — `useStreamPermissions` exposes the microphone permission state with the typed `MediaPermissionState` enum (`"granted" |… - [use-stream-permissions](./src/hooks/use-stream-permissions/use-stream-permissions.md) — `useStreamPermissions` exposes the microphone permission state with the typed `MediaPermissionState` enum (`"granted" |… - [use-stream-recording](./src/hooks/use-stream-recording/use-stream-recording.md) — `useStreamRecording` exposes the start/stop controls for capturing a session as a single audio file. The hook delegates… - [use-stream-recording](./src/hooks/use-stream-recording/use-stream-recording.md) — `useStreamRecording` exposes the start/stop controls for capturing a session as a single audio file. The hook delegates… - [use-stream-room](./src/hooks/use-stream-room/use-stream-room.md) — `useStreamRoom` projects the current room scope out of the session: the room id (or `null` when the session is not conn… - [use-stream-room](./src/hooks/use-stream-room/use-stream-room.md) — `useStreamRoom` projects the current room scope out of the session: the room id (or `null` when the session is not conn… - [use-stream-session](./src/hooks/use-stream-session/use-stream-session.md) — `useStreamSession` is the entry-point hook for chunk-C consumers. It returns the live `StreamSession` instance, its cur… - [use-stream-session](./src/hooks/use-stream-session/use-stream-session.md) — `useStreamSession` is the entry-point hook for chunk-C consumers. It returns the live `StreamSession` instance, its cur… - [use-transport-share](./src/hooks/use-transport-share/use-transport-share.md) — `useTransportShare` is the React entry point to the transport-share subsystem. It composes a `TransportShareCoordinator… - [use-transport-share](./src/hooks/use-transport-share/use-transport-share.md) — `useTransportShare` is the React entry point to the transport-share subsystem. It composes a `TransportShareCoordinator… - [stream-context](./src/provider/stream-context.md) — `StreamReactContext` is the single React context that publishes the live `StreamSession` to every chunk-C hook and comp… - [stream-provider](./src/provider/stream-provider.md) — `` is the singleton React surface that owns the live `StreamSession` for a tree. It calls the caller-su… - [session](./src/session/reconnect.md) — The reconnect module owns the auto-reconnect lifecycle that `StreamSession` runs after a disconnect interruption. It wr… - [interruption-classifier](./src/session/interruption-classifier/interruption-classifier.md) — `InterruptionClassifier` maps a structural disconnect cause to exactly one of `network | media-permission | signalling… - [interruption-classifier](./src/session/interruption-classifier/interruption-classifier.md) — `InterruptionClassifier` maps a structural disconnect cause to exactly one of `network | media-permission | signalling… - [session-fsm](./src/session/session-fsm/session-fsm.md) — The `session-fsm` module declares the canonical seven-state finite state machine that drives every `StreamSession`. Bui… - [session-fsm](./src/session/session-fsm/session-fsm.md) — The `session-fsm` module declares the canonical seven-state finite state machine that drives every `StreamSession`. Bui… - [stream-session](./src/session/stream-session/stream-session.md) — `StreamSession` is the public face of the stream-tier session core. It wraps the FSM, the transport adapter, the interr… - [stream-session](./src/session/stream-session/stream-session.md) — `StreamSession` is the public face of the stream-tier session core. It wraps the FSM, the transport adapter, the interr… - [stream-source-plugin](./src/session/stream-source-plugin/stream-source-plugin.md) — `StreamSourcePlugin` is the bridge that lets a remote peer's `MediaStream` participate in the audio engine's plugin-cha… - [stream-source-plugin](./src/session/stream-source-plugin/stream-source-plugin.md) — `StreamSourcePlugin` is the bridge that lets a remote peer's `MediaStream` participate in the audio engine's plugin-cha… - [reconnect](./src/session/reconnect.md) — The reconnect module owns the auto-reconnect lifecycle that `StreamSession` runs after a disconnect interruption. It wr… - [telemetry](./src/telemetry/telemetry.md) — The telemetry module owns every OpenTelemetry instrument published by `@suaveplan/react-audio-stream`. Concentrating th… - [telemetry](./src/telemetry/telemetry.md) — The telemetry module owns every OpenTelemetry instrument published by `@suaveplan/react-audio-stream`. Concentrating th… - [control-channel](./src/transport-share/control-channel.md) — The control-channel module is the wire-protocol heart of transport sharing. It defines the envelope shapes that flow be… - [share-state](./src/transport-share/share-state.md) — The share-state module owns the role-machine that decides whether a peer is in `'local'`, `'driving'`, or `'receiving'`… - [transports](./src/transports/transport.md) — The `transport.types.ts` module declares the structural contract that `StreamSession` (authored in chunk A of the `@sua… - [trystero](./src/transports/trystero/trystero-transport.md) — `TrysteroTransport` is the serverless `StreamTransportAdapter` powered by `@suaveplan/network-discovery-trystero`. It p… - [trystero-transport](./src/transports/trystero/trystero-transport.md) — `TrysteroTransport` is the serverless `StreamTransportAdapter` powered by `@suaveplan/network-discovery-trystero`. It p… - [webrtc](./src/transports/webrtc/webrtc-transport.md) — `WebRtcTransport` is the low-latency default `StreamTransportAdapter` for `@suaveplan/react-audio-stream`. It wires a c… - [webrtc-transport](./src/transports/webrtc/webrtc-transport.md) — `WebRtcTransport` is the low-latency default `StreamTransportAdapter` for `@suaveplan/react-audio-stream`. It wires a c… - [websocket](./src/transports/websocket/websocket-transport.md) — `WebSocketTransport` is the fallback `StreamTransportAdapter` consumers choose when a corporate or carrier NAT blocks W… - [websocket-transport](./src/transports/websocket/websocket-transport.md) — `WebSocketTransport` is the fallback `StreamTransportAdapter` consumers choose when a corporate or carrier NAT blocks W… - [transport](./src/transports/transport.md) — The `transport.types.ts` module declares the structural contract that `StreamSession` (authored in chunk A of the `@sua… - [test-setup](./src/test-setup.md) — `test-setup.ts` is the per-worker bootstrap file referenced by `vitest.config.ts`'s `setupFiles`. It registers `@testin… - [test-utils](./src/test-utils.md) — `test-utils.tsx` provides the in-memory `FakeSession` and the `withProvider` wrapper used by every chunk-C hook + compo… ## Provider - `` — StrictMode-safe singleton; injects a `StreamSession` lazily; fans seven session event channels into a single render-bump counter; disconnects on unmount. - `StreamReactContext` — exposed for advanced consumers that need raw context access. - Type-only mirrors (`SessionState`, `Peer`, `PeerMixerState`, `MediaPermissionState`, `LevelSample`, `RecordingResult`, `StreamSessionFactory`, `StreamSessionLike`, `SessionEventMap`, `ReactAudioStreamErrorLike`) for downstream typing. ## Hooks - `useStreamSession()` — session, FSM state, and `connect` / `join` / `leave` / `disconnect`. - `useStreamRoom()` — `roomId`, `isJoined`, `joinedAt`, `participants`. - `useStreamPeers()` — live `readonly Peer[]`. - `useStreamMixer()` — per-peer `setVolume` / `setMute` / `setSolo` with DAW solo semantics (when any peer is soloed, every non-soloed peer's track-volume → 0). Every mutation routes through the session's `setTrackVolume` / `setTrackMute` / `setTrackSolo`. - `useStreamLevels(peerId?)` — `{ peak, rms }` for the local mic or named peer. - `useStreamRecording()` — `start(peerIds?)` and `stop()` returning a `RecordingResult` blob. - `useStreamPermissions()` — typed `MediaPermissionState` with `request()` callback. ## Components - `` — headless render-prop wrapper exposing the room snapshot plus join / leave callbacks. - `` — per-peer mixer strip with range slider, `aria-pressed` mute/solo toggles, FX-slot read-out; supports `renderStrip` render-prop. - `` — record/stop toggle with `mm:ss` duration display and ARIA-live read-out. - `` — `role="status"` `aria-live="polite"` banner; renders nothing when permission is granted. ## Quick start ```tsx import { StreamProvider, useStreamSession } from "@suaveplan/react-audio-stream"; function Room() { const { state, connect, join } = useStreamSession(); if (state === "idle") return ; return

Joined!

; } export function App() { return ( createMyStreamSession()}> ); } ``` ## Constraints (from the canonical spec) - Zero browser audio APIs: no `AudioContext` / `AudioNode` / `AudioWorklet` imports. - DAW solo semantics live in the mixer hook, not in each component. - Every hook throws `REACT_AUDIO_STREAM.NO_PROVIDER` outside a ``.