@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/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
### [1.4.6](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.4.5...@stream-io/video-client-1.4.6) (2024-07-25)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* allow joining left call instances ([#1448](https://github.com/GetStream/stream-video-js/issues/1448)) ([2f72300](https://github.com/GetStream/stream-video-js/commit/2f72300f9377eac774516cee3366c28e99840425)), closes [#1433](https://github.com/GetStream/stream-video-js/issues/1433)
|
|
11
|
+
* allow reusing call instances after leaving ([#1433](https://github.com/GetStream/stream-video-js/issues/1433)) ([61e05af](https://github.com/GetStream/stream-video-js/commit/61e05af25c441b7db9db16166a6b4eca20ec7748))
|
|
12
|
+
|
|
13
|
+
### [1.4.5](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.4.4...@stream-io/video-client-1.4.5) (2024-07-12)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
* report the Plain-JS sdk version to the SFU ([#1438](https://github.com/GetStream/stream-video-js/issues/1438)) ([7ac54e4](https://github.com/GetStream/stream-video-js/commit/7ac54e46c80288debbf99339e861fe7f6cdb0fdf))
|
|
19
|
+
|
|
5
20
|
### [1.4.4](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.4.3...@stream-io/video-client-1.4.4) (2024-07-02)
|
|
6
21
|
|
|
7
22
|
|
package/dist/index.browser.es.js
CHANGED
|
@@ -925,6 +925,14 @@ var SdkType;
|
|
|
925
925
|
* @generated from protobuf enum value: SDK_TYPE_UNITY = 7;
|
|
926
926
|
*/
|
|
927
927
|
SdkType[SdkType["UNITY"] = 7] = "UNITY";
|
|
928
|
+
/**
|
|
929
|
+
* @generated from protobuf enum value: SDK_TYPE_GO = 8;
|
|
930
|
+
*/
|
|
931
|
+
SdkType[SdkType["GO"] = 8] = "GO";
|
|
932
|
+
/**
|
|
933
|
+
* @generated from protobuf enum value: SDK_TYPE_PLAIN_JAVASCRIPT = 9;
|
|
934
|
+
*/
|
|
935
|
+
SdkType[SdkType["PLAIN_JAVASCRIPT"] = 9] = "PLAIN_JAVASCRIPT";
|
|
928
936
|
})(SdkType || (SdkType = {}));
|
|
929
937
|
/**
|
|
930
938
|
* @generated from protobuf enum stream.video.sfu.models.TrackUnpublishReason
|
|
@@ -6527,7 +6535,14 @@ function getIceCandidate(candidate) {
|
|
|
6527
6535
|
}
|
|
6528
6536
|
}
|
|
6529
6537
|
|
|
6530
|
-
|
|
6538
|
+
const version = "1.4.6" ;
|
|
6539
|
+
const [major, minor, patch] = version.split('.');
|
|
6540
|
+
let sdkInfo = {
|
|
6541
|
+
type: SdkType.PLAIN_JAVASCRIPT,
|
|
6542
|
+
major,
|
|
6543
|
+
minor,
|
|
6544
|
+
patch,
|
|
6545
|
+
};
|
|
6531
6546
|
let osInfo;
|
|
6532
6547
|
let deviceInfo;
|
|
6533
6548
|
let webRtcInfo;
|
|
@@ -12469,6 +12484,8 @@ class Call {
|
|
|
12469
12484
|
this.reconnectAttempts = 0;
|
|
12470
12485
|
this.maxReconnectAttempts = 10;
|
|
12471
12486
|
this.isLeaving = false;
|
|
12487
|
+
this.initialized = false;
|
|
12488
|
+
this.joinLeaveConcurrencyTag = Symbol('joinLeaveConcurrencyTag');
|
|
12472
12489
|
/**
|
|
12473
12490
|
* A list hooks/functions to invoke when the call is left.
|
|
12474
12491
|
* A typical use case is to clean up some global event handlers.
|
|
@@ -12520,59 +12537,61 @@ class Call {
|
|
|
12520
12537
|
* Leave the call and stop the media streams that were published by the call.
|
|
12521
12538
|
*/
|
|
12522
12539
|
this.leave = async ({ reject = false, reason = 'user is leaving the call', } = {}) => {
|
|
12523
|
-
|
|
12524
|
-
|
|
12525
|
-
|
|
12526
|
-
|
|
12527
|
-
if (callingState === CallingState.JOINING) {
|
|
12528
|
-
await this.assertCallJoined();
|
|
12529
|
-
}
|
|
12530
|
-
this.isLeaving = true;
|
|
12531
|
-
if (this.ringing) {
|
|
12532
|
-
// I'm the one who started the call, so I should cancel it.
|
|
12533
|
-
const hasOtherParticipants = this.state.remoteParticipants.length > 0;
|
|
12534
|
-
if (this.isCreatedByMe &&
|
|
12535
|
-
!hasOtherParticipants &&
|
|
12536
|
-
callingState === CallingState.RINGING) {
|
|
12537
|
-
// Signals other users that I have cancelled my call to them
|
|
12538
|
-
// before they accepted it.
|
|
12539
|
-
await this.reject();
|
|
12540
|
+
await withoutConcurrency(this.joinLeaveConcurrencyTag, async () => {
|
|
12541
|
+
const callingState = this.state.callingState;
|
|
12542
|
+
if (callingState === CallingState.LEFT) {
|
|
12543
|
+
throw new Error('Cannot leave call that has already been left.');
|
|
12540
12544
|
}
|
|
12541
|
-
|
|
12542
|
-
|
|
12543
|
-
await this.reject();
|
|
12545
|
+
if (callingState === CallingState.JOINING) {
|
|
12546
|
+
await this.assertCallJoined();
|
|
12544
12547
|
}
|
|
12545
|
-
|
|
12546
|
-
|
|
12547
|
-
|
|
12548
|
-
|
|
12549
|
-
|
|
12550
|
-
|
|
12551
|
-
|
|
12552
|
-
|
|
12553
|
-
|
|
12554
|
-
|
|
12555
|
-
|
|
12556
|
-
|
|
12557
|
-
|
|
12558
|
-
|
|
12559
|
-
|
|
12560
|
-
|
|
12561
|
-
|
|
12562
|
-
|
|
12563
|
-
|
|
12564
|
-
|
|
12565
|
-
|
|
12566
|
-
|
|
12567
|
-
|
|
12568
|
-
|
|
12569
|
-
|
|
12570
|
-
|
|
12571
|
-
|
|
12572
|
-
|
|
12573
|
-
|
|
12574
|
-
|
|
12575
|
-
|
|
12548
|
+
this.isLeaving = true;
|
|
12549
|
+
if (this.ringing) {
|
|
12550
|
+
// I'm the one who started the call, so I should cancel it.
|
|
12551
|
+
const hasOtherParticipants = this.state.remoteParticipants.length > 0;
|
|
12552
|
+
if (this.isCreatedByMe &&
|
|
12553
|
+
!hasOtherParticipants &&
|
|
12554
|
+
callingState === CallingState.RINGING) {
|
|
12555
|
+
// Signals other users that I have cancelled my call to them
|
|
12556
|
+
// before they accepted it.
|
|
12557
|
+
await this.reject();
|
|
12558
|
+
}
|
|
12559
|
+
else if (reject && callingState === CallingState.RINGING) {
|
|
12560
|
+
// Signals other users that I have rejected the incoming call.
|
|
12561
|
+
await this.reject();
|
|
12562
|
+
}
|
|
12563
|
+
}
|
|
12564
|
+
this.statsReporter?.stop();
|
|
12565
|
+
this.statsReporter = undefined;
|
|
12566
|
+
this.sfuStatsReporter?.stop();
|
|
12567
|
+
this.sfuStatsReporter = undefined;
|
|
12568
|
+
this.subscriber?.close();
|
|
12569
|
+
this.subscriber = undefined;
|
|
12570
|
+
this.publisher?.close();
|
|
12571
|
+
this.publisher = undefined;
|
|
12572
|
+
this.sfuClient?.close(StreamSfuClient.NORMAL_CLOSURE, reason);
|
|
12573
|
+
this.sfuClient = undefined;
|
|
12574
|
+
this.state.setCallingState(CallingState.LEFT);
|
|
12575
|
+
// Call all leave call hooks, e.g. to clean up global event handlers
|
|
12576
|
+
this.leaveCallHooks.forEach((hook) => hook());
|
|
12577
|
+
this.initialized = false;
|
|
12578
|
+
this.clientStore.unregisterCall(this);
|
|
12579
|
+
this.camera.dispose();
|
|
12580
|
+
this.microphone.dispose();
|
|
12581
|
+
this.screenShare.dispose();
|
|
12582
|
+
this.speaker.dispose();
|
|
12583
|
+
const stopOnLeavePromises = [];
|
|
12584
|
+
if (this.camera.stopOnLeave) {
|
|
12585
|
+
stopOnLeavePromises.push(this.camera.disable(true));
|
|
12586
|
+
}
|
|
12587
|
+
if (this.microphone.stopOnLeave) {
|
|
12588
|
+
stopOnLeavePromises.push(this.microphone.disable(true));
|
|
12589
|
+
}
|
|
12590
|
+
if (this.screenShare.stopOnLeave) {
|
|
12591
|
+
stopOnLeavePromises.push(this.screenShare.disable(true));
|
|
12592
|
+
}
|
|
12593
|
+
await Promise.all(stopOnLeavePromises);
|
|
12594
|
+
});
|
|
12576
12595
|
};
|
|
12577
12596
|
/**
|
|
12578
12597
|
* Loads the information about the call.
|
|
@@ -12582,6 +12601,7 @@ class Call {
|
|
|
12582
12601
|
* @param params.members_limit the total number of members to return as part of the response.
|
|
12583
12602
|
*/
|
|
12584
12603
|
this.get = async (params) => {
|
|
12604
|
+
await this.setup();
|
|
12585
12605
|
const response = await this.streamClient.get(this.streamClientBasePath, params);
|
|
12586
12606
|
if (params?.ring && !this.ringing) {
|
|
12587
12607
|
this.ringingSubject.next(true);
|
|
@@ -12602,6 +12622,7 @@ class Call {
|
|
|
12602
12622
|
* @param data the data to create the call with.
|
|
12603
12623
|
*/
|
|
12604
12624
|
this.getOrCreate = async (data) => {
|
|
12625
|
+
await this.setup();
|
|
12605
12626
|
const response = await this.streamClient.post(this.streamClientBasePath, data);
|
|
12606
12627
|
if (data?.ring && !this.ringing) {
|
|
12607
12628
|
this.ringingSubject.next(true);
|
|
@@ -12666,14 +12687,12 @@ class Call {
|
|
|
12666
12687
|
* @returns a promise which resolves once the call join-flow has finished.
|
|
12667
12688
|
*/
|
|
12668
12689
|
this.join = async (data) => {
|
|
12690
|
+
await this.setup();
|
|
12669
12691
|
const callingState = this.state.callingState;
|
|
12670
12692
|
if ([CallingState.JOINED, CallingState.JOINING].includes(callingState)) {
|
|
12671
12693
|
this.logger('warn', 'Join method called twice, you should only call this once');
|
|
12672
12694
|
throw new Error(`Illegal State: Already joined.`);
|
|
12673
12695
|
}
|
|
12674
|
-
if (callingState === CallingState.LEFT) {
|
|
12675
|
-
throw new Error('Illegal State: Cannot join already left call. Create a new Call instance to join a call.');
|
|
12676
|
-
}
|
|
12677
12696
|
const isMigrating = callingState === CallingState.MIGRATING;
|
|
12678
12697
|
const isReconnecting = callingState === CallingState.RECONNECTING;
|
|
12679
12698
|
this.state.setCallingState(CallingState.JOINING);
|
|
@@ -13807,20 +13826,31 @@ class Call {
|
|
|
13807
13826
|
this.state.setMembers(members || []);
|
|
13808
13827
|
this.state.setOwnCapabilities(ownCapabilities || []);
|
|
13809
13828
|
this.state.setCallingState(ringing ? CallingState.RINGING : CallingState.IDLE);
|
|
13810
|
-
this.on('all', (event) => {
|
|
13811
|
-
// update state with the latest event data
|
|
13812
|
-
this.state.updateFromEvent(event);
|
|
13813
|
-
});
|
|
13814
|
-
this.leaveCallHooks.add(registerEventHandlers(this, this.state, this.dispatcher));
|
|
13815
|
-
this.registerEffects();
|
|
13816
|
-
this.leaveCallHooks.add(createSubscription(this.trackSubscriptionsSubject.pipe(debounce((v) => timer(v.type)), map$1((v) => v.data)), (subscriptions) => this.sfuClient?.updateSubscriptions(subscriptions).catch((err) => {
|
|
13817
|
-
this.logger('debug', `Failed to update track subscriptions`, err);
|
|
13818
|
-
})));
|
|
13819
13829
|
this.camera = new CameraManager(this);
|
|
13820
13830
|
this.microphone = new MicrophoneManager(this);
|
|
13821
13831
|
this.speaker = new SpeakerManager(this);
|
|
13822
13832
|
this.screenShare = new ScreenShareManager(this);
|
|
13823
13833
|
}
|
|
13834
|
+
async setup() {
|
|
13835
|
+
await withoutConcurrency(this.joinLeaveConcurrencyTag, async () => {
|
|
13836
|
+
if (this.initialized) {
|
|
13837
|
+
return;
|
|
13838
|
+
}
|
|
13839
|
+
this.leaveCallHooks.add(this.on('all', (event) => {
|
|
13840
|
+
// update state with the latest event data
|
|
13841
|
+
this.state.updateFromEvent(event);
|
|
13842
|
+
}));
|
|
13843
|
+
this.leaveCallHooks.add(registerEventHandlers(this, this.state, this.dispatcher));
|
|
13844
|
+
this.registerEffects();
|
|
13845
|
+
this.leaveCallHooks.add(createSubscription(this.trackSubscriptionsSubject.pipe(debounce((v) => timer(v.type)), map$1((v) => v.data)), (subscriptions) => this.sfuClient?.updateSubscriptions(subscriptions).catch((err) => {
|
|
13846
|
+
this.logger('debug', `Failed to update track subscriptions`, err);
|
|
13847
|
+
})));
|
|
13848
|
+
if (this.state.callingState === CallingState.LEFT) {
|
|
13849
|
+
this.state.setCallingState(CallingState.IDLE);
|
|
13850
|
+
}
|
|
13851
|
+
this.initialized = true;
|
|
13852
|
+
});
|
|
13853
|
+
}
|
|
13824
13854
|
registerEffects() {
|
|
13825
13855
|
this.leaveCallHooks.add(
|
|
13826
13856
|
// handles updating the permissions context when the settings change.
|
|
@@ -15506,7 +15536,7 @@ class StreamClient {
|
|
|
15506
15536
|
});
|
|
15507
15537
|
};
|
|
15508
15538
|
this.getUserAgent = () => {
|
|
15509
|
-
const version = "1.4.
|
|
15539
|
+
const version = "1.4.6" ;
|
|
15510
15540
|
return (this.userAgent ||
|
|
15511
15541
|
`stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
|
|
15512
15542
|
};
|