@stream-io/video-client 1.27.4 → 1.28.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 CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
4
 
5
+ ## [1.28.0](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.27.5...@stream-io/video-client-1.28.0) (2025-08-21)
6
+
7
+ ### Features
8
+
9
+ - Kick user from a call ([#1894](https://github.com/GetStream/stream-video-js/issues/1894)) ([32e2afc](https://github.com/GetStream/stream-video-js/commit/32e2afca0ea59e3f57e1ff9d05828c1e07fbff78))
10
+
11
+ ## [1.27.5](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.27.4...@stream-io/video-client-1.27.5) (2025-08-15)
12
+
13
+ ### Bug Fixes
14
+
15
+ - synchronize ring events ([#1888](https://github.com/GetStream/stream-video-js/issues/1888)) ([0951e6d](https://github.com/GetStream/stream-video-js/commit/0951e6d4c825806937d6bdc548df9f186c531466))
16
+
5
17
  ## [1.27.4](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.27.3...@stream-io/video-client-1.27.4) (2025-08-13)
6
18
 
7
19
  ### Bug Fixes
@@ -59,6 +59,20 @@ const FrameRecordingSettingsResponseModeEnum = {
59
59
  DISABLED: 'disabled',
60
60
  AUTO_ON: 'auto-on',
61
61
  };
62
+ /**
63
+ * @export
64
+ */
65
+ const IngressAudioEncodingOptionsRequestChannelsEnum = {
66
+ NUMBER_1: 1,
67
+ NUMBER_2: 2,
68
+ };
69
+ /**
70
+ * @export
71
+ */
72
+ const IngressVideoLayerRequestCodecEnum = {
73
+ H264: 'h264',
74
+ VP8: 'vp8',
75
+ };
62
76
  /**
63
77
  * @export
64
78
  */
@@ -91,6 +105,7 @@ const OwnCapability = {
91
105
  JOIN_BACKSTAGE: 'join-backstage',
92
106
  JOIN_CALL: 'join-call',
93
107
  JOIN_ENDED_CALL: 'join-ended-call',
108
+ KICK_USER: 'kick-user',
94
109
  MUTE_USERS: 'mute-users',
95
110
  PIN_FOR_EVERYONE: 'pin-for-everyone',
96
111
  READ_CALL: 'read-call',
@@ -4300,13 +4315,6 @@ class StreamVideoWriteableStateStore {
4300
4315
  */
4301
4316
  class StreamVideoReadOnlyStateStore {
4302
4317
  constructor(store) {
4303
- /**
4304
- * This method allows you the get the current value of a state variable.
4305
- *
4306
- * @param observable the observable to get the current value of.
4307
- * @returns the current value of the observable.
4308
- */
4309
- this.getCurrentValue = getCurrentValue;
4310
4318
  // convert and expose subjects as observables
4311
4319
  this.connectedUser$ = store.connectedUserSubject.asObservable();
4312
4320
  this.calls$ = store.callsSubject.asObservable();
@@ -5294,6 +5302,7 @@ class CallState {
5294
5302
  this.eventHandlers = {
5295
5303
  // these events are not updating the call state:
5296
5304
  'call.frame_recording_ready': undefined,
5305
+ 'call.kicked_user': undefined,
5297
5306
  'call.moderation_blur': undefined,
5298
5307
  'call.moderation_warning': undefined,
5299
5308
  'call.permission_request': undefined,
@@ -5303,6 +5312,7 @@ class CallState {
5303
5312
  'call.rtmp_broadcast_stopped': undefined,
5304
5313
  'call.stats_report_ready': undefined,
5305
5314
  'call.transcription_ready': undefined,
5315
+ 'call.user_feedback_submitted': undefined,
5306
5316
  'call.user_muted': undefined,
5307
5317
  'connection.error': undefined,
5308
5318
  'connection.ok': undefined,
@@ -5643,7 +5653,7 @@ const getSdkVersion = (sdk) => {
5643
5653
  return sdk ? `${sdk.major}.${sdk.minor}.${sdk.patch}` : '0.0.0-development';
5644
5654
  };
5645
5655
 
5646
- const version = "1.27.4";
5656
+ const version = "1.28.0";
5647
5657
  const [major, minor, patch] = version.split('.');
5648
5658
  let sdkInfo = {
5649
5659
  type: SdkType.PLAIN_JAVASCRIPT,
@@ -12794,6 +12804,13 @@ class Call {
12794
12804
  user_id: userId,
12795
12805
  });
12796
12806
  };
12807
+ /**
12808
+ * Kicks the user with the given `userId`.
12809
+ * @param data the kick request.
12810
+ */
12811
+ this.kickUser = async (data) => {
12812
+ return this.streamClient.post(`${this.streamClientBasePath}/kick`, data);
12813
+ };
12797
12814
  /**
12798
12815
  * Mutes the current user.
12799
12816
  *
@@ -14545,7 +14562,7 @@ class StreamClient {
14545
14562
  this.getUserAgent = () => {
14546
14563
  if (!this.cachedUserAgent) {
14547
14564
  const { clientAppIdentifier = {} } = this.options;
14548
- const { sdkName = 'js', sdkVersion = "1.27.4", ...extras } = clientAppIdentifier;
14565
+ const { sdkName = 'js', sdkVersion = "1.28.0", ...extras } = clientAppIdentifier;
14549
14566
  this.cachedUserAgent = [
14550
14567
  `stream-video-${sdkName}-v${sdkVersion}`,
14551
14568
  ...Object.entries(extras).map(([key, value]) => `${key}=${value}`),
@@ -14666,6 +14683,13 @@ class StreamClient {
14666
14683
  const getInstanceKey = (apiKey, user) => {
14667
14684
  return `${apiKey}/${user.id}`;
14668
14685
  };
14686
+ /**
14687
+ * Returns a concurrency tag for call initialization.
14688
+ * @internal
14689
+ *
14690
+ * @param cid the call cid.
14691
+ */
14692
+ const getCallInitConcurrencyTag = (cid) => `call.init-${cid}`;
14669
14693
  /**
14670
14694
  * Utility function to get the client app identifier.
14671
14695
  */
@@ -14734,7 +14758,7 @@ class StreamVideoClient {
14734
14758
  this.registerEffects = () => {
14735
14759
  if (this.effectsRegistered)
14736
14760
  return;
14737
- this.eventHandlersToUnregister.push(this.on('connection.changed', (event) => {
14761
+ this.eventHandlersToUnregister.push(this.on('call.created', (event) => this.initCallFromEvent(event)), this.on('call.ring', (event) => this.initCallFromEvent(event)), this.on('connection.changed', (event) => {
14738
14762
  if (!event.online)
14739
14763
  return;
14740
14764
  const callsToReWatch = this.writeableStateStore.calls
@@ -14751,50 +14775,52 @@ class StreamVideoClient {
14751
14775
  this.logger('error', 'Failed to re-watch calls', err);
14752
14776
  });
14753
14777
  }));
14754
- this.eventHandlersToUnregister.push(this.on('call.created', (event) => {
14755
- const { call, members } = event;
14756
- if (this.state.connectedUser?.id === call.created_by.id) {
14757
- this.logger('warn', 'Received `call.created` sent by the current user');
14758
- return;
14759
- }
14760
- this.logger('info', `New call created and registered: ${call.cid}`);
14761
- const newCall = new Call({
14762
- streamClient: this.streamClient,
14763
- type: call.type,
14764
- id: call.id,
14765
- members,
14766
- clientStore: this.writeableStateStore,
14767
- });
14768
- newCall.state.updateFromCallResponse(call);
14769
- this.writeableStateStore.registerCall(newCall);
14770
- }));
14771
- this.eventHandlersToUnregister.push(this.on('call.ring', async (event) => {
14772
- const { call, members } = event;
14773
- if (this.state.connectedUser?.id === call.created_by.id) {
14774
- this.logger('debug', 'Received `call.ring` sent by the current user so ignoring the event');
14775
- return;
14776
- }
14777
- // if `call.created` was received before `call.ring`.
14778
- // the client already has the call instance and we just need to update the state
14779
- const theCall = this.writeableStateStore.findCall(call.type, call.id);
14780
- if (theCall) {
14781
- await theCall.updateFromRingingEvent(event);
14782
- }
14783
- else {
14784
- // if client doesn't have the call instance, create the instance and fetch the latest state
14785
- // Note: related - we also have onRingingCall method to handle this case from push notifications
14786
- const newCallInstance = new Call({
14778
+ this.effectsRegistered = true;
14779
+ };
14780
+ /**
14781
+ * Initializes a call from a call created or ringing event.
14782
+ * @param e the event.
14783
+ */
14784
+ this.initCallFromEvent = async (e) => {
14785
+ if (this.state.connectedUser?.id === e.call.created_by.id) {
14786
+ this.logger('debug', `Ignoring ${e.type} event sent by the current user`);
14787
+ return;
14788
+ }
14789
+ try {
14790
+ const concurrencyTag = getCallInitConcurrencyTag(e.call_cid);
14791
+ await withoutConcurrency(concurrencyTag, async () => {
14792
+ const ringing = e.type === 'call.ring';
14793
+ let call = this.writeableStateStore.findCall(e.call.type, e.call.id);
14794
+ if (call) {
14795
+ if (ringing) {
14796
+ await call.updateFromRingingEvent(e);
14797
+ }
14798
+ else {
14799
+ call.state.updateFromCallResponse(e.call);
14800
+ }
14801
+ return;
14802
+ }
14803
+ call = new Call({
14787
14804
  streamClient: this.streamClient,
14788
- type: call.type,
14789
- id: call.id,
14790
- members,
14805
+ type: e.call.type,
14806
+ id: e.call.id,
14807
+ members: e.members,
14791
14808
  clientStore: this.writeableStateStore,
14792
- ringing: true,
14809
+ ringing,
14793
14810
  });
14794
- await newCallInstance.get();
14795
- }
14796
- }));
14797
- this.effectsRegistered = true;
14811
+ call.state.updateFromCallResponse(e.call);
14812
+ if (ringing) {
14813
+ await call.get();
14814
+ }
14815
+ else {
14816
+ this.writeableStateStore.registerCall(call);
14817
+ this.logger('info', `New call created and registered: ${call.cid}`);
14818
+ }
14819
+ });
14820
+ }
14821
+ catch (err) {
14822
+ this.logger('error', `Failed to init call from event ${e.type}`, err);
14823
+ }
14798
14824
  };
14799
14825
  /**
14800
14826
  * Connects the given user to the client.
@@ -14894,6 +14920,7 @@ class StreamVideoClient {
14894
14920
  *
14895
14921
  * @param type the type of the call.
14896
14922
  * @param id the id of the call.
14923
+ * @param options additional options for call creation.
14897
14924
  */
14898
14925
  this.call = (type, id, options = {}) => {
14899
14926
  const call = options.reuseInstance
@@ -15024,22 +15051,24 @@ class StreamVideoClient {
15024
15051
  * @returns
15025
15052
  */
15026
15053
  this.onRingingCall = async (call_cid) => {
15027
- // if we find the call and is already ringing, we don't need to create a new call
15028
- // as client would have received the call.ring state because the app had WS alive when receiving push notifications
15029
- let call = this.state.calls.find((c) => c.cid === call_cid && c.ringing);
15030
- if (!call) {
15031
- // if not it means that WS is not alive when receiving the push notifications and we need to fetch the call
15032
- const [callType, callId] = call_cid.split(':');
15033
- call = new Call({
15034
- streamClient: this.streamClient,
15035
- type: callType,
15036
- id: callId,
15037
- clientStore: this.writeableStateStore,
15038
- ringing: true,
15039
- });
15040
- await call.get();
15041
- }
15042
- return call;
15054
+ return withoutConcurrency(getCallInitConcurrencyTag(call_cid), async () => {
15055
+ // if we find the call and is already ringing, we don't need to create a new call
15056
+ // as client would have received the call.ring state because the app had WS alive when receiving push notifications
15057
+ let call = this.state.calls.find((c) => c.cid === call_cid && c.ringing);
15058
+ if (!call) {
15059
+ // if not it means that WS is not alive when receiving the push notifications and we need to fetch the call
15060
+ const [callType, callId] = call_cid.split(':');
15061
+ call = new Call({
15062
+ streamClient: this.streamClient,
15063
+ type: callType,
15064
+ id: callId,
15065
+ clientStore: this.writeableStateStore,
15066
+ ringing: true,
15067
+ });
15068
+ await call.get();
15069
+ }
15070
+ return call;
15071
+ });
15043
15072
  };
15044
15073
  /**
15045
15074
  * Connects the given anonymous user to the client.
@@ -15098,5 +15127,5 @@ class StreamVideoClient {
15098
15127
  }
15099
15128
  StreamVideoClient._instances = new Map();
15100
15129
 
15101
- export { AudioSettingsRequestDefaultDeviceEnum, AudioSettingsResponseDefaultDeviceEnum, browsers as Browsers, Call, CallState, CallType, CallTypes, CallingState, CameraManager, CameraManagerState, CreateDeviceRequestPushProviderEnum, DebounceType, DynascaleManager, ErrorFromResponse, FrameRecordingSettingsRequestModeEnum, FrameRecordingSettingsRequestQualityEnum, FrameRecordingSettingsResponseModeEnum, InputMediaDeviceManager, InputMediaDeviceManagerState, LayoutSettingsRequestNameEnum, MicrophoneManager, MicrophoneManagerState, NoiseCancellationSettingsModeEnum, OwnCapability, RNSpeechDetector, RTMPBroadcastRequestQualityEnum, RTMPSettingsRequestQualityEnum, RecordSettingsRequestModeEnum, RecordSettingsRequestQualityEnum, rxUtils as RxUtils, ScreenShareManager, ScreenShareState, events as SfuEvents, models as SfuModels, SpeakerManager, SpeakerState, StartClosedCaptionsRequestLanguageEnum, StartTranscriptionRequestLanguageEnum, StreamSfuClient, StreamVideoClient, StreamVideoReadOnlyStateStore, StreamVideoWriteableStateStore, TranscriptionSettingsRequestClosedCaptionModeEnum, TranscriptionSettingsRequestLanguageEnum, TranscriptionSettingsRequestModeEnum, TranscriptionSettingsResponseClosedCaptionModeEnum, TranscriptionSettingsResponseLanguageEnum, TranscriptionSettingsResponseModeEnum, VideoSettingsRequestCameraFacingEnum, VideoSettingsResponseCameraFacingEnum, ViewportTracker, VisibilityState, checkIfAudioOutputChangeSupported, combineComparators, conditional, createSoundDetector, defaultSortPreset, descending, deviceIds$, disposeOfMediaStream, dominantSpeaker, getAudioBrowserPermission, getAudioDevices, getAudioOutputDevices, getAudioStream, getClientDetails, getDeviceState, getLogLevel, getLogger, getScreenShareStream, getSdkInfo, getVideoBrowserPermission, getVideoDevices, getVideoStream, getWebRTCInfo, hasAudio, hasPausedTrack, hasScreenShare, hasScreenShareAudio, hasVideo, isPinned, livestreamOrAudioRoomSortPreset, logLevels, logToConsole, name, noopComparator, paginatedLayoutSortPreset, pinned, publishingAudio, publishingVideo, reactionType, resolveDeviceId, role, screenSharing, setDeviceInfo, setLogLevel, setLogger, setOSInfo, setPowerState, setSdkInfo, setThermalState, setWebRTCInfo, speakerLayoutSortPreset, speaking };
15130
+ export { AudioSettingsRequestDefaultDeviceEnum, AudioSettingsResponseDefaultDeviceEnum, browsers as Browsers, Call, CallState, CallType, CallTypes, CallingState, CameraManager, CameraManagerState, CreateDeviceRequestPushProviderEnum, DebounceType, DynascaleManager, ErrorFromResponse, FrameRecordingSettingsRequestModeEnum, FrameRecordingSettingsRequestQualityEnum, FrameRecordingSettingsResponseModeEnum, IngressAudioEncodingOptionsRequestChannelsEnum, IngressVideoLayerRequestCodecEnum, InputMediaDeviceManager, InputMediaDeviceManagerState, LayoutSettingsRequestNameEnum, MicrophoneManager, MicrophoneManagerState, NoiseCancellationSettingsModeEnum, OwnCapability, RNSpeechDetector, RTMPBroadcastRequestQualityEnum, RTMPSettingsRequestQualityEnum, RecordSettingsRequestModeEnum, RecordSettingsRequestQualityEnum, rxUtils as RxUtils, ScreenShareManager, ScreenShareState, events as SfuEvents, models as SfuModels, SpeakerManager, SpeakerState, StartClosedCaptionsRequestLanguageEnum, StartTranscriptionRequestLanguageEnum, StreamSfuClient, StreamVideoClient, StreamVideoReadOnlyStateStore, StreamVideoWriteableStateStore, TranscriptionSettingsRequestClosedCaptionModeEnum, TranscriptionSettingsRequestLanguageEnum, TranscriptionSettingsRequestModeEnum, TranscriptionSettingsResponseClosedCaptionModeEnum, TranscriptionSettingsResponseLanguageEnum, TranscriptionSettingsResponseModeEnum, VideoSettingsRequestCameraFacingEnum, VideoSettingsResponseCameraFacingEnum, ViewportTracker, VisibilityState, checkIfAudioOutputChangeSupported, combineComparators, conditional, createSoundDetector, defaultSortPreset, descending, deviceIds$, disposeOfMediaStream, dominantSpeaker, getAudioBrowserPermission, getAudioDevices, getAudioOutputDevices, getAudioStream, getClientDetails, getDeviceState, getLogLevel, getLogger, getScreenShareStream, getSdkInfo, getVideoBrowserPermission, getVideoDevices, getVideoStream, getWebRTCInfo, hasAudio, hasPausedTrack, hasScreenShare, hasScreenShareAudio, hasVideo, isPinned, livestreamOrAudioRoomSortPreset, logLevels, logToConsole, name, noopComparator, paginatedLayoutSortPreset, pinned, publishingAudio, publishingVideo, reactionType, resolveDeviceId, role, screenSharing, setDeviceInfo, setLogLevel, setLogger, setOSInfo, setPowerState, setSdkInfo, setThermalState, setWebRTCInfo, speakerLayoutSortPreset, speaking };
15102
15131
  //# sourceMappingURL=index.browser.es.js.map