@bigbinary/neeto-media-recorder 2.7.35 → 2.7.36

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.
package/core.js CHANGED
@@ -745,54 +745,74 @@ var buildRetryableApi = function buildRetryableApi(apiConnector) {
745
745
  retryDelay = _ref$retryDelay === void 0 ? INITIAL_RETRY_DELAY : _ref$retryDelay;
746
746
  return /*#__PURE__*/function () {
747
747
  var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(apiConnectorArgs) {
748
- var _config$signal;
748
+ var _config$signal, _config$signal2;
749
749
  var _apiConnectorArgs$con, config, remainingAttempts, shouldCancelRetries, _error$config, _error$response, _error$response2;
750
750
  return _regeneratorRuntime.wrap(function _callee$(_context) {
751
751
  while (1) switch (_context.prev = _context.next) {
752
752
  case 0:
753
- _apiConnectorArgs$con = apiConnectorArgs.config, config = _apiConnectorArgs$con === void 0 ? null : _apiConnectorArgs$con;
753
+ _apiConnectorArgs$con = apiConnectorArgs.config, config = _apiConnectorArgs$con === void 0 ? null : _apiConnectorArgs$con; // If the signal is already aborted before we start, addEventListener("abort")
754
+ // will never fire — so we'd otherwise run the full retry/backoff schedule
755
+ // against an aborted request.
756
+ if (!(config !== null && config !== void 0 && (_config$signal = config.signal) !== null && _config$signal !== void 0 && _config$signal.aborted)) {
757
+ _context.next = 3;
758
+ break;
759
+ }
760
+ throw new RetryError("Request cancelled or request retries exhausted");
761
+ case 3:
754
762
  remainingAttempts = retries + 1;
755
763
  shouldCancelRetries = false;
756
- config === null || config === void 0 ? void 0 : (_config$signal = config.signal) === null || _config$signal === void 0 ? void 0 : _config$signal.addEventListener("abort", function () {
764
+ config === null || config === void 0 ? void 0 : (_config$signal2 = config.signal) === null || _config$signal2 === void 0 ? void 0 : _config$signal2.addEventListener("abort", function () {
757
765
  shouldCancelRetries = true;
758
766
  });
759
- case 4:
767
+ case 6:
760
768
  if (!(remainingAttempts-- && !shouldCancelRetries)) {
761
- _context.next = 24;
769
+ _context.next = 30;
762
770
  break;
763
771
  }
764
- _context.prev = 5;
765
- _context.next = 8;
772
+ _context.prev = 7;
773
+ _context.next = 10;
766
774
  return apiConnector(apiConnectorArgs);
767
- case 8:
775
+ case 10:
768
776
  return _context.abrupt("return", _context.sent);
769
- case 11:
770
- _context.prev = 11;
771
- _context.t0 = _context["catch"](5);
777
+ case 13:
778
+ _context.prev = 13;
779
+ _context.t0 = _context["catch"](7);
780
+ if (!axios.isCancel(_context.t0)) {
781
+ _context.next = 17;
782
+ break;
783
+ }
784
+ throw _context.t0;
785
+ case 17:
772
786
  logger.error("buildRetryableApi -> Failed to connect, remainingAttempts:", _context.t0 === null || _context.t0 === void 0 ? void 0 : (_error$config = _context.t0.config) === null || _error$config === void 0 ? void 0 : _error$config.url, (_error$response = _context.t0.response) === null || _error$response === void 0 ? void 0 : _error$response.status, remainingAttempts);
773
787
  if (!(((_error$response2 = _context.t0.response) === null || _error$response2 === void 0 ? void 0 : _error$response2.status) !== 401 && remainingAttempts > 0)) {
774
- _context.next = 21;
788
+ _context.next = 27;
775
789
  break;
776
790
  }
777
791
  logger.info("buildRetryableApi -> Failed to connect -> retry in:", retryDelay);
778
- _context.next = 18;
792
+ _context.next = 22;
779
793
  return sleep(retryDelay);
780
- case 18:
794
+ case 22:
781
795
  retryDelay = min(retryDelay * 2, MAX_RETRY_DELAY);
782
- _context.next = 22;
796
+ if (!shouldCancelRetries) {
797
+ _context.next = 25;
798
+ break;
799
+ }
800
+ throw _context.t0;
801
+ case 25:
802
+ _context.next = 28;
783
803
  break;
784
- case 21:
804
+ case 27:
785
805
  throw _context.t0;
786
- case 22:
787
- _context.next = 4;
806
+ case 28:
807
+ _context.next = 6;
788
808
  break;
789
- case 24:
809
+ case 30:
790
810
  throw new RetryError("Request cancelled or request retries exhausted");
791
- case 25:
811
+ case 31:
792
812
  case "end":
793
813
  return _context.stop();
794
814
  }
795
- }, _callee, null, [[5, 11]]);
815
+ }, _callee, null, [[7, 13]]);
796
816
  }));
