livekit-client 2.3.1 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) 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 +14 -7
  4. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  5. package/dist/livekit-client.esm.mjs +325 -175
  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 +5 -2
  10. package/dist/src/api/SignalClient.d.ts.map +1 -1
  11. package/dist/src/connectionHelper/ConnectionCheck.d.ts.map +1 -1
  12. package/dist/src/connectionHelper/checks/Checker.d.ts.map +1 -1
  13. package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
  14. package/dist/src/e2ee/KeyProvider.d.ts.map +1 -1
  15. package/dist/src/e2ee/errors.d.ts +2 -1
  16. package/dist/src/e2ee/errors.d.ts.map +1 -1
  17. package/dist/src/e2ee/index.d.ts +1 -0
  18. package/dist/src/e2ee/index.d.ts.map +1 -1
  19. package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
  20. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts.map +1 -1
  21. package/dist/src/logger.d.ts.map +1 -1
  22. package/dist/src/room/PCTransport.d.ts +1 -2
  23. package/dist/src/room/PCTransport.d.ts.map +1 -1
  24. package/dist/src/room/RTCEngine.d.ts +2 -1
  25. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  26. package/dist/src/room/Room.d.ts +1 -0
  27. package/dist/src/room/Room.d.ts.map +1 -1
  28. package/dist/src/room/errors.d.ts +5 -0
  29. package/dist/src/room/errors.d.ts.map +1 -1
  30. package/dist/src/room/events.d.ts +15 -2
  31. package/dist/src/room/events.d.ts.map +1 -1
  32. package/dist/src/room/participant/LocalParticipant.d.ts +14 -6
  33. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  34. package/dist/src/room/participant/Participant.d.ts +8 -0
  35. package/dist/src/room/participant/Participant.d.ts.map +1 -1
  36. package/dist/src/room/timers.d.ts +4 -4
  37. package/dist/src/room/timers.d.ts.map +1 -1
  38. package/dist/src/room/track/RemoteTrackPublication.d.ts.map +1 -1
  39. package/dist/src/room/track/Track.d.ts.map +1 -1
  40. package/dist/src/room/track/TrackPublication.d.ts.map +1 -1
  41. package/dist/src/room/track/utils.d.ts +1 -0
  42. package/dist/src/room/track/utils.d.ts.map +1 -1
  43. package/dist/ts4.2/src/api/SignalClient.d.ts +5 -2
  44. package/dist/ts4.2/src/e2ee/errors.d.ts +2 -1
  45. package/dist/ts4.2/src/e2ee/index.d.ts +1 -0
  46. package/dist/ts4.2/src/room/PCTransport.d.ts +1 -2
  47. package/dist/ts4.2/src/room/RTCEngine.d.ts +2 -1
  48. package/dist/ts4.2/src/room/Room.d.ts +1 -0
  49. package/dist/ts4.2/src/room/errors.d.ts +5 -0
  50. package/dist/ts4.2/src/room/events.d.ts +15 -2
  51. package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +14 -6
  52. package/dist/ts4.2/src/room/participant/Participant.d.ts +8 -0
  53. package/dist/ts4.2/src/room/timers.d.ts +4 -4
  54. package/dist/ts4.2/src/room/track/utils.d.ts +1 -0
  55. package/package.json +12 -12
  56. package/src/api/SignalClient.ts +24 -2
  57. package/src/e2ee/errors.ts +8 -1
  58. package/src/e2ee/index.ts +1 -0
  59. package/src/e2ee/worker/FrameCryptor.ts +18 -4
  60. package/src/e2ee/worker/e2ee.worker.ts +5 -1
  61. package/src/logger.ts +4 -3
  62. package/src/room/DeviceManager.ts +1 -1
  63. package/src/room/RTCEngine.ts +3 -0
  64. package/src/room/Room.ts +11 -3
  65. package/src/room/errors.ts +11 -0
  66. package/src/room/events.ts +15 -0
  67. package/src/room/participant/LocalParticipant.ts +102 -10
  68. package/src/room/participant/Participant.ts +23 -0
  69. package/src/room/track/Track.ts +1 -1
  70. package/src/room/track/utils.test.ts +35 -1
  71. package/src/room/track/utils.ts +22 -0
@@ -3782,6 +3782,15 @@ const ParticipantInfo = /*@__PURE__*/proto3.makeMessageType("livekit.Participant
3782
3782
  name: "kind",
3783
3783
  kind: "enum",
3784
3784
  T: proto3.getEnumType(ParticipantInfo_Kind)
3785
+ }, {
3786
+ no: 15,
3787
+ name: "attributes",
3788
+ kind: "map",
3789
+ K: 9 /* ScalarType.STRING */,
3790
+ V: {
3791
+ kind: "scalar",
3792
+ T: 9 /* ScalarType.STRING */
3793
+ }
3785
3794
  }]);
3786
3795
 
3787
3796
  /**
@@ -4161,7 +4170,7 @@ const SipDTMF = /*@__PURE__*/proto3.makeMessageType("livekit.SipDTMF", () => [{
4161
4170
  */
4162
4171
  const Transcription = /*@__PURE__*/proto3.makeMessageType("livekit.Transcription", () => [{
4163
4172
  no: 2,
4164
- name: "participant_identity",
4173
+ name: "transcribed_participant_identity",
4165
4174
  kind: "scalar",
4166
4175
  T: 9 /* ScalarType.STRING */
4167
4176
  }, {
@@ -4731,6 +4740,12 @@ const SignalResponse = /*@__PURE__*/proto3.makeMessageType("livekit.SignalRespon
4731
4740
  kind: "message",
4732
4741
  T: SubscriptionResponse,
4733
4742
  oneof: "message"
4743
+ }, {
4744
+ no: 22,
4745
+ name: "error_response",
4746
+ kind: "message",
4747
+ T: ErrorResponse,
4748
+ oneof: "message"
4734
4749
  }]);
4735
4750
 
4736
4751
  /**
@@ -5171,6 +5186,20 @@ const UpdateParticipantMetadata = /*@__PURE__*/proto3.makeMessageType("livekit.U
5171
5186
  name: "name",
5172
5187
  kind: "scalar",
5173
5188
  T: 9 /* ScalarType.STRING */
5189
+ }, {
5190
+ no: 3,
5191
+ name: "attributes",
5192
+ kind: "map",
5193
+ K: 9 /* ScalarType.STRING */,
5194
+ V: {
5195
+ kind: "scalar",
5196
+ T: 9 /* ScalarType.STRING */
5197
+ }
5198
+ }, {
5199
+ no: 4,
5200
+ name: "request_id",
5201
+ kind: "scalar",
5202
+ T: 13 /* ScalarType.UINT32 */
5174
5203
  }]);
5175
5204
 
5176
5205
  /**
@@ -5585,6 +5614,43 @@ const SubscriptionResponse = /*@__PURE__*/proto3.makeMessageType("livekit.Subscr
5585
5614
  T: proto3.getEnumType(SubscriptionError)
5586
5615
  }]);
5587
5616
 
