@stream-io/video-client 1.35.0 → 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 +10 -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 +4 -3
  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.cjs.js CHANGED
@@ -5,12 +5,32 @@ var runtime = require('@protobuf-ts/runtime');
5
5
  var runtimeRpc = require('@protobuf-ts/runtime-rpc');
6
6
  var axios = require('axios');
7
7
  var twirpTransport = require('@protobuf-ts/twirp-transport');
8
+ var scopedLogger = require('@stream-io/logger');
8
9
  var rxjs = require('rxjs');
9
10
  var uaParserJs = require('ua-parser-js');
10
11
  var sdpTransform = require('sdp-transform');
11
12
  var workerTimer = require('@stream-io/worker-timer');
12
13
  var https = require('https');
13
14
 
15
+ function _interopNamespaceDefault(e) {
16
+ var n = Object.create(null);
17
+ if (e) {
18
+ Object.keys(e).forEach(function (k) {
19
+ if (k !== 'default') {
20
+ var d = Object.getOwnPropertyDescriptor(e, k);
21
+ Object.defineProperty(n, k, d.get ? d : {
22
+ enumerable: true,
23
+ get: function () { return e[k]; }
24
+ });
25
+ }
26
+ });
27
+ }
28
+ n.default = e;
29
+ return Object.freeze(n);
30
+ }
31
+
32
+ var scopedLogger__namespace = /*#__PURE__*/_interopNamespaceDefault(scopedLogger);
33
+
14
34
  /* tslint:disable */
15
35
  /**
16
36
  * @export
@@ -3727,7 +3747,7 @@ const withRequestLogger = (logger, level) => {
3727
3747
  return {
3728
3748
  interceptUnary: (next, method, input, options) => {
3729
3749
  const invocation = next(method, input, options);
3730
- logger(level, `Invoked SFU RPC method ${method.name}`, {
3750
+ logger[level](`Invoked SFU RPC method ${method.name}`, {
3731
3751
  request: invocation.request,
3732
3752
  headers: invocation.requestHeaders,
3733
3753
  response: invocation.response,
@@ -3863,16 +3883,6 @@ const isReactNative = () => {
3863
3883
  return navigator.product?.toLowerCase() === 'reactnative';
3864
3884
  };
3865
3885
 
3866
- // log levels, sorted by verbosity
3867
- const logLevels = Object.freeze({
3868
- trace: 0,
3869
- debug: 1,
3870
- info: 2,
3871
- warn: 3,
3872
- error: 4,
3873
- });
3874
- let logger;
3875
- let level = 'info';
3876
3886
  const logToConsole = (logLevel, message, ...args) => {
3877
3887
  let logMethod;
3878
3888
  switch (logLevel) {
@@ -3904,26 +3914,7 @@ const logToConsole = (logLevel, message, ...args) => {
3904
3914
  }
3905
3915
  logMethod(message, ...args);
3906
3916
  };
3907
- const setLogger = (l, lvl) => {
3908
- logger = l;
3909
- if (lvl) {
3910
- setLogLevel(lvl);
3911
- }
3912
- };
3913
- const setLogLevel = (l) => {
3914
- level = l;
3915
- };
3916
- const getLogLevel = () => level;
3917
- const getLogger = (withTags) => {
3918
- const loggerMethod = logger || logToConsole;
3919
- const tags = (withTags || []).filter(Boolean).join(':');
3920
- const result = (logLevel, message, ...args) => {
3921
- if (logLevels[logLevel] >= logLevels[level]) {
3922
- loggerMethod(logLevel, `[${tags}]: ${message}`, ...args);
3923
- }
3924
- };
3925
- return result;
3926
- };
3917
+ const videoLoggerSystem = scopedLogger__namespace.createLoggerSystem();
3927
3918
 
3928
3919
  /**
3929
3920
  * Creates a closure which wraps the given RPC call and retries invoking
@@ -3949,7 +3940,9 @@ const retryable = async (rpc, signal) => {
3949
3940
  const isAborted = signal?.aborted ?? false;
3950
3941
  if (isRequestCancelled || isAborted)
3951
3942
  throw err;
3952
- getLogger(['sfu-client', 'rpc'])('debug', `rpc failed (${attempt})`, err);
3943
+ videoLoggerSystem
3944
+ .getLogger('sfu-client', { tags: ['rpc'] })
3945
+ .debug(`rpc failed (${attempt})`, err);
3953
3946
  attempt++;
3954
3947
  }
3955
3948
  } while (!result || result.response.error?.shouldRetry);
@@ -4020,14 +4013,14 @@ const isSfuEvent = (eventName) => {
4020
4013
  };
4021
4014
  class Dispatcher {
4022
4015
  constructor() {
4023
- this.logger = getLogger(['Dispatcher']);
4016
+ this.logger = videoLoggerSystem.getLogger('Dispatcher');
4024
4017
  this.subscribers = {};
4025
4018
  this.dispatch = (message, tag = '0') => {
4026
4019
  const eventKind = message.eventPayload.oneofKind;
4027
4020
  if (!eventKind)
4028
4021
  return;
4029
4022
  const payload = message.eventPayload[eventKind];
4030
- this.logger('debug', `Dispatching ${eventKind}, tag=${tag}`, payload);
4023
+ this.logger.debug(`Dispatching ${eventKind}, tag=${tag}`, payload);
4031
4024
  const listeners = this.subscribers[eventKind];
4032
4025
  if (!listeners)
4033
4026
  return;
@@ -4036,7 +4029,7 @@ class Dispatcher {
4036
4029
  fn(payload);
4037
4030
  }
4038
4031
  catch (e) {
4039
- this.logger('warn', 'Listener failed with error', e);
4032
+ this.logger.warn('Listener failed with error', e);
4040
4033
  }
4041
4034
  }
4042
4035
  };
@@ -4072,8 +4065,8 @@ class IceTrickleBuffer {
4072
4065
  this.publisherCandidates.next(iceCandidate);
4073
4066
  }
4074
4067
  else {
4075
- const logger = getLogger(['sfu-client']);
4076
- logger('warn', `ICETrickle, Unknown peer type`, iceTrickle);
4068
+ const logger = videoLoggerSystem.getLogger('sfu-client');
4069
+ logger.warn(`ICETrickle, Unknown peer type`, iceTrickle);
4077
4070
  }
4078
4071
  };
4079
4072
  this.dispose = () => {
@@ -4087,8 +4080,8 @@ const toIceCandidate = (iceTrickle) => {
4087
4080
  return JSON.parse(iceTrickle.iceCandidate);
4088
4081
  }
4089
4082
  catch (e) {
4090
- const logger = getLogger(['sfu-client']);
4091
- logger('error', `Failed to parse ICE Trickle`, e, iceTrickle);
4083
+ const logger = videoLoggerSystem.getLogger('sfu-client');
4084
+ logger.error(`Failed to parse ICE Trickle`, e, iceTrickle);
4092
4085
  return undefined;
4093
4086
  }
4094
4087
  };
@@ -4264,7 +4257,9 @@ const updateValue = (subject, update) => {
4264
4257
  * @param handler the handler to call when the observable emits a value.
4265
4258
  * @param onError an optional error handler.
4266
4259
  */
