@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 +12 -0
- package/dist/index.browser.es.js +97 -68
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +98 -67
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +97 -68
- package/dist/index.es.js.map +1 -1
- package/dist/src/Call.d.ts +6 -1
- package/dist/src/StreamVideoClient.d.ts +6 -0
- package/dist/src/gen/coordinator/index.d.ts +429 -0
- package/dist/src/helpers/clientUtils.d.ts +7 -0
- package/dist/src/store/stateStore.d.ts +0 -7
- package/package.json +1 -1
- package/src/Call.ts +13 -0
- package/src/StreamVideoClient.ts +63 -64
- package/src/__tests__/StreamVideoClient.ringing.test.ts +167 -0
- package/src/__tests__/clientTestUtils.ts +72 -0
- package/src/__tests__/data.ts +621 -0
- package/src/gen/coordinator/index.ts +429 -0
- package/src/helpers/__tests__/clientUtils.test.ts +8 -0
- package/src/helpers/clientUtils.ts +8 -0
- package/src/store/CallState.ts +2 -0
- package/src/store/stateStore.ts +0 -8
package/dist/index.cjs.js
CHANGED
|
@@ -61,6 +61,20 @@ const FrameRecordingSettingsResponseModeEnum = {
|
|
|
61
61
|
DISABLED: 'disabled',
|
|
62
62
|
AUTO_ON: 'auto-on',
|
|
63
63
|
};
|
|
64
|
+
/**
|
|
65
|
+
* @export
|
|
66
|
+
*/
|
|
67
|
+
const IngressAudioEncodingOptionsRequestChannelsEnum = {
|
|
68
|
+
NUMBER_1: 1,
|
|
69
|
+
NUMBER_2: 2,
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* @export
|
|
73
|
+
*/
|
|
74
|
+
const IngressVideoLayerRequestCodecEnum = {
|
|
75
|
+
H264: 'h264',
|
|
76
|
+
VP8: 'vp8',
|
|
77
|
+
};
|
|
64
78
|
/**
|
|
65
79
|
* @export
|
|
66
80
|
*/
|
|
@@ -93,6 +107,7 @@ const OwnCapability = {
|
|
|
93
107
|
JOIN_BACKSTAGE: 'join-backstage',
|
|
94
108
|
JOIN_CALL: 'join-call',
|
|
95
109
|
JOIN_ENDED_CALL: 'join-ended-call',
|
|
110
|
+
KICK_USER: 'kick-user',
|
|
96
111
|
MUTE_USERS: 'mute-users',
|
|
97
112
|
PIN_FOR_EVERYONE: 'pin-for-everyone',
|
|
98
113
|
READ_CALL: 'read-call',
|
|
@@ -4302,13 +4317,6 @@ class StreamVideoWriteableStateStore {
|
|
|
4302
4317
|
*/
|
|
4303
4318
|
class StreamVideoReadOnlyStateStore {
|
|
4304
4319
|
constructor(store) {
|
|
4305
|
-
/**
|
|
4306
|
-
* This method allows you the get the current value of a state variable.
|
|
4307
|
-
*
|
|
4308
|
-
* @param observable the observable to get the current value of.
|
|
4309
|
-
* @returns the current value of the observable.
|
|
4310
|
-
*/
|
|
4311
|
-
this.getCurrentValue = getCurrentValue;
|
|
4312
4320
|
// convert and expose subjects as observables
|
|
4313
4321
|
this.connectedUser$ = store.connectedUserSubject.asObservable();
|
|
4314
4322
|
this.calls$ = store.callsSubject.asObservable();
|
|
@@ -5296,6 +5304,7 @@ class CallState {
|
|
|
5296
5304
|
this.eventHandlers = {
|
|
5297
5305
|
// these events are not updating the call state:
|
|
5298
5306
|
'call.frame_recording_ready': undefined,
|
|
5307
|
+
'call.kicked_user': undefined,
|
|
5299
5308
|
'call.moderation_blur': undefined,
|
|
5300
5309
|
'call.moderation_warning': undefined,
|
|
5301
5310
|
'call.permission_request': undefined,
|
|
@@ -5305,6 +5314,7 @@ class CallState {
|
|
|
5305
5314
|
'call.rtmp_broadcast_stopped': undefined,
|
|
5306
5315
|
'call.stats_report_ready': undefined,
|
|
5307
5316
|
'call.transcription_ready': undefined,
|
|
5317
|
+
'call.user_feedback_submitted': undefined,
|
|
5308
5318
|
'call.user_muted': undefined,
|
|
5309
5319
|
'connection.error': undefined,
|
|
5310
5320
|
'connection.ok': undefined,
|
|
@@ -5645,7 +5655,7 @@ const getSdkVersion = (sdk) => {
|
|
|
5645
5655
|
return sdk ? `${sdk.major}.${sdk.minor}.${sdk.patch}` : '0.0.0-development';
|
|
5646
5656
|
};
|
|
5647
5657
|
|
|
5648
|
-
const version = "1.
|
|
5658
|
+
const version = "1.28.0";
|
|
5649
5659
|
const [major, minor, patch] = version.split('.');
|
|
5650
5660
|
let sdkInfo = {
|
|
5651
5661
|
type: SdkType.PLAIN_JAVASCRIPT,
|
|
@@ -12796,6 +12806,13 @@ class Call {
|
|
|
12796
12806
|
user_id: userId,
|
|
12797
12807
|
});
|
|
12798
12808
|
};
|
|
12809
|
+
/**
|
|
12810
|
+
* Kicks the user with the given `userId`.
|
|
12811
|
+
* @param data the kick request.
|
|
12812
|
+
*/
|
|
12813
|
+
this.kickUser = async (data) => {
|
|
12814
|
+
return this.streamClient.post(`${this.streamClientBasePath}/kick`, data);
|
|
12815
|
+
};
|
|
12799
12816
|
/**
|
|
12800
12817
|
* Mutes the current user.
|
|
12801
12818
|
*
|
|
@@ -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.
|
|
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.
|
|
14755
|
-
|
|
14756
|
-
|
|
14757
|
-
|
|
14758
|
-
|
|
14759
|
-
|
|
14760
|
-
|
|
14761
|
-
|
|
14762
|
-
|
|
14763
|
-
|
|
14764
|
-
|
|
14765
|
-
|
|
14766
|
-
|
|
14767
|
-
|
|
14768
|
-
|
|
14769
|
-
|
|
14770
|
-
|
|
14771
|
-
|
|
14772
|
-
|
|
14773
|
-
|
|
14774
|
-
|
|
14775
|
-
|
|
14776
|
-
|
|
14777
|
-
|
|
14778
|
-
|
|
14779
|
-
|
|
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
|
|
14809
|
+
ringing,
|
|
14793
14810
|
});
|
|
14794
|
-
|
|
14795
|
-
|
|
14796
|
-
|
|
14797
|
-
|
|
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
|
-
|
|
15028
|
-
|
|
15029
|
-
|
|
15030
|
-
|
|
15031
|
-
|
|
15032
|
-
|
|
15033
|
-
|
|
15034
|
-
|
|
15035
|
-
|
|
15036
|
-
|
|
15037
|
-
|
|
15038
|
-
|
|
15039
|
-
|
|
15040
|
-
|
|
15041
|
-
|
|
15042
|
-
|
|
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.
|
|
@@ -15117,6 +15146,8 @@ exports.ErrorFromResponse = ErrorFromResponse;
|
|
|
15117
15146
|
exports.FrameRecordingSettingsRequestModeEnum = FrameRecordingSettingsRequestModeEnum;
|
|
15118
15147
|
exports.FrameRecordingSettingsRequestQualityEnum = FrameRecordingSettingsRequestQualityEnum;
|
|
15119
15148
|
exports.FrameRecordingSettingsResponseModeEnum = FrameRecordingSettingsResponseModeEnum;
|
|
15149
|
+
exports.IngressAudioEncodingOptionsRequestChannelsEnum = IngressAudioEncodingOptionsRequestChannelsEnum;
|
|
15150
|
+
exports.IngressVideoLayerRequestCodecEnum = IngressVideoLayerRequestCodecEnum;
|
|
15120
15151
|
exports.InputMediaDeviceManager = InputMediaDeviceManager;
|
|
15121
15152
|
exports.InputMediaDeviceManagerState = InputMediaDeviceManagerState;
|
|
15122
15153
|
exports.LayoutSettingsRequestNameEnum = LayoutSettingsRequestNameEnum;
|