@bigbinary/neeto-media-recorder 2.7.31 → 2.7.33

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 (3) hide show
  1. package/core.js +573 -178
  2. package/core.js.map +1 -1
  3. package/package.json +1 -1
package/core.js CHANGED
@@ -991,6 +991,7 @@ var _pendingS3ChunkUploads = /*#__PURE__*/new WeakMap();
991
991
  var _completeUploadPromise = /*#__PURE__*/new WeakMap();
992
992
  var _failedUpload = /*#__PURE__*/new WeakMap();
993
993
  var _uploadProgress = /*#__PURE__*/new WeakMap();
994
+ var _lastLoggedOverallPercent = /*#__PURE__*/new WeakMap();
994
995
  var _status = /*#__PURE__*/new WeakMap();
995
996
  var _id = /*#__PURE__*/new WeakMap();
996
997
  var _logger$1 = /*#__PURE__*/new WeakMap();
@@ -998,6 +999,7 @@ var _mimeType$1 = /*#__PURE__*/new WeakMap();
998
999
  var _status2 = /*#__PURE__*/new WeakMap();
999
1000
  var _fireCallbacks$1 = /*#__PURE__*/new WeakMap();
1000
1001
  var _handleChunkUploadError = /*#__PURE__*/new WeakMap();
1002
+ var _serializeUploadError = /*#__PURE__*/new WeakMap();
1001
1003
  var _uploadChunkToS = /*#__PURE__*/new WeakMap();
1002
1004
  var _getCurrentUnUploadedBlob = /*#__PURE__*/new WeakMap();
1003
1005
  var _isRecordingNotSet = /*#__PURE__*/new WeakMap();
@@ -1058,6 +1060,10 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1058
1060
  writable: true,
1059
1061
  value: {}
1060
1062
  });
1063
+ _classPrivateFieldInitSpec$1(this, _lastLoggedOverallPercent, {
1064
+ writable: true,
1065
+ value: -1
1066
+ });
1061
1067
  _classPrivateFieldInitSpec$1(this, _status, {
1062
1068
  writable: true,
1063
1069
  value: ""
@@ -1078,6 +1084,10 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1078
1084
  return _classPrivateFieldSet(_this, _mimeType$1, mimeType);
1079
1085
  });
