livekit-client 1.1.8 → 1.1.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 (36) hide show
  1. package/README.md +1 -0
  2. package/dist/livekit-client.esm.mjs +460 -118
  3. package/dist/livekit-client.esm.mjs.map +1 -1
  4. package/dist/livekit-client.umd.js +1 -1
  5. package/dist/livekit-client.umd.js.map +1 -1
  6. package/dist/src/api/SignalClient.d.ts +2 -1
  7. package/dist/src/api/SignalClient.d.ts.map +1 -1
  8. package/dist/src/index.d.ts +4 -3
  9. package/dist/src/index.d.ts.map +1 -1
  10. package/dist/src/proto/livekit_models.d.ts +234 -0
  11. package/dist/src/proto/livekit_models.d.ts.map +1 -1
  12. package/dist/src/proto/livekit_rtc.d.ts +944 -6
  13. package/dist/src/proto/livekit_rtc.d.ts.map +1 -1
  14. package/dist/src/room/RTCEngine.d.ts +2 -2
  15. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  16. package/dist/src/room/Room.d.ts +2 -2
  17. package/dist/src/room/Room.d.ts.map +1 -1
  18. package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
  19. package/dist/src/room/track/LocalTrack.d.ts +2 -0
  20. package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
  21. package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
  22. package/dist/src/room/track/RemoteTrack.d.ts.map +1 -1
  23. package/package.json +3 -1
  24. package/src/api/SignalClient.ts +19 -6
  25. package/src/index.ts +6 -2
  26. package/src/proto/livekit_models.ts +179 -4
  27. package/src/proto/livekit_rtc.ts +14 -1
  28. package/src/room/RTCEngine.ts +3 -2
  29. package/src/room/Room.ts +10 -8
  30. package/src/room/track/LocalAudioTrack.ts +16 -12
  31. package/src/room/track/LocalTrack.ts +37 -25
  32. package/src/room/track/LocalVideoTrack.ts +15 -11
  33. package/src/room/track/RemoteTrack.ts +1 -0
  34. package/dist/src/api/RequestQueue.d.ts +0 -13
  35. package/dist/src/api/RequestQueue.d.ts.map +0 -1
  36. package/src/api/RequestQueue.ts +0 -53
@@ -4484,6 +4484,82 @@ function clientConfigSettingToJSON(object) {
4484
4484
  return 'UNKNOWN';
4485
4485
  }
4486
4486
  }
4487
+ var DisconnectReason;
4488
+
4489
+ (function (DisconnectReason) {
4490
+ DisconnectReason[DisconnectReason["UNKNOWN_REASON"] = 0] = "UNKNOWN_REASON";
4491
+ DisconnectReason[DisconnectReason["CLIENT_INITIATED"] = 1] = "CLIENT_INITIATED";
4492
+ DisconnectReason[DisconnectReason["DUPLICATE_IDENTITY"] = 2] = "DUPLICATE_IDENTITY";
4493
+ DisconnectReason[DisconnectReason["SERVER_SHUTDOWN"] = 3] = "SERVER_SHUTDOWN";
4494
+ DisconnectReason[DisconnectReason["PARTICIPANT_REMOVED"] = 4] = "PARTICIPANT_REMOVED";
4495
+ DisconnectReason[DisconnectReason["ROOM_DELETED"] = 5] = "ROOM_DELETED";
4496
+ DisconnectReason[DisconnectReason["STATE_MISMATCH"] = 6] = "STATE_MISMATCH";
4497
+ DisconnectReason[DisconnectReason["UNRECOGNIZED"] = -1] = "UNRECOGNIZED";
4498
+ })(DisconnectReason || (DisconnectReason = {}));
4499
+
4500
+ function disconnectReasonFromJSON(object) {
4501
+ switch (object) {
4502
+ case 0:
4503
+ case 'UNKNOWN_REASON':
4504
+ return DisconnectReason.UNKNOWN_REASON;
4505
+
4506
+ case 1:
4507
+ case 'CLIENT_INITIATED':
4508
+ return DisconnectReason.CLIENT_INITIATED;
4509
+
4510
+ case 2:
4511
+ case 'DUPLICATE_IDENTITY':
4512
+ return DisconnectReason.DUPLICATE_IDENTITY;
4513
+
4514
+ case 3:
4515
+ case 'SERVER_SHUTDOWN':
4516
+ return DisconnectReason.SERVER_SHUTDOWN;
4517
+
4518
+ case 4:
4519
+ case 'PARTICIPANT_REMOVED':
4520
+ return DisconnectReason.PARTICIPANT_REMOVED;
4521
+
4522
+ case 5:
4523
+ case 'ROOM_DELETED':
4524
+ return DisconnectReason.ROOM_DELETED;
4525
+
4526
+ case 6:
4527
+ case 'STATE_MISMATCH':
4528
+ return DisconnectReason.STATE_MISMATCH;
4529
+
4530
+ case -1:
4531
+ case 'UNRECOGNIZED':
4532
+ default:
4533
+ return DisconnectReason.UNRECOGNIZED;
4534
+ }
4535
+ }
4536
+ function disconnectReasonToJSON(object) {
4537
+ switch (object) {
4538
+ case DisconnectReason.UNKNOWN_REASON:
4539
+ return 'UNKNOWN_REASON';
4540
+
4541
+ case DisconnectReason.CLIENT_INITIATED:
4542
+ return 'CLIENT_INITIATED';
4543
+
4544
+ case DisconnectReason.DUPLICATE_IDENTITY:
4545
+ return 'DUPLICATE_IDENTITY';
4546
+
4547
+ case DisconnectReason.SERVER_SHUTDOWN:
4548
+ return 'SERVER_SHUTDOWN';
4549
+
4550
+ case DisconnectReason.PARTICIPANT_REMOVED:
4551
+ return 'PARTICIPANT_REMOVED';
4552
+
4553
+ case DisconnectReason.ROOM_DELETED:
4554
+ return 'ROOM_DELETED';
4555
+
4556
+ case DisconnectReason.STATE_MISMATCH:
4557
+ return 'STATE_MISMATCH';
4558
+
4559
+ default:
4560
+ return 'UNKNOWN';
4561
+ }
4562
+ }
4487
4563
  var ParticipantInfo_State;
