@voltkit-rtc/client 0.6.1 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/CHANGELOG.md +109 -2
  2. package/README.md +236 -11
  3. package/dist/cjs/broadcast.d.ts.map +1 -1
  4. package/dist/cjs/broadcast.js +16 -7
  5. package/dist/cjs/broadcast.js.map +1 -1
  6. package/dist/cjs/chat.d.ts +11 -9
  7. package/dist/cjs/chat.d.ts.map +1 -1
  8. package/dist/cjs/chat.js +56 -19
  9. package/dist/cjs/chat.js.map +1 -1
  10. package/dist/cjs/errors.d.ts +571 -0
  11. package/dist/cjs/errors.d.ts.map +1 -0
  12. package/dist/cjs/errors.js +155 -0
  13. package/dist/cjs/errors.js.map +1 -0
  14. package/dist/cjs/index.d.ts +320 -16
  15. package/dist/cjs/index.d.ts.map +1 -1
  16. package/dist/cjs/index.js +728 -123
  17. package/dist/cjs/index.js.map +1 -1
  18. package/dist/cjs/media-permissions.d.ts +101 -0
  19. package/dist/cjs/media-permissions.d.ts.map +1 -0
  20. package/dist/cjs/media-permissions.js +166 -0
  21. package/dist/cjs/media-permissions.js.map +1 -0
  22. package/dist/cjs/network.d.ts +80 -0
  23. package/dist/cjs/network.d.ts.map +1 -0
  24. package/dist/cjs/network.js +190 -0
  25. package/dist/cjs/network.js.map +1 -0
  26. package/dist/cjs/token.d.ts +17 -0
  27. package/dist/cjs/token.d.ts.map +1 -0
  28. package/dist/cjs/token.js +36 -0
  29. package/dist/cjs/token.js.map +1 -0
  30. package/dist/esm/broadcast.d.ts.map +1 -1
  31. package/dist/esm/broadcast.js +16 -7
  32. package/dist/esm/broadcast.js.map +1 -1
  33. package/dist/esm/chat.d.ts +11 -9
  34. package/dist/esm/chat.d.ts.map +1 -1
  35. package/dist/esm/chat.js +56 -19
  36. package/dist/esm/chat.js.map +1 -1
  37. package/dist/esm/errors.d.ts +571 -0
  38. package/dist/esm/errors.d.ts.map +1 -0
  39. package/dist/esm/errors.js +149 -0
  40. package/dist/esm/errors.js.map +1 -0
  41. package/dist/esm/index.d.ts +320 -16
  42. package/dist/esm/index.d.ts.map +1 -1
  43. package/dist/esm/index.js +707 -114
  44. package/dist/esm/index.js.map +1 -1
  45. package/dist/esm/media-permissions.d.ts +101 -0
  46. package/dist/esm/media-permissions.d.ts.map +1 -0
  47. package/dist/esm/media-permissions.js +160 -0
  48. package/dist/esm/media-permissions.js.map +1 -0
  49. package/dist/esm/network.d.ts +80 -0
  50. package/dist/esm/network.d.ts.map +1 -0
  51. package/dist/esm/network.js +183 -0
  52. package/dist/esm/network.js.map +1 -0
  53. package/dist/esm/token.d.ts +17 -0
  54. package/dist/esm/token.d.ts.map +1 -0
  55. package/dist/esm/token.js +31 -0
  56. package/dist/esm/token.js.map +1 -0
  57. package/package.json +1 -1
  58. package/src/broadcast.ts +16 -7
  59. package/src/chat.ts +44 -18
  60. package/src/errors.ts +162 -0
  61. package/src/index.ts +842 -114
  62. package/src/media-permissions.ts +220 -0
  63. package/src/network.ts +212 -0
  64. package/src/token.ts +31 -0
package/CHANGELOG.md CHANGED
@@ -1,6 +1,113 @@
1
1
  # Changelog
2
2
 
