livekit-client 2.11.4 → 2.13.0

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 (60) 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 +25 -14
  4. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  5. package/dist/livekit-client.esm.mjs +155 -22
  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 +2 -1
  10. package/dist/src/api/SignalClient.d.ts.map +1 -1
  11. package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
  12. package/dist/src/e2ee/KeyProvider.d.ts +8 -5
  13. package/dist/src/e2ee/KeyProvider.d.ts.map +1 -1
  14. package/dist/src/e2ee/events.d.ts +8 -3
  15. package/dist/src/e2ee/events.d.ts.map +1 -1
  16. package/dist/src/e2ee/types.d.ts +5 -1
  17. package/dist/src/e2ee/types.d.ts.map +1 -1
  18. package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
  19. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts +4 -4
  20. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts.map +1 -1
  21. package/dist/src/room/RTCEngine.d.ts +2 -1
  22. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  23. package/dist/src/room/Room.d.ts +2 -0
  24. package/dist/src/room/Room.d.ts.map +1 -1
  25. package/dist/src/room/events.d.ts +22 -2
  26. package/dist/src/room/events.d.ts.map +1 -1
  27. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  28. package/dist/src/room/participant/Participant.d.ts +13 -0
  29. package/dist/src/room/participant/Participant.d.ts.map +1 -1
  30. package/dist/src/room/track/RemoteAudioTrack.d.ts.map +1 -1
  31. package/dist/src/room/track/create.d.ts.map +1 -1
  32. package/dist/src/version.d.ts +1 -1
  33. package/dist/ts4.2/src/api/SignalClient.d.ts +2 -1
  34. package/dist/ts4.2/src/e2ee/KeyProvider.d.ts +8 -5
  35. package/dist/ts4.2/src/e2ee/events.d.ts +8 -3
  36. package/dist/ts4.2/src/e2ee/types.d.ts +5 -1
  37. package/dist/ts4.2/src/e2ee/worker/ParticipantKeyHandler.d.ts +4 -4
  38. package/dist/ts4.2/src/room/RTCEngine.d.ts +2 -1
  39. package/dist/ts4.2/src/room/Room.d.ts +2 -0
  40. package/dist/ts4.2/src/room/events.d.ts +22 -2
  41. package/dist/ts4.2/src/room/participant/Participant.d.ts +13 -0
  42. package/dist/ts4.2/src/version.d.ts +1 -1
  43. package/package.json +2 -2
  44. package/src/api/SignalClient.ts +10 -0
  45. package/src/e2ee/E2eeManager.ts +6 -1
  46. package/src/e2ee/KeyProvider.ts +13 -6
  47. package/src/e2ee/events.ts +12 -3
  48. package/src/e2ee/types.ts +8 -1
  49. package/src/e2ee/worker/FrameCryptor.ts +8 -4
  50. package/src/e2ee/worker/ParticipantKeyHandler.test.ts +104 -4
  51. package/src/e2ee/worker/ParticipantKeyHandler.ts +22 -23
  52. package/src/e2ee/worker/e2ee.worker.ts +7 -2
  53. package/src/room/RTCEngine.ts +8 -2
  54. package/src/room/Room.ts +25 -0
  55. package/src/room/events.ts +23 -0
  56. package/src/room/participant/LocalParticipant.ts +1 -5
  57. package/src/room/participant/Participant.ts +47 -2
  58. package/src/room/track/RemoteAudioTrack.ts +3 -2
  59. package/src/room/track/create.ts +3 -5
  60. package/src/version.ts +1 -1
@@ -3884,6 +3884,9 @@ const DisconnectReason = /* @__PURE__ */proto3.makeEnum("livekit.DisconnectReaso
3884
3884
  }, {
3885
3885
  no: 13,
3886
3886
  name: "SIP_TRUNK_FAILURE"
3887
+ }, {
3888
+ no: 14,
3889
+ name: "CONNECTION_TIMEOUT"
3887
3890
  }]);
