livekit-client 2.15.16 → 2.16.1

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 (88) hide show
  1. package/README.md +105 -1
  2. package/dist/livekit-client.e2ee.worker.js +1 -1
  3. package/dist/livekit-client.e2ee.worker.js.map +1 -1
  4. package/dist/livekit-client.e2ee.worker.mjs +1 -0
  5. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  6. package/dist/livekit-client.esm.mjs +1175 -1341
  7. package/dist/livekit-client.esm.mjs.map +1 -1
  8. package/dist/livekit-client.umd.js +1 -1
  9. package/dist/livekit-client.umd.js.map +1 -1
  10. package/dist/src/api/SignalClient.d.ts.map +1 -1
  11. package/dist/src/api/utils.d.ts +1 -0
  12. package/dist/src/api/utils.d.ts.map +1 -1
  13. package/dist/src/connectionHelper/checks/turn.d.ts.map +1 -1
  14. package/dist/src/connectionHelper/checks/websocket.d.ts.map +1 -1
  15. package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
  16. package/dist/src/options.d.ts +4 -1
  17. package/dist/src/options.d.ts.map +1 -1
  18. package/dist/src/room/PCTransportManager.d.ts.map +1 -1
  19. package/dist/src/room/RTCEngine.d.ts +5 -0
  20. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  21. package/dist/src/room/RegionUrlProvider.d.ts +7 -0
  22. package/dist/src/room/RegionUrlProvider.d.ts.map +1 -1
  23. package/dist/src/room/Room.d.ts +1 -1
  24. package/dist/src/room/Room.d.ts.map +1 -1
  25. package/dist/src/room/data-stream/incoming/StreamReader.d.ts +3 -3
  26. package/dist/src/room/data-stream/incoming/StreamReader.d.ts.map +1 -1
  27. package/dist/src/room/data-stream/outgoing/OutgoingDataStreamManager.d.ts +0 -1
  28. package/dist/src/room/data-stream/outgoing/OutgoingDataStreamManager.d.ts.map +1 -1
  29. package/dist/src/room/errors.d.ts +74 -5
  30. package/dist/src/room/errors.d.ts.map +1 -1
  31. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  32. package/dist/src/room/participant/Participant.d.ts +1 -1
  33. package/dist/src/room/participant/Participant.d.ts.map +1 -1
  34. package/dist/src/room/token-source/TokenSource.d.ts +10 -2
  35. package/dist/src/room/token-source/TokenSource.d.ts.map +1 -1
  36. package/dist/src/room/track/LocalTrack.d.ts +0 -4
  37. package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
  38. package/dist/src/room/track/TrackPublication.d.ts.map +1 -1
  39. package/dist/src/room/track/create.d.ts.map +1 -1
  40. package/dist/src/room/track/processor/types.d.ts +0 -6
  41. package/dist/src/room/track/processor/types.d.ts.map +1 -1
  42. package/dist/src/room/types.d.ts +1 -1
  43. package/dist/src/room/types.d.ts.map +1 -1
  44. package/dist/src/room/utils.d.ts +4 -4
  45. package/dist/src/room/utils.d.ts.map +1 -1
  46. package/dist/src/test/mocks.d.ts.map +1 -1
  47. package/dist/ts4.2/api/utils.d.ts +1 -0
  48. package/dist/ts4.2/options.d.ts +4 -1
  49. package/dist/ts4.2/room/RTCEngine.d.ts +5 -0
  50. package/dist/ts4.2/room/RegionUrlProvider.d.ts +7 -0
  51. package/dist/ts4.2/room/Room.d.ts +1 -1
  52. package/dist/ts4.2/room/data-stream/incoming/StreamReader.d.ts +3 -3
  53. package/dist/ts4.2/room/data-stream/outgoing/OutgoingDataStreamManager.d.ts +0 -1
  54. package/dist/ts4.2/room/errors.d.ts +74 -5
  55. package/dist/ts4.2/room/participant/Participant.d.ts +1 -1
  56. package/dist/ts4.2/room/token-source/TokenSource.d.ts +1 -1
  57. package/dist/ts4.2/room/track/LocalTrack.d.ts +0 -4
  58. package/dist/ts4.2/room/track/processor/types.d.ts +0 -6
  59. package/dist/ts4.2/room/types.d.ts +1 -1
  60. package/dist/ts4.2/room/utils.d.ts +3 -3
  61. package/package.json +10 -6
  62. package/src/api/SignalClient.test.ts +12 -19
  63. package/src/api/SignalClient.ts +13 -28
  64. package/src/api/utils.ts +1 -1
  65. package/src/connectionHelper/checks/turn.ts +7 -0
  66. package/src/connectionHelper/checks/websocket.ts +40 -11
  67. package/src/e2ee/E2eeManager.ts +6 -4
  68. package/src/options.ts +4 -4
  69. package/src/room/PCTransport.ts +1 -1
  70. package/src/room/PCTransportManager.ts +4 -19
  71. package/src/room/RTCEngine.ts +64 -20
  72. package/src/room/RegionUrlProvider.test.ts +183 -9
  73. package/src/room/RegionUrlProvider.ts +97 -12
  74. package/src/room/Room.ts +25 -17
  75. package/src/room/data-stream/incoming/IncomingDataStreamManager.ts +2 -2
  76. package/src/room/data-stream/incoming/StreamReader.ts +5 -5
  77. package/src/room/data-stream/outgoing/OutgoingDataStreamManager.ts +0 -3
  78. package/src/room/errors.ts +144 -16
  79. package/src/room/participant/LocalParticipant.ts +12 -12
  80. package/src/room/participant/Participant.ts +2 -2
  81. package/src/room/token-source/TokenSource.ts +5 -1
  82. package/src/room/track/LocalTrack.ts +0 -4
  83. package/src/room/track/TrackPublication.ts +1 -1
  84. package/src/room/track/create.ts +6 -4
  85. package/src/room/track/processor/types.ts +0 -6
  86. package/src/room/types.ts +1 -1
  87. package/src/room/utils.ts +5 -4
  88. package/src/test/mocks.ts +0 -1
@@ -1,19 +1,4 @@
1
- function _mergeNamespaces(n, m) {
2
- m.forEach(function (e) {
3
- e && typeof e !== 'string' && !Array.isArray(e) && Object.keys(e).forEach(function (k) {
4
- if (k !== 'default' && !(k in n)) {
5
- var d = Object.getOwnPropertyDescriptor(e, k);
6
- Object.defineProperty(n, k, d.get ? d : {
7
- enumerable: true,
8
- get: function () { return e[k]; }
9
- });
10
- }
11
- });
12
- });
13
- return Object.freeze(n);
14
- }
15
-
16
- var e = Object.defineProperty;
1
+ function _mergeNamespaces(n, m){m.forEach(function(e){e&&typeof e!=='string'&&!Array.isArray(e)&&Object.keys(e).forEach(function(k){if(k!=='default'&&!(k in n)){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})});return Object.freeze(n);}var e = Object.defineProperty;
17
2
  var h = (i, s, t) => s in i ? e(i, s, {
18
3
  enumerable: true,
19
4
  configurable: true,
@@ -39,9 +24,7 @@ class _ {
39
24
  c = this._locking.then(() => s);
40
25
  return this._locking = this._locking.then(() => t), c;
41
26
  }
42
- }
43
-
44
- // Copyright 2021-2024 Buf Technologies, Inc.
27
+ }// Copyright 2021-2024 Buf Technologies, Inc.
45
28
  //
46
29
  // Licensed under the Apache License, Version 2.0 (the "License");
47
30
  // you may not use this file except in compliance with the License.
@@ -89,9 +72,7 @@ function assertFloat32(arg) {
89
72
  if (typeof arg !== "number") throw new Error("invalid float 32: " + typeof arg);
90
73
  if (!Number.isFinite(arg)) return;
91
74
  if (arg > FLOAT32_MAX || arg < FLOAT32_MIN) throw new Error("invalid float 32: " + arg); // eslint-disable-line @typescript-eslint/restrict-plus-operands -- we want the implicit conversion to string
92
- }
93
-
94
- // Copyright 2021-2024 Buf Technologies, Inc.
75
+ }// Copyright 2021-2024 Buf Technologies, Inc.
95
76
  //
96
77
  // Licensed under the Apache License, Version 2.0 (the "License");
97
78
  // you may not use this file except in compliance with the License.
@@ -178,9 +159,7 @@ function normalizeEnumValue(value) {
178
159
  return Object.assign(Object.assign({}, value), {
179
160
  localName: value.name
180
161
  });
181
- }
182
-
183
- // Copyright 2021-2024 Buf Technologies, Inc.
162
+ }// Copyright 2021-2024 Buf Technologies, Inc.
184
163
  //
185
164
  // Licensed under the Apache License, Version 2.0 (the "License");
186
165
  // you may not use this file except in compliance with the License.
@@ -312,9 +291,7 @@ class Message {
312
291
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-return
313
292
  return Object.getPrototypeOf(this).constructor;
314
293
  }
315
- }
316
-
317
- // Copyright 2021-2024 Buf Technologies, Inc.
294
+ }// Copyright 2021-2024 Buf Technologies, Inc.
318
295
  //
319
296
  // Licensed under the Apache License, Version 2.0 (the "License");
320
297
  // you may not use this file except in compliance with the License.
@@ -358,9 +335,7 @@ function makeMessageType(runtime, typeName, fields, opt) {
358
335
  }
359
336
  });
360
337
  return type;
361
- }
362
-
363
- // Copyright 2008 Google Inc. All rights reserved.
338
+ }// Copyright 2008 Google Inc. All rights reserved.
364
339
  //
365
340
  // Redistribution and use in source and binary forms, with or without
366
341
  // modification, are permitted provided that the following conditions are
@@ -676,9 +651,7 @@ function varint32read() {
676
651
  this.assertBounds();
677
652
  // Result can have 32 bits, convert it to unsigned
678
653
  return result >>> 0;
679
- }
680
-
681
- // Copyright 2021-2024 Buf Technologies, Inc.
654
+ }// Copyright 2021-2024 Buf Technologies, Inc.
682
655
  //
683
656
  // Licensed under the Apache License, Version 2.0 (the "License");
684
657
  // you may not use this file except in compliance with the License.
@@ -784,9 +757,7 @@ function makeInt64Support() {
784
757
  }
785
758
  };
786
759
  }
787
- const protoInt64 = makeInt64Support();
788
-
789
- // Copyright 2021-2024 Buf Technologies, Inc.
760
+ const protoInt64 = makeInt64Support();// Copyright 2021-2024 Buf Technologies, Inc.
790
761
  //
791
762
  // Licensed under the Apache License, Version 2.0 (the "License");
792
763
  // you may not use this file except in compliance with the License.
@@ -863,9 +834,7 @@ var LongType;
863
834
  * Field option `[jstype = JS_STRING]`.
864
835
  */
865
836
  LongType[LongType["STRING"] = 1] = "STRING";
866
- })(LongType || (LongType = {}));
867
-
868
- // Copyright 2021-2024 Buf Technologies, Inc.
837
+ })(LongType || (LongType = {}));// Copyright 2021-2024 Buf Technologies, Inc.
869
838
  //
870
839
  // Licensed under the Apache License, Version 2.0 (the "License");
871
840
  // you may not use this file except in compliance with the License.
@@ -962,9 +931,7 @@ function isScalarZeroValue(type, value) {
962
931
  return value == 0;
963
932
  // Loose comparison matches 0n, 0 and "0"
964
933
  }
965
- }
966
-
967
- // Copyright 2021-2024 Buf Technologies, Inc.
934
+ }// Copyright 2021-2024 Buf Technologies, Inc.
968
935
  //
969
936
  // Licensed under the Apache License, Version 2.0 (the "License");
970
937
  // you may not use this file except in compliance with the License.
@@ -1407,9 +1374,7 @@ class BinaryReader {
1407
1374
  string() {
1408
1375
  return this.textDecoder.decode(this.bytes());
1409
1376
  }
1410
- }
1411
-
1412
- // Copyright 2021-2024 Buf Technologies, Inc.
1377
+ }// Copyright 2021-2024 Buf Technologies, Inc.
1413
1378
  //
1414
1379
  // Licensed under the Apache License, Version 2.0 (the "License");
1415
1380
  // you may not use this file except in compliance with the License.
@@ -1488,9 +1453,7 @@ function filterUnknownFields(unknownFields, field) {
1488
1453
  return [];
1489
1454
  }
1490
1455
  return unknownFields.filter(uf => uf.no === field.no);
1491
- }
1492
-
1493
- // Copyright 2021-2024 Buf Technologies, Inc.
1456
+ }// Copyright 2021-2024 Buf Technologies, Inc.
1494
1457
  //
1495
1458
  // Licensed under the Apache License, Version 2.0 (the "License");
1496
1459
  // you may not use this file except in compliance with the License.
@@ -1617,9 +1580,7 @@ const protoBase64 = {
1617
1580
  }
1618
1581
  return base64;
1619
1582
  }
1620
- };
1621
-
1622
- // Copyright 2021-2024 Buf Technologies, Inc.
1583
+ };// Copyright 2021-2024 Buf Technologies, Inc.
1623
1584
  //
1624
1585
  // Licensed under the Apache License, Version 2.0 (the "License");
1625
1586
  // you may not use this file except in compliance with the License.
@@ -1699,9 +1660,7 @@ function hasExtension(message, extension) {
1699
1660
  }
1700
1661
  function assertExtendee(extension, message) {
1701
1662
  assert(extension.extendee.typeName == message.getType().typeName, "extension ".concat(extension.typeName, " can only be applied to message ").concat(extension.extendee.typeName));
1702
- }
1703
-
1704
- // Copyright 2021-2024 Buf Technologies, Inc.
1663
+ }// Copyright 2021-2024 Buf Technologies, Inc.
1705
1664
  //
1706
1665
  // Licensed under the Apache License, Version 2.0 (the "License");
1707
1666
  // you may not use this file except in compliance with the License.
@@ -1772,9 +1731,7 @@ function clearField(field, target) {
1772
1731
  break;
1773
1732
  }
1774
1733
  }
1775
- }
1776
-
1777
- // Copyright 2021-2024 Buf Technologies, Inc.
1734
+ }// Copyright 2021-2024 Buf Technologies, Inc.
1778
1735
  //
1779
1736
  // Licensed under the Apache License, Version 2.0 (the "License");
1780
1737
  // you may not use this file except in compliance with the License.
@@ -1817,9 +1774,7 @@ function isMessage(arg, type) {
1817
1774
  return false;
1818
1775
  }
1819
1776
  return type === undefined ? true : actualType.typeName == type.typeName;
1820
- }
1821
-
1822
- // Copyright 2021-2024 Buf Technologies, Inc.
1777
+ }// Copyright 2021-2024 Buf Technologies, Inc.
1823
1778
  //
1824
1779
  // Licensed under the Apache License, Version 2.0 (the "License");
1825
1780
  // you may not use this file except in compliance with the License.
@@ -1852,9 +1807,7 @@ function wrapField(type, value) {
1852
1807
  "google.protobuf.BoolValue": ScalarType.BOOL,
1853
1808
  "google.protobuf.StringValue": ScalarType.STRING,
1854
1809
  "google.protobuf.BytesValue": ScalarType.BYTES
1855
- });
1856
-
1857
- // Copyright 2021-2024 Buf Technologies, Inc.
1810
+ });// Copyright 2021-2024 Buf Technologies, Inc.
1858
1811
  //
1859
1812
  // Licensed under the Apache License, Version 2.0 (the "License");
1860
1813
  // you may not use this file except in compliance with the License.
@@ -2423,9 +2376,7 @@ function writeScalar$1(type, value) {
2423
2376
  assert(value instanceof Uint8Array);
2424
2377
  return protoBase64.enc(value);
2425
2378
  }
2426
- }
2427
-
2428
- // Copyright 2021-2024 Buf Technologies, Inc.
2379
+ }// Copyright 2021-2024 Buf Technologies, Inc.
2429
2380
  //
2430
2381
  // Licensed under the Apache License, Version 2.0 (the "License");
2431
2382
  // you may not use this file except in compliance with the License.
@@ -2832,9 +2783,7 @@ function scalarTypeInfo(type) {
2832
2783
  }
2833
2784
  const method = ScalarType[type].toLowerCase();
2834
2785
  return [wireType, method];
2835
- }
2836
-
2837
- // Copyright 2021-2024 Buf Technologies, Inc.
2786
+ }// Copyright 2021-2024 Buf Technologies, Inc.
2838
2787
  //
2839
2788
  // Licensed under the Apache License, Version 2.0 (the "License");
2840
2789
  // you may not use this file except in compliance with the License.
@@ -3068,9 +3017,7 @@ function cloneSingularField(value) {
3068
3017
  // converts any ArrayLike<number> to Uint8Array if necessary.
3069
3018
  function toU8Arr(input) {
3070
3019
  return input instanceof Uint8Array ? input : new Uint8Array(input);
3071
- }
3072
-
3073
- // Copyright 2021-2024 Buf Technologies, Inc.
3020
+ }// Copyright 2021-2024 Buf Technologies, Inc.
3074
3021
  //
3075
3022
  // Licensed under the Apache License, Version 2.0 (the "License");
3076
3023
  // you may not use this file except in compliance with the License.
@@ -3102,9 +3049,7 @@ function makeProtoRuntime(syntax, newFieldList, initFields) {
3102
3049
  return makeExtension(this, typeName, extendee, field);
3103
3050
  }
3104
3051
  };
3105
- }
3106
-
3107
- // Copyright 2021-2024 Buf Technologies, Inc.
3052
+ }// Copyright 2021-2024 Buf Technologies, Inc.
3108
3053
  //
3109
3054
  // Licensed under the Apache License, Version 2.0 (the "License");
3110
3055
  // you may not use this file except in compliance with the License.
@@ -3172,9 +3117,7 @@ class InternalFieldList {
3172
3117
  }
3173
3118
  return this.members;
3174
3119
  }
3175
- }
3176
-
3177
- // Copyright 2021-2024 Buf Technologies, Inc.
3120
+ }// Copyright 2021-2024 Buf Technologies, Inc.
3178
3121
  //
3179
3122
  // Licensed under the Apache License, Version 2.0 (the "License");
3180
3123
  // you may not use this file except in compliance with the License.
@@ -3289,9 +3232,7 @@ const safeObjectProperty = name => {
3289
3232
  return fallback(name);
3290
3233
  }
3291
3234
  return name;
3292
- };
3293
-
3294
- // Copyright 2021-2024 Buf Technologies, Inc.
3235
+ };// Copyright 2021-2024 Buf Technologies, Inc.
3295
3236
  //
3296
3237
  // Licensed under the Apache License, Version 2.0 (the "License");
3297
3238
  // you may not use this file except in compliance with the License.
@@ -3329,9 +3270,7 @@ class InternalOneofInfo {
3329
3270
  }
3330
3271
  return this._lookup[localName];
3331
3272
  }
3332
- }
3333
-
3334
- // Copyright 2021-2024 Buf Technologies, Inc.
3273
+ }// Copyright 2021-2024 Buf Technologies, Inc.
3335
3274
  //
3336
3275
  // Licensed under the Apache License, Version 2.0 (the "License");
3337
3276
  // you may not use this file except in compliance with the License.
@@ -3383,9 +3322,7 @@ function normalizeFieldInfos(fieldInfos, packedByDefault) {
3383
3322
  r.push(f);
3384
3323
  }
3385
3324
  return r;
3386
- }
3387
-
3388
- // Copyright 2021-2024 Buf Technologies, Inc.
3325
+ }// Copyright 2021-2024 Buf Technologies, Inc.
3389
3326
  //
3390
3327
  // Licensed under the Apache License, Version 2.0 (the "License");
3391
3328
  // you may not use this file except in compliance with the License.
@@ -3433,9 +3370,7 @@ target => {
3433
3370
  break;
3434
3371
  }
3435
3372
  }
3436
- });
3437
-
3438
- // Copyright 2021-2024 Buf Technologies, Inc.
3373
+ });// Copyright 2021-2024 Buf Technologies, Inc.
3439
3374
  //
3440
3375
  // Licensed under the Apache License, Version 2.0 (the "License");
3441
3376
  // you may not use this file except in compliance with the License.
