@stream-io/video-client 1.27.2 → 1.27.4
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 +195 -148
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +195 -148
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +195 -148
- package/dist/index.es.js.map +1 -1
- package/dist/src/StreamSfuClient.d.ts +0 -1
- package/dist/src/helpers/browsers.d.ts +7 -0
- package/dist/src/rtc/signal.d.ts +2 -0
- package/package.json +1 -1
- package/src/StreamSfuClient.ts +19 -14
- package/src/helpers/__tests__/browsers.test.ts +191 -0
- package/src/helpers/browsers.ts +25 -0
- package/src/helpers/client-details.ts +18 -3
- package/src/rtc/signal.ts +10 -6
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.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
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- expose isSupportedBrowser() utility ([#1859](https://github.com/GetStream/stream-video-js/issues/1859)) ([f51a434](https://github.com/GetStream/stream-video-js/commit/f51a4341f57407210ab2e9ba57f41818ddbd7ed9))
|
|
10
|
+
|
|
11
|
+
## [1.27.3](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.27.2...@stream-io/video-client-1.27.3) (2025-08-07)
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
- extended telemetry data for the signal websocket ([#1881](https://github.com/GetStream/stream-video-js/issues/1881)) ([984703d](https://github.com/GetStream/stream-video-js/commit/984703dabb8c6189eaf4d6925421568f6d0fd7fc))
|
|
16
|
+
|
|
5
17
|
## [1.27.2](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.27.1...@stream-io/video-client-1.27.2) (2025-08-05)
|
|
6
18
|
|
|
7
19
|
### Bug Fixes
|
package/dist/index.browser.es.js
CHANGED
|
@@ -5643,6 +5643,151 @@ const getSdkVersion = (sdk) => {
|
|
|
5643
5643
|
return sdk ? `${sdk.major}.${sdk.minor}.${sdk.patch}` : '0.0.0-development';
|
|
5644
5644
|
};
|
|
5645
5645
|
|
|
5646
|
+
const version = "1.27.4";
|
|
5647
|
+
const [major, minor, patch] = version.split('.');
|
|
5648
|
+
let sdkInfo = {
|
|
5649
|
+
type: SdkType.PLAIN_JAVASCRIPT,
|
|
5650
|
+
major,
|
|
5651
|
+
minor,
|
|
5652
|
+
patch,
|
|
5653
|
+
};
|
|
5654
|
+
let osInfo;
|
|
5655
|
+
let deviceInfo;
|
|
5656
|
+
let webRtcInfo;
|
|
5657
|
+
let deviceState = { oneofKind: undefined };
|
|
5658
|
+
const setSdkInfo = (info) => {
|
|
5659
|
+
sdkInfo = info;
|
|
5660
|
+
};
|
|
5661
|
+
const getSdkInfo = () => {
|
|
5662
|
+
return sdkInfo;
|
|
5663
|
+
};
|
|
5664
|
+
const setOSInfo = (info) => {
|
|
5665
|
+
osInfo = info;
|
|
5666
|
+
};
|
|
5667
|
+
const setDeviceInfo = (info) => {
|
|
5668
|
+
deviceInfo = info;
|
|
5669
|
+
};
|
|
5670
|
+
const getWebRTCInfo = () => {
|
|
5671
|
+
return webRtcInfo;
|
|
5672
|
+
};
|
|
5673
|
+
const setWebRTCInfo = (info) => {
|
|
5674
|
+
webRtcInfo = info;
|
|
5675
|
+
};
|
|
5676
|
+
const setThermalState = (state) => {
|
|
5677
|
+
if (!osInfo) {
|
|
5678
|
+
deviceState = { oneofKind: undefined };
|
|
5679
|
+
return;
|
|
5680
|
+
}
|
|
5681
|
+
if (osInfo.name === 'android') {
|
|
5682
|
+
const thermalState = AndroidThermalState[state] ||
|
|
5683
|
+
AndroidThermalState.UNSPECIFIED;
|
|
5684
|
+
deviceState = {
|
|
5685
|
+
oneofKind: 'android',
|
|
5686
|
+
android: {
|
|
5687
|
+
thermalState,
|
|
5688
|
+
isPowerSaverMode: deviceState?.oneofKind === 'android' &&
|
|
5689
|
+
deviceState.android.isPowerSaverMode,
|
|
5690
|
+
},
|
|
5691
|
+
};
|
|
5692
|
+
}
|
|
5693
|
+
if (osInfo.name.toLowerCase() === 'ios') {
|
|
5694
|
+
const thermalState = AppleThermalState[state] ||
|
|
5695
|
+
AppleThermalState.UNSPECIFIED;
|
|
5696
|
+
deviceState = {
|
|
5697
|
+
oneofKind: 'apple',
|
|
5698
|
+
apple: {
|
|
5699
|
+
thermalState,
|
|
5700
|
+
isLowPowerModeEnabled: deviceState?.oneofKind === 'apple' &&
|
|
5701
|
+
deviceState.apple.isLowPowerModeEnabled,
|
|
5702
|
+
},
|
|
5703
|
+
};
|
|
5704
|
+
}
|
|
5705
|
+
};
|
|
5706
|
+
const setPowerState = (powerMode) => {
|
|
5707
|
+
if (!osInfo) {
|
|
5708
|
+
deviceState = { oneofKind: undefined };
|
|
5709
|
+
return;
|
|
5710
|
+
}
|
|
5711
|
+
if (osInfo.name === 'android') {
|
|
5712
|
+
deviceState = {
|
|
5713
|
+
oneofKind: 'android',
|
|
5714
|
+
android: {
|
|
5715
|
+
thermalState: deviceState?.oneofKind === 'android'
|
|
5716
|
+
? deviceState.android.thermalState
|
|
5717
|
+
: AndroidThermalState.UNSPECIFIED,
|
|
5718
|
+
isPowerSaverMode: powerMode,
|
|
5719
|
+
},
|
|
5720
|
+
};
|
|
5721
|
+
}
|
|
5722
|
+
if (osInfo.name.toLowerCase() === 'ios') {
|
|
5723
|
+
deviceState = {
|
|
5724
|
+
oneofKind: 'apple',
|
|
5725
|
+
apple: {
|
|
5726
|
+
thermalState: deviceState?.oneofKind === 'apple'
|
|
5727
|
+
? deviceState.apple.thermalState
|
|
5728
|
+
: AppleThermalState.UNSPECIFIED,
|
|
5729
|
+
isLowPowerModeEnabled: powerMode,
|
|
5730
|
+
},
|
|
5731
|
+
};
|
|
5732
|
+
}
|
|
5733
|
+
};
|
|
5734
|
+
const getDeviceState = () => {
|
|
5735
|
+
return deviceState;
|
|
5736
|
+
};
|
|
5737
|
+
const getClientDetails = async () => {
|
|
5738
|
+
if (isReactNative()) {
|
|
5739
|
+
// Since RN doesn't support web, sharing browser info is not required
|
|
5740
|
+
return {
|
|
5741
|
+
sdk: sdkInfo,
|
|
5742
|
+
os: osInfo,
|
|
5743
|
+
device: deviceInfo,
|
|
5744
|
+
};
|
|
5745
|
+
}
|
|
5746
|
+
// @ts-expect-error - userAgentData is not yet in the TS types
|
|
5747
|
+
const userAgentDataApi = navigator.userAgentData;
|
|
5748
|
+
let userAgentData;
|
|
5749
|
+
if (userAgentDataApi && userAgentDataApi.getHighEntropyValues) {
|
|
5750
|
+
try {
|
|
5751
|
+
userAgentData = await userAgentDataApi.getHighEntropyValues([
|
|
5752
|
+
'platform',
|
|
5753
|
+
'platformVersion',
|
|
5754
|
+
'fullVersionList',
|
|
5755
|
+
]);
|
|
5756
|
+
}
|
|
5757
|
+
catch {
|
|
5758
|
+
// Ignore the error
|
|
5759
|
+
}
|
|
5760
|
+
}
|
|
5761
|
+
const userAgent = new UAParser(navigator.userAgent);
|
|
5762
|
+
const { browser, os, device, cpu } = userAgent.getResult();
|
|
5763
|
+
// If userAgentData is available, it means we are in a modern Chromium browser,
|
|
5764
|
+
// and we can use it to get more accurate browser information.
|
|
5765
|
+
// We hook into the fullVersionList to find the browser name and version and
|
|
5766
|
+
// eventually detect exotic browsers like Samsung Internet, AVG Secure Browser, etc.
|
|
5767
|
+
// who by default they identify themselves as "Chromium" in the user agent string.
|
|
5768
|
+
// Eliminates the generic "Chromium" name and "Not)A_Brand" name from the list.
|
|
5769
|
+
// https://wicg.github.io/ua-client-hints/#create-arbitrary-brands-section
|
|
5770
|
+
const uaBrowser = userAgentData?.fullVersionList?.find((v) => !v.brand.includes('Chromium') && !v.brand.match(/[()\-./:;=?_]/g));
|
|
5771
|
+
return {
|
|
5772
|
+
sdk: sdkInfo,
|
|
5773
|
+
browser: {
|
|
5774
|
+
name: uaBrowser?.brand || browser.name || navigator.userAgent,
|
|
5775
|
+
version: uaBrowser?.version || browser.version || '',
|
|
5776
|
+
},
|
|
5777
|
+
os: {
|
|
5778
|
+
name: userAgentData?.platform || os.name || '',
|
|
5779
|
+
version: userAgentData?.platformVersion || os.version || '',
|
|
5780
|
+
architecture: cpu.architecture || '',
|
|
5781
|
+
},
|
|
5782
|
+
device: {
|
|
5783
|
+
name: [device.vendor, device.model, device.type]
|
|
5784
|
+
.filter(Boolean)
|
|
5785
|
+
.join(' '),
|
|
5786
|
+
version: '',
|
|
5787
|
+
},
|
|
5788
|
+
};
|
|
5789
|
+
};
|
|
5790
|
+
|
|
5646
5791
|
/**
|
|
5647
5792
|
* Checks whether the current browser is Safari.
|
|
5648
5793
|
*/
|
|
@@ -5667,12 +5812,34 @@ const isChrome = () => {
|
|
|
5667
5812
|
return false;
|
|
5668
5813
|
return navigator.userAgent?.includes('Chrome');
|
|
5669
5814
|
};
|
|
5815
|
+
/**
|
|
5816
|
+
* Checks whether the current browser is among the list of first-class supported browsers.
|
|
5817
|
+
* This includes Chrome, Edge, Firefox, and Safari.
|
|
5818
|
+
*
|
|
5819
|
+
* Although the Stream Video SDK may work in other browsers, these are the ones we officially support.
|
|
5820
|
+
*/
|
|
5821
|
+
const isSupportedBrowser = async () => {
|
|
5822
|
+
const { browser } = await getClientDetails();
|
|
5823
|
+
if (!browser)
|
|
5824
|
+
return false; // we aren't running in a browser
|
|
5825
|
+
const name = browser.name.toLowerCase();
|
|
5826
|
+
const [major] = browser.version.split('.');
|
|
5827
|
+
const version = parseInt(major, 10);
|
|
5828
|
+
return ((name.includes('chrome') && version >= 124) ||
|
|
5829
|
+
(name.includes('edge') && version >= 124) ||
|
|
5830
|
+
(name.includes('firefox') && version >= 124) ||
|
|
5831
|
+
(name.includes('safari') && version >= 17) ||
|
|
5832
|
+
(name.includes('webkit') && version >= 605) || // WebView on iOS
|
|
5833
|
+
(name.includes('webview') && version >= 124) // WebView on Android
|
|
5834
|
+
);
|
|
5835
|
+
};
|
|
5670
5836
|
|
|
5671
5837
|
var browsers = /*#__PURE__*/Object.freeze({
|
|
5672
5838
|
__proto__: null,
|
|
5673
5839
|
isChrome: isChrome,
|
|
5674
5840
|
isFirefox: isFirefox,
|
|
5675
|
-
isSafari: isSafari
|
|
5841
|
+
isSafari: isSafari,
|
|
5842
|
+
isSupportedBrowser: isSupportedBrowser
|
|
5676
5843
|
});
|
|
5677
5844
|
|
|
5678
5845
|
/**
|
|
@@ -5914,142 +6081,6 @@ const aggregate = (stats) => {
|
|
|
5914
6081
|
return report;
|
|
5915
6082
|
};
|
|
5916
6083
|
|
|
5917
|
-
const version = "1.27.2";
|
|
5918
|
-
const [major, minor, patch] = version.split('.');
|
|
5919
|
-
let sdkInfo = {
|
|
5920
|
-
type: SdkType.PLAIN_JAVASCRIPT,
|
|
5921
|
-
major,
|
|
5922
|
-
minor,
|
|
5923
|
-
patch,
|
|
5924
|
-
};
|
|
5925
|
-
let osInfo;
|
|
5926
|
-
let deviceInfo;
|
|
5927
|
-
let webRtcInfo;
|
|
5928
|
-
let deviceState = { oneofKind: undefined };
|
|
5929
|
-
const setSdkInfo = (info) => {
|
|
5930
|
-
sdkInfo = info;
|
|
5931
|
-
};
|
|
5932
|
-
const getSdkInfo = () => {
|
|
5933
|
-
return sdkInfo;
|
|
5934
|
-
};
|
|
5935
|
-
const setOSInfo = (info) => {
|
|
5936
|
-
osInfo = info;
|
|
5937
|
-
};
|
|
5938
|
-
const setDeviceInfo = (info) => {
|
|
5939
|
-
deviceInfo = info;
|
|
5940
|
-
};
|
|
5941
|
-
const getWebRTCInfo = () => {
|
|
5942
|
-
return webRtcInfo;
|
|
5943
|
-
};
|
|
5944
|
-
const setWebRTCInfo = (info) => {
|
|
5945
|
-
webRtcInfo = info;
|
|
5946
|
-
};
|
|
5947
|
-
const setThermalState = (state) => {
|
|
5948
|
-
if (!osInfo) {
|
|
5949
|
-
deviceState = { oneofKind: undefined };
|
|
5950
|
-
return;
|
|
5951
|
-
}
|
|
5952
|
-
if (osInfo.name === 'android') {
|
|
5953
|
-
const thermalState = AndroidThermalState[state] ||
|
|
5954
|
-
AndroidThermalState.UNSPECIFIED;
|
|
5955
|
-
deviceState = {
|
|
5956
|
-
oneofKind: 'android',
|
|
5957
|
-
android: {
|
|
5958
|
-
thermalState,
|
|
5959
|
-
isPowerSaverMode: deviceState?.oneofKind === 'android' &&
|
|
5960
|
-
deviceState.android.isPowerSaverMode,
|
|
5961
|
-
},
|
|
5962
|
-
};
|
|
5963
|
-
}
|
|
5964
|
-
if (osInfo.name.toLowerCase() === 'ios') {
|
|
5965
|
-
const thermalState = AppleThermalState[state] ||
|
|
5966
|
-
AppleThermalState.UNSPECIFIED;
|
|
5967
|
-
deviceState = {
|
|
5968
|
-
oneofKind: 'apple',
|
|
5969
|
-
apple: {
|
|
5970
|
-
thermalState,
|
|
5971
|
-
isLowPowerModeEnabled: deviceState?.oneofKind === 'apple' &&
|
|
5972
|
-
deviceState.apple.isLowPowerModeEnabled,
|
|
5973
|
-
},
|
|
5974
|
-
};
|
|
5975
|
-
}
|
|
5976
|
-
};
|
|
5977
|
-
const setPowerState = (powerMode) => {
|
|
5978
|
-
if (!osInfo) {
|
|
5979
|
-
deviceState = { oneofKind: undefined };
|
|
5980
|
-
return;
|
|
5981
|
-
}
|
|
5982
|
-
if (osInfo.name === 'android') {
|
|
5983
|
-
deviceState = {
|
|
5984
|
-
oneofKind: 'android',
|
|
5985
|
-
android: {
|
|
5986
|
-
thermalState: deviceState?.oneofKind === 'android'
|
|
5987
|
-
? deviceState.android.thermalState
|
|
5988
|
-
: AndroidThermalState.UNSPECIFIED,
|
|
5989
|
-
isPowerSaverMode: powerMode,
|
|
5990
|
-
},
|
|
5991
|
-
};
|
|
5992
|
-
}
|
|
5993
|
-
if (osInfo.name.toLowerCase() === 'ios') {
|
|
5994
|
-
deviceState = {
|
|
5995
|
-
oneofKind: 'apple',
|
|
5996
|
-
apple: {
|
|
5997
|
-
thermalState: deviceState?.oneofKind === 'apple'
|
|
5998
|
-
? deviceState.apple.thermalState
|
|
5999
|
-
: AppleThermalState.UNSPECIFIED,
|
|
6000
|
-
isLowPowerModeEnabled: powerMode,
|
|
6001
|
-
},
|
|
6002
|
-
};
|
|
6003
|
-
}
|
|
6004
|
-
};
|
|
6005
|
-
const getDeviceState = () => {
|
|
6006
|
-
return deviceState;
|
|
6007
|
-
};
|
|
6008
|
-
const getClientDetails = async () => {
|
|
6009
|
-
if (isReactNative()) {
|
|
6010
|
-
// Since RN doesn't support web, sharing browser info is not required
|
|
6011
|
-
return {
|
|
6012
|
-
sdk: sdkInfo,
|
|
6013
|
-
os: osInfo,
|
|
6014
|
-
device: deviceInfo,
|
|
6015
|
-
};
|
|
6016
|
-
}
|
|
6017
|
-
// @ts-expect-error - userAgentData is not yet in the TS types
|
|
6018
|
-
const userAgentDataApi = navigator.userAgentData;
|
|
6019
|
-
let userAgentData;
|
|
6020
|
-
if (userAgentDataApi && userAgentDataApi.getHighEntropyValues) {
|
|
6021
|
-
try {
|
|
6022
|
-
userAgentData = await userAgentDataApi.getHighEntropyValues([
|
|
6023
|
-
'platform',
|
|
6024
|
-
'platformVersion',
|
|
6025
|
-
]);
|
|
6026
|
-
}
|
|
6027
|
-
catch {
|
|
6028
|
-
// Ignore the error
|
|
6029
|
-
}
|
|
6030
|
-
}
|
|
6031
|
-
const userAgent = new UAParser(navigator.userAgent);
|
|
6032
|
-
const { browser, os, device, cpu } = userAgent.getResult();
|
|
6033
|
-
return {
|
|
6034
|
-
sdk: sdkInfo,
|
|
6035
|
-
browser: {
|
|
6036
|
-
name: browser.name || navigator.userAgent,
|
|
6037
|
-
version: browser.version || '',
|
|
6038
|
-
},
|
|
6039
|
-
os: {
|
|
6040
|
-
name: userAgentData?.platform || os.name || '',
|
|
6041
|
-
version: userAgentData?.platformVersion || os.version || '',
|
|
6042
|
-
architecture: cpu.architecture || '',
|
|
6043
|
-
},
|
|
6044
|
-
device: {
|
|
6045
|
-
name: [device.vendor, device.model, device.type]
|
|
6046
|
-
.filter(Boolean)
|
|
6047
|
-
.join(' '),
|
|
6048
|
-
version: '',
|
|
6049
|
-
},
|
|
6050
|
-
};
|
|
6051
|
-
};
|
|
6052
|
-
|
|
6053
6084
|
class SfuStatsReporter {
|
|
6054
6085
|
constructor(sfuClient, { options, clientDetails, subscriber, publisher, microphone, camera, state, tracer, unifiedSessionId, }) {
|
|
6055
6086
|
this.logger = getLogger(['SfuStatsReporter']);
|
|
@@ -7633,19 +7664,22 @@ class Subscriber extends BasePeerConnection {
|
|
|
7633
7664
|
}
|
|
7634
7665
|
|
|
7635
7666
|
const createWebSocketSignalChannel = (opts) => {
|
|
7636
|
-
const { endpoint, onMessage, tag } = opts;
|
|
7667
|
+
const { endpoint, onMessage, tag, tracer } = opts;
|
|
7637
7668
|
const logger = getLogger(['SfuClientWS', tag]);
|
|
7638
7669
|
logger('debug', 'Creating signaling WS channel:', endpoint);
|
|
7639
7670
|
const ws = new WebSocket(endpoint);
|
|
7640
7671
|
ws.binaryType = 'arraybuffer'; // do we need this?
|
|
7641
7672
|
ws.addEventListener('error', (e) => {
|
|
7642
7673
|
logger('error', 'Signaling WS channel error', e);
|
|
7674
|
+
tracer?.trace('signal.ws.error', e);
|
|
7643
7675
|
});
|
|
7644
7676
|
ws.addEventListener('close', (e) => {
|
|
7645
7677
|
logger('info', 'Signaling WS channel is closed', e);
|
|
7678
|
+
tracer?.trace('signal.ws.close', e);
|
|
7646
7679
|
});
|
|
7647
7680
|
ws.addEventListener('open', (e) => {
|
|
7648
7681
|
logger('info', 'Signaling WS channel is open', e);
|
|
7682
|
+
tracer?.trace('signal.ws.open', e);
|
|
7649
7683
|
});
|
|
7650
7684
|
ws.addEventListener('message', (e) => {
|
|
7651
7685
|
try {
|
|
@@ -7655,7 +7689,9 @@ const createWebSocketSignalChannel = (opts) => {
|
|
|
7655
7689
|
onMessage(message);
|
|
7656
7690
|
}
|
|
7657
7691
|
catch (err) {
|
|
7658
|
-
|
|
7692
|
+
const message = 'Failed to decode a message. Check whether the Proto models match.';
|
|
7693
|
+
logger('error', message, { event: e, error: err });
|
|
7694
|
+
tracer?.trace('signal.ws.message.error', message);
|
|
7659
7695
|
}
|
|
7660
7696
|
});
|
|
7661
7697
|
return ws;
|
|
@@ -7927,6 +7963,7 @@ class StreamSfuClient {
|
|
|
7927
7963
|
this.signalWs = createWebSocketSignalChannel({
|
|
7928
7964
|
tag: this.tag,
|
|
7929
7965
|
endpoint: `${this.credentials.server.ws_endpoint}?${new URLSearchParams(params).toString()}`,
|
|
7966
|
+
tracer: this.tracer,
|
|
7930
7967
|
onMessage: (message) => {
|
|
7931
7968
|
this.lastMessageTimestamp = new Date();
|
|
7932
7969
|
this.scheduleConnectionCheck();
|
|
@@ -7937,9 +7974,13 @@ class StreamSfuClient {
|
|
|
7937
7974
|
this.dispatcher.dispatch(message, this.tag);
|
|
7938
7975
|
},
|
|
7939
7976
|
});
|
|
7977
|
+
let timeoutId;
|
|
7940
7978
|
this.signalReady = makeSafePromise(Promise.race([
|
|
7941
7979
|
new Promise((resolve, reject) => {
|
|
7980
|
+
let didOpen = false;
|
|
7942
7981
|
const onOpen = () => {
|
|
7982
|
+
didOpen = true;
|
|
7983
|
+
clearTimeout(timeoutId);
|
|
7943
7984
|
this.signalWs.removeEventListener('open', onOpen);
|
|
7944
7985
|
resolve(this.signalWs);
|
|
7945
7986
|
};
|
|
@@ -7947,19 +7988,25 @@ class StreamSfuClient {
|
|
|
7947
7988
|
this.signalWs.addEventListener('close', (e) => {
|
|
7948
7989
|
this.handleWebSocketClose(e);
|
|
7949
7990
|
// Normally, this shouldn't have any effect, because WS should never emit 'close'
|
|
7950
|
-
// before emitting 'open'. However,
|
|
7951
|
-
// want to leave signalReady in pending state.
|
|
7952
|
-
|
|
7991
|
+
// before emitting 'open'. However, stranger things have happened, and we don't
|
|
7992
|
+
// want to leave signalReady in a pending state.
|
|
7993
|
+
const message = didOpen
|
|
7994
|
+
? `SFU WS closed: ${e.code} ${e.reason}`
|
|
7995
|
+
: `SFU WS connection can't be established: ${e.code} ${e.reason}`;
|
|
7996
|
+
this.tracer?.trace('signal.close', message);
|
|
7997
|
+
clearTimeout(timeoutId);
|
|
7998
|
+
reject(new Error(message));
|
|
7953
7999
|
});
|
|
7954
8000
|
}),
|
|
7955
8001
|
new Promise((resolve, reject) => {
|
|
7956
|
-
setTimeout(() =>
|
|
8002
|
+
timeoutId = setTimeout(() => {
|
|
8003
|
+
const message = `SFU WS connection failed to open after ${this.joinResponseTimeout}ms`;
|
|
8004
|
+
this.tracer?.trace('signal.timeout', message);
|
|
8005
|
+
reject(new Error(message));
|
|
8006
|
+
}, this.joinResponseTimeout);
|
|
7957
8007
|
}),
|
|
7958
8008
|
]));
|
|
7959
8009
|
};
|
|
7960
|
-
this.cleanUpWebSocket = () => {
|
|
7961
|
-
this.signalWs.removeEventListener('close', this.handleWebSocketClose);
|
|
7962
|
-
};
|
|
7963
8010
|
this.handleWebSocketClose = (e) => {
|
|
7964
8011
|
this.signalWs.removeEventListener('close', this.handleWebSocketClose);
|
|
7965
8012
|
getTimers().clearInterval(this.keepAliveInterval);
|
|
@@ -7971,7 +8018,7 @@ class StreamSfuClient {
|
|
|
7971
8018
|
if (this.signalWs.readyState === WebSocket.OPEN) {
|
|
7972
8019
|
this.logger('debug', `Closing SFU WS connection: ${code} - ${reason}`);
|
|
7973
8020
|
this.signalWs.close(code, `js-client: ${reason}`);
|
|
7974
|
-
this.
|
|
8021
|
+
this.signalWs.removeEventListener('close', this.handleWebSocketClose);
|
|
7975
8022
|
}
|
|
7976
8023
|
this.dispose();
|
|
7977
8024
|
};
|
|
@@ -14498,7 +14545,7 @@ class StreamClient {
|
|
|
14498
14545
|
this.getUserAgent = () => {
|
|
14499
14546
|
if (!this.cachedUserAgent) {
|
|
14500
14547
|
const { clientAppIdentifier = {} } = this.options;
|
|
14501
|
-
const { sdkName = 'js', sdkVersion = "1.27.
|
|
14548
|
+
const { sdkName = 'js', sdkVersion = "1.27.4", ...extras } = clientAppIdentifier;
|
|
14502
14549
|
this.cachedUserAgent = [
|
|
14503
14550
|
`stream-video-${sdkName}-v${sdkVersion}`,
|
|
14504
14551
|
...Object.entries(extras).map(([key, value]) => `${key}=${value}`),
|