livekit-client 2.15.7 → 2.15.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) 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 +253 -118
  4. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  5. package/dist/livekit-client.esm.mjs +2442 -323
  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 +31 -2
  10. package/dist/src/api/SignalClient.d.ts.map +1 -1
  11. package/dist/src/api/WebSocketStream.d.ts +29 -0
  12. package/dist/src/api/WebSocketStream.d.ts.map +1 -0
  13. package/dist/src/api/utils.d.ts +2 -0
  14. package/dist/src/api/utils.d.ts.map +1 -1
  15. package/dist/src/connectionHelper/checks/publishVideo.d.ts.map +1 -1
  16. package/dist/src/connectionHelper/checks/turn.d.ts.map +1 -1
  17. package/dist/src/connectionHelper/checks/websocket.d.ts.map +1 -1
  18. package/dist/src/e2ee/E2eeManager.d.ts +16 -2
  19. package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
  20. package/dist/src/e2ee/types.d.ts +35 -1
  21. package/dist/src/e2ee/types.d.ts.map +1 -1
  22. package/dist/src/e2ee/utils.d.ts +2 -0
  23. package/dist/src/e2ee/utils.d.ts.map +1 -1
  24. package/dist/src/e2ee/worker/DataCryptor.d.ts +15 -0
  25. package/dist/src/e2ee/worker/DataCryptor.d.ts.map +1 -0
  26. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts +3 -2
  27. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts.map +1 -1
  28. package/dist/src/e2ee/worker/sifPayload.d.ts +6 -6
  29. package/dist/src/e2ee/worker/sifPayload.d.ts.map +1 -1
  30. package/dist/src/index.d.ts +5 -3
  31. package/dist/src/index.d.ts.map +1 -1
  32. package/dist/src/logger.d.ts +1 -0
  33. package/dist/src/logger.d.ts.map +1 -1
  34. package/dist/src/options.d.ts +10 -2
  35. package/dist/src/options.d.ts.map +1 -1
  36. package/dist/src/room/PCTransport.d.ts +1 -0
  37. package/dist/src/room/PCTransport.d.ts.map +1 -1
  38. package/dist/src/room/PCTransportManager.d.ts +6 -4
  39. package/dist/src/room/PCTransportManager.d.ts.map +1 -1
  40. package/dist/src/room/RTCEngine.d.ts +6 -3
  41. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  42. package/dist/src/room/Room.d.ts +3 -2
  43. package/dist/src/room/Room.d.ts.map +1 -1
  44. package/dist/src/room/data-stream/incoming/IncomingDataStreamManager.d.ts +2 -2
  45. package/dist/src/room/data-stream/incoming/IncomingDataStreamManager.d.ts.map +1 -1
  46. package/dist/src/room/data-stream/outgoing/OutgoingDataStreamManager.d.ts.map +1 -1
  47. package/dist/src/room/defaults.d.ts.map +1 -1
  48. package/dist/src/room/errors.d.ts +2 -1
  49. package/dist/src/room/errors.d.ts.map +1 -1
  50. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  51. package/dist/src/room/participant/Participant.d.ts +2 -2
  52. package/dist/src/room/participant/Participant.d.ts.map +1 -1
  53. package/dist/src/room/token-source/TokenSource.d.ts +70 -0
  54. package/dist/src/room/token-source/TokenSource.d.ts.map +1 -0
  55. package/dist/src/room/token-source/types.d.ts +68 -0
  56. package/dist/src/room/token-source/types.d.ts.map +1 -0
  57. package/dist/src/room/token-source/utils.d.ts +5 -0
  58. package/dist/src/room/token-source/utils.d.ts.map +1 -0
  59. package/dist/src/room/track/LocalTrack.d.ts +1 -1
  60. package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
  61. package/dist/src/room/track/options.d.ts +7 -3
  62. package/dist/src/room/track/options.d.ts.map +1 -1
  63. package/dist/src/room/track/utils.d.ts.map +1 -1
  64. package/dist/src/room/types.d.ts +1 -0
  65. package/dist/src/room/types.d.ts.map +1 -1
  66. package/dist/src/room/utils.d.ts +8 -1
  67. package/dist/src/room/utils.d.ts.map +1 -1
  68. package/dist/src/utils/camelToSnakeCase.d.ts +8 -0
  69. package/dist/src/utils/camelToSnakeCase.d.ts.map +1 -0
  70. package/dist/ts4.2/{src/api → api}/SignalClient.d.ts +31 -2
  71. package/dist/ts4.2/api/WebSocketStream.d.ts +29 -0
  72. package/dist/ts4.2/{src/api → api}/utils.d.ts +2 -0
  73. package/dist/ts4.2/{src/e2ee → e2ee}/E2eeManager.d.ts +16 -2
  74. package/dist/ts4.2/{src/e2ee → e2ee}/types.d.ts +35 -1
  75. package/dist/ts4.2/{src/e2ee → e2ee}/utils.d.ts +3 -0
  76. package/dist/ts4.2/e2ee/worker/DataCryptor.d.ts +15 -0
  77. package/dist/ts4.2/{src/e2ee → e2ee}/worker/ParticipantKeyHandler.d.ts +3 -2
  78. package/dist/ts4.2/{src/e2ee → e2ee}/worker/sifPayload.d.ts +6 -6
  79. package/dist/ts4.2/{src/index.d.ts → index.d.ts} +5 -3
  80. package/dist/ts4.2/{src/logger.d.ts → logger.d.ts} +1 -0
  81. package/dist/ts4.2/{src/options.d.ts → options.d.ts} +10 -2
  82. package/dist/ts4.2/{src/room → room}/PCTransport.d.ts +1 -0
  83. package/dist/ts4.2/{src/room → room}/PCTransportManager.d.ts +6 -4
  84. package/dist/ts4.2/{src/room → room}/RTCEngine.d.ts +6 -3
  85. package/dist/ts4.2/{src/room → room}/Room.d.ts +3 -2
  86. package/dist/ts4.2/{src/room → room}/data-stream/incoming/IncomingDataStreamManager.d.ts +2 -1
  87. package/dist/ts4.2/{src/room → room}/errors.d.ts +2 -1
  88. package/dist/ts4.2/{src/room → room}/participant/Participant.d.ts +2 -2
  89. package/dist/ts4.2/room/token-source/TokenSource.d.ts +71 -0
  90. package/dist/ts4.2/room/token-source/types.d.ts +68 -0
  91. package/dist/ts4.2/room/token-source/utils.d.ts +5 -0
  92. package/dist/ts4.2/{src/room → room}/track/LocalTrack.d.ts +1 -1
  93. package/dist/ts4.2/{src/room → room}/track/options.d.ts +10 -3
  94. package/dist/ts4.2/{src/room → room}/types.d.ts +1 -0
  95. package/dist/ts4.2/{src/room → room}/utils.d.ts +8 -1
  96. package/dist/ts4.2/utils/camelToSnakeCase.d.ts +8 -0
  97. package/package.json +11 -10
  98. package/src/api/SignalClient.test.ts +688 -0
  99. package/src/api/SignalClient.ts +308 -161
  100. package/src/api/WebSocketStream.test.ts +625 -0
  101. package/src/api/WebSocketStream.ts +118 -0
  102. package/src/api/utils.ts +10 -0
  103. package/src/connectionHelper/checks/publishVideo.ts +5 -0
  104. package/src/connectionHelper/checks/turn.ts +1 -0
  105. package/src/connectionHelper/checks/webrtc.ts +1 -1
  106. package/src/connectionHelper/checks/websocket.ts +1 -0
  107. package/src/e2ee/E2eeManager.ts +94 -2
  108. package/src/e2ee/types.ts +44 -1
  109. package/src/e2ee/utils.ts +16 -0
  110. package/src/e2ee/worker/DataCryptor.test.ts +271 -0
  111. package/src/e2ee/worker/DataCryptor.ts +147 -0
  112. package/src/e2ee/worker/ParticipantKeyHandler.ts +4 -3
  113. package/src/e2ee/worker/e2ee.worker.ts +47 -0
  114. package/src/e2ee/worker/sifPayload.ts +10 -6
  115. package/src/index.ts +16 -1
  116. package/src/logger.ts +1 -0
  117. package/src/options.ts +15 -2
  118. package/src/room/PCTransport.ts +7 -3
  119. package/src/room/PCTransportManager.ts +39 -35
  120. package/src/room/RTCEngine.ts +109 -22
  121. package/src/room/Room.ts +43 -18
  122. package/src/room/data-stream/incoming/IncomingDataStreamManager.ts +64 -17
  123. package/src/room/data-stream/outgoing/OutgoingDataStreamManager.ts +7 -0
  124. package/src/room/defaults.ts +1 -0
  125. package/src/room/errors.ts +3 -0
  126. package/src/room/participant/LocalParticipant.ts +8 -6
  127. package/src/room/participant/Participant.ts +6 -1
  128. package/src/room/token-source/TokenSource.ts +285 -0
  129. package/src/room/token-source/types.ts +84 -0
  130. package/src/room/token-source/utils.test.ts +63 -0
  131. package/src/room/token-source/utils.ts +40 -0
  132. package/src/room/track/LocalAudioTrack.ts +1 -1
  133. package/src/room/track/LocalTrack.ts +1 -1
  134. package/src/room/track/options.ts +12 -4
  135. package/src/room/track/utils.ts +10 -2
  136. package/src/room/types.ts +1 -0
  137. package/src/room/utils.ts +37 -4
  138. package/src/utils/camelToSnakeCase.ts +16 -0
  139. /package/dist/ts4.2/{src/connectionHelper → connectionHelper}/ConnectionCheck.d.ts +0 -0
  140. /package/dist/ts4.2/{src/connectionHelper → connectionHelper}/checks/Checker.d.ts +0 -0
  141. /package/dist/ts4.2/{src/connectionHelper → connectionHelper}/checks/cloudRegion.d.ts +0 -0
  142. /package/dist/ts4.2/{src/connectionHelper → connectionHelper}/checks/connectionProtocol.d.ts +0 -0
  143. /package/dist/ts4.2/{src/connectionHelper → connectionHelper}/checks/publishAudio.d.ts +0 -0
  144. /package/dist/ts4.2/{src/connectionHelper → connectionHelper}/checks/publishVideo.d.ts +0 -0
  145. /package/dist/ts4.2/{src/connectionHelper → connectionHelper}/checks/reconnect.d.ts +0 -0
  146. /package/dist/ts4.2/{src/connectionHelper → connectionHelper}/checks/turn.d.ts +0 -0
  147. /package/dist/ts4.2/{src/connectionHelper → connectionHelper}/checks/webrtc.d.ts +0 -0
  148. /package/dist/ts4.2/{src/connectionHelper → connectionHelper}/checks/websocket.d.ts +0 -0
  149. /package/dist/ts4.2/{src/e2ee → e2ee}/KeyProvider.d.ts +0 -0
  150. /package/dist/ts4.2/{src/e2ee → e2ee}/constants.d.ts +0 -0
  151. /package/dist/ts4.2/{src/e2ee → e2ee}/errors.d.ts +0 -0
  152. /package/dist/ts4.2/{src/e2ee → e2ee}/events.d.ts +0 -0
  153. /package/dist/ts4.2/{src/e2ee → e2ee}/index.d.ts +0 -0
  154. /package/dist/ts4.2/{src/e2ee → e2ee}/worker/FrameCryptor.d.ts +0 -0
  155. /package/dist/ts4.2/{src/e2ee → e2ee}/worker/e2ee.worker.d.ts +0 -0
  156. /package/dist/ts4.2/{src/e2ee → e2ee}/worker/naluUtils.d.ts +0 -0
  157. /package/dist/ts4.2/{src/room → room}/DefaultReconnectPolicy.d.ts +0 -0
  158. /package/dist/ts4.2/{src/room → room}/DeviceManager.d.ts +0 -0
  159. /package/dist/ts4.2/{src/room → room}/ReconnectPolicy.d.ts +0 -0
  160. /package/dist/ts4.2/{src/room → room}/RegionUrlProvider.d.ts +0 -0
  161. /package/dist/ts4.2/{src/room → room}/attribute-typings.d.ts +0 -0
  162. /package/dist/ts4.2/{src/room → room}/data-stream/incoming/StreamReader.d.ts +0 -0
  163. /package/dist/ts4.2/{src/room → room}/data-stream/outgoing/OutgoingDataStreamManager.d.ts +0 -0
  164. /package/dist/ts4.2/{src/room → room}/data-stream/outgoing/StreamWriter.d.ts +0 -0
  165. /package/dist/ts4.2/{src/room → room}/defaults.d.ts +0 -0
  166. /package/dist/ts4.2/{src/room → room}/events.d.ts +0 -0
  167. /package/dist/ts4.2/{src/room → room}/participant/LocalParticipant.d.ts +0 -0
  168. /package/dist/ts4.2/{src/room → room}/participant/ParticipantTrackPermission.d.ts +0 -0
  169. /package/dist/ts4.2/{src/room → room}/participant/RemoteParticipant.d.ts +0 -0
  170. /package/dist/ts4.2/{src/room → room}/participant/publishUtils.d.ts +0 -0
  171. /package/dist/ts4.2/{src/room → room}/rpc.d.ts +0 -0
  172. /package/dist/ts4.2/{src/room → room}/stats.d.ts +0 -0
  173. /package/dist/ts4.2/{src/room → room}/timers.d.ts +0 -0
  174. /package/dist/ts4.2/{src/room → room}/track/LocalAudioTrack.d.ts +0 -0
  175. /package/dist/ts4.2/{src/room → room}/track/LocalTrackPublication.d.ts +0 -0
  176. /package/dist/ts4.2/{src/room → room}/track/LocalVideoTrack.d.ts +0 -0
  177. /package/dist/ts4.2/{src/room → room}/track/RemoteAudioTrack.d.ts +0 -0
  178. /package/dist/ts4.2/{src/room → room}/track/RemoteTrack.d.ts +0 -0
  179. /package/dist/ts4.2/{src/room → room}/track/RemoteTrackPublication.d.ts +0 -0
  180. /package/dist/ts4.2/{src/room → room}/track/RemoteVideoTrack.d.ts +0 -0
  181. /package/dist/ts4.2/{src/room → room}/track/Track.d.ts +0 -0
  182. /package/dist/ts4.2/{src/room → room}/track/TrackPublication.d.ts +0 -0
  183. /package/dist/ts4.2/{src/room → room}/track/create.d.ts +0 -0
  184. /package/dist/ts4.2/{src/room → room}/track/facingMode.d.ts +0 -0
  185. /package/dist/ts4.2/{src/room → room}/track/processor/types.d.ts +0 -0
  186. /package/dist/ts4.2/{src/room → room}/track/record.d.ts +0 -0
  187. /package/dist/ts4.2/{src/room → room}/track/types.d.ts +0 -0
  188. /package/dist/ts4.2/{src/room → room}/track/utils.d.ts +0 -0
  189. /package/dist/ts4.2/{src/test → test}/MockMediaStreamTrack.d.ts +0 -0
  190. /package/dist/ts4.2/{src/test → test}/mocks.d.ts +0 -0
  191. /package/dist/ts4.2/{src/utils → utils}/AsyncQueue.d.ts +0 -0
  192. /package/dist/ts4.2/{src/utils → utils}/browserParser.d.ts +0 -0
  193. /package/dist/ts4.2/{src/utils → utils}/cloneDeep.d.ts +0 -0
  194. /package/dist/ts4.2/{src/utils → utils}/dataPacketBuffer.d.ts +0 -0
  195. /package/dist/ts4.2/{src/utils → utils}/ttlmap.d.ts +0 -0
  196. /package/dist/ts4.2/{src/version.d.ts → version.d.ts} +0 -0
@@ -3780,6 +3780,42 @@ const EventMetric = /* @__PURE__ */proto3.makeMessageType("livekit.EventMetric",
3780
3780
  T: 13
3781
3781
  /* ScalarType.UINT32 */
3782
3782
  }]);
