@sentry/replay 7.89.0 → 7.91.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/esm/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { addBreadcrumb, getClient, isSentryRequestUrl, getCurrentScope, addEventProcessor, prepareEvent, setContext, captureException } from '@sentry/core';
1
+ import { addBreadcrumb, getClient, isSentryRequestUrl, getCurrentScope, addEventProcessor, prepareEvent, getIsolationScope, setContext, captureException } from '@sentry/core';
2
2
  import { GLOBAL_OBJ, normalize, fill, htmlTreeAsString, browserPerformanceTimeOrigin, logger, uuid4, SENTRY_XHR_DATA_KEY, dropUndefinedKeys, stringMatchesSomePattern, addFetchInstrumentationHandler, addXhrInstrumentationHandler, addClickKeypressInstrumentationHandler, addHistoryInstrumentationHandler, createEnvelope, createEventEnvelopeHeaders, getSdkMetadataForEnvelopeHeader, updateRateLimits, isRateLimited, consoleSandbox, isBrowser } from '@sentry/utils';
3
3
  import { addPerformanceInstrumentationHandler, addLcpInstrumentationHandler } from '@sentry-internal/tracing';
4
4
 
@@ -52,6 +52,36 @@ const MIN_REPLAY_DURATION_LIMIT = 15000;
52
52
  /** The max. length of a replay. */
53
53
  const MAX_REPLAY_DURATION = 3600000; // 60 minutes in ms;
54
54
 
55
+ const CANVAS_QUALITY = {
56
+ low: {
57
+ sampling: {
58
+ canvas: 1,
59
+ },
60
+ dataURLOptions: {
61
+ type: 'image/webp',
62
+ quality: 0.25,
63
+ },
64
+ },
65
+ medium: {
66
+ sampling: {
67
+ canvas: 2,
68
+ },
69
+ dataURLOptions: {
70
+ type: 'image/webp',
71
+ quality: 0.4,
72
+ },
73
+ },
74
+ high: {
75
+ sampling: {
76
+ canvas: 4,
77
+ },
78
+ dataURLOptions: {
79
+ type: 'image/webp',
80
+ quality: 0.5,
81
+ },
82
+ },
83
+ };
84
+
55
85
  var NodeType$1;
