livekit-client 2.19.2 → 2.20.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 (123) 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 +23 -23
  4. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  5. package/dist/livekit-client.esm.mjs +179 -111
  6. package/dist/livekit-client.esm.mjs.map +1 -1
  7. package/dist/livekit-client.fm.worker.js +2 -0
  8. package/dist/{livekit-client.pt.worker.js.map → livekit-client.fm.worker.js.map} +1 -1
  9. package/dist/{livekit-client.pt.worker.mjs → livekit-client.fm.worker.mjs} +4 -4
  10. package/dist/livekit-client.fm.worker.mjs.map +1 -0
  11. package/dist/livekit-client.umd.js +1 -1
  12. package/dist/livekit-client.umd.js.map +1 -1
  13. package/dist/src/api/SignalClient.d.ts.map +1 -1
  14. package/dist/src/e2ee/E2eeManager.d.ts +1 -1
  15. package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
  16. package/dist/src/e2ee/types.d.ts +5 -5
  17. package/dist/src/e2ee/types.d.ts.map +1 -1
  18. package/dist/src/e2ee/worker/FrameCryptor.d.ts +8 -8
  19. package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
  20. package/dist/src/{packetTrailer/PacketTrailerManager.d.ts → frameMetadata/FrameMetadataManager.d.ts} +8 -4
  21. package/dist/src/{packetTrailer/PacketTrailerManager.d.ts.map → frameMetadata/FrameMetadataManager.d.ts.map} +1 -1
  22. package/dist/src/{packetTrailer/packetTrailer.d.ts → frameMetadata/frameMetadata.d.ts} +7 -7
  23. package/dist/src/frameMetadata/frameMetadata.d.ts.map +1 -0
  24. package/dist/src/{packetTrailer → frameMetadata}/types.d.ts +10 -6
  25. package/dist/src/frameMetadata/types.d.ts.map +1 -0
  26. package/dist/src/frameMetadata/utils.d.ts +9 -0
  27. package/dist/src/{packetTrailer → frameMetadata}/utils.d.ts.map +1 -1
  28. package/dist/src/frameMetadata/worker/frameMetadata.worker.d.ts +2 -0
  29. package/dist/src/frameMetadata/worker/frameMetadata.worker.d.ts.map +1 -0
  30. package/dist/src/index.d.ts +10 -2
  31. package/dist/src/index.d.ts.map +1 -1
  32. package/dist/src/options.d.ts +8 -4
  33. package/dist/src/options.d.ts.map +1 -1
  34. package/dist/src/room/PCTransport.d.ts +1 -0
  35. package/dist/src/room/PCTransport.d.ts.map +1 -1
  36. package/dist/src/room/PCTransportManager.d.ts +1 -0
  37. package/dist/src/room/PCTransportManager.d.ts.map +1 -1
  38. package/dist/src/room/RTCEngine.d.ts +3 -1
  39. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  40. package/dist/src/room/Room.d.ts +2 -2
  41. package/dist/src/room/Room.d.ts.map +1 -1
  42. package/dist/src/room/participant/LocalParticipant.d.ts +2 -2
  43. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  44. package/dist/src/room/participant/publishUtils.d.ts.map +1 -1
  45. package/dist/src/room/token-source/TokenSource.d.ts.map +1 -1
  46. package/dist/src/room/token-source/types.d.ts +1 -0
  47. package/dist/src/room/token-source/types.d.ts.map +1 -1
  48. package/dist/src/room/token-source/utils.d.ts.map +1 -1
  49. package/dist/src/room/track/FrameMetadataExtractor.d.ts +19 -0
  50. package/dist/src/room/track/FrameMetadataExtractor.d.ts.map +1 -0
  51. package/dist/src/room/track/RemoteVideoTrack.d.ts +7 -7
  52. package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
  53. package/dist/src/room/track/options.d.ts +17 -5
  54. package/dist/src/room/track/options.d.ts.map +1 -1
  55. package/dist/ts4.2/e2ee/E2eeManager.d.ts +1 -1
  56. package/dist/ts4.2/e2ee/types.d.ts +5 -5
  57. package/dist/ts4.2/e2ee/worker/FrameCryptor.d.ts +8 -8
  58. package/dist/ts4.2/{packetTrailer/PacketTrailerManager.d.ts → frameMetadata/FrameMetadataManager.d.ts} +8 -4
  59. package/dist/ts4.2/{packetTrailer/packetTrailer.d.ts → frameMetadata/frameMetadata.d.ts} +7 -7
  60. package/dist/ts4.2/{packetTrailer → frameMetadata}/types.d.ts +10 -6
  61. package/dist/ts4.2/frameMetadata/utils.d.ts +9 -0
  62. package/dist/ts4.2/frameMetadata/worker/frameMetadata.worker.d.ts +2 -0
  63. package/dist/ts4.2/index.d.ts +9 -3
  64. package/dist/ts4.2/options.d.ts +8 -4
  65. package/dist/ts4.2/room/PCTransport.d.ts +1 -0
  66. package/dist/ts4.2/room/PCTransportManager.d.ts +1 -0
  67. package/dist/ts4.2/room/RTCEngine.d.ts +3 -1
  68. package/dist/ts4.2/room/Room.d.ts +2 -2
  69. package/dist/ts4.2/room/participant/LocalParticipant.d.ts +2 -2
  70. package/dist/ts4.2/room/token-source/types.d.ts +1 -0
  71. package/dist/ts4.2/room/track/FrameMetadataExtractor.d.ts +19 -0
  72. package/dist/ts4.2/room/track/RemoteVideoTrack.d.ts +7 -7
  73. package/dist/ts4.2/room/track/options.d.ts +17 -5
  74. package/package.json +23 -18
  75. package/src/api/SignalClient.test.ts +4 -4
  76. package/src/api/SignalClient.ts +7 -3
  77. package/src/api/WebSocketStream.test.ts +7 -7
  78. package/src/e2ee/E2eeManager.ts +13 -11
  79. package/src/e2ee/types.ts +5 -5
  80. package/src/e2ee/worker/FrameCryptor.test.ts +5 -5
  81. package/src/e2ee/worker/FrameCryptor.ts +27 -23
  82. package/src/e2ee/worker/e2ee.worker.ts +5 -5
  83. package/src/e2ee/worker/tsconfig.json +4 -1
  84. package/src/{packetTrailer/PacketTrailerManager.test.ts → frameMetadata/FrameMetadataManager.test.ts} +10 -8
  85. package/src/{packetTrailer/PacketTrailerManager.ts → frameMetadata/FrameMetadataManager.ts} +21 -15
  86. package/src/{packetTrailer/packetTrailer.test.ts → frameMetadata/frameMetadata.test.ts} +1 -1
  87. package/src/{packetTrailer/packetTrailer.ts → frameMetadata/frameMetadata.ts} +9 -9
  88. package/src/{packetTrailer → frameMetadata}/types.ts +12 -6
  89. package/src/{packetTrailer → frameMetadata}/utils.test.ts +19 -19
  90. package/src/{packetTrailer → frameMetadata}/utils.ts +11 -11
  91. package/src/{packetTrailer/worker/packetTrailer.worker.ts → frameMetadata/worker/frameMetadata.worker.ts} +5 -5
  92. package/src/{packetTrailer → frameMetadata}/worker/tsconfig.json +4 -1
  93. package/src/index.ts +13 -2
  94. package/src/options.ts +9 -4
  95. package/src/room/PCTransport.ts +4 -0
  96. package/src/room/PCTransportManager.ts +4 -0
  97. package/src/room/RTCEngine.test.ts +143 -9
  98. package/src/room/RTCEngine.ts +111 -31
  99. package/src/room/Room.ts +10 -10
  100. package/src/room/participant/LocalParticipant.test.ts +19 -19
  101. package/src/room/participant/LocalParticipant.ts +21 -16
  102. package/src/room/participant/publishUtils.test.ts +6 -0
  103. package/src/room/participant/publishUtils.ts +4 -1
  104. package/src/room/rpc/client/RpcClientManager.ts +1 -1
  105. package/src/room/rpc/server/RpcServerManager.ts +1 -1
  106. package/src/room/token-source/TokenSource.ts +9 -23
  107. package/src/room/token-source/types.ts +1 -0
  108. package/src/room/token-source/utils.ts +1 -0
  109. package/src/room/track/{PacketTrailerExtractor.ts → FrameMetadataExtractor.ts} +8 -8
  110. package/src/room/track/RemoteVideoTrack.ts +7 -11
  111. package/src/room/track/options.ts +19 -5
  112. package/dist/livekit-client.pt.worker.js +0 -2
  113. package/dist/livekit-client.pt.worker.mjs.map +0 -1
  114. package/dist/src/packetTrailer/packetTrailer.d.ts.map +0 -1
  115. package/dist/src/packetTrailer/types.d.ts.map +0 -1
  116. package/dist/src/packetTrailer/utils.d.ts +0 -9
  117. package/dist/src/packetTrailer/worker/packetTrailer.worker.d.ts +0 -2
  118. package/dist/src/packetTrailer/worker/packetTrailer.worker.d.ts.map +0 -1
  119. package/dist/src/room/track/PacketTrailerExtractor.d.ts +0 -19
  120. package/dist/src/room/track/PacketTrailerExtractor.d.ts.map +0 -1
  121. package/dist/ts4.2/packetTrailer/utils.d.ts +0 -9
  122. package/dist/ts4.2/packetTrailer/worker/packetTrailer.worker.d.ts +0 -2
  123. package/dist/ts4.2/room/track/PacketTrailerExtractor.d.ts +0 -19