5617
+ /**
5618
+ * @generated from message livekit.ErrorResponse
5619
+ */
5620
+ const ErrorResponse = /*@__PURE__*/proto3.makeMessageType("livekit.ErrorResponse", () => [{
5621
+ no: 1,
5622
+ name: "request_id",
5623
+ kind: "scalar",
5624
+ T: 13 /* ScalarType.UINT32 */
5625
+ }, {
5626
+ no: 2,
5627
+ name: "reason",
5628
+ kind: "enum",
5629
+ T: proto3.getEnumType(ErrorResponse_Reason)
5630
+ }, {
5631
+ no: 3,
5632
+ name: "message",
5633
+ kind: "scalar",
5634
+ T: 9 /* ScalarType.STRING */
5635
+ }]);
5636
+
5637
+ /**
5638
+ * @generated from enum livekit.ErrorResponse.Reason
5639
+ */
5640
+ const ErrorResponse_Reason = /*@__PURE__*/proto3.makeEnum("livekit.ErrorResponse.Reason", [{
5641
+ no: 0,
5642
+ name: "UNKNOWN"
5643
+ }, {
5644
+ no: 1,
5645
+ name: "NOT_FOUND"
5646
+ }, {
5647
+ no: 2,
5648
+ name: "NOT_ALLOWED"
5649
+ }, {
5650
+ no: 3,
5651
+ name: "INVALID_ARGUMENT"
5652
+ }]);
5653
+
5588
5654
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
5589
5655
 
5590
5656
  function getDefaultExportFromCjs (x) {
@@ -5945,9 +6011,10 @@ function getLogger(name) {
5945
6011
  function setLogLevel(level, loggerName) {
5946
6012
  if (loggerName) {
5947
6013
  loglevelExports.getLogger(loggerName).setLevel(level);
5948
- }
5949
- for (const logger of livekitLoggers) {
5950
- logger.setLevel(level);
6014
+ } else {
6015
+ for (const logger of livekitLoggers) {
6016
+ logger.setLevel(level);
6017
+ }
5951
6018
  }
5952
6019
  }
5953
6020
  /**
@@ -6571,6 +6638,19 @@ function detectBrowser(window) {
6571
6638
  const {
6572
6639
  navigator
6573
6640
  } = window;
6641
+
6642
+ // Prefer navigator.userAgentData.
6643
+ if (navigator.userAgentData && navigator.userAgentData.brands) {
6644
+ const chromium = navigator.userAgentData.brands.find(brand => {
6645
+ return brand.brand === 'Chromium';
6646
+ });
6647
+ if (chromium) {
6648
+ return {
6649
+ browser: 'chrome',
6650
+ version: parseInt(chromium.version, 10)
6651
+ };
6652
+ }
6653
+ }
6574
6654
  if (navigator.mozGetUserMedia) {
6575
6655
  // Firefox.
6576
6656
  result.browser = 'firefox';
@@ -6846,51 +6926,6 @@ function shimGetUserMedia$2(window, browserDetails) {
6846
6926
  }
6847
6927
  }
6848
6928
 
6849
- /*
6850
- * Copyright (c) 2018 The adapter.js project authors. All Rights Reserved.
6851
- *
6852
- * Use of this source code is governed by a BSD-style license
6853
- * that can be found in the LICENSE file in the root of the source
6854
- * tree.
6855
- */
6856
- /* eslint-env node */
6857
-
6858
- function shimGetDisplayMedia$1(window, getSourceId) {
6859
- if (window.navigator.mediaDevices && 'getDisplayMedia' in window.navigator.mediaDevices) {
6860
- return;
6861
- }
6862
- if (!window.navigator.mediaDevices) {
6863
- return;
6864
- }
6865
- // getSourceId is a function that returns a promise resolving with
6866
- // the sourceId of the screen/window/tab to be shared.
6867
- if (typeof getSourceId !== 'function') {
6868
- console.error('shimGetDisplayMedia: getSourceId argument is not ' + 'a function');
6869
- return;
6870
- }
6871
- window.navigator.mediaDevices.getDisplayMedia = function getDisplayMedia(constraints) {
6872
- return getSourceId(constraints).then(sourceId => {
6873
- const widthSpecified = constraints.video && constraints.video.width;
6874
- const heightSpecified = constraints.video && constraints.video.height;
6875
- const frameRateSpecified = constraints.video && constraints.video.frameRate;
6876
- constraints.video = {
6877
- mandatory: {
6878
- chromeMediaSource: 'desktop',
6879
- chromeMediaSourceId: sourceId,
6880
- maxFrameRate: frameRateSpecified || 3
6881
- }
6882
- };
6883
- if (widthSpecified) {
6884
- constraints.video.mandatory.maxWidth = widthSpecified;
6885
- }
6886
- if (heightSpecified) {
6887
- constraints.video.mandatory.maxHeight = heightSpecified;
6888
- }
6889
- return window.navigator.mediaDevices.getUserMedia(constraints);
6890
- });
6891
- };
6892
- }
6893
-
6894
6929
  /*
6895
6930
  * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
6896
6931
  *
@@ -7065,64 +7100,6 @@ function shimGetSendersWithDtmf(window) {
7065
7100
  });
7066
7101
  }
7067
7102
  }
7068
- function shimGetStats(window) {
7069
- if (!window.RTCPeerConnection) {
7070
- return;
7071
- }
7072
- const origGetStats = window.RTCPeerConnection.prototype.getStats;
7073
- window.RTCPeerConnection.prototype.getStats = function getStats() {
7074
- const [selector, onSucc, onErr] = arguments;
7075
-
7076
- // If selector is a function then we are in the old style stats so just
7077
- // pass back the original getStats format to avoid breaking old users.
7078
- if (arguments.length > 0 && typeof selector === 'function') {
7079
- return origGetStats.apply(this, arguments);
7080
- }
7081
-
7082
- // When spec-style getStats is supported, return those when called with
7083
- // either no arguments or the selector argument is null.
7084
- if (origGetStats.length === 0 && (arguments.length === 0 || typeof selector !== 'function')) {
7085
- return origGetStats.apply(this, []);
7086
- }
7087
- const fixChromeStats_ = function (response) {
7088
- const standardReport = {};
7089
- const reports = response.result();
7090
- reports.forEach(report => {
7091
- const standardStats = {
7092
- id: report.id,
7093
- timestamp: report.timestamp,
7094
- type: {
7095
- localcandidate: 'local-candidate',
7096
- remotecandidate: 'remote-candidate'
7097
- }[report.type] || report.type
7098
- };
7099
- report.names().forEach(name => {
7100
- standardStats[name] = report.stat(name);
7101
- });
7102
- standardReport[standardStats.id] = standardStats;
7103
- });
7104
- return standardReport;
7105
- };
7106
-
7107
- // shim getStats with maplike support
7108
- const makeMapStats = function (stats) {
7109
- return new Map(Object.keys(stats).map(key => [key, stats[key]]));
7110
- };
7111
- if (arguments.length >= 2) {
7112
- const successCallbackWrapper_ = function (response) {
7113
- onSucc(makeMapStats(fixChromeStats_(response)));
7114
- };
7115
- return origGetStats.apply(this, [successCallbackWrapper_, selector]);
7116
- }
7117
-
7118
- // promise-support
7119
- return new Promise((resolve, reject) => {
7120
- origGetStats.apply(this, [function (response) {
7121
- resolve(makeMapStats(fixChromeStats_(response)));
7122
- }, reject]);
7123
- }).then(onSucc, onErr);
7124
- };
7125
- }
7126
7103
  function shimSenderReceiverGetStats(window) {
7127
7104
  if (!(typeof window === 'object' && window.RTCPeerConnection && window.RTCRtpSender && window.RTCRtpReceiver)) {
7128
7105
  return;
@@ -7506,9 +7483,7 @@ var chromeShim = /*#__PURE__*/Object.freeze({
7506
7483
  fixNegotiationNeeded: fixNegotiationNeeded,
7507
7484
  shimAddTrackRemoveTrack: shimAddTrackRemoveTrack,
7508
7485
  shimAddTrackRemoveTrackWithNative: shimAddTrackRemoveTrackWithNative,
7509
- shimGetDisplayMedia: shimGetDisplayMedia$1,
7510
7486
  shimGetSendersWithDtmf: shimGetSendersWithDtmf,
7511
- shimGetStats: shimGetStats,
7512
7487
  shimGetUserMedia: shimGetUserMedia$2,
7513
7488
  shimMediaStream: shimMediaStream,
7514
7489
  shimOnTrack: shimOnTrack$1,
@@ -9451,7 +9426,6 @@ function adapterFactory() {
9451
9426
  shimOnTrack$1(window);
9452
9427
  shimAddTrackRemoveTrack(window, browserDetails);
9453
9428
  shimGetSendersWithDtmf(window);
9454
- shimGetStats(window);
9455
9429
  shimSenderReceiverGetStats(window);
9456
9430
  fixNegotiationNeeded(window, browserDetails);
9457
9431
  shimRTCIceCandidate(window);
@@ -9843,6 +9817,13 @@ class PublishDataError extends LivekitError {
9843
9817
  super(13, message !== null && message !== void 0 ? message : 'unable to publish data');
9844
9818
  }
9845
9819
  }
9820
+ class SignalRequestError extends LivekitError {
9821
+ constructor(message) {
9822
+ let reason = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ErrorResponse_Reason.UNKNOWN;
9823
+ super(15, message);
9824
+ this.reason = reason;
9825
+ }
9826
+ }
9846
9827
  var MediaDeviceFailure;
9847
9828
  (function (MediaDeviceFailure) {
9848
9829
  // user rejected permissions
@@ -9871,6 +9852,22 @@ var MediaDeviceFailure;
9871
9852
  MediaDeviceFailure.getFailure = getFailure;
9872
9853
  })(MediaDeviceFailure || (MediaDeviceFailure = {}));
9873
9854
 
9855
+ var CryptorErrorReason;
9856
+ (function (CryptorErrorReason) {
9857
+ CryptorErrorReason[CryptorErrorReason["InvalidKey"] = 0] = "InvalidKey";
9858
+ CryptorErrorReason[CryptorErrorReason["MissingKey"] = 1] = "MissingKey";
9859
+ CryptorErrorReason[CryptorErrorReason["InternalError"] = 2] = "InternalError";
9860
+ })(CryptorErrorReason || (CryptorErrorReason = {}));
9861
+ class CryptorError extends LivekitError {
9862
+ constructor(message) {
9863
+ let reason = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : CryptorErrorReason.InternalError;
9864
+ let participantIdentity = arguments.length > 2 ? arguments[2] : undefined;
9865
+ super(40, message);
9866
+ this.reason = reason;
9867
+ this.participantIdentity = participantIdentity;
9868
+ }
9869
+ }
9870
+
9874
9871
  /**
9875
9872
  * Events are the primary way LiveKit notifies your application of changes.
9876
9873
  *
@@ -10036,6 +10033,12 @@ var RoomEvent;
10036
10033
  *
10037
10034
  */
10038
10035
  RoomEvent["ParticipantNameChanged"] = "participantNameChanged";
10036
+ /**
10037
+ * Participant attributes is an app-specific key value state to be pushed to
10038
+ * all users.
10039
+ * When a participant's attributes changed, this event will be emitted with the changed attributes and the participant
10040
+ */
10041
+ RoomEvent["ParticipantAttributesChanged"] = "participantAttributesChanged";
10039
10042
  /**
10040
10043
  * Room metadata is a simple way for app-specific state to be pushed to
10041
10044
  * all users.
@@ -10308,6 +10311,12 @@ var ParticipantEvent;
10308
10311
  ParticipantEvent["ParticipantPermissionsChanged"] = "participantPermissionsChanged";
10309
10312
  /** @internal */
10310
10313
  ParticipantEvent["PCTrackAdded"] = "pcTrackAdded";
10314
+ /**
10315
+ * Participant attributes is an app-specific key value state to be pushed to
10316
+ * all users.
10317
+ * When a participant's attributes changed, this event will be emitted with the changed attributes
10318
+ */
10319
+ ParticipantEvent["AttributesChanged"] = "attributesChanged";
10311
10320
  })(ParticipantEvent || (ParticipantEvent = {}));
10312
10321
  /** @internal */
10313
10322
  var EngineEvent;
@@ -10338,6 +10347,7 @@ var EngineEvent;
10338
10347
  EngineEvent["SubscribedQualityUpdate"] = "subscribedQualityUpdate";
10339
10348
  EngineEvent["LocalTrackUnpublished"] = "localTrackUnpublished";
10340
10349
  EngineEvent["Offline"] = "offline";
10350
+ EngineEvent["SignalRequestError"] = "signalRequestError";
10341
10351
  })(EngineEvent || (EngineEvent = {}));