3
- ## Unreleased — RTC-REF-001
3
+ ## 0.7.1
4
+
5
+ Bug fixes. No API changes; nothing to change in your code. An external review
6
+ (2026-10-16) found lifecycle bugs in the Flutter SDK and transport bugs in the
7
+ Node SDK. This release fixes the same kinds of bug, found in this SDK by the
8
+ check that followed.
9
+
10
+ - **BROWSER-01: `close()` is final while a connection is being made.**
11
+ - Before, closing while `connect()` waited for the join left `connect()`
12
+ pending for about 15 s, after which it failed with `timeout`.
13
+ - Closing just after the join, while the session was still being set up, put
14
+ `connectionState` back to `connected` and emitted `joined` after `closed`.
15
+ - Closing during a reconnect could emit an `error` after `closed`.
16
+
17
+ Now `close()` fails `connect()` and every request in flight at once, with
18
+ `not-connected`, and nothing is emitted after `closed`. The same holds for
19
+ `ChatClient`. `ChatClient.close()` now also closes a socket opened by a
20
+ `connect()` after an earlier `close()`, which it could not reach before.
21
+ - **BROWSER-02: a reconnect that ends the session closes its socket.** When
22
+ the server refused a reconnect for good (`room-ended`, `bad-token`, …), or the
23
+ reconnect attempts ran out, the session reported `closed: gave-up` but kept
24
+ the refused socket open and attached. Now that socket is closed and later
25
+ requests are refused without being sent. Both `StreamClient` and `ChatClient`.
26
+ - **BROWSER-03: `endRoom()` resolves when the room closes first.** The server
27
+ tells the room it has closed before it replies to `endRoom`, and that closes
28
+ the session, so the reply was never read and `endRoom()` failed with `timeout`
29
+ 15 s later, although the room had ended. Now a `roomClosed` that arrives
30
+ first resolves `endRoom()` with `{ ok: true }`, as the reply would. A refusal,
31
+ or a dropped connection with neither, still fails.
32
+ - **BROWSER-04: WHIP failures while reading the answer are `WhipError`s.**
33
+ `BroadcastPublisher.start()` failed with a raw `TimeoutError` or `TypeError`
34
+ when the media server's answer timed out or the connection dropped after its
35
+ headers. Now they are `WhipError`s with `status` 0, like the same failures
36
+ before the headers. The publish URL is never in the message.
37
+ - **BROWSER-05: a `null` message frame is ignored.** Valid JSON that is not a
38
+ message object no longer throws out of the socket's message listener; other
39
+ frames that are not messages were already ignored.
40
+ - Docs: the README says 60 fps is delivered only when the capture source
41
+ provides it (most phone and laptop cameras give browsers 30 fps), how to check
42
+ a camera's rates, and that billing follows the frame rate delivered.
43
+
44
+ ## 0.7.0
45
+
46
+ Additive: every 0.6 call works as before. Pairs with the controller's wallet
47
+ billing (join result `media` and `billing`, `walletLow`, `refreshToken`) and
48
+ works with older controllers too.
49
+
50
+ - **Audio quality.** `PublishOptions.audioQuality: 'std' | 'hd'`, `setAudioQuality()`
51
+ live and the `audioQuality` getter. Standard (the default) is mono Opus with
52
+ `maxaveragebitrate` 64000 and the sender held at 60 kbps (a little under the
53
+ declared rate: Opus VBR measured 60-65 kbps per 5 s window with a 64 kbps
54
+ cap, and standard must never measure above 64), so it stays standard on a
55
+ server that bills what it measures; HD is stereo Opus at up to 128 kbps.
56
+ `AUDIO_SETTINGS` carries both numbers (`maxBitrate`, `senderMaxBitrate`). The microphone's producer declares its `maxaveragebitrate` and
57
+ `appData.audioQuality` to the server. Switching re-creates the microphone's
58
+ producer and keeps it muted if it was. Music is unchanged (128 kbps stereo).
59
+ The microphone was stereo-flagged with no cap in 0.6.
60
+ - **Music is HD and free.** `publishMusic` stays a 128 kbps stereo track in
61
+ every project, also one limited to standard audio (the server allows it there
62
+ and never bills music: the microphone and video alone decide the tier).
63
+ - **Project media settings.** `mediaPermissions` (from the join result's
64
+ `media`, else the `video` policy) and `billingMode`. A kind the project
65
+ switched off is refused before anything is produced (`media-disabled`);
66
+ `setAudioQuality('hd')` without HD is refused (`audio-quality-not-allowed`);
67
+ HD in `publish()`, 60 fps without 60 fps modes and a 60 fps size that is not
68
+ enabled are capped with a warning carrying the server's code. Media profiles
69
+ narrow wallet sessions only. A wallet session waits for a video slot at
70
+ `media.fanout.maxVideoSubscriptions` instead of asking for a refusal.
71
+ - **Changed:** 60 fps refused by the project now warns `frame-rate-not-allowed`
72
+ (the server's code); `frame-rate-fallback` now means only that the camera,
73
+ device or upload cannot provide 60. `setVideoFrameRate(60)` in such a project
74
+ no longer re-creates the camera's producer.
75
+ - **Network quality.** `networkQuality { level, rttMs, lossPct, availableKbps }`
76
+ about every 3 s while listened to, from the transports' statistics, with the
77
+ thresholds in the README.
78
+ - **Tokens.** `updateToken(token)` sends a newer token on the live connection
79
+ (`refreshToken`; older servers keep it for the next reconnect), and
80
+ `tokenExpiring { expiresAt, secondsLeft }` fires a minute before the held
81
+ token expires when nobody refreshed it. Server-pushed tokens carry `expiresAt`.
82
+ - **Wallet.** Typed `walletLow { remainingSeconds, cleared? }`.
83
+ - **Connection state.** `connectionState` and `connectionStateChanged`
84
+ (`idle`, `connecting`, `connected`, `reconnecting`, `closed`).
85
+ - **Parity with the wire:** `claim`, `release`, `blockSlot`, `unblockSlot`,
86
+ `setMetadata`, `setRoomMetadata` and the `claimChanged`, `participantUpdated`
87
+ and `roomMetadataChanged` events, as the Flutter, Android and Swift SDKs
88
+ have. `info` keeps the roster, slots and room metadata current;
89
+ `participants` and `remoteTracks` getters.
90
+ - **Errors.** One registry shared by every SDK (`ERROR_CODES`, `errorInfo`,
91
+ `isTerminalError`, `ErrorCode`); every error the SDK raises is an `RpcError`
92
+ with a registry code (`not-connected`, `timeout`, `connect-failed`,
93
+ `replaced`, `reconnect-gave-up`, `devices-gone`, `unpublished`,
94
+ `codec-fallback`, ...); `RpcError.data` carries what the server attached.
95
+ `kicked` and `billing-unavailable` now end a reconnect at once, like the other
96
+ terminal codes. `CLIENT_EVENTS` and `CONNECTION_STATES` list the names.
97
+ - **Constructor options** (added 2026-10-14, before 0.7.0's first publish):
98
+ `new StreamClient(wsUrl, token, options?)` with `ClientOptions.handlerName`
99
+ (`DeviceHandlerName`), the mediasoup-client handler to build the Device with
100
+ instead of detecting the browser. Reserved for future native hosts; unset,
101
+ nothing changes.
102
+ - **Socket URL** (same date): the `token` query parameter is appended by
103
+ string (`?token=` or `&token=` after an existing query, URL-encoded) instead
104
+ of through `URL.searchParams`, which some non-browser `URL` polyfills do not
105
+ implement. Identical URLs in browsers.
106
+ - No package is published by this change: the owner publishes.
107
+
108
+ ## 0.6.1
109
+
110
+ (Published as RTC-REF-001.)
4
111
 
5
112
  - Ignore hidden-page and in-flight pre-switch samples in `videoLimited` and the optional 60→30 fps fallback. Resume with warm-up and fresh counters; sustained foreground limitation still triggers fallback.
6
113
  - FPS changes/fallback preserve existing capture constraints, including dimensions, facing mode and native-resize preference.
@@ -8,7 +115,7 @@
8
115
  - Optional `VideoSendStats.source` (sender input dimensions/FPS), `encoderImplementation` and `powerEfficientEncoder` diagnostics. Unsupported browser fields remain absent; H264 alone does not establish hardware encoding.
9
116
  - Codec selection, quality/bitrate ladders and publishing APIs are unchanged. Requires a new browser SDK publication and website dependency update to reach the deployed demo. No package published by this change.
10
117
 
11
- ## 0.6.0 (prepared, unpublished)
118
+ ## 0.6.0
12
119
 
13
120
  - Paid camera recording: `StreamClient.startRecording` / `stopRecording`, `CameraRecording` and `RecordingUploader`. Admin-controlled capture resolution/bitrate/FPS, default 360p; independent live-call quality.
14
121
  - Direct device-to-R2 multipart PUTs, 5/10 MiB chunks, bounded buffering, limited parallel uploads, retry URL renewal and recording-only backpressure. Short independently playable files; validation overlaps the next capture after upload buffers drain.
package/README.md CHANGED
@@ -9,6 +9,9 @@ rooms, chat, and live broadcast publishing.
9
9
  | **Chat** | on the room's own connection, or `ChatClient` for chat with no media |
10
10
  | **Broadcast** | `BroadcastPublisher` — go live to an audience of any size over WHIP |
11
11
 
12
+ Using React or Next.js? [`@voltkit-rtc/react`](https://voltkit.in/docs/react-sdk)
13
+ wraps this client in a provider, hooks and track components.
14
+
12
15
  Your backend mints a short-lived token with
13
16
  [`@voltkit-rtc/server`](https://voltkit.in/docs/server-sdk) and
14
17
  hands the page `{ token, wsUrl }`. This package turns that into a live session.
@@ -55,6 +58,13 @@ if (joined.role === 'host' || joined.role === 'cohost') {
55
58
  Always call `client.close()` when leaving. A client that is dropped without
56
59
  closing keeps its reconnect loop running.
57
60
 
61
+ `new StreamClient(wsUrl, token, options?)` takes `ClientOptions`, all optional
62
+ and none needed in a browser: `handlerName` names the mediasoup-client handler
63
+ to build the WebRTC side with (`'Chrome111'`, `'Chrome74'`, `'Firefox120'`,
64
+ `'Safari12'` or `'ReactNative106'`) instead of detecting the browser. It is
65
+ reserved for future native hosts, which have no browser to detect; leave it
66
+ unset.
67
+
58
68
  ### Publishing
59
69
 
60
70
  ```ts
@@ -74,6 +84,7 @@ phones and computers alike; they are kept for a reconnect's republish.
74
84
 
75
85
  | Option | Default | What it does |
76
86
  | --- | --- | --- |
87
+ | `audioQuality` | `'std'` | the microphone: `'std'` (mono, up to 64 kbps) or `'hd'` (stereo, up to 128 kbps); see [Audio quality](#audio-quality) |
77
88
  | `quality` | the highest the project allows | `'1080p'`, `'720p'` or `'480p'`; see [Video quality](#video-quality) |
78
89
  | `frameRate` | `30` | `30` or `60`; only the top layer runs at 60 fps; capture at 60 too |
79
90
  | `layers` | `2` on phones and tablets, `3` elsewhere | the most simulcast layers to send. When a phone is too busy, the browser shrinks the picture and may then send fewer layers, dropping the top one: asked for two, it keeps the full picture; asked for three, viewers were left with a quarter of it |
@@ -112,8 +123,9 @@ const media = await navigator.mediaDevices.getUserMedia({ audio: true, video: {
112
123
  await client.publish(media, undefined, { quality: '1080p' });
113
124
  await client.setVideoQuality('480p'); // resolves to the quality actually used
114
125
 
115
- client.videoPolicy; // { maxQuality: '480p' | '720p' | '1080p', maxFrameRate, maxBitrate } for this project
116
- client.videoQuality; // what is being sent now
126
+ client.videoPolicy; // { maxQuality: '480p' | '720p' | '1080p', maxFrameRate, maxBitrate } for this project
127
+ client.videoQuality; // what is being sent now
128
+ client.videoFrameRate; // 30 or 60, what the camera is being sent at
117
129
  ```
118
130
 
119
131
  | Quality | Layers from a computer at 30 fps | From a phone or tablet | Video upload |
@@ -140,14 +152,99 @@ const effectiveFps = await client.setVideoFrameRate(30); // camera only, other t
140
152
  Only the top layer uses 60 fps: 1080p is **9 Mbps**, 720p **4.5 Mbps**, and
141
153
  480p **1.8 Mbps**; smaller layers stay at 30. This means roughly 1.5× the top
142
154
  layer's data and twice the encoding work. Phones can heat up and use more
143
- battery, and many front cameras capture only 30. If capture is below 50 fps,
144
- a project restricts it, or sustained device/upload limitation prevents 60,
145
- the SDK uses 30 and emits `error` with `code: 'frame-rate-fallback'` as a warning.
146
- `setVideoFrameRate(60)` retries the preference while preserving a paused camera.
155
+ battery, and many front cameras capture only 30. When 60 cannot be used the SDK
156
+ sends 30 and says why on `error`, as a warning that stops nothing:
157
+
158
+ | `code` | Why |
159
+ | --- | --- |
160
+ | `frame-rate-not-allowed` | the project does not allow 60 fps (its settings, or no 60 fps mode is enabled) |
161
+ | `video-quality-not-allowed` | 60 fps is allowed, but not at the size you asked for: the largest size that is goes out at 60 |
162
+ | `frame-rate-fallback` | the camera captures below 50 fps, or the device or upload cannot keep 60 up |
163
+
164
+ `setVideoFrameRate(60)` retries the preference while preserving a paused
165
+ camera; in a project without 60 fps it changes nothing and warns again.
166
+ (Before 0.7.0 the project case was also reported as `frame-rate-fallback`.)
167
+
168
+ 60 fps is delivered only when the capture source provides it.
169
+ Phone makers usually keep 60 fps for their own camera app, so browsers and most
170
+ apps get 30 fps. Check a camera's supported rates in `chrome://media-internals`
171
+ → Video Capture. Billing follows the frame rate actually delivered. In our
172
+ tests a laptop webcam gave Chrome 20 fps at 1080p, and a phone whose own camera
173
+ app records 1080p60 gave 25–30 fps (14 fps in a dim room). Read what you got,
174
+ not what you asked for: `track.getSettings().frameRate` is the rate the camera
175
+ was opened at, and `getVideoStats()` reports the rate captured (`source.fps`,
176
+ where the browser supplies it) and sent (`fps`). For 60 fps, use a webcam or
177
+ capture card listed at 60 fps, or a virtual camera such as OBS Virtual Camera
178
+ set to 60 fps.
147
179
 
148
180
  The full guide, with data use:
149
181
  [voltkit.in/docs/video-quality](https://voltkit.in/docs/video-quality).
150
182
 
183
+ ### Audio quality
184
+
185
+ The microphone goes out as **standard** audio unless you ask for HD:
186
+
187
+ | `audioQuality` | Sent as | Billed as (wallet billing) |
188
+ | --- | --- | --- |
189
+ | `'std'` (default) | mono Opus, `maxaveragebitrate` 64000, the sender held at 60 kbps, DTX and FEC | standard audio |
190
+ | `'hd'` | stereo Opus, `maxaveragebitrate` 128000, DTX and FEC | HD audio |
191
+
192
+ ```ts
193
+ await client.publish(media, undefined, { audioQuality: 'hd' });
194
+ await client.setAudioQuality('std'); // while live; resolves to the quality in use
195
+ client.audioQuality; // 'std' | 'hd'
196
+ ```
197
+
198
+ The server bills what it can verify, never what a client claims: HD only when
199
+ the microphone declares more than 64 kbps or is measured above 72 kbps, so a
200
+ standard microphone really stays at or under 64 kbps: its sender is held at
201
+ 60 kbps, a little under the declared rate, because Opus VBR around a 64 kbps
202
+ target measured up to 65 kbps in a 5 s window. Switching re-creates the
203
+ microphone's producer (its codec settings are fixed per producer): listeners
204
+ hear a gap of a fraction of a second, and a muted microphone stays muted.
205
+
206
+ For HD, capture with `{ audio: { channelCount: { ideal: 2 }, echoCancellation:
207
+ true, noiseSuppression: true, autoGainControl: true } }`; turn the processing
208
+ off only for headphones or line-in music, or listeners hear their own echo.
209
+ Music (`publishMusic`) is a separate 128 kbps stereo track and is not affected:
210
+ it is HD and free whatever the microphone's quality (see [Music](#music)).
211
+
212
+ ### Project media settings
213
+
214
+ A project's owner chooses what it may publish: audio and video on or off, the
215
+ largest video quality, 30 or 60 fps, standard or HD audio. Allowing a mode
216
+ allows every mode below it (1080p at 60 fps opens 720p and 480p at 60 and every
217
+ 30 fps mode). The join result carries them, and the client follows them:
218
+
219
+ ```ts
220
+ client.mediaPermissions;
221
+ // { audio: true, video: true, maxVideoQuality: '1080p', maxFrameRate: 60,
222
+ // maxVideoQuality60: '720p', audioQualityMax: 'hd', maxVideoSubscriptions: 25, source: 'media' }
223
+ client.billingMode; // 'wallet' | 'legacy' | null (older servers)
224
+ ```
225
+
226
+ Offer only these in your UI. The server enforces them whatever a client sends;
227
+ the SDK never sends what it would refuse, and tells you with the server's own
228
+ codes:
229
+
230
+ - **Refused** (the call throws, nothing is produced): a kind the project
231
+ switched off -- `publish()` with such a track, `publishScreen()` without
232
+ video, `publishMusic()` without audio -- with `media-disabled`; and
233
+ `setAudioQuality('hd')` without HD audio, with `audio-quality-not-allowed`.
234
+ - **Capped** (the call goes on with the most the project allows, and `error`
235
+ carries a warning): HD audio asked for in `publish()` goes out standard
236
+ (`audio-quality-not-allowed`); 60 fps without 60 fps modes goes out at 30
237
+ (`frame-rate-not-allowed`); a 60 fps size that is not enabled goes out at the
238
+ largest that is (`video-quality-not-allowed`). A 30 fps quality above the
239
+ maximum is capped silently, as the server does.
240
+ - **Fan-out:** a session billed from the wallet receives at most
241
+ `maxVideoSubscriptions` videos at once (25 by default). Further videos wait,
242
+ with one `video-subscription-limit` warning each, and are received as others
243
+ end.
244
+
245
+ With an older server (no `media` in the join result) the `videoPolicy` alone
246
+ applies, as in 0.6.
247
+
151
248
  ### When the picture is soft
152
249
 
153
250
  A soft or stuttering picture usually comes from the publisher's device (too
@@ -289,6 +386,12 @@ await client.stopMusic();
289
386
 
290
387
  `setMicEnabled` and `setMusicEnabled` are independent, in both directions.
291
388
  `publishMusic` also takes a `MediaStream` or a `MediaStreamTrack`.
389
+ `client.musicPublishing` is whether music is published at all, and
390
+ `client.musicEnabled` whether the audience hears it now.
391
+
392
+ Music is HD and free: it always goes out at 128 kbps stereo, also in a project
393
+ limited to standard audio, and the service never bills it. Sending or hearing
394
+ music never changes anyone's rate; the microphone and video alone decide it.
292
395
 
293
396
  The host keeps hearing the music (`monitor`, on by default for an element). A
294
397
  file from another origin must be served with CORS headers and loaded with
@@ -340,18 +443,123 @@ await client.getRoomState();
340
443
  | `localMediaChanged` / `localStreamChanged` | your own mic, camera or stream changed |
341
444
  | `connected` / `disconnected` | the socket came up or dropped; reconnection is automatic |
342
445
  | `kicked` / `roomClosed` | you were removed, or the host ended the room |
446
+ | `mustReconnect` | the server moved this session (a promotion, a node lost); the client reconnects by itself, with the new token when one is given |
343
447
  | `error` | a failure or recoverable warning such as `frame-rate-fallback`; inspect its code |
344
448
  | `usageLimit` | your project ran out of minutes or hit a usage limit; the session ends at `endsAt` unless it is topped up |
345
449
  | `videoLimited` | your camera video is held back by this device (`cpu`) or the upload (`bandwidth`), or that cleared (`none`) |
346
450
  | `closed` | terminal — `replaced`, `kicked`, `room-closed` or `gave-up`, or `left` when your own `close()` ends the session |
451
+ | `connectionStateChanged` | `{ state, previous }`: `idle` → `connecting` → `connected` ⇄ `reconnecting` → `closed` |
452
+ | `participantUpdated` | someone changed their display metadata (`setMetadata`) |
453
+ | `claimChanged` | a slot was taken, went away, came back, was locked or freed: `{ key, identity, state, reason }` |
454
+ | `roomMetadataChanged` | a moderator changed the room metadata: `{ metadata, by }` |
455
+ | `walletLow` | wallet billing: what the project may spend covers less than the grace period (`{ remainingSeconds }`), or that is over (`{ remainingSeconds, cleared: true }`) |
456
+ | `tokenExpiring` | the token this client would reconnect with expires in about a minute and nobody refreshed it: `{ expiresAt, secondsLeft }` |
457
+ | `networkQuality` | about every 3 s while listened to: `{ level, rttMs, lossPct, availableKbps }` |
458
+
459
+ `on()` returns a function that removes the listener. `CLIENT_EVENTS` lists
460
+ every event name.
461
+
462
+ ### Connection state
347
463
 
348
- `on()` returns a function that removes the listener.
464
+ ```ts
465
+ client.connectionState; // 'idle' | 'connecting' | 'connected' | 'reconnecting' | 'closed' (CONNECTION_STATES)
466
+ client.on('connectionStateChanged', ({ state, previous }) => render(state));
467
+ client.participants; // who is in the room, kept current from the roster events
468
+ client.remoteTracks; // [{ producerId, identity, kind, source, track, paused }] being received
469
+ client.info; // the join result, kept current: roster, slots, room metadata
470
+ ```
471
+
472
+ ### Tokens
473
+
474
+ A room token authorises the connection, not the session: a live session stays
475
+ up past its expiry, and the server pushes a fresh token before the one the
476
+ client holds lapses. Your backend can refresh it as well:
477
+
478
+ ```ts
479
+ client.on('tokenExpiring', async ({ secondsLeft }) => {
480
+ const { token } = await fetch('/api/rtc/token', { method: 'POST' }).then((r) => r.json());
481
+ await client.updateToken(token); // { expiresAt } (ms)
482
+ });
483
+ ```
484
+
485
+ `updateToken` sends the token on the live connection (`refreshToken`), where the
486
+ server checks it like a join token: `bad-token` for one it would refuse,
487
+ `token-mismatch` for another room or identity; the session then keeps its
488
+ token. While reconnecting, or before `connect()`, the token is kept for the
489
+ next join. An older server without `refreshToken` keeps it for the next
490
+ reconnect. `tokenExpiring` fires only when nobody refreshed the token: the
491
+ server stops when the account may no longer be used, and a dropped socket
492
+ cannot receive one.
493
+
494
+ ### Wallet and usage notices
495
+
496
+ ```ts
497
+ client.on('walletLow', ({ remainingSeconds, cleared }) => {
498
+ if (cleared) hideBanner();
499
+ else showBanner(`Credits run out in about ${remainingSeconds} s. Recharge to keep the call going.`);
500
+ });
501
+ client.on('usageLimit', ({ reason, endsAt }) => showCountdown(endsAt));
502
+ ```
503
+
504
+ With wallet billing, `walletLow` warns while the funds the project may spend
505
+ (its own allocation, then the RTC allocation, then unallocated) cover less than
506
+ the grace period at the current burn; `usageLimit` is sent beside it for older
507
+ apps. The room closes with `roomClosed { reason: 'quota-exhausted' }` when the
508
+ funds reach zero unless the wallet is recharged first; a recharge sends
509
+ `walletLow { cleared: true }`, which also cancels the `usageLimit` countdown.
510
+
511
+ ### Network quality
512
+
513
+ ```ts
514
+ client.on('networkQuality', ({ level, rttMs, lossPct, availableKbps }) => showBars(level));
515
+ ```
516
+
517
+ Sampled from the media transports' statistics about every 3 s, only while
518
+ something listens and the session is connected. `rttMs` is the round trip to
519
+ the media server, `lossPct` the packets lost over the last interval in the
520
+ worse direction (sending or receiving), `availableKbps` the browser's bandwidth
521
+ estimate (upload while publishing). Each is `null` until known. The level:
522
+
523
+ | `level` | Round trip | and loss |
524
+ | --- | --- | --- |
525
+ | `excellent` | under 150 ms | under 1 % |
526
+ | `good` | under 300 ms | under 3 % |
527
+ | `poor` | under 500 ms | under 8 % |
528
+ | `bad` | anything worse | |
529
+
530
+ An unknown value does not lower the level. Bandwidth is reported, not graded:
531
+ `videoLimited` says when the camera is held back by the device or the upload.
532
+
533
+ ### Slots and room metadata
534
+
535
+ A slot is a named thing in the room that one participant holds at a time: a
536
+ seat on a board, a guest spot. Keys are yours.
537
+
538
+ ```ts
539
+ await client.claim('seat-3'); // take it; claim('seat-3', identity) grants it (moderators)
540
+ await client.release('seat-3');
541
+ await client.blockSlot('seat-9'); // moderators: lock it; refused with slot-occupied while held
542
+ await client.unblockSlot('seat-9');
543
+ await client.setMetadata({ name: 'Ana' }); // your display metadata; the room hears participantUpdated
544
+ await client.setRoomMetadata({ seats: 10 }, { requireFree: ['seat-11', 'seat-12'] }); // moderators; persisted
545
+
546
+ client.info.claims; // [{ key, identity, state: 'held' | 'away' }]
547
+ client.info.blockedSlots; // ['seat-9']
548
+ client.info.metadata; // the room metadata
549
+ ```
550
+
551
+ **Draw `away` as taken (greyed), never as free:** the holder's connection
552
+ dropped and the slot is kept for them for about a minute. A refused
553
+ `setRoomMetadata` names the slots in the way in `error.data.slots`.
349
554
 
350
555
  ### Reconnection
351
556
 
352
557
  Handled for you. A dropped socket is retried with backoff, the session is
353
- rejoined, and if you were publishing, your media is published again. `closed`
354
- with `gave-up` means it stopped trying.
558
+ rejoined, and if you were publishing, your media is published again (with the
559
+ same quality, frame rate and audio quality). `closed` with `gave-up` means it
560
+ stopped trying: after eight attempts, or at once for a join refused with a code
561
+ retrying cannot fix (`isTerminalError`: the room ended, the token is wrong, you
562
+ were removed, the account ran out).
355
563
 
356
564
  `replaced` means the same identity joined the same room somewhere else, and
357
565
  this connection lost. Do not reconnect on it: the two would take turns evicting
@@ -443,6 +651,8 @@ the user clicks "go live", and keep it out of logs and analytics.
443
651
  `start()` rejects with `WhipError` if the media server refuses. `isRefused`
444
652
  means the URL itself was not accepted — expired, for another stream, or the
445
653
  account is out of minutes — and a retry with the same URL is refused again.
654
+ A media server that cannot be reached, does not answer within 15 s, or drops
655
+ the connection while answering is a `WhipError` too, with `status` 0.
446
656
 
447
657
  Video is offered as **H.264 only**. The media server repackages H.264 into HLS
448
658
  untouched; any other codec makes it transcode every frame. A browser with no
@@ -487,8 +697,23 @@ if (video.canPlayType('application/vnd.apple.mpegurl')) {
487
697
  ## Errors
488
698
 
489
699
  Server refusals reject with `RpcError` (rooms) or `ChatRpcError` (`ChatClient`),
490
- both carrying a machine-readable `code`: `forbidden`, `bad-params`,
491
- `chat-muted`, `rate-limited`, `no-message`, and so on. The full list is in the
700
+ both carrying a machine-readable `code`; the SDK's own failures and warnings
701
+ are `RpcError`s too. Switch on `code`, never on the message. `RpcError.data`
702
+ is what the server attached to act on a refusal (`{ slots }` for
703
+ `slot-occupied`).
704
+
705
+ Every code is in one registry shared by all VoltKit SDKs:
706
+
707
+ ```ts
708
+ import { ERROR_CODES, errorInfo, isTerminalError } from '@voltkit-rtc/client';
709
+
710
+ errorInfo('quota-exhausted'); // { origin: 'server', terminal: true, retryable: false }
711
+ isTerminalError(code); // a join refused with it is not retried
712
+ ```
713
+
714
+ A newer server may send a code this release does not know: it is passed through
715
+ unchanged, and treated as not terminal. The registry with every meaning is in
716
+ the repository's `docs/SDK-CONTRACT.md`, the wire codes in the
492
717
  [API reference](https://voltkit.in/docs/api-reference).
493
718
 
494
719
  ## Help
@@ -1 +1 @@
1
- {"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../../src/broadcast.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../../src/broadcast.ts"],"names":[],"mappings":"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"}
@@ -43,23 +43,32 @@ const HELPER_FORMATS = new Set(['video/rtx', 'video/red', 'video/ulpfec', 'video
43
43
  * resource the server names for ending it.
44
44
  */
45
45
  async function whipOffer(whipUrl, offerSdp, timeoutMs = WHIP_TIMEOUT_MS) {
46
+ // One deadline for the request and the whole answer: the signal stays
47
+ // armed while the body is read.
48
+ const signal = AbortSignal.timeout(timeoutMs);
49
+ // Never echo the URL or the error: the URL carries the publish token.
50
+ const failed = (err, otherwise) => new WhipError(0, signal.aborted || err?.name === 'TimeoutError' ? 'the media server did not answer in time' : otherwise);
46
51
  let res;
47
52
  try {
48
53
  res = await fetch(whipUrl, {
49
54
  method: 'POST',
50
55
  headers: { 'Content-Type': 'application/sdp', Accept: 'application/sdp' },
51
56
  body: offerSdp,
52
- signal: AbortSignal.timeout(timeoutMs),
57
+ signal,
53
58
  });
54
59
  }
55
60
  catch (err) {
56
- // Never echo the URL: it carries the publish token.
57
- const timedOut = err?.name === 'TimeoutError';
58
- throw new WhipError(0, timedOut
59
- ? 'the media server did not answer in time'
60
- : 'could not reach the media server');
61
+ throw failed(err, 'could not reach the media server');
62
+ }
63
+ let body;
64
+ try {
65
+ // A deadline or a connection lost after the headers is the same failure
66
+ // as one before them, and is reported the same way.
67
+ body = await res.text();
68
+ }
69
+ catch (err) {
70
+ throw failed(err, 'the connection to the media server was lost');
61
71
  }
62
- const body = await res.text();
63
72
  if (res.status !== 201 && res.status !== 200) {
64
73
  const line = body.split('\n')[0]?.trim().slice(0, 200);
65
74
  throw new WhipError(res.status, line || 'the media server refused the stream');
@@ -1 +1 @@
1
- {"version":3,"file":"broadcast.js","sourceRoot":"","sources":["../../src/broadcast.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"broadcast.js","sourceRoot":"","sources":["../../src/broadcast.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,3 @@
1
- /**
2
- * Chat for the orchestrator's signaling protocol.
3
- *
4
- * A channel shares its name with the room of the same name, so there are two
5
- * ways into one conversation: `StreamClient` carries chat over the socket it
6
- * already holds for media, and `ChatClient` here opens a socket that carries
7
- * nothing else -- for an audience that is watching a broadcast over a CDN and
8
- * has no reason to be on an SFU.
9
- */
10
1
  import type { Role } from './index.js';
11
2
  export interface ChatMessage {
12
3
  /** Monotonic within a channel, so the oldest id held is a paging cursor. */
@@ -102,6 +93,11 @@ export declare class ChatClient {
102
93
  private token;
103
94
  private joinResult;
104
95
  private closedByUs;
96
+ /**
97
+ * Bumped by close(). A connect() under way when it ran -- the app's, or a
98
+ * reconnect's -- sees the change after its await and stops.
99
+ */
100
+ private lifecycle;
105
101
  private reconnecting;
106
102
  private reconnectAttempt;
107
103
  /** Set by the first successful join. Only a session that has joined is reconnected. */
@@ -114,6 +110,12 @@ export declare class ChatClient {
114
110
  connect(): Promise<ChatJoinResult>;
115
111
  private openSocket;
116
112
  private detachSocket;
113
+ /**
114
+ * A reconnect that ends the session lets go of its socket: a refused join
115
+ * leaves it open, and it would otherwise stay attached, and sending, after
116
+ * closed.
117
+ */
118
+ private releaseSocket;
117
119
  /** Single-flight, with backoff: the same shape as the room client's. */
118
120
  private scheduleReconnect;
119
121
  close(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/chat.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/chat.ts"],"names":[],"mappings":"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"}