@stream-io/video-client 1.7.2 → 1.7.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 +14 -0
- package/dist/index.browser.es.js +71 -36
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +71 -36
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +71 -36
- package/dist/index.es.js.map +1 -1
- package/dist/src/coordinator/connection/client.d.ts +4 -0
- package/dist/src/coordinator/connection/location.d.ts +1 -1
- package/dist/src/coordinator/connection/types.d.ts +4 -0
- package/dist/src/coordinator/connection/utils.d.ts +4 -0
- package/package.json +1 -1
- package/src/__tests__/Call.test.ts +40 -0
- package/src/coordinator/connection/client.ts +26 -13
- package/src/coordinator/connection/connection.ts +11 -0
- package/src/coordinator/connection/location.ts +28 -22
- package/src/coordinator/connection/types.ts +4 -0
- package/src/coordinator/connection/utils.ts +11 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
## [1.7.4](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.7.3...@stream-io/video-client-1.7.4) (2024-10-02)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* retryable location hint ([#1505](https://github.com/GetStream/stream-video-js/issues/1505)) ([087417f](https://github.com/GetStream/stream-video-js/commit/087417f926b3d43a5bcb814ac9bb5951c1e63479))
|
|
11
|
+
|
|
12
|
+
## [1.7.3](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.7.2...@stream-io/video-client-1.7.3) (2024-09-24)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* do not always error out api calls when web socket initially failed ([#1495](https://github.com/GetStream/stream-video-js/issues/1495)) ([7cdb62e](https://github.com/GetStream/stream-video-js/commit/7cdb62e75cad56098ee81eabbcc63382f93fd218))
|
|
18
|
+
|
|
5
19
|
## [1.7.2](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.7.1...@stream-io/video-client-1.7.2) (2024-09-20)
|
|
6
20
|
|
|
7
21
|
|
package/dist/index.browser.es.js
CHANGED
|
@@ -2875,6 +2875,13 @@ function convertErrorToJson(err) {
|
|
|
2875
2875
|
}
|
|
2876
2876
|
return jsonObj;
|
|
2877
2877
|
}
|
|
2878
|
+
/**
|
|
2879
|
+
* Informs if a promise is yet to be resolved or rejected
|
|
2880
|
+
*/
|
|
2881
|
+
async function isPromisePending(promise) {
|
|
2882
|
+
const emptyObj = {};
|
|
2883
|
+
return Promise.race([promise, emptyObj]).then((value) => (value === emptyObj ? true : false), () => false);
|
|
2884
|
+
}
|
|
2878
2885
|
/**
|
|
2879
2886
|
* isOnline safely return the navigator.online value for browser env
|
|
2880
2887
|
* if navigator is not in global object, it always return true
|
|
@@ -2928,7 +2935,7 @@ const logLevels = Object.freeze({
|
|
|
2928
2935
|
warn: 3,
|
|
2929
2936
|
error: 4,
|
|
2930
2937
|
});
|
|
2931
|
-
let logger
|
|
2938
|
+
let logger;
|
|
2932
2939
|
let level = 'info';
|
|
2933
2940
|
const logToConsole = (logLevel, message, ...args) => {
|
|
2934
2941
|
let logMethod;
|
|
@@ -2962,7 +2969,7 @@ const logToConsole = (logLevel, message, ...args) => {
|
|
|
2962
2969
|
logMethod(message, ...args);
|
|
2963
2970
|
};
|
|
2964
2971
|
const setLogger = (l, lvl) => {
|
|
2965
|
-
logger
|
|
2972
|
+
logger = l;
|
|
2966
2973
|
if (lvl) {
|
|
2967
2974
|
setLogLevel(lvl);
|
|
2968
2975
|
}
|
|
@@ -2972,7 +2979,7 @@ const setLogLevel = (l) => {
|
|
|
2972
2979
|
};
|
|
2973
2980
|
const getLogLevel = () => level;
|
|
2974
2981
|
const getLogger = (withTags) => {
|
|
2975
|
-
const loggerMethod = logger
|
|
2982
|
+
const loggerMethod = logger || logToConsole;
|
|
2976
2983
|
const tags = (withTags || []).filter(Boolean).join(':');
|
|
2977
2984
|
const result = (logLevel, message, ...args) => {
|
|
2978
2985
|
if (logLevels[logLevel] >= logLevels[level]) {
|
|
@@ -3013,7 +3020,7 @@ const retryable = async (rpc, signal) => {
|
|
|
3013
3020
|
return result;
|
|
3014
3021
|
};
|
|
3015
3022
|
|
|
3016
|
-
const version = "1.7.
|
|
3023
|
+
const version = "1.7.4";
|
|
3017
3024
|
const [major, minor, patch] = version.split('.');
|
|
3018
3025
|
let sdkInfo = {
|
|
3019
3026
|
type: SdkType.PLAIN_JAVASCRIPT,
|
|
@@ -11365,6 +11372,15 @@ class StableWSConnection {
|
|
|
11365
11372
|
this._log(`_connect() - tokenProvider failed before, so going to retry`);
|
|
11366
11373
|
await this.client.tokenManager.loadToken();
|
|
11367
11374
|
}
|
|
11375
|
+
let mustSetupConnectionIdPromise = true;
|
|
11376
|
+
if (this.client.connectionIdPromise) {
|
|
11377
|
+
if (await isPromisePending(this.client.connectionIdPromise)) {
|
|
11378
|
+
mustSetupConnectionIdPromise = false;
|
|
11379
|
+
}
|
|
11380
|
+
}
|
|
11381
|
+
if (mustSetupConnectionIdPromise) {
|
|
11382
|
+
this.client._setupConnectionIdPromise();
|
|
11383
|
+
}
|
|
11368
11384
|
this._setupConnectionPromise();
|
|
11369
11385
|
const wsURL = this._buildUrl();
|
|
11370
11386
|
this._log(`_connect() - Connecting to ${wsURL}`, {
|
|
@@ -11390,6 +11406,7 @@ class StableWSConnection {
|
|
|
11390
11406
|
}
|
|
11391
11407
|
}
|
|
11392
11408
|
catch (err) {
|
|
11409
|
+
await this.client._setupConnectionIdPromise();
|
|
11393
11410
|
this.isConnecting = false;
|
|
11394
11411
|
// @ts-ignore
|
|
11395
11412
|
this._log(`_connect() - Error - `, err);
|
|
@@ -11891,27 +11908,31 @@ class WSConnectionFallback {
|
|
|
11891
11908
|
}
|
|
11892
11909
|
}
|
|
11893
11910
|
|
|
11894
|
-
const
|
|
11895
|
-
const
|
|
11896
|
-
|
|
11897
|
-
|
|
11898
|
-
|
|
11899
|
-
|
|
11900
|
-
const
|
|
11901
|
-
|
|
11902
|
-
|
|
11903
|
-
|
|
11904
|
-
|
|
11905
|
-
|
|
11906
|
-
|
|
11907
|
-
|
|
11908
|
-
|
|
11909
|
-
|
|
11910
|
-
|
|
11911
|
-
|
|
11912
|
-
|
|
11913
|
-
|
|
11914
|
-
|
|
11911
|
+
const getLocationHint = async (hintUrl = `https://hint.stream-io-video.com/`, timeout = 2000, maxAttempts = 3) => {
|
|
11912
|
+
const logger = getLogger(['location-hint']);
|
|
11913
|
+
let attempt = 0;
|
|
11914
|
+
let locationHint = 'ERR';
|
|
11915
|
+
do {
|
|
11916
|
+
const abortController = new AbortController();
|
|
11917
|
+
const timeoutId = setTimeout(() => abortController.abort(), timeout);
|
|
11918
|
+
try {
|
|
11919
|
+
const response = await fetch(hintUrl, {
|
|
11920
|
+
method: 'HEAD',
|
|
11921
|
+
signal: abortController.signal,
|
|
11922
|
+
});
|
|
11923
|
+
const awsPop = response.headers.get('x-amz-cf-pop') || 'ERR';
|
|
11924
|
+
logger('debug', `Location header: ${awsPop}`);
|
|
11925
|
+
locationHint = awsPop.substring(0, 3); // AMS1-P2 -> AMS
|
|
11926
|
+
}
|
|
11927
|
+
catch (e) {
|
|
11928
|
+
logger('warn', `Failed to get location hint from ${hintUrl}`, e);
|
|
11929
|
+
locationHint = 'ERR';
|
|
11930
|
+
}
|
|
11931
|
+
finally {
|
|
11932
|
+
clearTimeout(timeoutId);
|
|
11933
|
+
}
|
|
11934
|
+
} while (locationHint === 'ERR' && ++attempt < maxAttempts);
|
|
11935
|
+
return locationHint;
|
|
11915
11936
|
};
|
|
11916
11937
|
|
|
11917
11938
|
class StreamClient {
|
|
@@ -12047,10 +12068,7 @@ class StreamClient {
|
|
|
12047
12068
|
this.logger('info', 'client:openConnection() - openConnection called twice, healthy connection already exists');
|
|
12048
12069
|
return Promise.resolve();
|
|
12049
12070
|
}
|
|
12050
|
-
this.
|
|
12051
|
-
this.resolveConnectionId = resolve;
|
|
12052
|
-
this.rejectConnectionId = reject;
|
|
12053
|
-
});
|
|
12071
|
+
this._setupConnectionIdPromise();
|
|
12054
12072
|
this.clientID = `${this.userID}--${randomId()}`;
|
|
12055
12073
|
this.wsPromise = this.connect();
|
|
12056
12074
|
return this.wsPromise;
|
|
@@ -12090,10 +12108,7 @@ class StreamClient {
|
|
|
12090
12108
|
*/
|
|
12091
12109
|
this.connectAnonymousUser = async (user, tokenOrProvider) => {
|
|
12092
12110
|
addConnectionEventListeners(this.updateNetworkConnectionStatus);
|
|
12093
|
-
this.
|
|
12094
|
-
this.resolveConnectionId = resolve;
|
|
12095
|
-
this.rejectConnectionId = reject;
|
|
12096
|
-
});
|
|
12111
|
+
this._setupConnectionIdPromise();
|
|
12097
12112
|
this.anonymous = true;
|
|
12098
12113
|
await this._setToken(user, tokenOrProvider, this.anonymous);
|
|
12099
12114
|
this._setUser(user);
|
|
@@ -12132,6 +12147,16 @@ class StreamClient {
|
|
|
12132
12147
|
this.logger('debug', `Removing listener for ${eventName} event`);
|
|
12133
12148
|
this.listeners[eventName] = this.listeners[eventName]?.filter((value) => value !== callback);
|
|
12134
12149
|
};
|
|
12150
|
+
/**
|
|
12151
|
+
* sets up the this.connectionIdPromise
|
|
12152
|
+
*/
|
|
12153
|
+
this._setupConnectionIdPromise = async () => {
|
|
12154
|
+
/** a promise that is resolved once connection id is set */
|
|
12155
|
+
this.connectionIdPromise = new Promise((resolve, reject) => {
|
|
12156
|
+
this.resolveConnectionId = resolve;
|
|
12157
|
+
this.rejectConnectionId = reject;
|
|
12158
|
+
});
|
|
12159
|
+
};
|
|
12135
12160
|
this._logApiRequest = (type, url, data, config) => {
|
|
12136
12161
|
this.logger('trace', `client: ${type} - Request - ${url}`, {
|
|
12137
12162
|
payload: data,
|
|
@@ -12154,8 +12179,18 @@ class StreamClient {
|
|
|
12154
12179
|
await Promise.all([
|
|
12155
12180
|
this.tokenManager.tokenReady(),
|
|
12156
12181
|
this.guestUserCreatePromise,
|
|
12157
|
-
this.connectionIdPromise,
|
|
12158
12182
|
]);
|
|
12183
|
+
// we need to wait for presence of connection id before making requests
|
|
12184
|
+
try {
|
|
12185
|
+
await this.connectionIdPromise;
|
|
12186
|
+
}
|
|
12187
|
+
catch (e) {
|
|
12188
|
+
// in case connection id was rejected
|
|
12189
|
+
// reconnection maybe in progress
|
|
12190
|
+
// we can wait for healthy connection to resolve, which rejects when 15s timeout is reached
|
|
12191
|
+
await this.wsConnection?._waitForHealthy();
|
|
12192
|
+
await this.connectionIdPromise;
|
|
12193
|
+
}
|
|
12159
12194
|
}
|
|
12160
12195
|
const requestConfig = this._enrichAxiosOptions(options);
|
|
12161
12196
|
try {
|
|
@@ -12338,7 +12373,7 @@ class StreamClient {
|
|
|
12338
12373
|
});
|
|
12339
12374
|
};
|
|
12340
12375
|
this.getUserAgent = () => {
|
|
12341
|
-
const version = "1.7.
|
|
12376
|
+
const version = "1.7.4";
|
|
12342
12377
|
return (this.userAgent ||
|
|
12343
12378
|
`stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
|
|
12344
12379
|
};
|
|
@@ -12421,7 +12456,7 @@ class StreamClient {
|
|
|
12421
12456
|
this.browser = inputOptions.browser || typeof window !== 'undefined';
|
|
12422
12457
|
this.node = !this.browser;
|
|
12423
12458
|
if (this.browser) {
|
|
12424
|
-
this.locationHint = getLocationHint(options?.locationHintUrl, options?.locationHintTimeout);
|
|
12459
|
+
this.locationHint = getLocationHint(options?.locationHintUrl, options?.locationHintTimeout, options?.locationHintMaxAttempts);
|
|
12425
12460
|
}
|
|
12426
12461
|
this.options = {
|
|
12427
12462
|
timeout: 5000,
|