10342
10352
  var TrackEvent;
10343
10353
  (function (TrackEvent) {
@@ -10529,7 +10539,7 @@ function getOSVersion(ua) {
10529
10539
  return ua.includes('mac os') ? getMatch(/\(.+?(\d+_\d+(:?_\d+)?)/, ua, 1).replace(/_/g, '.') : undefined;
10530
10540
  }
10531
10541
 
10532
- var version$1 = "2.3.1";
10542
+ var version$1 = "2.4.0";
10533
10543
 
10534
10544
  const version = version$1;
10535
10545
  const protocolVersion = 13;
@@ -10734,7 +10744,7 @@ class Track extends eventsExports.EventEmitter {
10734
10744
  if (this.kind === Track.Kind.Video) {
10735
10745
  elementType = 'video';
10736
10746
  }
10737
- if (this.attachedElements.length === 0 && Track.Kind.Video) {
10747
+ if (this.attachedElements.length === 0 && this.kind === Track.Kind.Video) {
10738
10748
  this.addAppVisibilityListener();
10739
10749
  }
10740
10750
  if (!element) {
@@ -11236,6 +11246,23 @@ function getLogContextFromTrack(track) {
11236
11246
  function supportsSynchronizationSources() {
11237
11247
  return typeof RTCRtpReceiver !== 'undefined' && 'getSynchronizationSources' in RTCRtpReceiver;
11238
11248
  }
11249
+ function diffAttributes(oldValues, newValues) {
11250
+ var _a;
11251
+ if (oldValues === undefined) {
11252
+ oldValues = {};
11253
+ }
11254
+ if (newValues === undefined) {
11255
+ newValues = {};
11256
+ }
11257
+ const allKeys = [...Object.keys(newValues), ...Object.keys(oldValues)];
11258
+ const diff = {};
11259
+ for (const key of allKeys) {
11260
+ if (oldValues[key] !== newValues[key]) {
11261
+ diff[key] = (_a = newValues[key]) !== null && _a !== void 0 ? _a : '';
11262
+ }
11263
+ }
11264
+ return diff;
11265
+ }
11239
11266
 
11240
11267
  const separator = '|';
11241
11268
  const ddExtensionURI = 'https://aomediacodec.github.io/av1-rtp-spec/#dependency-descriptor-rtp-header-extension';
@@ -11691,7 +11718,7 @@ class DeviceManager {
11691
11718
  if (requestPermissions &&
11692
11719
  // for safari we need to skip this check, as otherwise it will re-acquire user media and fail on iOS https://bugs.webkit.org/show_bug.cgi?id=179363
11693
11720
  !(isSafari() && _this.hasDeviceInUse(kind))) {
11694
- const isDummyDeviceOrEmpty = devices.length === 0 || devices.some(device => {
11721
+ const isDummyDeviceOrEmpty = devices.filter(d => d.kind === kind).length === 0 || devices.some(device => {
11695
11722
  const noLabel = device.label === '';
11696
11723
  const isRelevant = kind ? device.kind === kind : true;
11697
11724
  return noLabel && isRelevant;
@@ -12634,6 +12661,10 @@ class SignalClient {
12634
12661
  get isEstablishingConnection() {
12635
12662
  return this.state === SignalConnectionState.CONNECTING || this.state === SignalConnectionState.RECONNECTING;
12636
12663
  }
12664
+ getNextRequestId() {
12665
+ this._requestId += 1;
12666
+ return this._requestId;
12667
+ }
12637
12668
  constructor() {
12638
12669
  let useJSON = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
12639
12670
  let loggerOptions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
@@ -12642,6 +12673,7 @@ class SignalClient {
12642
12673
  this.rtt = 0;
12643
12674
  this.state = SignalConnectionState.DISCONNECTED;
12644
12675
  this.log = livekitLogger;
12676
+ this._requestId = 0;
12645
12677
  /** @internal */
12646
12678
  this.resetCallbacks = () => {
12647
12679
  this.onAnswer = undefined;
@@ -12912,13 +12944,23 @@ class SignalClient {
12912
12944
  value: req
12913
12945
  });
12914
12946
  }
12915
- sendUpdateLocalMetadata(metadata, name) {
12916
- return this.sendRequest({
12917
- case: 'updateMetadata',
12918
- value: new UpdateParticipantMetadata({
12919
- metadata,
12920
- name
12921
- })
12947
+ sendUpdateLocalMetadata(metadata_1, name_1) {
12948
+ return __awaiter(this, arguments, void 0, function (metadata, name) {
12949
+ var _this2 = this;
12950
+ let attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
12951
+ return function* () {
12952
+ const requestId = _this2.getNextRequestId();
12953
+ yield _this2.sendRequest({
12954
+ case: 'updateMetadata',
12955
+ value: new UpdateParticipantMetadata({
12956
+ requestId,
12957
+ metadata,
12958
+ name,
12959
+ attributes
12960
+ })
12961
+ });
12962
+ return requestId;
12963
+ }();
12922
12964
  });
12923
12965
  }
12924
12966
  sendUpdateTrackSettings(settings) {
@@ -12997,40 +13039,40 @@ class SignalClient {
12997
13039
  }
12998
13040
  sendRequest(message_1) {
12999
13041
  return __awaiter(this, arguments, void 0, function (message) {
13000
- var _this2 = this;
13042
+ var _this3 = this;
13001
13043
  let fromQueue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
13002
13044
  return function* () {
13003
13045
  // capture all requests while reconnecting and put them in a queue
13004
13046
  // unless the request originates from the queue, then don't enqueue again
13005
13047
  const canQueue = !fromQueue && !canPassThroughQueue(message);
13006
- if (canQueue && _this2.state === SignalConnectionState.RECONNECTING) {
13007
- _this2.queuedRequests.push(() => __awaiter(_this2, void 0, void 0, function* () {
13048
+ if (canQueue && _this3.state === SignalConnectionState.RECONNECTING) {
13049
+ _this3.queuedRequests.push(() => __awaiter(_this3, void 0, void 0, function* () {
13008
13050
  yield this.sendRequest(message, true);
13009
13051
  }));
13010
13052
  return;
13011
13053
  }
13012
13054
  // make sure previously queued requests are being sent first
13013
13055
  if (!fromQueue) {
13014
- yield _this2.requestQueue.flush();
13056
+ yield _this3.requestQueue.flush();
13015
13057
  }
13016
- if (_this2.signalLatency) {
13017
- yield sleep(_this2.signalLatency);
13058
+ if (_this3.signalLatency) {
13059
+ yield sleep(_this3.signalLatency);
13018
13060
  }
13019
- if (!_this2.ws || _this2.ws.readyState !== _this2.ws.OPEN) {
13020
- _this2.log.error("cannot send signal request before connected, type: ".concat(message === null || message === void 0 ? void 0 : message.case), _this2.logContext);
13061
+ if (!_this3.ws || _this3.ws.readyState !== _this3.ws.OPEN) {
13062
+ _this3.log.error("cannot send signal request before connected, type: ".concat(message === null || message === void 0 ? void 0 : message.case), _this3.logContext);
13021
13063
  return;
13022
13064
  }
13023
13065
  const req = new SignalRequest({
13024
13066
  message
13025
13067
  });
13026
13068
  try {
13027
- if (_this2.useJSON) {
13028
- _this2.ws.send(req.toJsonString());
13069
+ if (_this3.useJSON) {
13070
+ _this3.ws.send(req.toJsonString());
13029
13071
  } else {
13030
- _this2.ws.send(req.toBinary());
13072
+ _this3.ws.send(req.toBinary());
13031
13073
  }
13032
13074
  } catch (e) {
13033
- _this2.log.error('error sending signal message', Object.assign(Object.assign({}, _this2.logContext), {
13075
+ _this3.log.error('error sending signal message', Object.assign(Object.assign({}, _this3.logContext), {
13034
13076
  error: e
13035
13077
  }));
13036
13078
  }
@@ -13116,6 +13158,10 @@ class SignalClient {
13116
13158
  this.rtt = Date.now() - Number.parseInt(msg.value.lastPingTimestamp.toString());
13117
13159
  this.resetPingTimeout();
13118
13160
  pingHandled = true;
13161
+ } else if (msg.case === 'errorResponse') {
13162
+ if (this.onErrorResponse) {
13163
+ this.onErrorResponse(msg.value);
13164
+ }
13119
13165
  } else {
13120
13166
  this.log.debug('unsupported message', Object.assign(Object.assign({}, this.logContext), {
13121
13167
  msgCase: msg.case
@@ -15998,7 +16044,7 @@ class RTCEngine extends eventsExports.EventEmitter {
15998
16044
  this.maxJoinAttempts = 1;
15999
16045
  this.shouldFailNext = false;
16000
16046
  this.log = livekitLogger;
16001
- this.handleDataChannel = _b => __awaiter(this, [_b], void 0, function (_ref) {
16047
+ this.handleDataChannel = _a => __awaiter(this, [_a], void 0, function (_ref) {
16002
16048
  var _this = this;
16003
16049
  let {
16004
16050
  channel
@@ -16019,7 +16065,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16019
16065
  }();
16020
16066
  });
16021
16067
  this.handleDataMessage = message => __awaiter(this, void 0, void 0, function* () {
16022
- var _c, _d;
16068
+ var _a, _b;
16023
16069
  // make sure to respect incoming data message order by processing message events one after the other
16024
16070
  const unlock = yield this.dataProcessLock.lock();
16025
16071
  try {
@@ -16036,11 +16082,11 @@ class RTCEngine extends eventsExports.EventEmitter {
16036
16082
  return;
16037
16083
  }
16038
16084
  const dp = DataPacket.fromBinary(new Uint8Array(buffer));
16039
- if (((_c = dp.value) === null || _c === void 0 ? void 0 : _c.case) === 'speaker') {
16085
+ if (((_a = dp.value) === null || _a === void 0 ? void 0 : _a.case) === 'speaker') {
16040
16086
  // dispatch speaker updates
16041
16087
  this.emit(EngineEvent.ActiveSpeakersUpdate, dp.value.value.speakers);
16042
16088
  } else {
16043
- if (((_d = dp.value) === null || _d === void 0 ? void 0 : _d.case) === 'user') {
16089
+ if (((_b = dp.value) === null || _b === void 0 ? void 0 : _b.case) === 'user') {
16044
16090
  // compatibility
16045
16091
  applyUserDataCompat(dp, dp.value.value);
16046
16092
  }
@@ -16165,6 +16211,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16165
16211
  this.client.onSubscriptionPermissionUpdate = update => this.emit(EngineEvent.SubscriptionPermissionUpdate, update);
16166
16212
  this.client.onSpeakersChanged = update => this.emit(EngineEvent.SpeakersChanged, update);
16167
16213
  this.client.onStreamStateUpdate = update => this.emit(EngineEvent.StreamStateChanged, update);
16214
+ this.client.onErrorResponse = error => this.emit(EngineEvent.SignalRequestError, error);
16168
16215
  }
16169
16216
  /** @internal */
16170
16217
  get logContext() {
@@ -17973,6 +18020,10 @@ class Participant extends eventsExports.EventEmitter {
17973
18020
  get kind() {
17974
18021
  return this._kind;
17975
18022
  }
18023
+ /** participant attributes, similar to metadata, but as a key/value map */
18024
+ get attributes() {
18025
+ return Object.freeze(Object.assign({}, this._attributes));
18026
+ }
17976
18027
  /** @internal */
17977
18028
  constructor(sid, identity, name, metadata, loggerOptions) {
17978
18029
  let kind = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : ParticipantInfo_Kind.STANDARD;
@@ -17995,6 +18046,7 @@ class Participant extends eventsExports.EventEmitter {
17995
18046
  this.videoTrackPublications = new Map();
17996
18047
  this.trackPublications = new Map();
17997
18048
  this._kind = kind;
18049
+ this._attributes = {};
17998
18050
  }
17999
18051
  getTrackPublications() {
18000
18052
  return Array.from(this.trackPublications.values());
@@ -18062,6 +18114,7 @@ class Participant extends eventsExports.EventEmitter {
18062
18114
  this.sid = info.sid;
18063
18115
  this._setName(info.name);
18064
18116
  this._setMetadata(info.metadata);
18117
+ this._setAttributes(info.attributes);
18065
18118
  if (info.permission) {
18066
18119
  this.setPermissions(info.permission);
18067
18120
  }
@@ -18090,6 +18143,16 @@ class Participant extends eventsExports.EventEmitter {
18090
18143
  this.emit(ParticipantEvent.ParticipantNameChanged, name);
18091
18144
  }
18092
18145
  }
18146
+ /**
18147
+ * Updates metadata from server
18148
+ **/
18149
+ _setAttributes(attributes) {
18150
+ const diff = diffAttributes(attributes, this.attributes);
18151
+ this._attributes = attributes;
18152
+ if (Object.keys(diff).length > 0) {
18153
+ this.emit(ParticipantEvent.AttributesChanged, diff);
18154
+ }
18155
+ }
18093
18156
  /** @internal */
18094
18157
  setPermissions(permissions) {
18095
18158
  var _a, _b, _c, _d, _e;
@@ -18198,6 +18261,18 @@ class LocalParticipant extends Participant {
18198
18261
  this.reconnectFuture = undefined;
18199
18262
  }
18200
18263
  };
18264
+ this.handleSignalRequestError = error => {
18265
+ const {
18266
+ requestId,
18267
+ reason,
18268
+ message
18269
+ } = error;
18270
+ const failedRequest = this.pendingSignalRequests.get(requestId);
18271
+ if (failedRequest) {
18272
+ failedRequest.reject(new SignalRequestError(message, reason));
18273
+ this.pendingSignalRequests.delete(requestId);
18274
+ }
18275
+ };
18201
18276
  this.updateTrackSubscriptionPermissions = () => {
18202
18277
  this.log.debug('updating track subscription permissions', Object.assign(Object.assign({}, this.logContext), {
18203
18278
  allParticipantsAllowed: this.allParticipantsAllowedToSubscribe,
@@ -18339,6 +18414,7 @@ class LocalParticipant extends Participant {
18339
18414
  this.roomOptions = options;
18340
18415
  this.setupEngine(engine);
18341
18416
  this.activeDeviceMap = new Map();
18417
+ this.pendingSignalRequests = new Map();
18342
18418
  }
18343
18419
  get lastCameraError() {
18344
18420
  return this.cameraError;
@@ -18377,29 +18453,92 @@ class LocalParticipant extends Participant {
18377
18453
  pub.unmute();
18378
18454
  }
18379
18455
  });
18380
- this.engine.on(EngineEvent.Connected, this.handleReconnected).on(EngineEvent.SignalRestarted, this.handleReconnected).on(EngineEvent.SignalResumed, this.handleReconnected).on(EngineEvent.Restarting, this.handleReconnecting).on(EngineEvent.Resuming, this.handleReconnecting).on(EngineEvent.LocalTrackUnpublished, this.handleLocalTrackUnpublished).on(EngineEvent.SubscribedQualityUpdate, this.handleSubscribedQualityUpdate).on(EngineEvent.Disconnected, this.handleDisconnected);
18456
+ this.engine.on(EngineEvent.Connected, this.handleReconnected).on(EngineEvent.SignalRestarted, this.handleReconnected).on(EngineEvent.SignalResumed, this.handleReconnected).on(EngineEvent.Restarting, this.handleReconnecting).on(EngineEvent.Resuming, this.handleReconnecting).on(EngineEvent.LocalTrackUnpublished, this.handleLocalTrackUnpublished).on(EngineEvent.SubscribedQualityUpdate, this.handleSubscribedQualityUpdate).on(EngineEvent.Disconnected, this.handleDisconnected).on(EngineEvent.SignalRequestError, this.handleSignalRequestError);
18381
18457
  }
18382
18458
  /**
18383
18459
  * Sets and updates the metadata of the local participant.
18384
- * The change does not take immediate effect.
18385
- * If successful, a `ParticipantEvent.MetadataChanged` event will be emitted on the local participant.
18386
18460
  * Note: this requires `canUpdateOwnMetadata` permission.
18461
+ * method will throw if the user doesn't have the required permissions
18387
18462
  * @param metadata
18388
18463
  */
18389
18464
  setMetadata(metadata) {
18390
- var _a;
18391
- this.engine.client.sendUpdateLocalMetadata(metadata, (_a = this.name) !== null && _a !== void 0 ? _a : '');
18465
+ return __awaiter(this, void 0, void 0, function* () {
18466
+ yield this.requestMetadataUpdate({
18467
+ metadata
18468
+ });
18469
+ });
18392
18470
  }
18393
18471
  /**
18394
18472
  * Sets and updates the name of the local participant.
18395
- * The change does not take immediate effect.
18396
- * If successful, a `ParticipantEvent.ParticipantNameChanged` event will be emitted on the local participant.
18397
18473
  * Note: this requires `canUpdateOwnMetadata` permission.
18474
+ * method will throw if the user doesn't have the required permissions
18398
18475
  * @param metadata
18399
18476
  */
18400
18477
  setName(name) {
18401
- var _a;
18402
- this.engine.client.sendUpdateLocalMetadata((_a = this.metadata) !== null && _a !== void 0 ? _a : '', name);
18478
+ return __awaiter(this, void 0, void 0, function* () {
18479
+ yield this.requestMetadataUpdate({
18480
+ name
18481
+ });
18482
+ });
18483
+ }
18484
+ /**
18485
+ * Set or update participant attributes. It will make updates only to keys that
18486
+ * are present in `attributes`, and will not override others.
18487
+ * Note: this requires `canUpdateOwnMetadata` permission.
18488
+ * @param attributes attributes to update
18489
+ */
18490
+ setAttributes(attributes) {
18491
+ return __awaiter(this, void 0, void 0, function* () {
18492
+ yield this.requestMetadataUpdate({
18493
+ attributes
18494
+ });
18495
+ });
18496
+ }
18497
+ requestMetadataUpdate(_a) {
18498
+ return __awaiter(this, arguments, void 0, function (_ref) {
18499
+ var _this = this;
18500
+ let {
18501
+ metadata,
18502
+ name,
18503
+ attributes
18504
+ } = _ref;
18505
+ return function* () {
18506
+ return new Promise((resolve, reject) => __awaiter(_this, void 0, void 0, function* () {
18507
+ var _a, _b;
18508
+ try {
18509
+ let isRejected = false;
18510
+ const requestId = yield this.engine.client.sendUpdateLocalMetadata((_a = metadata !== null && metadata !== void 0 ? metadata : this.metadata) !== null && _a !== void 0 ? _a : '', (_b = name !== null && name !== void 0 ? name : this.name) !== null && _b !== void 0 ? _b : '', attributes);
18511
+ const startTime = performance.now();
18512
+ this.pendingSignalRequests.set(requestId, {
18513
+ resolve,
18514
+ reject: error => {
18515
+ reject(error);
18516
+ isRejected = true;
18517
+ },
18518
+ values: {
18519
+ name,
18520
+ metadata,
18521
+ attributes
18522
+ }
18523
+ });
18524
+ while (performance.now() - startTime < 5000 && !isRejected) {
18525
+ if ((!name || this.name === name) && (!metadata || this.metadata === metadata) && (!attributes || Object.entries(attributes).every(_ref2 => {
18526
+ let [key, value] = _ref2;
18527
+ return this.attributes[key] === value;
18528
+ }))) {
18529
+ this.pendingSignalRequests.delete(requestId);
18530
+ resolve();
18531
+ return;
18532
+ }
18533
+ yield sleep(50);
18534
+ }
18535
+ reject(new SignalRequestError('Request to update local metadata timed out'));
18536
+ } catch (e) {
18537
+ if (e instanceof Error) reject(e);
18538
+ }
18539
+ }));
18540
+ }();
18541
+ });
18403
18542
  }
18404
18543
  /**
18405
18544
  * Enable or disable a participant's camera track.
@@ -19038,6 +19177,13 @@ class LocalParticipant extends Participant {
19038
19177
  unpublishTrack(track, stopOnUnpublish) {
19039
19178
  return __awaiter(this, void 0, void 0, function* () {
19040
19179
  var _a, _b;
19180
+ if (track instanceof LocalTrack) {
19181
+ const publishPromise = this.pendingPublishPromises.get(track);
19182
+ if (publishPromise) {
19183
+ this.log.info('awaiting publish promise before attempting to unpublish', Object.assign(Object.assign({}, this.logContext), getLogContextFromTrack(track)));
19184
+ yield publishPromise;
19185
+ }
19186
+ }
19041
19187
  // look through all published tracks to find the right ones
19042
19188
  const publication = this.getPublicationForTrack(track);
19043
19189
  const pubLogContext = publication ? getLogContextFromTrack(publication) : undefined;
@@ -19120,11 +19266,11 @@ class LocalParticipant extends Participant {
19120
19266
  }
19121
19267
  republishAllTracks(options_1) {
19122
19268
  return __awaiter(this, arguments, void 0, function (options) {
19123
- var _this = this;
19269
+ var _this2 = this;
19124
19270
  let restartTracks = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
19125
19271
  return function* () {
19126
19272
  const localPubs = [];
19127
- _this.trackPublications.forEach(pub => {
19273
+ _this2.trackPublications.forEach(pub => {
19128
19274
  if (pub.track) {
19129
19275
  if (options) {
19130
19276
  pub.options = Object.assign(Object.assign({}, pub.options), options);
@@ -19132,7 +19278,7 @@ class LocalParticipant extends Participant {
19132
19278
  localPubs.push(pub);
19133
19279
  }
19134
19280
  });
19135
- yield Promise.all(localPubs.map(pub => __awaiter(_this, void 0, void 0, function* () {
19281
+ yield Promise.all(localPubs.map(pub => __awaiter(_this2, void 0, void 0, function* () {
19136
19282
  const track = pub.track;
19137
19283
  yield this.unpublishTrack(track, false);
19138
19284
  if (restartTracks && !track.isMuted && track.source !== Track.Source.ScreenShare && track.source !== Track.Source.ScreenShareAudio && (track instanceof LocalAudioTrack || track instanceof LocalVideoTrack) && !track.isUserProvided) {
@@ -19157,7 +19303,7 @@ class LocalParticipant extends Participant {
19157
19303
  */
19158
19304
  publishData(data_1) {
19159
19305
  return __awaiter(this, arguments, void 0, function (data) {
19160
- var _this2 = this;
19306
+ var _this3 = this;
19161
19307
  let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
19162
19308
  return function* () {
19163
19309
  const kind = options.reliable ? DataPacket_Kind.RELIABLE : DataPacket_Kind.LOSSY;
@@ -19168,14 +19314,14 @@ class LocalParticipant extends Participant {
19168
19314
  value: {
19169
19315
  case: 'user',
19170
19316
  value: new UserPacket({
19171
- participantIdentity: _this2.identity,
19317
+ participantIdentity: _this3.identity,
19172
19318
  payload: data,
19173
19319
  destinationIdentities,
19174
19320
  topic
19175
19321
  })
19176
19322
  }
19177
19323
  });
19178
- yield _this2.engine.sendDataPacket(packet, kind);
19324
+ yield _this3.engine.sendDataPacket(packet, kind);
19179
19325
  }();
19180
19326
  });
19181
19327
  }
@@ -19796,7 +19942,7 @@ class Room extends eventsExports.EventEmitter {
19796
19942
  this.bufferedEvents = [];
19797
19943
  this.isResuming = false;
19798
19944
  this.connect = (url, token, opts) => __awaiter(this, void 0, void 0, function* () {
19799
- var _c;
19945
+ var _a;
19800
19946
  if (!isBrowserSupported()) {
19801
19947
  if (isReactNative()) {
19802
19948
  throw Error("WebRTC isn't detected, have you called registerGlobals?");
@@ -19817,7 +19963,7 @@ class Room extends eventsExports.EventEmitter {
19817
19963
  return this.connectFuture.promise;
19818
19964
  }
19819
19965
  this.setAndEmitConnectionState(ConnectionState.Connecting);
19820
- if (((_c = this.regionUrlProvider) === null || _c === void 0 ? void 0 : _c.getServerUrl().toString()) !== url) {
19966
+ if (((_a = this.regionUrlProvider) === null || _a === void 0 ? void 0 : _a.getServerUrl().toString()) !== url) {
19821
19967
  this.regionUrl = undefined;
19822
19968
  this.regionUrlProvider = undefined;
19823
19969
  }
@@ -19837,7 +19983,7 @@ class Room extends eventsExports.EventEmitter {
19837
19983
  });
19838
19984
  }
19839
19985
  const connectFn = (resolve, reject, regionUrl) => __awaiter(this, void 0, void 0, function* () {
19840
- var _d;
19986
+ var _a;
19841
19987
  if (this.abortController) {
19842
19988
  this.abortController.abort();
19843
19989
  }
@@ -19854,7 +20000,7 @@ class Room extends eventsExports.EventEmitter {
19854
20000
  if (this.regionUrlProvider && e instanceof ConnectionError && e.reason !== 3 /* ConnectionErrorReason.Cancelled */ && e.reason !== 0 /* ConnectionErrorReason.NotAllowed */) {
19855
20001
  let nextUrl = null;
19856
20002
  try {
19857
- nextUrl = yield this.regionUrlProvider.getNextBestRegionUrl((_d = this.abortController) === null || _d === void 0 ? void 0 : _d.signal);
20003
+ nextUrl = yield this.regionUrlProvider.getNextBestRegionUrl((_a = this.abortController) === null || _a === void 0 ? void 0 : _a.signal);
19858
20004
  } catch (error) {
19859
20005
  if (error instanceof ConnectionError && (error.status === 401 || error.reason === 3 /* ConnectionErrorReason.Cancelled */)) {
19860
20006
  this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
@@ -19886,7 +20032,7 @@ class Room extends eventsExports.EventEmitter {
19886
20032
  return this.connectFuture.promise;
19887
20033
  });
19888
20034
  this.connectSignal = (url, token, engine, connectOptions, roomOptions, abortController) => __awaiter(this, void 0, void 0, function* () {
19889
- var _e, _f, _g;
20035
+ var _a, _b, _c;
19890
20036
  const joinResponse = yield engine.join(url, token, {
19891
20037
  autoSubscribe: connectOptions.autoSubscribe,
19892
20038
  adaptiveStream: typeof roomOptions.adaptiveStream === 'object' ? true : roomOptions.adaptiveStream,
@@ -19905,9 +20051,9 @@ class Room extends eventsExports.EventEmitter {
19905
20051
  let [key, value] = _ref;
19906
20052
  return "".concat(key, ": ").concat(value);
19907
20053
  }).join(', ')), {
19908
- room: (_e = joinResponse.room) === null || _e === void 0 ? void 0 : _e.name,
19909
- roomSid: (_f = joinResponse.room) === null || _f === void 0 ? void 0 : _f.sid,
19910
- identity: (_g = joinResponse.participant) === null || _g === void 0 ? void 0 : _g.identity
20054
+ room: (_a = joinResponse.room) === null || _a === void 0 ? void 0 : _a.name,
20055
+ roomSid: (_b = joinResponse.room) === null || _b === void 0 ? void 0 : _b.sid,
20056
+ identity: (_c = joinResponse.participant) === null || _c === void 0 ? void 0 : _c.identity
19911
20057
  });
19912
20058
  if (!joinResponse.serverVersion) {
19913
20059
  throw new UnsupportedServer('unknown server version');
@@ -19939,8 +20085,8 @@ class Room extends eventsExports.EventEmitter {
19939
20085
  }
19940
20086
  };
19941
20087
  this.attemptConnection = (url, token, opts, abortController) => __awaiter(this, void 0, void 0, function* () {
19942
- var _h, _j, _k;
19943
- if (this.state === ConnectionState.Reconnecting || this.isResuming || ((_h = this.engine) === null || _h === void 0 ? void 0 : _h.pendingReconnect)) {
20088
+ var _a, _b, _c;
20089
+ if (this.state === ConnectionState.Reconnecting || this.isResuming || ((_a = this.engine) === null || _a === void 0 ? void 0 : _a.pendingReconnect)) {
19944
20090
  this.log.info('Reconnection attempt replaced by new connection attempt', this.logContext);
19945
20091
  // make sure we close and recreate the existing engine in order to get rid of any potentially ongoing reconnection attempts
19946
20092
  this.recreateEngine();
@@ -19948,7 +20094,7 @@ class Room extends eventsExports.EventEmitter {
19948
20094
  // create engine if previously disconnected
19949
20095
  this.maybeCreateEngine();
19950
20096
  }
19951
- if ((_j = this.regionUrlProvider) === null || _j === void 0 ? void 0 : _j.isCloud()) {
20097
+ if ((_b = this.regionUrlProvider) === null || _b === void 0 ? void 0 : _b.isCloud()) {
19952
20098
  this.engine.setRegionUrlProvider(this.regionUrlProvider);
19953
20099
  }
19954
20100
  this.acquireAudioContext();
@@ -20001,7 +20147,7 @@ class Room extends eventsExports.EventEmitter {
20001
20147
  }
20002
20148
  if (isWeb()) {
20003
20149
  document.addEventListener('freeze', this.onPageLeave);
20004
- (_k = navigator.mediaDevices) === null || _k === void 0 ? void 0 : _k.addEventListener('devicechange', this.handleDeviceChange);
20150
+ (_c = navigator.mediaDevices) === null || _c === void 0 ? void 0 : _c.addEventListener('devicechange', this.handleDeviceChange);
20005
20151
  }
20006
20152
  this.setAndEmitConnectionState(ConnectionState.Connected);
20007
20153
  this.emit(RoomEvent.Connected);
@@ -20018,7 +20164,7 @@ class Room extends eventsExports.EventEmitter {
20018
20164
  var _this2 = this;
20019
20165
  let stopTracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
20020
20166
  return function* () {
20021
- var _l, _m, _o, _p;
20167
+ var _a, _b, _c, _d;
20022
20168
  const unlock = yield _this2.disconnectLock.lock();
20023
20169
  try {
20024
20170
  if (_this2.state === ConnectionState.Disconnected) {
@@ -20029,13 +20175,13 @@ class Room extends eventsExports.EventEmitter {
20029
20175
  if (_this2.state === ConnectionState.Connecting || _this2.state === ConnectionState.Reconnecting || _this2.isResuming) {
20030
20176
  // try aborting pending connection attempt
20031
20177
  _this2.log.warn('abort connection attempt', _this2.logContext);
20032
- (_l = _this2.abortController) === null || _l === void 0 ? void 0 : _l.abort();
20178
+ (_a = _this2.abortController) === null || _a === void 0 ? void 0 : _a.abort();
20033
20179
  // in case the abort controller didn't manage to cancel the connection attempt, reject the connect promise explicitly
20034
- (_o = (_m = _this2.connectFuture) === null || _m === void 0 ? void 0 : _m.reject) === null || _o === void 0 ? void 0 : _o.call(_m, new ConnectionError('Client initiated disconnect'));
20180
+ (_c = (_b = _this2.connectFuture) === null || _b === void 0 ? void 0 : _b.reject) === null || _c === void 0 ? void 0 : _c.call(_b, new ConnectionError('Client initiated disconnect'));
20035
20181
  _this2.connectFuture = undefined;
20036
20182
  }
20037
20183
  // send leave
20038
- if (!((_p = _this2.engine) === null || _p === void 0 ? void 0 : _p.client.isDisconnected)) {
20184
+ if (!((_d = _this2.engine) === null || _d === void 0 ? void 0 : _d.client.isDisconnected)) {
20039
20185
  yield _this2.engine.client.sendLeave();
20040
20186
  }
20041
20187
  // close engine (also closes client)
@@ -20177,7 +20323,7 @@ class Room extends eventsExports.EventEmitter {
20177
20323
  this.log.debug("fully reconnected to server", Object.assign(Object.assign({}, this.logContext), {
20178
20324
  region: joinResponse.serverRegion
20179
20325
  }));
20180
- } catch (_q) {
20326
+ } catch (_a) {
20181
20327
  // reconnection failed, handleDisconnect is being invoked already, just return here
20182
20328
  return;
20183
20329
  }
@@ -20245,6 +20391,10 @@ class Room extends eventsExports.EventEmitter {
20245
20391
  this.handleSpeakersChanged = speakerUpdates => {
20246
20392
  const lastSpeakers = new Map();
20247
20393
  this.activeSpeakers.forEach(p => {
20394
+ const remoteParticipant = this.remoteParticipants.get(p.identity);
20395
+ if (remoteParticipant && remoteParticipant.sid !== p.sid) {
20396
+ return;
20397
+ }
20248
20398
  lastSpeakers.set(p.sid, p);
20249
20399
  });
20250
20400
  speakerUpdates.forEach(speaker => {
@@ -20327,9 +20477,9 @@ class Room extends eventsExports.EventEmitter {
20327
20477
  participant === null || participant === void 0 ? void 0 : participant.emit(ParticipantEvent.SipDTMFReceived, dtmf);
20328
20478
  };
20329
20479
  this.bufferedSegments = new Map();
20330
- this.handleTranscription = (remoteParticipant, transcription) => {
20480
+ this.handleTranscription = (_remoteParticipant, transcription) => {
20331
20481
  // find the participant
20332
- const participant = transcription.participantIdentity === this.localParticipant.identity ? this.localParticipant : remoteParticipant;
20482
+ const participant = transcription.transcribedParticipantIdentity === this.localParticipant.identity ? this.localParticipant : this.getParticipantByIdentity(transcription.transcribedParticipantIdentity);
20333
20483
  const publication = participant === null || participant === void 0 ? void 0 : participant.trackPublications.get(transcription.trackId);
20334
20484
  const segments = extractTranscriptionSegments(transcription);
20335
20485
  publication === null || publication === void 0 ? void 0 : publication.emit(TrackEvent.TranscriptionReceived, segments);
@@ -20407,9 +20557,9 @@ class Room extends eventsExports.EventEmitter {
20407
20557
  (_a = processor === null || processor === void 0 ? void 0 : processor.onPublish) === null || _a === void 0 ? void 0 : _a.call(processor, this);
20408
20558
  };
20409
20559
  this.onLocalTrackPublished = pub => __awaiter(this, void 0, void 0, function* () {
20410
- var _r, _s, _t, _u, _v;
20411
- (_r = pub.track) === null || _r === void 0 ? void 0 : _r.on(TrackEvent.TrackProcessorUpdate, this.onTrackProcessorUpdate);
20412
- (_u = (_t = (_s = pub.track) === null || _s === void 0 ? void 0 : _s.getProcessor()) === null || _t === void 0 ? void 0 : _t.onPublish) === null || _u === void 0 ? void 0 : _u.call(_t, this);
20560
+ var _a, _b, _c, _d, _e;
20561
+ (_a = pub.track) === null || _a === void 0 ? void 0 : _a.on(TrackEvent.TrackProcessorUpdate, this.onTrackProcessorUpdate);
20562
+ (_d = (_c = (_b = pub.track) === null || _b === void 0 ? void 0 : _b.getProcessor()) === null || _c === void 0 ? void 0 : _c.onPublish) === null || _d === void 0 ? void 0 : _d.call(_c, this);
20413
20563
  this.emit(RoomEvent.LocalTrackPublished, pub, this.localParticipant);
20414
20564
  if (pub.track instanceof LocalAudioTrack) {
20415
20565
  const trackIsSilent = yield pub.track.checkForSilence();
@@ -20417,7 +20567,7 @@ class Room extends eventsExports.EventEmitter {
20417
20567
  this.emit(RoomEvent.LocalAudioSilenceDetected, pub);
20418
20568
  }
20419
20569
  }
20420
- const deviceId = yield (_v = pub.track) === null || _v === void 0 ? void 0 : _v.getDeviceId();
20570
+ const deviceId = yield (_e = pub.track) === null || _e === void 0 ? void 0 : _e.getDeviceId();
20421
20571
  const deviceKind = sourceToKind(pub.source);
20422
20572
  if (deviceKind && deviceId && deviceId !== this.localParticipant.activeDeviceMap.get(deviceKind)) {
20423
20573
  this.localParticipant.activeDeviceMap.set(deviceKind, deviceId);
@@ -22004,5 +22154,5 @@ function isFacingModeValue(item) {
22004
22154
  return item === undefined || allowedValues.includes(item);
22005
22155
  }
22006
22156
 
22007
- export { AudioPresets, BaseKeyProvider, CheckStatus, Checker, ConnectionCheck, ConnectionError, ConnectionQuality, ConnectionState, CriticalTimers, CryptorEvent, DataPacket_Kind, DefaultReconnectPolicy, DeviceUnsupportedError, DisconnectReason, EncryptionEvent, EngineEvent, ExternalE2EEKeyProvider, KeyHandlerEvent, KeyProviderEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalVideoTrack, LogLevel, LoggerNames, MediaDeviceFailure, Mutex, NegotiationError, Participant, ParticipantEvent, ParticipantInfo_Kind as ParticipantKind, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, ScreenSharePresets, SubscriptionError, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, createAudioAnalyser, createE2EEKey, createKeyMaterialFromBuffer, createKeyMaterialFromString, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, deriveKeys, detachTrack, facingModeFromDeviceLabel, facingModeFromLocalTrack, getBrowser, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, getLogger, importKey, isBackupCodec, isBrowserSupported, isE2EESupported, isInsertableStreamSupported, isScriptTransformSupported, isVideoFrame, needsRbspUnescaping, parseRbsp, protocolVersion, ratchet, setLogExtension, setLogLevel, supportsAV1, supportsAdaptiveStream, supportsDynacast, supportsVP9, version, videoCodecs, writeRbsp };
22157
+ export { AudioPresets, BaseKeyProvider, CheckStatus, Checker, ConnectionCheck, ConnectionError, ConnectionQuality, ConnectionState, CriticalTimers, CryptorError, CryptorErrorReason, CryptorEvent, DataPacket_Kind, DefaultReconnectPolicy, DeviceUnsupportedError, DisconnectReason, EncryptionEvent, EngineEvent, ExternalE2EEKeyProvider, KeyHandlerEvent, KeyProviderEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalVideoTrack, LogLevel, LoggerNames, MediaDeviceFailure, Mutex, NegotiationError, Participant, ParticipantEvent, ParticipantInfo_Kind as ParticipantKind, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, ScreenSharePresets, SignalRequestError, SubscriptionError, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, createAudioAnalyser, createE2EEKey, createKeyMaterialFromBuffer, createKeyMaterialFromString, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, deriveKeys, detachTrack, facingModeFromDeviceLabel, facingModeFromLocalTrack, getBrowser, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, getLogger, importKey, isBackupCodec, isBrowserSupported, isE2EESupported, isInsertableStreamSupported, isScriptTransformSupported, isVideoFrame, needsRbspUnescaping, parseRbsp, protocolVersion, ratchet, setLogExtension, setLogLevel, supportsAV1, supportsAdaptiveStream, supportsDynacast, supportsVP9, version, videoCodecs, writeRbsp };
22008
22158
  //# sourceMappingURL=livekit-client.esm.mjs.map