@stream-io/video-client 1.59.1 → 1.61.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.
- package/CHANGELOG.md +18 -0
- package/dist/index.browser.es.js +744 -156
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +744 -155
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +744 -156
- package/dist/index.es.js.map +1 -1
- package/dist/src/Call.d.ts +34 -8
- package/dist/src/coordinator/connection/types.d.ts +16 -0
- package/dist/src/events/call.d.ts +0 -11
- package/dist/src/gen/coordinator/index.d.ts +73 -0
- package/dist/src/reporting/ClientEventReporter.d.ts +11 -1
- package/dist/src/ringing/RingStatePoller.d.ts +46 -0
- package/dist/src/ringing/RingTimeout.d.ts +27 -0
- package/dist/src/ringing/index.d.ts +4 -0
- package/dist/src/ringing/reconcileRingState.d.ts +18 -0
- package/dist/src/ringing/resolveOwnRingOutcome.d.ts +32 -0
- package/dist/src/rtc/Publisher.d.ts +18 -0
- package/dist/src/rtc/TransceiverCache.d.ts +10 -0
- package/dist/src/rtc/e2ee/E2EEManager.d.ts +10 -1
- package/dist/src/stats/utils.d.ts +6 -0
- package/dist/src/store/CallState.d.ts +10 -1
- package/dist/src/types.d.ts +30 -1
- package/index.ts +1 -0
- package/package.json +1 -1
- package/src/Call.ts +272 -108
- package/src/StreamSfuClient.ts +6 -2
- package/src/__tests__/Call.autodrop.test.ts +116 -64
- package/src/__tests__/Call.getRingState.test.ts +87 -0
- package/src/__tests__/Call.lifecycle.test.ts +498 -5
- package/src/__tests__/Call.ringSettled.test.ts +71 -0
- package/src/__tests__/Call.ringingLifecycle.test.ts +242 -0
- package/src/__tests__/StreamSfuClient.test.ts +48 -0
- package/src/coordinator/connection/types.ts +19 -0
- package/src/events/__tests__/call.test.ts +2 -217
- package/src/events/call.ts +1 -73
- package/src/events/callEventHandlers.ts +12 -23
- package/src/gen/coordinator/index.ts +67 -0
- package/src/reporting/ClientEventReporter.ts +30 -4
- package/src/reporting/__tests__/ClientEventReporter.test.ts +184 -7
- package/src/ringing/RingStatePoller.ts +177 -0
- package/src/ringing/RingTimeout.ts +90 -0
- package/src/ringing/__tests__/RingStatePoller.test.ts +462 -0
- package/src/ringing/__tests__/RingTimeout.test.ts +199 -0
- package/src/ringing/__tests__/reconcileRingState.test.ts +330 -0
- package/src/ringing/__tests__/resolveOwnRingOutcome.test.ts +103 -0
- package/src/ringing/index.ts +4 -0
- package/src/ringing/reconcileRingState.ts +108 -0
- package/src/ringing/resolveOwnRingOutcome.ts +58 -0
- package/src/rtc/Publisher.ts +66 -12
- package/src/rtc/TransceiverCache.ts +17 -0
- package/src/rtc/__tests__/Publisher.test.ts +209 -0
- package/src/rtc/__tests__/mocks/webrtc.mocks.ts +1 -0
- package/src/rtc/e2ee/E2EEManager.ts +10 -1
- package/src/rtc/e2ee/EncryptionManager.ts +1 -1
- package/src/rtc/e2ee/SPEC.md +1 -1
- package/src/stats/__tests__/utils.test.ts +33 -0
- package/src/stats/utils.ts +15 -0
- package/src/store/CallState.ts +25 -0
- package/src/store/__tests__/CallState.test.ts +59 -0
- package/src/types.ts +37 -1
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
CallAcceptedEvent,
|
|
25
25
|
CallEndedEvent,
|
|
26
26
|
CallUpdatedEvent,
|
|
27
|
+
type GetCallRingStateResponse,
|
|
27
28
|
MemberResponse,
|
|
28
29
|
OwnCapability,
|
|
29
30
|
} from '../../gen/coordinator';
|
|
@@ -1474,4 +1475,62 @@ describe('CallState', () => {
|
|
|
1474
1475
|
expect(state['closedCaptionsTasks'].size).toBe(0);
|
|
1475
1476
|
});
|
|
1476
1477
|
});
|
|
1478
|
+
|
|
1479
|
+
describe('updateFromRingState', () => {
|
|
1480
|
+
const ringState = fromPartial<GetCallRingStateResponse>({
|
|
1481
|
+
session_id: 'session-1',
|
|
1482
|
+
accepted_by: { bob: '2026-08-24T10:00:04Z' },
|
|
1483
|
+
rejected_by: { carol: '2026-08-24T10:00:09Z' },
|
|
1484
|
+
missed_by: { dave: '2026-08-24T10:00:35Z' },
|
|
1485
|
+
});
|
|
1486
|
+
|
|
1487
|
+
const withSession = (id: string) => {
|
|
1488
|
+
const state = new CallState();
|
|
1489
|
+
state['sessionSubject'].next(
|
|
1490
|
+
fromPartial({
|
|
1491
|
+
id,
|
|
1492
|
+
accepted_by: {},
|
|
1493
|
+
rejected_by: {},
|
|
1494
|
+
missed_by: {},
|
|
1495
|
+
participants: [fromPartial({ user_session_id: 'p1' })],
|
|
1496
|
+
}),
|
|
1497
|
+
);
|
|
1498
|
+
return state;
|
|
1499
|
+
};
|
|
1500
|
+
|
|
1501
|
+
it('merges the ring maps into the current session', () => {
|
|
1502
|
+
const state = withSession('session-1');
|
|
1503
|
+
state.updateFromRingState(ringState);
|
|
1504
|
+
|
|
1505
|
+
expect(state.session?.accepted_by).toEqual(ringState.accepted_by);
|
|
1506
|
+
expect(state.session?.rejected_by).toEqual(ringState.rejected_by);
|
|
1507
|
+
expect(state.session?.missed_by).toEqual(ringState.missed_by);
|
|
1508
|
+
});
|
|
1509
|
+
|
|
1510
|
+
it('leaves the session roster untouched', () => {
|
|
1511
|
+
const state = withSession('session-1');
|
|
1512
|
+
state.updateFromRingState(ringState);
|
|
1513
|
+
|
|
1514
|
+
expect(state.session?.participants).toHaveLength(1);
|
|
1515
|
+
});
|
|
1516
|
+
|
|
1517
|
+
it('ignores a ring state that belongs to another session', () => {
|
|
1518
|
+
const state = withSession('session-2');
|
|
1519
|
+
state.updateFromRingState(ringState);
|
|
1520
|
+
|
|
1521
|
+
expect(state.session?.accepted_by).toEqual({});
|
|
1522
|
+
});
|
|
1523
|
+
|
|
1524
|
+
it('applies the end timestamps', () => {
|
|
1525
|
+
const state = withSession('session-1');
|
|
1526
|
+
state.updateFromRingState({
|
|
1527
|
+
...ringState,
|
|
1528
|
+
session_ended_at: '2026-08-24T10:01:00Z',
|
|
1529
|
+
call_ended_at: '2026-08-24T10:01:00Z',
|
|
1530
|
+
});
|
|
1531
|
+
|
|
1532
|
+
expect(state.session?.ended_at).toBe('2026-08-24T10:01:00Z');
|
|
1533
|
+
expect(state.endedAt).toEqual(new Date('2026-08-24T10:01:00Z'));
|
|
1534
|
+
});
|
|
1535
|
+
});
|
|
1477
1536
|
});
|
package/src/types.ts
CHANGED
|
@@ -458,7 +458,17 @@ type StreamRNVideoSDKEndCallReason =
|
|
|
458
458
|
| 'unknown';
|
|
459
459
|
|
|
460
460
|
type StreamRNVideoSDKCallingX = {
|
|
461
|
-
|
|
461
|
+
/**
|
|
462
|
+
* @param isCancelled - polled around the bridge's waits: registration is
|
|
463
|
+
* skipped, or undone, when it returns true. Supplied by the join attempt
|
|
464
|
+
* because the call's own state cannot distinguish a fresh join starting
|
|
465
|
+
* from `LEFT` from an abandoned one that reached `LEFT` while waiting.
|
|
466
|
+
*/
|
|
467
|
+
joinCall: (
|
|
468
|
+
call: Call,
|
|
469
|
+
activeCalls: Call[],
|
|
470
|
+
isCancelled?: () => boolean,
|
|
471
|
+
) => Promise<void>;
|
|
462
472
|
endCall: (
|
|
463
473
|
call: Call,
|
|
464
474
|
reason?: StreamRNVideoSDKEndCallReason,
|
|
@@ -468,8 +478,34 @@ type StreamRNVideoSDKCallingX = {
|
|
|
468
478
|
unwireAudioEngineSubscription: () => void;
|
|
469
479
|
};
|
|
470
480
|
|
|
481
|
+
/**
|
|
482
|
+
* React Native's preparation and cleanup for a ringing call's join.
|
|
483
|
+
*
|
|
484
|
+
* A ringing call is joined by the SDK rather than by app code, so there is no
|
|
485
|
+
* point at which the app holds the call and can still set it up. These are that
|
|
486
|
+
* point, and the matching release.
|
|
487
|
+
*/
|
|
488
|
+
type StreamRNVideoSDKRingingCallLifecycle = {
|
|
489
|
+
/**
|
|
490
|
+
* Runs the app's pre-join setup and resolves once it is done, bounded by a
|
|
491
|
+
* deadline. Rejecting fails the join closed rather than joining with nothing
|
|
492
|
+
* installed.
|
|
493
|
+
*/
|
|
494
|
+
beforeJoin: (call: Call) => Promise<void>;
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* The join failed terminally. Ends the ringing flow and releases what the
|
|
498
|
+
* setup installed. Never rejects, so the original join error survives.
|
|
499
|
+
*/
|
|
500
|
+
onJoinFailed: (call: Call) => Promise<void>;
|
|
501
|
+
|
|
502
|
+
/** The call has ended; release whatever the pre-join hook installed. */
|
|
503
|
+
onLeave: (call: Call) => void;
|
|
504
|
+
};
|
|
505
|
+
|
|
471
506
|
export type StreamRNVideoSDKGlobals = {
|
|
472
507
|
callingX: StreamRNVideoSDKCallingX;
|
|
508
|
+
ringingCallLifecycle: StreamRNVideoSDKRingingCallLifecycle;
|
|
473
509
|
callManager: {
|
|
474
510
|
/**
|
|
475
511
|
* Sets up the in call manager.
|