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