@voltkit-rtc/client 0.6.1 → 0.7.0

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 (57) hide show
  1. package/CHANGELOG.md +68 -2
  2. package/README.md +222 -11
  3. package/dist/cjs/chat.d.ts +0 -9
  4. package/dist/cjs/chat.d.ts.map +1 -1
  5. package/dist/cjs/chat.js +16 -14
  6. package/dist/cjs/chat.js.map +1 -1
  7. package/dist/cjs/errors.d.ts +571 -0
  8. package/dist/cjs/errors.d.ts.map +1 -0
  9. package/dist/cjs/errors.js +155 -0
  10. package/dist/cjs/errors.js.map +1 -0
  11. package/dist/cjs/index.d.ts +298 -16
  12. package/dist/cjs/index.d.ts.map +1 -1
  13. package/dist/cjs/index.js +654 -118
  14. package/dist/cjs/index.js.map +1 -1
  15. package/dist/cjs/media-permissions.d.ts +101 -0
  16. package/dist/cjs/media-permissions.d.ts.map +1 -0
  17. package/dist/cjs/media-permissions.js +166 -0
  18. package/dist/cjs/media-permissions.js.map +1 -0
  19. package/dist/cjs/network.d.ts +80 -0
  20. package/dist/cjs/network.d.ts.map +1 -0
  21. package/dist/cjs/network.js +190 -0
  22. package/dist/cjs/network.js.map +1 -0
  23. package/dist/cjs/token.d.ts +17 -0
  24. package/dist/cjs/token.d.ts.map +1 -0
  25. package/dist/cjs/token.js +36 -0
  26. package/dist/cjs/token.js.map +1 -0
  27. package/dist/esm/chat.d.ts +0 -9
  28. package/dist/esm/chat.d.ts.map +1 -1
  29. package/dist/esm/chat.js +16 -14
  30. package/dist/esm/chat.js.map +1 -1
  31. package/dist/esm/errors.d.ts +571 -0
  32. package/dist/esm/errors.d.ts.map +1 -0
  33. package/dist/esm/errors.js +149 -0
  34. package/dist/esm/errors.js.map +1 -0
  35. package/dist/esm/index.d.ts +298 -16
  36. package/dist/esm/index.d.ts.map +1 -1
  37. package/dist/esm/index.js +633 -109
  38. package/dist/esm/index.js.map +1 -1
  39. package/dist/esm/media-permissions.d.ts +101 -0
  40. package/dist/esm/media-permissions.d.ts.map +1 -0
  41. package/dist/esm/media-permissions.js +160 -0
  42. package/dist/esm/media-permissions.js.map +1 -0
  43. package/dist/esm/network.d.ts +80 -0
  44. package/dist/esm/network.d.ts.map +1 -0
  45. package/dist/esm/network.js +183 -0
  46. package/dist/esm/network.js.map +1 -0
  47. package/dist/esm/token.d.ts +17 -0
  48. package/dist/esm/token.d.ts.map +1 -0
  49. package/dist/esm/token.js +31 -0
  50. package/dist/esm/token.js.map +1 -0
  51. package/package.json +1 -1
  52. package/src/chat.ts +7 -14
  53. package/src/errors.ts +162 -0
  54. package/src/index.ts +775 -109
  55. package/src/media-permissions.ts +220 -0
  56. package/src/network.ts +212 -0
  57. package/src/token.ts +31 -0
