@stream-io/video-client 1.53.1 → 1.54.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 +17 -0
- package/dist/index.browser.es.js +41 -9
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +41 -9
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +41 -9
- package/dist/index.es.js.map +1 -1
- package/dist/src/coordinator/connection/types.d.ts +6 -0
- package/dist/src/reporting/ClientEventReporter.d.ts +2 -0
- package/package.json +1 -1
- package/src/Call.ts +40 -5
- package/src/StreamVideoClient.ts +1 -0
- package/src/coordinator/connection/types.ts +7 -0
- package/src/reporting/ClientEventReporter.ts +6 -2
- package/src/reporting/__tests__/ClientEventReporter.test.ts +33 -0
- package/src/rtc/__tests__/Call.reconnect.test.ts +149 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
## [1.54.0](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.53.2...@stream-io/video-client-1.54.0) (2026-06-19)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
- **client:** allow disabling client event reporter ([#2286](https://github.com/GetStream/stream-video-js/issues/2286)) ([d727916](https://github.com/GetStream/stream-video-js/commit/d72791614c98ca3bedafe0538e0ac68050260ead))
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
- **client:** avoid SFU socket close when online fires without offline recovery ([#2292](https://github.com/GetStream/stream-video-js/issues/2292)) ([3034188](https://github.com/GetStream/stream-video-js/commit/30341888eddbe878e97d39bb2f11c5b4455755d6))
|
|
14
|
+
- **client:** send migrating_from after repeated rejoin failures ([#2287](https://github.com/GetStream/stream-video-js/issues/2287)) ([1c14617](https://github.com/GetStream/stream-video-js/commit/1c14617ce8cccbb97cc68e8ba75225f49607ccbe))
|
|
15
|
+
|
|
16
|
+
## [1.53.2](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.53.1...@stream-io/video-client-1.53.2) (2026-06-12)
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
- **client:** keep user_id populated in call event telemetry when a disconnect races an in-flight join ([#2284](https://github.com/GetStream/stream-video-js/issues/2284)) ([4403348](https://github.com/GetStream/stream-video-js/commit/4403348115500499cd60919a417d97659546bb8b))
|
|
21
|
+
|
|
5
22
|
## [1.53.1](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.53.0...@stream-io/video-client-1.53.1) (2026-06-12)
|
|
6
23
|
|
|
7
24
|
### Bug Fixes
|
package/dist/index.browser.es.js
CHANGED
|
@@ -6640,7 +6640,7 @@ const getSdkVersion = (sdk) => {
|
|
|
6640
6640
|
return sdk ? `${sdk.major}.${sdk.minor}.${sdk.patch}` : '0.0.0-development';
|
|
6641
6641
|
};
|
|
6642
6642
|
|
|
6643
|
-
const version = "1.
|
|
6643
|
+
const version = "1.54.0";
|
|
6644
6644
|
const [major, minor, patch] = version.split('.');
|
|
6645
6645
|
let sdkInfo = {
|
|
6646
6646
|
type: SdkType.PLAIN_JAVASCRIPT,
|
|
@@ -14554,7 +14554,7 @@ class Call {
|
|
|
14554
14554
|
]);
|
|
14555
14555
|
const isReconnecting = this.reconnectStrategy !== WebsocketReconnectStrategy.UNSPECIFIED;
|
|
14556
14556
|
const reconnectDetails = isReconnecting
|
|
14557
|
-
? this.getReconnectDetails(
|
|
14557
|
+
? this.getReconnectDetails(previousSfuClient?.edgeName, previousSessionId)
|
|
14558
14558
|
: undefined;
|
|
14559
14559
|
const preferredPublishOptions = !isReconnecting
|
|
14560
14560
|
? this.getPreferredPublishOptions()
|
|
@@ -14923,6 +14923,7 @@ class Call {
|
|
|
14923
14923
|
const reconnectStartTime = Date.now();
|
|
14924
14924
|
this.reconnectStrategy = strategy;
|
|
14925
14925
|
this.reconnectReason = reason;
|
|
14926
|
+
const sfuRejoinFailures = new Map();
|
|
14926
14927
|
const markAsReconnectingFailed = async () => {
|
|
14927
14928
|
try {
|
|
14928
14929
|
// attempt to fetch the call data from the server, as the call
|
|
@@ -14981,7 +14982,8 @@ class Call {
|
|
|
14981
14982
|
if (this.reconnectStrategy !== WebsocketReconnectStrategy.FAST) {
|
|
14982
14983
|
this.reconnectAttempts++;
|
|
14983
14984
|
}
|
|
14984
|
-
const
|
|
14985
|
+
const attemptedStrategy = this.reconnectStrategy;
|
|
14986
|
+
const currentStrategy = WebsocketReconnectStrategy[attemptedStrategy];
|
|
14985
14987
|
try {
|
|
14986
14988
|
// wait until the network is available
|
|
14987
14989
|
await this.networkAvailableTask?.promise;
|
|
@@ -14994,9 +14996,24 @@ class Call {
|
|
|
14994
14996
|
case WebsocketReconnectStrategy.FAST:
|
|
14995
14997
|
await this.reconnectFast();
|
|
14996
14998
|
break;
|
|
14997
|
-
case WebsocketReconnectStrategy.REJOIN:
|
|
14998
|
-
|
|
14999
|
+
case WebsocketReconnectStrategy.REJOIN: {
|
|
15000
|
+
const confirmedBadSfus = Array.from(sfuRejoinFailures)
|
|
15001
|
+
.filter(([, failures]) => failures >= 2)
|
|
15002
|
+
.map(([sfu]) => sfu);
|
|
15003
|
+
if (this.joinCallData && confirmedBadSfus.length) {
|
|
15004
|
+
this.joinCallData.migrating_from =
|
|
15005
|
+
confirmedBadSfus[confirmedBadSfus.length - 1];
|
|
15006
|
+
this.joinCallData.migrating_from_list = confirmedBadSfus;
|
|
15007
|
+
}
|
|
15008
|
+
try {
|
|
15009
|
+
await this.reconnectRejoin();
|
|
15010
|
+
}
|
|
15011
|
+
finally {
|
|
15012
|
+
delete this.joinCallData?.migrating_from;
|
|
15013
|
+
delete this.joinCallData?.migrating_from_list;
|
|
15014
|
+
}
|
|
14999
15015
|
break;
|
|
15016
|
+
}
|
|
15000
15017
|
case WebsocketReconnectStrategy.MIGRATE:
|
|
15001
15018
|
await this.reconnectMigrate();
|
|
15002
15019
|
break;
|
|
@@ -15009,6 +15026,15 @@ class Call {
|
|
|
15009
15026
|
break; // do-while loop, reconnection worked, exit the loop
|
|
15010
15027
|
}
|
|
15011
15028
|
catch (error) {
|
|
15029
|
+
if (attemptedStrategy === WebsocketReconnectStrategy.REJOIN) {
|
|
15030
|
+
const failedSfu = this.credentials?.server.edge_name;
|
|
15031
|
+
if (failedSfu) {
|
|
15032
|
+
const switchSfu = error instanceof SfuJoinError &&
|
|
15033
|
+
SfuJoinError.isJoinErrorCode(error.errorEvent);
|
|
15034
|
+
const failures = (sfuRejoinFailures.get(failedSfu) ?? 0) + 1;
|
|
15035
|
+
sfuRejoinFailures.set(failedSfu, switchSfu ? Math.max(failures, 2) : failures);
|
|
15036
|
+
}
|
|
15037
|
+
}
|
|
15012
15038
|
if (this.state.callingState === CallingState.OFFLINE) {
|
|
15013
15039
|
this.logger.debug(`[Reconnect] Can't reconnect while offline, stopping reconnection attempts`);
|
|
15014
15040
|
break;
|
|
@@ -15204,6 +15230,8 @@ class Call {
|
|
|
15204
15230
|
this.state.setCallingState(CallingState.OFFLINE);
|
|
15205
15231
|
}
|
|
15206
15232
|
else {
|
|
15233
|
+
if (!this.networkAvailableTask)
|
|
15234
|
+
return;
|
|
15207
15235
|
this.logger.debug('[Reconnect] Going online');
|
|
15208
15236
|
this.sfuClient?.close(StreamSfuClient.DISPOSE_OLD_SOCKET, 'Closing WS to reconnect after going online');
|
|
15209
15237
|
// we went online, release the previous waiters and reset the state
|
|
@@ -17464,11 +17492,11 @@ class StreamClient {
|
|
|
17464
17492
|
return await this.wsConnection.connect(this.defaultWSTimeout);
|
|
17465
17493
|
};
|
|
17466
17494
|
this.getSdkVersion = () => this.options.clientAppIdentifier?.sdkVersion ||
|
|
17467
|
-
"1.
|
|
17495
|
+
"1.54.0";
|
|
17468
17496
|
this.getUserAgent = () => {
|
|
17469
17497
|
if (!this.cachedUserAgent) {
|
|
17470
17498
|
const { clientAppIdentifier = {} } = this.options;
|
|
17471
|
-
const { sdkName = 'js', sdkVersion = "1.
|
|
17499
|
+
const { sdkName = 'js', sdkVersion = "1.54.0", ...extras } = clientAppIdentifier;
|
|
17472
17500
|
this.cachedUserAgent = [
|
|
17473
17501
|
`stream-video-${sdkName}-v${sdkVersion}`,
|
|
17474
17502
|
...Object.entries(extras).map(([key, value]) => `${key}=${value}`),
|
|
@@ -17875,7 +17903,7 @@ class ClientEventReporter {
|
|
|
17875
17903
|
const coordinatorConnectId = this.coordinatorConnectId;
|
|
17876
17904
|
const ctx = this.callContexts.get(cid);
|
|
17877
17905
|
this.send({
|
|
17878
|
-
user_id: this.streamClient.userID,
|
|
17906
|
+
user_id: this.streamClient.userID || this.coordinatorConnectUserId,
|
|
17879
17907
|
type: ctx?.callType,
|
|
17880
17908
|
id: ctx?.callId,
|
|
17881
17909
|
call_cid: cid,
|
|
@@ -18128,7 +18156,7 @@ class ClientEventReporter {
|
|
|
18128
18156
|
const ctx = this.callContexts.get(cid);
|
|
18129
18157
|
const coordinatorConnectId = this.coordinatorConnectId;
|
|
18130
18158
|
return {
|
|
18131
|
-
user_id: this.streamClient.userID,
|
|
18159
|
+
user_id: this.streamClient.userID || this.coordinatorConnectUserId,
|
|
18132
18160
|
type: ctx?.callType ?? '',
|
|
18133
18161
|
id: ctx?.callId ?? '',
|
|
18134
18162
|
call_cid: cid,
|
|
@@ -18146,6 +18174,8 @@ class ClientEventReporter {
|
|
|
18146
18174
|
};
|
|
18147
18175
|
};
|
|
18148
18176
|
this.send = (body) => {
|
|
18177
|
+
if (!this.enabled)
|
|
18178
|
+
return;
|
|
18149
18179
|
void this.sendWithRetry(body);
|
|
18150
18180
|
};
|
|
18151
18181
|
this.sendWithRetry = async (body) => {
|
|
@@ -18171,6 +18201,7 @@ class ClientEventReporter {
|
|
|
18171
18201
|
return false;
|
|
18172
18202
|
};
|
|
18173
18203
|
this.streamClient = options.streamClient;
|
|
18204
|
+
this.enabled = options.enabled ?? true;
|
|
18174
18205
|
}
|
|
18175
18206
|
}
|
|
18176
18207
|
const readPermissionStatus = (permission) => {
|
|
@@ -18651,6 +18682,7 @@ class StreamVideoClient {
|
|
|
18651
18682
|
this.streamClient = createCoordinatorClient(apiKey, clientOptions);
|
|
18652
18683
|
this.clientEventReporter = new ClientEventReporter({
|
|
18653
18684
|
streamClient: this.streamClient,
|
|
18685
|
+
enabled: clientOptions?.clientEventsReportingEnabled ?? true,
|
|
18654
18686
|
});
|
|
18655
18687
|
this.writeableStateStore = new StreamVideoWriteableStateStore();
|
|
18656
18688
|
this.readOnlyStateStore = new StreamVideoReadOnlyStateStore(this.writeableStateStore);
|