@bigbinary/neeto-media-recorder 2.7.32 → 2.7.34

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 +622 -181
  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",
@@ -1562,6 +1719,10 @@ var _fireCallbacks = /*#__PURE__*/new WeakMap();
1562
1719
  var _onRecordingStart = /*#__PURE__*/new WeakMap();
1563
1720
  var _onRecordingActive = /*#__PURE__*/new WeakMap();
1564
1721
  var _onRecordingStop = /*#__PURE__*/new WeakMap();
1722
+ var _queryMicPermissionState = /*#__PURE__*/new WeakMap();
1723
+ var _serializeError = /*#__PURE__*/new WeakMap();
1724
+ var _summarizeStream = /*#__PURE__*/new WeakMap();
1725
+ var _summarizeRecorderState = /*#__PURE__*/new WeakMap();
1565
1726
  var _startMediaRecorder = /*#__PURE__*/new WeakMap();
1566
1727
  var _startCountdown = /*#__PURE__*/new WeakMap();
1567
1728
  var _startTimer = /*#__PURE__*/new WeakMap();
@@ -1763,36 +1924,81 @@ var ScreenRecorder = /*#__PURE__*/function () {
1763
1924
  return _regeneratorRuntime.wrap(function _callee$(_context) {
1764
1925
  while (1) switch (_context.prev = _context.next) {
1765
1926
  case 0:
1927
+ _classPrivateFieldGet(_this, _logger).info("startRecording -> begin", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this, {
1928
+ showCountdown: _classPrivateFieldGet(_this, _showCountdown),
1929
+ timeLimit: _classPrivateFieldGet(_this, _timeLimit),
1930
+ mimeType: _classPrivateFieldGet(_this, _mimeType),
1931
+ recordSystemAudio: _classPrivateFieldGet(_this, _recordSystemAudio),
1932
+ enableNoiseCancellation: _classPrivateFieldGet(_this, _enableNoiseCancellation),
1933
+ hasInjectedVideoStream: Boolean(_classPrivateFieldGet(_this, _videoStream))
1934
+ }));
1766
1935
  _classPrivateFieldGet(_this, _store).setState(pick(["error"], initialState));
1767
1936
  if (_classPrivateFieldGet(_this, _mediaStream)) {
1768
- _context.next = 5;
1937
+ _context.next = 6;
1769
1938
  break;
1770
1939
  }
1771
- _classPrivateFieldGet(_this, _logger).info("acquiring media stream");
1772
- _context.next = 5;
1940
+ _classPrivateFieldGet(_this, _logger).info("startRecording -> acquiring media stream");
1941
+ _context.next = 6;
1773
1942
  return _classPrivateFieldGet(_this, _acquireMediaStream).call(_this);
1774
- case 5:
1943
+ case 6:
1775
1944
  if (!(_classPrivateFieldGet(_this, _mediaStream) && isStreamEnded(_classPrivateFieldGet(_this, _mediaStream)))) {
1776
- _context.next = 9;
1945
+ _context.next = 10;
1777
1946
  break;
1778
1947
  }
1779
- _classPrivateFieldGet(_this, _logger).info("media stream ended, acquiring media stream again");
1780
- _context.next = 9;
1948
+ _classPrivateFieldGet(_this, _logger).info("startRecording -> media stream ended, re-acquiring", _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _mediaStream)));
1949
+ _context.next = 10;
1781
1950
  return _classPrivateFieldGet(_this, _acquireMediaStream).call(_this);
1782
- case 9:
1951
+ case 10:
1783
1952
  if (!(!_classPrivateFieldGet(_this, _mediaStream) || isStreamEnded(_classPrivateFieldGet(_this, _mediaStream)))) {
1784
- _context.next = 11;
1953
+ _context.next = 13;
1785
1954
  break;
1786
1955
  }
1956
+ _classPrivateFieldGet(_this, _logger).warn("startRecording -> aborting, media stream unavailable", {
1957
+ hasMediaStream: Boolean(_classPrivateFieldGet(_this, _mediaStream)),
1958
+ isEnded: _classPrivateFieldGet(_this, _mediaStream) ? isStreamEnded(_classPrivateFieldGet(_this, _mediaStream)) : true
1959
+ });
1787
1960
  return _context.abrupt("return");
1788
- case 11:
1961
+ case 13:
1789
1962
  options = getMediaRecorderOptions();
1963
+ _classPrivateFieldGet(_this, _logger).info("startRecording -> creating MediaRecorder", {
1964
+ options: options,
1965
+ mimeType: _classPrivateFieldGet(_this, _mimeType),
1966
+ stream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _mediaStream))
1967
+ });
1790
1968
  _classPrivateFieldSet(_this, _mediaChunks, []);
1969
+ _context.prev = 16;
1791
1970
  _classPrivateFieldSet(_this, _mediaRecorder, new MediaRecorder(_classPrivateFieldGet(_this, _mediaStream), options));
1971
+ _context.next = 25;
1972
+ break;
1973
+ case 20:
1974
+ _context.prev = 20;
1975
+ _context.t0 = _context["catch"](16);
1976
+ _classPrivateFieldGet(_this, _logger).error("startRecording -> failed to construct MediaRecorder", _classPrivateFieldGet(_this, _serializeError).call(_this, _context.t0), {
1977
+ options: options,
1978
+ mimeType: _classPrivateFieldGet(_this, _mimeType)
1979
+ });
1980
+ _classPrivateFieldGet(_this, _store).setState({
1981
+ status: SCREEN_RECORDER_STATUS.idle,
1982
+ error: SCREEN_RECORDER_ERROR.NoRecorder
1983
+ });
1984
+ return _context.abrupt("return");
1985
+ case 25:
1986
+ _classPrivateFieldGet(_this, _logger).info("startRecording -> MediaRecorder created", {
1987
+ state: _classPrivateFieldGet(_this, _mediaRecorder).state,
1988
+ mimeType: _classPrivateFieldGet(_this, _mediaRecorder).mimeType,
1989
+ videoBitsPerSecond: _classPrivateFieldGet(_this, _mediaRecorder).videoBitsPerSecond,
1990
+ audioBitsPerSecond: _classPrivateFieldGet(_this, _mediaRecorder).audioBitsPerSecond
1991
+ });
1792
1992
  _classPrivateFieldGet(_this, _mediaRecorder).ondataavailable = _classPrivateFieldGet(_this, _onRecordingActive);
1793
1993
  _classPrivateFieldGet(_this, _mediaRecorder).onstart = _classPrivateFieldGet(_this, _onRecordingStart);
1794
1994
  _classPrivateFieldGet(_this, _mediaRecorder).onstop = _classPrivateFieldGet(_this, _onRecordingStop);
