@stream-io/video-client 1.44.5 → 1.44.6-beta.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/dist/index.browser.es.js +76 -37
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +76 -37
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +76 -37
- package/dist/index.es.js.map +1 -1
- package/dist/src/Call.d.ts +1 -1
- package/dist/src/types.d.ts +37 -5
- package/package.json +1 -1
- package/src/Call.ts +85 -40
- package/src/devices/SpeakerManager.ts +1 -0
- package/src/events/call.ts +3 -0
- package/src/store/stateStore.ts +1 -1
- package/src/types.ts +48 -5
package/dist/index.browser.es.js
CHANGED
|
@@ -4784,7 +4784,7 @@ class StreamVideoWriteableStateStore {
|
|
|
4784
4784
|
* The currently connected user.
|
|
4785
4785
|
*/
|
|
4786
4786
|
get connectedUser() {
|
|
4787
|
-
return
|
|
4787
|
+
return this.connectedUserSubject.getValue();
|
|
4788
4788
|
}
|
|
4789
4789
|
/**
|
|
4790
4790
|
* A list of {@link Call} objects created/tracked by this client.
|
|
@@ -6283,7 +6283,7 @@ const getSdkVersion = (sdk) => {
|
|
|
6283
6283
|
return sdk ? `${sdk.major}.${sdk.minor}.${sdk.patch}` : '0.0.0-development';
|
|
6284
6284
|
};
|
|
6285
6285
|
|
|
6286
|
-
const version = "1.44.
|
|
6286
|
+
const version = "1.44.6-beta.0";
|
|
6287
6287
|
const [major, minor, patch] = version.split('.');
|
|
6288
6288
|
let sdkInfo = {
|
|
6289
6289
|
type: SdkType.PLAIN_JAVASCRIPT,
|
|
@@ -8982,6 +8982,7 @@ const watchCallRejected = (call) => {
|
|
|
8982
8982
|
else {
|
|
8983
8983
|
if (rejectedBy[eventCall.created_by.id]) {
|
|
8984
8984
|
call.logger.info('call creator rejected, leaving call');
|
|
8985
|
+
globalThis.streamRNVideoSDK?.callingX?.endCall(call, 'remote');
|
|
8985
8986
|
await call.leave({ message: 'ring: creator rejected' });
|
|
8986
8987
|
}
|
|
8987
8988
|
}
|
|
@@ -8992,6 +8993,7 @@ const watchCallRejected = (call) => {
|
|
|
8992
8993
|
*/
|
|
8993
8994
|
const watchCallEnded = (call) => {
|
|
8994
8995
|
return function onCallEnded() {
|
|
8996
|
+
globalThis.streamRNVideoSDK?.callingX?.endCall(call, 'remote');
|
|
8995
8997
|
const { callingState } = call.state;
|
|
8996
8998
|
if (callingState !== CallingState.IDLE &&
|
|
8997
8999
|
callingState !== CallingState.LEFT) {
|
|
@@ -9023,6 +9025,7 @@ const watchSfuCallEnded = (call) => {
|
|
|
9023
9025
|
// update the call state to reflect the call has ended.
|
|
9024
9026
|
call.state.setEndedAt(new Date());
|
|
9025
9027
|
const reason = CallEndedReason[e.reason];
|
|
9028
|
+
globalThis.streamRNVideoSDK?.callingX?.endCall(call, 'remote');
|
|
9026
9029
|
await call.leave({ message: `callEnded received: ${reason}` });
|
|
9027
9030
|
}
|
|
9028
9031
|
catch (err) {
|
|
@@ -12626,6 +12629,7 @@ class SpeakerManager {
|
|
|
12626
12629
|
this.defaultDevice = defaultDevice;
|
|
12627
12630
|
globalThis.streamRNVideoSDK?.callManager.setup({
|
|
12628
12631
|
defaultDevice,
|
|
12632
|
+
isRingingTypeCall: this.call.ringing,
|
|
12629
12633
|
});
|
|
12630
12634
|
}
|
|
12631
12635
|
}
|
|
@@ -12825,6 +12829,7 @@ class Call {
|
|
|
12825
12829
|
const currentUserId = this.currentUserId;
|
|
12826
12830
|
if (currentUserId && blockedUserIds.includes(currentUserId)) {
|
|
12827
12831
|
this.logger.info('Leaving call because of being blocked');
|
|
12832
|
+
globalThis.streamRNVideoSDK?.callingX?.endCall(this, 'restricted');
|
|
12828
12833
|
await this.leave({ message: 'user blocked' }).catch((err) => {
|
|
12829
12834
|
this.logger.error('Error leaving call after being blocked', err);
|
|
12830
12835
|
});
|
|
@@ -12861,6 +12866,7 @@ class Call {
|
|
|
12861
12866
|
const isAcceptedElsewhere = isAcceptedByMe && this.state.callingState === CallingState.RINGING;
|
|
12862
12867
|
if ((isAcceptedElsewhere || isRejectedByMe) &&
|
|
12863
12868
|
!hasPending(this.joinLeaveConcurrencyTag)) {
|
|
12869
|
+
globalThis.streamRNVideoSDK?.callingX?.endCall(this, isAcceptedElsewhere ? 'answeredElsewhere' : 'rejected');
|
|
12864
12870
|
this.leave().catch(() => {
|
|
12865
12871
|
this.logger.error('Could not leave a call that was accepted or rejected elsewhere');
|
|
12866
12872
|
});
|
|
@@ -12872,6 +12878,9 @@ class Call {
|
|
|
12872
12878
|
const receiver_id = this.clientStore.connectedUser?.id;
|
|
12873
12879
|
const ended_at = callSession?.ended_at;
|
|
12874
12880
|
const created_by_id = this.state.createdBy?.id;
|
|
12881
|
+
if (this.currentUserId && created_by_id === this.currentUserId) {
|
|
12882
|
+
globalThis.streamRNVideoSDK?.callingX?.registerOutgoingCall(this);
|
|
12883
|
+
}
|
|
12875
12884
|
const rejected_by = callSession?.rejected_by;
|
|
12876
12885
|
const accepted_by = callSession?.accepted_by;
|
|
12877
12886
|
let leaveCallIdle = false;
|
|
@@ -13010,17 +13019,28 @@ class Call {
|
|
|
13010
13019
|
}
|
|
13011
13020
|
if (callingState === CallingState.RINGING && reject !== false) {
|
|
13012
13021
|
if (reject) {
|
|
13013
|
-
|
|
13022
|
+
const reasonToEndCallReason = {
|
|
13023
|
+
timeout: 'missed',
|
|
13024
|
+
cancel: 'canceled',
|
|
13025
|
+
busy: 'busy',
|
|
13026
|
+
decline: 'rejected',
|
|
13027
|
+
};
|
|
13028
|
+
const rejectReason = reason ?? 'decline';
|
|
13029
|
+
const endCallReason = reasonToEndCallReason[rejectReason] ?? 'rejected';
|
|
13030
|
+
globalThis.streamRNVideoSDK?.callingX?.endCall(this, endCallReason);
|
|
13031
|
+
await this.reject(rejectReason);
|
|
13014
13032
|
}
|
|
13015
13033
|
else {
|
|
13016
13034
|
// if reject was undefined, we still have to cancel the call automatically
|
|
13017
13035
|
// when I am the creator and everyone else left the call
|
|
13018
13036
|
const hasOtherParticipants = this.state.remoteParticipants.length > 0;
|
|
13019
13037
|
if (this.isCreatedByMe && !hasOtherParticipants) {
|
|
13038
|
+
globalThis.streamRNVideoSDK?.callingX?.endCall(this, 'canceled');
|
|
13020
13039
|
await this.reject('cancel');
|
|
13021
13040
|
}
|
|
13022
13041
|
}
|
|
13023
13042
|
}
|
|
13043
|
+
globalThis.streamRNVideoSDK?.callingX?.endCall(this);
|
|
13024
13044
|
this.statsReporter?.stop();
|
|
13025
13045
|
this.statsReporter = undefined;
|
|
13026
13046
|
const leaveReason = message ?? reason ?? 'user is leaving the call';
|
|
@@ -13047,7 +13067,9 @@ class Call {
|
|
|
13047
13067
|
this.ringingSubject.next(false);
|
|
13048
13068
|
this.cancelAutoDrop();
|
|
13049
13069
|
this.clientStore.unregisterCall(this);
|
|
13050
|
-
globalThis.streamRNVideoSDK?.callManager.stop(
|
|
13070
|
+
globalThis.streamRNVideoSDK?.callManager.stop({
|
|
13071
|
+
isRingingTypeCall: this.ringing,
|
|
13072
|
+
});
|
|
13051
13073
|
this.camera.dispose();
|
|
13052
13074
|
this.microphone.dispose();
|
|
13053
13075
|
this.screenShare.dispose();
|
|
@@ -13213,11 +13235,19 @@ class Call {
|
|
|
13213
13235
|
* @returns a promise which resolves once the call join-flow has finished.
|
|
13214
13236
|
*/
|
|
13215
13237
|
this.join = async ({ maxJoinRetries = 3, joinResponseTimeout, rpcRequestTimeout, ...data } = {}) => {
|
|
13216
|
-
await this.setup();
|
|
13217
13238
|
const callingState = this.state.callingState;
|
|
13218
13239
|
if ([CallingState.JOINED, CallingState.JOINING].includes(callingState)) {
|
|
13219
13240
|
throw new Error(`Illegal State: call.join() shall be called only once`);
|
|
13220
13241
|
}
|
|
13242
|
+
if (data?.ring) {
|
|
13243
|
+
this.ringingSubject.next(true);
|
|
13244
|
+
}
|
|
13245
|
+
const callingX = globalThis.streamRNVideoSDK?.callingX;
|
|
13246
|
+
if (callingX) {
|
|
13247
|
+
// for Android/iOS, we need to start the call in the callingx library as soon as possible
|
|
13248
|
+
await callingX.joinCall(this, this.clientStore.calls);
|
|
13249
|
+
}
|
|
13250
|
+
await this.setup();
|
|
13221
13251
|
this.joinResponseTimeout = joinResponseTimeout;
|
|
13222
13252
|
this.rpcRequestTimeout = rpcRequestTimeout;
|
|
13223
13253
|
// we will count the number of join failures per SFU.
|
|
@@ -13226,38 +13256,44 @@ class Call {
|
|
|
13226
13256
|
const sfuJoinFailures = new Map();
|
|
13227
13257
|
const joinData = data;
|
|
13228
13258
|
maxJoinRetries = Math.max(maxJoinRetries, 1);
|
|
13229
|
-
|
|
13230
|
-
|
|
13231
|
-
|
|
13232
|
-
|
|
13233
|
-
|
|
13234
|
-
|
|
13235
|
-
|
|
13236
|
-
|
|
13237
|
-
catch (err) {
|
|
13238
|
-
this.logger.warn(`Failed to join call (${attempt})`, this.cid);
|
|
13239
|
-
if ((err instanceof ErrorFromResponse && err.unrecoverable) ||
|
|
13240
|
-
(err instanceof SfuJoinError && err.unrecoverable)) {
|
|
13241
|
-
// if the error is unrecoverable, we should not retry as that signals
|
|
13242
|
-
// that connectivity is good, but the coordinator doesn't allow the user
|
|
13243
|
-
// to join the call due to some reason (e.g., ended call, expired token...)
|
|
13244
|
-
throw err;
|
|
13245
|
-
}
|
|
13246
|
-
// immediately switch to a different SFU in case of recoverable join error
|
|
13247
|
-
const switchSfu = err instanceof SfuJoinError &&
|
|
13248
|
-
SfuJoinError.isJoinErrorCode(err.errorEvent);
|
|
13249
|
-
const sfuId = this.credentials?.server.edge_name || '';
|
|
13250
|
-
const failures = (sfuJoinFailures.get(sfuId) || 0) + 1;
|
|
13251
|
-
sfuJoinFailures.set(sfuId, failures);
|
|
13252
|
-
if (switchSfu || failures >= 2) {
|
|
13253
|
-
joinData.migrating_from = sfuId;
|
|
13254
|
-
joinData.migrating_from_list = Array.from(sfuJoinFailures.keys());
|
|
13259
|
+
try {
|
|
13260
|
+
for (let attempt = 0; attempt < maxJoinRetries; attempt++) {
|
|
13261
|
+
try {
|
|
13262
|
+
this.logger.trace(`Joining call (${attempt})`, this.cid);
|
|
13263
|
+
await this.doJoin(data);
|
|
13264
|
+
delete joinData.migrating_from;
|
|
13265
|
+
delete joinData.migrating_from_list;
|
|
13266
|
+
break;
|
|
13255
13267
|
}
|
|
13256
|
-
|
|
13257
|
-
|
|
13268
|
+
catch (err) {
|
|
13269
|
+
this.logger.warn(`Failed to join call (${attempt})`, this.cid);
|
|
13270
|
+
if ((err instanceof ErrorFromResponse && err.unrecoverable) ||
|
|
13271
|
+
(err instanceof SfuJoinError && err.unrecoverable)) {
|
|
13272
|
+
// if the error is unrecoverable, we should not retry as that signals
|
|
13273
|
+
// that connectivity is good, but the coordinator doesn't allow the user
|
|
13274
|
+
// to join the call due to some reason (e.g., ended call, expired token...)
|
|
13275
|
+
throw err;
|
|
13276
|
+
}
|
|
13277
|
+
// immediately switch to a different SFU in case of recoverable join error
|
|
13278
|
+
const switchSfu = err instanceof SfuJoinError &&
|
|
13279
|
+
SfuJoinError.isJoinErrorCode(err.errorEvent);
|
|
13280
|
+
const sfuId = this.credentials?.server.edge_name || '';
|
|
13281
|
+
const failures = (sfuJoinFailures.get(sfuId) || 0) + 1;
|
|
13282
|
+
sfuJoinFailures.set(sfuId, failures);
|
|
13283
|
+
if (switchSfu || failures >= 2) {
|
|
13284
|
+
joinData.migrating_from = sfuId;
|
|
13285
|
+
joinData.migrating_from_list = Array.from(sfuJoinFailures.keys());
|
|
13286
|
+
}
|
|
13287
|
+
if (attempt === maxJoinRetries - 1) {
|
|
13288
|
+
throw err;
|
|
13289
|
+
}
|
|
13258
13290
|
}
|
|
13291
|
+
await sleep(retryInterval(attempt));
|
|
13259
13292
|
}
|
|
13260
|
-
|
|
13293
|
+
}
|
|
13294
|
+
catch (error) {
|
|
13295
|
+
callingX?.endCall(this, 'error');
|
|
13296
|
+
throw error;
|
|
13261
13297
|
}
|
|
13262
13298
|
};
|
|
13263
13299
|
/**
|
|
@@ -13404,7 +13440,9 @@ class Call {
|
|
|
13404
13440
|
// re-apply them on later reconnections or server-side data fetches
|
|
13405
13441
|
if (!this.deviceSettingsAppliedOnce && this.state.settings) {
|
|
13406
13442
|
await this.applyDeviceConfig(this.state.settings, true, false);
|
|
13407
|
-
globalThis.streamRNVideoSDK?.callManager.start(
|
|
13443
|
+
globalThis.streamRNVideoSDK?.callManager.start({
|
|
13444
|
+
isRingingTypeCall: this.ringing,
|
|
13445
|
+
});
|
|
13408
13446
|
this.deviceSettingsAppliedOnce = true;
|
|
13409
13447
|
}
|
|
13410
13448
|
// We shouldn't persist the `ring` and `notify` state after joining the call
|
|
@@ -13832,6 +13870,7 @@ class Call {
|
|
|
13832
13870
|
if (strategy === WebsocketReconnectStrategy.UNSPECIFIED)
|
|
13833
13871
|
return;
|
|
13834
13872
|
if (strategy === WebsocketReconnectStrategy.DISCONNECT) {
|
|
13873
|
+
globalThis.streamRNVideoSDK?.callingX?.endCall(this, 'error');
|
|
13835
13874
|
this.leave({ message: 'SFU instructed to disconnect' }).catch((err) => {
|
|
13836
13875
|
this.logger.warn(`Can't leave call after disconnect request`, err);
|
|
13837
13876
|
});
|
|
@@ -14853,7 +14892,7 @@ class Call {
|
|
|
14853
14892
|
* A flag indicating whether the call was created by the current user.
|
|
14854
14893
|
*/
|
|
14855
14894
|
get isCreatedByMe() {
|
|
14856
|
-
return this.state.createdBy?.id === this.currentUserId;
|
|
14895
|
+
return (this.currentUserId && this.state.createdBy?.id === this.currentUserId);
|
|
14857
14896
|
}
|
|
14858
14897
|
}
|
|
14859
14898
|
|
|
@@ -15979,7 +16018,7 @@ class StreamClient {
|
|
|
15979
16018
|
this.getUserAgent = () => {
|
|
15980
16019
|
if (!this.cachedUserAgent) {
|
|
15981
16020
|
const { clientAppIdentifier = {} } = this.options;
|
|
15982
|
-
const { sdkName = 'js', sdkVersion = "1.44.
|
|
16021
|
+
const { sdkName = 'js', sdkVersion = "1.44.6-beta.0", ...extras } = clientAppIdentifier;
|
|
15983
16022
|
this.cachedUserAgent = [
|
|
15984
16023
|
`stream-video-${sdkName}-v${sdkVersion}`,
|
|
15985
16024
|
...Object.entries(extras).map(([key, value]) => `${key}=${value}`),
|