@@ -0,0 +1,149 @@
1
+ /**
2
+ * One error registry for every VoltKit SDK (docs/sdk-contract.json): the codes
3
+ * the controller and the media nodes answer with, passed through unchanged, and
4
+ * the ones the SDKs raise themselves. Switch on `error.code`, never on the
5
+ * message.
6
+ *
7
+ * Kept as a literal here, since the package cannot read the repository's docs
8
+ * at runtime, and checked against the contract by
9
+ * scripts/test/sdk-contract-browser.sh and test/contract.test.mjs. One code per
10
+ * line, so that check can read it.
11
+ */
12
+ export const ERROR_CODES = {
13
+ 'bad-json': { origin: 'server', terminal: false, retryable: false },
14
+ 'bad-params': { origin: 'server', terminal: false, retryable: false },
15
+ 'unknown-method': { origin: 'server', terminal: false, retryable: false },
16
+ 'too-many-requests': { origin: 'server', terminal: false, retryable: true },
17
+ 'not-joined': { origin: 'server', terminal: false, retryable: false },
18
+ 'already-joined': { origin: 'server', terminal: false, retryable: false },
19
+ 'internal': { origin: 'server', terminal: false, retryable: true },
20
+ 'node-error': { origin: 'server', terminal: false, retryable: true },
21
+ 'no-token': { origin: 'server', terminal: true, retryable: false },
22
+ 'bad-token': { origin: 'server', terminal: true, retryable: false },
23
+ 'wrong-tenant': { origin: 'server', terminal: true, retryable: false },
24
+ 'token-mismatch': { origin: 'server', terminal: false, retryable: false },
25
+ 'no-room': { origin: 'server', terminal: true, retryable: false },
26
+ 'room-ended': { origin: 'server', terminal: true, retryable: false },
27
+ 'kicked': { origin: 'server', terminal: true, retryable: false },
28
+ 'no-node': { origin: 'server', terminal: false, retryable: true },
29
+ 'no-capacity': { origin: 'server', terminal: false, retryable: true },
30
+ 'stage-full': { origin: 'server', terminal: false, retryable: true },
31
+ 'participant-quota': { origin: 'server', terminal: false, retryable: true },
32
+ 'viewer-quota': { origin: 'server', terminal: false, retryable: true },
33
+ 'quota-exhausted': { origin: 'server', terminal: true, retryable: false },
34
+ 'daily-limit-reached': { origin: 'server', terminal: true, retryable: false },
35
+ 'monthly-limit-reached': { origin: 'server', terminal: true, retryable: false },
36
+ 'tenant-suspended': { origin: 'server', terminal: true, retryable: false },
37
+ 'billing-unavailable': { origin: 'server', terminal: true, retryable: false },
38
+ 'forbidden': { origin: 'server', terminal: true, retryable: false },
39
+ 'not-in-room': { origin: 'server', terminal: false, retryable: false },
40
+ 'no-participant': { origin: 'server', terminal: false, retryable: false },
41
+ 'bad-transport': { origin: 'server', terminal: false, retryable: false },
42
+ 'no-transport': { origin: 'server', terminal: false, retryable: false },
43
+ 'no-producer': { origin: 'server', terminal: false, retryable: false },
44
+ 'no-consumer': { origin: 'server', terminal: false, retryable: false },
45
+ 'cannot-consume': { origin: 'server', terminal: false, retryable: false },
46
+ 'consumer-cap': { origin: 'server', terminal: false, retryable: true },
47
+ 'producer-cap': { origin: 'server', terminal: false, retryable: true },
48
+ 'room-cap': { origin: 'server', terminal: false, retryable: true },
49
+ 'draining': { origin: 'server', terminal: false, retryable: true },
50
+ 'bad-request': { origin: 'server', terminal: false, retryable: false },
51
+ 'source-already-published': { origin: 'server', terminal: false, retryable: false },
52
+ 'force-muted': { origin: 'server', terminal: false, retryable: false },
53
+ 'media-disabled': { origin: 'server', terminal: false, retryable: false },
54
+ 'frame-rate-not-allowed': { origin: 'server', terminal: false, retryable: false },
55
+ 'video-quality-not-allowed': { origin: 'server', terminal: false, retryable: false },
56
+ 'audio-quality-not-allowed': { origin: 'server', terminal: false, retryable: false },
57
+ 'video-not-allowed': { origin: 'server', terminal: false, retryable: false },
58
+ 'audio-not-allowed': { origin: 'server', terminal: false, retryable: false },
59
+ 'video-subscription-limit': { origin: 'server', terminal: false, retryable: false },
60
+ 'slot-taken': { origin: 'server', terminal: false, retryable: false },
61
+ 'slot-blocked': { origin: 'server', terminal: false, retryable: false },
62
+ 'slot-occupied': { origin: 'server', terminal: false, retryable: false },
63
+ 'chat-muted': { origin: 'server', terminal: false, retryable: false },
64
+ 'rate-limited': { origin: 'server', terminal: false, retryable: true },
65
+ 'no-message': { origin: 'server', terminal: false, retryable: false },
66
+ 'chat-unavailable': { origin: 'server', terminal: false, retryable: false },
67
+ 'closed': { origin: 'server', terminal: false, retryable: true },
68
+ 'unauthorized': { origin: 'server', terminal: false, retryable: false },
69
+ 'bad-signature': { origin: 'server', terminal: false, retryable: false },
70
+ 'operator-only': { origin: 'server', terminal: false, retryable: false },
71
+ 'bad-role': { origin: 'server', terminal: false, retryable: false },
72
+ 'room-exists': { origin: 'server', terminal: false, retryable: false },
73
+ 'room-quota': { origin: 'server', terminal: false, retryable: true },
74
+ 'no-nodes': { origin: 'server', terminal: false, retryable: true },
75
+ 'capacity-exhausted': { origin: 'server', terminal: false, retryable: true },
76
+ 'unavailable': { origin: 'server', terminal: false, retryable: true },
77
+ 'not-found': { origin: 'server', terminal: false, retryable: false },
78
+ 'broadcast-disabled': { origin: 'server', terminal: false, retryable: false },
79
+ 'chat-disabled': { origin: 'server', terminal: false, retryable: false },
80
+ 'no-stream': { origin: 'server', terminal: false, retryable: false },
81
+ 'stream-exists': { origin: 'server', terminal: false, retryable: false },
82
+ 'stream-quota': { origin: 'server', terminal: false, retryable: true },
83
+ 'network': { origin: 'sdk', terminal: false, retryable: true },
84
+ 'rates-unconfigured': { origin: 'sdk', terminal: false, retryable: false },
85
+ 'redirected': { origin: 'sdk', terminal: false, retryable: false },
86
+ 'not-connected': { origin: 'sdk', terminal: false, retryable: true },
87
+ 'timeout': { origin: 'sdk', terminal: false, retryable: true },
88
+ 'connect-failed': { origin: 'sdk', terminal: false, retryable: true },
89
+ 'replaced': { origin: 'sdk', terminal: true, retryable: false },
90
+ 'reconnect-gave-up': { origin: 'sdk', terminal: true, retryable: false },
91
+ 'devices-gone': { origin: 'sdk', terminal: false, retryable: false },
92
+ 'unpublished': { origin: 'sdk', terminal: false, retryable: false },
93
+ 'frame-rate-fallback': { origin: 'sdk', terminal: false, retryable: false },
94
+ 'codec-fallback': { origin: 'sdk', terminal: false, retryable: false },
95
+ 'quality-unavailable': { origin: 'sdk', terminal: false, retryable: false },
96
+ 'screen-share-active': { origin: 'sdk', terminal: false, retryable: false },
97
+ 'screen-share-unsupported': { origin: 'sdk', terminal: false, retryable: false },
98
+ 'screen-share-no-video': { origin: 'sdk', terminal: false, retryable: false },
99
+ 'disconnected': { origin: 'sdk', terminal: false, retryable: true },
100
+ 'produce-failed': { origin: 'sdk', terminal: false, retryable: true },
101
+ 'consume-failed': { origin: 'sdk', terminal: false, retryable: true },
102
+ 'media-unavailable': { origin: 'sdk', terminal: false, retryable: false },
103
+ 'music-unavailable': { origin: 'sdk', terminal: false, retryable: false },
104
+ 'no-camera': { origin: 'sdk', terminal: false, retryable: false },
105
+ 'camera-failed': { origin: 'sdk', terminal: false, retryable: true },
106
+ 'unknown-producer': { origin: 'sdk', terminal: false, retryable: false },
107
+ 'screen-share-denied': { origin: 'sdk', terminal: false, retryable: true },
108
+ 'screen-share-service-required': { origin: 'sdk', terminal: false, retryable: false },
109
+ 'screen-share-source-required': { origin: 'sdk', terminal: false, retryable: false },
110
+ 'screen-share-setup-required': { origin: 'sdk', terminal: false, retryable: false },
111
+ 'screen-share-start-timeout': { origin: 'sdk', terminal: false, retryable: true },
112
+ 'screen-share-ended': { origin: 'sdk', terminal: false, retryable: true },
113
+ 'screen-share-failed': { origin: 'sdk', terminal: false, retryable: true },
114
+ 'screen-share-size-unavailable': { origin: 'sdk', terminal: false, retryable: true },
115
+ 'screen-audio-unavailable': { origin: 'sdk', terminal: false, retryable: false },
116
+ 'screen-stop-failed': { origin: 'sdk', terminal: false, retryable: false },
117
+ 'degradation-preference-failed': { origin: 'sdk', terminal: false, retryable: false },
118
+ };
119
+ /** The registry entry for a code, or undefined for one this SDK does not know. */
120
+ export function errorInfo(code) {
121
+ return Object.prototype.hasOwnProperty.call(ERROR_CODES, code) ? ERROR_CODES[code] : undefined;
122
+ }
123
+ /**
124
+ * Whether reconnecting cannot fix a join refused with this code: a room that
125
+ * has ended is not coming back, and a token that is wrong will be wrong next
126
+ * time too. Unknown codes are not terminal, so a newer server's code never
127
+ * stops a reconnect that could succeed.
128
+ */
129
+ export function isTerminalError(code) {
130
+ return errorInfo(code)?.terminal === true;
131
+ }
132
+ /**
133
+ * An error with a machine-readable code: returned by the server (its code
134
+ * passed through unchanged, known to this SDK or not) or raised by the SDK
135
+ * itself with a registry code. `data` is what the server attached so the app
136
+ * can act on a refusal rather than merely report it: `{ slots }` for
137
+ * `slot-occupied`, for instance.
138
+ */
139
+ export class RpcError extends Error {
140
+ code;
141
+ data;
142
+ constructor(code, message, data) {
143
+ super(`${code}: ${message}`);
144
+ this.code = code;
145
+ this.data = data;
146
+ this.name = 'RpcError';
147
+ }
148
+ }
149
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,8 @@ import { type RecordingOptions, type RecordingFile } from './recording.js';
9
9
  import { type types as ms } from 'mediasoup-client';
