@stream-io/video-client 1.35.1 → 1.36.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.
Files changed (52) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/index.browser.es.js +217 -236
  3. package/dist/index.browser.es.js.map +1 -1
  4. package/dist/index.cjs.js +239 -240
  5. package/dist/index.cjs.js.map +1 -1
  6. package/dist/index.es.js +217 -236
  7. package/dist/index.es.js.map +1 -1
  8. package/dist/src/Call.d.ts +3 -2
  9. package/dist/src/StreamVideoClient.d.ts +3 -2
  10. package/dist/src/coordinator/connection/client.d.ts +3 -2
  11. package/dist/src/coordinator/connection/connection.d.ts +2 -1
  12. package/dist/src/coordinator/connection/types.d.ts +17 -1
  13. package/dist/src/devices/DeviceManager.d.ts +2 -2
  14. package/dist/src/logger.d.ts +9 -6
  15. package/dist/src/rpc/createClient.d.ts +3 -2
  16. package/dist/src/rtc/BasePeerConnection.d.ts +3 -2
  17. package/dist/src/store/CallState.d.ts +1 -1
  18. package/package.json +3 -2
  19. package/src/Call.ts +36 -48
  20. package/src/StreamSfuClient.ts +11 -11
  21. package/src/StreamVideoClient.ts +19 -21
  22. package/src/coordinator/connection/client.ts +21 -30
  23. package/src/coordinator/connection/connection.ts +5 -4
  24. package/src/coordinator/connection/location.ts +4 -4
  25. package/src/coordinator/connection/types.ts +21 -2
  26. package/src/devices/BrowserPermission.ts +5 -5
  27. package/src/devices/CameraManager.ts +3 -4
  28. package/src/devices/DeviceManager.ts +11 -11
  29. package/src/devices/MicrophoneManager.ts +8 -8
  30. package/src/devices/devices.ts +18 -14
  31. package/src/events/call.ts +6 -9
  32. package/src/events/internal.ts +4 -4
  33. package/src/events/mutes.ts +3 -8
  34. package/src/helpers/DynascaleManager.ts +9 -9
  35. package/src/helpers/RNSpeechDetector.ts +5 -5
  36. package/src/helpers/clientUtils.ts +1 -3
  37. package/src/helpers/ensureExhausted.ts +2 -2
  38. package/src/logger.ts +9 -34
  39. package/src/rpc/__tests__/createClient.test.ts +5 -1
  40. package/src/rpc/createClient.ts +4 -3
  41. package/src/rpc/retryable.ts +4 -2
  42. package/src/rtc/BasePeerConnection.ts +19 -22
  43. package/src/rtc/Dispatcher.ts +4 -4
  44. package/src/rtc/IceTrickleBuffer.ts +5 -5
  45. package/src/rtc/Publisher.ts +8 -8
  46. package/src/rtc/Subscriber.ts +12 -16
  47. package/src/rtc/signal.ts +7 -7
  48. package/src/stats/CallStateStatsReporter.ts +4 -4
  49. package/src/stats/SfuStatsReporter.ts +6 -6
  50. package/src/store/CallState.ts +3 -3
  51. package/src/store/rxUtils.ts +4 -2
  52. package/src/store/stateStore.ts +6 -6
package/dist/index.es.js CHANGED
@@ -4,6 +4,8 @@ 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 * as scopedLogger from '@stream-io/logger';
8
+ export { LogLevelEnum } from '@stream-io/logger';
7
9
  import { ReplaySubject, combineLatest, BehaviorSubject, shareReplay, map, distinctUntilChanged, startWith, takeWhile, distinctUntilKeyChanged, fromEventPattern, concatMap, merge, from, fromEvent, tap, debounceTime, pairwise, of } from 'rxjs';
8
10
  import { UAParser } from 'ua-parser-js';
9
11
  import { parse, write } from 'sdp-transform';
