livekit-client 1.15.7 → 1.15.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -10614,7 +10614,7 @@ function getMatch(exp, ua) {
10614
10614
  return match && match.length >= id && match[id] || '';
10615
10615
  }
10616
10616
 
10617
- var version$1 = "1.15.7";
10617
+ var version$1 = "1.15.9";
10618
10618
 
10619
10619
  const version = version$1;
10620
10620
  const protocolVersion = 11;
@@ -12753,6 +12753,18 @@ SimulateScenario.fields = proto3.util.newFieldList(() => [{
12753
12753
  kind: "scalar",
12754
12754
  T: 3 /* ScalarType.INT64 */,
12755
12755
  oneof: "scenario"
12756
+ }, {
12757
+ no: 7,
12758
+ name: "disconnect_signal_on_resume",
12759
+ kind: "scalar",
12760
+ T: 8 /* ScalarType.BOOL */,
12761
+ oneof: "scenario"
12762
+ }, {
12763
+ no: 8,
12764
+ name: "disconnect_signal_on_resume_no_messages",
12765
+ kind: "scalar",
12766
+ T: 8 /* ScalarType.BOOL */,
12767
+ oneof: "scenario"
12756
12768
  }]);
12757
12769
  /**
12758
12770
  * @generated from message livekit.Ping
@@ -14835,6 +14847,9 @@ class SignalClient {
14835
14847
  get isDisconnected() {
14836
14848
  return this.state === SignalConnectionState.DISCONNECTING || this.state === SignalConnectionState.DISCONNECTED;
14837
14849
  }
14850
+ get isEstablishingConnection() {
14851
+ return this.state === SignalConnectionState.CONNECTING || this.state === SignalConnectionState.RECONNECTING;
14852
+ }
14838
14853
  constructor() {
14839
14854
  let useJSON = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
14840
14855
  let loggerOptions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
@@ -14978,7 +14993,7 @@ class SignalClient {
14978
14993
  this.startPingInterval();
14979
14994
  }
14980
14995
  resolve(resp.message.value);
14981
- } else if (this.state === SignalConnectionState.RECONNECTING) {
14996
+ } else if (this.state === SignalConnectionState.RECONNECTING && resp.message.case !== 'leave') {
14982
14997
  // in reconnecting, any message received means signal reconnected
14983
14998
  this.state = SignalConnectionState.CONNECTED;
14984
14999
  abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.removeEventListener('abort', abortHandler);
@@ -14989,6 +15004,8 @@ class SignalClient {
14989
15004
  resolve();
14990
15005
  shouldProcessMessage = true;
14991
15006
  }
15007
+ } else if (this.isEstablishingConnection && resp.message.case === 'leave') {
15008
+ reject(new ConnectionError('Received leave request while trying to (re)connect'));
14992
15009
  } else if (!opts.reconnect) {
14993
15010
  // non-reconnect case, should receive join response first
14994
15011
  reject(new ConnectionError("did not receive join response, got ".concat((_d = resp.message) === null || _d === void 0 ? void 0 : _d.case, " instead")));
@@ -15003,8 +15020,12 @@ class SignalClient {
15003
15020
  this.handleSignalResponse(resp);
15004
15021
  });
15005
15022
  this.ws.onclose = ev => {
15023
+ if (this.isEstablishingConnection) {
15024
+ reject(new ConnectionError('Websocket got closed during a (re)connection attempt'));
15025
+ }
15006
15026
  this.log.warn("websocket closed", Object.assign(Object.assign({}, this.logContext), {
15007
- reason: ev.reason
15027
+ reason: ev.reason,
15028
+ state: this.state
15008
15029
  }));
15009
15030
  this.handleOnClose(ev.reason);
15010
15031
  };
@@ -16822,6 +16843,7 @@ class PCTransportManager {
16822
16843
  return __awaiter(this, void 0, void 0, function* () {
16823
16844
  this.log.debug('received server offer', Object.assign(Object.assign({}, this.logContext), {
16824
16845
  RTCSdpType: sd.type,
16846
+ sdp: sd.sdp,
16825
16847
  signalingState: this.subscriber.getSignallingState().toString()
16826
16848
  }));
16827
16849
  yield this.subscriber.setRemoteDescription(sd);
@@ -17393,6 +17415,9 @@ class RTCEngine extends eventsExports.EventEmitter {
17393
17415
  delete this.pendingTrackResolvers[res.cid];
17394
17416
  resolve(res.track);
17395
17417
  };
17418
+ this.client.onLocalTrackUnpublished = response => {
17419
+ this.emit(EngineEvent.LocalTrackUnpublished, response);
17420
+ };
17396
17421
  this.client.onTokenRefresh = token => {
17397
17422
  this.token = token;
17398
17423
  };
@@ -17615,6 +17640,7 @@ class RTCEngine extends eventsExports.EventEmitter {
17615
17640
  }
17616
17641
  // guard for attempting reconnection multiple times while one attempt is still not finished
17617
17642
  if (this.attemptingReconnect) {
17643
+ livekitLogger.warn('already attempting reconnect, returning early', this.logContext);
17618
17644
  return;
17619
17645
  }
17620
17646
  if (((_a = this.clientConfiguration) === null || _a === void 0 ? void 0 : _a.resumeConnection) === ClientConfigSetting.DISABLED ||
@@ -17704,6 +17730,10 @@ class RTCEngine extends eventsExports.EventEmitter {
17704
17730
  this.client.setReconnected();
17705
17731
  this.emit(EngineEvent.SignalRestarted, joinResponse);
17706
17732
  yield this.waitForPCReconnected();
17733
+ // re-check signal connection state before setting engine as resumed
17734
+ if (this.client.currentState !== SignalConnectionState.CONNECTED) {
17735
+ throw new SignalReconnectError('Signal connection got severed during reconnect');
17736
+ }
17707
17737
  (_a = this.regionUrlProvider) === null || _a === void 0 ? void 0 : _a.resetAttempts();
17708
17738
  // reconnect success
17709
17739
  this.emit(EngineEvent.Restarted);
@@ -17740,13 +17770,15 @@ class RTCEngine extends eventsExports.EventEmitter {
17740
17770
  const rtcConfig = this.makeRTCConfiguration(res);
17741
17771
  this.pcManager.updateConfiguration(rtcConfig);
17742
17772
  }
17743
- } catch (e) {
17773
+ } catch (error) {
17744
17774
  let message = '';
17745
- if (e instanceof Error) {
17746
- message = e.message;
17747
- this.log.error(e.message, this.logContext);
17775
+ if (error instanceof Error) {
17776
+ message = error.message;
17777
+ this.log.error(error.message, Object.assign(Object.assign({}, this.logContext), {
17778
+ error
17779
+ }));
17748
17780
  }
17749
- if (e instanceof ConnectionError && e.reason === 0 /* ConnectionErrorReason.NotAllowed */) {
17781
+ if (error instanceof ConnectionError && error.reason === 0 /* ConnectionErrorReason.NotAllowed */) {
17750
17782
  throw new UnexpectedConnectionState('could not reconnect, token might be expired');
17751
17783
  }
17752
17784
  throw new SignalReconnectError(message);
@@ -17758,6 +17790,10 @@ class RTCEngine extends eventsExports.EventEmitter {
17758
17790
  }
17759
17791
  yield this.pcManager.triggerIceRestart();
17760
17792
  yield this.waitForPCReconnected();
17793
+ // re-check signal connection state before setting engine as resumed
17794
+ if (this.client.currentState !== SignalConnectionState.CONNECTED) {
17795
+ throw new SignalReconnectError('Signal connection got severed during reconnect');
17796
+ }
17761
17797
  this.client.setReconnected();
17762
17798
  // recreate publish datachannel if it's id is null
17763
17799
  // (for safari https://bugs.webkit.org/show_bug.cgi?id=184688)
@@ -21566,7 +21602,7 @@ class LocalParticipant extends Participant {
21566
21602
  yield Promise.all(localPubs.map(pub => __awaiter(this, void 0, void 0, function* () {
21567
21603
  const track = pub.track;
21568
21604
  yield this.unpublishTrack(track, false);
21569
- if (restartTracks && !track.isMuted && (track instanceof LocalAudioTrack || track instanceof LocalVideoTrack) && !track.isUserProvided) {
21605
+ if (restartTracks && !track.isMuted && track.source !== Track.Source.ScreenShare && track.source !== Track.Source.ScreenShareAudio && (track instanceof LocalAudioTrack || track instanceof LocalVideoTrack) && !track.isUserProvided) {
21570
21606
  // generally we need to restart the track before publishing, often a full reconnect
21571
21607
  // is necessary because computer had gone to sleep.
21572
21608
  this.log.debug('restarting existing track', Object.assign(Object.assign({}, this.logContext), {
@@ -22066,30 +22102,7 @@ class Room extends eventsExports.EventEmitter {
22066
22102
  this.applyJoinResponse(joinResponse);
22067
22103
  try {
22068
22104
  // unpublish & republish tracks
22069
- const localPubs = [];
22070
- this.localParticipant.tracks.forEach(pub => {
22071
- if (pub.track) {
22072
- localPubs.push(pub);
22073
- }
22074
- });
22075
- yield Promise.all(localPubs.map(pub => __awaiter(this, void 0, void 0, function* () {
22076
- const track = pub.track;
22077
- this.localParticipant.unpublishTrack(track, false);
22078
- if (!track.isMuted) {
22079
- if ((track instanceof LocalAudioTrack || track instanceof LocalVideoTrack) && track.source !== Track.Source.ScreenShare && track.source !== Track.Source.ScreenShareAudio && !track.isUserProvided) {
22080
- // we need to restart the track before publishing, often a full reconnect
22081
- // is necessary because computer had gone to sleep.
22082
- this.log.debug('restarting existing track', Object.assign(Object.assign({}, this.logContext), {
22083
- track: pub.trackSid
22084
- }));
22085
- yield track.restartTrack();
22086
- }
22087
- this.log.debug('publishing new track', Object.assign(Object.assign({}, this.logContext), {
22088
- track: pub.trackSid
22089
- }));
22090
- yield this.localParticipant.publishTrack(track, pub.options);
22091
- }
22092
- })));
22105
+ yield this.localParticipant.republishAllTracks(undefined, true);
22093
22106
  } catch (error) {
22094
22107
  this.log.error('error trying to re-publish tracks after reconnection', Object.assign(Object.assign({}, this.logContext), {
22095
22108
  error
@@ -22584,6 +22597,30 @@ class Room extends eventsExports.EventEmitter {
22584
22597
  // @ts-expect-error function is private
22585
22598
  yield this.engine.client.handleOnClose('simulate resume-disconnect');
22586
22599
  break;
22600
+ case 'disconnect-signal-on-resume':
22601
+ postAction = () => __awaiter(this, void 0, void 0, function* () {
22602
+ // @ts-expect-error function is private
22603
+ yield this.engine.client.handleOnClose('simulate resume-disconnect');
22604
+ });
22605
+ req = new SimulateScenario({
22606
+ scenario: {
22607
+ case: 'disconnectSignalOnResume',
22608
+ value: true
22609
+ }
22610
+ });
22611
+ break;
22612
+ case 'disconnect-signal-on-resume-no-messages':
22613
+ postAction = () => __awaiter(this, void 0, void 0, function* () {
22614
+ // @ts-expect-error function is private
22615
+ yield this.engine.client.handleOnClose('simulate resume-disconnect');
22616
+ });
22617
+ req = new SimulateScenario({
22618
+ scenario: {
22619
+ case: 'disconnectSignalOnResumeNoMessages',
22620
+ value: true
22621
+ }
22622
+ });
22623
+ break;
22587
22624
  case 'full-reconnect':
22588
22625
  this.engine.fullReconnectOnNext = true;
22589
22626
  // @ts-expect-error function is private
@@ -22620,8 +22657,8 @@ class Room extends eventsExports.EventEmitter {
22620
22657
  break;
22621
22658
  }
22622
22659
  if (req) {
22623
- this.engine.client.sendSimulateScenario(req);
22624
- postAction();
22660
+ yield this.engine.client.sendSimulateScenario(req);
22661
+ yield postAction();
22625
22662
  }
22626
22663
  });
22627
22664
  }
@@ -22990,7 +23027,11 @@ class Room extends eventsExports.EventEmitter {
22990
23027
  !this.engine.verifyTransport()) {
22991
23028
  consecutiveFailures++;
22992
23029
  this.log.warn('detected connection state mismatch', Object.assign(Object.assign({}, this.logContext), {
22993
- numFailures: consecutiveFailures
23030
+ numFailures: consecutiveFailures,
23031
+ engine: {
23032
+ closed: this.engine.isClosed,
23033
+ transportsConnected: this.engine.verifyTransport()
23034
+ }
22994
23035
  }));
22995
23036
  if (consecutiveFailures >= 3) {
22996
23037
  this.recreateEngine();
@@ -23073,7 +23114,7 @@ class Room extends eventsExports.EventEmitter {
23073
23114
  name: 'video-dummy'
23074
23115
  }), new LocalVideoTrack(publishOptions.useRealTracks ? (yield window.navigator.mediaDevices.getUserMedia({
23075
23116
  video: true
23076
- })).getVideoTracks()[0] : createDummyVideoStreamTrack((_a = 160 * participantOptions.aspectRatios[0]) !== null && _a !== void 0 ? _a : 1, 160, true, true), undefined, false, {
23117
+ })).getVideoTracks()[0] : createDummyVideoStreamTrack(160 * ((_a = participantOptions.aspectRatios[0]) !== null && _a !== void 0 ? _a : 1), 160, true, true), undefined, false, {
23077
23118
  loggerName: this.options.loggerName,
23078
23119
  loggerContextCb: () => this.logContext
23079
23120
  }), {
@@ -23112,7 +23153,7 @@ class Room extends eventsExports.EventEmitter {
23112
23153
  });
23113
23154
  const p = this.getOrCreateParticipant(info.identity, info);
23114
23155
  if (participantOptions.video) {
23115
- const dummyVideo = createDummyVideoStreamTrack((_b = 160 * participantOptions.aspectRatios[i % participantOptions.aspectRatios.length]) !== null && _b !== void 0 ? _b : 1, 160, false, true);
23156
+ const dummyVideo = createDummyVideoStreamTrack(160 * ((_b = participantOptions.aspectRatios[i % participantOptions.aspectRatios.length]) !== null && _b !== void 0 ? _b : 1), 160, false, true);
23116
23157
  const videoTrack = new TrackInfo({
23117
23158
  source: TrackSource.CAMERA,
23118
23159
  sid: Math.floor(Math.random() * 10000).toString(),