10
10
  type RtpCapabilities = ms.RtpCapabilities;
11
11
  import type { ChatEvents, ChatMessage, ChatState, SendMessageOptions } from './chat.js';
12
+ import { type AudioQuality, type JoinBilling, type JoinMedia, type MediaPermissions } from './media-permissions.js';
13
+ import { type NetworkQuality } from './network.js';
12
14
  import { type CodecPreference } from './device.js';
13
15
  import { type MusicInput, type MusicOptions, type TrackSource } from './music.js';
14
16
  import { type ScreenMode, type ReceiveQuality, type VideoLayer, type LayerCount, type VideoPolicy, type VideoQuality } from './quality.js';
@@ -20,6 +22,13 @@ export { AudioMixer, MusicSource } from './music.js';
20
22
  export type { MusicInput, MusicOptions, TrackSource } from './music.js';
21
23
  export type { BroadcastEvents, BroadcastStartOptions, BroadcastState } from './broadcast.js';
22
24
  export { ChatClient, ChatRpcError } from './chat.js';
25
+ export { RpcError, ERROR_CODES, errorInfo, isTerminalError } from './errors.js';
26
+ export type { ErrorCode, ErrorInfo, ErrorOrigin } from './errors.js';
27
+ export { AUDIO_QUALITIES, AUDIO_SETTINGS, DEFAULT_MEDIA_PERMISSIONS, resolvePermissions } from './media-permissions.js';
28
+ export type { AudioQuality, BillingMode, JoinBilling, JoinMedia, MediaPermissions, MediaProfile } from './media-permissions.js';
29
+ export { NETWORK_QUALITY_INTERVAL_MS, NETWORK_QUALITY_LEVELS, networkLevel } from './network.js';
30
+ export type { NetworkQuality, NetworkQualityLevel } from './network.js';
31
+ export { TOKEN_EXPIRING_LEAD_MS, tokenExpiresAt } from './token.js';
23
32
  export { allowedQuality, layerBitrate, videoEncodings, VIDEO_QUALITIES } from './quality.js';
