@sentry/replay 7.59.3 → 7.60.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
@@ -46,6 +46,11 @@ const SLOW_CLICK_SCROLL_TIMEOUT = 300;
46
46
  /** When encountering a total segment size exceeding this size, stop the replay (as we cannot properly ingest it). */
47
47
  const REPLAY_MAX_EVENT_BUFFER_SIZE = 20000000; // ~20MB
48
48
 
49
+ /** Replays must be min. 5s long before we send them. */
50
+ const MIN_REPLAY_DURATION = 4999;
51
+ /* The max. allowed value that the minReplayDuration can be set to. */
52
+ const MIN_REPLAY_DURATION_LIMIT = 15000;
53
+
49
54
  var NodeType$1;
50
55
  (function (NodeType) {
51
56
  NodeType[NodeType["Document"] = 0] = "Document";
@@ -3270,6 +3275,22 @@ record.takeFullSnapshot = (isCheckout) => {
3270
3275
  };
3271
3276
  record.mirror = mirror;
3272
3277
 
3278
+ /**
3279
+ * Converts a timestamp to ms, if it was in s, or keeps it as ms.
3280
+ */
3281
+ function timestampToMs(timestamp) {
3282
+ const isMs = timestamp > 9999999999;
3283
+ return isMs ? timestamp : timestamp * 1000;
3284
+ }
3285
+
3286
+ /**
3287
+ * Converts a timestamp to s, if it was in ms, or keeps it as s.
3288
+ */
3289
+ function timestampToS(timestamp) {
3290
+ const isMs = timestamp > 9999999999;
3291
+ return isMs ? timestamp / 1000 : timestamp;
3292
+ }
3293
+
3273
3294
  /**
3274
3295
  * Add a breadcrumb event to replay.
3275
3296
  */
@@ -3469,7 +3490,7 @@ class ClickDetector {
3469
3490
  }
3470
3491
 
3471
3492
  const newClick = {
3472
- timestamp: breadcrumb.timestamp,
3493
+ timestamp: timestampToS(breadcrumb.timestamp),
3473
3494
  clickBreadcrumb: breadcrumb,
3474
3495
  // Set this to 0 so we know it originates from the click breadcrumb
3475
3496
  clickCount: 0,
@@ -3509,6 +3530,7 @@ class ClickDetector {
3509
3530
  click.scrollAfter = click.timestamp <= this._lastScroll ? this._lastScroll - click.timestamp : undefined;
3510
3531
  }
3511
3532
 
3533
+ // All of these are in seconds!
3512
3534
  if (click.timestamp + this._timeout <= now) {
3513
3535
  timedOutClicks.push(click);
3514
3536
  }
@@ -3516,10 +3538,10 @@ class ClickDetector {
3516
3538
 
3517
3539
  // Remove "old" clicks
3518
3540
  for (const click of timedOutClicks) {
3519
- this._generateBreadcrumbs(click);
3520
-
3521
3541
  const pos = this._clicks.indexOf(click);
3522
- if (pos !== -1) {
3542
+
3543
+ if (pos > -1) {
3544
+ this._generateBreadcrumbs(click);
3523
3545
  this._clicks.splice(pos, 1);
3524
3546
  }
3525
3547
  }
@@ -3984,14 +4006,6 @@ function t(t){let e=t.length;for(;--e>=0;)t[e]=0}const e=new Uint8Array([0,0,0,0
3984
4006
 
3985
4007
  function e(){const e=new Blob([r]);return URL.createObjectURL(e)}
3986
4008
 
3987
- /**
3988
- * Converts a timestamp to ms, if it was in s, or keeps it as ms.
3989
- */
3990
- function timestampToMs(timestamp) {
3991
- const isMs = timestamp > 9999999999;
3992
- return isMs ? timestamp : timestamp * 1000;
3993
- }
3994
-
3995
4009
  /** This error indicates that the event buffer size exceeded the limit.. */
3996
4010
  class EventBufferSizeExceededError extends Error {
3997
4011
  constructor() {
@@ -7940,6 +7954,9 @@ class ReplayContainer {
7940
7954
 
7941
7955
  const earliestEvent = eventBuffer.getEarliestTimestamp();
7942
7956
  if (earliestEvent && earliestEvent < this._context.initialTimestamp) {
7957
+ // eslint-disable-next-line no-console
7958
+ const log = this.getOptions()._experiments.traceInternals ? console.info : logger.info;
7959
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && log(`[Replay] Updating initial timestamp to ${earliestEvent}`);
7943
7960
  this._context.initialTimestamp = earliestEvent;
7944
7961
  }
7945
7962
  }
@@ -8054,6 +8071,23 @@ class ReplayContainer {
8054
8071
  return;
8055
8072
  }
8056
8073
 
8074
+ const start = this._context.initialTimestamp;
8075
+ const now = Date.now();
8076
+ const duration = now - start;
8077
+
8078
+ // If session is too short, or too long (allow some wiggle room over maxSessionLife), do not send it
8079
+ // This _should_ not happen, but it may happen if flush is triggered due to a page activity change or similar
8080
+ if (duration < this._options.minReplayDuration || duration > this.timeouts.maxSessionLife + 5000) {
8081
+ // eslint-disable-next-line no-console
8082
+ const log = this.getOptions()._experiments.traceInternals ? console.warn : logger.warn;
8083
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
8084
+ log(
8085
+ `[Replay] Session duration (${Math.floor(duration / 1000)}s) is too short or too long, not sending replay.`,
8086
+ );
8087
+
8088
+ return;
8089
+ }
8090
+
8057
8091
  // A flush is about to happen, cancel any queued flushes
8058
8092
  this._debouncedFlush.cancel();
8059
8093
 
@@ -8256,6 +8290,7 @@ class Replay {
8256
8290
  constructor({
8257
8291
  flushMinDelay = DEFAULT_FLUSH_MIN_DELAY,
8258
8292
  flushMaxDelay = DEFAULT_FLUSH_MAX_DELAY,
8293
+ minReplayDuration = MIN_REPLAY_DURATION,
8259
8294
  stickySession = true,
8260
8295
  useCompression = true,
8261
8296
  _experiments = {},
@@ -8332,6 +8367,7 @@ class Replay {
8332
8367
  this._initialOptions = {
8333
8368
  flushMinDelay,
8334
8369
  flushMaxDelay,
8370
+ minReplayDuration: Math.min(minReplayDuration, MIN_REPLAY_DURATION_LIMIT),
8335
8371
  stickySession,
8336
8372
  sessionSampleRate,
8337
8373
  errorSampleRate,