@stream-io/video-client 1.53.2 → 1.54.1-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/CHANGELOG.md +11 -0
- package/dist/index.browser.es.js +111 -12
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +111 -12
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +111 -12
- package/dist/index.es.js.map +1 -1
- package/dist/src/Call.d.ts +13 -1
- package/dist/src/coordinator/connection/types.d.ts +6 -0
- package/dist/src/gen/google/protobuf/struct.d.ts +3 -1
- package/dist/src/gen/google/protobuf/timestamp.d.ts +3 -1
- package/dist/src/gen/video/sfu/event/events.d.ts +22 -1
- package/dist/src/gen/video/sfu/models/models.d.ts +4 -0
- package/dist/src/gen/video/sfu/signal_rpc/signal.client.d.ts +23 -2
- package/dist/src/reporting/ClientEventReporter.d.ts +2 -0
- package/dist/src/rtc/Publisher.d.ts +4 -1
- package/dist/src/rtc/Subscriber.d.ts +7 -0
- package/package.json +1 -1
- package/src/Call.ts +86 -6
- package/src/StreamVideoClient.ts +1 -0
- package/src/coordinator/connection/types.ts +7 -0
- package/src/gen/google/protobuf/struct.ts +7 -12
- package/src/gen/google/protobuf/timestamp.ts +6 -7
- package/src/gen/video/sfu/event/events.ts +23 -25
- package/src/gen/video/sfu/models/models.ts +11 -1
- package/src/gen/video/sfu/signal_rpc/signal.client.ts +25 -29
- package/src/gen/video/sfu/signal_rpc/signal.ts +1 -0
- package/src/helpers/client-details.ts +1 -1
- package/src/reporting/ClientEventReporter.ts +4 -0
- package/src/reporting/__tests__/ClientEventReporter.test.ts +33 -0
- package/src/rtc/Publisher.ts +4 -0
- package/src/rtc/Subscriber.ts +28 -1
- package/src/rtc/__tests__/Call.reconnect.test.ts +149 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
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
|
+
|
|
5
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)
|
|
6
17
|
|
|
7
18
|
### Bug Fixes
|
package/dist/index.browser.es.js
CHANGED
|
@@ -507,6 +507,7 @@ class ErrorFromResponse extends Error {
|
|
|
507
507
|
}
|
|
508
508
|
}
|
|
509
509
|
|
|
510
|
+
/* eslint-disable */
|
|
510
511
|
// @generated by protobuf-ts 2.10.0 with parameter long_type_string,client_generic,server_none,eslint_disable,optimize_code_size
|
|
511
512
|
// @generated from protobuf file "google/protobuf/struct.proto" (package "google.protobuf", syntax proto3)
|
|
512
513
|
// tslint:disable
|
|
@@ -772,6 +773,7 @@ class ListValue$Type extends MessageType {
|
|
|
772
773
|
*/
|
|
773
774
|
const ListValue = new ListValue$Type();
|
|
774
775
|
|
|
776
|
+
/* eslint-disable */
|
|
775
777
|
// @generated by protobuf-ts 2.10.0 with parameter long_type_string,client_generic,server_none,eslint_disable,optimize_code_size
|
|
776
778
|
// @generated from protobuf file "google/protobuf/timestamp.proto" (package "google.protobuf", syntax proto3)
|
|
777
779
|
// tslint:disable
|
|
@@ -1838,6 +1840,12 @@ class TrackInfo$Type extends MessageType {
|
|
|
1838
1840
|
kind: 'scalar',
|
|
1839
1841
|
T: 5 /*ScalarType.INT32*/,
|
|
1840
1842
|
},
|
|
1843
|
+
{
|
|
1844
|
+
no: 13,
|
|
1845
|
+
name: 'self_sub_audio_video',
|
|
1846
|
+
kind: 'scalar',
|
|
1847
|
+
T: 8 /*ScalarType.BOOL*/,
|
|
1848
|
+
},
|
|
1841
1849
|
]);
|
|
1842
1850
|
}
|
|
1843
1851
|
}
|
|
@@ -6640,7 +6648,7 @@ const getSdkVersion = (sdk) => {
|
|
|
6640
6648
|
return sdk ? `${sdk.major}.${sdk.minor}.${sdk.patch}` : '0.0.0-development';
|
|
6641
6649
|
};
|
|
6642
6650
|
|
|
6643
|
-
const version = "1.
|
|
6651
|
+
const version = "1.54.1-beta.0";
|
|
6644
6652
|
const [major, minor, patch] = version.split('.');
|
|
6645
6653
|
let sdkInfo = {
|
|
6646
6654
|
type: SdkType.PLAIN_JAVASCRIPT,
|
|
@@ -6784,7 +6792,7 @@ const getClientDetails = async () => {
|
|
|
6784
6792
|
.join(' '),
|
|
6785
6793
|
version: '',
|
|
6786
6794
|
},
|
|
6787
|
-
webrtcVersion:
|
|
6795
|
+
webrtcVersion: webRtcInfo?.version || '',
|
|
6788
6796
|
};
|
|
6789
6797
|
};
|
|
6790
6798
|
|
|
@@ -8428,7 +8436,7 @@ class Publisher extends BasePeerConnection {
|
|
|
8428
8436
|
/**
|
|
8429
8437
|
* Constructs a new `Publisher` instance.
|
|
8430
8438
|
*/
|
|
8431
|
-
constructor(baseOptions, publishOptions) {
|
|
8439
|
+
constructor(baseOptions, publishOptions, opts = {}) {
|
|
8432
8440
|
super(PeerType.PUBLISHER_UNSPECIFIED, baseOptions);
|
|
8433
8441
|
this.transceiverCache = new TransceiverCache();
|
|
8434
8442
|
this.clonedTracks = new Set();
|
|
@@ -8849,6 +8857,7 @@ class Publisher extends BasePeerConnection {
|
|
|
8849
8857
|
muted: !isTrackLive,
|
|
8850
8858
|
codec: publishOption.codec,
|
|
8851
8859
|
publishOptionId: publishOption.id,
|
|
8860
|
+
selfSubAudioVideo: this.selfSubEnabled,
|
|
8852
8861
|
};
|
|
8853
8862
|
};
|
|
8854
8863
|
this.cloneTrack = (track) => {
|
|
@@ -8929,6 +8938,7 @@ class Publisher extends BasePeerConnection {
|
|
|
8929
8938
|
});
|
|
8930
8939
|
};
|
|
8931
8940
|
this.publishOptions = publishOptions;
|
|
8941
|
+
this.selfSubEnabled = opts.selfSubEnabled ?? false;
|
|
8932
8942
|
this.on('iceRestart', (iceRestart) => {
|
|
8933
8943
|
if (iceRestart.peerType !== PeerType.PUBLISHER_UNSPECIFIED)
|
|
8934
8944
|
return;
|
|
@@ -9010,6 +9020,13 @@ class Subscriber extends BasePeerConnection {
|
|
|
9010
9020
|
*/
|
|
9011
9021
|
constructor(opts) {
|
|
9012
9022
|
super(PeerType.SUBSCRIBER, opts);
|
|
9023
|
+
/**
|
|
9024
|
+
* Remote streams received from the SFU. For a self-sub case
|
|
9025
|
+
* we need to be able to distinguish between the local capture stream.
|
|
9026
|
+
* The map will never contain local streams so we can safely use it to
|
|
9027
|
+
* check if the stream is remote and dispose it when needed.
|
|
9028
|
+
*/
|
|
9029
|
+
this.trackedStreams = new WeakSet();
|
|
9013
9030
|
/**
|
|
9014
9031
|
* Restarts the ICE connection and renegotiates with the SFU.
|
|
9015
9032
|
*/
|
|
@@ -9044,6 +9061,7 @@ class Subscriber extends BasePeerConnection {
|
|
|
9044
9061
|
// example: `e3f6aaf8-b03d-4911-be36-83f47d37a76a:TRACK_TYPE_VIDEO`
|
|
9045
9062
|
const [trackId, rawTrackType] = primaryStream.id.split(':');
|
|
9046
9063
|
const participantToUpdate = this.state.participants.find((p) => p.trackLookupPrefix === trackId);
|
|
9064
|
+
const isSelfSub = !!participantToUpdate?.isLocalParticipant;
|
|
9047
9065
|
this.logger.debug(`[onTrack]: Got remote ${rawTrackType} track for userId: ${participantToUpdate?.userId}`, track.id, track);
|
|
9048
9066
|
const trackType = toTrackType(rawTrackType);
|
|
9049
9067
|
if (!trackType) {
|
|
@@ -9068,6 +9086,9 @@ class Subscriber extends BasePeerConnection {
|
|
|
9068
9086
|
this.setRemoteTrackInterrupted(trackId, trackType, true);
|
|
9069
9087
|
}
|
|
9070
9088
|
this.trackIdToTrackType.set(track.id, trackType);
|
|
9089
|
+
if (isSelfSub) {
|
|
9090
|
+
this.trackedStreams.add(primaryStream);
|
|
9091
|
+
}
|
|
9071
9092
|
if (!participantToUpdate) {
|
|
9072
9093
|
this.logger.warn(`[onTrack]: Received track for unknown participant: ${trackId}`, e);
|
|
9073
9094
|
this.state.registerOrphanedTrack({
|
|
@@ -9083,6 +9104,12 @@ class Subscriber extends BasePeerConnection {
|
|
|
9083
9104
|
this.logger.error(`Unknown track type: ${rawTrackType}`);
|
|
9084
9105
|
return;
|
|
9085
9106
|
}
|
|
9107
|
+
// Self-sub loopback audio routes to the speaker by default, which
|
|
9108
|
+
// would echo the local user's voice. Default-mute here; consumers
|
|
9109
|
+
// (the loopback recording hook) re-enable explicitly when needed.
|
|
9110
|
+
if (isSelfSub && e.track.kind === 'audio') {
|
|
9111
|
+
e.track.enabled = false;
|
|
9112
|
+
}
|
|
9086
9113
|
// get the previous stream to dispose it later
|
|
9087
9114
|
// usually this happens during migration, when the stream is replaced
|
|
9088
9115
|
// with a new one but the old one is still in the state
|
|
@@ -9091,8 +9118,12 @@ class Subscriber extends BasePeerConnection {
|
|
|
9091
9118
|
this.state.updateParticipant(participantToUpdate.sessionId, {
|
|
9092
9119
|
[streamKindProp]: primaryStream,
|
|
9093
9120
|
});
|
|
9094
|
-
// now, dispose the previous stream if it exists
|
|
9095
9121
|
if (previousStream) {
|
|
9122
|
+
if (isSelfSub && !this.trackedStreams.has(previousStream)) {
|
|
9123
|
+
// this is the local capture stream, we don't want to dispose it
|
|
9124
|
+
this.logger.debug(`[onTrack]: Skipping cleanup of previous ${e.track.kind} stream for userId: ${participantToUpdate.userId} because it is not tracked`);
|
|
9125
|
+
return;
|
|
9126
|
+
}
|
|
9096
9127
|
this.logger.info(`[onTrack]: Cleaning up previous remote ${track.kind} tracks for userId: ${participantToUpdate.userId}`);
|
|
9097
9128
|
previousStream.getTracks().forEach((t) => {
|
|
9098
9129
|
t.stop();
|
|
@@ -13915,6 +13946,7 @@ class Call {
|
|
|
13915
13946
|
// maintain the order of publishing tracks to restore them after a reconnection
|
|
13916
13947
|
// it shouldn't contain duplicates
|
|
13917
13948
|
this.trackPublishOrder = [];
|
|
13949
|
+
this.selfSubEnabled = false;
|
|
13918
13950
|
this.hasJoinedOnce = false;
|
|
13919
13951
|
this.deviceSettingsAppliedOnce = false;
|
|
13920
13952
|
this.initialized = false;
|
|
@@ -14264,6 +14296,30 @@ class Call {
|
|
|
14264
14296
|
await Promise.all(stopOnLeavePromises);
|
|
14265
14297
|
});
|
|
14266
14298
|
};
|
|
14299
|
+
/**
|
|
14300
|
+
* The largest video publish dimension across the current publish options.
|
|
14301
|
+
*
|
|
14302
|
+
* @internal
|
|
14303
|
+
*/
|
|
14304
|
+
this.getMaxVideoPublishDimension = () => {
|
|
14305
|
+
if (!this.currentPublishOptions)
|
|
14306
|
+
return undefined;
|
|
14307
|
+
let maxDimension;
|
|
14308
|
+
let maxArea = 0;
|
|
14309
|
+
for (const opt of this.currentPublishOptions) {
|
|
14310
|
+
if (opt.trackType !== TrackType.VIDEO)
|
|
14311
|
+
continue;
|
|
14312
|
+
const dim = opt.videoDimension;
|
|
14313
|
+
if (!dim || !dim.width || !dim.height)
|
|
14314
|
+
continue;
|
|
14315
|
+
const area = dim.width * dim.height;
|
|
14316
|
+
if (area > maxArea) {
|
|
14317
|
+
maxDimension = dim;
|
|
14318
|
+
maxArea = area;
|
|
14319
|
+
}
|
|
14320
|
+
}
|
|
14321
|
+
return maxDimension;
|
|
14322
|
+
};
|
|
14267
14323
|
/**
|
|
14268
14324
|
* Update from the call response from the "call.ring" event
|
|
14269
14325
|
* @internal
|
|
@@ -14410,7 +14466,7 @@ class Call {
|
|
|
14410
14466
|
*
|
|
14411
14467
|
* @returns a promise which resolves once the call join-flow has finished.
|
|
14412
14468
|
*/
|
|
14413
|
-
this.join = async ({ maxJoinRetries = 3, joinResponseTimeout, rpcRequestTimeout, ...data } = {}) => {
|
|
14469
|
+
this.join = async ({ maxJoinRetries = 3, joinResponseTimeout, rpcRequestTimeout, selfSubEnabled = false, ...data } = {}) => {
|
|
14414
14470
|
const callingState = this.state.callingState;
|
|
14415
14471
|
if ([CallingState.JOINED, CallingState.JOINING].includes(callingState)) {
|
|
14416
14472
|
throw new Error(`Illegal State: call.join() shall be called only once`);
|
|
@@ -14418,6 +14474,9 @@ class Call {
|
|
|
14418
14474
|
if (data?.ring) {
|
|
14419
14475
|
this.ringingSubject.next(true);
|
|
14420
14476
|
}
|
|
14477
|
+
// we need this to be set before the callingx.joinCall() is
|
|
14478
|
+
// called to avoid registering the test call in the CallKit/Telecom
|
|
14479
|
+
this.selfSubEnabled = selfSubEnabled;
|
|
14421
14480
|
const callingX = globalThis.streamRNVideoSDK?.callingX;
|
|
14422
14481
|
if (callingX) {
|
|
14423
14482
|
// for Android/iOS, we need to start the call in the callingx library as soon as possible
|
|
@@ -14554,7 +14613,7 @@ class Call {
|
|
|
14554
14613
|
]);
|
|
14555
14614
|
const isReconnecting = this.reconnectStrategy !== WebsocketReconnectStrategy.UNSPECIFIED;
|
|
14556
14615
|
const reconnectDetails = isReconnecting
|
|
14557
|
-
? this.getReconnectDetails(
|
|
14616
|
+
? this.getReconnectDetails(previousSfuClient?.edgeName, previousSessionId)
|
|
14558
14617
|
: undefined;
|
|
14559
14618
|
const preferredPublishOptions = !isReconnecting
|
|
14560
14619
|
? this.getPreferredPublishOptions()
|
|
@@ -14807,7 +14866,9 @@ class Call {
|
|
|
14807
14866
|
if (closePreviousInstances && this.publisher) {
|
|
14808
14867
|
await this.publisher.dispose();
|
|
14809
14868
|
}
|
|
14810
|
-
this.publisher = new Publisher(basePeerConnectionOptions, publishOptions
|
|
14869
|
+
this.publisher = new Publisher(basePeerConnectionOptions, publishOptions, {
|
|
14870
|
+
selfSubEnabled: this.selfSubEnabled,
|
|
14871
|
+
});
|
|
14811
14872
|
}
|
|
14812
14873
|
this.statsReporter?.stop();
|
|
14813
14874
|
if (this.statsReportingIntervalInMs > 0) {
|
|
@@ -14923,6 +14984,7 @@ class Call {
|
|
|
14923
14984
|
const reconnectStartTime = Date.now();
|
|
14924
14985
|
this.reconnectStrategy = strategy;
|
|
14925
14986
|
this.reconnectReason = reason;
|
|
14987
|
+
const sfuRejoinFailures = new Map();
|
|
14926
14988
|
const markAsReconnectingFailed = async () => {
|
|
14927
14989
|
try {
|
|
14928
14990
|
// attempt to fetch the call data from the server, as the call
|
|
@@ -14981,7 +15043,8 @@ class Call {
|
|
|
14981
15043
|
if (this.reconnectStrategy !== WebsocketReconnectStrategy.FAST) {
|
|
14982
15044
|
this.reconnectAttempts++;
|
|
14983
15045
|
}
|
|
14984
|
-
const
|
|
15046
|
+
const attemptedStrategy = this.reconnectStrategy;
|
|
15047
|
+
const currentStrategy = WebsocketReconnectStrategy[attemptedStrategy];
|
|
14985
15048
|
try {
|
|
14986
15049
|
// wait until the network is available
|
|
14987
15050
|
await this.networkAvailableTask?.promise;
|
|
@@ -14994,9 +15057,24 @@ class Call {
|
|
|
14994
15057
|
case WebsocketReconnectStrategy.FAST:
|
|
14995
15058
|
await this.reconnectFast();
|
|
14996
15059
|
break;
|
|
14997
|
-
case WebsocketReconnectStrategy.REJOIN:
|
|
14998
|
-
|
|
15060
|
+
case WebsocketReconnectStrategy.REJOIN: {
|
|
15061
|
+
const confirmedBadSfus = Array.from(sfuRejoinFailures)
|
|
15062
|
+
.filter(([, failures]) => failures >= 2)
|
|
15063
|
+
.map(([sfu]) => sfu);
|
|
15064
|
+
if (this.joinCallData && confirmedBadSfus.length) {
|
|
15065
|
+
this.joinCallData.migrating_from =
|
|
15066
|
+
confirmedBadSfus[confirmedBadSfus.length - 1];
|
|
15067
|
+
this.joinCallData.migrating_from_list = confirmedBadSfus;
|
|
15068
|
+
}
|
|
15069
|
+
try {
|
|
15070
|
+
await this.reconnectRejoin();
|
|
15071
|
+
}
|
|
15072
|
+
finally {
|
|
15073
|
+
delete this.joinCallData?.migrating_from;
|
|
15074
|
+
delete this.joinCallData?.migrating_from_list;
|
|
15075
|
+
}
|
|
14999
15076
|
break;
|
|
15077
|
+
}
|
|
15000
15078
|
case WebsocketReconnectStrategy.MIGRATE:
|
|
15001
15079
|
await this.reconnectMigrate();
|
|
15002
15080
|
break;
|
|
@@ -15009,6 +15087,15 @@ class Call {
|
|
|
15009
15087
|
break; // do-while loop, reconnection worked, exit the loop
|
|
15010
15088
|
}
|
|
15011
15089
|
catch (error) {
|
|
15090
|
+
if (attemptedStrategy === WebsocketReconnectStrategy.REJOIN) {
|
|
15091
|
+
const failedSfu = this.credentials?.server.edge_name;
|
|
15092
|
+
if (failedSfu) {
|
|
15093
|
+
const switchSfu = error instanceof SfuJoinError &&
|
|
15094
|
+
SfuJoinError.isJoinErrorCode(error.errorEvent);
|
|
15095
|
+
const failures = (sfuRejoinFailures.get(failedSfu) ?? 0) + 1;
|
|
15096
|
+
sfuRejoinFailures.set(failedSfu, switchSfu ? Math.max(failures, 2) : failures);
|
|
15097
|
+
}
|
|
15098
|
+
}
|
|
15012
15099
|
if (this.state.callingState === CallingState.OFFLINE) {
|
|
15013
15100
|
this.logger.debug(`[Reconnect] Can't reconnect while offline, stopping reconnection attempts`);
|
|
15014
15101
|
break;
|
|
@@ -15204,6 +15291,8 @@ class Call {
|
|
|
15204
15291
|
this.state.setCallingState(CallingState.OFFLINE);
|
|
15205
15292
|
}
|
|
15206
15293
|
else {
|
|
15294
|
+
if (!this.networkAvailableTask)
|
|
15295
|
+
return;
|
|
15207
15296
|
this.logger.debug('[Reconnect] Going online');
|
|
15208
15297
|
this.sfuClient?.close(StreamSfuClient.DISPOSE_OLD_SOCKET, 'Closing WS to reconnect after going online');
|
|
15209
15298
|
// we went online, release the previous waiters and reset the state
|
|
@@ -16275,6 +16364,12 @@ class Call {
|
|
|
16275
16364
|
get currentUserId() {
|
|
16276
16365
|
return this.clientStore.connectedUser?.id;
|
|
16277
16366
|
}
|
|
16367
|
+
/**
|
|
16368
|
+
* A flag indicating whether self-subscription is enabled for the call.
|
|
16369
|
+
*/
|
|
16370
|
+
get isSelfSubEnabled() {
|
|
16371
|
+
return this.selfSubEnabled;
|
|
16372
|
+
}
|
|
16278
16373
|
/**
|
|
16279
16374
|
* A flag indicating whether the call was created by the current user.
|
|
16280
16375
|
*/
|
|
@@ -17464,11 +17559,11 @@ class StreamClient {
|
|
|
17464
17559
|
return await this.wsConnection.connect(this.defaultWSTimeout);
|
|
17465
17560
|
};
|
|
17466
17561
|
this.getSdkVersion = () => this.options.clientAppIdentifier?.sdkVersion ||
|
|
17467
|
-
"1.
|
|
17562
|
+
"1.54.1-beta.0";
|
|
17468
17563
|
this.getUserAgent = () => {
|
|
17469
17564
|
if (!this.cachedUserAgent) {
|
|
17470
17565
|
const { clientAppIdentifier = {} } = this.options;
|
|
17471
|
-
const { sdkName = 'js', sdkVersion = "1.
|
|
17566
|
+
const { sdkName = 'js', sdkVersion = "1.54.1-beta.0", ...extras } = clientAppIdentifier;
|
|
17472
17567
|
this.cachedUserAgent = [
|
|
17473
17568
|
`stream-video-${sdkName}-v${sdkVersion}`,
|
|
17474
17569
|
...Object.entries(extras).map(([key, value]) => `${key}=${value}`),
|
|
@@ -18146,6 +18241,8 @@ class ClientEventReporter {
|
|
|
18146
18241
|
};
|
|
18147
18242
|
};
|
|
18148
18243
|
this.send = (body) => {
|
|
18244
|
+
if (!this.enabled)
|
|
18245
|
+
return;
|
|
18149
18246
|
void this.sendWithRetry(body);
|
|
18150
18247
|
};
|
|
18151
18248
|
this.sendWithRetry = async (body) => {
|
|
@@ -18171,6 +18268,7 @@ class ClientEventReporter {
|
|
|
18171
18268
|
return false;
|
|
18172
18269
|
};
|
|
18173
18270
|
this.streamClient = options.streamClient;
|
|
18271
|
+
this.enabled = options.enabled ?? true;
|
|
18174
18272
|
}
|
|
18175
18273
|
}
|
|
18176
18274
|
const readPermissionStatus = (permission) => {
|
|
@@ -18651,6 +18749,7 @@ class StreamVideoClient {
|
|
|
18651
18749
|
this.streamClient = createCoordinatorClient(apiKey, clientOptions);
|
|
18652
18750
|
this.clientEventReporter = new ClientEventReporter({
|
|
18653
18751
|
streamClient: this.streamClient,
|
|
18752
|
+
enabled: clientOptions?.clientEventsReportingEnabled ?? true,
|
|
18654
18753
|
});
|
|
18655
18754
|
this.writeableStateStore = new StreamVideoWriteableStateStore();
|
|
18656
18755
|
this.readOnlyStateStore = new StreamVideoReadOnlyStateStore(this.writeableStateStore);
|