@@ -3645,9 +3580,7 @@ Timestamp.fields = proto3.util.newFieldList(() => [{
3645
3580
  name: "nanos",
3646
3581
  kind: "scalar",
3647
3582
  T: 5 /* ScalarType.INT32 */
3648
- }]);
3649
-
3650
- const MetricsBatch = /* @__PURE__ */proto3.makeMessageType("livekit.MetricsBatch", () => [{
3583
+ }]);const MetricsBatch = /* @__PURE__ */proto3.makeMessageType("livekit.MetricsBatch", () => [{
3651
3584
  no: 1,
3652
3585
  name: "timestamp_ms",
3653
3586
  kind: "scalar",
@@ -7574,15 +7507,9 @@ const TokenSourceResponse = /* @__PURE__ */proto3.makeMessageType("livekit.Token
7574
7507
  kind: "scalar",
7575
7508
  T: 9
7576
7509
  /* ScalarType.STRING */
7577
- }]);
7578
-
7579
- function getDefaultExportFromCjs (x) {
7510
+ }]);function getDefaultExportFromCjs (x) {
7580
7511
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
7581
- }
7582
-
7583
- var loglevel$1 = {exports: {}};
7584
-
7585
- /*
7512
+ }var loglevel$1 = {exports: {}};/*
7586
7513
  * loglevel - https://github.com/pimterry/loglevel
7587
7514
  *
7588
7515
  * Copyright (c) 2013 Tim Perry
@@ -7902,11 +7829,7 @@ function requireLoglevel() {
7902
7829
  });
7903
7830
  })(loglevel$1);
7904
7831
  return loglevel$1.exports;
7905
- }
7906
-
7907
- var loglevelExports = requireLoglevel();
7908
-
7909
- var LogLevel;
7832
+ }var loglevelExports = requireLoglevel();var LogLevel;
7910
7833
  (function (LogLevel) {
7911
7834
  LogLevel[LogLevel["trace"] = 0] = "trace";
7912
7835
  LogLevel[LogLevel["debug"] = 1] = "debug";
@@ -7971,9 +7894,7 @@ function setLogExtension(extension, logger) {
7971
7894
  logR.setLevel(logR.getLevel());
7972
7895
  });
7973
7896
  }
7974
- const workerLogger = loglevelExports.getLogger('lk-e2ee');
7975
-
7976
- const maxRetryDelay = 7000;
7897
+ const workerLogger = loglevelExports.getLogger('lk-e2ee');const maxRetryDelay = 7000;
7977
7898
  const DEFAULT_RETRY_DELAYS_IN_MS = [0, 300, 2 * 2 * 300, 3 * 3 * 300, 4 * 4 * 300, maxRetryDelay, maxRetryDelay, maxRetryDelay, maxRetryDelay, maxRetryDelay];
7978
7899
  class DefaultReconnectPolicy {
7979
7900
  constructor(retryDelays) {
@@ -7985,9 +7906,7 @@ class DefaultReconnectPolicy {
7985
7906
  if (context.retryCount <= 1) return retryDelay;
7986
7907
  return retryDelay + Math.random() * 1000;
7987
7908
  }
7988
- }
7989
-
7990
- /******************************************************************************
7909
+ }/******************************************************************************
7991
7910
  Copyright (c) Microsoft Corporation.
7992
7911
 
7993
7912
  Permission to use, copy, modify, and/or distribute this software for any
@@ -8049,11 +7968,7 @@ function __asyncValues(o) {
8049
7968
  typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
8050
7969
  var e = new Error(message);
8051
7970
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
8052
- };
8053
-
8054
- var events = {exports: {}};
8055
-
8056
- var hasRequiredEvents;
7971
+ };var events = {exports: {}};var hasRequiredEvents;
8057
7972
  function requireEvents() {
8058
7973
  if (hasRequiredEvents) return events.exports;
8059
7974
  hasRequiredEvents = 1;
@@ -8434,11 +8349,7 @@ function requireEvents() {
8434
8349
  }
8435
8350
  }
8436
8351
  return events.exports;
8437
- }
8438
-
8439
- var eventsExports = requireEvents();
8440
-
8441
- /*
8352
+ }var eventsExports = requireEvents();/*
8442
8353
  * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
8443
8354
  *
8444
8355
  * Use of this source code is governed by a BSD-style license
@@ -8698,9 +8609,7 @@ function filterStats(result, track, outbound) {
8698
8609
  });
8699
8610
  });
8700
8611
  return filteredResult;
8701
- }
8702
-
8703
- /*
8612
+ }/*
8704
8613
  * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
8705
8614
  *
8706
8615
  * Use of this source code is governed by a BSD-style license
@@ -8877,9 +8786,7 @@ function shimGetUserMedia$2(window, browserDetails) {
8877
8786
  }, e => Promise.reject(shimError_(e))));
8878
8787
  };
8879
8788
  }
8880
- }
8881
-
8882
- /*
8789
+ }/*
8883
8790
  * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
8884
8791
  *
8885
8792
  * Use of this source code is governed by a BSD-style license
@@ -9429,22 +9336,7 @@ function fixNegotiationNeeded(window, browserDetails) {
9429
9336
  }
9430
9337
  return e;
9431
9338
  });
9432
- }
9433
-
9434
- var chromeShim = /*#__PURE__*/Object.freeze({
9435
- __proto__: null,
9436
- fixNegotiationNeeded: fixNegotiationNeeded,
9437
- shimAddTrackRemoveTrack: shimAddTrackRemoveTrack,
9438
- shimAddTrackRemoveTrackWithNative: shimAddTrackRemoveTrackWithNative,
9439
- shimGetSendersWithDtmf: shimGetSendersWithDtmf,
9440
- shimGetUserMedia: shimGetUserMedia$2,
9441
- shimMediaStream: shimMediaStream,
9442
- shimOnTrack: shimOnTrack$1,
9443
- shimPeerConnection: shimPeerConnection$1,
9444
- shimSenderReceiverGetStats: shimSenderReceiverGetStats
9445
- });
9446
-
9447
- /*
9339
+ }var chromeShim=/*#__PURE__*/Object.freeze({__proto__:null,fixNegotiationNeeded:fixNegotiationNeeded,shimAddTrackRemoveTrack:shimAddTrackRemoveTrack,shimAddTrackRemoveTrackWithNative:shimAddTrackRemoveTrackWithNative,shimGetSendersWithDtmf:shimGetSendersWithDtmf,shimGetUserMedia:shimGetUserMedia$2,shimMediaStream:shimMediaStream,shimOnTrack:shimOnTrack$1,shimPeerConnection:shimPeerConnection$1,shimSenderReceiverGetStats:shimSenderReceiverGetStats});/*
9448
9340
  * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
9449
9341
  *
9450
9342
  * Use of this source code is governed by a BSD-style license
@@ -9497,9 +9389,7 @@ function shimGetUserMedia$1(window, browserDetails) {
9497
9389
  };
9498
9390
  }
9499
9391
  }
9500
- }
9501
-
9502
- /*
9392
+ }/*
9503
9393
  * Copyright (c) 2018 The adapter.js project authors. All Rights Reserved.
9504
9394
  *
9505
9395
  * Use of this source code is governed by a BSD-style license
@@ -9532,9 +9422,7 @@ function shimGetDisplayMedia(window, preferredMediaSource) {
9532
9422
  }
9533
9423
  return window.navigator.mediaDevices.getUserMedia(constraints);
9534
9424
  };
9535
- }
9536
-
9537
- /*
9425
+ }/*
9538
9426
  * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
9539
9427
  *
9540
9428
  * Use of this source code is governed by a BSD-style license
@@ -9798,25 +9686,7 @@ function shimCreateAnswer(window) {
9798
9686
  }
9799
9687
  return origCreateAnswer.apply(this, arguments);
9800
9688
  };
9801
- }
9802
-
9803
- var firefoxShim = /*#__PURE__*/Object.freeze({
9804
- __proto__: null,
9805
- shimAddTransceiver: shimAddTransceiver,
9806
- shimCreateAnswer: shimCreateAnswer,
9807
- shimCreateOffer: shimCreateOffer,
9808
- shimGetDisplayMedia: shimGetDisplayMedia,
9809
- shimGetParameters: shimGetParameters,
9810
- shimGetUserMedia: shimGetUserMedia$1,
9811
- shimOnTrack: shimOnTrack,
9812
- shimPeerConnection: shimPeerConnection,
9813
- shimRTCDataChannel: shimRTCDataChannel,
9814
- shimReceiverGetStats: shimReceiverGetStats,
9815
- shimRemoveStream: shimRemoveStream,
9816
- shimSenderGetStats: shimSenderGetStats
9817
- });
9818
-
9819
- /*
9689
+ }var firefoxShim=/*#__PURE__*/Object.freeze({__proto__:null,shimAddTransceiver:shimAddTransceiver,shimCreateAnswer:shimCreateAnswer,shimCreateOffer:shimCreateOffer,shimGetDisplayMedia:shimGetDisplayMedia,shimGetParameters:shimGetParameters,shimGetUserMedia:shimGetUserMedia$1,shimOnTrack:shimOnTrack,shimPeerConnection:shimPeerConnection,shimRTCDataChannel:shimRTCDataChannel,shimReceiverGetStats:shimReceiverGetStats,shimRemoveStream:shimRemoveStream,shimSenderGetStats:shimSenderGetStats});/*
9820
9690
  * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
9821
9691
  *
9822
9692
  * Use of this source code is governed by a BSD-style license
@@ -10131,24 +10001,7 @@ function shimAudioContext(window) {
10131
10001
  return;
10132
10002
  }
10133
10003
  window.AudioContext = window.webkitAudioContext;
10134
- }
10135
-
10136
- var safariShim = /*#__PURE__*/Object.freeze({
10137
- __proto__: null,
10138
- shimAudioContext: shimAudioContext,
10139
- shimCallbacksAPI: shimCallbacksAPI,
10140
- shimConstraints: shimConstraints,
10141
- shimCreateOfferLegacy: shimCreateOfferLegacy,
10142
- shimGetUserMedia: shimGetUserMedia,
10143
- shimLocalStreamsAPI: shimLocalStreamsAPI,
10144
- shimRTCIceServerUrls: shimRTCIceServerUrls,
10145
- shimRemoteStreamsAPI: shimRemoteStreamsAPI,
10146
- shimTrackEventTransceiver: shimTrackEventTransceiver
10147
- });
10148
-
10149
- var sdp$1 = {exports: {}};
10150
-
10151
- /* eslint-env node */
10004
+ }var safariShim=/*#__PURE__*/Object.freeze({__proto__:null,shimAudioContext:shimAudioContext,shimCallbacksAPI:shimCallbacksAPI,shimConstraints:shimConstraints,shimCreateOfferLegacy:shimCreateOfferLegacy,shimGetUserMedia:shimGetUserMedia,shimLocalStreamsAPI:shimLocalStreamsAPI,shimRTCIceServerUrls:shimRTCIceServerUrls,shimRemoteStreamsAPI:shimRemoteStreamsAPI,shimTrackEventTransceiver:shimTrackEventTransceiver});var sdp$1 = {exports: {}};/* eslint-env node */
10152
10005
  var hasRequiredSdp;
10153
10006
  function requireSdp() {
10154
10007
  if (hasRequiredSdp) return sdp$1.exports;
@@ -10893,17 +10746,8 @@ function requireSdp() {
10893
10746
  }
10894
10747
  })(sdp$1);
10895
10748
  return sdp$1.exports;
10896
- }
10897
-
10898
- var sdpExports = requireSdp();
10899
- var SDPUtils = /*@__PURE__*/getDefaultExportFromCjs(sdpExports);
10900
-
10901
- var sdp = /*#__PURE__*/_mergeNamespaces({
10902
- __proto__: null,
10903
- default: SDPUtils
10904
- }, [sdpExports]);
10905
-
10906
- /*
10749
+ }var sdpExports = requireSdp();
10750
+ var SDPUtils = /*@__PURE__*/getDefaultExportFromCjs(sdpExports);var sdp=/*#__PURE__*/_mergeNamespaces({__proto__:null,default:SDPUtils},[sdpExports]);/*
10907
10751
  * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
10908
10752
  *
10909
10753
  * Use of this source code is governed by a BSD-style license
@@ -11317,21 +11161,7 @@ function shimParameterlessSetLocalDescription(window, browserDetails) {
11317
11161
  const func = desc.type === 'offer' ? this.createOffer : this.createAnswer;
11318
11162
  return func.apply(this).then(d => nativeSetLocalDescription.apply(this, [d]));
11319
11163
  };
11320
- }
11321
-
11322
- var commonShim = /*#__PURE__*/Object.freeze({
11323
- __proto__: null,
11324
- removeExtmapAllowMixed: removeExtmapAllowMixed,
11325
- shimAddIceCandidateNullOrEmpty: shimAddIceCandidateNullOrEmpty,
11326
- shimConnectionState: shimConnectionState,
11327
- shimMaxMessageSize: shimMaxMessageSize,
11328
- shimParameterlessSetLocalDescription: shimParameterlessSetLocalDescription,
11329
- shimRTCIceCandidate: shimRTCIceCandidate,
11330
- shimRTCIceCandidateRelayProtocol: shimRTCIceCandidateRelayProtocol,
11331
- shimSendThrowTypeError: shimSendThrowTypeError
11332
- });
11333
-
11334
- /*
11164
+ }var commonShim=/*#__PURE__*/Object.freeze({__proto__:null,removeExtmapAllowMixed:removeExtmapAllowMixed,shimAddIceCandidateNullOrEmpty:shimAddIceCandidateNullOrEmpty,shimConnectionState:shimConnectionState,shimMaxMessageSize:shimMaxMessageSize,shimParameterlessSetLocalDescription:shimParameterlessSetLocalDescription,shimRTCIceCandidate:shimRTCIceCandidate,shimRTCIceCandidateRelayProtocol:shimRTCIceCandidateRelayProtocol,shimSendThrowTypeError:shimSendThrowTypeError});/*
11335
11165
  * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
11336
11166
  *
11337
11167
  * Use of this source code is governed by a BSD-style license
@@ -11454,9 +11284,7 @@ function adapterFactory() {
11454
11284
  break;
11455
11285
  }
11456
11286
  return adapter;
11457
- }
11458
-
11459
- /*
11287
+ }/*
11460
11288
  * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
11461
11289
  *
11462
11290
  * Use of this source code is governed by a BSD-style license
@@ -11467,296 +11295,85 @@ function adapterFactory() {
11467
11295
 
11468
11296
  adapterFactory({
11469
11297
  window: typeof window === 'undefined' ? undefined : window
11470
- });
11471
-
11472
- const ENCRYPTION_ALGORITHM = 'AES-GCM';
11473
- // How many consecutive frames can fail decrypting before a particular key gets marked as invalid
11474
- const DECRYPTION_FAILURE_TOLERANCE = 10;
11475
- // flag set to indicate that e2ee has been setup for sender/receiver;
11476
- const E2EE_FLAG = 'lk_e2ee';
11477
- const SALT = 'LKFrameEncryptionKey';
11478
- const KEY_PROVIDER_DEFAULTS = {
11479
- sharedKey: false,
11480
- ratchetSalt: SALT,
11481
- ratchetWindowSize: 8,
11482
- failureTolerance: DECRYPTION_FAILURE_TOLERANCE,
11483
- keyringSize: 16
11484
- };
11485
-
11486
- var KeyProviderEvent;
11487
- (function (KeyProviderEvent) {
11488
- KeyProviderEvent["SetKey"] = "setKey";
11489
- /** Event for requesting to ratchet the key used to encrypt the stream */
11490
- KeyProviderEvent["RatchetRequest"] = "ratchetRequest";
11491
- /** Emitted when a key is ratcheted. Could be after auto-ratcheting on decryption failure or
11492
- * following a `RatchetRequest`, will contain the ratcheted key material */
11493
- KeyProviderEvent["KeyRatcheted"] = "keyRatcheted";
11494
- })(KeyProviderEvent || (KeyProviderEvent = {}));
11495
- var KeyHandlerEvent;
11496
- (function (KeyHandlerEvent) {
11497
- /** Emitted when a key has been ratcheted. Is emitted when any key has been ratcheted
11498
- * i.e. when the FrameCryptor tried to ratchet when decryption is failing */
11499
- KeyHandlerEvent["KeyRatcheted"] = "keyRatcheted";
11500
- })(KeyHandlerEvent || (KeyHandlerEvent = {}));
11501
- var EncryptionEvent;
11502
- (function (EncryptionEvent) {
11503
- EncryptionEvent["ParticipantEncryptionStatusChanged"] = "participantEncryptionStatusChanged";
11504
- EncryptionEvent["EncryptionError"] = "encryptionError";
11505
- })(EncryptionEvent || (EncryptionEvent = {}));
11506
- var CryptorEvent;
11507
- (function (CryptorEvent) {
11508
- CryptorEvent["Error"] = "cryptorError";
11509
- })(CryptorEvent || (CryptorEvent = {}));
11510
-
11511
- function isE2EESupported() {
11512
- return isInsertableStreamSupported() || isScriptTransformSupported();
11513
- }
11514
- function isScriptTransformSupported() {
11515
- // @ts-ignore
11516
- return typeof window.RTCRtpScriptTransform !== 'undefined';
11517
- }
11518
- function isInsertableStreamSupported() {
11519
- return typeof window.RTCRtpSender !== 'undefined' &&
11520
- // @ts-ignore
11521
- typeof window.RTCRtpSender.prototype.createEncodedStreams !== 'undefined';
11522
- }
11523
- function isVideoFrame(frame) {
11524
- return 'type' in frame;
11298
+ });// tiny, simplified version of https://github.com/lancedikson/bowser/blob/master/src/parser-browsers.js
11299
+ // reduced to only differentiate Chrome(ium) based browsers / Firefox / Safari
11300
+ const commonVersionIdentifier = /version\/(\d+(\.?_?\d+)+)/i;
11301
+ let browserDetails;
11302
+ /**
11303
+ * @internal
11304
+ */
11305
+ function getBrowser(userAgent) {
11306
+ let force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
11307
+ if (typeof userAgent === 'undefined' && typeof navigator === 'undefined') {
11308
+ return;
11309
+ }
11310
+ const ua = (userAgent !== null && userAgent !== void 0 ? userAgent : navigator.userAgent).toLowerCase();
11311
+ if (browserDetails === undefined || force) {
11312
+ const browser = browsersList.find(_ref => {
11313
+ let {
11314
+ test
11315
+ } = _ref;
11316
+ return test.test(ua);
11317
+ });
11318
+ browserDetails = browser === null || browser === void 0 ? void 0 : browser.describe(ua);
11319
+ }
11320
+ return browserDetails;
11525
11321
  }
