livekit-client 2.0.10 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/livekit-client.e2ee.worker.js +1 -1
  2. package/dist/livekit-client.e2ee.worker.js.map +1 -1
  3. package/dist/livekit-client.e2ee.worker.mjs +203 -140
  4. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  5. package/dist/livekit-client.esm.mjs +3876 -6838
  6. package/dist/livekit-client.esm.mjs.map +1 -1
  7. package/dist/livekit-client.umd.js +1 -1
  8. package/dist/livekit-client.umd.js.map +1 -1
  9. package/dist/src/api/SignalClient.d.ts +2 -1
  10. package/dist/src/api/SignalClient.d.ts.map +1 -1
  11. package/dist/src/connectionHelper/ConnectionCheck.d.ts +3 -2
  12. package/dist/src/connectionHelper/ConnectionCheck.d.ts.map +1 -1
  13. package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
  14. package/dist/src/index.d.ts +3 -2
  15. package/dist/src/index.d.ts.map +1 -1
  16. package/dist/src/room/RTCEngine.d.ts +1 -0
  17. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  18. package/dist/src/room/events.d.ts +5 -1
  19. package/dist/src/room/events.d.ts.map +1 -1
  20. package/dist/src/room/participant/LocalParticipant.d.ts +1 -0
  21. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  22. package/dist/src/room/participant/publishUtils.d.ts.map +1 -1
  23. package/dist/src/room/track/LocalAudioTrack.d.ts +7 -0
  24. package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
  25. package/dist/src/room/track/LocalTrackPublication.d.ts +3 -2
  26. package/dist/src/room/track/LocalTrackPublication.d.ts.map +1 -1
  27. package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
  28. package/dist/src/room/track/Track.d.ts +2 -1
  29. package/dist/src/room/track/Track.d.ts.map +1 -1
  30. package/dist/src/room/track/options.d.ts +1 -1
  31. package/dist/src/room/track/options.d.ts.map +1 -1
  32. package/dist/src/room/utils.d.ts +3 -0
  33. package/dist/src/room/utils.d.ts.map +1 -1
  34. package/dist/ts4.2/src/api/SignalClient.d.ts +2 -1
  35. package/dist/ts4.2/src/connectionHelper/ConnectionCheck.d.ts +3 -2
  36. package/dist/ts4.2/src/index.d.ts +3 -2
  37. package/dist/ts4.2/src/room/RTCEngine.d.ts +1 -0
  38. package/dist/ts4.2/src/room/events.d.ts +5 -1
  39. package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +1 -0
  40. package/dist/ts4.2/src/room/track/LocalAudioTrack.d.ts +7 -0
  41. package/dist/ts4.2/src/room/track/LocalTrackPublication.d.ts +3 -2
  42. package/dist/ts4.2/src/room/track/Track.d.ts +2 -1
  43. package/dist/ts4.2/src/room/track/options.d.ts +1 -1
  44. package/dist/ts4.2/src/room/utils.d.ts +3 -0
  45. package/package.json +10 -10
  46. package/src/api/SignalClient.ts +9 -0
  47. package/src/connectionHelper/ConnectionCheck.ts +6 -3
  48. package/src/e2ee/worker/FrameCryptor.ts +0 -1
  49. package/src/e2ee/worker/e2ee.worker.ts +3 -1
  50. package/src/index.ts +3 -0
  51. package/src/room/RTCEngine.ts +11 -1
  52. package/src/room/events.ts +5 -0
  53. package/src/room/participant/LocalParticipant.ts +14 -0
  54. package/src/room/participant/publishUtils.ts +2 -1
  55. package/src/room/track/LocalAudioTrack.ts +40 -0
  56. package/src/room/track/LocalTrackPublication.ts +28 -2
  57. package/src/room/track/LocalVideoTrack.ts +7 -3
  58. package/src/room/track/Track.ts +13 -0
  59. package/src/room/track/options.ts +22 -1
  60. package/src/room/utils.ts +3 -0
@@ -55,6 +55,8 @@ var loglevel = {exports: {}};
55
55
  var undefinedType = "undefined";
