@stream-io/video-client 1.61.0 → 2.0.0-beta.1

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.
Files changed (52) hide show
  1. package/CHANGELOG.md +10 -10
  2. package/dist/index.browser.es.js +358 -611
  3. package/dist/index.browser.es.js.map +1 -1
  4. package/dist/index.cjs.js +357 -611
  5. package/dist/index.cjs.js.map +1 -1
  6. package/dist/index.es.js +358 -611
  7. package/dist/index.es.js.map +1 -1
  8. package/dist/src/Call.d.ts +3 -3
  9. package/dist/src/StreamVideoClient.d.ts +15 -21
  10. package/dist/src/store/CallState.d.ts +108 -266
  11. package/dist/src/store/ClientState.d.ts +62 -0
  12. package/dist/src/store/index.d.ts +1 -1
  13. package/dist/src/store/subjects.d.ts +15 -0
  14. package/dist/src/store/types.d.ts +22 -0
  15. package/dist/src/types.d.ts +3 -3
  16. package/package.json +2 -2
  17. package/src/Call.ts +14 -18
  18. package/src/StreamVideoClient.ts +40 -47
  19. package/src/__tests__/Call.autodrop.test.ts +4 -4
  20. package/src/__tests__/Call.getRingState.test.ts +2 -2
  21. package/src/__tests__/Call.lifecycle.test.ts +8 -8
  22. package/src/__tests__/Call.publishing.test.ts +2 -2
  23. package/src/__tests__/Call.ringSettled.test.ts +4 -4
  24. package/src/__tests__/Call.ringingLifecycle.test.ts +2 -2
  25. package/src/__tests__/StreamVideoClient.disconnect.test.ts +62 -0
  26. package/src/devices/__tests__/CameraManager.test.ts +2 -2
  27. package/src/devices/__tests__/DeviceManager.test.ts +2 -2
  28. package/src/devices/__tests__/DeviceManagerFilters.test.ts +2 -2
  29. package/src/devices/__tests__/MicrophoneManager.test.ts +2 -2
  30. package/src/devices/__tests__/MicrophoneManagerRN.test.ts +2 -2
  31. package/src/devices/__tests__/ScreenShareManager.test.ts +3 -3
  32. package/src/devices/__tests__/SpeakerManager.test.ts +4 -4
  33. package/src/events/__tests__/call.test.ts +3 -3
  34. package/src/helpers/__tests__/AudioBindingsWatchdog.test.ts +2 -2
  35. package/src/helpers/__tests__/DynascaleManager.test.ts +2 -2
  36. package/src/helpers/__tests__/ViewportTracker.test.ts +2 -2
  37. package/src/ringing/__tests__/RingStatePoller.test.ts +7 -7
  38. package/src/ringing/__tests__/RingTimeout.test.ts +4 -4
  39. package/src/ringing/__tests__/reconcileRingState.test.ts +3 -3
  40. package/src/rtc/__tests__/Call.reconnect.test.ts +5 -5
  41. package/src/store/CallState.ts +281 -551
  42. package/src/store/ClientState.ts +101 -0
  43. package/src/store/__tests__/CallState.test.ts +1 -1
  44. package/src/store/__tests__/ClientState.test.ts +35 -0
  45. package/src/store/__tests__/rxUtils.test.ts +67 -1
  46. package/src/store/index.ts +1 -1
  47. package/src/store/rxUtils.ts +8 -4
  48. package/src/store/subjects.ts +30 -0
  49. package/src/store/types.ts +45 -0
  50. package/src/types.ts +3 -3
  51. package/dist/src/store/stateStore.d.ts +0 -84
  52. package/src/store/stateStore.ts +0 -156
package/dist/index.cjs.js CHANGED
@@ -5101,7 +5101,7 @@ const toIceCandidate = (iceTrickle) => {
5101
5101
  }
5102
5102
  };
5103
5103
 
5104
- const version = "1.61.0";
5104
+ const version = "2.0.0-beta.1";
5105
5105
  const [major, minor, patch] = version.split('.');