@@ -3726,7 +3728,7 @@ const withRequestLogger = (logger, level) => {
3726
3728
  return {
3727
3729
  interceptUnary: (next, method, input, options) => {
3728
3730
  const invocation = next(method, input, options);
3729
- logger(level, `Invoked SFU RPC method ${method.name}`, {
3731
+ logger[level](`Invoked SFU RPC method ${method.name}`, {
3730
3732
  request: invocation.request,
3731
3733
  headers: invocation.requestHeaders,
3732
3734
  response: invocation.response,
@@ -3862,16 +3864,6 @@ const isReactNative = () => {
3862
3864
  return navigator.product?.toLowerCase() === 'reactnative';
3863
3865
  };
3864
3866
 
3865
- // log levels, sorted by verbosity
3866
- const logLevels = Object.freeze({
3867
- trace: 0,
3868
- debug: 1,
3869
- info: 2,
3870
- warn: 3,
3871
- error: 4,
3872
- });
3873
- let logger;
3874
- let level = 'info';
3875
3867
  const logToConsole = (logLevel, message, ...args) => {
3876
3868
  let logMethod;
3877
3869
  switch (logLevel) {
@@ -3903,26 +3895,7 @@ const logToConsole = (logLevel, message, ...args) => {
3903
3895
  }
3904
3896
  logMethod(message, ...args);
3905
3897
  };
3906
- const setLogger = (l, lvl) => {
3907
- logger = l;
3908
- if (lvl) {
3909
- setLogLevel(lvl);
3910
- }
3911
- };
3912
- const setLogLevel = (l) => {
3913
- level = l;
3914
- };
3915
- const getLogLevel = () => level;
3916
- const getLogger = (withTags) => {
3917
- const loggerMethod = logger || logToConsole;
3918
- const tags = (withTags || []).filter(Boolean).join(':');
3919
- const result = (logLevel, message, ...args) => {
3920
- if (logLevels[logLevel] >= logLevels[level]) {
3921
- loggerMethod(logLevel, `[${tags}]: ${message}`, ...args);
3922
- }
3923
- };
3924
- return result;
3925
- };
3898
+ const videoLoggerSystem = scopedLogger.createLoggerSystem();
3926
3899
 
3927
3900
  /**
3928
3901
  * Creates a closure which wraps the given RPC call and retries invoking
@@ -3948,7 +3921,9 @@ const retryable = async (rpc, signal) => {
3948
3921
  const isAborted = signal?.aborted ?? false;
3949
3922
  if (isRequestCancelled || isAborted)
3950
3923
  throw err;
3951
- getLogger(['sfu-client', 'rpc'])('debug', `rpc failed (${attempt})`, err);
3924
+ videoLoggerSystem
3925
+ .getLogger('sfu-client', { tags: ['rpc'] })
3926
+ .debug(`rpc failed (${attempt})`, err);
3952
3927
  attempt++;
3953
3928
  }
3954
3929
  } while (!result || result.response.error?.shouldRetry);
@@ -4019,14 +3994,14 @@ const isSfuEvent = (eventName) => {
4019
3994
  };
4020
3995
  class Dispatcher {
4021
3996
  constructor() {
4022
- this.logger = getLogger(['Dispatcher']);
3997
+ this.logger = videoLoggerSystem.getLogger('Dispatcher');
4023
3998
  this.subscribers = {};
4024
3999
  this.dispatch = (message, tag = '0') => {
4025
4000
  const eventKind = message.eventPayload.oneofKind;
4026
4001
  if (!eventKind)
4027
4002
  return;
4028
4003
  const payload = message.eventPayload[eventKind];
4029
- this.logger('debug', `Dispatching ${eventKind}, tag=${tag}`, payload);
4004
+ this.logger.debug(`Dispatching ${eventKind}, tag=${tag}`, payload);
4030
4005
  const listeners = this.subscribers[eventKind];
4031
4006
  if (!listeners)
4032
4007
  return;
@@ -4035,7 +4010,7 @@ class Dispatcher {
4035
4010
  fn(payload);
4036
4011
  }
4037
4012
  catch (e) {
4038
- this.logger('warn', 'Listener failed with error', e);
4013
+ this.logger.warn('Listener failed with error', e);
4039
4014
  }
4040
4015
  }
4041
4016
  };
@@ -4071,8 +4046,8 @@ class IceTrickleBuffer {
4071
4046
  this.publisherCandidates.next(iceCandidate);
4072
4047
  }
4073
4048
  else {
4074
- const logger = getLogger(['sfu-client']);
4075
- logger('warn', `ICETrickle, Unknown peer type`, iceTrickle);
4049
+ const logger = videoLoggerSystem.getLogger('sfu-client');
4050
+ logger.warn(`ICETrickle, Unknown peer type`, iceTrickle);
4076
4051
  }
4077
4052
  };
4078
4053
  this.dispose = () => {
@@ -4086,8 +4061,8 @@ const toIceCandidate = (iceTrickle) => {
4086
4061
  return JSON.parse(iceTrickle.iceCandidate);
4087
4062
  }
4088
4063
  catch (e) {
4089
- const logger = getLogger(['sfu-client']);
4090
- logger('error', `Failed to parse ICE Trickle`, e, iceTrickle);
4064
+ const logger = videoLoggerSystem.getLogger('sfu-client');
4065
+ logger.error(`Failed to parse ICE Trickle`, e, iceTrickle);
4091
4066
  return undefined;
4092
4067
  }
4093
4068
  };
@@ -4263,7 +4238,9 @@ const updateValue = (subject, update) => {
4263
4238
  * @param handler the handler to call when the observable emits a value.
4264
4239
  * @param onError an optional error handler.
4265
4240
  */
4266
- const createSubscription = (observable, handler, onError = (error) => getLogger(['RxUtils'])('warn', 'An observable emitted an error', error)) => {
4241
+ const createSubscription = (observable, handler, onError = (error) => videoLoggerSystem
4242
+ .getLogger('RxUtils')
4243
+ .warn('An observable emitted an error', error)) => {
4267
4244
  const subscription = observable.subscribe({ next: handler, error: onError });
4268
4245
  return () => {
4269
4246
  subscription.unsubscribe();
@@ -4383,8 +4360,8 @@ class StreamVideoWriteableStateStore {
4383
4360
  * @param call the call to remove
4384
4361
  */
4385
4362
  this.unregisterCall = (call) => {
4386
- const logger = getLogger(['client-state']);
4387
- logger('trace', `Unregistering call: ${call.cid}`);
4363
+ const logger = videoLoggerSystem.getLogger('client-state');
4364
+ logger.trace(`Unregistering call: ${call.cid}`);
4388
4365
  return this.setCalls((calls) => calls.filter((c) => c !== call));
4389
4366
  };
4390
4367
  /**
@@ -4399,15 +4376,15 @@ class StreamVideoWriteableStateStore {
4399
4376
  this.connectedUserSubject.subscribe(async (user) => {
4400
4377
  // leave all calls when the user disconnects.
4401
4378
  if (!user) {
4402
- const logger = getLogger(['client-state']);
4379
+ const logger = videoLoggerSystem.getLogger('client-state');
4403
4380
  for (const call of this.calls) {
4404
4381
  if (call.state.callingState === CallingState.LEFT)
4405
4382
  continue;
4406
- logger('info', `User disconnected, leaving call: ${call.cid}`);
4383
+ logger.info(`User disconnected, leaving call: ${call.cid}`);
4407
4384
  await call
4408
4385
  .leave({ message: 'client.disconnectUser() called' })
4409
4386
  .catch((err) => {
4410
- logger('error', `Error leaving call: ${call.cid}`, err);
4387
+ logger.error(`Error leaving call: ${call.cid}`, err);
4411
4388
  });
4412
4389
  }
4413
4390
  }
@@ -4801,7 +4778,7 @@ class CallState {
4801
4778
  // We keep these tracks around until we can associate them with a participant.
4802
4779
  this.orphanedTracks = [];
4803
4780
  this.callGrantsSubject = new ReplaySubject(1);
4804
- this.logger = getLogger(['CallState']);
4781
+ this.logger = videoLoggerSystem.getLogger('CallState');
4805
4782
  /**
4806
4783
  * A list of comparators that are used to sort the participants.
4807
4784
  */
@@ -4982,7 +4959,7 @@ class CallState {
4982
4959
  this.updateParticipant = (sessionId, patch) => {
4983
4960
  const participant = this.findParticipantBySessionId(sessionId);
4984
4961
  if (!participant) {
4985
- this.logger('warn', `Participant with sessionId ${sessionId} not found`);
4962
+ this.logger.warn(`Participant with sessionId ${sessionId} not found`);
4986
4963
  return;
4987
4964
  }
4988
4965
  const thePatch = typeof patch === 'function' ? patch(participant) : patch;
@@ -5861,7 +5838,7 @@ const getSdkVersion = (sdk) => {
5861
5838
  return sdk ? `${sdk.major}.${sdk.minor}.${sdk.patch}` : '0.0.0-development';
5862
5839
  };
5863
5840
 
5864
- const version = "1.35.1";
5841
+ const version = "1.36.0";
5865
5842
  const [major, minor, patch] = version.split('.');
5866
5843
  let sdkInfo = {
5867
5844
  type: SdkType.PLAIN_JAVASCRIPT,
@@ -6064,7 +6041,7 @@ var browsers = /*#__PURE__*/Object.freeze({
6064
6041
  * Creates a new StatsReporter instance that collects metrics about the ongoing call and reports them to the state store
6065
6042
  */
6066
6043
  const createStatsReporter = ({ subscriber, publisher, state, datacenter, pollingIntervalInMs = 2000, }) => {
6067
- const logger = getLogger(['stats']);
6044
+ const logger = videoLoggerSystem.getLogger('stats');
6068
6045
  const getRawStatsForTrack = async (kind, selector) => {
6069
6046
  if (kind === 'subscriber' && subscriber) {
6070
6047
  return subscriber.getStats(selector);
@@ -6123,7 +6100,7 @@ const createStatsReporter = ({ subscriber, publisher, state, datacenter, polling
6123
6100
  participantStats[sessionId] = await getStatsForStream(kind, tracks);
6124
6101
  }
6125
6102
  catch (e) {
6126
- logger('warn', `Failed to collect ${kind} stats for ${userId}`, e);
6103
+ logger.warn(`Failed to collect ${kind} stats for ${userId}`, e);
6127
6104
  }
6128
6105
  }
6129
6106
  }
@@ -6155,7 +6132,7 @@ const createStatsReporter = ({ subscriber, publisher, state, datacenter, polling
6155
6132
  // (they are expensive) if no one is listening to them
6156
6133
  if (state.isCallStatsReportObserved) {
6157
6134
  await run().catch((e) => {
6158
- logger('debug', 'Failed to collect stats', e);
6135
+ logger.debug('Failed to collect stats', e);
6159
6136
  });
6160
6137
  }
6161
6138
  timeoutId = setTimeout(loop, pollingIntervalInMs);
@@ -6301,7 +6278,7 @@ const aggregate = (stats) => {
6301
6278
 
6302
6279
  class SfuStatsReporter {
6303
6280
  constructor(sfuClient, { options, clientDetails, subscriber, publisher, microphone, camera, state, tracer, unifiedSessionId, }) {
6304
- this.logger = getLogger(['SfuStatsReporter']);
6281
+ this.logger = videoLoggerSystem.getLogger('SfuStatsReporter');
6305
6282
  this.inputDevices = new Map();
6306
6283
  this.observeDevice = (device, kind) => {
6307
6284
  const { browserPermissionState$ } = device.state;
@@ -6352,7 +6329,7 @@ class SfuStatsReporter {
6352
6329
  // intentionally not awaiting the promise here
6353
6330
  // to avoid impeding with the ongoing actions.
6354
6331
  this.run(telemetryData).catch((err) => {
6355
- this.logger('warn', 'Failed to send telemetry data', err);
6332
+ this.logger.warn('Failed to send telemetry data', err);
6356
6333
  });
6357
6334
  };
6358
6335
  this.run = async (telemetry) => {
@@ -6411,7 +6388,7 @@ class SfuStatsReporter {
6411
6388
  clearInterval(this.intervalId);
6412
6389
  this.intervalId = setInterval(() => {
6413
6390
  this.run().catch((err) => {
6414
- this.logger('warn', 'Failed to report stats', err);
6391
+ this.logger.warn('Failed to report stats', err);
6415
6392
  });
6416
6393
  }, this.options.reporting_interval_ms);
6417
6394
  };
@@ -6428,14 +6405,14 @@ class SfuStatsReporter {
6428
6405
  };
6429
6406
  this.flush = () => {
6430
6407
  this.run().catch((err) => {
6431
- this.logger('warn', 'Failed to flush report stats', err);
6408
+ this.logger.warn('Failed to flush report stats', err);
6432
6409
  });
6433
6410
  };
6434
6411
  this.scheduleOne = (timeout) => {
6435
6412
  clearTimeout(this.timeoutId);
6436
6413
  this.timeoutId = setTimeout(() => {
6437
6414
  this.run().catch((err) => {
6438
- this.logger('warn', 'Failed to report stats', err);
6415
+ this.logger.warn('Failed to report stats', err);
6439
6416
  });
6440
6417
  }, timeout);
6441
6418
  };
@@ -6806,7 +6783,7 @@ class BasePeerConnection {
6806
6783
  this.tryRestartIce = () => {
6807
6784
  this.restartIce().catch((e) => {
6808
6785
  const reason = 'restartICE() failed, initiating reconnect';
6809
- this.logger('error', reason, e);
6786
+ this.logger.error(reason, e);
6810
6787
  const strategy = e instanceof NegotiationError &&
6811
6788
  e.error.code === ErrorCode.PARTICIPANT_SIGNAL_LOST
6812
6789
  ? WebsocketReconnectStrategy.FAST
@@ -6824,7 +6801,7 @@ class BasePeerConnection {
6824
6801
  withoutConcurrency(lockKey, async () => fn(e)).catch((err) => {
6825
6802
  if (this.isDisposed)
6826
6803
  return;
6827
- this.logger('warn', `Error handling ${event}`, err);
6804
+ this.logger.warn(`Error handling ${event}`, err);
6828
6805
  });
6829
6806
  }));
6830
6807
  };
@@ -6841,7 +6818,7 @@ class BasePeerConnection {
6841
6818
  return this.pc.addIceCandidate(candidate).catch((e) => {
6842
6819
  if (this.isDisposed)
6843
6820
  return;
6844
- this.logger('warn', `ICE candidate error`, e, candidate);
6821
+ this.logger.warn(`ICE candidate error`, e, candidate);
6845
6822
  });
6846
6823
  });
6847
6824
  };
@@ -6885,7 +6862,7 @@ class BasePeerConnection {
6885
6862
  this.onIceCandidate = (e) => {
6886
6863
  const { candidate } = e;
6887
6864
  if (!candidate) {
6888
- this.logger('debug', 'null ice candidate');
6865
+ this.logger.debug('null ice candidate');
6889
6866
  return;
6890
6867
  }
6891
6868
  const iceCandidate = this.asJSON(candidate);
@@ -6894,7 +6871,7 @@ class BasePeerConnection {
6894
6871
  .catch((err) => {
6895
6872
  if (this.isDisposed)
6896
6873
  return;
6897
- this.logger('warn', `ICETrickle failed`, err);
6874
+ this.logger.warn(`ICETrickle failed`, err);
6898
6875
  });
6899
6876
  };
6900
6877
  /**
@@ -6915,7 +6892,7 @@ class BasePeerConnection {
6915
6892
  */
6916
6893
  this.onConnectionStateChange = async () => {
6917
6894
  const state = this.pc.connectionState;
6918
- this.logger('debug', `Connection state changed`, state);
6895
+ this.logger.debug(`Connection state changed`, state);
6919
6896
  if (this.tracer && (state === 'connected' || state === 'failed')) {
6920
6897
  try {
6921
6898
  const stats = await this.stats.get();
@@ -6937,7 +6914,7 @@ class BasePeerConnection {
6937
6914
  */
6938
6915
  this.onIceConnectionStateChange = () => {
6939
6916
  const state = this.pc.iceConnectionState;
6940
- this.logger('debug', `ICE connection state changed`, state);
6917
+ this.logger.debug(`ICE connection state changed`, state);
6941
6918
  this.handleConnectionStateUpdate(state);
6942
6919
  };
6943
6920
  this.handleConnectionStateUpdate = (state) => {
@@ -6952,13 +6929,13 @@ class BasePeerConnection {
6952
6929
  switch (state) {
6953
6930
  case 'failed':
6954
6931
  // in the `failed` state, we try to restart ICE immediately
6955
- this.logger('info', 'restartICE due to failed connection');
6932
+ this.logger.info('restartICE due to failed connection');
6956
6933
  this.tryRestartIce();
6957
6934
  break;
6958
6935
  case 'disconnected':
6959
6936
  // in the `disconnected` state, we schedule a restartICE() after a delay
6960
6937
  // as the browser might recover the connection in the meantime
6961
- this.logger('info', 'disconnected connection, scheduling restartICE');
6938
+ this.logger.info('disconnected connection, scheduling restartICE');
6962
6939
  clearTimeout(this.iceRestartTimeout);
6963
6940
  this.iceRestartTimeout = setTimeout(() => {
6964
6941
  const currentState = this.pc.iceConnectionState;
@@ -6970,7 +6947,7 @@ class BasePeerConnection {
6970
6947
  case 'connected':
6971
6948
  // in the `connected` state, we clear the ice restart timeout if it exists
6972
6949
  if (this.iceRestartTimeout) {
6973
- this.logger('info', 'connected connection, canceling restartICE');
6950
+ this.logger.info('connected connection, canceling restartICE');
6974
6951
  clearTimeout(this.iceRestartTimeout);
6975
6952
  this.iceRestartTimeout = undefined;
6976
6953
  }
@@ -6984,19 +6961,19 @@ class BasePeerConnection {
6984
6961
  const errorMessage = e instanceof RTCPeerConnectionIceErrorEvent
6985
6962
  ? `${e.errorCode}: ${e.errorText}`
6986
6963
  : e;
6987
- this.logger('debug', 'ICE Candidate error', errorMessage);
6964
+ this.logger.debug('ICE Candidate error', errorMessage);
6988
6965
  };
6989
6966
  /**
6990
6967
  * Handles the ICE gathering state change event.
6991
6968
  */
6992
6969
  this.onIceGatherChange = () => {
6993
- this.logger('debug', `ICE Gathering State`, this.pc.iceGatheringState);
6970
+ this.logger.debug(`ICE Gathering State`, this.pc.iceGatheringState);
6994
6971
  };
6995
6972
  /**
6996
6973
  * Handles the signaling state change event.
6997
6974
  */
6998
6975
  this.onSignalingChange = () => {
6999
- this.logger('debug', `Signaling state changed`, this.pc.signalingState);
6976
+ this.logger.debug(`Signaling state changed`, this.pc.signalingState);
7000
6977
  };
7001
6978
  this.peerType = peerType;
7002
6979
  this.sfuClient = sfuClient;
@@ -7004,10 +6981,7 @@ class BasePeerConnection {
7004
6981
  this.dispatcher = dispatcher;
7005
6982
  this.iceRestartDelay = iceRestartDelay;
7006
6983
  this.onReconnectionNeeded = onReconnectionNeeded;
7007
- this.logger = getLogger([
7008
- peerType === PeerType.SUBSCRIBER ? 'Subscriber' : 'Publisher',
7009
- tag,
7010
- ]);
6984
+ this.logger = videoLoggerSystem.getLogger(peerType === PeerType.SUBSCRIBER ? 'Subscriber' : 'Publisher', { tags: [tag] });
7011
6985
  this.pc = this.createPeerConnection(connectionConfig);
7012
6986
  this.stats = new StatsTracer(this.pc, peerType, this.trackIdToTrackType);
7013
6987
  if (enableTracing) {
@@ -7130,7 +7104,7 @@ class TransceiverCache {
7130
7104
  }
7131
7105
 
7132
7106
  const ensureExhausted = (x, message) => {
7133
- getLogger(['helpers'])('warn', message, x);
7107
+ videoLoggerSystem.getLogger('helpers').warn(message, x);
7134
7108
  };
7135
7109
 
7136
7110
  const trackTypeToParticipantStreamKey = (trackType) => {
@@ -7469,7 +7443,7 @@ class Publisher extends BasePeerConnection {
7469
7443
  params.degradationPreference = 'maintain-framerate';
7470
7444
  await transceiver.sender.setParameters(params);
7471
7445
  const trackType = publishOption.trackType;
7472
- this.logger('debug', `Added ${TrackType[trackType]} transceiver`);
7446
+ this.logger.debug(`Added ${TrackType[trackType]} transceiver`);
7473
7447
  this.transceiverCache.add({ publishOption, transceiver, options });
7474
7448
  this.trackIdToTrackType.set(track.id, trackType);
7475
7449
  await this.negotiate();
@@ -7589,16 +7563,16 @@ class Publisher extends BasePeerConnection {
7589
7563
  const { trackType, layers, publishOptionId } = videoSender;
7590
7564
  const enabledLayers = layers.filter((l) => l.active);
7591
7565
  const tag = 'Update publish quality:';
7592
- this.logger('info', `${tag} requested layers by SFU:`, enabledLayers);
7566
+ this.logger.info(`${tag} requested layers by SFU:`, enabledLayers);
7593
7567
  const transceiverId = this.transceiverCache.find((t) => t.publishOption.id === publishOptionId &&
7594
7568
  t.publishOption.trackType === trackType);
7595
7569
  const sender = transceiverId?.transceiver.sender;
7596
7570
  if (!sender) {
7597
- return this.logger('warn', `${tag} no video sender found.`);
7571
+ return this.logger.warn(`${tag} no video sender found.`);
7598
7572
  }
7599
7573
  const params = sender.getParameters();
7600
7574
  if (params.encodings.length === 0) {
7601
- return this.logger('warn', `${tag} there are no encodings set.`);
7575
+ return this.logger.warn(`${tag} there are no encodings set.`);
7602
7576
  }
7603
7577
  const codecInUse = transceiverId?.publishOption.codec?.name;
7604
7578
  const usesSvcCodec = codecInUse && isSvcCodec(codecInUse);
@@ -7642,19 +7616,19 @@ class Publisher extends BasePeerConnection {
7642
7616
  }
7643
7617
  const activeEncoders = params.encodings.filter((e) => e.active);
7644
7618
  if (!changed) {
7645
- return this.logger('info', `${tag} no change:`, activeEncoders);
7619
+ return this.logger.info(`${tag} no change:`, activeEncoders);
7646
7620
  }
7647
7621
  await sender.setParameters(params);
7648
- this.logger('info', `${tag} enabled rids:`, activeEncoders);
7622
+ this.logger.info(`${tag} enabled rids:`, activeEncoders);
7649
7623
  };
7650
7624
  /**
7651
7625
  * Restarts the ICE connection and renegotiates with the SFU.
7652
7626
  */
7653
7627
  this.restartIce = async () => {
7654
- this.logger('debug', 'Restarting ICE connection');
7628
+ this.logger.debug('Restarting ICE connection');
7655
7629
  const signalingState = this.pc.signalingState;
7656
7630
  if (this.isIceRestarting || signalingState === 'have-local-offer') {
7657
- this.logger('debug', 'ICE restart is already in progress');
7631
+ this.logger.debug('ICE restart is already in progress');
7658
7632
  return;
7659
7633
  }
7660
7634
  await this.negotiate({ iceRestart: true });
@@ -7816,13 +7790,13 @@ class Subscriber extends BasePeerConnection {
7816
7790
  * Restarts the ICE connection and renegotiates with the SFU.
7817
7791
  */
7818
7792
  this.restartIce = async () => {
7819
- this.logger('debug', 'Restarting ICE connection');
7793
+ this.logger.debug('Restarting ICE connection');
7820
7794
  if (this.pc.signalingState === 'have-remote-offer') {
7821
- this.logger('debug', 'ICE restart is already in progress');
7795
+ this.logger.debug('ICE restart is already in progress');
7822
7796
  return;
7823
7797
  }
7824
7798
  if (this.pc.connectionState === 'new') {
7825
- this.logger('debug', `ICE connection is not yet established, skipping restart.`);
7799
+ this.logger.debug(`ICE connection is not yet established, skipping restart.`);
7826
7800
  return;
7827
7801
  }
7828
7802
  const previousIsIceRestarting = this.isIceRestarting;
@@ -7845,25 +7819,25 @@ class Subscriber extends BasePeerConnection {
7845
7819
  // example: `e3f6aaf8-b03d-4911-be36-83f47d37a76a:TRACK_TYPE_VIDEO`
7846
7820
  const [trackId, rawTrackType] = primaryStream.id.split(':');
7847
7821
  const participantToUpdate = this.state.participants.find((p) => p.trackLookupPrefix === trackId);
7848
- this.logger('debug', `[onTrack]: Got remote ${rawTrackType} track for userId: ${participantToUpdate?.userId}`, e.track.id, e.track);
7822
+ this.logger.debug(`[onTrack]: Got remote ${rawTrackType} track for userId: ${participantToUpdate?.userId}`, e.track.id, e.track);
7849
7823
  const trackDebugInfo = `${participantToUpdate?.userId} ${rawTrackType}:${trackId}`;
7850
7824
  e.track.addEventListener('mute', () => {
7851
- this.logger('info', `[onTrack]: Track muted: ${trackDebugInfo}`);
7825
+ this.logger.info(`[onTrack]: Track muted: ${trackDebugInfo}`);
7852
7826
  });
7853
7827
  e.track.addEventListener('unmute', () => {
7854
- this.logger('info', `[onTrack]: Track unmuted: ${trackDebugInfo}`);
7828
+ this.logger.info(`[onTrack]: Track unmuted: ${trackDebugInfo}`);
7855
7829
  });
7856
7830
  e.track.addEventListener('ended', () => {
7857
- this.logger('info', `[onTrack]: Track ended: ${trackDebugInfo}`);
7831
+ this.logger.info(`[onTrack]: Track ended: ${trackDebugInfo}`);
7858
7832
  this.state.removeOrphanedTrack(primaryStream.id);
7859
7833
  });
7860
7834
  const trackType = toTrackType(rawTrackType);
7861
7835
  if (!trackType) {
7862
- return this.logger('error', `Unknown track type: ${rawTrackType}`);
7836
+ return this.logger.error(`Unknown track type: ${rawTrackType}`);
7863
7837
  }
7864
7838
  this.trackIdToTrackType.set(e.track.id, trackType);
7865
7839
  if (!participantToUpdate) {
7866
- this.logger('warn', `[onTrack]: Received track for unknown participant: ${trackId}`, e);
7840
+ this.logger.warn(`[onTrack]: Received track for unknown participant: ${trackId}`, e);
7867
7841
  this.state.registerOrphanedTrack({
7868
7842
  id: primaryStream.id,
7869
7843
  trackLookupPrefix: trackId,
@@ -7874,7 +7848,7 @@ class Subscriber extends BasePeerConnection {
7874
7848
  }
7875
7849
  const streamKindProp = trackTypeToParticipantStreamKey(trackType);
7876
7850
  if (!streamKindProp) {
7877
- this.logger('error', `Unknown track type: ${rawTrackType}`);
7851
+ this.logger.error(`Unknown track type: ${rawTrackType}`);
7878
7852
  return;
7879
7853
  }
7880
7854
  // get the previous stream to dispose it later
@@ -7887,7 +7861,7 @@ class Subscriber extends BasePeerConnection {
7887
7861
  });
7888
7862
  // now, dispose the previous stream if it exists
7889
7863
  if (previousStream) {
7890
- this.logger('info', `[onTrack]: Cleaning up previous remote ${e.track.kind} tracks for userId: ${participantToUpdate.userId}`);
7864
+ this.logger.info(`[onTrack]: Cleaning up previous remote ${e.track.kind} tracks for userId: ${participantToUpdate.userId}`);
7891
7865
  previousStream.getTracks().forEach((t) => {
7892
7866
  t.stop();
7893
7867
  previousStream.removeTrack(t);
@@ -7914,7 +7888,7 @@ class Subscriber extends BasePeerConnection {
7914
7888
  this.pc.addEventListener('track', this.handleOnTrack);
7915
7889
  this.on('subscriberOffer', async (subscriberOffer) => {
7916
7890
  return this.negotiate(subscriberOffer).catch((err) => {
7917
- this.logger('error', `Negotiation failed.`, err);
7891
+ this.logger.error(`Negotiation failed.`, err);
7918
7892
  });
7919
7893
  });
7920
7894
  }
@@ -7931,20 +7905,20 @@ class Subscriber extends BasePeerConnection {
7931
7905
 
7932
7906
  const createWebSocketSignalChannel = (opts) => {
7933
7907
  const { endpoint, onMessage, tag, tracer } = opts;
7934
- const logger = getLogger(['SfuClientWS', tag]);
7935
- logger('debug', 'Creating signaling WS channel:', endpoint);
7908
+ const logger = videoLoggerSystem.getLogger('SfuClientWS', { tags: [tag] });
7909
+ logger.debug('Creating signaling WS channel:', endpoint);
7936
7910
  const ws = new WebSocket(endpoint);
7937
7911
  ws.binaryType = 'arraybuffer'; // do we need this?
7938
7912
  ws.addEventListener('error', (e) => {
7939
- logger('error', 'Signaling WS channel error', e);
7913
+ logger.error('Signaling WS channel error', e);
7940
7914
  tracer?.trace('signal.ws.error', e);
7941
7915
  });
7942
7916
  ws.addEventListener('close', (e) => {
7943
- logger('info', 'Signaling WS channel is closed', e);
7917
+ logger.info('Signaling WS channel is closed', e);
7944
7918
  tracer?.trace('signal.ws.close', e);
7945
7919
  });
7946
7920
  ws.addEventListener('open', (e) => {
7947
- logger('info', 'Signaling WS channel is open', e);
7921
+ logger.info('Signaling WS channel is open', e);
7948
7922
  tracer?.trace('signal.ws.open', e);
7949
7923
  });
7950
7924
  ws.addEventListener('message', (e) => {
@@ -7956,7 +7930,7 @@ const createWebSocketSignalChannel = (opts) => {
7956
7930
  }
7957
7931
  catch (err) {
7958
7932
  const message = 'Failed to decode a message. Check whether the Proto models match.';
7959
- logger('error', message, { event: e, error: err });
7933
+ logger.error(message, { event: e, error: err });
7960
7934
  tracer?.trace('signal.ws.message.error', message);
7961
7935
  }
7962
7936
  });
@@ -8157,14 +8131,14 @@ class StreamSfuClient {
8157
8131
  this.close = (code = StreamSfuClient.NORMAL_CLOSURE, reason) => {
8158
8132
  this.isClosingClean = code !== StreamSfuClient.ERROR_CONNECTION_UNHEALTHY;
8159
8133
  if (this.signalWs.readyState === WebSocket.OPEN) {
8160
- this.logger('debug', `Closing SFU WS connection: ${code} - ${reason}`);
8134
+ this.logger.debug(`Closing SFU WS connection: ${code} - ${reason}`);
8161
8135
  this.signalWs.close(code, `js-client: ${reason}`);
8162
8136
  this.signalWs.removeEventListener('close', this.handleWebSocketClose);
8163
8137
  }
8164
8138
  this.dispose();
8165
8139
  };
8166
8140
  this.dispose = () => {
8167
- this.logger('debug', 'Disposing SFU client');
8141
+ this.logger.debug('Disposing SFU client');
8168
8142
  this.unsubscribeIceTrickle();
8169
8143
  this.unsubscribeNetworkChanged();
8170
8144
  clearInterval(this.keepAliveInterval);
@@ -8184,7 +8158,7 @@ class StreamSfuClient {
8184
8158
  await this.notifyLeave(reason);
8185
8159
  }
8186
8160
  catch (err) {
8187
- this.logger('debug', 'Error notifying SFU about leaving call', err);
8161
+ this.logger.debug('Error notifying SFU about leaving call', err);
8188
8162
  }
8189
8163
  this.close(StreamSfuClient.NORMAL_CLOSURE, reason.substring(0, 115));
8190
8164
  };
@@ -8305,10 +8279,10 @@ class StreamSfuClient {
8305
8279
  await this.signalReady(); // wait for the signal ws to be open
8306
8280
  const msgJson = SfuRequest.toJson(message);
8307
8281
  if (this.signalWs.readyState !== WebSocket.OPEN) {
8308
- this.logger('debug', 'Signal WS is not open. Skipping message', msgJson);
8282
+ this.logger.debug('Signal WS is not open. Skipping message', msgJson);
8309
8283
  return;
8310
8284
  }
8311
- this.logger('debug', `Sending message to: ${this.edgeName}`, msgJson);
8285
+ this.logger.debug(`Sending message to: ${this.edgeName}`, msgJson);
8312
8286
  this.signalWs.send(SfuRequest.toBinary(message));
8313
8287
  };
8314
8288
  this.keepAlive = () => {
@@ -8316,7 +8290,7 @@ class StreamSfuClient {
8316
8290
  timers.clearInterval(this.keepAliveInterval);
8317
8291
  this.keepAliveInterval = timers.setInterval(() => {
8318
8292
  this.ping().catch((e) => {
8319
- this.logger('error', 'Error sending healthCheckRequest to SFU', e);
8293
+ this.logger.error('Error sending healthCheckRequest to SFU', e);
8320
8294
  });
8321
8295
  }, this.pingIntervalInMs);
8322
8296
  };
@@ -8339,7 +8313,7 @@ class StreamSfuClient {
8339
8313
  this.edgeName = server.edge_name;
8340
8314
  this.joinResponseTimeout = joinResponseTimeout;
8341
8315
  this.tag = tag;
8342
- this.logger = getLogger(['SfuClient', tag]);
8316
+ this.logger = videoLoggerSystem.getLogger('SfuClient', { tags: [tag] });
8343
8317
  this.tracer = enableTracing
8344
8318
  ? new Tracer(`${tag}-${this.edgeName}`)
8345
8319
  : undefined;
@@ -8348,7 +8322,8 @@ class StreamSfuClient {
8348
8322
  interceptors: [
8349
8323
  withHeaders({ Authorization: `Bearer ${token}` }),
8350
8324
  this.tracer && withRequestTracer(this.tracer.trace),
8351
- getLogLevel() === 'trace' && withRequestLogger(this.logger, 'trace'),
8325
+ this.logger.getLogLevel() === 'trace' &&
8326
+ withRequestLogger(this.logger, 'trace'),
8352
8327
  ].filter((v) => !!v),
8353
8328
  });
8354
8329
  // Special handling for the ICETrickle kind of events.
@@ -8436,13 +8411,13 @@ const watchCallRejected = (call) => {
8436
8411
  const { call: eventCall } = event;
8437
8412
  const { session: callSession } = eventCall;
8438
8413
  if (!callSession) {
8439
- call.logger('warn', 'No call session provided. Ignoring call.rejected event.', event);
8414
+ call.logger.warn('No call session provided. Ignoring call.rejected event.', event);
8440
8415
  return;
8441
8416
  }
8442
8417
  const rejectedBy = callSession.rejected_by;
8443
8418
  const { members, callingState } = call.state;
8444
8419
  if (callingState !== CallingState.RINGING) {
8445
- call.logger('info', 'Call is not in ringing mode (it is either accepted or rejected already). Ignoring call.rejected event.', event);
8420
+ call.logger.info('Call is not in ringing mode (it is either accepted or rejected already). Ignoring call.rejected event.', event);
8446
8421
  return;
8447
8422
  }
8448
8423
  if (call.isCreatedByMe) {
@@ -8450,7 +8425,7 @@ const watchCallRejected = (call) => {
8450
8425
  .filter((m) => m.user_id !== call.currentUserId)
8451
8426
  .every((m) => rejectedBy[m.user_id]);
8452
8427
  if (everyoneElseRejected) {
8453
- call.logger('info', 'everyone rejected, leaving the call');
8428
+ call.logger.info('everyone rejected, leaving the call');
8454
8429
  await call.leave({
8455
8430
  reject: true,
8456
8431
  reason: 'cancel',
@@ -8460,7 +8435,7 @@ const watchCallRejected = (call) => {
8460
8435
  }
8461
8436
  else {
8462
8437
  if (rejectedBy[eventCall.created_by.id]) {
8463
- call.logger('info', 'call creator rejected, leaving call');
8438
+ call.logger.info('call creator rejected, leaving call');
8464
8439
  await call.leave({ message: 'ring: creator rejected' });
8465
8440
  }
8466
8441
  }
@@ -8477,7 +8452,7 @@ const watchCallEnded = (call) => {
8477
8452
  call
8478
8453
  .leave({ message: 'call.ended event received', reject: false })
8479
8454
  .catch((err) => {
8480
- call.logger('error', 'Failed to leave call after call.ended ', err);
8455
+ call.logger.error('Failed to leave call after call.ended ', err);
8481
8456
  });
8482
8457
  }
8483
8458
  };
@@ -8505,7 +8480,7 @@ const watchSfuCallEnded = (call) => {
8505
8480
  await call.leave({ message: `callEnded received: ${reason}` });
8506
8481
  }
8507
8482
  catch (err) {
8508
- call.logger('error', 'Failed to leave call after being ended by the SFU', err);
8483
+ call.logger.error('Failed to leave call after being ended by the SFU', err);
8509
8484
  }
8510
8485
  });
8511
8486
  };
@@ -8588,7 +8563,7 @@ const watchLiveEnded = (dispatcher, call) => {
8588
8563
  call.state.setBackstage(true);
8589
8564
  if (!call.permissionsContext.hasPermission(OwnCapability.JOIN_BACKSTAGE)) {
8590
8565
  call.leave({ message: 'live ended' }).catch((err) => {
8591
- call.logger('error', 'Failed to leave call after live ended', err);
8566
+ call.logger.error('Failed to leave call after live ended', err);
8592
8567
  });
8593
8568
  }
8594
8569
  });
@@ -8600,9 +8575,9 @@ const watchSfuErrorReports = (dispatcher) => {
8600
8575
  return dispatcher.on('error', (e) => {
8601
8576
  if (!e.error)
8602
8577
  return;
8603
- const logger = getLogger(['SfuClient']);
8578
+ const logger = videoLoggerSystem.getLogger('SfuClient');
8604
8579
  const { error, reconnectStrategy } = e;
8605
- logger('error', 'SFU reported error', {
8580
+ logger.error('SFU reported error', {
8606
8581
  code: ErrorCode[error.code],
8607
8582
  reconnectStrategy: WebsocketReconnectStrategy[reconnectStrategy],
8608
8583
  message: error.message,
@@ -8656,7 +8631,7 @@ const handleRemoteSoftMute = (call) => {
8656
8631
  if (cause === TrackUnpublishReason.MODERATION &&
8657
8632
  sessionId === localParticipant?.sessionId) {
8658
8633
  const logger = call.logger;
8659
- logger('info', `Local participant's ${TrackType[type]} track is muted remotely`);
8634
+ logger.info(`Local participant's ${TrackType[type]} track is muted remotely`);
8660
8635
  try {
8661
8636
  if (type === TrackType.VIDEO) {
8662
8637
  await call.camera.disable();
@@ -8669,11 +8644,11 @@ const handleRemoteSoftMute = (call) => {
8669
8644
  await call.screenShare.disable();
8670
8645
  }
8671
8646
  else {
8672
- logger('warn', 'Unsupported track type to soft mute', TrackType[type]);
8647
+ logger.warn('Unsupported track type to soft mute', TrackType[type]);
8673
8648
  }
8674
8649
  }
8675
8650
  catch (error) {
8676
- logger('error', 'Failed to stop publishing', error);
8651
+ logger.error('Failed to stop publishing', error);
8677
8652
  }
8678
8653
  }
8679
8654
  });
@@ -8994,7 +8969,7 @@ class DynascaleManager {
8994
8969
  * The viewport tracker instance.
8995
8970
  */
8996
8971
  this.viewportTracker = new ViewportTracker();
8997
- this.logger = getLogger(['DynascaleManager']);
8972
+ this.logger = videoLoggerSystem.getLogger('DynascaleManager');
8998
8973
  this.pendingSubscriptionsUpdate = null;
8999
8974
  this.videoTrackSubscriptionOverridesSubject = new BehaviorSubject({});
9000
8975
  this.videoTrackSubscriptionOverrides$ = this.videoTrackSubscriptionOverridesSubject.asObservable();
@@ -9051,7 +9026,7 @@ class DynascaleManager {
9051
9026
  this.sfuClient
9052
9027
  ?.updateSubscriptions(this.trackSubscriptions)
9053
9028
  .catch((err) => {
9054
- this.logger('debug', `Failed to update track subscriptions`, err);
9029
+ this.logger.debug(`Failed to update track subscriptions`, err);
9055
9030
  });
9056
9031
  };
9057
9032
  if (debounceType) {
@@ -9140,7 +9115,7 @@ class DynascaleManager {
9140
9115
  // is not visible (e.g., has display: none).
9141
9116
  // we treat this as "unsubscription" as we don't want to keep
9142
9117
  // consuming bandwidth for a video that is not visible on the screen.
9143
- this.logger('debug', `Ignoring 0x0 dimension`, boundParticipant);
9118
+ this.logger.debug(`Ignoring 0x0 dimension`, boundParticipant);
9144
9119
  dimension = undefined;
9145
9120
  }
9146
9121
  this.callState.updateParticipantTracks(trackType, {
@@ -9245,7 +9220,7 @@ class DynascaleManager {
9245
9220
  setTimeout(() => {
9246
9221
  videoElement.srcObject = source ?? null;
9247
9222
  videoElement.play().catch((e) => {
9248
- this.logger('warn', `Failed to play stream`, e);
9223
+ this.logger.warn(`Failed to play stream`, e);
9249
9224
  });
9250
9225
  // we add extra delay until we attempt to force-play
9251
9226
  // the participant's media stream in Firefox and Safari,
@@ -9282,13 +9257,13 @@ class DynascaleManager {
9282
9257
  return;
9283
9258
  if ('setSinkId' in audioElement) {
9284
9259
  audioElement.setSinkId(deviceId).catch((e) => {
9285
- this.logger('warn', `Can't to set AudioElement sinkId`, e);
9260
+ this.logger.warn(`Can't to set AudioElement sinkId`, e);
9286
9261
  });
9287
9262
  }
9288
9263
  if (audioContext && 'setSinkId' in audioContext) {
9289
9264
  // @ts-expect-error setSinkId is not available in all browsers
9290
9265
  audioContext.setSinkId(deviceId).catch((e) => {
9291
- this.logger('warn', `Can't to set AudioContext sinkId`, e);
9266
+ this.logger.warn(`Can't to set AudioContext sinkId`, e);
9292
9267
  });
9293
9268
  }
9294
9269
  };
@@ -9330,7 +9305,7 @@ class DynascaleManager {
9330
9305
  // we will play audio directly through the audio element in other browsers
9331
9306
  audioElement.muted = false;
9332
9307
  audioElement.play().catch((e) => {
9333
- this.logger('warn', `Failed to play audio stream`, e);
9308
+ this.logger.warn(`Failed to play audio stream`, e);
9334
9309
  });
9335
9310
  }
9336
9311
  const { selectedDevice } = this.speaker.state;
@@ -9382,7 +9357,7 @@ class DynascaleManager {
9382
9357
  if (this.audioContext?.state === 'suspended') {
9383
9358
  this.audioContext
9384
9359
  .resume()
9385
- .catch((err) => this.logger('warn', `Can't resume audio context`, err))
9360
+ .catch((err) => this.logger.warn(`Can't resume audio context`, err))
9386
9361
  .then(() => {
9387
9362
  document.removeEventListener('click', this.resumeAudioContext);
9388
9363
  });
@@ -9619,7 +9594,7 @@ class BrowserPermission {
9619
9594
  this.disposeController = new AbortController();
9620
9595
  this.wasPrompted = false;
9621
9596
  this.listeners = new Set();
9622
- this.logger = getLogger(['permissions']);
9597
+ this.logger = videoLoggerSystem.getLogger('permissions');
9623
9598
  const signal = this.disposeController.signal;
9624
9599
  this.ready = (async () => {
9625
9600
  const assumeGranted = () => {
@@ -9645,7 +9620,7 @@ class BrowserPermission {
9645
9620
  }
9646
9621
  }
9647
9622
  catch (err) {
9648
- this.logger('debug', 'Failed to query permission status', err);
9623
+ this.logger.debug('Failed to query permission status', err);
9649
9624
  assumeGranted();
9650
9625
  }
9651
9626
  })();
@@ -9684,7 +9659,7 @@ class BrowserPermission {
9684
9659
  typeof e === 'object' &&
9685
9660
  'name' in e &&
9686
9661
  (e.name === 'NotAllowedError' || e.name === 'SecurityError')) {
9687
- this.logger('info', 'Browser permission was not granted', {
9662
+ this.logger.info('Browser permission was not granted', {
9688
9663
  permission: this.permission,
9689
9664
  });
9690
9665
  this.setState('denied');
@@ -9693,7 +9668,7 @@ class BrowserPermission {
9693
9668
  }
9694
9669
  return false;
9695
9670
  }
9696
- this.logger('error', `Failed to getUserMedia`, {
9671
+ this.logger.error(`Failed to getUserMedia`, {
9697
9672
  error: e,
9698
9673
  permission: this.permission,
9699
9674
  });
@@ -9914,10 +9889,12 @@ const getAudioStream = async (trackConstraints, tracer) => {
9914
9889
  if (isNotFoundOrOverconstrainedError(error) && trackConstraints?.deviceId) {
9915
9890
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
9916
9891
  const { deviceId, ...relaxedConstraints } = trackConstraints;
9917
- getLogger(['devices'])('warn', 'Failed to get audio stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
9892
+ videoLoggerSystem
9893
+ .getLogger('devices')
9894
+ .warn('Failed to get audio stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
9918
9895
  return getAudioStream(relaxedConstraints);
9919
9896
  }
9920
- getLogger(['devices'])('error', 'Failed to get audio stream', {
9897
+ videoLoggerSystem.getLogger('devices').error('Failed to get audio stream', {
9921
9898
  error,
9922
9899
  constraints,
9923
9900
  });
@@ -9950,10 +9927,12 @@ const getVideoStream = async (trackConstraints, tracer) => {
9950
9927
  if (isNotFoundOrOverconstrainedError(error) && trackConstraints?.deviceId) {
9951
9928
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
9952
9929
  const { deviceId, ...relaxedConstraints } = trackConstraints;
9953
- getLogger(['devices'])('warn', 'Failed to get video stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
9930
+ videoLoggerSystem
9931
+ .getLogger('devices')
9932
+ .warn('Failed to get video stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
9954
9933
  return getVideoStream(relaxedConstraints);
9955
9934
  }
9956
- getLogger(['devices'])('error', 'Failed to get video stream', {
9935
+ videoLoggerSystem.getLogger('devices').error('Failed to get video stream', {
9957
9936
  error,
9958
9937
  constraints,
9959
9938
  });
@@ -10002,7 +9981,9 @@ const getScreenShareStream = async (options, tracer) => {
10002
9981
  }
10003
9982
  catch (e) {
10004
9983
  tracer?.trace(`${tag}OnFailure`, e.name);
10005
- getLogger(['devices'])('error', 'Failed to get screen share stream', e);
9984
+ videoLoggerSystem
9985
+ .getLogger('devices')
9986
+ .error('Failed to get screen share stream', e);
10006
9987
  throw e;
10007
9988
  }
10008
9989
  };
@@ -10064,7 +10045,7 @@ class DeviceManager {
10064
10045
  this.call = call;
10065
10046
  this.state = state;
10066
10047
  this.trackType = trackType;
10067
- this.logger = getLogger([`${TrackType[trackType].toLowerCase()} manager`]);
10048
+ this.logger = videoLoggerSystem.getLogger(`${TrackType[trackType].toLowerCase()} manager`);
10068
10049
  this.setup();
10069
10050
  }
10070
10051
  setup() {
@@ -10227,6 +10208,7 @@ class DeviceManager {
10227
10208
  }
10228
10209
  }
10229
10210
  async applySettingsToStream() {
10211
+ console.log('applySettingsToStream ');
10230
10212
  await withCancellation(this.statusChangeConcurrencyTag, async (signal) => {
10231
10213
  if (this.enabled) {
10232
10214
  try {
@@ -10259,7 +10241,7 @@ class DeviceManager {
10259
10241
  const mediaStream = this.state.mediaStream;
10260
10242
  if (!mediaStream)
10261
10243
  return;
10262
- this.logger('debug', `${stopTracks ? 'Stopping' : 'Disabling'} stream`);
10244
+ this.logger.debug(`${stopTracks ? 'Stopping' : 'Disabling'} stream`);
10263
10245
  if (this.call.state.callingState === CallingState.JOINED) {
10264
10246
  await this.stopPublishStream();
10265
10247
  }
@@ -10305,7 +10287,7 @@ class DeviceManager {
10305
10287
  }
10306
10288
  }
10307
10289
  async unmuteStream() {
10308
- this.logger('debug', 'Starting stream');
10290
+ this.logger.debug('Starting stream');
10309
10291
  let stream;
10310
10292
  let rootStream;
10311
10293
  if (this.state.mediaStream &&
@@ -10386,7 +10368,7 @@ class DeviceManager {
10386
10368
  return output;
10387
10369
  })
10388
10370
  .then(chainWith(parent), (error) => {
10389
- this.logger('warn', 'Filter failed to start and will be ignored', error);
10371
+ this.logger.warn('Filter failed to start and will be ignored', error);
10390
10372
  return parent;
10391
10373
  }), rootStream);
10392
10374
  }
@@ -10409,7 +10391,7 @@ class DeviceManager {
10409
10391
  if (!isMobile() || this.trackType !== TrackType.VIDEO)
10410
10392
  return;
10411
10393
  this.call.notifyTrackMuteState(muted, this.trackType).catch((err) => {
10412
- this.logger('warn', 'Error while notifying track mute state', err);
10394
+ this.logger.warn('Error while notifying track mute state', err);
10413
10395
  });
10414
10396
  };
10415
10397
  stream.getTracks().forEach((track) => {
@@ -10473,7 +10455,7 @@ class DeviceManager {
10473
10455
  }
10474
10456
  }
10475
10457
  catch (err) {
10476
- this.logger('warn', 'Unexpected error while handling disconnected or replaced device', err);
10458
+ this.logger.warn('Unexpected error while handling disconnected or replaced device', err);
10477
10459
  }
10478
10460
  }));
10479
10461
  }
@@ -10680,7 +10662,7 @@ class CameraManager extends DeviceManager {
10680
10662
  */
10681
10663
  async selectDirection(direction) {
10682
10664
  if (!this.isDirectionSupportedByDevice()) {
10683
- this.logger('warn', 'Setting direction is not supported on this device');
10665
+ this.logger.warn('Setting direction is not supported on this device');
10684
10666
  return;
10685
10667
  }
10686
10668
  if (isReactNative()) {
@@ -10731,7 +10713,7 @@ class CameraManager extends DeviceManager {
10731
10713
  }
10732
10714
  catch (error) {
10733
10715
  // couldn't enable device, target resolution will be applied the next time user attempts to start the device
10734
- this.logger('warn', 'could not apply target resolution', error);
10716
+ this.logger.warn('could not apply target resolution', error);
10735
10717
  }
10736
10718
  }
10737
10719
  if (this.enabled && this.state.mediaStream) {
@@ -10742,7 +10724,7 @@ class CameraManager extends DeviceManager {
10742
10724
  if (width !== this.targetResolution.width ||
10743
10725
  height !== this.targetResolution.height) {
10744
10726
  await this.applySettingsToStream();
10745
- this.logger('debug', `${width}x${height} target resolution applied to media stream`);
10727
+ this.logger.debug(`${width}x${height} target resolution applied to media stream`);
10746
10728
  }
10747
10729
  }
10748
10730
  }
@@ -11006,8 +10988,8 @@ class RNSpeechDetector {
11006
10988
  };
11007
10989
  }
11008
10990
  catch (error) {
11009
- const logger = getLogger(['RNSpeechDetector']);
11010
- logger('error', 'error handling permissions: ', error);
10991
+ const logger = videoLoggerSystem.getLogger('RNSpeechDetector');
10992
+ logger.error('error handling permissions: ', error);
11011
10993
  return () => { };
11012
10994
  }
11013
10995
  }
@@ -11091,8 +11073,8 @@ class RNSpeechDetector {
11091
11073
  }
11092
11074
  }
11093
11075
  catch (error) {
11094
- const logger = getLogger(['RNSpeechDetector']);
11095
- logger('error', 'error checking audio level from stats', error);
11076
+ const logger = videoLoggerSystem.getLogger('RNSpeechDetector');
11077
+ logger.error('error checking audio level from stats', error);
11096
11078
  }
11097
11079
  };
11098
11080
  // Call checkAudioLevel periodically (every 100ms)
@@ -11152,7 +11134,7 @@ class MicrophoneManager extends AudioDeviceManager {
11152
11134
  }
11153
11135
  }
11154
11136
  catch (err) {
11155
- this.logger('warn', 'Could not enable speaking while muted', err);
11137
+ this.logger.warn('Could not enable speaking while muted', err);
11156
11138
  }
11157
11139
  }));
11158
11140
  this.subscriptions.push(createSubscription(this.call.state.callingState$, (callingState) => {
@@ -11175,7 +11157,7 @@ class MicrophoneManager extends AudioDeviceManager {
11175
11157
  }
11176
11158
  })
11177
11159
  .catch((err) => {
11178
- this.logger('warn', `Failed to enable noise cancellation`, err);
11160
+ this.logger.warn(`Failed to enable noise cancellation`, err);
11179
11161
  return this.call.notifyNoiseCancellationStopped();
11180
11162
  });
11181
11163
  }
@@ -11183,7 +11165,7 @@ class MicrophoneManager extends AudioDeviceManager {
11183
11165
  this.noiseCancellationRegistration
11184
11166
  .then(() => this.noiseCancellation?.disable())
11185
11167
  .catch((err) => {
11186
- this.logger('warn', `Failed to disable noise cancellation`, err);
11168
+ this.logger.warn(`Failed to disable noise cancellation`, err);
11187
11169
  });
11188
11170
  }
11189
11171
  }));
@@ -11212,12 +11194,12 @@ class MicrophoneManager extends AudioDeviceManager {
11212
11194
  this.call.tracer.trace('noiseCancellation.enabled', enabled);
11213
11195
  if (enabled) {
11214
11196
  this.call.notifyNoiseCancellationStarting().catch((err) => {
11215
- this.logger('warn', `notifyNoiseCancellationStart failed`, err);
11197
+ this.logger.warn(`notifyNoiseCancellationStart failed`, err);
11216
11198
  });
11217
11199
  }
11218
11200
  else {
11219
11201
  this.call.notifyNoiseCancellationStopped().catch((err) => {
11220
- this.logger('warn', `notifyNoiseCancellationStop failed`, err);
11202
+ this.logger.warn(`notifyNoiseCancellationStop failed`, err);
11221
11203
  });
11222
11204
  }
11223
11205
  });
@@ -11246,9 +11228,9 @@ class MicrophoneManager extends AudioDeviceManager {
11246
11228
  }
11247
11229
  }
11248
11230
  catch (e) {
11249
- this.logger('warn', 'Failed to enable noise cancellation', e);
11231
+ this.logger.warn('Failed to enable noise cancellation', e);
11250
11232
  await this.disableNoiseCancellation().catch((err) => {
11251
- this.logger('warn', 'Failed to disable noise cancellation', err);
11233
+ this.logger.warn('Failed to disable noise cancellation', err);
11252
11234
  });
11253
11235
  throw e;
11254
11236
  }
@@ -11261,7 +11243,7 @@ class MicrophoneManager extends AudioDeviceManager {
11261
11243
  .then(() => this.noiseCancellation?.disable())
11262
11244
  .then(() => this.noiseCancellationChangeUnsubscribe?.())
11263
11245
  .catch((err) => {
11264
- this.logger('warn', 'Failed to unregister noise cancellation', err);
11246
+ this.logger.warn('Failed to unregister noise cancellation', err);
11265
11247
  });
11266
11248
  this.call.tracer.trace('noiseCancellation.disabled', true);
11267
11249
  await this.call.notifyNoiseCancellationStopped();
@@ -11769,9 +11751,9 @@ class Call {
11769
11751
  return;
11770
11752
  const currentUserId = this.currentUserId;
11771
11753
  if (currentUserId && blockedUserIds.includes(currentUserId)) {
11772
- this.logger('info', 'Leaving call because of being blocked');
11754
+ this.logger.info('Leaving call because of being blocked');
11773
11755
  await this.leave({ message: 'user blocked' }).catch((err) => {
11774
- this.logger('error', 'Error leaving call after being blocked', err);
11756
+ this.logger.error('Error leaving call after being blocked', err);
11775
11757
  });
11776
11758
  }
11777
11759
  }));
@@ -11807,7 +11789,7 @@ class Call {
11807
11789
  if ((isAcceptedElsewhere || isRejectedByMe) &&
11808
11790
  !hasPending(this.joinLeaveConcurrencyTag)) {
11809
11791
  this.leave().catch(() => {
11810
- this.logger('error', 'Could not leave a call that was accepted or rejected elsewhere');
11792
+ this.logger.error('Could not leave a call that was accepted or rejected elsewhere');
11811
11793
  });
11812
11794
  }
11813
11795
  }));
@@ -11887,7 +11869,7 @@ class Call {
11887
11869
  }
11888
11870
  }
11889
11871
  catch (err) {
11890
- this.logger('error', `Can't disable mic/camera/screenshare after revoked permissions`, err);
11872
+ this.logger.error(`Can't disable mic/camera/screenshare after revoked permissions`, err);
11891
11873
  }
11892
11874
  }
11893
11875
  };
@@ -12148,13 +12130,13 @@ class Call {
12148
12130
  maxJoinRetries = Math.max(maxJoinRetries, 1);
12149
12131
  for (let attempt = 0; attempt < maxJoinRetries; attempt++) {
12150
12132
  try {
12151
- this.logger('trace', `Joining call (${attempt})`, this.cid);
12133
+ this.logger.trace(`Joining call (${attempt})`, this.cid);
12152
12134
  await this.doJoin(data);
12153
12135
  delete joinData.migrating_from;
12154
12136
  break;
12155
12137
  }
12156
12138
  catch (err) {
12157
- this.logger('warn', `Failed to join call (${attempt})`, this.cid);
12139
+ this.logger.warn(`Failed to join call (${attempt})`, this.cid);
12158
12140
  if (err instanceof ErrorFromResponse && err.unrecoverable) {
12159
12141
  // if the error is unrecoverable, we should not retry as that signals
12160
12142
  // that connectivity is good, but the coordinator doesn't allow the user
@@ -12184,7 +12166,7 @@ class Call {
12184
12166
  const connectStartTime = Date.now();
12185
12167
  const callingState = this.state.callingState;
12186
12168
  this.joinCallData = data;
12187
- this.logger('debug', 'Starting join flow');
12169
+ this.logger.debug('Starting join flow');
12188
12170
  this.state.setCallingState(CallingState.JOINING);
12189
12171
  const performingMigration = this.reconnectStrategy === WebsocketReconnectStrategy.MIGRATE;
12190
12172
  const performingRejoin = this.reconnectStrategy === WebsocketReconnectStrategy.REJOIN;
@@ -12269,7 +12251,7 @@ class Call {
12269
12251
  }
12270
12252
  }
12271
12253
  catch (error) {
12272
- this.logger('warn', 'Join SFU request failed', error);
12254
+ this.logger.warn('Join SFU request failed', error);
12273
12255
  sfuClient.close(StreamSfuClient.JOIN_FAILED, 'Join request failed, connection considered unhealthy');
12274
12256
  // restore the previous call state if the join-flow fails
12275
12257
  this.state.setCallingState(callingState);
@@ -12326,7 +12308,7 @@ class Call {
12326
12308
  // reset the reconnect strategy to unspecified after a successful reconnection
12327
12309
  this.reconnectStrategy = WebsocketReconnectStrategy.UNSPECIFIED;
12328
12310
  this.reconnectReason = '';
12329
- this.logger('info', `Joined call ${this.cid}`);
12311
+ this.logger.info(`Joined call ${this.cid}`);
12330
12312
  };
12331
12313
  /**
12332
12314
  * Prepares Reconnect Details object.
@@ -12439,7 +12421,7 @@ class Call {
12439
12421
  onReconnectionNeeded: (kind, reason) => {
12440
12422
  this.reconnect(kind, reason).catch((err) => {
12441
12423
  const message = `[Reconnect] Error reconnecting after a subscriber error: ${reason}`;
12442
- this.logger('warn', message, err);
12424
+ this.logger.warn(message, err);
12443
12425
  });
12444
12426
  },
12445
12427
  });
@@ -12461,7 +12443,7 @@ class Call {
12461
12443
  onReconnectionNeeded: (kind, reason) => {
12462
12444
  this.reconnect(kind, reason).catch((err) => {
12463
12445
  const message = `[Reconnect] Error reconnecting after a publisher error: ${reason}`;
12464
- this.logger('warn', message, err);
12446
+ this.logger.warn(message, err);
12465
12447
  });
12466
12448
  },
12467
12449
  });
@@ -12530,7 +12512,7 @@ class Call {
12530
12512
  * @param reason the reason for the closure.
12531
12513
  */
12532
12514
  this.handleSfuSignalClose = (sfuClient, reason) => {
12533
- this.logger('debug', '[Reconnect] SFU signal connection closed');
12515
+ this.logger.debug('[Reconnect] SFU signal connection closed');
12534
12516
  const { callingState } = this.state;
12535
12517
  if (
12536
12518
  // SFU WS closed before we finished current join,
@@ -12551,7 +12533,7 @@ class Call {
12551
12533
  ? WebsocketReconnectStrategy.FAST
12552
12534
  : WebsocketReconnectStrategy.REJOIN;
12553
12535
  this.reconnect(strategy, reason).catch((err) => {
12554
- this.logger('warn', '[Reconnect] Error reconnecting', err);
12536
+ this.logger.warn('[Reconnect] Error reconnecting', err);
12555
12537
  });
12556
12538
  };
12557
12539
  /**
@@ -12587,7 +12569,7 @@ class Call {
12587
12569
  const shouldGiveUpReconnecting = this.disconnectionTimeoutSeconds > 0 &&
12588
12570
  reconnectingTime / 1000 > this.disconnectionTimeoutSeconds;
12589
12571
  if (shouldGiveUpReconnecting) {
12590
- this.logger('warn', '[Reconnect] Stopping reconnection attempts after reaching disconnection timeout');
12572
+ this.logger.warn('[Reconnect] Stopping reconnection attempts after reaching disconnection timeout');
12591
12573
  await markAsReconnectingFailed();
12592
12574
  return;
12593
12575
  }
@@ -12599,11 +12581,11 @@ class Call {
12599
12581
  try {
12600
12582
  // wait until the network is available
12601
12583
  await this.networkAvailableTask?.promise;
12602
- this.logger('info', `[Reconnect] Reconnecting with strategy ${WebsocketReconnectStrategy[this.reconnectStrategy]}`);
12584
+ this.logger.info(`[Reconnect] Reconnecting with strategy ${WebsocketReconnectStrategy[this.reconnectStrategy]}`);
12603
12585
  switch (this.reconnectStrategy) {
12604
12586
  case WebsocketReconnectStrategy.UNSPECIFIED:
12605
12587
  case WebsocketReconnectStrategy.DISCONNECT:
12606
- this.logger('debug', `[Reconnect] No-op strategy ${currentStrategy}`);
12588
+ this.logger.debug(`[Reconnect] No-op strategy ${currentStrategy}`);
12607
12589
  break;
12608
12590
  case WebsocketReconnectStrategy.FAST:
12609
12591
  await this.reconnectFast();
@@ -12622,13 +12604,13 @@ class Call {
12622
12604
  }
12623
12605
  catch (error) {
12624
12606
  if (this.state.callingState === CallingState.OFFLINE) {
12625
- this.logger('debug', `[Reconnect] Can't reconnect while offline, stopping reconnection attempts`);
12607
+ this.logger.debug(`[Reconnect] Can't reconnect while offline, stopping reconnection attempts`);
12626
12608
  break;
12627
12609
  // we don't need to handle the error if the call is offline
12628
12610
  // network change event will trigger the reconnection
12629
12611
  }
12630
12612
  if (error instanceof ErrorFromResponse && error.unrecoverable) {
12631
- this.logger('warn', `[Reconnect] Can't reconnect due to coordinator unrecoverable error`, error);
12613
+ this.logger.warn(`[Reconnect] Can't reconnect due to coordinator unrecoverable error`, error);
12632
12614
  await markAsReconnectingFailed();
12633
12615
  return;
12634
12616
  }
@@ -12649,12 +12631,12 @@ class Call {
12649
12631
  ? WebsocketReconnectStrategy.REJOIN
12650
12632
  : WebsocketReconnectStrategy.FAST;
12651
12633
  this.reconnectStrategy = nextStrategy;
12652
- this.logger('info', `[Reconnect] ${currentStrategy} (${this.reconnectAttempts}) failed. Attempting with ${WebsocketReconnectStrategy[nextStrategy]}`, error);
12634
+ this.logger.info(`[Reconnect] ${currentStrategy} (${this.reconnectAttempts}) failed. Attempting with ${WebsocketReconnectStrategy[nextStrategy]}`, error);
12653
12635
  }
12654
12636
  } while (this.state.callingState !== CallingState.JOINED &&
12655
12637
  this.state.callingState !== CallingState.RECONNECTING_FAILED &&
12656
12638
  this.state.callingState !== CallingState.LEFT);
12657
- this.logger('info', '[Reconnect] Reconnection flow finished');
12639
+ this.logger.info('[Reconnect] Reconnection flow finished');
12658
12640
  });
12659
12641
  };
12660
12642
  /**
@@ -12736,7 +12718,7 @@ class Call {
12736
12718
  this.registerReconnectHandlers = () => {
12737
12719
  // handles the legacy "goAway" event
12738
12720
  const unregisterGoAway = this.on('goAway', () => {
12739
- this.reconnect(WebsocketReconnectStrategy.MIGRATE, 'goAway').catch((err) => this.logger('warn', '[Reconnect] Error reconnecting', err));
12721
+ this.reconnect(WebsocketReconnectStrategy.MIGRATE, 'goAway').catch((err) => this.logger.warn('[Reconnect] Error reconnecting', err));
12740
12722
  });
12741
12723
  // handles the "error" event, through which the SFU can request a reconnect
12742
12724
  const unregisterOnError = this.on('error', (e) => {
@@ -12745,19 +12727,19 @@ class Call {
12745
12727
  return;
12746
12728
  if (strategy === WebsocketReconnectStrategy.DISCONNECT) {
12747
12729
  this.leave({ message: 'SFU instructed to disconnect' }).catch((err) => {
12748
- this.logger('warn', `Can't leave call after disconnect request`, err);
12730
+ this.logger.warn(`Can't leave call after disconnect request`, err);
12749
12731
  });
12750
12732
  }
12751
12733
  else {
12752
12734
  this.reconnect(strategy, error?.message || 'SFU Error').catch((err) => {
12753
- this.logger('warn', '[Reconnect] Error reconnecting', err);
12735
+ this.logger.warn('[Reconnect] Error reconnecting', err);
12754
12736
  });
12755
12737
  }
12756
12738
  });
12757
12739
  const unregisterNetworkChanged = this.streamClient.on('network.changed', (e) => {
12758
12740
  this.tracer.trace('network.changed', e);
12759
12741
  if (!e.online) {
12760
- this.logger('debug', '[Reconnect] Going offline');
12742
+ this.logger.debug('[Reconnect] Going offline');
12761
12743
  if (!this.hasJoinedOnce)
12762
12744
  return;
12763
12745
  this.lastOfflineTimestamp = Date.now();
@@ -12774,7 +12756,7 @@ class Call {
12774
12756
  }
12775
12757
  }
12776
12758
  this.reconnect(strategy, 'Going online').catch((err) => {
12777
- this.logger('warn', '[Reconnect] Error reconnecting after going online', err);
12759
+ this.logger.warn('[Reconnect] Error reconnecting after going online', err);
12778
12760
  });
12779
12761
  });
12780
12762
  this.networkAvailableTask = networkAvailableTask;
@@ -12782,7 +12764,7 @@ class Call {
12782
12764
  this.state.setCallingState(CallingState.OFFLINE);
12783
12765
  }
12784
12766
  else {
12785
- this.logger('debug', '[Reconnect] Going online');
12767
+ this.logger.debug('[Reconnect] Going online');
12786
12768
  this.sfuClient?.close(StreamSfuClient.DISPOSE_OLD_SOCKET, 'Closing WS to reconnect after going online');
12787
12769
  // we went online, release the previous waiters and reset the state
12788
12770
  this.networkAvailableTask?.resolve();
@@ -12944,10 +12926,10 @@ class Call {
12944
12926
  * @param options the options to use.
12945
12927
  */
12946
12928
  this.updatePublishOptions = (options) => {
12947
- this.logger('warn', '[call.updatePublishOptions]: You are manually overriding the publish options for this call. ' +
12929
+ this.logger.warn('[call.updatePublishOptions]: You are manually overriding the publish options for this call. ' +
12948
12930
  'This is not recommended, and it can cause call stability/compatibility issues. Use with caution.');
12949
12931
  if (this.state.callingState === CallingState.JOINED) {
12950
- this.logger('warn', 'Updating publish options after joining the call does not have an effect');
12932
+ this.logger.warn('Updating publish options after joining the call does not have an effect');
12951
12933
  }
12952
12934
  this.clientPublishOptions = { ...this.clientPublishOptions, ...options };
12953
12935
  };
@@ -12958,7 +12940,7 @@ class Call {
12958
12940
  */
12959
12941
  this.notifyNoiseCancellationStarting = async () => {
12960
12942
  return this.sfuClient?.startNoiseCancellation().catch((err) => {
12961
- this.logger('warn', 'Failed to notify start of noise cancellation', err);
12943
+ this.logger.warn('Failed to notify start of noise cancellation', err);
12962
12944
  });
12963
12945
  };
12964
12946
  /**
@@ -12968,7 +12950,7 @@ class Call {
12968
12950
  */
12969
12951
  this.notifyNoiseCancellationStopped = async () => {
12970
12952
  return this.sfuClient?.stopNoiseCancellation().catch((err) => {
12971
- this.logger('warn', 'Failed to notify stop of noise cancellation', err);
12953
+ this.logger.warn('Failed to notify stop of noise cancellation', err);
12972
12954
  });
12973
12955
  };
12974
12956
  /**
@@ -13402,7 +13384,7 @@ class Call {
13402
13384
  reason: 'timeout',
13403
13385
  message: `ringing timeout - ${this.isCreatedByMe ? 'no one accepted' : `user didn't interact with incoming call screen`}`,
13404
13386
  }).catch((err) => {
13405
- this.logger('error', 'Failed to drop call', err);
13387
+ this.logger.error('Failed to drop call', err);
13406
13388
  });
13407
13389
  }, timeoutInMs);
13408
13390
  };
@@ -13514,10 +13496,10 @@ class Call {
13514
13496
  */
13515
13497
  this.applyDeviceConfig = async (settings, publish) => {
13516
13498
  await this.camera.apply(settings.video, publish).catch((err) => {
13517
- this.logger('warn', 'Camera init failed', err);
13499
+ this.logger.warn('Camera init failed', err);
13518
13500
  });
13519
13501
  await this.microphone.apply(settings.audio, publish).catch((err) => {
13520
- this.logger('warn', 'Mic init failed', err);
13502
+ this.logger.warn('Mic init failed', err);
13521
13503
  });
13522
13504
  };
13523
13505
  /**
@@ -13669,7 +13651,7 @@ class Call {
13669
13651
  this.streamClient = streamClient;
13670
13652
  this.clientStore = clientStore;
13671
13653
  this.streamClientBasePath = `/call/${this.type}/${this.id}`;
13672
- this.logger = getLogger(['Call']);
13654
+ this.logger = videoLoggerSystem.getLogger('Call');
13673
13655
  const callTypeConfig = CallTypes.get(type);
13674
13656
  const participantSorter = sortParticipantsBy || callTypeConfig.options.sortParticipantsBy;
13675
13657
  if (participantSorter) {
@@ -13756,7 +13738,7 @@ const APIErrorCodes = {
13756
13738
  class StableWSConnection {
13757
13739
  constructor(client) {
13758
13740
  this._log = (msg, extra = {}, level = 'info') => {
13759
- this.client.logger(level, `connection:${msg}`, extra);
13741
+ this.client.logger[level](`connection:${msg}`, extra);
13760
13742
  };
13761
13743
  this.setClient = (client) => {
13762
13744
  this.client = client;
@@ -13802,12 +13784,12 @@ class StableWSConnection {
13802
13784
  return;
13803
13785
  const user = this.client.user;
13804
13786
  if (!user) {
13805
- this.client.logger('error', `User not set, can't connect to WS`);
13787
+ this.client.logger.error(`User not set, can't connect to WS`);
13806
13788
  return;
13807
13789
  }
13808
13790
  const token = this.client._getToken();
13809
13791
  if (!token) {
13810
- this.client.logger('error', `Token not set, can't connect authenticate`);
13792
+ this.client.logger.error(`Token not set, can't connect authenticate`);
13811
13793
  return;
13812
13794
  }
13813
13795
  const authMessage = JSON.stringify({
@@ -14444,7 +14426,7 @@ class TokenManager {
14444
14426
  }
14445
14427
 
14446
14428
  const getLocationHint = async (hintUrl = `https://hint.stream-io-video.com/`, timeout = 2000, maxAttempts = 3) => {
14447
- const logger = getLogger(['location-hint']);
14429
+ const logger = videoLoggerSystem.getLogger('location-hint');
14448
14430
  let attempt = 0;
14449
14431
  let locationHint = 'ERR';
14450
14432
  do {
@@ -14456,11 +14438,11 @@ const getLocationHint = async (hintUrl = `https://hint.stream-io-video.com/`, ti
14456
14438
  signal: abortController.signal,
14457
14439
  });
14458
14440
  const awsPop = response.headers.get('x-amz-cf-pop') || 'ERR';
14459
- logger('debug', `Location header: ${awsPop}`);
14441
+ logger.debug(`Location header: ${awsPop}`);
14460
14442
  locationHint = awsPop.substring(0, 3); // AMS1-P2 -> AMS
14461
14443
  }
14462
14444
  catch (e) {
14463
- logger('warn', `Failed to get location hint from ${hintUrl}`, e);
14445
+ logger.warn(`Failed to get location hint from ${hintUrl}`, e);
14464
14446
  locationHint = 'ERR';
14465
14447
  }
14466
14448
  finally {
@@ -14521,14 +14503,14 @@ class StreamClient {
14521
14503
  * If the user id remains the same we don't throw error
14522
14504
  */
14523
14505
  if (this.userID === user.id && this.connectUserTask) {
14524
- this.logger('warn', 'Consecutive calls to connectUser is detected, ideally you should only call this function once in your app.');
14506
+ this.logger.warn('Consecutive calls to connectUser is detected, ideally you should only call this function once in your app.');
14525
14507
  return this.connectUserTask;
14526
14508
  }
14527
14509
  if (this.userID) {
14528
14510
  throw new Error('Use client.disconnect() before trying to connect as a different user. connectUser was called twice.');
14529
14511
  }
14530
14512
  if ((this.secret || this.node) && !this.options.allowServerSideConnect) {
14531
- this.logger('warn', 'Please do not use connectUser server side. Use our @stream-io/node-sdk instead: https://getstream.io/video/docs/api/');
14513
+ this.logger.warn('Please do not use connectUser server side. Use our @stream-io/node-sdk instead: https://getstream.io/video/docs/api/');
14532
14514
  }
14533
14515
  // we generate the client id client side
14534
14516
  this.userID = user.id;
@@ -14586,11 +14568,11 @@ class StreamClient {
14586
14568
  }
14587
14569
  const wsPromise = this.wsPromiseSafe?.();
14588
14570
  if (this.wsConnection?.isConnecting && wsPromise) {
14589
- this.logger('info', 'client:openConnection() - connection already in progress');
14571
+ this.logger.info('client:openConnection() - connection already in progress');
14590
14572
  return await wsPromise;
14591
14573
  }
14592
14574
  if (this.wsConnection?.isHealthy && this._hasConnectionID()) {
14593
- this.logger('info', 'client:openConnection() - openConnection called twice, healthy connection already exists');
14575
+ this.logger.info('client:openConnection() - openConnection called twice, healthy connection already exists');
14594
14576
  return;
14595
14577
  }
14596
14578
  this._setupConnectionIdPromise();
@@ -14606,7 +14588,7 @@ class StreamClient {
14606
14588
  * https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
14607
14589
  */
14608
14590
  this.disconnectUser = async (timeout) => {
14609
- this.logger('info', 'client:disconnect() - Disconnecting the client');
14591
+ this.logger.info('client:disconnect() - Disconnecting the client');
14610
14592
  // remove the user specific fields
14611
14593
  delete this.user;
14612
14594
  delete this._user;
@@ -14653,7 +14635,7 @@ class StreamClient {
14653
14635
  if (!this.listeners[eventName]) {
14654
14636
  this.listeners[eventName] = [];
14655
14637
  }
14656
- this.logger('debug', `Adding listener for ${eventName} event`);
14638
+ this.logger.debug(`Adding listener for ${eventName} event`);
14657
14639
  this.listeners[eventName]?.push(callback);
14658
14640
  return () => {
14659
14641
  this.off(eventName, callback);
@@ -14666,7 +14648,7 @@ class StreamClient {
14666
14648
  if (!this.listeners[eventName]) {
14667
14649
  this.listeners[eventName] = [];
14668
14650
  }
14669
- this.logger('debug', `Removing listener for ${eventName} event`);
14651
+ this.logger.debug(`Removing listener for ${eventName} event`);
14670
14652
  this.listeners[eventName] = this.listeners[eventName]?.filter((value) => value !== callback);
14671
14653
  };
14672
14654
  /**
@@ -14680,17 +14662,17 @@ class StreamClient {
14680
14662
  }));
14681
14663
  };
14682
14664
  this._logApiRequest = (type, url, data, config) => {
14683
- if (getLogLevel() !== 'trace')
14665
+ if (this.logger.getLogLevel() !== 'trace')
14684
14666
  return;
14685
- this.logger('trace', `client: ${type} - Request - ${url}`, {
14667
+ this.logger.trace(`client: ${type} - Request - ${url}`, {
14686
14668
  payload: data,
14687
14669
  config,
14688
14670
  });
14689
14671
  };
14690
14672
  this._logApiResponse = (type, url, response) => {
14691
- if (getLogLevel() !== 'trace')
14673
+ if (this.logger.getLogLevel() !== 'trace')
14692
14674
  return;
14693
- this.logger('trace', `client:${type} - Response - url: ${url} > status ${response.status}`, {
14675
+ this.logger.trace(`client:${type} - Response - url: ${url} > status ${response.status}`, {
14694
14676
  response,
14695
14677
  });
14696
14678
  };
@@ -14747,13 +14729,13 @@ class StreamClient {
14747
14729
  this.consecutiveFailures += 1;
14748
14730
  const { response } = e;
14749
14731
  if (!response || !isErrorResponse(response)) {
14750
- this.logger('error', `client:${type} url: ${url}`, e);
14732
+ this.logger.error(`client:${type} url: ${url}`, e);
14751
14733
  throw e;
14752
14734
  }
14753
14735
  const { data: responseData, status } = response;
14754
14736
  const isTokenExpired = responseData.code === KnownCodes.TOKEN_EXPIRED;
14755
14737
  if (isTokenExpired && !this.tokenManager.isStatic()) {
14756
- this.logger('warn', `client:${type}: url: ${url}`, response);
14738
+ this.logger.warn(`client:${type}: url: ${url}`, response);
14757
14739
  if (this.consecutiveFailures > 1) {
14758
14740
  await sleep(retryInterval(this.consecutiveFailures));
14759
14741
  }
@@ -14762,7 +14744,7 @@ class StreamClient {
14762
14744
  return await this.doAxiosRequest(type, url, data, options);
14763
14745
  }
14764
14746
  else {
14765
- this.logger('error', `client:${type} url: ${url}`, response);
14747
+ this.logger.error(`client:${type} url: ${url}`, response);
14766
14748
  throw new ErrorFromResponse({
14767
14749
  message: `Stream error code ${responseData.code}: ${responseData.message}`,
14768
14750
  code: responseData.code ?? null,
@@ -14793,7 +14775,7 @@ class StreamClient {
14793
14775
  });
14794
14776
  };
14795
14777
  this.dispatchEvent = (event) => {
14796
- this.logger('debug', `Dispatching event: ${event.type}`, event);
14778
+ this.logger.debug(`Dispatching event: ${event.type}`, event);
14797
14779
  if (!this.listeners)
14798
14780
  return;
14799
14781
  // call generic listeners
@@ -14818,13 +14800,13 @@ class StreamClient {
14818
14800
  throw Error('clientID is not set');
14819
14801
  // The StableWSConnection handles all the reconnection logic.
14820
14802
  this.wsConnection = new StableWSConnection(this);
14821
- this.logger('info', 'StreamClient.connect: this.wsConnection.connect()');
14803
+ this.logger.info('StreamClient.connect: this.wsConnection.connect()');
14822
14804
  return await this.wsConnection.connect(this.defaultWSTimeout);
14823
14805
  };
14824
14806
  this.getUserAgent = () => {
14825
14807
  if (!this.cachedUserAgent) {
14826
14808
  const { clientAppIdentifier = {} } = this.options;
14827
- const { sdkName = 'js', sdkVersion = "1.35.1", ...extras } = clientAppIdentifier;
14809
+ const { sdkName = 'js', sdkVersion = "1.36.0", ...extras } = clientAppIdentifier;
14828
14810
  this.cachedUserAgent = [
14829
14811
  `stream-video-${sdkName}-v${sdkVersion}`,
14830
14812
  ...Object.entries(extras).map(([key, value]) => `${key}=${value}`),
@@ -14875,11 +14857,11 @@ class StreamClient {
14875
14857
  };
14876
14858
  this.updateNetworkConnectionStatus = (event) => {
14877
14859
  if (event.type === 'offline') {
14878
- this.logger('debug', 'device went offline');
14860
+ this.logger.debug('device went offline');
14879
14861
  this.dispatchEvent({ type: 'network.changed', online: false });
14880
14862
  }
14881
14863
  else if (event.type === 'online') {
14882
- this.logger('debug', 'device went online');
14864
+ this.logger.debug('device went online');
14883
14865
  this.dispatchEvent({ type: 'network.changed', online: true });
14884
14866
  }
14885
14867
  };
@@ -14927,9 +14909,7 @@ class StreamClient {
14927
14909
  this.tokenManager = new TokenManager(this.secret);
14928
14910
  this.consecutiveFailures = 0;
14929
14911
  this.defaultWSTimeout = this.options.defaultWsTimeout ?? 15000;
14930
- this.logger = isFunction(inputOptions.logger)
14931
- ? inputOptions.logger
14932
- : () => null;
14912
+ this.logger = videoLoggerSystem.getLogger('coordinator');
14933
14913
  }
14934
14914
  get connectionIdPromise() {
14935
14915
  return this.connectionIdPromiseSafe?.();
@@ -14974,12 +14954,10 @@ const getClientAppIdentifier = (options) => {
14974
14954
  */
14975
14955
  const createCoordinatorClient = (apiKey, options) => {
14976
14956
  const clientAppIdentifier = getClientAppIdentifier(options);
14977
- const coordinatorLogger = getLogger(['coordinator']);
14978
14957
  return new StreamClient(apiKey, {
14979
14958
  persistUserOnConnectionFailure: true,
14980
14959
  ...options,
14981
14960
  clientAppIdentifier,
14982
- logger: coordinatorLogger,
14983
14961
  });
14984
14962
  };
14985
14963
  /**
@@ -15017,7 +14995,7 @@ class StreamVideoClient {
15017
14995
  this.registerClientInstance = (apiKey, user) => {
15018
14996
  const instanceKey = getInstanceKey(apiKey, user);
15019
14997
  if (StreamVideoClient._instances.has(instanceKey)) {
15020
- this.logger('warn', `A StreamVideoClient already exists for ${user.id}; Prefer using getOrCreateInstance method`);
14998
+ this.logger.warn(`A StreamVideoClient already exists for ${user.id}; Prefer using getOrCreateInstance method`);
15021
14999
  }
15022
15000
  StreamVideoClient._instances.set(instanceKey, this);
15023
15001
  };
@@ -15032,13 +15010,13 @@ class StreamVideoClient {
15032
15010
  .map((call) => call.cid);
15033
15011
  if (callsToReWatch.length <= 0)
15034
15012
  return;
15035
- this.logger('info', `Rewatching calls ${callsToReWatch.join(', ')}`);
15013
+ this.logger.info(`Rewatching calls ${callsToReWatch.join(', ')}`);
15036
15014
  this.queryCalls({
15037
15015
  watch: true,
15038
15016
  filter_conditions: { cid: { $in: callsToReWatch } },
15039
15017
  sort: [{ field: 'cid', direction: 1 }],
15040
15018
  }).catch((err) => {
15041
- this.logger('error', 'Failed to re-watch calls', err);
15019
+ this.logger.error('Failed to re-watch calls', err);
15042
15020
  });
15043
15021
  }));
15044
15022
  this.effectsRegistered = true;
@@ -15049,7 +15027,7 @@ class StreamVideoClient {
15049
15027
  */
15050
15028
  this.initCallFromEvent = async (e) => {
15051
15029
  if (this.state.connectedUser?.id === e.call.created_by.id) {
15052
- this.logger('debug', `Ignoring ${e.type} event sent by the current user`);
15030
+ this.logger.debug(`Ignoring ${e.type} event sent by the current user`);
15053
15031
  return;
15054
15032
  }
15055
15033
  try {
@@ -15060,7 +15038,7 @@ class StreamVideoClient {
15060
15038
  if (call) {
15061
15039
  if (ringing) {
15062
15040
  if (this.shouldRejectCall(call.cid)) {
15063
- this.logger('info', `Leaving call with busy reject reason ${call.cid} because user is busy`);
15041
+ this.logger.info(`Leaving call with busy reject reason ${call.cid} because user is busy`);
15064
15042
  // remove the instance from the state store
15065
15043
  await call.leave();
15066
15044
  // explicitly reject the call with busy reason as calling state was not ringing before and leave would not call it therefore
@@ -15085,7 +15063,7 @@ class StreamVideoClient {
15085
15063
  });
15086
15064
  if (ringing) {
15087
15065
  if (this.shouldRejectCall(call.cid)) {
15088
- this.logger('info', `Rejecting call ${call.cid} because user is busy`);
15066
+ this.logger.info(`Rejecting call ${call.cid} because user is busy`);
15089
15067
  // call is not in the state store yet, so just reject api is enough
15090
15068
  await call.reject('busy');
15091
15069
  }
@@ -15097,12 +15075,12 @@ class StreamVideoClient {
15097
15075
  else {
15098
15076
  call.state.updateFromCallResponse(e.call);
15099
15077
  this.writeableStateStore.registerCall(call);
15100
- this.logger('info', `New call created and registered: ${call.cid}`);
15078
+ this.logger.info(`New call created and registered: ${call.cid}`);
15101
15079
  }
15102
15080
  });
15103
15081
  }
15104
15082
  catch (err) {
15105
- this.logger('error', `Failed to init call from event ${e.type}`, err);
15083
+ this.logger.error(`Failed to init call from event ${e.type}`, err);
15106
15084
  }
15107
15085
  };
15108
15086
  /**
@@ -15126,13 +15104,13 @@ class StreamVideoClient {
15126
15104
  const errorQueue = [];
15127
15105
  for (let attempt = 0; attempt < maxConnectUserRetries; attempt++) {
15128
15106
  try {
15129
- this.logger('trace', `Connecting user (${attempt})`, user);
15107
+ this.logger.trace(`Connecting user (${attempt})`, user);
15130
15108
  return user.type === 'guest'
15131
15109
  ? await client.connectGuestUser(user)
15132
15110
  : await client.connectUser(user, tokenOrProvider);
15133
15111
  }
15134
15112
  catch (err) {
15135
- this.logger('warn', `Failed to connect a user (${attempt})`, err);
15113
+ this.logger.warn(`Failed to connect a user (${attempt})`, err);
15136
15114
  errorQueue.push(err);
15137
15115
  if (attempt === maxConnectUserRetries - 1) {
15138
15116
  onConnectUserError?.(err, errorQueue);
@@ -15377,8 +15355,11 @@ class StreamVideoClient {
15377
15355
  if (clientOptions?.enableTimerWorker)
15378
15356
  enableTimerWorker();
15379
15357
  const rootLogger = clientOptions?.logger || logToConsole;
15380
- setLogger(rootLogger, clientOptions?.logLevel || 'warn');
15381
- this.logger = getLogger(['client']);
15358
+ videoLoggerSystem.configureLoggers({
15359
+ default: { sink: rootLogger, level: clientOptions?.logLevel || 'warn' },
15360
+ ...clientOptions?.logOptions,
15361
+ });
15362
+ this.logger = videoLoggerSystem.getLogger('client');
15382
15363
  this.rejectCallWhenBusy = clientOptions?.rejectCallWhenBusy ?? false;
15383
15364
  this.streamClient = createCoordinatorClient(apiKey, clientOptions);
15384
15365
  this.writeableStateStore = new StreamVideoWriteableStateStore();
@@ -15391,7 +15372,7 @@ class StreamVideoClient {
15391
15372
  this.registerClientInstance(apiKey, user);
15392
15373
  const tokenOrProvider = createTokenOrProvider(apiKeyOrArgs);
15393
15374
  this.connectUser(user, tokenOrProvider).catch((err) => {
15394
- this.logger('error', 'Failed to connect', err);
15375
+ this.logger.error('Failed to connect', err);
15395
15376
  });
15396
15377
  }
15397
15378
  }
@@ -15421,5 +15402,5 @@ class StreamVideoClient {
15421
15402
  }
15422
15403
  StreamVideoClient._instances = new Map();
15423
15404
 
15424
- export { AudioSettingsRequestDefaultDeviceEnum, AudioSettingsResponseDefaultDeviceEnum, browsers as Browsers, Call, CallState, CallType, CallTypes, CallingState, CameraManager, CameraManagerState, CreateDeviceRequestPushProviderEnum, DebounceType, DeviceManager, DeviceManagerState, DynascaleManager, ErrorFromResponse, FrameRecordingSettingsRequestModeEnum, FrameRecordingSettingsRequestQualityEnum, FrameRecordingSettingsResponseModeEnum, IngressAudioEncodingOptionsRequestChannelsEnum, IngressSourceRequestFpsEnum, IngressVideoLayerRequestCodecEnum, LayoutSettingsRequestNameEnum, MicrophoneManager, MicrophoneManagerState, NoiseCancellationSettingsModeEnum, OwnCapability, RNSpeechDetector, RTMPBroadcastRequestQualityEnum, RTMPSettingsRequestQualityEnum, RecordSettingsRequestModeEnum, RecordSettingsRequestQualityEnum, rxUtils as RxUtils, ScreenShareManager, ScreenShareState, events as SfuEvents, models as SfuModels, SpeakerManager, SpeakerState, StartClosedCaptionsRequestLanguageEnum, StartTranscriptionRequestLanguageEnum, 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, getDeviceState, getLogLevel, getLogger, getScreenShareStream, getSdkInfo, getVideoBrowserPermission, getVideoDevices, getVideoStream, getWebRTCInfo, hasAudio, hasPausedTrack, hasScreenShare, hasScreenShareAudio, hasVideo, isPinned, livestreamOrAudioRoomSortPreset, logLevels, logToConsole, name, noopComparator, paginatedLayoutSortPreset, pinned, publishingAudio, publishingVideo, reactionType, resolveDeviceId, role, screenSharing, setDeviceInfo, setLogLevel, setLogger, setOSInfo, setPowerState, setSdkInfo, setThermalState, setWebRTCInfo, speakerLayoutSortPreset, speaking, withParticipantSource };
15405
+ export { AudioSettingsRequestDefaultDeviceEnum, AudioSettingsResponseDefaultDeviceEnum, browsers as Browsers, Call, CallState, CallType, CallTypes, CallingState, CameraManager, CameraManagerState, CreateDeviceRequestPushProviderEnum, DebounceType, DeviceManager, DeviceManagerState, DynascaleManager, ErrorFromResponse, FrameRecordingSettingsRequestModeEnum, FrameRecordingSettingsRequestQualityEnum, FrameRecordingSettingsResponseModeEnum, IngressAudioEncodingOptionsRequestChannelsEnum, IngressSourceRequestFpsEnum, IngressVideoLayerRequestCodecEnum, LayoutSettingsRequestNameEnum, MicrophoneManager, MicrophoneManagerState, NoiseCancellationSettingsModeEnum, OwnCapability, RNSpeechDetector, RTMPBroadcastRequestQualityEnum, RTMPSettingsRequestQualityEnum, RecordSettingsRequestModeEnum, RecordSettingsRequestQualityEnum, rxUtils as RxUtils, ScreenShareManager, ScreenShareState, events as SfuEvents, models as SfuModels, SpeakerManager, SpeakerState, StartClosedCaptionsRequestLanguageEnum, StartTranscriptionRequestLanguageEnum, 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, getDeviceState, getScreenShareStream, getSdkInfo, getVideoBrowserPermission, getVideoDevices, getVideoStream, getWebRTCInfo, hasAudio, hasPausedTrack, hasScreenShare, hasScreenShareAudio, hasVideo, isPinned, livestreamOrAudioRoomSortPreset, logToConsole, name, noopComparator, paginatedLayoutSortPreset, pinned, publishingAudio, publishingVideo, reactionType, resolveDeviceId, role, screenSharing, setDeviceInfo, setOSInfo, setPowerState, setSdkInfo, setThermalState, setWebRTCInfo, speakerLayoutSortPreset, speaking, videoLoggerSystem, withParticipantSource };
15425
15406
  //# sourceMappingURL=index.es.js.map