56
56
  var isIE = typeof window !== undefinedType && typeof window.navigator !== undefinedType && /Trident\/|MSIE /.test(window.navigator.userAgent);
57
57
  var logMethods = ["trace", "debug", "info", "warn", "error"];
58
+ var _loggersByName = {};
59
+ var defaultLogger = null;
58
60
 
59
61
  // Cross-browser bind equivalent that works at least back to IE6
60
62
  function bindMethod(obj, methodName) {
@@ -107,23 +109,31 @@ var loglevel = {exports: {}};
107
109
 
108
110
  // These private functions always need `this` to be set properly
109
111
 
110
- function replaceLoggingMethods(level, loggerName) {
112
+ function replaceLoggingMethods() {
111
113
  /*jshint validthis:true */
114
+ var level = this.getLevel();
115
+
116
+ // Replace the actual methods.
112
117
  for (var i = 0; i < logMethods.length; i++) {
113
118
  var methodName = logMethods[i];
114
- this[methodName] = i < level ? noop : this.methodFactory(methodName, level, loggerName);
119
+ this[methodName] = i < level ? noop : this.methodFactory(methodName, level, this.name);
115
120
  }
116
121
 
117
122
  // Define log.log as an alias for log.debug
118
123
  this.log = this.debug;
124
+
125
+ // Return any important warnings.
126
+ if (typeof console === undefinedType && level < this.levels.SILENT) {
127
+ return "No console available for logging";
128
+ }
119
129
  }
120
130
 
121
131
  // In old IE versions, the console isn't present until you first open it.
122
132
  // We build realMethod() replacements here that regenerate logging methods
123
- function enableLoggingWhenConsoleArrives(methodName, level, loggerName) {
133
+ function enableLoggingWhenConsoleArrives(methodName) {
124
134
  return function () {
125
135
  if (typeof console !== undefinedType) {
126
- replaceLoggingMethods.call(this, level, loggerName);
136
+ replaceLoggingMethods.call(this);
127
137
  this[methodName].apply(this, arguments);
128
138
  }
129
139
  };
@@ -131,14 +141,34 @@ var loglevel = {exports: {}};
131
141
 
132
142
  // By default, we use closely bound real methods wherever possible, and
133
143
  // otherwise we wait for a console to appear, and then try again.
134
- function defaultMethodFactory(methodName, level, loggerName) {
144
+ function defaultMethodFactory(methodName, _level, _loggerName) {
135
145
  /*jshint validthis:true */
136
146
  return realMethod(methodName) || enableLoggingWhenConsoleArrives.apply(this, arguments);
137
147
  }
138
- function Logger(name, defaultLevel, factory) {
148
+ function Logger(name, factory) {
149
+ // Private instance variables.
139
150
  var self = this;
140
- var currentLevel;
141
- defaultLevel = defaultLevel == null ? "WARN" : defaultLevel;
151
+ /**
152
+ * The level inherited from a parent logger (or a global default). We
153
+ * cache this here rather than delegating to the parent so that it stays
154
+ * in sync with the actual logging methods that we have installed (the
155
+ * parent could change levels but we might not have rebuilt the loggers
156
+ * in this child yet).
157
+ * @type {number}
158
+ */
159
+ var inheritedLevel;
160
+ /**
161
+ * The default level for this logger, if any. If set, this overrides
162
+ * `inheritedLevel`.
163
+ * @type {number|null}
164
+ */
165
+ var defaultLevel;
166
+ /**
167
+ * A user-specific level for this logger. If set, this overrides
168
+ * `defaultLevel`.
169
+ * @type {number|null}
170
+ */
171
+ var userLevel;
142
172
  var storageKey = "loglevel";
143
173
  if (typeof name === "string") {
144
174
  storageKey += ":" + name;
@@ -171,9 +201,10 @@ var loglevel = {exports: {}};
171
201
  if (typeof storedLevel === undefinedType) {
172
202
  try {
173
203
  var cookie = window.document.cookie;
174
- var location = cookie.indexOf(encodeURIComponent(storageKey) + "=");
204
+ var cookieName = encodeURIComponent(storageKey);
205
+ var location = cookie.indexOf(cookieName + "=");
175
206
  if (location !== -1) {
176
- storedLevel = /^([^;]+)/.exec(cookie.slice(location))[1];
207
+ storedLevel = /^([^;]+)/.exec(cookie.slice(location + cookieName.length + 1))[1];
177
208
  }
178
209
  } catch (ignore) {}
179
210
  }
@@ -190,7 +221,6 @@ var loglevel = {exports: {}};
190
221
  // Use localStorage if available
191
222
  try {
192
223
  window.localStorage.removeItem(storageKey);
193
- return;
194
224
  } catch (ignore) {}
195
225
 
196
226
  // Use session cookie as fallback
@@ -198,6 +228,17 @@ var loglevel = {exports: {}};
198
228
  window.document.cookie = encodeURIComponent(storageKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC";
199
229
  } catch (ignore) {}
200
230
  }
231
+ function normalizeLevel(input) {
232
+ var level = input;
233
+ if (typeof level === "string" && self.levels[level.toUpperCase()] !== undefined) {
234
+ level = self.levels[level.toUpperCase()];
235
+ }
236
+ if (typeof level === "number" && level >= 0 && level <= self.levels.SILENT) {
237
+ return level;
238
+ } else {
239
+ throw new TypeError("log.setLevel() called with invalid level: " + input);
240
+ }
241
+ }
201
242
 
202
243
  /*
203
244
  *
@@ -216,35 +257,34 @@ var loglevel = {exports: {}};
216
257
  };
217
258
  self.methodFactory = factory || defaultMethodFactory;
218
259
  self.getLevel = function () {
219
- return currentLevel;
260
+ if (userLevel != null) {
261
+ return userLevel;
262
+ } else if (defaultLevel != null) {
263
+ return defaultLevel;
264
+ } else {
265
+ return inheritedLevel;
266
+ }
220
267
  };
221
268
  self.setLevel = function (level, persist) {
222
- if (typeof level === "string" && self.levels[level.toUpperCase()] !== undefined) {
223
- level = self.levels[level.toUpperCase()];
224
- }
225
- if (typeof level === "number" && level >= 0 && level <= self.levels.SILENT) {
226
- currentLevel = level;
227
- if (persist !== false) {
228
- // defaults to true
229
- persistLevelIfPossible(level);
230
- }
231
- replaceLoggingMethods.call(self, level, name);
232
- if (typeof console === undefinedType && level < self.levels.SILENT) {
233
- return "No console available for logging";
234
- }
235
- } else {
236
- throw "log.setLevel() called with invalid level: " + level;
269
+ userLevel = normalizeLevel(level);
270
+ if (persist !== false) {
271
+ // defaults to true
272
+ persistLevelIfPossible(userLevel);
237
273
  }
274
+
275
+ // NOTE: in v2, this should call rebuild(), which updates children.
276
+ return replaceLoggingMethods.call(self);
238
277
  };
239
278
  self.setDefaultLevel = function (level) {
240
- defaultLevel = level;
279
+ defaultLevel = normalizeLevel(level);
241
280
  if (!getPersistedLevel()) {
242
281
  self.setLevel(level, false);
243
282
  }
244
283
  };
245
284
  self.resetLevel = function () {
246
- self.setLevel(defaultLevel, false);
285
+ userLevel = null;
247
286
  clearPersistedLevel();
287
+ replaceLoggingMethods.call(self);
248
288
  };
249
289
  self.enableAll = function (persist) {
250
290
  self.setLevel(self.levels.TRACE, persist);
@@ -252,13 +292,25 @@ var loglevel = {exports: {}};
252
292
  self.disableAll = function (persist) {
253
293
  self.setLevel(self.levels.SILENT, persist);
254
294
  };
295
+ self.rebuild = function () {
296
+ if (defaultLogger !== self) {
297
+ inheritedLevel = normalizeLevel(defaultLogger.getLevel());
298
+ }
299
+ replaceLoggingMethods.call(self);
300
+ if (defaultLogger === self) {
301
+ for (var childName in _loggersByName) {
302
+ _loggersByName[childName].rebuild();
303
+ }
304
+ }
305
+ };
255
306
 
256
- // Initialize with the right level
307
+ // Initialize all the internal levels.
308
+ inheritedLevel = normalizeLevel(defaultLogger ? defaultLogger.getLevel() : "WARN");
257
309
  var initialLevel = getPersistedLevel();
258
- if (initialLevel == null) {
259
- initialLevel = defaultLevel;
310
+ if (initialLevel != null) {
311
+ userLevel = normalizeLevel(initialLevel);
260
312
  }
261
- self.setLevel(initialLevel, false);
313
+ replaceLoggingMethods.call(self);
262
314
  }
263
315
 
264
316
  /*
@@ -267,15 +319,14 @@ var loglevel = {exports: {}};
267
319
  *
268
320
  */
269
321
 
270
- var defaultLogger = new Logger();
271
- var _loggersByName = {};
322
+ defaultLogger = new Logger();
272
323
  defaultLogger.getLogger = function getLogger(name) {
273
324
  if (typeof name !== "symbol" && typeof name !== "string" || name === "") {
274
325
  throw new TypeError("You must supply a name when creating a logger.");
275
326
  }
276
327
  var logger = _loggersByName[name];
277
328
  if (!logger) {
278
- logger = _loggersByName[name] = new Logger(name, defaultLogger.getLevel(), defaultLogger.methodFactory);
329
+ logger = _loggersByName[name] = new Logger(name, defaultLogger.methodFactory);
279
330
  }
280
331
  return logger;
281
332
  };
@@ -811,14 +862,16 @@ var eventsExports = events.exports;
811
862
  function isVideoFrame(frame) {
812
863
  return 'type' in frame;
813
864
  }
814
- function importKey(keyBytes) {
815
- let algorithm = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
816
- name: ENCRYPTION_ALGORITHM
817
- };
818
- let usage = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'encrypt';
819
- return __awaiter(this, void 0, void 0, function* () {
820
- // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey
821
- return crypto.subtle.importKey('raw', keyBytes, algorithm, false, usage === 'derive' ? ['deriveBits', 'deriveKey'] : ['encrypt', 'decrypt']);
865
+ function importKey(keyBytes_1) {
866
+ return __awaiter(this, arguments, void 0, function (keyBytes) {
867
+ let algorithm = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
868
+ name: ENCRYPTION_ALGORITHM
869
+ };
870
+ let usage = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'encrypt';
871
+ return function* () {
872
+ // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey
873
+ return crypto.subtle.importKey('raw', keyBytes, algorithm, false, usage === 'derive' ? ['deriveBits', 'deriveKey'] : ['encrypt', 'decrypt']);
874
+ }();
822
875
  });
823
876
  }
824
877
  function getAlgoOptions(algorithmName, salt) {
@@ -1091,8 +1144,8 @@ class FrameCryptor extends BaseFrameCryptor {
1091
1144
  * 9) Enqueue the encrypted frame for sending.
1092
1145
  */
1093
1146
  encodeFunction(encodedFrame, controller) {
1094
- var _a;
1095
1147
  return __awaiter(this, void 0, void 0, function* () {
1148
+ var _a;
1096
1149
  if (!this.isEnabled() ||
1097
1150
  // skip for encryption for empty dtx frames
1098
1151
  encodedFrame.data.byteLength === 0) {
@@ -1210,89 +1263,92 @@ class FrameCryptor extends BaseFrameCryptor {
1210
1263
  * Function that will decrypt the given encoded frame. If the decryption fails, it will
1211
1264
  * ratchet the key for up to RATCHET_WINDOW_SIZE times.
1212
1265
  */
1213
- decryptFrame(encodedFrame, keyIndex) {
1214
- let initialMaterial = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
1215
- let ratchetOpts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {
1216
- ratchetCount: 0
1217
- };
1218
- var _a;
1219
- return __awaiter(this, void 0, void 0, function* () {
1220
- const keySet = this.keys.getKeySet(keyIndex);
1221
- if (!ratchetOpts.encryptionKey && !keySet) {
1222
- throw new TypeError("no encryption key found for decryption of ".concat(this.participantIdentity));
1223
- }
1224
- let frameInfo = this.getUnencryptedBytes(encodedFrame);
1225
- // Construct frame trailer. Similar to the frame header described in
1226
- // https://tools.ietf.org/html/draft-omara-sframe-00#section-4.2
1227
- // but we put it at the end.
1228
- //
1229
- // ---------+-------------------------+-+---------+----
1230
- // payload |IV...(length = IV_LENGTH)|R|IV_LENGTH|KID |
1231
- // ---------+-------------------------+-+---------+----
1232
- try {
1233
- const frameHeader = new Uint8Array(encodedFrame.data, 0, frameInfo.unencryptedBytes);
1234
- var encryptedData = new Uint8Array(encodedFrame.data, frameHeader.length, encodedFrame.data.byteLength - frameHeader.length);
1235
- if (frameInfo.isH264 && needsRbspUnescaping(encryptedData)) {
1236
- encryptedData = parseRbsp(encryptedData);
1237
- const newUint8 = new Uint8Array(frameHeader.byteLength + encryptedData.byteLength);
1238
- newUint8.set(frameHeader);
1239
- newUint8.set(encryptedData, frameHeader.byteLength);
1240
- encodedFrame.data = newUint8.buffer;
1266
+ decryptFrame(encodedFrame_1, keyIndex_1) {
1267
+ return __awaiter(this, arguments, void 0, function (encodedFrame, keyIndex) {
1268
+ var _this = this;
1269
+ let initialMaterial = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
1270
+ let ratchetOpts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {
1271
+ ratchetCount: 0
1272
+ };
1273
+ return function* () {
1274
+ var _a;
1275
+ const keySet = _this.keys.getKeySet(keyIndex);
1276
+ if (!ratchetOpts.encryptionKey && !keySet) {
1277
+ throw new TypeError("no encryption key found for decryption of ".concat(_this.participantIdentity));
1241
1278
  }
1242
- const frameTrailer = new Uint8Array(encodedFrame.data, encodedFrame.data.byteLength - 2, 2);
1243
- const ivLength = frameTrailer[0];
1244
- const iv = new Uint8Array(encodedFrame.data, encodedFrame.data.byteLength - ivLength - frameTrailer.byteLength, ivLength);
1245
- const cipherTextStart = frameHeader.byteLength;
1246
- const cipherTextLength = encodedFrame.data.byteLength - (frameHeader.byteLength + ivLength + frameTrailer.byteLength);
1247
- const plainText = yield crypto.subtle.decrypt({
1248
- name: ENCRYPTION_ALGORITHM,
1249
- iv,
1250
- additionalData: new Uint8Array(encodedFrame.data, 0, frameHeader.byteLength)
1251
- }, (_a = ratchetOpts.encryptionKey) !== null && _a !== void 0 ? _a : keySet.encryptionKey, new Uint8Array(encodedFrame.data, cipherTextStart, cipherTextLength));
1252
- const newData = new ArrayBuffer(frameHeader.byteLength + plainText.byteLength);
1253
- const newUint8 = new Uint8Array(newData);
1254
- newUint8.set(new Uint8Array(encodedFrame.data, 0, frameHeader.byteLength));
1255
- newUint8.set(new Uint8Array(plainText), frameHeader.byteLength);
1256
- encodedFrame.data = newData;
1257
- return encodedFrame;
1258
- } catch (error) {
1259
- if (this.keyProviderOptions.ratchetWindowSize > 0) {
1260
- if (ratchetOpts.ratchetCount < this.keyProviderOptions.ratchetWindowSize) {
1261
- workerLogger.debug("ratcheting key attempt ".concat(ratchetOpts.ratchetCount, " of ").concat(this.keyProviderOptions.ratchetWindowSize, ", for kind ").concat(encodedFrame instanceof RTCEncodedAudioFrame ? 'audio' : 'video'));
1262
- let ratchetedKeySet;
1263
- if ((initialMaterial !== null && initialMaterial !== void 0 ? initialMaterial : keySet) === this.keys.getKeySet(keyIndex)) {
1264
- // only ratchet if the currently set key is still the same as the one used to decrypt this frame
1265
- // if not, it might be that a different frame has already ratcheted and we try with that one first
1266
- const newMaterial = yield this.keys.ratchetKey(keyIndex, false);
1267
- ratchetedKeySet = yield deriveKeys(newMaterial, this.keyProviderOptions.ratchetSalt);
1268
- }
1269
- const frame = yield this.decryptFrame(encodedFrame, keyIndex, initialMaterial || keySet, {
1270
- ratchetCount: ratchetOpts.ratchetCount + 1,
1271
- encryptionKey: ratchetedKeySet === null || ratchetedKeySet === void 0 ? void 0 : ratchetedKeySet.encryptionKey
1272
- });
1273
- if (frame && ratchetedKeySet) {
1274
- // before updating the keys, make sure that the keySet used for this frame is still the same as the currently set key
1275
- // if it's not, a new key might have been set already, which we don't want to override
1276
- if ((initialMaterial !== null && initialMaterial !== void 0 ? initialMaterial : keySet) === this.keys.getKeySet(keyIndex)) {
1277
- this.keys.setKeySet(ratchetedKeySet, keyIndex, true);
1278
- // decryption was successful, set the new key index to reflect the ratcheted key set
1279
- this.keys.setCurrentKeyIndex(keyIndex);
1279
+ let frameInfo = _this.getUnencryptedBytes(encodedFrame);
1280
+ // Construct frame trailer. Similar to the frame header described in
1281
+ // https://tools.ietf.org/html/draft-omara-sframe-00#section-4.2
1282
+ // but we put it at the end.
1283
+ //
1284
+ // ---------+-------------------------+-+---------+----
1285
+ // payload |IV...(length = IV_LENGTH)|R|IV_LENGTH|KID |
1286
+ // ---------+-------------------------+-+---------+----
1287
+ try {
1288
+ const frameHeader = new Uint8Array(encodedFrame.data, 0, frameInfo.unencryptedBytes);
1289
+ var encryptedData = new Uint8Array(encodedFrame.data, frameHeader.length, encodedFrame.data.byteLength - frameHeader.length);
1290
+ if (frameInfo.isH264 && needsRbspUnescaping(encryptedData)) {
1291
+ encryptedData = parseRbsp(encryptedData);
1292
+ const newUint8 = new Uint8Array(frameHeader.byteLength + encryptedData.byteLength);
1293
+ newUint8.set(frameHeader);
1294
+ newUint8.set(encryptedData, frameHeader.byteLength);
1295
+ encodedFrame.data = newUint8.buffer;
1296
+ }
1297
+ const frameTrailer = new Uint8Array(encodedFrame.data, encodedFrame.data.byteLength - 2, 2);
1298
+ const ivLength = frameTrailer[0];
1299
+ const iv = new Uint8Array(encodedFrame.data, encodedFrame.data.byteLength - ivLength - frameTrailer.byteLength, ivLength);
1300
+ const cipherTextStart = frameHeader.byteLength;
1301
+ const cipherTextLength = encodedFrame.data.byteLength - (frameHeader.byteLength + ivLength + frameTrailer.byteLength);
1302
+ const plainText = yield crypto.subtle.decrypt({
1303
+ name: ENCRYPTION_ALGORITHM,
1304
+ iv,
1305
+ additionalData: new Uint8Array(encodedFrame.data, 0, frameHeader.byteLength)
1306
+ }, (_a = ratchetOpts.encryptionKey) !== null && _a !== void 0 ? _a : keySet.encryptionKey, new Uint8Array(encodedFrame.data, cipherTextStart, cipherTextLength));
1307
+ const newData = new ArrayBuffer(frameHeader.byteLength + plainText.byteLength);
1308
+ const newUint8 = new Uint8Array(newData);
1309
+ newUint8.set(new Uint8Array(encodedFrame.data, 0, frameHeader.byteLength));
1310
+ newUint8.set(new Uint8Array(plainText), frameHeader.byteLength);
1311
+ encodedFrame.data = newData;
1312
+ return encodedFrame;
1313
+ } catch (error) {
1314
+ if (_this.keyProviderOptions.ratchetWindowSize > 0) {
1315
+ if (ratchetOpts.ratchetCount < _this.keyProviderOptions.ratchetWindowSize) {
1316
+ workerLogger.debug("ratcheting key attempt ".concat(ratchetOpts.ratchetCount, " of ").concat(_this.keyProviderOptions.ratchetWindowSize, ", for kind ").concat(encodedFrame instanceof RTCEncodedAudioFrame ? 'audio' : 'video'));
1317
+ let ratchetedKeySet;
1318
+ if ((initialMaterial !== null && initialMaterial !== void 0 ? initialMaterial : keySet) === _this.keys.getKeySet(keyIndex)) {
1319
+ // only ratchet if the currently set key is still the same as the one used to decrypt this frame
1320
+ // if not, it might be that a different frame has already ratcheted and we try with that one first
1321
+ const newMaterial = yield _this.keys.ratchetKey(keyIndex, false);
1322
+ ratchetedKeySet = yield deriveKeys(newMaterial, _this.keyProviderOptions.ratchetSalt);
1280
1323
  }
1324
+ const frame = yield _this.decryptFrame(encodedFrame, keyIndex, initialMaterial || keySet, {
1325
+ ratchetCount: ratchetOpts.ratchetCount + 1,
1326
+ encryptionKey: ratchetedKeySet === null || ratchetedKeySet === void 0 ? void 0 : ratchetedKeySet.encryptionKey
1327
+ });
1328
+ if (frame && ratchetedKeySet) {
1329
+ // before updating the keys, make sure that the keySet used for this frame is still the same as the currently set key
1330
+ // if it's not, a new key might have been set already, which we don't want to override
1331
+ if ((initialMaterial !== null && initialMaterial !== void 0 ? initialMaterial : keySet) === _this.keys.getKeySet(keyIndex)) {
1332
+ _this.keys.setKeySet(ratchetedKeySet, keyIndex, true);
1333
+ // decryption was successful, set the new key index to reflect the ratcheted key set
1334
+ _this.keys.setCurrentKeyIndex(keyIndex);
1335
+ }
1336
+ }
1337
+ return frame;
1338
+ } else {
1339
+ /**
1340
+ * Because we only set a new key once decryption has been successful,
1341
+ * we can be sure that we don't need to reset the key to the initial material at this point
1342
+ * as the key has not been updated on the keyHandler instance
1343
+ */
1344
+ workerLogger.warn('maximum ratchet attempts exceeded');
1345
+ throw new CryptorError("valid key missing for participant ".concat(_this.participantIdentity), CryptorErrorReason.InvalidKey);
1281
1346
  }
1282
- return frame;
1283
1347
  } else {
1284
- /**
1285
- * Because we only set a new key once decryption has been successful,
1286
- * we can be sure that we don't need to reset the key to the initial material at this point
1287
- * as the key has not been updated on the keyHandler instance
1288
- */
1289
- workerLogger.warn('maximum ratchet attempts exceeded');
1290
- throw new CryptorError("valid key missing for participant ".concat(this.participantIdentity), CryptorErrorReason.InvalidKey);
1348
+ throw new CryptorError("Decryption failed: ".concat(error.message), CryptorErrorReason.InvalidKey);
1291
1349
  }
1292
- } else {
1293
- throw new CryptorError("Decryption failed: ".concat(error.message), CryptorErrorReason.InvalidKey);
1294
1350
  }
1295
- }
1351
+ }();
1296
1352
  });
1297
1353
  }
1298
1354
  /**
@@ -1388,7 +1444,6 @@ class FrameCryptor extends BaseFrameCryptor {
1388
1444
  if (this.rtpMap.size === 0) {
1389
1445
  return undefined;
1390
1446
  }
1391
- // @ts-expect-error payloadType is not yet part of the typescript definition and currently not supported in Safari
1392
1447
  const payloadType = frame.getMetadata().payloadType;
1393
1448
  const codec = payloadType ? this.rtpMap.get(payloadType) : undefined;
1394
1449
  return codec;
@@ -1572,11 +1627,14 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter {
1572
1627
  * together with the material
1573
1628
  * also resets the valid key property and updates the currentKeyIndex
1574
1629
  */
1575
- setKey(material) {
1576
- let keyIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
1577
- return __awaiter(this, void 0, void 0, function* () {
1578
- yield this.setKeyFromMaterial(material, keyIndex);
1579
- this.resetKeyStatus();
1630
+ setKey(material_1) {
1631
+ return __awaiter(this, arguments, void 0, function (material) {
1632
+ var _this = this;
1633
+ let keyIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
1634
+ return function* () {
1635
+ yield _this.setKeyFromMaterial(material, keyIndex);
1636
+ _this.resetKeyStatus();
1637
+ }();
1580
1638
  });
1581
1639
  }
1582
1640
  /**
@@ -1585,18 +1643,21 @@ class ParticipantKeyHandler extends eventsExports.EventEmitter {
1585
1643
  * together with the material
1586
1644
  * also updates the currentKeyIndex
1587
1645
  */
1588
- setKeyFromMaterial(material, keyIndex) {
1589
- let emitRatchetEvent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
1590
- return __awaiter(this, void 0, void 0, function* () {
1591
- const keySet = yield deriveKeys(material, this.keyProviderOptions.ratchetSalt);
1592
- const newIndex = keyIndex >= 0 ? keyIndex % this.cryptoKeyRing.length : this.currentKeyIndex;
1593
- workerLogger.debug("setting new key with index ".concat(keyIndex), {
1594
- usage: material.usages,
1595
- algorithm: material.algorithm,
1596
- ratchetSalt: this.keyProviderOptions.ratchetSalt
1597
- });
1598
- this.setKeySet(keySet, newIndex, emitRatchetEvent);
1599
- if (newIndex >= 0) this.currentKeyIndex = newIndex;
1646
+ setKeyFromMaterial(material_1, keyIndex_1) {
1647
+ return __awaiter(this, arguments, void 0, function (material, keyIndex) {
1648
+ var _this2 = this;
1649
+ let emitRatchetEvent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
1650
+ return function* () {
1651
+ const keySet = yield deriveKeys(material, _this2.keyProviderOptions.ratchetSalt);
1652
+ const newIndex = keyIndex >= 0 ? keyIndex % _this2.cryptoKeyRing.length : _this2.currentKeyIndex;
1653
+ workerLogger.debug("setting new key with index ".concat(keyIndex), {
1654
+ usage: material.usages,
1655
+ algorithm: material.algorithm,
1656
+ ratchetSalt: _this2.keyProviderOptions.ratchetSalt
1657
+ });
1658
+ _this2.setKeySet(keySet, newIndex, emitRatchetEvent);
1659
+ if (newIndex >= 0) _this2.currentKeyIndex = newIndex;
1660
+ }();
1600
1661
  });
1601
1662
  }
1602
1663
  setKeySet(keySet, keyIndex) {
@@ -1831,8 +1892,10 @@ if (self.RTCTransformEvent) {
1831
1892
  workerLogger.debug('setup transform event');
1832
1893
  // @ts-ignore
1833
1894
  self.onrtctransform = event => {
1895
+ // @ts-ignore .transformer property is part of RTCTransformEvent
1834
1896
  const transformer = event.transformer;
1835
1897
  workerLogger.debug('transformer', transformer);
1898
+ // @ts-ignore monkey patching non standard flag
1836
1899
  transformer.handled = true;
1837
1900
  const {
1838
1901
  kind,