@@ -8776,8 +8776,7 @@ function requireEvents() {
8776
8776
  }
8777
8777
  }
8778
8778
  return events.exports;
8779
- }var eventsExports = requireEvents();
8780
- var EventEmitter = /*@__PURE__*/getDefaultExportFromCjs(eventsExports);/*
8779
+ }var eventsExports = requireEvents();/*
8781
8780
  * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
8782
8781
  *
8783
8782
  * Use of this source code is governed by a BSD-style license
@@ -11844,7 +11843,7 @@ function getMatch(exp, ua) {
11844
11843
  }
11845
11844
  function getOSVersion(ua) {
11846
11845
  return ua.includes('mac os') ? getMatch(/\(.+?(\d+_\d+(:?_\d+)?)/, ua, 1).replace(/_/g, '.') : undefined;
11847
- }var version$1 = "2.19.2";const version = version$1;
11846
+ }var version$1 = "2.20.0";const version = version$1;
11848
11847
  const protocolVersion = 17;
11849
11848
  /** Initial client protocol. */
11850
11849
  const CLIENT_PROTOCOL_DEFAULT = 0;
@@ -14443,16 +14442,16 @@ class CryptorError extends LivekitError {
14443
14442
  this.reason = reason;
14444
14443
  this.participantIdentity = participantIdentity;
14445
14444
  }
14446
- }function shouldUsePacketTrailerScriptTransform() {
14445
+ }function shouldUseFrameMetadataScriptTransform() {
14447
14446
  return isScriptTransformSupportedForWorker();
14448
14447
  }