56
86
  (function (NodeType) {
57
87
  NodeType[NodeType["Document"] = 0] = "Document";
@@ -3914,7 +3944,9 @@ function addBreadcrumbEvent(replay, breadcrumb) {
3914
3944
  }
3915
3945
 
3916
3946
  replay.addUpdate(() => {
3917
- void replay.throttledAddEvent({
3947
+ // This should never reject
3948
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
3949
+ replay.throttledAddEvent({
3918
3950
  type: EventType.Custom,
3919
3951
  // TODO: We were converting from ms to seconds for breadcrumbs, spans,
3920
3952
  // but maybe we should just keep them as milliseconds
@@ -4345,6 +4377,7 @@ const ATTRIBUTES_TO_RECORD = new Set([
4345
4377
  'data-testid',
4346
4378
  'disabled',
4347
4379
  'aria-disabled',
4380
+ 'data-sentry-component',
4348
4381
  ]);
4349
4382
 
4350
4383
  /**
@@ -5028,7 +5061,9 @@ class EventBufferCompressionWorker {
5028
5061
  this.hasCheckout = false;
5029
5062
 
5030
5063
  // We do not wait on this, as we assume the order of messages is consistent for the worker
5031
- void this._worker.postMessage('clear');
5064
+ this._worker.postMessage('clear').then(null, e => {
5065
+ DEBUG_BUILD && logger.warn('[Replay] Sending "clear" message to worker failed', e);
5066
+ });
5032
5067
  }
5033
5068
 
5034
5069
  /** @inheritdoc */
@@ -5464,7 +5499,9 @@ function addEventSync(replay, event, isCheckout) {
5464
5499
  return false;
5465
5500
  }
5466
5501
 
5467
- void _addEvent(replay, event, isCheckout);
5502
+ // This should never reject
5503
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
5504
+ _addEvent(replay, event, isCheckout);
5468
5505
 
5469
5506
  return true;
5470
5507
  }
@@ -5661,7 +5698,9 @@ function handleErrorEvent(replay, event) {
5661
5698
 
5662
5699
  setTimeout(() => {
5663
5700
  // Capture current event buffer as new replay
5664
- void replay.sendBufferedReplayOrFlush();
5701
+ // This should never reject
5702
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
5703
+ replay.sendBufferedReplayOrFlush();
5665
5704
  });
5666
5705
  }
5667
5706
 
@@ -5705,8 +5744,9 @@ function handleHydrationError(replay, event) {
5705
5744
  // Example https://reactjs.org/docs/error-decoder.html?invariant=423
5706
5745
  exceptionValue.match(/reactjs\.org\/docs\/error-decoder\.html\?invariant=(418|419|422|423|425)/) ||
5707
5746
  // Development builds of react-dom
5708
- // Example Text: content did not match. Server: "A" Client: "B"
5709
- exceptionValue.match(/(hydration|content does not match|did not match)/i)
5747
+ // Error 1: Hydration failed because the initial UI does not match what was rendered on the server.
5748
+ // Error 2: Text content does not match server-rendered HTML. Warning: Text content did not match.
5749
+ exceptionValue.match(/(does not match server-rendered HTML|Hydration failed because)/i)
5710
5750
  ) {
5711
5751
  const breadcrumb = createBreadcrumb({
5712
5752
  category: 'replay.hydrate-error',
@@ -5743,7 +5783,9 @@ function addFeedbackBreadcrumb(replay, event) {
5743
5783
  return true;
5744
5784
  }
5745
5785
 
5746
- void replay.throttledAddEvent({
5786
+ // This should never reject
5787
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
5788
+ replay.throttledAddEvent({
5747
5789
  type: EventType.Custom,
5748
5790
  timestamp: event.timestamp * 1000,
5749
5791
  data: {
@@ -5821,7 +5863,9 @@ function handleGlobalEventListener(
5821
5863
  }
5822
5864
 
5823
5865
  if (isFeedbackEvent(event)) {
5824
- void replay.flush();
5866
+ // This should never reject
5867
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
5868
+ replay.flush();
5825
5869
  event.contexts.feedback.replay_id = replay.getSessionId();
5826
5870
  // Add a replay breadcrumb for this piece of feedback
5827
5871
  addFeedbackBreadcrumb(replay, event);
@@ -6875,7 +6919,9 @@ function beforeAddNetworkBreadcrumb(
6875
6919
  // So any async mutations to it will not be reflected in the final breadcrumb
6876
6920
  enrichXhrBreadcrumb(breadcrumb, hint, options);
6877
6921
 
6878
- void captureXhrBreadcrumbToReplay(breadcrumb, hint, options);
6922
+ // This call should not reject
6923
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
6924
+ captureXhrBreadcrumbToReplay(breadcrumb, hint, options);
6879
6925
  }
6880
6926
 
6881
6927
  if (_isFetchBreadcrumb(breadcrumb) && _isFetchHint(hint)) {
@@ -6884,7 +6930,9 @@ function beforeAddNetworkBreadcrumb(
6884
6930
  // So any async mutations to it will not be reflected in the final breadcrumb
6885
6931
  enrichFetchBreadcrumb(breadcrumb, hint, options);
6886
6932
 
6887
- void captureFetchBreadcrumbToReplay(breadcrumb, hint, options);
6933
+ // This call should not reject
6934
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
6935
+ captureFetchBreadcrumbToReplay(breadcrumb, hint, options);
6888
6936
  }
6889
6937
  } catch (e) {
6890
6938
  DEBUG_BUILD && logger.warn('Error when enriching network breadcrumb');
@@ -7067,7 +7115,9 @@ function addGlobalListeners(replay) {
7067
7115
  client.on('beforeSendFeedback', (feedbackEvent, options) => {
7068
7116
  const replayId = replay.getSessionId();
7069
7117
  if (options && options.includeReplay && replay.isEnabled() && replayId) {
7070
- void replay.flush();
7118
+ // This should never reject
7119
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
7120
+ replay.flush();
7071
7121
  if (feedbackEvent.contexts && feedbackEvent.contexts.feedback) {
7072
7122
  feedbackEvent.contexts.feedback.replay_id = replayId;
7073
7123
  }
@@ -7273,6 +7323,9 @@ function getHandleRecordingEmit(replay) {
7273
7323
  // a previous session ID. In this case, we want to buffer events
7274
7324
  // for a set amount of time before flushing. This can help avoid
7275
7325
  // capturing replays of users that immediately close the window.
7326
+
7327
+ // This should never reject
7328
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
7276
7329
  void replay.flush();
7277
7330
  }
7278
7331
 
@@ -7408,6 +7461,7 @@ async function prepareReplayEvent({
7408
7461
  eventHint,
7409
7462
  scope,
7410
7463
  client,
7464
+ getIsolationScope(),
7411
7465
  )) ;
7412
7466
 
7413
7467
  // If e.g. a global event processor returned null
@@ -7955,15 +8009,12 @@ class ReplayContainer {
7955
8009
  ...(this.recordingMode === 'buffer' && { checkoutEveryNms: BUFFER_CHECKOUT_TIME }),
7956
8010
  emit: getHandleRecordingEmit(this),
7957
8011
  onMutation: this._onMutationHandler,
7958
- ...(canvas && {
7959
- recordCanvas: true,
7960
- sampling: { canvas: canvas.fps || 4 },
7961
- dataURLOptions: {
7962
- type: canvas.type || 'image/webp',
7963
- quality: canvas.quality || 0.6,
7964
- },
7965
- getCanvasManager: canvas.manager,
7966
- }),
8012
+ ...(canvas &&
8013
+ canvas.manager && {
8014
+ recordCanvas: true,
8015
+ getCanvasManager: canvas.manager,
8016
+ ...(CANVAS_QUALITY[canvas.quality || 'medium'] || CANVAS_QUALITY.medium),
8017
+ }),
7967
8018
  });
7968
8019
  } catch (err) {
7969
8020
  this._handleException(err);
@@ -8403,7 +8454,9 @@ class ReplayContainer {
8403
8454
  maxReplayDuration: this._options.maxReplayDuration,
8404
8455
  })
8405
8456
  ) {
8406
- void this._refreshSession(currentSession);
8457
+ // This should never reject
8458
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
8459
+ this._refreshSession(currentSession);
8407
8460
  return false;
8408
8461
  }
8409
8462
 
@@ -8542,6 +8595,8 @@ class ReplayContainer {
8542
8595
  // Send replay when the page/tab becomes hidden. There is no reason to send
8543
8596
  // replay if it becomes visible, since no actions we care about were done
8544
8597
  // while it was hidden
8598
+ // This should never reject
8599
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
8545
8600
  void this.conditionalFlush();
8546
8601
  }
8547
8602
 
@@ -8590,7 +8645,9 @@ class ReplayContainer {
8590
8645
  */
8591
8646
  _createCustomBreadcrumb(breadcrumb) {
8592
8647
  this.addUpdate(() => {
8593
- void this.throttledAddEvent({
8648
+ // This should never reject
8649
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
8650
+ this.throttledAddEvent({
8594
8651
  type: EventType.Custom,
8595
8652
  timestamp: breadcrumb.timestamp || 0,
8596
8653
  data: {
@@ -8731,7 +8788,9 @@ class ReplayContainer {
8731
8788
  // This means we retried 3 times and all of them failed,
8732
8789
  // or we ran into a problem we don't want to retry, like rate limiting.
8733
8790
  // In this case, we want to completely stop the replay - otherwise, we may get inconsistent segments
8734
- void this.stop({ reason: 'sendReplay' });
8791
+ // This should never reject
8792
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
8793
+ this.stop({ reason: 'sendReplay' });
8735
8794
 
8736
8795
  const client = getClient();
8737
8796
 
@@ -8850,7 +8909,9 @@ class ReplayContainer {
8850
8909
 
8851
8910
  // Stop replay if over the mutation limit
8852
8911
  if (overMutationLimit) {
8853
- void this.stop({ reason: 'mutationLimit', forceFlush: this.recordingMode === 'session' });
8912
+ // This should never reject
8913
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
8914
+ this.stop({ reason: 'mutationLimit', forceFlush: this.recordingMode === 'session' });
8854
8915
  return false;
8855
8916
  }
8856
8917