4488
4564
 
4489
4565
  (function (ParticipantInfo_State) {
@@ -5204,7 +5280,8 @@ function createBaseSimulcastCodecInfo() {
5204
5280
  return {
5205
5281
  mimeType: '',
5206
5282
  mid: '',
5207
- cid: ''
5283
+ cid: '',
5284
+ layers: []
5208
5285
  };
5209
5286
  }
5210
5287
 
@@ -5224,6 +5301,10 @@ const SimulcastCodecInfo = {
5224
5301
  writer.uint32(26).string(message.cid);
5225
5302
  }
5226
5303
 
5304
+ for (const v of message.layers) {
5305
+ VideoLayer.encode(v, writer.uint32(34).fork()).ldelim();
5306
+ }
5307
+
5227
5308
  return writer;
5228
5309
  },
5229
5310
 
@@ -5248,6 +5329,10 @@ const SimulcastCodecInfo = {
5248
5329
  message.cid = reader.string();
5249
5330
  break;
5250
5331
 
5332
+ case 4:
5333
+ message.layers.push(VideoLayer.decode(reader, reader.uint32()));
5334
+ break;
5335
+
5251
5336
  default:
5252
5337
  reader.skipType(tag & 7);
5253
5338
  break;
@@ -5261,7 +5346,8 @@ const SimulcastCodecInfo = {
5261
5346
  return {
5262
5347
  mimeType: isSet$1(object.mimeType) ? String(object.mimeType) : '',
5263
5348
  mid: isSet$1(object.mid) ? String(object.mid) : '',
5264
- cid: isSet$1(object.cid) ? String(object.cid) : ''
5349
+ cid: isSet$1(object.cid) ? String(object.cid) : '',
5350
+ layers: Array.isArray(object === null || object === void 0 ? void 0 : object.layers) ? object.layers.map(e => VideoLayer.fromJSON(e)) : []
5265
5351
  };
5266
5352
  },
5267
5353
 
@@ -5270,16 +5356,24 @@ const SimulcastCodecInfo = {
5270
5356
  message.mimeType !== undefined && (obj.mimeType = message.mimeType);
5271
5357
  message.mid !== undefined && (obj.mid = message.mid);
5272
5358
  message.cid !== undefined && (obj.cid = message.cid);
5359
+
5360
+ if (message.layers) {
5361
+ obj.layers = message.layers.map(e => e ? VideoLayer.toJSON(e) : undefined);
5362
+ } else {
5363
+ obj.layers = [];
5364
+ }
5365
+
5273
5366
  return obj;
5274
5367
  },
5275
5368
 
5276
5369
  fromPartial(object) {
5277
- var _a, _b, _c;
5370
+ var _a, _b, _c, _d;
5278
5371
 
5279
5372
  const message = createBaseSimulcastCodecInfo();
5280
5373
  message.mimeType = (_a = object.mimeType) !== null && _a !== void 0 ? _a : '';
5281
5374
  message.mid = (_b = object.mid) !== null && _b !== void 0 ? _b : '';
5282
5375
  message.cid = (_c = object.cid) !== null && _c !== void 0 ? _c : '';
5376
+ message.layers = ((_d = object.layers) === null || _d === void 0 ? void 0 : _d.map(e => VideoLayer.fromPartial(e))) || [];
5283
5377
  return message;
5284
5378
  }
5285
5379
 
@@ -6179,7 +6273,8 @@ function createBaseClientConfiguration() {
6179
6273
  return {
6180
6274
  video: undefined,
6181
6275
  screen: undefined,
6182
- resumeConnection: 0
6276
+ resumeConnection: 0,
6277
+ disabledCodecs: undefined
6183
6278
  };
6184
6279
  }
6185
6280
 
@@ -6199,6 +6294,10 @@ const ClientConfiguration = {
6199
6294
  writer.uint32(24).int32(message.resumeConnection);
6200
6295
  }
6201
6296
 
6297
+ if (message.disabledCodecs !== undefined) {
6298
+ DisabledCodecs.encode(message.disabledCodecs, writer.uint32(34).fork()).ldelim();
6299
+ }
6300
+
6202
6301
  return writer;
6203
6302
  },
6204
6303
 
@@ -6223,6 +6322,10 @@ const ClientConfiguration = {
6223
6322
  message.resumeConnection = reader.int32();
6224
6323
  break;
6225
6324
 
6325
+ case 4:
6326
+ message.disabledCodecs = DisabledCodecs.decode(reader, reader.uint32());
6327
+ break;
6328
+
6226
6329
  default:
6227
6330
  reader.skipType(tag & 7);
6228
6331
  break;
@@ -6236,7 +6339,8 @@ const ClientConfiguration = {
6236
6339
  return {
6237
6340
  video: isSet$1(object.video) ? VideoConfiguration.fromJSON(object.video) : undefined,
6238
6341
  screen: isSet$1(object.screen) ? VideoConfiguration.fromJSON(object.screen) : undefined,
6239
- resumeConnection: isSet$1(object.resumeConnection) ? clientConfigSettingFromJSON(object.resumeConnection) : 0
6342
+ resumeConnection: isSet$1(object.resumeConnection) ? clientConfigSettingFromJSON(object.resumeConnection) : 0,
6343
+ disabledCodecs: isSet$1(object.disabledCodecs) ? DisabledCodecs.fromJSON(object.disabledCodecs) : undefined
6240
6344
  };
6241
6345
  },
6242
6346
 
@@ -6245,6 +6349,7 @@ const ClientConfiguration = {
6245
6349
  message.video !== undefined && (obj.video = message.video ? VideoConfiguration.toJSON(message.video) : undefined);
6246
6350
  message.screen !== undefined && (obj.screen = message.screen ? VideoConfiguration.toJSON(message.screen) : undefined);
6247
6351
  message.resumeConnection !== undefined && (obj.resumeConnection = clientConfigSettingToJSON(message.resumeConnection));
6352
+ message.disabledCodecs !== undefined && (obj.disabledCodecs = message.disabledCodecs ? DisabledCodecs.toJSON(message.disabledCodecs) : undefined);
6248
6353
  return obj;
6249
6354
  },
6250
6355
 
@@ -6255,6 +6360,7 @@ const ClientConfiguration = {
6255
6360
  message.video = object.video !== undefined && object.video !== null ? VideoConfiguration.fromPartial(object.video) : undefined;
6256
6361
  message.screen = object.screen !== undefined && object.screen !== null ? VideoConfiguration.fromPartial(object.screen) : undefined;
6257
6362
  message.resumeConnection = (_a = object.resumeConnection) !== null && _a !== void 0 ? _a : 0;
6363
+ message.disabledCodecs = object.disabledCodecs !== undefined && object.disabledCodecs !== null ? DisabledCodecs.fromPartial(object.disabledCodecs) : undefined;
6258
6364
  return message;
6259
6365
  }
6260
6366
 
@@ -6321,6 +6427,73 @@ const VideoConfiguration = {
6321
6427
 
6322
6428
  };
6323
6429
 
6430
+ function createBaseDisabledCodecs() {
6431
+ return {
6432
+ codecs: []
6433
+ };
6434
+ }
6435
+
6436
+ const DisabledCodecs = {
6437
+ encode(message) {
6438
+ let writer = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : minimal.Writer.create();
6439
+
6440
+ for (const v of message.codecs) {
6441
+ Codec.encode(v, writer.uint32(10).fork()).ldelim();
6442
+ }
6443
+
6444
+ return writer;
6445
+ },
6446
+
6447
+ decode(input, length) {
6448
+ const reader = input instanceof minimal.Reader ? input : new minimal.Reader(input);
6449
+ let end = length === undefined ? reader.len : reader.pos + length;
6450
+ const message = createBaseDisabledCodecs();
6451
+
6452
+ while (reader.pos < end) {
6453
+ const tag = reader.uint32();
6454
+
6455
+ switch (tag >>> 3) {
6456
+ case 1:
6457
+ message.codecs.push(Codec.decode(reader, reader.uint32()));
6458
+ break;
6459
+
6460
+ default:
6461
+ reader.skipType(tag & 7);
6462
+ break;
6463
+ }
6464
+ }
6465
+
6466
+ return message;
6467
+ },
6468
+
6469
+ fromJSON(object) {
6470
+ return {
6471
+ codecs: Array.isArray(object === null || object === void 0 ? void 0 : object.codecs) ? object.codecs.map(e => Codec.fromJSON(e)) : []
6472
+ };
6473
+ },
6474
+
6475
+ toJSON(message) {
6476
+ const obj = {};
6477
+
6478
+ if (message.codecs) {
6479
+ obj.codecs = message.codecs.map(e => e ? Codec.toJSON(e) : undefined);
6480
+ } else {
6481
+ obj.codecs = [];
6482
+ }
6483
+
6484
+ return obj;
6485
+ },
6486
+
6487
+ fromPartial(object) {
6488
+ var _a;
6489
+
6490
+ const message = createBaseDisabledCodecs();
6491
+ message.codecs = ((_a = object.codecs) === null || _a === void 0 ? void 0 : _a.map(e => Codec.fromPartial(e))) || [];
6492
+ return message;
6493
+ }
6494
+
6495
+ };
6496
+
6324
6497
  var globalThis$1 = (() => {
6325
6498
  if (typeof globalThis$1 !== 'undefined') return globalThis$1;
6326
6499
  if (typeof self !== 'undefined') return self;
@@ -6346,9 +6519,11 @@ const btoa = globalThis$1.btoa || (bin => globalThis$1.Buffer.from(bin, 'binary'
6346
6519
 
6347
6520
  function base64FromBytes(arr) {
6348
6521
  const bin = [];
6349
- arr.forEach(byte => {
6522
+
6523
+ for (const byte of arr) {
6350
6524
  bin.push(String.fromCharCode(byte));
6351
- });
6525
+ }
6526
+
6352
6527
  return btoa(bin.join(''));
6353
6528
  }
6354
6529
 
@@ -8033,7 +8208,8 @@ const UpdateTrackSettings = {
8033
8208
 
8034
8209
  function createBaseLeaveRequest() {
8035
8210
  return {
8036
- canReconnect: false
8211
+ canReconnect: false,
8212
+ reason: 0
8037
8213
  };
8038
8214
  }
8039
8215
 
@@ -8045,6 +8221,10 @@ const LeaveRequest = {
8045
8221
  writer.uint32(8).bool(message.canReconnect);
8046
8222
  }
8047
8223
 
8224
+ if (message.reason !== 0) {
8225
+ writer.uint32(16).int32(message.reason);
8226
+ }
8227
+
8048
8228
  return writer;
8049
8229
  },
8050
8230
 
@@ -8061,6 +8241,10 @@ const LeaveRequest = {
8061
8241
  message.canReconnect = reader.bool();
8062
8242
  break;
8063
8243
 
8244
+ case 2:
8245
+ message.reason = reader.int32();
8246
+ break;
8247
+
8064
8248
  default:
8065
8249
  reader.skipType(tag & 7);
8066
8250
  break;
@@ -8072,21 +8256,24 @@ const LeaveRequest = {
8072
8256
 
8073
8257
  fromJSON(object) {
8074
8258
  return {
8075
- canReconnect: isSet(object.canReconnect) ? Boolean(object.canReconnect) : false
8259
+ canReconnect: isSet(object.canReconnect) ? Boolean(object.canReconnect) : false,
8260
+ reason: isSet(object.reason) ? disconnectReasonFromJSON(object.reason) : 0
8076
8261
  };
8077
8262
  },
8078
8263
 
8079
8264
  toJSON(message) {
8080
8265
  const obj = {};
8081
8266
  message.canReconnect !== undefined && (obj.canReconnect = message.canReconnect);
8267
+ message.reason !== undefined && (obj.reason = disconnectReasonToJSON(message.reason));
8082
8268
  return obj;
8083
8269
  },
8084
8270
 
8085
8271
  fromPartial(object) {
8086
- var _a;
8272
+ var _a, _b;
8087
8273
 
8088
8274
  const message = createBaseLeaveRequest();
8089
8275
  message.canReconnect = (_a = object.canReconnect) !== null && _a !== void 0 ? _a : false;
8276
+ message.reason = (_b = object.reason) !== null && _b !== void 0 ? _b : 0;
8090
8277
  return message;
8091
8278
  }
8092
8279
 
@@ -10070,7 +10257,7 @@ function computeBitrate(currentStats, prevStats) {
10070
10257
  return (bytesNow - bytesPrev) * 8 * 1000 / (currentStats.timestamp - prevStats.timestamp);
10071
10258
  }
10072
10259
 
10073
- var version$1 = "1.1.8";
10260
+ var version$1 = "1.1.9";
10074
10261
 
10075
10262
  const version = version$1;
10076
10263
  const protocolVersion = 8;
@@ -10190,6 +10377,178 @@ class Future {
10190
10377
 
10191
10378
  }
10192
10379
 
10380
+ class Queue {
10381
+ /**
10382
+ * @class Queue
10383
+ *
10384
+ * Priority queue with rate limiting<br>
10385
+ * See the medium article:<br>
10386
+ * https://mmomtchev.medium.com/parallelizing-download-loops-in-js-with-async-await-queue-670420880cd6
10387
+ *
10388
+ * @param {number} [_maxConcurrent=1] Number of tasks allowed to run simultaneously
10389
+ * @param {number} [_minCycle=0] Minimum number of milliseconds between two consecutive tasks
10390
+ */
10391
+ constructor(_maxConcurrent, _minCycle) {
10392
+ this.maxConcurrent = _maxConcurrent || 1;
10393
+ this.minCycle = _minCycle || 0;
10394
+ this.queueRunning = [];
10395
+ this.queueWaiting = {};
10396
+ this.lastRun = 0;
10397
+ }
10398
+ /** @private */
10399
+
10400
+
10401
+ dequeue(hash) {
10402
+ const q = this.queueRunning;
10403
+ const idx = q.findIndex(x => x.hash === hash);
10404
+ if (idx == -1) throw 'queue desync';
10405
+ const o = q[idx];
10406
+ q.splice(idx, 1);
10407
+ return o;
10408
+ }
10409
+ /** @private */
10410
+
10411
+
10412
+ getFirstWaiting() {
10413
+ for (let p of Object.keys(this.queueWaiting).sort((a, b) => a - b)) if (this.queueWaiting[p] !== undefined && this.queueWaiting[p].length > 0) return this.queueWaiting[p];
10414
+
10415
+ return undefined;
10416
+ }
10417
+ /**
10418
+ * Signal that the task `hash` has finished.<br>
10419
+ * Frees its slot in the queue
10420
+ *
10421
+ * @method end
10422
+ * @param {any} hash Unique hash identifying the task, Symbol() works very well
10423
+ */
10424
+
10425
+
10426
+ end(hash) {
10427
+ const me = this.dequeue(hash);
10428
+ me.resolve();
10429
+ /* Choose the next task to run and unblock its promise */
10430
+
10431
+ const q = this.getFirstWaiting();
10432
+
10433
+ if (q !== undefined) {
10434
+ const next = q.shift();
10435
+ next.resolve();
10436
+ }
10437
+ }
10438
+ /**
10439
+ * Wait for a slot in the queue
10440
+ *
10441
+ * @method wait
10442
+ * @param {any} hash Unique hash identifying the task
10443
+ * @param {number} [priority=0] Optional priority, -1 is higher priority than 1
10444
+ * @return {Promise<void>} Resolved when the task is ready to run
10445
+ */
10446
+
10447
+
10448
+ async wait(hash, _priority) {
10449
+ const priority = _priority === undefined ? 0 : _priority;
10450
+ /* Us on the queue */
10451
+
10452
+ let me = {
10453
+ hash,
10454
+ priority
10455
+ };
10456
+ /* Create priorities on the fly */
10457
+
10458
+ if (this.queueWaiting[priority] == undefined) this.queueWaiting[priority] = [];
10459
+ /* Are we allowed to run? */
10460
+
10461
+ if (this.queueRunning.length >= this.maxConcurrent) {
10462
+ /* This promise will be unlocked from the outside */
10463
+
10464
+ /* and it cannot reject */
10465
+ me.promise = new Promise(resolve => {
10466
+ me.resolve = resolve;
10467
+ });
10468
+ /* Get in the line */
10469
+
10470
+ this.queueWaiting[priority].push(me);
10471
+ await me.promise;
10472
+ }
10473
+
10474
+ this.queueRunning.push(me);
10475
+ me.promise = new Promise(resolve => {
10476
+ me.resolve = resolve;
10477
+ });
10478
+ /* Wait if it is too soon */
10479
+
10480
+ while (Date.now() - this.lastRun < this.minCycle) {
10481
+ await new Promise(resolve => setTimeout(resolve, this.minCycle - Date.now() + this.lastRun));
10482
+ }
10483
+
10484
+ this.lastRun = Date.now();
10485
+ }
10486
+ /**
10487
+ * Run a job (equivalent to calling Queue.wait(), fn() and then Queue.end())<br>
10488
+ * fn can be both synchronous or asynchronous function
10489
+ *
10490
+ * @method run
10491
+ * @param {Function} fn The job
10492
+ * @param {number} [priority=0] Optional priority, -1 is higher priority than 1
10493
+ * @return {Promise<any>} Resolved when the task has finished with the return value of fn
10494
+ */
10495
+
10496
+
10497
+ run(job, _priority) {
10498
+ const priority = _priority === undefined ? 0 : _priority;
10499
+ const id = Symbol();
10500
+ return this.wait(id, priority).then(() => job()).finally(() => {
10501
+ this.end(id);
10502
+ });
10503
+ }
10504
+ /**
10505
+ * @interface QueueStats {running: number, waiting: number, last: number}
10506
+ */
10507
+
10508
+ /**
10509
+ * Return the number of running and waiting jobs
10510
+ *
10511
+ * @method stat
10512
+ * @return {QueueStats} running, waiting, last
10513
+ */
10514
+
10515
+
10516
+ stat() {
10517
+ return {
10518
+ running: this.queueRunning.length,
10519
+ waiting: Object.keys(this.queueWaiting).reduce((t, x) => t += this.queueWaiting[x].length, 0),
10520
+ last: this.lastRun
10521
+ };
10522
+ }
10523
+ /**
10524
+ * Returns a promise that resolves when the queue is empty
10525
+ *
10526
+ * @method flush
10527
+ * @return {Promise<void>}
10528
+ */
10529
+
10530
+
10531
+ async flush() {
10532
+ /* Aways wait on the lowest priority in the queue */
10533
+ while (this.stat().waiting > 0) {
10534
+ for (let p of Object.keys(this.queueWaiting).sort((a, b) => b - a)) {
10535
+ const qp = this.queueWaiting[p];
10536
+
10537
+ if (qp !== undefined && qp.length > 0) {
10538
+ await qp[qp.length - 1].promise;
10539
+ }
10540
+ }
10541
+ }
10542
+ /* And then finish on the running queue */
10543
+
10544
+
10545
+ while (this.queueRunning.length > 0) {
10546
+ await Promise.allSettled(this.queueRunning.map(x => x.promise));
10547
+ }
10548
+ }
10549
+
10550
+ }
10551
+
10193
10552
  const defaultId = 'default';
10194
10553
  class DeviceManager {
10195
10554
  static getInstance() {
@@ -11098,6 +11457,7 @@ class LocalTrack extends Track {
11098
11457
  this.reacquireTrack = false;
11099
11458
  this.wasMuted = false;
11100
11459
  this.providedByUser = userProvidedTrack;
11460
+ this.muteQueue = new Queue();
11101
11461
  }
11102
11462
 
11103
11463
  get id() {
@@ -11178,7 +11538,9 @@ class LocalTrack extends Track {
11178
11538
  // 'A MediaStreamTrack ended due to a capture failure`
11179
11539
 
11180
11540
 
11181
- this._mediaStreamTrack.stop();
11541
+ if (!this.providedByUser) {
11542
+ this._mediaStreamTrack.stop();
11543
+ }
11182
11544
 
11183
11545
  track.addEventListener('ended', this.handleEnded);
11184
11546
  livekitLogger.debug('replace MediaStreamTrack');
@@ -11246,6 +11608,8 @@ class LocalTrack extends Track {
11246
11608
  }
11247
11609
 
11248
11610
  setTrackMuted(muted) {
11611
+ livekitLogger.debug("setting ".concat(this.kind, " track ").concat(muted ? 'muted' : 'unmuted'));
11612
+
11249
11613
  if (this.isMuted === muted) {
11250
11614
  return;
11251
11615
  }
@@ -11279,34 +11643,38 @@ class LocalTrack extends Track {
11279
11643
  }
11280
11644
 
11281
11645
  async pauseUpstream() {
11282
- if (this._isUpstreamPaused === true) {
11283
- return;
11284
- }
11646
+ this.muteQueue.run(async () => {
11647
+ if (this._isUpstreamPaused === true) {
11648
+ return;
11649
+ }
11285
11650
 
11286
- if (!this.sender) {
11287
- livekitLogger.warn('unable to pause upstream for an unpublished track');
11288
- return;
11289
- }
11651
+ if (!this.sender) {
11652
+ livekitLogger.warn('unable to pause upstream for an unpublished track');
11653
+ return;
11654
+ }
11290
11655
 
11291
- this._isUpstreamPaused = true;
11292
- this.emit(TrackEvent.UpstreamPaused, this);
11293
- const emptyTrack = this.kind === Track.Kind.Audio ? getEmptyAudioStreamTrack() : getEmptyVideoStreamTrack();
11294
- await this.sender.replaceTrack(emptyTrack);
11656
+ this._isUpstreamPaused = true;
11657
+ this.emit(TrackEvent.UpstreamPaused, this);
11658
+ const emptyTrack = this.kind === Track.Kind.Audio ? getEmptyAudioStreamTrack() : getEmptyVideoStreamTrack();
11659
+ await this.sender.replaceTrack(emptyTrack);
11660
+ });
11295
11661
  }
11296
11662
 
11297
11663
  async resumeUpstream() {
11298
- if (this._isUpstreamPaused === false) {
11299
- return;
11300
- }
11664
+ this.muteQueue.run(async () => {
11665
+ if (this._isUpstreamPaused === false) {
11666
+ return;
11667
+ }
11301
11668
 
11302
- if (!this.sender) {
11303
- livekitLogger.warn('unable to resume upstream for an unpublished track');
11304
- return;
11305
- }
11669
+ if (!this.sender) {
11670
+ livekitLogger.warn('unable to resume upstream for an unpublished track');
11671
+ return;
11672
+ }
11306
11673
 
11307
- this._isUpstreamPaused = false;
11308
- this.emit(TrackEvent.UpstreamResumed, this);
11309
- await this.sender.replaceTrack(this._mediaStreamTrack);
11674
+ this._isUpstreamPaused = false;
11675
+ this.emit(TrackEvent.UpstreamResumed, this);
11676
+ await this.sender.replaceTrack(this._mediaStreamTrack);
11677
+ });
11310
11678
  }
11311
11679
 
11312
11680
  }
@@ -11464,24 +11832,28 @@ class LocalAudioTrack extends LocalTrack {
11464
11832
  }
11465
11833
 
11466
11834
  async mute() {
11467
- // disabled special handling as it will cause BT headsets to switch communication modes
11468
- if (this.source === Track.Source.Microphone && this.stopOnMute) {
11469
- livekitLogger.debug('stopping mic track'); // also stop the track, so that microphone indicator is turned off
11835
+ await this.muteQueue.run(async () => {
11836
+ // disabled special handling as it will cause BT headsets to switch communication modes
11837
+ if (this.source === Track.Source.Microphone && this.stopOnMute && !this.isUserProvided) {
11838
+ livekitLogger.debug('stopping mic track'); // also stop the track, so that microphone indicator is turned off
11470
11839
 
11471
- this._mediaStreamTrack.stop();
11472
- }
11840
+ this._mediaStreamTrack.stop();
11841
+ }
11473
11842
 
11474
- await super.mute();
11843
+ await super.mute();
11844
+ });
11475
11845
  return this;
11476
11846
  }
11477
11847
 
11478
11848
  async unmute() {
11479
- if (this.source === Track.Source.Microphone && this.stopOnMute && !this.isUserProvided) {
11480
- livekitLogger.debug('reacquiring mic track');
11481
- await this.restartTrack();
11482
- }
11849
+ await this.muteQueue.run(async () => {
11850
+ if (this.source === Track.Source.Microphone && this.stopOnMute && !this.isUserProvided) {
11851
+ livekitLogger.debug('reacquiring mic track');
11852
+ await this.restartTrack();
11853
+ }
11483
11854
 
11484
- await super.unmute();
11855
+ await super.unmute();
11856
+ });
11485
11857
  return this;
11486
11858
  }
11487
11859
 
@@ -11647,23 +12019,27 @@ class LocalVideoTrack extends LocalTrack {
11647
12019
  }
11648
12020
 
11649
12021
  async mute() {
11650
- if (this.source === Track.Source.Camera) {
11651
- livekitLogger.debug('stopping camera track'); // also stop the track, so that camera indicator is turned off
12022
+ await this.muteQueue.run(async () => {
12023
+ if (this.source === Track.Source.Camera && !this.isUserProvided) {
12024
+ livekitLogger.debug('stopping camera track'); // also stop the track, so that camera indicator is turned off
11652
12025
 
11653
- this._mediaStreamTrack.stop();
11654
- }
12026
+ this._mediaStreamTrack.stop();
12027
+ }
11655
12028
 
11656
- await super.mute();
12029
+ await super.mute();
12030
+ });
11657
12031
  return this;
11658
12032
  }
11659
12033
 
11660
12034
  async unmute() {
11661
- if (this.source === Track.Source.Camera && !this.isUserProvided) {
11662
- livekitLogger.debug('reacquiring camera track');
11663
- await this.restartTrack();
11664
- }
12035
+ await this.muteQueue.run(async () => {
12036
+ if (this.source === Track.Source.Camera && !this.isUserProvided) {
12037
+ livekitLogger.debug('reacquiring camera track');
12038
+ await this.restartTrack();
12039
+ }
11665
12040
 
11666
- await super.unmute();
12041
+ await super.unmute();
12042
+ });
11667
12043
  return this;
11668
12044
  }
11669
12045
 
@@ -11980,6 +12356,7 @@ class RemoteTrack extends Track {
11980
12356
  setMuted(muted) {
11981
12357
  if (this.isMuted !== muted) {
11982
12358
  this.isMuted = muted;
12359
+ this._mediaStreamTrack.enabled = !muted;
11983
12360
  this.emit(muted ? TrackEvent.Muted : TrackEvent.Unmuted, this);
11984
12361
  }
11985
12362
  }
@@ -18141,57 +18518,6 @@ adapterFactory({
18141
18518
  window: typeof window === 'undefined' ? undefined : window
18142
18519
  });
18143
18520
 
18144
- class Queue {
18145
- constructor() {
18146
- this.queue = [];
18147
- this.running = false;
18148
- }
18149
-
18150
- enqueue(cb) {
18151
- livekitLogger.trace('enqueuing request to fire later');
18152
- this.queue.push(cb);
18153
- }
18154
-
18155
- dequeue() {
18156
- const evt = this.queue.shift();
18157
- if (evt) evt();
18158
- livekitLogger.trace('firing request from queue');
18159
- }
18160
-
18161
- async run() {
18162
- if (this.running) return;
18163
- livekitLogger.trace('start queue');
18164
- this.running = true;
18165
-
18166
- while (this.running && this.queue.length > 0) {
18167
- this.dequeue();
18168
- }
18169
-
18170
- this.running = false;
18171
- livekitLogger.trace('queue finished');
18172
- }
18173
-
18174
- pause() {
18175
- livekitLogger.trace('pausing queue');
18176
- this.running = false;
18177
- }
18178
-
18179
- reset() {
18180
- livekitLogger.trace('resetting queue');
18181
- this.running = false;
18182
- this.queue = [];
18183
- }
18184
-
18185
- isRunning() {
18186
- return this.running;
18187
- }
18188
-
18189
- isEmpty() {
18190
- return this.queue.length === 0;
18191
- }
18192
-
18193
- }
18194
-
18195
18521
  const passThroughQueueSignals = ['syncState', 'trickle', 'offer', 'answer', 'simulate', 'leave'];
18196
18522
 
18197
18523
  function canPassThroughQueue(req) {
@@ -18212,6 +18538,7 @@ class SignalClient {
18212
18538
  this.isReconnecting = false;
18213
18539
  this.useJSON = useJSON;
18214
18540
  this.requestQueue = new Queue();
18541
+ this.queuedRequests = [];
18215
18542
  }
18216
18543
 
18217
18544
  async join(url, token, opts, abortSignal) {
@@ -18439,14 +18766,20 @@ class SignalClient {
18439
18766
 
18440
18767
  async sendRequest(req) {
18441
18768
  let fromQueue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
18442
- // capture all requests while reconnecting and put them in a queue.
18443
- // keep order by queueing up new events as long as the queue is not empty
18769
+ // capture all requests while reconnecting and put them in a queue
18444
18770
  // unless the request originates from the queue, then don't enqueue again
18445
18771
  const canQueue = !fromQueue && !canPassThroughQueue(req);
18446
18772
 
18447
- if (canQueue && (this.isReconnecting || !this.requestQueue.isEmpty())) {
18448
- this.requestQueue.enqueue(() => this.sendRequest(req, true));
18773
+ if (canQueue && this.isReconnecting) {
18774
+ this.queuedRequests.push(async () => {
18775
+ await this.sendRequest(req, true);
18776
+ });
18449
18777
  return;
18778
+ } // make sure previously queued requests are being sent first
18779
+
18780
+
18781
+ if (!fromQueue) {
18782
+ await this.requestQueue.flush();
18450
18783
  }
18451
18784
 
18452
18785
  if (this.signalLatency) {
@@ -18544,8 +18877,15 @@ class SignalClient {
18544
18877
  }
18545
18878
 
18546
18879
  setReconnected() {
18880
+ while (this.queuedRequests.length > 0) {
18881
+ const req = this.queuedRequests.shift();
18882
+
18883
+ if (req) {
18884
+ this.requestQueue.run(req);
18885
+ }
18886
+ }
18887
+
18547
18888
  this.isReconnecting = false;
18548
- this.requestQueue.run();
18549
18889
  }
18550
18890
 
18551
18891
  handleWSError(ev) {
@@ -19173,7 +19513,7 @@ class RTCEngine extends events.exports.EventEmitter {
19173
19513
  this.fullReconnectOnNext = true;
19174
19514
  this.primaryPC = undefined;
19175
19515
  } else {
19176
- this.emit(EngineEvent.Disconnected);
19516
+ this.emit(EngineEvent.Disconnected, leave === null || leave === void 0 ? void 0 : leave.reason);
19177
19517
  this.close();
19178
19518
  }
19179
19519
 
@@ -19925,8 +20265,8 @@ class Room extends events.exports.EventEmitter {
19925
20265
  this.engine.client.onConnectionQuality = this.handleConnectionQualityUpdate;
19926
20266
  this.engine.on(EngineEvent.MediaTrackAdded, (mediaTrack, stream, receiver) => {
19927
20267
  this.onTrackAdded(mediaTrack, stream, receiver);
19928
- }).on(EngineEvent.Disconnected, () => {
19929
- this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
20268
+ }).on(EngineEvent.Disconnected, reason => {
20269
+ this.handleDisconnect(this.options.stopLocalTrackOnUnpublish, reason);
19930
20270
  }).on(EngineEvent.ActiveSpeakersUpdate, this.handleActiveSpeakersUpdate).on(EngineEvent.DataPacketReceived, this.handleDataPacket).on(EngineEvent.Resuming, () => {
19931
20271
  if (this.setAndEmitConnectionState(ConnectionState.Reconnecting)) {
19932
20272
  this.emit(RoomEvent.Reconnecting);
@@ -20146,15 +20486,16 @@ class Room extends events.exports.EventEmitter {
20146
20486
  // at that time, ICE connectivity has not been established so the track is not
20147
20487
  // technically subscribed.
20148
20488
  // We'll defer these events until when the room is connected or eventually disconnected.
20149
- if (this.state === ConnectionState.Connecting || this.state === ConnectionState.Reconnecting) {
20150
- setTimeout(() => {
20489
+ if (this.connectFuture) {
20490
+ this.connectFuture.promise.then(() => {
20151
20491
  this.onTrackAdded(mediaTrack, stream, receiver);
20152
- }, 50);
20492
+ });
20153
20493
  return;
20154
20494
  }
20155
20495
 
20156
20496
  if (this.state === ConnectionState.Disconnected) {
20157
20497
  livekitLogger.warn('skipping incoming track after Room disconnected');
20498
+ return;
20158
20499
  }
20159
20500
 
20160
20501
  const parts = unpackStreamId(stream.id);
@@ -20183,6 +20524,7 @@ class Room extends events.exports.EventEmitter {
20183
20524
 
20184
20525
  handleDisconnect() {
20185
20526
  let shouldStopTracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
20527
+ let reason = arguments.length > 1 ? arguments[1] : undefined;
20186
20528
 
20187
20529
  var _a;
20188
20530
 
@@ -20217,7 +20559,7 @@ class Room extends events.exports.EventEmitter {
20217
20559
  }
20218
20560
 
20219
20561
  this.setAndEmitConnectionState(ConnectionState.Disconnected);
20220
- this.emit(RoomEvent.Disconnected);
20562
+ this.emit(RoomEvent.Disconnected, reason);
20221
20563
  }
20222
20564
 
20223
20565
  handleParticipantDisconnected(sid, participant) {
@@ -20543,5 +20885,5 @@ async function createLocalScreenTracks(options) {
20543
20885
  return localTracks;
20544
20886
  }
20545
20887
 
20546
- export { AudioPresets, ConnectionError, ConnectionQuality, ConnectionState, DataPacket_Kind, EngineEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalVideoTrack, LogLevel, MediaDeviceFailure, Participant, ParticipantEvent, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, RoomState, ScreenSharePresets, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, detachTrack, protocolVersion, setLogExtension, setLogLevel, version };
20888
+ export { AudioPresets, ConnectionError, ConnectionQuality, ConnectionState, DataPacket_Kind, DisconnectReason, EngineEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalVideoTrack, LogLevel, MediaDeviceFailure, Participant, ParticipantEvent, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, RoomState, ScreenSharePresets, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, detachTrack, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, protocolVersion, setLogExtension, setLogLevel, version };
20547
20889
  //# sourceMappingURL=livekit-client.esm.mjs.map