1080
1086
  _defineProperty(this, "setRecording", function (recordingId, uploadId) {
1087
+ _classPrivateFieldGet(_this, _logger$1).info("setRecording", {
1088
+ recordingId: recordingId,
1089
+ uploadId: uploadId
1090
+ });
1081
1091
  _classPrivateFieldSet(_this, _recordingId, recordingId);
1082
1092
  _classPrivateFieldSet(_this, _uploadId, uploadId);
1083
1093
  _classPrivateFieldSet(_this, _abortController, new AbortController());
@@ -1086,9 +1096,22 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1086
1096
  if (data.size > 0) {
1087
1097
  _classPrivateFieldGet(_this, _unUploadedChunks).push(data);
1088
1098
  }
1089
- _classPrivateFieldGet(_this, _logger$1).info("Current unuploaded data size is ", _classPrivateFieldGet(_this, _getCurrentUnUploadedBlob).call(_this).size / 1024 / 1024, "MB");
1090
- if (_classPrivateFieldGet(_this, _isRecordingNotSet)) return;
1091
- if (_classPrivateFieldGet(_this, _getCurrentUnUploadedBlob).call(_this).size > _this.MIN_UPLOAD_CHUNK_SIZE) {
1099
+ var unUploadedBytes = _classPrivateFieldGet(_this, _getCurrentUnUploadedBlob).call(_this).size;
1100
+ _classPrivateFieldGet(_this, _logger$1).info("push -> chunk buffered", {
1101
+ chunkBytes: data === null || data === void 0 ? void 0 : data.size,
1102
+ chunkType: data === null || data === void 0 ? void 0 : data.type,
1103
+ bufferedChunks: _classPrivateFieldGet(_this, _unUploadedChunks).length,
1104
+ bufferedBytes: unUploadedBytes,
1105
+ bufferedMB: Number((unUploadedBytes / 1024 / 1024).toFixed(2)),
1106
+ threshold: _this.MIN_UPLOAD_CHUNK_SIZE,
1107
+ recordingId: _classPrivateFieldGet(_this, _recordingId),
1108
+ uploadId: _classPrivateFieldGet(_this, _uploadId)
1109
+ });
1110
+ if (_classPrivateFieldGet(_this, _isRecordingNotSet)) {
1111
+ _classPrivateFieldGet(_this, _logger$1).warn("push -> recording not yet set, holding chunk in buffer");
1112
+ return;
1113
+ }
1114
+ if (unUploadedBytes > _this.MIN_UPLOAD_CHUNK_SIZE) {
1092
1115
  var uploadChunkToS3Promise = _classPrivateFieldGet(_this, _uploadChunkToS).call(_this, _classPrivateFieldGet(_this, _unUploadedChunks));
1093
1116
  _classPrivateFieldGet(_this, _pendingS3ChunkUploads).push(uploadChunkToS3Promise);
1094
1117
  _classPrivateFieldSet(_this, _unUploadedChunks, []);
@@ -1111,22 +1134,36 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1111
1134
  });
1112
1135
  _defineProperty(this, "completeUpload", /*#__PURE__*/function () {
1113
1136
  var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(sessionLogs) {
1114
- var uploadChunkToS3Promise, resolvedS3PartUploadPromises, parts;
1137
+ var completeStartedAt, lastChunkBytes, uploadChunkToS3Promise, resolvedS3PartUploadPromises, parts, notifyStartedAt;
1115
1138
  return _regeneratorRuntime.wrap(function _callee$(_context) {
1116
1139
  while (1) switch (_context.prev = _context.next) {
1117
1140
  case 0:
1118
- _context.prev = 0;
1141
+ completeStartedAt = Date.now();
1142
+ _classPrivateFieldGet(_this, _logger$1).info("completeUpload -> begin", {
1143
+ recordingId: _classPrivateFieldGet(_this, _recordingId),
1144
+ uploadId: _classPrivateFieldGet(_this, _uploadId),
1145
+ pendingChunks: _classPrivateFieldGet(_this, _pendingS3ChunkUploads).length,
1146
+ bufferedBytes: _classPrivateFieldGet(_this, _getCurrentUnUploadedBlob).call(_this).size,
1147
+ totalPartsStarted: _classPrivateFieldGet(_this, _partNumber) - 1
1148
+ });
1149
+ _context.prev = 2;
1119
1150
  _classPrivateFieldSet(_this, _status2, UPLOAD_STATUS.uploading);
1120
1151
  if (!_classPrivateFieldGet(_this, _isRecordingNotSet)) {
1121
- _context.next = 5;
1152
+ _context.next = 7;
1122
1153
  break;
1123
1154
  }
1124
- _classPrivateFieldGet(_this, _logger$1).error("completeUpload -> not initialized");
1155
+ _classPrivateFieldGet(_this, _logger$1).error("completeUpload -> not initialized", {
1156
+ recordingId: _classPrivateFieldGet(_this, _recordingId),
1157
+ uploadId: _classPrivateFieldGet(_this, _uploadId)
1158
+ });
1125
1159
  return _context.abrupt("return");
1126
- case 5:
1160
+ case 7:
1127
1161
  // Upload last chunk; only if last chunk has data
1128
- if (_classPrivateFieldGet(_this, _getCurrentUnUploadedBlob).call(_this).size > 0) {
1129
- _classPrivateFieldGet(_this, _logger$1).info("completeUpload -> need to upload last chunk");
1162
+ lastChunkBytes = _classPrivateFieldGet(_this, _getCurrentUnUploadedBlob).call(_this).size;
1163
+ if (lastChunkBytes > 0) {
1164
+ _classPrivateFieldGet(_this, _logger$1).info("completeUpload -> uploading final buffered chunk", {
1165
+ bytes: lastChunkBytes
1166
+ });
1130
1167
  uploadChunkToS3Promise = _classPrivateFieldGet(_this, _uploadChunkToS).call(_this, _classPrivateFieldGet(_this, _unUploadedChunks));
1131
1168
  _classPrivateFieldGet(_this, _pendingS3ChunkUploads).push(uploadChunkToS3Promise);
1132
1169
  }
@@ -1139,32 +1176,41 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1139
1176
  * adding the new presignedUrl part upload to s3PartUploadPromises.
1140
1177
  * This results in incorrect partNumbers.
1141
1178
  */
1142
- _classPrivateFieldGet(_this, _logger$1).info("completeUpload -> uploading all pending chunks...", _classPrivateFieldGet(_this, _pendingS3ChunkUploads).length);
1143
- _context.next = 9;
1144
- return Promise.all(_classPrivateFieldGet(_this, _pendingS3ChunkUploads));
1145
- case 9:
1146
- _classPrivateFieldGet(_this, _logger$1).info("completeUpload -> finishing part uploads...");
1179
+ _classPrivateFieldGet(_this, _logger$1).info("completeUpload -> awaiting pending chunks", {
1180
+ pendingS3ChunkUploads: _classPrivateFieldGet(_this, _pendingS3ChunkUploads).length
1181
+ });
1147
1182
  _context.next = 12;
1148
- return Promise.all(_classPrivateFieldGet(_this, _s3PartUploadPromises));
1183
+ return Promise.all(_classPrivateFieldGet(_this, _pendingS3ChunkUploads));
1149
1184
  case 12:
1185
+ _classPrivateFieldGet(_this, _logger$1).info("completeUpload -> awaiting part uploads", {
1186
+ s3PartUploadPromises: _classPrivateFieldGet(_this, _s3PartUploadPromises).length
1187
+ });
1188
+ _context.next = 15;
1189
+ return Promise.all(_classPrivateFieldGet(_this, _s3PartUploadPromises));
1190
+ case 15:
1150
1191
  resolvedS3PartUploadPromises = _context.sent;
1151
1192
  if (!isNotEmpty(_classPrivateFieldGet(_this, _failedUpload))) {
1152
- _context.next = 18;
1193
+ _context.next = 21;
1153
1194
  break;
1154
1195
  }
1155
- _classPrivateFieldGet(_this, _logger$1).info("completeUpload -> chunks with these partNumbers failed:", _classPrivateFieldGet(_this, _failedUpload));
1196
+ _classPrivateFieldGet(_this, _logger$1).error("completeUpload -> failed parts present, aborting completion", {
1197
+ failedPartNumbers: _classPrivateFieldGet(_this, _failedUpload)
1198
+ });
1156
1199
  _classPrivateFieldSet(_this, _status2, UPLOAD_STATUS.error);
1157
1200
  _classPrivateFieldGet(_this, _fireCallbacks$1).call(_this, UPLOAD_EVENT.onError);
1158
1201
  return _context.abrupt("return");
1159
- case 18:
1202
+ case 21:
1160
1203
  if (!(resolvedS3PartUploadPromises.length === 0)) {
1161
- _context.next = 22;
1204
+ _context.next = 25;
1162
1205
  break;
1163
1206
  }
1164
- _classPrivateFieldGet(_this, _logger$1).info("completeUpload -> insufficient data");
1207
+ _classPrivateFieldGet(_this, _logger$1).warn("completeUpload -> no parts uploaded", {
1208
+ recordingId: _classPrivateFieldGet(_this, _recordingId),
1209
+ uploadId: _classPrivateFieldGet(_this, _uploadId)
1210
+ });
1165
1211
  _classPrivateFieldSet(_this, _status2, UPLOAD_STATUS.insufficient_data);
1166
1212
  return _context.abrupt("return");
1167
- case 22:
1213
+ case 25:
1168
1214
  parts = resolvedS3PartUploadPromises.filter(isNotCancelledRequest).map(function (resolvedResponse) {
1169
1215
  return {
1170
1216
  etag: resolvedResponse.headers.etag,
@@ -1173,42 +1219,54 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1173
1219
  }).toSorted(function (a, b) {
1174
1220
  return Number(a.partNumber) - Number(b.partNumber);
1175
1221
  });
1176
- _classPrivateFieldGet(_this, _logger$1).info("completeUpload -> uploaded parts: ", parts);
1222
+ _classPrivateFieldGet(_this, _logger$1).info("completeUpload -> notifying server", {
1223
+ partCount: parts.length,
1224
+ parts: parts
1225
+ });
1226
+ notifyStartedAt = Date.now();
1177
1227
  _classPrivateFieldSet(_this, _completeUploadPromise, _this.completeUploadNotifyServer(parts, sessionLogs));
1178
- _classPrivateFieldGet(_this, _logger$1).info("completeUpload -> completing upload... ");
1179
- _context.next = 28;
1228
+ _context.next = 31;
1180
1229
  return _classPrivateFieldGet(_this, _completeUploadPromise);
1181
- case 28:
1182
- _classPrivateFieldGet(_this, _logger$1).info("completeUpload -> upload completed");
1230
+ case 31:
1231
+ _classPrivateFieldGet(_this, _logger$1).info("completeUpload -> server notified, upload finalized", {
1232
+ notifyDurationMs: Date.now() - notifyStartedAt,
1233
+ totalDurationMs: Date.now() - completeStartedAt
1234
+ });
1183
1235
  if (!(_this.status === UPLOAD_STATUS.aborting)) {
1184
- _context.next = 32;
1236
+ _context.next = 35;
1185
1237
  break;
1186
1238
  }
1187
- _classPrivateFieldGet(_this, _logger$1).info("completeUpload -> upload was marked as aborted");
1239
+ _classPrivateFieldGet(_this, _logger$1).warn("completeUpload -> finished but state was set to aborting");
1188
1240
  return _context.abrupt("return");
1189
- case 32:
1241
+ case 35:
1190
1242
  _classPrivateFieldSet(_this, _status2, UPLOAD_STATUS.completed);
1191
1243
  _classPrivateFieldGet(_this, _fireCallbacks$1).call(_this, UPLOAD_EVENT.onComplete);
1192
- _context.next = 39;
1244
+ _context.next = 42;
1193
1245
  break;
1194
- case 36:
1195
- _context.prev = 36;
1196
- _context.t0 = _context["catch"](0);
1246
+ case 39:
1247
+ _context.prev = 39;
1248
+ _context.t0 = _context["catch"](2);
1197
1249
  // ignore if aborted
1198
1250
  if (!axios.isCancel(_context.t0)) {
1199
1251
  _classPrivateFieldSet(_this, _status2, UPLOAD_STATUS.error);
1200
1252
  _classPrivateFieldGet(_this, _fireCallbacks$1).call(_this, UPLOAD_EVENT.onError);
1201
- _classPrivateFieldGet(_this, _logger$1).error(_context.t0);
1253
+ _classPrivateFieldGet(_this, _logger$1).error("completeUpload -> error", _objectSpread$2(_objectSpread$2({}, _classPrivateFieldGet(_this, _serializeUploadError).call(_this, _context.t0)), {}, {
1254
+ totalDurationMs: Date.now() - completeStartedAt,
1255
+ recordingId: _classPrivateFieldGet(_this, _recordingId),
1256
+ uploadId: _classPrivateFieldGet(_this, _uploadId)
1257
+ }));
1258
+ } else {
1259
+ _classPrivateFieldGet(_this, _logger$1).info("completeUpload -> request cancelled (expected)");
1202
1260
  }
1203
- case 39:
1204
- _context.prev = 39;
1205
- _classPrivateFieldSet(_this, _completeUploadPromise, null);
1206
- return _context.finish(39);
1207
1261
  case 42:
1262
+ _context.prev = 42;
1263
+ _classPrivateFieldSet(_this, _completeUploadPromise, null);
1264
+ return _context.finish(42);
1265
+ case 45:
1208
1266
  case "end":
1209
1267
  return _context.stop();
1210
1268
  }
1211
- }, _callee, null, [[0, 36, 39, 42]]);
1269
+ }, _callee, null, [[2, 39, 42, 45]]);
1212
1270
  }));
1213
1271
  return function (_x) {
1214
1272
  return _ref.apply(this, arguments);
@@ -1217,6 +1275,7 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1217
1275
  _defineProperty(this, "abortUpload", /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
1218
1276
  var forceAbort,
1219
1277
  sessionLogs,
1278
+ abortStartedAt,
1220
1279
  recordingId,
1221
1280
  uploadId,
1222
1281
  _args2 = arguments;
@@ -1225,30 +1284,43 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1225
1284
  case 0:
1226
1285
  forceAbort = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : false;
1227
1286
  sessionLogs = _args2.length > 1 ? _args2[1] : undefined;
1228
- _context2.prev = 2;
1287
+ abortStartedAt = Date.now();
1288
+ _context2.prev = 3;
1229
1289
  if (!(_this.status === UPLOAD_STATUS.aborting && !forceAbort)) {
1230
- _context2.next = 6;
1290
+ _context2.next = 7;
1231
1291
  break;
1232
1292
  }
1233
- _classPrivateFieldGet(_this, _logger$1).info("abortUpload -> already aborting");
1293
+ _classPrivateFieldGet(_this, _logger$1).info("abortUpload -> already aborting", {
1294
+ forceAbort: forceAbort
1295
+ });
1234
1296
  return _context2.abrupt("return");
1235
- case 6:
1297
+ case 7:
1236
1298
  _classPrivateFieldSet(_this, _status2, UPLOAD_STATUS.aborting);
1237
1299
  if (!_classPrivateFieldGet(_this, _isRecordingNotSet)) {
1238
- _context2.next = 10;
1300
+ _context2.next = 11;
1239
1301
  break;
1240
1302
  }
1241
1303
  _classPrivateFieldGet(_this, _logger$1).info("abortUpload -> not initialized");
1242
1304
  return _context2.abrupt("return");
1243
- case 10:
1305
+ case 11:
1244
1306
  recordingId = _classPrivateFieldGet(_this, _recordingId);
1245
1307
  uploadId = _classPrivateFieldGet(_this, _uploadId);
1246
- _context2.next = 14;
1247
- return _classPrivateFieldGet(_this, _completeUploadPromise);
1248
- case 14:
1308
+ _classPrivateFieldGet(_this, _logger$1).info("abortUpload -> begin", {
1309
+ recordingId: recordingId,
1310
+ uploadId: uploadId,
1311
+ forceAbort: forceAbort,
1312
+ partsStarted: _classPrivateFieldGet(_this, _partNumber) - 1,
1313
+ pendingS3ChunkUploads: _classPrivateFieldGet(_this, _pendingS3ChunkUploads).length
1314
+ });
1315
+
1316
+ // Don't let a rejected completeUpload stop us from issuing the abort API
1317
+ // call below — we still need to release the upload server-side.
1318
+ // eslint-disable-next-line promise/prefer-await-to-then
1319
+ _context2.next = 16;
1320
+ return Promise.resolve(_classPrivateFieldGet(_this, _completeUploadPromise))["catch"](function () {});
1321
+ case 16:
1249
1322
  _classPrivateFieldGet(_this, _abortController).abort();
1250
- _classPrivateFieldGet(_this, _logger$1).info("abortUpload -> aborting...");
1251
- _context2.next = 18;
1323
+ _context2.next = 19;
1252
1324
  return abortUploadApi.create({
1253
1325
  recordingId: recordingId,
1254
1326
  payload: {
@@ -1257,25 +1329,29 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1257
1329
  logs: sessionLogs
1258
1330
  }
1259
1331
  });
1260
- case 18:
1261
- _classPrivateFieldGet(_this, _logger$1).info("abortUpload -> abort successful");
1332
+ case 19:
1333
+ _classPrivateFieldGet(_this, _logger$1).info("abortUpload -> success", {
1334
+ durationMs: Date.now() - abortStartedAt
1335
+ });
1262
1336
  _classPrivateFieldGet(_this, _fireCallbacks$1).call(_this, UPLOAD_EVENT.onAbort);
1263
1337
  _classPrivateFieldSet(_this, _unUploadedChunks, []);
1264
1338
  _classPrivateFieldSet(_this, _partNumber, 1);
1265
1339
  _classPrivateFieldSet(_this, _s3PartUploadPromises, []);
1266
1340
  _classPrivateFieldSet(_this, _status2, "");
1267
1341
  _classPrivateFieldSet(_this, _abortController, null);
1268
- _context2.next = 30;
1342
+ _context2.next = 31;
1269
1343
  break;
1270
- case 27:
1271
- _context2.prev = 27;
1272
- _context2.t0 = _context2["catch"](2);
1273
- _classPrivateFieldGet(_this, _logger$1).error("abortUpload -> abort failed", _context2.t0 === null || _context2.t0 === void 0 ? void 0 : _context2.t0.message);
1274
- case 30:
1344
+ case 28:
1345
+ _context2.prev = 28;
1346
+ _context2.t0 = _context2["catch"](3);
1347
+ _classPrivateFieldGet(_this, _logger$1).error("abortUpload -> failed", _objectSpread$2(_objectSpread$2({}, _classPrivateFieldGet(_this, _serializeUploadError).call(_this, _context2.t0)), {}, {
1348
+ durationMs: Date.now() - abortStartedAt
1349
+ }));
1350
+ case 31:
1275
1351
  case "end":
1276
1352
  return _context2.stop();
1277
1353
  }
1278
- }, _callee2, null, [[2, 27]]);
1354
+ }, _callee2, null, [[3, 28]]);
1279
1355
  })));
1280
1356
  _defineProperty(this, "resetState", function () {
1281
1357
  _classPrivateFieldSet(_this, _recordingId, "");
@@ -1287,6 +1363,7 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1287
1363
  _classPrivateFieldSet(_this, _callbacks$1, {});
1288
1364
  _classPrivateFieldSet(_this, _failedUpload, []);
1289
1365
  _classPrivateFieldSet(_this, _uploadProgress, {});
1366
+ _classPrivateFieldSet(_this, _lastLoggedOverallPercent, -1);
1290
1367
  _classPrivateFieldSet(_this, _status2, "");
1291
1368
  });