5106
5106
  let sdkInfo = {
5107
5107
  type: SdkType.PLAIN_JAVASCRIPT,
@@ -5481,11 +5481,14 @@ const isFunctionPatch = (update) => typeof update === 'function';
5481
5481
  * @param observable$ the observable to get the value from.
5482
5482
  */
5483
5483
  const getCurrentValue = (observable$) => {
5484
+ if (observable$ instanceof rxjs.BehaviorSubject) {
5485
+ return observable$.getValue();
5486
+ }
5484
5487
  let value;
5485
5488
  let err = undefined;
5486
- rxjs.combineLatest([observable$])
5489
+ observable$
5487
5490
  .subscribe({
5488
- next: ([v]) => {
5491
+ next: (v) => {
5489
5492
  value = v;
5490
5493
  },
5491
5494
  error: (e) => {
@@ -5634,38 +5637,39 @@ exports.CallingState = void 0;
5634
5637
  CallingState["OFFLINE"] = "offline";
5635
5638
  })(exports.CallingState || (exports.CallingState = {}));
5636
5639
 
5637
- class StreamVideoWriteableStateStore {
5638
- /**
5639
- * A store keeping data of a successfully connected user over WS to the coordinator server.
5640
- */
5641
- connectedUserSubject = new rxjs.BehaviorSubject(undefined);
5642
- /**
5643
- * A list of {@link Call} objects created/tracked by this client.
5644
- */
5645
- callsSubject = new rxjs.BehaviorSubject([]);
5646
- constructor() {
5647
- this.connectedUserSubject.subscribe(async (user) => {
5648
- // leave all calls when the user disconnects.
5649
- if (!user) {
5650
- const logger = videoLoggerSystem.getLogger('client-state');
5651
- for (const call of this.calls) {
5652
- if (call.state.callingState === exports.CallingState.LEFT)
5653
- continue;
5654
- logger.info(`User disconnected, leaving call: ${call.cid}`);
5655
- await call
5656
- .leave({ message: 'client.disconnectUser() called' })
5657
- .catch((err) => {
5658
- logger.error(`Error leaving call: ${call.cid}`, err);
5659
- });
5660
- }
5661
- }
5662
- });
5663
- }
5664
- /**
5665
- * The currently connected user.
5666
- */
5640
+ function subject(initialValue) {
5641
+ return new rxjs.BehaviorSubject(initialValue);
5642
+ }
5643
+ /**
5644
+ * Creates an Observable from the given subject by piping it to the
5645
+ * `distinctUntilChanged()` operator.
5646
+ */
5647
+ const duc = (source, comparator) => source.pipe(rxjs.distinctUntilChanged(comparator));
5648
+ /**
5649
+ * Multicasts the given Observable, replaying the latest computed value to
5650
+ * every new subscriber instead of re-running the pipeline for each of them.
5651
+ */
5652
+ const shared = (source) => source.pipe(rxjs.shareReplay({ bufferSize: 1, refCount: true }));
5653
+
5654
+ /**
5655
+ * Holds the state of the client, and the calls it created or tracks.
5656
+ * You can subscribe to the exposed observables to get notified about changes.
5657
+ */
5658
+ class ClientState {
5659
+ logger = videoLoggerSystem.getLogger('ClientState');
5660
+ connectedUserSubject = subject();
5661
+ callsSubject = subject([]);
5662
+ /** Data describing a user successfully connected over WS to the coordinator. */
5663
+ connectedUser$ = this.connectedUserSubject.asObservable();
5664
+ /** A list of {@link Call} objects created/tracked by this client. */
5665
+ calls$ = this.callsSubject.asObservable();
5666
+ /** The currently connected user. */
5667
5667
  get connectedUser() {
5668
- return this.connectedUserSubject.getValue();
5668
+ return getCurrentValue(this.connectedUserSubject);
5669
+ }
5670
+ /** A list of {@link Call} objects created/tracked by this client. */
5671
+ get calls() {
5672
+ return getCurrentValue(this.callsSubject);
5669
5673
  }
5670
5674
  /**
5671
5675
  * Sets the currently connected user.
@@ -5676,22 +5680,19 @@ class StreamVideoWriteableStateStore {
5676
5680
  setConnectedUser = (user) => {
5677
5681
  return setCurrentValue(this.connectedUserSubject, user);
5678
5682
  };
5679
- /**
5680
- * A list of {@link Call} objects created/tracked by this client.
5681
- */
5682
- get calls() {
5683
- return getCurrentValue(this.callsSubject);
5684
- }
5685
5683
  /**
5686
5684
  * Sets the list of {@link Call} objects created/tracked by this client.
5687
- * @param calls
5685
+ *
5686
+ * @internal
5687
+ * @param calls the calls to set.
5688
5688
  */
5689
5689
  setCalls = (calls) => {
5690
5690
  return setCurrentValue(this.callsSubject, calls);
5691
5691
  };
5692
5692
  /**
5693
- * Adds a {@link Call} object to the list of {@link Call} objects created/tracked by this client.
5693
+ * Adds a {@link Call} object to the list of calls tracked by this client.
5694
5694
  *
5695
+ * @internal
5695
5696
  * @param call the call to add.
5696
5697
  */
5697
5698
  registerCall = (call) => {
@@ -5702,6 +5703,7 @@ class StreamVideoWriteableStateStore {
5702
5703
  /**
5703
5704
  * Registers a {@link Call} object if it doesn't exist, otherwise updates it.
5704
5705
  *
5706
+ * @internal
5705
5707
  * @param call the call to register or update.
5706
5708
  */
5707
5709
  registerOrUpdateCall = (call) => {
@@ -5713,17 +5715,17 @@ class StreamVideoWriteableStateStore {
5713
5715
  }
5714
5716
  };
5715
5717
  /**
5716
- * Removes a {@link Call} object from the list of {@link Call} objects created/tracked by this client.
5718
+ * Removes a {@link Call} object from the list of calls tracked by this client.
5717
5719
  *
5718
- * @param call the call to remove
5720
+ * @internal
5721
+ * @param call the call to remove.
5719
5722
  */
5720
5723
  unregisterCall = (call) => {
5721
- const logger = videoLoggerSystem.getLogger('client-state');
5722
- logger.trace(`Unregistering call: ${call.cid}`);
5724
+ this.logger.trace(`Unregistering call: ${call.cid}`);
5723
5725
  return this.setCalls((calls) => calls.filter((c) => c !== call));
5724
5726
  };
5725
5727
  /**
5726
- * Finds a {@link Call} object in the list of {@link Call} objects created/tracked by this client.
5728
+ * Finds a {@link Call} object in the list of calls tracked by this client.
5727
5729
  *
5728
5730
  * @param type the type of call to find.
5729
5731
  * @param id the id of the call to find.
@@ -5732,38 +5734,6 @@ class StreamVideoWriteableStateStore {
5732
5734
  return this.calls.find((c) => c.type === type && c.id === id);
5733
5735
  };
5734
5736
  }
5735
- /**
5736
- * A reactive store that exposes state variables in a reactive manner.
5737
- * You can subscribe to changes of the different state variables.
5738
- * This central store contains all the state variables related to [`StreamVideoClient`](./StreamVideClient.md) and [`Call`](./Call.md).
5739
- */
5740
- class StreamVideoReadOnlyStateStore {
5741
- /**
5742
- * Data describing a user successfully connected over WS to coordinator server.
5743
- */
5744
- connectedUser$;
5745
- /**
5746
- * A list of {@link Call} objects created/tracked by this client.
5747
- */
5748
- calls$;
5749
- constructor(store) {
5750
- // convert and expose subjects as observables
5751
- this.connectedUser$ = store.connectedUserSubject.asObservable();
5752
- this.calls$ = store.callsSubject.asObservable();
5753
- }
5754
- /**
5755
- * The current user connected over WS to the backend.
5756
- */
5757
- get connectedUser() {
5758
- return getCurrentValue(this.connectedUser$);
5759
- }
5760
- /**
5761
- * A list of {@link Call} objects created/tracked by this client.
5762
- */
5763
- get calls() {
5764
- return getCurrentValue(this.calls$);
5765
- }
5766
- }
5767
5737
 
5768
5738
  /**
5769
5739
  * Creates a new combined {@link Comparator<T>} which sorts items by the given comparators.
@@ -6096,9 +6066,7 @@ const paginatedLayoutSortPreset = combineComparators(pinned, ifInvisibleOrUnknow
6096
6066
  */
6097
6067
  const livestreamOrAudioRoomSortPreset = combineComparators(publishing, ifInvisibleOrUnknownBy(combineComparators(dominantSpeaker, speaking, reactionType('raised-hand'), withVideoIngressSource, publishingVideo, publishingAudio)), role('admin', 'host', 'speaker'));
6098
6068
 
6099
- /**
6100
- * Returns the default egress object - when no egress data is available.
6101
- */
6069
+ /** Returns the default egress object - when no egress data is available. */
6102
6070
  const defaultEgress = {
6103
6071
  broadcasting: false,
6104
6072
  hls: { playlist_url: '', status: '' },
@@ -6109,93 +6077,120 @@ const defaultEgress = {
6109
6077
  * @react You don't have to use this class directly, as we are exposing the state through Hooks.
6110
6078
  */
6111
6079
  class CallState {
6112
- backstageSubject = new rxjs.BehaviorSubject(true);
6113
- blockedUserIdsSubject = new rxjs.BehaviorSubject([]);
6114
- createdAtSubject = new rxjs.BehaviorSubject(new Date());
6115
- endedAtSubject = new rxjs.BehaviorSubject(undefined);
6116
- startsAtSubject = new rxjs.BehaviorSubject(undefined);
6117
- updatedAtSubject = new rxjs.BehaviorSubject(new Date());
6118
- createdBySubject = new rxjs.BehaviorSubject(undefined);
6119
- customSubject = new rxjs.BehaviorSubject({});
6120
- egressSubject = new rxjs.BehaviorSubject(undefined);
6121
- ingressSubject = new rxjs.BehaviorSubject(undefined);
6122
- recordingSubject = new rxjs.BehaviorSubject(false);
6123
- individualRecordingSubject = new rxjs.BehaviorSubject(false);
6124
- rawRecordingSubject = new rxjs.BehaviorSubject(false);
6125
- sessionSubject = new rxjs.BehaviorSubject(undefined);
6126
- settingsSubject = new rxjs.BehaviorSubject(undefined);
6127
- transcribingSubject = new rxjs.BehaviorSubject(false);
6128
- captioningSubject = new rxjs.BehaviorSubject(false);
6129
- e2eeEnabledSubject = new rxjs.BehaviorSubject(false);
6130
- endedBySubject = new rxjs.BehaviorSubject(undefined);
6131
- thumbnailsSubject = new rxjs.BehaviorSubject(undefined);
6132
- membersSubject = new rxjs.BehaviorSubject([]);
6133
- ownCapabilitiesSubject = new rxjs.BehaviorSubject([]);
6134
- callingStateSubject = new rxjs.BehaviorSubject(exports.CallingState.UNKNOWN);
6135
- startedAtSubject = new rxjs.BehaviorSubject(undefined);
6136
- participantCountSubject = new rxjs.BehaviorSubject(0);
6137
- anonymousParticipantCountSubject = new rxjs.BehaviorSubject(0);
6138
- participantsSubject = new rxjs.BehaviorSubject([]);
6139
- callStatsReportSubject = new rxjs.BehaviorSubject(undefined);
6140
- closedCaptionsSubject = new rxjs.BehaviorSubject([]);
6141
- // These are tracks that were delivered to the Subscriber's onTrack event
6142
- // that we couldn't associate with a participant yet.
6143
- // This happens when the participantJoined event hasn't been received yet.
6144
- // We keep these tracks around until we can associate them with a participant.
6145
- orphanedTracks = [];
6080
+ logger = videoLoggerSystem.getLogger('CallState');
6081
+ /** A list of comparators that are used to sort the participants. */
6082
+ sortParticipantsBy = defaultSortPreset;
6083
+ backstageSubject = subject(true);
6084
+ blockedUserIdsSubject = subject([]);
6085
+ createdAtSubject = subject(new Date());
6086
+ endedAtSubject = subject();
6087
+ startsAtSubject = subject();
6088
+ updatedAtSubject = subject(new Date());
6089
+ createdBySubject = subject();
6090
+ customSubject = subject({});
6091
+ egressSubject = subject();
6092
+ ingressSubject = subject();
6093
+ recordingSubject = subject(false);
6094
+ individualRecordingSubject = subject(false);
6095
+ rawRecordingSubject = subject(false);
6096
+ sessionSubject = subject();
6097
+ settingsSubject = subject();
6098
+ transcribingSubject = subject(false);
6099
+ captioningSubject = subject(false);
6100
+ e2eeEnabledSubject = subject(false);
6101
+ endedBySubject = subject();
6102
+ thumbnailsSubject = subject();
6103
+ membersSubject = subject([]);
6104
+ ownCapabilitiesSubject = subject([]);
6105
+ callingStateSubject = subject(exports.CallingState.UNKNOWN);
6106
+ startedAtSubject = subject();
6107
+ participantCountSubject = subject(0);
6108
+ anonymousParticipantCountSubject = subject(0);
6109
+ participantsSubject = subject([]);
6110
+ callStatsReportSubject = subject();
6111
+ closedCaptionsSubject = subject([]);
6146
6112
  callGrantsSubject = new rxjs.ReplaySubject(1);
6147
- // Derived state
6113
+ /** The backstage state. */
6114
+ backstage$ = duc(this.backstageSubject);
6115
+ /** Will provide the list of blocked user IDs. */
6116
+ blockedUserIds$ = duc(this.blockedUserIdsSubject, isShallowArrayEqual);
6117
+ /** Will provide the time when this call has been created. */
6118
+ createdAt$ = this.createdAtSubject.asObservable();
6119
+ /** Will provide the time when this call has been ended. */
6120
+ endedAt$ = this.endedAtSubject.asObservable();
6121
+ /** Will provide the time when this call has been scheduled to start. */
6122
+ startsAt$ = this.startsAtSubject.asObservable();
6123
+ /** Will provide the time when this call has been updated. */
6124
+ updatedAt$ = this.updatedAtSubject.asObservable();
6125
+ /** Will provide the user who created this call. */
6126
+ createdBy$ = this.createdBySubject.asObservable();
6127
+ /** Will provide the custom data of this call. */
6128
+ custom$ = this.customSubject.asObservable();
6129
+ /** Will provide the egress data of this call. */
6130
+ egress$ = this.egressSubject.asObservable();
6131
+ /** Will provide the ingress data of this call. */
6132
+ ingress$ = this.ingressSubject.asObservable();
6133
+ /** Will provide the recording state of this call. */
6134
+ recording$ = duc(this.recordingSubject);
6135
+ /** Will provide the recording state of this call. */
6136
+ individualRecording$ = duc(this.individualRecordingSubject);
6137
+ /** Will provide the recording state of this call. */
6138
+ rawRecording$ = duc(this.rawRecordingSubject);
6139
+ /** Will provide the session data of this call. */
6140
+ session$ = this.sessionSubject.asObservable();
6141
+ /** Will provide the settings of this call. */
6142
+ settings$ = this.settingsSubject.asObservable();
6143
+ /** Will provide the transcribing state of this call. */
6144
+ transcribing$ = duc(this.transcribingSubject);
6145
+ /** Will provide the closed captioning state of this call. */
6146
+ captioning$ = duc(this.captioningSubject);
6147
+ /**
6148
+ * Whether end-to-end encryption is active for this call, as reported by the
6149
+ * SFU in the join response.
6150
+ */
6151
+ e2eeEnabled$ = duc(this.e2eeEnabledSubject);
6152
+ /** Will provide the user who ended this call. */
6153
+ endedBy$ = this.endedBySubject.asObservable();
6154
+ /** Will provide the thumbnails of this call. */
6155
+ thumbnails$ = this.thumbnailsSubject.asObservable();
6156
+ /** The list of members in the current call. */
6157
+ members$ = this.membersSubject.asObservable();
6158
+ /** The calling state. */
6159
+ callingState$ = duc(this.callingStateSubject);
6148
6160
  /**
6149
6161
  * The time the call session actually started.
6150
6162
  * Useful for displaying the call duration.
6151
6163
  */
6152
- startedAt$;
6164
+ startedAt$ = this.startedAtSubject.asObservable();
6153
6165
  /**
6154
6166
  * The server-side counted number of participants connected to the current call.
6155
6167
  * This number includes the anonymous participants as well.
6156
6168
  */
6157
- participantCount$;
6169
+ participantCount$ = duc(this.participantCountSubject);
6158
6170
  /**
6159
6171
  * The server-side counted number of anonymous participants connected to the current call.
6160
6172
  * This number excludes the regular participants.
6161
6173
  */
6162
- anonymousParticipantCount$;
6174
+ anonymousParticipantCount$ = duc(this.anonymousParticipantCountSubject);
6163
6175
  /**
6164
6176
  * All participants of the current call (this includes the current user and other participants as well),
6165
6177
  * unsorted. This observable only updates when participants join or leave the call.
6166
6178
  */
6167
- rawParticipants$;
6168
- /**
6169
- * All participants of the current call (this includes the current user and other participants as well),
6170
- * sorted according to the current `sortByParticipantsBy` setting
6171
- */
6172
- participants$;
6173
- /**
6174
- * Remote participants of the current call (this includes every participant except the logged-in user).
6175
- */
6176
- remoteParticipants$;
6177
- /**
6178
- * The local participant of the current call (the logged-in user).
6179
- */
6180
- localParticipant$;
6181
- /**
6182
- * Pinned participants of the current call.
6183
- */
6184
- pinnedParticipants$;
6185
- /**
6186
- * The currently elected dominant speaker in the current call.
6187
- */
6188
- dominantSpeaker$;
6189
- /**
6190
- * Emits true whenever there is an active screen sharing session within
6191
- * the current call. Useful for displaying a "screen sharing" indicator and
6192
- * switching the layout to a screen sharing layout.
6193
- *
6194
- * The actual screen sharing track isn't exposed here, but can be retrieved
6195
- * from the list of call participants. We also don't want to be limiting
6196
- * to the number of share screen tracks are displayed in a call.
6197
- */
6198
- hasOngoingScreenShare$;
6179
+ rawParticipants$ = shared(this.participantsSubject.asObservable());
6180
+ /** All participants of the current call sorted according to the current `sortByParticipantsBy` setting. */
6181
+ participants$ = shared(this.participantsSubject.asObservable().pipe(
6182
+ // maintain stable-sort by mutating the participants stored in the original subject
6183
+ rxjs.map((ps) => ps.sort(this.sortParticipantsBy))));
6184
+ /** The local participant of the current call. */
6185
+ localParticipant$ = shared(this.participants$.pipe(rxjs.map((ps) => ps.find((p) => p.isLocalParticipant))));
6186
+ /** Remote participants of the current call (all except the local participant). */
6187
+ remoteParticipants$ = shared(this.participants$.pipe(rxjs.map((ps) => ps.filter((p) => !p.isLocalParticipant))));
6188
+ /** Pinned participants of the current call. */
6189
+ pinnedParticipants$ = shared(this.participants$.pipe(rxjs.map((ps) => ps.filter((p) => !!p.pin))));
6190
+ /** The currently elected dominant speaker in the current call. */
6191
+ dominantSpeaker$ = shared(this.participants$.pipe(rxjs.map((ps) => ps.find((p) => p.isDominantSpeaker))));
6192
+ /** Emits true whenever there is an active screen sharing session within the current call. */
6193
+ hasOngoingScreenShare$ = shared(this.participants$.pipe(rxjs.map((ps) => ps.some((p) => hasScreenShare(p))), rxjs.distinctUntilChanged()));
6199
6194
  /**
6200
6195
  * The latest stats report of the current call.
6201
6196
  * When stats gathering is enabled, this observable will emit a new value
@@ -6204,232 +6199,66 @@ class CallState {
6204
6199
  * Consumers of this observable can implement their own batching logic
6205
6200
  * in case they want to show historical stats data.
6206
6201
  */
6207
- callStatsReport$;
6208
- /**
6209
- * The list of members in the current call.
6210
- */
6211
- members$;
6212
- /**
6213
- * The list of capabilities of the current user.
6214
- */
6215
- ownCapabilities$;
6216
- /**
6217
- * The calling state.
6218
- */
6219
- callingState$;
6220
- /**
6221
- * The backstage state.
6222
- */
6223
- backstage$;
6224
- /**
6225
- * Will provide the list of blocked user IDs.
6226
- */
6227
- blockedUserIds$;
6228
- /**
6229
- * Will provide the time when this call has been created.
6230
- */
6231
- createdAt$;
6232
- /**
6233
- * Will provide the time when this call has been ended.
6234
- */
6235
- endedAt$;
6236
- /**
6237
- * Will provide the time when this call has been scheduled to start.
6238
- */
6239
- startsAt$;
6240
- /**
6241
- * Will provide the time when this call has been updated.
6242
- */
6243
- updatedAt$;
6244
- /**
6245
- * Will provide the user who created this call.
6246
- */
6247
- createdBy$;
6248
- /**
6249
- * Will provide the custom data of this call.
6250
- */
6251
- custom$;
6252
- /**
6253
- * Will provide the egress data of this call.
6254
- */
6255
- egress$;
6256
- /**
6257
- * Will provide the ingress data of this call.
6258
- */
6259
- ingress$;
6260
- /**
6261
- * Will provide the recording state of this call.
6262
- */
6263
- recording$;
6264
- /**
6265
- * Will provide the recording state of this call.
6266
- */
6267
- individualRecording$;
6268
- /**
6269
- * Will provide the recording state of this call.
6270
- */
6271
- rawRecording$;
6272
- /**
6273
- * Will provide the session data of this call.
6274
- */
6275
- session$;
6276
- /**
6277
- * Will provide the settings of this call.
6278
- */
6279
- settings$;
6280
- /**
6281
- * Will provide the transcribing state of this call.
6282
- */
6283
- transcribing$;
6284
- /**
6285
- * Will provide the closed captioning state of this call.
6286
- */
6287
- captioning$;
6288
- /**
6289
- * Whether end-to-end encryption is active for this call, as reported by the
6290
- * SFU in the join response.
6291
- */
6292
- e2eeEnabled$;
6293
- /**
6294
- * Will provide the user who ended this call.
6295
- */
6296
- endedBy$;
6297
- /**
6298
- * Will provide the thumbnails of this call.
6299
- */
6300
- thumbnails$;
6301
- /**
6302
- * The queue of closed captions.
6303
- */
6304
- closedCaptions$;
6305
- logger = videoLoggerSystem.getLogger('CallState');
6306
- /**
6307
- * A list of comparators that are used to sort the participants.
6308
- */
6309
- sortParticipantsBy = defaultSortPreset;
6310
- /**
6311
- * The closed captions configuration.
6312
- */
6202
+ callStatsReport$ = this.callStatsReportSubject.asObservable();
6203
+ /** The queue of closed captions. */
6204
+ closedCaptions$ = this.closedCaptionsSubject.asObservable();
6205
+ /** The list of capabilities of the current user. */
6206
+ ownCapabilities$ = shared(rxjs.combineLatest([
6207
+ this.ownCapabilitiesSubject,
6208
+ this.callGrantsSubject.pipe(rxjs.startWith(undefined)),
6209
+ ]).pipe(rxjs.map(([capabilities, grants]) => {
6210
+ if (!grants)
6211
+ return capabilities;
6212
+ const { canPublishAudio, canPublishVideo, canScreenshare } = grants;
6213
+ const update = {
6214
+ [OwnCapability.SEND_AUDIO]: canPublishAudio,
6215
+ [OwnCapability.SEND_VIDEO]: canPublishVideo,
6216
+ [OwnCapability.SCREENSHARE]: canScreenshare,
6217
+ };
6218
+ const nextCapabilities = [...capabilities];
6219
+ for (const _capability in update) {
6220
+ const capability = _capability;
6221
+ const allowed = update[capability];
6222
+ // grants take precedence over capabilities, reconstruct the capabilities
6223
+ if (allowed && !nextCapabilities.includes(capability)) {
6224
+ nextCapabilities.push(capability);
6225
+ }
6226
+ else if (!allowed && nextCapabilities.includes(capability)) {
6227
+ const index = nextCapabilities.indexOf(capability);
6228
+ nextCapabilities.splice(index, 1);
6229
+ }
6230
+ }
6231
+ return nextCapabilities;
6232
+ }), rxjs.distinctUntilChanged(isShallowArrayEqual)));
6233
+ // These are tracks that were delivered to the Subscriber's onTrack event
6234
+ // that we couldn't associate with a participant yet.
6235
+ // This happens when the participantJoined event hasn't been received yet.
6236
+ // We keep these tracks around until we can associate them with a participant.
6237
+ orphanedTracks = [];
6238
+ /** The closed captions configuration. */
6313
6239
  closedCaptionsSettings;
6314
6240
  closedCaptionsTasks = new Map();
6315
6241
  eventHandlers;
6316
- /**
6317
- * Creates a new instance of the CallState class.
6318
- *
6319
- */
6242
+ /** Creates a new instance of the CallState class. */
6320
6243
  constructor() {
6321
- this.rawParticipants$ = this.participantsSubject
6322
- .asObservable()
6323
- .pipe(rxjs.shareReplay({ bufferSize: 1, refCount: true }));
6324
- this.participants$ = this.participantsSubject.asObservable().pipe(
6325
- // maintain stable-sort by mutating the participants stored
6326
- // in the original subject
6327
- rxjs.map((ps) => ps.sort(this.sortParticipantsBy)), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
6328
- this.localParticipant$ = this.participants$.pipe(rxjs.map((participants) => participants.find((p) => p.isLocalParticipant)), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
6329
- this.remoteParticipants$ = this.participants$.pipe(rxjs.map((participants) => participants.filter((p) => !p.isLocalParticipant)), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
6330
- this.pinnedParticipants$ = this.participants$.pipe(rxjs.map((participants) => participants.filter((p) => !!p.pin)), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
6331
- this.dominantSpeaker$ = this.participants$.pipe(rxjs.map((participants) => participants.find((p) => p.isDominantSpeaker)), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
6332
- this.hasOngoingScreenShare$ = this.participants$.pipe(rxjs.map((participants) => participants.some((p) => hasScreenShare(p))), rxjs.distinctUntilChanged(), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
6333
- // dates
6334
- this.createdAt$ = this.createdAtSubject.asObservable();
6335
- this.endedAt$ = this.endedAtSubject.asObservable();
6336
- this.startsAt$ = this.startsAtSubject.asObservable();
6337
- this.startedAt$ = this.startedAtSubject.asObservable();
6338
- this.updatedAt$ = this.updatedAtSubject.asObservable();
6339
- this.callStatsReport$ = this.callStatsReportSubject.asObservable();
6340
- this.members$ = this.membersSubject.asObservable();
6341
- // complex objects should work as streams of data
6342
- this.createdBy$ = this.createdBySubject.asObservable();
6343
- this.custom$ = this.customSubject.asObservable();
6344
- this.egress$ = this.egressSubject.asObservable();
6345
- this.ingress$ = this.ingressSubject.asObservable();
6346
- this.session$ = this.sessionSubject.asObservable();
6347
- this.settings$ = this.settingsSubject.asObservable();
6348
- this.endedBy$ = this.endedBySubject.asObservable();
6349
- this.thumbnails$ = this.thumbnailsSubject.asObservable();
6350
- this.closedCaptions$ = this.closedCaptionsSubject.asObservable();
6351
- /**
6352
- * Creates an Observable from the given subject by piping to the
6353
- * `distinctUntilChanged()` operator.
6354
- */
6355
- const duc = (subject, comparator) => subject.pipe(rxjs.distinctUntilChanged(comparator));
6356
- // primitive values should only emit once the value they hold changes
6357
- this.anonymousParticipantCount$ = duc(this.anonymousParticipantCountSubject);
6358
- this.blockedUserIds$ = duc(this.blockedUserIdsSubject, isShallowArrayEqual);
6359
- this.backstage$ = duc(this.backstageSubject);
6360
- this.callingState$ = duc(this.callingStateSubject);
6361
- this.ownCapabilities$ = rxjs.combineLatest([
6362
- this.ownCapabilitiesSubject,
6363
- this.callGrantsSubject.pipe(rxjs.startWith(undefined)),
6364
- ]).pipe(rxjs.map(([capabilities, grants]) => {
6365
- if (!grants)
6366
- return capabilities;
6367
- const { canPublishAudio, canPublishVideo, canScreenshare } = grants;
6368
- const update = {
6369
- [OwnCapability.SEND_AUDIO]: canPublishAudio,
6370
- [OwnCapability.SEND_VIDEO]: canPublishVideo,
6371
- [OwnCapability.SCREENSHARE]: canScreenshare,
6372
- };
6373
- const nextCapabilities = [...capabilities];
6374
- for (const _capability in update) {
6375
- const capability = _capability;
6376
- const allowed = update[capability];
6377
- // grants take precedence over capabilities, reconstruct the capabilities
6378
- if (allowed && !nextCapabilities.includes(capability)) {
6379
- nextCapabilities.push(capability);
6380
- }
6381
- else if (!allowed && nextCapabilities.includes(capability)) {
6382
- const index = nextCapabilities.indexOf(capability);
6383
- nextCapabilities.splice(index, 1);
6384
- }
6385
- }
6386
- return nextCapabilities;
6387
- }), rxjs.distinctUntilChanged(isShallowArrayEqual), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
6388
- this.participantCount$ = duc(this.participantCountSubject);
6389
- this.recording$ = duc(this.recordingSubject);
6390
- this.individualRecording$ = duc(this.individualRecordingSubject);
6391
- this.rawRecording$ = duc(this.rawRecordingSubject);
6392
- this.transcribing$ = duc(this.transcribingSubject);
6393
- this.captioning$ = duc(this.captioningSubject);
6394
- this.e2eeEnabled$ = duc(this.e2eeEnabledSubject);
6395
6244
  this.eventHandlers = {
6396
- // these events are not updating the call state:
6397
- 'call.frame_recording_ready': undefined,
6398
- 'call.kicked_user': undefined,
6399
- 'call.moderation_blur': undefined,
6400
- 'call.moderation_warning': undefined,
6401
- 'call.permission_request': undefined,
6402
- 'call.recording_ready': undefined,
6403
- 'call.rtmp_broadcast_failed': undefined,
6404
- 'call.rtmp_broadcast_started': undefined,
6405
- 'call.rtmp_broadcast_stopped': undefined,
6406
- 'call.stats_report_ready': undefined,
6407
- 'call.transcription_ready': undefined,
6408
- 'call.user_feedback_submitted': undefined,
6409
- 'call.user_muted': undefined,
6410
- 'connection.error': undefined,
6411
- 'connection.ok': undefined,
6412
- 'health.check': undefined,
6413
- 'user.updated': undefined,
6414
- custom: undefined,
6415
- // events that update call state:
6416
6245
  'call.accepted': (e) => this.updateFromCallResponse(e.call),
6417
6246
  'call.blocked_user': this.blockUser,
6418
6247
  'call.closed_caption': this.updateFromClosedCaptions,
6419
6248
  'call.closed_captions_failed': () => {
6420
- this.setCurrentValue(this.captioningSubject, false);
6249
+ setCurrentValue(this.captioningSubject, false);
6421
6250
  },
6422
6251
  'call.closed_captions_started': () => {
6423
- this.setCurrentValue(this.captioningSubject, true);
6252
+ setCurrentValue(this.captioningSubject, true);
6424
6253
  },
6425
6254
  'call.closed_captions_stopped': () => {
6426
- this.setCurrentValue(this.captioningSubject, false);
6255
+ setCurrentValue(this.captioningSubject, false);
6427
6256
  },
6428
6257
  'call.created': (e) => this.updateFromCallResponse(e.call),
6429
6258
  'call.deleted': (e) => this.updateFromCallResponse(e.call),
6430
6259
  'call.ended': (e) => {
6431
6260
  this.updateFromCallResponse(e.call);
6432
- this.setCurrentValue(this.endedBySubject, e.user);
6261
+ setCurrentValue(this.endedBySubject, e.user);
6433
6262
  },
6434
6263
  'call.frame_recording_failed': (e) => {
6435
6264
  this.updateFromCallResponse(e.call);
@@ -6474,21 +6303,19 @@ class CallState {
6474
6303
  'call.session_participant_left': this.updateFromSessionParticipantLeft,
6475
6304
  'call.session_started': (e) => this.updateFromCallResponse(e.call),
6476
6305
  'call.transcription_started': () => {
6477
- this.setCurrentValue(this.transcribingSubject, true);
6306
+ setCurrentValue(this.transcribingSubject, true);
6478
6307
  },
6479
6308
  'call.transcription_stopped': () => {
6480
- this.setCurrentValue(this.transcribingSubject, false);
6309
+ setCurrentValue(this.transcribingSubject, false);
6481
6310
  },
6482
6311
  'call.transcription_failed': () => {
6483
- this.setCurrentValue(this.transcribingSubject, false);
6312
+ setCurrentValue(this.transcribingSubject, false);
6484
6313
  },
6485
6314
  'call.unblocked_user': this.unblockUser,
6486
6315
  'call.updated': (e) => this.updateFromCallResponse(e.call),
6487
6316
  };
6488
6317
  }
6489
- /**
6490
- * Runs the cleanup tasks.
6491
- */
6318
+ /** Runs the cleanup tasks. */
6492
6319
  dispose = () => {
6493
6320
  for (const [ccKey, taskId] of this.closedCaptionsTasks.entries()) {
6494
6321
  clearTimeout(taskId);
@@ -6505,39 +6332,18 @@ class CallState {
6505
6332
  setSortParticipantsBy = (comparator) => {
6506
6333
  this.sortParticipantsBy = comparator;
6507
6334
  // trigger re-sorting of participants
6508
- this.setCurrentValue(this.participantsSubject, (ps) => ps);
6335
+ setCurrentValue(this.participantsSubject, (ps) => ps);
6509
6336
  };
6510
- /**
6511
- * Returns the comparator currently used to sort the participants.
6512
- */
6337
+ /** Returns the comparator currently used to sort the participants. */
6513
6338
  getSortParticipantsBy = () => {
6514
6339
  return this.sortParticipantsBy;
6515
6340
  };
6516
- /**
6517
- * Gets the current value of an observable, or undefined if the observable has
6518
- * not emitted a value yet.
6519
- *
6520
- * @param observable$ the observable to get the value from.
6521
- */
6522
- getCurrentValue = getCurrentValue;
6523
- /**
6524
- * Updates the value of the provided Subject.
6525
- * An `update` can either be a new value or a function which takes
6526
- * the current value and returns a new value.
6527
- *
6528
- * @internal
6529
- *
6530
- * @param subject the subject to update.
6531
- * @param update the update to apply to the subject.
6532
- * @return the updated value.
6533
- */
6534
- setCurrentValue = setCurrentValue;
6535
6341
  /**
6536
6342
  * The server-side counted number of participants connected to the current call.
6537
6343
  * This number includes the anonymous participants as well.
6538
6344
  */
6539
6345
  get participantCount() {
6540
- return this.getCurrentValue(this.participantCount$);
6346
+ return getCurrentValue(this.participantCountSubject);
6541
6347
  }
6542
6348
  /**
6543
6349
  * Sets the number of participants in the current call.
@@ -6546,14 +6352,14 @@ class CallState {
6546
6352
  * @param count the number of participants.
6547
6353
  */
6548
6354
  setParticipantCount = (count) => {
6549
- return this.setCurrentValue(this.participantCountSubject, count);
6355
+ return setCurrentValue(this.participantCountSubject, count);
6550
6356
  };
6551
6357
  /**
6552
6358
  * The time the call session actually started.
6553
6359
  * Useful for displaying the call duration.
6554
6360
  */
6555
6361
  get startedAt() {
6556
- return this.getCurrentValue(this.startedAt$);
6362
+ return getCurrentValue(this.startedAtSubject);
6557
6363
  }
6558
6364
  /**
6559
6365
  * Sets the time the call session actually started.
@@ -6562,13 +6368,11 @@ class CallState {
6562
6368
  * @param startedAt the time the call session actually started.
6563
6369
  */
6564
6370
  setStartedAt = (startedAt) => {
6565
- return this.setCurrentValue(this.startedAtSubject, startedAt);
6371
+ return setCurrentValue(this.startedAtSubject, startedAt);
6566
6372
  };
6567
- /**
6568
- * Returns whether closed captions are enabled in the current call.
6569
- */
6373
+ /** Returns whether closed captions are enabled in the current call. */
6570
6374
  get captioning() {
6571
- return this.getCurrentValue(this.captioning$);
6375
+ return getCurrentValue(this.captioningSubject);
6572
6376
  }
6573
6377
  /**
6574
6378
  * Sets the closed captioning state of the current call.
@@ -6584,7 +6388,7 @@ class CallState {
6584
6388
  * This number includes the anonymous participants as well.
6585
6389
  */
6586
6390
  get anonymousParticipantCount() {
6587
- return this.getCurrentValue(this.anonymousParticipantCount$);
6391
+ return getCurrentValue(this.anonymousParticipantCountSubject);
6588
6392
  }
6589
6393
  /**
6590
6394
  * Sets the number of anonymous participants in the current call.
@@ -6593,19 +6397,15 @@ class CallState {
6593
6397
  * @param count the number of anonymous participants.
6594
6398
  */
6595
6399
  setAnonymousParticipantCount = (count) => {
6596
- return this.setCurrentValue(this.anonymousParticipantCountSubject, count);
6400
+ return setCurrentValue(this.anonymousParticipantCountSubject, count);
6597
6401
  };
6598
- /**
6599
- * The list of participants in the current call.
6600
- */
6402
+ /** The list of participants in the current call. */
6601
6403
  get participants() {
6602
- return this.getCurrentValue(this.participants$);
6404
+ return getCurrentValue(this.participants$);
6603
6405
  }
6604
- /**
6605
- * The stable list of participants in the current call, unsorted.
6606
- */
6406
+ /** The stable list of participants in the current call, unsorted. */
6607
6407
  get rawParticipants() {
6608
- return this.getCurrentValue(this.rawParticipants$);
6408
+ return getCurrentValue(this.rawParticipants$);
6609
6409
  }
6610
6410
  /**
6611
6411
  * Returns the current participants array directly from the BehaviorSubject.
@@ -6626,43 +6426,31 @@ class CallState {
6626
6426
  * @param participants the list of participants.
6627
6427
  */
6628
6428
  setParticipants = (participants) => {
6629
- return this.setCurrentValue(this.participantsSubject, participants);
6429
+ return setCurrentValue(this.participantsSubject, participants);
6630
6430
  };
6631
- /**
6632
- * The local participant in the current call.
6633
- */
6431
+ /** The local participant in the current call. */
6634
6432
  get localParticipant() {
6635
- return this.getCurrentValue(this.localParticipant$);
6433
+ return getCurrentValue(this.localParticipant$);
6636
6434
  }
6637
- /**
6638
- * The list of remote participants in the current call.
6639
- */
6435
+ /** The list of remote participants in the current call. */
6640
6436
  get remoteParticipants() {
6641
- return this.getCurrentValue(this.remoteParticipants$);
6437
+ return getCurrentValue(this.remoteParticipants$);
6642
6438
  }
6643
- /**
6644
- * The dominant speaker in the current call.
6645
- */
6439
+ /** The dominant speaker in the current call. */
6646
6440
  get dominantSpeaker() {
6647
- return this.getCurrentValue(this.dominantSpeaker$);
6441
+ return getCurrentValue(this.dominantSpeaker$);
6648
6442
  }
6649
- /**
6650
- * The list of pinned participants in the current call.
6651
- */
6443
+ /** The list of pinned participants in the current call. */
6652
6444
  get pinnedParticipants() {
6653
- return this.getCurrentValue(this.pinnedParticipants$);
6445
+ return getCurrentValue(this.pinnedParticipants$);
6654
6446
  }
6655
- /**
6656
- * Tell if there is an ongoing screen share in this call.
6657
- */
6447
+ /** Tell if there is an ongoing screen share in this call. */
6658
6448
  get hasOngoingScreenShare() {
6659
- return this.getCurrentValue(this.hasOngoingScreenShare$);
6449
+ return getCurrentValue(this.hasOngoingScreenShare$);
6660
6450
  }
6661
- /**
6662
- * The calling state.
6663
- */
6451
+ /** The calling state. */
6664
6452
  get callingState() {
6665
- return this.getCurrentValue(this.callingState$);
6453
+ return getCurrentValue(this.callingStateSubject);
6666
6454
  }
6667
6455
  /**
6668
6456
  * Sets the calling state.
@@ -6671,13 +6459,11 @@ class CallState {
6671
6459
  * @param state the new calling state.
6672
6460
  */
6673
6461
  setCallingState = (state) => {
6674
- return this.setCurrentValue(this.callingStateSubject, state);
6462
+ return setCurrentValue(this.callingStateSubject, state);
6675
6463
  };
6676
- /**
6677
- * The call stats report.
6678
- */
6464
+ /** The call stats report. */
6679
6465
  get callStatsReport() {
6680
- return this.getCurrentValue(this.callStatsReport$);
6466
+ return getCurrentValue(this.callStatsReportSubject);
6681
6467
  }
6682
6468
  /**
6683
6469
  * Returns whether the call stats report is being observed or not.
@@ -6693,13 +6479,11 @@ class CallState {
6693
6479
  * @param report the report to set.
6694
6480
  */
6695
6481
  setCallStatsReport = (report) => {
6696
- return this.setCurrentValue(this.callStatsReportSubject, report);
6482
+ return setCurrentValue(this.callStatsReportSubject, report);
6697
6483
  };
6698
- /**
6699
- * The members of the current call.
6700
- */
6484
+ /** The members of the current call. */
6701
6485
  get members() {
6702
- return this.getCurrentValue(this.members$);
6486
+ return getCurrentValue(this.membersSubject);
6703
6487
  }
6704
6488
  /**
6705
6489
  * Sets the members of the current call.
@@ -6708,13 +6492,11 @@ class CallState {
6708
6492
  * @param members the members to set.
6709
6493
  */
6710
6494
  setMembers = (members) => {
6711
- this.setCurrentValue(this.membersSubject, members);
6495
+ setCurrentValue(this.membersSubject, members);
6712
6496
  };
6713
- /**
6714
- * The capabilities of the current user for the current call.
6715
- */
6497
+ /** The capabilities of the current user for the current call. */
6716
6498
  get ownCapabilities() {
6717
- return this.getCurrentValue(this.ownCapabilities$);
6499
+ return getCurrentValue(this.ownCapabilities$);
6718
6500
  }
6719
6501
  /**
6720
6502
  * Sets the own capabilities.
@@ -6723,7 +6505,7 @@ class CallState {
6723
6505
  * @param capabilities the capabilities to set.
6724
6506
  */
6725
6507
  setOwnCapabilities = (capabilities) => {
6726
- return this.setCurrentValue(this.ownCapabilitiesSubject, capabilities);
6508
+ return setCurrentValue(this.ownCapabilitiesSubject, capabilities);
6727
6509
  };
6728
6510
  /**
6729
6511
  * Sets the call grants (used for own capabilities).
@@ -6732,141 +6514,105 @@ class CallState {
6732
6514
  * @param grants the grants to set.
6733
6515
  */
6734
6516
  setCallGrants = (grants) => {
6735
- return this.setCurrentValue(this.callGrantsSubject, grants);
6517
+ return setCurrentValue(this.callGrantsSubject, grants);
6736
6518
  };
6737
- /**
6738
- * The backstage state.
6739
- */
6519
+ /** The backstage state. */
6740
6520
  get backstage() {
6741
- return this.getCurrentValue(this.backstage$);
6521
+ return getCurrentValue(this.backstageSubject);
6742
6522
  }
6743
6523
  /**
6744
6524
  * Sets the backstage state.
6745
6525
  * @param backstage the backstage state.
6746
6526
  */
6747
6527
  setBackstage = (backstage) => {
6748
- return this.setCurrentValue(this.backstageSubject, backstage);
6528
+ return setCurrentValue(this.backstageSubject, backstage);
6749
6529
  };
6750
- /**
6751
- * Will provide the list of blocked user IDs.
6752
- */
6530
+ /** Will provide the list of blocked user IDs. */
6753
6531
  get blockedUserIds() {
6754
- return this.getCurrentValue(this.blockedUserIds$);
6532
+ return getCurrentValue(this.blockedUserIdsSubject);
6755
6533
  }
6756
- /**
6757
- * Will provide the time when this call has been created.
6758
- */
6534
+ /** Will provide the time when this call has been created. */
6759
6535
  get createdAt() {
6760
- return this.getCurrentValue(this.createdAt$);
6536
+ return getCurrentValue(this.createdAtSubject);
6761
6537
  }
6762
- /**
6763
- * Will provide the time when this call has been ended.
6764
- */
6538
+ /** Will provide the time when this call has been ended. */
6765
6539
  get endedAt() {
6766
- return this.getCurrentValue(this.endedAt$);
6540
+ return getCurrentValue(this.endedAtSubject);
6767
6541
  }
6768
6542
  /**
6769
6543
  * Sets the time when this call has been ended.
6770
6544
  * @param endedAt the time when this call has been ended.
6771
6545
  */
6772
6546
  setEndedAt = (endedAt) => {
6773
- return this.setCurrentValue(this.endedAtSubject, endedAt);
6547
+ return setCurrentValue(this.endedAtSubject, endedAt);
6774
6548
  };
6775
- /**
6776
- * Will provide the time when this call has been scheduled to start.
6777
- */
6549
+ /** Will provide the time when this call has been scheduled to start. */
6778
6550
  get startsAt() {
6779
- return this.getCurrentValue(this.startsAt$);
6551
+ return getCurrentValue(this.startsAtSubject);
6780
6552
  }
6781
- /**
6782
- * Will provide the time when this call has been updated.
6783
- */
6553
+ /** Will provide the time when this call has been updated. */
6784
6554
  get updatedAt() {
6785
- return this.getCurrentValue(this.updatedAt$);
6555
+ return getCurrentValue(this.updatedAtSubject);
6786
6556
  }
6787
- /**
6788
- * Will provide the user who created this call.
6789
- */
6557
+ /** Will provide the user who created this call. */
6790
6558
  get createdBy() {
6791
- return this.getCurrentValue(this.createdBy$);
6559
+ return getCurrentValue(this.createdBySubject);
6792
6560
  }
6793
- /**
6794
- * Will provide the custom data of this call.
6795
- */
6561
+ /** Will provide the custom data of this call. */
6796
6562
  get custom() {
6797
- return this.getCurrentValue(this.custom$);
6563
+ return getCurrentValue(this.customSubject);
6798
6564
  }
6799
6565
  /**
6800
6566
  * Will provide the egress data of this call.
6801
6567
  */
6802
6568
  get egress() {
6803
- return this.getCurrentValue(this.egress$);
6569
+ return getCurrentValue(this.egressSubject);
6804
6570
  }
6805
- /**
6806
- * Will provide the ingress data of this call.
6807
- */
6571
+ /** Will provide the ingress data of this call. */
6808
6572
  get ingress() {
6809
- return this.getCurrentValue(this.ingress$);
6573
+ return getCurrentValue(this.ingressSubject);
6810
6574
  }
6811
- /**
6812
- * Will provide the composite recording state of this call.
6813
- */
6575
+ /** Will provide the composite recording state of this call. */
6814
6576
  get recording() {
6815
- return this.getCurrentValue(this.recording$);
6577
+ return getCurrentValue(this.recordingSubject);
6816
6578
  }
6817
- /**
6818
- * Will provide the individual recording state of this call.
6819
- */
6579
+ /** Will provide the individual recording state of this call. */
6820
6580
  get individualRecording() {
6821
- return this.getCurrentValue(this.individualRecording$);
6581
+ return getCurrentValue(this.individualRecordingSubject);
6822
6582
  }
6823
- /**
6824
- * Will provide the raw recording state of this call.
6825
- */
6583
+ /** Will provide the raw recording state of this call. */
6826
6584
  get rawRecording() {
6827
- return this.getCurrentValue(this.rawRecording$);
6585
+ return getCurrentValue(this.rawRecordingSubject);
6828
6586
  }
6829
- /**
6830
- * Will provide the session data of this call.
6831
- */
6587
+ /** Will provide the session data of this call. */
6832
6588
  get session() {
6833
- return this.getCurrentValue(this.session$);
6589
+ return getCurrentValue(this.sessionSubject);
6834
6590
  }
6835
- /**
6836
- * Will provide the settings of this call.
6837
- */
6591
+ /** Will provide the settings of this call. */
6838
6592
  get settings() {
6839
- return this.getCurrentValue(this.settings$);
6593
+ return getCurrentValue(this.settingsSubject);
6840
6594
  }
6841
- /**
6842
- * Will provide the transcribing state of this call.
6843
- */
6595
+ /** Will provide the transcribing state of this call. */
6844
6596
  get transcribing() {
6845
- return this.getCurrentValue(this.transcribing$);
6597
+ return getCurrentValue(this.transcribingSubject);
6846
6598
  }
6847
- /**
6848
- * Whether end-to-end encryption is active for this call.
6849
- */
6599
+ /** Whether end-to-end encryption is active for this call. */
6850
6600
  get e2eeEnabled() {
6851
- return this.getCurrentValue(this.e2eeEnabled$);
6601
+ return getCurrentValue(this.e2eeEnabledSubject);
6852
6602
  }
6853
- /**
6854
- * Will provide the user who ended this call.
6855
- */
6603
+ /** Will provide the user who ended this call. */
6856
6604
  get endedBy() {
6857
- return this.getCurrentValue(this.endedBy$);
6605
+ return getCurrentValue(this.endedBySubject);
6858
6606
  }
6859
6607
  /**
6860
6608
  * Will provide the thumbnails of this call, if enabled in the call settings.
6861
6609
  */
6862
6610
  get thumbnails() {
6863
- return this.getCurrentValue(this.thumbnails$);
6611
+ return getCurrentValue(this.thumbnailsSubject);
6864
6612
  }
6865
- /**
6866
- * Returns the current queue of closed captions.
6867
- */
6613
+ /** Returns the current queue of closed captions. */
6868
6614
  get closedCaptions() {
6869
- return this.getCurrentValue(this.closedCaptions$);
6615
+ return getCurrentValue(this.closedCaptionsSubject);
6870
6616
  }
6871
6617
  /**
6872
6618
  * Will try to find the participant with the given sessionId in the current call.
@@ -6877,9 +6623,7 @@ class CallState {
6877
6623
  findParticipantBySessionId = (sessionId) => {
6878
6624
  return this.participants.find((p) => p.sessionId === sessionId);
6879
6625
  };
6880
- /**
6881
- * Returns a new lookup table of participants indexed by their session ID.
6882
- */
6626
+ /** Returns a new lookup table of participants indexed by their session ID. */
6883
6627
  getParticipantLookupBySessionId = () => {
6884
6628
  return this.participants.reduce((lookupTable, participant) => {
6885
6629
  lookupTable[participant.sessionId] = participant;
@@ -7114,25 +6858,25 @@ class CallState {
7114
6858
  */
7115
6859
  updateFromCallResponse = (call) => {
7116
6860
  this.setBackstage(call.backstage);
7117
- this.setCurrentValue(this.blockedUserIdsSubject, call.blocked_user_ids);
7118
- this.setCurrentValue(this.createdAtSubject, new Date(call.created_at));
7119
- this.setCurrentValue(this.updatedAtSubject, new Date(call.updated_at));
7120
- this.setCurrentValue(this.startsAtSubject, call.starts_at ? new Date(call.starts_at) : undefined);
6861
+ setCurrentValue(this.blockedUserIdsSubject, call.blocked_user_ids);
6862
+ setCurrentValue(this.createdAtSubject, new Date(call.created_at));
6863
+ setCurrentValue(this.updatedAtSubject, new Date(call.updated_at));
6864
+ setCurrentValue(this.startsAtSubject, call.starts_at ? new Date(call.starts_at) : undefined);
7121
6865
  this.setEndedAt(call.ended_at ? new Date(call.ended_at) : undefined);
7122
- this.setCurrentValue(this.createdBySubject, call.created_by);
7123
- this.setCurrentValue(this.customSubject, call.custom);
7124
- this.setCurrentValue(this.egressSubject, call.egress);
7125
- this.setCurrentValue(this.ingressSubject, call.ingress);
6866
+ setCurrentValue(this.createdBySubject, call.created_by);
6867
+ setCurrentValue(this.customSubject, call.custom);
6868
+ setCurrentValue(this.egressSubject, call.egress);
6869
+ setCurrentValue(this.ingressSubject, call.ingress);
7126
6870
  const { individual_recording, composite_recording, raw_recording } = call.egress;
7127
- this.setCurrentValue(this.recordingSubject, call.recording || composite_recording?.status === 'running');
7128
- this.setCurrentValue(this.individualRecordingSubject, individual_recording?.status === 'running');
7129
- this.setCurrentValue(this.rawRecordingSubject, raw_recording?.status === 'running');
7130
- const s = this.setCurrentValue(this.sessionSubject, call.session);
6871
+ setCurrentValue(this.recordingSubject, call.recording || composite_recording?.status === 'running');
6872
+ setCurrentValue(this.individualRecordingSubject, individual_recording?.status === 'running');
6873
+ setCurrentValue(this.rawRecordingSubject, raw_recording?.status === 'running');
6874
+ const s = setCurrentValue(this.sessionSubject, call.session);
7131
6875
  this.updateParticipantCountFromSession(s);
7132
- this.setCurrentValue(this.settingsSubject, call.settings);
7133
- this.setCurrentValue(this.transcribingSubject, call.transcribing);
7134
- this.setCurrentValue(this.captioningSubject, call.captioning);
7135
- this.setCurrentValue(this.thumbnailsSubject, call.thumbnails);
6876
+ setCurrentValue(this.settingsSubject, call.settings);
6877
+ setCurrentValue(this.transcribingSubject, call.transcribing);
6878
+ setCurrentValue(this.captioningSubject, call.captioning);
6879
+ setCurrentValue(this.thumbnailsSubject, call.thumbnails);
7136
6880
  };
7137
6881
  /**
7138
6882
  * Merges a polled ring state into the current session. Only the ring fields
@@ -7143,7 +6887,7 @@ class CallState {
7143
6887
  * @param ringState the ring state as returned by the coordinator.
7144
6888
  */
7145
6889
  updateFromRingState = (ringState) => {
7146
- this.setCurrentValue(this.sessionSubject, (session) => {
6890
+ setCurrentValue(this.sessionSubject, (session) => {
7147
6891
  if (!session || session.id !== ringState.session_id)
7148
6892
  return session;
7149
6893
  return {
@@ -7194,21 +6938,21 @@ class CallState {
7194
6938
  this.setAnonymousParticipantCount(participantCount?.anonymous || 0);
7195
6939
  this.setStartedAt(startedAt ? Timestamp.toDate(startedAt) : new Date());
7196
6940
  this.setServerSidePins(pins);
7197
- this.setCurrentValue(this.e2eeEnabledSubject, e2EeEnabled);
6941
+ setCurrentValue(this.e2eeEnabledSubject, e2EeEnabled);
7198
6942
  };
7199
6943
  updateFromMemberRemoved = (event) => {
7200
6944
  this.updateFromCallResponse(event.call);
7201
- this.setCurrentValue(this.membersSubject, (members) => members.filter((m) => event.members.indexOf(m.user_id) === -1));
6945
+ setCurrentValue(this.membersSubject, (members) => members.filter((m) => event.members.indexOf(m.user_id) === -1));
7202
6946
  };
7203
6947
  updateFromMemberAdded = (event) => {
7204
6948
  this.updateFromCallResponse(event.call);
7205
- this.setCurrentValue(this.membersSubject, (members) => [
6949
+ setCurrentValue(this.membersSubject, (members) => [
7206
6950
  ...members,
7207
6951
  ...event.members,
7208
6952
  ]);
7209
6953
  };
7210
6954
  updateFromHLSBroadcastStopped = () => {
7211
- this.setCurrentValue(this.egressSubject, (egress = defaultEgress) => ({
6955
+ setCurrentValue(this.egressSubject, (egress = defaultEgress) => ({
7212
6956
  ...egress,
7213
6957
  broadcasting: false,
7214
6958
  hls: {
@@ -7218,7 +6962,7 @@ class CallState {
7218
6962
  }));
7219
6963
  };
7220
6964
  updateFromHLSBroadcastingFailed = () => {
7221
- this.setCurrentValue(this.egressSubject, (egress = defaultEgress) => ({
6965
+ setCurrentValue(this.egressSubject, (egress = defaultEgress) => ({
7222
6966
  ...egress,
7223
6967
  broadcasting: false,
7224
6968
  hls: {
@@ -7230,13 +6974,13 @@ class CallState {
7230
6974
  updateFromRecordingEvent = (type, running) => {
7231
6975
  // handle the legacy format, where `type` is absent in the emitted events
7232
6976
  if (type === undefined || type === 'composite') {
7233
- this.setCurrentValue(this.recordingSubject, running);
6977
+ setCurrentValue(this.recordingSubject, running);
7234
6978
  }
7235
6979
  else if (type === 'individual') {
7236
- this.setCurrentValue(this.individualRecordingSubject, running);
6980
+ setCurrentValue(this.individualRecordingSubject, running);
7237
6981
  }
7238
6982
  else if (type === 'raw') {
7239
- this.setCurrentValue(this.rawRecordingSubject, running);
6983
+ setCurrentValue(this.rawRecordingSubject, running);
7240
6984
  }
7241
6985
  else {
7242
6986
  ensureExhausted(type, 'Unknown recording type');
@@ -7253,7 +6997,7 @@ class CallState {
7253
6997
  this.setAnonymousParticipantCount(session.anonymous_participant_count || 0);
7254
6998
  };
7255
6999
  updateFromSessionParticipantCountUpdate = (event) => {
7256
- const s = this.setCurrentValue(this.sessionSubject, (session) => {
7000
+ const s = setCurrentValue(this.sessionSubject, (session) => {
7257
7001
  if (!session)
7258
7002
  return session;
7259
7003
  return {
@@ -7265,7 +7009,7 @@ class CallState {
7265
7009
  this.updateParticipantCountFromSession(s);
7266
7010
  };
7267
7011
  updateFromSessionParticipantLeft = (event) => {
7268
- const s = this.setCurrentValue(this.sessionSubject, (session) => {
7012
+ const s = setCurrentValue(this.sessionSubject, (session) => {
7269
7013
  if (!session)
7270
7014
  return session;
7271
7015
  const { participants, participants_count_by_role } = session;
@@ -7282,7 +7026,7 @@ class CallState {
7282
7026
  this.updateParticipantCountFromSession(s);
7283
7027
  };
7284
7028
  updateFromSessionParticipantJoined = (event) => {
7285
- const s = this.setCurrentValue(this.sessionSubject, (session) => {
7029
+ const s = setCurrentValue(this.sessionSubject, (session) => {
7286
7030
  if (!session)
7287
7031
  return session;
7288
7032
  const { participants, participants_count_by_role } = session;
@@ -7319,7 +7063,7 @@ class CallState {
7319
7063
  };
7320
7064
  updateMembers = (event) => {
7321
7065
  this.updateFromCallResponse(event.call);
7322
- this.setCurrentValue(this.membersSubject, (members) => members.map((member) => {
7066
+ setCurrentValue(this.membersSubject, (members) => members.map((member) => {
7323
7067
  const memberUpdate = event.members.find((m) => m.user_id === member.user_id);
7324
7068
  return memberUpdate ? memberUpdate : member;
7325
7069
  }));
@@ -7344,14 +7088,14 @@ class CallState {
7344
7088
  });
7345
7089
  };
7346
7090
  unblockUser = (event) => {
7347
- this.setCurrentValue(this.blockedUserIdsSubject, (current) => {
7091
+ setCurrentValue(this.blockedUserIdsSubject, (current) => {
7348
7092
  if (!current)
7349
7093
  return current;
7350
7094
  return current.filter((id) => id !== event.user.id);
7351
7095
  });
7352
7096
  };
7353
7097
  blockUser = (event) => {
7354
- this.setCurrentValue(this.blockedUserIdsSubject, (current) => [
7098
+ setCurrentValue(this.blockedUserIdsSubject, (current) => [
7355
7099
  ...(current || []),
7356
7100
  event.user.id,
7357
7101
  ]);
@@ -7362,7 +7106,7 @@ class CallState {
7362
7106
  }
7363
7107
  };
7364
7108
  updateFromClosedCaptions = (event) => {
7365
- this.setCurrentValue(this.closedCaptionsSubject, (queue) => {
7109
+ setCurrentValue(this.closedCaptionsSubject, (queue) => {
7366
7110
  const { closed_caption } = event;
7367
7111
  const keyOf = (c) => `${c.speaker_id}/${c.start_time}`;
7368
7112
  const currentKey = keyOf(closed_caption);
@@ -7374,7 +7118,7 @@ class CallState {
7374
7118
  // schedule the removal of the closed caption after the retention time
7375
7119
  if (visibilityDurationMs > 0) {
7376
7120
  const taskId = setTimeout(() => {
7377
- this.setCurrentValue(this.closedCaptionsSubject, (captions) => captions.filter((caption) => caption !== closed_caption));
7121
+ setCurrentValue(this.closedCaptionsSubject, (captions) => captions.filter((caption) => caption !== closed_caption));
7378
7122
  this.closedCaptionsTasks.delete(currentKey);
7379
7123
  }, visibilityDurationMs);
7380
7124
  this.closedCaptionsTasks.set(currentKey, taskId);
@@ -15596,7 +15340,7 @@ class Call {
15596
15340
  lastStatsOptions;
15597
15341
  ringTimeout;
15598
15342
  ringStatePoller;
15599
- clientStore;
15343
+ clientState;
15600
15344
  streamClient;
15601
15345
  clientEventReporter;
15602
15346
  sfuClient;
@@ -15663,7 +15407,7 @@ class Call {
15663
15407
  * Use the [`StreamVideoClient.call`](./StreamVideoClient.md/#call)
15664
15408
  * method to construct a `Call` instance.
15665
15409
  */
15666
- constructor({ type, id, streamClient, clientEventReporter, members, ownCapabilities, sortParticipantsBy, clientStore, ringing = false, watching = false, }) {
15410
+ constructor({ type, id, streamClient, clientEventReporter, members, ownCapabilities, sortParticipantsBy, clientState, ringing = false, watching = false, }) {
15667
15411
  this.type = type;
15668
15412
  this.id = id;
15669
15413
  this.cid = `${type}:${id}`;
@@ -15671,7 +15415,7 @@ class Call {
15671
15415
  this.watching = watching;
15672
15416
  this.streamClient = streamClient;
15673
15417
  this.clientEventReporter = clientEventReporter;
15674
- this.clientStore = clientStore;
15418
+ this.clientState = clientState;
15675
15419
  this.streamClientBasePath = `/call/${this.type}/${this.id}`;
15676
15420
  this.logger = videoLoggerSystem.getLogger('Call');
15677
15421
  const callTypeConfig = CallTypes.get(type);
@@ -15790,7 +15534,7 @@ class Call {
15790
15534
  };
15791
15535
  handleRingingCall = () => {
15792
15536
  const callSession = this.state.session;
15793
- const receiver_id = this.clientStore.connectedUser?.id;
15537
+ const receiver_id = this.clientState.connectedUser?.id;
15794
15538
  const ended_at = callSession?.ended_at;
15795
15539
  const created_by_id = this.state.createdBy?.id;
15796
15540
  if (this.currentUserId && created_by_id === this.currentUserId) {
@@ -16019,7 +15763,7 @@ class Call {
16019
15763
  this.ringingSubject.next(false);
16020
15764
  this.cancelAutoDrop();
16021
15765
  this.cancelRingStatePolling();
16022
- this.clientStore.unregisterCall(this);
15766
+ this.clientState.unregisterCall(this);
16023
15767
  globalThis.streamRNVideoSDK?.callManager.stop({
16024
15768
  isRingingTypeCall: this.ringing,
16025
15769
  shouldStopCallManager: this.callManagerStarted,
@@ -16078,7 +15822,7 @@ class Call {
16078
15822
  * Retrieves the current user ID.
16079
15823
  */
16080
15824
  get currentUserId() {
16081
- return this.clientStore.connectedUser?.id;
15825
+ return this.clientState.connectedUser?.id;
16082
15826
  }
16083
15827
  /**
16084
15828
  * A flag indicating whether self-subscription is enabled for the call.
@@ -16139,8 +15883,8 @@ class Call {
16139
15883
  this.ringingSubject.next(true);
16140
15884
  // we remove the instance from the calls list to enable the following filter in useCalls hook
16141
15885
  // const calls = useCalls().filter((c) => c.ringing);
16142
- const calls = this.clientStore.calls.filter((c) => c.cid !== this.cid);
16143
- this.clientStore.setCalls([this, ...calls]);
15886
+ const calls = this.clientState.calls.filter((c) => c.cid !== this.cid);
15887
+ this.clientState.setCalls([this, ...calls]);
16144
15888
  await this.applyDeviceConfig(settings, { publish: false });
16145
15889
  };
16146
15890
  /**
@@ -16174,7 +15918,7 @@ class Call {
16174
15918
  }
16175
15919
  if (this.streamClient._hasConnectionID()) {
16176
15920
  this.watching = true;
16177
- this.clientStore.registerOrUpdateCall(this);
15921
+ this.clientState.registerOrUpdateCall(this);
16178
15922
  }
16179
15923
  await this.applyDeviceConfig(response.call.settings, { publish: false });
16180
15924
  return response;
@@ -16193,7 +15937,7 @@ class Call {
16193
15937
  }
16194
15938
  if (this.streamClient._hasConnectionID()) {
16195
15939
  this.watching = true;
16196
- this.clientStore.registerOrUpdateCall(this);
15940
+ this.clientState.registerOrUpdateCall(this);
16197
15941
  }
16198
15942
  await this.applyDeviceConfig(response.call.settings, { publish: false });
16199
15943
  return response;
@@ -16314,7 +16058,7 @@ class Call {
16314
16058
  }
16315
16059
  if (callingX) {
16316
16060
  // for Android/iOS, we need to start the call in the callingx library as soon as possible
16317
- await callingX.joinCall(this, this.clientStore.calls, supersededByLeave);
16061
+ await callingX.joinCall(this, this.clientState.calls, supersededByLeave);
16318
16062
  if (supersededByLeave()) {
16319
16063
  this.logger.debug('Join superseded by leave; not setting up');
16320
16064
  return;
@@ -16844,7 +16588,7 @@ class Call {
16844
16588
  }
16845
16589
  if (this.streamClient._hasConnectionID()) {
16846
16590
  this.watching = true;
16847
- this.clientStore.registerOrUpdateCall(this);
16591
+ this.clientState.registerOrUpdateCall(this);
16848
16592
  }
16849
16593
  return joinResponse;
16850
16594
  };
@@ -17532,7 +17276,7 @@ class Call {
17532
17276
  });
17533
17277
  };
17534
17278
  /**
17535
- * Will enhance the reported stats with additional participant-specific information (`callStatsReport$` state [store variable](./StreamVideoClient.md/#readonlystatestore)).
17279
+ * Will enhance the reported stats with additional participant-specific information (the `callStatsReport$` state variable).
17536
17280
  * This is usually helpful when detailed stats for a specific participant are needed.
17537
17281
  *
17538
17282
  * @param sessionId the sessionId to start reporting for.
@@ -19651,11 +19395,11 @@ class StreamClient {
19651
19395
  return await this.wsConnection.connect(this.defaultWSTimeout);
19652
19396
  };
19653
19397
  getSdkVersion = () => this.options.clientAppIdentifier?.sdkVersion ||
19654
- "1.61.0";
19398
+ "2.0.0-beta.1";
19655
19399
  getUserAgent = () => {
19656
19400
  if (!this.cachedUserAgent) {
19657
19401
  const { clientAppIdentifier = {} } = this.options;
19658
- const { sdkName = 'js', sdkVersion = "1.61.0", ...extras } = clientAppIdentifier;
19402
+ const { sdkName = 'js', sdkVersion = "2.0.0-beta.1", ...extras } = clientAppIdentifier;
19659
19403
  this.cachedUserAgent = [
19660
19404
  `stream-video-${sdkName}-v${sdkVersion}`,
19661
19405
  ...Object.entries(extras).map(([key, value]) => `${key}=${value}`),
@@ -20411,16 +20155,11 @@ const mapWsJoinError = (err) => {
20411
20155
  */
20412
20156
  class StreamVideoClient {
20413
20157
  /**
20414
- * A reactive store that exposes all the state variables reactively.
20158
+ * The reactive state of this client.
20415
20159
  * You can subscribe to changes of the different state variables.
20416
- * Our library is built in a way that all state changes are exposed in this store,
20417
- * o all UI changes in your application should be handled by subscribing to these variables.
20418
- *
20419
- * @deprecated use the `client.state` getter.
20420
20160
  */
20421
- readOnlyStateStore;
20161
+ state = new ClientState();
20422
20162
  logger;
20423
- writeableStateStore;
20424
20163
  streamClient;
20425
20164
  clientEventReporter;
20426
20165
  effectsRegistered = false;
@@ -20445,8 +20184,6 @@ class StreamVideoClient {
20445
20184
  streamClient: this.streamClient,
20446
20185
  enabled: clientOptions?.clientEventsReportingEnabled ?? true,
20447
20186
  });
20448
- this.writeableStateStore = new StreamVideoWriteableStateStore();
20449
- this.readOnlyStateStore = new StreamVideoReadOnlyStateStore(this.writeableStateStore);
20450
20187
  if (typeof apiKeyOrArgs !== 'string' && apiKeyOrArgs.user) {
20451
20188
  const user = apiKeyOrArgs.user;
20452
20189
  if (user.type === 'anonymous')
@@ -20483,19 +20220,13 @@ class StreamVideoClient {
20483
20220
  }
20484
20221
  StreamVideoClient._instances.set(instanceKey, this);
20485
20222
  };
20486
- /**
20487
- * Return the reactive state store, use this if you want to be notified about changes to the client state
20488
- */
20489
- get state() {
20490
- return this.readOnlyStateStore;
20491
- }
20492
20223
  registerEffects = () => {
20493
20224
  if (this.effectsRegistered)
20494
20225
  return;
20495
20226
  this.eventHandlersToUnregister.push(this.on('call.created', (event) => this.initCallFromEvent(event)), this.on('call.ring', (event) => this.initCallFromEvent(event)), this.on('connection.changed', (event) => {
20496
20227
  if (!event.online)
20497
20228
  return;
20498
- const callsToReWatch = this.writeableStateStore.calls
20229
+ const callsToReWatch = this.state.calls
20499
20230
  .filter((call) => call.watching)
20500
20231
  .map((call) => call.cid);
20501
20232
  if (callsToReWatch.length <= 0)
@@ -20515,7 +20246,7 @@ class StreamVideoClient {
20515
20246
  const concurrencyTag = getCallInitConcurrencyTag(e.call_cid);
20516
20247
  await withoutConcurrency(concurrencyTag, async () => {
20517
20248
  const ringing = e.type === 'call.ring';
20518
- let call = this.writeableStateStore.findCall(e.call.type, e.call.id);
20249
+ let call = this.state.findCall(e.call.type, e.call.id);
20519
20250
  if (call) {
20520
20251
  if (ringing) {
20521
20252
  if (this.shouldRejectCall(call.cid)) {
@@ -20541,7 +20272,7 @@ class StreamVideoClient {
20541
20272
  type: e.call.type,
20542
20273
  id: e.call.id,
20543
20274
  members: e.members,
20544
- clientStore: this.writeableStateStore,
20275
+ clientState: this.state,
20545
20276
  ringing,
20546
20277
  });
20547
20278
  if (ringing) {
@@ -20557,7 +20288,7 @@ class StreamVideoClient {
20557
20288
  }
20558
20289
  else {
20559
20290
  call.state.updateFromCallResponse(e.call);
20560
- this.writeableStateStore.registerCall(call);
20291
+ this.state.registerCall(call);
20561
20292
  this.logger.info(`New call created and registered: ${call.cid}`);
20562
20293
  }
20563
20294
  });
@@ -20588,7 +20319,7 @@ class StreamVideoClient {
20588
20319
  filter_conditions: { cid: { $in: callsToReWatch } },
20589
20320
  });
20590
20321
  for (const c of response.calls) {
20591
- const call = this.writeableStateStore.findCall(c.call.type, c.call.id);
20322
+ const call = this.state.findCall(c.call.type, c.call.id);
20592
20323
  if (call) {
20593
20324
  call.updateFromCallStateResponse(c);
20594
20325
  }
@@ -20609,8 +20340,6 @@ class StreamVideoClient {
20609
20340
  };
20610
20341
  /**
20611
20342
  * Connects the given user to the client.
20612
- * Only one user can connect at a time, if you want to change users, call `disconnectUser` before connecting a new user.
20613
- * If the connection is successful, the connected user [state variable](#readonlystatestore) will be updated accordingly.
20614
20343
  *
20615
20344
  * @param user the user to connect.
20616
20345
  * @param tokenOrProvider a token or a function that returns a token.
@@ -20654,24 +20383,40 @@ class StreamVideoClient {
20654
20383
  });
20655
20384
  // connectUserResponse will be void if connectUser called twice for the same user
20656
20385
  if (connectUserResponse?.me) {
20657
- this.writeableStateStore.setConnectedUser(connectUserResponse.me);
20386
+ this.state.setConnectedUser(connectUserResponse.me);
20658
20387
  }
20659
20388
  this.registerEffects();
20660
20389
  return connectUserResponse;
20661
20390
  };
20391
+ /**
20392
+ * Leaves every call this client still tracks. Runs while the coordinator
20393
+ * connection is alive, so that the leave requests each call sends reach the
20394
+ * backend.
20395
+ */
20396
+ leaveAllCalls = async () => {
20397
+ for (const call of this.state.calls) {
20398
+ if (call.state.callingState === exports.CallingState.LEFT)
20399
+ continue;
20400
+ this.logger.info(`User disconnected, leaving call: ${call.cid}`);
20401
+ await call
20402
+ .leave({ message: 'client.disconnectUser() called' })
20403
+ .catch((err) => {
20404
+ this.logger.error(`Error leaving call: ${call.cid}`, err);
20405
+ });
20406
+ }
20407
+ };
20662
20408
  /**
20663
20409
  * Disconnects the currently connected user from the client.
20664
- *
20665
- * If the connection is successfully disconnected, the connected user [state variable](#readonlystatestore) will be updated accordingly
20410
+ * Leaves every call the user is still in, and updates `client.state`accordingly.
20666
20411
  *
20667
20412
  * @param timeout Max number of ms, to wait for close event of websocket, before forcefully assuming successful disconnection.
20668
- * https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
20669
20413
  */
20670
20414
  disconnectUser = async (timeout) => {
20671
20415
  await withoutConcurrency(this.connectionConcurrencyTag, async () => {
20672
20416
  const { user, key } = this.streamClient;
20673
20417
  if (!user)
20674
20418
  return;
20419
+ await this.leaveAllCalls();
20675
20420
  await this.streamClient.disconnectUser(timeout);
20676
20421
  if (user.id) {
20677
20422
  StreamVideoClient._instances.delete(getInstanceKey(key, user));
@@ -20679,13 +20424,15 @@ class StreamVideoClient {
20679
20424
  this.eventHandlersToUnregister.forEach((unregister) => unregister());
20680
20425
  this.eventHandlersToUnregister = [];
20681
20426
  this.effectsRegistered = false;
20682
- this.writeableStateStore.setConnectedUser(undefined);
20427
+ this.state.setConnectedUser(undefined);
20683
20428
  });
20684
20429
  };
20685
20430
  /**
20686
20431
  * You can subscribe to WebSocket events provided by the API.
20687
20432
  * To remove a subscription, call the `off` method or, execute the returned unsubscribe function.
20688
- * Please note that subscribing to WebSocket events is an advanced use-case, for most use-cases it should be enough to watch for changes in the reactive [state store](#readonlystatestore).
20433
+ * Please note that subscribing to WebSocket events is an advanced use-case,
20434
+ * for most use-cases it should be enough to watch for changes in the reactive
20435
+ * `client.state`.
20689
20436
  *
20690
20437
  * @param eventName the event name or 'all'.
20691
20438
  * @param callback the callback which will be called when the event is emitted.
@@ -20712,7 +20459,7 @@ class StreamVideoClient {
20712
20459
  */
20713
20460
  call = (type, id, options = {}) => {
20714
20461
  const call = options.reuseInstance
20715
- ? this.writeableStateStore.findCall(type, id)
20462
+ ? this.state.findCall(type, id)
20716
20463
  : undefined;
20717
20464
  return (call ??
20718
20465
  new Call({
@@ -20720,7 +20467,7 @@ class StreamVideoClient {
20720
20467
  clientEventReporter: this.clientEventReporter,
20721
20468
  id: id,
20722
20469
  type: type,
20723
- clientStore: this.writeableStateStore,
20470
+ clientState: this.state,
20724
20471
  }));
20725
20472
  };
20726
20473
  /**
@@ -20750,7 +20497,7 @@ class StreamVideoClient {
20750
20497
  members: c.members,
20751
20498
  ownCapabilities: c.own_capabilities,
20752
20499
  watching: data.watch,
20753
- clientStore: this.writeableStateStore,
20500
+ clientState: this.state,
20754
20501
  });
20755
20502
  call.state.updateFromCallResponse(c.call);
20756
20503
  await call.applyDeviceConfig(c.call.settings, {
@@ -20759,7 +20506,7 @@ class StreamVideoClient {
20759
20506
  });
20760
20507
  if (data.watch) {
20761
20508
  await call.setup();
20762
- this.writeableStateStore.registerCall(call);
20509
+ this.state.registerCall(call);
20763
20510
  }
20764
20511
  calls.push(call);
20765
20512
  }
@@ -20858,7 +20605,7 @@ class StreamVideoClient {
20858
20605
  clientEventReporter: this.clientEventReporter,
20859
20606
  type: callType,
20860
20607
  id: callId,
20861
- clientStore: this.writeableStateStore,
20608
+ clientState: this.state,
20862
20609
  ringing: true,
20863
20610
  });
20864
20611
  await call.get();
@@ -21476,6 +21223,7 @@ exports.CallType = CallType;
21476
21223
  exports.CallTypes = CallTypes;
21477
21224
  exports.CameraManager = CameraManager;
21478
21225
  exports.CameraManagerState = CameraManagerState;
21226
+ exports.ClientState = ClientState;
21479
21227
  exports.CreateDeviceRequestPushProviderEnum = CreateDeviceRequestPushProviderEnum;
21480
21228
  exports.DEFAULT_LOOPBACK_RECORDING_DURATION_MS = DEFAULT_LOOPBACK_RECORDING_DURATION_MS;
21481
21229
  exports.DeviceManager = DeviceManager;
@@ -21525,8 +21273,6 @@ exports.StartClosedCaptionsRequestLanguageEnum = StartClosedCaptionsRequestLangu
21525
21273
  exports.StartTranscriptionRequestLanguageEnum = StartTranscriptionRequestLanguageEnum;
21526
21274
  exports.StreamSfuClient = StreamSfuClient;
21527
21275
  exports.StreamVideoClient = StreamVideoClient;
21528
- exports.StreamVideoReadOnlyStateStore = StreamVideoReadOnlyStateStore;
21529
- exports.StreamVideoWriteableStateStore = StreamVideoWriteableStateStore;
21530
21276
  exports.TranscriptionSettingsRequestClosedCaptionModeEnum = TranscriptionSettingsRequestClosedCaptionModeEnum;
21531
21277
  exports.TranscriptionSettingsRequestLanguageEnum = TranscriptionSettingsRequestLanguageEnum;
21532
21278
  exports.TranscriptionSettingsRequestModeEnum = TranscriptionSettingsRequestModeEnum;