@stream-io/video-client 1.3.1 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.js CHANGED
@@ -8276,8 +8276,9 @@ class Publisher {
8276
8276
  * @param isDtxEnabled whether DTX is enabled.
8277
8277
  * @param isRedEnabled whether RED is enabled.
8278
8278
  * @param iceRestartDelay the delay in milliseconds to wait before restarting ICE once connection goes to `disconnected` state.
8279
+ * @param onUnrecoverableError a callback to call when an unrecoverable error occurs.
8279
8280
  */
8280
- constructor({ connectionConfig, sfuClient, dispatcher, state, isDtxEnabled, isRedEnabled, iceRestartDelay = 2500, }) {
8281
+ constructor({ connectionConfig, sfuClient, dispatcher, state, isDtxEnabled, isRedEnabled, iceRestartDelay = 2500, onUnrecoverableError, }) {
8281
8282
  this.transceiverRegistry = {
8282
8283
  [TrackType.AUDIO]: undefined,
8283
8284
  [TrackType.VIDEO]: undefined,
@@ -8798,15 +8799,16 @@ class Publisher {
8798
8799
  logger$3('debug', `ICE Connection state changed to`, state);
8799
8800
  const hasNetworkConnection = this.state.callingState !== exports.CallingState.OFFLINE;
8800
8801
  if (state === 'failed') {
8801
- logger$3('warn', `Attempting to restart ICE`);
8802
+ logger$3('debug', `Attempting to restart ICE`);
8802
8803
  this.restartIce().catch((e) => {
8803
8804
  logger$3('error', `ICE restart error`, e);
8805
+ this.onUnrecoverableError?.();
8804
8806
  });
8805
8807
  }
8806
8808
  else if (state === 'disconnected' && hasNetworkConnection) {
8807
8809
  // when in `disconnected` state, the browser may recover automatically,
8808
8810
  // hence, we delay the ICE restart
8809
- logger$3('warn', `Scheduling ICE restart in ${this.iceRestartDelay} ms.`);
8811
+ logger$3('debug', `Scheduling ICE restart in ${this.iceRestartDelay} ms.`);
8810
8812
  this.iceRestartTimeout = setTimeout(() => {
8811
8813
  // check if the state is still `disconnected` or `failed`
8812
8814
  // as the connection may have recovered (or failed) in the meantime
@@ -8814,6 +8816,7 @@ class Publisher {
8814
8816
  this.pc.iceConnectionState === 'failed') {
8815
8817
  this.restartIce().catch((e) => {
8816
8818
  logger$3('error', `ICE restart error`, e);
8819
+ this.onUnrecoverableError?.();
8817
8820
  });
8818
8821
  }
8819
8822
  else {
@@ -8841,11 +8844,13 @@ class Publisher {
8841
8844
  this.isDtxEnabled = isDtxEnabled;
8842
8845
  this.isRedEnabled = isRedEnabled;
8843
8846
  this.iceRestartDelay = iceRestartDelay;
8847
+ this.onUnrecoverableError = onUnrecoverableError;
8844
8848
  this.unsubscribeOnIceRestart = dispatcher.on('iceRestart', (iceRestart) => {
8845
8849
  if (iceRestart.peerType !== PeerType.PUBLISHER_UNSPECIFIED)
8846
8850
  return;
8847
8851
  this.restartIce().catch((err) => {
8848
8852
  logger$3('warn', `ICERestart failed`, err);
8853
+ this.onUnrecoverableError?.();
8849
8854
  });
8850
8855
  });
8851
8856
  }
@@ -8875,8 +8880,9 @@ class Subscriber {
8875
8880
  * @param state the state of the call.
8876
8881
  * @param connectionConfig the connection configuration to use.
8877
8882
  * @param iceRestartDelay the delay in milliseconds to wait before restarting ICE when connection goes to `disconnected` state.
8883
+ * @param onUnrecoverableError a callback to call when an unrecoverable error occurs.
8878
8884
  */
8879
- constructor({ sfuClient, dispatcher, state, connectionConfig, iceRestartDelay = 2500, }) {
8885
+ constructor({ sfuClient, dispatcher, state, connectionConfig, iceRestartDelay = 2500, onUnrecoverableError, }) {
8880
8886
  this.isIceRestarting = false;
8881
8887
  /**
8882
8888
  * Creates a new `RTCPeerConnection` instance with the given configuration.
@@ -8986,6 +8992,10 @@ class Subscriber {
8986
8992
  logger$2('debug', 'ICE restart is already in progress');
8987
8993
  return;
8988
8994
  }
8995
+ if (this.pc.connectionState === 'new') {
8996
+ logger$2('debug', `ICE connection is not yet established, skipping restart.`);
8997
+ return;
8998
+ }
8989
8999
  const previousIsIceRestarting = this.isIceRestarting;
8990
9000
  try {
8991
9001
  this.isIceRestarting = true;
@@ -9006,17 +9016,18 @@ class Subscriber {
9006
9016
  const participantToUpdate = this.state.participants.find((p) => p.trackLookupPrefix === trackId);
9007
9017
  logger$2('debug', `[onTrack]: Got remote ${trackType} track for userId: ${participantToUpdate?.userId}`, e.track.id, e.track);
9008
9018
  if (!participantToUpdate) {
9009
- logger$2('error', `[onTrack]: Received track for unknown participant: ${trackId}`, e);
9019
+ logger$2('warn', `[onTrack]: Received track for unknown participant: ${trackId}`, e);
9010
9020
  return;
9011
9021
  }
9022
+ const trackDebugInfo = `${participantToUpdate.userId} ${trackType}:${trackId}`;
9012
9023
  e.track.addEventListener('mute', () => {
9013
- logger$2('info', `[onTrack]: Track muted: ${participantToUpdate.userId} ${trackType}:${trackId}`);
9024
+ logger$2('info', `[onTrack]: Track muted: ${trackDebugInfo}`);
9014
9025
  });
9015
9026
  e.track.addEventListener('unmute', () => {
9016
- logger$2('info', `[onTrack]: Track unmuted: ${participantToUpdate.userId} ${trackType}:${trackId}`);
9027
+ logger$2('info', `[onTrack]: Track unmuted: ${trackDebugInfo}`);
9017
9028
  });
9018
9029
  e.track.addEventListener('ended', () => {
9019
- logger$2('info', `[onTrack]: Track ended: ${participantToUpdate.userId} ${trackType}:${trackId}`);
9030
+ logger$2('info', `[onTrack]: Track ended: ${trackDebugInfo}`);
9020
9031
  });
9021
9032
  const streamKindProp = {
9022
9033
  TRACK_TYPE_AUDIO: 'audioStream',
@@ -9086,15 +9097,16 @@ class Subscriber {
9086
9097
  return;
9087
9098
  const hasNetworkConnection = this.state.callingState !== exports.CallingState.OFFLINE;
9088
9099
  if (state === 'failed') {
9089
- logger$2('warn', `Attempting to restart ICE`);
9100
+ logger$2('debug', `Attempting to restart ICE`);
9090
9101
  this.restartIce().catch((e) => {
9091
9102
  logger$2('error', `ICE restart failed`, e);
9103
+ this.onUnrecoverableError?.();
9092
9104
  });
9093
9105
  }
9094
9106
  else if (state === 'disconnected' && hasNetworkConnection) {
9095
9107
  // when in `disconnected` state, the browser may recover automatically,
9096
9108
  // hence, we delay the ICE restart
9097
- logger$2('warn', `Scheduling ICE restart in ${this.iceRestartDelay} ms.`);
9109
+ logger$2('debug', `Scheduling ICE restart in ${this.iceRestartDelay} ms.`);
9098
9110
  this.iceRestartTimeout = setTimeout(() => {
9099
9111
  // check if the state is still `disconnected` or `failed`
9100
9112
  // as the connection may have recovered (or failed) in the meantime
@@ -9102,12 +9114,13 @@ class Subscriber {
9102
9114
  this.pc.iceConnectionState === 'failed') {
9103
9115
  this.restartIce().catch((e) => {
9104
9116
  logger$2('error', `ICE restart failed`, e);
9117
+ this.onUnrecoverableError?.();
9105
9118
  });
9106
9119
  }
9107
9120
  else {
9108
9121
  logger$2('debug', `Scheduled ICE restart: connection recovered, canceled.`);
9109
9122
  }
9110
- }, 5000);
9123
+ }, this.iceRestartDelay);
9111
9124
  }
9112
9125
  };
9113
9126
  this.onIceGatheringStateChange = () => {
@@ -9123,6 +9136,7 @@ class Subscriber {
9123
9136
  this.sfuClient = sfuClient;
9124
9137
  this.state = state;
9125
9138
  this.iceRestartDelay = iceRestartDelay;
9139
+ this.onUnrecoverableError = onUnrecoverableError;
9126
9140
  this.pc = this.createPeerConnection(connectionConfig);
9127
9141
  this.unregisterOnSubscriberOffer = dispatcher.on('subscriberOffer', (subscriberOffer) => {
9128
9142
  this.negotiate(subscriberOffer).catch((err) => {
@@ -9134,6 +9148,7 @@ class Subscriber {
9134
9148
  return;
9135
9149
  this.restartIce().catch((err) => {
9136
9150
  logger$2('warn', `ICERestart failed`, err);
9151
+ this.onUnrecoverableError?.();
9137
9152
  });
9138
9153
  });
9139
9154
  }
@@ -12816,6 +12831,11 @@ class Call {
12816
12831
  dispatcher: this.dispatcher,
12817
12832
  state: this.state,
12818
12833
  connectionConfig,
12834
+ onUnrecoverableError: () => {
12835
+ reconnect('full', 'unrecoverable subscriber error').catch((err) => {
12836
+ this.logger('debug', '[Rejoin]: Rejoin failed', err);
12837
+ });
12838
+ },
12819
12839
  });
12820
12840
  }
12821
12841
  // anonymous users can't publish anything hence, there is no need
@@ -12832,6 +12852,11 @@ class Call {
12832
12852
  connectionConfig,
12833
12853
  isDtxEnabled,
12834
12854
  isRedEnabled,
12855
+ onUnrecoverableError: () => {
12856
+ reconnect('full', 'unrecoverable publisher error').catch((err) => {
12857
+ this.logger('debug', '[Rejoin]: Rejoin failed', err);
12858
+ });
12859
+ },
12835
12860
  });
12836
12861
  }
12837
12862
  if (!this.statsReporter) {
@@ -15403,7 +15428,7 @@ class StreamClient {
15403
15428
  });
15404
15429
  };
15405
15430
  this.getUserAgent = () => {
15406
- const version = "1.3.1" ;
15431
+ const version = "1.4.1" ;
15407
15432
  return (this.userAgent ||
15408
15433
  `stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
15409
15434
  };