livekit-client 1.6.6 → 1.6.7

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 (30) hide show
  1. package/dist/livekit-client.esm.mjs +96 -84
  2. package/dist/livekit-client.esm.mjs.map +1 -1
  3. package/dist/livekit-client.umd.js +1 -1
  4. package/dist/livekit-client.umd.js.map +1 -1
  5. package/dist/src/room/PCTransport.d.ts.map +1 -1
  6. package/dist/src/room/RTCEngine.d.ts +10 -3
  7. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  8. package/dist/src/room/Room.d.ts.map +1 -1
  9. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  10. package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
  11. package/dist/src/room/track/RemoteTrackPublication.d.ts +1 -1
  12. package/dist/src/room/track/RemoteTrackPublication.d.ts.map +1 -1
  13. package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
  14. package/dist/src/room/track/Track.d.ts +2 -1
  15. package/dist/src/room/track/Track.d.ts.map +1 -1
  16. package/dist/src/room/track/options.d.ts +2 -2
  17. package/dist/ts4.2/src/room/RTCEngine.d.ts +10 -3
  18. package/dist/ts4.2/src/room/track/RemoteTrackPublication.d.ts +1 -1
  19. package/dist/ts4.2/src/room/track/Track.d.ts +2 -1
  20. package/dist/ts4.2/src/room/track/options.d.ts +2 -2
  21. package/package.json +13 -13
  22. package/src/room/PCTransport.ts +2 -0
  23. package/src/room/RTCEngine.ts +46 -51
  24. package/src/room/Room.ts +13 -3
  25. package/src/room/participant/LocalParticipant.ts +19 -7
  26. package/src/room/participant/RemoteParticipant.ts +2 -3
  27. package/src/room/track/RemoteTrackPublication.ts +3 -2
  28. package/src/room/track/RemoteVideoTrack.ts +0 -3
  29. package/src/room/track/Track.ts +2 -1
  30. package/src/room/track/options.ts +2 -2
@@ -13800,7 +13800,7 @@ var uaParser = {
13800
13800
  })(uaParser, uaParserExports);
13801
13801
  var UAParser = uaParserExports;
13802
13802
 
13803
- var version$1 = "1.6.6";
13803
+ var version$1 = "1.6.7";
13804
13804
 
13805
13805
  const version = version$1;
13806
13806
  const protocolVersion = 8;
@@ -14781,7 +14781,8 @@ class Track extends eventsExports.EventEmitter {
14781
14781
  this.attachedElements = [];
14782
14782
  this.isMuted = false;
14783
14783
  /**
14784
- * indicates current state of stream
14784
+ * indicates current state of stream, it'll indicate `paused` if the track
14785
+ * has been paused by congestion controller
14785
14786
  */
14786
14787
  this.streamState = Track.StreamState.Active;
14787
14788
  this._currentBitrate = 0;
@@ -16115,9 +16116,6 @@ class RemoteVideoTrack extends RemoteTrack {
16115
16116
  this.updateDimensions();
16116
16117
  }, REACTION_DELAY);
16117
16118
  this.adaptiveStreamSettings = adaptiveStreamSettings;
16118
- if (this.isAdaptiveStream) {
16119
- this.streamState = Track.StreamState.Paused;
16120
- }
16121
16119
  }
