livekit-client 2.18.7 → 2.18.9

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 (59) hide show
  1. package/dist/livekit-client.e2ee.worker.js +1 -1
  2. package/dist/livekit-client.e2ee.worker.js.map +1 -1
  3. package/dist/livekit-client.e2ee.worker.mjs +2 -2
  4. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  5. package/dist/livekit-client.esm.mjs +408 -255
  6. package/dist/livekit-client.esm.mjs.map +1 -1
  7. package/dist/livekit-client.umd.js +1 -1
  8. package/dist/livekit-client.umd.js.map +1 -1
  9. package/dist/src/api/SignalClient.d.ts.map +1 -1
  10. package/dist/src/logger.d.ts +11 -1
  11. package/dist/src/logger.d.ts.map +1 -1
  12. package/dist/src/room/PCTransport.d.ts +13 -3
  13. package/dist/src/room/PCTransport.d.ts.map +1 -1
  14. package/dist/src/room/PCTransportManager.d.ts +3 -1
  15. package/dist/src/room/PCTransportManager.d.ts.map +1 -1
  16. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  17. package/dist/src/room/Room.d.ts.map +1 -1
  18. package/dist/src/room/data-track/LocalDataTrack.d.ts +32 -0
  19. package/dist/src/room/data-track/LocalDataTrack.d.ts.map +1 -1
  20. package/dist/src/room/data-track/RemoteDataTrack.d.ts.map +1 -1
  21. package/dist/src/room/data-track/handle.d.ts +1 -0
  22. package/dist/src/room/data-track/handle.d.ts.map +1 -1
  23. package/dist/src/room/data-track/incoming/IncomingDataTrackManager.d.ts +4 -3
  24. package/dist/src/room/data-track/incoming/IncomingDataTrackManager.d.ts.map +1 -1
  25. package/dist/src/room/data-track/outgoing/OutgoingDataTrackManager.d.ts +18 -3
  26. package/dist/src/room/data-track/outgoing/OutgoingDataTrackManager.d.ts.map +1 -1
  27. package/dist/src/room/data-track/outgoing/types.d.ts +7 -0
  28. package/dist/src/room/data-track/outgoing/types.d.ts.map +1 -1
  29. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  30. package/dist/src/room/participant/Participant.d.ts.map +1 -1
  31. package/dist/src/utils/subscribeToEvents.d.ts.map +1 -1
  32. package/dist/ts4.2/logger.d.ts +11 -1
  33. package/dist/ts4.2/room/PCTransport.d.ts +13 -3
  34. package/dist/ts4.2/room/PCTransportManager.d.ts +3 -1
  35. package/dist/ts4.2/room/data-track/LocalDataTrack.d.ts +32 -0
  36. package/dist/ts4.2/room/data-track/handle.d.ts +1 -0
  37. package/dist/ts4.2/room/data-track/incoming/IncomingDataTrackManager.d.ts +4 -3
  38. package/dist/ts4.2/room/data-track/outgoing/OutgoingDataTrackManager.d.ts +18 -3
  39. package/dist/ts4.2/room/data-track/outgoing/types.d.ts +7 -0
  40. package/package.json +1 -1
  41. package/src/api/SignalClient.ts +19 -31
  42. package/src/logger.test.ts +61 -0
  43. package/src/logger.ts +38 -4
  44. package/src/room/PCTransport.ts +26 -3
  45. package/src/room/PCTransportManager.test.ts +281 -0
  46. package/src/room/PCTransportManager.ts +45 -31
  47. package/src/room/RTCEngine.ts +34 -52
  48. package/src/room/Room.ts +37 -59
  49. package/src/room/data-track/LocalDataTrack.ts +60 -1
  50. package/src/room/data-track/RemoteDataTrack.ts +4 -1
  51. package/src/room/data-track/handle.ts +4 -0
  52. package/src/room/data-track/incoming/IncomingDataTrackManager.test.ts +72 -2
  53. package/src/room/data-track/incoming/IncomingDataTrackManager.ts +5 -3
  54. package/src/room/data-track/outgoing/OutgoingDataTrackManager.test.ts +387 -1
  55. package/src/room/data-track/outgoing/OutgoingDataTrackManager.ts +51 -3
  56. package/src/room/data-track/outgoing/types.ts +5 -0
  57. package/src/room/participant/LocalParticipant.ts +59 -144
  58. package/src/room/participant/Participant.ts +4 -1
  59. package/src/utils/subscribeToEvents.ts +11 -8