3783
+ const AudioCodec = /* @__PURE__ */proto3.makeEnum("livekit.AudioCodec", [{
3784
+ no: 0,
3785
+ name: "DEFAULT_AC"
3786
+ }, {
3787
+ no: 1,
3788
+ name: "OPUS"
3789
+ }, {
3790
+ no: 2,
3791
+ name: "AAC"
3792
+ }, {
3793
+ no: 3,
3794
+ name: "AC_MP3"
3795
+ }]);
3796
+ const VideoCodec = /* @__PURE__ */proto3.makeEnum("livekit.VideoCodec", [{
3797
+ no: 0,
3798
+ name: "DEFAULT_VC"
3799
+ }, {
3800
+ no: 1,
3801
+ name: "H264_BASELINE"
3802
+ }, {
3803
+ no: 2,
3804
+ name: "H264_MAIN"
3805
+ }, {
3806
+ no: 3,
3807
+ name: "H264_HIGH"
3808
+ }, {
3809
+ no: 4,
3810
+ name: "VP8"
3811
+ }]);
3812
+ const ImageCodec = /* @__PURE__ */proto3.makeEnum("livekit.ImageCodec", [{
3813
+ no: 0,
3814
+ name: "IC_DEFAULT"
3815
+ }, {
3816
+ no: 1,
3817
+ name: "IC_JPEG"
3818
+ }]);
3783
3819
  const BackupCodecPolicy$1 = /* @__PURE__ */proto3.makeEnum("livekit.BackupCodecPolicy", [{
3784
3820
  no: 0,
3785
3821
  name: "PREFER_REGRESSION"
@@ -4268,6 +4304,17 @@ const SimulcastCodecInfo = /* @__PURE__ */proto3.makeMessageType("livekit.Simulc
4268
4304
  kind: "message",
4269
4305
  T: VideoLayer,
4270
4306
  repeated: true
4307
+ }, {
4308
+ no: 5,
4309
+ name: "video_layer_mode",
4310
+ kind: "enum",
4311
+ T: proto3.getEnumType(VideoLayer_Mode)
4312
+ }, {
4313
+ no: 6,
4314
+ name: "sdp_cid",
4315
+ kind: "scalar",
4316
+ T: 9
4317
+ /* ScalarType.STRING */
4271
4318
  }]);
4272
4319
  const TrackInfo = /* @__PURE__ */proto3.makeMessageType("livekit.TrackInfo", () => [{
4273
4320
  no: 1,
@@ -4427,6 +4474,19 @@ const VideoLayer = /* @__PURE__ */proto3.makeMessageType("livekit.VideoLayer", (
4427
4474
  T: 9
4428
4475
  /* ScalarType.STRING */
4429
4476
  }]);
4477
+ const VideoLayer_Mode = /* @__PURE__ */proto3.makeEnum("livekit.VideoLayer.Mode", [{
4478
+ no: 0,
4479
+ name: "MODE_UNUSED"
4480
+ }, {
4481
+ no: 1,
4482
+ name: "ONE_SPATIAL_LAYER_PER_STREAM"
4483
+ }, {
4484
+ no: 2,
4485
+ name: "MULTIPLE_SPATIAL_LAYERS_PER_STREAM"
4486
+ }, {
4487
+ no: 3,
4488
+ name: "ONE_SPATIAL_LAYER_PER_STREAM_INCOMPLETE_RTCP_SR"
4489
+ }]);
4430
4490
  const DataPacket = /* @__PURE__ */proto3.makeMessageType("livekit.DataPacket", () => [{
4431
4491
  no: 1,
4432
4492
  name: "kind",
@@ -4516,6 +4576,12 @@ const DataPacket = /* @__PURE__ */proto3.makeMessageType("livekit.DataPacket", (
4516
4576
  kind: "message",
4517
4577
  T: DataStream_Trailer,
4518
4578
  oneof: "value"
4579
+ }, {
4580
+ no: 18,
4581
+ name: "encrypted_packet",
4582
+ kind: "message",
4583
+ T: EncryptedPacket,
4584
+ oneof: "value"
4519
4585
  }, {
4520
4586
  no: 16,
4521
4587
  name: "sequence",
@@ -4536,6 +4602,79 @@ const DataPacket_Kind = /* @__PURE__ */proto3.makeEnum("livekit.DataPacket.Kind"
4536
4602
  no: 1,
4537
4603
  name: "LOSSY"
4538
4604
  }]);
4605
+ const EncryptedPacket = /* @__PURE__ */proto3.makeMessageType("livekit.EncryptedPacket", () => [{
4606
+ no: 1,
4607
+ name: "encryption_type",
4608
+ kind: "enum",
4609
+ T: proto3.getEnumType(Encryption_Type)
4610
+ }, {
4611
+ no: 2,
4612
+ name: "iv",
4613
+ kind: "scalar",
4614
+ T: 12
4615
+ /* ScalarType.BYTES */
4616
+ }, {
4617
+ no: 3,
4618
+ name: "key_index",
4619
+ kind: "scalar",
4620
+ T: 13
4621
+ /* ScalarType.UINT32 */
4622
+ }, {
4623
+ no: 4,
4624
+ name: "encrypted_value",
4625
+ kind: "scalar",
4626
+ T: 12
4627
+ /* ScalarType.BYTES */
4628
+ }]);
4629
+ const EncryptedPacketPayload = /* @__PURE__ */proto3.makeMessageType("livekit.EncryptedPacketPayload", () => [{
4630
+ no: 1,
4631
+ name: "user",
4632
+ kind: "message",
4633
+ T: UserPacket,
4634
+ oneof: "value"
4635
+ }, {
4636
+ no: 3,
4637
+ name: "chat_message",
4638
+ kind: "message",
4639
+ T: ChatMessage,
4640
+ oneof: "value"
4641
+ }, {
4642
+ no: 4,
4643
+ name: "rpc_request",
4644
+ kind: "message",
4645
+ T: RpcRequest,
4646
+ oneof: "value"
4647
+ }, {
4648
+ no: 5,
4649
+ name: "rpc_ack",
4650
+ kind: "message",
4651
+ T: RpcAck,
4652
+ oneof: "value"
4653
+ }, {
4654
+ no: 6,
4655
+ name: "rpc_response",
4656
+ kind: "message",
4657
+ T: RpcResponse,
4658
+ oneof: "value"
4659
+ }, {
4660
+ no: 7,
4661
+ name: "stream_header",
4662
+ kind: "message",
4663
+ T: DataStream_Header,
4664
+ oneof: "value"
4665
+ }, {
4666
+ no: 8,
4667
+ name: "stream_chunk",
4668
+ kind: "message",
4669
+ T: DataStream_Chunk,
4670
+ oneof: "value"
4671
+ }, {
4672
+ no: 9,
4673
+ name: "stream_trailer",
4674
+ kind: "message",
4675
+ T: DataStream_Trailer,
4676
+ oneof: "value"
4677
+ }]);
4539
4678
  const ActiveSpeakerUpdate = /* @__PURE__ */proto3.makeMessageType("livekit.ActiveSpeakerUpdate", () => [{
4540
4679
  no: 1,
4541
4680
  name: "speakers",
@@ -5209,93 +5348,872 @@ const DataStream_Trailer = /* @__PURE__ */proto3.makeMessageType("livekit.DataSt
5209
5348
  }], {
5210
5349
  localName: "DataStream_Trailer"
5211
5350
  });
5212
- const SignalTarget = /* @__PURE__ */proto3.makeEnum("livekit.SignalTarget", [{
5351
+ const WebhookConfig = /* @__PURE__ */proto3.makeMessageType("livekit.WebhookConfig", () => [{
5352
+ no: 1,
5353
+ name: "url",
5354
+ kind: "scalar",
5355
+ T: 9
5356
+ /* ScalarType.STRING */
5357
+ }, {
5358
+ no: 2,
5359
+ name: "signing_key",
5360
+ kind: "scalar",
5361
+ T: 9
5362
+ /* ScalarType.STRING */
5363
+ }]);
5364
+ const SubscribedAudioCodec = /* @__PURE__ */proto3.makeMessageType("livekit.SubscribedAudioCodec", () => [{
5365
+ no: 1,
5366
+ name: "codec",
5367
+ kind: "scalar",
5368
+ T: 9
5369
+ /* ScalarType.STRING */
5370
+ }, {
5371
+ no: 2,
5372
+ name: "enabled",
5373
+ kind: "scalar",
5374
+ T: 8
5375
+ /* ScalarType.BOOL */
5376
+ }]);
5377
+ const RoomAgentDispatch = /* @__PURE__ */proto3.makeMessageType("livekit.RoomAgentDispatch", () => [{
5378
+ no: 1,
5379
+ name: "agent_name",
5380
+ kind: "scalar",
5381
+ T: 9
5382
+ /* ScalarType.STRING */
5383
+ }, {
5384
+ no: 2,
5385
+ name: "metadata",
5386
+ kind: "scalar",
5387
+ T: 9
5388
+ /* ScalarType.STRING */
5389
+ }]);
5390
+ const EncodedFileType = /* @__PURE__ */proto3.makeEnum("livekit.EncodedFileType", [{
5213
5391
  no: 0,
5214
- name: "PUBLISHER"
5392
+ name: "DEFAULT_FILETYPE"
5215
5393
  }, {
5216
5394
  no: 1,
5217
- name: "SUBSCRIBER"
5395
+ name: "MP4"
5396
+ }, {
5397
+ no: 2,
5398
+ name: "OGG"
5399
+ }, {
5400
+ no: 3,
5401
+ name: "MP3"
5218
5402
  }]);
5219
- const StreamState = /* @__PURE__ */proto3.makeEnum("livekit.StreamState", [{
5403
+ const SegmentedFileProtocol = /* @__PURE__ */proto3.makeEnum("livekit.SegmentedFileProtocol", [{
5220
5404
  no: 0,
5221
- name: "ACTIVE"
5405
+ name: "DEFAULT_SEGMENTED_FILE_PROTOCOL"
5222
5406
  }, {
5223
5407
  no: 1,
5224
- name: "PAUSED"
5408
+ name: "HLS_PROTOCOL"
5225
5409
  }]);
5226
- const CandidateProtocol = /* @__PURE__ */proto3.makeEnum("livekit.CandidateProtocol", [{
5410
+ const SegmentedFileSuffix = /* @__PURE__ */proto3.makeEnum("livekit.SegmentedFileSuffix", [{
5227
5411
  no: 0,
5228
- name: "UDP"
5412
+ name: "INDEX"
5229
5413
  }, {
5230
5414
  no: 1,
5231
- name: "TCP"
5415
+ name: "TIMESTAMP"
5416
+ }]);
5417
+ const ImageFileSuffix = /* @__PURE__ */proto3.makeEnum("livekit.ImageFileSuffix", [{
5418
+ no: 0,
5419
+ name: "IMAGE_SUFFIX_INDEX"
5420
+ }, {
5421
+ no: 1,
5422
+ name: "IMAGE_SUFFIX_TIMESTAMP"
5232
5423
  }, {
5233
5424
  no: 2,
5234
- name: "TLS"
5425
+ name: "IMAGE_SUFFIX_NONE_OVERWRITE"
5235
5426
  }]);
5236
- const SignalRequest = /* @__PURE__ */proto3.makeMessageType("livekit.SignalRequest", () => [{
5427
+ const StreamProtocol = /* @__PURE__ */proto3.makeEnum("livekit.StreamProtocol", [{
5428
+ no: 0,
5429
+ name: "DEFAULT_PROTOCOL"
5430
+ }, {
5237
5431
  no: 1,
5238
- name: "offer",
5239
- kind: "message",
5240
- T: SessionDescription,
5241
- oneof: "message"
5432
+ name: "RTMP"
5242
5433
  }, {
5243
5434
  no: 2,
5244
- name: "answer",
5245
- kind: "message",
5246
- T: SessionDescription,
5247
- oneof: "message"
5435
+ name: "SRT"
5436
+ }]);
5437
+ const AudioMixing = /* @__PURE__ */proto3.makeEnum("livekit.AudioMixing", [{
5438
+ no: 0,
5439
+ name: "DEFAULT_MIXING"
5440
+ }, {
5441
+ no: 1,
5442
+ name: "DUAL_CHANNEL_AGENT"
5443
+ }, {
5444
+ no: 2,
5445
+ name: "DUAL_CHANNEL_ALTERNATE"
5446
+ }]);
5447
+ const EncodingOptionsPreset = /* @__PURE__ */proto3.makeEnum("livekit.EncodingOptionsPreset", [{
5448
+ no: 0,
5449
+ name: "H264_720P_30"
5450
+ }, {
5451
+ no: 1,
5452
+ name: "H264_720P_60"
5453
+ }, {
5454
+ no: 2,
5455
+ name: "H264_1080P_30"
5248
5456
  }, {
5249
5457
  no: 3,
5250
- name: "trickle",
5251
- kind: "message",
5252
- T: TrickleRequest,
5253
- oneof: "message"
5458
+ name: "H264_1080P_60"
5254
5459
  }, {
5255
5460
  no: 4,
5256
- name: "add_track",
5257
- kind: "message",
5258
- T: AddTrackRequest,
5259
- oneof: "message"
5461
+ name: "PORTRAIT_H264_720P_30"
5260
5462
  }, {
5261
5463
  no: 5,
5262
- name: "mute",
5263
- kind: "message",
5264
- T: MuteTrackRequest,
5265
- oneof: "message"
5464
+ name: "PORTRAIT_H264_720P_60"
5266
5465
  }, {
5267
5466
  no: 6,
5268
- name: "subscription",
5269
- kind: "message",
5270
- T: UpdateSubscription,
5271
- oneof: "message"
5467
+ name: "PORTRAIT_H264_1080P_30"
5272
5468
  }, {
5273
5469
  no: 7,
5274
- name: "track_setting",
5470
+ name: "PORTRAIT_H264_1080P_60"
5471
+ }]);
5472
+ const RoomCompositeEgressRequest = /* @__PURE__ */proto3.makeMessageType("livekit.RoomCompositeEgressRequest", () => [{
5473
+ no: 1,
5474
+ name: "room_name",
5475
+ kind: "scalar",
5476
+ T: 9
5477
+ /* ScalarType.STRING */
5478
+ }, {
5479
+ no: 2,
5480
+ name: "layout",
5481
+ kind: "scalar",
5482
+ T: 9
5483
+ /* ScalarType.STRING */
5484
+ }, {
5485
+ no: 3,
5486
+ name: "audio_only",
5487
+ kind: "scalar",
5488
+ T: 8
5489
+ /* ScalarType.BOOL */
5490
+ }, {
5491
+ no: 15,
5492
+ name: "audio_mixing",
5493
+ kind: "enum",
5494
+ T: proto3.getEnumType(AudioMixing)
5495
+ }, {
5496
+ no: 4,
5497
+ name: "video_only",
5498
+ kind: "scalar",
5499
+ T: 8
5500
+ /* ScalarType.BOOL */
5501
+ }, {
5502
+ no: 5,
5503
+ name: "custom_base_url",
5504
+ kind: "scalar",
5505
+ T: 9
5506
+ /* ScalarType.STRING */
5507
+ }, {
5508
+ no: 6,
5509
+ name: "file",
5275
5510
  kind: "message",
5276
- T: UpdateTrackSettings,
5277
- oneof: "message"
5511
+ T: EncodedFileOutput,
5512
+ oneof: "output"
5278
5513
  }, {
5279
- no: 8,
5280
- name: "leave",
5514
+ no: 7,
5515
+ name: "stream",
5281
5516
  kind: "message",
5282
- T: LeaveRequest,
5283
- oneof: "message"
5517
+ T: StreamOutput,
5518
+ oneof: "output"
5284
5519
  }, {
5285
5520
  no: 10,
5286
- name: "update_layers",
5521
+ name: "segments",
5287
5522
  kind: "message",
5288
- T: UpdateVideoLayers,
5289
- oneof: "message"
5523
+ T: SegmentedFileOutput,
5524
+ oneof: "output"
5525
+ }, {
5526
+ no: 8,
5527
+ name: "preset",
5528
+ kind: "enum",
5529
+ T: proto3.getEnumType(EncodingOptionsPreset),
5530
+ oneof: "options"
5531
+ }, {
5532
+ no: 9,
5533
+ name: "advanced",
5534
+ kind: "message",
5535
+ T: EncodingOptions,
5536
+ oneof: "options"
5290
5537
  }, {
5291
5538
  no: 11,
5292
- name: "subscription_permission",
5539
+ name: "file_outputs",
5293
5540
  kind: "message",
5294
- T: SubscriptionPermission,
5295
- oneof: "message"
5541
+ T: EncodedFileOutput,
5542
+ repeated: true
5296
5543
  }, {
5297
5544
  no: 12,
5298
- name: "sync_state",
5545
+ name: "stream_outputs",
5546
+ kind: "message",
5547
+ T: StreamOutput,
5548
+ repeated: true
5549
+ }, {
5550
+ no: 13,
5551
+ name: "segment_outputs",
5552
+ kind: "message",
5553
+ T: SegmentedFileOutput,
5554
+ repeated: true
5555
+ }, {
5556
+ no: 14,
5557
+ name: "image_outputs",
5558
+ kind: "message",
5559
+ T: ImageOutput,
5560
+ repeated: true
5561
+ }, {
5562
+ no: 16,
5563
+ name: "webhooks",
5564
+ kind: "message",
5565
+ T: WebhookConfig,
5566
+ repeated: true
5567
+ }]);
5568
+ const EncodedFileOutput = /* @__PURE__ */proto3.makeMessageType("livekit.EncodedFileOutput", () => [{
5569
+ no: 1,
5570
+ name: "file_type",
5571
+ kind: "enum",
5572
+ T: proto3.getEnumType(EncodedFileType)
5573
+ }, {
5574
+ no: 2,
5575
+ name: "filepath",
5576
+ kind: "scalar",
5577
+ T: 9
5578
+ /* ScalarType.STRING */
5579
+ }, {
5580
+ no: 6,
5581
+ name: "disable_manifest",
5582
+ kind: "scalar",
5583
+ T: 8
5584
+ /* ScalarType.BOOL */
5585
+ }, {
5586
+ no: 3,
5587
+ name: "s3",
5588
+ kind: "message",
5589
+ T: S3Upload,
5590
+ oneof: "output"
5591
+ }, {
5592
+ no: 4,
5593
+ name: "gcp",
5594
+ kind: "message",
5595
+ T: GCPUpload,
5596
+ oneof: "output"
5597
+ }, {
5598
+ no: 5,
5599
+ name: "azure",
5600
+ kind: "message",
5601
+ T: AzureBlobUpload,
5602
+ oneof: "output"
5603
+ }, {
5604
+ no: 7,
5605
+ name: "aliOSS",
5606
+ kind: "message",
5607
+ T: AliOSSUpload,
5608
+ oneof: "output"
5609
+ }]);
5610
+ const SegmentedFileOutput = /* @__PURE__ */proto3.makeMessageType("livekit.SegmentedFileOutput", () => [{
5611
+ no: 1,
5612
+ name: "protocol",
5613
+ kind: "enum",
5614
+ T: proto3.getEnumType(SegmentedFileProtocol)
5615
+ }, {
5616
+ no: 2,
5617
+ name: "filename_prefix",
5618
+ kind: "scalar",
5619
+ T: 9
5620
+ /* ScalarType.STRING */
5621
+ }, {
5622
+ no: 3,
5623
+ name: "playlist_name",
5624
+ kind: "scalar",
5625
+ T: 9
5626
+ /* ScalarType.STRING */
5627
+ }, {
5628
+ no: 11,
5629
+ name: "live_playlist_name",
5630
+ kind: "scalar",
5631
+ T: 9
5632
+ /* ScalarType.STRING */
5633
+ }, {
5634
+ no: 4,
5635
+ name: "segment_duration",
5636
+ kind: "scalar",
5637
+ T: 13
5638
+ /* ScalarType.UINT32 */
5639
+ }, {
5640
+ no: 10,
5641
+ name: "filename_suffix",
5642
+ kind: "enum",
5643
+ T: proto3.getEnumType(SegmentedFileSuffix)
5644
+ }, {
5645
+ no: 8,
5646
+ name: "disable_manifest",
5647
+ kind: "scalar",
5648
+ T: 8
5649
+ /* ScalarType.BOOL */
5650
+ }, {
5651
+ no: 5,
5652
+ name: "s3",
5653
+ kind: "message",
5654
+ T: S3Upload,
5655
+ oneof: "output"
5656
+ }, {
5657
+ no: 6,
5658
+ name: "gcp",
5659
+ kind: "message",
5660
+ T: GCPUpload,
5661
+ oneof: "output"
5662
+ }, {
5663
+ no: 7,
5664
+ name: "azure",
5665
+ kind: "message",
5666
+ T: AzureBlobUpload,
5667
+ oneof: "output"
5668
+ }, {
5669
+ no: 9,
5670
+ name: "aliOSS",
5671
+ kind: "message",
5672
+ T: AliOSSUpload,
5673
+ oneof: "output"
5674
+ }]);
5675
+ const ImageOutput = /* @__PURE__ */proto3.makeMessageType("livekit.ImageOutput", () => [{
5676
+ no: 1,
5677
+ name: "capture_interval",
5678
+ kind: "scalar",
5679
+ T: 13
5680
+ /* ScalarType.UINT32 */
5681
+ }, {
5682
+ no: 2,
5683
+ name: "width",
5684
+ kind: "scalar",
5685
+ T: 5
5686
+ /* ScalarType.INT32 */
5687
+ }, {
5688
+ no: 3,
5689
+ name: "height",
5690
+ kind: "scalar",
5691
+ T: 5
5692
+ /* ScalarType.INT32 */
5693
+ }, {
5694
+ no: 4,
5695
+ name: "filename_prefix",
5696
+ kind: "scalar",
5697
+ T: 9
5698
+ /* ScalarType.STRING */
5699
+ }, {
5700
+ no: 5,
5701
+ name: "filename_suffix",
5702
+ kind: "enum",
5703
+ T: proto3.getEnumType(ImageFileSuffix)
5704
+ }, {
5705
+ no: 6,
5706
+ name: "image_codec",
5707
+ kind: "enum",
5708
+ T: proto3.getEnumType(ImageCodec)
5709
+ }, {
5710
+ no: 7,
5711
+ name: "disable_manifest",
5712
+ kind: "scalar",
5713
+ T: 8
5714
+ /* ScalarType.BOOL */
5715
+ }, {
5716
+ no: 8,
5717
+ name: "s3",
5718
+ kind: "message",
5719
+ T: S3Upload,
5720
+ oneof: "output"
5721
+ }, {
5722
+ no: 9,
5723
+ name: "gcp",
5724
+ kind: "message",
5725
+ T: GCPUpload,
5726
+ oneof: "output"
5727
+ }, {
5728
+ no: 10,
5729
+ name: "azure",
5730
+ kind: "message",
5731
+ T: AzureBlobUpload,
5732
+ oneof: "output"
5733
+ }, {
5734
+ no: 11,
5735
+ name: "aliOSS",
5736
+ kind: "message",
5737
+ T: AliOSSUpload,
5738
+ oneof: "output"
5739
+ }]);
5740
+ const S3Upload = /* @__PURE__ */proto3.makeMessageType("livekit.S3Upload", () => [{
5741
+ no: 1,
5742
+ name: "access_key",
5743
+ kind: "scalar",
5744
+ T: 9
5745
+ /* ScalarType.STRING */
5746
+ }, {
5747
+ no: 2,
5748
+ name: "secret",
5749
+ kind: "scalar",
5750
+ T: 9
5751
+ /* ScalarType.STRING */
5752
+ }, {
5753
+ no: 11,
5754
+ name: "session_token",
5755
+ kind: "scalar",
5756
+ T: 9
5757
+ /* ScalarType.STRING */
5758
+ }, {
5759
+ no: 12,
5760
+ name: "assume_role_arn",
5761
+ kind: "scalar",
5762
+ T: 9
5763
+ /* ScalarType.STRING */
5764
+ }, {
5765
+ no: 13,
5766
+ name: "assume_role_external_id",
5767
+ kind: "scalar",
5768
+ T: 9
5769
+ /* ScalarType.STRING */
5770
+ }, {
5771
+ no: 3,
5772
+ name: "region",
5773
+ kind: "scalar",
5774
+ T: 9
5775
+ /* ScalarType.STRING */
5776
+ }, {
5777
+ no: 4,
5778
+ name: "endpoint",
5779
+ kind: "scalar",
5780
+ T: 9
5781
+ /* ScalarType.STRING */
5782
+ }, {
5783
+ no: 5,
5784
+ name: "bucket",
5785
+ kind: "scalar",
5786
+ T: 9
5787
+ /* ScalarType.STRING */
5788
+ }, {
5789
+ no: 6,
5790
+ name: "force_path_style",
5791
+ kind: "scalar",
5792
+ T: 8
5793
+ /* ScalarType.BOOL */
5794
+ }, {
5795
+ no: 7,
5796
+ name: "metadata",
5797
+ kind: "map",
5798
+ K: 9,
5799
+ V: {
5800
+ kind: "scalar",
5801
+ T: 9
5802
+ /* ScalarType.STRING */
5803
+ }
5804
+ }, {
5805
+ no: 8,
5806
+ name: "tagging",
5807
+ kind: "scalar",
5808
+ T: 9
5809
+ /* ScalarType.STRING */
5810
+ }, {
5811
+ no: 9,
5812
+ name: "content_disposition",
5813
+ kind: "scalar",
5814
+ T: 9
5815
+ /* ScalarType.STRING */
5816
+ }, {
5817
+ no: 10,
5818
+ name: "proxy",
5819
+ kind: "message",
5820
+ T: ProxyConfig
5821
+ }]);
5822
+ const GCPUpload = /* @__PURE__ */proto3.makeMessageType("livekit.GCPUpload", () => [{
5823
+ no: 1,
5824
+ name: "credentials",
5825
+ kind: "scalar",
5826
+ T: 9
5827
+ /* ScalarType.STRING */
5828
+ }, {
5829
+ no: 2,
5830
+ name: "bucket",
5831
+ kind: "scalar",
5832
+ T: 9
5833
+ /* ScalarType.STRING */
5834
+ }, {
5835
+ no: 3,
5836
+ name: "proxy",
5837
+ kind: "message",
5838
+ T: ProxyConfig
5839
+ }]);
5840
+ const AzureBlobUpload = /* @__PURE__ */proto3.makeMessageType("livekit.AzureBlobUpload", () => [{
5841
+ no: 1,
5842
+ name: "account_name",
5843
+ kind: "scalar",
5844
+ T: 9
5845
+ /* ScalarType.STRING */
5846
+ }, {
5847
+ no: 2,
5848
+ name: "account_key",
5849
+ kind: "scalar",
5850
+ T: 9
5851
+ /* ScalarType.STRING */
5852
+ }, {
5853
+ no: 3,
5854
+ name: "container_name",
5855
+ kind: "scalar",
5856
+ T: 9
5857
+ /* ScalarType.STRING */
5858
+ }]);
5859
+ const AliOSSUpload = /* @__PURE__ */proto3.makeMessageType("livekit.AliOSSUpload", () => [{
5860
+ no: 1,
5861
+ name: "access_key",
5862
+ kind: "scalar",
5863
+ T: 9
5864
+ /* ScalarType.STRING */
5865
+ }, {
5866
+ no: 2,
5867
+ name: "secret",
5868
+ kind: "scalar",
5869
+ T: 9
5870
+ /* ScalarType.STRING */
5871
+ }, {
5872
+ no: 3,
5873
+ name: "region",
5874
+ kind: "scalar",
5875
+ T: 9
5876
+ /* ScalarType.STRING */
5877
+ }, {
5878
+ no: 4,
5879
+ name: "endpoint",
5880
+ kind: "scalar",
5881
+ T: 9
5882
+ /* ScalarType.STRING */
5883
+ }, {
5884
+ no: 5,
5885
+ name: "bucket",
5886
+ kind: "scalar",
5887
+ T: 9
5888
+ /* ScalarType.STRING */
5889
+ }]);
5890
+ const ProxyConfig = /* @__PURE__ */proto3.makeMessageType("livekit.ProxyConfig", () => [{
5891
+ no: 1,
5892
+ name: "url",
5893
+ kind: "scalar",
5894
+ T: 9
5895
+ /* ScalarType.STRING */
5896
+ }, {
5897
+ no: 2,
5898
+ name: "username",
5899
+ kind: "scalar",
5900
+ T: 9
5901
+ /* ScalarType.STRING */
5902
+ }, {
5903
+ no: 3,
5904
+ name: "password",
5905
+ kind: "scalar",
5906
+ T: 9
5907
+ /* ScalarType.STRING */
5908
+ }]);
5909
+ const StreamOutput = /* @__PURE__ */proto3.makeMessageType("livekit.StreamOutput", () => [{
5910
+ no: 1,
5911
+ name: "protocol",
5912
+ kind: "enum",
5913
+ T: proto3.getEnumType(StreamProtocol)
5914
+ }, {
5915
+ no: 2,
5916
+ name: "urls",
5917
+ kind: "scalar",
5918
+ T: 9,
5919
+ repeated: true
5920
+ }]);
5921
+ const EncodingOptions = /* @__PURE__ */proto3.makeMessageType("livekit.EncodingOptions", () => [{
5922
+ no: 1,
5923
+ name: "width",
5924
+ kind: "scalar",
5925
+ T: 5
5926
+ /* ScalarType.INT32 */
5927
+ }, {
5928
+ no: 2,
5929
+ name: "height",
5930
+ kind: "scalar",
5931
+ T: 5
5932
+ /* ScalarType.INT32 */
5933
+ }, {
5934
+ no: 3,
5935
+ name: "depth",
5936
+ kind: "scalar",
5937
+ T: 5
5938
+ /* ScalarType.INT32 */
5939
+ }, {
5940
+ no: 4,
5941
+ name: "framerate",
5942
+ kind: "scalar",
5943
+ T: 5
5944
+ /* ScalarType.INT32 */
5945
+ }, {
5946
+ no: 5,
5947
+ name: "audio_codec",
5948
+ kind: "enum",
5949
+ T: proto3.getEnumType(AudioCodec)
5950
+ }, {
5951
+ no: 6,
5952
+ name: "audio_bitrate",
5953
+ kind: "scalar",
5954
+ T: 5
5955
+ /* ScalarType.INT32 */
5956
+ }, {
5957
+ no: 11,
5958
+ name: "audio_quality",
5959
+ kind: "scalar",
5960
+ T: 5
5961
+ /* ScalarType.INT32 */
5962
+ }, {
5963
+ no: 7,
5964
+ name: "audio_frequency",
5965
+ kind: "scalar",
5966
+ T: 5
5967
+ /* ScalarType.INT32 */
5968
+ }, {
5969
+ no: 8,
5970
+ name: "video_codec",
5971
+ kind: "enum",
5972
+ T: proto3.getEnumType(VideoCodec)
5973
+ }, {
5974
+ no: 9,
5975
+ name: "video_bitrate",
5976
+ kind: "scalar",
5977
+ T: 5
5978
+ /* ScalarType.INT32 */
5979
+ }, {
5980
+ no: 12,
5981
+ name: "video_quality",
5982
+ kind: "scalar",
5983
+ T: 5
5984
+ /* ScalarType.INT32 */
5985
+ }, {
5986
+ no: 10,
5987
+ name: "key_frame_interval",
5988
+ kind: "scalar",
5989
+ T: 1
5990
+ /* ScalarType.DOUBLE */
5991
+ }]);
5992
+ const AutoParticipantEgress = /* @__PURE__ */proto3.makeMessageType("livekit.AutoParticipantEgress", () => [{
5993
+ no: 1,
5994
+ name: "preset",
5995
+ kind: "enum",
5996
+ T: proto3.getEnumType(EncodingOptionsPreset),
5997
+ oneof: "options"
5998
+ }, {
5999
+ no: 2,
6000
+ name: "advanced",
6001
+ kind: "message",
6002
+ T: EncodingOptions,
6003
+ oneof: "options"
6004
+ }, {
6005
+ no: 3,
6006
+ name: "file_outputs",
6007
+ kind: "message",
6008
+ T: EncodedFileOutput,
6009
+ repeated: true
6010
+ }, {
6011
+ no: 4,
6012
+ name: "segment_outputs",
6013
+ kind: "message",
6014
+ T: SegmentedFileOutput,
6015
+ repeated: true
6016
+ }]);
6017
+ const AutoTrackEgress = /* @__PURE__ */proto3.makeMessageType("livekit.AutoTrackEgress", () => [{
6018
+ no: 1,
6019
+ name: "filepath",
6020
+ kind: "scalar",
6021
+ T: 9
6022
+ /* ScalarType.STRING */
6023
+ }, {
6024
+ no: 5,
6025
+ name: "disable_manifest",
6026
+ kind: "scalar",
6027
+ T: 8
6028
+ /* ScalarType.BOOL */
6029
+ }, {
6030
+ no: 2,
6031
+ name: "s3",
6032
+ kind: "message",
6033
+ T: S3Upload,
6034
+ oneof: "output"
6035
+ }, {
6036
+ no: 3,
6037
+ name: "gcp",
6038
+ kind: "message",
6039
+ T: GCPUpload,
6040
+ oneof: "output"
6041
+ }, {
6042
+ no: 4,
6043
+ name: "azure",
6044
+ kind: "message",
6045
+ T: AzureBlobUpload,
6046
+ oneof: "output"
6047
+ }, {
6048
+ no: 6,
6049
+ name: "aliOSS",
6050
+ kind: "message",
6051
+ T: AliOSSUpload,
6052
+ oneof: "output"
6053
+ }]);
6054
+ const RoomEgress = /* @__PURE__ */proto3.makeMessageType("livekit.RoomEgress", () => [{
6055
+ no: 1,
6056
+ name: "room",
6057
+ kind: "message",
6058
+ T: RoomCompositeEgressRequest
6059
+ }, {
6060
+ no: 3,
6061
+ name: "participant",
6062
+ kind: "message",
6063
+ T: AutoParticipantEgress
6064
+ }, {
6065
+ no: 2,
6066
+ name: "tracks",
6067
+ kind: "message",
6068
+ T: AutoTrackEgress
6069
+ }]);
6070
+ const RoomConfiguration = /* @__PURE__ */proto3.makeMessageType("livekit.RoomConfiguration", () => [{
6071
+ no: 1,
6072
+ name: "name",
6073
+ kind: "scalar",
6074
+ T: 9
6075
+ /* ScalarType.STRING */
6076
+ }, {
6077
+ no: 2,
6078
+ name: "empty_timeout",
6079
+ kind: "scalar",
6080
+ T: 13
6081
+ /* ScalarType.UINT32 */
6082
+ }, {
6083
+ no: 3,
6084
+ name: "departure_timeout",
6085
+ kind: "scalar",
6086
+ T: 13
6087
+ /* ScalarType.UINT32 */
6088
+ }, {
6089
+ no: 4,
6090
+ name: "max_participants",
6091
+ kind: "scalar",
6092
+ T: 13
6093
+ /* ScalarType.UINT32 */
6094
+ }, {
6095
+ no: 11,
6096
+ name: "metadata",
6097
+ kind: "scalar",
6098
+ T: 9
6099
+ /* ScalarType.STRING */
6100
+ }, {
6101
+ no: 5,
6102
+ name: "egress",
6103
+ kind: "message",
6104
+ T: RoomEgress
6105
+ }, {
6106
+ no: 7,
6107
+ name: "min_playout_delay",
6108
+ kind: "scalar",
6109
+ T: 13
6110
+ /* ScalarType.UINT32 */
6111
+ }, {
6112
+ no: 8,
6113
+ name: "max_playout_delay",
6114
+ kind: "scalar",
6115
+ T: 13
6116
+ /* ScalarType.UINT32 */
6117
+ }, {
6118
+ no: 9,
6119
+ name: "sync_streams",
6120
+ kind: "scalar",
6121
+ T: 8
6122
+ /* ScalarType.BOOL */
6123
+ }, {
6124
+ no: 10,
6125
+ name: "agents",
6126
+ kind: "message",
6127
+ T: RoomAgentDispatch,
6128
+ repeated: true
6129
+ }]);
6130
+ const SignalTarget = /* @__PURE__ */proto3.makeEnum("livekit.SignalTarget", [{
6131
+ no: 0,
6132
+ name: "PUBLISHER"
6133
+ }, {
6134
+ no: 1,
6135
+ name: "SUBSCRIBER"
6136
+ }]);
6137
+ const StreamState = /* @__PURE__ */proto3.makeEnum("livekit.StreamState", [{
6138
+ no: 0,
6139
+ name: "ACTIVE"
6140
+ }, {
6141
+ no: 1,
6142
+ name: "PAUSED"
6143
+ }]);
6144
+ const CandidateProtocol = /* @__PURE__ */proto3.makeEnum("livekit.CandidateProtocol", [{
6145
+ no: 0,
6146
+ name: "UDP"
6147
+ }, {
6148
+ no: 1,
6149
+ name: "TCP"
6150
+ }, {
6151
+ no: 2,
6152
+ name: "TLS"
6153
+ }]);
6154
+ const SignalRequest = /* @__PURE__ */proto3.makeMessageType("livekit.SignalRequest", () => [{
6155
+ no: 1,
6156
+ name: "offer",
6157
+ kind: "message",
6158
+ T: SessionDescription,
6159
+ oneof: "message"
6160
+ }, {
6161
+ no: 2,
6162
+ name: "answer",
6163
+ kind: "message",
6164
+ T: SessionDescription,
6165
+ oneof: "message"
6166
+ }, {
6167
+ no: 3,
6168
+ name: "trickle",
6169
+ kind: "message",
6170
+ T: TrickleRequest,
6171
+ oneof: "message"
6172
+ }, {
6173
+ no: 4,
6174
+ name: "add_track",
6175
+ kind: "message",
6176
+ T: AddTrackRequest,
6177
+ oneof: "message"
6178
+ }, {
6179
+ no: 5,
6180
+ name: "mute",
6181
+ kind: "message",
6182
+ T: MuteTrackRequest,
6183
+ oneof: "message"
6184
+ }, {
6185
+ no: 6,
6186
+ name: "subscription",
6187
+ kind: "message",
6188
+ T: UpdateSubscription,
6189
+ oneof: "message"
6190
+ }, {
6191
+ no: 7,
6192
+ name: "track_setting",
6193
+ kind: "message",
6194
+ T: UpdateTrackSettings,
6195
+ oneof: "message"
6196
+ }, {
6197
+ no: 8,
6198
+ name: "leave",
6199
+ kind: "message",
6200
+ T: LeaveRequest,
6201
+ oneof: "message"
6202
+ }, {
6203
+ no: 10,
6204
+ name: "update_layers",
6205
+ kind: "message",
6206
+ T: UpdateVideoLayers,
6207
+ oneof: "message"
6208
+ }, {
6209
+ no: 11,
6210
+ name: "subscription_permission",
6211
+ kind: "message",
6212
+ T: SubscriptionPermission,
6213
+ oneof: "message"
6214
+ }, {
6215
+ no: 12,
6216
+ name: "sync_state",
5299
6217
  kind: "message",
5300
6218
  T: SyncState,
5301
6219
  oneof: "message"
@@ -5474,6 +6392,18 @@ const SignalResponse = /* @__PURE__ */proto3.makeMessageType("livekit.SignalResp
5474
6392
  kind: "message",
5475
6393
  T: RoomMovedResponse,
5476
6394
  oneof: "message"
6395
+ }, {
6396
+ no: 25,
6397
+ name: "media_sections_requirement",
6398
+ kind: "message",
6399
+ T: MediaSectionsRequirement,
6400
+ oneof: "message"
6401
+ }, {
6402
+ no: 26,
6403
+ name: "subscribed_audio_codec_update",
6404
+ kind: "message",
6405
+ T: SubscribedAudioCodecUpdate,
6406
+ oneof: "message"
5477
6407
  }]);
5478
6408
  const SimulcastCodec = /* @__PURE__ */proto3.makeMessageType("livekit.SimulcastCodec", () => [{
5479
6409
  no: 1,
@@ -5487,6 +6417,17 @@ const SimulcastCodec = /* @__PURE__ */proto3.makeMessageType("livekit.SimulcastC
5487
6417
  kind: "scalar",
5488
6418
  T: 9
5489
6419
  /* ScalarType.STRING */
6420
+ }, {
6421
+ no: 4,
6422
+ name: "layers",
6423
+ kind: "message",
6424
+ T: VideoLayer,
6425
+ repeated: true
6426
+ }, {
6427
+ no: 5,
6428
+ name: "video_layer_mode",
6429
+ kind: "enum",
6430
+ T: proto3.getEnumType(VideoLayer_Mode)
5490
6431
  }]);
5491
6432
  const AddTrackRequest = /* @__PURE__ */proto3.makeMessageType("livekit.AddTrackRequest", () => [{
5492
6433
  no: 1,
@@ -6066,6 +7007,19 @@ const SubscribedQualityUpdate = /* @__PURE__ */proto3.makeMessageType("livekit.S
6066
7007
  T: SubscribedCodec,
6067
7008
  repeated: true
6068
7009
  }]);
7010
+ const SubscribedAudioCodecUpdate = /* @__PURE__ */proto3.makeMessageType("livekit.SubscribedAudioCodecUpdate", () => [{
7011
+ no: 1,
7012
+ name: "track_sid",
7013
+ kind: "scalar",
7014
+ T: 9
7015
+ /* ScalarType.STRING */
7016
+ }, {
7017
+ no: 2,
7018
+ name: "subscribed_audio_codecs",
7019
+ kind: "message",
7020
+ T: SubscribedAudioCodec,
7021
+ repeated: true
7022
+ }]);
6069
7023
  const TrackPermission = /* @__PURE__ */proto3.makeMessageType("livekit.TrackPermission", () => [{
6070
7024
  no: 1,
6071
7025
  name: "participant_sid",
@@ -6338,38 +7292,254 @@ const SubscriptionResponse = /* @__PURE__ */proto3.makeMessageType("livekit.Subs
6338
7292
  }]);
6339
7293
  const RequestResponse = /* @__PURE__ */proto3.makeMessageType("livekit.RequestResponse", () => [{
6340
7294
  no: 1,
6341
- name: "request_id",
7295
+ name: "request_id",
7296
+ kind: "scalar",
7297
+ T: 13
7298
+ /* ScalarType.UINT32 */
7299
+ }, {
7300
+ no: 2,
7301
+ name: "reason",
7302
+ kind: "enum",
7303
+ T: proto3.getEnumType(RequestResponse_Reason)
7304
+ }, {
7305
+ no: 3,
7306
+ name: "message",
7307
+ kind: "scalar",
7308
+ T: 9
7309
+ /* ScalarType.STRING */
7310
+ }, {
7311
+ no: 4,
7312
+ name: "trickle",
7313
+ kind: "message",
7314
+ T: TrickleRequest,
7315
+ oneof: "request"
7316
+ }, {
7317
+ no: 5,
7318
+ name: "add_track",
7319
+ kind: "message",
7320
+ T: AddTrackRequest,
7321
+ oneof: "request"
7322
+ }, {
7323
+ no: 6,
7324
+ name: "mute",
7325
+ kind: "message",
7326
+ T: MuteTrackRequest,
7327
+ oneof: "request"
7328
+ }, {
7329
+ no: 7,
7330
+ name: "update_metadata",
7331
+ kind: "message",
7332
+ T: UpdateParticipantMetadata,
7333
+ oneof: "request"
7334
+ }, {
7335
+ no: 8,
7336
+ name: "update_audio_track",
7337
+ kind: "message",
7338
+ T: UpdateLocalAudioTrack,
7339
+ oneof: "request"
7340
+ }, {
7341
+ no: 9,
7342
+ name: "update_video_track",
7343
+ kind: "message",
7344
+ T: UpdateLocalVideoTrack,
7345
+ oneof: "request"
7346
+ }]);
7347
+ const RequestResponse_Reason = /* @__PURE__ */proto3.makeEnum("livekit.RequestResponse.Reason", [{
7348
+ no: 0,
7349
+ name: "OK"
7350
+ }, {
7351
+ no: 1,
7352
+ name: "NOT_FOUND"
7353
+ }, {
7354
+ no: 2,
7355
+ name: "NOT_ALLOWED"
7356
+ }, {
7357
+ no: 3,
7358
+ name: "LIMIT_EXCEEDED"
7359
+ }, {
7360
+ no: 4,
7361
+ name: "QUEUED"
7362
+ }, {
7363
+ no: 5,
7364
+ name: "UNSUPPORTED_TYPE"
7365
+ }, {
7366
+ no: 6,
7367
+ name: "UNCLASSIFIED_ERROR"
7368
+ }]);
7369
+ const TrackSubscribed = /* @__PURE__ */proto3.makeMessageType("livekit.TrackSubscribed", () => [{
7370
+ no: 1,
7371
+ name: "track_sid",
7372
+ kind: "scalar",
7373
+ T: 9
7374
+ /* ScalarType.STRING */
7375
+ }]);
7376
+ const ConnectionSettings = /* @__PURE__ */proto3.makeMessageType("livekit.ConnectionSettings", () => [{
7377
+ no: 1,
7378
+ name: "auto_subscribe",
7379
+ kind: "scalar",
7380
+ T: 8
7381
+ /* ScalarType.BOOL */
7382
+ }, {
7383
+ no: 2,
7384
+ name: "adaptive_stream",
7385
+ kind: "scalar",
7386
+ T: 8
7387
+ /* ScalarType.BOOL */
7388
+ }, {
7389
+ no: 3,
7390
+ name: "subscriber_allow_pause",
7391
+ kind: "scalar",
7392
+ T: 8,
7393
+ opt: true
7394
+ }, {
7395
+ no: 4,
7396
+ name: "disable_ice_lite",
7397
+ kind: "scalar",
7398
+ T: 8
7399
+ /* ScalarType.BOOL */
7400
+ }]);
7401
+ const JoinRequest = /* @__PURE__ */proto3.makeMessageType("livekit.JoinRequest", () => [{
7402
+ no: 1,
7403
+ name: "client_info",
7404
+ kind: "message",
7405
+ T: ClientInfo
7406
+ }, {
7407
+ no: 2,
7408
+ name: "connection_settings",
7409
+ kind: "message",
7410
+ T: ConnectionSettings
7411
+ }, {
7412
+ no: 3,
7413
+ name: "metadata",
7414
+ kind: "scalar",
7415
+ T: 9
7416
+ /* ScalarType.STRING */
7417
+ }, {
7418
+ no: 4,
7419
+ name: "participant_attributes",
7420
+ kind: "map",
7421
+ K: 9,
7422
+ V: {
7423
+ kind: "scalar",
7424
+ T: 9
7425
+ /* ScalarType.STRING */
7426
+ }
7427
+ }, {
7428
+ no: 5,
7429
+ name: "add_track_requests",
7430
+ kind: "message",
7431
+ T: AddTrackRequest,
7432
+ repeated: true
7433
+ }, {
7434
+ no: 6,
7435
+ name: "publisher_offer",
7436
+ kind: "message",
7437
+ T: SessionDescription
7438
+ }, {
7439
+ no: 7,
7440
+ name: "reconnect",
7441
+ kind: "scalar",
7442
+ T: 8
7443
+ /* ScalarType.BOOL */
7444
+ }, {
7445
+ no: 8,
7446
+ name: "reconnect_reason",
7447
+ kind: "enum",
7448
+ T: proto3.getEnumType(ReconnectReason)
7449
+ }, {
7450
+ no: 9,
7451
+ name: "participant_sid",
7452
+ kind: "scalar",
7453
+ T: 9
7454
+ /* ScalarType.STRING */
7455
+ }, {
7456
+ no: 10,
7457
+ name: "sync_state",
7458
+ kind: "message",
7459
+ T: SyncState
7460
+ }]);
7461
+ const WrappedJoinRequest = /* @__PURE__ */proto3.makeMessageType("livekit.WrappedJoinRequest", () => [{
7462
+ no: 1,
7463
+ name: "compression",
7464
+ kind: "enum",
7465
+ T: proto3.getEnumType(WrappedJoinRequest_Compression)
7466
+ }, {
7467
+ no: 2,
7468
+ name: "join_request",
7469
+ kind: "scalar",
7470
+ T: 12
7471
+ /* ScalarType.BYTES */
7472
+ }]);
7473
+ const WrappedJoinRequest_Compression = /* @__PURE__ */proto3.makeEnum("livekit.WrappedJoinRequest.Compression", [{
7474
+ no: 0,
7475
+ name: "NONE"
7476
+ }, {
7477
+ no: 1,
7478
+ name: "GZIP"
7479
+ }]);
7480
+ const MediaSectionsRequirement = /* @__PURE__ */proto3.makeMessageType("livekit.MediaSectionsRequirement", () => [{
7481
+ no: 1,
7482
+ name: "num_audios",
6342
7483
  kind: "scalar",
6343
7484
  T: 13
6344
7485
  /* ScalarType.UINT32 */
6345
7486
  }, {
6346
7487
  no: 2,
6347
- name: "reason",
6348
- kind: "enum",
6349
- T: proto3.getEnumType(RequestResponse_Reason)
6350
- }, {
6351
- no: 3,
6352
- name: "message",
7488
+ name: "num_videos",
6353
7489
  kind: "scalar",
6354
- T: 9
6355
- /* ScalarType.STRING */
7490
+ T: 13
7491
+ /* ScalarType.UINT32 */
6356
7492
  }]);
6357
- const RequestResponse_Reason = /* @__PURE__ */proto3.makeEnum("livekit.RequestResponse.Reason", [{
6358
- no: 0,
6359
- name: "OK"
6360
- }, {
7493
+ const TokenSourceRequest = /* @__PURE__ */proto3.makeMessageType("livekit.TokenSourceRequest", () => [{
6361
7494
  no: 1,
6362
- name: "NOT_FOUND"
7495
+ name: "room_name",
7496
+ kind: "scalar",
7497
+ T: 9,
7498
+ opt: true
6363
7499
  }, {
6364
7500
  no: 2,
6365
- name: "NOT_ALLOWED"
7501
+ name: "participant_name",
7502
+ kind: "scalar",
7503
+ T: 9,
7504
+ opt: true
6366
7505
  }, {
6367
7506
  no: 3,
6368
- name: "LIMIT_EXCEEDED"
7507
+ name: "participant_identity",
7508
+ kind: "scalar",
7509
+ T: 9,
7510
+ opt: true
7511
+ }, {
7512
+ no: 4,
7513
+ name: "participant_metadata",
7514
+ kind: "scalar",
7515
+ T: 9,
7516
+ opt: true
7517
+ }, {
7518
+ no: 5,
7519
+ name: "participant_attributes",
7520
+ kind: "map",
7521
+ K: 9,
7522
+ V: {
7523
+ kind: "scalar",
7524
+ T: 9
7525
+ /* ScalarType.STRING */
7526
+ }
7527
+ }, {
7528
+ no: 6,
7529
+ name: "room_config",
7530
+ kind: "message",
7531
+ T: RoomConfiguration,
7532
+ opt: true
6369
7533
  }]);
6370
- const TrackSubscribed = /* @__PURE__ */proto3.makeMessageType("livekit.TrackSubscribed", () => [{
7534
+ const TokenSourceResponse = /* @__PURE__ */proto3.makeMessageType("livekit.TokenSourceResponse", () => [{
6371
7535
  no: 1,
6372
- name: "track_sid",
7536
+ name: "server_url",
7537
+ kind: "scalar",
7538
+ T: 9
7539
+ /* ScalarType.STRING */
7540
+ }, {
7541
+ no: 2,
7542
+ name: "participant_token",
6373
7543
  kind: "scalar",
6374
7544
  T: 9
6375
7545
  /* ScalarType.STRING */
@@ -6718,6 +7888,7 @@ var LoggerNames;
6718
7888
  (function (LoggerNames) {
6719
7889
  LoggerNames["Default"] = "livekit";
6720
7890
  LoggerNames["Room"] = "livekit-room";
7891
+ LoggerNames["TokenSource"] = "livekit-token-source";
6721
7892
  LoggerNames["Participant"] = "livekit-participant";
6722
7893
  LoggerNames["Track"] = "livekit-track";
6723
7894
  LoggerNames["Publication"] = "livekit-track-publication";
@@ -7432,7 +8603,7 @@ function detectBrowser(window) {
7432
8603
  * @param {*} val The something you want to check.
7433
8604
  * @return true if val is an object, false otherwise.
7434
8605
  */
7435
- function isObject(val) {
8606
+ function isObject$1(val) {
7436
8607
  return Object.prototype.toString.call(val) === '[object Object]';
7437
8608
  }
7438
8609
 
@@ -7442,11 +8613,11 @@ function isObject(val) {
7442
8613
  * of Lodash's `compact`.
7443
8614
  */
7444
8615
  function compactObject(data) {
7445
- if (!isObject(data)) {
8616
+ if (!isObject$1(data)) {
7446
8617
  return data;
7447
8618
  }
7448
8619
  return Object.keys(data).reduce(function (accumulator, key) {
7449
- const isObj = isObject(data[key]);
8620
+ const isObj = isObject$1(data[key]);
7450
8621
  const value = isObj ? compactObject(data[key]) : data[key];
7451
8622
  const isEmptyObject = isObj && !Object.keys(value).length;
7452
8623
  if (value === undefined || isEmptyObject) {
@@ -10453,6 +11624,15 @@ function writeRbsp(data_in) {
10453
11624
  }
10454
11625
  return new Uint8Array(dataOut);
10455
11626
  }
11627
+ function asEncryptablePacket(packet) {
11628
+ var _a, _b, _c, _d, _e;
11629
+ if (((_a = packet.value) === null || _a === void 0 ? void 0 : _a.case) !== 'sipDtmf' && ((_b = packet.value) === null || _b === void 0 ? void 0 : _b.case) !== 'metrics' && ((_c = packet.value) === null || _c === void 0 ? void 0 : _c.case) !== 'speaker' && ((_d = packet.value) === null || _d === void 0 ? void 0 : _d.case) !== 'transcription' && ((_e = packet.value) === null || _e === void 0 ? void 0 : _e.case) !== 'encryptedPacket') {
11630
+ return new EncryptedPacketPayload({
11631
+ value: packet.value
11632
+ });
11633
+ }
11634
+ return undefined;
11635
+ }
10456
11636
 
10457
11637
  /**
10458
11638
  * @experimental
@@ -10632,6 +11812,8 @@ var DataStreamErrorReason;
10632
11812
  DataStreamErrorReason[DataStreamErrorReason["Incomplete"] = 4] = "Incomplete";
10633
11813
  // Unable to register a stream handler more than once.
10634
11814
  DataStreamErrorReason[DataStreamErrorReason["HandlerAlreadyRegistered"] = 7] = "HandlerAlreadyRegistered";
11815
+ // Encryption type mismatch.
11816
+ DataStreamErrorReason[DataStreamErrorReason["EncryptionTypeMismatch"] = 8] = "EncryptionTypeMismatch";
10635
11817
  })(DataStreamErrorReason || (DataStreamErrorReason = {}));
10636
11818
  class DataStreamError extends LivekitError {
10637
11819
  constructor(message, reason) {
@@ -11388,7 +12570,7 @@ function getOSVersion(ua) {
11388
12570
  return ua.includes('mac os') ? getMatch(/\(.+?(\d+_\d+(:?_\d+)?)/, ua, 1).replace(/_/g, '.') : undefined;
11389
12571
  }
11390
12572
 
11391
- var version$1 = "2.15.7";
12573
+ var version$1 = "2.15.9";
11392
12574
 
11393
12575
  const version = version$1;
11394
12576
  const protocolVersion = 16;
@@ -11828,11 +13010,15 @@ class VideoPreset {
11828
13010
  };
11829
13011
  }
11830
13012
  }
11831
- const backupCodecs = ['vp8', 'h264'];
13013
+ // `red` is not technically a codec, but treated as one in signalling protocol
13014
+ const audioCodecs = ['opus', 'red'];
13015
+ const backupVideoCodecs = ['vp8', 'h264'];
11832
13016
  const videoCodecs = ['vp8', 'h264', 'vp9', 'av1', 'h265'];
11833
- function isBackupCodec(codec) {
11834
- return !!backupCodecs.find(backup => backup === codec);
13017
+ function isBackupVideoCodec(codec) {
13018
+ return !!backupVideoCodecs.find(backup => backup === codec);
11835
13019
  }
13020
+ /** @deprecated Use {@link isBackupVideoCodec} instead */
13021
+ const isBackupCodec = isBackupVideoCodec;
11836
13022
  var BackupCodecPolicy;
11837
13023
  (function (BackupCodecPolicy) {
11838
13024
  // codec regression is preferred, the sfu will try to regress codec if possible but not guaranteed
@@ -11944,7 +13130,7 @@ function supportsAV1() {
11944
13130
  let hasAV1 = false;
11945
13131
  if (capabilities) {
11946
13132
  for (const codec of capabilities.codecs) {
11947
- if (codec.mimeType === 'video/AV1') {
13133
+ if (codec.mimeType.toLowerCase() === 'video/av1') {
11948
13134
  hasAV1 = true;
11949
13135
  break;
11950
13136
  }
@@ -11976,7 +13162,7 @@ function supportsVP9() {
11976
13162
  let hasVP9 = false;
11977
13163
  if (capabilities) {
11978
13164
  for (const codec of capabilities.codecs) {
11979
- if (codec.mimeType === 'video/VP9') {
13165
+ if (codec.mimeType.toLowerCase() === 'video/vp9') {
11980
13166
  hasVP9 = true;
11981
13167
  break;
11982
13168
  }
@@ -11996,6 +13182,14 @@ function supportsSetSinkId(elm) {
11996
13182
  }
11997
13183
  return 'setSinkId' in elm;
11998
13184
  }
13185
+ /**
13186
+ * Checks whether or not setting an audio output via {@link Room#setActiveDevice}
13187
+ * is supported for the current browser.
13188
+ */
13189
+ function supportsAudioOutputSelection() {
13190
+ // Note: this is method publicly exported under a user friendly name and currently only proxying `supportsSetSinkId`
13191
+ return supportsSetSinkId();
13192
+ }
11999
13193
  function isBrowserSupported() {
12000
13194
  if (typeof RTCPeerConnection === 'undefined') {
12001
13195
  return false;
@@ -12276,6 +13470,9 @@ function createAudioAnalyser(track, options) {
12276
13470
  cleanup
12277
13471
  };
12278
13472
  }
13473
+ function isAudioCodec(maybeCodec) {
13474
+ return audioCodecs.includes(maybeCodec);
13475
+ }
12279
13476
  function isVideoCodec(maybeCodec) {
12280
13477
  return videoCodecs.includes(maybeCodec);
12281
13478
  }
@@ -12570,8 +13767,16 @@ function getNewAudioContext() {
12570
13767
  }
12571
13768
  } catch (e) {
12572
13769
  console.warn('Error trying to auto-resume audio context', e);
13770
+ } finally {
13771
+ (_a = window.document.body) === null || _a === void 0 ? void 0 : _a.removeEventListener('click', handleResume);
13772
+ }
13773
+ });
13774
+ // https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/statechange_event
13775
+ audioContext.addEventListener('statechange', () => {
13776
+ var _a;
13777
+ if (audioContext.state === 'closed') {
13778
+ (_a = window.document.body) === null || _a === void 0 ? void 0 : _a.removeEventListener('click', handleResume);
12573
13779
  }
12574
- (_a = window.document.body) === null || _a === void 0 ? void 0 : _a.removeEventListener('click', handleResume);
12575
13780
  });
12576
13781
  window.document.body.addEventListener('click', handleResume);
12577
13782
  }
@@ -12754,8 +13959,10 @@ function layerDimensionsFor(trackInfo, quality) {
12754
13959
  * @experimental
12755
13960
  */
12756
13961
  class E2EEManager extends eventsExports.EventEmitter {
12757
- constructor(options) {
13962
+ constructor(options, dcEncryptionEnabled) {
12758
13963
  super();
13964
+ this.decryptDataRequests = new Map();
13965
+ this.encryptDataRequests = new Map();
12759
13966
  this.onWorkerMessage = ev => {
12760
13967
  var _a, _b;
12761
13968
  const {
@@ -12794,6 +14001,18 @@ class E2EEManager extends eventsExports.EventEmitter {
12794
14001
  case 'ratchetKey':
12795
14002
  this.keyProvider.emit(KeyProviderEvent.KeyRatcheted, data.ratchetResult, data.participantIdentity, data.keyIndex);
12796
14003
  break;
14004
+ case 'decryptDataResponse':
14005
+ const decryptFuture = this.decryptDataRequests.get(data.uuid);
14006
+ if (decryptFuture === null || decryptFuture === void 0 ? void 0 : decryptFuture.resolve) {
14007
+ decryptFuture.resolve(data);
14008
+ }
14009
+ break;
14010
+ case 'encryptDataResponse':
14011
+ const encryptFuture = this.encryptDataRequests.get(data.uuid);
14012
+ if (encryptFuture === null || encryptFuture === void 0 ? void 0 : encryptFuture.resolve) {
14013
+ encryptFuture.resolve(data);
14014
+ }
14015
+ break;
12797
14016
  }
12798
14017
  };
12799
14018
  this.onWorkerError = ev => {
@@ -12805,6 +14024,13 @@ class E2EEManager extends eventsExports.EventEmitter {
12805
14024
  this.keyProvider = options.keyProvider;
12806
14025
  this.worker = options.worker;
12807
14026
  this.encryptionEnabled = false;
14027
+ this.dataChannelEncryptionEnabled = dcEncryptionEnabled;
14028
+ }
14029
+ get isEnabled() {
14030
+ return this.encryptionEnabled;
14031
+ }
14032
+ get isDataChannelEncryptionEnabled() {
14033
+ return this.isEnabled && this.dataChannelEncryptionEnabled;
12808
14034
  }
12809
14035
  /**
12810
14036
  * @internal
@@ -12908,6 +14134,52 @@ class E2EEManager extends eventsExports.EventEmitter {
12908
14134
  });
12909
14135
  keyProvider.on(KeyProviderEvent.SetKey, keyInfo => this.postKey(keyInfo)).on(KeyProviderEvent.RatchetRequest, (participantId, keyIndex) => this.postRatchetRequest(participantId, keyIndex));
12910
14136
  }
14137
+ encryptData(data) {
14138
+ return __awaiter(this, void 0, void 0, function* () {
14139
+ if (!this.worker) {
14140
+ throw Error('could not encrypt data, worker is missing');
14141
+ }
14142
+ const uuid = crypto.randomUUID();
14143
+ const msg = {
14144
+ kind: 'encryptDataRequest',
14145
+ data: {
14146
+ uuid,
14147
+ payload: data,
14148
+ participantIdentity: this.room.localParticipant.identity
14149
+ }
14150
+ };
14151
+ const future = new Future();
14152
+ future.onFinally = () => {
14153
+ this.encryptDataRequests.delete(uuid);
14154
+ };
14155
+ this.encryptDataRequests.set(uuid, future);
14156
+ this.worker.postMessage(msg);
14157
+ return future.promise;
14158
+ });
14159
+ }
14160
+ handleEncryptedData(payload, iv, participantIdentity, keyIndex) {
14161
+ if (!this.worker) {
14162
+ throw Error('could not handle encrypted data, worker is missing');
14163
+ }
14164
+ const uuid = crypto.randomUUID();
14165
+ const msg = {
14166
+ kind: 'decryptDataRequest',
14167
+ data: {
14168
+ uuid,
14169
+ payload,
14170
+ iv,
14171
+ participantIdentity,
14172
+ keyIndex
14173
+ }
14174
+ };
14175
+ const future = new Future();
14176
+ future.onFinally = () => {
14177
+ this.decryptDataRequests.delete(uuid);
14178
+ };
14179
+ this.decryptDataRequests.set(uuid, future);
14180
+ this.worker.postMessage(msg);
14181
+ return future.promise;
14182
+ }
12911
14183
  postRatchetRequest(participantIdentity, keyIndex) {
12912
14184
  if (!this.worker) {
12913
14185
  throw Error('could not ratchet key, worker is missing');
@@ -13245,6 +14517,102 @@ class AsyncQueue {
13245
14517
  }
13246
14518
  }
13247
14519
 
14520
+ /**
14521
+ * [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) with [Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API)
14522
+ *
14523
+ * @see https://web.dev/websocketstream/
14524
+ */
14525
+ class WebSocketStream {
14526
+ get readyState() {
14527
+ return this.ws.readyState;
14528
+ }
14529
+ constructor(url) {
14530
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
14531
+ var _a, _b;
14532
+ if ((_a = options.signal) === null || _a === void 0 ? void 0 : _a.aborted) {
14533
+ throw new DOMException('This operation was aborted', 'AbortError');
14534
+ }
14535
+ this.url = url;
14536
+ const ws = new WebSocket(url, (_b = options.protocols) !== null && _b !== void 0 ? _b : []);
14537
+ ws.binaryType = 'arraybuffer';
14538
+ this.ws = ws;
14539
+ const closeWithInfo = function () {
14540
+ let {
14541
+ closeCode: code,
14542
+ reason
14543
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
14544
+ return ws.close(code, reason);
14545
+ };
14546
+ this.opened = new Promise((resolve, reject) => {
14547
+ ws.onopen = () => {
14548
+ resolve({
14549
+ readable: new ReadableStream({
14550
+ start(controller) {
14551
+ ws.onmessage = _ref => {
14552
+ let {
14553
+ data
14554
+ } = _ref;
14555
+ return controller.enqueue(data);
14556
+ };
14557
+ ws.onerror = e => controller.error(e);
14558
+ },
14559
+ cancel: closeWithInfo
14560
+ }),
14561
+ writable: new WritableStream({
14562
+ write(chunk) {
14563
+ ws.send(chunk);
14564
+ },
14565
+ abort() {
14566
+ ws.close();
14567
+ },
14568
+ close: closeWithInfo
14569
+ }),
14570
+ protocol: ws.protocol,
14571
+ extensions: ws.extensions
14572
+ });
14573
+ ws.removeEventListener('error', reject);
14574
+ };
14575
+ ws.addEventListener('error', reject);
14576
+ });
14577
+ this.closed = new Promise((resolve, reject) => {
14578
+ const rejectHandler = () => __awaiter(this, void 0, void 0, function* () {
14579
+ const closePromise = new Promise(res => {
14580
+ if (ws.readyState === WebSocket.CLOSED) return;else {
14581
+ ws.addEventListener('close', closeEv => {
14582
+ res(closeEv);
14583
+ }, {
14584
+ once: true
14585
+ });
14586
+ }
14587
+ });
14588
+ const reason = yield Promise.race([sleep(250), closePromise]);
14589
+ if (!reason) {
14590
+ reject(new Error('Encountered unspecified websocket error without a timely close event'));
14591
+ } else {
14592
+ // if we can infer the close reason from the close event then resolve the promise, we don't need to throw
14593
+ resolve(reason);
14594
+ }
14595
+ });
14596
+ ws.onclose = _ref2 => {
14597
+ let {
14598
+ code,
14599
+ reason
14600
+ } = _ref2;
14601
+ resolve({
14602
+ closeCode: code,
14603
+ reason
14604
+ });
14605
+ ws.removeEventListener('error', rejectHandler);
14606
+ };
14607
+ ws.addEventListener('error', rejectHandler);
14608
+ });
14609
+ if (options.signal) {
14610
+ options.signal.onabort = () => ws.close();
14611
+ }
14612
+ this.close = closeWithInfo;
14613
+ }
14614
+ }
14615
+
13248
14616
  function createRtcUrl(url, searchParams) {
13249
14617
  const urlObj = new URL(toWebsocketUrl(url));
13250
14618
  searchParams.forEach((value, key) => {
@@ -13263,6 +14631,16 @@ function appendUrlPath(urlObj, path) {
13263
14631
  urlObj.pathname = "".concat(ensureTrailingSlash(urlObj.pathname)).concat(path);
13264
14632
  return urlObj.toString();
13265
14633
  }
14634
+ function parseSignalResponse(value) {
14635
+ if (typeof value === 'string') {
14636
+ return SignalResponse.fromJson(JSON.parse(value), {
14637
+ ignoreUnknownFields: true
14638
+ });
14639
+ } else if (value instanceof ArrayBuffer) {
14640
+ return SignalResponse.fromBinary(new Uint8Array(value));
14641
+ }
14642
+ throw new Error("could not decode websocket message: ".concat(typeof value));
14643
+ }
13266
14644
 
13267
14645
  const passThroughQueueSignals = ['syncState', 'trickle', 'offer', 'answer', 'simulate', 'leave'];
13268
14646
  function canPassThroughQueue(req) {
@@ -13281,6 +14659,8 @@ var SignalConnectionState;
13281
14659
  SignalConnectionState[SignalConnectionState["DISCONNECTING"] = 3] = "DISCONNECTING";
13282
14660
  SignalConnectionState[SignalConnectionState["DISCONNECTED"] = 4] = "DISCONNECTED";
13283
14661
  })(SignalConnectionState || (SignalConnectionState = {}));
14662
+ /** specifies how much time (in ms) we allow for the ws to close its connection gracefully before continuing */
14663
+ const MAX_WS_CLOSE_TIME = 250;
13284
14664
  /** @internal */
13285
14665
  class SignalClient {
13286
14666
  get currentState() {
@@ -13318,6 +14698,7 @@ class SignalClient {
13318
14698
  this.onTokenRefresh = undefined;
13319
14699
  this.onTrickle = undefined;
13320
14700
  this.onClose = undefined;
14701
+ this.onMediaSectionsRequirement = undefined;
13321
14702
  };
13322
14703
  this.log = getLogger((_a = loggerOptions.loggerName) !== null && _a !== void 0 ? _a : LoggerNames.Signal);
13323
14704
  this.loggerContextCb = loggerOptions.loggerContextCb;
@@ -13360,137 +14741,140 @@ class SignalClient {
13360
14741
  });
13361
14742
  }
13362
14743
  connect(url, token, opts, abortSignal) {
13363
- this.connectOptions = opts;
13364
- const clientInfo = getClientInfo();
13365
- const params = createConnectionParams(token, clientInfo, opts);
13366
- const rtcUrl = createRtcUrl(url, params);
13367
- const validateUrl = createValidateUrl(rtcUrl);
13368
- return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
14744
+ return __awaiter(this, void 0, void 0, function* () {
13369
14745
  const unlock = yield this.connectionLock.lock();
13370
- try {
13371
- const abortHandler = () => __awaiter(this, void 0, void 0, function* () {
13372
- this.close();
13373
- clearTimeout(wsTimeout);
13374
- reject(new ConnectionError('room connection has been cancelled (signal)', ConnectionErrorReason.Cancelled));
13375
- });
13376
- const wsTimeout = setTimeout(() => {
13377
- this.close();
13378
- reject(new ConnectionError('room connection has timed out (signal)', ConnectionErrorReason.ServerUnreachable));
13379
- }, opts.websocketTimeout);
13380
- if (abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.aborted) {
13381
- abortHandler();
13382
- }
13383
- abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.addEventListener('abort', abortHandler);
13384
- const redactedUrl = new URL(rtcUrl);
13385
- if (redactedUrl.searchParams.has('access_token')) {
13386
- redactedUrl.searchParams.set('access_token', '<redacted>');
13387
- }
13388
- this.log.debug("connecting to ".concat(redactedUrl), Object.assign({
13389
- reconnect: opts.reconnect,
13390
- reconnectReason: opts.reconnectReason
13391
- }, this.logContext));
13392
- if (this.ws) {
13393
- yield this.close(false);
13394
- }
13395
- this.ws = new WebSocket(rtcUrl);
13396
- this.ws.binaryType = 'arraybuffer';
13397
- this.ws.onopen = () => {
13398
- clearTimeout(wsTimeout);
13399
- };
13400
- this.ws.onerror = ev => __awaiter(this, void 0, void 0, function* () {
13401
- if (this.state !== SignalConnectionState.CONNECTED) {
13402
- this.state = SignalConnectionState.DISCONNECTED;
14746
+ this.connectOptions = opts;
14747
+ const clientInfo = getClientInfo();
14748
+ const params = opts.singlePeerConnection ? createJoinRequestConnectionParams(token, clientInfo, opts) : createConnectionParams(token, clientInfo, opts);
14749
+ const rtcUrl = createRtcUrl(url, params);
14750
+ const validateUrl = createValidateUrl(rtcUrl);
14751
+ return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
14752
+ var _a, _b;
14753
+ try {
14754
+ const timeoutAbortController = new AbortController();
14755
+ const signals = abortSignal ? [timeoutAbortController.signal, abortSignal] : [timeoutAbortController.signal];
14756
+ const combinedAbort = AbortSignal.any(signals);
14757
+ const abortHandler = event => __awaiter(this, void 0, void 0, function* () {
14758
+ this.close();
13403
14759
  clearTimeout(wsTimeout);
13404
- try {
13405
- const resp = yield fetch(validateUrl);
13406
- if (resp.status.toFixed(0).startsWith('4')) {
13407
- const msg = yield resp.text();
13408
- reject(new ConnectionError(msg, ConnectionErrorReason.NotAllowed, resp.status));
13409
- } else {
13410
- reject(new ConnectionError("Encountered unknown websocket error during connection: ".concat(ev.toString()), ConnectionErrorReason.InternalError, resp.status));
13411
- }
13412
- } catch (e) {
13413
- reject(new ConnectionError(e instanceof Error ? e.message : 'server was not reachable', ConnectionErrorReason.ServerUnreachable));
13414
- }
13415
- return;
14760
+ const target = event.currentTarget;
14761
+ reject(target instanceof AbortSignal ? target.reason : target);
14762
+ });
14763
+ combinedAbort.addEventListener('abort', abortHandler);
14764
+ const wsTimeout = setTimeout(() => {
14765
+ timeoutAbortController.abort(new ConnectionError('room connection has timed out (signal)', ConnectionErrorReason.ServerUnreachable));
14766
+ }, opts.websocketTimeout);
14767
+ const handleSignalConnected = (connection, firstMessage) => {
14768
+ this.handleSignalConnected(connection, wsTimeout, firstMessage);
14769
+ };
14770
+ const redactedUrl = new URL(rtcUrl);
14771
+ if (redactedUrl.searchParams.has('access_token')) {
14772
+ redactedUrl.searchParams.set('access_token', '<redacted>');
13416
14773
  }
13417
- // other errors, handle
13418
- this.handleWSError(ev);
13419
- });
13420
- this.ws.onmessage = ev => __awaiter(this, void 0, void 0, function* () {
13421
- var _a, _b, _c;
13422
- // not considered connected until JoinResponse is received
13423
- let resp;
13424
- if (typeof ev.data === 'string') {
13425
- const json = JSON.parse(ev.data);
13426
- resp = SignalResponse.fromJson(json, {
13427
- ignoreUnknownFields: true
13428
- });
13429
- } else if (ev.data instanceof ArrayBuffer) {
13430
- resp = SignalResponse.fromBinary(new Uint8Array(ev.data));
13431
- } else {
13432
- this.log.error("could not decode websocket message: ".concat(typeof ev.data), this.logContext);
13433
- return;
14774
+ this.log.debug("connecting to ".concat(redactedUrl), Object.assign({
14775
+ reconnect: opts.reconnect,
14776
+ reconnectReason: opts.reconnectReason
14777
+ }, this.logContext));
14778
+ if (this.ws) {
14779
+ yield this.close(false);
13434
14780
  }
13435
- if (this.state !== SignalConnectionState.CONNECTED) {
13436
- let shouldProcessMessage = false;
13437
- // handle join message only
13438
- if (((_a = resp.message) === null || _a === void 0 ? void 0 : _a.case) === 'join') {
13439
- this.state = SignalConnectionState.CONNECTED;
13440
- abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.removeEventListener('abort', abortHandler);
13441
- this.pingTimeoutDuration = resp.message.value.pingTimeout;
13442
- this.pingIntervalDuration = resp.message.value.pingInterval;
14781
+ this.ws = new WebSocketStream(rtcUrl, {
14782
+ signal: combinedAbort
14783
+ });
14784
+ try {
14785
+ this.ws.closed.then(closeInfo => {
14786
+ if (this.isEstablishingConnection) {
14787
+ reject(new ConnectionError("Websocket got closed during a (re)connection attempt: ".concat(closeInfo.reason), ConnectionErrorReason.InternalError));
14788
+ }
14789
+ if (closeInfo.closeCode !== 1000) {
14790
+ this.log.warn("websocket closed", Object.assign(Object.assign({}, this.logContext), {
14791
+ reason: closeInfo.reason,
14792
+ code: closeInfo.closeCode,
14793
+ wasClean: closeInfo.closeCode === 1000,
14794
+ state: this.state
14795
+ }));
14796
+ }
14797
+ return;
14798
+ }).catch(reason => {
14799
+ if (this.isEstablishingConnection) {
14800
+ reject(new ConnectionError("Websocket error during a (re)connection attempt: ".concat(reason), ConnectionErrorReason.InternalError));
14801
+ }
14802
+ });
14803
+ const connection = yield this.ws.opened.catch(reason => __awaiter(this, void 0, void 0, function* () {
14804
+ if (this.state !== SignalConnectionState.CONNECTED) {
14805
+ this.state = SignalConnectionState.DISCONNECTED;
14806
+ clearTimeout(wsTimeout);
14807
+ const error = yield this.handleConnectionError(reason, validateUrl);
14808
+ reject(error);
14809
+ return;
14810
+ }
14811
+ // other errors, handle
14812
+ this.handleWSError(reason);
14813
+ reject(reason);
14814
+ return;
14815
+ }));
14816
+ clearTimeout(wsTimeout);
14817
+ if (!connection) {
14818
+ return;
14819
+ }
14820
+ const signalReader = connection.readable.getReader();
14821
+ const firstMessage = yield signalReader.read();
14822
+ signalReader.releaseLock();
14823
+ if (!firstMessage.value) {
14824
+ throw new ConnectionError('no message received as first message', ConnectionErrorReason.InternalError);
14825
+ }
14826
+ const firstSignalResponse = parseSignalResponse(firstMessage.value);
14827
+ // Validate the first message
14828
+ const validation = this.validateFirstMessage(firstSignalResponse, (_a = opts.reconnect) !== null && _a !== void 0 ? _a : false);
14829
+ if (!validation.isValid) {
14830
+ reject(validation.error);
14831
+ return;
14832
+ }
14833
+ // Handle join response - set up ping configuration
14834
+ if (((_b = firstSignalResponse.message) === null || _b === void 0 ? void 0 : _b.case) === 'join') {
14835
+ this.pingTimeoutDuration = firstSignalResponse.message.value.pingTimeout;
14836
+ this.pingIntervalDuration = firstSignalResponse.message.value.pingInterval;
13443
14837
  if (this.pingTimeoutDuration && this.pingTimeoutDuration > 0) {
13444
14838
  this.log.debug('ping config', Object.assign(Object.assign({}, this.logContext), {
13445
14839
  timeout: this.pingTimeoutDuration,
13446
14840
  interval: this.pingIntervalDuration
13447
14841
  }));
13448
- this.startPingInterval();
13449
- }
13450
- resolve(resp.message.value);
13451
- } else if (this.state === SignalConnectionState.RECONNECTING && resp.message.case !== 'leave') {
13452
- // in reconnecting, any message received means signal reconnected
13453
- this.state = SignalConnectionState.CONNECTED;
13454
- abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.removeEventListener('abort', abortHandler);
13455
- this.startPingInterval();
13456
- if (((_b = resp.message) === null || _b === void 0 ? void 0 : _b.case) === 'reconnect') {
13457
- resolve(resp.message.value);
13458
- } else {
13459
- this.log.debug('declaring signal reconnected without reconnect response received', this.logContext);
13460
- resolve(undefined);
13461
- shouldProcessMessage = true;
13462
14842
  }
13463
- } else if (this.isEstablishingConnection && resp.message.case === 'leave') {
13464
- reject(new ConnectionError('Received leave request while trying to (re)connect', ConnectionErrorReason.LeaveRequest, undefined, resp.message.value.reason));
13465
- } else if (!opts.reconnect) {
13466
- // non-reconnect case, should receive join response first
13467
- reject(new ConnectionError("did not receive join response, got ".concat((_c = resp.message) === null || _c === void 0 ? void 0 : _c.case, " instead"), ConnectionErrorReason.InternalError));
13468
14843
  }
13469
- if (!shouldProcessMessage) {
13470
- return;
13471
- }
13472
- }
13473
- if (this.signalLatency) {
13474
- yield sleep(this.signalLatency);
13475
- }
13476
- this.handleSignalResponse(resp);
13477
- });
13478
- this.ws.onclose = ev => {
13479
- if (this.isEstablishingConnection) {
13480
- reject(new ConnectionError('Websocket got closed during a (re)connection attempt', ConnectionErrorReason.InternalError));
14844
+ // Handle successful connection
14845
+ const firstMessageToProcess = validation.shouldProcessFirstMessage ? firstSignalResponse : undefined;
14846
+ handleSignalConnected(connection, firstMessageToProcess);
14847
+ resolve(validation.response);
14848
+ } catch (e) {
14849
+ clearTimeout(wsTimeout);
14850
+ reject(e);
13481
14851
  }
13482
- this.log.warn("websocket closed", Object.assign(Object.assign({}, this.logContext), {
13483
- reason: ev.reason,
13484
- code: ev.code,
13485
- wasClean: ev.wasClean,
13486
- state: this.state
13487
- }));
13488
- this.handleOnClose(ev.reason);
13489
- };
13490
- } finally {
13491
- unlock();
14852
+ } finally {
14853
+ unlock();
14854
+ }
14855
+ }));
14856
+ });
14857
+ }
14858
+ startReadingLoop(signalReader, firstMessage) {
14859
+ return __awaiter(this, void 0, void 0, function* () {
14860
+ if (firstMessage) {
14861
+ this.handleSignalResponse(firstMessage);
13492
14862
  }
13493
- }));
14863
+ while (true) {
14864
+ if (this.signalLatency) {
14865
+ yield sleep(this.signalLatency);
14866
+ }
14867
+ const {
14868
+ done,
14869
+ value
14870
+ } = yield signalReader.read();
14871
+ if (done) {
14872
+ break;
14873
+ }
14874
+ const resp = parseSignalResponse(value);
14875
+ this.handleSignalResponse(resp);
14876
+ }
14877
+ });
13494
14878
  }
13495
14879
  close() {
13496
14880
  return __awaiter(this, arguments, void 0, function () {
@@ -13504,26 +14888,20 @@ class SignalClient {
13504
14888
  _this.state = SignalConnectionState.DISCONNECTING;
13505
14889
  }
13506
14890
  if (_this.ws) {
13507
- _this.ws.onmessage = null;
13508
- _this.ws.onopen = null;
13509
- _this.ws.onclose = null;
13510
- // calling `ws.close()` only starts the closing handshake (CLOSING state), prefer to wait until state is actually CLOSED
13511
- const closePromise = new Promise(resolve => {
13512
- if (_this.ws) {
13513
- _this.ws.onclose = () => {
13514
- resolve();
13515
- };
13516
- } else {
13517
- resolve();
13518
- }
14891
+ _this.ws.close({
14892
+ closeCode: 1000,
14893
+ reason: 'Close method called on signal client'
13519
14894
  });
13520
- if (_this.ws.readyState < _this.ws.CLOSING) {
13521
- _this.ws.close();
13522
- // 250ms grace period for ws to close gracefully
13523
- yield Promise.race([closePromise, sleep(250)]);
13524
- }
14895
+ // calling `ws.close()` only starts the closing handshake (CLOSING state), prefer to wait until state is actually CLOSED
14896
+ const closePromise = _this.ws.closed;
13525
14897
  _this.ws = undefined;
14898
+ _this.streamWriter = undefined;
14899
+ yield Promise.race([closePromise, sleep(MAX_WS_CLOSE_TIME)]);
13526
14900
  }
14901
+ } catch (e) {
14902
+ _this.log.debug('websocket error while closing', Object.assign(Object.assign({}, _this.logContext), {
14903
+ error: e
14904
+ }));
13527
14905
  } finally {
13528
14906
  if (updateState) {
13529
14907
  _this.state = SignalConnectionState.DISCONNECTED;
@@ -13700,7 +15078,7 @@ class SignalClient {
13700
15078
  _this3.log.debug("skipping signal request (type: ".concat(message.case, ") - SignalClient disconnected"));
13701
15079
  return;
13702
15080
  }
13703
- if (!_this3.ws || _this3.ws.readyState !== _this3.ws.OPEN) {
15081
+ if (!_this3.streamWriter) {
13704
15082
  _this3.log.error("cannot send signal request before connected, type: ".concat(message === null || message === void 0 ? void 0 : message.case), _this3.logContext);
13705
15083
  return;
13706
15084
  }
@@ -13709,9 +15087,9 @@ class SignalClient {
13709
15087
  });
13710
15088
  try {
13711
15089
  if (_this3.useJSON) {
13712
- _this3.ws.send(req.toJsonString());
15090
+ yield _this3.streamWriter.write(req.toJsonString());
13713
15091
  } else {
13714
- _this3.ws.send(req.toBinary());
15092
+ yield _this3.streamWriter.write(req.toBinary());
13715
15093
  }
13716
15094
  } catch (e) {
13717
15095
  _this3.log.error('error sending signal message', Object.assign(Object.assign({}, _this3.logContext), {
@@ -13815,6 +15193,10 @@ class SignalClient {
13815
15193
  if (this.onRoomMoved) {
13816
15194
  this.onRoomMoved(msg.value);
13817
15195
  }
15196
+ } else if (msg.case === 'mediaSectionsRequirement') {
15197
+ if (this.onMediaSectionsRequirement) {
15198
+ this.onMediaSectionsRequirement(msg.value);
15199
+ }
13818
15200
  } else {
13819
15201
  this.log.debug('unsupported message', Object.assign(Object.assign({}, this.logContext), {
13820
15202
  msgCase: msg.case
@@ -13845,9 +15227,9 @@ class SignalClient {
13845
15227
  }
13846
15228
  });
13847
15229
  }
13848
- handleWSError(ev) {
15230
+ handleWSError(error) {
13849
15231
  this.log.error('websocket error', Object.assign(Object.assign({}, this.logContext), {
13850
- error: ev
15232
+ error
13851
15233
  }));
13852
15234
  }
13853
15235
  /**
@@ -13892,6 +15274,90 @@ class SignalClient {
13892
15274
  CriticalTimers.clearInterval(this.pingInterval);
13893
15275
  }
13894
15276
  }
15277
+ /**
15278
+ * Handles the successful connection to the signal server
15279
+ * @param connection The WebSocket connection
15280
+ * @param timeoutHandle The timeout handle to clear
15281
+ * @param firstMessage Optional first message to process
15282
+ * @internal
15283
+ */
15284
+ handleSignalConnected(connection, timeoutHandle, firstMessage) {
15285
+ this.state = SignalConnectionState.CONNECTED;
15286
+ clearTimeout(timeoutHandle);
15287
+ this.startPingInterval();
15288
+ this.startReadingLoop(connection.readable.getReader(), firstMessage);
15289
+ this.streamWriter = connection.writable.getWriter();
15290
+ }
15291
+ /**
15292
+ * Validates the first message received from the signal server
15293
+ * @param firstSignalResponse The first signal response received
15294
+ * @param isReconnect Whether this is a reconnection attempt
15295
+ * @returns Validation result with response or error
15296
+ * @internal
15297
+ */
15298
+ validateFirstMessage(firstSignalResponse, isReconnect) {
15299
+ var _a, _b, _c, _d, _e;
15300
+ if (((_a = firstSignalResponse.message) === null || _a === void 0 ? void 0 : _a.case) === 'join') {
15301
+ return {
15302
+ isValid: true,
15303
+ response: firstSignalResponse.message.value
15304
+ };
15305
+ } else if (this.state === SignalConnectionState.RECONNECTING && ((_b = firstSignalResponse.message) === null || _b === void 0 ? void 0 : _b.case) !== 'leave') {
15306
+ if (((_c = firstSignalResponse.message) === null || _c === void 0 ? void 0 : _c.case) === 'reconnect') {
15307
+ return {
15308
+ isValid: true,
15309
+ response: firstSignalResponse.message.value
15310
+ };
15311
+ } else {
15312
+ // in reconnecting, any message received means signal reconnected and we still need to process it
15313
+ this.log.debug('declaring signal reconnected without reconnect response received', this.logContext);
15314
+ return {
15315
+ isValid: true,
15316
+ response: undefined,
15317
+ shouldProcessFirstMessage: true
15318
+ };
15319
+ }
15320
+ } else if (this.isEstablishingConnection && ((_d = firstSignalResponse.message) === null || _d === void 0 ? void 0 : _d.case) === 'leave') {
15321
+ return {
15322
+ isValid: false,
15323
+ error: new ConnectionError('Received leave request while trying to (re)connect', ConnectionErrorReason.LeaveRequest, undefined, firstSignalResponse.message.value.reason)
15324
+ };
15325
+ } else if (!isReconnect) {
15326
+ // non-reconnect case, should receive join response first
15327
+ return {
15328
+ isValid: false,
15329
+ error: new ConnectionError("did not receive join response, got ".concat((_e = firstSignalResponse.message) === null || _e === void 0 ? void 0 : _e.case, " instead"), ConnectionErrorReason.InternalError)
15330
+ };
15331
+ }
15332
+ return {
15333
+ isValid: false,
15334
+ error: new ConnectionError('Unexpected first message', ConnectionErrorReason.InternalError)
15335
+ };
15336
+ }
15337
+ /**
15338
+ * Handles WebSocket connection errors by validating with the server
15339
+ * @param reason The error that occurred
15340
+ * @param validateUrl The URL to validate the connection with
15341
+ * @returns A ConnectionError with appropriate reason and status
15342
+ * @internal
15343
+ */
15344
+ handleConnectionError(reason, validateUrl) {
15345
+ return __awaiter(this, void 0, void 0, function* () {
15346
+ try {
15347
+ const resp = yield fetch(validateUrl);
15348
+ if (resp.status.toFixed(0).startsWith('4')) {
15349
+ const msg = yield resp.text();
15350
+ return new ConnectionError(msg, ConnectionErrorReason.NotAllowed, resp.status);
15351
+ } else if (reason instanceof ConnectionError) {
15352
+ return reason;
15353
+ } else {
15354
+ return new ConnectionError("Encountered unknown websocket error during connection: ".concat(reason), ConnectionErrorReason.InternalError, resp.status);
15355
+ }
15356
+ } catch (e) {
15357
+ return e instanceof ConnectionError ? e : new ConnectionError(e instanceof Error ? e.message : 'server was not reachable', ConnectionErrorReason.ServerUnreachable);
15358
+ }
15359
+ });
15360
+ }
13895
15361
  }
13896
15362
  function fromProtoSessionDescription(sd) {
13897
15363
  const rsd = {
@@ -13960,6 +15426,27 @@ function createConnectionParams(token, info, opts) {
13960
15426
  }
13961
15427
  return params;
13962
15428
  }
15429
+ function createJoinRequestConnectionParams(token, info, opts) {
15430
+ const params = new URLSearchParams();
15431
+ params.set('access_token', token);
15432
+ const joinRequest = new JoinRequest({
15433
+ clientInfo: info,
15434
+ connectionSettings: new ConnectionSettings({
15435
+ autoSubscribe: !!opts.autoSubscribe,
15436
+ adaptiveStream: !!opts.adaptiveStream
15437
+ }),
15438
+ reconnect: !!opts.reconnect,
15439
+ participantSid: opts.sid ? opts.sid : undefined
15440
+ });
15441
+ if (opts.reconnectReason) {
15442
+ joinRequest.reconnectReason = opts.reconnectReason;
15443
+ }
15444
+ const wrappedJoinRequest = new WrappedJoinRequest({
15445
+ joinRequest: joinRequest.toBinary()
15446
+ });
15447
+ params.set('join_request', btoa(new TextDecoder('utf-8').decode(wrappedJoinRequest.toBinary())));
15448
+ return params;
15449
+ }
13963
15450
 
13964
15451
  class DataPacketBuffer {
13965
15452
  constructor() {
@@ -14972,7 +16459,7 @@ class PCTransport extends eventsExports.EventEmitter {
14972
16459
  sdpParsed.media.forEach(media => {
14973
16460
  const mid = getMidString(media.mid);
14974
16461
  if (media.type === 'audio') {
14975
- // mung sdp for opus bitrate settings
16462
+ // munge sdp for opus bitrate settings
14976
16463
  this.trackBitrates.some(trackbr => {
14977
16464
  if (!trackbr.transceiver || mid != trackbr.transceiver.mid) {
14978
16465
  return false;
@@ -15077,7 +16564,7 @@ class PCTransport extends eventsExports.EventEmitter {
15077
16564
  sdpParsed.media.forEach(media => {
15078
16565
  ensureIPAddrMatchVersion(media);
15079
16566
  if (media.type === 'audio') {
15080
- ensureAudioNackAndStereo(media, [], []);
16567
+ ensureAudioNackAndStereo(media, ['all'], []);
15081
16568
  } else if (media.type === 'video') {
15082
16569
  this.trackBitrates.some(trackbr => {
15083
16570
  if (!media.msid || !trackbr.cid || !media.msid.includes(trackbr.cid)) {
@@ -15153,6 +16640,9 @@ class PCTransport extends eventsExports.EventEmitter {
15153
16640
  addTransceiver(mediaStreamTrack, transceiverInit) {
15154
16641
  return this.pc.addTransceiver(mediaStreamTrack, transceiverInit);
15155
16642
  }
16643
+ addTransceiverOfKind(kind, transceiverInit) {
16644
+ return this.pc.addTransceiver(kind, transceiverInit);
16645
+ }
15156
16646
  addTrack(track) {
15157
16647
  if (!this._pc) {
15158
16648
  throw new UnexpectedConnectionState('PC closed, cannot add track');
@@ -15347,7 +16837,7 @@ function ensureAudioNackAndStereo(media, stereoMids, nackMids) {
15347
16837
  type: 'nack'
15348
16838
  });
15349
16839
  }
15350
- if (stereoMids.includes(mid)) {
16840
+ if (stereoMids.includes(mid) || stereoMids.length === 1 && stereoMids[0] === 'all') {
15351
16841
  media.fmtp.some(fmtp => {
15352
16842
  if (fmtp.payload === opusPayload) {
15353
16843
  if (!fmtp.config.includes('stereo=1')) {
@@ -15447,7 +16937,8 @@ const roomOptionDefaults = {
15447
16937
  stopLocalTrackOnUnpublish: true,
15448
16938
  reconnectPolicy: new DefaultReconnectPolicy(),
15449
16939
  disconnectOnPageLeave: true,
15450
- webAudioMix: false
16940
+ webAudioMix: false,
16941
+ singlePeerConnection: false
15451
16942
  };
15452
16943
  const roomConnectOptionDefaults = {
15453
16944
  autoSubscribe: true,
@@ -15475,12 +16966,12 @@ class PCTransportManager {
15475
16966
  get currentState() {
15476
16967
  return this.state;
15477
16968
  }
15478
- constructor(rtcConfig, subscriberPrimary, loggerOptions) {
16969
+ constructor(rtcConfig, mode, loggerOptions) {
15479
16970
  var _a;
15480
16971
  this.peerConnectionTimeout = roomConnectOptionDefaults.peerConnectionTimeout;
15481
16972
  this.log = livekitLogger;
15482
16973
  this.updateState = () => {
15483
- var _a;
16974
+ var _a, _b;
15484
16975
  const previousState = this.state;
15485
16976
  const connectionStates = this.requiredTransports.map(tr => tr.getConnectionState());
15486
16977
  if (connectionStates.every(st => st === 'connected')) {
@@ -15498,35 +16989,41 @@ class PCTransportManager {
15498
16989
  }
15499
16990
  if (previousState !== this.state) {
15500
16991
  this.log.debug("pc state change: from ".concat(PCTransportState[previousState], " to ").concat(PCTransportState[this.state]), this.logContext);
15501
- (_a = this.onStateChange) === null || _a === void 0 ? void 0 : _a.call(this, this.state, this.publisher.getConnectionState(), this.subscriber.getConnectionState());
16992
+ (_a = this.onStateChange) === null || _a === void 0 ? void 0 : _a.call(this, this.state, this.publisher.getConnectionState(), (_b = this.subscriber) === null || _b === void 0 ? void 0 : _b.getConnectionState());
15502
16993
  }
15503
16994
  };
15504
16995
  this.log = getLogger((_a = loggerOptions.loggerName) !== null && _a !== void 0 ? _a : LoggerNames.PCManager);
15505
16996
  this.loggerOptions = loggerOptions;
15506
- this.isPublisherConnectionRequired = !subscriberPrimary;
15507
- this.isSubscriberConnectionRequired = subscriberPrimary;
16997
+ this.isPublisherConnectionRequired = mode !== 'subscriber-primary';
16998
+ this.isSubscriberConnectionRequired = mode === 'subscriber-primary';
15508
16999
  this.publisher = new PCTransport(rtcConfig, loggerOptions);
15509
- this.subscriber = new PCTransport(rtcConfig, loggerOptions);
17000
+ if (mode !== 'publisher-only') {
17001
+ this.subscriber = new PCTransport(rtcConfig, loggerOptions);
17002
+ this.subscriber.onConnectionStateChange = this.updateState;
17003
+ this.subscriber.onIceConnectionStateChange = this.updateState;
17004
+ this.subscriber.onSignalingStatechange = this.updateState;
17005
+ this.subscriber.onIceCandidate = candidate => {
17006
+ var _a;
17007
+ (_a = this.onIceCandidate) === null || _a === void 0 ? void 0 : _a.call(this, candidate, SignalTarget.SUBSCRIBER);
17008
+ };
17009
+ // in subscriber primary mode, server side opens sub data channels.
17010
+ this.subscriber.onDataChannel = ev => {
17011
+ var _a;
17012
+ (_a = this.onDataChannel) === null || _a === void 0 ? void 0 : _a.call(this, ev);
17013
+ };
17014
+ this.subscriber.onTrack = ev => {
17015
+ var _a;
17016
+ (_a = this.onTrack) === null || _a === void 0 ? void 0 : _a.call(this, ev);
17017
+ };
17018
+ }
15510
17019
  this.publisher.onConnectionStateChange = this.updateState;
15511
- this.subscriber.onConnectionStateChange = this.updateState;
15512
17020
  this.publisher.onIceConnectionStateChange = this.updateState;
15513
- this.subscriber.onIceConnectionStateChange = this.updateState;
15514
17021
  this.publisher.onSignalingStatechange = this.updateState;
15515
- this.subscriber.onSignalingStatechange = this.updateState;
15516
17022
  this.publisher.onIceCandidate = candidate => {
15517
17023
  var _a;
15518
17024
  (_a = this.onIceCandidate) === null || _a === void 0 ? void 0 : _a.call(this, candidate, SignalTarget.PUBLISHER);
15519
17025
  };
15520
- this.subscriber.onIceCandidate = candidate => {
15521
- var _a;
15522
- (_a = this.onIceCandidate) === null || _a === void 0 ? void 0 : _a.call(this, candidate, SignalTarget.SUBSCRIBER);
15523
- };
15524
- // in subscriber primary mode, server side opens sub data channels.
15525
- this.subscriber.onDataChannel = ev => {
15526
- var _a;
15527
- (_a = this.onDataChannel) === null || _a === void 0 ? void 0 : _a.call(this, ev);
15528
- };
15529
- this.subscriber.onTrack = ev => {
17026
+ this.publisher.onTrack = ev => {
15530
17027
  var _a;
15531
17028
  (_a = this.onTrack) === null || _a === void 0 ? void 0 : _a.call(this, ev);
15532
17029
  };
@@ -15547,11 +17044,6 @@ class PCTransportManager {
15547
17044
  this.isPublisherConnectionRequired = require;
15548
17045
  this.updateState();
15549
17046
  }
15550
- requireSubscriber() {
15551
- let require = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
15552
- this.isSubscriberConnectionRequired = require;
15553
- this.updateState();
15554
- }
15555
17047
  createAndSendPublisherOffer(options) {
15556
17048
  return this.publisher.createAndSendOffer(options);
15557
17049
  }
@@ -15563,6 +17055,7 @@ class PCTransportManager {
15563
17055
  }
15564
17056
  close() {
15565
17057
  return __awaiter(this, void 0, void 0, function* () {
17058
+ var _a;
15566
17059
  if (this.publisher && this.publisher.getSignallingState() !== 'closed') {
15567
17060
  const publisher = this.publisher;
15568
17061
  for (const sender of publisher.getSenders()) {
@@ -15578,13 +17071,15 @@ class PCTransportManager {
15578
17071
  }
15579
17072
  }
15580
17073
  }
15581
- yield Promise.all([this.publisher.close(), this.subscriber.close()]);
17074
+ yield Promise.all([this.publisher.close(), (_a = this.subscriber) === null || _a === void 0 ? void 0 : _a.close()]);
15582
17075
  this.updateState();
15583
17076
  });
15584
17077
  }
15585
17078
  triggerIceRestart() {
15586
17079
  return __awaiter(this, void 0, void 0, function* () {
15587
- this.subscriber.restartingIce = true;
17080
+ if (this.subscriber) {
17081
+ this.subscriber.restartingIce = true;
17082
+ }
15588
17083
  // only restart publisher if it's needed
15589
17084
  if (this.needsPublisher) {
15590
17085
  yield this.createAndSendPublisherOffer({
@@ -15595,28 +17090,30 @@ class PCTransportManager {
15595
17090
  }
15596
17091
  addIceCandidate(candidate, target) {
15597
17092
  return __awaiter(this, void 0, void 0, function* () {
17093
+ var _a;
15598
17094
  if (target === SignalTarget.PUBLISHER) {
15599
17095
  yield this.publisher.addIceCandidate(candidate);
15600
17096
  } else {
15601
- yield this.subscriber.addIceCandidate(candidate);
17097
+ yield (_a = this.subscriber) === null || _a === void 0 ? void 0 : _a.addIceCandidate(candidate);
15602
17098
  }
15603
17099
  });
15604
17100
  }
15605
17101
  createSubscriberAnswerFromOffer(sd, offerId) {
15606
17102
  return __awaiter(this, void 0, void 0, function* () {
17103
+ var _a, _b, _c;
15607
17104
  this.log.debug('received server offer', Object.assign(Object.assign({}, this.logContext), {
15608
17105
  RTCSdpType: sd.type,
15609
17106
  sdp: sd.sdp,
15610
- signalingState: this.subscriber.getSignallingState().toString()
17107
+ signalingState: (_a = this.subscriber) === null || _a === void 0 ? void 0 : _a.getSignallingState().toString()
15611
17108
  }));
15612
17109
  const unlock = yield this.remoteOfferLock.lock();
15613
17110
  try {
15614
- const success = yield this.subscriber.setRemoteDescription(sd, offerId);
17111
+ const success = yield (_b = this.subscriber) === null || _b === void 0 ? void 0 : _b.setRemoteDescription(sd, offerId);
15615
17112
  if (!success) {
15616
17113
  return undefined;
15617
17114
  }
15618
17115
  // answer the offer
15619
- const answer = yield this.subscriber.createAndSetAnswer();
17116
+ const answer = yield (_c = this.subscriber) === null || _c === void 0 ? void 0 : _c.createAndSetAnswer();
15620
17117
  return answer;
15621
17118
  } finally {
15622
17119
  unlock();
@@ -15624,8 +17121,9 @@ class PCTransportManager {
15624
17121
  });
15625
17122
  }
15626
17123
  updateConfiguration(config, iceRestart) {
17124
+ var _a;
15627
17125
  this.publisher.setConfiguration(config);
15628
- this.subscriber.setConfiguration(config);
17126
+ (_a = this.subscriber) === null || _a === void 0 ? void 0 : _a.setConfiguration(config);
15629
17127
  if (iceRestart) {
15630
17128
  this.triggerIceRestart();
15631
17129
  }
@@ -15675,6 +17173,9 @@ class PCTransportManager {
15675
17173
  addPublisherTransceiver(track, transceiverInit) {
15676
17174
  return this.publisher.addTransceiver(track, transceiverInit);
15677
17175
  }
17176
+ addPublisherTransceiverOfKind(kind, transceiverInit) {
17177
+ return this.publisher.addTransceiverOfKind(kind, transceiverInit);
17178
+ }
15678
17179
  addPublisherTrack(track) {
15679
17180
  return this.publisher.addTrack(track);
15680
17181
  }
@@ -15697,7 +17198,7 @@ class PCTransportManager {
15697
17198
  if (this.isPublisherConnectionRequired) {
15698
17199
  transports.push(this.publisher);
15699
17200
  }
15700
- if (this.isSubscriberConnectionRequired) {
17201
+ if (this.isSubscriberConnectionRequired && this.subscriber) {
15701
17202
  transports.push(this.subscriber);
15702
17203
  }
15703
17204
  return transports;
@@ -16768,7 +18269,7 @@ class LocalAudioTrack extends LocalTrack {
16768
18269
  const trackIsSilent = yield detectSilence(this);
16769
18270
  if (trackIsSilent) {
16770
18271
  if (!this.isMuted) {
16771
- this.log.warn('silence detected on local audio track', this.logContext);
18272
+ this.log.debug('silence detected on local audio track', this.logContext);
16772
18273
  }
16773
18274
  this.emit(TrackEvent.AudioSilenceDetected);
16774
18275
  }
@@ -17856,7 +19357,7 @@ class RTCEngine extends eventsExports.EventEmitter {
17856
19357
  }();
17857
19358
  });
17858
19359
  this.handleDataMessage = message => __awaiter(this, void 0, void 0, function* () {
17859
- var _a, _b;
19360
+ var _a, _b, _c, _d, _e;
17860
19361
  // make sure to respect incoming data message order by processing message events one after the other
17861
19362
  const unlock = yield this.dataProcessLock.lock();
17862
19363
  try {
@@ -17884,12 +19385,29 @@ class RTCEngine extends eventsExports.EventEmitter {
17884
19385
  if (((_a = dp.value) === null || _a === void 0 ? void 0 : _a.case) === 'speaker') {
17885
19386
  // dispatch speaker updates
17886
19387
  this.emit(EngineEvent.ActiveSpeakersUpdate, dp.value.value.speakers);
19388
+ } else if (((_b = dp.value) === null || _b === void 0 ? void 0 : _b.case) === 'encryptedPacket') {
19389
+ if (!this.e2eeManager) {
19390
+ this.log.error('Received encrypted packet but E2EE not set up', this.logContext);
19391
+ return;
19392
+ }
19393
+ const decryptedData = yield (_c = this.e2eeManager) === null || _c === void 0 ? void 0 : _c.handleEncryptedData(dp.value.value.encryptedValue, dp.value.value.iv, dp.participantIdentity, dp.value.value.keyIndex);
19394
+ const decryptedPacket = EncryptedPacketPayload.fromBinary(decryptedData.payload);
19395
+ const newDp = new DataPacket({
19396
+ value: decryptedPacket.value,
19397
+ participantIdentity: dp.participantIdentity,
19398
+ participantSid: dp.participantSid
19399
+ });
19400
+ if (((_d = newDp.value) === null || _d === void 0 ? void 0 : _d.case) === 'user') {
19401
+ // compatibility
19402
+ applyUserDataCompat(newDp, newDp.value.value);
19403
+ }
19404
+ this.emit(EngineEvent.DataPacketReceived, newDp, dp.value.value.encryptionType);
17887
19405
  } else {
17888
- if (((_b = dp.value) === null || _b === void 0 ? void 0 : _b.case) === 'user') {
19406
+ if (((_e = dp.value) === null || _e === void 0 ? void 0 : _e.case) === 'user') {
17889
19407
  // compatibility
17890
19408
  applyUserDataCompat(dp, dp.value.value);
17891
19409
  }
17892
- this.emit(EngineEvent.DataPacketReceived, dp);
19410
+ this.emit(EngineEvent.DataPacketReceived, dp, Encryption_Type.NONE);
17893
19411
  }
17894
19412
  } finally {
17895
19413
  unlock();
@@ -18002,7 +19520,6 @@ class RTCEngine extends eventsExports.EventEmitter {
18002
19520
  this.client = new SignalClient(undefined, this.loggerOptions);
18003
19521
  this.client.signalLatency = this.options.expSignalLatency;
18004
19522
  this.reconnectPolicy = this.options.reconnectPolicy;
18005
- this.registerOnLineListener();
18006
19523
  this.closingLock = new _();
18007
19524
  this.dataProcessLock = new _();
18008
19525
  this.dcBufferStatus = new Map([[DataPacket_Kind.LOSSY, true], [DataPacket_Kind.RELIABLE, true]]);
@@ -18043,8 +19560,11 @@ class RTCEngine extends eventsExports.EventEmitter {
18043
19560
  }
18044
19561
  // create offer
18045
19562
  if (!this.subscriberPrimary || joinResponse.fastPublish) {
18046
- this.negotiate();
19563
+ this.negotiate().catch(err => {
19564
+ livekitLogger.error(err, this.logContext);
19565
+ });
18047
19566
  }
19567
+ this.registerOnLineListener();
18048
19568
  this.clientConfiguration = joinResponse.clientConfiguration;
18049
19569
  this.emit(EngineEvent.SignalConnected, joinResponse);
18050
19570
  return joinResponse;
@@ -18190,7 +19710,7 @@ class RTCEngine extends eventsExports.EventEmitter {
18190
19710
  }
18191
19711
  this.participantSid = (_a = joinResponse.participant) === null || _a === void 0 ? void 0 : _a.sid;
18192
19712
  const rtcConfig = this.makeRTCConfiguration(joinResponse);
18193
- this.pcManager = new PCTransportManager(rtcConfig, joinResponse.subscriberPrimary, this.loggerOptions);
19713
+ this.pcManager = new PCTransportManager(rtcConfig, this.options.singlePeerConnection ? 'publisher-only' : joinResponse.subscriberPrimary ? 'subscriber-primary' : 'publisher-primary', this.loggerOptions);
18194
19714
  this.emit(EngineEvent.TransportsCreated, this.pcManager.publisher, this.pcManager.subscriber);
18195
19715
  this.pcManager.onIceCandidate = (candidate, target) => {
18196
19716
  this.client.sendIceCandidate(candidate, target);
@@ -18213,7 +19733,7 @@ class RTCEngine extends eventsExports.EventEmitter {
18213
19733
  }
18214
19734
  } else if (connectionState === PCTransportState.FAILED) {
18215
19735
  // on Safari, PeerConnection will switch to 'disconnected' during renegotiation
18216
- if (this.pcState === PCState.Connected) {
19736
+ if (this.pcState === PCState.Connected || this.pcState === PCState.Reconnecting) {
18217
19737
  this.pcState = PCState.Disconnected;
18218
19738
  this.handleDisconnect('peerconnection failed', subscriberState === 'failed' ? ReconnectReason.RR_SUBSCRIBER_FAILED : ReconnectReason.RR_PUBLISHER_FAILED);
18219
19739
  }
@@ -18226,6 +19746,9 @@ class RTCEngine extends eventsExports.EventEmitter {
18226
19746
  }
18227
19747
  });
18228
19748
  this.pcManager.onTrack = ev => {
19749
+ // this fires after the underlying transceiver is stopped and potentially
19750
+ // peer connection closed, so do not bubble up if there are no streams
19751
+ if (ev.streams.length === 0) return;
18229
19752
  this.emit(EngineEvent.MediaTrackAdded, ev.track, ev.streams[0], ev.receiver);
18230
19753
  };
18231
19754
  if (!supportOptionalDatachannel((_b = joinResponse.serverInfo) === null || _b === void 0 ? void 0 : _b.protocol)) {
@@ -18307,6 +19830,19 @@ class RTCEngine extends eventsExports.EventEmitter {
18307
19830
  }
18308
19831
  this.emit(EngineEvent.RoomMoved, res);
18309
19832
  };
19833
+ this.client.onMediaSectionsRequirement = requirement => {
19834
+ var _a, _b;
19835
+ const transceiverInit = {
19836
+ direction: 'recvonly'
19837
+ };
19838
+ for (let i = 0; i < requirement.numAudios; i++) {
19839
+ (_a = this.pcManager) === null || _a === void 0 ? void 0 : _a.addPublisherTransceiverOfKind('audio', transceiverInit);
19840
+ }
19841
+ for (let i = 0; i < requirement.numVideos; i++) {
19842
+ (_b = this.pcManager) === null || _b === void 0 ? void 0 : _b.addPublisherTransceiverOfKind('video', transceiverInit);
19843
+ }
19844
+ this.negotiate();
19845
+ };
18310
19846
  this.client.onClose = () => {
18311
19847
  this.handleDisconnect('signal', ReconnectReason.RR_SIGNAL_DISCONNECTED);
18312
19848
  };
@@ -18734,6 +20270,20 @@ class RTCEngine extends eventsExports.EventEmitter {
18734
20270
  return __awaiter(this, void 0, void 0, function* () {
18735
20271
  // make sure we do have a data connection
18736
20272
  yield this.ensurePublisherConnected(kind);
20273
+ if (this.e2eeManager && this.e2eeManager.isDataChannelEncryptionEnabled) {
20274
+ const encryptablePacket = asEncryptablePacket(packet);
20275
+ if (encryptablePacket) {
20276
+ const encryptedData = yield this.e2eeManager.encryptData(encryptablePacket.toBinary());
20277
+ packet.value = {
20278
+ case: 'encryptedPacket',
20279
+ value: new EncryptedPacket({
20280
+ encryptedValue: encryptedData.payload,
20281
+ iv: encryptedData.iv,
20282
+ keyIndex: encryptedData.keyIndex
20283
+ })
20284
+ };
20285
+ }
20286
+ }
18737
20287
  if (kind === DataPacket_Kind.RELIABLE) {
18738
20288
  packet.sequence = this.reliableDataSequence;
18739
20289
  this.reliableDataSequence += 1;
@@ -18810,7 +20360,9 @@ class RTCEngine extends eventsExports.EventEmitter {
18810
20360
  }
18811
20361
  if (needNegotiation) {
18812
20362
  // start negotiation
18813
- _this2.negotiate();
20363
+ _this2.negotiate().catch(err => {
20364
+ livekitLogger.error(err, _this2.logContext);
20365
+ });
18814
20366
  }
18815
20367
  const targetChannel = _this2.dataChannelForKind(kind, subscriber);
18816
20368
  if ((targetChannel === null || targetChannel === void 0 ? void 0 : targetChannel.readyState) === 'open') {
@@ -18920,19 +20472,21 @@ class RTCEngine extends eventsExports.EventEmitter {
18920
20472
  }
18921
20473
  /** @internal */
18922
20474
  sendSyncState(remoteTracks, localTracks) {
18923
- var _a, _b;
20475
+ var _a, _b, _c, _d;
18924
20476
  if (!this.pcManager) {
18925
20477
  this.log.warn('sync state cannot be sent without peer connection setup', this.logContext);
18926
20478
  return;
18927
20479
  }
18928
- const previousAnswer = this.pcManager.subscriber.getLocalDescription();
18929
- const previousOffer = this.pcManager.subscriber.getRemoteDescription();
20480
+ const previousPublisherOffer = this.pcManager.publisher.getLocalDescription();
20481
+ const previousPublisherAnswer = this.pcManager.publisher.getRemoteDescription();
20482
+ const previousSubscriberOffer = (_a = this.pcManager.subscriber) === null || _a === void 0 ? void 0 : _a.getRemoteDescription();
20483
+ const previousSubscriberAnswer = (_b = this.pcManager.subscriber) === null || _b === void 0 ? void 0 : _b.getLocalDescription();
18930
20484
  /* 1. autosubscribe on, so subscribed tracks = all tracks - unsub tracks,
18931
20485
  in this case, we send unsub tracks, so server add all tracks to this
18932
20486
  subscribe pc and unsub special tracks from it.
18933
20487
  2. autosubscribe off, we send subscribed tracks.
18934
20488
  */
18935
- const autoSubscribe = (_b = (_a = this.signalOpts) === null || _a === void 0 ? void 0 : _a.autoSubscribe) !== null && _b !== void 0 ? _b : true;
20489
+ const autoSubscribe = (_d = (_c = this.signalOpts) === null || _c === void 0 ? void 0 : _c.autoSubscribe) !== null && _d !== void 0 ? _d : true;
18936
20490
  const trackSids = new Array();
18937
20491
  const trackSidsDisabled = new Array();
18938
20492
  remoteTracks.forEach(track => {
@@ -18944,13 +20498,19 @@ class RTCEngine extends eventsExports.EventEmitter {
18944
20498
  }
18945
20499
  });
18946
20500
  this.client.sendSyncState(new SyncState({
18947
- answer: previousAnswer ? toProtoSessionDescription({
18948
- sdp: previousAnswer.sdp,
18949
- type: previousAnswer.type
20501
+ answer: this.options.singlePeerConnection ? previousPublisherAnswer ? toProtoSessionDescription({
20502
+ sdp: previousPublisherAnswer.sdp,
20503
+ type: previousPublisherAnswer.type
20504
+ }) : undefined : previousSubscriberAnswer ? toProtoSessionDescription({
20505
+ sdp: previousSubscriberAnswer.sdp,
20506
+ type: previousSubscriberAnswer.type
18950
20507
  }) : undefined,
18951
- offer: previousOffer ? toProtoSessionDescription({
18952
- sdp: previousOffer.sdp,
18953
- type: previousOffer.type
20508
+ offer: this.options.singlePeerConnection ? previousPublisherOffer ? toProtoSessionDescription({
20509
+ sdp: previousPublisherOffer.sdp,
20510
+ type: previousPublisherOffer.type
20511
+ }) : undefined : previousSubscriberOffer ? toProtoSessionDescription({
20512
+ sdp: previousSubscriberOffer.sdp,
20513
+ type: previousSubscriberOffer.type
18954
20514
  }) : undefined,
18955
20515
  subscription: new UpdateSubscription({
18956
20516
  trackSids,
@@ -19427,21 +20987,21 @@ class IncomingDataStreamManager {
19427
20987
  }
19428
20988
  }
19429
20989
  }
19430
- handleDataStreamPacket(packet) {
20990
+ handleDataStreamPacket(packet, encryptionType) {
19431
20991
  return __awaiter(this, void 0, void 0, function* () {
19432
20992
  switch (packet.value.case) {
19433
20993
  case 'streamHeader':
19434
- return this.handleStreamHeader(packet.value.value, packet.participantIdentity);
20994
+ return this.handleStreamHeader(packet.value.value, packet.participantIdentity, encryptionType);
19435
20995
  case 'streamChunk':
19436
- return this.handleStreamChunk(packet.value.value);
20996
+ return this.handleStreamChunk(packet.value.value, encryptionType);
19437
20997
  case 'streamTrailer':
19438
- return this.handleStreamTrailer(packet.value.value);
20998
+ return this.handleStreamTrailer(packet.value.value, encryptionType);
19439
20999
  default:
19440
21000
  throw new Error("DataPacket of value \"".concat(packet.value.case, "\" is not data stream related!"));
19441
21001
  }
19442
21002
  });
19443
21003
  }
19444
- handleStreamHeader(streamHeader, participantIdentity) {
21004
+ handleStreamHeader(streamHeader, participantIdentity, encryptionType) {
19445
21005
  return __awaiter(this, void 0, void 0, function* () {
19446
21006
  var _a;
19447
21007
  if (streamHeader.contentHeader.case === 'byteHeader') {
@@ -19452,6 +21012,9 @@ class IncomingDataStreamManager {
19452
21012
  }
19453
21013
  let streamController;
19454
21014
  const outOfBandFailureRejectingFuture = new Future();
21015
+ outOfBandFailureRejectingFuture.promise.catch(err => {
21016
+ this.log.error(err);
21017
+ });
19455
21018
  const info = {
19456
21019
  id: streamHeader.streamId,
19457
21020
  name: (_a = streamHeader.contentHeader.value.name) !== null && _a !== void 0 ? _a : 'unknown',
@@ -19459,7 +21022,8 @@ class IncomingDataStreamManager {
19459
21022
  size: streamHeader.totalLength ? Number(streamHeader.totalLength) : undefined,
19460
21023
  topic: streamHeader.topic,
19461
21024
  timestamp: bigIntToNumber(streamHeader.timestamp),
19462
- attributes: streamHeader.attributes
21025
+ attributes: streamHeader.attributes,
21026
+ encryptionType
19463
21027
  };
19464
21028
  const stream = new ReadableStream({
19465
21029
  start: controller => {
@@ -19487,13 +21051,17 @@ class IncomingDataStreamManager {
19487
21051
  }
19488
21052
  let streamController;
19489
21053
  const outOfBandFailureRejectingFuture = new Future();
21054
+ outOfBandFailureRejectingFuture.promise.catch(err => {
21055
+ this.log.error(err);
21056
+ });
19490
21057
  const info = {
19491
21058
  id: streamHeader.streamId,
19492
21059
  mimeType: streamHeader.mimeType,
19493
21060
  size: streamHeader.totalLength ? Number(streamHeader.totalLength) : undefined,
19494
21061
  topic: streamHeader.topic,
19495
21062
  timestamp: Number(streamHeader.timestamp),
19496
- attributes: streamHeader.attributes
21063
+ attributes: streamHeader.attributes,
21064
+ encryptionType
19497
21065
  };
19498
21066
  const stream = new ReadableStream({
19499
21067
  start: controller => {
@@ -19516,34 +21084,46 @@ class IncomingDataStreamManager {
19516
21084
  }
19517
21085
  });
19518
21086
  }
19519
- handleStreamChunk(chunk) {
21087
+ handleStreamChunk(chunk, encryptionType) {
19520
21088
  const fileBuffer = this.byteStreamControllers.get(chunk.streamId);
19521
21089
  if (fileBuffer) {
19522
- if (chunk.content.length > 0) {
21090
+ if (fileBuffer.info.encryptionType !== encryptionType) {
21091
+ fileBuffer.controller.error(new DataStreamError("Encryption type mismatch for stream ".concat(chunk.streamId, ". Expected ").concat(encryptionType, ", got ").concat(fileBuffer.info.encryptionType), DataStreamErrorReason.EncryptionTypeMismatch));
21092
+ this.byteStreamControllers.delete(chunk.streamId);
21093
+ } else if (chunk.content.length > 0) {
19523
21094
  fileBuffer.controller.enqueue(chunk);
19524
21095
  }
19525
21096
  }
19526
21097
  const textBuffer = this.textStreamControllers.get(chunk.streamId);
19527
21098
  if (textBuffer) {
19528
- if (chunk.content.length > 0) {
21099
+ if (textBuffer.info.encryptionType !== encryptionType) {
21100
+ textBuffer.controller.error(new DataStreamError("Encryption type mismatch for stream ".concat(chunk.streamId, ". Expected ").concat(encryptionType, ", got ").concat(textBuffer.info.encryptionType), DataStreamErrorReason.EncryptionTypeMismatch));
21101
+ this.textStreamControllers.delete(chunk.streamId);
21102
+ } else if (chunk.content.length > 0) {
19529
21103
  textBuffer.controller.enqueue(chunk);
19530
21104
  }
19531
21105
  }
19532
21106
  }
19533
- handleStreamTrailer(trailer) {
21107
+ handleStreamTrailer(trailer, encryptionType) {
19534
21108
  const textBuffer = this.textStreamControllers.get(trailer.streamId);
19535
21109
  if (textBuffer) {
19536
- textBuffer.info.attributes = Object.assign(Object.assign({}, textBuffer.info.attributes), trailer.attributes);
19537
- textBuffer.controller.close();
19538
- this.textStreamControllers.delete(trailer.streamId);
21110
+ if (textBuffer.info.encryptionType !== encryptionType) {
21111
+ textBuffer.controller.error(new DataStreamError("Encryption type mismatch for stream ".concat(trailer.streamId, ". Expected ").concat(encryptionType, ", got ").concat(textBuffer.info.encryptionType), DataStreamErrorReason.EncryptionTypeMismatch));
21112
+ } else {
21113
+ textBuffer.info.attributes = Object.assign(Object.assign({}, textBuffer.info.attributes), trailer.attributes);
21114
+ textBuffer.controller.close();
21115
+ this.textStreamControllers.delete(trailer.streamId);
21116
+ }
19539
21117
  }
19540
21118
  const fileBuffer = this.byteStreamControllers.get(trailer.streamId);
19541
21119
  if (fileBuffer) {
19542
- {
21120
+ if (fileBuffer.info.encryptionType !== encryptionType) {
21121
+ fileBuffer.controller.error(new DataStreamError("Encryption type mismatch for stream ".concat(trailer.streamId, ". Expected ").concat(encryptionType, ", got ").concat(fileBuffer.info.encryptionType), DataStreamErrorReason.EncryptionTypeMismatch));
21122
+ } else {
19543
21123
  fileBuffer.info.attributes = Object.assign(Object.assign({}, fileBuffer.info.attributes), trailer.attributes);
19544
21124
  fileBuffer.controller.close();
19545
- this.byteStreamControllers.delete(trailer.streamId);
19546
21125
  }
21126
+ this.byteStreamControllers.delete(trailer.streamId);
19547
21127
  }
19548
21128
  }
19549
21129
  }
@@ -19630,7 +21210,7 @@ class OutgoingDataStreamManager {
19630
21210
  */
19631
21211
  streamText(options) {
19632
21212
  return __awaiter(this, void 0, void 0, function* () {
19633
- var _a, _b;
21213
+ var _a, _b, _c;
19634
21214
  const streamId = (_a = options === null || options === void 0 ? void 0 : options.streamId) !== null && _a !== void 0 ? _a : crypto.randomUUID();
19635
21215
  const info = {
19636
21216
  id: streamId,
@@ -19638,7 +21218,8 @@ class OutgoingDataStreamManager {
19638
21218
  timestamp: Date.now(),
19639
21219
  topic: (_b = options === null || options === void 0 ? void 0 : options.topic) !== null && _b !== void 0 ? _b : '',
19640
21220
  size: options === null || options === void 0 ? void 0 : options.totalSize,
19641
- attributes: options === null || options === void 0 ? void 0 : options.attributes
21221
+ attributes: options === null || options === void 0 ? void 0 : options.attributes,
21222
+ encryptionType: ((_c = this.engine.e2eeManager) === null || _c === void 0 ? void 0 : _c.isDataChannelEncryptionEnabled) ? Encryption_Type.GCM : Encryption_Type.NONE
19642
21223
  };
19643
21224
  const header = new DataStream_Header({
19644
21225
  streamId,
@@ -19756,7 +21337,7 @@ class OutgoingDataStreamManager {
19756
21337
  }
19757
21338
  streamBytes(options) {
19758
21339
  return __awaiter(this, void 0, void 0, function* () {
19759
- var _a, _b, _c, _d, _e;
21340
+ var _a, _b, _c, _d, _e, _f;
19760
21341
  const streamId = (_a = options === null || options === void 0 ? void 0 : options.streamId) !== null && _a !== void 0 ? _a : crypto.randomUUID();
19761
21342
  const destinationIdentities = options === null || options === void 0 ? void 0 : options.destinationIdentities;
19762
21343
  const info = {
@@ -19766,10 +21347,11 @@ class OutgoingDataStreamManager {
19766
21347
  timestamp: Date.now(),
19767
21348
  attributes: options === null || options === void 0 ? void 0 : options.attributes,
19768
21349
  size: options === null || options === void 0 ? void 0 : options.totalSize,
19769
- name: (_d = options === null || options === void 0 ? void 0 : options.name) !== null && _d !== void 0 ? _d : 'unknown'
21350
+ name: (_d = options === null || options === void 0 ? void 0 : options.name) !== null && _d !== void 0 ? _d : 'unknown',
21351
+ encryptionType: ((_e = this.engine.e2eeManager) === null || _e === void 0 ? void 0 : _e.isDataChannelEncryptionEnabled) ? Encryption_Type.GCM : Encryption_Type.NONE
19770
21352
  };
19771
21353
  const header = new DataStream_Header({
19772
- totalLength: numberToBigInt((_e = info.size) !== null && _e !== void 0 ? _e : 0),
21354
+ totalLength: numberToBigInt((_f = info.size) !== null && _f !== void 0 ? _f : 0),
19773
21355
  mimeType: info.mimeType,
19774
21356
  streamId,
19775
21357
  topic: info.topic,
@@ -22523,16 +24105,17 @@ class LocalParticipant extends Participant {
22523
24105
  const kind = options.reliable ? DataPacket_Kind.RELIABLE : DataPacket_Kind.LOSSY;
22524
24106
  const destinationIdentities = options.destinationIdentities;
22525
24107
  const topic = options.topic;
24108
+ let userPacket = new UserPacket({
24109
+ participantIdentity: _this4.identity,
24110
+ payload: data,
24111
+ destinationIdentities,
24112
+ topic
24113
+ });
22526
24114
  const packet = new DataPacket({
22527
24115
  kind: kind,
22528
24116
  value: {
22529
24117
  case: 'user',
22530
- value: new UserPacket({
22531
- participantIdentity: _this4.identity,
22532
- payload: data,
22533
- destinationIdentities,
22534
- topic
22535
- })
24118
+ value: userPacket
22536
24119
  }
22537
24120
  });
22538
24121
  yield _this4.engine.sendDataPacket(packet, kind);
@@ -23457,6 +25040,9 @@ const connectionReconcileFrequency = 4 * 1000;
23457
25040
  * @noInheritDoc
23458
25041
  */
23459
25042
  class Room extends eventsExports.EventEmitter {
25043
+ get hasE2EESetup() {
25044
+ return this.e2eeManager !== undefined;
25045
+ }
23460
25046
  /**
23461
25047
  * Creates a new Room, the primary construct for a LiveKit session.
23462
25048
  * @param options
@@ -23584,7 +25170,8 @@ class Room extends eventsExports.EventEmitter {
23584
25170
  adaptiveStream: typeof roomOptions.adaptiveStream === 'object' ? true : roomOptions.adaptiveStream,
23585
25171
  maxRetries: connectOptions.maxRetries,
23586
25172
  e2eeEnabled: !!this.e2eeManager,
23587
- websocketTimeout: connectOptions.websocketTimeout
25173
+ websocketTimeout: connectOptions.websocketTimeout,
25174
+ singlePeerConnection: roomOptions.singlePeerConnection
23588
25175
  }, abortController.signal);
23589
25176
  let serverInfo = joinResponse.serverInfo;
23590
25177
  if (!serverInfo) {
@@ -23617,7 +25204,7 @@ class Room extends eventsExports.EventEmitter {
23617
25204
  this.localParticipant.sid = pi.sid;
23618
25205
  this.localParticipant.identity = pi.identity;
23619
25206
  this.localParticipant.setEnabledPublishCodecs(joinResponse.enabledPublishCodecs);
23620
- if (this.options.e2ee && this.e2eeManager) {
25207
+ if (this.e2eeManager) {
23621
25208
  try {
23622
25209
  this.e2eeManager.setSifTrailer(joinResponse.sifTrailer);
23623
25210
  } catch (e) {
@@ -23721,8 +25308,9 @@ class Room extends eventsExports.EventEmitter {
23721
25308
  _this2.log.info('disconnect from room', Object.assign({}, _this2.logContext));
23722
25309
  if (_this2.state === ConnectionState.Connecting || _this2.state === ConnectionState.Reconnecting || _this2.isResuming) {
23723
25310
  // try aborting pending connection attempt
23724
- _this2.log.warn('abort connection attempt', _this2.logContext);
23725
- (_a = _this2.abortController) === null || _a === void 0 ? void 0 : _a.abort();
25311
+ const msg = 'Abort connection attempt due to user initiated disconnect';
25312
+ _this2.log.warn(msg, _this2.logContext);
25313
+ (_a = _this2.abortController) === null || _a === void 0 ? void 0 : _a.abort(msg);
23726
25314
  // in case the abort controller didn't manage to cancel the connection attempt, reject the connect promise explicitly
23727
25315
  (_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', ConnectionErrorReason.Cancelled));
23728
25316
  _this2.connectFuture = undefined;
@@ -24005,11 +25593,11 @@ class Room extends eventsExports.EventEmitter {
24005
25593
  }
24006
25594
  pub.setSubscriptionError(update.err);
24007
25595
  };
24008
- this.handleDataPacket = packet => {
25596
+ this.handleDataPacket = (packet, encryptionType) => {
24009
25597
  // find the participant
24010
25598
  const participant = this.remoteParticipants.get(packet.participantIdentity);
24011
25599
  if (packet.value.case === 'user') {
24012
- this.handleUserPacket(participant, packet.value.value, packet.kind);
25600
+ this.handleUserPacket(participant, packet.value.value, packet.kind, encryptionType);
24013
25601
  } else if (packet.value.case === 'transcription') {
24014
25602
  this.handleTranscription(participant, packet.value.value);
24015
25603
  } else if (packet.value.case === 'sipDtmf') {
@@ -24019,16 +25607,16 @@ class Room extends eventsExports.EventEmitter {
24019
25607
  } else if (packet.value.case === 'metrics') {
24020
25608
  this.handleMetrics(packet.value.value, participant);
24021
25609
  } else if (packet.value.case === 'streamHeader' || packet.value.case === 'streamChunk' || packet.value.case === 'streamTrailer') {
24022
- this.handleDataStream(packet);
25610
+ this.handleDataStream(packet, encryptionType);
24023
25611
  } else if (packet.value.case === 'rpcRequest') {
24024
25612
  const rpc = packet.value.value;
24025
25613
  this.handleIncomingRpcRequest(packet.participantIdentity, rpc.id, rpc.method, rpc.payload, rpc.responseTimeoutMs, rpc.version);
24026
25614
  }
24027
25615
  };
24028
- this.handleUserPacket = (participant, userPacket, kind) => {
24029
- this.emit(RoomEvent.DataReceived, userPacket.payload, participant, kind, userPacket.topic);
25616
+ this.handleUserPacket = (participant, userPacket, kind, encryptionType) => {
25617
+ this.emit(RoomEvent.DataReceived, userPacket.payload, participant, kind, userPacket.topic, encryptionType);
24030
25618
  // also emit on the participant
24031
- participant === null || participant === void 0 ? void 0 : participant.emit(ParticipantEvent.DataReceived, userPacket.payload, kind);
25619
+ participant === null || participant === void 0 ? void 0 : participant.emit(ParticipantEvent.DataReceived, userPacket.payload, kind, encryptionType);
24032
25620
  };
24033
25621
  this.handleSipDtmf = (participant, dtmf) => {
24034
25622
  this.emit(RoomEvent.SipDTMFReceived, dtmf, participant);
@@ -24051,8 +25639,8 @@ class Room extends eventsExports.EventEmitter {
24051
25639
  this.handleMetrics = (metrics, participant) => {
24052
25640
  this.emit(RoomEvent.MetricsReceived, metrics, participant);
24053
25641
  };
24054
- this.handleDataStream = packet => {
24055
- this.incomingDataStreamManager.handleDataStreamPacket(packet);
25642
+ this.handleDataStream = (packet, encryptionType) => {
25643
+ this.incomingDataStreamManager.handleDataStreamPacket(packet, encryptionType);
24056
25644
  };
24057
25645
  this.bufferedSegments = new Map();
24058
25646
  this.handleAudioPlaybackStarted = () => {
@@ -24193,6 +25781,10 @@ class Room extends eventsExports.EventEmitter {
24193
25781
  this.outgoingDataStreamManager = new OutgoingDataStreamManager(this.engine, this.log);
24194
25782
  this.disconnectLock = new _();
24195
25783
  this.localParticipant = new LocalParticipant('', '', this.engine, this.options, this.rpcHandlers, this.outgoingDataStreamManager);
25784
+ if (this.options.e2ee || this.options.encryption) {
25785
+ this.setupE2EE();
25786
+ }
25787
+ this.engine.e2eeManager = this.e2eeManager;
24196
25788
  if (this.options.videoCaptureDefaults.deviceId) {
24197
25789
  this.localParticipant.activeDeviceMap.set('videoinput', unwrapConstraint(this.options.videoCaptureDefaults.deviceId));
24198
25790
  }
@@ -24202,9 +25794,6 @@ class Room extends eventsExports.EventEmitter {
24202
25794
  if ((_b = this.options.audioOutput) === null || _b === void 0 ? void 0 : _b.deviceId) {
24203
25795
  this.switchActiveDevice('audiooutput', unwrapConstraint(this.options.audioOutput.deviceId)).catch(e => this.log.warn("Could not set audio output: ".concat(e.message), this.logContext));
24204
25796
  }
24205
- if (this.options.e2ee) {
24206
- this.setupE2EE();
24207
- }
24208
25797
  if (isWeb()) {
24209
25798
  const abortController = new AbortController();
24210
25799
  // in order to catch device changes prior to room connection we need to register the event in the constructor
@@ -24286,12 +25875,16 @@ class Room extends eventsExports.EventEmitter {
24286
25875
  });
24287
25876
  }
24288
25877
  setupE2EE() {
25878
+ // when encryption is enabled via `options.encryption`, we enable data channel encryption
24289
25879
  var _a;
24290
- if (this.options.e2ee) {
24291
- if ('e2eeManager' in this.options.e2ee) {
24292
- this.e2eeManager = this.options.e2ee.e2eeManager;
25880
+ const dcEncryptionEnabled = !!this.options.encryption;
25881
+ const e2eeOptions = this.options.encryption || this.options.e2ee;
25882
+ if (e2eeOptions) {
25883
+ if ('e2eeManager' in e2eeOptions) {
25884
+ this.e2eeManager = e2eeOptions.e2eeManager;
25885
+ this.e2eeManager.isDataChannelEncryptionEnabled = dcEncryptionEnabled;
24293
25886
  } else {
24294
- this.e2eeManager = new E2EEManager(this.options.e2ee);
25887
+ this.e2eeManager = new E2EEManager(e2eeOptions, dcEncryptionEnabled);
24295
25888
  }
24296
25889
  this.e2eeManager.on(EncryptionEvent.ParticipantEncryptionStatusChanged, (enabled, participant) => {
24297
25890
  if (isLocalParticipant(participant)) {
@@ -24369,6 +25962,7 @@ class Room extends eventsExports.EventEmitter {
24369
25962
  return;
24370
25963
  }
24371
25964
  this.engine = new RTCEngine(this.options);
25965
+ this.engine.e2eeManager = this.e2eeManager;
24372
25966
  this.engine.on(EngineEvent.ParticipantUpdate, this.handleParticipantUpdates).on(EngineEvent.RoomUpdate, this.handleRoomUpdate).on(EngineEvent.SpeakersChanged, this.handleSpeakersChanged).on(EngineEvent.StreamStateChanged, this.handleStreamStateUpdate).on(EngineEvent.ConnectionQualityUpdate, this.handleConnectionQualityUpdate).on(EngineEvent.SubscriptionError, this.handleSubscriptionError).on(EngineEvent.SubscriptionPermissionUpdate, this.handleSubscriptionPermissionUpdate).on(EngineEvent.MediaTrackAdded, (mediaTrack, stream, receiver) => {
24373
25967
  this.onTrackAdded(mediaTrack, stream, receiver);
24374
25968
  }).on(EngineEvent.Disconnected, reason => {
@@ -25769,6 +27363,11 @@ class PublishVideoCheck extends Checker {
25769
27363
  const video = document.createElement('video');
25770
27364
  video.srcObject = stream;
25771
27365
  video.muted = true;
27366
+ video.autoplay = true;
27367
+ video.playsInline = true;
27368
+ // For iOS Safari
27369
+ video.setAttribute('playsinline', 'true');
27370
+ document.body.appendChild(video);
25772
27371
  yield new Promise(resolve => {
25773
27372
  video.onplay = () => {
25774
27373
  setTimeout(() => {
@@ -25858,7 +27457,8 @@ class TURNCheck extends Checker {
25858
27457
  autoSubscribe: true,
25859
27458
  maxRetries: 0,
25860
27459
  e2eeEnabled: false,
25861
- websocketTimeout: 15000
27460
+ websocketTimeout: 15000,
27461
+ singlePeerConnection: false
25862
27462
  });
25863
27463
  let hasTLS = false;
25864
27464
  let hasTURN = false;
@@ -25908,6 +27508,7 @@ class WebRTCCheck extends Checker {
25908
27508
  let hasTcp = false;
25909
27509
  let hasIpv4Udp = false;
25910
27510
  this.room.on(RoomEvent.SignalConnected, () => {
27511
+ var _a;
25911
27512
  const prevTrickle = this.room.engine.client.onTrickle;
25912
27513
  this.room.engine.client.onTrickle = (sd, target) => {
25913
27514
  if (sd.candidate) {
@@ -25931,7 +27532,7 @@ class WebRTCCheck extends Checker {
25931
27532
  prevTrickle(sd, target);
25932
27533
  }
25933
27534
  };
25934
- if (this.room.engine.pcManager) {
27535
+ if ((_a = this.room.engine.pcManager) === null || _a === void 0 ? void 0 : _a.subscriber) {
25935
27536
  this.room.engine.pcManager.subscriber.onIceCandidateError = ev => {
25936
27537
  if (ev instanceof RTCPeerConnectionIceErrorEvent) {
25937
27538
  this.appendWarning("error with ICE candidate: ".concat(ev.errorCode, " ").concat(ev.errorText, " ").concat(ev.url));
@@ -25987,7 +27588,8 @@ class WebSocketCheck extends Checker {
25987
27588
  autoSubscribe: true,
25988
27589
  maxRetries: 0,
25989
27590
  e2eeEnabled: false,
25990
- websocketTimeout: 15000
27591
+ websocketTimeout: 15000,
27592
+ singlePeerConnection: false
25991
27593
  });
25992
27594
  this.appendMessage("Connected to server, version ".concat(joinRes.serverVersion, "."));
25993
27595
  if (((_a = joinRes.serverInfo) === null || _a === void 0 ? void 0 : _a.edition) === ServerInfo_Edition.Cloud && ((_b = joinRes.serverInfo) === null || _b === void 0 ? void 0 : _b.region)) {
@@ -26088,6 +27690,523 @@ class ConnectionCheck extends eventsExports.EventEmitter {
26088
27690
  }
26089
27691
  }
26090
27692
 
27693
+ /** A Fixed TokenSource is a token source that takes no parameters and returns a completely
27694
+ * independently derived value on each fetch() call.
27695
+ *
27696
+ * The most common downstream implementer is {@link TokenSourceLiteral}.
27697
+ */
27698
+ class TokenSourceFixed {}
27699
+ /** A Configurable TokenSource is a token source that takes a
27700
+ * {@link TokenSourceFetchOptions} object as input and returns a deterministic
27701
+ * {@link TokenSourceResponseObject} output based on the options specified.
27702
+ *
27703
+ * For example, if options.participantName is set, it should be expected that
27704
+ * all tokens that are generated will have participant name field set to the
27705
+ * provided value.
27706
+ *
27707
+ * A few common downstream implementers are {@link TokenSourceEndpoint}
27708
+ * and {@link TokenSourceCustom}.
27709
+ */
27710
+ class TokenSourceConfigurable {}
27711
+
27712
+ function _defineProperty(e, r, t) {
27713
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
27714
+ value: t,
27715
+ enumerable: true,
27716
+ configurable: true,
27717
+ writable: true
27718
+ }) : e[r] = t, e;
27719
+ }
27720
+ function _toPrimitive(t, r) {
27721
+ if ("object" != typeof t || !t) return t;
27722
+ var e = t[Symbol.toPrimitive];
27723
+ if (void 0 !== e) {
27724
+ var i = e.call(t, r);
27725
+ if ("object" != typeof i) return i;
27726
+ throw new TypeError("@@toPrimitive must return a primitive value.");
27727
+ }
27728
+ return ("string" === r ? String : Number)(t);
27729
+ }
27730
+ function _toPropertyKey(t) {
27731
+ var i = _toPrimitive(t, "string");
27732
+ return "symbol" == typeof i ? i : i + "";
27733
+ }
27734
+
27735
+ new TextEncoder();
27736
+ const decoder = new TextDecoder();
27737
+
27738
+ function decodeBase64(encoded) {
27739
+ if (Uint8Array.fromBase64) {
27740
+ return Uint8Array.fromBase64(encoded);
27741
+ }
27742
+ const binary = atob(encoded);
27743
+ const bytes = new Uint8Array(binary.length);
27744
+ for (let i = 0; i < binary.length; i++) {
27745
+ bytes[i] = binary.charCodeAt(i);
27746
+ }
27747
+ return bytes;
27748
+ }
27749
+
27750
+ function decode(input) {
27751
+ if (Uint8Array.fromBase64) {
27752
+ return Uint8Array.fromBase64(typeof input === 'string' ? input : decoder.decode(input), {
27753
+ alphabet: 'base64url'
27754
+ });
27755
+ }
27756
+ let encoded = input;
27757
+ if (encoded instanceof Uint8Array) {
27758
+ encoded = decoder.decode(encoded);
27759
+ }
27760
+ encoded = encoded.replace(/-/g, '+').replace(/_/g, '/').replace(/\s/g, '');
27761
+ try {
27762
+ return decodeBase64(encoded);
27763
+ } catch (_unused) {
27764
+ throw new TypeError('The input to be decoded is not correctly encoded.');
27765
+ }
27766
+ }
27767
+
27768
+ class JOSEError extends Error {
27769
+ constructor(message, options) {
27770
+ var _Error$captureStackTr;
27771
+ super(message, options);
27772
+ _defineProperty(this, "code", 'ERR_JOSE_GENERIC');
27773
+ this.name = this.constructor.name;
27774
+ (_Error$captureStackTr = Error.captureStackTrace) === null || _Error$captureStackTr === void 0 || _Error$captureStackTr.call(Error, this, this.constructor);
27775
+ }
27776
+ }
27777
+ _defineProperty(JOSEError, "code", 'ERR_JOSE_GENERIC');
27778
+ class JWTClaimValidationFailed extends JOSEError {
27779
+ constructor(message, payload) {
27780
+ let claim = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'unspecified';
27781
+ let reason = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'unspecified';
27782
+ super(message, {
27783
+ cause: {
27784
+ claim,
27785
+ reason,
27786
+ payload
27787
+ }
27788
+ });
27789
+ _defineProperty(this, "code", 'ERR_JWT_CLAIM_VALIDATION_FAILED');
27790
+ _defineProperty(this, "claim", void 0);
27791
+ _defineProperty(this, "reason", void 0);
27792
+ _defineProperty(this, "payload", void 0);
27793
+ this.claim = claim;
27794
+ this.reason = reason;
27795
+ this.payload = payload;
27796
+ }
27797
+ }
27798
+ _defineProperty(JWTClaimValidationFailed, "code", 'ERR_JWT_CLAIM_VALIDATION_FAILED');
27799
+ class JWTExpired extends JOSEError {
27800
+ constructor(message, payload) {
27801
+ let claim = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'unspecified';
27802
+ let reason = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'unspecified';
27803
+ super(message, {
27804
+ cause: {
27805
+ claim,
27806
+ reason,
27807
+ payload
27808
+ }
27809
+ });
27810
+ _defineProperty(this, "code", 'ERR_JWT_EXPIRED');
27811
+ _defineProperty(this, "claim", void 0);
27812
+ _defineProperty(this, "reason", void 0);
27813
+ _defineProperty(this, "payload", void 0);
27814
+ this.claim = claim;
27815
+ this.reason = reason;
27816
+ this.payload = payload;
27817
+ }
27818
+ }
27819
+ _defineProperty(JWTExpired, "code", 'ERR_JWT_EXPIRED');
27820
+ class JOSEAlgNotAllowed extends JOSEError {
27821
+ constructor() {
27822
+ super(...arguments);
27823
+ _defineProperty(this, "code", 'ERR_JOSE_ALG_NOT_ALLOWED');
27824
+ }
27825
+ }
27826
+ _defineProperty(JOSEAlgNotAllowed, "code", 'ERR_JOSE_ALG_NOT_ALLOWED');
27827
+ class JOSENotSupported extends JOSEError {
27828
+ constructor() {
27829
+ super(...arguments);
27830
+ _defineProperty(this, "code", 'ERR_JOSE_NOT_SUPPORTED');
27831
+ }
27832
+ }
27833
+ _defineProperty(JOSENotSupported, "code", 'ERR_JOSE_NOT_SUPPORTED');
27834
+ class JWEDecryptionFailed extends JOSEError {
27835
+ constructor() {
27836
+ let message = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'decryption operation failed';
27837
+ let options = arguments.length > 1 ? arguments[1] : undefined;
27838
+ super(message, options);
27839
+ _defineProperty(this, "code", 'ERR_JWE_DECRYPTION_FAILED');
27840
+ }
27841
+ }
27842
+ _defineProperty(JWEDecryptionFailed, "code", 'ERR_JWE_DECRYPTION_FAILED');
27843
+ class JWEInvalid extends JOSEError {
27844
+ constructor() {
27845
+ super(...arguments);
27846
+ _defineProperty(this, "code", 'ERR_JWE_INVALID');
27847
+ }
27848
+ }
27849
+ _defineProperty(JWEInvalid, "code", 'ERR_JWE_INVALID');
27850
+ class JWSInvalid extends JOSEError {
27851
+ constructor() {
27852
+ super(...arguments);
27853
+ _defineProperty(this, "code", 'ERR_JWS_INVALID');
27854
+ }
27855
+ }
27856
+ _defineProperty(JWSInvalid, "code", 'ERR_JWS_INVALID');
27857
+ class JWTInvalid extends JOSEError {
27858
+ constructor() {
27859
+ super(...arguments);
27860
+ _defineProperty(this, "code", 'ERR_JWT_INVALID');
27861
+ }
27862
+ }
27863
+ _defineProperty(JWTInvalid, "code", 'ERR_JWT_INVALID');
27864
+ class JWKInvalid extends JOSEError {
27865
+ constructor() {
27866
+ super(...arguments);
27867
+ _defineProperty(this, "code", 'ERR_JWK_INVALID');
27868
+ }
27869
+ }
27870
+ _defineProperty(JWKInvalid, "code", 'ERR_JWK_INVALID');
27871
+ class JWKSInvalid extends JOSEError {
27872
+ constructor() {
27873
+ super(...arguments);
27874
+ _defineProperty(this, "code", 'ERR_JWKS_INVALID');
27875
+ }
27876
+ }
27877
+ _defineProperty(JWKSInvalid, "code", 'ERR_JWKS_INVALID');
27878
+ class JWKSNoMatchingKey extends JOSEError {
27879
+ constructor() {
27880
+ let message = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'no applicable key found in the JSON Web Key Set';
27881
+ let options = arguments.length > 1 ? arguments[1] : undefined;
27882
+ super(message, options);
27883
+ _defineProperty(this, "code", 'ERR_JWKS_NO_MATCHING_KEY');
27884
+ }
27885
+ }
27886
+ _defineProperty(JWKSNoMatchingKey, "code", 'ERR_JWKS_NO_MATCHING_KEY');
27887
+ class JWKSMultipleMatchingKeys extends JOSEError {
27888
+ constructor() {
27889
+ let message = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'multiple matching keys found in the JSON Web Key Set';
27890
+ let options = arguments.length > 1 ? arguments[1] : undefined;
27891
+ super(message, options);
27892
+ _defineProperty(this, Symbol.asyncIterator, void 0);
27893
+ _defineProperty(this, "code", 'ERR_JWKS_MULTIPLE_MATCHING_KEYS');
27894
+ }
27895
+ }
27896
+ _defineProperty(JWKSMultipleMatchingKeys, "code", 'ERR_JWKS_MULTIPLE_MATCHING_KEYS');
27897
+ class JWKSTimeout extends JOSEError {
27898
+ constructor() {
27899
+ let message = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'request timed out';
27900
+ let options = arguments.length > 1 ? arguments[1] : undefined;
27901
+ super(message, options);
27902
+ _defineProperty(this, "code", 'ERR_JWKS_TIMEOUT');
27903
+ }
27904
+ }
27905
+ _defineProperty(JWKSTimeout, "code", 'ERR_JWKS_TIMEOUT');
27906
+ class JWSSignatureVerificationFailed extends JOSEError {
27907
+ constructor() {
27908
+ let message = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'signature verification failed';
27909
+ let options = arguments.length > 1 ? arguments[1] : undefined;
27910
+ super(message, options);
27911
+ _defineProperty(this, "code", 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED');
27912
+ }
27913
+ }
27914
+ _defineProperty(JWSSignatureVerificationFailed, "code", 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED');
27915
+
27916
+ function isObjectLike(value) {
27917
+ return typeof value === 'object' && value !== null;
27918
+ }
27919
+ var isObject = input => {
27920
+ if (!isObjectLike(input) || Object.prototype.toString.call(input) !== '[object Object]') {
27921
+ return false;
27922
+ }
27923
+ if (Object.getPrototypeOf(input) === null) {
27924
+ return true;
27925
+ }
27926
+ let proto = input;
27927
+ while (Object.getPrototypeOf(proto) !== null) {
27928
+ proto = Object.getPrototypeOf(proto);
27929
+ }
27930
+ return Object.getPrototypeOf(input) === proto;
27931
+ };
27932
+
27933
+ function decodeJwt(jwt) {
27934
+ if (typeof jwt !== 'string') throw new JWTInvalid('JWTs must use Compact JWS serialization, JWT must be a string');
27935
+ const {
27936
+ 1: payload,
27937
+ length
27938
+ } = jwt.split('.');
27939
+ if (length === 5) throw new JWTInvalid('Only JWTs using Compact JWS serialization can be decoded');
27940
+ if (length !== 3) throw new JWTInvalid('Invalid JWT');
27941
+ if (!payload) throw new JWTInvalid('JWTs must contain a payload');
27942
+ let decoded;
27943
+ try {
27944
+ decoded = decode(payload);
27945
+ } catch (_unused) {
27946
+ throw new JWTInvalid('Failed to base64url decode the payload');
27947
+ }
27948
+ let result;
27949
+ try {
27950
+ result = JSON.parse(decoder.decode(decoded));
27951
+ } catch (_unused2) {
27952
+ throw new JWTInvalid('Failed to parse the decoded payload as JSON');
27953
+ }
27954
+ if (!isObject(result)) throw new JWTInvalid('Invalid JWT Claims Set');
27955
+ return result;
27956
+ }
27957
+
27958
+ const ONE_SECOND_IN_MILLISECONDS = 1000;
27959
+ const ONE_MINUTE_IN_MILLISECONDS = 60 * ONE_SECOND_IN_MILLISECONDS;
27960
+ function isResponseTokenValid(response) {
27961
+ const jwtPayload = decodeTokenPayload(response.participantToken);
27962
+ if (!(jwtPayload === null || jwtPayload === void 0 ? void 0 : jwtPayload.nbf) || !(jwtPayload === null || jwtPayload === void 0 ? void 0 : jwtPayload.exp)) {
27963
+ return true;
27964
+ }
27965
+ const now = new Date();
27966
+ const nbfInMilliseconds = jwtPayload.nbf * ONE_SECOND_IN_MILLISECONDS;
27967
+ const nbfDate = new Date(nbfInMilliseconds);
27968
+ const expInMilliseconds = jwtPayload.exp * ONE_SECOND_IN_MILLISECONDS;
27969
+ const expDate = new Date(expInMilliseconds - ONE_MINUTE_IN_MILLISECONDS);
27970
+ return nbfDate <= now && expDate > now;
27971
+ }
27972
+ function decodeTokenPayload(token) {
27973
+ const payload = decodeJwt(token);
27974
+ const {
27975
+ roomConfig
27976
+ } = payload,
27977
+ rest = __rest(payload, ["roomConfig"]);
27978
+ const mappedPayload = Object.assign(Object.assign({}, rest), {
27979
+ roomConfig: payload.roomConfig ? RoomConfiguration.fromJson(payload.roomConfig) : undefined
27980
+ });
27981
+ return mappedPayload;
27982
+ }
27983
+
27984
+ /** A TokenSourceCached is a TokenSource which caches the last {@link TokenSourceResponseObject} value and returns it
27985
+ * until a) it expires or b) the {@link TokenSourceFetchOptions} provided to .fetch(...) change. */
27986
+ class TokenSourceCached extends TokenSourceConfigurable {
27987
+ constructor() {
27988
+ super(...arguments);
27989
+ this.cachedFetchOptions = null;
27990
+ this.cachedResponse = null;
27991
+ this.fetchMutex = new _();
27992
+ }
27993
+ isSameAsCachedFetchOptions(options) {
27994
+ if (!this.cachedFetchOptions) {
27995
+ return false;
27996
+ }
27997
+ for (const key of Object.keys(this.cachedFetchOptions)) {
27998
+ switch (key) {
27999
+ case 'roomName':
28000
+ case 'participantName':
28001
+ case 'participantIdentity':
28002
+ case 'participantMetadata':
28003
+ case 'participantAttributes':
28004
+ case 'agentName':
28005
+ case 'agentMetadata':
28006
+ if (this.cachedFetchOptions[key] !== options[key]) {
28007
+ return false;
28008
+ }
28009
+ break;
28010
+ default:
28011
+ // ref: https://stackoverflow.com/a/58009992
28012
+ const exhaustiveCheckedKey = key;
28013
+ throw new Error("Options key ".concat(exhaustiveCheckedKey, " not being checked for equality!"));
28014
+ }
28015
+ }
28016
+ return true;
28017
+ }
28018
+ shouldReturnCachedValueFromFetch(fetchOptions) {
28019
+ if (!this.cachedResponse) {
28020
+ return false;
28021
+ }
28022
+ if (!isResponseTokenValid(this.cachedResponse)) {
28023
+ return false;
28024
+ }
28025
+ if (this.isSameAsCachedFetchOptions(fetchOptions)) {
28026
+ return false;
28027
+ }
28028
+ return true;
28029
+ }
28030
+ getCachedResponseJwtPayload() {
28031
+ if (!this.cachedResponse) {
28032
+ return null;
28033
+ }
28034
+ return decodeTokenPayload(this.cachedResponse.participantToken);
28035
+ }
28036
+ fetch(options) {
28037
+ return __awaiter(this, void 0, void 0, function* () {
28038
+ const unlock = yield this.fetchMutex.lock();
28039
+ try {
28040
+ if (this.shouldReturnCachedValueFromFetch(options)) {
28041
+ return this.cachedResponse.toJson();
28042
+ }
28043
+ this.cachedFetchOptions = options;
28044
+ const tokenResponse = yield this.update(options);
28045
+ this.cachedResponse = tokenResponse;
28046
+ return tokenResponse.toJson();
28047
+ } finally {
28048
+ unlock();
28049
+ }
28050
+ });
28051
+ }
28052
+ }
28053
+ class TokenSourceLiteral extends TokenSourceFixed {
28054
+ constructor(literalOrFn) {
28055
+ super();
28056
+ this.literalOrFn = literalOrFn;
28057
+ }
28058
+ fetch() {
28059
+ return __awaiter(this, void 0, void 0, function* () {
28060
+ if (typeof this.literalOrFn === 'function') {
28061
+ return this.literalOrFn();
28062
+ } else {
28063
+ return this.literalOrFn;
28064
+ }
28065
+ });
28066
+ }
28067
+ }
28068
+ class TokenSourceCustom extends TokenSourceCached {
28069
+ constructor(customFn) {
28070
+ super();
28071
+ this.customFn = customFn;
28072
+ }
28073
+ update(options) {
28074
+ return __awaiter(this, void 0, void 0, function* () {
28075
+ const resultMaybePromise = this.customFn(options);
28076
+ let result;
28077
+ if (resultMaybePromise instanceof Promise) {
28078
+ result = yield resultMaybePromise;
28079
+ } else {
28080
+ result = resultMaybePromise;
28081
+ }
28082
+ return TokenSourceResponse.fromJson(result, {
28083
+ // NOTE: it could be possible that the response body could contain more fields than just
28084
+ // what's in TokenSourceResponse depending on the implementation
28085
+ ignoreUnknownFields: true
28086
+ });
28087
+ });
28088
+ }
28089
+ }
28090
+ class TokenSourceEndpoint extends TokenSourceCached {
28091
+ constructor(url) {
28092
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
28093
+ super();
28094
+ this.url = url;
28095
+ this.endpointOptions = options;
28096
+ }
28097
+ createRequestFromOptions(options) {
28098
+ var _a, _b, _c;
28099
+ const request = new TokenSourceRequest();
28100
+ for (const key of Object.keys(options)) {
28101
+ switch (key) {
28102
+ case 'roomName':
28103
+ case 'participantName':
28104
+ case 'participantIdentity':
28105
+ case 'participantMetadata':
28106
+ request[key] = options[key];
28107
+ break;
28108
+ case 'participantAttributes':
28109
+ request.participantAttributes = (_a = options.participantAttributes) !== null && _a !== void 0 ? _a : {};
28110
+ break;
28111
+ case 'agentName':
28112
+ request.roomConfig = (_b = request.roomConfig) !== null && _b !== void 0 ? _b : new RoomConfiguration();
28113
+ if (request.roomConfig.agents.length === 0) {
28114
+ request.roomConfig.agents.push(new RoomAgentDispatch());
28115
+ }
28116
+ request.roomConfig.agents[0].agentName = options.agentName;
28117
+ break;
28118
+ case 'agentMetadata':
28119
+ request.roomConfig = (_c = request.roomConfig) !== null && _c !== void 0 ? _c : new RoomConfiguration();
28120
+ if (request.roomConfig.agents.length === 0) {
28121
+ request.roomConfig.agents.push(new RoomAgentDispatch());
28122
+ }
28123
+ request.roomConfig.agents[0].metadata = options.agentMetadata;
28124
+ break;
28125
+ default:
28126
+ // ref: https://stackoverflow.com/a/58009992
28127
+ const exhaustiveCheckedKey = key;
28128
+ throw new Error("Options key ".concat(exhaustiveCheckedKey, " not being included in forming request!"));
28129
+ }
28130
+ }
28131
+ return request;
28132
+ }
28133
+ update(options) {
28134
+ return __awaiter(this, void 0, void 0, function* () {
28135
+ var _a;
28136
+ const request = this.createRequestFromOptions(options);
28137
+ const response = yield fetch(this.url, Object.assign(Object.assign({}, this.endpointOptions), {
28138
+ method: (_a = this.endpointOptions.method) !== null && _a !== void 0 ? _a : 'POST',
28139
+ headers: Object.assign({
28140
+ 'Content-Type': 'application/json'
28141
+ }, this.endpointOptions.headers),
28142
+ body: request.toJsonString({
28143
+ useProtoFieldName: true
28144
+ })
28145
+ }));
28146
+ if (!response.ok) {
28147
+ throw new Error("Error generating token from endpoint ".concat(this.url, ": received ").concat(response.status, " / ").concat(yield response.text()));
28148
+ }
28149
+ const body = yield response.json();
28150
+ return TokenSourceResponse.fromJson(body, {
28151
+ // NOTE: it could be possible that the response body could contain more fields than just
28152
+ // what's in TokenSourceResponse depending on the implementation (ie, SandboxTokenServer)
28153
+ ignoreUnknownFields: true
28154
+ });
28155
+ });
28156
+ }
28157
+ }
28158
+ class TokenSourceSandboxTokenServer extends TokenSourceEndpoint {
28159
+ constructor(sandboxId, options) {
28160
+ const {
28161
+ baseUrl = 'https://cloud-api.livekit.io'
28162
+ } = options,
28163
+ rest = __rest(options, ["baseUrl"]);
28164
+ super("".concat(baseUrl, "/api/v2/sandbox/connection-details"), Object.assign(Object.assign({}, rest), {
28165
+ headers: {
28166
+ 'X-Sandbox-ID': sandboxId
28167
+ }
28168
+ }));
28169
+ }
28170
+ }
28171
+ const TokenSource = {
28172
+ /** TokenSource.literal contains a single, literal set of {@link TokenSourceResponseObject}
28173
+ * credentials, either provided directly or returned from a provided function. */
28174
+ literal(literalOrFn) {
28175
+ return new TokenSourceLiteral(literalOrFn);
28176
+ },
28177
+ /**
28178
+ * TokenSource.custom allows a user to define a manual function which generates new
28179
+ * {@link TokenSourceResponseObject} values on demand.
28180
+ *
28181
+ * Use this to get credentials from custom backends / etc.
28182
+ */
28183
+ custom(customFn) {
28184
+ return new TokenSourceCustom(customFn);
28185
+ },
28186
+ /**
28187
+ * TokenSource.endpoint creates a token source that fetches credentials from a given URL using
28188
+ * the standard endpoint format:
28189
+ * FIXME: add docs link here in the future!
28190
+ */
28191
+ endpoint(url) {
28192
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
28193
+ return new TokenSourceEndpoint(url, options);
28194
+ },
28195
+ /**
28196
+ * TokenSource.sandboxTokenServer queries a sandbox token server for credentials,
28197
+ * which supports quick prototyping / getting started types of use cases.
28198
+ *
28199
+ * This token provider is INSECURE and should NOT be used in production.
28200
+ *
28201
+ * For more info:
28202
+ * @see https://cloud.livekit.io/projects/p_/sandbox/templates/token-server
28203
+ */
28204
+ sandboxTokenServer(sandboxId) {
28205
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
28206
+ return new TokenSourceSandboxTokenServer(sandboxId, options);
28207
+ }
28208
+ };
28209
+
26091
28210
  /**
26092
28211
  * Try to analyze the local track to determine the facing mode of a track.
26093
28212
  *
@@ -26169,5 +28288,5 @@ function isFacingModeValue(item) {
26169
28288
  return item === undefined || allowedValues.includes(item);
26170
28289
  }
26171
28290
 
26172
- export { AudioPresets, BackupCodecPolicy, BaseKeyProvider, CheckStatus, Checker, ConnectionCheck, ConnectionError, ConnectionErrorReason, ConnectionQuality, ConnectionState, CriticalTimers, CryptorError, CryptorErrorReason, CryptorEvent, DataPacket_Kind, DataStreamError, DataStreamErrorReason, DefaultReconnectPolicy, DeviceUnsupportedError, DisconnectReason, EncryptionEvent, EngineEvent, ExternalE2EEKeyProvider, KeyHandlerEvent, KeyProviderEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalTrackRecorder, LocalVideoTrack, LogLevel, LoggerNames, MediaDeviceFailure, _ as Mutex, NegotiationError, Participant, ParticipantEvent, ParticipantInfo_Kind as ParticipantKind, PublishDataError, PublishTrackError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, RpcError, ScreenSharePresets, SignalRequestError, SubscriptionError, Track, TrackEvent, TrackInvalidError, TrackPublication, TrackType, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, attributeTypings as attributes, compareVersions, createAudioAnalyser, createE2EEKey, createKeyMaterialFromBuffer, createKeyMaterialFromString, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, deriveKeys, detachTrack, facingModeFromDeviceLabel, facingModeFromLocalTrack, getBrowser, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, getLogger, importKey, isAudioTrack, isBackupCodec, isBrowserSupported, isE2EESupported, isInsertableStreamSupported, isLocalParticipant, isLocalTrack, isRemoteParticipant, isRemoteTrack, isScriptTransformSupported, isVideoFrame, isVideoTrack, needsRbspUnescaping, parseRbsp, protocolVersion, ratchet, setLogExtension, setLogLevel, supportsAV1, supportsAdaptiveStream, supportsDynacast, supportsVP9, version, videoCodecs, writeRbsp };
28291
+ export { AudioPresets, BackupCodecPolicy, BaseKeyProvider, CheckStatus, Checker, ConnectionCheck, ConnectionError, ConnectionErrorReason, ConnectionQuality, ConnectionState, CriticalTimers, CryptorError, CryptorErrorReason, CryptorEvent, DataPacket_Kind, DataStreamError, DataStreamErrorReason, DefaultReconnectPolicy, DeviceUnsupportedError, DisconnectReason, EncryptionEvent, Encryption_Type, EngineEvent, ExternalE2EEKeyProvider, KeyHandlerEvent, KeyProviderEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalTrackRecorder, LocalVideoTrack, LogLevel, LoggerNames, MediaDeviceFailure, _ as Mutex, NegotiationError, Participant, ParticipantEvent, ParticipantInfo_Kind as ParticipantKind, PublishDataError, PublishTrackError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, RpcError, ScreenSharePresets, SignalRequestError, SubscriptionError, TokenSource, TokenSourceConfigurable, TokenSourceCustom, TokenSourceEndpoint, TokenSourceFixed, TokenSourceLiteral, TokenSourceSandboxTokenServer, Track, TrackEvent, TrackInvalidError, TrackPublication, TrackType, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, asEncryptablePacket, attachToElement, attributeTypings as attributes, audioCodecs, compareVersions, createAudioAnalyser, createE2EEKey, createKeyMaterialFromBuffer, createKeyMaterialFromString, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, deriveKeys, detachTrack, facingModeFromDeviceLabel, facingModeFromLocalTrack, getBrowser, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, getLogger, importKey, isAudioCodec, isAudioTrack, isBackupCodec, isBackupVideoCodec, isBrowserSupported, isE2EESupported, isInsertableStreamSupported, isLocalParticipant, isLocalTrack, isRemoteParticipant, isRemoteTrack, isScriptTransformSupported, isVideoCodec, isVideoFrame, isVideoTrack, needsRbspUnescaping, parseRbsp, protocolVersion, ratchet, setLogExtension, setLogLevel, supportsAV1, supportsAdaptiveStream, supportsAudioOutputSelection, supportsDynacast, supportsVP9, version, videoCodecs, writeRbsp };
26173
28292
  //# sourceMappingURL=livekit-client.esm.mjs.map