16122
16120
  get isAdaptiveStream() {
16123
16121
  return this.adaptiveStreamSettings !== undefined;
@@ -17023,8 +17021,8 @@ function sortPresets(presets) {
17023
17021
  }
17024
17022
 
17025
17023
  class RemoteTrackPublication extends TrackPublication {
17026
- constructor(kind, id, name, autoSubscribe) {
17027
- super(kind, id, name);
17024
+ constructor(kind, ti, autoSubscribe) {
17025
+ super(kind, ti.sid, ti.name);
17028
17026
  this.track = undefined;
17029
17027
  /** @internal */
17030
17028
  this.allowed = true;
@@ -17049,6 +17047,7 @@ class RemoteTrackPublication extends TrackPublication {
17049
17047
  this.emitTrackUpdate();
17050
17048
  };
17051
17049
  this.subscribed = autoSubscribe;
17050
+ this.updateInfo(ti);
17052
17051
  }
17053
17052
  /**
17054
17053
  * Subscribe or unsubscribe to this remote track
@@ -17415,12 +17414,12 @@ class RemoteParticipant extends Participant {
17415
17414
  if (!kind) {
17416
17415
  return;
17417
17416
  }
17418
- publication = new RemoteTrackPublication(kind, ti.sid, ti.name, (_a = this.signalClient.connectOptions) === null || _a === void 0 ? void 0 : _a.autoSubscribe);
17417
+ publication = new RemoteTrackPublication(kind, ti, (_a = this.signalClient.connectOptions) === null || _a === void 0 ? void 0 : _a.autoSubscribe);
17419
17418
  publication.updateInfo(ti);
17420
17419
  newTracks.set(ti.sid, publication);
17421
17420
  const existingTrackOfSource = Array.from(this.tracks.values()).find(publishedTrack => publishedTrack.source === (publication === null || publication === void 0 ? void 0 : publication.source));
17422
17421
  if (existingTrackOfSource && publication.source !== Track.Source.Unknown) {
17423
- livekitLogger.warn("received a second track publication for ".concat(this.identity, " with the same source: ").concat(publication.source), {
17422
+ livekitLogger.debug("received a second track publication for ".concat(this.identity, " with the same source: ").concat(publication.source), {
17424
17423
  oldTrack: existingTrackOfSource,
17425
17424
  newTrack: publication,
17426
17425
  participant: this,
@@ -17928,7 +17927,7 @@ class LocalParticipant extends Participant {
17928
17927
  * @param options
17929
17928
  */
17930
17929
  async publishTrack(track, options) {
17931
- var _a, _b, _c, _d, _e;
17930
+ var _a, _b, _c, _d, _e, _f;
17932
17931
  // convert raw media track into audio or video track
17933
17932
  if (track instanceof MediaStreamTrack) {
17934
17933
  switch (track.kind) {
@@ -17953,7 +17952,11 @@ class LocalParticipant extends Participant {
17953
17952
  if (options.dtx === undefined) {
17954
17953
  livekitLogger.info("Opus DTX will be disabled for stereo tracks by default. Enable them explicitly to make it work.");
17955
17954
  }
17955
+ if (options.red === undefined) {
17956
+ livekitLogger.info("Opus RED will be disabled for stereo tracks by default. Enable them explicitly to make it work.");
17957
+ }
17956
17958
  (_a = options.dtx) !== null && _a !== void 0 ? _a : options.dtx = false;
17959
+ (_b = options.red) !== null && _b !== void 0 ? _b : options.red = false;
17957
17960
  }
17958
17961
  const opts = _objectSpread2(_objectSpread2({}, this.roomOptions.publishDefaults), options);
17959
17962
  // is it already published? if so skip
@@ -18011,9 +18014,9 @@ class LocalParticipant extends Participant {
18011
18014
  type: Track.kindToProto(track.kind),
18012
18015
  muted: track.isMuted,
18013
18016
  source: Track.sourceToProto(track.source),
18014
- disableDtx: !((_b = opts.dtx) !== null && _b !== void 0 ? _b : true),
18017
+ disableDtx: !((_c = opts.dtx) !== null && _c !== void 0 ? _c : true),
18015
18018
  stereo: isStereo,
18016
- disableRed: !((_c = opts.red) !== null && _c !== void 0 ? _c : true)
18019
+ disableRed: !((_d = opts.red) !== null && _d !== void 0 ? _d : true)
18017
18020
  });
18018
18021
  // compute encodings and layers for video
18019
18022
  let encodings;
@@ -18036,7 +18039,7 @@ class LocalParticipant extends Participant {
18036
18039
  if (track instanceof LocalVideoTrack) {
18037
18040
  if ((opts === null || opts === void 0 ? void 0 : opts.videoCodec) === 'av1') {
18038
18041
  // set scalabilityMode to 'L3T3' by default
18039
- opts.scalabilityMode = (_d = opts.scalabilityMode) !== null && _d !== void 0 ? _d : 'L3T3';
18042
+ opts.scalabilityMode = (_e = opts.scalabilityMode) !== null && _e !== void 0 ? _e : 'L3T3';
18040
18043
  }
18041
18044
  // set up backup
18042
18045
  if (opts.videoCodec && opts.backupCodec && opts.videoCodec !== opts.backupCodec.codec) {
@@ -18078,7 +18081,7 @@ class LocalParticipant extends Participant {
18078
18081
  });
18079
18082
  // store RTPSender
18080
18083
  track.sender = await this.engine.createSender(track, opts, encodings);
18081
- if (track.codec === 'av1' && encodings && ((_e = encodings[0]) === null || _e === void 0 ? void 0 : _e.maxBitrate)) {
18084
+ if (track.codec === 'av1' && encodings && ((_f = encodings[0]) === null || _f === void 0 ? void 0 : _f.maxBitrate)) {
18082
18085
  this.engine.publisher.setTrackCodecBitrate(req.cid, track.codec, encodings[0].maxBitrate / 1000);
18083
18086
  }
18084
18087
  this.engine.negotiate();
@@ -18174,13 +18177,20 @@ class LocalParticipant extends Participant {
18174
18177
  if (stopOnUnpublish) {
18175
18178
  track.stop();
18176
18179
  }
18177
- if (this.engine.publisher && this.engine.publisher.pc.connectionState !== 'closed' && track.sender) {
18180
+ let negotiationNeeded = false;
18181
+ const trackSender = track.sender;
18182
+ track.sender = undefined;
18183
+ if (this.engine.publisher && this.engine.publisher.pc.connectionState !== 'closed' && trackSender) {
18178
18184
  try {
18179
- this.engine.removeTrack(track.sender);
18185
+ if (this.engine.removeTrack(trackSender)) {
18186
+ negotiationNeeded = true;
18187
+ }
18180
18188
  if (track instanceof LocalVideoTrack) {
18181
18189
  for (const [, trackInfo] of track.simulcastCodecs) {
18182
18190
  if (trackInfo.sender) {
18183
- this.engine.removeTrack(trackInfo.sender);
18191
+ if (this.engine.removeTrack(trackInfo.sender)) {
18192
+ negotiationNeeded = true;
18193
+ }
18184
18194
  trackInfo.sender = undefined;
18185
18195
  }
18186
18196
  }
@@ -18191,11 +18201,8 @@ class LocalParticipant extends Participant {
18191
18201
  error: e,
18192
18202
  method: 'unpublishTrack'
18193
18203
  });
18194
- } finally {
18195
- await this.engine.negotiate();
18196
18204
  }
18197
18205
  }
18198
- track.sender = undefined;
18199
18206
  // remove from our maps
18200
18207
  this.tracks.delete(publication.trackSid);
18201
18208
  switch (publication.kind) {
@@ -18208,6 +18215,9 @@ class LocalParticipant extends Participant {
18208
18215
  }
18209
18216
  this.emit(ParticipantEvent.LocalTrackUnpublished, publication);
18210
18217
  publication.setTrack(undefined);
18218
+ if (negotiationNeeded) {
18219
+ await this.engine.negotiate();
18220
+ }
18211
18221
  return publication;
18212
18222
  }
18213
18223
  async unpublishTracks(tracks) {
@@ -19757,6 +19767,8 @@ class PCTransport extends eventsExports {
19757
19767
  });
19758
19768
  }
19759
19769
  close() {
19770
+ this.pc.onconnectionstatechange = null;
19771
+ this.pc.oniceconnectionstatechange = null;
19760
19772
  this.pc.close();
19761
19773
  }
19762
19774
  async setMungedLocalDescription(sd, munged) {
@@ -19875,9 +19887,7 @@ class RTCEngine extends eventsExports.EventEmitter {
19875
19887
  return this._isClosed;
19876
19888
  }
19877
19889
  constructor(options) {
19878
- var _this;
19879
19890
  super();
19880
- _this = this;
19881
19891
  this.options = options;
19882
19892
  this.rtcConfig = {};
19883
19893
  this.peerConnectionTimeout = roomConnectOptionDefaults.peerConnectionTimeout;
@@ -19896,6 +19906,7 @@ class RTCEngine extends eventsExports.EventEmitter {
19896
19906
  this.joinAttempts = 0;
19897
19907
  /** specifies how often an initial join connection is allowed to retry */
19898
19908
  this.maxJoinAttempts = 1;
19909
+ this.shouldFailNext = false;
19899
19910
  this.handleDataChannel = async _ref => {
19900
19911
  let {
19901
19912
  channel
@@ -19948,26 +19959,24 @@ class RTCEngine extends eventsExports.EventEmitter {
19948
19959
  // websocket reconnect behavior. if websocket is interrupted, and the PeerConnection
19949
19960
  // continues to work, we can reconnect to websocket to continue the session
19950
19961
  // after a number of retries, we'll close and give up permanently
19951
- this.handleDisconnect = function (connection) {
19952
- let signalEvents = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
19953
- let disconnectReason = arguments.length > 2 ? arguments[2] : undefined;
19954
- if (_this._isClosed) {
19962
+ this.handleDisconnect = (connection, disconnectReason) => {
19963
+ if (this._isClosed) {
19955
19964
  return;
19956
19965
  }
19957
19966
  livekitLogger.warn("".concat(connection, " disconnected"));
19958
- if (_this.reconnectAttempts === 0) {
19967
+ if (this.reconnectAttempts === 0) {
19959
19968
  // only reset start time on the first try
19960
- _this.reconnectStart = Date.now();
19969
+ this.reconnectStart = Date.now();
19961
19970
  }
19962
19971
  const disconnect = duration => {
19963
- livekitLogger.warn("could not recover connection after ".concat(_this.reconnectAttempts, " attempts, ").concat(duration, "ms. giving up"));
19964
- _this.emit(EngineEvent.Disconnected);
19965
- _this.close();
19972
+ livekitLogger.warn("could not recover connection after ".concat(this.reconnectAttempts, " attempts, ").concat(duration, "ms. giving up"));
19973
+ this.emit(EngineEvent.Disconnected);
19974
+ this.close();
19966
19975
  };
19967
- const duration = Date.now() - _this.reconnectStart;
19968
- let delay = _this.getNextRetryDelay({
19976
+ const duration = Date.now() - this.reconnectStart;
19977
+ let delay = this.getNextRetryDelay({
19969
19978
  elapsedMs: duration,
19970
- retryCount: _this.reconnectAttempts
19979
+ retryCount: this.reconnectAttempts
19971
19980
  });
19972
19981
  if (delay === null) {
19973
19982
  disconnect(duration);
@@ -19977,14 +19986,14 @@ class RTCEngine extends eventsExports.EventEmitter {
19977
19986
  delay = 0;
19978
19987
  }
19979
19988
  livekitLogger.debug("reconnecting in ".concat(delay, "ms"));
19980
- _this.clearReconnectTimeout();
19981
- _this.reconnectTimeout = CriticalTimers.setTimeout(() => _this.attemptReconnect(signalEvents, disconnectReason), delay);
19989
+ this.clearReconnectTimeout();
19990
+ this.reconnectTimeout = CriticalTimers.setTimeout(() => this.attemptReconnect(disconnectReason), delay);
19982
19991
  };
19983
19992
  this.handleBrowserOnLine = () => {
19984
19993
  // in case the engine is currently reconnecting, attempt a reconnect immediately after the browser state has changed to 'onLine'
19985
19994
  if (this.client.isReconnecting) {
19986
19995
  this.clearReconnectTimeout();
19987
- this.attemptReconnect(true, ReconnectReason.REASON_SIGNAL_DISCONNECTED);
19996
+ this.attemptReconnect(ReconnectReason.REASON_SIGNAL_DISCONNECTED);
19988
19997
  }
19989
19998
  };
19990
19999
  this.client = new SignalClient();
@@ -20083,6 +20092,12 @@ class RTCEngine extends eventsExports.EventEmitter {
20083
20092
  this.client.sendAddTrack(req);
20084
20093
  });
20085
20094
  }
20095
+ /**
20096
+ * Removes sender from PeerConnection, returning true if it was removed successfully
20097
+ * and a negotiation is necessary
20098
+ * @param sender
20099
+ * @returns
20100
+ */
20086
20101
  removeTrack(sender) {
20087
20102
  var _a;
20088
20103
  if (sender.track && this.pendingTrackResolvers[sender.track.id]) {
@@ -20096,12 +20111,14 @@ class RTCEngine extends eventsExports.EventEmitter {
20096
20111
  }
20097
20112
  try {
20098
20113
  (_a = this.publisher) === null || _a === void 0 ? void 0 : _a.pc.removeTrack(sender);
20114
+ return true;
20099
20115
  } catch (e) {
20100
20116
  livekitLogger.warn('failed to remove track', {
20101
20117
  error: e,
20102
20118
  method: 'removeTrack'
20103
20119
  });
20104
20120
  }
20121
+ return false;
20105
20122
  }
20106
20123
  updateMuteStatus(trackSid, muted) {
20107
20124
  this.client.sendMuteTrack(trackSid, muted);
@@ -20110,8 +20127,11 @@ class RTCEngine extends eventsExports.EventEmitter {
20110
20127
  var _a;
20111
20128
  return (_a = this.reliableDCSub) === null || _a === void 0 ? void 0 : _a.readyState;
20112
20129
  }
20113
- get connectedServerAddress() {
20114
- return this.connectedServerAddr;
20130
+ async getConnectedServerAddress() {
20131
+ if (this.primaryPC === undefined) {
20132
+ return undefined;
20133
+ }
20134
+ return getConnectedAddress(this.primaryPC);
20115
20135
  }
20116
20136
  configure(joinResponse) {
20117
20137
  var _a;
@@ -20149,13 +20169,6 @@ class RTCEngine extends eventsExports.EventEmitter {
20149
20169
  primaryPC.onconnectionstatechange = async () => {
20150
20170
  livekitLogger.debug("primary PC state changed ".concat(primaryPC.connectionState));
20151
20171
  if (primaryPC.connectionState === 'connected') {
20152
- try {
20153
- this.connectedServerAddr = await getConnectedAddress(primaryPC);
20154
- } catch (e) {
20155
- livekitLogger.warn('could not get connected server address', {
20156
- error: e
20157
- });
20158
- }
20159
20172
  const shouldEmit = this.pcState === PCState.New;
20160
20173
  this.pcState = PCState.Connected;
20161
20174
  if (shouldEmit) {
@@ -20165,7 +20178,7 @@ class RTCEngine extends eventsExports.EventEmitter {
20165
20178
  // on Safari, PeerConnection will switch to 'disconnected' during renegotiation
20166
20179
  if (this.pcState === PCState.Connected) {
20167
20180
  this.pcState = PCState.Disconnected;
20168
- this.handleDisconnect('primary peerconnection', false, subscriberPrimary ? ReconnectReason.REASON_SUBSCRIBER_FAILED : ReconnectReason.REASON_PUBLISHER_FAILED);
20181
+ this.handleDisconnect('primary peerconnection', subscriberPrimary ? ReconnectReason.REASON_SUBSCRIBER_FAILED : ReconnectReason.REASON_PUBLISHER_FAILED);
20169
20182
  }
20170
20183
  }
20171
20184
  };
@@ -20173,7 +20186,7 @@ class RTCEngine extends eventsExports.EventEmitter {
20173
20186
  livekitLogger.debug("secondary PC state changed ".concat(secondaryPC.connectionState));
20174
20187
  // also reconnect if secondary peerconnection fails
20175
20188
  if (secondaryPC.connectionState === 'failed') {
20176
- this.handleDisconnect('secondary peerconnection', false, subscriberPrimary ? ReconnectReason.REASON_PUBLISHER_FAILED : ReconnectReason.REASON_SUBSCRIBER_FAILED);
20189
+ this.handleDisconnect('secondary peerconnection', subscriberPrimary ? ReconnectReason.REASON_PUBLISHER_FAILED : ReconnectReason.REASON_SUBSCRIBER_FAILED);
20177
20190
  }
20178
20191
  };
20179
20192
  this.subscriber.pc.ontrack = ev => {
@@ -20236,7 +20249,7 @@ class RTCEngine extends eventsExports.EventEmitter {
20236
20249
  this.token = token;
20237
20250
  };
20238
20251
  this.client.onClose = () => {
20239
- this.handleDisconnect('signal', false, ReconnectReason.REASON_SIGNAL_DISCONNECTED);
20252
+ this.handleDisconnect('signal', ReconnectReason.REASON_SIGNAL_DISCONNECTED);
20240
20253
  };
20241
20254
  this.client.onLeave = leave => {
20242
20255
  if (leave === null || leave === void 0 ? void 0 : leave.canReconnect) {
@@ -20410,9 +20423,7 @@ class RTCEngine extends eventsExports.EventEmitter {
20410
20423
  }
20411
20424
  return this.publisher.pc.addTrack(track);
20412
20425
  }
20413
- async attemptReconnect() {
20414
- let signalEvents = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
20415
- let reason = arguments.length > 1 ? arguments[1] : undefined;
20426
+ async attemptReconnect(reason) {
20416
20427
  var _a, _b, _c;
20417
20428
  if (this._isClosed) {
20418
20429
  return;
@@ -20430,17 +20441,15 @@ class RTCEngine extends eventsExports.EventEmitter {
20430
20441
  try {
20431
20442
  this.attemptingReconnect = true;
20432
20443
  if (this.fullReconnectOnNext) {
20433
- await this.restartConnection(signalEvents);
20444
+ await this.restartConnection();
20434
20445
  } else {
20435
- await this.resumeConnection(signalEvents, reason);
20446
+ await this.resumeConnection(reason);
20436
20447
  }
20437
20448
  this.clearPendingReconnect();
20438
20449
  this.fullReconnectOnNext = false;
20439
20450
  } catch (e) {
20440
20451
  this.reconnectAttempts += 1;
20441
- let reconnectRequired = false;
20442
20452
  let recoverable = true;
20443
- let requireSignalEvents = false;
20444
20453
  if (e instanceof UnexpectedConnectionState) {
20445
20454
  livekitLogger.debug('received unrecoverable error', {
20446
20455
  error: e
@@ -20449,16 +20458,10 @@ class RTCEngine extends eventsExports.EventEmitter {
20449
20458
  recoverable = false;
20450
20459
  } else if (!(e instanceof SignalReconnectError)) {
20451
20460
  // cannot resume
20452
- reconnectRequired = true;
20453
- }
20454
- // when we flip from resume to reconnect
20455
- // we need to fire the right reconnecting events
20456
- if (reconnectRequired && !this.fullReconnectOnNext) {
20457
20461
  this.fullReconnectOnNext = true;
20458
- requireSignalEvents = true;
20459
20462
  }
20460
20463
  if (recoverable) {
20461
- this.handleDisconnect('reconnect', requireSignalEvents, ReconnectReason.REASON_UNKOWN);
20464
+ this.handleDisconnect('reconnect', ReconnectReason.REASON_UNKOWN);
20462
20465
  } else {
20463
20466
  livekitLogger.info("could not recover connection after ".concat(this.reconnectAttempts, " attempts, ").concat(Date.now() - this.reconnectStart, "ms. giving up"));
20464
20467
  this.emit(EngineEvent.Disconnected);
@@ -20480,16 +20483,13 @@ class RTCEngine extends eventsExports.EventEmitter {
20480
20483
  return null;
20481
20484
  }
20482
20485
  async restartConnection() {
20483
- let emitRestarting = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
20484
20486
  var _a, _b;
20485
20487
  if (!this.url || !this.token) {
20486
20488
  // permanent failure, don't attempt reconnection
20487
20489
  throw new UnexpectedConnectionState('could not reconnect, url or token not saved');
20488
20490
  }
20489
20491
  livekitLogger.info("reconnecting, attempt: ".concat(this.reconnectAttempts));
20490
- if (emitRestarting || this.reconnectAttempts === 0) {
20491
- this.emit(EngineEvent.Restarting);
20492
- }
20492
+ this.emit(EngineEvent.Restarting);
20493
20493
  if (this.client.isConnected) {
20494
20494
  await this.client.sendLeave();
20495
20495
  }
@@ -20509,14 +20509,16 @@ class RTCEngine extends eventsExports.EventEmitter {
20509
20509
  } catch (e) {
20510
20510
  throw new SignalReconnectError();
20511
20511
  }
20512
+ if (this.shouldFailNext) {
20513
+ this.shouldFailNext = false;
20514
+ throw new Error('simulated failure');
20515
+ }
20512
20516
  await this.waitForPCConnected();
20513
20517
  this.client.setReconnected();
20514
20518
  // reconnect success
20515
20519
  this.emit(EngineEvent.Restarted, joinResponse);
20516
20520
  }
20517
- async resumeConnection() {
20518
- let emitResuming = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
20519
- let reason = arguments.length > 1 ? arguments[1] : undefined;
20521
+ async resumeConnection(reason) {
20520
20522
  var _a;
20521
20523
  if (!this.url || !this.token) {
20522
20524
  // permanent failure, don't attempt reconnection
@@ -20527,9 +20529,7 @@ class RTCEngine extends eventsExports.EventEmitter {
20527
20529
  throw new UnexpectedConnectionState('publisher and subscriber connections unset');
20528
20530
  }
20529
20531
  livekitLogger.info("resuming signal connection, attempt ".concat(this.reconnectAttempts));
20530
- if (emitResuming || this.reconnectAttempts === 0) {
20531
- this.emit(EngineEvent.Resuming);
20532
- }
20532
+ this.emit(EngineEvent.Resuming);
20533
20533
  try {
20534
20534
  const res = await this.client.reconnect(this.url, this.token, this.participantSid, reason);
20535
20535
  if (res) {
@@ -20545,6 +20545,10 @@ class RTCEngine extends eventsExports.EventEmitter {
20545
20545
  throw new SignalReconnectError(message);
20546
20546
  }
20547
20547
  this.emit(EngineEvent.SignalResumed);
20548
+ if (this.shouldFailNext) {
20549
+ this.shouldFailNext = false;
20550
+ throw new Error('simulated failure');
20551
+ }
20548
20552
  this.subscriber.restartingIce = true;
20549
20553
  // only restart publisher if it's needed
20550
20554
  if (this.hasPublished) {
@@ -20578,13 +20582,6 @@ class RTCEngine extends eventsExports.EventEmitter {
20578
20582
  // manually
20579
20583
  now - startTime > minReconnectWait && ((_a = this.primaryPC) === null || _a === void 0 ? void 0 : _a.connectionState) === 'connected') {
20580
20584
  this.pcState = PCState.Connected;
20581
- try {
20582
- this.connectedServerAddr = await getConnectedAddress(this.primaryPC);
20583
- } catch (e) {
20584
- livekitLogger.warn('could not get connected server address', {
20585
- error: e
20586
- });
20587
- }
20588
20585
  }
20589
20586
  if (this.pcState === PCState.Connected) {
20590
20587
  return;
@@ -20656,7 +20653,7 @@ class RTCEngine extends eventsExports.EventEmitter {
20656
20653
  this.on(EngineEvent.Closing, handleClosed);
20657
20654
  const negotiationTimeout = setTimeout(() => {
20658
20655
  reject('negotiation timed out');
20659
- this.handleDisconnect('negotiation', false, ReconnectReason.REASON_SIGNAL_DISCONNECTED);
20656
+ this.handleDisconnect('negotiation', ReconnectReason.REASON_SIGNAL_DISCONNECTED);
20660
20657
  }, this.peerConnectionTimeout);
20661
20658
  const cleanup = () => {
20662
20659
  clearTimeout(negotiationTimeout);
@@ -20675,7 +20672,7 @@ class RTCEngine extends eventsExports.EventEmitter {
20675
20672
  if (e instanceof NegotiationError) {
20676
20673
  this.fullReconnectOnNext = true;
20677
20674
  }
20678
- this.handleDisconnect('negotiation', false, ReconnectReason.REASON_UNKOWN);
20675
+ this.handleDisconnect('negotiation', ReconnectReason.REASON_UNKOWN);
20679
20676
  });
20680
20677
  });
20681
20678
  }
@@ -20696,6 +20693,11 @@ class RTCEngine extends eventsExports.EventEmitter {
20696
20693
  }
20697
20694
  }
20698
20695
  }
20696
+ /* @internal */
20697
+ failNext() {
20698
+ // debugging method to fail the next reconnect/resume attempt
20699
+ this.shouldFailNext = true;
20700
+ }
20699
20701
  clearReconnectTimeout() {
20700
20702
  if (this.reconnectTimeout) {
20701
20703
  CriticalTimers.clearTimeout(this.reconnectTimeout);
@@ -21015,6 +21017,9 @@ class Room extends eventsExports.EventEmitter {
21015
21017
  });
21016
21018
  await track.restartTrack();
21017
21019
  }
21020
+ livekitLogger.debug('publishing new track', {
21021
+ track: pub.trackSid
21022
+ });
21018
21023
  await this.localParticipant.publishTrack(track, pub.options);
21019
21024
  }
21020
21025
  }));
@@ -21337,6 +21342,13 @@ class Room extends eventsExports.EventEmitter {
21337
21342
  }
21338
21343
  });
21339
21344
  break;
21345
+ case 'resume-reconnect':
21346
+ this.engine.failNext();
21347
+ await this.engine.client.close();
21348
+ if (this.engine.client.onClose) {
21349
+ this.engine.client.onClose('simulate resume-reconnect');
21350
+ }
21351
+ break;
21340
21352
  case 'force-tcp':
21341
21353
  case 'force-tls':
21342
21354
  req = SimulateScenario.fromPartial({
@@ -21571,7 +21583,7 @@ class Room extends eventsExports.EventEmitter {
21571
21583
  participant.tracks.forEach(publication => {
21572
21584
  participant.unpublishTrack(publication.trackSid, true);
21573
21585
  });
21574
- this.emitWhenConnected(RoomEvent.ParticipantDisconnected, participant);
21586
+ this.emit(RoomEvent.ParticipantDisconnected, participant);
21575
21587
  }
21576
21588
  async acquireAudioContext() {
21577
21589
  var _a, _b;
@@ -21632,7 +21644,7 @@ class Room extends eventsExports.EventEmitter {
21632
21644
  }
21633
21645
  this.emit(RoomEvent.TrackSubscribed, track, publication, participant);
21634
21646
  }).on(ParticipantEvent.TrackUnpublished, publication => {
21635
- this.emitWhenConnected(RoomEvent.TrackUnpublished, publication, participant);
21647
+ this.emit(RoomEvent.TrackUnpublished, publication, participant);
21636
21648
  }).on(ParticipantEvent.TrackUnsubscribed, (track, publication) => {
21637
21649
  this.emit(RoomEvent.TrackUnsubscribed, track, publication, participant);
21638
21650
  }).on(ParticipantEvent.TrackSubscriptionFailed, sid => {