@stream-io/video-client 1.16.6 → 1.17.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 +14 -0
- package/dist/index.browser.es.js +144 -139
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +143 -138
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.es.js +144 -139
- package/dist/index.es.js.map +1 -1
- package/dist/src/StreamVideoClient.d.ts +16 -16
- package/dist/src/coordinator/connection/token_manager.d.ts +8 -10
- package/dist/src/{client-details.d.ts → helpers/client-details.d.ts} +3 -3
- package/dist/src/helpers/clientUtils.d.ts +20 -0
- package/dist/src/stats/SfuStatsReporter.d.ts +1 -1
- package/dist/src/stats/utils.d.ts +1 -1
- package/index.ts +1 -2
- package/package.json +14 -14
- package/src/Call.ts +1 -1
- package/src/StreamVideoClient.ts +96 -150
- package/src/__tests__/StreamVideoClient.test.ts +85 -0
- package/src/coordinator/connection/token_manager.ts +19 -21
- package/src/devices/devices.ts +22 -11
- package/src/helpers/__tests__/clientUtils.test.ts +59 -0
- package/src/{client-details.ts → helpers/client-details.ts} +3 -3
- package/src/helpers/clientUtils.ts +67 -0
- package/src/stats/SfuStatsReporter.ts +1 -1
- package/src/stats/utils.ts +1 -1
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.17.0](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.16.7...@stream-io/video-client-1.17.0) (2025-02-17)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* support static token and token provider at the same time ([#1685](https://github.com/GetStream/stream-video-js/issues/1685)) ([4365a3d](https://github.com/GetStream/stream-video-js/commit/4365a3dd0a14c98041982bde8be21258b8cfd571))
|
|
11
|
+
|
|
12
|
+
## [1.16.7](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.16.6...@stream-io/video-client-1.16.7) (2025-02-12)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* relax device constraints on NotFoundError DOMException ([#1680](https://github.com/GetStream/stream-video-js/issues/1680)) ([c682908](https://github.com/GetStream/stream-video-js/commit/c682908408395f6863fd1549958cf4203bcc7f32))
|
|
18
|
+
|
|
5
19
|
## [1.16.6](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.16.5...@stream-io/video-client-1.16.6) (2025-02-11)
|
|
6
20
|
|
|
7
21
|
|
package/dist/index.browser.es.js
CHANGED
|
@@ -4,7 +4,7 @@ import { ServiceType, stackIntercept, RpcError } from '@protobuf-ts/runtime-rpc'
|
|
|
4
4
|
import axios from 'axios';
|
|
5
5
|
export { AxiosError } from 'axios';
|
|
6
6
|
import { TwirpFetchTransport, TwirpErrorCode } from '@protobuf-ts/twirp-transport';
|
|
7
|
-
import { ReplaySubject, combineLatest, BehaviorSubject, map, shareReplay, distinctUntilChanged, takeWhile, distinctUntilKeyChanged, fromEventPattern, startWith, concatMap, from, fromEvent, debounceTime,
|
|
7
|
+
import { ReplaySubject, combineLatest, BehaviorSubject, map, shareReplay, distinctUntilChanged, takeWhile, distinctUntilKeyChanged, fromEventPattern, startWith, concatMap, merge, from, fromEvent, debounceTime, pairwise, of } from 'rxjs';
|
|
8
8
|
import { parse } from 'sdp-transform';
|
|
9
9
|
import { UAParser } from 'ua-parser-js';
|
|
10
10
|
|
|
@@ -3302,10 +3302,7 @@ function isFunction(value) {
|
|
|
3302
3302
|
*/
|
|
3303
3303
|
const KnownCodes = {
|
|
3304
3304
|
TOKEN_EXPIRED: 40,
|
|
3305
|
-
WS_CLOSED_SUCCESS: 1000
|
|
3306
|
-
WS_CLOSED_ABRUPTLY: 1006,
|
|
3307
|
-
WS_POLICY_VIOLATION: 1008,
|
|
3308
|
-
};
|
|
3305
|
+
WS_CLOSED_SUCCESS: 1000};
|
|
3309
3306
|
/**
|
|
3310
3307
|
* retryInterval - A retry interval which increases acc to number of failures
|
|
3311
3308
|
*
|
|
@@ -7464,7 +7461,7 @@ const aggregate = (stats) => {
|
|
|
7464
7461
|
return report;
|
|
7465
7462
|
};
|
|
7466
7463
|
|
|
7467
|
-
const version = "1.
|
|
7464
|
+
const version = "1.17.0";
|
|
7468
7465
|
const [major, minor, patch] = version.split('.');
|
|
7469
7466
|
let sdkInfo = {
|
|
7470
7467
|
type: SdkType.PLAIN_JAVASCRIPT,
|
|
@@ -8556,13 +8553,23 @@ const getStream = async (constraints) => {
|
|
|
8556
8553
|
}
|
|
8557
8554
|
return stream;
|
|
8558
8555
|
};
|
|
8559
|
-
function
|
|
8560
|
-
|
|
8561
|
-
|
|
8562
|
-
|
|
8563
|
-
|
|
8564
|
-
|
|
8565
|
-
|
|
8556
|
+
function isNotFoundOrOverconstrainedError(error) {
|
|
8557
|
+
if (!error || typeof error !== 'object') {
|
|
8558
|
+
return false;
|
|
8559
|
+
}
|
|
8560
|
+
if ('name' in error && typeof error.name === 'string') {
|
|
8561
|
+
const name = error.name;
|
|
8562
|
+
if (['OverconstrainedError', 'NotFoundError'].includes(name)) {
|
|
8563
|
+
return true;
|
|
8564
|
+
}
|
|
8565
|
+
}
|
|
8566
|
+
if ('message' in error && typeof error.message === 'string') {
|
|
8567
|
+
const message = error.message;
|
|
8568
|
+
if (message.startsWith('OverconstrainedError')) {
|
|
8569
|
+
return true;
|
|
8570
|
+
}
|
|
8571
|
+
}
|
|
8572
|
+
return false;
|
|
8566
8573
|
}
|
|
8567
8574
|
/**
|
|
8568
8575
|
* Returns an audio media stream that fulfills the given constraints.
|
|
@@ -8587,7 +8594,7 @@ const getAudioStream = async (trackConstraints) => {
|
|
|
8587
8594
|
return await getStream(constraints);
|
|
8588
8595
|
}
|
|
8589
8596
|
catch (error) {
|
|
8590
|
-
if (
|
|
8597
|
+
if (isNotFoundOrOverconstrainedError(error) && trackConstraints?.deviceId) {
|
|
8591
8598
|
const { deviceId, ...relaxedConstraints } = trackConstraints;
|
|
8592
8599
|
getLogger(['devices'])('warn', 'Failed to get audio stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
|
|
8593
8600
|
return getAudioStream(relaxedConstraints);
|
|
@@ -8622,7 +8629,7 @@ const getVideoStream = async (trackConstraints) => {
|
|
|
8622
8629
|
return await getStream(constraints);
|
|
8623
8630
|
}
|
|
8624
8631
|
catch (error) {
|
|
8625
|
-
if (
|
|
8632
|
+
if (isNotFoundOrOverconstrainedError(error) && trackConstraints?.deviceId) {
|
|
8626
8633
|
const { deviceId, ...relaxedConstraints } = trackConstraints;
|
|
8627
8634
|
getLogger(['devices'])('warn', 'Failed to get video stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
|
|
8628
8635
|
return getVideoStream(relaxedConstraints);
|
|
@@ -12571,9 +12578,6 @@ const decodeBase64 = (s) => {
|
|
|
12571
12578
|
* Handles all the operations around user token.
|
|
12572
12579
|
*/
|
|
12573
12580
|
class TokenManager {
|
|
12574
|
-
/**
|
|
12575
|
-
* Constructor
|
|
12576
|
-
*/
|
|
12577
12581
|
constructor(secret) {
|
|
12578
12582
|
/**
|
|
12579
12583
|
* Set the static string token or token provider.
|
|
@@ -12584,8 +12588,9 @@ class TokenManager {
|
|
|
12584
12588
|
* @param {boolean} isAnonymous - whether the user is anonymous or not.
|
|
12585
12589
|
*/
|
|
12586
12590
|
this.setTokenOrProvider = async (tokenOrProvider, user, isAnonymous) => {
|
|
12587
|
-
this.validateToken(tokenOrProvider, user, isAnonymous);
|
|
12588
12591
|
this.user = user;
|
|
12592
|
+
this.isAnonymous = isAnonymous;
|
|
12593
|
+
this.validateToken(tokenOrProvider);
|
|
12589
12594
|
if (isFunction(tokenOrProvider)) {
|
|
12590
12595
|
this.tokenProvider = tokenOrProvider;
|
|
12591
12596
|
this.type = 'provider';
|
|
@@ -12608,28 +12613,28 @@ class TokenManager {
|
|
|
12608
12613
|
this.loadTokenPromise = null;
|
|
12609
12614
|
};
|
|
12610
12615
|
// Validates the user token.
|
|
12611
|
-
this.validateToken = (tokenOrProvider
|
|
12616
|
+
this.validateToken = (tokenOrProvider) => {
|
|
12612
12617
|
// allow empty token for anon user
|
|
12613
|
-
if (user && isAnonymous && !tokenOrProvider)
|
|
12618
|
+
if (this.user && this.isAnonymous && !tokenOrProvider)
|
|
12614
12619
|
return;
|
|
12615
12620
|
// Don't allow empty token for non-server side client.
|
|
12616
12621
|
if (!this.secret && !tokenOrProvider) {
|
|
12617
|
-
throw new Error('
|
|
12622
|
+
throw new Error('User token can not be empty');
|
|
12618
12623
|
}
|
|
12619
12624
|
if (tokenOrProvider &&
|
|
12620
12625
|
typeof tokenOrProvider !== 'string' &&
|
|
12621
12626
|
!isFunction(tokenOrProvider)) {
|
|
12622
|
-
throw new Error('
|
|
12627
|
+
throw new Error('User token should either be a string or a function');
|
|
12623
12628
|
}
|
|
12624
12629
|
if (typeof tokenOrProvider === 'string') {
|
|
12625
12630
|
// Allow empty token for anonymous users
|
|
12626
|
-
if (isAnonymous && tokenOrProvider === '')
|
|
12631
|
+
if (this.isAnonymous && tokenOrProvider === '')
|
|
12627
12632
|
return;
|
|
12628
12633
|
const tokenUserId = getUserFromToken(tokenOrProvider);
|
|
12629
12634
|
if (tokenOrProvider != null &&
|
|
12630
12635
|
(tokenUserId == null ||
|
|
12631
12636
|
tokenUserId === '' ||
|
|
12632
|
-
(!isAnonymous && tokenUserId !== user.id))) {
|
|
12637
|
+
(!this.isAnonymous && tokenUserId !== this.user.id))) {
|
|
12633
12638
|
throw new Error('userToken does not have a user_id or is not matching with user.id');
|
|
12634
12639
|
}
|
|
12635
12640
|
}
|
|
@@ -12646,7 +12651,9 @@ class TokenManager {
|
|
|
12646
12651
|
}
|
|
12647
12652
|
if (this.tokenProvider && typeof this.tokenProvider !== 'string') {
|
|
12648
12653
|
try {
|
|
12649
|
-
|
|
12654
|
+
const token = await this.tokenProvider();
|
|
12655
|
+
this.validateToken(token);
|
|
12656
|
+
this.token = token;
|
|
12650
12657
|
}
|
|
12651
12658
|
catch (e) {
|
|
12652
12659
|
return reject(new Error(`Call to tokenProvider failed with message: ${e}`));
|
|
@@ -13067,7 +13074,7 @@ class StreamClient {
|
|
|
13067
13074
|
return await this.wsConnection.connect(this.defaultWSTimeout);
|
|
13068
13075
|
};
|
|
13069
13076
|
this.getUserAgent = () => {
|
|
13070
|
-
const version = "1.
|
|
13077
|
+
const version = "1.17.0";
|
|
13071
13078
|
return (this.userAgent ||
|
|
13072
13079
|
`stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
|
|
13073
13080
|
};
|
|
@@ -13184,14 +13191,68 @@ class StreamClient {
|
|
|
13184
13191
|
}
|
|
13185
13192
|
}
|
|
13186
13193
|
|
|
13194
|
+
/**
|
|
13195
|
+
* Utility function to get the instance key.
|
|
13196
|
+
*/
|
|
13197
|
+
const getInstanceKey = (apiKey, user) => {
|
|
13198
|
+
return `${apiKey}/${user.id}`;
|
|
13199
|
+
};
|
|
13200
|
+
/**
|
|
13201
|
+
* Creates a coordinator client.
|
|
13202
|
+
*/
|
|
13203
|
+
const createCoordinatorClient = (apiKey, options) => {
|
|
13204
|
+
const coordinatorLogger = getLogger(['coordinator']);
|
|
13205
|
+
const streamClient = new StreamClient(apiKey, {
|
|
13206
|
+
persistUserOnConnectionFailure: true,
|
|
13207
|
+
...options,
|
|
13208
|
+
logger: coordinatorLogger,
|
|
13209
|
+
});
|
|
13210
|
+
const sdkInfo = getSdkInfo();
|
|
13211
|
+
if (sdkInfo) {
|
|
13212
|
+
const sdkName = SdkType[sdkInfo.type].toLowerCase();
|
|
13213
|
+
const sdkVersion = `${sdkInfo.major}.${sdkInfo.minor}.${sdkInfo.patch}`;
|
|
13214
|
+
const userAgent = streamClient.getUserAgent();
|
|
13215
|
+
streamClient.setUserAgent(`${userAgent}-video-${sdkName}-sdk-${sdkVersion}`);
|
|
13216
|
+
}
|
|
13217
|
+
return streamClient;
|
|
13218
|
+
};
|
|
13219
|
+
/**
|
|
13220
|
+
* Creates a token provider and allows integrators to provide
|
|
13221
|
+
* a static token and a token provider at the same time.
|
|
13222
|
+
*
|
|
13223
|
+
* When both of them are provided, this function will create an internal
|
|
13224
|
+
* token provider that will use the static token on the first invocation
|
|
13225
|
+
* and the token provider on the later invocations.
|
|
13226
|
+
*/
|
|
13227
|
+
const createTokenOrProvider = (options) => {
|
|
13228
|
+
const { token, tokenProvider } = options;
|
|
13229
|
+
if (token && tokenProvider) {
|
|
13230
|
+
let initialTokenUsed = false;
|
|
13231
|
+
return async function wrappedTokenProvider() {
|
|
13232
|
+
if (!initialTokenUsed) {
|
|
13233
|
+
initialTokenUsed = true;
|
|
13234
|
+
return token;
|
|
13235
|
+
}
|
|
13236
|
+
return tokenProvider();
|
|
13237
|
+
};
|
|
13238
|
+
}
|
|
13239
|
+
return token || tokenProvider;
|
|
13240
|
+
};
|
|
13241
|
+
|
|
13187
13242
|
/**
|
|
13188
13243
|
* A `StreamVideoClient` instance lets you communicate with our API, and authenticate users.
|
|
13189
13244
|
*/
|
|
13190
13245
|
class StreamVideoClient {
|
|
13191
13246
|
constructor(apiKeyOrArgs, opts) {
|
|
13192
|
-
this.logLevel = 'warn';
|
|
13193
13247
|
this.eventHandlersToUnregister = [];
|
|
13194
13248
|
this.connectionConcurrencyTag = Symbol('connectionConcurrencyTag');
|
|
13249
|
+
this.registerClientInstance = (apiKey, user) => {
|
|
13250
|
+
const instanceKey = getInstanceKey(apiKey, user);
|
|
13251
|
+
if (StreamVideoClient._instances.has(instanceKey)) {
|
|
13252
|
+
this.logger('warn', `A StreamVideoClient already exists for ${user.id}; Prefer using getOrCreateInstance method`);
|
|
13253
|
+
}
|
|
13254
|
+
StreamVideoClient._instances.set(instanceKey, this);
|
|
13255
|
+
};
|
|
13195
13256
|
/**
|
|
13196
13257
|
* Connects the given user to the client.
|
|
13197
13258
|
* Only one user can connect at a time, if you want to change users, call `disconnectUser` before connecting a new user.
|
|
@@ -13205,37 +13266,30 @@ class StreamVideoClient {
|
|
|
13205
13266
|
user.id = '!anon';
|
|
13206
13267
|
return this.connectAnonymousUser(user, token);
|
|
13207
13268
|
}
|
|
13208
|
-
|
|
13209
|
-
|
|
13210
|
-
|
|
13211
|
-
if (user.type === 'guest') {
|
|
13212
|
-
connectUser = async () => {
|
|
13213
|
-
return this.streamClient.connectGuestUser(user);
|
|
13214
|
-
};
|
|
13215
|
-
}
|
|
13269
|
+
const connectUser = user.type === 'guest'
|
|
13270
|
+
? () => this.streamClient.connectGuestUser(user)
|
|
13271
|
+
: () => this.streamClient.connectUser(user, token);
|
|
13216
13272
|
const connectUserResponse = await withoutConcurrency(this.connectionConcurrencyTag, () => connectUser());
|
|
13217
13273
|
// connectUserResponse will be void if connectUser called twice for the same user
|
|
13218
13274
|
if (connectUserResponse?.me) {
|
|
13219
13275
|
this.writeableStateStore.setConnectedUser(connectUserResponse.me);
|
|
13220
13276
|
}
|
|
13221
13277
|
this.eventHandlersToUnregister.push(this.on('connection.changed', (event) => {
|
|
13222
|
-
if (event.online)
|
|
13223
|
-
|
|
13224
|
-
|
|
13225
|
-
|
|
13226
|
-
|
|
13227
|
-
|
|
13228
|
-
|
|
13229
|
-
|
|
13230
|
-
|
|
13231
|
-
|
|
13232
|
-
|
|
13233
|
-
|
|
13234
|
-
|
|
13235
|
-
|
|
13236
|
-
|
|
13237
|
-
}
|
|
13238
|
-
}
|
|
13278
|
+
if (!event.online)
|
|
13279
|
+
return;
|
|
13280
|
+
const callsToReWatch = this.writeableStateStore.calls
|
|
13281
|
+
.filter((call) => call.watching)
|
|
13282
|
+
.map((call) => call.cid);
|
|
13283
|
+
if (callsToReWatch.length <= 0)
|
|
13284
|
+
return;
|
|
13285
|
+
this.logger('info', `Rewatching calls ${callsToReWatch.join(', ')}`);
|
|
13286
|
+
this.queryCalls({
|
|
13287
|
+
watch: true,
|
|
13288
|
+
filter_conditions: { cid: { $in: callsToReWatch } },
|
|
13289
|
+
sort: [{ field: 'cid', direction: 1 }],
|
|
13290
|
+
}).catch((err) => {
|
|
13291
|
+
this.logger('error', 'Failed to re-watch calls', err);
|
|
13292
|
+
});
|
|
13239
13293
|
}));
|
|
13240
13294
|
this.eventHandlersToUnregister.push(this.on('call.created', (event) => {
|
|
13241
13295
|
const { call, members } = event;
|
|
@@ -13291,15 +13345,12 @@ class StreamVideoClient {
|
|
|
13291
13345
|
* https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
|
|
13292
13346
|
*/
|
|
13293
13347
|
this.disconnectUser = async (timeout) => {
|
|
13294
|
-
|
|
13348
|
+
const { user, key } = this.streamClient;
|
|
13349
|
+
if (!user)
|
|
13295
13350
|
return;
|
|
13296
|
-
|
|
13297
|
-
|
|
13298
|
-
|
|
13299
|
-
const disconnectUser = () => this.streamClient.disconnectUser(timeout);
|
|
13300
|
-
await withoutConcurrency(this.connectionConcurrencyTag, () => disconnectUser());
|
|
13301
|
-
if (userId) {
|
|
13302
|
-
StreamVideoClient._instanceMap.delete(apiKey + userId);
|
|
13351
|
+
await withoutConcurrency(this.connectionConcurrencyTag, () => this.streamClient.disconnectUser(timeout));
|
|
13352
|
+
if (user.id) {
|
|
13353
|
+
StreamVideoClient._instances.delete(getInstanceKey(key, user));
|
|
13303
13354
|
}
|
|
13304
13355
|
this.eventHandlersToUnregister.forEach((unregister) => unregister());
|
|
13305
13356
|
this.eventHandlersToUnregister = [];
|
|
@@ -13480,92 +13531,46 @@ class StreamVideoClient {
|
|
|
13480
13531
|
* @param tokenOrProvider a token or a function that returns a token.
|
|
13481
13532
|
*/
|
|
13482
13533
|
this.connectAnonymousUser = async (user, tokenOrProvider) => {
|
|
13483
|
-
|
|
13484
|
-
|
|
13485
|
-
|
|
13486
|
-
|
|
13487
|
-
|
|
13488
|
-
|
|
13489
|
-
|
|
13490
|
-
|
|
13491
|
-
if (opts?.enableTimerWorker)
|
|
13492
|
-
enableTimerWorker();
|
|
13493
|
-
}
|
|
13494
|
-
else {
|
|
13495
|
-
logLevel = apiKeyOrArgs.options?.logLevel || logLevel;
|
|
13496
|
-
logger = apiKeyOrArgs.options?.logger || logger;
|
|
13497
|
-
if (apiKeyOrArgs.options?.enableTimerWorker)
|
|
13498
|
-
enableTimerWorker();
|
|
13499
|
-
}
|
|
13500
|
-
setLogger(logger, logLevel);
|
|
13534
|
+
return withoutConcurrency(this.connectionConcurrencyTag, () => this.streamClient.connectAnonymousUser(user, tokenOrProvider));
|
|
13535
|
+
};
|
|
13536
|
+
const apiKey = typeof apiKeyOrArgs === 'string' ? apiKeyOrArgs : apiKeyOrArgs.apiKey;
|
|
13537
|
+
const clientOptions = typeof apiKeyOrArgs === 'string' ? opts : apiKeyOrArgs.options;
|
|
13538
|
+
if (clientOptions?.enableTimerWorker)
|
|
13539
|
+
enableTimerWorker();
|
|
13540
|
+
const rootLogger = clientOptions?.logger || logToConsole;
|
|
13541
|
+
setLogger(rootLogger, clientOptions?.logLevel || 'warn');
|
|
13501
13542
|
this.logger = getLogger(['client']);
|
|
13502
|
-
|
|
13503
|
-
if (typeof apiKeyOrArgs === 'string') {
|
|
13504
|
-
this.streamClient = new StreamClient(apiKeyOrArgs, {
|
|
13505
|
-
persistUserOnConnectionFailure: true,
|
|
13506
|
-
...opts,
|
|
13507
|
-
logLevel,
|
|
13508
|
-
logger: coordinatorLogger,
|
|
13509
|
-
});
|
|
13510
|
-
}
|
|
13511
|
-
else {
|
|
13512
|
-
this.streamClient = new StreamClient(apiKeyOrArgs.apiKey, {
|
|
13513
|
-
persistUserOnConnectionFailure: true,
|
|
13514
|
-
...apiKeyOrArgs.options,
|
|
13515
|
-
logLevel,
|
|
13516
|
-
logger: coordinatorLogger,
|
|
13517
|
-
});
|
|
13518
|
-
const sdkInfo = getSdkInfo();
|
|
13519
|
-
if (sdkInfo) {
|
|
13520
|
-
const sdkName = SdkType[sdkInfo.type].toLowerCase();
|
|
13521
|
-
const sdkVersion = `${sdkInfo.major}.${sdkInfo.minor}.${sdkInfo.patch}`;
|
|
13522
|
-
const userAgent = this.streamClient.getUserAgent();
|
|
13523
|
-
this.streamClient.setUserAgent(`${userAgent}-video-${sdkName}-sdk-${sdkVersion}`);
|
|
13524
|
-
}
|
|
13525
|
-
}
|
|
13543
|
+
this.streamClient = createCoordinatorClient(apiKey, clientOptions);
|
|
13526
13544
|
this.writeableStateStore = new StreamVideoWriteableStateStore();
|
|
13527
13545
|
this.readOnlyStateStore = new StreamVideoReadOnlyStateStore(this.writeableStateStore);
|
|
13528
|
-
if (typeof apiKeyOrArgs !== 'string') {
|
|
13546
|
+
if (typeof apiKeyOrArgs !== 'string' && apiKeyOrArgs.user) {
|
|
13529
13547
|
const user = apiKeyOrArgs.user;
|
|
13530
|
-
|
|
13531
|
-
|
|
13532
|
-
|
|
13533
|
-
|
|
13534
|
-
|
|
13535
|
-
|
|
13536
|
-
|
|
13537
|
-
|
|
13538
|
-
this.logger('warn', `A StreamVideoClient already exists for ${user.type === 'anonymous' ? 'an anonymous user' : id}; Prefer using getOrCreateInstance method`);
|
|
13539
|
-
}
|
|
13540
|
-
user.id = id;
|
|
13541
|
-
StreamVideoClient._instanceMap.set(apiKeyOrArgs.apiKey + id, this);
|
|
13542
|
-
}
|
|
13543
|
-
this.connectUser(user, token).catch((err) => {
|
|
13544
|
-
this.logger('error', 'Failed to connect', err);
|
|
13545
|
-
});
|
|
13546
|
-
}
|
|
13548
|
+
if (user.type === 'anonymous')
|
|
13549
|
+
user.id = '!anon';
|
|
13550
|
+
if (user.id)
|
|
13551
|
+
this.registerClientInstance(apiKey, user);
|
|
13552
|
+
const tokenOrProvider = createTokenOrProvider(apiKeyOrArgs);
|
|
13553
|
+
this.connectUser(user, tokenOrProvider).catch((err) => {
|
|
13554
|
+
this.logger('error', 'Failed to connect', err);
|
|
13555
|
+
});
|
|
13547
13556
|
}
|
|
13548
13557
|
}
|
|
13558
|
+
/**
|
|
13559
|
+
* Gets or creates a StreamVideoClient instance based on the given options.
|
|
13560
|
+
*/
|
|
13549
13561
|
static getOrCreateInstance(args) {
|
|
13550
|
-
const user = args
|
|
13551
|
-
if (!user.id) {
|
|
13552
|
-
|
|
13553
|
-
user.id = '!anon';
|
|
13554
|
-
}
|
|
13555
|
-
else {
|
|
13556
|
-
throw new Error('User ID is required for a non-anonymous user');
|
|
13557
|
-
}
|
|
13558
|
-
}
|
|
13559
|
-
if (!args.token && !args.tokenProvider) {
|
|
13560
|
-
if (args.user.type !== 'anonymous' && args.user.type !== 'guest') {
|
|
13561
|
-
throw new Error('TokenProvider or token is required for a user that is not a guest or anonymous');
|
|
13562
|
-
}
|
|
13562
|
+
const { apiKey, user, token, tokenProvider } = args;
|
|
13563
|
+
if (!user.id && user.type !== 'anonymous') {
|
|
13564
|
+
throw new Error('user.id is required for a non-anonymous user');
|
|
13563
13565
|
}
|
|
13564
|
-
|
|
13565
|
-
|
|
13566
|
-
|
|
13566
|
+
if (!token &&
|
|
13567
|
+
!tokenProvider &&
|
|
13568
|
+
user.type !== 'anonymous' &&
|
|
13569
|
+
user.type !== 'guest') {
|
|
13570
|
+
throw new Error('tokenProvider or token is required for a authenticated users');
|
|
13567
13571
|
}
|
|
13568
|
-
return
|
|
13572
|
+
return (StreamVideoClient._instances.get(getInstanceKey(apiKey, user)) ||
|
|
13573
|
+
new StreamVideoClient(args));
|
|
13569
13574
|
}
|
|
13570
13575
|
/**
|
|
13571
13576
|
* Return the reactive state store, use this if you want to be notified about changes to the client state
|
|
@@ -13574,7 +13579,7 @@ class StreamVideoClient {
|
|
|
13574
13579
|
return this.readOnlyStateStore;
|
|
13575
13580
|
}
|
|
13576
13581
|
}
|
|
13577
|
-
StreamVideoClient.
|
|
13582
|
+
StreamVideoClient._instances = new Map();
|
|
13578
13583
|
|
|
13579
13584
|
export { AudioSettingsRequestDefaultDeviceEnum, AudioSettingsResponseDefaultDeviceEnum, browsers as Browsers, Call, CallState, CallType, CallTypes, CallingState, CameraManager, CameraManagerState, CreateDeviceRequestPushProviderEnum, DebounceType, DynascaleManager, ErrorFromResponse, FrameRecordingSettingsRequestModeEnum, FrameRecordingSettingsResponseModeEnum, InputMediaDeviceManager, InputMediaDeviceManagerState, LayoutSettingsRequestNameEnum, MicrophoneManager, MicrophoneManagerState, NoiseCancellationSettingsModeEnum, OwnCapability, RTMPBroadcastRequestQualityEnum, RTMPSettingsRequestQualityEnum, RecordSettingsRequestModeEnum, RecordSettingsRequestQualityEnum, rxUtils as RxUtils, ScreenShareManager, ScreenShareState, events as SfuEvents, models as SfuModels, SpeakerManager, SpeakerState, 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, getDeviceInfo, getDeviceState, getLogLevel, getLogger, getOSInfo, getScreenShareStream, getSdkInfo, getVideoBrowserPermission, getVideoDevices, getVideoStream, getWebRTCInfo, hasAudio, hasScreenShare, hasScreenShareAudio, hasVideo, isPinned, livestreamOrAudioRoomSortPreset, logLevels, logToConsole, name, noopComparator, paginatedLayoutSortPreset, pinned, publishingAudio, publishingVideo, reactionType, role, screenSharing, setDeviceInfo, setLogLevel, setLogger, setOSInfo, setPowerState, setSdkInfo, setThermalState, setWebRTCInfo, speakerLayoutSortPreset, speaking };
|
|
13580
13585
|
//# sourceMappingURL=index.browser.es.js.map
|