797
817
  return function (_x) {
798
818
  return _ref2.apply(this, arguments);
@@ -1007,10 +1027,15 @@ var _serializeUploadError = /*#__PURE__*/new WeakMap();
1007
1027
  var _uploadChunkToS = /*#__PURE__*/new WeakMap();
1008
1028
  var _getCurrentUnUploadedBlob = /*#__PURE__*/new WeakMap();
1009
1029
  var _isRecordingNotSet = /*#__PURE__*/new WeakMap();
1030
+ var _isTerminalStatus = /*#__PURE__*/new WeakMap();
1010
1031
  var MultipartS3Uploader = /*#__PURE__*/function () {
1011
1032
  function MultipartS3Uploader() {
1012
1033
  var _this = this;
1013
1034
  _classCallCheck(this, MultipartS3Uploader);
1035
+ _classPrivateFieldInitSpec$1(this, _isTerminalStatus, {
1036
+ get: _get_isTerminalStatus,
1037
+ set: void 0
1038
+ });
1014
1039
  _classPrivateFieldInitSpec$1(this, _isRecordingNotSet, {
1015
1040
  get: _get_isRecordingNotSet,
1016
1041
  set: void 0
@@ -1097,6 +1122,19 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1097
1122
  _classPrivateFieldSet(_this, _abortController, new AbortController());
1098
1123
  });
1099
1124
  _defineProperty(this, "push", function (data) {
1125
+ // Once an uploader has been aborted, any further chunks belong to a
1126
+ // recording that no longer exists server-side. Drop them so we don't
1127
+ // spawn new part uploads against an aborted multipart upload (which
1128
+ // would otherwise loop on retries until the network gives up).
1129
+ if (_classPrivateFieldGet(_this, _isTerminalStatus)) {
1130
+ _classPrivateFieldGet(_this, _logger$1).warn("push -> uploader is no longer active, dropping chunk", {
1131
+ chunkBytes: data === null || data === void 0 ? void 0 : data.size,
1132
+ status: _classPrivateFieldGet(_this, _status),
1133
+ recordingId: _classPrivateFieldGet(_this, _recordingId)
1134
+ });
1135
+ _classPrivateFieldSet(_this, _unUploadedChunks, []);
1136
+ return;
1137
+ }
1100
1138
  if (data.size > 0) {
1101
1139
  _classPrivateFieldGet(_this, _unUploadedChunks).push(data);
1102
1140
  }
@@ -1280,6 +1318,8 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1280
1318
  var forceAbort,
1281
1319
  sessionLogs,
1282
1320
  abortStartedAt,
1321
+ phase,
1322
+ _classPrivateFieldGet3,
1283
1323
  recordingId,
1284
1324
  uploadId,
1285
1325
  _args2 = arguments;
@@ -1289,24 +1329,25 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1289
1329
  forceAbort = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : false;
1290
1330
  sessionLogs = _args2.length > 1 ? _args2[1] : undefined;
1291
1331
  abortStartedAt = Date.now();
1292
- _context2.prev = 3;
1332
+ phase = "init";
1333
+ _context2.prev = 4;
1293
1334
  if (!(_this.status === UPLOAD_STATUS.aborting && !forceAbort)) {
1294
- _context2.next = 7;
1335
+ _context2.next = 8;
1295
1336
  break;
1296
1337
  }
1297
1338
  _classPrivateFieldGet(_this, _logger$1).info("abortUpload -> already aborting", {
1298
1339
  forceAbort: forceAbort
1299
1340
  });
1300
1341
  return _context2.abrupt("return");
1301
- case 7:
1342
+ case 8:
1302
1343
  _classPrivateFieldSet(_this, _status2, UPLOAD_STATUS.aborting);
1303
1344
  if (!_classPrivateFieldGet(_this, _isRecordingNotSet)) {
1304
- _context2.next = 11;
1345
+ _context2.next = 12;
1305
1346
  break;
1306
1347
  }
1307
1348
  _classPrivateFieldGet(_this, _logger$1).info("abortUpload -> not initialized");
1308
1349
  return _context2.abrupt("return");
1309
- case 11:
1350
+ case 12:
1310
1351
  recordingId = _classPrivateFieldGet(_this, _recordingId);
1311
1352
  uploadId = _classPrivateFieldGet(_this, _uploadId);
1312
1353
  _classPrivateFieldGet(_this, _logger$1).info("abortUpload -> begin", {
@@ -1314,18 +1355,25 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1314
1355
  uploadId: uploadId,
1315
1356
  forceAbort: forceAbort,
1316
1357
  partsStarted: _classPrivateFieldGet(_this, _partNumber) - 1,
1317
- pendingS3ChunkUploads: _classPrivateFieldGet(_this, _pendingS3ChunkUploads).length
1358
+ pendingS3ChunkUploads: _classPrivateFieldGet(_this, _pendingS3ChunkUploads).length,
1359
+ hasAbortController: Boolean(_classPrivateFieldGet(_this, _abortController))
1318
1360
  });
1319
1361
 
1320
1362
  // Don't let a rejected completeUpload stop us from issuing the abort API
1321
1363
  // call below — we still need to release the upload server-side.
1364
+ phase = "awaitCompleteUploadPromise";
1322
1365
  // eslint-disable-next-line promise/prefer-await-to-then
1323
- _context2.next = 16;
1366
+ _context2.next = 18;
1324
1367
  return Promise.resolve(_classPrivateFieldGet(_this, _completeUploadPromise))["catch"](function () {});
1325
- case 16:
1326
- _classPrivateFieldGet(_this, _abortController).abort();
1327
- _context2.prev = 17;
1328
- _context2.next = 20;
1368
+ case 18:
1369
+ // Guard against a missing AbortController. If abortUpload is somehow
1370
+ // invoked twice, the second call would hit a null #abortController and
1371
+ // throw a TypeError into the outer catch — masking the real failure.
1372
+ phase = "abortInflight";
1373
+ (_classPrivateFieldGet3 = _classPrivateFieldGet(_this, _abortController)) === null || _classPrivateFieldGet3 === void 0 ? void 0 : _classPrivateFieldGet3.abort();
1374
+ phase = "abortUploadApi";
1375
+ _context2.prev = 21;
1376
+ _context2.next = 24;
1329
1377
  return abortUploadApi.create({
1330
1378
  recordingId: recordingId,
1331
1379
  payload: {
@@ -1334,41 +1382,45 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1334
1382
  logs: sessionLogs
1335
1383
  }
1336
1384
  });
1337
- case 20:
1385
+ case 24:
1338
1386
  _classPrivateFieldGet(_this, _logger$1).info("abortUpload -> success", {
1339
1387
  durationMs: Date.now() - abortStartedAt
1340
1388
  });
1341
- _context2.next = 26;
1389
+ _context2.next = 30;
1342
1390
  break;
1343
- case 23:
1344
- _context2.prev = 23;
1345
- _context2.t0 = _context2["catch"](17);
1391
+ case 27:
1392
+ _context2.prev = 27;
1393
+ _context2.t0 = _context2["catch"](21);
1346
1394
  // After retries are exhausted, proceed with local cleanup so the
1347
1395
  // caller can navigate away / close tab. The server-side upload
1348
1396
  // will be cleaned up by S3 lifecycle rules.
1349
1397
  _classPrivateFieldGet(_this, _logger$1).error("abortUpload -> mark as discarded failed", _objectSpread$2(_objectSpread$2({}, _classPrivateFieldGet(_this, _serializeUploadError).call(_this, _context2.t0)), {}, {
1350
1398
  durationMs: Date.now() - abortStartedAt
1351
1399
  }));
1352
- case 26:
1400
+ case 30:
1401
+ phase = "fireOnAbort";
1353
1402
  _classPrivateFieldGet(_this, _fireCallbacks$1).call(_this, UPLOAD_EVENT.onAbort);
1403
+ phase = "cleanup";
1354
1404
  _classPrivateFieldSet(_this, _unUploadedChunks, []);
1355
1405
  _classPrivateFieldSet(_this, _partNumber, 1);
1356
1406
  _classPrivateFieldSet(_this, _s3PartUploadPromises, []);
1357
1407
  _classPrivateFieldSet(_this, _status2, "");
1358
1408
  _classPrivateFieldSet(_this, _abortController, null);
1359
- _context2.next = 37;
1409
+ _context2.next = 43;
1360
1410
  break;
1361
- case 34:
1362
- _context2.prev = 34;
1363
- _context2.t1 = _context2["catch"](3);
1364
- _classPrivateFieldGet(_this, _logger$1).error("abortUpload -> failed", _objectSpread$2(_objectSpread$2({}, _classPrivateFieldGet(_this, _serializeUploadError).call(_this, _context2.t1)), {}, {
1411
+ case 40:
1412
+ _context2.prev = 40;
1413
+ _context2.t1 = _context2["catch"](4);
1414
+ _classPrivateFieldGet(_this, _logger$1).error("abortUpload -> failed", _objectSpread$2(_objectSpread$2({
1415
+ phase: phase
1416
+ }, _classPrivateFieldGet(_this, _serializeUploadError).call(_this, _context2.t1)), {}, {
1365
1417
  durationMs: Date.now() - abortStartedAt
1366
1418
  }));
1367
- case 37:
1419
+ case 43:
1368
1420
  case "end":
1369
1421
  return _context2.stop();
1370
1422
  }
1371
- }, _callee2, null, [[3, 34], [17, 23]]);
1423
+ }, _callee2, null, [[4, 40], [21, 27]]);
1372
1424
  })));
