livekit-client 1.6.6 → 1.6.7

Sign up to get free protection for your applications and to get access to all the features.
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 => {