@@ -254,7 +254,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
254
254
 
255
255
  constructor(private options: InternalRoomOptions) {
256
256
  super();
257
- this.log = getLogger(options.loggerName ?? LoggerNames.Engine);
257
+ this.log = getLogger(options.loggerName ?? LoggerNames.Engine, () => this.logContext);
258
258
  this.loggerOptions = {
259
259
  loggerName: options.loggerName,
260
260
  loggerContextCb: () => this.logContext,
@@ -364,7 +364,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
364
364
  // create offer
365
365
  if (!this.subscriberPrimary || joinResponse.fastPublish) {
366
366
  this.negotiate().catch((err) => {
367
- log.error(err, this.logContext);
367
+ this.log.error(err);
368
368
  });
369
369
  }
370
370
  }
@@ -377,15 +377,10 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
377
377
  if (!serverInfo) {
378
378
  serverInfo = { version: joinResponse.serverVersion, region: joinResponse.serverRegion };
379
379
  }
380
- this.log.debug(
380
+ this.log.info(
381
381
  `connected to Livekit Server ${Object.entries(serverInfo)
382
382
  .map(([key, value]) => `${key}: ${value}`)
383
383
  .join(', ')}`,
384
- {
385
- room: joinResponse.room?.name,
386
- roomSid: joinResponse.room?.sid,
387
- identity: joinResponse.participant?.identity,
388
- },
389
384
  );
390
385
 
391
386
  return { joinResponse, serverInfo };
@@ -394,7 +389,6 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
394
389
  if (e.reason === ConnectionErrorReason.ServerUnreachable) {
395
390
  this.log.warn(
396
391
  `Couldn't connect to server, attempt ${this.joinAttempts} of ${this.maxJoinAttempts}`,
397
- this.logContext,
398
392
  );
399
393
  if (this.joinAttempts < this.maxJoinAttempts) {
400
394
  return this.join(url, token, opts, abortSignal, useV0Path);
@@ -531,7 +525,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
531
525
  this.pcManager!.removeTrack(sender);
532
526
  return true;
533
527
  } catch (e: unknown) {
534
- this.log.warn('failed to remove track', { ...this.logContext, error: e });
528
+ this.log.warn('failed to remove track', { error: e });
535
529
  }
536
530
  return false;
537
531
  }
@@ -588,7 +582,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
588
582
 
589
583
  this.pcManager.onDataChannel = this.handleDataChannel;
590
584
  this.pcManager.onStateChange = async (connectionState, publisherState, subscriberState) => {
591
- this.log.debug(`primary PC state changed ${connectionState}`, this.logContext);
585
+ this.log.debug(`primary PC state changed ${connectionState}`);
592
586
 
593
587
  if (['closed', 'disconnected', 'failed'].includes(publisherState)) {
594
588
  // reset publisher connection promise
@@ -642,7 +636,6 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
642
636
  return;
643
637
  }
644
638
  this.log.debug('received server answer', {
645
- ...this.logContext,
646
639
  RTCSdpType: sd.type,
647
640
  sdp: sd.sdp,
648
641
  midToTrackId,
@@ -656,7 +649,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
656
649
  if (!this.pcManager) {
657
650
  return;
658
651
  }
659
- this.log.debug('got ICE candidate from peer', { ...this.logContext, candidate, target });
652
+ this.log.debug('got ICE candidate from peer', { candidate, target });
660
653
  this.pcManager.addIceCandidate(candidate, target);
661
654
  };
662
655
 
@@ -675,15 +668,11 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
675
668
 
676
669
  this.client.onLocalTrackPublished = (res: TrackPublishedResponse) => {
677
670
  this.log.debug('received trackPublishedResponse', {
678
- ...this.logContext,
679
671
  cid: res.cid,
680
672
  track: res.track?.sid,
681
673
  });
682
674
  if (!this.pendingTrackResolvers[res.cid]) {
683
- this.log.error(`missing track resolver for ${res.cid}`, {
684
- ...this.logContext,
685
- cid: res.cid,
686
- });
675
+ this.log.error(`missing track resolver for ${res.cid}`, { cid: res.cid });
687
676
  return;
688
677
  }
689
678
  const { resolve } = this.pendingTrackResolvers[res.cid];
@@ -742,9 +731,11 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
742
731
  };
743
732
 
744
733
  this.client.onLeave = (leave: LeaveRequest) => {
745
- this.log.debug('client leave request', { ...this.logContext, reason: leave?.reason });
734
+ this.log.info(`client leave request received (action=${leave?.action})`, {
735
+ reason: leave?.reason,
736
+ });
746
737
  if (leave.regions) {
747
- this.log.debug('updating regions', this.logContext);
738
+ this.log.debug('updating regions');
748
739
  this.emit(EngineEvent.ServerRegionsReported, leave.regions);
749
740
  }
750
741
  switch (leave.action) {
@@ -772,7 +763,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
772
763
  const rtcConfig = { ...this.rtcConfig };
773
764
 
774
765
  if (this.signalOpts?.e2eeEnabled) {
775
- this.log.debug('E2EE - setting up transports with insertable streams', this.logContext);
766
+ this.log.debug('E2EE - setting up transports with insertable streams');
776
767
  // this makes sure that no data is sent before the transforms are ready
777
768
  // @ts-ignore
778
769
  rtcConfig.encodedInsertableStreams = true;
@@ -911,7 +902,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
911
902
  } else {
912
903
  return;
913
904
  }
914
- this.log.debug(`on data channel ${channel.id}, ${channel.label}`, this.logContext);
905
+ this.log.debug(`on data channel ${channel.id}, ${channel.label}`);
915
906
  channel.onmessage = handler;
916
907
  };
917
908
 
@@ -926,7 +917,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
926
917
  } else if (message.data instanceof Blob) {
927
918
  buffer = await message.data.arrayBuffer();
928
919
  } else {
929
- this.log.error('unsupported data type', { ...this.logContext, data: message.data });
920
+ this.log.error('unsupported data type', { data: message.data });
930
921
  return;
931
922
  }
932
923
  const dp = DataPacket.fromBinary(new Uint8Array(buffer));
@@ -945,7 +936,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
945
936
  this.emit(EngineEvent.ActiveSpeakersUpdate, dp.value.value.speakers);
946
937
  } else if (dp.value?.case === 'encryptedPacket') {
947
938
  if (!this.e2eeManager) {
948
- this.log.error('Received encrypted packet but E2EE not set up', this.logContext);
939
+ this.log.error('Received encrypted packet but E2EE not set up');
949
940
  return;
950
941
  }
951
942
  const decryptedData = await this.e2eeManager?.handleEncryptedData(
@@ -985,7 +976,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
985
976
  } else if (message.data instanceof Blob) {
986
977
  buffer = await message.data.arrayBuffer();
987
978
  } else {
988
- this.log.error('unsupported data type', { ...this.logContext, data: message.data });
979
+ this.log.error('unsupported data type', { data: message.data });
989
980
  return;
990
981
  }
991
982
 
@@ -998,12 +989,9 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
998
989
 
999
990
  if (event instanceof ErrorEvent && event.error) {
1000
991
  const { error } = event.error;
1001
- this.log.error(`DataChannel error on ${channelKind}: ${event.message}`, {
1002
- ...this.logContext,
1003
- error,
1004
- });
992
+ this.log.error(`DataChannel error on ${channelKind}: ${event.message}`, { error });
1005
993
  } else {
1006
- this.log.error(`Unknown DataChannel error on ${channelKind}`, { ...this.logContext, event });
994
+ this.log.error(`Unknown DataChannel error on ${channelKind}`, { event });
1007
995
  }
1008
996
  };
1009
997
 
@@ -1021,7 +1009,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1021
1009
  return sender;
1022
1010
  }
1023
1011
  if (supportsAddTrack()) {
1024
- this.log.warn('using add-track fallback', this.logContext);
1012
+ this.log.warn('using add-track fallback');
1025
1013
  const sender = await this.createRTCRtpSender(track.mediaStreamTrack);
1026
1014
  return sender;
1027
1015
  }
@@ -1039,7 +1027,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1039
1027
  return this.createSimulcastTransceiverSender(track, simulcastTrack, opts, encodings);
1040
1028
  }
1041
1029
  if (supportsAddTrack()) {
1042
- this.log.debug('using add-track fallback', this.logContext);
1030
+ this.log.debug('using add-track fallback');
1043
1031
  return this.createRTCRtpSender(track.mediaStreamTrack);
1044
1032
  }
1045
1033
 
@@ -1118,7 +1106,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1118
1106
  return;
1119
1107
  }