24
33
  export type { LayerCount, VideoEncoding, VideoPolicy, VideoQuality, VideoLayer, ReceiveQuality, ScreenMode } from './quality.js';
25
34
  export type { CodecPreference } from './device.js';
@@ -33,6 +42,52 @@ export interface UsageLimitNotice {
33
42
  /** When the session will be ended, in ms since the epoch. */
34
43
  endsAt: number;
35
44
  }
45
+ /**
46
+ * Wallet billing: what the project may still spend covers less than the
47
+ * grace period at the current burn, or (`cleared: true`) a recharge or a
48
+ * lower burn lifted it back above it.
49
+ */
50
+ export interface WalletLowNotice {
51
+ /** Seconds the funds cover at the current burn; -1 on a cleared notice when nothing limits them. */
52
+ remainingSeconds: number;
53
+ /** True once the warning is over: hide the banner, and the `usageLimit` countdown sent beside it is cancelled. */
54
+ cleared?: boolean;
55
+ }
56
+ /** The token this client would reconnect with lapses soon, and nobody has refreshed it. */
57
+ export interface TokenExpiringNotice {
58
+ /** When it expires, in ms since the epoch. */
59
+ expiresAt: number;
60
+ secondsLeft: number;
61
+ }
62
+ /** Where a session stands, in the order a session goes through them. `closed` is final; the `closed` event says why. */
63
+ export declare const CONNECTION_STATES: readonly ["idle", "connecting", "connected", "reconnecting", "closed"];
64
+ export type ConnectionState = (typeof CONNECTION_STATES)[number];
65
+ export type ClosedReason = 'replaced' | 'kicked' | 'room-closed' | 'gave-up' | 'left';
66
+ /** A slot changed hands, went away, came back, was locked or was freed. */
67
+ export interface ClaimChange {
68
+ key: string;
69
+ /** Null when the slot is now free or blocked. */
70
+ identity: string | null;
71
+ state: 'held' | 'away' | 'free' | 'blocked';
72
+ /** `claimed`, `moved`, `released`, `disconnected`, `reconnected`, `expired`, `blocked` or `unblocked`. */
73
+ reason: string;
74
+ }
75
+ /** A track this client is receiving. */
76
+ export interface RemoteTrack {
77
+ producerId: string;
78
+ identity: string;
79
+ kind: 'audio' | 'video';
80
+ source: TrackSource;
81
+ track: MediaStreamTrack;
82
+ /** Its publisher has it switched off (or a moderator does). */
83
+ paused: boolean;
84
+ }
85
+ /** What this client publishes, as `localMediaChanged` reports it. */
86
+ export interface LocalMediaState {
87
+ micEnabled: boolean;
88
+ camEnabled: boolean;
89
+ musicEnabled: boolean;
90
+ }
36
91
  export interface JoinResult {
37
92
  roomId: string;
38
93
  identity: string;
@@ -54,8 +109,23 @@ export interface JoinResult {
54
109
  * on a publisher's incoming bitrate. Absent from older servers: 1080p.
55
110
  */
56
111
  video?: VideoPolicy;
112
+ /**
113
+ * The project's media settings, the modes they allow and the fan-out
114
+ * limits. Absent from older servers; `mediaPermissions` resolves either.
115
+ */
116
+ media?: JoinMedia;
117
+ /** How this session is billed. Absent from older servers. */
118
+ billing?: JoinBilling;
57
119
  }
58
120
  export interface PublishOptions {
121
+ /**
122
+ * The microphone: `'std'` (the default) is mono Opus up to 64 kbps, billed
123
+ * as standard audio; `'hd'` is stereo Opus up to 128 kbps, billed as HD
124
+ * audio. HD in a project limited to standard audio sends standard and warns
125
+ * on `error` with `audio-quality-not-allowed`. Change it live with
126
+ * `setAudioQuality`. Music (`publishMusic`) is not affected.
127
+ */
128
+ audioQuality?: AudioQuality;
59
129
  /** 30 by default. Only the top layer uses 60; capture at 60 too. */
60
130
  frameRate?: 30 | 60;
61
131
  /**
@@ -99,6 +169,21 @@ export interface ScreenPublishOptions {
99
169
  /** An existing screen stream; otherwise capture is requested from this user gesture. */
100
170
  stream?: MediaStream;
101
171
  }
172
+ /**
173
+ * The handlers mediasoup-client can make its Device with. `ReactNative106` is
174
+ * reserved for future native hosts (react-native-webrtc); nothing published
175
+ * uses it yet.
176
+ */
177
+ export type DeviceHandlerName = 'Chrome111' | 'Chrome74' | 'Firefox120' | 'Safari12' | 'ReactNative106';
178
+ /** `new StreamClient(wsUrl, token, options)`. Everything here is optional; a browser needs none of it. */
179
+ export interface ClientOptions {
180
+ /**
181
+ * The mediasoup-client handler to make the Device with, instead of detecting
182
+ * the browser from its user agent. Leave it unset in browsers; it is
183
+ * reserved for future native hosts, which have no user agent to detect.
184
+ */
185
+ handlerName?: DeviceHandlerName;
186
+ }
102
187
  export interface SlotClaim {
103
188
  key: string;
104
189
  identity: string;
@@ -131,6 +216,11 @@ export interface RemoteProducer {
131
216
  export interface ClientEvents extends ChatEvents {
132
217
  connected: () => void;
133
218
  disconnected: (reason: string) => void;
219
+ /** idle → connecting → connected ⇄ reconnecting → closed. Read it any time as `connectionState`. */
220
+ connectionStateChanged: (e: {
221
+ state: ConnectionState;
222
+ previous: ConnectionState;
223
+ }) => void;
134
224
  joined: (result: JoinResult) => void;
135
225
  track: (info: {
136
226
  identity: string;
@@ -162,6 +252,11 @@ export interface ClientEvents extends ChatEvents {
162
252
  kind?: 'audio' | 'video' | '';
163
253
  paused: boolean;
164
254
  }) => void;
255
+ /** Someone's display metadata changed (their own `setMetadata`). */
256
+ participantUpdated: (e: {
257
+ identity: string;
258
+ metadata: unknown;
259
+ }) => void;
165
260
  roleChanged: (e: {
166
261
  identity: string;
167
262
  role: Role;
@@ -182,6 +277,17 @@ export interface ClientEvents extends ChatEvents {
182
277
  kind?: 'audio' | 'video' | '';
183
278
  paused: boolean;
184
279
  }) => void;
280
+ /**
281
+ * A slot changed. **Draw `away` as taken (greyed), never as free**: the
282
+ * holder's connection dropped and the slot is kept for them. `info.claims`
283
+ * and `info.blockedSlots` are kept current from these.
284
+ */
285
+ claimChanged: (e: ClaimChange) => void;
286
+ /** Room metadata changed (a moderator's `setRoomMetadata`); persisted, so `info.metadata` is kept current too. */
287
+ roomMetadataChanged: (e: {
288
+ metadata: unknown;
289
+ by?: string;
290
+ }) => void;
185
291
  mustReconnect: (e: {
186
292
  reason: string;
187
293
  token?: string;
@@ -201,12 +307,13 @@ export interface ClientEvents extends ChatEvents {
201
307
  screenShareEnded: (e: {
202
308
  reason: 'stopped' | 'track-ended';
203
309
  }) => void;
310
+ /**
311
+ * A failure, or a warning that changes nothing else: an `RpcError` whose
312
+ * `code` is in `ERROR_CODES` (`frame-rate-fallback`,
313
+ * `audio-quality-not-allowed`, ...). Switch on the code.
314
+ */
204
315
  error: (err: Error) => void;
205
- localMediaChanged: (state: {
206
- micEnabled: boolean;
207
- camEnabled: boolean;
208
- musicEnabled: boolean;
209
- }) => void;
316
+ localMediaChanged: (state: LocalMediaState) => void;
210
317
  /** The local stream was replaced, typically after reacquiring devices on a reconnect. */
211
318
  localStreamChanged: (stream: MediaStream | null) => void;
212
319
  /** Media stopped arriving but the connection is intact -- the publisher is reconnecting. */
@@ -214,13 +321,33 @@ export interface ClientEvents extends ChatEvents {
214
321
  reason: string;
215
322
  }) => void;
216
323
  /** The session ended and will not recover. Nothing further will be emitted. */
217
- closed: (reason: 'replaced' | 'kicked' | 'room-closed' | 'gave-up' | 'left') => void;
324
+ closed: (reason: ClosedReason) => void;
218
325
  /**
219
326
  * The account behind this session ran out of minutes or reached a usage
220
327
  * limit. The session ends at `endsAt` (after `graceSeconds`) unless the
221
328
  * account is topped up first -- tell the user, and stop asking them to wait.
222
329
  */
223
330
  usageLimit: (e: UsageLimitNotice) => void;
331
+ /**
332
+ * Wallet billing: the funds this project may spend cover less than the
333
+ * grace period at the current burn, repeated while it lasts; the room closes
334
+ * when they reach zero unless the wallet is recharged. A notice with
335
+ * `cleared: true` ends the warning (and the `usageLimit` countdown beside it).
336
+ */
337
+ walletLow: (e: WalletLowNotice) => void;
338
+ /**
339
+ * The token this client would reconnect with expires in about a minute and
340
+ * the server has not refreshed it (it stops when the account may no longer
341
+ * be used, or the socket is down). Mint a new one on your backend and hand it
342
+ * over with `updateToken`.
343
+ */
344
+ tokenExpiring: (e: TokenExpiringNotice) => void;
345
+ /**
346
+ * Round trip, packet loss and available bandwidth to the media server, about
347
+ * every 3 s while listened to and media is flowing, with a level for the UI
348
+ * (thresholds in the README). Sampled only while someone listens.
349
+ */
350
+ networkQuality: (e: NetworkQuality) => void;
224
351
  /**
225
352
  * Your camera video is being held back by this device (`cpu`: too busy to
226
353
  * encode it), by the upload (`bandwidth`), or by something else (`other`);
@@ -231,13 +358,11 @@ export interface ClientEvents extends ChatEvents {
231
358
  */
232
359
  videoLimited: (e: VideoLimitedEvent) => void;
233
360
  }
234
- /** An error returned by the server, carrying its machine-readable code. */
235
- export declare class RpcError extends Error {
236
- readonly code: string;
237
- constructor(code: string, message: string);
238
- }
361
+ /** The names of every event `StreamClient.on` accepts. */
362
+ export declare const CLIENT_EVENTS: readonly (keyof ClientEvents)[];
239
363
  export declare class StreamClient {
240
364
  private readonly wsUrl;
365
+ private readonly options;
241
366
  private ws;
242
367
  private device;
243
368
  private sendTransport;
@@ -294,12 +419,39 @@ export declare class StreamClient {
294
419
  private readonly sendStatsBaseline;
295
420
  private readonly recvStatsBaseline;
296
421
  private readonly limitWatch;
297
- constructor(wsUrl: string, token: string);
422
+ /** Where the session stands; see connectionStateChanged. */
423
+ private state;
424
+ /** When the token held for reconnects expires (unix ms), and the timer that warns before it does. */
425
+ private tokenExpiry;
426
+ private tokenTimer;
427
+ /** Whose each received track is and whether it is switched off, by producerId. */
428
+ private readonly remoteInfo;
429
+ /** Videos left unconsumed at the fan-out limit, oldest first; consumed as others end. */
430
+ private readonly skippedVideos;
431
+ /** Producers whose video this client receives, or is about to: the fan-out count. */
432
+ private readonly videoSlots;
433
+ /** The quality the microphone producer was made with. */
434
+ private micQuality;
435
+ private micQueue;
436
+ private audioCapReported;
437
+ private sizeCapReported;
438
+ private readonly networkWatch;
439
+ constructor(wsUrl: string, token: string, options?: ClientOptions);
298
440
  on<K extends keyof ClientEvents>(event: K, fn: ClientEvents[K]): () => void;
441
+ /** Where the session stands: idle, connecting, connected, reconnecting or closed. */
442
+ get connectionState(): ConnectionState;
443
+ private setState;
444
+ /** Over for good: the state, then the event that says why. */
445
+ private finish;
446
+ private stopTimers;
299
447
  private listenerCount;
300
448
  private emit;
301
449
  connect(): Promise<JoinResult>;
302
- /** A new mediasoup Device for each join. Its own method so tests, which have no WebRTC, can stand one in. */
450
+ /**
451
+ * A new mediasoup Device for each join: the handler named in the options, or
452
+ * the one detected from the browser. Its own method so tests, which have no
453
+ * WebRTC, can stand one in.
454
+ */
303
455
  private createDevice;
304
456
  private openSocket;
305
457
  private detachSocket;
@@ -311,12 +463,56 @@ export declare class StreamClient {
311
463
  private scheduleReconnect;
312
464
  close(): void;
313
465
  private teardownMedia;
314
- /** Everything currently known about the room, for rendering. */
466
+ /**
467
+ * Everything currently known about the room, for rendering: the join
468
+ * result, kept current -- participants, roles, hands, mutes, display
469
+ * metadata, slots and room metadata follow the events.
470
+ */
315
471
  get info(): JoinResult | null;
472
+ /** Who is in the room now, this client included; kept current from the roster events. */
473
+ get participants(): ParticipantInfo[];
474
+ /** Every track this client is receiving now. */
475
+ get remoteTracks(): RemoteTrack[];
476
+ /**
477
+ * What this project lets this client publish: from the join result's
478
+ * `media` (servers with wallet billing), else its `video` policy, else
479
+ * everything before a join. Offer only these in your UI; the SDK refuses
480
+ * or caps anything else with the server's own codes.
481
+ */
482
+ get mediaPermissions(): MediaPermissions;
483
+ /** How this session is billed: `legacy` (minutes) or `wallet`; null before a join or on older servers. */
484
+ get billingMode(): 'legacy' | 'wallet' | null;
485
+ /**
486
+ * Hand the session a newer room token, minted by your backend for the same
487
+ * room and identity (`POST /v1/rooms/{roomId}/tokens`), typically on
488
+ * `tokenExpiring`. On a live connection the server checks it like a join
489
+ * token (`bad-token`, or `token-mismatch` for another room or identity; the
490
+ * session then keeps its token); otherwise it is kept for the next join,
491
+ * which checks it there. Resolves to when it expires (unix ms), when known.
492
+ */
493
+ updateToken(token: string): Promise<{
494
+ expiresAt: number | null;
495
+ }>;
496
+ /** The token reconnects use from now on, with its expiry (read from the token when not given). */
497
+ private setToken;
498
+ /**
499
+ * Warn TOKEN_EXPIRING_LEAD_MS before the token held for reconnects
500
+ * expires. Every new token -- the server's refresh, a promotion's, the
501
+ * app's -- reschedules it, so it fires only when nobody refreshed it.
502
+ */
503
+ private scheduleTokenExpiring;
504
+ /** networkQuality sampling runs while someone listens and the session is connected. */
505
+ private syncNetworkWatch;
506
+ /** Each live media transport's statistics, keyed by transport so a new one starts fresh. */
507
+ private transportStats;
316
508
  private rpc;
317
509
  private failAllPending;
318
510
  private onMessage;
319
511
  private onEvent;
512
+ /** Change the roster the join result holds; a new array each time, so a renderer sees the change. */
513
+ private updateRoster;
514
+ /** Keep the join result's slots current: claims held or away, and the moderator's locks. */
515
+ private applyClaim;
320
516
  private ensureSendTransport;
321
517
  private createSendTransport;
322
518
  private ensureRecvTransport;
@@ -334,10 +530,42 @@ export declare class StreamClient {
334
530
  * kept for a reconnect's republish.
335
531
  */
336
532
  publish(stream: MediaStream, constraints?: MediaStreamConstraints, options?: PublishOptions): Promise<void>;
533
+ private publishStream;
534
+ /**
535
+ * The microphone's audio quality: what it is being sent at while
536
+ * published, else what the next publish will use, after the project's limit.
537
+ */
538
+ get audioQuality(): AudioQuality;
539
+ /**
540
+ * Switch the microphone between standard (mono, up to 64 kbps) and HD
541
+ * (stereo, up to 128 kbps) while live. The codec settings are fixed per
542
+ * producer, so the microphone's producer is replaced: listeners hear a gap
543
+ * of a fraction of a second, and a microphone that is off stays off. Rejects
544
+ * with `audio-quality-not-allowed` when the project allows standard audio
545
+ * only. Resolves to the quality in use.
546
+ */
547
+ setAudioQuality(quality: AudioQuality): Promise<AudioQuality>;
548
+ private micProducer;
549
+ private micTask;
550
+ /** The audio quality to send: the request, capped to the project's, with the cap reported once. */
551
+ private audioQualityFor;
552
+ /**
553
+ * Produce the microphone at the audio quality in force. A track handed over
554
+ * switched off (or paused before a reconnect or a quality change) starts
555
+ * paused, on both ends.
556
+ */
557
+ private produceMic;
558
+ /** Close the microphone producer and produce its track again at the quality now in force. */
559
+ private reproduceMic;
337
560
  /** What this project may publish. Known once joined; 1080p before that. */
338
561
  get videoPolicy(): VideoPolicy;
339
- /** The quality video is being sent at, after the project's limit. */
562
+ /**
563
+ * The quality video is being sent at, after the project's limit: at 60 fps
564
+ * the largest size the project allows at 60, otherwise its 30 fps maximum.
565
+ */
340
566
  get videoQuality(): VideoQuality;
567
+ /** The camera's frame rate: what it is being sent at while published, else 30 until a publish decides. */
568
+ get videoFrameRate(): 30 | 60;
341
569
  /**
342
570
  * Change the video quality while publishing. The camera's producer is
343
571
  * replaced, so viewers see a brief pause while the new one starts. Resolves
@@ -345,8 +573,21 @@ export declare class StreamClient {
345
573
  * that size (for example with `track.applyConstraints`) first.
346
574
  */
347
575
  setVideoQuality(quality: VideoQuality): Promise<VideoQuality>;
348
- /** Change the camera frame rate without stopping screen, microphone or music. */
576
+ /**
577
+ * Change the camera frame rate without stopping screen, microphone or music.
578
+ * 60 where the project allows none stays at 30 and warns on `error` with
579
+ * `frame-rate-not-allowed`, without touching the camera; a camera or device
580
+ * that cannot keep 60 up falls back with `frame-rate-fallback`. Resolves to
581
+ * the frame rate used.
582
+ */
349
583
  setVideoFrameRate(frameRate: 30 | 60): Promise<30 | 60>;
584
+ /** Whether this project allows any 60 fps mode. */
585
+ private allows60;
586
+ /**
587
+ * The quality to send at a frame rate. A request above what 60 fps allows
588
+ * is sent at the largest size it does allow, and said so once.
589
+ */
590
+ private cameraQuality;
350
591
  /**
351
592
  * Send a different video track from now on: a canvas with effects drawn on
352
593
  * it, the raw camera again, another camera. When the new track needs the
@@ -452,6 +693,13 @@ export declare class StreamClient {
452
693
  private releaseScreen;
453
694
  private stopScreen;
454
695
  private restoreScreen;
696
+ /**
697
+ * 60 only when asked for, allowed by the project, captured at 50 or more and
698
+ * not fallen back from. The project's refusal and the camera's are reported
699
+ * apart, each once: `frame-rate-not-allowed` is the server's own code for a
700
+ * 60 fps producer the project does not allow, `frame-rate-fallback` means
701
+ * the camera or device cannot provide it.
702
+ */
455
703
  private frameRateFor;
456
704
  private sampleCamera;
457
705
  /**
@@ -477,6 +725,9 @@ export declare class StreamClient {
477
725
  stopMusic(): Promise<void>;
478
726
  private emitLocalMedia;
479
727
  private consume;
728
+ /** The oldest videos left waiting at the fan-out limit take the slots that opened. */
729
+ private consumeSkipped;
730
+ private consumeNow;
480
731
  /** True once this client has at least one live producer. */
481
732
  get publishing(): boolean;
482
733
  get micEnabled(): boolean;
@@ -510,6 +761,37 @@ export declare class StreamClient {
510
761
  kick(identity: string, reason?: string): Promise<unknown>;
511
762
  endRoom(): Promise<unknown>;
512
763
  getRoomState(): Promise<unknown>;
764
+ /**
765
+ * Take a slot, or (moderators) grant one by naming `identity`. One claim
766
+ * per identity: a second moves you. Refused with `slot-taken` when someone
767
+ * holds it (away included) and `slot-blocked` when a moderator locked it.
768
+ * Claim first, then promote: if the slot has gone, nothing has happened yet.
769
+ */
770
+ claim(key: string, identity?: string): Promise<void>;
771
+ /** Give up a slot. Moderators may release anyone's. */
772
+ release(key: string): Promise<void>;
773
+ /**
774
+ * Lock a slot so nobody may claim it. Moderators only. Refused with
775
+ * `slot-occupied` while someone holds it: taking a seat from a person using
776
+ * it is two deliberate acts, not a side effect of one tap.
777
+ */
778
+ blockSlot(key: string): Promise<void>;
779
+ /** Unlock a slot. Moderators only. */
780
+ unblockSlot(key: string): Promise<void>;
781
+ /** Replace your own display metadata; the room hears it as participantUpdated. */
782
+ setMetadata(metadata: Record<string, unknown>): Promise<void>;
783
+ /**
784
+ * Change room-scoped metadata. Moderators only, and persisted, so a client
785
+ * joining later reads it from `info.metadata`. Merges one key deep by
786
+ * default (a null value deletes its key); `replace` swaps the whole object.
787
+ * `requireFree` names slots that must be unheld for the change to apply,
788
+ * checked and applied together: the refusal (`slot-occupied`) names the
789
+ * offending keys in `RpcError.data.slots`. Resolves to the metadata now.
790
+ */
791
+ setRoomMetadata(metadata: Record<string, unknown>, options?: {
792
+ replace?: boolean;
793
+ requireFree?: string[];
794
+ }): Promise<unknown>;
513
795
  sendMessage(text: string, opts?: SendMessageOptions): Promise<{
514
796
  id: string;
515
797
  ts: number;