@tribe-nest/media-client 0.1.1 → 0.4.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 (44) hide show
  1. package/build/core/index.d.ts +1 -1
  2. package/build/core/index.d.ts.map +1 -1
  3. package/build/core/index.js.map +1 -1
  4. package/build/core/reconnect.d.ts +29 -0
  5. package/build/core/reconnect.d.ts.map +1 -1
  6. package/build/core/reconnect.js +49 -9
  7. package/build/core/reconnect.js.map +1 -1
  8. package/build/core/signal.d.ts +9 -0
  9. package/build/core/signal.d.ts.map +1 -1
  10. package/build/core/signal.js +18 -2
  11. package/build/core/signal.js.map +1 -1
  12. package/build/core/state.d.ts +31 -0
  13. package/build/core/state.d.ts.map +1 -1
  14. package/build/core/state.js +113 -8
  15. package/build/core/state.js.map +1 -1
  16. package/build/index.d.ts +1 -1
  17. package/build/index.d.ts.map +1 -1
  18. package/build/index.js.map +1 -1
  19. package/build/react/index.d.ts +78 -16
  20. package/build/react/index.d.ts.map +1 -1
  21. package/build/react/index.js +289 -12
  22. package/build/react/index.js.map +1 -1
  23. package/build/room/browserDevice.d.ts.map +1 -1
  24. package/build/room/browserDevice.js +13 -4
  25. package/build/room/browserDevice.js.map +1 -1
  26. package/build/room/device.d.ts +19 -0
  27. package/build/room/device.d.ts.map +1 -1
  28. package/build/room/room.d.ts +298 -3
  29. package/build/room/room.d.ts.map +1 -1
  30. package/build/room/room.js +742 -24
  31. package/build/room/room.js.map +1 -1
  32. package/package.json +2 -2
  33. package/src/core/_tests/reconnect.spec.ts +92 -0
  34. package/src/core/_tests/state.spec.ts +138 -0
  35. package/src/core/index.ts +2 -0
  36. package/src/core/reconnect.ts +76 -9
  37. package/src/core/signal.ts +16 -2
  38. package/src/core/state.ts +163 -11
  39. package/src/index.ts +2 -0
  40. package/src/react/index.tsx +323 -19
  41. package/src/room/_tests/room.spec.ts +954 -4
  42. package/src/room/browserDevice.ts +14 -4
  43. package/src/room/device.ts +19 -0
  44. package/src/room/room.ts +913 -26
@@ -60,6 +60,8 @@ export interface MediaTransport {
60
60
  track: MediaStreamTrack;
61
61
  appData?: Record<string, unknown>;
62
62
  encodings?: unknown[];
63
+ /** Prefer this codec from the loaded capabilities; ignored when absent. */
64
+ codec?: "h264" | "vp8";
63
65
  }): Promise<MediaProducerHandle>;
