@stream-io/video-client 1.27.3 → 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 +6 -0
- package/dist/index.browser.es.js +169 -138
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +169 -138
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +169 -138
- package/dist/index.es.js.map +1 -1
- package/dist/src/helpers/browsers.d.ts +7 -0
- package/package.json +1 -1
- 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/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
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
|
+
|
|
5
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)
|
|
6
12
|
|
|
7
13
|
### 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.3";
|
|
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']);
|
|
@@ -14514,7 +14545,7 @@ class StreamClient {
|
|
|
14514
14545
|
this.getUserAgent = () => {
|
|
14515
14546
|
if (!this.cachedUserAgent) {
|
|
14516
14547
|
const { clientAppIdentifier = {} } = this.options;
|
|
14517
|
-
const { sdkName = 'js', sdkVersion = "1.27.
|
|
14548
|
+
const { sdkName = 'js', sdkVersion = "1.27.4", ...extras } = clientAppIdentifier;
|
|
14518
14549
|
this.cachedUserAgent = [
|
|
14519
14550
|
`stream-video-${sdkName}-v${sdkVersion}`,
|
|
14520
14551
|
...Object.entries(extras).map(([key, value]) => `${key}=${value}`),
|