1373
1425
  _defineProperty(this, "resetState", function () {
1374
1426
  _classPrivateFieldSet(_this, _recordingId, "");
@@ -1384,22 +1436,22 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1384
1436
  _classPrivateFieldSet(_this, _status2, "");
1385
1437
  });
1386
1438
  _defineProperty(this, "addCallback", function (event, callback) {
1387
- var _classPrivateFieldGet3;
1388
- var existingCallbacks = (_classPrivateFieldGet3 = _classPrivateFieldGet(_this, _callbacks$1)[event]) !== null && _classPrivateFieldGet3 !== void 0 ? _classPrivateFieldGet3 : [];
1439
+ var _classPrivateFieldGet4;
1440
+ var existingCallbacks = (_classPrivateFieldGet4 = _classPrivateFieldGet(_this, _callbacks$1)[event]) !== null && _classPrivateFieldGet4 !== void 0 ? _classPrivateFieldGet4 : [];
1389
1441
  _classPrivateFieldSet(_this, _callbacks$1, _objectSpread$2(_objectSpread$2({}, _classPrivateFieldGet(_this, _callbacks$1)), {}, _defineProperty({}, event, [].concat(_toConsumableArray(existingCallbacks), [callback]))));
1390
1442
  });
1391
1443
  _defineProperty(this, "removeCallback", function (event, callback) {
1392
- var _classPrivateFieldGet4;
1393
- var registeredCallbacks = (_classPrivateFieldGet4 = _classPrivateFieldGet(_this, _callbacks$1)[event]) !== null && _classPrivateFieldGet4 !== void 0 ? _classPrivateFieldGet4 : [];
1444
+ var _classPrivateFieldGet5;
1445
+ var registeredCallbacks = (_classPrivateFieldGet5 = _classPrivateFieldGet(_this, _callbacks$1)[event]) !== null && _classPrivateFieldGet5 !== void 0 ? _classPrivateFieldGet5 : [];
1394
1446
  var updatedCallbacks = registeredCallbacks.filter(isNot(callback));
1395
1447
  _classPrivateFieldSet(_this, _callbacks$1, _objectSpread$2(_objectSpread$2({}, _classPrivateFieldGet(_this, _callbacks$1)), {}, _defineProperty({}, event, updatedCallbacks)));
1396
1448
  });
