@sentry/replay 7.54.0 → 7.55.1

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 (39) hide show
  1. package/cjs/index.js +104 -63
  2. package/cjs/index.js.map +1 -1
  3. package/esm/index.js +104 -63
  4. package/esm/index.js.map +1 -1
  5. package/package.json +5 -5
  6. package/types/constants.d.ts +2 -0
  7. package/types/constants.d.ts.map +1 -1
  8. package/types/coreHandlers/handleDom.d.ts.map +1 -1
  9. package/types/coreHandlers/handleKeyboardEvent.d.ts.map +1 -1
  10. package/types/coreHandlers/handleScope.d.ts +4 -1
  11. package/types/coreHandlers/handleScope.d.ts.map +1 -1
  12. package/types/coreHandlers/handleSlowClick.d.ts +2 -0
  13. package/types/coreHandlers/handleSlowClick.d.ts.map +1 -1
  14. package/types/coreHandlers/util/getAttributesToRecord.d.ts.map +1 -1
  15. package/types/index.d.ts +1 -0
  16. package/types/index.d.ts.map +1 -1
  17. package/types/integration.d.ts +1 -1
  18. package/types/integration.d.ts.map +1 -1
  19. package/types/replay.d.ts +8 -0
  20. package/types/replay.d.ts.map +1 -1
  21. package/types/session/getSession.d.ts.map +1 -1
  22. package/types/types/index.d.ts +6 -0
  23. package/types/types/index.d.ts.map +1 -0
  24. package/types/types/performance.d.ts +124 -0
  25. package/types/types/performance.d.ts.map +1 -0
  26. package/types/{types.d.ts → types/replay.d.ts} +21 -144
  27. package/types/types/replay.d.ts.map +1 -0
  28. package/types/types/replayFrame.d.ts +160 -0
  29. package/types/types/replayFrame.d.ts.map +1 -0
  30. package/types/types/request.d.ts +15 -0
  31. package/types/types/request.d.ts.map +1 -0
  32. package/types/types/rrweb.d.ts +1 -9
  33. package/types/types/rrweb.d.ts.map +1 -1
  34. package/types/util/addEvent.d.ts.map +1 -1
  35. package/types/util/createBreadcrumb.d.ts +2 -4
  36. package/types/util/createBreadcrumb.d.ts.map +1 -1
  37. package/types/util/handleRecordingEmit.d.ts +2 -2
  38. package/types/util/handleRecordingEmit.d.ts.map +1 -1
  39. package/types/types.d.ts.map +0 -1
package/esm/index.js CHANGED
@@ -38,6 +38,11 @@ const NETWORK_BODY_MAX_SIZE = 150000;
38
38
  /* The max size of a single console arg that is captured. Any arg larger than this will be truncated. */
39
39
  const CONSOLE_ARG_MAX_SIZE = 5000;
40
40
 
41
+ /* Min. time to wait before we consider something a slow click. */
42
+ const SLOW_CLICK_THRESHOLD = 3000;
43
+ /* For scroll actions after a click, we only look for a very short time period to detect programmatic scrolling. */
44
+ const SLOW_CLICK_SCROLL_TIMEOUT = 300;
45
+
41
46
  var NodeType$1;
42
47
  (function (NodeType) {
43
48
  NodeType[NodeType["Document"] = 0] = "Document";
@@ -991,7 +996,7 @@ function skipAttribute(tagName, attributeName, value) {
991
996
  return ((tagName === 'video' || tagName === 'audio') && attributeName === 'autoplay');
992
997
  }
993
998
 
994
- var EventType$1;
999
+ var EventType;
995
1000
  (function (EventType) {
996
1001
  EventType[EventType["DomContentLoaded"] = 0] = "DomContentLoaded";
997
1002
  EventType[EventType["Load"] = 1] = "Load";
@@ -1000,7 +1005,7 @@ var EventType$1;
1000
1005
  EventType[EventType["Meta"] = 4] = "Meta";
1001
1006
  EventType[EventType["Custom"] = 5] = "Custom";
1002
1007
  EventType[EventType["Plugin"] = 6] = "Plugin";
1003
- })(EventType$1 || (EventType$1 = {}));
1008
+ })(EventType || (EventType = {}));
1004
1009
  var IncrementalSource;