64
66
  consume(input: {
65
67
  id: string;
@@ -75,7 +77,18 @@ export type MediaProducerHandle = {
75
77
  pause(): void;
76
78
  resume(): void;
77
79
  close(): void;
80
+ /** Swap the capture feeding this producer. The node sees nothing. */
81
+ replaceTrack(track: MediaStreamTrack): Promise<void>;
78
82
  readonly closed: boolean;
83
+ /**
84
+ * The underlying sender, when the implementation has one.
85
+ *
86
+ * Exposed for `degradationPreference`, which is a SENDER-level setting with
87
+ * no per-encoding equivalent, so there is no way to ask for it through
88
+ * `produce()`. Optional because a non-browser implementation has no such
89
+ * object, and every caller has to cope with its absence anyway.
90
+ */
91
+ readonly rtpSender?: RTCRtpSender | null;
79
92
  };
80
93
  export type MediaConsumerHandle = {
81
94
  readonly id: string;
@@ -85,6 +98,12 @@ export type MediaConsumerHandle = {
85
98
  pause(): void;
86
99
  resume(): void;
87
100
  close(): void;
101
+ /**
102
+ * The browser's inbound stats for this consumer, when the implementation
103
+ * has them (mediasoup-client does; a fake need not). What the diagnostics
104
+ * read decoded resolution and bitrate from.
105
+ */
106
+ getStats?(): Promise<unknown>;
88
107
  };
89
108
  /**
90
109
  * The device: capability negotiation plus transport construction.
@@ -1 +1 @@
1
- {"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../src/room/device.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../src/room/device.ts"],"names":[],"mappings":"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"}
@@ -55,15 +55,160 @@ export type MediaTrack = {
55
55
  track: MediaStreamTrack;
56
56
  /** Paused at the SOURCE, as the publisher left it. */
57
57
  paused: boolean;
58
+ /** The publisher's declared label, when the node relayed one. Rendering only. */
59
+ source?: string;
58
60
  };
59
61
  /** What a local track is, in the vocabulary the node checks against `publishKinds`. */
60
62
  export type LocalPublicationSource = "camera" | "microphone" | "screen";
63
+ /**
64
+ * Every label this SDK publishes under.
65
+ *
66
+ * `program` is a COMPOSED feed rather than a device: a broadcast studio's
67
+ * rendered output, published so a server-side egress can restream it. It is
68
+ * not a capture, so it is never a "lost source" to re-offer a person after a
69
+ * drop, and `useLocalMedia`'s device controls never touch it. The node treats
70
+ * it as its track's kind (`requiredPublishKind`), so a token needs only
71
+ * `publishKinds: ["audio", "video"]`.
72
+ */
73
+ export type PublishSourceLabel = LocalPublicationSource | "program";
74
+ /**
75
+ * How to encode one publication, where the default is wrong.
76
+ *
77
+ * A camera takes the browser's defaults. A composed program feed does not:
78
+ * an RTMP restream needs H.264 (RTMP carries nothing else, and the egress
79
+ * copies rather than transcodes), and a 1080p canvas at the default bitrate
80
+ * is a smear. Both are per-publication facts, not per-room ones.
81
+ */
82
+ export type PublishOptions = {
83
+ /** Pick this codec from the router's list. Ignored when the router lacks it. */
84
+ codec?: "h264" | "vp8";
85
+ /** Cap for the encoder, in kbit/s. Read as the TOP layer under simulcast. */
86
+ maxBitrateKbps?: number;
87
+ /**
88
+ * Send three spatial layers instead of one, so each consumer can be served
89
+ * the one its connection can carry.
90
+ *
91
+ * The choosing is not ours and does not need to be: mediasoup picks a layer
92
+ * per consumer from that transport's own bandwidth estimate, so a viewer on
93
+ * a poor line gets 360p rather than a stall, with nothing to implement on
94
+ * either end. What we decide is only whether the layers exist to choose
95
+ * from.
96
+ *
97
+ * Use it for a feed with an AUDIENCE. It is wrong for a camera in a small
98
+ * call, where everyone can carry the one encoding and the extra layers are
99
+ * encoder time spent on nobody.
100
+ *
101
+ * ## Why VP8 and not H.264
102
+ *
103
+ * Browser simulcast is reliable on VP8 and is not on H.264, where it depends
104
+ * on the hardware encoder and quietly degrades to one layer. A caller that
105
+ * needs H.264 downstream (an RTMP restream copies rather than transcodes)
106
+ * should publish one encoding and leave this off. The two are exclusive by
107
+ * design rather than by accident.
108
+ */
109
+ simulcast?: boolean;
110
+ };
111
+ /**
112
+ * Which simulcast layer a tile of `widthPx` deserves: 0 = q, 1 = h, 2 = f.
113
+ *
114
+ * The policy lives HERE, not on the node, because the tile width is a fact
115
+ * only the renderer has; the node obeys. Buckets, not a formula, so a resize
116
+ * only crosses a boundary occasionally and a boundary crossing is the only
117
+ * thing that costs a request. Screen shares always get the full layer:
118
+ * downscaled text is unreadable, and shares are rarely simulcast anyway.
119
+ */
120
+ export declare function spatialLayerForWidth(widthPx: number, source?: string): 0 | 1 | 2;
121
+ /** One tile the UI is currently rendering, reported through `setViewport`. */
122
+ export type ViewportEntry = {
123
+ producerId: string;
124
+ /** Rendered width, used to pick a simulcast layer. 0 is a valid "tiny". */
125
+ widthPx: number;
126
+ };
127
+ /** One rendered tile's health, local view merged with the node's answer. */
128
+ export type TileDiagnostics = {
129
+ producerId: string;
130
+ identity: string;
131
+ kind: "audio" | "video";
132
+ source?: string;
133
+ /** The simulcast layer this client last ASKED for: 0 q, 1 h, 2 f. */
134
+ requestedLayer?: number;
135
+ /** What the node is actually GIVING, from its consumer's currentLayers. */
136
+ currentLayer?: number;
137
+ viewportWidthPx?: number;
138
+ pausedByViewport: boolean;
139
+ /** Decoded picture, from the browser's inbound-rtp stats. */
140
+ frameWidth?: number;
141
+ frameHeight?: number;
142
+ framesPerSecond?: number;
143
+ /** Delta-computed between successive `getDiagnostics` calls; absent on the first. */
144
+ bitrateKbps?: number;
145
+ };
146
+ /** The node's half of `getDiagnostics`, absent against an older node. */
147
+ export type NodeDiagnostics = {
148
+ transports: {
149
+ transportId: string;
150
+ availableOutgoingBitrate?: number;
151
+ iceState?: string;
152
+ dtlsState?: string;
153
+ }[];
154
+ producers: {
155
+ producerId: string;
156
+ kind: string;
157
+ paused: boolean;
158
+ source?: string;
159
+ layers: {
160
+ rid?: string;
161
+ score: number;
162
+ }[];
163
+ }[];
164
+ consumers: {
165
+ consumerId: string;
166
+ producerId: string;
167
+ kind: string;
168
+ paused: boolean;
169
+ preferredLayers?: {
170
+ spatialLayer: number;
171
+ temporalLayer?: number;
172
+ };
173
+ currentLayers?: {
174
+ spatialLayer: number;
175
+ temporalLayer?: number;
176
+ };
177
+ score?: unknown;
178
+ }[];
179
+ };
180
+ export type CallDiagnostics = {
181
+ tiles: TileDiagnostics[];
182
+ /**
183
+ * The recv transport's congestion estimate in bits per second, from the
184
+ * node. THE number to look at first: every video consumer shares it, and
185
+ * an estimate sitting at the low hundreds of kbps in a group call is the
186
+ * estimator pinning everyone to the quarter layer, whatever anyone asked.
187
+ */
188
+ availableOutgoingBitrate?: number;
189
+ /** This participant's own publishers, per-encoding arrival scores included:
190
+ * a layer scored 0 is a layer the node is not receiving. */
191
+ localProducers?: NodeDiagnostics["producers"];
192
+ /** The raw node answer, for anything the shaped fields above leave out. */
193
+ node?: NodeDiagnostics;
194
+ };
195
+ /** How an incoming ephemeral broadcast reaches the application. */
196
+ export type BroadcastEvent = {
197
+ type: string;
198
+ identity: string;
199
+ data: Record<string, unknown>;
200
+ /** Origin node clock. Animation ordering only. */
201
+ at: number;
202
+ };
61
203
  export type LocalPublication = {
62
204
  producerId: string;
63
205
  kind: "audio" | "video";
64
- source: LocalPublicationSource;
206
+ source: PublishSourceLabel;
65
207
  track: MediaStreamTrack;
66
208
  handle: MediaProducerHandle;
209
+ /** As given to `publish`, kept so a planned server move can republish the
210
+ * same encoding (codec, simulcast, bitrate) without asking anyone. */
211
+ options: PublishOptions;
67
212
  /**
68
213
  * Paused at the source by `setPaused`. The capture is still open and the
69
214
  * producer still exists; nothing is being sent. This is what a mute is.
@@ -92,11 +237,25 @@ export type MediaRoomOptions = {
92
237
  webSocket?: MediaWebSocketFactory;
93
238
  /**
94
239
  * How hard to try to get back in after a drop. Defaults to
95
- * `DEFAULT_RECONNECT_OPTIONS`; `{ maxAttempts: 0 }` turns automatic recovery
240
+ * `DEFAULT_RECONNECT_OPTIONS`; `{ maxAttempts: 0 }` turns FAILURE recovery
96
241
  * off, which leaves `isRecovering` false and is what tells a UI to offer a
97
242
  * control instead of a spinner.
243
+ *
244
+ * A server-ordered drain MOVE is deliberately not a failure and happens
245
+ * even at `maxAttempts: 0`: the node asked to be left and named where to
246
+ * go, and honoring that is what keeps the call alive through a deploy.
247
+ * If the move's rejoin then FAILS, the off switch applies to every retry
248
+ * after it.
98
249
  */
99
250
  reconnect?: Partial<ReconnectOptions>;
251
+ /**
252
+ * How long a video consumer that fell out of the viewport stays PAUSED
253
+ * before it is closed. Pause is cheap and reversible (a page flip back
254
+ * costs a resume, not a consume plus a keyframe); close frees the node's
255
+ * consumer slot and eventually the mirror and pipe. Mirrors the
256
+ * `mirrorGraceMs` reasoning on the node.
257
+ */
258
+ viewportCloseGraceMs?: number;
100
259
  onLog?: (level: SignalLogLevel, message: string, detail?: unknown) => void;
101
260
  };
102
261
  type Listener = () => void;
@@ -114,14 +273,45 @@ export declare class MediaRoom {
114
273
  /** Per publication: stop listening for the track ending on its own. */
115
274
  private readonly trackEndWatchers;
116
275
  private readonly listeners;
276
+ private readonly broadcastListeners;
117
277
  /** One in-flight subscribe per producer, so a burst of activeSpeakers frames
118
278
  * does not race itself into two consumers for one producer. */
119
279
  private readonly subscribing;
280
+ /**
281
+ * What the UI says it is rendering. `null` (never set, or cleared) is the
282
+ * legacy behavior: subscribe the whole active set, which is what every
283
+ * headless consumer (egress, harness, agents) keeps. `[]` is a hidden tab:
284
+ * zero video, audio untouched.
285
+ */
286
+ private viewport;
287
+ private viewportTimer;
288
+ private pendingViewport;
289
+ /** Video consumers paused because their tile is off-viewport, each holding
290
+ * its close timer. Single owner of the pause/close decision. */
291
+ private readonly pausedByViewport;
292
+ /** The last spatial layer requested per producer, so a resize storm only
293
+ * speaks up when a bucket boundary is crossed. */
294
+ private readonly sentLayer;
295
+ /** Old-node degradation: each new verb is disabled on its first
296
+ * `bad_request`, never retried into the frame budget. */
297
+ private readonly unsupported;
120
298
  private stateValue;
121
299
  private connection;
122
300
  private lastError;
123
301
  /** Consecutive failed attempts since the last successful join. */
124
302
  private reconnectAttempt;
303
+ /** When the current OUTAGE began, for the reconnect time budget. Null while
304
+ * connected. The budget, not the attempt count, is what decides when a
305
+ * room with a person in front of it stops trying. */
306
+ private outageStartedAt;
307
+ /**
308
+ * The planned-move machine. `scheduled` is the jittered wait after a
309
+ * `draining` frame, during which the call continues untouched; `moving`
310
+ * holds the STASH: the live capture tracks that survive the reconnect and
311
+ * are republished on the far side, which is what makes a drain smooth
312
+ * instead of a mute-everything drop.
313
+ */
314
+ private migration;
125
315
  private reconnectTimer;
126
316
  private recovering;
127
317
  /** `close()` has been called. Nothing may open a socket after that. */
@@ -132,6 +322,23 @@ export declare class MediaRoom {
132
322
  * it ended after an hour or before a socket was ever opened.
133
323
  */
134
324
  private onDisconnect;
325
+ /**
326
+ * The active set was an instruction about consumers on the connection that
327
+ * just ended. Left standing, it would be mistaken by the next `joined` for
328
+ * a set the new node had sent ahead of the snapshot. The split, the levels
329
+ * and the enforcement flag go with it.
330
+ */
331
+ private clearActiveSetState;
332
+ /** The captures a move was carrying, for the republish on the far side.
333
+ * Program feeds are excluded exactly as they are from `lostSources`. */
334
+ private buildStash;
335
+ /**
336
+ * A move that is over, one way or the other. On failure the stashed
337
+ * captures are STOPPED and surfaced as lost sources: the camera light must
338
+ * never outlive both its session and its migration, and from here the UX
339
+ * is exactly the ordinary-drop one, a person and a button.
340
+ */
341
+ private stopStash;
135
342
  get state(): RoomState;
136
343
  get connectionState(): ConnectionState;
137
344
  get error(): DisconnectCause | undefined;
@@ -179,9 +386,24 @@ export declare class MediaRoom {
179
386
  * here, because `useSyncExternalStore` reads it.
180
387
  */
181
388
  get lostPublicationSources(): readonly LocalPublicationSource[];
389
+ /**
390
+ * Why does the call look the way it looks, answered without
391
+ * webrtc-internals: per tile, the layer this client ASKED for, the layer
392
+ * the node is GIVING, and the picture the browser is decoding; plus the
393
+ * node's congestion estimate and this side's own publish health. Built for
394
+ * polling (a diagnostics HUD calls it once a second); bitrate is computed
395
+ * from the byte delta between calls. Degrades gracefully everywhere: an
396
+ * old node contributes nothing, a fake device without stats contributes
397
+ * nothing, and the local half always answers.
398
+ */
399
+ getDiagnostics(): Promise<CallDiagnostics>;
400
+ /** Byte counters from the previous `getDiagnostics`, for the bitrate delta. */
401
+ private readonly statsBaseline;
402
+ private inboundStats;
182
403
  /** Subscribe to changes. Returns an unsubscribe. */
183
404
  onChange(listener: Listener): () => void;
184
405
  connect(): Promise<void>;
406
+ private restoreStash;
185
407
  close(): Promise<void>;
186
408
  /**
187
409
  * Decide whether to come back, and book the attempt. Returns whether one was.
@@ -206,7 +428,18 @@ export declare class MediaRoom {
206
428
  * `publishKinds`: a token granting audio only must not be able to publish a
207
429
  * screen share by relabelling it, and the node is where that is decided.
208
430
  */
209
- publish(track: MediaStreamTrack, source: LocalPublicationSource): Promise<LocalPublication>;
431
+ publish(track: MediaStreamTrack, source: PublishSourceLabel, options?: PublishOptions): Promise<LocalPublication>;
432
+ /**
433
+ * Swap the capture behind a publication, keeping the producer.
434
+ *
435
+ * A device change (another camera, another microphone) is this, and it is
436
+ * deliberately NOT unpublish plus publish: that changes the producer id,
437
+ * which is the key every consumer's tile and every studio's scene holds, so
438
+ * a switched camera vanished from the stage until somebody re-added it.
439
+ * The old capture is stopped here; the new one is watched for ending the
440
+ * same way the first was.
441
+ */
442
+ replaceTrack(producerId: string, track: MediaStreamTrack): Promise<void>;
210
443
  unpublish(producerId: string): Promise<void>;
211
444
  /**
212
445
  * Mute or unmute at the source, keeping the capture and the producer.
@@ -231,8 +464,70 @@ export declare class MediaRoom {
231
464
  * are the same thing and this needs no special case.
232
465
  */
233
466
  syncSubscriptions(): Promise<void>;
467
+ /**
468
+ * Tell the room what the UI is rendering: which producers, at what width.
469
+ *
470
+ * Debounced inside the room (a scroll fires many times), trailing 150ms.
471
+ * Never call this from a headless consumer; not calling it IS the legacy
472
+ * subscribe-the-whole-set behavior.
473
+ */
474
+ setViewport(entries: readonly ViewportEntry[]): void;
475
+ /** Back to the legacy behavior: subscribe the whole active set. */
476
+ clearViewport(): void;
477
+ /** The width the UI reported for a producer's tile, if it reported one. */
478
+ private viewportWidth;
479
+ private dropConsumer;
480
+ private beginViewportPause;
481
+ private cancelViewportPause;
482
+ /**
483
+ * Bring every live video consumer onto the layer its reported width implies.
484
+ * Bucket-change only: the last sent layer is remembered, so a resize storm
485
+ * costs nothing until a boundary is crossed. A layer change keeps the
486
+ * consumer, the pipe and the SSRC, which is what makes page flips instant.
487
+ */
488
+ private applyPreferredLayers;
489
+ /**
490
+ * A request an OLD node may not understand. Disabled for the session on the
491
+ * first `bad_request` rather than retried: a retry loop meets the node's
492
+ * frame budget, and the frame budget closes sockets.
493
+ */
494
+ private requestOptional;
234
495
  subscribe(producerId: string): Promise<void>;
235
496
  private doSubscribe;
497
+ /**
498
+ * Send an ephemeral, unstored fan-out to the room: a flying reaction, a
499
+ * courtesy lower-hand. Grant-gated on the node (`canPublishData`) and
500
+ * rate-limited there; NOT a chat transport, and nothing durable may be
501
+ * derived from one.
502
+ */
503
+ sendReaction(data: Record<string, unknown>): Promise<void>;
504
+ /**
505
+ * Ask another participant to lower their hand. Honorific by design: the
506
+ * TARGET's client obeys by calling `setHandRaised(false)` itself; the
507
+ * server-held hand state only ever moves on its owner's verb.
508
+ */
509
+ sendLowerHand(target: string): Promise<void>;
510
+ /**
511
+ * Raise or lower this participant's own hand. Server-materialized room
512
+ * state: it survives reconnects and appears in late joiners' snapshots, so
513
+ * `state.raisedHands` is the truth to render, not the reply.
514
+ */
515
+ setHandRaised(raised: boolean): Promise<void>;
516
+ /**
517
+ * Incoming broadcasts, as EVENTS rather than state: a reaction is an
518
+ * animation, and holding a list of them in `RoomState` would make every
519
+ * emoji a whole-room re-render. Unknown types included; ignore what you
520
+ * do not recognize.
521
+ */
522
+ onBroadcast(listener: (event: BroadcastEvent) => void): () => void;
523
+ /**
524
+ * The node asked to be left, with a jittered window. THE fix for the drain
525
+ * experience: this frame used to be recorded and ignored, so the "told,
526
+ * not cut" design never executed and everyone was cut at the deadline.
527
+ * The call continues untouched during the wait; the UI is not told.
528
+ */
529
+ private onDrainingFrame;
530
+ private beginPlannedMove;
236
531
  /**
237
532
  * RULE 2: lazily, and once.
238
533
  *
@@ -1 +1 @@
1
- {"version":3,"file":"room.d.ts","sourceRoot":"","sources":["../../src/room/room.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"room.d.ts","sourceRoot":"","sources":["../../src/room/room.ts"],"names":[],"mappings":"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"}