1397
1449
  _classPrivateFieldInitSpec$1(this, _fireCallbacks$1, {
1398
1450
  writable: true,
1399
1451
  value: function value(event) {
1400
- var _classPrivateFieldGet5;
1452
+ var _classPrivateFieldGet6;
1401
1453
  var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
1402
- (_classPrivateFieldGet5 = _classPrivateFieldGet(_this, _callbacks$1)[event]) === null || _classPrivateFieldGet5 === void 0 ? void 0 : _classPrivateFieldGet5.forEach(function (callback) {
1454
+ (_classPrivateFieldGet6 = _classPrivateFieldGet(_this, _callbacks$1)[event]) === null || _classPrivateFieldGet6 === void 0 ? void 0 : _classPrivateFieldGet6.forEach(function (callback) {
1403
1455
  callback.apply(void 0, _toConsumableArray(args));
1404
1456
  });
1405
1457
  }
@@ -1449,7 +1501,7 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1449
1501
  }
1450
1502
  });
1451
1503
  _defineProperty(this, "generatePreSignedUrl", function (partNumber) {
1452
- var _classPrivateFieldGet6;
1504
+ var _classPrivateFieldGet7;
1453
1505
  return partPresignedUrlApi.create({
1454
1506
  recordingId: _classPrivateFieldGet(_this, _recordingId),
1455
1507
  payload: {
@@ -1458,7 +1510,7 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1458
1510
  isMp4: _classPrivateFieldGet(_this, _mimeType$1).includes(MIME_TYPE.mp4)
1459
1511
  },
1460
1512
  config: {
1461
- signal: (_classPrivateFieldGet6 = _classPrivateFieldGet(_this, _abortController)) === null || _classPrivateFieldGet6 === void 0 ? void 0 : _classPrivateFieldGet6.signal
1513
+ signal: (_classPrivateFieldGet7 = _classPrivateFieldGet(_this, _abortController)) === null || _classPrivateFieldGet7 === void 0 ? void 0 : _classPrivateFieldGet7.signal
1462
1514
  }
1463
1515
  });
1464
1516
  });
@@ -1466,7 +1518,7 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1466
1518
  writable: true,
1467
1519
  value: function () {
1468
1520
  var _value = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(chunks) {
1469
- var _this$partNumber, _classPrivateFieldGet7;
1521
+ var _this$partNumber, _classPrivateFieldGet8;
1470
1522
  var partNumber, partBlob, partBytes, presignStartedAt, presignedUrl, _yield$_this$generate, uploadStartedAt, s3PartUploadPromise;
1471
1523
  return _regeneratorRuntime.wrap(function _callee3$(_context3) {
1472
1524
  while (1) switch (_context3.prev = _context3.next) {
@@ -1520,7 +1572,7 @@ var MultipartS3Uploader = /*#__PURE__*/function () {
1520
1572
  "Content-Type": _classPrivateFieldGet(_this, _mimeType$1)
1521
1573
  },
1522
1574
  includeMetadataInResponse: true,
1523
- signal: (_classPrivateFieldGet7 = _classPrivateFieldGet(_this, _abortController)) === null || _classPrivateFieldGet7 === void 0 ? void 0 : _classPrivateFieldGet7.signal,
1575
+ signal: (_classPrivateFieldGet8 = _classPrivateFieldGet(_this, _abortController)) === null || _classPrivateFieldGet8 === void 0 ? void 0 : _classPrivateFieldGet8.signal,
1524
1576
  onUploadProgress: function onUploadProgress(e) {
1525
1577
  _classPrivateFieldGet(_this, _uploadProgress)[partNumber] = {
1526
1578
  uploaded: e.loaded,
@@ -1621,6 +1673,9 @@ function _set_status(status) {
1621
1673
  function _get_isRecordingNotSet() {
1622
1674
  return isEmpty(_classPrivateFieldGet(this, _uploadId) + _classPrivateFieldGet(this, _recordingId));
1623
1675
  }
1676
+ function _get_isTerminalStatus() {
1677
+ return _classPrivateFieldGet(this, _status) === UPLOAD_STATUS.aborting || _classPrivateFieldGet(this, _status) === UPLOAD_STATUS.completed || _classPrivateFieldGet(this, _status) === UPLOAD_STATUS.error;
1678
+ }
1624
1679
  var multipartS3Uploader = new MultipartS3Uploader();
1625
1680
  var getMultipartS3Uploader = function getMultipartS3Uploader() {
1626
1681
  var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},