1005
1010
  (function (IncrementalSource) {
1006
1011
  IncrementalSource[IncrementalSource["Mutation"] = 0] = "Mutation";
@@ -2973,17 +2978,17 @@ function record(options = {}) {
2973
2978
  wrappedEmit = (e, isCheckout) => {
2974
2979
  var _a;
2975
2980
  if (((_a = mutationBuffers[0]) === null || _a === void 0 ? void 0 : _a.isFrozen()) &&
2976
- e.type !== EventType$1.FullSnapshot &&
2977
- !(e.type === EventType$1.IncrementalSnapshot &&
2981
+ e.type !== EventType.FullSnapshot &&
2982
+ !(e.type === EventType.IncrementalSnapshot &&
2978
2983
  e.data.source === IncrementalSource.Mutation)) {
2979
2984
  mutationBuffers.forEach((buf) => buf.unfreeze());
2980
2985
  }
2981
2986
  emit(eventProcessor(e), isCheckout);
2982
- if (e.type === EventType$1.FullSnapshot) {
2987
+ if (e.type === EventType.FullSnapshot) {
2983
2988
  lastFullSnapshotEvent = e;
2984
2989
  incrementalSnapshotCount = 0;
2985
2990
  }
2986
- else if (e.type === EventType$1.IncrementalSnapshot) {
2991
+ else if (e.type === EventType.IncrementalSnapshot) {
2987
2992
  if (e.data.source === IncrementalSource.Mutation &&
2988
2993
  e.data.isAttachIframe) {
2989
2994
  return;
@@ -2999,16 +3004,16 @@ function record(options = {}) {
2999
3004
  };
3000
3005
  const wrappedMutationEmit = (m) => {
3001
3006
  wrappedEmit(wrapEvent({
3002
- type: EventType$1.IncrementalSnapshot,
3007
+ type: EventType.IncrementalSnapshot,
3003
3008
  data: Object.assign({ source: IncrementalSource.Mutation }, m),
3004
3009
  }));
3005
3010
  };
3006
3011
  const wrappedScrollEmit = (p) => wrappedEmit(wrapEvent({
3007
- type: EventType$1.IncrementalSnapshot,
3012
+ type: EventType.IncrementalSnapshot,
3008
3013
  data: Object.assign({ source: IncrementalSource.Scroll }, p),
3009
3014
  }));
3010
3015
  const wrappedCanvasMutationEmit = (p) => wrappedEmit(wrapEvent({
3011
- type: EventType$1.IncrementalSnapshot,
3016
+ type: EventType.IncrementalSnapshot,
3012
3017
  data: Object.assign({ source: IncrementalSource.CanvasMutation }, p),
3013
3018
  }));
3014
3019
  const iframeManager = new IframeManager({
@@ -3053,7 +3058,7 @@ function record(options = {}) {
3053
3058
  takeFullSnapshot = (isCheckout = false) => {
3054
3059
  var _a, _b, _c, _d;
3055
3060
  wrappedEmit(wrapEvent({
3056
- type: EventType$1.Meta,
3061
+ type: EventType.Meta,
3057
3062
  data: {
3058
3063
  href: window.location.href,
3059
3064
  width: getWindowWidth(),
@@ -3096,7 +3101,7 @@ function record(options = {}) {
3096
3101
  }
3097
3102
  mirror.map = idNodeMap;
3098
3103
  wrappedEmit(wrapEvent({
3099
- type: EventType$1.FullSnapshot,
3104
+ type: EventType.FullSnapshot,
3100
3105
  data: {
3101
3106
  node,
3102
3107
  initialOffset: {
@@ -3121,7 +3126,7 @@ function record(options = {}) {
3121
3126
  const handlers = [];
3122
3127
  handlers.push(on('DOMContentLoaded', () => {
3123
3128
  wrappedEmit(wrapEvent({
3124
- type: EventType$1.DomContentLoaded,
3129
+ type: EventType.DomContentLoaded,
3125
3130
  data: {},
3126
3131
  }));
3127
3132
  }));
@@ -3131,40 +3136,40 @@ function record(options = {}) {
3131
3136
  onMutation,
3132
3137
  mutationCb: wrappedMutationEmit,
3133
3138
  mousemoveCb: (positions, source) => wrappedEmit(wrapEvent({
3134
- type: EventType$1.IncrementalSnapshot,
3139
+ type: EventType.IncrementalSnapshot,
3135
3140
  data: {
3136
3141
  source,
3137
3142
  positions,
3138
3143
  },
3139
3144
  })),
3140
3145
  mouseInteractionCb: (d) => wrappedEmit(wrapEvent({
3141
- type: EventType$1.IncrementalSnapshot,
3146
+ type: EventType.IncrementalSnapshot,
3142
3147
  data: Object.assign({ source: IncrementalSource.MouseInteraction }, d),
3143
3148
  })),
3144
3149
  scrollCb: wrappedScrollEmit,
3145
3150
  viewportResizeCb: (d) => wrappedEmit(wrapEvent({
3146
- type: EventType$1.IncrementalSnapshot,
3151
+ type: EventType.IncrementalSnapshot,
3147
3152
  data: Object.assign({ source: IncrementalSource.ViewportResize }, d),
3148
3153
  })),
3149
3154
  inputCb: (v) => wrappedEmit(wrapEvent({
3150
- type: EventType$1.IncrementalSnapshot,
3155
+ type: EventType.IncrementalSnapshot,
3151
3156
  data: Object.assign({ source: IncrementalSource.Input }, v),
3152
3157
  })),
3153
3158
  mediaInteractionCb: (p) => wrappedEmit(wrapEvent({
3154
- type: EventType$1.IncrementalSnapshot,
3159
+ type: EventType.IncrementalSnapshot,
3155
3160
  data: Object.assign({ source: IncrementalSource.MediaInteraction }, p),
3156
3161
  })),
3157
3162
  styleSheetRuleCb: (r) => wrappedEmit(wrapEvent({
3158
- type: EventType$1.IncrementalSnapshot,
3163
+ type: EventType.IncrementalSnapshot,
3159
3164
  data: Object.assign({ source: IncrementalSource.StyleSheetRule }, r),
3160
3165
  })),
3161
3166
  styleDeclarationCb: (r) => wrappedEmit(wrapEvent({
3162
- type: EventType$1.IncrementalSnapshot,
3167
+ type: EventType.IncrementalSnapshot,
3163
3168
  data: Object.assign({ source: IncrementalSource.StyleDeclaration }, r),
3164
3169
  })),
3165
3170
  canvasMutationCb: wrappedCanvasMutationEmit,
3166
3171
  fontCb: (p) => wrappedEmit(wrapEvent({
3167
- type: EventType$1.IncrementalSnapshot,
3172
+ type: EventType.IncrementalSnapshot,
3168
3173
  data: Object.assign({ source: IncrementalSource.Font }, p),
3169
3174
  })),
3170
3175
  blockClass,
@@ -3197,7 +3202,7 @@ function record(options = {}) {
3197
3202
  observer: p.observer,
3198
3203
  options: p.options,
3199
3204
  callback: (payload) => wrappedEmit(wrapEvent({
3200
- type: EventType$1.Plugin,
3205
+ type: EventType.Plugin,
3201
3206
  data: {
3202
3207
  plugin: p.name,
3203
3208
  payload,
@@ -3225,7 +3230,7 @@ function record(options = {}) {
3225
3230
  else {
3226
3231
  handlers.push(on('load', () => {
3227
3232
  wrappedEmit(wrapEvent({
3228
- type: EventType$1.Load,
3233
+ type: EventType.Load,
3229
3234
  data: {},
3230
3235
  }));
3231
3236
  init();
@@ -3244,7 +3249,7 @@ record.addCustomEvent = (tag, payload) => {
3244
3249
  throw new Error('please add custom event after start recording');
3245
3250
  }
3246
3251
  wrappedEmit(wrapEvent({
3247
- type: EventType$1.Custom,
3252
+ type: EventType.Custom,
3248
3253
  data: {
3249
3254
  tag,
3250
3255
  payload,
@@ -3301,7 +3306,7 @@ function addBreadcrumbEvent(replay, breadcrumb) {
3301
3306
 
3302
3307
  replay.addUpdate(() => {
3303
3308
  void replay.throttledAddEvent({
3304
- type: EventType$1.Custom,
3309
+ type: EventType.Custom,
3305
3310
  // TODO: We were converting from ms to seconds for breadcrumbs, spans,
3306
3311
  // but maybe we should just keep them as milliseconds
3307
3312
  timestamp: (breadcrumb.timestamp || 0) * 1000,
@@ -3423,15 +3428,16 @@ function handleSlowClick(
3423
3428
  addBreadcrumbEvent(replay, breadcrumb);
3424
3429
  }
3425
3430
 
3426
- const SLOW_CLICK_IGNORE_TAGS = ['SELECT', 'OPTION'];
3431
+ const SLOW_CLICK_TAGS = ['A', 'BUTTON', 'INPUT'];
3427
3432
 
3433
+ /** exported for tests only */
3428
3434
  function ignoreElement(node, config) {
3429
- // If <input> tag, we only want to consider input[type='submit'] & input[type='button']
3430
- if (node.tagName === 'INPUT' && !['submit', 'button'].includes(node.getAttribute('type') || '')) {
3435
+ if (!SLOW_CLICK_TAGS.includes(node.tagName)) {
3431
3436
  return true;
3432
3437
  }
3433
3438
 
3434
- if (SLOW_CLICK_IGNORE_TAGS.includes(node.tagName)) {
3439
+ // If <input> tag, we only want to consider input[type='submit'] & input[type='button']
3440
+ if (node.tagName === 'INPUT' && !['submit', 'button'].includes(node.getAttribute('type') || '')) {
3435
3441
  return true;
3436
3442
  }
3437
3443
 
@@ -3464,6 +3470,8 @@ const ATTRIBUTES_TO_RECORD = new Set([
3464
3470
  'title',
3465
3471
  'data-test-id',
3466
3472
  'data-testid',
3473
+ 'disabled',
3474
+ 'aria-disabled',
3467
3475
  ]);
3468
3476
 
3469
3477
  /**
@@ -3489,14 +3497,14 @@ function getAttributesToRecord(attributes) {
3489
3497
  const handleDomListener = (
3490
3498
  replay,
3491
3499
  ) => {
3492
- const slowClickExperiment = replay.getOptions()._experiments.slowClicks;
3500
+ const { slowClickTimeout, slowClickIgnoreSelectors } = replay.getOptions();
3493
3501
 
3494
- const slowClickConfig = slowClickExperiment
3502
+ const slowClickConfig = slowClickTimeout
3495
3503
  ? {
3496
- threshold: slowClickExperiment.threshold,
3497
- timeout: slowClickExperiment.timeout,
3498
- scrollTimeout: slowClickExperiment.scrollTimeout,
3499
- ignoreSelector: slowClickExperiment.ignoreSelectors ? slowClickExperiment.ignoreSelectors.join(',') : '',
3504
+ threshold: Math.min(SLOW_CLICK_THRESHOLD, slowClickTimeout),
3505
+ timeout: slowClickTimeout,
3506
+ scrollTimeout: SLOW_CLICK_SCROLL_TIMEOUT,
3507
+ ignoreSelector: slowClickIgnoreSelectors ? slowClickIgnoreSelectors.join(',') : '',
3500
3508
  }
3501
3509
  : undefined;
3502
3510
 
@@ -3625,7 +3633,10 @@ function handleKeyboardEvent(replay, event) {
3625
3633
  return;
3626
3634
  }
3627
3635
 
3628
- replay.triggerUserActivity();
3636
+ // Update user activity, but do not restart recording as it can create
3637
+ // noisy/low-value replays (e.g. user comes back from idle, hits alt-tab, new
3638
+ // session with a single "keydown" breadcrumb is created)
3639
+ replay.updateUserActivity();
3629
3640
 
3630
3641
  const breadcrumb = getKeyboardBreadcrumb(event);
3631
3642
 
@@ -4376,11 +4387,13 @@ function getSession({
4376
4387
  // within "max session time").
4377
4388
  const isExpired = isSessionExpired(session, timeouts);
4378
4389
 
4379
- if (!isExpired) {
4390
+ if (!isExpired || (allowBuffering && session.shouldRefresh)) {
4380
4391
  return { type: 'saved', session };
4381
4392
  } else if (!session.shouldRefresh) {
4382
- // In this case, stop
4383
- // This is the case if we have an error session that is completed (=triggered an error)
4393
+ // This is the case if we have an error session that is completed
4394
+ // (=triggered an error). Session will continue as session-based replay,
4395
+ // and when this session is expired, it will not be renewed until user
4396
+ // reloads.
4384
4397
  const discardedSession = makeSession({ sampled: false });
4385
4398
  return { type: 'new', session: discardedSession };
4386
4399
  } else {
@@ -4398,22 +4411,9 @@ function getSession({
4398
4411
  return { type: 'new', session: newSession };
4399
4412
  }
4400
4413
 
4401
- /* eslint-disable @typescript-eslint/naming-convention */
4402
-
4403
- var EventType; (function (EventType) {
4404
- const DomContentLoaded = 0; EventType[EventType["DomContentLoaded"] = DomContentLoaded] = "DomContentLoaded";
4405
- const Load = 1; EventType[EventType["Load"] = Load] = "Load";
4406
- const FullSnapshot = 2; EventType[EventType["FullSnapshot"] = FullSnapshot] = "FullSnapshot";
4407
- const IncrementalSnapshot = 3; EventType[EventType["IncrementalSnapshot"] = IncrementalSnapshot] = "IncrementalSnapshot";
4408
- const Meta = 4; EventType[EventType["Meta"] = Meta] = "Meta";
4409
- const Custom = 5; EventType[EventType["Custom"] = Custom] = "Custom";
4410
- const Plugin = 6; EventType[EventType["Plugin"] = Plugin] = "Plugin";
4411
- })(EventType || (EventType = {}));
4412
-
4413
- /**
4414
- * This is a partial copy of rrweb's eventWithTime type which only contains the properties
4415
- * we specifcally need in the SDK.
4416
- */
4414
+ function isCustomEvent(event) {
4415
+ return event.type === EventType.Custom;
4416
+ }
4417
4417
 
4418
4418
  /**
4419
4419
  * Add an event to the event buffer.
@@ -4452,7 +4452,7 @@ async function addEvent(
4452
4452
  const replayOptions = replay.getOptions();
4453
4453
 
4454
4454
  const eventAfterPossibleCallback =
4455
- typeof replayOptions.beforeAddRecordingEvent === 'function' && event.type === EventType.Custom
4455
+ typeof replayOptions.beforeAddRecordingEvent === 'function' && isCustomEvent(event)
4456
4456
  ? replayOptions.beforeAddRecordingEvent(event)
4457
4457
  : event;
4458
4458
 
@@ -4667,7 +4667,7 @@ function createPerformanceSpans(
4667
4667
  ) {
4668
4668
  return entries.map(({ type, start, end, name, data }) => {
4669
4669
  const response = replay.throttledAddEvent({
4670
- type: EventType$1.Custom,
4670
+ type: EventType.Custom,
4671
4671
  timestamp: start,
4672
4672
  data: {
4673
4673
  tag: 'performanceSpan',
@@ -5901,6 +5901,10 @@ function _isFetchHint(hint) {
5901
5901
 
5902
5902
  let _LAST_BREADCRUMB = null;
5903
5903
 
5904
+ function isBreadcrumbWithCategory(breadcrumb) {
5905
+ return !!breadcrumb.category;
5906
+ }
5907
+
5904
5908
  const handleScopeListener =
5905
5909
  (replay) =>
5906
5910
  (scope) => {
@@ -5936,9 +5940,9 @@ function handleScope(scope) {
5936
5940
  _LAST_BREADCRUMB = newBreadcrumb;
5937
5941
 
5938
5942
  if (
5939
- newBreadcrumb.category &&
5940
- (['fetch', 'xhr', 'sentry.event', 'sentry.transaction'].includes(newBreadcrumb.category) ||
5941
- newBreadcrumb.category.startsWith('ui.'))
5943
+ !isBreadcrumbWithCategory(newBreadcrumb) ||
5944
+ ['fetch', 'xhr', 'sentry.event', 'sentry.transaction'].includes(newBreadcrumb.category) ||
5945
+ newBreadcrumb.category.startsWith('ui.')
5942
5946
  ) {
5943
5947
  return null;
5944
5948
  }
@@ -5951,7 +5955,9 @@ function handleScope(scope) {
5951
5955
  }
5952
5956
 
5953
5957
  /** exported for tests only */
5954
- function normalizeConsoleBreadcrumb(breadcrumb) {
5958
+ function normalizeConsoleBreadcrumb(
5959
+ breadcrumb,
5960
+ ) {
5955
5961
  const args = breadcrumb.data && breadcrumb.data.arguments;
5956
5962
 
5957
5963
  if (!Array.isArray(args) || args.length === 0) {
@@ -6400,6 +6406,10 @@ function getHandleRecordingEmit(replay) {
6400
6406
  // a previous session ID. In this case, we want to buffer events
6401
6407
  // for a set amount of time before flushing. This can help avoid
6402
6408
  // capturing replays of users that immediately close the window.
6409
+ // TODO: We should check `recordingMode` here and do nothing if it's
6410
+ // buffer, instead of checking inside of timeout, this will make our
6411
+ // tests a bit cleaner as we will need to wait on the delay in order to
6412
+ // do nothing.
6403
6413
  setTimeout(() => replay.conditionalFlush(), options._experiments.delayFlushOnCheckout);
6404
6414
 
6405
6415
  // Cancel any previously debounced flushes to ensure there are no [near]
@@ -7166,6 +7176,8 @@ class ReplayContainer {
7166
7176
  return this.flushImmediate();
7167
7177
  }
7168
7178
 
7179
+ const activityTime = Date.now();
7180
+
7169
7181
  // Allow flush to complete before resuming as a session recording, otherwise
7170
7182
  // the checkout from `startRecording` may be included in the payload.
7171
7183
  // Prefer to keep the error replay as a separate (and smaller) segment
@@ -7187,6 +7199,18 @@ class ReplayContainer {
7187
7199
  // Once this session ends, we do not want to refresh it
7188
7200
  if (this.session) {
7189
7201
  this.session.shouldRefresh = false;
7202
+
7203
+ // It's possible that the session lifespan is > max session lifespan
7204
+ // because we have been buffering beyond max session lifespan (we ignore
7205
+ // expiration given that `shouldRefresh` is true). Since we flip
7206
+ // `shouldRefresh`, the session could be considered expired due to
7207
+ // lifespan, which is not what we want. Update session start date to be
7208
+ // the current timestamp, so that session is not considered to be
7209
+ // expired. This means that max replay duration can be MAX_SESSION_LIFE +
7210
+ // (length of buffer), which we are ok with.
7211
+ this._updateUserActivity(activityTime);
7212
+ this._updateSessionActivity(activityTime);
7213
+ this.session.started = activityTime;
7190
7214
  this._maybeSaveSession();
7191
7215
  }
7192
7216
 
@@ -7250,6 +7274,18 @@ class ReplayContainer {
7250
7274
  this._updateSessionActivity();
7251
7275
  }
7252
7276
 
7277
+ /**
7278
+ * Updates the user activity timestamp *without* resuming
7279
+ * recording. Some user events (e.g. keydown) can be create
7280
+ * low-value replays that only contain the keypress as a
7281
+ * breadcrumb. Instead this would require other events to
7282
+ * create a new replay after a session has expired.
7283
+ */
7284
+ updateUserActivity() {
7285
+ this._updateUserActivity();
7286
+ this._updateSessionActivity();
7287
+ }
7288
+
7253
7289
  /**
7254
7290
  * Only flush if `this.recordingMode === 'session'`
7255
7291
  */
@@ -7370,7 +7406,7 @@ class ReplayContainer {
7370
7406
 
7371
7407
  this.addUpdate(() => {
7372
7408
  void addEvent(this, {
7373
- type: EventType$1.Custom,
7409
+ type: EventType.Custom,
7374
7410
  timestamp: breadcrumb.timestamp || 0,
7375
7411
  data: {
7376
7412
  tag: 'breadcrumb',
@@ -7440,7 +7476,7 @@ class ReplayContainer {
7440
7476
  stickySession: Boolean(this._options.stickySession),
7441
7477
  currentSession: this.session,
7442
7478
  sessionSampleRate: this._options.sessionSampleRate,
7443
- allowBuffering: this._options.errorSampleRate > 0,
7479
+ allowBuffering: this._options.errorSampleRate > 0 || this.recordingMode === 'buffer',
7444
7480
  });
7445
7481
 
7446
7482
  // If session was newly created (i.e. was not loaded from storage), then
@@ -7636,7 +7672,7 @@ class ReplayContainer {
7636
7672
  _createCustomBreadcrumb(breadcrumb) {
7637
7673
  this.addUpdate(() => {
7638
7674
  void this.throttledAddEvent({
7639
- type: EventType$1.Custom,
7675
+ type: EventType.Custom,
7640
7676
  timestamp: breadcrumb.timestamp || 0,
7641
7677
  data: {
7642
7678
  tag: 'breadcrumb',
@@ -8010,6 +8046,9 @@ class Replay {
8010
8046
  mutationBreadcrumbLimit = 750,
8011
8047
  mutationLimit = 10000,
8012
8048
 
8049
+ slowClickTimeout = 7000,
8050
+ slowClickIgnoreSelectors = [],
8051
+
8013
8052
  networkDetailAllowUrls = [],
8014
8053
  networkCaptureBodies = true,
8015
8054
  networkRequestHeaders = [],
@@ -8079,6 +8118,8 @@ class Replay {
8079
8118
  maskAllText,
8080
8119
  mutationBreadcrumbLimit,
8081
8120
  mutationLimit,
8121
+ slowClickTimeout,
8122
+ slowClickIgnoreSelectors,
8082
8123
  networkDetailAllowUrls,
8083
8124
  networkCaptureBodies,
8084
8125
  networkRequestHeaders: _getMergedNetworkHeaders(networkRequestHeaders),