@stream-io/video-client 1.4.4 → 1.4.6
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 +15 -0
- package/dist/index.browser.es.js +95 -65
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +95 -65
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +95 -65
- package/dist/index.es.js.map +1 -1
- package/dist/src/Call.d.ts +3 -0
- package/dist/src/gen/video/sfu/models/models.d.ts +9 -1
- package/package.json +1 -1
- package/src/Call.ts +100 -84
- package/src/__tests__/Call.test.ts +114 -0
- package/src/client-details.ts +17 -2
- package/src/gen/video/sfu/models/models.ts +8 -0
package/dist/index.cjs.js
CHANGED
|
@@ -946,6 +946,14 @@ var SdkType;
|
|
|
946
946
|
* @generated from protobuf enum value: SDK_TYPE_UNITY = 7;
|
|
947
947
|
*/
|
|
948
948
|
SdkType[SdkType["UNITY"] = 7] = "UNITY";
|
|
949
|
+
/**
|
|
950
|
+
* @generated from protobuf enum value: SDK_TYPE_GO = 8;
|
|
951
|
+
*/
|
|
952
|
+
SdkType[SdkType["GO"] = 8] = "GO";
|
|
953
|
+
/**
|
|
954
|
+
* @generated from protobuf enum value: SDK_TYPE_PLAIN_JAVASCRIPT = 9;
|
|
955
|
+
*/
|
|
956
|
+
SdkType[SdkType["PLAIN_JAVASCRIPT"] = 9] = "PLAIN_JAVASCRIPT";
|
|
949
957
|
})(SdkType || (SdkType = {}));
|
|
950
958
|
/**
|
|
951
959
|
* @generated from protobuf enum stream.video.sfu.models.TrackUnpublishReason
|
|
@@ -6548,7 +6556,14 @@ function getIceCandidate(candidate) {
|
|
|
6548
6556
|
}
|
|
6549
6557
|
}
|
|
6550
6558
|
|
|
6551
|
-
|
|
6559
|
+
const version = "1.4.6" ;
|
|
6560
|
+
const [major, minor, patch] = version.split('.');
|
|
6561
|
+
let sdkInfo = {
|
|
6562
|
+
type: SdkType.PLAIN_JAVASCRIPT,
|
|
6563
|
+
major,
|
|
6564
|
+
minor,
|
|
6565
|
+
patch,
|
|
6566
|
+
};
|
|
6552
6567
|
let osInfo;
|
|
6553
6568
|
let deviceInfo;
|
|
6554
6569
|
let webRtcInfo;
|
|
@@ -12490,6 +12505,8 @@ class Call {
|
|
|
12490
12505
|
this.reconnectAttempts = 0;
|
|
12491
12506
|
this.maxReconnectAttempts = 10;
|
|
12492
12507
|
this.isLeaving = false;
|
|
12508
|
+
this.initialized = false;
|
|
12509
|
+
this.joinLeaveConcurrencyTag = Symbol('joinLeaveConcurrencyTag');
|
|
12493
12510
|
/**
|
|
12494
12511
|
* A list hooks/functions to invoke when the call is left.
|
|
12495
12512
|
* A typical use case is to clean up some global event handlers.
|
|
@@ -12541,59 +12558,61 @@ class Call {
|
|
|
12541
12558
|
* Leave the call and stop the media streams that were published by the call.
|
|
12542
12559
|
*/
|
|
12543
12560
|
this.leave = async ({ reject = false, reason = 'user is leaving the call', } = {}) => {
|
|
12544
|
-
|
|
12545
|
-
|
|
12546
|
-
|
|
12547
|
-
|
|
12548
|
-
if (callingState === exports.CallingState.JOINING) {
|
|
12549
|
-
await this.assertCallJoined();
|
|
12550
|
-
}
|
|
12551
|
-
this.isLeaving = true;
|
|
12552
|
-
if (this.ringing) {
|
|
12553
|
-
// I'm the one who started the call, so I should cancel it.
|
|
12554
|
-
const hasOtherParticipants = this.state.remoteParticipants.length > 0;
|
|
12555
|
-
if (this.isCreatedByMe &&
|
|
12556
|
-
!hasOtherParticipants &&
|
|
12557
|
-
callingState === exports.CallingState.RINGING) {
|
|
12558
|
-
// Signals other users that I have cancelled my call to them
|
|
12559
|
-
// before they accepted it.
|
|
12560
|
-
await this.reject();
|
|
12561
|
+
await withoutConcurrency(this.joinLeaveConcurrencyTag, async () => {
|
|
12562
|
+
const callingState = this.state.callingState;
|
|
12563
|
+
if (callingState === exports.CallingState.LEFT) {
|
|
12564
|
+
throw new Error('Cannot leave call that has already been left.');
|
|
12561
12565
|
}
|
|
12562
|
-
|
|
12563
|
-
|
|
12564
|
-
await this.reject();
|
|
12566
|
+
if (callingState === exports.CallingState.JOINING) {
|
|
12567
|
+
await this.assertCallJoined();
|
|
12565
12568
|
}
|
|
12566
|
-
|
|
12567
|
-
|
|
12568
|
-
|
|
12569
|
-
|
|
12570
|
-
|
|
12571
|
-
|
|
12572
|
-
|
|
12573
|
-
|
|
12574
|
-
|
|
12575
|
-
|
|
12576
|
-
|
|
12577
|
-
|
|
12578
|
-
|
|
12579
|
-
|
|
12580
|
-
|
|
12581
|
-
|
|
12582
|
-
|
|
12583
|
-
|
|
12584
|
-
|
|
12585
|
-
|
|
12586
|
-
|
|
12587
|
-
|
|
12588
|
-
|
|
12589
|
-
|
|
12590
|
-
|
|
12591
|
-
|
|
12592
|
-
|
|
12593
|
-
|
|
12594
|
-
|
|
12595
|
-
|
|
12596
|
-
|
|
12569
|
+
this.isLeaving = true;
|
|
12570
|
+
if (this.ringing) {
|
|
12571
|
+
// I'm the one who started the call, so I should cancel it.
|
|
12572
|
+
const hasOtherParticipants = this.state.remoteParticipants.length > 0;
|
|
12573
|
+
if (this.isCreatedByMe &&
|
|
12574
|
+
!hasOtherParticipants &&
|
|
12575
|
+
callingState === exports.CallingState.RINGING) {
|
|
12576
|
+
// Signals other users that I have cancelled my call to them
|
|
12577
|
+
// before they accepted it.
|
|
12578
|
+
await this.reject();
|
|
12579
|
+
}
|
|
12580
|
+
else if (reject && callingState === exports.CallingState.RINGING) {
|
|
12581
|
+
// Signals other users that I have rejected the incoming call.
|
|
12582
|
+
await this.reject();
|
|
12583
|
+
}
|
|
12584
|
+
}
|
|
12585
|
+
this.statsReporter?.stop();
|
|
12586
|
+
this.statsReporter = undefined;
|
|
12587
|
+
this.sfuStatsReporter?.stop();
|
|
12588
|
+
this.sfuStatsReporter = undefined;
|
|
12589
|
+
this.subscriber?.close();
|
|
12590
|
+
this.subscriber = undefined;
|
|
12591
|
+
this.publisher?.close();
|
|
12592
|
+
this.publisher = undefined;
|
|
12593
|
+
this.sfuClient?.close(StreamSfuClient.NORMAL_CLOSURE, reason);
|
|
12594
|
+
this.sfuClient = undefined;
|
|
12595
|
+
this.state.setCallingState(exports.CallingState.LEFT);
|
|
12596
|
+
// Call all leave call hooks, e.g. to clean up global event handlers
|
|
12597
|
+
this.leaveCallHooks.forEach((hook) => hook());
|
|
12598
|
+
this.initialized = false;
|
|
12599
|
+
this.clientStore.unregisterCall(this);
|
|
12600
|
+
this.camera.dispose();
|
|
12601
|
+
this.microphone.dispose();
|
|
12602
|
+
this.screenShare.dispose();
|
|
12603
|
+
this.speaker.dispose();
|
|
12604
|
+
const stopOnLeavePromises = [];
|
|
12605
|
+
if (this.camera.stopOnLeave) {
|
|
12606
|
+
stopOnLeavePromises.push(this.camera.disable(true));
|
|
12607
|
+
}
|
|
12608
|
+
if (this.microphone.stopOnLeave) {
|
|
12609
|
+
stopOnLeavePromises.push(this.microphone.disable(true));
|
|
12610
|
+
}
|
|
12611
|
+
if (this.screenShare.stopOnLeave) {
|
|
12612
|
+
stopOnLeavePromises.push(this.screenShare.disable(true));
|
|
12613
|
+
}
|
|
12614
|
+
await Promise.all(stopOnLeavePromises);
|
|
12615
|
+
});
|
|
12597
12616
|
};
|
|
12598
12617
|
/**
|
|
12599
12618
|
* Loads the information about the call.
|
|
@@ -12603,6 +12622,7 @@ class Call {
|
|
|
12603
12622
|
* @param params.members_limit the total number of members to return as part of the response.
|
|
12604
12623
|
*/
|
|
12605
12624
|
this.get = async (params) => {
|
|
12625
|
+
await this.setup();
|
|
12606
12626
|
const response = await this.streamClient.get(this.streamClientBasePath, params);
|
|
12607
12627
|
if (params?.ring && !this.ringing) {
|
|
12608
12628
|
this.ringingSubject.next(true);
|
|
@@ -12623,6 +12643,7 @@ class Call {
|
|
|
12623
12643
|
* @param data the data to create the call with.
|
|
12624
12644
|
*/
|
|
12625
12645
|
this.getOrCreate = async (data) => {
|
|
12646
|
+
await this.setup();
|
|
12626
12647
|
const response = await this.streamClient.post(this.streamClientBasePath, data);
|
|
12627
12648
|
if (data?.ring && !this.ringing) {
|
|
12628
12649
|
this.ringingSubject.next(true);
|
|
@@ -12687,14 +12708,12 @@ class Call {
|
|
|
12687
12708
|
* @returns a promise which resolves once the call join-flow has finished.
|
|
12688
12709
|
*/
|
|
12689
12710
|
this.join = async (data) => {
|
|
12711
|
+
await this.setup();
|
|
12690
12712
|
const callingState = this.state.callingState;
|
|
12691
12713
|
if ([exports.CallingState.JOINED, exports.CallingState.JOINING].includes(callingState)) {
|
|
12692
12714
|
this.logger('warn', 'Join method called twice, you should only call this once');
|
|
12693
12715
|
throw new Error(`Illegal State: Already joined.`);
|
|
12694
12716
|
}
|
|
12695
|
-
if (callingState === exports.CallingState.LEFT) {
|
|
12696
|
-
throw new Error('Illegal State: Cannot join already left call. Create a new Call instance to join a call.');
|
|
12697
|
-
}
|
|
12698
12717
|
const isMigrating = callingState === exports.CallingState.MIGRATING;
|
|
12699
12718
|
const isReconnecting = callingState === exports.CallingState.RECONNECTING;
|
|
12700
12719
|
this.state.setCallingState(exports.CallingState.JOINING);
|
|
@@ -13828,20 +13847,31 @@ class Call {
|
|
|
13828
13847
|
this.state.setMembers(members || []);
|
|
13829
13848
|
this.state.setOwnCapabilities(ownCapabilities || []);
|
|
13830
13849
|
this.state.setCallingState(ringing ? exports.CallingState.RINGING : exports.CallingState.IDLE);
|
|
13831
|
-
this.on('all', (event) => {
|
|
13832
|
-
// update state with the latest event data
|
|
13833
|
-
this.state.updateFromEvent(event);
|
|
13834
|
-
});
|
|
13835
|
-
this.leaveCallHooks.add(registerEventHandlers(this, this.state, this.dispatcher));
|
|
13836
|
-
this.registerEffects();
|
|
13837
|
-
this.leaveCallHooks.add(createSubscription(this.trackSubscriptionsSubject.pipe(rxjs.debounce((v) => rxjs.timer(v.type)), rxjs.map((v) => v.data)), (subscriptions) => this.sfuClient?.updateSubscriptions(subscriptions).catch((err) => {
|
|
13838
|
-
this.logger('debug', `Failed to update track subscriptions`, err);
|
|
13839
|
-
})));
|
|
13840
13850
|
this.camera = new CameraManager(this);
|
|
13841
13851
|
this.microphone = new MicrophoneManager(this);
|
|
13842
13852
|
this.speaker = new SpeakerManager(this);
|
|
13843
13853
|
this.screenShare = new ScreenShareManager(this);
|
|
13844
13854
|
}
|
|
13855
|
+
async setup() {
|
|
13856
|
+
await withoutConcurrency(this.joinLeaveConcurrencyTag, async () => {
|
|
13857
|
+
if (this.initialized) {
|
|
13858
|
+
return;
|
|
13859
|
+
}
|
|
13860
|
+
this.leaveCallHooks.add(this.on('all', (event) => {
|
|
13861
|
+
// update state with the latest event data
|
|
13862
|
+
this.state.updateFromEvent(event);
|
|
13863
|
+
}));
|
|
13864
|
+
this.leaveCallHooks.add(registerEventHandlers(this, this.state, this.dispatcher));
|
|
13865
|
+
this.registerEffects();
|
|
13866
|
+
this.leaveCallHooks.add(createSubscription(this.trackSubscriptionsSubject.pipe(rxjs.debounce((v) => rxjs.timer(v.type)), rxjs.map((v) => v.data)), (subscriptions) => this.sfuClient?.updateSubscriptions(subscriptions).catch((err) => {
|
|
13867
|
+
this.logger('debug', `Failed to update track subscriptions`, err);
|
|
13868
|
+
})));
|
|
13869
|
+
if (this.state.callingState === exports.CallingState.LEFT) {
|
|
13870
|
+
this.state.setCallingState(exports.CallingState.IDLE);
|
|
13871
|
+
}
|
|
13872
|
+
this.initialized = true;
|
|
13873
|
+
});
|
|
13874
|
+
}
|
|
13845
13875
|
registerEffects() {
|
|
13846
13876
|
this.leaveCallHooks.add(
|
|
13847
13877
|
// handles updating the permissions context when the settings change.
|
|
@@ -15525,7 +15555,7 @@ class StreamClient {
|
|
|
15525
15555
|
});
|
|
15526
15556
|
};
|
|
15527
15557
|
this.getUserAgent = () => {
|
|
15528
|
-
const version = "1.4.
|
|
15558
|
+
const version = "1.4.6" ;
|
|
15529
15559
|
return (this.userAgent ||
|
|
15530
15560
|
`stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
|
|
15531
15561
|
};
|