4267
- const createSubscription = (observable, handler, onError = (error) => getLogger(['RxUtils'])('warn', 'An observable emitted an error', error)) => {
4260
+ const createSubscription = (observable, handler, onError = (error) => videoLoggerSystem
4261
+ .getLogger('RxUtils')
4262
+ .warn('An observable emitted an error', error)) => {
4268
4263
  const subscription = observable.subscribe({ next: handler, error: onError });
4269
4264
  return () => {
4270
4265
  subscription.unsubscribe();
@@ -4384,8 +4379,8 @@ class StreamVideoWriteableStateStore {
4384
4379
  * @param call the call to remove
4385
4380
  */
4386
4381
  this.unregisterCall = (call) => {
4387
- const logger = getLogger(['client-state']);
4388
- logger('trace', `Unregistering call: ${call.cid}`);
4382
+ const logger = videoLoggerSystem.getLogger('client-state');
4383
+ logger.trace(`Unregistering call: ${call.cid}`);
4389
4384
  return this.setCalls((calls) => calls.filter((c) => c !== call));
4390
4385
  };
4391
4386
  /**
@@ -4400,15 +4395,15 @@ class StreamVideoWriteableStateStore {
4400
4395
  this.connectedUserSubject.subscribe(async (user) => {
4401
4396
  // leave all calls when the user disconnects.
4402
4397
  if (!user) {
4403
- const logger = getLogger(['client-state']);
4398
+ const logger = videoLoggerSystem.getLogger('client-state');
4404
4399
  for (const call of this.calls) {
4405
4400
  if (call.state.callingState === exports.CallingState.LEFT)
4406
4401
  continue;
4407
- logger('info', `User disconnected, leaving call: ${call.cid}`);
4402
+ logger.info(`User disconnected, leaving call: ${call.cid}`);
4408
4403
  await call
4409
4404
  .leave({ message: 'client.disconnectUser() called' })
4410
4405
  .catch((err) => {
4411
- logger('error', `Error leaving call: ${call.cid}`, err);
4406
+ logger.error(`Error leaving call: ${call.cid}`, err);
4412
4407
  });
4413
4408
  }
4414
4409
  }
@@ -4802,7 +4797,7 @@ class CallState {
4802
4797
  // We keep these tracks around until we can associate them with a participant.
4803
4798
  this.orphanedTracks = [];
4804
4799
  this.callGrantsSubject = new rxjs.ReplaySubject(1);
4805
- this.logger = getLogger(['CallState']);
4800
+ this.logger = videoLoggerSystem.getLogger('CallState');
4806
4801
  /**
4807
4802
  * A list of comparators that are used to sort the participants.
4808
4803
  */
@@ -4983,7 +4978,7 @@ class CallState {
4983
4978
  this.updateParticipant = (sessionId, patch) => {
4984
4979
  const participant = this.findParticipantBySessionId(sessionId);
4985
4980
  if (!participant) {
4986
- this.logger('warn', `Participant with sessionId ${sessionId} not found`);
4981
+ this.logger.warn(`Participant with sessionId ${sessionId} not found`);
4987
4982
  return;
4988
4983
  }
4989
4984
  const thePatch = typeof patch === 'function' ? patch(participant) : patch;
@@ -5862,7 +5857,7 @@ const getSdkVersion = (sdk) => {
5862
5857
  return sdk ? `${sdk.major}.${sdk.minor}.${sdk.patch}` : '0.0.0-development';
5863
5858
  };
5864
5859
 
5865
- const version = "1.35.0";
5860
+ const version = "1.36.0";
5866
5861
  const [major, minor, patch] = version.split('.');
5867
5862
  let sdkInfo = {
5868
5863
  type: SdkType.PLAIN_JAVASCRIPT,
@@ -6065,7 +6060,7 @@ var browsers = /*#__PURE__*/Object.freeze({
6065
6060
  * Creates a new StatsReporter instance that collects metrics about the ongoing call and reports them to the state store
6066
6061
  */
6067
6062
  const createStatsReporter = ({ subscriber, publisher, state, datacenter, pollingIntervalInMs = 2000, }) => {
6068
- const logger = getLogger(['stats']);
6063
+ const logger = videoLoggerSystem.getLogger('stats');
6069
6064
  const getRawStatsForTrack = async (kind, selector) => {
6070
6065
  if (kind === 'subscriber' && subscriber) {
6071
6066
  return subscriber.getStats(selector);
@@ -6124,7 +6119,7 @@ const createStatsReporter = ({ subscriber, publisher, state, datacenter, polling
6124
6119
  participantStats[sessionId] = await getStatsForStream(kind, tracks);
6125
6120
  }
6126
6121
  catch (e) {
6127
- logger('warn', `Failed to collect ${kind} stats for ${userId}`, e);
6122
+ logger.warn(`Failed to collect ${kind} stats for ${userId}`, e);
6128
6123
  }
6129
6124
  }
6130
6125
  }
@@ -6156,7 +6151,7 @@ const createStatsReporter = ({ subscriber, publisher, state, datacenter, polling
6156
6151
  // (they are expensive) if no one is listening to them
6157
6152
  if (state.isCallStatsReportObserved) {
6158
6153
  await run().catch((e) => {
6159
- logger('debug', 'Failed to collect stats', e);
6154
+ logger.debug('Failed to collect stats', e);
6160
6155
  });
6161
6156
  }
6162
6157
  timeoutId = setTimeout(loop, pollingIntervalInMs);
@@ -6302,7 +6297,7 @@ const aggregate = (stats) => {
6302
6297
 
6303
6298
  class SfuStatsReporter {
6304
6299
  constructor(sfuClient, { options, clientDetails, subscriber, publisher, microphone, camera, state, tracer, unifiedSessionId, }) {
6305
- this.logger = getLogger(['SfuStatsReporter']);
6300
+ this.logger = videoLoggerSystem.getLogger('SfuStatsReporter');
6306
6301
  this.inputDevices = new Map();
6307
6302
  this.observeDevice = (device, kind) => {
6308
6303
  const { browserPermissionState$ } = device.state;
@@ -6353,7 +6348,7 @@ class SfuStatsReporter {
6353
6348
  // intentionally not awaiting the promise here
6354
6349
  // to avoid impeding with the ongoing actions.
6355
6350
  this.run(telemetryData).catch((err) => {
6356
- this.logger('warn', 'Failed to send telemetry data', err);
6351
+ this.logger.warn('Failed to send telemetry data', err);
6357
6352
  });
6358
6353
  };
6359
6354
  this.run = async (telemetry) => {
@@ -6412,7 +6407,7 @@ class SfuStatsReporter {
6412
6407
  clearInterval(this.intervalId);
6413
6408
  this.intervalId = setInterval(() => {
6414
6409
  this.run().catch((err) => {
6415
- this.logger('warn', 'Failed to report stats', err);
6410
+ this.logger.warn('Failed to report stats', err);
6416
6411
  });
6417
6412
  }, this.options.reporting_interval_ms);
6418
6413
  };
@@ -6429,14 +6424,14 @@ class SfuStatsReporter {
6429
6424
  };
6430
6425
  this.flush = () => {
6431
6426
  this.run().catch((err) => {
6432
- this.logger('warn', 'Failed to flush report stats', err);
6427
+ this.logger.warn('Failed to flush report stats', err);
6433
6428
  });
6434
6429
  };
6435
6430
  this.scheduleOne = (timeout) => {
6436
6431
  clearTimeout(this.timeoutId);
6437
6432
  this.timeoutId = setTimeout(() => {
6438
6433
  this.run().catch((err) => {
6439
- this.logger('warn', 'Failed to report stats', err);
6434
+ this.logger.warn('Failed to report stats', err);
6440
6435
  });
6441
6436
  }, timeout);
6442
6437
  };
@@ -6807,7 +6802,7 @@ class BasePeerConnection {
6807
6802
  this.tryRestartIce = () => {
6808
6803
  this.restartIce().catch((e) => {
6809
6804
  const reason = 'restartICE() failed, initiating reconnect';
6810
- this.logger('error', reason, e);
6805
+ this.logger.error(reason, e);
6811
6806
  const strategy = e instanceof NegotiationError &&
6812
6807
  e.error.code === ErrorCode.PARTICIPANT_SIGNAL_LOST
6813
6808
  ? WebsocketReconnectStrategy.FAST
@@ -6825,7 +6820,7 @@ class BasePeerConnection {
6825
6820
  withoutConcurrency(lockKey, async () => fn(e)).catch((err) => {
6826
6821
  if (this.isDisposed)
6827
6822
  return;
6828
- this.logger('warn', `Error handling ${event}`, err);
6823
+ this.logger.warn(`Error handling ${event}`, err);
6829
6824
  });
6830
6825
  }));
6831
6826
  };
@@ -6842,7 +6837,7 @@ class BasePeerConnection {
6842
6837
  return this.pc.addIceCandidate(candidate).catch((e) => {
6843
6838
  if (this.isDisposed)
6844
6839
  return;
6845
- this.logger('warn', `ICE candidate error`, e, candidate);
6840
+ this.logger.warn(`ICE candidate error`, e, candidate);
6846
6841
  });
6847
6842
  });
6848
6843
  };
@@ -6886,7 +6881,7 @@ class BasePeerConnection {
6886
6881
  this.onIceCandidate = (e) => {
6887
6882
  const { candidate } = e;
6888
6883
  if (!candidate) {
6889
- this.logger('debug', 'null ice candidate');
6884
+ this.logger.debug('null ice candidate');
6890
6885
  return;
6891
6886
  }
6892
6887
  const iceCandidate = this.asJSON(candidate);
@@ -6895,7 +6890,7 @@ class BasePeerConnection {
6895
6890
  .catch((err) => {
6896
6891
  if (this.isDisposed)
6897
6892
  return;
6898
- this.logger('warn', `ICETrickle failed`, err);
6893
+ this.logger.warn(`ICETrickle failed`, err);
6899
6894
  });
6900
6895
  };
6901
6896
  /**
@@ -6916,7 +6911,7 @@ class BasePeerConnection {
6916
6911
  */
6917
6912
  this.onConnectionStateChange = async () => {
6918
6913
  const state = this.pc.connectionState;
6919
- this.logger('debug', `Connection state changed`, state);
6914
+ this.logger.debug(`Connection state changed`, state);
6920
6915
  if (this.tracer && (state === 'connected' || state === 'failed')) {
6921
6916
  try {
6922
6917
  const stats = await this.stats.get();
@@ -6938,7 +6933,7 @@ class BasePeerConnection {
6938
6933
  */
6939
6934
  this.onIceConnectionStateChange = () => {
6940
6935
  const state = this.pc.iceConnectionState;
6941
- this.logger('debug', `ICE connection state changed`, state);
6936
+ this.logger.debug(`ICE connection state changed`, state);
6942
6937
  this.handleConnectionStateUpdate(state);
6943
6938
  };
6944
6939
  this.handleConnectionStateUpdate = (state) => {
@@ -6953,13 +6948,13 @@ class BasePeerConnection {
6953
6948
  switch (state) {
6954
6949
  case 'failed':
6955
6950
  // in the `failed` state, we try to restart ICE immediately
6956
- this.logger('info', 'restartICE due to failed connection');
6951
+ this.logger.info('restartICE due to failed connection');
6957
6952
  this.tryRestartIce();
6958
6953
  break;
6959
6954
  case 'disconnected':
6960
6955
  // in the `disconnected` state, we schedule a restartICE() after a delay
6961
6956
  // as the browser might recover the connection in the meantime
6962
- this.logger('info', 'disconnected connection, scheduling restartICE');
6957
+ this.logger.info('disconnected connection, scheduling restartICE');
6963
6958
  clearTimeout(this.iceRestartTimeout);
6964
6959
  this.iceRestartTimeout = setTimeout(() => {
6965
6960
  const currentState = this.pc.iceConnectionState;
@@ -6971,7 +6966,7 @@ class BasePeerConnection {
6971
6966
  case 'connected':
6972
6967
  // in the `connected` state, we clear the ice restart timeout if it exists
6973
6968
  if (this.iceRestartTimeout) {
6974
- this.logger('info', 'connected connection, canceling restartICE');
6969
+ this.logger.info('connected connection, canceling restartICE');
6975
6970
  clearTimeout(this.iceRestartTimeout);
6976
6971
  this.iceRestartTimeout = undefined;
6977
6972
  }
@@ -6985,19 +6980,19 @@ class BasePeerConnection {
6985
6980
  const errorMessage = e instanceof RTCPeerConnectionIceErrorEvent
6986
6981
  ? `${e.errorCode}: ${e.errorText}`
6987
6982
  : e;
6988
- this.logger('debug', 'ICE Candidate error', errorMessage);
6983
+ this.logger.debug('ICE Candidate error', errorMessage);
6989
6984
  };
6990
6985
  /**
6991
6986
  * Handles the ICE gathering state change event.
6992
6987
  */
6993
6988
  this.onIceGatherChange = () => {
6994
- this.logger('debug', `ICE Gathering State`, this.pc.iceGatheringState);
6989
+ this.logger.debug(`ICE Gathering State`, this.pc.iceGatheringState);
6995
6990
  };
6996
6991
  /**
6997
6992
  * Handles the signaling state change event.
6998
6993
  */
6999
6994
  this.onSignalingChange = () => {
7000
- this.logger('debug', `Signaling state changed`, this.pc.signalingState);
6995
+ this.logger.debug(`Signaling state changed`, this.pc.signalingState);
7001
6996
  };
7002
6997
  this.peerType = peerType;
7003
6998
  this.sfuClient = sfuClient;
@@ -7005,10 +7000,7 @@ class BasePeerConnection {
7005
7000
  this.dispatcher = dispatcher;
7006
7001
  this.iceRestartDelay = iceRestartDelay;
7007
7002
  this.onReconnectionNeeded = onReconnectionNeeded;
7008
- this.logger = getLogger([
7009
- peerType === PeerType.SUBSCRIBER ? 'Subscriber' : 'Publisher',
7010
- tag,
7011
- ]);
7003
+ this.logger = videoLoggerSystem.getLogger(peerType === PeerType.SUBSCRIBER ? 'Subscriber' : 'Publisher', { tags: [tag] });
7012
7004
  this.pc = this.createPeerConnection(connectionConfig);
7013
7005
  this.stats = new StatsTracer(this.pc, peerType, this.trackIdToTrackType);
7014
7006
  if (enableTracing) {
@@ -7131,7 +7123,7 @@ class TransceiverCache {
7131
7123
  }
7132
7124
 
7133
7125
  const ensureExhausted = (x, message) => {
7134
- getLogger(['helpers'])('warn', message, x);
7126
+ videoLoggerSystem.getLogger('helpers').warn(message, x);
7135
7127
  };
7136
7128
 
7137
7129
  const trackTypeToParticipantStreamKey = (trackType) => {
@@ -7470,7 +7462,7 @@ class Publisher extends BasePeerConnection {
7470
7462
  params.degradationPreference = 'maintain-framerate';
7471
7463
  await transceiver.sender.setParameters(params);
7472
7464
  const trackType = publishOption.trackType;
7473
- this.logger('debug', `Added ${TrackType[trackType]} transceiver`);
7465
+ this.logger.debug(`Added ${TrackType[trackType]} transceiver`);
7474
7466
  this.transceiverCache.add({ publishOption, transceiver, options });
7475
7467
  this.trackIdToTrackType.set(track.id, trackType);
7476
7468
  await this.negotiate();
@@ -7590,16 +7582,16 @@ class Publisher extends BasePeerConnection {
7590
7582
  const { trackType, layers, publishOptionId } = videoSender;
7591
7583
  const enabledLayers = layers.filter((l) => l.active);
7592
7584
  const tag = 'Update publish quality:';
7593
- this.logger('info', `${tag} requested layers by SFU:`, enabledLayers);
7585
+ this.logger.info(`${tag} requested layers by SFU:`, enabledLayers);
7594
7586
  const transceiverId = this.transceiverCache.find((t) => t.publishOption.id === publishOptionId &&
7595
7587
  t.publishOption.trackType === trackType);
7596
7588
  const sender = transceiverId?.transceiver.sender;
7597
7589
  if (!sender) {
7598
- return this.logger('warn', `${tag} no video sender found.`);
7590
+ return this.logger.warn(`${tag} no video sender found.`);
7599
7591
  }
7600
7592
  const params = sender.getParameters();
7601
7593
  if (params.encodings.length === 0) {
7602
- return this.logger('warn', `${tag} there are no encodings set.`);
7594
+ return this.logger.warn(`${tag} there are no encodings set.`);
7603
7595
  }
7604
7596
  const codecInUse = transceiverId?.publishOption.codec?.name;
7605
7597
  const usesSvcCodec = codecInUse && isSvcCodec(codecInUse);
@@ -7643,19 +7635,19 @@ class Publisher extends BasePeerConnection {
7643
7635
  }
7644
7636
  const activeEncoders = params.encodings.filter((e) => e.active);
7645
7637
  if (!changed) {
7646
- return this.logger('info', `${tag} no change:`, activeEncoders);
7638
+ return this.logger.info(`${tag} no change:`, activeEncoders);
7647
7639
  }
7648
7640
  await sender.setParameters(params);
7649
- this.logger('info', `${tag} enabled rids:`, activeEncoders);
7641
+ this.logger.info(`${tag} enabled rids:`, activeEncoders);
7650
7642
  };
7651
7643
  /**
7652
7644
  * Restarts the ICE connection and renegotiates with the SFU.
7653
7645
  */
7654
7646
  this.restartIce = async () => {
7655
- this.logger('debug', 'Restarting ICE connection');
7647
+ this.logger.debug('Restarting ICE connection');
7656
7648
  const signalingState = this.pc.signalingState;
7657
7649
  if (this.isIceRestarting || signalingState === 'have-local-offer') {
7658
- this.logger('debug', 'ICE restart is already in progress');
7650
+ this.logger.debug('ICE restart is already in progress');
7659
7651
  return;
7660
7652
  }
7661
7653
  await this.negotiate({ iceRestart: true });
@@ -7817,13 +7809,13 @@ class Subscriber extends BasePeerConnection {
7817
7809
  * Restarts the ICE connection and renegotiates with the SFU.
7818
7810
  */
7819
7811
  this.restartIce = async () => {
7820
- this.logger('debug', 'Restarting ICE connection');
7812
+ this.logger.debug('Restarting ICE connection');
7821
7813
  if (this.pc.signalingState === 'have-remote-offer') {
7822
- this.logger('debug', 'ICE restart is already in progress');
7814
+ this.logger.debug('ICE restart is already in progress');
7823
7815
  return;
7824
7816
  }
7825
7817
  if (this.pc.connectionState === 'new') {
7826
- this.logger('debug', `ICE connection is not yet established, skipping restart.`);
7818
+ this.logger.debug(`ICE connection is not yet established, skipping restart.`);
7827
7819
  return;
7828
7820
  }
7829
7821
  const previousIsIceRestarting = this.isIceRestarting;
@@ -7846,25 +7838,25 @@ class Subscriber extends BasePeerConnection {
7846
7838
  // example: `e3f6aaf8-b03d-4911-be36-83f47d37a76a:TRACK_TYPE_VIDEO`
7847
7839
  const [trackId, rawTrackType] = primaryStream.id.split(':');
7848
7840
  const participantToUpdate = this.state.participants.find((p) => p.trackLookupPrefix === trackId);
7849
- this.logger('debug', `[onTrack]: Got remote ${rawTrackType} track for userId: ${participantToUpdate?.userId}`, e.track.id, e.track);
7841
+ this.logger.debug(`[onTrack]: Got remote ${rawTrackType} track for userId: ${participantToUpdate?.userId}`, e.track.id, e.track);
7850
7842
  const trackDebugInfo = `${participantToUpdate?.userId} ${rawTrackType}:${trackId}`;
7851
7843
  e.track.addEventListener('mute', () => {
7852
- this.logger('info', `[onTrack]: Track muted: ${trackDebugInfo}`);
7844
+ this.logger.info(`[onTrack]: Track muted: ${trackDebugInfo}`);
7853
7845
  });
7854
7846
  e.track.addEventListener('unmute', () => {
7855
- this.logger('info', `[onTrack]: Track unmuted: ${trackDebugInfo}`);
7847
+ this.logger.info(`[onTrack]: Track unmuted: ${trackDebugInfo}`);
7856
7848
  });
7857
7849
  e.track.addEventListener('ended', () => {
7858
- this.logger('info', `[onTrack]: Track ended: ${trackDebugInfo}`);
7850
+ this.logger.info(`[onTrack]: Track ended: ${trackDebugInfo}`);
7859
7851
  this.state.removeOrphanedTrack(primaryStream.id);
7860
7852
  });
7861
7853
  const trackType = toTrackType(rawTrackType);
7862
7854
  if (!trackType) {
7863
- return this.logger('error', `Unknown track type: ${rawTrackType}`);
7855
+ return this.logger.error(`Unknown track type: ${rawTrackType}`);
7864
7856
  }
7865
7857
  this.trackIdToTrackType.set(e.track.id, trackType);
7866
7858
  if (!participantToUpdate) {
7867
- this.logger('warn', `[onTrack]: Received track for unknown participant: ${trackId}`, e);
7859
+ this.logger.warn(`[onTrack]: Received track for unknown participant: ${trackId}`, e);
7868
7860
  this.state.registerOrphanedTrack({
7869
7861
  id: primaryStream.id,
7870
7862
  trackLookupPrefix: trackId,
@@ -7875,7 +7867,7 @@ class Subscriber extends BasePeerConnection {
7875
7867
  }
7876
7868
  const streamKindProp = trackTypeToParticipantStreamKey(trackType);
7877
7869
  if (!streamKindProp) {
7878
- this.logger('error', `Unknown track type: ${rawTrackType}`);
7870
+ this.logger.error(`Unknown track type: ${rawTrackType}`);
7879
7871
  return;
7880
7872
  }
7881
7873
  // get the previous stream to dispose it later
@@ -7888,7 +7880,7 @@ class Subscriber extends BasePeerConnection {
7888
7880
  });
7889
7881
  // now, dispose the previous stream if it exists
7890
7882
  if (previousStream) {
7891
- this.logger('info', `[onTrack]: Cleaning up previous remote ${e.track.kind} tracks for userId: ${participantToUpdate.userId}`);
7883
+ this.logger.info(`[onTrack]: Cleaning up previous remote ${e.track.kind} tracks for userId: ${participantToUpdate.userId}`);
7892
7884
  previousStream.getTracks().forEach((t) => {
7893
7885
  t.stop();
7894
7886
  previousStream.removeTrack(t);
@@ -7915,7 +7907,7 @@ class Subscriber extends BasePeerConnection {
7915
7907
  this.pc.addEventListener('track', this.handleOnTrack);
7916
7908
  this.on('subscriberOffer', async (subscriberOffer) => {
7917
7909
  return this.negotiate(subscriberOffer).catch((err) => {
7918
- this.logger('error', `Negotiation failed.`, err);
7910
+ this.logger.error(`Negotiation failed.`, err);
7919
7911
  });
7920
7912
  });
7921
7913
  }
@@ -7932,20 +7924,20 @@ class Subscriber extends BasePeerConnection {
7932
7924
 
7933
7925
  const createWebSocketSignalChannel = (opts) => {
7934
7926
  const { endpoint, onMessage, tag, tracer } = opts;
7935
- const logger = getLogger(['SfuClientWS', tag]);
7936
- logger('debug', 'Creating signaling WS channel:', endpoint);
7927
+ const logger = videoLoggerSystem.getLogger('SfuClientWS', { tags: [tag] });
7928
+ logger.debug('Creating signaling WS channel:', endpoint);
7937
7929
  const ws = new WebSocket(endpoint);
7938
7930
  ws.binaryType = 'arraybuffer'; // do we need this?
7939
7931
  ws.addEventListener('error', (e) => {
7940
- logger('error', 'Signaling WS channel error', e);
7932
+ logger.error('Signaling WS channel error', e);
7941
7933
  tracer?.trace('signal.ws.error', e);
7942
7934
  });
7943
7935
  ws.addEventListener('close', (e) => {
7944
- logger('info', 'Signaling WS channel is closed', e);
7936
+ logger.info('Signaling WS channel is closed', e);
7945
7937
  tracer?.trace('signal.ws.close', e);
7946
7938
  });
7947
7939
  ws.addEventListener('open', (e) => {
7948
- logger('info', 'Signaling WS channel is open', e);
7940
+ logger.info('Signaling WS channel is open', e);
7949
7941
  tracer?.trace('signal.ws.open', e);
7950
7942
  });
7951
7943
  ws.addEventListener('message', (e) => {
@@ -7957,7 +7949,7 @@ const createWebSocketSignalChannel = (opts) => {
7957
7949
  }
7958
7950
  catch (err) {
7959
7951
  const message = 'Failed to decode a message. Check whether the Proto models match.';
7960
- logger('error', message, { event: e, error: err });
7952
+ logger.error(message, { event: e, error: err });
7961
7953
  tracer?.trace('signal.ws.message.error', message);
7962
7954
  }
7963
7955
  });
@@ -8158,14 +8150,14 @@ class StreamSfuClient {
8158
8150
  this.close = (code = StreamSfuClient.NORMAL_CLOSURE, reason) => {
8159
8151
  this.isClosingClean = code !== StreamSfuClient.ERROR_CONNECTION_UNHEALTHY;
8160
8152
  if (this.signalWs.readyState === WebSocket.OPEN) {
8161
- this.logger('debug', `Closing SFU WS connection: ${code} - ${reason}`);
8153
+ this.logger.debug(`Closing SFU WS connection: ${code} - ${reason}`);
8162
8154
  this.signalWs.close(code, `js-client: ${reason}`);
8163
8155
  this.signalWs.removeEventListener('close', this.handleWebSocketClose);
8164
8156
  }
8165
8157
  this.dispose();
8166
8158
  };
8167
8159
  this.dispose = () => {
8168
- this.logger('debug', 'Disposing SFU client');
8160
+ this.logger.debug('Disposing SFU client');
8169
8161
  this.unsubscribeIceTrickle();
8170
8162
  this.unsubscribeNetworkChanged();
8171
8163
  clearInterval(this.keepAliveInterval);
@@ -8185,7 +8177,7 @@ class StreamSfuClient {
8185
8177
  await this.notifyLeave(reason);
8186
8178
  }
8187
8179
  catch (err) {
8188
- this.logger('debug', 'Error notifying SFU about leaving call', err);
8180
+ this.logger.debug('Error notifying SFU about leaving call', err);
8189
8181
  }
8190
8182
  this.close(StreamSfuClient.NORMAL_CLOSURE, reason.substring(0, 115));
8191
8183
  };
@@ -8306,10 +8298,10 @@ class StreamSfuClient {
8306
8298
  await this.signalReady(); // wait for the signal ws to be open
8307
8299
  const msgJson = SfuRequest.toJson(message);
8308
8300
  if (this.signalWs.readyState !== WebSocket.OPEN) {
8309
- this.logger('debug', 'Signal WS is not open. Skipping message', msgJson);
8301
+ this.logger.debug('Signal WS is not open. Skipping message', msgJson);
8310
8302
  return;
8311
8303
  }
8312
- this.logger('debug', `Sending message to: ${this.edgeName}`, msgJson);
8304
+ this.logger.debug(`Sending message to: ${this.edgeName}`, msgJson);
8313
8305
  this.signalWs.send(SfuRequest.toBinary(message));
8314
8306
  };
8315
8307
  this.keepAlive = () => {
@@ -8317,7 +8309,7 @@ class StreamSfuClient {
8317
8309
  timers.clearInterval(this.keepAliveInterval);
8318
8310
  this.keepAliveInterval = timers.setInterval(() => {
8319
8311
  this.ping().catch((e) => {
8320
- this.logger('error', 'Error sending healthCheckRequest to SFU', e);
8312
+ this.logger.error('Error sending healthCheckRequest to SFU', e);
8321
8313
  });
8322
8314
  }, this.pingIntervalInMs);
8323
8315
  };
@@ -8340,7 +8332,7 @@ class StreamSfuClient {
8340
8332
  this.edgeName = server.edge_name;
8341
8333
  this.joinResponseTimeout = joinResponseTimeout;
8342
8334
  this.tag = tag;
8343
- this.logger = getLogger(['SfuClient', tag]);
8335
+ this.logger = videoLoggerSystem.getLogger('SfuClient', { tags: [tag] });
8344
8336
  this.tracer = enableTracing
8345
8337
  ? new Tracer(`${tag}-${this.edgeName}`)
8346
8338
  : undefined;
@@ -8349,7 +8341,8 @@ class StreamSfuClient {
8349
8341
  interceptors: [
8350
8342
  withHeaders({ Authorization: `Bearer ${token}` }),
8351
8343
  this.tracer && withRequestTracer(this.tracer.trace),
8352
- getLogLevel() === 'trace' && withRequestLogger(this.logger, 'trace'),
8344
+ this.logger.getLogLevel() === 'trace' &&
8345
+ withRequestLogger(this.logger, 'trace'),
8353
8346
  ].filter((v) => !!v),
8354
8347
  });
8355
8348
  // Special handling for the ICETrickle kind of events.
@@ -8437,13 +8430,13 @@ const watchCallRejected = (call) => {
8437
8430
  const { call: eventCall } = event;
8438
8431
  const { session: callSession } = eventCall;
8439
8432
  if (!callSession) {
8440
- call.logger('warn', 'No call session provided. Ignoring call.rejected event.', event);
8433
+ call.logger.warn('No call session provided. Ignoring call.rejected event.', event);
8441
8434
  return;
8442
8435
  }
8443
8436
  const rejectedBy = callSession.rejected_by;
8444
8437
  const { members, callingState } = call.state;
8445
8438
  if (callingState !== exports.CallingState.RINGING) {
8446
- call.logger('info', 'Call is not in ringing mode (it is either accepted or rejected already). Ignoring call.rejected event.', event);
8439
+ call.logger.info('Call is not in ringing mode (it is either accepted or rejected already). Ignoring call.rejected event.', event);
8447
8440
  return;
8448
8441
  }
8449
8442
  if (call.isCreatedByMe) {
@@ -8451,7 +8444,7 @@ const watchCallRejected = (call) => {
8451
8444
  .filter((m) => m.user_id !== call.currentUserId)
8452
8445
  .every((m) => rejectedBy[m.user_id]);
8453
8446
  if (everyoneElseRejected) {
8454
- call.logger('info', 'everyone rejected, leaving the call');
8447
+ call.logger.info('everyone rejected, leaving the call');
8455
8448
  await call.leave({
8456
8449
  reject: true,
8457
8450
  reason: 'cancel',
@@ -8461,7 +8454,7 @@ const watchCallRejected = (call) => {
8461
8454
  }
8462
8455
  else {
8463
8456
  if (rejectedBy[eventCall.created_by.id]) {
8464
- call.logger('info', 'call creator rejected, leaving call');
8457
+ call.logger.info('call creator rejected, leaving call');
8465
8458
  await call.leave({ message: 'ring: creator rejected' });
8466
8459
  }
8467
8460
  }
@@ -8478,7 +8471,7 @@ const watchCallEnded = (call) => {
8478
8471
  call
8479
8472
  .leave({ message: 'call.ended event received', reject: false })
8480
8473
  .catch((err) => {
8481
- call.logger('error', 'Failed to leave call after call.ended ', err);
8474
+ call.logger.error('Failed to leave call after call.ended ', err);
8482
8475
  });
8483
8476
  }
8484
8477
  };
@@ -8506,7 +8499,7 @@ const watchSfuCallEnded = (call) => {
8506
8499
  await call.leave({ message: `callEnded received: ${reason}` });
8507
8500
  }
8508
8501
  catch (err) {
8509
- call.logger('error', 'Failed to leave call after being ended by the SFU', err);
8502
+ call.logger.error('Failed to leave call after being ended by the SFU', err);
8510
8503
  }
8511
8504
  });
8512
8505
  };
@@ -8589,7 +8582,7 @@ const watchLiveEnded = (dispatcher, call) => {
8589
8582
  call.state.setBackstage(true);
8590
8583
  if (!call.permissionsContext.hasPermission(OwnCapability.JOIN_BACKSTAGE)) {
8591
8584
  call.leave({ message: 'live ended' }).catch((err) => {
8592
- call.logger('error', 'Failed to leave call after live ended', err);
8585
+ call.logger.error('Failed to leave call after live ended', err);
8593
8586
  });
8594
8587
  }
8595
8588
  });
@@ -8601,9 +8594,9 @@ const watchSfuErrorReports = (dispatcher) => {
8601
8594
  return dispatcher.on('error', (e) => {
8602
8595
  if (!e.error)
8603
8596
  return;
8604
- const logger = getLogger(['SfuClient']);
8597
+ const logger = videoLoggerSystem.getLogger('SfuClient');
8605
8598
  const { error, reconnectStrategy } = e;
8606
- logger('error', 'SFU reported error', {
8599
+ logger.error('SFU reported error', {
8607
8600
  code: ErrorCode[error.code],
8608
8601
  reconnectStrategy: WebsocketReconnectStrategy[reconnectStrategy],
8609
8602
  message: error.message,
@@ -8657,7 +8650,7 @@ const handleRemoteSoftMute = (call) => {
8657
8650
  if (cause === TrackUnpublishReason.MODERATION &&
8658
8651
  sessionId === localParticipant?.sessionId) {
8659
8652
  const logger = call.logger;
8660
- logger('info', `Local participant's ${TrackType[type]} track is muted remotely`);
8653
+ logger.info(`Local participant's ${TrackType[type]} track is muted remotely`);
8661
8654
  try {
8662
8655
  if (type === TrackType.VIDEO) {
8663
8656
  await call.camera.disable();
@@ -8670,11 +8663,11 @@ const handleRemoteSoftMute = (call) => {
8670
8663
  await call.screenShare.disable();
8671
8664
  }
8672
8665
  else {
8673
- logger('warn', 'Unsupported track type to soft mute', TrackType[type]);
8666
+ logger.warn('Unsupported track type to soft mute', TrackType[type]);
8674
8667
  }
8675
8668
  }
8676
8669
  catch (error) {
8677
- logger('error', 'Failed to stop publishing', error);
8670
+ logger.error('Failed to stop publishing', error);
8678
8671
  }
8679
8672
  }
8680
8673
  });
@@ -8995,7 +8988,7 @@ class DynascaleManager {
8995
8988
  * The viewport tracker instance.
8996
8989
  */
8997
8990
  this.viewportTracker = new ViewportTracker();
8998
- this.logger = getLogger(['DynascaleManager']);
8991
+ this.logger = videoLoggerSystem.getLogger('DynascaleManager');
8999
8992
  this.pendingSubscriptionsUpdate = null;
9000
8993
  this.videoTrackSubscriptionOverridesSubject = new rxjs.BehaviorSubject({});
9001
8994
  this.videoTrackSubscriptionOverrides$ = this.videoTrackSubscriptionOverridesSubject.asObservable();
@@ -9052,7 +9045,7 @@ class DynascaleManager {
9052
9045
  this.sfuClient
9053
9046
  ?.updateSubscriptions(this.trackSubscriptions)
9054
9047
  .catch((err) => {
9055
- this.logger('debug', `Failed to update track subscriptions`, err);
9048
+ this.logger.debug(`Failed to update track subscriptions`, err);
9056
9049
  });
9057
9050
  };
9058
9051
  if (debounceType) {
@@ -9141,7 +9134,7 @@ class DynascaleManager {
9141
9134
  // is not visible (e.g., has display: none).
9142
9135
  // we treat this as "unsubscription" as we don't want to keep
9143
9136
  // consuming bandwidth for a video that is not visible on the screen.
9144
- this.logger('debug', `Ignoring 0x0 dimension`, boundParticipant);
9137
+ this.logger.debug(`Ignoring 0x0 dimension`, boundParticipant);
9145
9138
  dimension = undefined;
9146
9139
  }
9147
9140
  this.callState.updateParticipantTracks(trackType, {
@@ -9246,7 +9239,7 @@ class DynascaleManager {
9246
9239
  setTimeout(() => {
9247
9240
  videoElement.srcObject = source ?? null;
9248
9241
  videoElement.play().catch((e) => {
9249
- this.logger('warn', `Failed to play stream`, e);
9242
+ this.logger.warn(`Failed to play stream`, e);
9250
9243
  });
9251
9244
  // we add extra delay until we attempt to force-play
9252
9245
  // the participant's media stream in Firefox and Safari,
@@ -9283,13 +9276,13 @@ class DynascaleManager {
9283
9276
  return;
9284
9277
  if ('setSinkId' in audioElement) {
9285
9278
  audioElement.setSinkId(deviceId).catch((e) => {
9286
- this.logger('warn', `Can't to set AudioElement sinkId`, e);
9279
+ this.logger.warn(`Can't to set AudioElement sinkId`, e);
9287
9280
  });
9288
9281
  }
9289
9282
  if (audioContext && 'setSinkId' in audioContext) {
9290
9283
  // @ts-expect-error setSinkId is not available in all browsers
9291
9284
  audioContext.setSinkId(deviceId).catch((e) => {
9292
- this.logger('warn', `Can't to set AudioContext sinkId`, e);
9285
+ this.logger.warn(`Can't to set AudioContext sinkId`, e);
9293
9286
  });
9294
9287
  }
9295
9288
  };
@@ -9331,7 +9324,7 @@ class DynascaleManager {
9331
9324
  // we will play audio directly through the audio element in other browsers
9332
9325
  audioElement.muted = false;
9333
9326
  audioElement.play().catch((e) => {
9334
- this.logger('warn', `Failed to play audio stream`, e);
9327
+ this.logger.warn(`Failed to play audio stream`, e);
9335
9328
  });
9336
9329
  }
9337
9330
  const { selectedDevice } = this.speaker.state;
@@ -9383,7 +9376,7 @@ class DynascaleManager {
9383
9376
  if (this.audioContext?.state === 'suspended') {
9384
9377
  this.audioContext
9385
9378
  .resume()
9386
- .catch((err) => this.logger('warn', `Can't resume audio context`, err))
9379
+ .catch((err) => this.logger.warn(`Can't resume audio context`, err))
9387
9380
  .then(() => {
9388
9381
  document.removeEventListener('click', this.resumeAudioContext);
9389
9382
  });
@@ -9620,7 +9613,7 @@ class BrowserPermission {
9620
9613
  this.disposeController = new AbortController();
9621
9614
  this.wasPrompted = false;
9622
9615
  this.listeners = new Set();
9623
- this.logger = getLogger(['permissions']);
9616
+ this.logger = videoLoggerSystem.getLogger('permissions');
9624
9617
  const signal = this.disposeController.signal;
9625
9618
  this.ready = (async () => {
9626
9619
  const assumeGranted = () => {
@@ -9646,7 +9639,7 @@ class BrowserPermission {
9646
9639
  }
9647
9640
  }
9648
9641
  catch (err) {
9649
- this.logger('debug', 'Failed to query permission status', err);
9642
+ this.logger.debug('Failed to query permission status', err);
9650
9643
  assumeGranted();
9651
9644
  }
9652
9645
  })();
@@ -9685,7 +9678,7 @@ class BrowserPermission {
9685
9678
  typeof e === 'object' &&
9686
9679
  'name' in e &&
9687
9680
  (e.name === 'NotAllowedError' || e.name === 'SecurityError')) {
9688
- this.logger('info', 'Browser permission was not granted', {
9681
+ this.logger.info('Browser permission was not granted', {
9689
9682
  permission: this.permission,
9690
9683
  });
9691
9684
  this.setState('denied');
@@ -9694,7 +9687,7 @@ class BrowserPermission {
9694
9687
  }
9695
9688
  return false;
9696
9689
  }
9697
- this.logger('error', `Failed to getUserMedia`, {
9690
+ this.logger.error(`Failed to getUserMedia`, {
9698
9691
  error: e,
9699
9692
  permission: this.permission,
9700
9693
  });
@@ -9915,10 +9908,12 @@ const getAudioStream = async (trackConstraints, tracer) => {
9915
9908
  if (isNotFoundOrOverconstrainedError(error) && trackConstraints?.deviceId) {
9916
9909
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
9917
9910
  const { deviceId, ...relaxedConstraints } = trackConstraints;
9918
- getLogger(['devices'])('warn', 'Failed to get audio stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
9911
+ videoLoggerSystem
9912
+ .getLogger('devices')
9913
+ .warn('Failed to get audio stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
9919
9914
  return getAudioStream(relaxedConstraints);
9920
9915
  }
9921
- getLogger(['devices'])('error', 'Failed to get audio stream', {
9916
+ videoLoggerSystem.getLogger('devices').error('Failed to get audio stream', {
9922
9917
  error,
9923
9918
  constraints,
9924
9919
  });
@@ -9951,10 +9946,12 @@ const getVideoStream = async (trackConstraints, tracer) => {
9951
9946
  if (isNotFoundOrOverconstrainedError(error) && trackConstraints?.deviceId) {
9952
9947
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
9953
9948
  const { deviceId, ...relaxedConstraints } = trackConstraints;
9954
- getLogger(['devices'])('warn', 'Failed to get video stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
9949
+ videoLoggerSystem
9950
+ .getLogger('devices')
9951
+ .warn('Failed to get video stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
9955
9952
  return getVideoStream(relaxedConstraints);
9956
9953
  }
9957
- getLogger(['devices'])('error', 'Failed to get video stream', {
9954
+ videoLoggerSystem.getLogger('devices').error('Failed to get video stream', {
9958
9955
  error,
9959
9956
  constraints,
9960
9957
  });
@@ -10003,7 +10000,9 @@ const getScreenShareStream = async (options, tracer) => {
10003
10000
  }
10004
10001
  catch (e) {
10005
10002
  tracer?.trace(`${tag}OnFailure`, e.name);
10006
- getLogger(['devices'])('error', 'Failed to get screen share stream', e);
10003
+ videoLoggerSystem
10004
+ .getLogger('devices')
10005
+ .error('Failed to get screen share stream', e);
10007
10006
  throw e;
10008
10007
  }
10009
10008
  };
@@ -10065,7 +10064,7 @@ class DeviceManager {
10065
10064
  this.call = call;
10066
10065
  this.state = state;
10067
10066
  this.trackType = trackType;
10068
- this.logger = getLogger([`${TrackType[trackType].toLowerCase()} manager`]);
10067
+ this.logger = videoLoggerSystem.getLogger(`${TrackType[trackType].toLowerCase()} manager`);
10069
10068
  this.setup();
10070
10069
  }
10071
10070
  setup() {
@@ -10228,6 +10227,7 @@ class DeviceManager {
10228
10227
  }
10229
10228
  }
10230
10229
  async applySettingsToStream() {
10230
+ console.log('applySettingsToStream ');
10231
10231
  await withCancellation(this.statusChangeConcurrencyTag, async (signal) => {
10232
10232
  if (this.enabled) {
10233
10233
  try {
@@ -10260,7 +10260,7 @@ class DeviceManager {
10260
10260
  const mediaStream = this.state.mediaStream;
10261
10261
  if (!mediaStream)
10262
10262
  return;
10263
- this.logger('debug', `${stopTracks ? 'Stopping' : 'Disabling'} stream`);
10263
+ this.logger.debug(`${stopTracks ? 'Stopping' : 'Disabling'} stream`);
10264
10264
  if (this.call.state.callingState === exports.CallingState.JOINED) {
10265
10265
  await this.stopPublishStream();
10266
10266
  }
@@ -10306,7 +10306,7 @@ class DeviceManager {
10306
10306
  }
10307
10307
  }
10308
10308
  async unmuteStream() {
10309
- this.logger('debug', 'Starting stream');
10309
+ this.logger.debug('Starting stream');
10310
10310
  let stream;
10311
10311
  let rootStream;
10312
10312
  if (this.state.mediaStream &&
@@ -10387,7 +10387,7 @@ class DeviceManager {
10387
10387
  return output;
10388
10388
  })
10389
10389
  .then(chainWith(parent), (error) => {
10390
- this.logger('warn', 'Filter failed to start and will be ignored', error);
10390
+ this.logger.warn('Filter failed to start and will be ignored', error);
10391
10391
  return parent;
10392
10392
  }), rootStream);
10393
10393
  }
@@ -10410,7 +10410,7 @@ class DeviceManager {
10410
10410
  if (!isMobile() || this.trackType !== TrackType.VIDEO)
10411
10411
  return;
10412
10412
  this.call.notifyTrackMuteState(muted, this.trackType).catch((err) => {
10413
- this.logger('warn', 'Error while notifying track mute state', err);
10413
+ this.logger.warn('Error while notifying track mute state', err);
10414
10414
  });
10415
10415
  };
10416
10416
  stream.getTracks().forEach((track) => {
@@ -10474,7 +10474,7 @@ class DeviceManager {
10474
10474
  }
10475
10475
  }
10476
10476
  catch (err) {
10477
- this.logger('warn', 'Unexpected error while handling disconnected or replaced device', err);
10477
+ this.logger.warn('Unexpected error while handling disconnected or replaced device', err);
10478
10478
  }
10479
10479
  }));
10480
10480
  }
@@ -10681,7 +10681,7 @@ class CameraManager extends DeviceManager {
10681
10681
  */
10682
10682
  async selectDirection(direction) {
10683
10683
  if (!this.isDirectionSupportedByDevice()) {
10684
- this.logger('warn', 'Setting direction is not supported on this device');
10684
+ this.logger.warn('Setting direction is not supported on this device');
10685
10685
  return;
10686
10686
  }
10687
10687
  if (isReactNative()) {
@@ -10732,7 +10732,7 @@ class CameraManager extends DeviceManager {
10732
10732
  }
10733
10733
  catch (error) {
10734
10734
  // couldn't enable device, target resolution will be applied the next time user attempts to start the device
10735
- this.logger('warn', 'could not apply target resolution', error);
10735
+ this.logger.warn('could not apply target resolution', error);
10736
10736
  }
10737
10737
  }
10738
10738
  if (this.enabled && this.state.mediaStream) {
@@ -10743,7 +10743,7 @@ class CameraManager extends DeviceManager {
10743
10743
  if (width !== this.targetResolution.width ||
10744
10744
  height !== this.targetResolution.height) {
10745
10745
  await this.applySettingsToStream();
10746
- this.logger('debug', `${width}x${height} target resolution applied to media stream`);
10746
+ this.logger.debug(`${width}x${height} target resolution applied to media stream`);
10747
10747
  }
10748
10748
  }
10749
10749
  }
@@ -11007,8 +11007,8 @@ class RNSpeechDetector {
11007
11007
  };
11008
11008
  }
11009
11009
  catch (error) {
11010
- const logger = getLogger(['RNSpeechDetector']);
11011
- logger('error', 'error handling permissions: ', error);
11010
+ const logger = videoLoggerSystem.getLogger('RNSpeechDetector');
11011
+ logger.error('error handling permissions: ', error);
11012
11012
  return () => { };
11013
11013
  }
11014
11014
  }
@@ -11092,8 +11092,8 @@ class RNSpeechDetector {
11092
11092
  }
11093
11093
  }
11094
11094
  catch (error) {
11095
- const logger = getLogger(['RNSpeechDetector']);
11096
- logger('error', 'error checking audio level from stats', error);
11095
+ const logger = videoLoggerSystem.getLogger('RNSpeechDetector');
11096
+ logger.error('error checking audio level from stats', error);
11097
11097
  }
11098
11098
  };
11099
11099
  // Call checkAudioLevel periodically (every 100ms)
@@ -11153,7 +11153,7 @@ class MicrophoneManager extends AudioDeviceManager {
11153
11153
  }
11154
11154
  }
11155
11155
  catch (err) {
11156
- this.logger('warn', 'Could not enable speaking while muted', err);
11156
+ this.logger.warn('Could not enable speaking while muted', err);
11157
11157
  }
11158
11158
  }));
11159
11159
  this.subscriptions.push(createSubscription(this.call.state.callingState$, (callingState) => {
@@ -11176,7 +11176,7 @@ class MicrophoneManager extends AudioDeviceManager {
11176
11176
  }
11177
11177
  })
11178
11178
  .catch((err) => {
11179
- this.logger('warn', `Failed to enable noise cancellation`, err);
11179
+ this.logger.warn(`Failed to enable noise cancellation`, err);
11180
11180
  return this.call.notifyNoiseCancellationStopped();
11181
11181
  });
11182
11182
  }
@@ -11184,7 +11184,7 @@ class MicrophoneManager extends AudioDeviceManager {
11184
11184
  this.noiseCancellationRegistration
11185
11185
  .then(() => this.noiseCancellation?.disable())
11186
11186
  .catch((err) => {
11187
- this.logger('warn', `Failed to disable noise cancellation`, err);
11187
+ this.logger.warn(`Failed to disable noise cancellation`, err);
11188
11188
  });
11189
11189
  }
11190
11190
  }));
@@ -11213,12 +11213,12 @@ class MicrophoneManager extends AudioDeviceManager {
11213
11213
  this.call.tracer.trace('noiseCancellation.enabled', enabled);
11214
11214
  if (enabled) {
11215
11215
  this.call.notifyNoiseCancellationStarting().catch((err) => {
11216
- this.logger('warn', `notifyNoiseCancellationStart failed`, err);
11216
+ this.logger.warn(`notifyNoiseCancellationStart failed`, err);
11217
11217
  });
11218
11218
  }
11219
11219
  else {
11220
11220
  this.call.notifyNoiseCancellationStopped().catch((err) => {
11221
- this.logger('warn', `notifyNoiseCancellationStop failed`, err);
11221
+ this.logger.warn(`notifyNoiseCancellationStop failed`, err);
11222
11222
  });
11223
11223
  }
11224
11224
  });
@@ -11247,9 +11247,9 @@ class MicrophoneManager extends AudioDeviceManager {
11247
11247
  }
11248
11248
  }
11249
11249
  catch (e) {
11250
- this.logger('warn', 'Failed to enable noise cancellation', e);
11250
+ this.logger.warn('Failed to enable noise cancellation', e);
11251
11251
  await this.disableNoiseCancellation().catch((err) => {
11252
- this.logger('warn', 'Failed to disable noise cancellation', err);
11252
+ this.logger.warn('Failed to disable noise cancellation', err);
11253
11253
  });
11254
11254
  throw e;
11255
11255
  }
@@ -11262,7 +11262,7 @@ class MicrophoneManager extends AudioDeviceManager {
11262
11262
  .then(() => this.noiseCancellation?.disable())
11263
11263
  .then(() => this.noiseCancellationChangeUnsubscribe?.())
11264
11264
  .catch((err) => {
11265
- this.logger('warn', 'Failed to unregister noise cancellation', err);
11265
+ this.logger.warn('Failed to unregister noise cancellation', err);
11266
11266
  });
11267
11267
  this.call.tracer.trace('noiseCancellation.disabled', true);
11268
11268
  await this.call.notifyNoiseCancellationStopped();
@@ -11770,9 +11770,9 @@ class Call {
11770
11770
  return;
11771
11771
  const currentUserId = this.currentUserId;
11772
11772
  if (currentUserId && blockedUserIds.includes(currentUserId)) {
11773
- this.logger('info', 'Leaving call because of being blocked');
11773
+ this.logger.info('Leaving call because of being blocked');
11774
11774
  await this.leave({ message: 'user blocked' }).catch((err) => {
11775
- this.logger('error', 'Error leaving call after being blocked', err);
11775
+ this.logger.error('Error leaving call after being blocked', err);
11776
11776
  });
11777
11777
  }
11778
11778
  }));
@@ -11808,7 +11808,7 @@ class Call {
11808
11808
  if ((isAcceptedElsewhere || isRejectedByMe) &&
11809
11809
  !hasPending(this.joinLeaveConcurrencyTag)) {
11810
11810
  this.leave().catch(() => {
11811
- this.logger('error', 'Could not leave a call that was accepted or rejected elsewhere');
11811
+ this.logger.error('Could not leave a call that was accepted or rejected elsewhere');
11812
11812
  });
11813
11813
  }
11814
11814
  }));
@@ -11888,7 +11888,7 @@ class Call {
11888
11888
  }
11889
11889
  }
11890
11890
  catch (err) {
11891
- this.logger('error', `Can't disable mic/camera/screenshare after revoked permissions`, err);
11891
+ this.logger.error(`Can't disable mic/camera/screenshare after revoked permissions`, err);
11892
11892
  }
11893
11893
  }
11894
11894
  };
@@ -12149,13 +12149,13 @@ class Call {
12149
12149
  maxJoinRetries = Math.max(maxJoinRetries, 1);
12150
12150
  for (let attempt = 0; attempt < maxJoinRetries; attempt++) {
12151
12151
  try {
12152
- this.logger('trace', `Joining call (${attempt})`, this.cid);
12152
+ this.logger.trace(`Joining call (${attempt})`, this.cid);
12153
12153
  await this.doJoin(data);
12154
12154
  delete joinData.migrating_from;
12155
12155
  break;
12156
12156
  }
12157
12157
  catch (err) {
12158
- this.logger('warn', `Failed to join call (${attempt})`, this.cid);
12158
+ this.logger.warn(`Failed to join call (${attempt})`, this.cid);
12159
12159
  if (err instanceof ErrorFromResponse && err.unrecoverable) {
12160
12160
  // if the error is unrecoverable, we should not retry as that signals
12161
12161
  // that connectivity is good, but the coordinator doesn't allow the user
@@ -12185,7 +12185,7 @@ class Call {
12185
12185
  const connectStartTime = Date.now();
12186
12186
  const callingState = this.state.callingState;
12187
12187
  this.joinCallData = data;
12188
- this.logger('debug', 'Starting join flow');
12188
+ this.logger.debug('Starting join flow');
12189
12189
  this.state.setCallingState(exports.CallingState.JOINING);
12190
12190
  const performingMigration = this.reconnectStrategy === WebsocketReconnectStrategy.MIGRATE;
12191
12191
  const performingRejoin = this.reconnectStrategy === WebsocketReconnectStrategy.REJOIN;
@@ -12270,7 +12270,7 @@ class Call {
12270
12270
  }
12271
12271
  }
12272
12272
  catch (error) {
12273
- this.logger('warn', 'Join SFU request failed', error);
12273
+ this.logger.warn('Join SFU request failed', error);
12274
12274
  sfuClient.close(StreamSfuClient.JOIN_FAILED, 'Join request failed, connection considered unhealthy');
12275
12275
  // restore the previous call state if the join-flow fails
12276
12276
  this.state.setCallingState(callingState);
@@ -12327,7 +12327,7 @@ class Call {
12327
12327
  // reset the reconnect strategy to unspecified after a successful reconnection
12328
12328
  this.reconnectStrategy = WebsocketReconnectStrategy.UNSPECIFIED;
12329
12329
  this.reconnectReason = '';
12330
- this.logger('info', `Joined call ${this.cid}`);
12330
+ this.logger.info(`Joined call ${this.cid}`);
12331
12331
  };
12332
12332
  /**
12333
12333
  * Prepares Reconnect Details object.
@@ -12440,7 +12440,7 @@ class Call {
12440
12440
  onReconnectionNeeded: (kind, reason) => {
12441
12441
  this.reconnect(kind, reason).catch((err) => {
12442
12442
  const message = `[Reconnect] Error reconnecting after a subscriber error: ${reason}`;
12443
- this.logger('warn', message, err);
12443
+ this.logger.warn(message, err);
12444
12444
  });
12445
12445
  },
12446
12446
  });
@@ -12462,7 +12462,7 @@ class Call {
12462
12462
  onReconnectionNeeded: (kind, reason) => {
12463
12463
  this.reconnect(kind, reason).catch((err) => {
12464
12464
  const message = `[Reconnect] Error reconnecting after a publisher error: ${reason}`;
12465
- this.logger('warn', message, err);
12465
+ this.logger.warn(message, err);
12466
12466
  });
12467
12467
  },
12468
12468
  });
@@ -12531,7 +12531,7 @@ class Call {
12531
12531
  * @param reason the reason for the closure.
12532
12532
  */
12533
12533
  this.handleSfuSignalClose = (sfuClient, reason) => {
12534
- this.logger('debug', '[Reconnect] SFU signal connection closed');
12534
+ this.logger.debug('[Reconnect] SFU signal connection closed');
12535
12535
  const { callingState } = this.state;
12536
12536
  if (
12537
12537
  // SFU WS closed before we finished current join,
@@ -12552,7 +12552,7 @@ class Call {
12552
12552
  ? WebsocketReconnectStrategy.FAST
12553
12553
  : WebsocketReconnectStrategy.REJOIN;
12554
12554
  this.reconnect(strategy, reason).catch((err) => {
12555
- this.logger('warn', '[Reconnect] Error reconnecting', err);
12555
+ this.logger.warn('[Reconnect] Error reconnecting', err);
12556
12556
  });
12557
12557
  };
12558
12558
  /**
@@ -12588,7 +12588,7 @@ class Call {
12588
12588
  const shouldGiveUpReconnecting = this.disconnectionTimeoutSeconds > 0 &&
12589
12589
  reconnectingTime / 1000 > this.disconnectionTimeoutSeconds;
12590
12590
  if (shouldGiveUpReconnecting) {
12591
- this.logger('warn', '[Reconnect] Stopping reconnection attempts after reaching disconnection timeout');
12591
+ this.logger.warn('[Reconnect] Stopping reconnection attempts after reaching disconnection timeout');
12592
12592
  await markAsReconnectingFailed();
12593
12593
  return;
12594
12594
  }
@@ -12600,11 +12600,11 @@ class Call {
12600
12600
  try {
12601
12601
  // wait until the network is available
12602
12602
  await this.networkAvailableTask?.promise;
12603
- this.logger('info', `[Reconnect] Reconnecting with strategy ${WebsocketReconnectStrategy[this.reconnectStrategy]}`);
12603
+ this.logger.info(`[Reconnect] Reconnecting with strategy ${WebsocketReconnectStrategy[this.reconnectStrategy]}`);
12604
12604
  switch (this.reconnectStrategy) {
12605
12605
  case WebsocketReconnectStrategy.UNSPECIFIED:
12606
12606
  case WebsocketReconnectStrategy.DISCONNECT:
12607
- this.logger('debug', `[Reconnect] No-op strategy ${currentStrategy}`);
12607
+ this.logger.debug(`[Reconnect] No-op strategy ${currentStrategy}`);
12608
12608
  break;
12609
12609
  case WebsocketReconnectStrategy.FAST:
12610
12610
  await this.reconnectFast();
@@ -12623,13 +12623,13 @@ class Call {
12623
12623
  }
12624
12624
  catch (error) {
12625
12625
  if (this.state.callingState === exports.CallingState.OFFLINE) {
12626
- this.logger('debug', `[Reconnect] Can't reconnect while offline, stopping reconnection attempts`);
12626
+ this.logger.debug(`[Reconnect] Can't reconnect while offline, stopping reconnection attempts`);
12627
12627
  break;
12628
12628
  // we don't need to handle the error if the call is offline
12629
12629
  // network change event will trigger the reconnection
12630
12630
  }
12631
12631
  if (error instanceof ErrorFromResponse && error.unrecoverable) {
12632
- this.logger('warn', `[Reconnect] Can't reconnect due to coordinator unrecoverable error`, error);
12632
+ this.logger.warn(`[Reconnect] Can't reconnect due to coordinator unrecoverable error`, error);
12633
12633
  await markAsReconnectingFailed();
12634
12634
  return;
12635
12635
  }
@@ -12650,12 +12650,12 @@ class Call {
12650
12650
  ? WebsocketReconnectStrategy.REJOIN
12651
12651
  : WebsocketReconnectStrategy.FAST;
12652
12652
  this.reconnectStrategy = nextStrategy;
12653
- this.logger('info', `[Reconnect] ${currentStrategy} (${this.reconnectAttempts}) failed. Attempting with ${WebsocketReconnectStrategy[nextStrategy]}`, error);
12653
+ this.logger.info(`[Reconnect] ${currentStrategy} (${this.reconnectAttempts}) failed. Attempting with ${WebsocketReconnectStrategy[nextStrategy]}`, error);
12654
12654
  }
12655
12655
  } while (this.state.callingState !== exports.CallingState.JOINED &&
12656
12656
  this.state.callingState !== exports.CallingState.RECONNECTING_FAILED &&
12657
12657
  this.state.callingState !== exports.CallingState.LEFT);
12658
- this.logger('info', '[Reconnect] Reconnection flow finished');
12658
+ this.logger.info('[Reconnect] Reconnection flow finished');
12659
12659
  });
12660
12660
  };
12661
12661
  /**
@@ -12737,7 +12737,7 @@ class Call {
12737
12737
  this.registerReconnectHandlers = () => {
12738
12738
  // handles the legacy "goAway" event
12739
12739
  const unregisterGoAway = this.on('goAway', () => {
12740
- this.reconnect(WebsocketReconnectStrategy.MIGRATE, 'goAway').catch((err) => this.logger('warn', '[Reconnect] Error reconnecting', err));
12740
+ this.reconnect(WebsocketReconnectStrategy.MIGRATE, 'goAway').catch((err) => this.logger.warn('[Reconnect] Error reconnecting', err));
12741
12741
  });
12742
12742
  // handles the "error" event, through which the SFU can request a reconnect
12743
12743
  const unregisterOnError = this.on('error', (e) => {
@@ -12746,19 +12746,19 @@ class Call {
12746
12746
  return;
12747
12747
  if (strategy === WebsocketReconnectStrategy.DISCONNECT) {
12748
12748
  this.leave({ message: 'SFU instructed to disconnect' }).catch((err) => {
12749
- this.logger('warn', `Can't leave call after disconnect request`, err);
12749
+ this.logger.warn(`Can't leave call after disconnect request`, err);
12750
12750
  });
12751
12751
  }
12752
12752
  else {
12753
12753
  this.reconnect(strategy, error?.message || 'SFU Error').catch((err) => {
12754
- this.logger('warn', '[Reconnect] Error reconnecting', err);
12754
+ this.logger.warn('[Reconnect] Error reconnecting', err);
12755
12755
  });
12756
12756
  }
12757
12757
  });
12758
12758
  const unregisterNetworkChanged = this.streamClient.on('network.changed', (e) => {
12759
12759
  this.tracer.trace('network.changed', e);
12760
12760
  if (!e.online) {
12761
- this.logger('debug', '[Reconnect] Going offline');
12761
+ this.logger.debug('[Reconnect] Going offline');
12762
12762
  if (!this.hasJoinedOnce)
12763
12763
  return;
12764
12764
  this.lastOfflineTimestamp = Date.now();
@@ -12775,7 +12775,7 @@ class Call {
12775
12775
  }
12776
12776
  }
12777
12777
  this.reconnect(strategy, 'Going online').catch((err) => {
12778
- this.logger('warn', '[Reconnect] Error reconnecting after going online', err);
12778
+ this.logger.warn('[Reconnect] Error reconnecting after going online', err);
12779
12779
  });
12780
12780
  });
12781
12781
  this.networkAvailableTask = networkAvailableTask;
@@ -12783,7 +12783,7 @@ class Call {
12783
12783
  this.state.setCallingState(exports.CallingState.OFFLINE);
12784
12784
  }
12785
12785
  else {
12786
- this.logger('debug', '[Reconnect] Going online');
12786
+ this.logger.debug('[Reconnect] Going online');
12787
12787
  this.sfuClient?.close(StreamSfuClient.DISPOSE_OLD_SOCKET, 'Closing WS to reconnect after going online');
12788
12788
  // we went online, release the previous waiters and reset the state
12789
12789
  this.networkAvailableTask?.resolve();
@@ -12945,10 +12945,10 @@ class Call {
12945
12945
  * @param options the options to use.
12946
12946
  */
12947
12947
  this.updatePublishOptions = (options) => {
12948
- this.logger('warn', '[call.updatePublishOptions]: You are manually overriding the publish options for this call. ' +
12948
+ this.logger.warn('[call.updatePublishOptions]: You are manually overriding the publish options for this call. ' +
12949
12949
  'This is not recommended, and it can cause call stability/compatibility issues. Use with caution.');
12950
12950
  if (this.state.callingState === exports.CallingState.JOINED) {
12951
- this.logger('warn', 'Updating publish options after joining the call does not have an effect');
12951
+ this.logger.warn('Updating publish options after joining the call does not have an effect');
12952
12952
  }
12953
12953
  this.clientPublishOptions = { ...this.clientPublishOptions, ...options };
12954
12954
  };
@@ -12959,7 +12959,7 @@ class Call {
12959
12959
  */
12960
12960
  this.notifyNoiseCancellationStarting = async () => {
12961
12961
  return this.sfuClient?.startNoiseCancellation().catch((err) => {
12962
- this.logger('warn', 'Failed to notify start of noise cancellation', err);
12962
+ this.logger.warn('Failed to notify start of noise cancellation', err);
12963
12963
  });
12964
12964
  };
12965
12965
  /**
@@ -12969,7 +12969,7 @@ class Call {
12969
12969
  */
12970
12970
  this.notifyNoiseCancellationStopped = async () => {
12971
12971
  return this.sfuClient?.stopNoiseCancellation().catch((err) => {
12972
- this.logger('warn', 'Failed to notify stop of noise cancellation', err);
12972
+ this.logger.warn('Failed to notify stop of noise cancellation', err);
12973
12973
  });
12974
12974
  };
12975
12975
  /**
@@ -13403,7 +13403,7 @@ class Call {
13403
13403
  reason: 'timeout',
13404
13404
  message: `ringing timeout - ${this.isCreatedByMe ? 'no one accepted' : `user didn't interact with incoming call screen`}`,
13405
13405
  }).catch((err) => {
13406
- this.logger('error', 'Failed to drop call', err);
13406
+ this.logger.error('Failed to drop call', err);
13407
13407
  });
13408
13408
  }, timeoutInMs);
13409
13409
  };
@@ -13515,10 +13515,10 @@ class Call {
13515
13515
  */
13516
13516
  this.applyDeviceConfig = async (settings, publish) => {
13517
13517
  await this.camera.apply(settings.video, publish).catch((err) => {
13518
- this.logger('warn', 'Camera init failed', err);
13518
+ this.logger.warn('Camera init failed', err);
13519
13519
  });
13520
13520
  await this.microphone.apply(settings.audio, publish).catch((err) => {
13521
- this.logger('warn', 'Mic init failed', err);
13521
+ this.logger.warn('Mic init failed', err);
13522
13522
  });
13523
13523
  };
13524
13524
  /**
@@ -13670,7 +13670,7 @@ class Call {
13670
13670
  this.streamClient = streamClient;
13671
13671
  this.clientStore = clientStore;
13672
13672
  this.streamClientBasePath = `/call/${this.type}/${this.id}`;
13673
- this.logger = getLogger(['Call']);
13673
+ this.logger = videoLoggerSystem.getLogger('Call');
13674
13674
  const callTypeConfig = CallTypes.get(type);
13675
13675
  const participantSorter = sortParticipantsBy || callTypeConfig.options.sortParticipantsBy;
13676
13676
  if (participantSorter) {
@@ -13757,7 +13757,7 @@ const APIErrorCodes = {
13757
13757
  class StableWSConnection {
13758
13758
  constructor(client) {
13759
13759
  this._log = (msg, extra = {}, level = 'info') => {
13760
- this.client.logger(level, `connection:${msg}`, extra);
13760
+ this.client.logger[level](`connection:${msg}`, extra);
13761
13761
  };
13762
13762
  this.setClient = (client) => {
13763
13763
  this.client = client;
@@ -13803,12 +13803,12 @@ class StableWSConnection {
13803
13803
  return;
13804
13804
  const user = this.client.user;
13805
13805
  if (!user) {
13806
- this.client.logger('error', `User not set, can't connect to WS`);
13806
+ this.client.logger.error(`User not set, can't connect to WS`);
13807
13807
  return;
13808
13808
  }
13809
13809
  const token = this.client._getToken();
13810
13810
  if (!token) {
13811
- this.client.logger('error', `Token not set, can't connect authenticate`);
13811
+ this.client.logger.error(`Token not set, can't connect authenticate`);
13812
13812
  return;
13813
13813
  }
13814
13814
  const authMessage = JSON.stringify({
@@ -14445,7 +14445,7 @@ class TokenManager {
14445
14445
  }
14446
14446
 
14447
14447
  const getLocationHint = async (hintUrl = `https://hint.stream-io-video.com/`, timeout = 2000, maxAttempts = 3) => {
14448
- const logger = getLogger(['location-hint']);
14448
+ const logger = videoLoggerSystem.getLogger('location-hint');
14449
14449
  let attempt = 0;
14450
14450
  let locationHint = 'ERR';
14451
14451
  do {
@@ -14457,11 +14457,11 @@ const getLocationHint = async (hintUrl = `https://hint.stream-io-video.com/`, ti
14457
14457
  signal: abortController.signal,
14458
14458
  });
14459
14459
  const awsPop = response.headers.get('x-amz-cf-pop') || 'ERR';
14460
- logger('debug', `Location header: ${awsPop}`);
14460
+ logger.debug(`Location header: ${awsPop}`);
14461
14461
  locationHint = awsPop.substring(0, 3); // AMS1-P2 -> AMS
14462
14462
  }
14463
14463
  catch (e) {
14464
- logger('warn', `Failed to get location hint from ${hintUrl}`, e);
14464
+ logger.warn(`Failed to get location hint from ${hintUrl}`, e);
14465
14465
  locationHint = 'ERR';
14466
14466
  }
14467
14467
  finally {
@@ -14522,14 +14522,14 @@ class StreamClient {
14522
14522
  * If the user id remains the same we don't throw error
14523
14523
  */
14524
14524
  if (this.userID === user.id && this.connectUserTask) {
14525
- this.logger('warn', 'Consecutive calls to connectUser is detected, ideally you should only call this function once in your app.');
14525
+ this.logger.warn('Consecutive calls to connectUser is detected, ideally you should only call this function once in your app.');
14526
14526
  return this.connectUserTask;
14527
14527
  }
14528
14528
  if (this.userID) {
14529
14529
  throw new Error('Use client.disconnect() before trying to connect as a different user. connectUser was called twice.');
14530
14530
  }
14531
14531
  if ((this.secret || this.node) && !this.options.allowServerSideConnect) {
14532
- this.logger('warn', 'Please do not use connectUser server side. Use our @stream-io/node-sdk instead: https://getstream.io/video/docs/api/');
14532
+ this.logger.warn('Please do not use connectUser server side. Use our @stream-io/node-sdk instead: https://getstream.io/video/docs/api/');
14533
14533
  }
14534
14534
  // we generate the client id client side
14535
14535
  this.userID = user.id;
@@ -14587,11 +14587,11 @@ class StreamClient {
14587
14587
  }
14588
14588
  const wsPromise = this.wsPromiseSafe?.();
14589
14589
  if (this.wsConnection?.isConnecting && wsPromise) {
14590
- this.logger('info', 'client:openConnection() - connection already in progress');
14590
+ this.logger.info('client:openConnection() - connection already in progress');
14591
14591
  return await wsPromise;
14592
14592
  }
14593
14593
  if (this.wsConnection?.isHealthy && this._hasConnectionID()) {
14594
- this.logger('info', 'client:openConnection() - openConnection called twice, healthy connection already exists');
14594
+ this.logger.info('client:openConnection() - openConnection called twice, healthy connection already exists');
14595
14595
  return;
14596
14596
  }
14597
14597
  this._setupConnectionIdPromise();
@@ -14607,7 +14607,7 @@ class StreamClient {
14607
14607
  * https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
14608
14608
  */
14609
14609
  this.disconnectUser = async (timeout) => {
14610
- this.logger('info', 'client:disconnect() - Disconnecting the client');
14610
+ this.logger.info('client:disconnect() - Disconnecting the client');
14611
14611
  // remove the user specific fields
14612
14612
  delete this.user;
14613
14613
  delete this._user;
@@ -14654,7 +14654,7 @@ class StreamClient {
14654
14654
  if (!this.listeners[eventName]) {
14655
14655
  this.listeners[eventName] = [];
14656
14656
  }
14657
- this.logger('debug', `Adding listener for ${eventName} event`);
14657
+ this.logger.debug(`Adding listener for ${eventName} event`);
14658
14658
  this.listeners[eventName]?.push(callback);
14659
14659
  return () => {
14660
14660
  this.off(eventName, callback);
@@ -14667,7 +14667,7 @@ class StreamClient {
14667
14667
  if (!this.listeners[eventName]) {
14668
14668
  this.listeners[eventName] = [];
14669
14669
  }
14670
- this.logger('debug', `Removing listener for ${eventName} event`);
14670
+ this.logger.debug(`Removing listener for ${eventName} event`);
14671
14671
  this.listeners[eventName] = this.listeners[eventName]?.filter((value) => value !== callback);
14672
14672
  };
14673
14673
  /**
@@ -14681,17 +14681,17 @@ class StreamClient {
14681
14681
  }));
14682
14682
  };
14683
14683
  this._logApiRequest = (type, url, data, config) => {
14684
- if (getLogLevel() !== 'trace')
14684
+ if (this.logger.getLogLevel() !== 'trace')
14685
14685
  return;
14686
- this.logger('trace', `client: ${type} - Request - ${url}`, {
14686
+ this.logger.trace(`client: ${type} - Request - ${url}`, {
14687
14687
  payload: data,
14688
14688
  config,
14689
14689
  });
14690
14690
  };
14691
14691
  this._logApiResponse = (type, url, response) => {
14692
- if (getLogLevel() !== 'trace')
14692
+ if (this.logger.getLogLevel() !== 'trace')
14693
14693
  return;
14694
- this.logger('trace', `client:${type} - Response - url: ${url} > status ${response.status}`, {
14694
+ this.logger.trace(`client:${type} - Response - url: ${url} > status ${response.status}`, {
14695
14695
  response,
14696
14696
  });
14697
14697
  };
@@ -14748,13 +14748,13 @@ class StreamClient {
14748
14748
  this.consecutiveFailures += 1;
14749
14749
  const { response } = e;
14750
14750
  if (!response || !isErrorResponse(response)) {
14751
- this.logger('error', `client:${type} url: ${url}`, e);
14751
+ this.logger.error(`client:${type} url: ${url}`, e);
14752
14752
  throw e;
14753
14753
  }
14754
14754
  const { data: responseData, status } = response;
14755
14755
  const isTokenExpired = responseData.code === KnownCodes.TOKEN_EXPIRED;
14756
14756
  if (isTokenExpired && !this.tokenManager.isStatic()) {
14757
- this.logger('warn', `client:${type}: url: ${url}`, response);
14757
+ this.logger.warn(`client:${type}: url: ${url}`, response);
14758
14758
  if (this.consecutiveFailures > 1) {
14759
14759
  await sleep(retryInterval(this.consecutiveFailures));
14760
14760
  }
@@ -14763,7 +14763,7 @@ class StreamClient {
14763
14763
  return await this.doAxiosRequest(type, url, data, options);
14764
14764
  }
14765
14765
  else {
14766
- this.logger('error', `client:${type} url: ${url}`, response);
14766
+ this.logger.error(`client:${type} url: ${url}`, response);
14767
14767
  throw new ErrorFromResponse({
14768
14768
  message: `Stream error code ${responseData.code}: ${responseData.message}`,
14769
14769
  code: responseData.code ?? null,
@@ -14794,7 +14794,7 @@ class StreamClient {
14794
14794
  });
14795
14795
  };
14796
14796
  this.dispatchEvent = (event) => {
14797
- this.logger('debug', `Dispatching event: ${event.type}`, event);
14797
+ this.logger.debug(`Dispatching event: ${event.type}`, event);
14798
14798
  if (!this.listeners)
14799
14799
  return;
14800
14800
  // call generic listeners
@@ -14819,13 +14819,13 @@ class StreamClient {
14819
14819
  throw Error('clientID is not set');
14820
14820
  // The StableWSConnection handles all the reconnection logic.
14821
14821
  this.wsConnection = new StableWSConnection(this);
14822
- this.logger('info', 'StreamClient.connect: this.wsConnection.connect()');
14822
+ this.logger.info('StreamClient.connect: this.wsConnection.connect()');
14823
14823
  return await this.wsConnection.connect(this.defaultWSTimeout);
14824
14824
  };
14825
14825
  this.getUserAgent = () => {
14826
14826
  if (!this.cachedUserAgent) {
14827
14827
  const { clientAppIdentifier = {} } = this.options;
14828
- const { sdkName = 'js', sdkVersion = "1.35.0", ...extras } = clientAppIdentifier;
14828
+ const { sdkName = 'js', sdkVersion = "1.36.0", ...extras } = clientAppIdentifier;
14829
14829
  this.cachedUserAgent = [
14830
14830
  `stream-video-${sdkName}-v${sdkVersion}`,
14831
14831
  ...Object.entries(extras).map(([key, value]) => `${key}=${value}`),
@@ -14876,11 +14876,11 @@ class StreamClient {
14876
14876
  };
14877
14877
  this.updateNetworkConnectionStatus = (event) => {
14878
14878
  if (event.type === 'offline') {
14879
- this.logger('debug', 'device went offline');
14879
+ this.logger.debug('device went offline');
14880
14880
  this.dispatchEvent({ type: 'network.changed', online: false });
14881
14881
  }
14882
14882
  else if (event.type === 'online') {
14883
- this.logger('debug', 'device went online');
14883
+ this.logger.debug('device went online');
14884
14884
  this.dispatchEvent({ type: 'network.changed', online: true });
14885
14885
  }
14886
14886
  };
@@ -14928,9 +14928,7 @@ class StreamClient {
14928
14928
  this.tokenManager = new TokenManager(this.secret);
14929
14929
  this.consecutiveFailures = 0;
14930
14930
  this.defaultWSTimeout = this.options.defaultWsTimeout ?? 15000;
14931
- this.logger = isFunction(inputOptions.logger)
14932
- ? inputOptions.logger
14933
- : () => null;
14931
+ this.logger = videoLoggerSystem.getLogger('coordinator');
14934
14932
  }
14935
14933
  get connectionIdPromise() {
14936
14934
  return this.connectionIdPromiseSafe?.();
@@ -14975,12 +14973,10 @@ const getClientAppIdentifier = (options) => {
14975
14973
  */
14976
14974
  const createCoordinatorClient = (apiKey, options) => {
14977
14975
  const clientAppIdentifier = getClientAppIdentifier(options);
14978
- const coordinatorLogger = getLogger(['coordinator']);
14979
14976
  return new StreamClient(apiKey, {
14980
14977
  persistUserOnConnectionFailure: true,
14981
14978
  ...options,
14982
14979
  clientAppIdentifier,
14983
- logger: coordinatorLogger,
14984
14980
  });
14985
14981
  };
14986
14982
  /**
@@ -15018,7 +15014,7 @@ class StreamVideoClient {
15018
15014
  this.registerClientInstance = (apiKey, user) => {
15019
15015
  const instanceKey = getInstanceKey(apiKey, user);
15020
15016
  if (StreamVideoClient._instances.has(instanceKey)) {
15021
- this.logger('warn', `A StreamVideoClient already exists for ${user.id}; Prefer using getOrCreateInstance method`);
15017
+ this.logger.warn(`A StreamVideoClient already exists for ${user.id}; Prefer using getOrCreateInstance method`);
15022
15018
  }
15023
15019
  StreamVideoClient._instances.set(instanceKey, this);
15024
15020
  };
@@ -15033,13 +15029,13 @@ class StreamVideoClient {
15033
15029
  .map((call) => call.cid);
15034
15030
  if (callsToReWatch.length <= 0)
15035
15031
  return;
15036
- this.logger('info', `Rewatching calls ${callsToReWatch.join(', ')}`);
15032
+ this.logger.info(`Rewatching calls ${callsToReWatch.join(', ')}`);
15037
15033
  this.queryCalls({
15038
15034
  watch: true,
15039
15035
  filter_conditions: { cid: { $in: callsToReWatch } },
15040
15036
  sort: [{ field: 'cid', direction: 1 }],
15041
15037
  }).catch((err) => {
15042
- this.logger('error', 'Failed to re-watch calls', err);
15038
+ this.logger.error('Failed to re-watch calls', err);
15043
15039
  });
15044
15040
  }));
15045
15041
  this.effectsRegistered = true;
@@ -15050,7 +15046,7 @@ class StreamVideoClient {
15050
15046
  */
15051
15047
  this.initCallFromEvent = async (e) => {
15052
15048
  if (this.state.connectedUser?.id === e.call.created_by.id) {
15053
- this.logger('debug', `Ignoring ${e.type} event sent by the current user`);
15049
+ this.logger.debug(`Ignoring ${e.type} event sent by the current user`);
15054
15050
  return;
15055
15051
  }
15056
15052
  try {
@@ -15061,7 +15057,7 @@ class StreamVideoClient {
15061
15057
  if (call) {
15062
15058
  if (ringing) {
15063
15059
  if (this.shouldRejectCall(call.cid)) {
15064
- this.logger('info', `Leaving call with busy reject reason ${call.cid} because user is busy`);
15060
+ this.logger.info(`Leaving call with busy reject reason ${call.cid} because user is busy`);
15065
15061
  // remove the instance from the state store
15066
15062
  await call.leave();
15067
15063
  // explicitly reject the call with busy reason as calling state was not ringing before and leave would not call it therefore
@@ -15086,7 +15082,7 @@ class StreamVideoClient {
15086
15082
  });
15087
15083
  if (ringing) {
15088
15084
  if (this.shouldRejectCall(call.cid)) {
15089
- this.logger('info', `Rejecting call ${call.cid} because user is busy`);
15085
+ this.logger.info(`Rejecting call ${call.cid} because user is busy`);
15090
15086
  // call is not in the state store yet, so just reject api is enough
15091
15087
  await call.reject('busy');
15092
15088
  }
@@ -15098,12 +15094,12 @@ class StreamVideoClient {
15098
15094
  else {
15099
15095
  call.state.updateFromCallResponse(e.call);
15100
15096
  this.writeableStateStore.registerCall(call);
15101
- this.logger('info', `New call created and registered: ${call.cid}`);
15097
+ this.logger.info(`New call created and registered: ${call.cid}`);
15102
15098
  }
15103
15099
  });
15104
15100
  }
15105
15101
  catch (err) {
15106
- this.logger('error', `Failed to init call from event ${e.type}`, err);
15102
+ this.logger.error(`Failed to init call from event ${e.type}`, err);
15107
15103
  }
15108
15104
  };
15109
15105
  /**
@@ -15127,13 +15123,13 @@ class StreamVideoClient {
15127
15123
  const errorQueue = [];
15128
15124
  for (let attempt = 0; attempt < maxConnectUserRetries; attempt++) {
15129
15125
  try {
15130
- this.logger('trace', `Connecting user (${attempt})`, user);
15126
+ this.logger.trace(`Connecting user (${attempt})`, user);
15131
15127
  return user.type === 'guest'
15132
15128
  ? await client.connectGuestUser(user)
15133
15129
  : await client.connectUser(user, tokenOrProvider);
15134
15130
  }
15135
15131
  catch (err) {
15136
- this.logger('warn', `Failed to connect a user (${attempt})`, err);
15132
+ this.logger.warn(`Failed to connect a user (${attempt})`, err);
15137
15133
  errorQueue.push(err);
15138
15134
  if (attempt === maxConnectUserRetries - 1) {
15139
15135
  onConnectUserError?.(err, errorQueue);
@@ -15378,8 +15374,11 @@ class StreamVideoClient {
15378
15374
  if (clientOptions?.enableTimerWorker)
15379
15375
  enableTimerWorker();
15380
15376
  const rootLogger = clientOptions?.logger || logToConsole;
15381
- setLogger(rootLogger, clientOptions?.logLevel || 'warn');
15382
- this.logger = getLogger(['client']);
15377
+ videoLoggerSystem.configureLoggers({
15378
+ default: { sink: rootLogger, level: clientOptions?.logLevel || 'warn' },
15379
+ ...clientOptions?.logOptions,
15380
+ });
15381
+ this.logger = videoLoggerSystem.getLogger('client');
15383
15382
  this.rejectCallWhenBusy = clientOptions?.rejectCallWhenBusy ?? false;
15384
15383
  this.streamClient = createCoordinatorClient(apiKey, clientOptions);
15385
15384
  this.writeableStateStore = new StreamVideoWriteableStateStore();
@@ -15392,7 +15391,7 @@ class StreamVideoClient {
15392
15391
  this.registerClientInstance(apiKey, user);
15393
15392
  const tokenOrProvider = createTokenOrProvider(apiKeyOrArgs);
15394
15393
  this.connectUser(user, tokenOrProvider).catch((err) => {
15395
- this.logger('error', 'Failed to connect', err);
15394
+ this.logger.error('Failed to connect', err);
15396
15395
  });
15397
15396
  }
15398
15397
  }
@@ -15426,6 +15425,10 @@ Object.defineProperty(exports, "AxiosError", {
15426
15425
  enumerable: true,
15427
15426
  get: function () { return axios.AxiosError; }
15428
15427
  });
15428
+ Object.defineProperty(exports, "LogLevelEnum", {
15429
+ enumerable: true,
15430
+ get: function () { return scopedLogger.LogLevelEnum; }
15431
+ });
15429
15432
  exports.AudioSettingsRequestDefaultDeviceEnum = AudioSettingsRequestDefaultDeviceEnum;
15430
15433
  exports.AudioSettingsResponseDefaultDeviceEnum = AudioSettingsResponseDefaultDeviceEnum;
15431
15434
  exports.Browsers = browsers;
@@ -15493,8 +15496,6 @@ exports.getAudioOutputDevices = getAudioOutputDevices;
15493
15496
  exports.getAudioStream = getAudioStream;
15494
15497
  exports.getClientDetails = getClientDetails;
15495
15498
  exports.getDeviceState = getDeviceState;
15496
- exports.getLogLevel = getLogLevel;
15497
- exports.getLogger = getLogger;
15498
15499
  exports.getScreenShareStream = getScreenShareStream;
15499
15500
  exports.getSdkInfo = getSdkInfo;
15500
15501
  exports.getVideoBrowserPermission = getVideoBrowserPermission;
@@ -15508,7 +15509,6 @@ exports.hasScreenShareAudio = hasScreenShareAudio;
15508
15509
  exports.hasVideo = hasVideo;
15509
15510
  exports.isPinned = isPinned;
15510
15511
  exports.livestreamOrAudioRoomSortPreset = livestreamOrAudioRoomSortPreset;
15511
- exports.logLevels = logLevels;
15512
15512
  exports.logToConsole = logToConsole;
15513
15513
  exports.name = name;
15514
15514
  exports.noopComparator = noopComparator;
@@ -15521,8 +15521,6 @@ exports.resolveDeviceId = resolveDeviceId;
15521
15521
  exports.role = role;
15522
15522
  exports.screenSharing = screenSharing;
15523
15523
  exports.setDeviceInfo = setDeviceInfo;
15524
- exports.setLogLevel = setLogLevel;
15525
- exports.setLogger = setLogger;
15526
15524
  exports.setOSInfo = setOSInfo;
15527
15525
  exports.setPowerState = setPowerState;
15528
15526
  exports.setSdkInfo = setSdkInfo;
@@ -15530,5 +15528,6 @@ exports.setThermalState = setThermalState;
15530
15528
  exports.setWebRTCInfo = setWebRTCInfo;
15531
15529
  exports.speakerLayoutSortPreset = speakerLayoutSortPreset;
15532
15530
  exports.speaking = speaking;
15531
+ exports.videoLoggerSystem = videoLoggerSystem;
15533
15532
  exports.withParticipantSource = withParticipantSource;
15534
15533
  //# sourceMappingURL=index.cjs.js.map