livekit-client 2.18.1 → 2.18.2

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 (35) hide show
  1. package/dist/livekit-client.esm.mjs +244 -134
  2. package/dist/livekit-client.esm.mjs.map +1 -1
  3. package/dist/livekit-client.umd.js +1 -1
  4. package/dist/livekit-client.umd.js.map +1 -1
  5. package/dist/src/connectionHelper/ConnectionCheck.d.ts +1 -1
  6. package/dist/src/connectionHelper/ConnectionCheck.d.ts.map +1 -1
  7. package/dist/src/index.d.ts +1 -0
  8. package/dist/src/index.d.ts.map +1 -1
  9. package/dist/src/room/RTCEngine.d.ts +6 -5
  10. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  11. package/dist/src/room/Room.d.ts +1 -0
  12. package/dist/src/room/Room.d.ts.map +1 -1
  13. package/dist/src/room/data-stream/incoming/IncomingDataStreamManager.d.ts +5 -1
  14. package/dist/src/room/data-stream/incoming/IncomingDataStreamManager.d.ts.map +1 -1
  15. package/dist/src/room/data-track/incoming/IncomingDataTrackManager.d.ts.map +1 -1
  16. package/dist/src/room/participant/LocalParticipant.d.ts +1 -0
  17. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  18. package/dist/src/utils/serializer.d.ts +48 -0
  19. package/dist/src/utils/serializer.d.ts.map +1 -0
  20. package/dist/ts4.2/connectionHelper/ConnectionCheck.d.ts +2 -1
  21. package/dist/ts4.2/index.d.ts +2 -0
  22. package/dist/ts4.2/room/RTCEngine.d.ts +6 -5
  23. package/dist/ts4.2/room/Room.d.ts +1 -0
  24. package/dist/ts4.2/room/data-stream/incoming/IncomingDataStreamManager.d.ts +5 -1
  25. package/dist/ts4.2/room/participant/LocalParticipant.d.ts +1 -0
  26. package/dist/ts4.2/utils/serializer.d.ts +48 -0
  27. package/package.json +1 -1
  28. package/src/connectionHelper/ConnectionCheck.ts +1 -1
  29. package/src/index.ts +7 -0
  30. package/src/room/RTCEngine.ts +47 -15
  31. package/src/room/Room.ts +19 -23
  32. package/src/room/data-stream/incoming/IncomingDataStreamManager.ts +26 -2
  33. package/src/room/data-track/incoming/IncomingDataTrackManager.ts +7 -0
  34. package/src/room/participant/LocalParticipant.ts +17 -2
  35. package/src/utils/serializer.ts +72 -0
@@ -11629,7 +11629,7 @@ function getMatch(exp, ua) {
11629
11629
  }
11630
11630
  function getOSVersion(ua) {
11631
11631
  return ua.includes('mac os') ? getMatch(/\(.+?(\d+_\d+(:?_\d+)?)/, ua, 1).replace(/_/g, '.') : undefined;
11632
- }var version$1 = "2.18.1";const version = version$1;
11632
+ }var version$1 = "2.18.2";const version = version$1;
11633
11633
  const protocolVersion = 16;/** Base error that all LiveKit specific custom errors inherit from. */