1795
- _classPrivateFieldGet(_this, _mediaRecorder).onerror = function () {
1995
+ _classPrivateFieldGet(_this, _mediaRecorder).onerror = function (event) {
1996
+ var _classPrivateFieldGet4;
1997
+ _classPrivateFieldGet(_this, _logger).error("MediaRecorder.onerror fired", _classPrivateFieldGet(_this, _serializeError).call(_this, event === null || event === void 0 ? void 0 : event.error), {
1998
+ state: (_classPrivateFieldGet4 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet4 === void 0 ? void 0 : _classPrivateFieldGet4.state,
1999
+ chunkCount: _classPrivateFieldGet(_this, _mediaChunks).length,
2000
+ stream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _mediaStream))
2001
+ });
1796
2002
  _classPrivateFieldGet(_this, _store).setState({
1797
2003
  status: SCREEN_RECORDER_STATUS.idle,
1798
2004
  error: SCREEN_RECORDER_ERROR.NoRecorder
@@ -1803,24 +2009,24 @@ var ScreenRecorder = /*#__PURE__*/function () {
1803
2009
  } else {
1804
2010
  _classPrivateFieldGet(_this, _startMediaRecorder).call(_this);
1805
2011
  }
1806
- case 19:
2012
+ case 31:
1807
2013
  case "end":
1808
2014
  return _context.stop();
1809
2015
  }
1810
- }, _callee);
2016
+ }, _callee, null, [[16, 20]]);
1811
2017
  })));