14449
- function isPacketTrailerSupported(options) {
14450
- return !!(options === null || options === void 0 ? void 0 : options.worker) && (isInsertableStreamSupported() || shouldUsePacketTrailerScriptTransform());
14448
+ function isFrameMetadataSupported(options) {
14449
+ return !!(options === null || options === void 0 ? void 0 : options.worker) && (isInsertableStreamSupported() || shouldUseFrameMetadataScriptTransform());
14451
14450
  }
14452
- function hasPacketTrailerPublishOptions(options) {
14451
+ function hasFrameMetadataPublishOptions(options) {
14453
14452
  return !!((options === null || options === void 0 ? void 0 : options.timestamp) || (options === null || options === void 0 ? void 0 : options.frameId));
14454
14453
  }
14455
- function getPacketTrailerFeatures(options) {
14454
+ function getFrameMetadataFeatures(options) {
14456
14455
  const features = [];
14457
14456
  if (options === null || options === void 0 ? void 0 : options.timestamp) {
14458
14457
  features.push(PacketTrailerFeature.PTF_USER_TIMESTAMP);
@@ -14462,7 +14461,7 @@ function getPacketTrailerFeatures(options) {
14462
14461
  }
14463
14462
  return features;
14464
14463
  }
14465
- function getPacketTrailerPublishOptions(features) {
14464
+ function getFrameMetadataPublishOptions(features) {
14466
14465
  if (!features || features.length === 0) {
14467
14466
  return undefined;
14468
14467
  }
@@ -14736,14 +14735,14 @@ class RemoteVideoTrack extends RemoteTrack {
14736
14735
  * Use with the `TrackEvent.TimeSyncUpdate` event to correlate displayed frames
14737
14736
  * with their capture-time metadata.
14738
14737
  *
14739
- * Requires the room to be configured with the `packetTrailer` worker option
14740
- * and the publishing track to have packet trailer features enabled.
14738
+ * Requires the room to be configured with the `frameMetadata` worker option
14739
+ * and the publishing track to have frame metadata features enabled.
14741
14740
  *
14742
14741
  */
14743
14742
  lookupFrameMetadata(_ref) {
14744
14743
  let rtpTimestamp = _ref.rtpTimestamp;
14745
14744
  var _a;
14746
- return (_a = this.packetTrailerExtractor) === null || _a === void 0 ? void 0 : _a.lookupMetadata(rtpTimestamp);
14745
+ return (_a = this.frameMetadataExtractor) === null || _a === void 0 ? void 0 : _a.lookupMetadata(rtpTimestamp);
14747
14746
  }
14748
14747
  setStreamState(value) {
14749
14748
  super.setStreamState(value);
@@ -15136,7 +15135,7 @@ class E2EEManager extends eventsExports.EventEmitter {
15136
15135
  }
15137
15136
  break;
15138
15137
  case 'packetTrailerMetadata':
15139
- this.handlePacketTrailerMetadata(data.trackId, data.rtpTimestamp, data.ssrc, data.metadata);
15138
+ this.handleFrameMetadata(data.trackId, data.rtpTimestamp, data.ssrc, data.metadata);
15140
15139
  break;
15141
15140
  }
15142
15141
  };
@@ -15203,14 +15202,14 @@ class E2EEManager extends eventsExports.EventEmitter {
15203
15202
  this.postSifTrailer(trailer);
15204
15203
  }
15205
15204
  }
15206
- handlePacketTrailerMetadata(trackId, rtpTimestamp, ssrc, metadata) {
15205
+ handleFrameMetadata(trackId, rtpTimestamp, ssrc, metadata) {
15207
15206
  if (!this.room) {
15208
15207
  return;
15209
15208
  }
15210
15209
  for (const participant of [this.room.localParticipant, ...this.room.remoteParticipants.values()]) {
15211
15210
  for (const pub of participant.trackPublications.values()) {
15212
- if (pub.track && pub.track.mediaStreamID === trackId && pub.track instanceof RemoteVideoTrack && pub.track.packetTrailerExtractor) {
15213
- pub.track.packetTrailerExtractor.storeMetadata(rtpTimestamp, ssrc, metadata);
15211
+ if (pub.track && pub.track.mediaStreamID === trackId && pub.track instanceof RemoteVideoTrack && pub.track.frameMetadataExtractor) {
15212
+ pub.track.frameMetadataExtractor.storeMetadata(rtpTimestamp, ssrc, metadata);
15214
15213
  return;
15215
15214
  }
15216
15215
  }
@@ -15408,12 +15407,12 @@ class E2EEManager extends eventsExports.EventEmitter {
15408
15407
  this.handleReceiver(track.receiver, track.mediaStreamID, remoteId, track.kind === 'video' ? mimeTypeToVideoCodecString(trackInfo.mimeType) : undefined, hasPacketTrailer);
15409
15408
  }
15410
15409
  setupE2EESender(track, sender) {
15411
- var _a;
15410
+ var _a, _b, _c;
15412
15411
  if (!isLocalTrack(track) || !sender) {
15413
15412
  if (!sender) livekitLogger.warn('early return because sender is not ready');
15414
15413
  return;
15415
15414
  }
15416
- this.handleSender(sender, track.mediaStreamID, undefined, isVideoTrack(track) ? (_a = track.publishOptions) === null || _a === void 0 ? void 0 : _a.packetTrailer : undefined);
15415
+ this.handleSender(sender, track.mediaStreamID, undefined, isVideoTrack(track) ? (_b = (_a = track.publishOptions) === null || _a === void 0 ? void 0 : _a.frameMetadata) !== null && _b !== void 0 ? _b : (_c = track.publishOptions) === null || _c === void 0 ? void 0 : _c.packetTrailer : undefined);
15417
15416
  }
15418
15417
  /**
15419
15418
  * Handles the given {@code RTCRtpReceiver} by creating a {@code TransformStream} which will inject
@@ -15487,7 +15486,7 @@ class E2EEManager extends eventsExports.EventEmitter {
15487
15486
  * a frame encoder.
15488
15487
  *
15489
15488
  */
15490
- handleSender(sender, trackId, codec, packetTrailer) {
15489
+ handleSender(sender, trackId, codec, frameMetadata) {
15491
15490
  var _a;
15492
15491
  if (E2EE_FLAG in sender || !this.worker) {
15493
15492
  return;
@@ -15502,8 +15501,8 @@ class E2EEManager extends eventsExports.EventEmitter {
15502
15501
  participantIdentity: this.room.localParticipant.identity,
15503
15502
  trackId,
15504
15503
  codec,
15505
- hasPacketTrailer: hasPacketTrailerPublishOptions(packetTrailer),
15506
- packetTrailer
15504
+ hasPacketTrailer: hasFrameMetadataPublishOptions(frameMetadata),
15505
+ packetTrailer: frameMetadata
15507
15506
  };
15508
15507
  // @ts-ignore
15509
15508
  sender.transform = new RTCRtpScriptTransform(this.worker, options);
@@ -15520,8 +15519,8 @@ class E2EEManager extends eventsExports.EventEmitter {
15520
15519
  trackId,
15521
15520
  participantIdentity: this.room.localParticipant.identity,
15522
15521
  isReuse: false,
15523
- hasPacketTrailer: hasPacketTrailerPublishOptions(packetTrailer),
15524
- packetTrailer
15522
+ hasPacketTrailer: hasFrameMetadataPublishOptions(frameMetadata),
15523
+ packetTrailer: frameMetadata
15525
15524
  }
15526
15525
  };
15527
15526
  this.worker.postMessage(msg, [senderStreams.readable, senderStreams.writable]);
@@ -15531,16 +15530,16 @@ class E2EEManager extends eventsExports.EventEmitter {
15531
15530
  }
15532
15531
  }const MAX_ENTRIES = 300;
15533
15532
  /**
15534
- * Caches packet trailer metadata extracted from received video frames,
15533
+ * Caches frame metadata extracted from received video frames,
15535
15534
  * keyed by RTP timestamp so it can be looked up when the frame is displayed.
15536
15535
  *
15537
- * Metadata is populated either by the packet trailer worker managed by
15538
- * `PacketTrailerManager` (non-E2EE) or by the E2EE FrameCryptor worker
15536
+ * Metadata is populated either by the frame metadata worker managed by
15537
+ * `FrameMetadataManager` (non-E2EE) or by the E2EE FrameCryptor worker
15539
15538
  * after decryption (E2EE).
15540
15539
  *
15541
15540
  * @experimental
15542
15541
  */
15543
- class PacketTrailerExtractor {
15542
+ class FrameMetadataExtractor {
15544
15543
  constructor() {
15545
15544
  this.metadataMap = new Map();
15546
15545
  this.activeSsrc = 0;
@@ -15580,7 +15579,7 @@ class PacketTrailerExtractor {
15580
15579
  *
15581
15580
  * @experimental
15582
15581
  */
15583
- class PacketTrailerManager {
15582
+ class FrameMetadataManager {
15584
15583
  constructor(options) {
15585
15584
  this.extractors = new Map();
15586
15585
  /**
@@ -15600,7 +15599,7 @@ class PacketTrailerManager {
15600
15599
  }
15601
15600
  };
15602
15601
  this.onWorkerError = ev => {
15603
- livekitLogger.error('packet trailer worker encountered an error:', {
15602
+ livekitLogger.error('frame metadata worker encountered an error:', {
15604
15603
  error: ev.error
15605
15604
  });
15606
15605
  };
@@ -15646,16 +15645,16 @@ class PacketTrailerManager {
15646
15645
  }
15647
15646
  return;
15648
15647
  }
15649
- if (!isPacketTrailerSupported(this.worker ? {
15648
+ if (!isFrameMetadataSupported(this.worker ? {
15650
15649
  worker: this.worker
15651
15650
  } : undefined) && !((_b = this.room) === null || _b === void 0 ? void 0 : _b.hasE2EESetup)) {
15652
- livekitLogger.warn('packet trailer transform not supported; skipping extraction');
15651
+ livekitLogger.warn('frame metadata transform not supported; skipping extraction');
15653
15652
  return;
15654
15653
  }
15655
- const extractor = new PacketTrailerExtractor();
15654
+ const extractor = new FrameMetadataExtractor();
15656
15655
  const trackId = track.mediaStreamID;
15657
15656
  this.extractors.set(trackId, extractor);
15658
- track.packetTrailerExtractor = extractor;
15657
+ track.frameMetadataExtractor = extractor;
15659
15658
  if ((_c = this.room) === null || _c === void 0 ? void 0 : _c.hasE2EESetup) {
15660
15659
  // E2EE worker strips the trailer and injects metadata directly into
15661
15660
  // the extractor via E2eeManager; no pipeline is needed here.
@@ -15664,14 +15663,14 @@ class PacketTrailerManager {
15664
15663
  this.setupWorkerReceiver(receiver, trackId, true);
15665
15664
  }
15666
15665
  setupPassthroughReceiver(receiver, trackId) {
15667
- if (shouldUsePacketTrailerScriptTransform()) {
15666
+ if (shouldUseFrameMetadataScriptTransform()) {
15668
15667
  if ('transform' in receiver) {
15669
15668
  // @ts-ignore
15670
15669
  receiver.transform = null;
15671
15670
  }
15672
15671
  return;
15673
15672
  }
15674
- if (this.worker && isPacketTrailerSupported({
15673
+ if (this.worker && isFrameMetadataSupported({
15675
15674
  worker: this.worker
15676
15675
  }) && !this.workerPipelines.has(receiver)) {
15677
15676
  this.setupWorkerReceiver(receiver, trackId, false);
@@ -15687,7 +15686,7 @@ class PacketTrailerManager {
15687
15686
  if (!worker) {
15688
15687
  return;
15689
15688
  }
15690
- if (shouldUsePacketTrailerScriptTransform()) {
15689
+ if (shouldUseFrameMetadataScriptTransform()) {
15691
15690
  // @ts-ignore
15692
15691
  receiver.transform = new RTCRtpScriptTransform(worker, {
15693
15692
  kind: 'decode',
@@ -15746,7 +15745,7 @@ class PacketTrailerManager {
15746
15745
  this.extractors.delete(trackId);
15747
15746
  }
15748
15747
  if (track instanceof RemoteVideoTrack) {
15749
- track.packetTrailerExtractor = undefined;
15748
+ track.frameMetadataExtractor = undefined;
15750
15749
  }
15751
15750
  // The receiver pipeline is intentionally left running. If the receiver is
15752
15751
  // reused for a new track, `setupReceiver` will remap it. If the room
@@ -15763,7 +15762,9 @@ class PacketTrailerManager {
15763
15762
  this.workerPipelines.clear();
15764
15763
  (_a = this.worker) === null || _a === void 0 ? void 0 : _a.terminate();
15765
15764
  }
15766
- }const CONNECTION_BACKOFF_MIN_MS = 500;
15765
+ }
15766
+ /** @deprecated Use {@link FrameMetadataManager} instead. */
15767
+ const PacketTrailerManager = FrameMetadataManager;const CONNECTION_BACKOFF_MIN_MS = 500;
15767
15768
  const CONNECTION_BACKOFF_MAX_MS = 15000;
15768
15769
  /**
15769
15770
  * BackOffStrategy implements exponential backoff for connection failures.
@@ -16414,13 +16415,15 @@ class SignalClient {
16414
16415
  if (redactedUrl.searchParams.has('access_token')) {
16415
16416
  redactedUrl.searchParams.set('access_token', '<redacted>');
16416
16417
  }
16418
+ if (this.ws) {
16419
+ const startClose = performance.now();
16420
+ yield this.close(false);
16421
+ this.log.debug("closed previous ws connection in ".concat(performance.now() - startClose, "ms"));
16422
+ }
16417
16423
  this.log.info("signal connecting to ".concat(redactedUrl), {
16418
16424
  reconnect: opts.reconnect,
16419
16425
  reconnectReason: opts.reconnectReason
16420
16426
  });
16421
- if (this.ws) {
16422
- yield this.close(false);
16423
- }
16424
16427
  this.ws = new WebSocketStream(rtcUrl);
16425
16428
  try {
16426
16429
  this.ws.closed.then(closeInfo => {
@@ -18449,6 +18452,10 @@ class PCTransport extends eventsExports.EventEmitter {
18449
18452
  getStats() {
18450
18453
  return this.pc.getStats();
18451
18454
  }
18455
+ getMaxMessageSize() {
18456
+ var _a, _b;
18457
+ return (_b = (_a = this._pc) === null || _a === void 0 ? void 0 : _a.sctp) === null || _b === void 0 ? void 0 : _b.maxMessageSize;
18458
+ }
18452
18459
  getConnectedAddress() {
18453
18460
  return __awaiter(this, void 0, void 0, function* () {
18454
18461
  var _a;
@@ -18960,6 +18967,9 @@ class PCTransportManager {
18960
18967
  const matchingTransceiver = transceivers.find(transceiver => transceiver.receiver === receiver);
18961
18968
  return matchingTransceiver === null || matchingTransceiver === void 0 ? void 0 : matchingTransceiver.mid;
18962
18969
  }
18970
+ getMaxPublisherMessageSize() {
18971
+ return this.publisher.getMaxMessageSize();
18972
+ }
18963
18973
  addPublisherTrack(track) {
18964
18974
  return this.publisher.addTrack(track);
18965
18975
  }
@@ -20231,7 +20241,10 @@ function encodingsFromPresets(width, height, presets, sourceFramerate) {
20231
20241
  /** @internal */
20232
20242
  function sortPresets(presets) {
20233
20243
  if (!presets) return;
20234
- return presets.sort((a, b) => {
20244
+ // Sort a copy so we don't mutate the caller's array in place. Mutating the
20245
+ // passed-in simulcast layers can cause consumers that compare options by value
20246
+ // (e.g. components-react's useLiveKitRoom) to detect a spurious change.
20247
+ return presets.slice().sort((a, b) => {
20235
20248
  const aEnc = a.encoding;
20236
20249
  const bEnc = b.encoding;
20237
20250
  if (aEnc.maxBitrate > bEnc.maxBitrate) {
@@ -21060,6 +21073,10 @@ var DataChannelKind;
21060
21073
  DataChannelKind[DataChannelKind["LOSSY"] = 1] = "LOSSY";
21061
21074
  DataChannelKind[DataChannelKind["DATA_TRACK_LOSSY"] = 2] = "DATA_TRACK_LOSSY";
21062
21075
  })(DataChannelKind || (DataChannelKind = {}));
21076
+ // Default data-channel max message size (bytes), used when the remote SDP
21077
+ // answer does not advertise an `a=max-message-size` attribute (RFC 8841).
21078
+ // `0` means "no limit".
21079
+ const DEFAULT_MAX_MESSAGE_SIZE = 64000;
21063
21080
  /** @internal */
21064
21081
  class RTCEngine extends eventsExports.EventEmitter {
21065
21082
  get isClosed() {
@@ -21204,12 +21221,21 @@ class RTCEngine extends eventsExports.EventEmitter {
21204
21221
  this.emit('dataTrackPacketReceived', new Uint8Array(buffer));
21205
21222
  });
21206
21223
  this.handleDataError = event => {
21224
+ // Errors fired while we're tearing the connection down (e.g. the SCTP transport aborting as
21225
+ // the peer connection closes) carry no actionable information — the channel is going away
21226
+ // regardless. Suppress them so a graceful disconnect doesn't surface spurious errors.
21227
+ // See livekit/client-sdk-js#1953.
21228
+ if (this._isClosed) {
21229
+ return;
21230
+ }
21207
21231
  const channel = event.currentTarget;
21208
21232
  const channelKind = channel.maxRetransmits === 0 ? 'lossy' : 'reliable';
21209
- if (event instanceof ErrorEvent && event.error) {
21210
- const error = event.error.error;
21211
- this.log.error("DataChannel error on ".concat(channelKind, ": ").concat(event.message), {
21212
- error
21233
+ if (typeof RTCErrorEvent !== 'undefined' && event instanceof RTCErrorEvent && event.error) {
21234
+ const error = event.error;
21235
+ this.log.error("DataChannel error on ".concat(channelKind, ": ").concat(error.message), {
21236
+ error,
21237
+ errorDetail: error.errorDetail,
21238
+ sctpCauseCode: error.sctpCauseCode
21213
21239
  });
21214
21240
  } else {
21215
21241
  this.log.error("Unknown DataChannel error on ".concat(channelKind), {
@@ -21217,6 +21243,15 @@ class RTCEngine extends eventsExports.EventEmitter {
21217
21243
  });
21218
21244
  }
21219
21245
  };
21246
+ this.handleDataChannelClose = kind => () => {
21247
+ var _a;
21248
+ // A publisher DC closing while the session is up and the publisher PC is still
21249
+ // connected is the signature of an oversized message having aborted the channel
21250
+ // (see livekit/rust-sdks#1137). Surface it; do not attempt renegotiation.
21251
+ if (!this._isClosed && ((_a = this.pcManager) === null || _a === void 0 ? void 0 : _a.publisher.getConnectionState()) === 'connected') {
21252
+ this.log.error("publisher data channel '".concat(DataChannelKind[kind], "' closed unexpectedly"), this.logContext);
21253
+ }
21254
+ };
21220
21255
  this.handleBufferedAmountLow = channelKind => {
21221
21256
  this.updateAndEmitDCBufferStatus(channelKind);
21222
21257
  };
@@ -21516,17 +21551,23 @@ class RTCEngine extends eventsExports.EventEmitter {
21516
21551
  cleanupPeerConnections() {
21517
21552
  return __awaiter(this, void 0, void 0, function* () {
21518
21553
  var _a;
21519
- yield (_a = this.pcManager) === null || _a === void 0 ? void 0 : _a.close();
21520
- this.pcManager = undefined;
21521
21554
  const dcCleanup = dc => {
21522
- if (!dc) return;
21523
- dc.close();
21555
+ if (!dc) {
21556
+ return;
21557
+ }
21558
+ // Detach the data channel handlers before closing anything. Closing a peer connection tears
21559
+ // down the SCTP transport, which can dispatch `error`/`close` events on the still-open data
21560
+ // channels; if our handlers are still attached at that point, handleDataError logs a spurious
21561
+ // "Unknown DataChannel error" during an otherwise graceful disconnect. Removing the handlers
21562
+ // before dc.close()/pcManager.close() makes this deterministic regardless of how/when the
21563
+ // browser dispatches those teardown events. See livekit/client-sdk-js#1953.
21524
21564
  dc.onbufferedamountlow = null;
21525
21565
  dc.onclose = null;
21526
21566
  dc.onclosing = null;
21527
21567
  dc.onerror = null;
21528
21568
  dc.onmessage = null;
21529
21569
  dc.onopen = null;
21570
+ dc.close();
21530
21571
  };
21531
21572
  dcCleanup(this.lossyDC);
21532
21573
  dcCleanup(this.lossyDCSub);
@@ -21534,6 +21575,8 @@ class RTCEngine extends eventsExports.EventEmitter {
21534
21575
  dcCleanup(this.reliableDCSub);
21535
21576
  dcCleanup(this.dataTrackDC);
21536
21577
  dcCleanup(this.dataTrackDCSub);
21578
+ yield (_a = this.pcManager) === null || _a === void 0 ? void 0 : _a.close();
21579
+ this.pcManager = undefined;
21537
21580
  this.lossyDC = undefined;
21538
21581
  this.lossyDCSub = undefined;
21539
21582
  this.reliableDC = undefined;
@@ -21806,12 +21849,12 @@ class RTCEngine extends eventsExports.EventEmitter {
21806
21849
  };
21807
21850
  }
21808
21851
  makeRTCConfiguration(serverResponse) {
21809
- var _a, _b;
21852
+ var _a;
21810
21853
  const rtcConfig = Object.assign({}, this.rtcConfig);
21811
21854
  // E2EE and packet trailer extraction both rely on encoded frame transforms.
21812
21855
  // Only opt into the createEncodedStreams flavor when that path will be
21813
21856
  // used; RTCRtpScriptTransform does not need the PeerConnection flag.
21814
- const needsInsertableStreams = ((_a = this.signalOpts) === null || _a === void 0 ? void 0 : _a.e2eeEnabled) || ((_b = this.options.packetTrailer) === null || _b === void 0 ? void 0 : _b.worker) && !shouldUsePacketTrailerScriptTransform();
21857
+ const needsInsertableStreams = ((_a = this.signalOpts) === null || _a === void 0 ? void 0 : _a.e2eeEnabled) || this.frameMetadataWorker && !shouldUseFrameMetadataScriptTransform();
21815
21858
  if (needsInsertableStreams && isInsertableStreamSupported()) {
21816
21859
  this.log.debug('E2EE - setting up transports with insertable streams');
21817
21860
  // this makes sure that no data is sent before the transforms are ready
@@ -21853,7 +21896,15 @@ class RTCEngine extends eventsExports.EventEmitter {
21853
21896
  */
21854
21897
  applyInitialPublisherLayout() {
21855
21898
  this.createDataChannels();
21856
- this.addMediaSections(initialMediaSectionsAudio, initialMediaSectionsVideo);
21899
+ /**
21900
+ * Native libwebrtc does not support pre-populating the media sections,
21901
+ * so we skip it for React Native.
21902
+ *
21903
+ * Related: https://github.com/livekit/rust-sdks/pull/1151
21904
+ */
21905
+ if (!isReactNative()) {
21906
+ this.addMediaSections(initialMediaSectionsAudio, initialMediaSectionsVideo);
21907
+ }
21857
21908
  }
21858
21909
  addMediaSections(numAudios, numVideos) {
21859
21910
  var _a, _b;
@@ -21875,14 +21926,17 @@ class RTCEngine extends eventsExports.EventEmitter {
21875
21926
  if (this.lossyDC) {
21876
21927
  this.lossyDC.onmessage = null;
21877
21928
  this.lossyDC.onerror = null;
21929
+ this.lossyDC.onclose = null;
21878
21930
  }
21879
21931
  if (this.reliableDC) {
21880
21932
  this.reliableDC.onmessage = null;
21881
21933
  this.reliableDC.onerror = null;
21934
+ this.reliableDC.onclose = null;
21882
21935
  }
21883
21936
  if (this.dataTrackDC) {
21884
21937
  this.dataTrackDC.onmessage = null;
21885
21938
  this.dataTrackDC.onerror = null;
21939
+ this.dataTrackDC.onclose = null;
21886
21940
  }
21887
21941
  // create data channels
21888
21942
  this.lossyDC = this.pcManager.createPublisherDataChannel(lossyDataChannel, {
@@ -21904,6 +21958,10 @@ class RTCEngine extends eventsExports.EventEmitter {
21904
21958
  this.lossyDC.onerror = this.handleDataError;
21905
21959
  this.reliableDC.onerror = this.handleDataError;
21906
21960
  this.dataTrackDC.onerror = this.handleDataError;
21961
+ // detect unexpected publisher data channel closes
21962
+ this.lossyDC.onclose = this.handleDataChannelClose(DataChannelKind.LOSSY);
21963
+ this.reliableDC.onclose = this.handleDataChannelClose(DataChannelKind.RELIABLE);
21964
+ this.dataTrackDC.onclose = this.handleDataChannelClose(DataChannelKind.DATA_TRACK_LOSSY);
21907
21965
  // set up dc buffer threshold, set to 64kB (otherwise 0 by default)
21908
21966
  this.lossyDC.bufferedAmountLowThreshold = 65535;
21909
21967
  this.reliableDC.bufferedAmountLowThreshold = 65535;
@@ -21935,7 +21993,7 @@ class RTCEngine extends eventsExports.EventEmitter {
21935
21993
  } else {
21936
21994
  throw new UnexpectedConnectionState('Required webRTC APIs not supported on this device');
21937
21995
  }
21938
- this.setupPacketTrailerSender(sender, opts);
21996
+ this.setupFrameMetadataSender(sender, opts);
21939
21997
  return sender;
21940
21998
  });
21941
21999
  }
@@ -21951,32 +22009,37 @@ class RTCEngine extends eventsExports.EventEmitter {
21951
22009
  throw new UnexpectedConnectionState('Cannot stream on this device');
21952
22010
  }
21953
22011
  if (sender) {
21954
- this.setupPacketTrailerSender(sender, opts);
22012
+ this.setupFrameMetadataSender(sender, opts);
21955
22013
  }
21956
22014
  return sender;
21957
22015
  });
21958
22016
  }
21959
- setupPacketTrailerSender(sender) {
21960
- let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
22017
+ get frameMetadataWorker() {
21961
22018
  var _a, _b;
21962
- if (!((_a = this.options.packetTrailer) === null || _a === void 0 ? void 0 : _a.worker) || ((_b = this.signalOpts) === null || _b === void 0 ? void 0 : _b.e2eeEnabled)) {
22019
+ return (_b = (_a = this.options.frameMetadata) !== null && _a !== void 0 ? _a : this.options.packetTrailer) === null || _b === void 0 ? void 0 : _b.worker;
22020
+ }
22021
+ setupFrameMetadataSender(sender) {
22022
+ let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
22023
+ var _a, _b, _c;
22024
+ const worker = this.frameMetadataWorker;
22025
+ if (!worker || ((_a = this.signalOpts) === null || _a === void 0 ? void 0 : _a.e2eeEnabled)) {
21963
22026
  return;
21964
22027
  }
21965
- const packetTrailer = opts.packetTrailer;
21966
- const hasPacketTrailer = hasPacketTrailerPublishOptions(packetTrailer);
21967
- if (shouldUsePacketTrailerScriptTransform()) {
21968
- if (hasPacketTrailer) {
22028
+ const frameMetadata = (_b = opts.frameMetadata) !== null && _b !== void 0 ? _b : opts.packetTrailer;
22029
+ const hasMetadata = hasFrameMetadataPublishOptions(frameMetadata);
22030
+ if (shouldUseFrameMetadataScriptTransform()) {
22031
+ if (hasMetadata) {
21969
22032
  // @ts-ignore
21970
- sender.transform = new RTCRtpScriptTransform(this.options.packetTrailer.worker, {
22033
+ sender.transform = new RTCRtpScriptTransform(worker, {
21971
22034
  kind: 'encode',
21972
- packetTrailer
22035
+ packetTrailer: frameMetadata
21973
22036
  });
21974
22037
  }
21975
22038
  return;
21976
22039
  }
21977
- if (!isPacketTrailerSupported(this.options.packetTrailer) || !('createEncodedStreams' in sender)) {
21978
- if (hasPacketTrailer) {
21979
- this.log.warn('packet trailer transform not supported; skipping write', this.logContext);
22040
+ if (!isFrameMetadataSupported((_c = this.options.frameMetadata) !== null && _c !== void 0 ? _c : this.options.packetTrailer) || !('createEncodedStreams' in sender)) {
22041
+ if (hasMetadata) {
22042
+ this.log.warn('frame metadata transform not supported; skipping write', this.logContext);
21980
22043
  }
21981
22044
  return;
21982
22045
  }
@@ -21984,13 +22047,13 @@ class RTCEngine extends eventsExports.EventEmitter {
21984
22047
  const _sender$createEncoded = sender.createEncodedStreams(),
21985
22048
  readable = _sender$createEncoded.readable,
21986
22049
  writable = _sender$createEncoded.writable;
21987
- if (hasPacketTrailer) {
21988
- this.options.packetTrailer.worker.postMessage({
22050
+ if (hasMetadata) {
22051
+ worker.postMessage({
21989
22052
  kind: 'encode',
21990
22053
  data: {
21991
22054
  readableStream: readable,
21992
22055
  writableStream: writable,
21993
- packetTrailer
22056
+ packetTrailer: frameMetadata
21994
22057
  }
21995
22058
  }, [readable, writable]);
21996
22059
  } else {
@@ -22278,6 +22341,7 @@ class RTCEngine extends eventsExports.EventEmitter {
22278
22341
  /* @internal */
22279
22342
  sendDataPacket(packet, kind) {
22280
22343
  return __awaiter(this, void 0, void 0, function* () {
22344
+ var _a, _b;
22281
22345
  // make sure we do have a data connection
22282
22346
  yield this.ensurePublisherConnected(kind);
22283
22347
  if (this.e2eeManager && this.e2eeManager.isDataChannelEncryptionEnabled) {
@@ -22299,6 +22363,13 @@ class RTCEngine extends eventsExports.EventEmitter {
22299
22363
  this.reliableDataSequence += 1;
22300
22364
  }
22301
22365
  const msg = packet.toBinary();
22366
+ // Clamp to the SDK default - libwebrtc advertises larger (~256 KiB)
22367
+ // than LiveKit/pion can deliver end-to-end (~64 KiB), so we trust
22368
+ // the answer up untilthe built in ceiling.
22369
+ const maxPublisherMessageSizeBytes = Math.min((_b = (_a = this.pcManager) === null || _a === void 0 ? void 0 : _a.getMaxPublisherMessageSize()) !== null && _b !== void 0 ? _b : DEFAULT_MAX_MESSAGE_SIZE, DEFAULT_MAX_MESSAGE_SIZE);
22370
+ if (typeof maxPublisherMessageSizeBytes !== 'undefined' && maxPublisherMessageSizeBytes !== 0 /* 0 means "no limit" */ && msg.byteLength > maxPublisherMessageSizeBytes) {
22371
+ throw new PublishDataError("cannot publish data packet larger than ".concat(maxPublisherMessageSizeBytes, " bytes (got ").concat(msg.byteLength, ")"));
22372
+ }
22302
22373
  switch (kind) {
22303
22374
  case DataChannelKind.LOSSY:
22304
22375
  case DataChannelKind.DATA_TRACK_LOSSY:
@@ -25978,7 +26049,7 @@ function truncateBytes(str, maxBytes) {
25978
26049
  * ack/response state, and handling incoming ack/response packets.
25979
26050
  * @internal
25980
26051
  */
25981
- class RpcClientManager extends EventEmitter {
26052
+ class RpcClientManager extends eventsExports.EventEmitter {
25982
26053
  constructor(log, outgoingDataStreamManager, getRemoteParticipantClientProtocol, getServerVersion) {
25983
26054
  super();
25984
26055
  this.pendingAcks = new Map();
@@ -26178,7 +26249,7 @@ class RpcClientManager extends EventEmitter {
26178
26249
  * managing registered method handlers, and sending responses.
26179
26250
  * @internal
26180
26251
  */
26181
- class RpcServerManager extends EventEmitter {
26252
+ class RpcServerManager extends eventsExports.EventEmitter {
26182
26253
  constructor(log, outgoingDataStreamManager, getRemoteParticipantClientProtocol) {
26183
26254
  super();
26184
26255
  this.rpcHandlers = new Map();
@@ -28140,7 +28211,7 @@ class Participant extends eventsExports.EventEmitter {
28140
28211
  if (isLocalAudioTrack(track) && track.hasPreConnectBuffer) {
28141
28212
  audioFeatures.push(AudioTrackFeature.TF_PRECONNECT_BUFFER);
28142
28213
  }
28143
- const packetTrailerFeatures = this.normalizeRequestedPacketTrailerOptions(track, opts);
28214
+ const packetTrailerFeatures = this.normalizeRequestedFrameMetadataOptions(track, opts);
28144
28215
  // create track publication from track
28145
28216
  const req = new AddTrackRequest({
28146
28217
  // get local track id for use during publishing
@@ -28436,21 +28507,28 @@ class Participant extends eventsExports.EventEmitter {
28436
28507
  return publication;
28437
28508
  });
28438
28509
  }
28439
- canPublishPacketTrailer() {
28440
- return !!(this.roomOptions.e2ee || this.roomOptions.encryption || isPacketTrailerSupported(this.roomOptions.packetTrailer));
28510
+ canPublishFrameMetadata() {
28511
+ var _a;
28512
+ return !!(this.roomOptions.e2ee || this.roomOptions.encryption || isFrameMetadataSupported((_a = this.roomOptions.frameMetadata) !== null && _a !== void 0 ? _a : this.roomOptions.packetTrailer));
28441
28513
  }
28442
- normalizeRequestedPacketTrailerOptions(track, opts) {
28443
- if (track.kind !== Track.Kind.Video || !hasPacketTrailerPublishOptions(opts.packetTrailer)) {
28514
+ normalizeRequestedFrameMetadataOptions(track, opts) {
28515
+ var _a;
28516
+ const fmOpts = (_a = opts.frameMetadata) !== null && _a !== void 0 ? _a : opts.packetTrailer;
28517
+ if (track.kind !== Track.Kind.Video || !hasFrameMetadataPublishOptions(fmOpts)) {
28518
+ opts.frameMetadata = undefined;
28444
28519
  opts.packetTrailer = undefined;
28445
28520
  return [];
28446
28521
  }
28447
- if (!this.canPublishPacketTrailer()) {
28448
- this.log.warn('packet trailer transform not supported; not advertising features', Object.assign(Object.assign({}, this.logContext), getLogContextFromTrack(track)));
28522
+ if (!this.canPublishFrameMetadata()) {
28523
+ this.log.warn('frame metadata transform not supported; not advertising features', Object.assign(Object.assign({}, this.logContext), getLogContextFromTrack(track)));
28524
+ opts.frameMetadata = undefined;
28449
28525
  opts.packetTrailer = undefined;
28450
28526
  return [];
28451
28527
  }
28452
- const features = getPacketTrailerFeatures(opts.packetTrailer);
28453
- opts.packetTrailer = getPacketTrailerPublishOptions(features);
28528
+ const features = getFrameMetadataFeatures(fmOpts);
28529
+ const normalized = getFrameMetadataPublishOptions(features);
28530
+ opts.frameMetadata = normalized;
28531
+ opts.packetTrailer = normalized;
28454
28532
  return features;
28455
28533
  }
28456
28534
  get isLocal() {
@@ -28492,7 +28570,7 @@ class Participant extends eventsExports.EventEmitter {
28492
28570
  if (!simulcastTrack) {
28493
28571
  return;
28494
28572
  }
28495
- const packetTrailerFeatures = this.normalizeRequestedPacketTrailerOptions(track, opts);
28573
+ const packetTrailerFeatures = this.normalizeRequestedFrameMetadataOptions(track, opts);
28496
28574
  const req = new AddTrackRequest({
28497
28575
  cid: simulcastTrack.mediaStreamTrack.id,
28498
28576
  type: Track.kindToProto(track.kind),
@@ -29764,10 +29842,11 @@ class Room extends eventsExports.EventEmitter {
29764
29842
  return this.connectFuture.promise;
29765
29843
  });
29766
29844
  this.connectSignal = (url, token, engine, connectOptions, roomOptions, abortController) => __awaiter(this, void 0, void 0, function* () {
29845
+ var _a;
29767
29846
  const _yield$engine$join = yield engine.join(url, token, {
29768
29847
  autoSubscribe: connectOptions.autoSubscribe,
29769
29848
  adaptiveStream: typeof roomOptions.adaptiveStream === 'object' ? true : roomOptions.adaptiveStream,
29770
- clientInfoCapabilities: isPacketTrailerSupported(roomOptions.packetTrailer) || !!this.e2eeManager ? [ClientInfo_Capability.CAP_PACKET_TRAILER] : undefined,
29849
+ clientInfoCapabilities: isFrameMetadataSupported((_a = roomOptions.frameMetadata) !== null && _a !== void 0 ? _a : roomOptions.packetTrailer) || !!this.e2eeManager ? [ClientInfo_Capability.CAP_PACKET_TRAILER] : undefined,
29771
29850
  maxRetries: connectOptions.maxRetries,
29772
29851
  e2eeEnabled: !!this.e2eeManager,
29773
29852
  websocketTimeout: connectOptions.websocketTimeout
@@ -30454,7 +30533,7 @@ class Room extends eventsExports.EventEmitter {
30454
30533
  });
30455
30534
  this.disconnectLock = new _();
30456
30535
  this.localParticipant = new LocalParticipant('', '', this.engine, this.options, this.outgoingDataStreamManager, this.outgoingDataTrackManager, this.rpcClientManager, this.rpcServerManager);
30457
- this.setupPacketTrailer();
30536
+ this.setupFrameMetadata();
30458
30537
  if (this.options.e2ee || this.options.encryption) {
30459
30538
  this.setupE2EE();
30460
30539
  }
@@ -30596,11 +30675,11 @@ class Room extends eventsExports.EventEmitter {
30596
30675
  (_b = this.e2eeManager) === null || _b === void 0 ? void 0 : _b.setupEngine(this.engine);
30597
30676
  }
30598
30677
  }
30599
- setupPacketTrailer() {
30600
- // The manager is always created so tracks that advertise packet trailer
30601
- // features can be wired up when the app passes a packet trailer worker.
30602
- this.packetTrailerManager = new PacketTrailerManager(this.options.packetTrailer);
30603
- this.packetTrailerManager.setup(this);
30678
+ setupFrameMetadata() {
30679
+ var _a;
30680
+ const opts = (_a = this.options.frameMetadata) !== null && _a !== void 0 ? _a : this.options.packetTrailer;
30681
+ this.frameMetadataManager = new FrameMetadataManager(opts);
30682
+ this.frameMetadataManager.setup(this);
30604
30683
  }
30605
30684
  get logContext() {
30606
30685
  var _a, _b, _c;
@@ -32784,6 +32863,7 @@ function areTokenSourceFetchOptionsEqual(a, b) {
32784
32863
  case 'participantAttributes':
32785
32864
  case 'agentName':
32786
32865
  case 'agentMetadata':
32866
+ case 'deployment':
32787
32867
  if (a[key] !== b[key]) {
32788
32868
  return false;
32789
32869
  }
@@ -32808,26 +32888,7 @@ class TokenSourceCached extends TokenSourceConfigurable {
32808
32888
  if (!this.cachedFetchOptions) {
32809
32889
  return false;
32810
32890
  }
32811
- for (const key of Object.keys(this.cachedFetchOptions)) {
32812
- switch (key) {
32813
- case 'roomName':
32814
- case 'participantName':
32815
- case 'participantIdentity':
32816
- case 'participantMetadata':
32817
- case 'participantAttributes':
32818
- case 'agentName':
32819
- case 'agentMetadata':
32820
- if (this.cachedFetchOptions[key] !== options[key]) {
32821
- return false;
32822
- }
32823
- break;
32824
- default:
32825
- // ref: https://stackoverflow.com/a/58009992
32826
- const exhaustiveCheckedKey = key;
32827
- throw new Error("Options key ".concat(exhaustiveCheckedKey, " not being checked for equality!"));
32828
- }
32829
- }
32830
- return true;
32891
+ return areTokenSourceFetchOptionsEqual(options, this.cachedFetchOptions);
32831
32892
  }
32832
32893
  shouldReturnCachedValueFromFetch(fetchOptions) {
32833
32894
  if (!this.cachedResponse) {
@@ -32912,7 +32973,7 @@ class TokenSourceEndpoint extends TokenSourceCached {
32912
32973
  this.endpointOptions = options;
32913
32974
  }
32914
32975
  createRequestFromOptions(options) {
32915
- var _a, _b, _c;
32976
+ var _a, _b, _c, _d;
32916
32977
  const request = new TokenSourceRequest();
32917
32978
  for (const key of Object.keys(options)) {
32918
32979
  switch (key) {
@@ -32939,6 +33000,13 @@ class TokenSourceEndpoint extends TokenSourceCached {
32939
33000
  }
32940
33001
  request.roomConfig.agents[0].metadata = options.agentMetadata;
32941
33002
  break;
33003
+ case 'deployment':
33004
+ request.roomConfig = (_d = request.roomConfig) !== null && _d !== void 0 ? _d : new RoomConfiguration();
33005
+ if (request.roomConfig.agents.length === 0) {
33006
+ request.roomConfig.agents.push(new RoomAgentDispatch());
33007
+ }
33008
+ request.roomConfig.agents[0].deployment = options.deployment;
33009
+ break;
32942
33010
  default:
32943
33011
  // ref: https://stackoverflow.com/a/58009992
32944
33012
  const exhaustiveCheckedKey = key;
@@ -33147,4 +33215,4 @@ const serializers = {
33147
33215
  json,
33148
33216
  raw,
33149
33217
  custom
33150
- };export{AudioPresets,BackupCodecPolicy,BaseKeyProvider,CLIENT_PROTOCOL_DATA_STREAM_RPC,CLIENT_PROTOCOL_DEFAULT,CheckStatus,Checker,ConnectionCheck,ConnectionError,ConnectionErrorReason,ConnectionQuality,ConnectionState,CriticalTimers,CryptorError,CryptorErrorReason,CryptorEvent,DataPacket_Kind,DataStreamError,DataStreamErrorReason,DataTrackPacket,DefaultReconnectPolicy,DeviceUnsupportedError,DisconnectReason,EncryptionEvent,Encryption_Type,EngineEvent,ExternalE2EEKeyProvider,KeyHandlerEvent,KeyProviderEvent,LivekitError,LivekitReasonedError,LocalAudioTrack,LocalDataTrack,LocalParticipant,LocalTrack,LocalTrackPublication,LocalTrackRecorder,LocalVideoTrack,LogLevel,LoggerNames,MediaDeviceFailure,_ as Mutex,NegotiationError,PacketTrailerManager,Participant,ParticipantEvent,ParticipantInfo_Kind as ParticipantKind,PublishDataError,PublishTrackError,RemoteAudioTrack,RemoteDataTrack,RemoteParticipant,RemoteTrack,RemoteTrackPublication,RemoteVideoTrack,Room,RoomEvent,RpcError,ScreenSharePresets,SignalReconnectError,SignalRequestError,SimulatedError,SubscriptionError,TokenSource,TokenSourceConfigurable,TokenSourceFixed,Track,TrackEvent,TrackInvalidError,TrackPublication,TrackType,UnexpectedConnectionState,UnsupportedServer,VideoPreset,VideoPresets,VideoPresets43,VideoQuality,areTokenSourceFetchOptionsEqual,asEncryptablePacket,attachToElement,attributeTypings as attributes,audioCodecs,clientProtocol,compareVersions,createAudioAnalyser,createE2EEKey,createKeyMaterialFromBuffer,createKeyMaterialFromString,createLocalAudioTrack,createLocalScreenTracks,createLocalTracks,createLocalVideoTrack,decodeTokenPayload,deriveKeys,detachTrack,facingModeFromDeviceLabel,facingModeFromLocalTrack,getBrowser,getEmptyAudioStreamTrack,getEmptyVideoStreamTrack,getLogger,importKey,isAudioCodec,isAudioTrack,isBackupCodec,isBackupVideoCodec,isBrowserSupported,isE2EESupported,isInsertableStreamSupported,isLocalParticipant,isLocalTrack,isRemoteParticipant,isRemoteTrack,isScriptTransformSupported,isSerializer,isVideoCodec,isVideoFrame,isVideoTrack,needsRbspUnescaping,parseRbsp,protocolVersion,ratchet,serializers,setLogExtension,setLogLevel,supportsAV1,supportsAdaptiveStream,supportsAudioOutputSelection,supportsDynacast,supportsVP9,version,videoCodecs,writeRbsp};//# sourceMappingURL=livekit-client.esm.mjs.map
33218
+ };export{AudioPresets,BackupCodecPolicy,BaseKeyProvider,CLIENT_PROTOCOL_DATA_STREAM_RPC,CLIENT_PROTOCOL_DEFAULT,CheckStatus,Checker,ConnectionCheck,ConnectionError,ConnectionErrorReason,ConnectionQuality,ConnectionState,CriticalTimers,CryptorError,CryptorErrorReason,CryptorEvent,DataPacket_Kind,DataStreamError,DataStreamErrorReason,DataTrackPacket,DefaultReconnectPolicy,DeviceUnsupportedError,DisconnectReason,EncryptionEvent,Encryption_Type,EngineEvent,ExternalE2EEKeyProvider,FrameMetadataManager,KeyHandlerEvent,KeyProviderEvent,LivekitError,LivekitReasonedError,LocalAudioTrack,LocalDataTrack,LocalParticipant,LocalTrack,LocalTrackPublication,LocalTrackRecorder,LocalVideoTrack,LogLevel,LoggerNames,MediaDeviceFailure,_ as Mutex,NegotiationError,PacketTrailerManager,Participant,ParticipantEvent,ParticipantInfo_Kind as ParticipantKind,PublishDataError,PublishTrackError,RemoteAudioTrack,RemoteDataTrack,RemoteParticipant,RemoteTrack,RemoteTrackPublication,RemoteVideoTrack,Room,RoomEvent,RpcError,ScreenSharePresets,SignalReconnectError,SignalRequestError,SimulatedError,SubscriptionError,TokenSource,TokenSourceConfigurable,TokenSourceFixed,Track,TrackEvent,TrackInvalidError,TrackPublication,TrackType,UnexpectedConnectionState,UnsupportedServer,VideoPreset,VideoPresets,VideoPresets43,VideoQuality,areTokenSourceFetchOptionsEqual,asEncryptablePacket,attachToElement,attributeTypings as attributes,audioCodecs,clientProtocol,compareVersions,createAudioAnalyser,createE2EEKey,createKeyMaterialFromBuffer,createKeyMaterialFromString,createLocalAudioTrack,createLocalScreenTracks,createLocalTracks,createLocalVideoTrack,decodeTokenPayload,deriveKeys,detachTrack,facingModeFromDeviceLabel,facingModeFromLocalTrack,getBrowser,getEmptyAudioStreamTrack,getEmptyVideoStreamTrack,getLogger,importKey,isAudioCodec,isAudioTrack,isBackupCodec,isBackupVideoCodec,isBrowserSupported,isE2EESupported,isInsertableStreamSupported,isLocalParticipant,isLocalTrack,isRemoteParticipant,isRemoteTrack,isScriptTransformSupported,isSerializer,isVideoCodec,isVideoFrame,isVideoTrack,needsRbspUnescaping,parseRbsp,protocolVersion,ratchet,serializers,setLogExtension,setLogLevel,supportsAV1,supportsAdaptiveStream,supportsAudioOutputSelection,supportsDynacast,supportsVP9,version,videoCodecs,writeRbsp};//# sourceMappingURL=livekit-client.esm.mjs.map