1292
1369
  _defineProperty(this, "addCallback", function (event, callback) {
@@ -1313,9 +1390,21 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1313
1390
  _classPrivateFieldInitSpec$1(this, _handleChunkUploadError, {
1314
1391
  writable: true,
1315
1392
  value: function value(error, partNumber) {
1393
+ var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1316
1394
  // ignore if aborted
1317
- if (axios.isCancel(error)) return;
1318
- _classPrivateFieldGet(_this, _logger$1).error("Failed to upload partNumber:", partNumber);
1395
+ if (axios.isCancel(error)) {
1396
+ _classPrivateFieldGet(_this, _logger$1).info("upload chunk -> request cancelled (expected)", {
1397
+ partNumber: partNumber
1398
+ });
1399
+ return;
1400
+ }
1401
+ _classPrivateFieldGet(_this, _logger$1).error("upload chunk -> failed", _objectSpread$2(_objectSpread$2(_objectSpread$2({
1402
+ partNumber: partNumber
1403
+ }, _classPrivateFieldGet(_this, _serializeUploadError).call(_this, error)), context), {}, {
1404
+ uploadStatus: _this.status,
1405
+ recordingId: _classPrivateFieldGet(_this, _recordingId),
1406
+ uploadId: _classPrivateFieldGet(_this, _uploadId)
1407
+ }));
1319
1408
  if (_this.status === UPLOAD_STATUS.uploading) {
1320
1409
  _classPrivateFieldSet(_this, _status2, UPLOAD_STATUS.error);
1321
1410
  _classPrivateFieldGet(_this, _fireCallbacks$1).call(_this, UPLOAD_EVENT.onError);
@@ -1324,6 +1413,24 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1324
1413
  }
1325
1414
  }
1326
1415
  });
1416
+ _classPrivateFieldInitSpec$1(this, _serializeUploadError, {
1417
+ writable: true,
1418
+ value: function value(error) {
1419
+ var _error$response, _error$response2, _error$response3, _error$response4;
1420
+ if (!error) return {
1421
+ error: null
1422
+ };
1423
+ return {
1424
+ name: error.name,
1425
+ message: error.message,
1426
+ code: error.code,
1427
+ stack: error.stack,
1428
+ responseStatus: (_error$response = error.response) === null || _error$response === void 0 ? void 0 : _error$response.status,
1429
+ responseStatusText: (_error$response2 = error.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.statusText,
1430
+ responseData: typeof ((_error$response3 = error.response) === null || _error$response3 === void 0 ? void 0 : _error$response3.data) === "string" ? error.response.data.slice(0, 500) : (_error$response4 = error.response) === null || _error$response4 === void 0 ? void 0 : _error$response4.data
1431
+ };
1432
+ }
1433
+ });
1327
1434
  _defineProperty(this, "generatePreSignedUrl", function (partNumber) {
1328
1435
  var _classPrivateFieldGet6;
1329
1436
  return partPresignedUrlApi.create({
@@ -1342,32 +1449,55 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1342
1449
  writable: true,
1343
1450
  value: function () {
1344
1451
  var _value = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(chunks) {
1345
- var _this$partNumber;
1346
- var partNumber, _classPrivateFieldGet7, _yield$_this$generate, presignedUrl, s3PartUploadPromise;
1452
+ var _this$partNumber, _classPrivateFieldGet7;
1453
+ var partNumber, partBlob, partBytes, presignStartedAt, presignedUrl, _yield$_this$generate, uploadStartedAt, s3PartUploadPromise;
1347
1454
  return _regeneratorRuntime.wrap(function _callee3$(_context3) {
1348
1455
  while (1) switch (_context3.prev = _context3.next) {
1349
1456
  case 0:
1350
- _classPrivateFieldGet(_this, _logger$1).info("Part ready to be uploaded: ", _classPrivateFieldGet(_this, _partNumber));
1351
1457
  partNumber = _classPrivateFieldGet(_this, _partNumber);
1352
1458
  _classPrivateFieldSet(_this, _partNumber, (_this$partNumber = _classPrivateFieldGet(_this, _partNumber), _this$partNumber++, _this$partNumber));
1459
+ partBlob = new Blob(chunks, {
1460
+ type: _classPrivateFieldGet(_this, _mimeType$1)
1461
+ });
1462
+ partBytes = partBlob.size;
1353
1463
  _classPrivateFieldGet(_this, _uploadProgress)[partNumber] = {
1354
1464
  uploaded: 0,
1355
- total: new Blob(chunks, {
1356
- type: _classPrivateFieldGet(_this, _mimeType$1)
1357
- }).size
1465
+ total: partBytes
1358
1466
  };
1359
- _context3.prev = 4;
1360
- _context3.next = 7;
1467
+ _classPrivateFieldGet(_this, _logger$1).info("upload chunk -> begin", {
1468
+ partNumber: partNumber,
1469
+ partBytes: partBytes,
1470
+ partMB: Number((partBytes / 1024 / 1024).toFixed(2)),
1471
+ mimeType: _classPrivateFieldGet(_this, _mimeType$1),
1472
+ recordingId: _classPrivateFieldGet(_this, _recordingId),
1473
+ uploadId: _classPrivateFieldGet(_this, _uploadId)
1474
+ });
1475
+ presignStartedAt = Date.now();
1476
+ _context3.prev = 7;
1477
+ _context3.next = 10;
1361
1478
  return _this.generatePreSignedUrl(partNumber);
1362
- case 7:
1479
+ case 10:
1363
1480
  _yield$_this$generate = _context3.sent;
1364
1481
  presignedUrl = _yield$_this$generate.presignedUrl;
1365
- _classPrivateFieldGet(_this, _logger$1).info("Presigned url created for partNumber:", partNumber);
1482
+ _classPrivateFieldGet(_this, _logger$1).info("upload chunk -> presigned url ready", {
1483
+ partNumber: partNumber,
1484
+ presignDurationMs: Date.now() - presignStartedAt
1485
+ });
1486
+ _context3.next = 19;
1487
+ break;
1488
+ case 15:
1489
+ _context3.prev = 15;
1490
+ _context3.t0 = _context3["catch"](7);
1491
+ _classPrivateFieldGet(_this, _handleChunkUploadError).call(_this, _context3.t0, partNumber, {
1492
+ phase: "presign",
1493
+ presignDurationMs: Date.now() - presignStartedAt
1494
+ });
1495
+ return _context3.abrupt("return");
1496
+ case 19:
1497
+ uploadStartedAt = Date.now();
1366
1498
  s3PartUploadPromise = s3Api.presignedUpload({
1367
1499
  presignedUrl: presignedUrl,
1368
- blob: new Blob(chunks, {
1369
- type: _classPrivateFieldGet(_this, _mimeType$1)
1370
- }),
1500
+ blob: partBlob,
1371
1501
  config: {
1372
1502
  headers: {
1373
1503
  "Content-Type": _classPrivateFieldGet(_this, _mimeType$1)
@@ -1381,28 +1511,52 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1381
1511
  };
1382
1512
  if (_this.status === UPLOAD_STATUS.uploading) {
1383
1513
  var percentCompleted = calculateUploadProgress(_classPrivateFieldGet(_this, _uploadProgress));
1384
- _classPrivateFieldGet(_this, _logger$1).info("Upload Progress: ".concat(percentCompleted, "%"));
1514
+
1515
+ // Only log every 10% to keep noise down while still being useful.
1516
+ // Tracker is on the instance so concurrent chunk uploads don't
1517
+ // each log when the *overall* percent crosses a threshold.
1518
+ if (percentCompleted - _classPrivateFieldGet(_this, _lastLoggedOverallPercent) >= 10 || percentCompleted === 100) {
1519
+ _classPrivateFieldGet(_this, _logger$1).info("upload progress", {
1520
+ overallPercent: percentCompleted,
1521
+ partNumber: partNumber,
1522
+ partLoaded: e.loaded,
1523
+ partTotal: e.total
1524
+ });
1525
+ _classPrivateFieldSet(_this, _lastLoggedOverallPercent, percentCompleted);
1526
+ }
1385
1527
  _classPrivateFieldGet(_this, _fireCallbacks$1).call(_this, UPLOAD_EVENT.onProgress, [percentCompleted]);
1386
1528
  }
1387
1529
  }
1388
1530
  }
1389
1531
  })
1390
1532
  // eslint-disable-next-line promise/prefer-await-to-then
1533
+ .then(function (response) {
1534
+ var _response$headers;
1535
+ var durationMs = Date.now() - uploadStartedAt;
1536
+ _classPrivateFieldGet(_this, _logger$1).info("upload chunk -> success", {
1537
+ partNumber: partNumber,
1538
+ partBytes: partBytes,
1539
+ durationMs: durationMs,
1540
+ throughputMbps: durationMs ? Number((partBytes * 8 / 1000 / durationMs).toFixed(2)) : null,
1541
+ httpStatus: response === null || response === void 0 ? void 0 : response.status,
1542
+ etag: response === null || response === void 0 ? void 0 : (_response$headers = response.headers) === null || _response$headers === void 0 ? void 0 : _response$headers.etag
1543
+ });
1544
+ return response;
1545
+ })
1546
+ // eslint-disable-next-line promise/prefer-await-to-then
1391
1547
  ["catch"](function (error) {
1392
- _classPrivateFieldGet(_this, _handleChunkUploadError).call(_this, error, partNumber);
1548
+ _classPrivateFieldGet(_this, _handleChunkUploadError).call(_this, error, partNumber, {
1549
+ phase: "upload",
1550
+ uploadDurationMs: Date.now() - uploadStartedAt,
1551
+ partBytes: partBytes
1552
+ });
1393
1553
  });
1394
1554
  _classPrivateFieldGet(_this, _s3PartUploadPromises).push(s3PartUploadPromise);
1395
- _context3.next = 17;
1396
- break;
1397
- case 14:
1398
- _context3.prev = 14;
1399
- _context3.t0 = _context3["catch"](4);
1400
- _classPrivateFieldGet(_this, _handleChunkUploadError).call(_this, _context3.t0, partNumber);
1401
- case 17:
1555
+ case 22:
1402
1556
  case "end":
1403
1557
  return _context3.stop();
1404
1558
  }
1405
- }, _callee3, null, [[4, 14]]);
1559
+ }, _callee3, null, [[7, 15]]);
1406
1560
  }));
1407
1561
  function value(_x2) {
1408
1562
  return _value.apply(this, arguments);
@@ -1418,7 +1572,10 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1418
1572
  });
1419
1573
  }
1420
1574
  });
1421
- _classPrivateFieldGet(this, _logger$1).info("Uploader initialized");
1575
+ _classPrivateFieldGet(this, _logger$1).info("Uploader initialized", {
1576
+ mimeType: _classPrivateFieldGet(this, _mimeType$1),
1577
+ minUploadChunkSize: this.MIN_UPLOAD_CHUNK_SIZE
1578
+ });
1422
1579
  }