1812
2018
  _defineProperty(this, "stopRecording", function () {
1813
- var _classPrivateFieldGet4;
2019
+ var _classPrivateFieldGet5;
1814
2020
  if (_classPrivateFieldGet(_this, _mediaRecorder) === undefined) {
1815
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> stopRecording. mediaRecorder undefined");
2021
+ _classPrivateFieldGet(_this, _logger).info("stopRecording -> mediaRecorder undefined, stopping streams only", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1816
2022
  /**
1817
2023
  * If the permission is denied and "Stop sharing" overlay is clicked
1818
2024
  */
1819
2025
  _classPrivateFieldGet(_this, _stopAllStreams).call(_this);
1820
2026
  return;
1821
2027
  }
1822
- if (((_classPrivateFieldGet4 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet4 === void 0 ? void 0 : _classPrivateFieldGet4.state) === "inactive") {
1823
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> stopRecording. mediaRecorder state inactive");
2028
+ if (((_classPrivateFieldGet5 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet5 === void 0 ? void 0 : _classPrivateFieldGet5.state) === "inactive") {
2029
+ _classPrivateFieldGet(_this, _logger).info("stopRecording -> mediaRecorder inactive, treating as discard during countdown", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1824
2030
  // When recording is stopped from the 'Stop Sharing' overlay
1825
2031
  // before it even starts, i.e during the countdown.
1826
2032
  // Or if the recording is stopped before startRecordingTimeoutID timeout executes
@@ -1831,6 +2037,7 @@ var ScreenRecorder = /*#__PURE__*/function () {
1831
2037
  _classPrivateFieldGet(_this, _fireCallbacks).call(_this, SCREEN_RECORDER_EVENT.onDiscardDuringCountdown);
1832
2038
  return;
1833
2039
  }
2040
+ _classPrivateFieldGet(_this, _logger).info("stopRecording -> stopping", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1834
2041
  _classPrivateFieldGet(_this, _store).setState({
1835
2042
  status: SCREEN_RECORDER_STATUS.stopping
1836
2043
  });
@@ -1839,31 +2046,38 @@ var ScreenRecorder = /*#__PURE__*/function () {
1839
2046
  _classPrivateFieldGet(_this, _stopTimer).call(_this);
1840
2047
  });
1841
2048
  _defineProperty(this, "pauseRecording", function () {
1842
- var _classPrivateFieldGet5;
1843
- if (((_classPrivateFieldGet5 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet5 === void 0 ? void 0 : _classPrivateFieldGet5.state) === "recording") {
1844
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> pauseRecording.");
2049
+ var _classPrivateFieldGet6;
2050
+ if (((_classPrivateFieldGet6 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet6 === void 0 ? void 0 : _classPrivateFieldGet6.state) === "recording") {
2051
+ _classPrivateFieldGet(_this, _logger).info("pauseRecording", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1845
2052
  _classPrivateFieldGet(_this, _store).setState({
1846
2053
  status: SCREEN_RECORDER_STATUS.paused
1847
2054
  });
1848
2055
  _classPrivateFieldGet(_this, _mediaRecorder).pause();
2056
+ } else {
2057
+ _classPrivateFieldGet(_this, _logger).warn("pauseRecording -> ignored, recorder not in recording state", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1849
2058
  }
1850
2059
  _classPrivateFieldGet(_this, _stopTimer).call(_this);
1851
2060
  });
1852
2061
  _defineProperty(this, "resumeRecording", function () {
1853
- var _classPrivateFieldGet6;
1854
- if (((_classPrivateFieldGet6 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet6 === void 0 ? void 0 : _classPrivateFieldGet6.state) === "paused") {
1855
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> resumeRecording.");
2062
+ var _classPrivateFieldGet7;
2063
+ if (((_classPrivateFieldGet7 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet7 === void 0 ? void 0 : _classPrivateFieldGet7.state) === "paused") {
2064
+ _classPrivateFieldGet(_this, _logger).info("resumeRecording", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1856
2065
  _classPrivateFieldGet(_this, _store).setState({
1857
2066
  status: SCREEN_RECORDER_STATUS.recording
1858
2067
  });
1859
2068
  _classPrivateFieldGet(_this, _mediaRecorder).resume();
2069
+ } else {
2070
+ _classPrivateFieldGet(_this, _logger).warn("resumeRecording -> ignored, recorder not paused", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1860
2071
  }
1861
2072
  _classPrivateFieldGet(_this, _startTimer).call(_this);
1862
2073
  });
1863
2074
  _defineProperty(this, "discardRecording", function () {
1864
- var _classPrivateFieldGet7;
1865
- if (((_classPrivateFieldGet7 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet7 === void 0 ? void 0 : _classPrivateFieldGet7.state) === "inactive") return;
1866
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> discardRecording.");
2075
+ var _classPrivateFieldGet8;
2076
+ if (((_classPrivateFieldGet8 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet8 === void 0 ? void 0 : _classPrivateFieldGet8.state) === "inactive") {
2077
+ _classPrivateFieldGet(_this, _logger).info("discardRecording -> ignored, recorder already inactive", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
2078
+ return;
2079
+ }
2080
+ _classPrivateFieldGet(_this, _logger).info("discardRecording", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1867
2081
  _classPrivateFieldGet(_this, _store).setState({
1868
2082
  status: SCREEN_RECORDER_STATUS.stopping
1869
2083
  });
@@ -1876,7 +2090,7 @@ var ScreenRecorder = /*#__PURE__*/function () {
1876
2090
  _classPrivateFieldGet(_this, _fireCallbacks).call(_this, SCREEN_RECORDER_EVENT.onDiscard);
1877
2091
  });
1878
2092
  _defineProperty(this, "restartRecording", function () {
1879
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> restartRecording.");
2093
+ _classPrivateFieldGet(_this, _logger).info("restartRecording", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1880
2094
  _classPrivateFieldGet(_this, _store).setState({
1881
2095
  status: SCREEN_RECORDER_STATUS.stopping
1882
2096
  });
@@ -1889,7 +2103,7 @@ var ScreenRecorder = /*#__PURE__*/function () {
1889
2103
  _this.startRecording();
1890
2104
  });
1891
2105
  _defineProperty(this, "resetState", function () {
1892
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> resetState.");
2106
+ _classPrivateFieldGet(_this, _logger).info("resetState", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1893
2107
  _classPrivateFieldSet(_this, _mediaChunks, []);
1894
2108
  _classPrivateFieldSet(_this, _callbacks, {});
1895
2109
  _classPrivateFieldSet(_this, _dataReceiving, false);
@@ -1899,7 +2113,7 @@ var ScreenRecorder = /*#__PURE__*/function () {
1899
2113
  _classPrivateFieldGet(_this, _checkCompatibility).call(_this);
1900
2114
  });
1901
2115
  _defineProperty(this, "revokePermissions", function () {
1902
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> revokePermissions.");
2116
+ _classPrivateFieldGet(_this, _logger).info("revokePermissions", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
1903
2117
  if (!_classPrivateFieldGet(_this, _mediaRecorder)) return;
1904
2118
  _classPrivateFieldGet(_this, _mediaRecorder).onstop = null;
1905
2119
  _classPrivateFieldGet(_this, _stopAllStreams).call(_this);
@@ -1907,18 +2121,23 @@ var ScreenRecorder = /*#__PURE__*/function () {
1907
2121
  _classPrivateFieldInitSpec(this, _stopAllStreams, {
1908
2122
  writable: true,
1909
2123
  value: function value() {
1910
- var _classPrivateFieldGet8, _classPrivateFieldGet9, _classPrivateFieldGet10, _classPrivateFieldGet11, _classPrivateFieldGet12, _classPrivateFieldGet13;
1911
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> stopAllStreams.");
1912
- _classPrivateFieldGet(_this, _mediaStream) && ((_classPrivateFieldGet8 = _classPrivateFieldGet(_this, _mediaStream)) === null || _classPrivateFieldGet8 === void 0 ? void 0 : _classPrivateFieldGet8.getTracks().forEach(function (track) {
2124
+ var _classPrivateFieldGet9, _classPrivateFieldGet10, _classPrivateFieldGet11, _classPrivateFieldGet12, _classPrivateFieldGet13, _classPrivateFieldGet14;
2125
+ _classPrivateFieldGet(_this, _logger).info("stopAllStreams", {
2126
+ mediaStream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _mediaStream)),
2127
+ stream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _stream)),
2128
+ audioStream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _audioStream)),
2129
+ micAudioStream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _micAudioStream))
2130
+ });
2131
+ _classPrivateFieldGet(_this, _mediaStream) && ((_classPrivateFieldGet9 = _classPrivateFieldGet(_this, _mediaStream)) === null || _classPrivateFieldGet9 === void 0 ? void 0 : _classPrivateFieldGet9.getTracks().forEach(function (track) {
1913
2132
  return track.stop();
1914
2133
  }));
1915
- (_classPrivateFieldGet9 = _classPrivateFieldGet(_this, _stream)) === null || _classPrivateFieldGet9 === void 0 ? void 0 : _classPrivateFieldGet9.getTracks().forEach(function (track) {
2134
+ (_classPrivateFieldGet10 = _classPrivateFieldGet(_this, _stream)) === null || _classPrivateFieldGet10 === void 0 ? void 0 : _classPrivateFieldGet10.getTracks().forEach(function (track) {
1916
2135
  return track.stop();
1917
2136
  });
1918
- (_classPrivateFieldGet10 = _classPrivateFieldGet(_this, _audioStream)) === null || _classPrivateFieldGet10 === void 0 ? void 0 : (_classPrivateFieldGet11 = _classPrivateFieldGet10.getAudioTracks()) === null || _classPrivateFieldGet11 === void 0 ? void 0 : _classPrivateFieldGet11.forEach(function (track) {
2137
+ (_classPrivateFieldGet11 = _classPrivateFieldGet(_this, _audioStream)) === null || _classPrivateFieldGet11 === void 0 ? void 0 : (_classPrivateFieldGet12 = _classPrivateFieldGet11.getAudioTracks()) === null || _classPrivateFieldGet12 === void 0 ? void 0 : _classPrivateFieldGet12.forEach(function (track) {
1919
2138
  return track.stop();
1920
2139
  });
1921
- (_classPrivateFieldGet12 = _classPrivateFieldGet(_this, _micAudioStream)) === null || _classPrivateFieldGet12 === void 0 ? void 0 : (_classPrivateFieldGet13 = _classPrivateFieldGet12.getAudioTracks()) === null || _classPrivateFieldGet13 === void 0 ? void 0 : _classPrivateFieldGet13.forEach(function (track) {
2140
+ (_classPrivateFieldGet13 = _classPrivateFieldGet(_this, _micAudioStream)) === null || _classPrivateFieldGet13 === void 0 ? void 0 : (_classPrivateFieldGet14 = _classPrivateFieldGet13.getAudioTracks()) === null || _classPrivateFieldGet14 === void 0 ? void 0 : _classPrivateFieldGet14.forEach(function (track) {
1922
2141
  return track.stop();
1923
2142
  });
1924
2143
  }
@@ -1953,39 +2172,72 @@ var ScreenRecorder = /*#__PURE__*/function () {
1953
2172
  writable: true,
1954
2173
  value: function () {
1955
2174
  var _value = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
1956
- var stream, constraints, audioConfig, audioStream, workletUrl, audioContext, audioStreamSource, destinationStream, noiseSuppressorNode, finalStream, _audioContext, desktopAudio, microphoneAudio, combinedAudio;
2175
+ var acquireStartedAt, micState, stream, constraints, displayMediaStartedAt, audioConfig, micStartedAt, audioStream, workletUrl, workletStartedAt, audioContext, audioStreamSource, destinationStream, noiseSuppressorNode, finalStream, _audioContext, desktopAudio, microphoneAudio, combinedAudio;
1957
2176
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
1958
2177
  while (1) switch (_context2.prev = _context2.next) {
1959
2178
  case 0:
1960
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> acquireMediaStream.");
2179
+ acquireStartedAt = Date.now();
2180
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> begin", {
2181
+ hasInjectedVideoStream: Boolean(_classPrivateFieldGet(_this, _videoStream)),
2182
+ audio: Boolean(_classPrivateFieldGet(_this, _audio)),
2183
+ recordSystemAudio: _classPrivateFieldGet(_this, _recordSystemAudio),
2184
+ enableNoiseCancellation: _classPrivateFieldGet(_this, _enableNoiseCancellation)
2185
+ });
1961
2186
  _classPrivateFieldGet(_this, _store).setState({
1962
2187
  status: SCREEN_RECORDER_STATUS.acquiring_media
1963
2188
  });
1964
- _context2.prev = 2;
2189
+ if (!(_classPrivateFieldGet(_this, _audio) && !_classPrivateFieldGet(_this, _videoStream))) {
2190
+ _context2.next = 11;
2191
+ break;
2192
+ }
2193
+ _context2.next = 6;
2194
+ return _classPrivateFieldGet(_this, _queryMicPermissionState).call(_this);
2195
+ case 6:
2196
+ micState = _context2.sent;
2197
+ if (!(micState === "denied")) {
2198
+ _context2.next = 11;
2199
+ break;
2200
+ }
2201
+ _classPrivateFieldGet(_this, _logger).warn("acquireMediaStream -> mic permission denied, skipping screen prompt", {
2202
+ micState: micState
2203
+ });
2204
+ _classPrivateFieldGet(_this, _store).setState({
2205
+ error: SCREEN_RECORDER_ERROR.MicPermissionDenied,
2206
+ status: SCREEN_RECORDER_STATUS.idle
2207
+ });
2208
+ return _context2.abrupt("return");
2209
+ case 11:
2210
+ _context2.prev = 11;
1965
2211
  if (!_classPrivateFieldGet(_this, _videoStream)) {
1966
- _context2.next = 7;
2212
+ _context2.next = 17;
1967
2213
  break;
1968
2214
  }
2215
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> using injected videoStream", _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _videoStream)));
1969
2216
  stream = _classPrivateFieldGet(_this, _videoStream);
1970
- _context2.next = 13;
2217
+ _context2.next = 25;
1971
2218
  break;
1972
- case 7:
2219
+ case 17:
1973
2220
  constraints = {
1974
2221
  video: _classPrivateFieldGet(_this, _video),
1975
2222
  audio: _classPrivateFieldGet(_this, _recordSystemAudio)
1976
2223
  };
1977
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> getDisplayMedia contraints.", constraints);
1978
- _context2.next = 11;
2224
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> getDisplayMedia constraints", constraints);
2225
+ displayMediaStartedAt = Date.now();
2226
+ _context2.next = 22;
1979
2227
  return window.navigator.mediaDevices.getDisplayMedia(constraints);
1980
- case 11:
2228
+ case 22:
1981
2229
  stream = _context2.sent;
2230
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> getDisplayMedia resolved", {
2231
+ durationMs: Date.now() - displayMediaStartedAt,
2232
+ stream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, stream)
2233
+ });
1982
2234
  _classPrivateFieldGet(_this, _fireCallbacks).call(_this, SCREEN_RECORDER_EVENT.onShareSelected);
1983
- case 13:
2235
+ case 25:
1984
2236
  if (!_classPrivateFieldGet(_this, _audio)) {
1985
- _context2.next = 48;
2237
+ _context2.next = 68;
1986
2238
  break;
1987
2239
  }
1988
- _context2.prev = 14;
2240
+ _context2.prev = 26;
1989
2241
  audioConfig = {
1990
2242
  audio: _objectSpread(_objectSpread({
1991
2243
  echoCancellation: false
@@ -1995,60 +2247,93 @@ var ScreenRecorder = /*#__PURE__*/function () {
1995
2247
  }
1996
2248
  })
1997
2249
  };
1998
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> audioConfig", audioConfig);
2250
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> getUserMedia audioConfig", audioConfig);
2251
+ micStartedAt = Date.now();
1999
2252
  _context2.t0 = _classPrivateFieldSet;
2000
2253
  _context2.t1 = _this;
2001
2254
  _context2.t2 = _micAudioStream;
2002
- _context2.next = 22;
2255
+ _context2.next = 35;
2003
2256
  return window.navigator.mediaDevices.getUserMedia(audioConfig);
2004
- case 22:
2257
+ case 35:
2005
2258
  _context2.t3 = _context2.sent;
2006
2259
  (0, _context2.t0)(_context2.t1, _context2.t2, _context2.t3);
2260
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> mic acquired", {
2261
+ durationMs: Date.now() - micStartedAt,
2262
+ stream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _micAudioStream))
2263
+ });
2007
2264
  audioStream = addGainNode(_classPrivateFieldGet(_this, _micAudioStream), 1.75); // Increase volume by 50%
2008
2265
  _classPrivateFieldSet(_this, _audioStream, audioStream);
2009
2266
  if (!_classPrivateFieldGet(_this, _enableNoiseCancellation)) {
2010
- _context2.next = 43;
2267
+ _context2.next = 60;
2011
2268
  break;
2012
2269
  }
2013
- _context2.prev = 27;
2270
+ _context2.prev = 41;
2014
2271
  workletUrl = IS_EXTENSION ?
2015
2272
  // eslint-disable-next-line no-undef
2016
2273
  chrome.runtime.getURL("public/NoiseSuppressorWorklet.js") : "NoiseSuppressorWorklet.js";
2274
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> loading noise suppressor worklet", {
2275
+ workletUrl: workletUrl
2276
+ });
2277
+ workletStartedAt = Date.now();
2017
2278
  audioContext = new AudioContext();
2018
- _context2.next = 32;
2279
+ _context2.next = 48;
2019
2280
  return audioContext.audioWorklet.addModule(workletUrl);
2020
- case 32:
2281
+ case 48:
2021
2282
  audioStreamSource = audioContext.createMediaStreamSource(audioStream);
2022
2283
  destinationStream = audioContext.createMediaStreamDestination();
2023
2284
  noiseSuppressorNode = new AudioWorkletNode(audioContext, "nn-suppressor-processor");
2024
2285
  audioStreamSource.connect(noiseSuppressorNode);
2025
2286
  noiseSuppressorNode.connect(destinationStream);
2026
2287
  _classPrivateFieldSet(_this, _audioStream, destinationStream.stream);
2027
- _context2.next = 43;
2288
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> noise suppressor wired up", {
2289
+ durationMs: Date.now() - workletStartedAt
2290
+ });
2291
+ _context2.next = 60;
2028
2292
  break;
2029
- case 40:
2030
- _context2.prev = 40;
2031
- _context2.t4 = _context2["catch"](27);
2032
- _classPrivateFieldGet(_this, _logger).error("Failed to load audio worklet:", _context2.t4);
2033
- case 43:
2034
- _context2.next = 48;
2293
+ case 57:
2294
+ _context2.prev = 57;
2295
+ _context2.t4 = _context2["catch"](41);
2296
+ _classPrivateFieldGet(_this, _logger).error("acquireMediaStream -> failed to load audio worklet", _classPrivateFieldGet(_this, _serializeError).call(_this, _context2.t4));
2297
+ case 60:
2298
+ _context2.next = 68;
2035
2299
  break;
2036
- case 45:
2037
- _context2.prev = 45;
2038
- _context2.t5 = _context2["catch"](14);
2300
+ case 62:
2301
+ _context2.prev = 62;
2302
+ _context2.t5 = _context2["catch"](26);
2039
2303
  // Mic access can fail independently of screen capture (OS-level
2040
- // block, no device, deviceId mismatch). Screen sharing already
2041
- // succeeded, so fall back to a video-only recording instead of
2042
- // surfacing the failure as a screen permission error.
2043
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> mic unavailable, recording without audio", _context2.t5 === null || _context2.t5 === void 0 ? void 0 : _context2.t5.name, _context2.t5 === null || _context2.t5 === void 0 ? void 0 : _context2.t5.message);
2044
- case 48:
2304
+ // block, no device, deviceId mismatch). Stop the screen stream and
2305
+ // surface a mic-only error so the user sees the proper callout
2306
+ // ("doesn't have access to your microphone" with Grant / I don't
2307
+ // need audio actions) instead of being misrouted to the screen
2308
+ // permission denied flow.
2309
+ _classPrivateFieldGet(_this, _logger).warn("acquireMediaStream -> mic unavailable", _classPrivateFieldGet(_this, _serializeError).call(_this, _context2.t5), {
2310
+ audioConfigRequested: _classPrivateFieldGet(_this, _audio)
2311
+ });
2312
+ if (!_classPrivateFieldGet(_this, _videoStream)) {
2313
+ stream.getTracks().forEach(function (track) {
2314
+ return track.stop();
2315
+ });
2316
+ }
2317
+ _classPrivateFieldGet(_this, _store).setState({
2318
+ error: SCREEN_RECORDER_ERROR.MicPermissionDenied,
2319
+ status: SCREEN_RECORDER_STATUS.idle
2320
+ });
2321
+ return _context2.abrupt("return");
2322
+ case 68:
2045
2323
  // Event triggered when the user clicks on the stop sharing overlay button
2046
2324
  stream.getVideoTracks()[0].addEventListener("ended", function () {
2325
+ var _classPrivateFieldGet15;
2326
+ _classPrivateFieldGet(_this, _logger).info("display video track ended event received", {
2327
+ recorderState: (_classPrivateFieldGet15 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet15 === void 0 ? void 0 : _classPrivateFieldGet15.state,
2328
+ status: _classPrivateFieldGet(_this, _store).getState().status,
2329
+ stream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, stream)
2330
+ });
2047
2331
  _this.stopRecording();
2048
2332
  });
2049
2333
  finalStream = new MediaStream();
2050
2334
  if (_classPrivateFieldGet(_this, _audio) && _classPrivateFieldGet(_this, _audioStream)) {
2051
2335
  if (isNotEmpty(stream.getAudioTracks())) {
2336
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> mixing system audio + mic");
2052
2337
  _audioContext = new AudioContext();
2053
2338
  desktopAudio = _audioContext.createMediaStreamSource(stream);
2054
2339
  microphoneAudio = _audioContext.createMediaStreamSource(_classPrivateFieldGet(_this, _audioStream));
@@ -2059,14 +2344,18 @@ var ScreenRecorder = /*#__PURE__*/function () {
2059
2344
  return finalStream.addTrack(track);
2060
2345
  });
2061
2346
  } else {
2347
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> using mic audio only (no system audio in display stream)");
2062
2348
  _classPrivateFieldGet(_this, _audioStream).getAudioTracks().forEach(function (track) {
2063
2349
  return finalStream.addTrack(track);
2064
2350
  });
2065
2351
  }
2066
2352
  } else if (_classPrivateFieldGet(_this, _recordSystemAudio)) {
2353
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> using system audio only");
2067
2354
  stream.getAudioTracks().forEach(function (track) {
2068
2355
  return finalStream.addTrack(track);
2069
2356
  });
2357
+ } else {
2358
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> recording without audio");
2070
2359
  }
2071
2360
  stream.getVideoTracks().forEach(function (track) {
2072
2361
  return finalStream.addTrack(track);
@@ -2076,12 +2365,21 @@ var ScreenRecorder = /*#__PURE__*/function () {
2076
2365
  _classPrivateFieldGet(_this, _store).setState({
2077
2366
  status: SCREEN_RECORDER_STATUS.media_acquired
2078
2367
  });
2079
- _context2.next = 61;
2368
+ _classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> success", {
2369
+ totalDurationMs: Date.now() - acquireStartedAt,
2370
+ finalStream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _mediaStream))
2371
+ });
2372
+ _context2.next = 82;
2080
2373
  break;
2081
- case 57:
2082
- _context2.prev = 57;
2083
- _context2.t6 = _context2["catch"](2);
2084
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> acquireMediaStream:error", _context2.t6 === null || _context2.t6 === void 0 ? void 0 : _context2.t6.name, _context2.t6 === null || _context2.t6 === void 0 ? void 0 : _context2.t6.message);
2374
+ case 78:
2375
+ _context2.prev = 78;
2376
+ _context2.t6 = _context2["catch"](11);
2377
+ _classPrivateFieldGet(_this, _logger).error("acquireMediaStream -> error", _classPrivateFieldGet(_this, _serializeError).call(_this, _context2.t6), {
2378
+ totalDurationMs: Date.now() - acquireStartedAt,
2379
+ hasAudio: Boolean(_classPrivateFieldGet(_this, _audio)),
2380
+ hasAudioStream: Boolean(_classPrivateFieldGet(_this, _audioStream)),
2381
+ hasMediaStream: Boolean(_classPrivateFieldGet(_this, _mediaStream))
2382
+ });
2085
2383
  if (SCREEN_RECORDER_ERROR[_context2.t6 === null || _context2.t6 === void 0 ? void 0 : _context2.t6.name]) {
2086
2384
  _classPrivateFieldGet(_this, _store).setState({
2087
2385
  error: SCREEN_RECORDER_ERROR[_context2.t6.name],
@@ -2098,11 +2396,11 @@ var ScreenRecorder = /*#__PURE__*/function () {
2098
2396
  status: SCREEN_RECORDER_STATUS.idle
2099
2397
  });
2100
2398
  }
2101
- case 61:
2399
+ case 82:
2102
2400
  case "end":
2103
2401
  return _context2.stop();
2104
2402
  }
2105
- }, _callee2, null, [[2, 57], [14, 45], [27, 40]]);
2403
+ }, _callee2, null, [[11, 78], [26, 62], [41, 57]]);
2106
2404
  }));
2107
2405
  function value() {
2108
2406
  return _value.apply(this, arguments);
@@ -2113,9 +2411,9 @@ var ScreenRecorder = /*#__PURE__*/function () {
2113
2411
  _classPrivateFieldInitSpec(this, _fireCallbacks, {
2114
2412
  writable: true,
2115
2413
  value: function value(event) {
2116
- var _classPrivateFieldGet14;
2414
+ var _classPrivateFieldGet16;
2117
2415
  var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
2118
- (_classPrivateFieldGet14 = _classPrivateFieldGet(_this, _callbacks)[event]) === null || _classPrivateFieldGet14 === void 0 ? void 0 : _classPrivateFieldGet14.forEach(function (callback) {
2416
+ (_classPrivateFieldGet16 = _classPrivateFieldGet(_this, _callbacks)[event]) === null || _classPrivateFieldGet16 === void 0 ? void 0 : _classPrivateFieldGet16.forEach(function (callback) {
2119
2417
  callback.apply(void 0, _toConsumableArray(args));
2120
2418
  });
2121
2419
  }
@@ -2123,25 +2421,49 @@ var ScreenRecorder = /*#__PURE__*/function () {
2123
2421
  _classPrivateFieldInitSpec(this, _onRecordingStart, {
2124
2422
  writable: true,
2125
2423
  value: function value() {
2126
- _classPrivateFieldGet(_this, _logger).info("screenRecorder -> onRecordingStart.");
2424
+ _classPrivateFieldGet(_this, _logger).info("MediaRecorder.onstart fired", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
2127
2425
  _classPrivateFieldGet(_this, _fireCallbacks).call(_this, SCREEN_RECORDER_EVENT.onStart);
2128
2426
  }
2129
2427
  });
2130
2428
  _classPrivateFieldInitSpec(this, _onRecordingActive, {
2131
2429
  writable: true,
2132
2430
  value: function value(_ref2) {
2431
+ var _classPrivateFieldGet17;
2133
2432
  var data = _ref2.data;
2134
- _classPrivateFieldGet(_this, _logger).info("received data in onRecordingActive");
2135
- if (data.size <= 0) return;
2433
+ if (data.size <= 0) {
2434
+ _classPrivateFieldGet(_this, _logger).warn("ondataavailable -> empty chunk, ignoring", {
2435
+ chunkCount: _classPrivateFieldGet(_this, _mediaChunks).length
2436
+ });
2437
+ return;
2438
+ }
2136
2439
  _classPrivateFieldSet(_this, _dataReceiving, true);
2137
2440
  _classPrivateFieldGet(_this, _mediaChunks).push(data);
2441
+ var totalBytes = _classPrivateFieldGet(_this, _mediaChunks).reduce(function (sum, chunk) {
2442
+ var _chunk$size;
2443
+ return sum + ((_chunk$size = chunk === null || chunk === void 0 ? void 0 : chunk.size) !== null && _chunk$size !== void 0 ? _chunk$size : 0);
2444
+ }, 0);
2445
+ _classPrivateFieldGet(_this, _logger).info("ondataavailable -> chunk received", {
2446
+ chunkBytes: data.size,
2447
+ chunkType: data.type,
2448
+ chunkCount: _classPrivateFieldGet(_this, _mediaChunks).length,
2449
+ totalBytes: totalBytes,
2450
+ recorderState: (_classPrivateFieldGet17 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet17 === void 0 ? void 0 : _classPrivateFieldGet17.state
2451
+ });
2138
2452
  _classPrivateFieldGet(_this, _fireCallbacks).call(_this, SCREEN_RECORDER_EVENT.onDataAvailable, [data]);
2139
2453
  }
2140
2454
  });
2141
2455
  _classPrivateFieldInitSpec(this, _onRecordingStop, {
2142
2456
  writable: true,
2143
2457
  value: function value() {
2144
- _classPrivateFieldGet(_this, _logger).info("stopping recording in onRecordingStop");
2458
+ var _classPrivateFieldGet18, _classPrivateFieldGet19;
2459
+ var totalBytes = _classPrivateFieldGet(_this, _mediaChunks).reduce(function (sum, chunk) {
2460
+ var _chunk$size2;
2461
+ return sum + ((_chunk$size2 = chunk === null || chunk === void 0 ? void 0 : chunk.size) !== null && _chunk$size2 !== void 0 ? _chunk$size2 : 0);
2462
+ }, 0);
2463
+ _classPrivateFieldGet(_this, _logger).info("MediaRecorder.onstop fired", _objectSpread(_objectSpread({}, _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this)), {}, {
2464
+ totalBytes: totalBytes,
2465
+ mediaStreamActive: (_classPrivateFieldGet18 = _classPrivateFieldGet(_this, _mediaStream)) === null || _classPrivateFieldGet18 === void 0 ? void 0 : _classPrivateFieldGet18.active
2466
+ }));
2145
2467
  _classPrivateFieldGet(_this, _store).setState({
2146
2468
  status: SCREEN_RECORDER_STATUS.stopped
2147
2469
  });
@@ -2149,22 +2471,113 @@ var ScreenRecorder = /*#__PURE__*/function () {
2149
2471
 
2150
2472
  // If mediaStream is active after stopping mediaRecorder, then that means that
2151
2473
  // we are restarting and not stopping.
2152
- if (_classPrivateFieldGet(_this, _mediaStream).active) {
2474
+ if ((_classPrivateFieldGet19 = _classPrivateFieldGet(_this, _mediaStream)) !== null && _classPrivateFieldGet19 !== void 0 && _classPrivateFieldGet19.active) {
2475
+ _classPrivateFieldGet(_this, _logger).info("onRecordingStop -> mediaStream still active, transitioning to restarting");
2153
2476
  _classPrivateFieldGet(_this, _store).setState({
2154
2477
  status: SCREEN_RECORDER_STATUS.restarting
2155
2478
  });
2156
2479
  }
2157
2480
  }
2158
2481
  });
2482
+ _classPrivateFieldInitSpec(this, _queryMicPermissionState, {
2483
+ writable: true,
2484
+ value: function () {
2485
+ var _value2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
2486
+ var result;
2487
+ return _regeneratorRuntime.wrap(function _callee3$(_context3) {
2488
+ while (1) switch (_context3.prev = _context3.next) {
2489
+ case 0:
2490
+ _context3.prev = 0;
2491
+ _context3.next = 3;
2492
+ return window.navigator.permissions.query({
2493
+ name: "microphone"
2494
+ });
2495
+ case 3:
2496
+ result = _context3.sent;
2497
+ return _context3.abrupt("return", result.state);
2498
+ case 7:
2499
+ _context3.prev = 7;
2500
+ _context3.t0 = _context3["catch"](0);
2501
+ // Permissions API or the "microphone" descriptor is unsupported
2502
+ // (e.g. Safari). Fall through to the live getUserMedia attempt.
2503
+ _classPrivateFieldGet(_this, _logger).info("queryMicPermissionState -> unsupported", _classPrivateFieldGet(_this, _serializeError).call(_this, _context3.t0));
2504
+ return _context3.abrupt("return", "prompt");
2505
+ case 11:
2506
+ case "end":
2507
+ return _context3.stop();
2508
+ }
2509
+ }, _callee3, null, [[0, 7]]);
2510
+ }));
2511
+ function value() {
2512
+ return _value2.apply(this, arguments);
2513
+ }
2514
+ return value;
2515
+ }()
2516
+ });
2517
+ _classPrivateFieldInitSpec(this, _serializeError, {
2518
+ writable: true,
2519
+ value: function value(error) {
2520
+ if (!error) return {
2521
+ error: null
2522
+ };
2523
+ return {
2524
+ name: error.name,
2525
+ message: error.message,
2526
+ stack: error.stack,
2527
+ code: error.code,
2528
+ constraint: error.constraint
2529
+ };
2530
+ }
2531
+ });
2532
+ _classPrivateFieldInitSpec(this, _summarizeStream, {
2533
+ writable: true,
2534
+ value: function value(stream) {
2535
+ var _stream$getVideoTrack, _stream$getVideoTrack2, _stream$getAudioTrack, _stream$getAudioTrack2;
2536
+ if (!stream) return null;
2537
+ var summarizeTrack = function summarizeTrack(track) {
2538
+ return {
2539
+ kind: track.kind,
2540
+ readyState: track.readyState,
2541
+ enabled: track.enabled,
2542
+ muted: track.muted,
2543
+ label: track.label,
2544
+ settings: typeof track.getSettings === "function" ? track.getSettings() : undefined
2545
+ };
2546
+ };
2547
+ return {
2548
+ id: stream.id,
2549
+ active: stream.active,
2550
+ 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 : [],
2551
+ 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 : []
2552
+ };
2553
+ }
2554
+ });
2555
+ _classPrivateFieldInitSpec(this, _summarizeRecorderState, {
2556
+ writable: true,
2557
+ value: function value() {
2558
+ var _classPrivateFieldGet20;
2559
+ var extra = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
2560
+ return _objectSpread({
2561
+ recorderState: (_classPrivateFieldGet20 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet20 === void 0 ? void 0 : _classPrivateFieldGet20.state,
2562
+ status: _classPrivateFieldGet(_this, _store).getState().status,
2563
+ elapsedTime: _classPrivateFieldGet(_this, _store).getState().elapsedTime,
2564
+ chunkCount: _classPrivateFieldGet(_this, _mediaChunks).length,
2565
+ dataReceiving: _classPrivateFieldGet(_this, _dataReceiving),
2566
+ countdownTimeLeft: _classPrivateFieldGet(_this, _store).getState().countdownTimeLeft
2567
+ }, extra);
2568
+ }
2569
+ });
2159
2570
  _classPrivateFieldInitSpec(this, _startMediaRecorder, {
2160
2571
  writable: true,
2161
2572
  value: function value() {
2573
+ _classPrivateFieldGet(_this, _logger).info("startMediaRecorder -> scheduled", _objectSpread({
2574
+ delayMs: HALF_A_SECOND_IN_MILLISECONDS
2575
+ }, _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this)));
2162
2576
  _classPrivateFieldSet(_this, _startRecordingTimeoutID, setTimeout(function () {
2163
2577
  try {
2164
- var _classPrivateFieldGet15;
2165
- _classPrivateFieldGet(_this, _logger).info("starting mediaRecorder");
2578
+ var _classPrivateFieldGet21;
2166
2579
  if (!_classPrivateFieldGet(_this, _mediaRecorder)) {
2167
- _classPrivateFieldGet(_this, _logger).info("mediaRecorder is not defined");
2580
+ _classPrivateFieldGet(_this, _logger).error("startMediaRecorder -> aborted, mediaRecorder is null", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
2168
2581
  _classPrivateFieldGet(_this, _store).setState({
2169
2582
  status: SCREEN_RECORDER_STATUS.idle,
2170
2583
  error: SCREEN_RECORDER_ERROR.FailedToStart
@@ -2172,22 +2585,29 @@ var ScreenRecorder = /*#__PURE__*/function () {
2172
2585
  return;
2173
2586
  }
2174
2587
  if (!_classPrivateFieldGet(_this, _mediaStream) || isStreamEnded(_classPrivateFieldGet(_this, _mediaStream))) {
2175
- _classPrivateFieldGet(_this, _logger).info("media stream ended, not starting mediaRecorder");
2588
+ _classPrivateFieldGet(_this, _logger).error("startMediaRecorder -> aborted, media stream unavailable or ended", {
2589
+ hasMediaStream: Boolean(_classPrivateFieldGet(_this, _mediaStream)),
2590
+ isEnded: _classPrivateFieldGet(_this, _mediaStream) ? isStreamEnded(_classPrivateFieldGet(_this, _mediaStream)) : true,
2591
+ stream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _mediaStream))
2592
+ });
2176
2593
  _classPrivateFieldGet(_this, _store).setState({
2177
2594
  status: SCREEN_RECORDER_STATUS.idle,
2178
2595
  error: SCREEN_RECORDER_ERROR.FailedToStart
2179
2596
  });
2180
2597
  return;
2181
2598
  }
2182
- if (((_classPrivateFieldGet15 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet15 === void 0 ? void 0 : _classPrivateFieldGet15.state) === "recording") {
2183
- _classPrivateFieldGet(_this, _logger).info("mediaRecorder is already recording");
2599
+ if (((_classPrivateFieldGet21 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet21 === void 0 ? void 0 : _classPrivateFieldGet21.state) === "recording") {
2600
+ _classPrivateFieldGet(_this, _logger).warn("startMediaRecorder -> mediaRecorder already recording, skipping", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
2184
2601
  return;
2185
2602
  }
2603
+ _classPrivateFieldGet(_this, _logger).info("startMediaRecorder -> calling start()", _objectSpread({
2604
+ timesliceMs: 5000
2605
+ }, _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this)));
2186
2606
  _classPrivateFieldGet(_this, _mediaRecorder).start(5000);
2187
- _classPrivateFieldGet(_this, _logger).info("started mediaRecorder");
2607
+ _classPrivateFieldGet(_this, _logger).info("startMediaRecorder -> start() returned", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
2188
2608
  _classPrivateFieldGet(_this, _startTimer).call(_this);
2189
2609
  } catch (error) {
2190
- _classPrivateFieldGet(_this, _logger).info("Failed to start mediaRecorder", error);
2610
+ _classPrivateFieldGet(_this, _logger).error("startMediaRecorder -> failed", _classPrivateFieldGet(_this, _serializeError).call(_this, error), _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
2191
2611
  _classPrivateFieldGet(_this, _store).setState({
2192
2612
  status: SCREEN_RECORDER_STATUS.idle,
2193
2613
  error: SCREEN_RECORDER_ERROR.FailedToStart
@@ -2213,7 +2633,14 @@ var ScreenRecorder = /*#__PURE__*/function () {
2213
2633
  _classPrivateFieldInitSpec(this, _startCountdown, {
2214
2634
  writable: true,
2215
2635
  value: function value() {
2216
- if (_classPrivateFieldGet(_this, _countdownTimerId)) return;
2636
+ if (_classPrivateFieldGet(_this, _countdownTimerId)) {
2637
+ _classPrivateFieldGet(_this, _logger).warn("startCountdown -> already running, ignoring", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
2638
+ return;
2639
+ }
2640
+ _classPrivateFieldGet(_this, _logger).info("startCountdown -> begin", {
2641
+ countdownTimeLeft: _classPrivateFieldGet(_this, _store).getState().countdownTimeLeft,
2642
+ playCountdownAudio: _classPrivateFieldGet(_this, _playCountdownAudio)
2643
+ });
2217
2644
  _classPrivateFieldGet(_this, _fireCallbacks).call(_this, SCREEN_RECORDER_EVENT.onCountdownStart);
2218
2645
  _classPrivateFieldSet(_this, _countdownTimerId, setInterval(function () {
2219
2646
  var shouldBeep = false;
@@ -2221,6 +2648,9 @@ var ScreenRecorder = /*#__PURE__*/function () {
2221
2648
  var countdownTimeLeft = _ref3.countdownTimeLeft;
2222
2649
  if (countdownTimeLeft - ONE_SECOND > 0) {
2223
2650
  var next = countdownTimeLeft - ONE_SECOND;
2651
+ _classPrivateFieldGet(_this, _logger).info("startCountdown -> tick", {
2652
+ remaining: next
2653
+ });
2224
2654
  _classPrivateFieldGet(_this, _fireCallbacks).call(_this, SCREEN_RECORDER_EVENT.onCountdown, [next]);
2225
2655
  shouldBeep = true;
2226
2656
  return {
@@ -2229,6 +2659,7 @@ var ScreenRecorder = /*#__PURE__*/function () {
2229
2659
  }
2230
2660
  _classPrivateFieldGet(_this, _fireCallbacks).call(_this, SCREEN_RECORDER_EVENT.onCountdown, [0]);
2231
2661
  setTimeout(function () {
2662
+ _classPrivateFieldGet(_this, _logger).info("startCountdown -> end, starting recorder");
2232
2663
  if (_classPrivateFieldGet(_this, _playCountdownAudio)) _classPrivateFieldGet(_this, _startRecordingAudio).play();
2233
2664
  _classPrivateFieldGet(_this, _fireCallbacks).call(_this, SCREEN_RECORDER_EVENT.onCountdownEnd);
2234
2665
  _classPrivateFieldGet(_this, _store).setState({
@@ -2280,12 +2711,22 @@ var ScreenRecorder = /*#__PURE__*/function () {
2280
2711
  var oneMinuteBeforeTimeLimit = _classPrivateFieldGet(_this, _timeLimit) - ONE_MINUTE_IN_MILLISECONDS;
2281
2712
  if (elapsedTime <= oneMinuteBeforeTimeLimit) return;
2282
2713
  if (elapsedTime < _classPrivateFieldGet(_this, _timeLimit) && elapsedTime > oneMinuteBeforeTimeLimit) {
2283
- not(_classPrivateFieldGet(_this, _store).getState().showTimeLimitWarning) && _classPrivateFieldGet(_this, _recordingLimitWarningAudio).play();
2714
+ if (not(_classPrivateFieldGet(_this, _store).getState().showTimeLimitWarning)) {
2715
+ _classPrivateFieldGet(_this, _logger).info("time limit warning threshold crossed", {
2716
+ elapsedTime: elapsedTime,
2717
+ timeLimit: _classPrivateFieldGet(_this, _timeLimit)
2718
+ });
2719
+ _classPrivateFieldGet(_this, _recordingLimitWarningAudio).play();
2720
+ }
2284
2721
  _classPrivateFieldGet(_this, _store).setState({
2285
2722
  showTimeLimitWarning: true
2286
2723
  });
2287
2724
  return;
2288
2725
  }
2726
+ _classPrivateFieldGet(_this, _logger).info("time limit reached, stopping recording", {
2727
+ elapsedTime: elapsedTime,
2728
+ timeLimit: _classPrivateFieldGet(_this, _timeLimit)
2729
+ });
2289
2730
  _classPrivateFieldGet(_this, _stopRecordingDueToLimitReachedAudio).play();
2290
2731
  _this.stopRecording();
2291
2732
  }
@@ -2313,8 +2754,8 @@ var ScreenRecorder = /*#__PURE__*/function () {
2313
2754
  }, {
2314
2755
  key: "displaySurface",
2315
2756
  get: function get() {
2316
- var _classPrivateFieldGet16, _classPrivateFieldGet17;
2317
- var _ref5 = (_classPrivateFieldGet16 = (_classPrivateFieldGet17 = _classPrivateFieldGet(this, _mediaStream)) === null || _classPrivateFieldGet17 === void 0 ? void 0 : _classPrivateFieldGet17.getVideoTracks()) !== null && _classPrivateFieldGet16 !== void 0 ? _classPrivateFieldGet16 : [],
2757
+ var _classPrivateFieldGet22, _classPrivateFieldGet23;
2758
+ var _ref5 = (_classPrivateFieldGet22 = (_classPrivateFieldGet23 = _classPrivateFieldGet(this, _mediaStream)) === null || _classPrivateFieldGet23 === void 0 ? void 0 : _classPrivateFieldGet23.getVideoTracks()) !== null && _classPrivateFieldGet22 !== void 0 ? _classPrivateFieldGet22 : [],
2318
2759
  _ref6 = _slicedToArray(_ref5, 1),
2319
2760
  videoTrack = _ref6[0];
2320
2761
  return videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.getSettings().displaySurface;