11634
11634
  class LivekitError extends Error {
11635
11635
  constructor(code, message, options) {
@@ -20533,7 +20533,7 @@ class RTCEngine extends eventsExports.EventEmitter {
20533
20533
  var _this2 = this;
20534
20534
  let useV0Path = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
20535
20535
  return function* () {
20536
- var _a, _b, _c;
20536
+ var _a, _b, _c, _d, _e, _f;
20537
20537
  _this2._isNewlyCreated = false;
20538
20538
  _this2.url = url;
20539
20539
  _this2.token = token;
@@ -20578,7 +20578,25 @@ class RTCEngine extends eventsExports.EventEmitter {
20578
20578
  _this2.registerOnLineListener();
20579
20579
  _this2.clientConfiguration = joinResponse.clientConfiguration;
20580
20580
  _this2.emit(EngineEvent.SignalConnected, joinResponse);
20581
- return joinResponse;
20581
+ let serverInfo = joinResponse.serverInfo;
20582
+ if (!serverInfo) {
20583
+ serverInfo = {
20584
+ version: joinResponse.serverVersion,
20585
+ region: joinResponse.serverRegion
20586
+ };
20587
+ }
20588
+ _this2.log.debug("connected to Livekit Server ".concat(Object.entries(serverInfo).map(_ref2 => {
20589
+ let [key, value] = _ref2;
20590
+ return "".concat(key, ": ").concat(value);
20591
+ }).join(', ')), {
20592
+ room: (_d = joinResponse.room) === null || _d === void 0 ? void 0 : _d.name,
20593
+ roomSid: (_e = joinResponse.room) === null || _e === void 0 ? void 0 : _e.sid,
20594
+ identity: (_f = joinResponse.participant) === null || _f === void 0 ? void 0 : _f.identity
20595
+ });
20596
+ return {
20597
+ joinResponse,
20598
+ serverInfo
20599
+ };
20582
20600
  } catch (e) {
20583
20601
  if (e instanceof ConnectionError) {
20584
20602
  if (e.reason === ConnectionErrorReason.ServerUnreachable) {
@@ -21179,7 +21197,7 @@ class RTCEngine extends eventsExports.EventEmitter {
21179
21197
  throw new SignalReconnectError();
21180
21198
  }
21181
21199
  // in case a regionUrl is passed, the region URL takes precedence
21182
- joinResponse = yield this.join(regionUrl !== null && regionUrl !== void 0 ? regionUrl : this.url, this.token, this.signalOpts, undefined, !this.options.singlePeerConnection);
21200
+ joinResponse = (yield this.join(regionUrl !== null && regionUrl !== void 0 ? regionUrl : this.url, this.token, this.signalOpts, undefined, !this.options.singlePeerConnection)).joinResponse;
21183
21201
  } catch (e) {
21184
21202
  if (e instanceof ConnectionError && e.reason === ConnectionErrorReason.NotAllowed) {
21185
21203
  throw new UnexpectedConnectionState('could not reconnect, token might be expired');
@@ -21441,19 +21459,30 @@ class RTCEngine extends eventsExports.EventEmitter {
21441
21459
  });
21442
21460
  }
21443
21461
  waitForBufferStatusLow(kind) {
21444
- return new TypedPromise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
21445
- if (this.isBufferStatusLow(kind)) {
21446
- resolve();
21447
- } else {
21448
- const onClosing = () => reject(new UnexpectedConnectionState('engine closed'));
21449
- this.once(EngineEvent.Closing, onClosing);
21450
- while (!this.dcBufferStatus.get(kind)) {
21451
- yield sleep(10);
21462
+ return __awaiter(this, void 0, void 0, function* () {
21463
+ return new TypedPromise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
21464
+ if (this.isClosed) {
21465
+ reject(new UnexpectedConnectionState('engine closed'));
21452
21466
  }
21453
- this.off(EngineEvent.Closing, onClosing);
21454
- resolve();
21455
- }
21456
- }));
21467
+ if (this.isBufferStatusLow(kind)) {
21468
+ resolve();
21469
+ } else {
21470
+ const onClosing = () => reject(new UnexpectedConnectionState('engine closed'));
21471
+ this.once(EngineEvent.Closing, onClosing);
21472
+ const dc = this.dataChannelForKind(kind);
21473
+ if (!dc) {
21474
+ reject(new UnexpectedConnectionState("DataChannel not found, kind: ".concat(kind)));
21475
+ return;
21476
+ }
21477
+ dc.addEventListener('bufferedamountlow', () => {
21478
+ this.off(EngineEvent.Closing, onClosing);
21479
+ resolve();
21480
+ }, {
21481
+ once: true
21482
+ });
21483
+ }
21484
+ }));
21485
+ });
21457
21486
  }
21458
21487
  /**
21459
21488
  * @internal
@@ -21719,8 +21748,8 @@ class RTCEngine extends eventsExports.EventEmitter {
21719
21748
  var _a;
21720
21749
  const mid = (_a = this.pcManager) === null || _a === void 0 ? void 0 : _a.getMidForReceiver(receiver);
21721
21750
  if (mid) {
21722
- const match = Object.entries(this.midToTrackId).find(_ref2 => {
21723
- let [key] = _ref2;
21751
+ const match = Object.entries(this.midToTrackId).find(_ref3 => {
21752
+ let [key] = _ref3;
21724
21753
  return key === mid;
21725
21754
  });
21726
21755
  if (match) {
@@ -22017,6 +22046,24 @@ class TextStreamReader extends BaseStreamReader {
22017
22046
  this.textStreamControllers = new Map();
22018
22047
  this.byteStreamHandlers = new Map();
22019
22048
  this.textStreamHandlers = new Map();
22049
+ this.isConnected = false;
22050
+ this.bufferedPackets = [];
22051
+ }
22052
+ setConnected(connected) {
22053
+ this.isConnected = connected;
22054
+ if (connected) {
22055
+ this.flushBufferedPackets();
22056
+ }
22057
+ }
22058
+ flushBufferedPackets() {
22059
+ const packets = this.bufferedPackets;
22060
+ this.bufferedPackets = [];
22061
+ for (const {
22062
+ packet,
22063
+ encryptionType
22064
+ } of packets) {
22065
+ this.handleDataStreamPacket(packet, encryptionType);
22066
+ }
22020
22067
  }
22021
22068
  registerTextStreamHandler(topic, callback) {
22022
22069
  if (this.textStreamHandlers.has(topic)) {
@@ -22039,6 +22086,7 @@ class TextStreamReader extends BaseStreamReader {
22039
22086
  clearControllers() {
22040
22087
  this.byteStreamControllers.clear();
22041
22088
  this.textStreamControllers.clear();
22089
+ this.bufferedPackets = [];
22042
22090
  }
22043
22091
  validateParticipantHasNoActiveDataStreams(participantIdentity) {
22044
22092
  // Terminate any in flight data stream receives from the given participant
@@ -22057,92 +22105,95 @@ class TextStreamReader extends BaseStreamReader {
22057
22105
  }
22058
22106
  }
22059
22107
  handleDataStreamPacket(packet, encryptionType) {
22060
- return __awaiter(this, void 0, void 0, function* () {
22061
- switch (packet.value.case) {
22062
- case 'streamHeader':
22063
- return this.handleStreamHeader(packet.value.value, packet.participantIdentity, encryptionType);
22064
- case 'streamChunk':
22065
- return this.handleStreamChunk(packet.value.value, encryptionType);
22066
- case 'streamTrailer':
22067
- return this.handleStreamTrailer(packet.value.value, encryptionType);
22068
- default:
22069
- throw new Error("DataPacket of value \"".concat(packet.value.case, "\" is not data stream related!"));
22070
- }
22071
- });
22108
+ if (!this.isConnected) {
22109
+ this.bufferedPackets.push({
22110
+ packet,
22111
+ encryptionType
22112
+ });
22113
+ return;
22114
+ }
22115
+ switch (packet.value.case) {
22116
+ case 'streamHeader':
22117
+ return this.handleStreamHeader(packet.value.value, packet.participantIdentity, encryptionType);
22118
+ case 'streamChunk':
22119
+ return this.handleStreamChunk(packet.value.value, encryptionType);
22120
+ case 'streamTrailer':
22121
+ return this.handleStreamTrailer(packet.value.value, encryptionType);
22122
+ default:
22123
+ throw new Error("DataPacket of value \"".concat(packet.value.case, "\" is not data stream related!"));
22124
+ }
22072
22125
  }
22073
22126
  handleStreamHeader(streamHeader, participantIdentity, encryptionType) {
22074
- return __awaiter(this, void 0, void 0, function* () {
22075
- var _a;
22076
- if (streamHeader.contentHeader.case === 'byteHeader') {
22077
- const streamHandlerCallback = this.byteStreamHandlers.get(streamHeader.topic);
22078
- if (!streamHandlerCallback) {
22079
- this.log.debug('ignoring incoming byte stream due to no handler for topic', streamHeader.topic);
22080
- return;
22081
- }
22082
- let streamController;
22083
- const info = {
22084
- id: streamHeader.streamId,
22085
- name: (_a = streamHeader.contentHeader.value.name) !== null && _a !== void 0 ? _a : 'unknown',
22086
- mimeType: streamHeader.mimeType,
22087
- size: streamHeader.totalLength ? Number(streamHeader.totalLength) : undefined,
22088
- topic: streamHeader.topic,
22089
- timestamp: bigIntToNumber(streamHeader.timestamp),
22090
- attributes: streamHeader.attributes,
22091
- encryptionType
22092
- };
22093
- const stream = new ReadableStream({
22094
- start: controller => {
22095
- streamController = controller;
22096
- if (this.textStreamControllers.has(streamHeader.streamId)) {
22097
- throw new DataStreamError("A data stream read is already in progress for a stream with id ".concat(streamHeader.streamId, "."), DataStreamErrorReason.AlreadyOpened);
22098
- }
22099
- this.byteStreamControllers.set(streamHeader.streamId, {
22100
- info,
22101
- controller: streamController,
22102
- startTime: Date.now(),
22103
- sendingParticipantIdentity: participantIdentity
22104
- });
22127
+ var _a;
22128
+ if (streamHeader.contentHeader.case === 'byteHeader') {
22129
+ const streamHandlerCallback = this.byteStreamHandlers.get(streamHeader.topic);
22130
+ if (!streamHandlerCallback) {
22131
+ this.log.debug('ignoring incoming byte stream due to no handler for topic', streamHeader.topic);
22132
+ return;
22133
+ }
22134
+ let streamController;
22135
+ const info = {
22136
+ id: streamHeader.streamId,
22137
+ name: (_a = streamHeader.contentHeader.value.name) !== null && _a !== void 0 ? _a : 'unknown',
22138
+ mimeType: streamHeader.mimeType,
22139
+ size: streamHeader.totalLength ? Number(streamHeader.totalLength) : undefined,
22140
+ topic: streamHeader.topic,
22141
+ timestamp: bigIntToNumber(streamHeader.timestamp),
22142
+ attributes: streamHeader.attributes,
22143
+ encryptionType
22144
+ };
22145
+ const stream = new ReadableStream({
22146
+ start: controller => {
22147
+ streamController = controller;
22148
+ if (this.textStreamControllers.has(streamHeader.streamId)) {
22149
+ throw new DataStreamError("A data stream read is already in progress for a stream with id ".concat(streamHeader.streamId, "."), DataStreamErrorReason.AlreadyOpened);
22105
22150
  }
22106
- });
22107
- streamHandlerCallback(new ByteStreamReader(info, stream, bigIntToNumber(streamHeader.totalLength)), {
22108
- identity: participantIdentity
22109
- });
22110
- } else if (streamHeader.contentHeader.case === 'textHeader') {
22111
- const streamHandlerCallback = this.textStreamHandlers.get(streamHeader.topic);
22112
- if (!streamHandlerCallback) {
22113
- this.log.debug('ignoring incoming text stream due to no handler for topic', streamHeader.topic);
22114
- return;
22151
+ this.byteStreamControllers.set(streamHeader.streamId, {
22152
+ info,
22153
+ controller: streamController,
22154
+ startTime: Date.now(),
22155
+ sendingParticipantIdentity: participantIdentity
22156
+ });
22115
22157
  }
22116
- let streamController;
22117
- const info = {
22118
- id: streamHeader.streamId,
22119
- mimeType: streamHeader.mimeType,
22120
- size: streamHeader.totalLength ? Number(streamHeader.totalLength) : undefined,
22121
- topic: streamHeader.topic,
22122
- timestamp: Number(streamHeader.timestamp),
22123
- attributes: streamHeader.attributes,
22124
- encryptionType,
22125
- attachedStreamIds: streamHeader.contentHeader.value.attachedStreamIds
22126
- };
22127
- const stream = new ReadableStream({
22128
- start: controller => {
22129
- streamController = controller;
22130
- if (this.textStreamControllers.has(streamHeader.streamId)) {
22131
- throw new DataStreamError("A data stream read is already in progress for a stream with id ".concat(streamHeader.streamId, "."), DataStreamErrorReason.AlreadyOpened);
22132
- }
22133
- this.textStreamControllers.set(streamHeader.streamId, {
22134
- info,
22135
- controller: streamController,
22136
- startTime: Date.now(),
22137
- sendingParticipantIdentity: participantIdentity
22138
- });
22139
- }
22140
- });
22141
- streamHandlerCallback(new TextStreamReader(info, stream, bigIntToNumber(streamHeader.totalLength)), {
22142
- identity: participantIdentity
22143
- });
22158
+ });
22159
+ streamHandlerCallback(new ByteStreamReader(info, stream, bigIntToNumber(streamHeader.totalLength)), {
22160
+ identity: participantIdentity
22161
+ });
22162
+ } else if (streamHeader.contentHeader.case === 'textHeader') {
22163
+ const streamHandlerCallback = this.textStreamHandlers.get(streamHeader.topic);
22164
+ if (!streamHandlerCallback) {
22165
+ this.log.debug('ignoring incoming text stream due to no handler for topic', streamHeader.topic);
22166
+ return;
22144
22167
  }
22145
- });
22168
+ let streamController;
22169
+ const info = {
22170
+ id: streamHeader.streamId,
22171
+ mimeType: streamHeader.mimeType,
22172
+ size: streamHeader.totalLength ? Number(streamHeader.totalLength) : undefined,
22173
+ topic: streamHeader.topic,
22174
+ timestamp: Number(streamHeader.timestamp),
22175
+ attributes: streamHeader.attributes,
22176
+ encryptionType,
22177
+ attachedStreamIds: streamHeader.contentHeader.value.attachedStreamIds
22178
+ };
22179
+ const stream = new ReadableStream({
22180
+ start: controller => {
22181
+ streamController = controller;
22182
+ if (this.textStreamControllers.has(streamHeader.streamId)) {
22183
+ throw new DataStreamError("A data stream read is already in progress for a stream with id ".concat(streamHeader.streamId, "."), DataStreamErrorReason.AlreadyOpened);
22184
+ }
22185
+ this.textStreamControllers.set(streamHeader.streamId, {
22186
+ info,
22187
+ controller: streamController,
22188
+ startTime: Date.now(),
22189
+ sendingParticipantIdentity: participantIdentity
22190
+ });
22191
+ }
22192
+ });
22193
+ streamHandlerCallback(new TextStreamReader(info, stream, bigIntToNumber(streamHeader.totalLength)), {
22194
+ identity: participantIdentity
22195
+ });
22196
+ }
22146
22197
  }
22147
22198
  handleStreamChunk(chunk, encryptionType) {
22148
22199
  const fileBuffer = this.byteStreamControllers.get(chunk.streamId);
@@ -23694,6 +23745,9 @@ class IncomingDataTrackManager extends eventsExports.EventEmitter {
23694
23745
  }
23695
23746
  this.descriptors.delete(sid);
23696
23747
  if (descriptor.subscription.type === 'active') {
23748
+ descriptor.subscription.streamControllers.forEach(controller => {
23749
+ controller.close();
23750
+ });
23697
23751
  this.subscriptionHandles.delete(descriptor.subscription.subcriptionHandle);
23698
23752
  }
23699
23753
  this.emit('trackUnpublished', {
@@ -23837,6 +23891,9 @@ class IncomingDataTrackManager extends eventsExports.EventEmitter {
23837
23891
  if (descriptor.subscription.type === 'pending') {
23838
23892
  (_b = (_a = descriptor.subscription.completionFuture).reject) === null || _b === void 0 ? void 0 : _b.call(_a, DataTrackSubscribeError.disconnected());
23839
23893
  }
23894
+ if (descriptor.subscription.type === 'active') {
23895
+ descriptor.subscription.streamControllers.forEach(controller => controller.close());
23896
+ }
23840
23897
  }
23841
23898
  this.descriptors.clear();
23842
23899
  }
@@ -25794,6 +25851,7 @@ class Participant extends eventsExports.EventEmitter {
25794
25851
  this.participantTrackPermissions = [];
25795
25852
  this.allParticipantsAllowedToSubscribe = true;
25796
25853
  this.encryptionType = Encryption_Type.NONE;
25854
+ this.e2eeStateMutex = new _();
25797
25855
  this.enabledPublishVideoCodecs = [];
25798
25856
  this.pendingAcks = new Map();
25799
25857
  this.pendingResponses = new Map();
@@ -26209,8 +26267,17 @@ class Participant extends eventsExports.EventEmitter {
26209
26267
  /** @internal */
26210
26268
  setE2EEEnabled(enabled) {
26211
26269
  return __awaiter(this, void 0, void 0, function* () {
26212
- this.encryptionType = enabled ? Encryption_Type.GCM : Encryption_Type.NONE;
26213
- yield this.republishAllTracks(undefined, false);
26270
+ const unlock = yield this.e2eeStateMutex.lock();
26271
+ try {
26272
+ this.encryptionType = enabled ? Encryption_Type.GCM : Encryption_Type.NONE;
26273
+ yield Promise.all(this.pendingPublishPromises.values());
26274
+ if (this.trackPublications.size === 0 || Array.from(this.trackPublications.values()).every(pub => pub.isEncrypted === enabled)) {
26275
+ return;
26276
+ }
26277
+ yield this.republishAllTracks(undefined, false);
26278
+ } finally {
26279
+ unlock();
26280
+ }
26214
26281
  });
26215
26282
  }
26216
26283
  setTrackEnabled(source, enabled, options, publishOptions) {
@@ -28227,6 +28294,7 @@ class Room extends eventsExports.EventEmitter {
28227
28294
  /** reflects the sender encryption status of the local participant */
28228
28295
  this.isE2EEEnabled = false;
28229
28296
  this.audioEnabled = true;
28297
+ this.e2eeStateMutex = new _();
28230
28298
  this.isVideoPlaybackBlocked = false;
28231
28299
  this.log = livekitLogger;
28232
28300
  this.bufferedEvents = [];
@@ -28341,30 +28409,17 @@ class Room extends eventsExports.EventEmitter {
28341
28409
  return this.connectFuture.promise;
28342
28410
  });
28343
28411
  this.connectSignal = (url, token, engine, connectOptions, roomOptions, abortController) => __awaiter(this, void 0, void 0, function* () {
28344
- var _a, _b, _c;
28345
- const joinResponse = yield engine.join(url, token, {
28412
+ const {
28413
+ joinResponse,
28414
+ serverInfo
28415
+ } = yield engine.join(url, token, {
28346
28416
  autoSubscribe: connectOptions.autoSubscribe,
28347
28417
  adaptiveStream: typeof roomOptions.adaptiveStream === 'object' ? true : roomOptions.adaptiveStream,
28348
28418
  maxRetries: connectOptions.maxRetries,
28349
28419
  e2eeEnabled: !!this.e2eeManager,
28350
28420
  websocketTimeout: connectOptions.websocketTimeout
28351
28421
  }, abortController.signal, !roomOptions.singlePeerConnection);
28352
- let serverInfo = joinResponse.serverInfo;
28353
- if (!serverInfo) {
28354
- serverInfo = {
28355
- version: joinResponse.serverVersion,
28356
- region: joinResponse.serverRegion
28357
- };
28358
- }
28359
28422
  this.serverInfo = serverInfo;
28360
- this.log.debug("connected to Livekit Server ".concat(Object.entries(serverInfo).map(_ref => {
28361
- let [key, value] = _ref;
28362
- return "".concat(key, ": ").concat(value);
28363
- }).join(', ')), {
28364
- room: (_a = joinResponse.room) === null || _a === void 0 ? void 0 : _a.name,
28365
- roomSid: (_b = joinResponse.room) === null || _b === void 0 ? void 0 : _b.sid,
28366
- identity: (_c = joinResponse.participant) === null || _c === void 0 ? void 0 : _c.identity
28367
- });
28368
28423
  if (!serverInfo.version) {
28369
28424
  throw new UnsupportedServer('unknown server version');
28370
28425
  }
@@ -29002,10 +29057,10 @@ class Room extends eventsExports.EventEmitter {
29002
29057
  this.emit(RoomEvent.LocalDataTrackPublished, event.track);
29003
29058
  }).on('trackUnpublished', event => {
29004
29059
  this.emit(RoomEvent.LocalDataTrackUnpublished, event.sid);
29005
- }).on('packetAvailable', _ref2 => {
29060
+ }).on('packetAvailable', _ref => {
29006
29061
  let {
29007
29062
  bytes
29008
- } = _ref2;
29063
+ } = _ref;
29009
29064
  this.engine.sendLossyBytes(bytes, DataChannelKind.DATA_TRACK_LOSSY, 'wait');
29010
29065
  });
29011
29066
  this.disconnectLock = new _();
@@ -29095,19 +29150,26 @@ class Room extends eventsExports.EventEmitter {
29095
29150
  */
29096
29151
  setE2EEEnabled(enabled) {
29097
29152
  return __awaiter(this, void 0, void 0, function* () {
29098
- if (this.e2eeManager) {
29099
- yield Promise.all([this.localParticipant.setE2EEEnabled(enabled)]);
29100
- if (this.localParticipant.identity !== '') {
29101
- this.e2eeManager.setParticipantCryptorEnabled(enabled, this.localParticipant.identity);
29153
+ const unlock = yield this.e2eeStateMutex.lock();
29154
+ try {
29155
+ if (this.e2eeManager) {
29156
+ if (this.isE2EEEnabled !== enabled) {
29157
+ yield this.localParticipant.setE2EEEnabled(enabled);
29158
+ if (this.localParticipant.identity !== '') {
29159
+ this.e2eeManager.setParticipantCryptorEnabled(enabled, this.localParticipant.identity);
29160
+ }
29161
+ }
29162
+ } else {
29163
+ throw Error('e2ee not configured, please set e2ee settings within the room options');
29102
29164
  }
29103
- } else {
29104
- throw Error('e2ee not configured, please set e2ee settings within the room options');
29165
+ } finally {
29166
+ unlock();
29105
29167
  }
29106
29168
  });
29107
29169
  }
29108
29170
  setupE2EE() {
29109
29171
  // when encryption is enabled via `options.encryption`, we enable data channel encryption
29110
- var _a;
29172
+ var _a, _b;
29111
29173
  const dcEncryptionEnabled = !!this.options.encryption;
29112
29174
  const e2eeOptions = this.options.encryption || this.options.e2ee;
29113
29175
  if (e2eeOptions) {
@@ -29128,6 +29190,7 @@ class Room extends eventsExports.EventEmitter {
29128
29190
  this.emit(RoomEvent.EncryptionError, error, participant);
29129
29191
  });
29130
29192
  (_a = this.e2eeManager) === null || _a === void 0 ? void 0 : _a.setup(this);
29193
+ (_b = this.e2eeManager) === null || _b === void 0 ? void 0 : _b.setupEngine(this.engine);
29131
29194
  }
29132
29195
  }
29133
29196
  get logContext() {
@@ -29227,10 +29290,10 @@ class Room extends eventsExports.EventEmitter {
29227
29290
  }).on(EngineEvent.DCBufferStatusChanged, (status, kind) => {
29228
29291
  this.emit(RoomEvent.DCBufferStatusChanged, status, kind);
29229
29292
  }).on(EngineEvent.LocalTrackSubscribed, subscribedSid => {
29230
- const trackPublication = this.localParticipant.getTrackPublications().find(_ref3 => {
29293
+ const trackPublication = this.localParticipant.getTrackPublications().find(_ref2 => {
29231
29294
  let {
29232
29295
  trackSid
29233
- } = _ref3;
29296
+ } = _ref2;
29234
29297
  return trackSid === subscribedSid;
29235
29298
  });
29236
29299
  if (!trackPublication) {
@@ -29274,8 +29337,8 @@ class Room extends eventsExports.EventEmitter {
29274
29337
  }
29275
29338
  this.outgoingDataTrackManager.receivedSfuUnpublishResponse(event.info.pubHandle);
29276
29339
  }).on(EngineEvent.DataTrackSubscriberHandles, event => {
29277
- const handleToSidMapping = new Map(Object.entries(event.subHandles).map(_ref4 => {
29278
- let [key, value] = _ref4;
29340
+ const handleToSidMapping = new Map(Object.entries(event.subHandles).map(_ref3 => {
29341
+ let [key, value] = _ref3;
29279
29342
  return [parseInt(key, 10), value.trackSid];
29280
29343
  }));
29281
29344
  this.incomingDataTrackManager.receivedSfuSubscriberHandles(handleToSidMapping);
@@ -30058,12 +30121,13 @@ class Room extends eventsExports.EventEmitter {
30058
30121
  return false;
30059
30122
  }
30060
30123
  this.state = state;
30124
+ this.incomingDataStreamManager.setConnected(state === ConnectionState.Connected);
30061
30125
  this.emit(RoomEvent.ConnectionStateChanged, this.state);
30062
30126
  return true;
30063
30127
  }
30064
30128
  emitBufferedEvents() {
30065
- this.bufferedEvents.forEach(_ref5 => {
30066
- let [ev, args] = _ref5;
30129
+ this.bufferedEvents.forEach(_ref4 => {
30130
+ let [ev, args] = _ref4;
30067
30131
  this.emit(ev, ...args);
30068
30132
  });
30069
30133
  this.bufferedEvents = [];
@@ -31601,4 +31665,50 @@ function facingModeFromDeviceLabel(deviceLabel) {
31601
31665
  function isFacingModeValue(item) {
31602
31666
  const allowedValues = ['user', 'environment', 'left', 'right'];
31603
31667
  return item === undefined || allowedValues.includes(item);
31604
- }export{AudioPresets,BackupCodecPolicy,BaseKeyProvider,CheckStatus,Checker,ConnectionCheck,ConnectionError,ConnectionErrorReason,ConnectionQuality,ConnectionState,CriticalTimers,CryptorError,CryptorErrorReason,CryptorEvent,DataPacket_Kind,DataStreamError,DataStreamErrorReason,DataTrackPacket,DefaultReconnectPolicy,DeviceUnsupportedError,DisconnectReason,EncryptionEvent,Encryption_Type,EngineEvent,ExternalE2EEKeyProvider,KeyHandlerEvent,KeyProviderEvent,LivekitError,LivekitReasonedError,LocalAudioTrack,LocalDataTrack,LocalParticipant,LocalTrack,LocalTrackPublication,LocalTrackRecorder,LocalVideoTrack,LogLevel,LoggerNames,MediaDeviceFailure,_ as Mutex,NegotiationError,Participant,ParticipantEvent,ParticipantInfo_Kind as ParticipantKind,PublishDataError,PublishTrackError,RemoteAudioTrack,RemoteDataTrack,RemoteParticipant,RemoteTrack,RemoteTrackPublication,RemoteVideoTrack,Room,RoomEvent,RpcError,ScreenSharePresets,SignalReconnectError,SignalRequestError,SimulatedError,SubscriptionError,TokenSource,TokenSourceConfigurable,TokenSourceFixed,Track,TrackEvent,TrackInvalidError,TrackPublication,TrackType,UnexpectedConnectionState,UnsupportedServer,VideoPreset,VideoPresets,VideoPresets43,VideoQuality,areTokenSourceFetchOptionsEqual,asEncryptablePacket,attachToElement,attributeTypings as attributes,audioCodecs,compareVersions,createAudioAnalyser,createE2EEKey,createKeyMaterialFromBuffer,createKeyMaterialFromString,createLocalAudioTrack,createLocalScreenTracks,createLocalTracks,createLocalVideoTrack,decodeTokenPayload,deriveKeys,detachTrack,facingModeFromDeviceLabel,facingModeFromLocalTrack,getBrowser,getEmptyAudioStreamTrack,getEmptyVideoStreamTrack,getLogger,importKey,isAudioCodec,isAudioTrack,isBackupCodec,isBackupVideoCodec,isBrowserSupported,isE2EESupported,isInsertableStreamSupported,isLocalParticipant,isLocalTrack,isRemoteParticipant,isRemoteTrack,isScriptTransformSupported,isVideoCodec,isVideoFrame,isVideoTrack,needsRbspUnescaping,parseRbsp,protocolVersion,ratchet,setLogExtension,setLogLevel,supportsAV1,supportsAdaptiveStream,supportsAudioOutputSelection,supportsDynacast,supportsVP9,version,videoCodecs,writeRbsp};//# sourceMappingURL=livekit-client.esm.mjs.map
31668
+ }const SerializerSymbol = Symbol.for('lk.serializer');
31669
+ function isSerializer(v) {
31670
+ return typeof v === 'object' && v !== null && 'symbol' in v && v.symbol === SerializerSymbol;
31671
+ }
31672
+ /** @internal */
31673
+ function base(params) {
31674
+ return Object.assign(Object.assign({}, params), {
31675
+ symbol: SerializerSymbol
31676
+ });
31677
+ }
31678
+ /**
31679
+ * JSON serializer — `JSON.parse` on the way in, `JSON.stringify` on the way out.
31680
+ * Defaults to `any` so individual handlers can annotate their own payload types.
31681
+ */
31682
+ function json() {
31683
+ return base({
31684
+ parse: rawString => JSON.parse(rawString),
31685
+ serialize: val => JSON.stringify(val)
31686
+ });
31687
+ }
31688
+ /** Raw string serializer — passes payloads through as plain strings with no encoding. */
31689
+ function raw() {
31690
+ return base({
31691
+ parse: rawString => rawString,
31692
+ serialize: val => val
31693
+ });
31694
+ }
31695
+ /** Custom serializer - allows custom defined parse and serialize functions */
31696
+ function custom(params) {
31697
+ return base(params);
31698
+ }
31699
+ /**
31700
+ * Serializer helpers for message payload encoding.
31701
+ *
31702
+ * @example
31703
+ * ```ts
31704
+ * const a = serializers.raw(); // Serializer<string, string>
31705
+ * const b = serializer.json<{ foo: string }, { bar: string }>(); // Serializer<{ foo: string }, { bar: string }>
31706
+ * ```
31707
+ *
31708
+ * @beta
31709
+ */
31710
+ const serializers = {
31711
+ json,
31712
+ raw,
31713
+ custom
31714
+ };export{AudioPresets,BackupCodecPolicy,BaseKeyProvider,CheckStatus,Checker,ConnectionCheck,ConnectionError,ConnectionErrorReason,ConnectionQuality,ConnectionState,CriticalTimers,CryptorError,CryptorErrorReason,CryptorEvent,DataPacket_Kind,DataStreamError,DataStreamErrorReason,DataTrackPacket,DefaultReconnectPolicy,DeviceUnsupportedError,DisconnectReason,EncryptionEvent,Encryption_Type,EngineEvent,ExternalE2EEKeyProvider,KeyHandlerEvent,KeyProviderEvent,LivekitError,LivekitReasonedError,LocalAudioTrack,LocalDataTrack,LocalParticipant,LocalTrack,LocalTrackPublication,LocalTrackRecorder,LocalVideoTrack,LogLevel,LoggerNames,MediaDeviceFailure,_ as Mutex,NegotiationError,Participant,ParticipantEvent,ParticipantInfo_Kind as ParticipantKind,PublishDataError,PublishTrackError,RemoteAudioTrack,RemoteDataTrack,RemoteParticipant,RemoteTrack,RemoteTrackPublication,RemoteVideoTrack,Room,RoomEvent,RpcError,ScreenSharePresets,SignalReconnectError,SignalRequestError,SimulatedError,SubscriptionError,TokenSource,TokenSourceConfigurable,TokenSourceFixed,Track,TrackEvent,TrackInvalidError,TrackPublication,TrackType,UnexpectedConnectionState,UnsupportedServer,VideoPreset,VideoPresets,VideoPresets43,VideoQuality,areTokenSourceFetchOptionsEqual,asEncryptablePacket,attachToElement,attributeTypings as attributes,audioCodecs,compareVersions,createAudioAnalyser,createE2EEKey,createKeyMaterialFromBuffer,createKeyMaterialFromString,createLocalAudioTrack,createLocalScreenTracks,createLocalTracks,createLocalVideoTrack,decodeTokenPayload,deriveKeys,detachTrack,facingModeFromDeviceLabel,facingModeFromLocalTrack,getBrowser,getEmptyAudioStreamTrack,getEmptyVideoStreamTrack,getLogger,importKey,isAudioCodec,isAudioTrack,isBackupCodec,isBackupVideoCodec,isBrowserSupported,isE2EESupported,isInsertableStreamSupported,isLocalParticipant,isLocalTrack,isRemoteParticipant,isRemoteTrack,isScriptTransformSupported,isSerializer,isVideoCodec,isVideoFrame,isVideoTrack,needsRbspUnescaping,parseRbsp,protocolVersion,ratchet,serializers,setLogExtension,setLogLevel,supportsAV1,supportsAdaptiveStream,supportsAudioOutputSelection,supportsDynacast,supportsVP9,version,videoCodecs,writeRbsp};//# sourceMappingURL=livekit-client.esm.mjs.map