1423
1580
  _createClass(MultipartS3Uploader, [{
1424
1581
  key: "status",
@@ -1550,6 +1707,7 @@ var _timeLimit = /*#__PURE__*/new WeakMap();
1550
1707
  var _startRecordingTimeoutID = /*#__PURE__*/new WeakMap();
1551
1708
  var _enableNoiseCancellation = /*#__PURE__*/new WeakMap();
1552
1709
  var _showCountdown = /*#__PURE__*/new WeakMap();
1710
+ var _playCountdownAudio = /*#__PURE__*/new WeakMap();
1553
1711
  var _mimeType = /*#__PURE__*/new WeakMap();
1554
1712
  var _dataReceiving = /*#__PURE__*/new WeakMap();
1555
1713
  var _recordSystemAudio = /*#__PURE__*/new WeakMap();
@@ -1561,12 +1719,19 @@ var _fireCallbacks = /*#__PURE__*/new WeakMap();
1561
1719
  var _onRecordingStart = /*#__PURE__*/new WeakMap();
1562
1720
  var _onRecordingActive = /*#__PURE__*/new WeakMap();
1563
1721
  var _onRecordingStop = /*#__PURE__*/new WeakMap();
1722
+ var _serializeError = /*#__PURE__*/new WeakMap();
1723
+ var _summarizeStream = /*#__PURE__*/new WeakMap();
1724
+ var _summarizeRecorderState = /*#__PURE__*/new WeakMap();
1564
1725
  var _startMediaRecorder = /*#__PURE__*/new WeakMap();
1565
1726
  var _startCountdown = /*#__PURE__*/new WeakMap();
1566
1727
  var _startTimer = /*#__PURE__*/new WeakMap();
1567
1728
  var _stopTimer = /*#__PURE__*/new WeakMap();
1568
1729
  var _checkIfTimeLimitReached = /*#__PURE__*/new WeakMap();
1569
1730
  var ScreenRecorder = /*#__PURE__*/function () {
1731
+ // Lets a host (e.g. the chrome extension) take over the countdown beeps and
1732
+ // recording-start chime so it can schedule them via Web Audio. Defaults to
1733
+ // true to preserve behavior for callers that don't manage audio themselves.
1734
+
1570
1735
  function ScreenRecorder(_audio2, video) {
1571
1736
  var _this = this;
1572
1737
  _classCallCheck(this, ScreenRecorder);
@@ -1662,6 +1827,10 @@ var ScreenRecorder = /*#__PURE__*/function () {
1662
1827
  writable: true,
1663
1828
  value: true
1664
1829
  });
1830
+ _classPrivateFieldInitSpec(this, _playCountdownAudio, {
1831
+ writable: true,
1832
+ value: true
1833
+ });
1665
1834
  _classPrivateFieldInitSpec(this, _mimeType, {
1666
1835
  writable: true,
1667
1836
  value: getSupportedMimeType()
@@ -1718,6 +1887,9 @@ var ScreenRecorder = /*#__PURE__*/function () {
1718
1887
  _defineProperty(this, "setShowCountdown", function (showCountdown) {
1719
1888
  return _classPrivateFieldSet(_this, _showCountdown, showCountdown);
1720
1889
  });
1890
+ _defineProperty(this, "setPlayCountdownAudio", function (value) {
1891
+ return _classPrivateFieldSet(_this, _playCountdownAudio, value);
1892
+ });
1721
1893
  _defineProperty(this, "setTimeLimit", function () {
1722
1894
  var timeLimit = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : RECORDING_TIME_LIMIT_FREE_PLAN;
1723
1895
  return _classPrivateFieldSet(_this, _timeLimit, timeLimit);
@@ -1751,36 +1923,81 @@ var ScreenRecorder = /*#__PURE__*/function () {
1751
1923
  return _regeneratorRuntime.wrap(function _callee$(_context) {
1752
1924
  while (1) switch (_context.prev = _context.next) {
1753
1925
  case 0:
1926
+ _classPrivateFieldGet(_this, _logger).info("startRecording -> begin", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this, {
1927
+ showCountdown: _classPrivateFieldGet(_this, _showCountdown),
1928
+ timeLimit: _classPrivateFieldGet(_this, _timeLimit),
1929
+ mimeType: _classPrivateFieldGet(_this, _mimeType),
1930
+ recordSystemAudio: _classPrivateFieldGet(_this, _recordSystemAudio),
1931
+ enableNoiseCancellation: _classPrivateFieldGet(_this, _enableNoiseCancellation),
1932
+ hasInjectedVideoStream: Boolean(_classPrivateFieldGet(_this, _videoStream))
1933
+ }));
1754
1934
  _classPrivateFieldGet(_this, _store).setState(pick(["error"], initialState));
1755
1935
  if (_classPrivateFieldGet(_this, _mediaStream)) {
1756
- _context.next = 5;
1936
+ _context.next = 6;
1757
1937
  break;
1758
1938
  }
1759
- _classPrivateFieldGet(_this, _logger).info("acquiring media stream");
1760
- _context.next = 5;
1939
+ _classPrivateFieldGet(_this, _logger).info("startRecording -> acquiring media stream");
1940
+ _context.next = 6;
1761
1941
  return _classPrivateFieldGet(_this, _acquireMediaStream).call(_this);
1762
- case 5:
1942
+ case 6:
1763
1943
  if (!(_classPrivateFieldGet(_this, _mediaStream) && isStreamEnded(_classPrivateFieldGet(_this, _mediaStream)))) {
1764
- _context.next = 9;
1944
+ _context.next = 10;
1765
1945
  break;
1766
1946
  }
1767
- _classPrivateFieldGet(_this, _logger).info("media stream ended, acquiring media stream again");
1768
- _context.next = 9;
1947
+ _classPrivateFieldGet(_this, _logger).info("startRecording -> media stream ended, re-acquiring", _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _mediaStream)));
1948
+ _context.next = 10;
1769
1949
  return _classPrivateFieldGet(_this, _acquireMediaStream).call(_this);
1770
- case 9:
1950
+ case 10:
1771
1951
  if (!(!_classPrivateFieldGet(_this, _mediaStream) || isStreamEnded(_classPrivateFieldGet(_this, _mediaStream)))) {
1772
- _context.next = 11;
1952
+ _context.next = 13;
1773
1953
  break;
1774
1954
  }
1955
+ _classPrivateFieldGet(_this, _logger).warn("startRecording -> aborting, media stream unavailable", {
1956
+ hasMediaStream: Boolean(_classPrivateFieldGet(_this, _mediaStream)),
1957
+ isEnded: _classPrivateFieldGet(_this, _mediaStream) ? isStreamEnded(_classPrivateFieldGet(_this, _mediaStream)) : true
1958
+ });
1775
1959
  return _context.abrupt("return");
1776
- case 11:
1960
+ case 13:
1777
1961
  options = getMediaRecorderOptions();
1962
+ _classPrivateFieldGet(_this, _logger).info("startRecording -> creating MediaRecorder", {
1963
+ options: options,
1964
+ mimeType: _classPrivateFieldGet(_this, _mimeType),
1965
+ stream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _mediaStream))
1966
+ });
1778
1967
  _classPrivateFieldSet(_this, _mediaChunks, []);
1968
+ _context.prev = 16;
1779
1969
  _classPrivateFieldSet(_this, _mediaRecorder, new MediaRecorder(_classPrivateFieldGet(_this, _mediaStream), options));
1970
+ _context.next = 25;
1971
+ break;
1972
+ case 20:
1973
+ _context.prev = 20;
1974
+ _context.t0 = _context["catch"](16);
1975
+ _classPrivateFieldGet(_this, _logger).error("startRecording -> failed to construct MediaRecorder", _classPrivateFieldGet(_this, _serializeError).call(_this, _context.t0), {
1976
+ options: options,
1977
+ mimeType: _classPrivateFieldGet(_this, _mimeType)
1978
+ });
1979
+ _classPrivateFieldGet(_this, _store).setState({
1980
+ status: SCREEN_RECORDER_STATUS.idle,
1981
+ error: SCREEN_RECORDER_ERROR.NoRecorder
1982
+ });
1983
+ return _context.abrupt("return");
1984
+ case 25:
1985
+ _classPrivateFieldGet(_this, _logger).info("startRecording -> MediaRecorder created", {
1986
+ state: _classPrivateFieldGet(_this, _mediaRecorder).state,
1987
+ mimeType: _classPrivateFieldGet(_this, _mediaRecorder).mimeType,
1988
+ videoBitsPerSecond: _classPrivateFieldGet(_this, _mediaRecorder).videoBitsPerSecond,
1989
+ audioBitsPerSecond: _classPrivateFieldGet(_this, _mediaRecorder).audioBitsPerSecond
1990
+ });
1780
1991
  _classPrivateFieldGet(_this, _mediaRecorder).ondataavailable = _classPrivateFieldGet(_this, _onRecordingActive);
1781
1992
  _classPrivateFieldGet(_this, _mediaRecorder).onstart = _classPrivateFieldGet(_this, _onRecordingStart);
1782
1993
  _classPrivateFieldGet(_this, _mediaRecorder).onstop = _classPrivateFieldGet(_this, _onRecordingStop);
1783
- _classPrivateFieldGet(_this, _mediaRecorder).onerror = function () {
1994
+ _classPrivateFieldGet(_this, _mediaRecorder).onerror = function (event) {
1995
+ var _classPrivateFieldGet4;
1996
+ _classPrivateFieldGet(_this, _logger).error("MediaRecorder.onerror fired", _classPrivateFieldGet(_this, _serializeError).call(_this, event === null || event === void 0 ? void 0 : event.error), {
1997
+ state: (_classPrivateFieldGet4 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet4 === void 0 ? void 0 : _classPrivateFieldGet4.state,
1998
+ chunkCount: _classPrivateFieldGet(_this, _mediaChunks).length,
1999
+ stream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _mediaStream))
2000
+ });
1784
2001
  _classPrivateFieldGet(_this, _store).setState({
1785
2002
  status: SCREEN_RECORDER_STATUS.idle,
1786
2003
  error: SCREEN_RECORDER_ERROR.NoRecorder
@@ -1791,24 +2008,24 @@ var ScreenRecorder = /*#__PURE__*/function () {
1791
2008
  } else {
1792
2009
  _classPrivateFieldGet(_this, _startMediaRecorder).call(_this);
1793
2010
  }
1794
- case 19:
2011
+ case 31:
1795
2012
  case "end":
1796
2013
  return _context.stop();
1797
2014
  }
1798
- }, _callee);
2015
+ }, _callee, null, [[16, 20]]);
1799
2016
  })));
1800
2017
  _defineProperty(this, "stopRecording", function () {
1801
- var _classPrivateFieldGet4;
2018
+ var _classPrivateFieldGet5;
1802
2019
  if (_classPrivateFieldGet(_this, _mediaRecorder) === undefined) {
1803
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> stopRecording. mediaRecorder undefined");
2020
+ _classPrivateFieldGet(_this, _logger).info("stopRecording -> mediaRecorder undefined, stopping streams only", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1804
2021
  /**
1805
2022
  * If the permission is denied and "Stop sharing" overlay is clicked
1806
2023
  */
1807
2024
  _classPrivateFieldGet(_this, _stopAllStreams).call(_this);
1808
2025
  return;
1809
2026
  }
1810
- if (((_classPrivateFieldGet4 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet4 === void 0 ? void 0 : _classPrivateFieldGet4.state) === "inactive") {
1811
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> stopRecording. mediaRecorder state inactive");
2027
+ if (((_classPrivateFieldGet5 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet5 === void 0 ? void 0 : _classPrivateFieldGet5.state) === "inactive") {
2028
+ _classPrivateFieldGet(_this, _logger).info("stopRecording -> mediaRecorder inactive, treating as discard during countdown", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1812
2029
  // When recording is stopped from the 'Stop Sharing' overlay
1813
2030
  // before it even starts, i.e during the countdown.
1814
2031
  // Or if the recording is stopped before startRecordingTimeoutID timeout executes
@@ -1819,6 +2036,7 @@ var ScreenRecorder = /*#__PURE__*/function () {
1819
2036
  _classPrivateFieldGet(_this, _fireCallbacks).call(_this, SCREEN_RECORDER_EVENT.onDiscardDuringCountdown);
1820
2037
  return;
1821
2038
  }
2039
+ _classPrivateFieldGet(_this, _logger).info("stopRecording -> stopping", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1822
2040
  _classPrivateFieldGet(_this, _store).setState({
1823
2041
  status: SCREEN_RECORDER_STATUS.stopping
1824
2042
  });
@@ -1827,31 +2045,38 @@ var ScreenRecorder = /*#__PURE__*/function () {
1827
2045
  _classPrivateFieldGet(_this, _stopTimer).call(_this);
1828
2046
  });
1829
2047
  _defineProperty(this, "pauseRecording", function () {
1830
- var _classPrivateFieldGet5;
1831
- if (((_classPrivateFieldGet5 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet5 === void 0 ? void 0 : _classPrivateFieldGet5.state) === "recording") {
1832
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> pauseRecording.");
2048
+ var _classPrivateFieldGet6;
2049
+ if (((_classPrivateFieldGet6 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet6 === void 0 ? void 0 : _classPrivateFieldGet6.state) === "recording") {
2050
+ _classPrivateFieldGet(_this, _logger).info("pauseRecording", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1833
2051
  _classPrivateFieldGet(_this, _store).setState({
1834
2052
  status: SCREEN_RECORDER_STATUS.paused
1835
2053
  });
1836
2054
  _classPrivateFieldGet(_this, _mediaRecorder).pause();
2055
+ } else {
2056
+ _classPrivateFieldGet(_this, _logger).warn("pauseRecording -> ignored, recorder not in recording state", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1837
2057
  }
1838
2058
  _classPrivateFieldGet(_this, _stopTimer).call(_this);
1839
2059
  });
1840
2060
  _defineProperty(this, "resumeRecording", function () {
1841
- var _classPrivateFieldGet6;
1842
- if (((_classPrivateFieldGet6 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet6 === void 0 ? void 0 : _classPrivateFieldGet6.state) === "paused") {
1843
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> resumeRecording.");
2061
+ var _classPrivateFieldGet7;
2062
+ if (((_classPrivateFieldGet7 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet7 === void 0 ? void 0 : _classPrivateFieldGet7.state) === "paused") {
2063
+ _classPrivateFieldGet(_this, _logger).info("resumeRecording", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1844
2064
  _classPrivateFieldGet(_this, _store).setState({
1845
2065
  status: SCREEN_RECORDER_STATUS.recording
1846
2066
  });
1847
2067
  _classPrivateFieldGet(_this, _mediaRecorder).resume();
2068
+ } else {
2069
+ _classPrivateFieldGet(_this, _logger).warn("resumeRecording -> ignored, recorder not paused", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1848
2070
  }
1849
2071
  _classPrivateFieldGet(_this, _startTimer).call(_this);
1850
2072
  });
1851
2073
  _defineProperty(this, "discardRecording", function () {
1852
- var _classPrivateFieldGet7;
1853
- if (((_classPrivateFieldGet7 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet7 === void 0 ? void 0 : _classPrivateFieldGet7.state) === "inactive") return;
1854
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> discardRecording.");
2074
+ var _classPrivateFieldGet8;
2075
+ if (((_classPrivateFieldGet8 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet8 === void 0 ? void 0 : _classPrivateFieldGet8.state) === "inactive") {
2076
+ _classPrivateFieldGet(_this, _logger).info("discardRecording -> ignored, recorder already inactive", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
2077
+ return;
2078
+ }
2079
+ _classPrivateFieldGet(_this, _logger).info("discardRecording", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1855
2080
  _classPrivateFieldGet(_this, _store).setState({
1856
2081
  status: SCREEN_RECORDER_STATUS.stopping
1857
2082
  });
@@ -1864,7 +2089,7 @@ var ScreenRecorder = /*#__PURE__*/function () {
1864
2089
  _classPrivateFieldGet(_this, _fireCallbacks).call(_this, SCREEN_RECORDER_EVENT.onDiscard);
1865
2090
  });
1866
2091
  _defineProperty(this, "restartRecording", function () {
1867
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> restartRecording.");
2092
+ _classPrivateFieldGet(_this, _logger).info("restartRecording", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1868
2093
  _classPrivateFieldGet(_this, _store).setState({
1869
2094
  status: SCREEN_RECORDER_STATUS.stopping
1870
2095
  });
@@ -1877,7 +2102,7 @@ var ScreenRecorder = /*#__PURE__*/function () {
1877
2102
  _this.startRecording();
1878
2103
  });
1879
2104
  _defineProperty(this, "resetState", function () {
1880
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> resetState.");
2105
+ _classPrivateFieldGet(_this, _logger).info("resetState", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1881
2106
  _classPrivateFieldSet(_this, _mediaChunks, []);
1882
2107
  _classPrivateFieldSet(_this, _callbacks, {});
1883
2108
  _classPrivateFieldSet(_this, _dataReceiving, false);
@@ -1887,7 +2112,7 @@ var ScreenRecorder = /*#__PURE__*/function () {
1887
2112
  _classPrivateFieldGet(_this, _checkCompatibility).call(_this);
1888
2113
  });
1889
2114
  _defineProperty(this, "revokePermissions", function () {
1890
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> revokePermissions.");
2115
+ _classPrivateFieldGet(_this, _logger).info("revokePermissions", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1891
2116
  if (!_classPrivateFieldGet(_this, _mediaRecorder)) return;
1892
2117
  _classPrivateFieldGet(_this, _mediaRecorder).onstop = null;
1893
2118
  _classPrivateFieldGet(_this, _stopAllStreams).call(_this);
@@ -1895,18 +2120,23 @@ var ScreenRecorder = /*#__PURE__*/function () {
1895
2120
  _classPrivateFieldInitSpec(this, _stopAllStreams, {
1896
2121
  writable: true,
1897
2122
  value: function value() {
1898
- var _classPrivateFieldGet8, _classPrivateFieldGet9, _classPrivateFieldGet10, _classPrivateFieldGet11, _classPrivateFieldGet12, _classPrivateFieldGet13;
1899
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> stopAllStreams.");
1900
- _classPrivateFieldGet(_this, _mediaStream) && ((_classPrivateFieldGet8 = _classPrivateFieldGet(_this, _mediaStream)) === null || _classPrivateFieldGet8 === void 0 ? void 0 : _classPrivateFieldGet8.getTracks().forEach(function (track) {
2123
+ var _classPrivateFieldGet9, _classPrivateFieldGet10, _classPrivateFieldGet11, _classPrivateFieldGet12, _classPrivateFieldGet13, _classPrivateFieldGet14;
2124
+ _classPrivateFieldGet(_this, _logger).info("stopAllStreams", {
2125
+ mediaStream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _mediaStream)),
2126
+ stream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _stream)),
2127
+ audioStream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _audioStream)),
2128
+ micAudioStream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _micAudioStream))
2129
+ });
2130
+ _classPrivateFieldGet(_this, _mediaStream) && ((_classPrivateFieldGet9 = _classPrivateFieldGet(_this, _mediaStream)) === null || _classPrivateFieldGet9 === void 0 ? void 0 : _classPrivateFieldGet9.getTracks().forEach(function (track) {
1901
2131
  return track.stop();
1902
2132
  }));
1903
- (_classPrivateFieldGet9 = _classPrivateFieldGet(_this, _stream)) === null || _classPrivateFieldGet9 === void 0 ? void 0 : _classPrivateFieldGet9.getTracks().forEach(function (track) {
2133
+ (_classPrivateFieldGet10 = _classPrivateFieldGet(_this, _stream)) === null || _classPrivateFieldGet10 === void 0 ? void 0 : _classPrivateFieldGet10.getTracks().forEach(function (track) {
1904
2134
  return track.stop();
1905
2135
  });
1906
- (_classPrivateFieldGet10 = _classPrivateFieldGet(_this, _audioStream)) === null || _classPrivateFieldGet10 === void 0 ? void 0 : (_classPrivateFieldGet11 = _classPrivateFieldGet10.getAudioTracks()) === null || _classPrivateFieldGet11 === void 0 ? void 0 : _classPrivateFieldGet11.forEach(function (track) {
2136
+ (_classPrivateFieldGet11 = _classPrivateFieldGet(_this, _audioStream)) === null || _classPrivateFieldGet11 === void 0 ? void 0 : (_classPrivateFieldGet12 = _classPrivateFieldGet11.getAudioTracks()) === null || _classPrivateFieldGet12 === void 0 ? void 0 : _classPrivateFieldGet12.forEach(function (track) {
1907
2137
  return track.stop();
1908
2138
  });
1909
- (_classPrivateFieldGet12 = _classPrivateFieldGet(_this, _micAudioStream)) === null || _classPrivateFieldGet12 === void 0 ? void 0 : (_classPrivateFieldGet13 = _classPrivateFieldGet12.getAudioTracks()) === null || _classPrivateFieldGet13 === void 0 ? void 0 : _classPrivateFieldGet13.forEach(function (track) {
2139
+ (_classPrivateFieldGet13 = _classPrivateFieldGet(_this, _micAudioStream)) === null || _classPrivateFieldGet13 === void 0 ? void 0 : (_classPrivateFieldGet14 = _classPrivateFieldGet13.getAudioTracks()) === null || _classPrivateFieldGet14 === void 0 ? void 0 : _classPrivateFieldGet14.forEach(function (track) {
1910
2140
  return track.stop();
1911
2141
  });
1912
2142
  }
@@ -1941,38 +2171,51 @@ var ScreenRecorder = /*#__PURE__*/function () {
1941
2171
  writable: true,
1942
2172
  value: function () {
1943
2173
  var _value = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
1944
- var stream, constraints, audioConfig, audioStream, workletUrl, audioContext, audioStreamSource, destinationStream, noiseSuppressorNode, finalStream, _audioContext, desktopAudio, microphoneAudio, combinedAudio;
2174
+ var acquireStartedAt, stream, constraints, displayMediaStartedAt, audioConfig, micStartedAt, audioStream, workletUrl, workletStartedAt, audioContext, audioStreamSource, destinationStream, noiseSuppressorNode, finalStream, _audioContext, desktopAudio, microphoneAudio, combinedAudio;
1945
2175
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
1946
2176
  while (1) switch (_context2.prev = _context2.next) {
1947
2177
  case 0:
1948
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> acquireMediaStream.");
2178
+ acquireStartedAt = Date.now();
2179
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> begin", {
2180
+ hasInjectedVideoStream: Boolean(_classPrivateFieldGet(_this, _videoStream)),
2181
+ audio: Boolean(_classPrivateFieldGet(_this, _audio)),
2182
+ recordSystemAudio: _classPrivateFieldGet(_this, _recordSystemAudio),
2183
+ enableNoiseCancellation: _classPrivateFieldGet(_this, _enableNoiseCancellation)
2184
+ });
1949
2185
  _classPrivateFieldGet(_this, _store).setState({
1950
2186
  status: SCREEN_RECORDER_STATUS.acquiring_media
1951
2187
  });
1952
- _context2.prev = 2;
2188
+ _context2.prev = 3;
1953
2189
  if (!_classPrivateFieldGet(_this, _videoStream)) {
1954
- _context2.next = 7;
2190
+ _context2.next = 9;
1955
2191
  break;
1956
2192
  }
2193
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> using injected videoStream", _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _videoStream)));
1957
2194
  stream = _classPrivateFieldGet(_this, _videoStream);
1958
- _context2.next = 13;
2195
+ _context2.next = 17;
1959
2196
  break;
1960
- case 7:
2197
+ case 9:
1961
2198
  constraints = {
1962
2199
  video: _classPrivateFieldGet(_this, _video),
1963
2200
  audio: _classPrivateFieldGet(_this, _recordSystemAudio)
1964
2201
  };
1965
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> getDisplayMedia contraints.", constraints);
1966
- _context2.next = 11;
2202
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> getDisplayMedia constraints", constraints);
2203
+ displayMediaStartedAt = Date.now();
2204
+ _context2.next = 14;
1967
2205
  return window.navigator.mediaDevices.getDisplayMedia(constraints);
1968
- case 11:
2206
+ case 14:
1969
2207
  stream = _context2.sent;
2208
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> getDisplayMedia resolved", {
2209
+ durationMs: Date.now() - displayMediaStartedAt,
2210
+ stream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, stream)
2211
+ });
1970
2212
  _classPrivateFieldGet(_this, _fireCallbacks).call(_this, SCREEN_RECORDER_EVENT.onShareSelected);
1971
- case 13:
2213
+ case 17:
1972
2214
  if (!_classPrivateFieldGet(_this, _audio)) {
1973
- _context2.next = 42;
2215
+ _context2.next = 57;
1974
2216
  break;
1975
2217
  }
2218
+ _context2.prev = 18;
1976
2219
  audioConfig = {
1977
2220
  audio: _objectSpread(_objectSpread({
1978
2221
  echoCancellation: false
@@ -1982,49 +2225,81 @@ var ScreenRecorder = /*#__PURE__*/function () {
1982
2225
  }
1983
2226
  })
1984
2227
  };
1985
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> audioConfig", audioConfig);
2228
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> getUserMedia audioConfig", audioConfig);
2229
+ micStartedAt = Date.now();
1986
2230
  _context2.t0 = _classPrivateFieldSet;
1987
2231
  _context2.t1 = _this;
1988
2232
  _context2.t2 = _micAudioStream;
1989
- _context2.next = 21;
2233
+ _context2.next = 27;
1990
2234
  return window.navigator.mediaDevices.getUserMedia(audioConfig);
1991
- case 21:
2235
+ case 27:
1992
2236
  _context2.t3 = _context2.sent;
1993
2237
  (0, _context2.t0)(_context2.t1, _context2.t2, _context2.t3);
2238
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> mic acquired", {
2239
+ durationMs: Date.now() - micStartedAt,
2240
+ stream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _micAudioStream))
2241
+ });
1994
2242
  audioStream = addGainNode(_classPrivateFieldGet(_this, _micAudioStream), 1.75); // Increase volume by 50%
1995
2243
  _classPrivateFieldSet(_this, _audioStream, audioStream);
1996
2244
  if (!_classPrivateFieldGet(_this, _enableNoiseCancellation)) {
1997
- _context2.next = 42;
2245
+ _context2.next = 52;
1998
2246
  break;
1999
2247
  }
2000
- _context2.prev = 26;
2248
+ _context2.prev = 33;
2001
2249
  workletUrl = IS_EXTENSION ?
2002
2250
  // eslint-disable-next-line no-undef
2003
2251
  chrome.runtime.getURL("public/NoiseSuppressorWorklet.js") : "NoiseSuppressorWorklet.js";
2252
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> loading noise suppressor worklet", {
2253
+ workletUrl: workletUrl
2254
+ });
2255
+ workletStartedAt = Date.now();
2004
2256
  audioContext = new AudioContext();
2005
- _context2.next = 31;
2257
+ _context2.next = 40;
2006
2258
  return audioContext.audioWorklet.addModule(workletUrl);
2007
- case 31:
2259
+ case 40:
2008
2260
  audioStreamSource = audioContext.createMediaStreamSource(audioStream);
2009
2261
  destinationStream = audioContext.createMediaStreamDestination();
2010
2262
  noiseSuppressorNode = new AudioWorkletNode(audioContext, "nn-suppressor-processor");
2011
2263
  audioStreamSource.connect(noiseSuppressorNode);
2012
2264
  noiseSuppressorNode.connect(destinationStream);
2013
2265
  _classPrivateFieldSet(_this, _audioStream, destinationStream.stream);
2014
- _context2.next = 42;
2266
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> noise suppressor wired up", {
2267
+ durationMs: Date.now() - workletStartedAt
2268
+ });
2269
+ _context2.next = 52;
2015
2270
  break;
2016
- case 39:
2017
- _context2.prev = 39;
2018
- _context2.t4 = _context2["catch"](26);
2019
- logger.error("Failed to load audio worklet:", _context2.t4);
2020
- case 42:
2271
+ case 49:
2272
+ _context2.prev = 49;
2273
+ _context2.t4 = _context2["catch"](33);
2274
+ _classPrivateFieldGet(_this, _logger).error("acquireMediaStream -> failed to load audio worklet", _classPrivateFieldGet(_this, _serializeError).call(_this, _context2.t4));
2275
+ case 52:
2276
+ _context2.next = 57;
2277
+ break;
2278
+ case 54:
2279
+ _context2.prev = 54;
2280
+ _context2.t5 = _context2["catch"](18);
2281
+ // Mic access can fail independently of screen capture (OS-level
2282
+ // block, no device, deviceId mismatch). Screen sharing already
2283
+ // succeeded, so fall back to a video-only recording instead of
2284
+ // surfacing the failure as a screen permission error.
2285
+ _classPrivateFieldGet(_this, _logger).warn("acquireMediaStream -> mic unavailable, falling back to video-only", _classPrivateFieldGet(_this, _serializeError).call(_this, _context2.t5), {
2286
+ audioConfigRequested: _classPrivateFieldGet(_this, _audio)
2287
+ });
2288
+ case 57:
2021
2289
  // Event triggered when the user clicks on the stop sharing overlay button
2022
2290
  stream.getVideoTracks()[0].addEventListener("ended", function () {
2291
+ var _classPrivateFieldGet15;
2292
+ _classPrivateFieldGet(_this, _logger).info("display video track ended event received", {
2293
+ recorderState: (_classPrivateFieldGet15 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet15 === void 0 ? void 0 : _classPrivateFieldGet15.state,
2294
+ status: _classPrivateFieldGet(_this, _store).getState().status,
2295
+ stream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, stream)
2296
+ });
2023
2297
  _this.stopRecording();
2024
2298
  });
2025
2299
  finalStream = new MediaStream();
2026
2300
  if (_classPrivateFieldGet(_this, _audio) && _classPrivateFieldGet(_this, _audioStream)) {
2027
2301
  if (isNotEmpty(stream.getAudioTracks())) {
2302
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> mixing system audio + mic");
2028
2303
  _audioContext = new AudioContext();
2029
2304
  desktopAudio = _audioContext.createMediaStreamSource(stream);
2030
2305
  microphoneAudio = _audioContext.createMediaStreamSource(_classPrivateFieldGet(_this, _audioStream));
@@ -2035,14 +2310,18 @@ var ScreenRecorder = /*#__PURE__*/function () {
2035
2310
  return finalStream.addTrack(track);
2036
2311
  });
2037
2312
  } else {
2313
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> using mic audio only (no system audio in display stream)");
2038
2314
  _classPrivateFieldGet(_this, _audioStream).getAudioTracks().forEach(function (track) {
2039
2315
  return finalStream.addTrack(track);
2040
2316
  });
2041
2317
  }
2042
2318
  } else if (_classPrivateFieldGet(_this, _recordSystemAudio)) {
2319
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> using system audio only");
2043
2320
  stream.getAudioTracks().forEach(function (track) {
2044
2321
  return finalStream.addTrack(track);
2045
2322
  });
2323
+ } else {
2324
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> recording without audio");
2046
2325
  }
2047
2326
  stream.getVideoTracks().forEach(function (track) {
2048
2327
  return finalStream.addTrack(track);
@@ -2052,15 +2331,24 @@ var ScreenRecorder = /*#__PURE__*/function () {
2052
2331
  _classPrivateFieldGet(_this, _store).setState({
2053
2332
  status: SCREEN_RECORDER_STATUS.media_acquired
2054
2333
  });
2055
- _context2.next = 55;
2334
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> success", {
2335
+ totalDurationMs: Date.now() - acquireStartedAt,
2336
+ finalStream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _mediaStream))
2337
+ });
2338
+ _context2.next = 71;
2056
2339
  break;
2057
- case 51:
2058
- _context2.prev = 51;
2059
- _context2.t5 = _context2["catch"](2);
2060
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> acquireMediaStream:error", _context2.t5 === null || _context2.t5 === void 0 ? void 0 : _context2.t5.name, _context2.t5 === null || _context2.t5 === void 0 ? void 0 : _context2.t5.message);
2061
- if (SCREEN_RECORDER_ERROR[_context2.t5 === null || _context2.t5 === void 0 ? void 0 : _context2.t5.name]) {
2340
+ case 67:
2341
+ _context2.prev = 67;
2342
+ _context2.t6 = _context2["catch"](3);
2343
+ _classPrivateFieldGet(_this, _logger).error("acquireMediaStream -> error", _classPrivateFieldGet(_this, _serializeError).call(_this, _context2.t6), {
2344
+ totalDurationMs: Date.now() - acquireStartedAt,
2345
+ hasAudio: Boolean(_classPrivateFieldGet(_this, _audio)),
2346
+ hasAudioStream: Boolean(_classPrivateFieldGet(_this, _audioStream)),
2347
+ hasMediaStream: Boolean(_classPrivateFieldGet(_this, _mediaStream))
2348
+ });
2349
+ if (SCREEN_RECORDER_ERROR[_context2.t6 === null || _context2.t6 === void 0 ? void 0 : _context2.t6.name]) {
2062
2350
  _classPrivateFieldGet(_this, _store).setState({
2063
- error: SCREEN_RECORDER_ERROR[_context2.t5.name],
2351
+ error: SCREEN_RECORDER_ERROR[_context2.t6.name],
2064
2352
  status: SCREEN_RECORDER_STATUS.idle
2065
2353
  });
2066
2354
  } else if (_classPrivateFieldGet(_this, _audio) && !_classPrivateFieldGet(_this, _audioStream)) {
@@ -2070,15 +2358,15 @@ var ScreenRecorder = /*#__PURE__*/function () {
2070
2358
  });
2071
2359
  } else if (!_classPrivateFieldGet(_this, _mediaStream) || isStreamEnded(_classPrivateFieldGet(_this, _mediaStream))) {
2072
2360
  _classPrivateFieldGet(_this, _store).setState({
2073
- error: SCREEN_RECORDER_ERROR[_context2.t5 === null || _context2.t5 === void 0 ? void 0 : _context2.t5.name],
2361
+ error: SCREEN_RECORDER_ERROR[_context2.t6 === null || _context2.t6 === void 0 ? void 0 : _context2.t6.name],
2074
2362
  status: SCREEN_RECORDER_STATUS.idle
2075
2363
  });
2076
2364
  }
2077
- case 55:
2365
+ case 71:
2078
2366
  case "end":
2079
2367
  return _context2.stop();
2080
2368
  }
2081
- }, _callee2, null, [[2, 51], [26, 39]]);
2369
+ }, _callee2, null, [[3, 67], [18, 54], [33, 49]]);
2082
2370
  }));
2083
2371
  function value() {
2084
2372
  return _value.apply(this, arguments);
@@ -2089,9 +2377,9 @@ var ScreenRecorder = /*#__PURE__*/function () {
2089
2377
  _classPrivateFieldInitSpec(this, _fireCallbacks, {
2090
2378
  writable: true,
2091
2379
  value: function value(event) {
2092
- var _classPrivateFieldGet14;
2380
+ var _classPrivateFieldGet16;
2093
2381
  var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
2094
- (_classPrivateFieldGet14 = _classPrivateFieldGet(_this, _callbacks)[event]) === null || _classPrivateFieldGet14 === void 0 ? void 0 : _classPrivateFieldGet14.forEach(function (callback) {
2382
+ (_classPrivateFieldGet16 = _classPrivateFieldGet(_this, _callbacks)[event]) === null || _classPrivateFieldGet16 === void 0 ? void 0 : _classPrivateFieldGet16.forEach(function (callback) {
2095
2383
  callback.apply(void 0, _toConsumableArray(args));
2096
2384
  });
2097
2385
  }
@@ -2099,25 +2387,49 @@ var ScreenRecorder = /*#__PURE__*/function () {
2099
2387
  _classPrivateFieldInitSpec(this, _onRecordingStart, {
2100
2388
  writable: true,
2101
2389
  value: function value() {
2102
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> onRecordingStart.");
2390
+ _classPrivateFieldGet(_this, _logger).info("MediaRecorder.onstart fired", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
2103
2391
  _classPrivateFieldGet(_this, _fireCallbacks).call(_this, SCREEN_RECORDER_EVENT.onStart);
2104
2392
  }
2105
2393
  });
2106
2394
  _classPrivateFieldInitSpec(this, _onRecordingActive, {
2107
2395
  writable: true,
2108
2396
  value: function value(_ref2) {
2397
+ var _classPrivateFieldGet17;
2109
2398
  var data = _ref2.data;
2110
- _classPrivateFieldGet(_this, _logger).info("received data in onRecordingActive");
2111
- if (data.size <= 0) return;
2399
+ if (data.size <= 0) {
2400
+ _classPrivateFieldGet(_this, _logger).warn("ondataavailable -> empty chunk, ignoring", {
2401
+ chunkCount: _classPrivateFieldGet(_this, _mediaChunks).length
2402
+ });
2403
+ return;
2404
+ }
2112
2405
  _classPrivateFieldSet(_this, _dataReceiving, true);
2113
2406
  _classPrivateFieldGet(_this, _mediaChunks).push(data);
2407
+ var totalBytes = _classPrivateFieldGet(_this, _mediaChunks).reduce(function (sum, chunk) {
2408
+ var _chunk$size;
2409
+ return sum + ((_chunk$size = chunk === null || chunk === void 0 ? void 0 : chunk.size) !== null && _chunk$size !== void 0 ? _chunk$size : 0);
2410
+ }, 0);
2411
+ _classPrivateFieldGet(_this, _logger).info("ondataavailable -> chunk received", {
2412
+ chunkBytes: data.size,
2413
+ chunkType: data.type,
2414
+ chunkCount: _classPrivateFieldGet(_this, _mediaChunks).length,
2415
+ totalBytes: totalBytes,
2416
+ recorderState: (_classPrivateFieldGet17 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet17 === void 0 ? void 0 : _classPrivateFieldGet17.state
2417
+ });
2114
2418
  _classPrivateFieldGet(_this, _fireCallbacks).call(_this, SCREEN_RECORDER_EVENT.onDataAvailable, [data]);
2115
2419
  }
2116
2420
  });
2117
2421
  _classPrivateFieldInitSpec(this, _onRecordingStop, {
2118
2422
  writable: true,
2119
2423
  value: function value() {
2120
- _classPrivateFieldGet(_this, _logger).info("stopping recording in onRecordingStop");
2424
+ var _classPrivateFieldGet18, _classPrivateFieldGet19;
2425
+ var totalBytes = _classPrivateFieldGet(_this, _mediaChunks).reduce(function (sum, chunk) {
2426
+ var _chunk$size2;
2427
+ return sum + ((_chunk$size2 = chunk === null || chunk === void 0 ? void 0 : chunk.size) !== null && _chunk$size2 !== void 0 ? _chunk$size2 : 0);
2428
+ }, 0);
2429
+ _classPrivateFieldGet(_this, _logger).info("MediaRecorder.onstop fired", _objectSpread(_objectSpread({}, _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this)), {}, {
2430
+ totalBytes: totalBytes,
2431
+ mediaStreamActive: (_classPrivateFieldGet18 = _classPrivateFieldGet(_this, _mediaStream)) === null || _classPrivateFieldGet18 === void 0 ? void 0 : _classPrivateFieldGet18.active
2432
+ }));
2121
2433
  _classPrivateFieldGet(_this, _store).setState({
2122
2434
  status: SCREEN_RECORDER_STATUS.stopped
2123
2435
  });
@@ -2125,22 +2437,78 @@ var ScreenRecorder = /*#__PURE__*/function () {
2125
2437
 
2126
2438
  // If mediaStream is active after stopping mediaRecorder, then that means that
2127
2439
  // we are restarting and not stopping.
2128
- if (_classPrivateFieldGet(_this, _mediaStream).active) {
2440
+ if ((_classPrivateFieldGet19 = _classPrivateFieldGet(_this, _mediaStream)) !== null && _classPrivateFieldGet19 !== void 0 && _classPrivateFieldGet19.active) {
2441
+ _classPrivateFieldGet(_this, _logger).info("onRecordingStop -> mediaStream still active, transitioning to restarting");
2129
2442
  _classPrivateFieldGet(_this, _store).setState({
2130
2443
  status: SCREEN_RECORDER_STATUS.restarting
2131
2444
  });
2132
2445
  }
2133
2446
  }
2134
2447
  });
2448
+ _classPrivateFieldInitSpec(this, _serializeError, {
2449
+ writable: true,
2450
+ value: function value(error) {
2451
+ if (!error) return {
2452
+ error: null
2453
+ };
2454
+ return {
2455
+ name: error.name,
2456
+ message: error.message,
2457
+ stack: error.stack,
2458
+ code: error.code,
2459
+ constraint: error.constraint
2460
+ };
2461
+ }
2462
+ });
2463
+ _classPrivateFieldInitSpec(this, _summarizeStream, {
2464
+ writable: true,
2465
+ value: function value(stream) {
2466
+ var _stream$getVideoTrack, _stream$getVideoTrack2, _stream$getAudioTrack, _stream$getAudioTrack2;
2467
+ if (!stream) return null;
2468
+ var summarizeTrack = function summarizeTrack(track) {
2469
+ return {
2470
+ kind: track.kind,
2471
+ readyState: track.readyState,
2472
+ enabled: track.enabled,
2473
+ muted: track.muted,
2474
+ label: track.label,
2475
+ settings: typeof track.getSettings === "function" ? track.getSettings() : undefined
2476
+ };
2477
+ };
2478
+ return {
2479
+ id: stream.id,
2480
+ active: stream.active,
2481
+ videoTracks: (_stream$getVideoTrack = (_stream$getVideoTrack2 = stream.getVideoTracks) === null || _stream$getVideoTrack2 === void 0 ? void 0 : _stream$getVideoTrack2.call(stream).map(summarizeTrack)) !== null && _stream$getVideoTrack !== void 0 ? _stream$getVideoTrack : [],
2482
+ audioTracks: (_stream$getAudioTrack = (_stream$getAudioTrack2 = stream.getAudioTracks) === null || _stream$getAudioTrack2 === void 0 ? void 0 : _stream$getAudioTrack2.call(stream).map(summarizeTrack)) !== null && _stream$getAudioTrack !== void 0 ? _stream$getAudioTrack : []
2483
+ };
2484
+ }
2485
+ });
2486
+ _classPrivateFieldInitSpec(this, _summarizeRecorderState, {
2487
+ writable: true,
2488
+ value: function value() {
2489
+ var _classPrivateFieldGet20;
2490
+ var extra = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2491
+ return _objectSpread({
2492
+ recorderState: (_classPrivateFieldGet20 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet20 === void 0 ? void 0 : _classPrivateFieldGet20.state,
2493
+ status: _classPrivateFieldGet(_this, _store).getState().status,
2494
+ elapsedTime: _classPrivateFieldGet(_this, _store).getState().elapsedTime,
2495
+ chunkCount: _classPrivateFieldGet(_this, _mediaChunks).length,
2496
+ dataReceiving: _classPrivateFieldGet(_this, _dataReceiving),
2497
+ countdownTimeLeft: _classPrivateFieldGet(_this, _store).getState().countdownTimeLeft
2498
+ }, extra);
2499
+ }
2500
+ });
2135
2501
  _classPrivateFieldInitSpec(this, _startMediaRecorder, {
2136
2502
  writable: true,
2137
2503
  value: function value() {
2504
+ _classPrivateFieldGet(_this, _logger).info("startMediaRecorder -> scheduled", _objectSpread({
2505
+ delayMs: HALF_A_SECOND_IN_MILLISECONDS
2506
+ }, _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this)));
2138
2507
  _classPrivateFieldSet(_this, _startRecordingTimeoutID, setTimeout(function () {
2139
2508
  try {
2140
- var _classPrivateFieldGet15;
2141
- _classPrivateFieldGet(_this, _logger).info("starting mediaRecorder");
2509
+ var _classPrivateFieldGet21;
2142
2510
  if (!_classPrivateFieldGet(_this, _mediaRecorder)) {
2143
- _classPrivateFieldGet(_this, _logger).info("mediaRecorder is not defined");
2511
+ _classPrivateFieldGet(_this, _logger).error("startMediaRecorder -> aborted, mediaRecorder is null", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
2144
2512
  _classPrivateFieldGet(_this, _store).setState({
2145
2513
  status: SCREEN_RECORDER_STATUS.idle,
2146
2514
  error: SCREEN_RECORDER_ERROR.FailedToStart
@@ -2148,22 +2516,29 @@ var ScreenRecorder = /*#__PURE__*/function () {
2148
2516
  return;
2149
2517
  }
2150
2518
  if (!_classPrivateFieldGet(_this, _mediaStream) || isStreamEnded(_classPrivateFieldGet(_this, _mediaStream))) {
2151
- _classPrivateFieldGet(_this, _logger).info("media stream ended, not starting mediaRecorder");
2519
+ _classPrivateFieldGet(_this, _logger).error("startMediaRecorder -> aborted, media stream unavailable or ended", {
2520
+ hasMediaStream: Boolean(_classPrivateFieldGet(_this, _mediaStream)),
2521
+ isEnded: _classPrivateFieldGet(_this, _mediaStream) ? isStreamEnded(_classPrivateFieldGet(_this, _mediaStream)) : true,
2522
+ stream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _mediaStream))
2523
+ });
2152
2524
  _classPrivateFieldGet(_this, _store).setState({
2153
2525
  status: SCREEN_RECORDER_STATUS.idle,
2154
2526
  error: SCREEN_RECORDER_ERROR.FailedToStart
2155
2527
  });
2156
2528
  return;
2157
2529
  }
2158
- if (((_classPrivateFieldGet15 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet15 === void 0 ? void 0 : _classPrivateFieldGet15.state) === "recording") {
2159
- _classPrivateFieldGet(_this, _logger).info("mediaRecorder is already recording");
2530
+ if (((_classPrivateFieldGet21 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet21 === void 0 ? void 0 : _classPrivateFieldGet21.state) === "recording") {
2531
+ _classPrivateFieldGet(_this, _logger).warn("startMediaRecorder -> mediaRecorder already recording, skipping", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
2160
2532
  return;
2161
2533
  }
2534
+ _classPrivateFieldGet(_this, _logger).info("startMediaRecorder -> calling start()", _objectSpread({
2535
+ timesliceMs: 5000
2536
+ }, _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this)));
2162
2537
  _classPrivateFieldGet(_this, _mediaRecorder).start(5000);
2163
- _classPrivateFieldGet(_this, _logger).info("started mediaRecorder");
2538
+ _classPrivateFieldGet(_this, _logger).info("startMediaRecorder -> start() returned", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
2164
2539
  _classPrivateFieldGet(_this, _startTimer).call(_this);
2165
2540
  } catch (error) {
2166
- _classPrivateFieldGet(_this, _logger).info("Failed to start mediaRecorder", error);
2541
+ _classPrivateFieldGet(_this, _logger).error("startMediaRecorder -> failed", _classPrivateFieldGet(_this, _serializeError).call(_this, error), _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
2167
2542
  _classPrivateFieldGet(_this, _store).setState({
2168
2543
  status: SCREEN_RECORDER_STATUS.idle,
2169
2544
  error: SCREEN_RECORDER_ERROR.FailedToStart
@@ -2189,14 +2564,24 @@ var ScreenRecorder = /*#__PURE__*/function () {
2189
2564
  _classPrivateFieldInitSpec(this, _startCountdown, {
2190
2565
  writable: true,
2191
2566
  value: function value() {
2192
- if (_classPrivateFieldGet(_this, _countdownTimerId)) return;
2567
+ if (_classPrivateFieldGet(_this, _countdownTimerId)) {
2568
+ _classPrivateFieldGet(_this, _logger).warn("startCountdown -> already running, ignoring", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
2569
+ return;
2570
+ }
2571
+ _classPrivateFieldGet(_this, _logger).info("startCountdown -> begin", {
2572
+ countdownTimeLeft: _classPrivateFieldGet(_this, _store).getState().countdownTimeLeft,
2573
+ playCountdownAudio: _classPrivateFieldGet(_this, _playCountdownAudio)
2574
+ });
2193
2575
  _classPrivateFieldGet(_this, _fireCallbacks).call(_this, SCREEN_RECORDER_EVENT.onCountdownStart);
2194
2576
  _classPrivateFieldSet(_this, _countdownTimerId, setInterval(function () {
2195
- var shouldBeep = true;
2577
+ var shouldBeep = false;
2196
2578
  _classPrivateFieldGet(_this, _store).setState(function (_ref3) {
2197
2579
  var countdownTimeLeft = _ref3.countdownTimeLeft;
2198
2580
  if (countdownTimeLeft - ONE_SECOND > 0) {
2199
2581
  var next = countdownTimeLeft - ONE_SECOND;
2582
+ _classPrivateFieldGet(_this, _logger).info("startCountdown -> tick", {
2583
+ remaining: next
2584
+ });
2200
2585
  _classPrivateFieldGet(_this, _fireCallbacks).call(_this, SCREEN_RECORDER_EVENT.onCountdown, [next]);
2201
2586
  shouldBeep = true;
2202
2587
  return {
@@ -2204,9 +2589,9 @@ var ScreenRecorder = /*#__PURE__*/function () {
2204
2589
  };
2205
2590
  }
2206
2591
  _classPrivateFieldGet(_this, _fireCallbacks).call(_this, SCREEN_RECORDER_EVENT.onCountdown, [0]);
2207
- shouldBeep = false;
2208
2592
  setTimeout(function () {
2209
- _classPrivateFieldGet(_this, _startRecordingAudio).play();
2593
+ _classPrivateFieldGet(_this, _logger).info("startCountdown -> end, starting recorder");
2594
+ if (_classPrivateFieldGet(_this, _playCountdownAudio)) _classPrivateFieldGet(_this, _startRecordingAudio).play();
2210
2595
  _classPrivateFieldGet(_this, _fireCallbacks).call(_this, SCREEN_RECORDER_EVENT.onCountdownEnd);
2211
2596
  _classPrivateFieldGet(_this, _store).setState({
2212
2597
  status: SCREEN_RECORDER_STATUS.recording
@@ -2219,7 +2604,7 @@ var ScreenRecorder = /*#__PURE__*/function () {
2219
2604
  countdownTimeLeft: 0
2220
2605
  };
2221
2606
  });
2222
- if (shouldBeep) _classPrivateFieldGet(_this, _playCountdownBeep).call(_this);
2607
+ if (shouldBeep && _classPrivateFieldGet(_this, _playCountdownAudio)) _classPrivateFieldGet(_this, _playCountdownBeep).call(_this);
2223
2608
  }, ONE_SECOND_IN_MILLISECONDS));
2224
2609
  }
2225
2610
  });
@@ -2257,12 +2642,22 @@ var ScreenRecorder = /*#__PURE__*/function () {
2257
2642
  var oneMinuteBeforeTimeLimit = _classPrivateFieldGet(_this, _timeLimit) - ONE_MINUTE_IN_MILLISECONDS;
2258
2643
  if (elapsedTime <= oneMinuteBeforeTimeLimit) return;
2259
2644
  if (elapsedTime < _classPrivateFieldGet(_this, _timeLimit) && elapsedTime > oneMinuteBeforeTimeLimit) {
2260
- not(_classPrivateFieldGet(_this, _store).getState().showTimeLimitWarning) && _classPrivateFieldGet(_this, _recordingLimitWarningAudio).play();
2645
+ if (not(_classPrivateFieldGet(_this, _store).getState().showTimeLimitWarning)) {
2646
+ _classPrivateFieldGet(_this, _logger).info("time limit warning threshold crossed", {
2647
+ elapsedTime: elapsedTime,
2648
+ timeLimit: _classPrivateFieldGet(_this, _timeLimit)
2649
+ });
2650
+ _classPrivateFieldGet(_this, _recordingLimitWarningAudio).play();
2651
+ }
2261
2652
  _classPrivateFieldGet(_this, _store).setState({
2262
2653
  showTimeLimitWarning: true
2263
2654
  });
2264
2655
  return;
2265
2656
  }
2657
+ _classPrivateFieldGet(_this, _logger).info("time limit reached, stopping recording", {
2658
+ elapsedTime: elapsedTime,
2659
+ timeLimit: _classPrivateFieldGet(_this, _timeLimit)
2660
+ });
2266
2661
  _classPrivateFieldGet(_this, _stopRecordingDueToLimitReachedAudio).play();
2267
2662
  _this.stopRecording();
2268
2663
  }
@@ -2290,8 +2685,8 @@ var ScreenRecorder = /*#__PURE__*/function () {
2290
2685
  }, {
2291
2686
  key: "displaySurface",
2292
2687
  get: function get() {
2293
- var _classPrivateFieldGet16, _classPrivateFieldGet17;
2294
- var _ref5 = (_classPrivateFieldGet16 = (_classPrivateFieldGet17 = _classPrivateFieldGet(this, _mediaStream)) === null || _classPrivateFieldGet17 === void 0 ? void 0 : _classPrivateFieldGet17.getVideoTracks()) !== null && _classPrivateFieldGet16 !== void 0 ? _classPrivateFieldGet16 : [],
2688
+ var _classPrivateFieldGet22, _classPrivateFieldGet23;
2689
+ var _ref5 = (_classPrivateFieldGet22 = (_classPrivateFieldGet23 = _classPrivateFieldGet(this, _mediaStream)) === null || _classPrivateFieldGet23 === void 0 ? void 0 : _classPrivateFieldGet23.getVideoTracks()) !== null && _classPrivateFieldGet22 !== void 0 ? _classPrivateFieldGet22 : [],
2295
2690
  _ref6 = _slicedToArray(_ref5, 1),
2296
2691
  videoTrack = _ref6[0];
2297
2692
  return videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.getSettings().displaySurface;