11526
- function importKey(keyBytes_1) {
11527
- return __awaiter(this, arguments, void 0, function (keyBytes) {
11528
- let algorithm = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
11529
- name: ENCRYPTION_ALGORITHM
11322
+ const browsersList = [{
11323
+ test: /firefox|iceweasel|fxios/i,
11324
+ describe(ua) {
11325
+ const browser = {
11326
+ name: 'Firefox',
11327
+ version: getMatch(/(?:firefox|iceweasel|fxios)[\s/](\d+(\.?_?\d+)+)/i, ua),
11328
+ os: ua.toLowerCase().includes('fxios') ? 'iOS' : undefined,
11329
+ osVersion: getOSVersion(ua)
11530
11330
  };
11531
- let usage = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'encrypt';
11532
- return function* () {
11533
- // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey
11534
- return crypto.subtle.importKey('raw', keyBytes, algorithm, false, usage === 'derive' ? ['deriveBits', 'deriveKey'] : ['encrypt', 'decrypt']);
11535
- }();
11536
- });
11331
+ return browser;
11332
+ }
11333
+ }, {
11334
+ test: /chrom|crios|crmo/i,
11335
+ describe(ua) {
11336
+ const browser = {
11337
+ name: 'Chrome',
11338
+ version: getMatch(/(?:chrome|chromium|crios|crmo)\/(\d+(\.?_?\d+)+)/i, ua),
11339
+ os: ua.toLowerCase().includes('crios') ? 'iOS' : undefined,
11340
+ osVersion: getOSVersion(ua)
11341
+ };
11342
+ return browser;
11343
+ }
11344
+ }, /* Safari */
11345
+ {
11346
+ test: /safari|applewebkit/i,
11347
+ describe(ua) {
11348
+ const browser = {
11349
+ name: 'Safari',
11350
+ version: getMatch(commonVersionIdentifier, ua),
11351
+ os: ua.includes('mobile/') ? 'iOS' : 'macOS',
11352
+ osVersion: getOSVersion(ua)
11353
+ };
11354
+ return browser;
11355
+ }
11356
+ }];
11357
+ function getMatch(exp, ua) {
11358
+ let id = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
11359
+ const match = ua.match(exp);
11360
+ return match && match.length >= id && match[id] || '';
11537
11361
  }
11538
- function createKeyMaterialFromString(password) {
11539
- return __awaiter(this, void 0, void 0, function* () {
11540
- let enc = new TextEncoder();
11541
- const keyMaterial = yield crypto.subtle.importKey('raw', enc.encode(password), {
11542
- name: 'PBKDF2'
11543
- }, false, ['deriveBits', 'deriveKey']);
11544
- return keyMaterial;
11545
- });
11362
+ function getOSVersion(ua) {
11363
+ return ua.includes('mac os') ? getMatch(/\(.+?(\d+_\d+(:?_\d+)?)/, ua, 1).replace(/_/g, '.') : undefined;
11364
+ }var version$1 = "2.16.1";const version = version$1;
11365
+ const protocolVersion = 16;class LivekitError extends Error {
11366
+ constructor(code, message) {
11367
+ super(message || 'an error has occured');
11368
+ this.name = 'LiveKitError';
11369
+ this.code = code;
11370
+ }
11546
11371
  }
11547
- function createKeyMaterialFromBuffer(cryptoBuffer) {
11548
- return __awaiter(this, void 0, void 0, function* () {
11549
- const keyMaterial = yield crypto.subtle.importKey('raw', cryptoBuffer, 'HKDF', false, ['deriveBits', 'deriveKey']);
11550
- return keyMaterial;
11551
- });
11552
- }
11553
- function getAlgoOptions(algorithmName, salt) {
11554
- const textEncoder = new TextEncoder();
11555
- const encodedSalt = textEncoder.encode(salt);
11556
- switch (algorithmName) {
11557
- case 'HKDF':
11558
- return {
11559
- name: 'HKDF',
11560
- salt: encodedSalt,
11561
- hash: 'SHA-256',
11562
- info: new ArrayBuffer(128)
11563
- };
11564
- case 'PBKDF2':
11565
- {
11566
- return {
11567
- name: 'PBKDF2',
11568
- salt: encodedSalt,
11569
- hash: 'SHA-256',
11570
- iterations: 100000
11571
- };
11572
- }
11573
- default:
11574
- throw new Error("algorithm ".concat(algorithmName, " is currently unsupported"));
11575
- }
11576
- }
11577
- /**
11578
- * Derives a set of keys from the master key.
11579
- * See https://tools.ietf.org/html/draft-omara-sframe-00#section-4.3.1
11580
- */
11581
- function deriveKeys(material, salt) {
11582
- return __awaiter(this, void 0, void 0, function* () {
11583
- const algorithmOptions = getAlgoOptions(material.algorithm.name, salt);
11584
- // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveKey#HKDF
11585
- // https://developer.mozilla.org/en-US/docs/Web/API/HkdfParams
11586
- const encryptionKey = yield crypto.subtle.deriveKey(algorithmOptions, material, {
11587
- name: ENCRYPTION_ALGORITHM,
11588
- length: 128
11589
- }, false, ['encrypt', 'decrypt']);
11590
- return {
11591
- material,
11592
- encryptionKey
11593
- };
11594
- });
11595
- }
11596
- function createE2EEKey() {
11597
- return window.crypto.getRandomValues(new Uint8Array(32));
11598
- }
11599
- /**
11600
- * Ratchets a key. See
11601
- * https://tools.ietf.org/html/draft-omara-sframe-00#section-4.3.5.1
11602
- */
11603
- function ratchet(material, salt) {
11604
- return __awaiter(this, void 0, void 0, function* () {
11605
- const algorithmOptions = getAlgoOptions(material.algorithm.name, salt);
11606
- // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveBits
11607
- return crypto.subtle.deriveBits(algorithmOptions, material, 256);
11608
- });
11609
- }
11610
- function needsRbspUnescaping(frameData) {
11611
- for (var i = 0; i < frameData.length - 3; i++) {
11612
- if (frameData[i] == 0 && frameData[i + 1] == 0 && frameData[i + 2] == 3) return true;
11613
- }
11614
- return false;
11615
- }
11616
- function parseRbsp(stream) {
11617
- const dataOut = [];
11618
- var length = stream.length;
11619
- for (var i = 0; i < stream.length;) {
11620
- // Be careful about over/underflow here. byte_length_ - 3 can underflow, and
11621
- // i + 3 can overflow, but byte_length_ - i can't, because i < byte_length_
11622
- // above, and that expression will produce the number of bytes left in
11623
- // the stream including the byte at i.
11624
- if (length - i >= 3 && !stream[i] && !stream[i + 1] && stream[i + 2] == 3) {
11625
- // Two rbsp bytes.
11626
- dataOut.push(stream[i++]);
11627
- dataOut.push(stream[i++]);
11628
- // Skip the emulation byte.
11629
- i++;
11630
- } else {
11631
- // Single rbsp byte.
11632
- dataOut.push(stream[i++]);
11633
- }
11634
- }
11635
- return new Uint8Array(dataOut);
11636
- }
11637
- const kZerosInStartSequence = 2;
11638
- const kEmulationByte = 3;
11639
- function writeRbsp(data_in) {
11640
- const dataOut = [];
11641
- var numConsecutiveZeros = 0;
11642
- for (var i = 0; i < data_in.length; ++i) {
11643
- var byte = data_in[i];
11644
- if (byte <= kEmulationByte && numConsecutiveZeros >= kZerosInStartSequence) {
11645
- // Need to escape.
11646
- dataOut.push(kEmulationByte);
11647
- numConsecutiveZeros = 0;
11648
- }
11649
- dataOut.push(byte);
11650
- if (byte == 0) {
11651
- ++numConsecutiveZeros;
11652
- } else {
11653
- numConsecutiveZeros = 0;
11654
- }
11655
- }
11656
- return new Uint8Array(dataOut);
11657
- }
11658
- function asEncryptablePacket(packet) {
11659
- var _a, _b, _c, _d, _e;
11660
- 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') {
11661
- return new EncryptedPacketPayload({
11662
- value: packet.value
11663
- });
11664
- }
11665
- return undefined;
11666
- }
11667
-
11668
- /**
11669
- * @experimental
11670
- */
11671
- class BaseKeyProvider extends eventsExports.EventEmitter {
11672
- constructor() {
11673
- let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
11674
- super();
11675
- /**
11676
- * Callback being invoked after a key has been ratcheted.
11677
- * Can happen when:
11678
- * - A decryption failure occurs and the key is auto-ratcheted
11679
- * - A ratchet request is sent (see {@link ratchetKey()})
11680
- * @param ratchetResult Contains the ratcheted chain key (exportable to other participants) and the derived new key material.
11681
- * @param participantId
11682
- * @param keyIndex
11683
- */
11684
- this.onKeyRatcheted = (ratchetResult, participantId, keyIndex) => {
11685
- livekitLogger.debug('key ratcheted event received', {
11686
- ratchetResult,
11687
- participantId,
11688
- keyIndex
11689
- });
11690
- };
11691
- this.keyInfoMap = new Map();
11692
- this.options = Object.assign(Object.assign({}, KEY_PROVIDER_DEFAULTS), options);
11693
- this.on(KeyProviderEvent.KeyRatcheted, this.onKeyRatcheted);
11694
- }
11695
- /**
11696
- * callback to invoke once a key has been set for a participant
11697
- * @param key
11698
- * @param participantIdentity
11699
- * @param keyIndex
11700
- */
11701
- onSetEncryptionKey(key, participantIdentity, keyIndex) {
11702
- const keyInfo = {
11703
- key,
11704
- participantIdentity,
11705
- keyIndex
11706
- };
11707
- if (!this.options.sharedKey && !participantIdentity) {
11708
- throw new Error('participant identity needs to be passed for encryption key if sharedKey option is false');
11709
- }
11710
- this.keyInfoMap.set("".concat(participantIdentity !== null && participantIdentity !== void 0 ? participantIdentity : 'shared', "-").concat(keyIndex !== null && keyIndex !== void 0 ? keyIndex : 0), keyInfo);
11711
- this.emit(KeyProviderEvent.SetKey, keyInfo);
11712
- }
11713
- getKeys() {
11714
- return Array.from(this.keyInfoMap.values());
11715
- }
11716
- getOptions() {
11717
- return this.options;
11718
- }
11719
- ratchetKey(participantIdentity, keyIndex) {
11720
- this.emit(KeyProviderEvent.RatchetRequest, participantIdentity, keyIndex);
11721
- }
11722
- }
11723
- /**
11724
- * A basic KeyProvider implementation intended for a single shared
11725
- * passphrase between all participants
11726
- * @experimental
11727
- */
11728
- class ExternalE2EEKeyProvider extends BaseKeyProvider {
11372
+ class SimulatedError extends LivekitError {
11729
11373
  constructor() {
11730
- let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
11731
- const opts = Object.assign(Object.assign({}, options), {
11732
- sharedKey: true,
11733
- // for a shared key provider failing to decrypt for a specific participant
11734
- // should not mark the key as invalid, so we accept wrong keys forever
11735
- // and won't try to auto-ratchet
11736
- ratchetWindowSize: 0,
11737
- failureTolerance: -1
11738
- });
11739
- super(opts);
11740
- }
11741
- /**
11742
- * Accepts a passphrase that's used to create the crypto keys.
11743
- * When passing in a string, PBKDF2 is used.
11744
- * When passing in an Array buffer of cryptographically random numbers, HKDF is being used. (recommended)
11745
- * @param key
11746
- */
11747
- setKey(key) {
11748
- return __awaiter(this, void 0, void 0, function* () {
11749
- const derivedKey = typeof key === 'string' ? yield createKeyMaterialFromString(key) : yield createKeyMaterialFromBuffer(key);
11750
- this.onSetEncryptionKey(derivedKey);
11751
- });
11752
- }
11753
- }
11754
-
11755
- class LivekitError extends Error {
11756
- constructor(code, message) {
11757
- super(message || 'an error has occured');
11758
- this.name = 'LiveKitError';
11759
- this.code = code;
11374
+ let message = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'Simulated failure';
11375
+ super(-1, message);
11376
+ this.name = 'simulated';
11760
11377
  }
11761
11378
  }
11762
11379
  var ConnectionErrorReason;
@@ -11767,6 +11384,7 @@ var ConnectionErrorReason;
11767
11384
  ConnectionErrorReason[ConnectionErrorReason["Cancelled"] = 3] = "Cancelled";
11768
11385
  ConnectionErrorReason[ConnectionErrorReason["LeaveRequest"] = 4] = "LeaveRequest";
11769
11386
  ConnectionErrorReason[ConnectionErrorReason["Timeout"] = 5] = "Timeout";
11387
+ ConnectionErrorReason[ConnectionErrorReason["WebSocket"] = 6] = "WebSocket";
11770
11388
  })(ConnectionErrorReason || (ConnectionErrorReason = {}));
11771
11389
  class ConnectionError extends LivekitError {
11772
11390
  constructor(message, reason, status, context) {
@@ -11777,6 +11395,27 @@ class ConnectionError extends LivekitError {
11777
11395
  this.context = context;
11778
11396
  this.reasonName = ConnectionErrorReason[reason];
11779
11397
  }
11398
+ static notAllowed(message, status, context) {
11399
+ return new ConnectionError(message, ConnectionErrorReason.NotAllowed, status, context);
11400
+ }
11401
+ static timeout(message) {
11402
+ return new ConnectionError(message, ConnectionErrorReason.Timeout);
11403
+ }
11404
+ static leaveRequest(message, context) {
11405
+ return new ConnectionError(message, ConnectionErrorReason.LeaveRequest, undefined, context);
11406
+ }
11407
+ static internal(message, context) {
11408
+ return new ConnectionError(message, ConnectionErrorReason.InternalError, undefined, context);
11409
+ }
11410
+ static cancelled(message) {
11411
+ return new ConnectionError(message, ConnectionErrorReason.Cancelled);
11412
+ }
11413
+ static serverUnreachable(message, status) {
11414
+ return new ConnectionError(message, ConnectionErrorReason.ServerUnreachable, status);
11415
+ }
11416
+ static websocket(message, status, reason) {
11417
+ return new ConnectionError(message, ConnectionErrorReason.WebSocket, status, reason);
11418
+ }
11780
11419
  }
11781
11420
  class DeviceUnsupportedError extends LivekitError {
11782
11421
  constructor(message) {
@@ -11824,6 +11463,7 @@ class PublishTrackError extends LivekitError {
11824
11463
  class SignalRequestError extends LivekitError {
11825
11464
  constructor(message, reason) {
11826
11465
  super(15, message);
11466
+ this.name = 'SignalRequestError';
11827
11467
  this.reason = reason;
11828
11468
  this.reasonName = typeof reason === 'string' ? reason : RequestResponse_Reason[reason];
11829
11469
  }
@@ -11854,6 +11494,12 @@ class DataStreamError extends LivekitError {
11854
11494
  this.reasonName = DataStreamErrorReason[reason];
11855
11495
  }
11856
11496
  }
11497
+ class SignalReconnectError extends LivekitError {
11498
+ constructor(message) {
11499
+ super(18, message);
11500
+ this.name = 'SignalReconnectError';
11501
+ }
11502
+ }
11857
11503
  var MediaDeviceFailure;
11858
11504
  (function (MediaDeviceFailure) {
11859
11505
  // user rejected permissions
@@ -11880,25 +11526,26 @@ var MediaDeviceFailure;
11880
11526
  }
11881
11527
  }
11882
11528
  MediaDeviceFailure.getFailure = getFailure;
11883
- })(MediaDeviceFailure || (MediaDeviceFailure = {}));
11884
-
11885
- var CryptorErrorReason;
11886
- (function (CryptorErrorReason) {
11887
- CryptorErrorReason[CryptorErrorReason["InvalidKey"] = 0] = "InvalidKey";
11888
- CryptorErrorReason[CryptorErrorReason["MissingKey"] = 1] = "MissingKey";
11889
- CryptorErrorReason[CryptorErrorReason["InternalError"] = 2] = "InternalError";
11890
- })(CryptorErrorReason || (CryptorErrorReason = {}));
11891
- class CryptorError extends LivekitError {
11892
- constructor(message) {
11893
- let reason = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : CryptorErrorReason.InternalError;
11894
- let participantIdentity = arguments.length > 2 ? arguments[2] : undefined;
11895
- super(40, message);
11896
- this.reason = reason;
11897
- this.participantIdentity = participantIdentity;
11898
- }
11899
- }
11900
-
11901
- /**
11529
+ })(MediaDeviceFailure || (MediaDeviceFailure = {}));/**
11530
+ * Timers that can be overridden with platform specific implementations
11531
+ * that ensure that they are fired. These should be used when it is critical
11532
+ * that the timer fires on time.
11533
+ */
11534
+ class CriticalTimers {}
11535
+ CriticalTimers.setTimeout = function () {
11536
+ return setTimeout(...arguments);
11537
+ };
11538
+ CriticalTimers.setInterval =
11539
+ // eslint-disable-next-line @typescript-eslint/no-implied-eval
11540
+ function () {
11541
+ return setInterval(...arguments);
11542
+ };
11543
+ CriticalTimers.clearTimeout = function () {
11544
+ return clearTimeout(...arguments);
11545
+ };
11546
+ CriticalTimers.clearInterval = function () {
11547
+ return clearInterval(...arguments);
11548
+ };/**
11902
11549
  * Events are the primary way LiveKit notifies your application of changes.
11903
11550
  *
11904
11551
  * The following are events emitted by [[Room]], listen to room events like
@@ -12516,9 +12163,7 @@ var TrackEvent;
12516
12163
  * @internal
12517
12164
  */
12518
12165
  TrackEvent["PreConnectBufferFlushed"] = "preConnectBufferFlushed";
12519
- })(TrackEvent || (TrackEvent = {}));
12520
-
12521
- function cloneDeep(value) {
12166
+ })(TrackEvent || (TrackEvent = {}));function cloneDeep(value) {
12522
12167
  if (typeof value === 'undefined') {
12523
12168
  return value;
12524
12169
  }
@@ -12531,103 +12176,443 @@ function cloneDeep(value) {
12531
12176
  } else {
12532
12177
  return JSON.parse(JSON.stringify(value));
12533
12178
  }
12534
- }
12535
-
12536
- // tiny, simplified version of https://github.com/lancedikson/bowser/blob/master/src/parser-browsers.js
12537
- // reduced to only differentiate Chrome(ium) based browsers / Firefox / Safari
12538
- const commonVersionIdentifier = /version\/(\d+(\.?_?\d+)+)/i;
12539
- let browserDetails;
12179
+ }class VideoPreset {
12180
+ constructor(widthOrOptions, height, maxBitrate, maxFramerate, priority) {
12181
+ if (typeof widthOrOptions === 'object') {
12182
+ this.width = widthOrOptions.width;
12183
+ this.height = widthOrOptions.height;
12184
+ this.aspectRatio = widthOrOptions.aspectRatio;
12185
+ this.encoding = {
12186
+ maxBitrate: widthOrOptions.maxBitrate,
12187
+ maxFramerate: widthOrOptions.maxFramerate,
12188
+ priority: widthOrOptions.priority
12189
+ };
12190
+ } else if (height !== undefined && maxBitrate !== undefined) {
12191
+ this.width = widthOrOptions;
12192
+ this.height = height;
12193
+ this.aspectRatio = widthOrOptions / height;
12194
+ this.encoding = {
12195
+ maxBitrate,
12196
+ maxFramerate,
12197
+ priority
12198
+ };
12199
+ } else {
12200
+ throw new TypeError('Unsupported options: provide at least width, height and maxBitrate');
12201
+ }
12202
+ }
12203
+ get resolution() {
12204
+ return {
12205
+ width: this.width,
12206
+ height: this.height,
12207
+ frameRate: this.encoding.maxFramerate,
12208
+ aspectRatio: this.aspectRatio
12209
+ };
12210
+ }
12211
+ }
12212
+ // `red` is not technically a codec, but treated as one in signalling protocol
12213
+ const audioCodecs = ['opus', 'red'];
12214
+ const backupVideoCodecs = ['vp8', 'h264'];
12215
+ const videoCodecs = ['vp8', 'h264', 'vp9', 'av1', 'h265'];
12216
+ function isBackupVideoCodec(codec) {
12217
+ return !!backupVideoCodecs.find(backup => backup === codec);
12218
+ }
12219
+ /** @deprecated Use {@link isBackupVideoCodec} instead */
12220
+ const isBackupCodec = isBackupVideoCodec;
12221
+ var BackupCodecPolicy;
12222
+ (function (BackupCodecPolicy) {
12223
+ // codec regression is preferred, the sfu will try to regress codec if possible but not guaranteed
12224
+ BackupCodecPolicy[BackupCodecPolicy["PREFER_REGRESSION"] = 0] = "PREFER_REGRESSION";
12225
+ // multi-codec simulcast, publish both primary and backup codec at the same time
12226
+ BackupCodecPolicy[BackupCodecPolicy["SIMULCAST"] = 1] = "SIMULCAST";
12227
+ // always use backup codec only
12228
+ BackupCodecPolicy[BackupCodecPolicy["REGRESSION"] = 2] = "REGRESSION";
12229
+ })(BackupCodecPolicy || (BackupCodecPolicy = {}));
12230
+ var AudioPresets;
12231
+ (function (AudioPresets) {
12232
+ AudioPresets.telephone = {
12233
+ maxBitrate: 12000
12234
+ };
12235
+ AudioPresets.speech = {
12236
+ maxBitrate: 24000
12237
+ };
12238
+ AudioPresets.music = {
12239
+ maxBitrate: 48000
12240
+ };
12241
+ AudioPresets.musicStereo = {
12242
+ maxBitrate: 64000
12243
+ };
12244
+ AudioPresets.musicHighQuality = {
12245
+ maxBitrate: 96000
12246
+ };
12247
+ AudioPresets.musicHighQualityStereo = {
12248
+ maxBitrate: 128000
12249
+ };
12250
+ })(AudioPresets || (AudioPresets = {}));
12540
12251
  /**
12541
- * @internal
12252
+ * Sane presets for video resolution/encoding
12542
12253
  */