1120
1108
 
1121
- this.log.warn(`${connection} disconnected`, this.logContext);
1109
+ this.log.warn(`${connection} disconnected`);
1122
1110
  if (this.reconnectAttempts === 0) {
1123
1111
  // only reset start time on the first try
1124
1112
  this.reconnectStart = Date.now();
@@ -1127,7 +1115,6 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1127
1115
  const disconnect = (duration: number) => {
1128
1116
  this.log.warn(
1129
1117
  `could not recover connection after ${this.reconnectAttempts} attempts, ${duration}ms. giving up`,
1130
- this.logContext,
1131
1118
  );
1132
1119
  this.emit(EngineEvent.Disconnected);
1133
1120
  this.close();
@@ -1147,7 +1134,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1147
1134
  delay = 0;
1148
1135
  }
1149
1136
 
1150
- this.log.debug(`reconnecting in ${delay}ms`, this.logContext);
1137
+ this.log.debug(`reconnecting in ${delay}ms`);
1151
1138
 
1152
1139
  this.clearReconnectTimeout();
1153
1140
  if (this.token) {
@@ -1168,7 +1155,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1168
1155
  }
1169
1156
  // guard for attempting reconnection multiple times while one attempt is still not finished
1170
1157
  if (this.attemptingReconnect) {
1171
- log.warn('already attempting reconnect, returning early', this.logContext);
1158
+ this.log.warn('already attempting reconnect, returning early');
1172
1159
  return;
1173
1160
  }
1174
1161
  if (
@@ -1193,7 +1180,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1193
1180
  this.reconnectAttempts += 1;
1194
1181
  let recoverable = true;
1195
1182
  if (e instanceof UnexpectedConnectionState) {
1196
- this.log.debug('received unrecoverable error', { ...this.logContext, error: e });
1183
+ this.log.debug('received unrecoverable error', { error: e });
1197
1184
  // unrecoverable
1198
1185
  recoverable = false;
1199
1186
  } else if (!(e instanceof SignalReconnectError)) {
@@ -1208,7 +1195,6 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1208
1195
  `could not recover connection after ${this.reconnectAttempts} attempts, ${
1209
1196
  Date.now() - this.reconnectStart
1210
1197
  }ms. giving up`,
1211
- this.logContext,
1212
1198
  );
1213
1199
  this.emit(EngineEvent.Disconnected);
1214
1200
  await this.close();
@@ -1222,7 +1208,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1222
1208
  try {
1223
1209
  return this.reconnectPolicy.nextRetryDelayInMs(context);
1224
1210
  } catch (e) {
1225
- this.log.warn('encountered error in reconnect policy', { ...this.logContext, error: e });
1211
+ this.log.warn('encountered error in reconnect policy', { error: e });
1226
1212
  }
1227
1213
 
1228
1214
  // error in user code with provided reconnect policy, stop reconnecting
@@ -1236,7 +1222,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1236
1222
  throw new UnexpectedConnectionState('could not reconnect, url or token not saved');
1237
1223
  }
1238
1224
 
1239
- this.log.info(`reconnecting, attempt: ${this.reconnectAttempts}`, this.logContext);
1225
+ this.log.info(`reconnecting, attempt: ${this.reconnectAttempts}`);
1240
1226
  this.emit(EngineEvent.Restarting);
1241
1227
 
1242
1228
  if (!this.client.isDisconnected) {
@@ -1248,10 +1234,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1248
1234
  let joinResponse: JoinResponse;
1249
1235
  try {
1250
1236
  if (!this.signalOpts) {
1251
- this.log.warn(
1252
- 'attempted connection restart, without signal options present',
1253
- this.logContext,
1254
- );
1237
+ this.log.warn('attempted connection restart, without signal options present');
1255
1238
  throw new SignalReconnectError();
1256
1239
  }
1257
1240
  // in case a regionUrl is passed, the region URL takes precedence
@@ -1312,7 +1295,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1312
1295
  throw new UnexpectedConnectionState('publisher and subscriber connections unset');
1313
1296
  }
1314
1297
 
1315
- this.log.info(`resuming signal connection, attempt ${this.reconnectAttempts}`, this.logContext);
1298
+ this.log.info(`resuming signal connection, attempt ${this.reconnectAttempts}`);
1316
1299
  this.emit(EngineEvent.Resuming);
1317
1300
  let res: ReconnectResponse | undefined;
1318
1301
  try {
@@ -1322,7 +1305,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1322
1305
  let message = '';
1323
1306
  if (error instanceof Error) {
1324
1307
  message = error.message;
1325
- this.log.error(error.message, { ...this.logContext, error });
1308
+ this.log.error(error.message, { error });
1326
1309
  }
1327
1310
  if (error instanceof ConnectionError && error.reason === ConnectionErrorReason.NotAllowed) {
1328
1311
  throw new UnexpectedConnectionState('could not reconnect, token might be expired');
@@ -1341,7 +1324,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1341
1324
  this.latestJoinResponse.serverInfo = res.serverInfo;
1342
1325
  }
1343
1326
  } else {
1344
- this.log.warn('Did not receive reconnect response', this.logContext);
1327
+ this.log.warn('Did not receive reconnect response');
1345
1328
  }
1346
1329
 
1347
1330
  if (this.shouldFailNext) {
@@ -1384,7 +1367,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1384
1367
  private async waitForPCReconnected() {
1385
1368
  this.pcState = PCState.Reconnecting;
1386
1369
 
1387
- this.log.debug('waiting for peer connection to reconnect', this.logContext);
1370
+ this.log.debug('waiting for peer connection to reconnect');
1388
1371
  try {
1389
1372
  await sleep(minReconnectWait); // FIXME setTimeout again not ideal for a connection critical path
1390
1373
  if (!this.pcManager) {
@@ -1531,7 +1514,6 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1531
1514
  if (this.lossyDataDropCount % 100 === 0) {
1532
1515
  this.log.warn(
1533
1516
  `dropping lossy data channel messages, total dropped: ${this.lossyDataDropCount}`,
1534
- this.logContext,
1535
1517
  );
1536
1518
  }
1537
1519
  return;
@@ -1637,7 +1619,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1637
1619
  if (needNegotiation) {
1638
1620
  // start negotiation
1639
1621
  this.negotiate().catch((err) => {
1640
- log.error(err, this.logContext);
1622
+ this.log.error(err);
1641
1623
  });
1642
1624
  }
1643
1625
 
@@ -1714,7 +1696,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1714
1696
 
1715
1697
  const handleClosed = () => {
1716
1698
  abortController.abort();
1717
- this.log.debug('engine disconnected while negotiation was ongoing', this.logContext);
1699
+ this.log.debug('engine disconnected while negotiation was ongoing');
1718
1700
  resolve();
1719
1701
  return;
1720
1702
  };
@@ -1795,7 +1777,7 @@ export default class RTCEngine extends (EventEmitter as new () => TypedEventEmit
1795
1777
  localDataTrackInfos: Array<DataTrackInfo>,
1796
1778
  ) {
1797
1779
  if (!this.pcManager) {
1798
- this.log.warn('sync state cannot be sent without peer connection setup', this.logContext);
1780
+ this.log.warn('sync state cannot be sent without peer connection setup');
1799
1781
  return;
1800
1782
  }
1801
1783
  const previousPublisherOffer = this.pcManager.publisher.getLocalDescription();