3888
3891
  const ReconnectReason = /* @__PURE__ */proto3.makeEnum("livekit.ReconnectReason", [{
3889
3892
  no: 0,
@@ -3929,6 +3932,9 @@ const AudioTrackFeature = /* @__PURE__ */proto3.makeEnum("livekit.AudioTrackFeat
3929
3932
  }, {
3930
3933
  no: 5,
3931
3934
  name: "TF_ENHANCED_NOISE_CANCELLATION"
3935
+ }, {
3936
+ no: 6,
3937
+ name: "TF_PRECONNECT_BUFFER"
3932
3938
  }]);
3933
3939
  const Room$1 = /* @__PURE__ */proto3.makeMessageType("livekit.Room", () => [{
3934
3940
  no: 1,
@@ -4929,6 +4935,9 @@ const ClientInfo_SDK = /* @__PURE__ */proto3.makeEnum("livekit.ClientInfo.SDK",
4929
4935
  }, {
4930
4936
  no: 12,
4931
4937
  name: "NODE"
4938
+ }, {
4939
+ no: 13,
4940
+ name: "UNREAL"
4932
4941
  }]);
4933
4942
  const ClientConfiguration = /* @__PURE__ */proto3.makeMessageType("livekit.ClientConfiguration", () => [{
4934
4943
  no: 1,
@@ -5419,6 +5428,12 @@ const SignalResponse = /* @__PURE__ */proto3.makeMessageType("livekit.SignalResp
5419
5428
  kind: "message",
5420
5429
  T: TrackSubscribed,
5421
5430
  oneof: "message"
5431
+ }, {
5432
+ no: 24,
5433
+ name: "room_moved",
5434
+ kind: "message",
5435
+ T: RoomMovedResponse,
5436
+ oneof: "message"
5422
5437
  }]);
5423
5438
  const SimulcastCodec = /* @__PURE__ */proto3.makeMessageType("livekit.SimulcastCodec", () => [{
5424
5439
  no: 1,
@@ -5525,6 +5540,12 @@ const AddTrackRequest = /* @__PURE__ */proto3.makeMessageType("livekit.AddTrackR
5525
5540
  name: "backup_codec_policy",
5526
5541
  kind: "enum",
5527
5542
  T: proto3.getEnumType(BackupCodecPolicy$1)
5543
+ }, {
5544
+ no: 17,
5545
+ name: "audio_features",
5546
+ kind: "enum",
5547
+ T: proto3.getEnumType(AudioTrackFeature),
5548
+ repeated: true
5528
5549
  }]);
5529
5550
  const TrickleRequest = /* @__PURE__ */proto3.makeMessageType("livekit.TrickleRequest", () => [{
5530
5551
  no: 1,
@@ -6045,6 +6066,29 @@ const SubscriptionPermissionUpdate = /* @__PURE__ */proto3.makeMessageType("live
6045
6066
  T: 8
6046
6067
  /* ScalarType.BOOL */
6047
6068
  }]);
6069
+ const RoomMovedResponse = /* @__PURE__ */proto3.makeMessageType("livekit.RoomMovedResponse", () => [{
6070
+ no: 1,
6071
+ name: "room",
6072
+ kind: "message",
6073
+ T: Room$1
6074
+ }, {
6075
+ no: 2,
6076
+ name: "token",
6077
+ kind: "scalar",
6078
+ T: 9
6079
+ /* ScalarType.STRING */
6080
+ }, {
6081
+ no: 3,
6082
+ name: "participant",
6083
+ kind: "message",
6084
+ T: ParticipantInfo
6085
+ }, {
6086
+ no: 4,
6087
+ name: "other_participants",
6088
+ kind: "message",
6089
+ T: ParticipantInfo,
6090
+ repeated: true
6091
+ }]);
6048
6092
  const SyncState = /* @__PURE__ */proto3.makeMessageType("livekit.SyncState", () => [{
6049
6093
  no: 1,
6050
6094
  name: "answer",
@@ -10162,11 +10206,16 @@ const KEY_PROVIDER_DEFAULTS = {
10162
10206
  var KeyProviderEvent;
10163
10207
  (function (KeyProviderEvent) {
10164
10208
  KeyProviderEvent["SetKey"] = "setKey";
10209
+ /** Event for requesting to ratchet the key used to encrypt the stream */
10165
10210
  KeyProviderEvent["RatchetRequest"] = "ratchetRequest";
10211
+ /** Emitted when a key is ratcheted. Could be after auto-ratcheting on decryption failure or
10212
+ * following a `RatchetRequest`, will contain the ratcheted key material */
10166
10213
  KeyProviderEvent["KeyRatcheted"] = "keyRatcheted";
10167
10214
  })(KeyProviderEvent || (KeyProviderEvent = {}));
10168
10215
  var KeyHandlerEvent;
10169
10216
  (function (KeyHandlerEvent) {
10217
+ /** Emitted when a key has been ratcheted. Is emitted when any key has been ratcheted
10218
+ * i.e. when the FrameCryptor tried to ratchet when decryption is failing */
10170
10219
  KeyHandlerEvent["KeyRatcheted"] = "keyRatcheted";
10171
10220
  })(KeyHandlerEvent || (KeyHandlerEvent = {}));
10172
10221
  var EncryptionEvent;
@@ -10335,14 +10384,18 @@ class BaseKeyProvider extends eventsExports.EventEmitter {
10335
10384
  let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
10336
10385
  super();
10337
10386
  /**
10338
- * callback being invoked after a ratchet request has been performed on a participant
10339
- * that surfaces the new key material.
10340
- * @param material
10387
+ * Callback being invoked after a key has been ratcheted.
10388
+ * Can happen when:
10389
+ * - A decryption failure occurs and the key is auto-ratcheted
10390
+ * - A ratchet request is sent (see {@link ratchetKey()})
10391
+ * @param ratchetResult Contains the ratcheted chain key (exportable to other participants) and the derived new key material.
10392
+ * @param participantId
10341
10393
  * @param keyIndex
10342
10394
  */
10343
- this.onKeyRatcheted = (material, keyIndex) => {
10395
+ this.onKeyRatcheted = (ratchetResult, participantId, keyIndex) => {
10344
10396
  livekitLogger.debug('key ratcheted event received', {
10345
- material,
10397
+ ratchetResult,
10398
+ participantId,
10346
10399
  keyIndex
10347
10400
  });
10348
10401
  };
@@ -10577,6 +10630,15 @@ var RoomEvent;
10577
10630
  * args: ([[ConnectionState]])
10578
10631
  */
10579
10632
  RoomEvent["ConnectionStateChanged"] = "connectionStateChanged";
10633
+ /**
10634
+ * When participant has been moved to a different room by the service request.
10635
+ * The behavior looks like the participant has been disconnected and reconnected to a different room
10636
+ * seamlessly without connection state transition.
10637
+ * A new token will be provided for reconnecting to the new room if needed.
10638
+ *
10639
+ * args: ([[room: string, token: string]])
10640
+ */
10641
+ RoomEvent["Moved"] = "moved";
10580
10642
  /**
10581
10643
  * When input or output devices on the machine have changed.
10582
10644
  */
@@ -10701,6 +10763,12 @@ var RoomEvent;
10701
10763
  * args: (changedAttributes: [[Record<string, string]], participant: [[Participant]])
10702
10764
  */
10703
10765
  RoomEvent["ParticipantAttributesChanged"] = "participantAttributesChanged";
10766
+ /**
10767
+ * Emitted when the participant's state changes to ACTIVE and is ready to send/receive data messages
10768
+ *
10769
+ * args: (participant: [[Participant]])
10770
+ */
10771
+ RoomEvent["ParticipantActive"] = "participantActive";
10704
10772
  /**
10705
10773
  * Room metadata is a simple way for app-specific state to be pushed to
10706
10774
  * all users.
@@ -10995,6 +11063,10 @@ var ParticipantEvent;
10995
11063
  ParticipantEvent["LocalTrackSubscribed"] = "localTrackSubscribed";
10996
11064
  /** only emitted on local participant */
10997
11065
  ParticipantEvent["ChatMessage"] = "chatMessage";
11066
+ /**
11067
+ * Emitted when the participant's state changes to ACTIVE and is ready to send/receive data messages
11068
+ */
11069
+ ParticipantEvent["Active"] = "active";
10998
11070
  })(ParticipantEvent || (ParticipantEvent = {}));
10999
11071
  /** @internal */
11000
11072
  var EngineEvent;
@@ -11028,6 +11100,7 @@ var EngineEvent;
11028
11100
  EngineEvent["Offline"] = "offline";
11029
11101
  EngineEvent["SignalRequestResponse"] = "signalRequestResponse";
11030
11102
  EngineEvent["SignalConnected"] = "signalConnected";
11103
+ EngineEvent["RoomMoved"] = "roomMoved";
11031
11104
  })(EngineEvent || (EngineEvent = {}));
11032
11105
  var TrackEvent;
11033
11106
  (function (TrackEvent) {
@@ -11186,10 +11259,10 @@ function getOSVersion(ua) {
11186
11259
  return ua.includes('mac os') ? getMatch(/\(.+?(\d+_\d+(:?_\d+)?)/, ua, 1).replace(/_/g, '.') : undefined;
11187
11260
  }
11188
11261
 
11189
- var version$1 = "2.11.4";
11262
+ var version$1 = "2.13.0";
11190
11263
 
11191
11264
  const version = version$1;
11192
- const protocolVersion = 15;
11265
+ const protocolVersion = 16;
11193
11266
 
11194
11267
  /**
11195
11268
  * Timers that can be overridden with platform specific implementations
@@ -12547,7 +12620,7 @@ class E2EEManager extends eventsExports.EventEmitter {
12547
12620
  }
12548
12621
  break;
12549
12622
  case 'ratchetKey':
12550
- this.keyProvider.emit(KeyProviderEvent.KeyRatcheted, data.material, data.keyIndex);
12623
+ this.keyProvider.emit(KeyProviderEvent.KeyRatcheted, data.ratchetResult, data.participantIdentity, data.keyIndex);
12551
12624
  break;
12552
12625
  }
12553
12626
  };
@@ -13540,6 +13613,13 @@ class SignalClient {
13540
13613
  if (this.onLocalTrackSubscribed) {
13541
13614
  this.onLocalTrackSubscribed(msg.value.trackSid);
13542
13615
  }
13616
+ } else if (msg.case === 'roomMoved') {
13617
+ if (this.onTokenRefresh) {
13618
+ this.onTokenRefresh(msg.value.token);
13619
+ }
13620
+ if (this.onRoomMoved) {
13621
+ this.onRoomMoved(msg.value);
13622
+ }
13543
13623
  } else {
13544
13624
  this.log.debug('unsupported message', Object.assign(Object.assign({}, this.logContext), {
13545
13625
  msgCase: msg.case
@@ -17644,6 +17724,11 @@ class RTCEngine extends eventsExports.EventEmitter {
17644
17724
  this.client.onSubscribedQualityUpdate = update => {
17645
17725
  this.emit(EngineEvent.SubscribedQualityUpdate, update);
17646
17726
  };
17727
+ this.client.onRoomMoved = res => {
17728
+ var _a;
17729
+ this.participantSid = (_a = res.participant) === null || _a === void 0 ? void 0 : _a.sid;
17730
+ this.emit(EngineEvent.RoomMoved, res);
17731
+ };
17647
17732
  this.client.onClose = () => {
17648
17733
  this.handleDisconnect('signal', ReconnectReason.RR_SIGNAL_DISCONNECTED);
17649
17734
  };
@@ -17719,8 +17804,7 @@ class RTCEngine extends eventsExports.EventEmitter {
17719
17804
  }
17720
17805
  // create data channels
17721
17806
  this.lossyDC = this.pcManager.createPublisherDataChannel(lossyDataChannel, {
17722
- // will drop older packets that arrive
17723
- ordered: true,
17807
+ ordered: false,
17724
17808
  maxRetransmits: 0
17725
17809
  });
17726
17810
  this.reliableDC = this.pcManager.createPublisherDataChannel(reliableDataChannel, {
@@ -18797,8 +18881,9 @@ class RemoteAudioTrack extends RemoteTrack {
18797
18881
  super.attach(element);
18798
18882
  }
18799
18883
  if (this.sinkId && supportsSetSinkId(element)) {
18800
- /* @ts-ignore */
18801
- element.setSinkId(this.sinkId);
18884
+ element.setSinkId(this.sinkId).catch(e => {
18885
+ this.log.error('Failed to set sink id on remote audio track', e, this.logContext);
18886
+ });
18802
18887
  }
18803
18888
  if (this.audioContext && needsNewWebAudioConnection) {
18804
18889
  this.log.debug('using audio context mapping', this.logContext);
@@ -19500,16 +19585,17 @@ function createLocalTracks(options, loggerOptions) {
19500
19585
  }
19501
19586
  });
19502
19587
  }
19503
- // TODO if internal options don't have device Id specified, set it to 'default'
19504
19588
  if (internalOptions.audio === true || typeof internalOptions.audio === 'object' && !internalOptions.audio.deviceId) {
19505
19589
  internalOptions.audio = {
19506
19590
  deviceId: 'default'
19507
19591
  };
19508
19592
  }
19509
- if (internalOptions.video === true || typeof internalOptions.video === 'object' && !internalOptions.video.deviceId) {
19593
+ if (internalOptions.video === true) {
19510
19594
  internalOptions.video = {
19511
19595
  deviceId: 'default'
19512
19596
  };
19597
+ } else if (typeof internalOptions.video === 'object' && !internalOptions.video.deviceId) {
19598
+ internalOptions.video.deviceId = 'default';
19513
19599
  }
19514
19600
  const opts = mergeDefaultOptions(internalOptions, audioDefaults, videoDefaults);
19515
19601
  const constraints = constraintsForOptions(opts);
@@ -19666,6 +19752,10 @@ class Participant extends eventsExports.EventEmitter {
19666
19752
  var _a;
19667
19753
  return ((_a = this.permissions) === null || _a === void 0 ? void 0 : _a.agent) || this.kind === ParticipantInfo_Kind.AGENT;
19668
19754
  }
19755
+ get isActive() {
19756
+ var _a;
19757
+ return ((_a = this.participantInfo) === null || _a === void 0 ? void 0 : _a.state) === ParticipantInfo_State.ACTIVE;
19758
+ }
19669
19759
  get kind() {
19670
19760
  return this._kind;
19671
19761
  }
@@ -19721,6 +19811,25 @@ class Participant extends eventsExports.EventEmitter {
19721
19811
  }
19722
19812
  }
19723
19813
  }
19814
+ /**
19815
+ * Waits until the participant is active and ready to receive data messages
19816
+ * @returns a promise that resolves when the participant is active
19817
+ */
19818
+ waitUntilActive() {
19819
+ if (this.isActive) {
19820
+ return Promise.resolve();
19821
+ }
19822
+ if (this.activeFuture) {
19823
+ return this.activeFuture.promise;
19824
+ }
19825
+ this.activeFuture = new Future();
19826
+ this.once(ParticipantEvent.Active, () => {
19827
+ var _a, _b;
19828
+ (_b = (_a = this.activeFuture) === null || _a === void 0 ? void 0 : _a.resolve) === null || _b === void 0 ? void 0 : _b.call(_a);
19829
+ this.activeFuture = undefined;
19830
+ });
19831
+ return this.activeFuture.promise;
19832
+ }
19724
19833
  get connectionQuality() {
19725
19834
  return this._connectionQuality;
19726
19835
  }
@@ -19750,6 +19859,7 @@ class Participant extends eventsExports.EventEmitter {
19750
19859
  }
19751
19860
  /** @internal */
19752
19861
  updateInfo(info) {
19862
+ var _a;
19753
19863
  // it's possible the update could be applied out of order due to await
19754
19864
  // during reconnect sequences. when that happens, it's possible for server
19755
19865
  // to have sent more recent version of participant info while JS is waiting
@@ -19764,14 +19874,14 @@ class Participant extends eventsExports.EventEmitter {
19764
19874
  this._setName(info.name);
19765
19875
  this._setMetadata(info.metadata);
19766
19876
  this._setAttributes(info.attributes);
19877
+ if (info.state === ParticipantInfo_State.ACTIVE && ((_a = this.participantInfo) === null || _a === void 0 ? void 0 : _a.state) !== ParticipantInfo_State.ACTIVE) {
19878
+ this.emit(ParticipantEvent.Active);
19879
+ }
19767
19880
  if (info.permission) {
19768
19881
  this.setPermissions(info.permission);
19769
19882
  }
19770
19883
  // set this last so setMetadata can detect changes
19771
19884
  this.participantInfo = info;
19772
- this.log.trace('update participant info', Object.assign(Object.assign({}, this.logContext), {
19773
- info
19774
- }));
19775
19885
  return true;
19776
19886
  }
19777
19887
  /**
@@ -19835,6 +19945,16 @@ class Participant extends eventsExports.EventEmitter {
19835
19945
  this.emit(ParticipantEvent.ConnectionQualityChanged, this._connectionQuality);
19836
19946
  }
19837
19947
  }
19948
+ /**
19949
+ * @internal
19950
+ */
19951
+ setDisconnected() {
19952
+ var _a, _b;
19953
+ if (this.activeFuture) {
19954
+ (_b = (_a = this.activeFuture).reject) === null || _b === void 0 ? void 0 : _b.call(_a, new Error('Participant disconnected'));
19955
+ this.activeFuture = undefined;
19956
+ }
19957
+ }
19838
19958
  /**
19839
19959
  * @internal
19840
19960
  */
@@ -21361,6 +21481,7 @@ class LocalParticipant extends Participant {
21361
21481
  streamId,
21362
21482
  topic: info.topic,
21363
21483
  timestamp: numberToBigInt(Date.now()),
21484
+ attributes: info.attributes,
21364
21485
  contentHeader: {
21365
21486
  case: 'byteHeader',
21366
21487
  value: new DataStream_ByteHeader({
@@ -21600,11 +21721,6 @@ class LocalParticipant extends Participant {
21600
21721
  }
21601
21722
  /** @internal */
21602
21723
  updateInfo(info) {
21603
- if (info.sid !== this.sid) {
21604
- // drop updates that specify a wrong sid.
21605
- // the sid for local participant is only explicitly set on join and full reconnect
21606
- return false;
21607
- }
21608
21724
  if (!super.updateInfo(info)) {
21609
21725
  return false;
21610
21726
  }
@@ -23228,6 +23344,20 @@ class Room extends eventsExports.EventEmitter {
23228
23344
  }
23229
23345
  this.localParticipant.emit(ParticipantEvent.LocalTrackSubscribed, trackPublication);
23230
23346
  this.emitWhenConnected(RoomEvent.LocalTrackSubscribed, trackPublication, this.localParticipant);
23347
+ }).on(EngineEvent.RoomMoved, roomMoved => {
23348
+ this.log.debug('room moved', roomMoved);
23349
+ if (roomMoved.room) {
23350
+ this.handleRoomUpdate(roomMoved.room);
23351
+ }
23352
+ this.remoteParticipants.forEach((participant, identity) => {
23353
+ this.handleParticipantDisconnected(identity, participant);
23354
+ });
23355
+ this.emit(RoomEvent.Moved, roomMoved.room.name, roomMoved.token);
23356
+ if (roomMoved.participant) {
23357
+ this.handleParticipantUpdates([roomMoved.participant, ...roomMoved.otherParticipants]);
23358
+ } else {
23359
+ this.handleParticipantUpdates(roomMoved.otherParticipants);
23360
+ }
23231
23361
  });
23232
23362
  if (this.localParticipant) {
23233
23363
  this.localParticipant.setupEngine(this.engine);
@@ -23656,6 +23786,7 @@ class Room extends eventsExports.EventEmitter {
23656
23786
  participant.unpublishTrack(publication.trackSid, true);
23657
23787
  });
23658
23788
  this.emit(RoomEvent.ParticipantDisconnected, participant);
23789
+ participant.setDisconnected();
23659
23790
  (_a = this.localParticipant) === null || _a === void 0 ? void 0 : _a.handleParticipantDisconnected(participant.identity);
23660
23791
  }
23661
23792
  handleStreamHeader(streamHeader, participantIdentity) {
@@ -23862,6 +23993,8 @@ class Room extends eventsExports.EventEmitter {
23862
23993
  this.emit(RoomEvent.TrackSubscriptionFailed, trackSid, participant, error);
23863
23994
  }).on(ParticipantEvent.TrackSubscriptionPermissionChanged, (pub, status) => {
23864
23995
  this.emitWhenConnected(RoomEvent.TrackSubscriptionPermissionChanged, pub, status, participant);
23996
+ }).on(ParticipantEvent.Active, () => {
23997
+ this.emitWhenConnected(RoomEvent.ParticipantActive, participant);
23865
23998
  });
23866
23999
  // update info at the end after callbacks have been set up
23867
24000
  if (info) {