12543
- function getBrowser(userAgent) {
12544
- let force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
12545
- if (typeof userAgent === 'undefined' && typeof navigator === 'undefined') {
12546
- return;
12254
+ const VideoPresets = {
12255
+ h90: new VideoPreset(160, 90, 90000, 20),
12256
+ h180: new VideoPreset(320, 180, 160000, 20),
12257
+ h216: new VideoPreset(384, 216, 180000, 20),
12258
+ h360: new VideoPreset(640, 360, 450000, 20),
12259
+ h540: new VideoPreset(960, 540, 800000, 25),
12260
+ h720: new VideoPreset(1280, 720, 1700000, 30),
12261
+ h1080: new VideoPreset(1920, 1080, 3000000, 30),
12262
+ h1440: new VideoPreset(2560, 1440, 5000000, 30),
12263
+ h2160: new VideoPreset(3840, 2160, 8000000, 30)
12264
+ };
12265
+ /**
12266
+ * Four by three presets
12267
+ */
12268
+ const VideoPresets43 = {
12269
+ h120: new VideoPreset(160, 120, 70000, 20),
12270
+ h180: new VideoPreset(240, 180, 125000, 20),
12271
+ h240: new VideoPreset(320, 240, 140000, 20),
12272
+ h360: new VideoPreset(480, 360, 330000, 20),
12273
+ h480: new VideoPreset(640, 480, 500000, 20),
12274
+ h540: new VideoPreset(720, 540, 600000, 25),
12275
+ h720: new VideoPreset(960, 720, 1300000, 30),
12276
+ h1080: new VideoPreset(1440, 1080, 2300000, 30),
12277
+ h1440: new VideoPreset(1920, 1440, 3800000, 30)
12278
+ };
12279
+ const ScreenSharePresets = {
12280
+ h360fps3: new VideoPreset(640, 360, 200000, 3, 'medium'),
12281
+ h360fps15: new VideoPreset(640, 360, 400000, 15, 'medium'),
12282
+ h720fps5: new VideoPreset(1280, 720, 800000, 5, 'medium'),
12283
+ h720fps15: new VideoPreset(1280, 720, 1500000, 15, 'medium'),
12284
+ h720fps30: new VideoPreset(1280, 720, 2000000, 30, 'medium'),
12285
+ h1080fps15: new VideoPreset(1920, 1080, 2500000, 15, 'medium'),
12286
+ h1080fps30: new VideoPreset(1920, 1080, 5000000, 30, 'medium'),
12287
+ // original resolution, without resizing
12288
+ original: new VideoPreset(0, 0, 7000000, 30, 'medium')
12289
+ };function mergeDefaultOptions(options, audioDefaults, videoDefaults) {
12290
+ var _a, _b;
12291
+ var _c, _d;
12292
+ const {
12293
+ optionsWithoutProcessor,
12294
+ audioProcessor,
12295
+ videoProcessor
12296
+ } = extractProcessorsFromOptions(options !== null && options !== void 0 ? options : {});
12297
+ const defaultAudioProcessor = audioDefaults === null || audioDefaults === void 0 ? void 0 : audioDefaults.processor;
12298
+ const defaultVideoProcessor = videoDefaults === null || videoDefaults === void 0 ? void 0 : videoDefaults.processor;
12299
+ const clonedOptions = optionsWithoutProcessor !== null && optionsWithoutProcessor !== void 0 ? optionsWithoutProcessor : {};
12300
+ if (clonedOptions.audio === true) clonedOptions.audio = {};
12301
+ if (clonedOptions.video === true) clonedOptions.video = {};
12302
+ // use defaults
12303
+ if (clonedOptions.audio) {
12304
+ mergeObjectWithoutOverwriting(clonedOptions.audio, audioDefaults);
12305
+ (_a = (_c = clonedOptions.audio).deviceId) !== null && _a !== void 0 ? _a : _c.deviceId = {
12306
+ ideal: 'default'
12307
+ };
12308
+ if (audioProcessor || defaultAudioProcessor) {
12309
+ clonedOptions.audio.processor = audioProcessor !== null && audioProcessor !== void 0 ? audioProcessor : defaultAudioProcessor;
12310
+ }
12547
12311
  }
12548
- const ua = (userAgent !== null && userAgent !== void 0 ? userAgent : navigator.userAgent).toLowerCase();
12549
- if (browserDetails === undefined || force) {
12550
- const browser = browsersList.find(_ref => {
12551
- let {
12552
- test
12553
- } = _ref;
12554
- return test.test(ua);
12312
+ if (clonedOptions.video) {
12313
+ mergeObjectWithoutOverwriting(clonedOptions.video, videoDefaults);
12314
+ (_b = (_d = clonedOptions.video).deviceId) !== null && _b !== void 0 ? _b : _d.deviceId = {
12315
+ ideal: 'default'
12316
+ };
12317
+ if (videoProcessor || defaultVideoProcessor) {
12318
+ clonedOptions.video.processor = videoProcessor !== null && videoProcessor !== void 0 ? videoProcessor : defaultVideoProcessor;
12319
+ }
12320
+ }
12321
+ return clonedOptions;
12322
+ }
12323
+ function mergeObjectWithoutOverwriting(mainObject, objectToMerge) {
12324
+ Object.keys(objectToMerge).forEach(key => {
12325
+ if (mainObject[key] === undefined) mainObject[key] = objectToMerge[key];
12326
+ });
12327
+ return mainObject;
12328
+ }
12329
+ function constraintsForOptions(options) {
12330
+ var _a, _b;
12331
+ var _c, _d;
12332
+ const constraints = {};
12333
+ if (options.video) {
12334
+ // default video options
12335
+ if (typeof options.video === 'object') {
12336
+ const videoOptions = {};
12337
+ const target = videoOptions;
12338
+ const source = options.video;
12339
+ Object.keys(source).forEach(key => {
12340
+ switch (key) {
12341
+ case 'resolution':
12342
+ // flatten VideoResolution fields
12343
+ mergeObjectWithoutOverwriting(target, source.resolution);
12344
+ break;
12345
+ default:
12346
+ target[key] = source[key];
12347
+ }
12348
+ });
12349
+ constraints.video = videoOptions;
12350
+ (_a = (_c = constraints.video).deviceId) !== null && _a !== void 0 ? _a : _c.deviceId = {
12351
+ ideal: 'default'
12352
+ };
12353
+ } else {
12354
+ constraints.video = options.video ? {
12355
+ deviceId: {
12356
+ ideal: 'default'
12357
+ }
12358
+ } : false;
12359
+ }
12360
+ } else {
12361
+ constraints.video = false;
12362
+ }
12363
+ if (options.audio) {
12364
+ if (typeof options.audio === 'object') {
12365
+ constraints.audio = options.audio;
12366
+ (_b = (_d = constraints.audio).deviceId) !== null && _b !== void 0 ? _b : _d.deviceId = {
12367
+ ideal: 'default'
12368
+ };
12369
+ } else {
12370
+ constraints.audio = {
12371
+ deviceId: {
12372
+ ideal: 'default'
12373
+ }
12374
+ };
12375
+ }
12376
+ } else {
12377
+ constraints.audio = false;
12378
+ }
12379
+ return constraints;
12380
+ }
12381
+ /**
12382
+ * This function detects silence on a given [[Track]] instance.
12383
+ * Returns true if the track seems to be entirely silent.
12384
+ */
12385
+ function detectSilence(track_1) {
12386
+ return __awaiter(this, arguments, void 0, function (track) {
12387
+ let timeOffset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 200;
12388
+ return function* () {
12389
+ const ctx = getNewAudioContext();
12390
+ if (ctx) {
12391
+ const analyser = ctx.createAnalyser();
12392
+ analyser.fftSize = 2048;
12393
+ const bufferLength = analyser.frequencyBinCount;
12394
+ const dataArray = new Uint8Array(bufferLength);
12395
+ const source = ctx.createMediaStreamSource(new MediaStream([track.mediaStreamTrack]));
12396
+ source.connect(analyser);
12397
+ yield sleep(timeOffset);
12398
+ analyser.getByteTimeDomainData(dataArray);
12399
+ const someNoise = dataArray.some(sample => sample !== 128 && sample !== 0);
12400
+ ctx.close();
12401
+ return !someNoise;
12402
+ }
12403
+ return false;
12404
+ }();
12405
+ });
12406
+ }
12407
+ /**
12408
+ * @internal
12409
+ */
12410
+ function getNewAudioContext() {
12411
+ var _a;
12412
+ const AudioContext =
12413
+ // @ts-ignore
12414
+ typeof window !== 'undefined' && (window.AudioContext || window.webkitAudioContext);
12415
+ if (AudioContext) {
12416
+ const audioContext = new AudioContext({
12417
+ latencyHint: 'interactive'
12555
12418
  });
12556
- browserDetails = browser === null || browser === void 0 ? void 0 : browser.describe(ua);
12419
+ // If the audio context is suspended, we need to resume it when the user clicks on the page
12420
+ if (audioContext.state === 'suspended' && typeof window !== 'undefined' && ((_a = window.document) === null || _a === void 0 ? void 0 : _a.body)) {
12421
+ const handleResume = () => __awaiter(this, void 0, void 0, function* () {
12422
+ var _a;
12423
+ try {
12424
+ if (audioContext.state === 'suspended') {
12425
+ yield audioContext.resume();
12426
+ }
12427
+ } catch (e) {
12428
+ console.warn('Error trying to auto-resume audio context', e);
12429
+ } finally {
12430
+ (_a = window.document.body) === null || _a === void 0 ? void 0 : _a.removeEventListener('click', handleResume);
12431
+ }
12432
+ });
12433
+ // https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/statechange_event
12434
+ audioContext.addEventListener('statechange', () => {
12435
+ var _a;
12436
+ if (audioContext.state === 'closed') {
12437
+ (_a = window.document.body) === null || _a === void 0 ? void 0 : _a.removeEventListener('click', handleResume);
12438
+ }
12439
+ });
12440
+ window.document.body.addEventListener('click', handleResume);
12441
+ }
12442
+ return audioContext;
12557
12443
  }
12558
- return browserDetails;
12559
12444
  }
12560
- const browsersList = [{
12561
- test: /firefox|iceweasel|fxios/i,
12562
- describe(ua) {
12563
- const browser = {
12564
- name: 'Firefox',
12565
- version: getMatch(/(?:firefox|iceweasel|fxios)[\s/](\d+(\.?_?\d+)+)/i, ua),
12566
- os: ua.toLowerCase().includes('fxios') ? 'iOS' : undefined,
12567
- osVersion: getOSVersion(ua)
12568
- };
12569
- return browser;
12445
+ /**
12446
+ * @internal
12447
+ */
12448
+ function kindToSource(kind) {
12449
+ if (kind === 'audioinput') {
12450
+ return Track.Source.Microphone;
12451
+ } else if (kind === 'videoinput') {
12452
+ return Track.Source.Camera;
12453
+ } else {
12454
+ return Track.Source.Unknown;
12570
12455
  }
12571
- }, {
12572
- test: /chrom|crios|crmo/i,
12573
- describe(ua) {
12574
- const browser = {
12575
- name: 'Chrome',
12576
- version: getMatch(/(?:chrome|chromium|crios|crmo)\/(\d+(\.?_?\d+)+)/i, ua),
12577
- os: ua.toLowerCase().includes('crios') ? 'iOS' : undefined,
12578
- osVersion: getOSVersion(ua)
12456
+ }
12457
+ /**
12458
+ * @internal
12459
+ */
12460
+ function sourceToKind(source) {
12461
+ if (source === Track.Source.Microphone) {
12462
+ return 'audioinput';
12463
+ } else if (source === Track.Source.Camera) {
12464
+ return 'videoinput';
12465
+ } else {
12466
+ return undefined;
12467
+ }
12468
+ }
12469
+ /**
12470
+ * @internal
12471
+ */
12472
+ function screenCaptureToDisplayMediaStreamOptions(options) {
12473
+ var _a, _b;
12474
+ let videoConstraints = (_a = options.video) !== null && _a !== void 0 ? _a : true;
12475
+ // treat 0 as uncapped
12476
+ if (options.resolution && options.resolution.width > 0 && options.resolution.height > 0) {
12477
+ videoConstraints = typeof videoConstraints === 'boolean' ? {} : videoConstraints;
12478
+ if (isSafari()) {
12479
+ videoConstraints = Object.assign(Object.assign({}, videoConstraints), {
12480
+ width: {
12481
+ max: options.resolution.width
12482
+ },
12483
+ height: {
12484
+ max: options.resolution.height
12485
+ },
12486
+ frameRate: options.resolution.frameRate
12487
+ });
12488
+ } else {
12489
+ videoConstraints = Object.assign(Object.assign({}, videoConstraints), {
12490
+ width: {
12491
+ ideal: options.resolution.width
12492
+ },
12493
+ height: {
12494
+ ideal: options.resolution.height
12495
+ },
12496
+ frameRate: options.resolution.frameRate
12497
+ });
12498
+ }
12499
+ }
12500
+ return {
12501
+ audio: (_b = options.audio) !== null && _b !== void 0 ? _b : false,
12502
+ video: videoConstraints,
12503
+ // @ts-expect-error support for experimental display media features
12504
+ controller: options.controller,
12505
+ selfBrowserSurface: options.selfBrowserSurface,
12506
+ surfaceSwitching: options.surfaceSwitching,
12507
+ systemAudio: options.systemAudio,
12508
+ preferCurrentTab: options.preferCurrentTab
12509
+ };
12510
+ }
12511
+ function mimeTypeToVideoCodecString(mimeType) {
12512
+ return mimeType.split('/')[1].toLowerCase();
12513
+ }
12514
+ function getTrackPublicationInfo(tracks) {
12515
+ const infos = [];
12516
+ tracks.forEach(track => {
12517
+ if (track.track !== undefined) {
12518
+ infos.push(new TrackPublishedResponse({
12519
+ cid: track.track.mediaStreamID,
12520
+ track: track.trackInfo
12521
+ }));
12522
+ }
12523
+ });
12524
+ return infos;
12525
+ }
12526
+ function getLogContextFromTrack(track) {
12527
+ if ('mediaStreamTrack' in track) {
12528
+ return {
12529
+ trackID: track.sid,
12530
+ source: track.source,
12531
+ muted: track.isMuted,
12532
+ enabled: track.mediaStreamTrack.enabled,
12533
+ kind: track.kind,
12534
+ streamID: track.mediaStreamID,
12535
+ streamTrackID: track.mediaStreamTrack.id
12579
12536
  };
12580
- return browser;
12537
+ } else {
12538
+ return {
12539
+ trackID: track.trackSid,
12540
+ enabled: track.isEnabled,
12541
+ muted: track.isMuted,
12542
+ trackInfo: Object.assign({
12543
+ mimeType: track.mimeType,
12544
+ name: track.trackName,
12545
+ encrypted: track.isEncrypted,
12546
+ kind: track.kind,
12547
+ source: track.source
12548
+ }, track.track ? getLogContextFromTrack(track.track) : {})
12549
+ };
12550
+ }
12551
+ }
12552
+ function supportsSynchronizationSources() {
12553
+ return typeof RTCRtpReceiver !== 'undefined' && 'getSynchronizationSources' in RTCRtpReceiver;
12554
+ }
12555
+ function diffAttributes(oldValues, newValues) {
12556
+ var _a;
12557
+ if (oldValues === undefined) {
12558
+ oldValues = {};
12559
+ }
12560
+ if (newValues === undefined) {
12561
+ newValues = {};
12562
+ }
12563
+ const allKeys = [...Object.keys(newValues), ...Object.keys(oldValues)];
12564
+ const diff = {};
12565
+ for (const key of allKeys) {
12566
+ if (oldValues[key] !== newValues[key]) {
12567
+ diff[key] = (_a = newValues[key]) !== null && _a !== void 0 ? _a : '';
12568
+ }
12569
+ }
12570
+ return diff;
12571
+ }
12572
+ /** @internal */
12573
+ function extractProcessorsFromOptions(options) {
12574
+ const newOptions = Object.assign({}, options);
12575
+ let audioProcessor;
12576
+ let videoProcessor;
12577
+ if (typeof newOptions.audio === 'object' && newOptions.audio.processor) {
12578
+ audioProcessor = newOptions.audio.processor;
12579
+ newOptions.audio = Object.assign(Object.assign({}, newOptions.audio), {
12580
+ processor: undefined
12581
+ });
12582
+ }
12583
+ if (typeof newOptions.video === 'object' && newOptions.video.processor) {
12584
+ videoProcessor = newOptions.video.processor;
12585
+ newOptions.video = Object.assign(Object.assign({}, newOptions.video), {
12586
+ processor: undefined
12587
+ });
12581
12588
  }
12582
- }, /* Safari */
12583
- {
12584
- test: /safari|applewebkit/i,
12585
- describe(ua) {
12586
- const browser = {
12587
- name: 'Safari',
12588
- version: getMatch(commonVersionIdentifier, ua),
12589
- os: ua.includes('mobile/') ? 'iOS' : 'macOS',
12590
- osVersion: getOSVersion(ua)
12591
- };
12592
- return browser;
12589
+ return {
12590
+ audioProcessor,
12591
+ videoProcessor,
12592
+ optionsWithoutProcessor: cloneDeep(newOptions)
12593
+ };
12594
+ }
12595
+ function getTrackSourceFromProto(source) {
12596
+ switch (source) {
12597
+ case TrackSource.CAMERA:
12598
+ return Track.Source.Camera;
12599
+ case TrackSource.MICROPHONE:
12600
+ return Track.Source.Microphone;
12601
+ case TrackSource.SCREEN_SHARE:
12602
+ return Track.Source.ScreenShare;
12603
+ case TrackSource.SCREEN_SHARE_AUDIO:
12604
+ return Track.Source.ScreenShareAudio;
12605
+ default:
12606
+ return Track.Source.Unknown;
12593
12607
  }
12594
- }];
12595
- function getMatch(exp, ua) {
12596
- let id = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
12597
- const match = ua.match(exp);
12598
- return match && match.length >= id && match[id] || '';
12599
12608
  }
12600
- function getOSVersion(ua) {
12601
- return ua.includes('mac os') ? getMatch(/\(.+?(\d+_\d+(:?_\d+)?)/, ua, 1).replace(/_/g, '.') : undefined;
12609
+ function areDimensionsSmaller(a, b) {
12610
+ return a.width * a.height < b.width * b.height;
12602
12611
  }
12603
-
12604
- var version$1 = "2.15.16";
12605
-
12606
- const version = version$1;
12607
- const protocolVersion = 16;
12608
-
12609
- /**
12610
- * Timers that can be overridden with platform specific implementations
12611
- * that ensure that they are fired. These should be used when it is critical
12612
- * that the timer fires on time.
12613
- */
12614
- class CriticalTimers {}
12615
- CriticalTimers.setTimeout = function () {
12616
- return setTimeout(...arguments);
12617
- };
12618
- CriticalTimers.setInterval =
12619
- // eslint-disable-next-line @typescript-eslint/no-implied-eval
12620
- function () {
12621
- return setInterval(...arguments);
12622
- };
12623
- CriticalTimers.clearTimeout = function () {
12624
- return clearTimeout(...arguments);
12625
- };
12626
- CriticalTimers.clearInterval = function () {
12627
- return clearInterval(...arguments);
12628
- };
12629
-
12630
- const BACKGROUND_REACTION_DELAY = 5000;
12612
+ function layerDimensionsFor(trackInfo, quality) {
12613
+ var _a;
12614
+ return (_a = trackInfo.layers) === null || _a === void 0 ? void 0 : _a.find(l => l.quality === quality);
12615
+ }const BACKGROUND_REACTION_DELAY = 5000;
12631
12616
  // keep old audio elements when detached, we would re-use them since on iOS
12632
12617
  // Safari tracks which audio elements have been "blessed" by the user.
12633
12618
  const recycledElements = [];
@@ -13006,121 +12991,7 @@ function detachTrack(track, element) {
13006
12991
  }
13007
12992
  }
13008
12993
  Track.streamStateFromProto = streamStateFromProto;
13009
- })(Track || (Track = {}));
13010
-
13011
- class VideoPreset {
13012
- constructor(widthOrOptions, height, maxBitrate, maxFramerate, priority) {
13013
- if (typeof widthOrOptions === 'object') {
13014
- this.width = widthOrOptions.width;
13015
- this.height = widthOrOptions.height;
13016
- this.aspectRatio = widthOrOptions.aspectRatio;
13017
- this.encoding = {
13018
- maxBitrate: widthOrOptions.maxBitrate,
13019
- maxFramerate: widthOrOptions.maxFramerate,
13020
- priority: widthOrOptions.priority
13021
- };
13022
- } else if (height !== undefined && maxBitrate !== undefined) {
13023
- this.width = widthOrOptions;
13024
- this.height = height;
13025
- this.aspectRatio = widthOrOptions / height;
13026
- this.encoding = {
13027
- maxBitrate,
13028
- maxFramerate,
13029
- priority
13030
- };
13031
- } else {
13032
- throw new TypeError('Unsupported options: provide at least width, height and maxBitrate');
13033
- }
13034
- }
13035
- get resolution() {
13036
- return {
13037
- width: this.width,
13038
- height: this.height,
13039
- frameRate: this.encoding.maxFramerate,
13040
- aspectRatio: this.aspectRatio
13041
- };
13042
- }
13043
- }
13044
- // `red` is not technically a codec, but treated as one in signalling protocol
13045
- const audioCodecs = ['opus', 'red'];
13046
- const backupVideoCodecs = ['vp8', 'h264'];
13047
- const videoCodecs = ['vp8', 'h264', 'vp9', 'av1', 'h265'];
13048
- function isBackupVideoCodec(codec) {
13049
- return !!backupVideoCodecs.find(backup => backup === codec);
13050
- }
13051
- /** @deprecated Use {@link isBackupVideoCodec} instead */
13052
- const isBackupCodec = isBackupVideoCodec;
13053
- var BackupCodecPolicy;
13054
- (function (BackupCodecPolicy) {
13055
- // codec regression is preferred, the sfu will try to regress codec if possible but not guaranteed
13056
- BackupCodecPolicy[BackupCodecPolicy["PREFER_REGRESSION"] = 0] = "PREFER_REGRESSION";
13057
- // multi-codec simulcast, publish both primary and backup codec at the same time
13058
- BackupCodecPolicy[BackupCodecPolicy["SIMULCAST"] = 1] = "SIMULCAST";
13059
- // always use backup codec only
13060
- BackupCodecPolicy[BackupCodecPolicy["REGRESSION"] = 2] = "REGRESSION";
13061
- })(BackupCodecPolicy || (BackupCodecPolicy = {}));
13062
- var AudioPresets;
13063
- (function (AudioPresets) {
13064
- AudioPresets.telephone = {
13065
- maxBitrate: 12000
13066
- };
13067
- AudioPresets.speech = {
13068
- maxBitrate: 24000
13069
- };
13070
- AudioPresets.music = {
13071
- maxBitrate: 48000
13072
- };
13073
- AudioPresets.musicStereo = {
13074
- maxBitrate: 64000
13075
- };
13076
- AudioPresets.musicHighQuality = {
13077
- maxBitrate: 96000
13078
- };
13079
- AudioPresets.musicHighQualityStereo = {
13080
- maxBitrate: 128000
13081
- };
13082
- })(AudioPresets || (AudioPresets = {}));
13083
- /**
13084
- * Sane presets for video resolution/encoding
13085
- */
13086
- const VideoPresets = {
13087
- h90: new VideoPreset(160, 90, 90000, 20),
13088
- h180: new VideoPreset(320, 180, 160000, 20),
13089
- h216: new VideoPreset(384, 216, 180000, 20),
13090
- h360: new VideoPreset(640, 360, 450000, 20),
13091
- h540: new VideoPreset(960, 540, 800000, 25),
13092
- h720: new VideoPreset(1280, 720, 1700000, 30),
13093
- h1080: new VideoPreset(1920, 1080, 3000000, 30),
13094
- h1440: new VideoPreset(2560, 1440, 5000000, 30),
13095
- h2160: new VideoPreset(3840, 2160, 8000000, 30)
13096
- };
13097
- /**
13098
- * Four by three presets
13099
- */
13100
- const VideoPresets43 = {
13101
- h120: new VideoPreset(160, 120, 70000, 20),
13102
- h180: new VideoPreset(240, 180, 125000, 20),
13103
- h240: new VideoPreset(320, 240, 140000, 20),
13104
- h360: new VideoPreset(480, 360, 330000, 20),
13105
- h480: new VideoPreset(640, 480, 500000, 20),
13106
- h540: new VideoPreset(720, 540, 600000, 25),
13107
- h720: new VideoPreset(960, 720, 1300000, 30),
13108
- h1080: new VideoPreset(1440, 1080, 2300000, 30),
13109
- h1440: new VideoPreset(1920, 1440, 3800000, 30)
13110
- };
13111
- const ScreenSharePresets = {
13112
- h360fps3: new VideoPreset(640, 360, 200000, 3, 'medium'),
13113
- h360fps15: new VideoPreset(640, 360, 400000, 15, 'medium'),
13114
- h720fps5: new VideoPreset(1280, 720, 800000, 5, 'medium'),
13115
- h720fps15: new VideoPreset(1280, 720, 1500000, 15, 'medium'),
13116
- h720fps30: new VideoPreset(1280, 720, 2000000, 30, 'medium'),
13117
- h1080fps15: new VideoPreset(1920, 1080, 2500000, 15, 'medium'),
13118
- h1080fps30: new VideoPreset(1920, 1080, 5000000, 30, 'medium'),
13119
- // original resolution, without resizing
13120
- original: new VideoPreset(0, 0, 7000000, 30, 'medium')
13121
- };
13122
-
13123
- const separator = '|';
12994
+ })(Track || (Track = {}));const separator = '|';
13124
12995
  const ddExtensionURI = 'https://aomediacodec.github.io/av1-rtp-spec/#dependency-descriptor-rtp-header-extension';
13125
12996
  function unpackStreamId(packed) {
13126
12997
  const parts = packed.split(separator);
@@ -13667,347 +13538,348 @@ function splitUtf8(s, n) {
13667
13538
  }
13668
13539
  return result;
13669
13540
  }
13670
- function extractMaxAgeFromRequestHeaders(headers) {
13671
- var _a;
13672
- const cacheControl = headers.get('Cache-Control');
13673
- if (cacheControl) {
13674
- const maxAge = (_a = cacheControl.match(/(?:^|[,\s])max-age=(\d+)/)) === null || _a === void 0 ? void 0 : _a[1];
13675
- if (maxAge) {
13676
- return parseInt(maxAge, 10);
13677
- }
13678
- }
13679
- return undefined;
13541
+ function extractMaxAgeFromRequestHeaders(headers) {
13542
+ var _a;
13543
+ const cacheControl = headers.get('Cache-Control');
13544
+ if (cacheControl) {
13545
+ const maxAge = (_a = cacheControl.match(/(?:^|[,\s])max-age=(\d+)/)) === null || _a === void 0 ? void 0 : _a[1];
13546
+ if (maxAge) {
13547
+ return parseInt(maxAge, 10);
13548
+ }
13549
+ }
13550
+ return undefined;
13551
+ }function createRtcUrl(url, searchParams) {
13552
+ const urlObj = new URL(toWebsocketUrl(url));
13553
+ searchParams.forEach((value, key) => {
13554
+ urlObj.searchParams.set(key, value);
13555
+ });
13556
+ return appendUrlPath(urlObj, 'rtc');
13557
+ }
13558
+ function createValidateUrl(rtcWsUrl) {
13559
+ const urlObj = new URL(toHttpUrl(rtcWsUrl));
13560
+ return appendUrlPath(urlObj, 'validate');
13561
+ }
13562
+ function ensureTrailingSlash(path) {
13563
+ return path.endsWith('/') ? path : "".concat(path, "/");
13564
+ }
13565
+ function appendUrlPath(urlObj, path) {
13566
+ urlObj.pathname = "".concat(ensureTrailingSlash(urlObj.pathname)).concat(path);
13567
+ return urlObj.toString();
13568
+ }
13569
+ function parseSignalResponse(value) {
13570
+ if (typeof value === 'string') {
13571
+ return SignalResponse.fromJson(JSON.parse(value), {
13572
+ ignoreUnknownFields: true
13573
+ });
13574
+ } else if (value instanceof ArrayBuffer) {
13575
+ return SignalResponse.fromBinary(new Uint8Array(value));
13576
+ }
13577
+ throw new Error("could not decode websocket message: ".concat(typeof value));
13578
+ }
13579
+ function getAbortReasonAsString(signal) {
13580
+ let defaultMessage = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'Unknown reason';
13581
+ if (!(signal instanceof AbortSignal)) {
13582
+ return defaultMessage;
13583
+ }
13584
+ const reason = signal.reason;
13585
+ switch (typeof reason) {
13586
+ case 'string':
13587
+ return reason;
13588
+ case 'object':
13589
+ return reason instanceof Error ? reason.message : defaultMessage;
13590
+ default:
13591
+ return 'toString' in reason ? reason.toString() : defaultMessage;
13592
+ }
13593
+ }const ENCRYPTION_ALGORITHM = 'AES-GCM';
13594
+ // How many consecutive frames can fail decrypting before a particular key gets marked as invalid
13595
+ const DECRYPTION_FAILURE_TOLERANCE = 10;
13596
+ // flag set to indicate that e2ee has been setup for sender/receiver;
13597
+ const E2EE_FLAG = 'lk_e2ee';
13598
+ const SALT = 'LKFrameEncryptionKey';
13599
+ const KEY_PROVIDER_DEFAULTS = {
13600
+ sharedKey: false,
13601
+ ratchetSalt: SALT,
13602
+ ratchetWindowSize: 8,
13603
+ failureTolerance: DECRYPTION_FAILURE_TOLERANCE,
13604
+ keyringSize: 16
13605
+ };var KeyProviderEvent;
13606
+ (function (KeyProviderEvent) {
13607
+ KeyProviderEvent["SetKey"] = "setKey";
13608
+ /** Event for requesting to ratchet the key used to encrypt the stream */
13609
+ KeyProviderEvent["RatchetRequest"] = "ratchetRequest";
13610
+ /** Emitted when a key is ratcheted. Could be after auto-ratcheting on decryption failure or
13611
+ * following a `RatchetRequest`, will contain the ratcheted key material */
13612
+ KeyProviderEvent["KeyRatcheted"] = "keyRatcheted";
13613
+ })(KeyProviderEvent || (KeyProviderEvent = {}));
13614
+ var KeyHandlerEvent;
13615
+ (function (KeyHandlerEvent) {
13616
+ /** Emitted when a key has been ratcheted. Is emitted when any key has been ratcheted
13617
+ * i.e. when the FrameCryptor tried to ratchet when decryption is failing */
13618
+ KeyHandlerEvent["KeyRatcheted"] = "keyRatcheted";
13619
+ })(KeyHandlerEvent || (KeyHandlerEvent = {}));
13620
+ var EncryptionEvent;
13621
+ (function (EncryptionEvent) {
13622
+ EncryptionEvent["ParticipantEncryptionStatusChanged"] = "participantEncryptionStatusChanged";
13623
+ EncryptionEvent["EncryptionError"] = "encryptionError";
13624
+ })(EncryptionEvent || (EncryptionEvent = {}));
13625
+ var CryptorEvent;
13626
+ (function (CryptorEvent) {
13627
+ CryptorEvent["Error"] = "cryptorError";
13628
+ })(CryptorEvent || (CryptorEvent = {}));function isE2EESupported() {
13629
+ return isInsertableStreamSupported() || isScriptTransformSupported();
13630
+ }
13631
+ function isScriptTransformSupported() {
13632
+ // @ts-ignore
13633
+ return typeof window.RTCRtpScriptTransform !== 'undefined';
13680
13634
  }
13681
-
13682
- function mergeDefaultOptions(options, audioDefaults, videoDefaults) {
13683
- var _a, _b;
13684
- var _c, _d;
13685
- const {
13686
- optionsWithoutProcessor,
13687
- audioProcessor,
13688
- videoProcessor
13689
- } = extractProcessorsFromOptions(options !== null && options !== void 0 ? options : {});
13690
- const defaultAudioProcessor = audioDefaults === null || audioDefaults === void 0 ? void 0 : audioDefaults.processor;
13691
- const defaultVideoProcessor = videoDefaults === null || videoDefaults === void 0 ? void 0 : videoDefaults.processor;
13692
- const clonedOptions = optionsWithoutProcessor !== null && optionsWithoutProcessor !== void 0 ? optionsWithoutProcessor : {};
13693
- if (clonedOptions.audio === true) clonedOptions.audio = {};
13694
- if (clonedOptions.video === true) clonedOptions.video = {};
13695
- // use defaults
13696
- if (clonedOptions.audio) {
13697
- mergeObjectWithoutOverwriting(clonedOptions.audio, audioDefaults);
13698
- (_a = (_c = clonedOptions.audio).deviceId) !== null && _a !== void 0 ? _a : _c.deviceId = {
13699
- ideal: 'default'
13700
- };
13701
- if (audioProcessor || defaultAudioProcessor) {
13702
- clonedOptions.audio.processor = audioProcessor !== null && audioProcessor !== void 0 ? audioProcessor : defaultAudioProcessor;
13703
- }
13704
- }
13705
- if (clonedOptions.video) {
13706
- mergeObjectWithoutOverwriting(clonedOptions.video, videoDefaults);
13707
- (_b = (_d = clonedOptions.video).deviceId) !== null && _b !== void 0 ? _b : _d.deviceId = {
13708
- ideal: 'default'
13635
+ function isInsertableStreamSupported() {
13636
+ return typeof window.RTCRtpSender !== 'undefined' &&
13637
+ // @ts-ignore
13638
+ typeof window.RTCRtpSender.prototype.createEncodedStreams !== 'undefined';
13639
+ }
13640
+ function isVideoFrame(frame) {
13641
+ return 'type' in frame;
13642
+ }
13643
+ function importKey(keyBytes_1) {
13644
+ return __awaiter(this, arguments, void 0, function (keyBytes) {
13645
+ let algorithm = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
13646
+ name: ENCRYPTION_ALGORITHM
13709
13647
  };
13710
- if (videoProcessor || defaultVideoProcessor) {
13711
- clonedOptions.video.processor = videoProcessor !== null && videoProcessor !== void 0 ? videoProcessor : defaultVideoProcessor;
13712
- }
13713
- }
13714
- return clonedOptions;
13648
+ let usage = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'encrypt';
13649
+ return function* () {
13650
+ // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey
13651
+ return crypto.subtle.importKey('raw', keyBytes, algorithm, false, usage === 'derive' ? ['deriveBits', 'deriveKey'] : ['encrypt', 'decrypt']);
13652
+ }();
13653
+ });
13715
13654
  }
13716
- function mergeObjectWithoutOverwriting(mainObject, objectToMerge) {
13717
- Object.keys(objectToMerge).forEach(key => {
13718
- if (mainObject[key] === undefined) mainObject[key] = objectToMerge[key];
13655
+ function createKeyMaterialFromString(password) {
13656
+ return __awaiter(this, void 0, void 0, function* () {
13657
+ let enc = new TextEncoder();
13658
+ const keyMaterial = yield crypto.subtle.importKey('raw', enc.encode(password), {
13659
+ name: 'PBKDF2'
13660
+ }, false, ['deriveBits', 'deriveKey']);
13661
+ return keyMaterial;
13719
13662
  });
13720
- return mainObject;
13721
13663
  }
13722
- function constraintsForOptions(options) {
13723
- var _a, _b;
13724
- var _c, _d;
13725
- const constraints = {};
13726
- if (options.video) {
13727
- // default video options
13728
- if (typeof options.video === 'object') {
13729
- const videoOptions = {};
13730
- const target = videoOptions;
13731
- const source = options.video;
13732
- Object.keys(source).forEach(key => {
13733
- switch (key) {
13734
- case 'resolution':
13735
- // flatten VideoResolution fields
13736
- mergeObjectWithoutOverwriting(target, source.resolution);
13737
- break;
13738
- default:
13739
- target[key] = source[key];
13740
- }
13741
- });
13742
- constraints.video = videoOptions;
13743
- (_a = (_c = constraints.video).deviceId) !== null && _a !== void 0 ? _a : _c.deviceId = {
13744
- ideal: 'default'
13745
- };
13746
- } else {
13747
- constraints.video = options.video ? {
13748
- deviceId: {
13749
- ideal: 'default'
13750
- }
13751
- } : false;
13752
- }
13753
- } else {
13754
- constraints.video = false;
13755
- }
13756
- if (options.audio) {
13757
- if (typeof options.audio === 'object') {
13758
- constraints.audio = options.audio;
13759
- (_b = (_d = constraints.audio).deviceId) !== null && _b !== void 0 ? _b : _d.deviceId = {
13760
- ideal: 'default'
13761
- };
13762
- } else {
13763
- constraints.audio = {
13764
- deviceId: {
13765
- ideal: 'default'
13766
- }
13664
+ function createKeyMaterialFromBuffer(cryptoBuffer) {
13665
+ return __awaiter(this, void 0, void 0, function* () {
13666
+ const keyMaterial = yield crypto.subtle.importKey('raw', cryptoBuffer, 'HKDF', false, ['deriveBits', 'deriveKey']);
13667
+ return keyMaterial;
13668
+ });
13669
+ }
13670
+ function getAlgoOptions(algorithmName, salt) {
13671
+ const textEncoder = new TextEncoder();
13672
+ const encodedSalt = textEncoder.encode(salt);
13673
+ switch (algorithmName) {
13674
+ case 'HKDF':
13675
+ return {
13676
+ name: 'HKDF',
13677
+ salt: encodedSalt,
13678
+ hash: 'SHA-256',
13679
+ info: new ArrayBuffer(128)
13767
13680
  };
13768
- }
13769
- } else {
13770
- constraints.audio = false;
13681
+ case 'PBKDF2':
13682
+ {
13683
+ return {
13684
+ name: 'PBKDF2',
13685
+ salt: encodedSalt,
13686
+ hash: 'SHA-256',
13687
+ iterations: 100000
13688
+ };
13689
+ }
13690
+ default:
13691
+ throw new Error("algorithm ".concat(algorithmName, " is currently unsupported"));
13771
13692
  }
13772
- return constraints;
13773
13693
  }
13774
13694
  /**
13775
- * This function detects silence on a given [[Track]] instance.
13776
- * Returns true if the track seems to be entirely silent.
13695
+ * Derives a set of keys from the master key.
13696
+ * See https://tools.ietf.org/html/draft-omara-sframe-00#section-4.3.1
13777
13697
  */
13778
- function detectSilence(track_1) {
13779
- return __awaiter(this, arguments, void 0, function (track) {
13780
- let timeOffset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 200;
13781
- return function* () {
13782
- const ctx = getNewAudioContext();
13783
- if (ctx) {
13784
- const analyser = ctx.createAnalyser();
13785
- analyser.fftSize = 2048;
13786
- const bufferLength = analyser.frequencyBinCount;
13787
- const dataArray = new Uint8Array(bufferLength);
13788
- const source = ctx.createMediaStreamSource(new MediaStream([track.mediaStreamTrack]));
13789
- source.connect(analyser);
13790
- yield sleep(timeOffset);
13791
- analyser.getByteTimeDomainData(dataArray);
13792
- const someNoise = dataArray.some(sample => sample !== 128 && sample !== 0);
13793
- ctx.close();
13794
- return !someNoise;
13795
- }
13796
- return false;
13797
- }();
13698
+ function deriveKeys(material, salt) {
13699
+ return __awaiter(this, void 0, void 0, function* () {
13700
+ const algorithmOptions = getAlgoOptions(material.algorithm.name, salt);
13701
+ // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveKey#HKDF
13702
+ // https://developer.mozilla.org/en-US/docs/Web/API/HkdfParams
13703
+ const encryptionKey = yield crypto.subtle.deriveKey(algorithmOptions, material, {
13704
+ name: ENCRYPTION_ALGORITHM,
13705
+ length: 128
13706
+ }, false, ['encrypt', 'decrypt']);
13707
+ return {
13708
+ material,
13709
+ encryptionKey
13710
+ };
13798
13711
  });
13799
13712
  }
13800
- /**
13801
- * @internal
13802
- */
13803
- function getNewAudioContext() {
13804
- var _a;
13805
- const AudioContext =
13806
- // @ts-ignore
13807
- typeof window !== 'undefined' && (window.AudioContext || window.webkitAudioContext);
13808
- if (AudioContext) {
13809
- const audioContext = new AudioContext({
13810
- latencyHint: 'interactive'
13811
- });
13812
- // If the audio context is suspended, we need to resume it when the user clicks on the page
13813
- if (audioContext.state === 'suspended' && typeof window !== 'undefined' && ((_a = window.document) === null || _a === void 0 ? void 0 : _a.body)) {
13814
- const handleResume = () => __awaiter(this, void 0, void 0, function* () {
13815
- var _a;
13816
- try {
13817
- if (audioContext.state === 'suspended') {
13818
- yield audioContext.resume();
13819
- }
13820
- } catch (e) {
13821
- console.warn('Error trying to auto-resume audio context', e);
13822
- } finally {
13823
- (_a = window.document.body) === null || _a === void 0 ? void 0 : _a.removeEventListener('click', handleResume);
13824
- }
13825
- });
13826
- // https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/statechange_event
13827
- audioContext.addEventListener('statechange', () => {
13828
- var _a;
13829
- if (audioContext.state === 'closed') {
13830
- (_a = window.document.body) === null || _a === void 0 ? void 0 : _a.removeEventListener('click', handleResume);
13831
- }
13832
- });
13833
- window.document.body.addEventListener('click', handleResume);
13834
- }
13835
- return audioContext;
13836
- }
13837
- }
13838
- /**
13839
- * @internal
13840
- */
13841
- function kindToSource(kind) {
13842
- if (kind === 'audioinput') {
13843
- return Track.Source.Microphone;
13844
- } else if (kind === 'videoinput') {
13845
- return Track.Source.Camera;
13846
- } else {
13847
- return Track.Source.Unknown;
13848
- }
13713
+ function createE2EEKey() {
13714
+ return window.crypto.getRandomValues(new Uint8Array(32));
13849
13715
  }
13850
13716
  /**
13851
- * @internal
13717
+ * Ratchets a key. See
13718
+ * https://tools.ietf.org/html/draft-omara-sframe-00#section-4.3.5.1
13852
13719
  */
13853
- function sourceToKind(source) {
13854
- if (source === Track.Source.Microphone) {
13855
- return 'audioinput';
13856
- } else if (source === Track.Source.Camera) {
13857
- return 'videoinput';
13858
- } else {
13859
- return undefined;
13720
+ function ratchet(material, salt) {
13721
+ return __awaiter(this, void 0, void 0, function* () {
13722
+ const algorithmOptions = getAlgoOptions(material.algorithm.name, salt);
13723
+ // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveBits
13724
+ return crypto.subtle.deriveBits(algorithmOptions, material, 256);
13725
+ });
13726
+ }
13727
+ function needsRbspUnescaping(frameData) {
13728
+ for (var i = 0; i < frameData.length - 3; i++) {
13729
+ if (frameData[i] == 0 && frameData[i + 1] == 0 && frameData[i + 2] == 3) return true;
13860
13730
  }
13731
+ return false;
13861
13732
  }
13862
- /**
13863
- * @internal
13864
- */
13865
- function screenCaptureToDisplayMediaStreamOptions(options) {
13866
- var _a, _b;
13867
- let videoConstraints = (_a = options.video) !== null && _a !== void 0 ? _a : true;
13868
- // treat 0 as uncapped
13869
- if (options.resolution && options.resolution.width > 0 && options.resolution.height > 0) {
13870
- videoConstraints = typeof videoConstraints === 'boolean' ? {} : videoConstraints;
13871
- if (isSafari()) {
13872
- videoConstraints = Object.assign(Object.assign({}, videoConstraints), {
13873
- width: {
13874
- max: options.resolution.width
13875
- },
13876
- height: {
13877
- max: options.resolution.height
13878
- },
13879
- frameRate: options.resolution.frameRate
13880
- });
13733
+ function parseRbsp(stream) {
13734
+ const dataOut = [];
13735
+ var length = stream.length;
13736
+ for (var i = 0; i < stream.length;) {
13737
+ // Be careful about over/underflow here. byte_length_ - 3 can underflow, and
13738
+ // i + 3 can overflow, but byte_length_ - i can't, because i < byte_length_
13739
+ // above, and that expression will produce the number of bytes left in
13740
+ // the stream including the byte at i.
13741
+ if (length - i >= 3 && !stream[i] && !stream[i + 1] && stream[i + 2] == 3) {
13742
+ // Two rbsp bytes.
13743
+ dataOut.push(stream[i++]);
13744
+ dataOut.push(stream[i++]);
13745
+ // Skip the emulation byte.
13746
+ i++;
13881
13747
  } else {
13882
- videoConstraints = Object.assign(Object.assign({}, videoConstraints), {
13883
- width: {
13884
- ideal: options.resolution.width
13885
- },
13886
- height: {
13887
- ideal: options.resolution.height
13888
- },
13889
- frameRate: options.resolution.frameRate
13890
- });
13748
+ // Single rbsp byte.
13749
+ dataOut.push(stream[i++]);
13891
13750
  }
13892
13751
  }
13893
- return {
13894
- audio: (_b = options.audio) !== null && _b !== void 0 ? _b : false,
13895
- video: videoConstraints,
13896
- // @ts-expect-error support for experimental display media features
13897
- controller: options.controller,
13898
- selfBrowserSurface: options.selfBrowserSurface,
13899
- surfaceSwitching: options.surfaceSwitching,
13900
- systemAudio: options.systemAudio,
13901
- preferCurrentTab: options.preferCurrentTab
13902
- };
13903
- }
13904
- function mimeTypeToVideoCodecString(mimeType) {
13905
- return mimeType.split('/')[1].toLowerCase();
13752
+ return new Uint8Array(dataOut);
13906
13753
  }
13907
- function getTrackPublicationInfo(tracks) {
13908
- const infos = [];
13909
- tracks.forEach(track => {
13910
- if (track.track !== undefined) {
13911
- infos.push(new TrackPublishedResponse({
13912
- cid: track.track.mediaStreamID,
13913
- track: track.trackInfo
13914
- }));
13754
+ const kZerosInStartSequence = 2;
13755
+ const kEmulationByte = 3;
13756
+ function writeRbsp(data_in) {
13757
+ const dataOut = [];
13758
+ var numConsecutiveZeros = 0;
13759
+ for (var i = 0; i < data_in.length; ++i) {
13760
+ var byte = data_in[i];
13761
+ if (byte <= kEmulationByte && numConsecutiveZeros >= kZerosInStartSequence) {
13762
+ // Need to escape.
13763
+ dataOut.push(kEmulationByte);
13764
+ numConsecutiveZeros = 0;
13915
13765
  }
13916
- });
13917
- return infos;
13766
+ dataOut.push(byte);
13767
+ if (byte == 0) {
13768
+ ++numConsecutiveZeros;
13769
+ } else {
13770
+ numConsecutiveZeros = 0;
13771
+ }
13772
+ }
13773
+ return new Uint8Array(dataOut);
13918
13774
  }
13919
- function getLogContextFromTrack(track) {
13920
- if ('mediaStreamTrack' in track) {
13921
- return {
13922
- trackID: track.sid,
13923
- source: track.source,
13924
- muted: track.isMuted,
13925
- enabled: track.mediaStreamTrack.enabled,
13926
- kind: track.kind,
13927
- streamID: track.mediaStreamID,
13928
- streamTrackID: track.mediaStreamTrack.id
13775
+ function asEncryptablePacket(packet) {
13776
+ var _a, _b, _c, _d, _e;
13777
+ 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') {
13778
+ return new EncryptedPacketPayload({
13779
+ value: packet.value
13780
+ });
13781
+ }
13782
+ return undefined;
13783
+ }/**
13784
+ * @experimental
13785
+ */
13786
+ class BaseKeyProvider extends eventsExports.EventEmitter {
13787
+ constructor() {
13788
+ let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
13789
+ super();
13790
+ /**
13791
+ * Callback being invoked after a key has been ratcheted.
13792
+ * Can happen when:
13793
+ * - A decryption failure occurs and the key is auto-ratcheted
13794
+ * - A ratchet request is sent (see {@link ratchetKey()})
13795
+ * @param ratchetResult Contains the ratcheted chain key (exportable to other participants) and the derived new key material.
13796
+ * @param participantId
13797
+ * @param keyIndex
13798
+ */
13799
+ this.onKeyRatcheted = (ratchetResult, participantId, keyIndex) => {
13800
+ livekitLogger.debug('key ratcheted event received', {
13801
+ ratchetResult,
13802
+ participantId,
13803
+ keyIndex
13804
+ });
13929
13805
  };
13930
- } else {
13931
- return {
13932
- trackID: track.trackSid,
13933
- enabled: track.isEnabled,
13934
- muted: track.isMuted,
13935
- trackInfo: Object.assign({
13936
- mimeType: track.mimeType,
13937
- name: track.trackName,
13938
- encrypted: track.isEncrypted,
13939
- kind: track.kind,
13940
- source: track.source
13941
- }, track.track ? getLogContextFromTrack(track.track) : {})
13806
+ this.keyInfoMap = new Map();
13807
+ this.options = Object.assign(Object.assign({}, KEY_PROVIDER_DEFAULTS), options);
13808
+ this.on(KeyProviderEvent.KeyRatcheted, this.onKeyRatcheted);
13809
+ }
13810
+ /**
13811
+ * callback to invoke once a key has been set for a participant
13812
+ * @param key
13813
+ * @param participantIdentity
13814
+ * @param keyIndex
13815
+ */
13816
+ onSetEncryptionKey(key, participantIdentity, keyIndex) {
13817
+ const keyInfo = {
13818
+ key,
13819
+ participantIdentity,
13820
+ keyIndex
13942
13821
  };
13822
+ if (!this.options.sharedKey && !participantIdentity) {
13823
+ throw new Error('participant identity needs to be passed for encryption key if sharedKey option is false');
13824
+ }
13825
+ this.keyInfoMap.set("".concat(participantIdentity !== null && participantIdentity !== void 0 ? participantIdentity : 'shared', "-").concat(keyIndex !== null && keyIndex !== void 0 ? keyIndex : 0), keyInfo);
13826
+ this.emit(KeyProviderEvent.SetKey, keyInfo);
13943
13827
  }
13944
- }
13945
- function supportsSynchronizationSources() {
13946
- return typeof RTCRtpReceiver !== 'undefined' && 'getSynchronizationSources' in RTCRtpReceiver;
13947
- }
13948
- function diffAttributes(oldValues, newValues) {
13949
- var _a;
13950
- if (oldValues === undefined) {
13951
- oldValues = {};
13828
+ getKeys() {
13829
+ return Array.from(this.keyInfoMap.values());
13952
13830
  }
13953
- if (newValues === undefined) {
13954
- newValues = {};
13831
+ getOptions() {
13832
+ return this.options;
13955
13833
  }
13956
- const allKeys = [...Object.keys(newValues), ...Object.keys(oldValues)];
13957
- const diff = {};
13958
- for (const key of allKeys) {
13959
- if (oldValues[key] !== newValues[key]) {
13960
- diff[key] = (_a = newValues[key]) !== null && _a !== void 0 ? _a : '';
13961
- }
13834
+ ratchetKey(participantIdentity, keyIndex) {
13835
+ this.emit(KeyProviderEvent.RatchetRequest, participantIdentity, keyIndex);
13962
13836
  }
13963
- return diff;
13964
13837
  }
13965
- /** @internal */
13966
- function extractProcessorsFromOptions(options) {
13967
- const newOptions = Object.assign({}, options);
13968
- let audioProcessor;
13969
- let videoProcessor;
13970
- if (typeof newOptions.audio === 'object' && newOptions.audio.processor) {
13971
- audioProcessor = newOptions.audio.processor;
13972
- newOptions.audio = Object.assign(Object.assign({}, newOptions.audio), {
13973
- processor: undefined
13838
+ /**
13839
+ * A basic KeyProvider implementation intended for a single shared
13840
+ * passphrase between all participants
13841
+ * @experimental
13842
+ */
13843
+ class ExternalE2EEKeyProvider extends BaseKeyProvider {
13844
+ constructor() {
13845
+ let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
13846
+ const opts = Object.assign(Object.assign({}, options), {
13847
+ sharedKey: true,
13848
+ // for a shared key provider failing to decrypt for a specific participant
13849
+ // should not mark the key as invalid, so we accept wrong keys forever
13850
+ // and won't try to auto-ratchet
13851
+ ratchetWindowSize: 0,
13852
+ failureTolerance: -1
13974
13853
  });
13854
+ super(opts);
13975
13855
  }
13976
- if (typeof newOptions.video === 'object' && newOptions.video.processor) {
13977
- videoProcessor = newOptions.video.processor;
13978
- newOptions.video = Object.assign(Object.assign({}, newOptions.video), {
13979
- processor: undefined
13856
+ /**
13857
+ * Accepts a passphrase that's used to create the crypto keys.
13858
+ * When passing in a string, PBKDF2 is used.
13859
+ * When passing in an Array buffer of cryptographically random numbers, HKDF is being used. (recommended)
13860
+ * @param key
13861
+ */
13862
+ setKey(key) {
13863
+ return __awaiter(this, void 0, void 0, function* () {
13864
+ const derivedKey = typeof key === 'string' ? yield createKeyMaterialFromString(key) : yield createKeyMaterialFromBuffer(key);
13865
+ this.onSetEncryptionKey(derivedKey);
13980
13866
  });
13981
13867
  }
13982
- return {
13983
- audioProcessor,
13984
- videoProcessor,
13985
- optionsWithoutProcessor: cloneDeep(newOptions)
13986
- };
13987
- }
13988
- function getTrackSourceFromProto(source) {
13989
- switch (source) {
13990
- case TrackSource.CAMERA:
13991
- return Track.Source.Camera;
13992
- case TrackSource.MICROPHONE:
13993
- return Track.Source.Microphone;
13994
- case TrackSource.SCREEN_SHARE:
13995
- return Track.Source.ScreenShare;
13996
- case TrackSource.SCREEN_SHARE_AUDIO:
13997
- return Track.Source.ScreenShareAudio;
13998
- default:
13999
- return Track.Source.Unknown;
13868
+ }var CryptorErrorReason;
13869
+ (function (CryptorErrorReason) {
13870
+ CryptorErrorReason[CryptorErrorReason["InvalidKey"] = 0] = "InvalidKey";
13871
+ CryptorErrorReason[CryptorErrorReason["MissingKey"] = 1] = "MissingKey";
13872
+ CryptorErrorReason[CryptorErrorReason["InternalError"] = 2] = "InternalError";
13873
+ })(CryptorErrorReason || (CryptorErrorReason = {}));
13874
+ class CryptorError extends LivekitError {
13875
+ constructor(message) {
13876
+ let reason = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : CryptorErrorReason.InternalError;
13877
+ let participantIdentity = arguments.length > 2 ? arguments[2] : undefined;
13878
+ super(40, message);
13879
+ this.reason = reason;
13880
+ this.participantIdentity = participantIdentity;
14000
13881
  }
14001
- }
14002
- function areDimensionsSmaller(a, b) {
14003
- return a.width * a.height < b.width * b.height;
14004
- }
14005
- function layerDimensionsFor(trackInfo, quality) {
14006
- var _a;
14007
- return (_a = trackInfo.layers) === null || _a === void 0 ? void 0 : _a.find(l => l.quality === quality);
14008
- }
14009
-
14010
- /**
13882
+ }/**
14011
13883
  * @experimental
14012
13884
  */
14013
13885
  class E2EEManager extends eventsExports.EventEmitter {
@@ -14453,9 +14325,7 @@ class E2EEManager extends eventsExports.EventEmitter {
14453
14325
  // @ts-ignore
14454
14326
  sender[E2EE_FLAG] = true;
14455
14327
  }
14456
- }
14457
-
14458
- const CONNECTION_BACKOFF_MIN_MS = 500;
14328
+ }const CONNECTION_BACKOFF_MIN_MS = 500;
14459
14329
  const CONNECTION_BACKOFF_MAX_MS = 15000;
14460
14330
  /**
14461
14331
  * BackOffStrategy implements exponential backoff for connection failures.
@@ -14514,9 +14384,7 @@ class BackOffStrategy {
14514
14384
  this.failedConnectionAttempts.clear();
14515
14385
  }
14516
14386
  }
14517
- BackOffStrategy._instance = null;
14518
-
14519
- const defaultId = 'default';
14387
+ BackOffStrategy._instance = null;const defaultId = 'default';
14520
14388
  class DeviceManager {
14521
14389
  constructor() {
14522
14390
  this._previousDevices = [];
@@ -14607,9 +14475,7 @@ class DeviceManager {
14607
14475
  }
14608
14476
  }
14609
14477
  DeviceManager.mediaDeviceKinds = ['audioinput', 'audiooutput', 'videoinput'];
14610
- DeviceManager.userMediaPromiseMap = new Map();
14611
-
14612
- var QueueTaskStatus;
14478
+ DeviceManager.userMediaPromiseMap = new Map();var QueueTaskStatus;
14613
14479
  (function (QueueTaskStatus) {
14614
14480
  QueueTaskStatus[QueueTaskStatus["WAITING"] = 0] = "WAITING";
14615
14481
  QueueTaskStatus[QueueTaskStatus["RUNNING"] = 1] = "RUNNING";
@@ -14649,9 +14515,7 @@ class AsyncQueue {
14649
14515
  snapshot() {
14650
14516
  return Array.from(this.pendingTasks.values());
14651
14517
  }
14652
- }
14653
-
14654
- /**
14518
+ }/**
14655
14519
  * [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)
14656
14520
  *
14657
14521
  * @see https://web.dev/websocketstream/
@@ -14745,53 +14609,7 @@ class WebSocketStream {
14745
14609
  }
14746
14610
  this.close = closeWithInfo;
14747
14611
  }
14748
- }
14749
-
14750
- function createRtcUrl(url, searchParams) {
14751
- const urlObj = new URL(toWebsocketUrl(url));
14752
- searchParams.forEach((value, key) => {
14753
- urlObj.searchParams.set(key, value);
14754
- });
14755
- return appendUrlPath(urlObj, 'rtc');
14756
- }
14757
- function createValidateUrl(rtcWsUrl) {
14758
- const urlObj = new URL(toHttpUrl(rtcWsUrl));
14759
- return appendUrlPath(urlObj, 'validate');
14760
- }
14761
- function ensureTrailingSlash(path) {
14762
- return path.endsWith('/') ? path : "".concat(path, "/");
14763
- }
14764
- function appendUrlPath(urlObj, path) {
14765
- urlObj.pathname = "".concat(ensureTrailingSlash(urlObj.pathname)).concat(path);
14766
- return urlObj.toString();
14767
- }
14768
- function parseSignalResponse(value) {
14769
- if (typeof value === 'string') {
14770
- return SignalResponse.fromJson(JSON.parse(value), {
14771
- ignoreUnknownFields: true
14772
- });
14773
- } else if (value instanceof ArrayBuffer) {
14774
- return SignalResponse.fromBinary(new Uint8Array(value));
14775
- }
14776
- throw new Error("could not decode websocket message: ".concat(typeof value));
14777
- }
14778
- function getAbortReasonAsString(signal) {
14779
- let defaultMessage = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'Unknown reason';
14780
- if (!(signal instanceof AbortSignal)) {
14781
- return defaultMessage;
14782
- }
14783
- const reason = signal.reason;
14784
- switch (typeof reason) {
14785
- case 'string':
14786
- return reason;
14787
- case 'object':
14788
- return reason instanceof Error ? reason.message : defaultMessage;
14789
- default:
14790
- return 'toString' in reason ? reason.toString() : defaultMessage;
14791
- }
14792
- }
14793
-
14794
- const passThroughQueueSignals = ['syncState', 'trickle', 'offer', 'answer', 'simulate', 'leave'];
14612
+ }const passThroughQueueSignals = ['syncState', 'trickle', 'offer', 'answer', 'simulate', 'leave'];
14795
14613
  function canPassThroughQueue(req) {
14796
14614
  const canPass = passThroughQueueSignals.indexOf(req.case) >= 0;
14797
14615
  livekitLogger.trace('request allowed to bypass queue:', {
@@ -14918,7 +14736,7 @@ class SignalClient {
14918
14736
  this.close();
14919
14737
  }
14920
14738
  cleanupAbortHandlers();
14921
- reject(target instanceof AbortSignal ? target.reason : target);
14739
+ reject(ConnectionError.cancelled(reason));
14922
14740
  });
14923
14741
  abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.addEventListener('abort', abortHandler);
14924
14742
  const cleanupAbortHandlers = () => {
@@ -14926,7 +14744,7 @@ class SignalClient {
14926
14744
  abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.removeEventListener('abort', abortHandler);
14927
14745
  };
14928
14746
  const wsTimeout = setTimeout(() => {
14929
- abortHandler(new ConnectionError('room connection has timed out (signal)', ConnectionErrorReason.ServerUnreachable));
14747
+ abortHandler(ConnectionError.timeout('room connection has timed out (signal)'));
14930
14748
  }, opts.websocketTimeout);
14931
14749
  const handleSignalConnected = (connection, firstMessage) => {
14932
14750
  this.handleSignalConnected(connection, wsTimeout, firstMessage);
@@ -14947,7 +14765,7 @@ class SignalClient {
14947
14765
  this.ws.closed.then(closeInfo => {
14948
14766
  var _a;
14949
14767
  if (this.isEstablishingConnection) {
14950
- reject(new ConnectionError("Websocket got closed during a (re)connection attempt: ".concat(closeInfo.reason), ConnectionErrorReason.InternalError));
14768
+ reject(ConnectionError.internal("Websocket got closed during a (re)connection attempt: ".concat(closeInfo.reason)));
14951
14769
  }
14952
14770
  if (closeInfo.closeCode !== 1000) {
14953
14771
  this.log.warn("websocket closed", Object.assign(Object.assign({}, this.logContext), {
@@ -14963,7 +14781,7 @@ class SignalClient {
14963
14781
  return;
14964
14782
  }).catch(reason => {
14965
14783
  if (this.isEstablishingConnection) {
14966
- reject(new ConnectionError("Websocket error during a (re)connection attempt: ".concat(reason), ConnectionErrorReason.InternalError));
14784
+ reject(ConnectionError.internal("Websocket error during a (re)connection attempt: ".concat(reason)));
14967
14785
  }
14968
14786
  });
14969
14787
  const connection = yield this.ws.opened.catch(reason => __awaiter(this, void 0, void 0, function* () {
@@ -14988,7 +14806,7 @@ class SignalClient {
14988
14806
  const firstMessage = yield signalReader.read();
14989
14807
  signalReader.releaseLock();
14990
14808
  if (!firstMessage.value) {
14991
- throw new ConnectionError('no message received as first message', ConnectionErrorReason.InternalError);
14809
+ throw ConnectionError.internal('no message received as first message');
14992
14810
  }
14993
14811
  const firstSignalResponse = parseSignalResponse(firstMessage.value);
14994
14812
  // Validate the first message
@@ -15492,18 +15310,18 @@ class SignalClient {
15492
15310
  } else if (this.isEstablishingConnection && ((_d = firstSignalResponse.message) === null || _d === void 0 ? void 0 : _d.case) === 'leave') {
15493
15311
  return {
15494
15312
  isValid: false,
15495
- error: new ConnectionError('Received leave request while trying to (re)connect', ConnectionErrorReason.LeaveRequest, undefined, firstSignalResponse.message.value.reason)
15313
+ error: ConnectionError.leaveRequest('Received leave request while trying to (re)connect', firstSignalResponse.message.value.reason)
15496
15314
  };
15497
15315
  } else if (!isReconnect) {
15498
15316
  // non-reconnect case, should receive join response first
15499
15317
  return {
15500
15318
  isValid: false,
15501
- error: new ConnectionError("did not receive join response, got ".concat((_e = firstSignalResponse.message) === null || _e === void 0 ? void 0 : _e.case, " instead"), ConnectionErrorReason.InternalError)
15319
+ error: ConnectionError.internal("did not receive join response, got ".concat((_e = firstSignalResponse.message) === null || _e === void 0 ? void 0 : _e.case, " instead"))
15502
15320
  };
15503
15321
  }
15504
15322
  return {
15505
15323
  isValid: false,
15506
- error: new ConnectionError('Unexpected first message', ConnectionErrorReason.InternalError)
15324
+ error: ConnectionError.internal('Unexpected first message')
15507
15325
  };
15508
15326
  }
15509
15327
  /**
@@ -15519,14 +15337,17 @@ class SignalClient {
15519
15337
  const resp = yield fetch(validateUrl);
15520
15338
  if (resp.status.toFixed(0).startsWith('4')) {
15521
15339
  const msg = yield resp.text();
15522
- return new ConnectionError(msg, ConnectionErrorReason.NotAllowed, resp.status);
15340
+ return ConnectionError.notAllowed(msg, resp.status);
15523
15341
  } else if (reason instanceof ConnectionError) {
15524
15342
  return reason;
15525
15343
  } else {
15526
- return new ConnectionError("Encountered unknown websocket error during connection: ".concat(reason), ConnectionErrorReason.InternalError, resp.status);
15344
+ return ConnectionError.internal("Encountered unknown websocket error during connection: ".concat(reason), {
15345
+ status: resp.status,
15346
+ statusText: resp.statusText
15347
+ });
15527
15348
  }
15528
15349
  } catch (e) {
15529
- return e instanceof ConnectionError ? e : new ConnectionError(e instanceof Error ? e.message : 'server was not reachable', ConnectionErrorReason.ServerUnreachable);
15350
+ return e instanceof ConnectionError ? e : ConnectionError.serverUnreachable(e instanceof Error ? e.message : 'server was not reachable');
15530
15351
  }
15531
15352
  });
15532
15353
  }
@@ -15618,9 +15439,7 @@ function createJoinRequestConnectionParams(token, info, opts) {
15618
15439
  });
15619
15440
  params.set('join_request', btoa(new TextDecoder('utf-8').decode(wrappedJoinRequest.toBinary())));
15620
15441
  return params;
15621
- }
15622
-
15623
- class DataPacketBuffer {
15442
+ }class DataPacketBuffer {
15624
15443
  constructor() {
15625
15444
  this.buffer = [];
15626
15445
  this._totalSize = 0;
@@ -15661,9 +15480,7 @@ class DataPacketBuffer {
15661
15480
  get length() {
15662
15481
  return this.buffer.length;
15663
15482
  }
15664
- }
15665
-
15666
- class TTLMap {
15483
+ }class TTLMap {
15667
15484
  /**
15668
15485
  * @param ttl ttl of the key (ms)
15669
15486
  */
@@ -15747,15 +15564,7 @@ class TTLMap {
15747
15564
  }
15748
15565
  return result;
15749
15566
  }
15750
- }
15751
-
15752
- var lib = {};
15753
-
15754
- var parser = {};
15755
-
15756
- var grammar = {exports: {}};
15757
-
15758
- var hasRequiredGrammar;
15567
+ }var lib = {};var parser = {};var grammar = {exports: {}};var hasRequiredGrammar;
15759
15568
  function requireGrammar() {
15760
15569
  if (hasRequiredGrammar) return grammar.exports;
15761
15570
  hasRequiredGrammar = 1;
@@ -16196,9 +16005,7 @@ function requireGrammar() {
16196
16005
  });
16197
16006
  });
16198
16007
  return grammar.exports;
16199
- }
16200
-
16201
- var hasRequiredParser;
16008
+ }var hasRequiredParser;
16202
16009
  function requireParser() {
16203
16010
  if (hasRequiredParser) return parser;
16204
16011
  hasRequiredParser = 1;
@@ -16316,9 +16123,7 @@ function requireParser() {
16316
16123
  };
16317
16124
  })(parser);
16318
16125
  return parser;
16319
- }
16320
-
16321
- var writer;
16126
+ }var writer;
16322
16127
  var hasRequiredWriter;
16323
16128
  function requireWriter() {
16324
16129
  if (hasRequiredWriter) return writer;
@@ -16422,9 +16227,7 @@ function requireWriter() {
16422
16227
  return sdp.join('\r\n') + '\r\n';
16423
16228
  };
16424
16229
  return writer;
16425
- }
16426
-
16427
- var hasRequiredLib;
16230
+ }var hasRequiredLib;
16428
16231
  function requireLib() {
16429
16232
  if (hasRequiredLib) return lib;
16430
16233
  hasRequiredLib = 1;
@@ -16441,11 +16244,7 @@ function requireLib() {
16441
16244
  lib.parseImageAttributes = parser.parseImageAttributes;
16442
16245
  lib.parseSimulcastStreamList = parser.parseSimulcastStreamList;
16443
16246
  return lib;
16444
- }
16445
-
16446
- var libExports = requireLib();
16447
-
16448
- function r(r, e, n) {
16247
+ }var libExports = requireLib();function r(r, e, n) {
16449
16248
  var i, t, o;
16450
16249
  void 0 === e && (e = 50), void 0 === n && (n = {});
16451
16250
  var a = null != (i = n.isImmediate) && i,
@@ -16487,9 +16286,7 @@ function r(r, e, n) {
16487
16286
  return (0, e.reject)(r);
16488
16287
  }), l = [];
16489
16288
  }, d;
16490
- }
16491
-
16492
- /* The svc codec (av1/vp9) would use a very low bitrate at the begining and
16289
+ }/* The svc codec (av1/vp9) would use a very low bitrate at the begining and
16493
16290
  increase slowly by the bandwidth estimator until it reach the target bitrate. The
16494
16291
  process commonly cost more than 10 seconds cause subscriber will get blur video at
16495
16292
  the first few seconds. So we use a 70% of target bitrate here as the start bitrate to
@@ -17072,9 +16869,7 @@ function ensureIPAddrMatchVersion(media) {
17072
16869
  }
17073
16870
  function getMidString(mid) {
17074
16871
  return typeof mid === 'number' ? mid.toFixed(0) : mid;
17075
- }
17076
-
17077
- const defaultVideoCodec = 'vp8';
16872
+ }const defaultVideoCodec = 'vp8';
17078
16873
  const publishDefaults = {
17079
16874
  audioPreset: AudioPresets.music,
17080
16875
  dtx: true,
@@ -17116,9 +16911,7 @@ const roomConnectOptionDefaults = {
17116
16911
  maxRetries: 1,
17117
16912
  peerConnectionTimeout: 15000,
17118
16913
  websocketTimeout: 15000
17119
- };
17120
-
17121
- var PCTransportState;
16914
+ };var PCTransportState;
17122
16915
  (function (PCTransportState) {
17123
16916
  PCTransportState[PCTransportState["NEW"] = 0] = "NEW";
17124
16917
  PCTransportState[PCTransportState["CONNECTING"] = 1] = "CONNECTING";
@@ -17392,7 +17185,7 @@ class PCTransportManager {
17392
17185
  const abortHandler = () => {
17393
17186
  this.log.warn('abort transport connection', this.logContext);
17394
17187
  CriticalTimers.clearTimeout(connectTimeout);
17395
- reject(new ConnectionError('room connection has been cancelled', ConnectionErrorReason.Cancelled));
17188
+ reject(ConnectionError.cancelled('room connection has been cancelled'));
17396
17189
  };
17397
17190
  if (abortController === null || abortController === void 0 ? void 0 : abortController.signal.aborted) {
17398
17191
  abortHandler();
@@ -17400,12 +17193,12 @@ class PCTransportManager {
17400
17193
  abortController === null || abortController === void 0 ? void 0 : abortController.signal.addEventListener('abort', abortHandler);
17401
17194
  const connectTimeout = CriticalTimers.setTimeout(() => {
17402
17195
  abortController === null || abortController === void 0 ? void 0 : abortController.signal.removeEventListener('abort', abortHandler);
17403
- reject(new ConnectionError('could not establish pc connection', ConnectionErrorReason.InternalError));
17196
+ reject(ConnectionError.internal('could not establish pc connection'));
17404
17197
  }, timeout);
17405
17198
  while (this.state !== PCTransportState.CONNECTED) {
17406
17199
  yield sleep(50); // FIXME we shouldn't rely on `sleep` in the connection paths, as it invokes `setTimeout` which can be drastically throttled by browser implementations
17407
17200
  if (abortController === null || abortController === void 0 ? void 0 : abortController.signal.aborted) {
17408
- reject(new ConnectionError('room connection has been cancelled', ConnectionErrorReason.Cancelled));
17201
+ reject(ConnectionError.cancelled('room connection has been cancelled'));
17409
17202
  return;
17410
17203
  }
17411
17204
  }
@@ -17416,9 +17209,8 @@ class PCTransportManager {
17416
17209
  }();
17417
17210
  });
17418
17211
  }
17419
- }
17420
-
17421
- const DEFAULT_MAX_AGE_MS = 5000;
17212
+ }const DEFAULT_MAX_AGE_MS = 5000;
17213
+ const STOP_REFETCH_DELAY_MS = 30000;
17422
17214
  class RegionUrlProvider {
17423
17215
  static fetchRegionSettings(serverUrl, token, signal) {
17424
17216
  return __awaiter(this, void 0, void 0, function* () {
@@ -17440,17 +17232,21 @@ class RegionUrlProvider {
17440
17232
  maxAgeInMs
17441
17233
  };
17442
17234
  } else {
17443
- throw new ConnectionError("Could not fetch region settings: ".concat(regionSettingsResponse.statusText), regionSettingsResponse.status === 401 ? ConnectionErrorReason.NotAllowed : ConnectionErrorReason.InternalError, regionSettingsResponse.status);
17235
+ if (regionSettingsResponse.status === 401) {
17236
+ throw ConnectionError.notAllowed("Could not fetch region settings: ".concat(regionSettingsResponse.statusText), regionSettingsResponse.status);
17237
+ } else {
17238
+ throw ConnectionError.internal("Could not fetch region settings: ".concat(regionSettingsResponse.statusText));
17239
+ }
17444
17240
  }
17445
17241
  } catch (e) {
17446
17242
  if (e instanceof ConnectionError) {
17447
17243
  // rethrow connection errors
17448
17244
  throw e;
17449
17245
  } else if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
17450
- throw new ConnectionError("Region fetching was aborted", ConnectionErrorReason.Cancelled);
17246
+ throw ConnectionError.cancelled("Region fetching was aborted");
17451
17247
  } else {
17452
- // wrap other errors as connection errors (e.g. timeouts)
17453
- throw new ConnectionError("Could not fetch region settings, ".concat(e instanceof Error ? "".concat(e.name, ": ").concat(e.message) : e), ConnectionErrorReason.ServerUnreachable, 500);
17248
+ // wrap other errors as connection errors
17249
+ throw ConnectionError.serverUnreachable("Could not fetch region settings, ".concat(e instanceof Error ? "".concat(e.name, ": ").concat(e.message) : e));
17454
17250
  }
17455
17251
  } finally {
17456
17252
  unlock();
@@ -17466,6 +17262,10 @@ class RegionUrlProvider {
17466
17262
  const newSettings = yield RegionUrlProvider.fetchRegionSettings(url, token);
17467
17263
  RegionUrlProvider.updateCachedRegionSettings(url, token, newSettings);
17468
17264
  } catch (error) {
17265
+ if (error instanceof ConnectionError && error.reason === ConnectionErrorReason.NotAllowed) {
17266
+ livekitLogger.debug('token is not valid, cancelling auto region refresh');
17267
+ return;
17268
+ }
17469
17269
  livekitLogger.debug('auto refetching of region settings failed', {
17470
17270
  error
17471
17271
  });
@@ -17479,6 +17279,68 @@ class RegionUrlProvider {
17479
17279
  RegionUrlProvider.cache.set(url.hostname, settings);
17480
17280
  RegionUrlProvider.scheduleRefetch(url, token, settings.maxAgeInMs);
17481
17281
  }
17282
+ static stopRefetch(hostname) {
17283
+ const timeout = RegionUrlProvider.settingsTimeouts.get(hostname);
17284
+ if (timeout) {
17285
+ clearTimeout(timeout);
17286
+ RegionUrlProvider.settingsTimeouts.delete(hostname);
17287
+ }
17288
+ }
17289
+ static scheduleCleanup(hostname) {
17290
+ let tracker = RegionUrlProvider.connectionTrackers.get(hostname);
17291
+ if (!tracker) {
17292
+ return;
17293
+ }
17294
+ // Cancel any existing cleanup timeout
17295
+ if (tracker.cleanupTimeout) {
17296
+ clearTimeout(tracker.cleanupTimeout);
17297
+ }
17298
+ // Schedule cleanup to stop refetch after delay
17299
+ tracker.cleanupTimeout = setTimeout(() => {
17300
+ const currentTracker = RegionUrlProvider.connectionTrackers.get(hostname);
17301
+ if (currentTracker && currentTracker.connectionCount === 0) {
17302
+ livekitLogger.debug('stopping region refetch after disconnect delay', {
17303
+ hostname
17304
+ });
17305
+ RegionUrlProvider.stopRefetch(hostname);
17306
+ }
17307
+ if (currentTracker) {
17308
+ currentTracker.cleanupTimeout = undefined;
17309
+ }
17310
+ }, STOP_REFETCH_DELAY_MS);
17311
+ }
17312
+ static cancelCleanup(hostname) {
17313
+ const tracker = RegionUrlProvider.connectionTrackers.get(hostname);
17314
+ if (tracker === null || tracker === void 0 ? void 0 : tracker.cleanupTimeout) {
17315
+ clearTimeout(tracker.cleanupTimeout);
17316
+ tracker.cleanupTimeout = undefined;
17317
+ }
17318
+ }
17319
+ notifyConnected() {
17320
+ const hostname = this.serverUrl.hostname;
17321
+ let tracker = RegionUrlProvider.connectionTrackers.get(hostname);
17322
+ if (!tracker) {
17323
+ tracker = {
17324
+ connectionCount: 0
17325
+ };
17326
+ RegionUrlProvider.connectionTrackers.set(hostname, tracker);
17327
+ }
17328
+ tracker.connectionCount++;
17329
+ // Cancel any scheduled cleanup since we have an active connection
17330
+ RegionUrlProvider.cancelCleanup(hostname);
17331
+ }
17332
+ notifyDisconnected() {
17333
+ const hostname = this.serverUrl.hostname;
17334
+ const tracker = RegionUrlProvider.connectionTrackers.get(hostname);
17335
+ if (!tracker) {
17336
+ return;
17337
+ }
17338
+ tracker.connectionCount = Math.max(0, tracker.connectionCount - 1);
17339
+ // If no more connections, schedule cleanup
17340
+ if (tracker.connectionCount === 0) {
17341
+ RegionUrlProvider.scheduleCleanup(hostname);
17342
+ }
17343
+ }
17482
17344
  constructor(url, token) {
17483
17345
  this.attemptedRegions = [];
17484
17346
  this.serverUrl = new URL(url);
@@ -17529,12 +17391,11 @@ class RegionUrlProvider {
17529
17391
  }
17530
17392
  RegionUrlProvider.cache = new Map();
17531
17393
  RegionUrlProvider.settingsTimeouts = new Map();
17394
+ RegionUrlProvider.connectionTrackers = new Map();
17532
17395
  RegionUrlProvider.fetchLock = new _();
17533
17396
  function getCloudConfigUrl(serverUrl) {
17534
17397
  return "".concat(serverUrl.protocol.replace('ws', 'http'), "//").concat(serverUrl.host, "/settings");
17535
- }
17536
-
17537
- // SPDX-FileCopyrightText: 2024 LiveKit, Inc.
17398
+ }// SPDX-FileCopyrightText: 2024 LiveKit, Inc.
17538
17399
  //
17539
17400
  // SPDX-License-Identifier: Apache-2.0
17540
17401
  /**
@@ -17646,9 +17507,7 @@ function truncateBytes(str, maxBytes) {
17646
17507
  }
17647
17508
  }
17648
17509
  return str.slice(0, low);
17649
- }
17650
-
17651
- const monitorFrequency = 2000;
17510
+ }const monitorFrequency = 2000;
17652
17511
  function computeBitrate(currentStats, prevStats) {
17653
17512
  if (!prevStats) {
17654
17513
  return 0;
@@ -17666,9 +17525,7 @@ function computeBitrate(currentStats, prevStats) {
17666
17525
  return 0;
17667
17526
  }
17668
17527
  return (bytesNow - bytesPrev) * 8 * 1000 / (currentStats.timestamp - prevStats.timestamp);
17669
- }
17670
-
17671
- // Check if MediaRecorder is available
17528
+ }// Check if MediaRecorder is available
17672
17529
  const isMediaRecorderAvailable = typeof MediaRecorder !== 'undefined';
17673
17530
  // Fallback class for environments without MediaRecorder
17674
17531
  class FallbackRecorder {
@@ -17734,9 +17591,7 @@ class LocalTrackRecorder extends RecorderBase {
17734
17591
  // Helper function to check if recording is supported
17735
17592
  function isRecordingSupported() {
17736
17593
  return isMediaRecorderAvailable;
17737
- }
17738
-
17739
- const DEFAULT_DIMENSIONS_TIMEOUT = 1000;
17594
+ }const DEFAULT_DIMENSIONS_TIMEOUT = 1000;
17740
17595
  const PRE_CONNECT_BUFFER_TIMEOUT = 10000;
17741
17596
  class LocalTrack extends Track {
17742
17597
  /** @internal */
@@ -18185,8 +18040,6 @@ class LocalTrack extends Track {
18185
18040
  * Sets a processor on this track.
18186
18041
  * See https://github.com/livekit/track-processors-js for example usage
18187
18042
  *
18188
- * @experimental
18189
- *
18190
18043
  * @param processor
18191
18044
  * @param showProcessedStreamLocally
18192
18045
  * @returns
@@ -18261,8 +18114,6 @@ class LocalTrack extends Track {
18261
18114
  * Stops the track processor
18262
18115
  * See https://github.com/livekit/track-processors-js for example usage
18263
18116
  *
18264
- * @experimental
18265
- * @returns
18266
18117
  */
18267
18118
  stopProcessor() {
18268
18119
  return __awaiter(this, arguments, void 0, function () {
@@ -18349,9 +18200,7 @@ class LocalTrack extends Track {
18349
18200
  var _a;
18350
18201
  return (_a = this.localTrackRecorder) === null || _a === void 0 ? void 0 : _a.mimeType;
18351
18202
  }
18352
- }
18353
-
18354
- class LocalAudioTrack extends LocalTrack {
18203
+ }class LocalAudioTrack extends LocalTrack {
18355
18204
  /**
18356
18205
  * boolean indicating whether enhanced noise cancellation is currently being used on this track
18357
18206
  */
@@ -18568,9 +18417,7 @@ class LocalAudioTrack extends LocalTrack {
18568
18417
  return trackIsSilent;
18569
18418
  });
18570
18419
  }
18571
- }
18572
-
18573
- /** @internal */
18420
+ }/** @internal */
18574
18421
  function mediaTrackToLocalTrack(mediaStreamTrack, constraints, loggerOptions) {
18575
18422
  switch (mediaStreamTrack.kind) {
18576
18423
  case 'audio':
@@ -18917,9 +18764,7 @@ function getDefaultDegradationPreference(track) {
18917
18764
  } else {
18918
18765
  return 'balanced';
18919
18766
  }
18920
- }
18921
-
18922
- const refreshSubscribedCodecAfterNewCodec = 5000;
18767
+ }const refreshSubscribedCodecAfterNewCodec = 5000;
18923
18768
  class LocalVideoTrack extends LocalTrack {
18924
18769
  get sender() {
18925
18770
  return this._sender;
@@ -19578,13 +19423,13 @@ function videoLayersFromEncodings(width, height, encodings, svc) {
19578
19423
  ssrc: 0
19579
19424
  });
19580
19425
  });
19581
- }
19582
-
19583
- const lossyDataChannel = '_lossy';
19426
+ }const lossyDataChannel = '_lossy';
19584
19427
  const reliableDataChannel = '_reliable';
19585
19428
  const minReconnectWait = 2 * 1000;
19586
19429
  const leaveReconnect = 'leave-reconnect';
19587
19430
  const reliabeReceiveStateTTL = 30000;
19431
+ const lossyDataChannelBufferThresholdMin = 8 * 1024;
19432
+ const lossyDataChannelBufferThresholdMax = 256 * 1024;
19588
19433
  var PCState;
19589
19434
  (function (PCState) {
19590
19435
  PCState[PCState["New"] = 0] = "New";
@@ -19628,6 +19473,9 @@ class RTCEngine extends eventsExports.EventEmitter {
19628
19473
  this.reliableDataSequence = 1;
19629
19474
  this.reliableMessageBuffer = new DataPacketBuffer();
19630
19475
  this.reliableReceivedState = new TTLMap(reliabeReceiveStateTTL);
19476
+ this.lossyDataStatCurrentBytes = 0;
19477
+ this.lossyDataStatByterate = 0;
19478
+ this.lossyDataDropCount = 0;
19631
19479
  this.midToTrackId = {};
19632
19480
  /** used to indicate whether the browser is currently waiting to reconnect */
19633
19481
  this.isWaitingForNetworkReconnect = false;
@@ -19785,6 +19633,12 @@ class RTCEngine extends eventsExports.EventEmitter {
19785
19633
  });
19786
19634
  };
19787
19635
  this.updateAndEmitDCBufferStatus = kind => {
19636
+ if (kind === DataPacket_Kind.RELIABLE) {
19637
+ const dc = this.dataChannelForKind(kind);
19638
+ if (dc) {
19639
+ this.reliableMessageBuffer.alignBufferedAmount(dc.bufferedAmount);
19640
+ }
19641
+ }
19788
19642
  const status = this.isBufferStatusLow(kind);
19789
19643
  if (typeof status !== 'undefined' && status !== this.dcBufferStatus.get(kind)) {
19790
19644
  this.dcBufferStatus.set(kind, status);
@@ -19794,9 +19648,6 @@ class RTCEngine extends eventsExports.EventEmitter {
19794
19648
  this.isBufferStatusLow = kind => {
19795
19649
  const dc = this.dataChannelForKind(kind);
19796
19650
  if (dc) {
19797
- if (kind === DataPacket_Kind.RELIABLE) {
19798
- this.reliableMessageBuffer.alignBufferedAmount(dc.bufferedAmount);
19799
- }
19800
19651
  return dc.bufferedAmount <= dc.bufferedAmountLowThreshold;
19801
19652
  }
19802
19653
  };
@@ -19922,6 +19773,7 @@ class RTCEngine extends eventsExports.EventEmitter {
19922
19773
  this.removeAllListeners();
19923
19774
  this.deregisterOnLineListener();
19924
19775
  this.clearPendingReconnect();
19776
+ this.cleanupLossyDataStats();
19925
19777
  yield this.cleanupPeerConnections();
19926
19778
  yield this.cleanupClient();
19927
19779
  } finally {
@@ -19957,6 +19809,15 @@ class RTCEngine extends eventsExports.EventEmitter {
19957
19809
  this.reliableReceivedState.clear();
19958
19810
  });
19959
19811
  }
19812
+ cleanupLossyDataStats() {
19813
+ this.lossyDataStatByterate = 0;
19814
+ this.lossyDataStatCurrentBytes = 0;
19815
+ if (this.lossyDataStatInterval) {
19816
+ clearInterval(this.lossyDataStatInterval);
19817
+ this.lossyDataStatInterval = undefined;
19818
+ }
19819
+ this.lossyDataDropCount = 0;
19820
+ }
19960
19821
  cleanupClient() {
19961
19822
  return __awaiter(this, void 0, void 0, function* () {
19962
19823
  yield this.client.close();
@@ -19970,7 +19831,7 @@ class RTCEngine extends eventsExports.EventEmitter {
19970
19831
  return new Promise((resolve, reject) => {
19971
19832
  const publicationTimeout = setTimeout(() => {
19972
19833
  delete this.pendingTrackResolvers[req.cid];
19973
- reject(new ConnectionError('publication of local track timed out, no response from server', ConnectionErrorReason.Timeout));
19834
+ reject(ConnectionError.timeout('publication of local track timed out, no response from server'));
19974
19835
  }, 10000);
19975
19836
  this.pendingTrackResolvers[req.cid] = {
19976
19837
  resolve: info => {
@@ -20145,7 +20006,9 @@ class RTCEngine extends eventsExports.EventEmitter {
20145
20006
  this.emit(EngineEvent.LocalTrackSubscribed, trackSid);
20146
20007
  };
20147
20008
  this.client.onTokenRefresh = token => {
20009
+ var _a;
20148
20010
  this.token = token;
20011
+ (_a = this.regionUrlProvider) === null || _a === void 0 ? void 0 : _a.updateToken(token);
20149
20012
  };
20150
20013
  this.client.onRemoteMuteChanged = (trackSid, muted) => {
20151
20014
  this.emit(EngineEvent.RemoteMute, trackSid, muted);
@@ -20271,6 +20134,17 @@ class RTCEngine extends eventsExports.EventEmitter {
20271
20134
  // handle buffer amount low events
20272
20135
  this.lossyDC.onbufferedamountlow = this.handleBufferedAmountLow;
20273
20136
  this.reliableDC.onbufferedamountlow = this.handleBufferedAmountLow;
20137
+ this.cleanupLossyDataStats();
20138
+ this.lossyDataStatInterval = setInterval(() => {
20139
+ this.lossyDataStatByterate = this.lossyDataStatCurrentBytes;
20140
+ this.lossyDataStatCurrentBytes = 0;
20141
+ const dc = this.dataChannelForKind(DataPacket_Kind.LOSSY);
20142
+ if (dc) {
20143
+ // control buffered latency to ~100ms
20144
+ const threshold = this.lossyDataStatByterate / 10;
20145
+ dc.bufferedAmountLowThreshold = Math.min(Math.max(threshold, lossyDataChannelBufferThresholdMin), lossyDataChannelBufferThresholdMax);
20146
+ }
20147
+ }, 1000);
20274
20148
  }
20275
20149
  createSender(track, opts, encodings) {
20276
20150
  return __awaiter(this, void 0, void 0, function* () {
@@ -20557,7 +20431,7 @@ class RTCEngine extends eventsExports.EventEmitter {
20557
20431
  } catch (e) {
20558
20432
  // TODO do we need a `failed` state here for the PC?
20559
20433
  this.pcState = PCState.Disconnected;
20560
- throw new ConnectionError("could not establish PC connection, ".concat(e.message), ConnectionErrorReason.InternalError);
20434
+ throw ConnectionError.internal("could not establish PC connection, ".concat(e.message));
20561
20435
  }
20562
20436
  });
20563
20437
  }
@@ -20627,10 +20501,21 @@ class RTCEngine extends eventsExports.EventEmitter {
20627
20501
  const dc = this.dataChannelForKind(kind);
20628
20502
  if (dc) {
20629
20503
  if (kind === DataPacket_Kind.RELIABLE) {
20504
+ yield this.waitForBufferStatusLow(kind);
20630
20505
  this.reliableMessageBuffer.push({
20631
20506
  data: msg,
20632
20507
  sequence: packet.sequence
20633
20508
  });
20509
+ } else {
20510
+ // lossy channel, drop messages to reduce latency
20511
+ if (!this.isBufferStatusLow(kind)) {
20512
+ this.lossyDataDropCount += 1;
20513
+ if (this.lossyDataDropCount % 100 === 0) {
20514
+ this.log.warn("dropping lossy data channel messages, total dropped: ".concat(this.lossyDataDropCount), this.logContext);
20515
+ }
20516
+ return;
20517
+ }
20518
+ this.lossyDataStatCurrentBytes += msg.byteLength;
20634
20519
  }
20635
20520
  if (this.attemptingReconnect) {
20636
20521
  return;
@@ -20683,7 +20568,7 @@ class RTCEngine extends eventsExports.EventEmitter {
20683
20568
  const transport = subscriber ? _this2.pcManager.subscriber : _this2.pcManager.publisher;
20684
20569
  const transportName = subscriber ? 'Subscriber' : 'Publisher';
20685
20570
  if (!transport) {
20686
- throw new ConnectionError("".concat(transportName, " connection not set"), ConnectionErrorReason.InternalError);
20571
+ throw ConnectionError.internal("".concat(transportName, " connection not set"));
20687
20572
  }
20688
20573
  let needNegotiation = false;
20689
20574
  if (!subscriber && !_this2.dataChannelForKind(kind, subscriber)) {
@@ -20711,7 +20596,7 @@ class RTCEngine extends eventsExports.EventEmitter {
20711
20596
  }
20712
20597
  yield sleep(50);
20713
20598
  }
20714
- throw new ConnectionError("could not establish ".concat(transportName, " connection, state: ").concat(transport.getICEConnectionState()), ConnectionErrorReason.InternalError);
20599
+ throw ConnectionError.internal("could not establish ".concat(transportName, " connection, state: ").concat(transport.getICEConnectionState()));
20715
20600
  }();
20716
20601
  });
20717
20602
  }
@@ -20920,7 +20805,6 @@ class RTCEngine extends eventsExports.EventEmitter {
20920
20805
  }
20921
20806
  }
20922
20807
  }
20923
- class SignalReconnectError extends Error {}
20924
20808
  function supportOptionalDatachannel(protocol) {
20925
20809
  return protocol !== undefined && protocol > 13;
20926
20810
  }
@@ -20931,9 +20815,7 @@ function applyUserDataCompat(newObj, oldObj) {
20931
20815
  const destinationIdentities = newObj.destinationIdentities.length !== 0 ? newObj.destinationIdentities : oldObj.destinationIdentities;
20932
20816
  newObj.destinationIdentities = destinationIdentities;
20933
20817
  oldObj.destinationIdentities = destinationIdentities;
20934
- }
20935
-
20936
- class BaseStreamReader {
20818
+ }class BaseStreamReader {
20937
20819
  get info() {
20938
20820
  return this._info;
20939
20821
  }
@@ -21220,9 +21102,7 @@ class TextStreamReader extends BaseStreamReader {
21220
21102
  }();
21221
21103
  });
21222
21104
  }
21223
- }
21224
-
21225
- class IncomingDataStreamManager {
21105
+ }class IncomingDataStreamManager {
21226
21106
  constructor() {
21227
21107
  this.log = livekitLogger;
21228
21108
  this.byteStreamControllers = new Map();
@@ -21408,9 +21288,7 @@ class IncomingDataStreamManager {
21408
21288
  this.byteStreamControllers.delete(trailer.streamId);
21409
21289
  }
21410
21290
  }
21411
- }
21412
-
21413
- class BaseStreamWriter {
21291
+ }class BaseStreamWriter {
21414
21292
  constructor(writableStream, info, onClose) {
21415
21293
  this.writableStream = writableStream;
21416
21294
  this.defaultWriter = writableStream.getWriter();
@@ -21430,9 +21308,7 @@ class BaseStreamWriter {
21430
21308
  }
21431
21309
  }
21432
21310
  class TextStreamWriter extends BaseStreamWriter {}
21433
- class ByteStreamWriter extends BaseStreamWriter {}
21434
-
21435
- const STREAM_CHUNK_SIZE = 15000;
21311
+ class ByteStreamWriter extends BaseStreamWriter {}const STREAM_CHUNK_SIZE = 15000;
21436
21312
  /**
21437
21313
  * Manages sending custom user data via data channels.
21438
21314
  * @internal
@@ -21488,7 +21364,6 @@ class OutgoingDataStreamManager {
21488
21364
  }
21489
21365
  /**
21490
21366
  * @internal
21491
- * @experimental CAUTION, might get removed in a minor release
21492
21367
  */
21493
21368
  streamText(options) {
21494
21369
  return __awaiter(this, void 0, void 0, function* () {
@@ -21536,7 +21411,6 @@ class OutgoingDataStreamManager {
21536
21411
  write(text) {
21537
21412
  return __awaiter(this, void 0, void 0, function* () {
21538
21413
  for (const textByteChunk of splitUtf8(text, STREAM_CHUNK_SIZE)) {
21539
- yield engine.waitForBufferStatusLow(DataPacket_Kind.RELIABLE);
21540
21414
  const chunk = new DataStream_Chunk({
21541
21415
  content: textByteChunk,
21542
21416
  streamId,
@@ -21666,7 +21540,6 @@ class OutgoingDataStreamManager {
21666
21540
  try {
21667
21541
  while (byteOffset < chunk.byteLength) {
21668
21542
  const subChunk = chunk.slice(byteOffset, byteOffset + STREAM_CHUNK_SIZE);
21669
- yield engine.waitForBufferStatusLow(DataPacket_Kind.RELIABLE);
21670
21543
  const chunkPacket = new DataPacket({
21671
21544
  destinationIdentities,
21672
21545
  value: {
@@ -21710,9 +21583,7 @@ class OutgoingDataStreamManager {
21710
21583
  return byteWriter;
21711
21584
  });
21712
21585
  }
21713
- }
21714
-
21715
- class RemoteTrack extends Track {
21586
+ }class RemoteTrack extends Track {
21716
21587
  constructor(mediaTrack, sid, kind, receiver, loggerOptions) {
21717
21588
  super(mediaTrack, kind, loggerOptions);
21718
21589
  this.sid = sid;
@@ -21833,9 +21704,7 @@ class RemoteTrack extends Track {
21833
21704
  };
21834
21705
  loop();
21835
21706
  }
21836
- }
21837
-
21838
- class RemoteAudioTrack extends RemoteTrack {
21707
+ }class RemoteAudioTrack extends RemoteTrack {
21839
21708
  constructor(mediaTrack, sid, receiver, audioContext, audioOutput, loggerOptions) {
21840
21709
  super(mediaTrack, sid, Track.Kind.Audio, receiver, loggerOptions);
21841
21710
  this.monitorReceiver = () => __awaiter(this, void 0, void 0, function* () {
@@ -22034,9 +21903,7 @@ class RemoteAudioTrack extends RemoteTrack {
22034
21903
  return receiverStats;
22035
21904
  });
22036
21905
  }
22037
- }
22038
-
22039
- const REACTION_DELAY = 100;
21906
+ }const REACTION_DELAY = 100;
22040
21907
  class RemoteVideoTrack extends RemoteTrack {
22041
21908
  constructor(mediaTrack, sid, receiver, adaptiveStreamSettings, loggerOptions) {
22042
21909
  super(mediaTrack, sid, Track.Kind.Video, receiver, loggerOptions);
@@ -22376,9 +22243,7 @@ function isElementInViewport(el, win) {
22376
22243
  left += el.offsetLeft;
22377
22244
  }
22378
22245
  return top < viewportWindow.pageYOffset + viewportWindow.innerHeight && left < viewportWindow.pageXOffset + viewportWindow.innerWidth && top + height > viewportWindow.pageYOffset && left + width > viewportWindow.pageXOffset && !hidden && display !== 'none';
22379
- }
22380
-
22381
- class TrackPublication extends eventsExports.EventEmitter {
22246
+ }class TrackPublication extends eventsExports.EventEmitter {
22382
22247
  constructor(kind, id, name, loggerOptions) {
22383
22248
  var _a;
22384
22249
  super();
@@ -22474,9 +22339,7 @@ class TrackPublication extends eventsExports.EventEmitter {
22474
22339
  PermissionStatus["Allowed"] = "allowed";
22475
22340
  PermissionStatus["NotAllowed"] = "not_allowed";
22476
22341
  })(TrackPublication.PermissionStatus || (TrackPublication.PermissionStatus = {}));
22477
- })(TrackPublication || (TrackPublication = {}));
22478
-
22479
- class LocalTrackPublication extends TrackPublication {
22342
+ })(TrackPublication || (TrackPublication = {}));class LocalTrackPublication extends TrackPublication {
22480
22343
  get isUpstreamPaused() {
22481
22344
  var _a;
22482
22345
  return (_a = this.track) === null || _a === void 0 ? void 0 : _a.isUpstreamPaused;
@@ -22586,9 +22449,7 @@ class LocalTrackPublication extends TrackPublication {
22586
22449
  return Array.from(features.values());
22587
22450
  } else return [];
22588
22451
  }
22589
- }
22590
-
22591
- /**
22452
+ }/**
22592
22453
  * Creates a local video and audio track at the same time. When acquiring both
22593
22454
  * audio and video tracks together, it'll display a single permission prompt to
22594
22455
  * the user instead of two separate ones.
@@ -22636,10 +22497,14 @@ function createLocalTracks(options, loggerOptions) {
22636
22497
  }
22637
22498
  });
22638
22499
  }
22639
- if (internalOptions.audio === true || typeof internalOptions.audio === 'object' && !internalOptions.audio.deviceId) {
22500
+ if (internalOptions.audio === true) {
22640
22501
  internalOptions.audio = {
22641
22502
  deviceId: 'default'
22642
22503
  };
22504
+ } else if (typeof internalOptions.audio === 'object' && internalOptions.audio !== null) {
22505
+ internalOptions.audio = Object.assign(Object.assign({}, internalOptions.audio), {
22506
+ deviceId: internalOptions.audio.deviceId || 'default'
22507
+ });
22643
22508
  }
22644
22509
  if (internalOptions.video === true) {
22645
22510
  internalOptions.video = {
@@ -22763,9 +22628,7 @@ function createLocalScreenTracks(options) {
22763
22628
  }
22764
22629
  return localTracks;
22765
22630
  });
22766
- }
22767
-
22768
- var ConnectionQuality;
22631
+ }var ConnectionQuality;
22769
22632
  (function (ConnectionQuality) {
22770
22633
  ConnectionQuality["Excellent"] = "excellent";
22771
22634
  ConnectionQuality["Good"] = "good";
@@ -23035,9 +22898,7 @@ class Participant extends eventsExports.EventEmitter {
23035
22898
  break;
23036
22899
  }
23037
22900
  }
23038
- }
23039
-
23040
- function trackPermissionToProto(perms) {
22901
+ }function trackPermissionToProto(perms) {
23041
22902
  var _a, _b, _c;
23042
22903
  if (!perms.participantSid && !perms.participantIdentity) {
23043
22904
  throw new Error('Invalid track permission, must provide at least one of participantIdentity and participantSid');
@@ -23048,9 +22909,7 @@ function trackPermissionToProto(perms) {
23048
22909
  allTracks: (_c = perms.allowAll) !== null && _c !== void 0 ? _c : false,
23049
22910
  trackSids: perms.allowedTrackSids || []
23050
22911
  });
23051
- }
23052
-
23053
- class LocalParticipant extends Participant {
22912
+ }class LocalParticipant extends Participant {
23054
22913
  /** @internal */
23055
22914
  constructor(sid, identity, engine, options, roomRpcHandlers, roomOutgoingDataStreamManager) {
23056
22915
  super(sid, identity, undefined, undefined, undefined, {
@@ -23080,14 +22939,14 @@ class LocalParticipant extends Participant {
23080
22939
  var _a, _b, _c, _d, _e, _f;
23081
22940
  if (this.reconnectFuture) {
23082
22941
  this.reconnectFuture.promise.catch(e => this.log.warn(e.message, this.logContext));
23083
- (_b = (_a = this.reconnectFuture) === null || _a === void 0 ? void 0 : _a.reject) === null || _b === void 0 ? void 0 : _b.call(_a, 'Got disconnected during reconnection attempt');
22942
+ (_b = (_a = this.reconnectFuture) === null || _a === void 0 ? void 0 : _a.reject) === null || _b === void 0 ? void 0 : _b.call(_a, new Error('Got disconnected during reconnection attempt'));
23084
22943
  this.reconnectFuture = undefined;
23085
22944
  }
23086
22945
  if (this.signalConnectedFuture) {
23087
- (_d = (_c = this.signalConnectedFuture).reject) === null || _d === void 0 ? void 0 : _d.call(_c, 'Got disconnected without signal connected');
22946
+ (_d = (_c = this.signalConnectedFuture).reject) === null || _d === void 0 ? void 0 : _d.call(_c, new Error('Got disconnected without signal connected'));
23088
22947
  this.signalConnectedFuture = undefined;
23089
22948
  }
23090
- (_f = (_e = this.activeAgentFuture) === null || _e === void 0 ? void 0 : _e.reject) === null || _f === void 0 ? void 0 : _f.call(_e, 'Got disconnected without active agent present');
22949
+ (_f = (_e = this.activeAgentFuture) === null || _e === void 0 ? void 0 : _e.reject) === null || _f === void 0 ? void 0 : _f.call(_e, new Error('Got disconnected without active agent present'));
23091
22950
  this.activeAgentFuture = undefined;
23092
22951
  this.firstActiveAgent = undefined;
23093
22952
  };
@@ -24572,7 +24431,7 @@ class LocalParticipant extends Participant {
24572
24431
  resolve: (responsePayload, responseError) => {
24573
24432
  clearTimeout(responseTimeoutId);
24574
24433
  if (this.pendingAcks.has(id)) {
24575
- console.warn('RPC response received before ack', id);
24434
+ this.log.warn('RPC response received before ack', id);
24576
24435
  this.pendingAcks.delete(id);
24577
24436
  clearTimeout(ackTimeoutId);
24578
24437
  }
@@ -24722,7 +24581,7 @@ class LocalParticipant extends Participant {
24722
24581
  if (agent) {
24723
24582
  (_b = (_a = this.activeAgentFuture) === null || _a === void 0 ? void 0 : _a.resolve) === null || _b === void 0 ? void 0 : _b.call(_a, agent);
24724
24583
  } else {
24725
- (_d = (_c = this.activeAgentFuture) === null || _c === void 0 ? void 0 : _c.reject) === null || _d === void 0 ? void 0 : _d.call(_c, 'Agent disconnected');
24584
+ (_d = (_c = this.activeAgentFuture) === null || _c === void 0 ? void 0 : _c.reject) === null || _d === void 0 ? void 0 : _d.call(_c, new Error('Agent disconnected'));
24726
24585
  }
24727
24586
  this.activeAgentFuture = undefined;
24728
24587
  }
@@ -24771,9 +24630,7 @@ class LocalParticipant extends Participant {
24771
24630
  }
24772
24631
  });
24773
24632
  }
24774
- }
24775
-
24776
- class RemoteTrackPublication extends TrackPublication {
24633
+ }class RemoteTrackPublication extends TrackPublication {
24777
24634
  constructor(kind, ti, autoSubscribe, loggerOptions) {
24778
24635
  super(kind, ti.sid, ti.name, loggerOptions);
24779
24636
  this.track = undefined;
@@ -25043,9 +24900,7 @@ class RemoteTrackPublication extends TrackPublication {
25043
24900
  }
25044
24901
  this.emit(TrackEvent.UpdateSettings, settings);
25045
24902
  }
25046
- }
25047
-
25048
- class RemoteParticipant extends Participant {
24903
+ }class RemoteParticipant extends Participant {
25049
24904
  /** @internal */
25050
24905
  static fromParticipantInfo(signalClient, pi, loggerOptions) {
25051
24906
  return new RemoteParticipant(signalClient, pi.sid, pi.identity, pi.name, pi.metadata, pi.attributes, loggerOptions, pi.kind);
@@ -25310,9 +25165,7 @@ class RemoteParticipant extends Participant {
25310
25165
  }));
25311
25166
  return super.emit(event, ...args);
25312
25167
  }
25313
- }
25314
-
25315
- var ConnectionState;
25168
+ }var ConnectionState;
25316
25169
  (function (ConnectionState) {
25317
25170
  ConnectionState["Disconnected"] = "disconnected";
25318
25171
  ConnectionState["Connecting"] = "connecting";
@@ -25378,7 +25231,7 @@ class Room extends eventsExports.EventEmitter {
25378
25231
  return this.connectFuture.promise;
25379
25232
  }
25380
25233
  this.setAndEmitConnectionState(ConnectionState.Connecting);
25381
- if (((_a = this.regionUrlProvider) === null || _a === void 0 ? void 0 : _a.getServerUrl().toString()) !== url) {
25234
+ if (((_a = this.regionUrlProvider) === null || _a === void 0 ? void 0 : _a.getServerUrl().toString()) !== ensureTrailingSlash(url)) {
25382
25235
  this.regionUrl = undefined;
25383
25236
  this.regionUrlProvider = undefined;
25384
25237
  }
@@ -25413,7 +25266,7 @@ class Room extends eventsExports.EventEmitter {
25413
25266
  try {
25414
25267
  yield BackOffStrategy.getInstance().getBackOffPromise(url);
25415
25268
  if (abortController.signal.aborted) {
25416
- throw new ConnectionError('Connection attempt aborted', ConnectionErrorReason.Cancelled);
25269
+ throw ConnectionError.cancelled('Connection attempt aborted');
25417
25270
  }
25418
25271
  yield this.attemptConnection(regionUrl !== null && regionUrl !== void 0 ? regionUrl : url, token, opts, abortController);
25419
25272
  this.abortController = undefined;
@@ -25550,7 +25403,7 @@ class Room extends eventsExports.EventEmitter {
25550
25403
  } catch (err) {
25551
25404
  yield this.engine.close();
25552
25405
  this.recreateEngine();
25553
- const resultingError = new ConnectionError("could not establish signal connection", abortController.signal.aborted ? ConnectionErrorReason.Cancelled : ConnectionErrorReason.ServerUnreachable);
25406
+ const resultingError = abortController.signal.aborted ? ConnectionError.cancelled('Signal connection aborted') : ConnectionError.serverUnreachable('could not establish signal connection');
25554
25407
  if (err instanceof Error) {
25555
25408
  resultingError.message = "".concat(resultingError.message, ": ").concat(err.message);
25556
25409
  }
@@ -25566,7 +25419,7 @@ class Room extends eventsExports.EventEmitter {
25566
25419
  if (abortController.signal.aborted) {
25567
25420
  yield this.engine.close();
25568
25421
  this.recreateEngine();
25569
- throw new ConnectionError("Connection attempt aborted", ConnectionErrorReason.Cancelled);
25422
+ throw ConnectionError.cancelled("Connection attempt aborted");
25570
25423
  }
25571
25424
  try {
25572
25425
  yield this.engine.waitForPCInitialConnection(this.connOptions.peerConnectionTimeout, abortController);
@@ -25582,12 +25435,16 @@ class Room extends eventsExports.EventEmitter {
25582
25435
  window.addEventListener('beforeunload', this.onPageLeave);
25583
25436
  }
25584
25437
  if (isWeb()) {
25585
- document.addEventListener('freeze', this.onPageLeave);
25438
+ window.addEventListener('freeze', this.onPageLeave);
25586
25439
  }
25587
25440
  this.setAndEmitConnectionState(ConnectionState.Connected);
25588
25441
  this.emit(RoomEvent.Connected);
25589
25442
  BackOffStrategy.getInstance().resetFailedConnectionAttempts(url);
25590
25443
  this.registerConnectionReconcile();
25444
+ // Notify region provider about successful connection
25445
+ if (this.regionUrlProvider) {
25446
+ this.regionUrlProvider.notifyConnected();
25447
+ }
25591
25448
  });
25592
25449
  /**
25593
25450
  * disconnects the room, emits [[RoomEvent.Disconnected]]
@@ -25614,7 +25471,7 @@ class Room extends eventsExports.EventEmitter {
25614
25471
  _this2.log.warn(msg, _this2.logContext);
25615
25472
  (_a = _this2.abortController) === null || _a === void 0 ? void 0 : _a.abort(msg);
25616
25473
  // in case the abort controller didn't manage to cancel the connection attempt, reject the connect promise explicitly
25617
- (_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));
25474
+ (_c = (_b = _this2.connectFuture) === null || _b === void 0 ? void 0 : _b.reject) === null || _c === void 0 ? void 0 : _c.call(_b, ConnectionError.cancelled('Client initiated disconnect'));
25618
25475
  _this2.connectFuture = undefined;
25619
25476
  }
25620
25477
  // close engine (also closes client)
@@ -26743,6 +26600,10 @@ class Room extends eventsExports.EventEmitter {
26743
26600
  return;
26744
26601
  }
26745
26602
  this.regionUrl = undefined;
26603
+ // Notify region provider about disconnect to potentially stop auto-refetch
26604
+ if (this.regionUrlProvider) {
26605
+ this.regionUrlProvider.notifyDisconnected();
26606
+ }
26746
26607
  try {
26747
26608
  this.remoteParticipants.forEach(p => {
26748
26609
  p.trackPublications.forEach(pub => {
@@ -26821,7 +26682,7 @@ class Room extends eventsExports.EventEmitter {
26821
26682
  });
26822
26683
  if (byteLength(response) > MAX_PAYLOAD_BYTES) {
26823
26684
  responseError = RpcError.builtIn('RESPONSE_PAYLOAD_TOO_LARGE');
26824
- console.warn("RPC Response payload too large for ".concat(method));
26685
+ this.log.warn("RPC Response payload too large for ".concat(method));
26825
26686
  } else {
26826
26687
  responsePayload = response;
26827
26688
  }
@@ -26829,7 +26690,7 @@ class Room extends eventsExports.EventEmitter {
26829
26690
  if (error instanceof RpcError) {
26830
26691
  responseError = error;
26831
26692
  } else {
26832
- console.warn("Uncaught error returned by RPC handler for ".concat(method, ". Returning APPLICATION_ERROR instead."), error);
26693
+ this.log.warn("Uncaught error returned by RPC handler for ".concat(method, ". Returning APPLICATION_ERROR instead."), error);
26833
26694
  responseError = RpcError.builtIn('APPLICATION_ERROR');
26834
26695
  }
26835
26696
  }
@@ -27250,9 +27111,7 @@ function mapArgs(args) {
27250
27111
  }
27251
27112
  return arg;
27252
27113
  });
27253
- }
27254
-
27255
- // This file was generated from JSON Schema using quicktype, do not modify it directly.
27114
+ }// This file was generated from JSON Schema using quicktype, do not modify it directly.
27256
27115
  // The code generation lives at https://github.com/livekit/attribute-definitions
27257
27116
  //
27258
27117
  // To parse this data:
@@ -27275,14 +27134,7 @@ class Convert {
27275
27134
  static transcriptionAttributesToJson(value) {
27276
27135
  return JSON.stringify(value);
27277
27136
  }
27278
- }
27279
-
27280
- var attributeTypings = /*#__PURE__*/Object.freeze({
27281
- __proto__: null,
27282
- Convert: Convert
27283
- });
27284
-
27285
- var CheckStatus;
27137
+ }var attributeTypings=/*#__PURE__*/Object.freeze({__proto__:null,Convert:Convert});var CheckStatus;
27286
27138
  (function (CheckStatus) {
27287
27139
  CheckStatus[CheckStatus["IDLE"] = 0] = "IDLE";
27288
27140
  CheckStatus[CheckStatus["RUNNING"] = 1] = "RUNNING";
@@ -27425,9 +27277,7 @@ class Checker extends eventsExports.EventEmitter {
27425
27277
  description: this.description
27426
27278
  };
27427
27279
  }
27428
- }
27429
-
27430
- /**
27280
+ }/**
27431
27281
  * Checks for connections quality to closests Cloud regions and determining the best quality
27432
27282
  */
27433
27283
  class CloudRegionCheck extends Checker {
@@ -27508,9 +27358,7 @@ class CloudRegionCheck extends Checker {
27508
27358
  return regionStats;
27509
27359
  });
27510
27360
  }
27511
- }
27512
-
27513
- const TEST_DURATION = 10000;
27361
+ }const TEST_DURATION = 10000;
27514
27362
  class ConnectionProtocolCheck extends Checker {
27515
27363
  get description() {
27516
27364
  return 'Connection via UDP vs TCP';
@@ -27620,9 +27468,7 @@ class ConnectionProtocolCheck extends Checker {
27620
27468
  return protocolStats;
27621
27469
  });
27622
27470
  }
27623
- }
27624
-
27625
- class PublishAudioCheck extends Checker {
27471
+ }class PublishAudioCheck extends Checker {
27626
27472
  get description() {
27627
27473
  return 'Can publish audio';
27628
27474
  }
@@ -27656,9 +27502,7 @@ class PublishAudioCheck extends Checker {
27656
27502
  this.appendMessage("published ".concat(numPackets, " audio packets"));
27657
27503
  });
27658
27504
  }
27659
- }
27660
-
27661
- class PublishVideoCheck extends Checker {
27505
+ }class PublishVideoCheck extends Checker {
27662
27506
  get description() {
27663
27507
  return 'Can publish video';
27664
27508
  }
@@ -27739,9 +27583,7 @@ class PublishVideoCheck extends Checker {
27739
27583
  video.remove();
27740
27584
  });
27741
27585
  }
27742
- }
27743
-
27744
- class ReconnectCheck extends Checker {
27586
+ }class ReconnectCheck extends Checker {
27745
27587
  get description() {
27746
27588
  return 'Resuming connection after interruption';
27747
27589
  }
@@ -27777,15 +27619,17 @@ class ReconnectCheck extends Checker {
27777
27619
  }
27778
27620
  });
27779
27621
  }
27780
- }
27781
-
27782
- class TURNCheck extends Checker {
27622
+ }class TURNCheck extends Checker {
27783
27623
  get description() {
27784
27624
  return 'Can connect via TURN';
27785
27625
  }
27786
27626
  perform() {
27787
27627
  return __awaiter(this, void 0, void 0, function* () {
27788
- var _a, _b;
27628
+ var _a, _b, _c;
27629
+ if (isCloud(new URL(this.url))) {
27630
+ this.appendMessage('Using region specific url');
27631
+ this.url = (_a = yield new RegionUrlProvider(this.url, this.token).getNextBestRegionUrl()) !== null && _a !== void 0 ? _a : this.url;
27632
+ }
27789
27633
  const signalClient = new SignalClient();
27790
27634
  const joinRes = yield signalClient.join(this.url, this.token, {
27791
27635
  autoSubscribe: true,
@@ -27818,7 +27662,7 @@ class TURNCheck extends Checker {
27818
27662
  this.appendWarning('TURN is configured server side, but TURN/TLS is unavailable.');
27819
27663
  }
27820
27664
  yield signalClient.close();
27821
- if (((_b = (_a = this.connectOptions) === null || _a === void 0 ? void 0 : _a.rtcConfig) === null || _b === void 0 ? void 0 : _b.iceServers) || hasTURN) {
27665
+ if (((_c = (_b = this.connectOptions) === null || _b === void 0 ? void 0 : _b.rtcConfig) === null || _c === void 0 ? void 0 : _c.iceServers) || hasTURN) {
27822
27666
  yield this.room.connect(this.url, this.token, {
27823
27667
  rtcConfig: {
27824
27668
  iceTransportPolicy: 'relay'
@@ -27831,9 +27675,7 @@ class TURNCheck extends Checker {
27831
27675
  }
27832
27676
  });
27833
27677
  }
27834
- }
27835
-
27836
- class WebRTCCheck extends Checker {
27678
+ }class WebRTCCheck extends Checker {
27837
27679
  get description() {
27838
27680
  return 'Establishing WebRTC connection';
27839
27681
  }
@@ -27905,9 +27747,7 @@ function isIPPrivate(address) {
27905
27747
  }
27906
27748
  }
27907
27749
  return false;
27908
- }
27909
-
27910
- class WebSocketCheck extends Checker {
27750
+ }class WebSocketCheck extends Checker {
27911
27751
  get description() {
27912
27752
  return 'Connecting to signal connection via WebSocket';
27913
27753
  }
@@ -27918,23 +27758,44 @@ class WebSocketCheck extends Checker {
27918
27758
  this.appendWarning('Server is insecure, clients may block connections to it');
27919
27759
  }
27920
27760
  let signalClient = new SignalClient();
27921
- const joinRes = yield signalClient.join(this.url, this.token, {
27922
- autoSubscribe: true,
27923
- maxRetries: 0,
27924
- e2eeEnabled: false,
27925
- websocketTimeout: 15000,
27926
- singlePeerConnection: false
27927
- });
27928
- this.appendMessage("Connected to server, version ".concat(joinRes.serverVersion, "."));
27929
- 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)) {
27930
- this.appendMessage("LiveKit Cloud: ".concat((_c = joinRes.serverInfo) === null || _c === void 0 ? void 0 : _c.region));
27761
+ let joinRes;
27762
+ try {
27763
+ joinRes = yield signalClient.join(this.url, this.token, {
27764
+ autoSubscribe: true,
27765
+ maxRetries: 0,
27766
+ e2eeEnabled: false,
27767
+ websocketTimeout: 15000,
27768
+ singlePeerConnection: false
27769
+ });
27770
+ } catch (e) {
27771
+ if (isCloud(new URL(this.url))) {
27772
+ this.appendMessage("Initial connection failed with error ".concat(e.message, ". Retrying with region fallback"));
27773
+ const regionProvider = new RegionUrlProvider(this.url, this.token);
27774
+ const regionUrl = yield regionProvider.getNextBestRegionUrl();
27775
+ if (regionUrl) {
27776
+ joinRes = yield signalClient.join(regionUrl, this.token, {
27777
+ autoSubscribe: true,
27778
+ maxRetries: 0,
27779
+ e2eeEnabled: false,
27780
+ websocketTimeout: 15000,
27781
+ singlePeerConnection: false
27782
+ });
27783
+ this.appendMessage("Fallback to region worked. To avoid initial connections failing, ensure you're calling room.prepareConnection() ahead of time");
27784
+ }
27785
+ }
27786
+ }
27787
+ if (joinRes) {
27788
+ this.appendMessage("Connected to server, version ".concat(joinRes.serverVersion, "."));
27789
+ 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)) {
27790
+ this.appendMessage("LiveKit Cloud: ".concat((_c = joinRes.serverInfo) === null || _c === void 0 ? void 0 : _c.region));
27791
+ }
27792
+ } else {
27793
+ this.appendError("Websocket connection could not be established");
27931
27794
  }
27932
27795
  yield signalClient.close();
27933
27796
  });
27934
27797
  }
27935
- }
27936
-
27937
- class ConnectionCheck extends eventsExports.EventEmitter {
27798
+ }class ConnectionCheck extends eventsExports.EventEmitter {
27938
27799
  constructor(url, token) {
27939
27800
  let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
27940
27801
  super();
@@ -28022,9 +27883,7 @@ class ConnectionCheck extends eventsExports.EventEmitter {
28022
27883
  return this.createAndRunCheck(CloudRegionCheck);
28023
27884
  });
28024
27885
  }
28025
- }
28026
-
28027
- /** A Fixed TokenSource is a token source that takes no parameters and returns a completely
27886
+ }/** A Fixed TokenSource is a token source that takes no parameters and returns a completely
28028
27887
  * independently derived value on each fetch() call.
28029
27888
  *
28030
27889
  * The most common downstream implementer is {@link TokenSourceLiteral}.
@@ -28041,9 +27900,7 @@ class TokenSourceFixed {}
28041
27900
  * A few common downstream implementers are {@link TokenSourceEndpoint}
28042
27901
  * and {@link TokenSourceCustom}.
28043
27902
  */
28044
- class TokenSourceConfigurable {}
28045
-
28046
- function _defineProperty(e, r, t) {
27903
+ class TokenSourceConfigurable {}function _defineProperty(e, r, t) {
28047
27904
  return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
28048
27905
  value: t,
28049
27906
  enumerable: true,
@@ -28064,12 +27921,8 @@ function _toPrimitive(t, r) {
28064
27921
  function _toPropertyKey(t) {
28065
27922
  var i = _toPrimitive(t, "string");
28066
27923
  return "symbol" == typeof i ? i : i + "";
28067
- }
28068
-
28069
- new TextEncoder();
28070
- const decoder = new TextDecoder();
28071
-
28072
- function decodeBase64(encoded) {
27924
+ }new TextEncoder();
27925
+ const decoder = new TextDecoder();function decodeBase64(encoded) {
28073
27926
  if (Uint8Array.fromBase64) {
28074
27927
  return Uint8Array.fromBase64(encoded);
28075
27928
  }
@@ -28079,9 +27932,7 @@ function decodeBase64(encoded) {
28079
27932
  bytes[i] = binary.charCodeAt(i);
28080
27933
  }
28081
27934
  return bytes;
28082
- }
28083
-
28084
- function decode(input) {
27935
+ }function decode(input) {
28085
27936
  if (Uint8Array.fromBase64) {
28086
27937
  return Uint8Array.fromBase64(typeof input === 'string' ? input : decoder.decode(input), {
28087
27938
  alphabet: 'base64url'
@@ -28091,15 +27942,13 @@ function decode(input) {
28091
27942
  if (encoded instanceof Uint8Array) {
28092
27943
  encoded = decoder.decode(encoded);
28093
27944
  }
28094
- encoded = encoded.replace(/-/g, '+').replace(/_/g, '/').replace(/\s/g, '');
27945
+ encoded = encoded.replace(/-/g, '+').replace(/_/g, '/');
28095
27946
  try {
28096
27947
  return decodeBase64(encoded);
28097
27948
  } catch (_unused) {
28098
27949
  throw new TypeError('The input to be decoded is not correctly encoded.');
28099
27950
  }
28100
- }
28101
-
28102
- class JOSEError extends Error {
27951
+ }class JOSEError extends Error {
28103
27952
  constructor(message, options) {
28104
27953
  var _Error$captureStackTr;
28105
27954
  super(message, options);
@@ -28245,12 +28094,8 @@ class JWSSignatureVerificationFailed extends JOSEError {
28245
28094
  _defineProperty(this, "code", 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED');
28246
28095
  }
28247
28096
  }
28248
- _defineProperty(JWSSignatureVerificationFailed, "code", 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED');
28249
-
28250
- function isObjectLike(value) {
28251
- return typeof value === 'object' && value !== null;
28252
- }
28253
- var isObject = input => {
28097
+ _defineProperty(JWSSignatureVerificationFailed, "code", 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED');const isObjectLike = value => typeof value === 'object' && value !== null;
28098
+ function isObject(input) {
28254
28099
  if (!isObjectLike(input) || Object.prototype.toString.call(input) !== '[object Object]') {
28255
28100
  return false;
28256
28101
  }
@@ -28262,9 +28107,7 @@ var isObject = input => {
28262
28107
  proto = Object.getPrototypeOf(proto);
28263
28108
  }
28264
28109
  return Object.getPrototypeOf(input) === proto;
28265
- };
28266
-
28267
- function decodeJwt(jwt) {
28110
+ }function decodeJwt(jwt) {
28268
28111
  if (typeof jwt !== 'string') throw new JWTInvalid('JWTs must use Compact JWS serialization, JWT must be a string');
28269
28112
  const {
28270
28113
  1: payload,
@@ -28287,9 +28130,7 @@ function decodeJwt(jwt) {
28287
28130
  }
28288
28131
  if (!isObject(result)) throw new JWTInvalid('Invalid JWT Claims Set');
28289
28132
  return result;
28290
- }
28291
-
28292
- const ONE_SECOND_IN_MILLISECONDS = 1000;
28133
+ }const ONE_SECOND_IN_MILLISECONDS = 1000;
28293
28134
  const ONE_MINUTE_IN_MILLISECONDS = 60 * ONE_SECOND_IN_MILLISECONDS;
28294
28135
  function isResponseTokenValid(response) {
28295
28136
  const jwtPayload = decodeTokenPayload(response.participantToken);
@@ -28338,9 +28179,7 @@ function areTokenSourceFetchOptionsEqual(a, b) {
28338
28179
  }
28339
28180
  }
28340
28181
  return true;
28341
- }
28342
-
28343
- /** A TokenSourceCached is a TokenSource which caches the last {@link TokenSourceResponseObject} value and returns it
28182
+ }/** A TokenSourceCached is a TokenSource which caches the last {@link TokenSourceResponseObject} value and returns it
28344
28183
  * until a) it expires or b) the {@link TokenSourceFetchOptions} provided to .fetch(...) change. */
28345
28184
  class TokenSourceCached extends TokenSourceConfigurable {
28346
28185
  constructor() {
@@ -28545,7 +28384,7 @@ const TokenSource = {
28545
28384
  /**
28546
28385
  * TokenSource.endpoint creates a token source that fetches credentials from a given URL using
28547
28386
  * the standard endpoint format:
28548
- * FIXME: add docs link here in the future!
28387
+ * @see https://cloud.livekit.io/projects/p_/sandbox/templates/token-server
28549
28388
  */
28550
28389
  endpoint(url) {
28551
28390
  let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
@@ -28564,9 +28403,7 @@ const TokenSource = {
28564
28403
  let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
28565
28404
  return new TokenSourceSandboxTokenServer(sandboxId, options);
28566
28405
  }
28567
- };
28568
-
28569
- /**
28406
+ };/**
28570
28407
  * Try to analyze the local track to determine the facing mode of a track.
28571
28408
  *
28572
28409
  * @remarks
@@ -28645,7 +28482,4 @@ function facingModeFromDeviceLabel(deviceLabel) {
28645
28482
  function isFacingModeValue(item) {
28646
28483
  const allowedValues = ['user', 'environment', 'left', 'right'];
28647
28484
  return item === undefined || allowedValues.includes(item);
28648
- }
28649
-
28650
- 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, 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 };
28651
- //# sourceMappingURL=livekit-client.esm.mjs.map
28485
+ }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,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