mixpanel-browser 2.71.1 → 2.73.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.
Files changed (40) hide show
  1. package/.github/workflows/tests.yml +1 -0
  2. package/CHANGELOG.md +12 -0
  3. package/dist/mixpanel-core.cjs.d.ts +84 -13
  4. package/dist/mixpanel-core.cjs.js +180 -28
  5. package/dist/mixpanel-recorder.js +684 -114
  6. package/dist/mixpanel-recorder.min.js +1 -1
  7. package/dist/mixpanel-recorder.min.js.map +1 -1
  8. package/dist/mixpanel-with-async-recorder.cjs.d.ts +84 -13
  9. package/dist/mixpanel-with-async-recorder.cjs.js +180 -28
  10. package/dist/mixpanel-with-recorder.d.ts +84 -13
  11. package/dist/mixpanel-with-recorder.js +860 -140
  12. package/dist/mixpanel-with-recorder.min.d.ts +84 -13
  13. package/dist/mixpanel-with-recorder.min.js +1 -1
  14. package/dist/mixpanel.amd.d.ts +84 -13
  15. package/dist/mixpanel.amd.js +860 -140
  16. package/dist/mixpanel.cjs.d.ts +84 -13
  17. package/dist/mixpanel.cjs.js +860 -140
  18. package/dist/mixpanel.globals.js +180 -28
  19. package/dist/mixpanel.min.js +172 -170
  20. package/dist/mixpanel.module.d.ts +84 -13
  21. package/dist/mixpanel.module.js +860 -140
  22. package/dist/mixpanel.umd.d.ts +84 -13
  23. package/dist/mixpanel.umd.js +860 -140
  24. package/dist/rrweb-bundled.js +12760 -0
  25. package/dist/rrweb-compiled.js +2496 -7176
  26. package/package.json +3 -2
  27. package/rollup.config.mjs +15 -4
  28. package/src/autocapture/index.js +1 -1
  29. package/src/autocapture/rageclick.js +20 -1
  30. package/src/autocapture/shadow-dom-observer.js +3 -15
  31. package/src/autocapture/utils.js +30 -0
  32. package/src/config.js +1 -1
  33. package/src/index.d.ts +84 -13
  34. package/src/mixpanel-core.js +127 -10
  35. package/src/recorder/recorder.js +1 -1
  36. package/src/recorder/rrweb-entrypoint.js +6 -0
  37. package/src/recorder/session-recording.js +69 -12
  38. package/src/utils.js +24 -0
  39. package/src/window.js +3 -1
  40. package/.claude/settings.local.json +0 -9
@@ -18,7 +18,9 @@
18
18
  screen: { width: 0, height: 0 },
19
19
  location: loc,
20
20
  addEventListener: function() {},
21
- removeEventListener: function() {}
21
+ removeEventListener: function() {},
22
+ dispatchEvent: function() {},
23
+ CustomEvent: function () {}
22
24
  };
23
25
  } else {
24
26
  win = window;
@@ -325,30 +327,30 @@
325
327
  };
326
328
  throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
327
329
  }
328
- var __defProp = Object.defineProperty;
329
- var __defNormalProp = function(obj, key, value) {
330
- return key in obj ? __defProp(obj, key, {
330
+ var __defProp$1 = Object.defineProperty;
331
+ var __defNormalProp$1 = function(obj, key, value) {
332
+ return key in obj ? __defProp$1(obj, key, {
331
333
  enumerable: true,
332
334
  configurable: true,
333
335
  writable: true,
334
336
  value: value
335
337
  }) : obj[key] = value;
336
338
  };
337
- var __publicField = function(obj, key, value) {
338
- return __defNormalProp(obj, (typeof key === "undefined" ? "undefined" : _type_of(key)) !== "symbol" ? key + "" : key, value);
339
+ var __publicField$1 = function(obj, key, value) {
340
+ return __defNormalProp$1(obj, (typeof key === "undefined" ? "undefined" : _type_of(key)) !== "symbol" ? key + "" : key, value);
339
341
  };
340
342
  var _a;
341
- var __defProp$1 = Object.defineProperty;
342
- var __defNormalProp$1 = function(obj, key, value) {
343
- return key in obj ? __defProp$1(obj, key, {
343
+ var __defProp$1$1 = Object.defineProperty;
344
+ var __defNormalProp$1$1 = function(obj, key, value) {
345
+ return key in obj ? __defProp$1$1(obj, key, {
344
346
  enumerable: true,
345
347
  configurable: true,
346
348
  writable: true,
347
349
  value: value
348
350
  }) : obj[key] = value;
349
351
  };
350
- var __publicField$1 = function(obj, key, value) {
351
- return __defNormalProp$1(obj, (typeof key === "undefined" ? "undefined" : _type_of(key)) !== "symbol" ? key + "" : key, value);
352
+ var __publicField$1$1 = function(obj, key, value) {
353
+ return __defNormalProp$1$1(obj, (typeof key === "undefined" ? "undefined" : _type_of(key)) !== "symbol" ? key + "" : key, value);
352
354
  };
353
355
  var NodeType$3 = /* @__PURE__ */ function(NodeType2) {
354
356
  NodeType2[NodeType2["Document"] = 0] = "Document";
@@ -618,8 +620,8 @@
618
620
  }
619
621
  var Mirror = /*#__PURE__*/ function() {
620
622
  function Mirror() {
621
- __publicField$1(this, "idNodeMap", /* @__PURE__ */ new Map());
622
- __publicField$1(this, "nodeMetaMap", /* @__PURE__ */ new WeakMap());
623
+ __publicField$1$1(this, "idNodeMap", /* @__PURE__ */ new Map());
624
+ __publicField$1$1(this, "nodeMetaMap", /* @__PURE__ */ new WeakMap());
623
625
  }
624
626
  var _proto = Mirror.prototype;
625
627
  _proto.getId = function getId(n2) {
@@ -2503,7 +2505,8 @@
2503
2505
  return id;
2504
2506
  };
2505
2507
  var nonSecure$1 = {
2506
- nanoid: nanoid$1$1};
2508
+ nanoid: nanoid$1$1
2509
+ };
2507
2510
  var SourceMapConsumer$2$1 = require$$2$1.SourceMapConsumer, SourceMapGenerator$2$1 = require$$2$1.SourceMapGenerator;
2508
2511
  var existsSync$1 = require$$2$1.existsSync, readFileSync$1 = require$$2$1.readFileSync;
2509
2512
  var dirname$1$1 = require$$2$1.dirname, join$1 = require$$2$1.join;
@@ -6654,7 +6657,8 @@
6654
6657
  return id;
6655
6658
  };
6656
6659
  var nonSecure = {
6657
- nanoid: nanoid$1};
6660
+ nanoid: nanoid$1
6661
+ };
6658
6662
  var SourceMapConsumer$2 = require$$2.SourceMapConsumer, SourceMapGenerator$2 = require$$2.SourceMapGenerator;
6659
6663
  var existsSync = require$$2.existsSync, readFileSync = require$$2.readFileSync;
6660
6664
  var dirname$1 = require$$2.dirname, join = require$$2.join;
@@ -9814,7 +9818,7 @@
9814
9818
  var LazyResult22 = lazyResult;
9815
9819
  var Container22 = container;
9816
9820
  var Processor22 = processor;
9817
- var stringify = stringify_1;
9821
+ var stringify$6 = stringify_1;
9818
9822
  var fromJSON = fromJSON_1;
9819
9823
  var Document222 = document$1$2;
9820
9824
  var Warning22 = warning;
@@ -9868,7 +9872,7 @@
9868
9872
  };
9869
9873
  return creator;
9870
9874
  };
9871
- postcss.stringify = stringify;
9875
+ postcss.stringify = stringify$6;
9872
9876
  postcss.parse = parse;
9873
9877
  postcss.fromJSON = fromJSON;
9874
9878
  postcss.list = list;
@@ -10118,7 +10122,7 @@
10118
10122
  function mutationObserverCtor() {
10119
10123
  return getUntaintedPrototype("MutationObserver").constructor;
10120
10124
  }
10121
- function patch(source, name, replacement) {
10125
+ function patch$2(source, name, replacement) {
10122
10126
  try {
10123
10127
  if (!(name in source)) {
10124
10128
  return function() {};
@@ -10155,7 +10159,7 @@
10155
10159
  querySelector: querySelector,
10156
10160
  querySelectorAll: querySelectorAll,
10157
10161
  mutationObserver: mutationObserverCtor,
10158
- patch: patch
10162
+ patch: patch$2
10159
10163
  };
10160
10164
  function on(type, fn, target) {
10161
10165
  if (target === void 0) target = document;
@@ -10350,9 +10354,9 @@
10350
10354
  }
10351
10355
  var StyleSheetMirror = /*#__PURE__*/ function() {
10352
10356
  function StyleSheetMirror() {
10353
- __publicField(this, "id", 1);
10354
- __publicField(this, "styleIDMap", /* @__PURE__ */ new WeakMap());
10355
- __publicField(this, "idStyleMap", /* @__PURE__ */ new Map());
10357
+ __publicField$1(this, "id", 1);
10358
+ __publicField$1(this, "styleIDMap", /* @__PURE__ */ new WeakMap());
10359
+ __publicField$1(this, "idStyleMap", /* @__PURE__ */ new Map());
10356
10360
  }
10357
10361
  var _proto = StyleSheetMirror.prototype;
10358
10362
  _proto.getId = function getId(stylesheet) {
@@ -10488,9 +10492,9 @@
10488
10492
  }
10489
10493
  var DoubleLinkedList = /*#__PURE__*/ function() {
10490
10494
  function DoubleLinkedList() {
10491
- __publicField(this, "length", 0);
10492
- __publicField(this, "head", null);
10493
- __publicField(this, "tail", null);
10495
+ __publicField$1(this, "length", 0);
10496
+ __publicField$1(this, "head", null);
10497
+ __publicField$1(this, "tail", null);
10494
10498
  }
10495
10499
  var _proto = DoubleLinkedList.prototype;
10496
10500
  _proto.get = function get(position) {
@@ -10571,14 +10575,14 @@
10571
10575
  var MutationBuffer = /*#__PURE__*/ function() {
10572
10576
  function MutationBuffer() {
10573
10577
  var _this = this;
10574
- __publicField(this, "frozen", false);
10575
- __publicField(this, "locked", false);
10576
- __publicField(this, "texts", []);
10577
- __publicField(this, "attributes", []);
10578
- __publicField(this, "attributeMap", /* @__PURE__ */ new WeakMap());
10579
- __publicField(this, "removes", []);
10580
- __publicField(this, "mapRemoves", []);
10581
- __publicField(this, "movedMap", {});
10578
+ __publicField$1(this, "frozen", false);
10579
+ __publicField$1(this, "locked", false);
10580
+ __publicField$1(this, "texts", []);
10581
+ __publicField$1(this, "attributes", []);
10582
+ __publicField$1(this, "attributeMap", /* @__PURE__ */ new WeakMap());
10583
+ __publicField$1(this, "removes", []);
10584
+ __publicField$1(this, "mapRemoves", []);
10585
+ __publicField$1(this, "movedMap", {});
10582
10586
  /**
10583
10587
  * the browser MutationObserver emits multiple mutations after
10584
10588
  * a delay for performance reasons, making tracing added nodes hard
@@ -10595,37 +10599,37 @@
10595
10599
  * collect added nodes from the Set which have no duplicate copy. But
10596
10600
  * this also causes newly added nodes will not be serialized with id ASAP,
10597
10601
  * which means all the id related calculation should be lazy too.
10598
- */ __publicField(this, "addedSet", /* @__PURE__ */ new Set());
10599
- __publicField(this, "movedSet", /* @__PURE__ */ new Set());
10600
- __publicField(this, "droppedSet", /* @__PURE__ */ new Set());
10601
- __publicField(this, "removesSubTreeCache", /* @__PURE__ */ new Set());
10602
- __publicField(this, "mutationCb");
10603
- __publicField(this, "blockClass");
10604
- __publicField(this, "blockSelector");
10605
- __publicField(this, "maskTextClass");
10606
- __publicField(this, "maskTextSelector");
10607
- __publicField(this, "inlineStylesheet");
10608
- __publicField(this, "maskInputOptions");
10609
- __publicField(this, "maskTextFn");
10610
- __publicField(this, "maskInputFn");
10611
- __publicField(this, "keepIframeSrcFn");
10612
- __publicField(this, "recordCanvas");
10613
- __publicField(this, "inlineImages");
10614
- __publicField(this, "slimDOMOptions");
10615
- __publicField(this, "dataURLOptions");
10616
- __publicField(this, "doc");
10617
- __publicField(this, "mirror");
10618
- __publicField(this, "iframeManager");
10619
- __publicField(this, "stylesheetManager");
10620
- __publicField(this, "shadowDomManager");
10621
- __publicField(this, "canvasManager");
10622
- __publicField(this, "processedNodeManager");
10623
- __publicField(this, "unattachedDoc");
10624
- __publicField(this, "processMutations", function(mutations) {
10602
+ */ __publicField$1(this, "addedSet", /* @__PURE__ */ new Set());
10603
+ __publicField$1(this, "movedSet", /* @__PURE__ */ new Set());
10604
+ __publicField$1(this, "droppedSet", /* @__PURE__ */ new Set());
10605
+ __publicField$1(this, "removesSubTreeCache", /* @__PURE__ */ new Set());
10606
+ __publicField$1(this, "mutationCb");
10607
+ __publicField$1(this, "blockClass");
10608
+ __publicField$1(this, "blockSelector");
10609
+ __publicField$1(this, "maskTextClass");
10610
+ __publicField$1(this, "maskTextSelector");
10611
+ __publicField$1(this, "inlineStylesheet");
10612
+ __publicField$1(this, "maskInputOptions");
10613
+ __publicField$1(this, "maskTextFn");
10614
+ __publicField$1(this, "maskInputFn");
10615
+ __publicField$1(this, "keepIframeSrcFn");
10616
+ __publicField$1(this, "recordCanvas");
10617
+ __publicField$1(this, "inlineImages");
10618
+ __publicField$1(this, "slimDOMOptions");
10619
+ __publicField$1(this, "dataURLOptions");
10620
+ __publicField$1(this, "doc");
10621
+ __publicField$1(this, "mirror");
10622
+ __publicField$1(this, "iframeManager");
10623
+ __publicField$1(this, "stylesheetManager");
10624
+ __publicField$1(this, "shadowDomManager");
10625
+ __publicField$1(this, "canvasManager");
10626
+ __publicField$1(this, "processedNodeManager");
10627
+ __publicField$1(this, "unattachedDoc");
10628
+ __publicField$1(this, "processMutations", function(mutations) {
10625
10629
  mutations.forEach(_this.processMutation);
10626
10630
  _this.emit();
10627
10631
  });
10628
- __publicField(this, "emit", function() {
10632
+ __publicField$1(this, "emit", function() {
10629
10633
  if (_this.frozen || _this.locked) {
10630
10634
  return;
10631
10635
  }
@@ -10826,7 +10830,7 @@
10826
10830
  _this.movedMap = {};
10827
10831
  _this.mutationCb(payload);
10828
10832
  });
10829
- __publicField(this, "genTextAreaValueMutation", function(textarea) {
10833
+ __publicField$1(this, "genTextAreaValueMutation", function(textarea) {
10830
10834
  var item = _this.attributeMap.get(textarea);
10831
10835
  if (!item) {
10832
10836
  item = {
@@ -10850,7 +10854,7 @@
10850
10854
  maskInputFn: _this.maskInputFn
10851
10855
  });
10852
10856
  });
10853
- __publicField(this, "processMutation", function(m) {
10857
+ __publicField$1(this, "processMutation", function(m) {
10854
10858
  if (isIgnored(m.target, _this.mirror, _this.slimDOMOptions)) {
10855
10859
  return;
10856
10860
  }
@@ -10995,7 +10999,7 @@
10995
10999
  });
10996
11000
  /**
10997
11001
  * Make sure you check if `n`'s parent is blocked before calling this function
10998
- * */ __publicField(this, "genAdds", function(n2, target) {
11002
+ * */ __publicField$1(this, "genAdds", function(n2, target) {
10999
11003
  if (_this.processedNodeManager.inOtherBuffer(n2, _this)) return;
11000
11004
  if (_this.addedSet.has(n2) || _this.movedSet.has(n2)) return;
11001
11005
  if (_this.mirror.hasNode(n2)) {
@@ -11841,7 +11845,7 @@
11841
11845
  });
11842
11846
  return fontFace;
11843
11847
  };
11844
- var restoreHandler = patch(doc.fonts, "add", function(original) {
11848
+ var restoreHandler = patch$2(doc.fonts, "add", function(original) {
11845
11849
  return function(fontFace) {
11846
11850
  setTimeout(callbackWrapper(function() {
11847
11851
  var p = fontMap.get(fontFace);
@@ -11897,7 +11901,7 @@
11897
11901
  var doc = param.doc, customElementCb = param.customElementCb;
11898
11902
  var win = doc.defaultView;
11899
11903
  if (!win || !win.customElements) return function() {};
11900
- var restoreHandler = patch(win.customElements, "define", function(original) {
11904
+ var restoreHandler = patch$2(win.customElements, "define", function(original) {
11901
11905
  return function(name, constructor, options) {
11902
11906
  try {
11903
11907
  customElementCb({
@@ -12124,8 +12128,8 @@
12124
12128
  }
12125
12129
  var CrossOriginIframeMirror = /*#__PURE__*/ function() {
12126
12130
  function CrossOriginIframeMirror(generateIdFn) {
12127
- __publicField(this, "iframeIdToRemoteIdMap", /* @__PURE__ */ new WeakMap());
12128
- __publicField(this, "iframeRemoteIdToIdMap", /* @__PURE__ */ new WeakMap());
12131
+ __publicField$1(this, "iframeIdToRemoteIdMap", /* @__PURE__ */ new WeakMap());
12132
+ __publicField$1(this, "iframeRemoteIdToIdMap", /* @__PURE__ */ new WeakMap());
12129
12133
  this.generateIdFn = generateIdFn;
12130
12134
  }
12131
12135
  var _proto = CrossOriginIframeMirror.prototype;
@@ -12191,17 +12195,17 @@
12191
12195
  }();
12192
12196
  var IframeManager = /*#__PURE__*/ function() {
12193
12197
  function IframeManager(options) {
12194
- __publicField(this, "iframes", /* @__PURE__ */ new WeakMap());
12195
- __publicField(this, "crossOriginIframeMap", /* @__PURE__ */ new WeakMap());
12196
- __publicField(this, "crossOriginIframeMirror", new CrossOriginIframeMirror(genId));
12197
- __publicField(this, "crossOriginIframeStyleMirror");
12198
- __publicField(this, "crossOriginIframeRootIdMap", /* @__PURE__ */ new WeakMap());
12199
- __publicField(this, "mirror");
12200
- __publicField(this, "mutationCb");
12201
- __publicField(this, "wrappedEmit");
12202
- __publicField(this, "loadListener");
12203
- __publicField(this, "stylesheetManager");
12204
- __publicField(this, "recordCrossOriginIframes");
12198
+ __publicField$1(this, "iframes", /* @__PURE__ */ new WeakMap());
12199
+ __publicField$1(this, "crossOriginIframeMap", /* @__PURE__ */ new WeakMap());
12200
+ __publicField$1(this, "crossOriginIframeMirror", new CrossOriginIframeMirror(genId));
12201
+ __publicField$1(this, "crossOriginIframeStyleMirror");
12202
+ __publicField$1(this, "crossOriginIframeRootIdMap", /* @__PURE__ */ new WeakMap());
12203
+ __publicField$1(this, "mirror");
12204
+ __publicField$1(this, "mutationCb");
12205
+ __publicField$1(this, "wrappedEmit");
12206
+ __publicField$1(this, "loadListener");
12207
+ __publicField$1(this, "stylesheetManager");
12208
+ __publicField$1(this, "recordCrossOriginIframes");
12205
12209
  this.mutationCb = options.mutationCb;
12206
12210
  this.wrappedEmit = options.wrappedEmit;
12207
12211
  this.stylesheetManager = options.stylesheetManager;
@@ -12448,12 +12452,12 @@
12448
12452
  }();
12449
12453
  var ShadowDomManager = /*#__PURE__*/ function() {
12450
12454
  function ShadowDomManager(options) {
12451
- __publicField(this, "shadowDoms", /* @__PURE__ */ new WeakSet());
12452
- __publicField(this, "mutationCb");
12453
- __publicField(this, "scrollCb");
12454
- __publicField(this, "bypassOptions");
12455
- __publicField(this, "mirror");
12456
- __publicField(this, "restoreHandlers", []);
12455
+ __publicField$1(this, "shadowDoms", /* @__PURE__ */ new WeakSet());
12456
+ __publicField$1(this, "mutationCb");
12457
+ __publicField$1(this, "scrollCb");
12458
+ __publicField$1(this, "bypassOptions");
12459
+ __publicField$1(this, "mirror");
12460
+ __publicField$1(this, "restoreHandlers", []);
12457
12461
  this.mutationCb = options.mutationCb;
12458
12462
  this.scrollCb = options.scrollCb;
12459
12463
  this.bypassOptions = options.bypassOptions;
@@ -12504,7 +12508,7 @@
12504
12508
  * Patch 'attachShadow' to observe newly added shadow doms.
12505
12509
  */ _proto.patchAttachShadow = function patchAttachShadow(element, doc) {
12506
12510
  var manager = this;
12507
- this.restoreHandlers.push(patch(element.prototype, "attachShadow", function(original) {
12511
+ this.restoreHandlers.push(patch$2(element.prototype, "attachShadow", function(original) {
12508
12512
  return function(option) {
12509
12513
  var sRoot = original.call(this, option);
12510
12514
  var shadowRootEl = index.shadowRoot(this);
@@ -12670,7 +12674,7 @@
12670
12674
  if (typeof win.CanvasRenderingContext2D.prototype[prop] !== "function") {
12671
12675
  return "continue";
12672
12676
  }
12673
- var restoreHandler = patch(win.CanvasRenderingContext2D.prototype, prop, function(original) {
12677
+ var restoreHandler = patch$2(win.CanvasRenderingContext2D.prototype, prop, function(original) {
12674
12678
  return function() {
12675
12679
  var _this = this;
12676
12680
  for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
@@ -12721,7 +12725,7 @@
12721
12725
  function initCanvasContextObserver(win, blockClass, blockSelector, setPreserveDrawingBufferToTrue) {
12722
12726
  var handlers = [];
12723
12727
  try {
12724
- var restoreHandler = patch(win.HTMLCanvasElement.prototype, "getContext", function(original) {
12728
+ var restoreHandler = patch$2(win.HTMLCanvasElement.prototype, "getContext", function(original) {
12725
12729
  return function(contextType) {
12726
12730
  for(var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++){
12727
12731
  args[_key - 1] = arguments[_key];
@@ -12776,7 +12780,7 @@
12776
12780
  if (typeof prototype[prop] !== "function") {
12777
12781
  return "continue";
12778
12782
  }
12779
- var restoreHandler = patch(prototype, prop, function(original) {
12783
+ var restoreHandler = patch$2(prototype, prop, function(original) {
12780
12784
  return function() {
12781
12785
  for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
12782
12786
  args[_key] = arguments[_key];
@@ -12865,17 +12869,17 @@
12865
12869
  var CanvasManager = /*#__PURE__*/ function() {
12866
12870
  function CanvasManager(options) {
12867
12871
  var _this = this;
12868
- __publicField(this, "pendingCanvasMutations", /* @__PURE__ */ new Map());
12869
- __publicField(this, "rafStamps", {
12872
+ __publicField$1(this, "pendingCanvasMutations", /* @__PURE__ */ new Map());
12873
+ __publicField$1(this, "rafStamps", {
12870
12874
  latestId: 0,
12871
12875
  invokeId: null
12872
12876
  });
12873
- __publicField(this, "mirror");
12874
- __publicField(this, "mutationCb");
12875
- __publicField(this, "resetObservers");
12876
- __publicField(this, "frozen", false);
12877
- __publicField(this, "locked", false);
12878
- __publicField(this, "processMutation", function(target, mutation) {
12877
+ __publicField$1(this, "mirror");
12878
+ __publicField$1(this, "mutationCb");
12879
+ __publicField$1(this, "resetObservers");
12880
+ __publicField$1(this, "frozen", false);
12881
+ __publicField$1(this, "locked", false);
12882
+ __publicField$1(this, "processMutation", function(target, mutation) {
12879
12883
  var newFrame = _this.rafStamps.invokeId && _this.rafStamps.latestId !== _this.rafStamps.invokeId;
12880
12884
  if (newFrame || !_this.rafStamps.invokeId) _this.rafStamps.invokeId = _this.rafStamps.latestId;
12881
12885
  if (!_this.pendingCanvasMutations.has(target)) {
@@ -13088,10 +13092,10 @@
13088
13092
  }();
13089
13093
  var StylesheetManager = /*#__PURE__*/ function() {
13090
13094
  function StylesheetManager(options) {
13091
- __publicField(this, "trackedLinkElements", /* @__PURE__ */ new WeakSet());
13092
- __publicField(this, "mutationCb");
13093
- __publicField(this, "adoptedStyleSheetCb");
13094
- __publicField(this, "styleMirror", new StyleSheetMirror());
13095
+ __publicField$1(this, "trackedLinkElements", /* @__PURE__ */ new WeakSet());
13096
+ __publicField$1(this, "mutationCb");
13097
+ __publicField$1(this, "adoptedStyleSheetCb");
13098
+ __publicField$1(this, "styleMirror", new StyleSheetMirror());
13095
13099
  this.mutationCb = options.mutationCb;
13096
13100
  this.adoptedStyleSheetCb = options.adoptedStyleSheetCb;
13097
13101
  }
@@ -13153,8 +13157,8 @@
13153
13157
  }();
13154
13158
  var ProcessedNodeManager = /*#__PURE__*/ function() {
13155
13159
  function ProcessedNodeManager() {
13156
- __publicField(this, "nodeMap", /* @__PURE__ */ new WeakMap());
13157
- __publicField(this, "active", false);
13160
+ __publicField$1(this, "nodeMap", /* @__PURE__ */ new WeakMap());
13161
+ __publicField$1(this, "active", false);
13158
13162
  }
13159
13163
  var _proto = ProcessedNodeManager.prototype;
13160
13164
  _proto.inOtherBuffer = function inOtherBuffer(node2, thisBuffer) {
@@ -13679,6 +13683,493 @@
13679
13683
  record.addCustomEvent;
13680
13684
  record.freezePage;
13681
13685
  record.takeFullSnapshot;
13686
+ var __defProp = Object.defineProperty;
13687
+ var __defNormalProp = function(obj, key, value) {
13688
+ return key in obj ? __defProp(obj, key, {
13689
+ enumerable: true,
13690
+ configurable: true,
13691
+ writable: true,
13692
+ value: value
13693
+ }) : obj[key] = value;
13694
+ };
13695
+ var __publicField = function(obj, key, value) {
13696
+ return __defNormalProp(obj, (typeof key === "undefined" ? "undefined" : _type_of(key)) !== "symbol" ? key + "" : key, value);
13697
+ };
13698
+ function patch(source, name, replacement) {
13699
+ try {
13700
+ if (!(name in source)) {
13701
+ return function() {};
13702
+ }
13703
+ var original = source[name];
13704
+ var wrapped = replacement(original);
13705
+ if (typeof wrapped === "function") {
13706
+ wrapped.prototype = wrapped.prototype || {};
13707
+ Object.defineProperties(wrapped, {
13708
+ __rrweb_original__: {
13709
+ enumerable: false,
13710
+ value: original
13711
+ }
13712
+ });
13713
+ }
13714
+ source[name] = wrapped;
13715
+ return function() {
13716
+ source[name] = original;
13717
+ };
13718
+ } catch (e) {
13719
+ return function() {};
13720
+ }
13721
+ }
13722
+ var StackFrame = /*#__PURE__*/ function() {
13723
+ function StackFrame(obj) {
13724
+ __publicField(this, "fileName");
13725
+ __publicField(this, "functionName");
13726
+ __publicField(this, "lineNumber");
13727
+ __publicField(this, "columnNumber");
13728
+ this.fileName = obj.fileName || "";
13729
+ this.functionName = obj.functionName || "";
13730
+ this.lineNumber = obj.lineNumber;
13731
+ this.columnNumber = obj.columnNumber;
13732
+ }
13733
+ var _proto = StackFrame.prototype;
13734
+ _proto.toString = function toString() {
13735
+ var lineNumber = this.lineNumber || "";
13736
+ var columnNumber = this.columnNumber || "";
13737
+ if (this.functionName) return this.functionName + " (" + this.fileName + ":" + lineNumber + ":" + columnNumber + ")";
13738
+ return this.fileName + ":" + lineNumber + ":" + columnNumber;
13739
+ };
13740
+ return StackFrame;
13741
+ }();
13742
+ var FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\S+:\d+/;
13743
+ var CHROME_IE_STACK_REGEXP = /^\s*at .*(\S+:\d+|\(native\))/m;
13744
+ var SAFARI_NATIVE_CODE_REGEXP = /^(eval@)?(\[native code])?$/;
13745
+ var ErrorStackParser = {
13746
+ /**
13747
+ * Given an Error object, extract the most information from it.
13748
+ */ parse: function parse(error) {
13749
+ if (!error) {
13750
+ return [];
13751
+ }
13752
+ if (// eslint-disable-next-line @typescript-eslint/ban-ts-comment
13753
+ // @ts-ignore
13754
+ typeof error.stacktrace !== "undefined" || // eslint-disable-next-line @typescript-eslint/ban-ts-comment
13755
+ // @ts-ignore
13756
+ typeof error["opera#sourceloc"] !== "undefined") {
13757
+ return this.parseOpera(error);
13758
+ } else if (error.stack && error.stack.match(CHROME_IE_STACK_REGEXP)) {
13759
+ return this.parseV8OrIE(error);
13760
+ } else if (error.stack) {
13761
+ return this.parseFFOrSafari(error);
13762
+ } else {
13763
+ console.warn("[console-record-plugin]: Failed to parse error object:", error);
13764
+ return [];
13765
+ }
13766
+ },
13767
+ // Separate line and column numbers from a string of the form: (URI:Line:Column)
13768
+ extractLocation: function extractLocation(urlLike) {
13769
+ if (urlLike.indexOf(":") === -1) {
13770
+ return [
13771
+ urlLike
13772
+ ];
13773
+ }
13774
+ var regExp = /(.+?)(?::(\d+))?(?::(\d+))?$/;
13775
+ var parts = regExp.exec(urlLike.replace(/[()]/g, ""));
13776
+ if (!parts) throw new Error("Cannot parse given url: " + urlLike);
13777
+ return [
13778
+ parts[1],
13779
+ parts[2] || void 0,
13780
+ parts[3] || void 0
13781
+ ];
13782
+ },
13783
+ parseV8OrIE: function parseV8OrIE(error) {
13784
+ var filtered = error.stack.split("\n").filter(function(line) {
13785
+ return !!line.match(CHROME_IE_STACK_REGEXP);
13786
+ }, this);
13787
+ return filtered.map(function(line) {
13788
+ if (line.indexOf("(eval ") > -1) {
13789
+ line = line.replace(/eval code/g, "eval").replace(/(\(eval at [^()]*)|(\),.*$)/g, "");
13790
+ }
13791
+ var sanitizedLine = line.replace(/^\s+/, "").replace(/\(eval code/g, "(");
13792
+ var location = sanitizedLine.match(/ (\((.+):(\d+):(\d+)\)$)/);
13793
+ sanitizedLine = location ? sanitizedLine.replace(location[0], "") : sanitizedLine;
13794
+ var tokens = sanitizedLine.split(/\s+/).slice(1);
13795
+ var locationParts = this.extractLocation(location ? location[1] : tokens.pop());
13796
+ var functionName = tokens.join(" ") || void 0;
13797
+ var fileName = [
13798
+ "eval",
13799
+ "<anonymous>"
13800
+ ].indexOf(locationParts[0]) > -1 ? void 0 : locationParts[0];
13801
+ return new StackFrame({
13802
+ functionName: functionName,
13803
+ fileName: fileName,
13804
+ lineNumber: locationParts[1],
13805
+ columnNumber: locationParts[2]
13806
+ });
13807
+ }, this);
13808
+ },
13809
+ parseFFOrSafari: function parseFFOrSafari(error) {
13810
+ var filtered = error.stack.split("\n").filter(function(line) {
13811
+ return !line.match(SAFARI_NATIVE_CODE_REGEXP);
13812
+ }, this);
13813
+ return filtered.map(function(line) {
13814
+ if (line.indexOf(" > eval") > -1) {
13815
+ line = line.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g, ":$1");
13816
+ }
13817
+ if (line.indexOf("@") === -1 && line.indexOf(":") === -1) {
13818
+ return new StackFrame({
13819
+ functionName: line
13820
+ });
13821
+ } else {
13822
+ var functionNameRegex = /((.*".+"[^@]*)?[^@]*)(?:@)/;
13823
+ var matches = line.match(functionNameRegex);
13824
+ var functionName = matches && matches[1] ? matches[1] : void 0;
13825
+ var locationParts = this.extractLocation(line.replace(functionNameRegex, ""));
13826
+ return new StackFrame({
13827
+ functionName: functionName,
13828
+ fileName: locationParts[0],
13829
+ lineNumber: locationParts[1],
13830
+ columnNumber: locationParts[2]
13831
+ });
13832
+ }
13833
+ }, this);
13834
+ },
13835
+ parseOpera: function parseOpera(e) {
13836
+ if (!e.stacktrace || e.message.indexOf("\n") > -1 && e.message.split("\n").length > e.stacktrace.split("\n").length) {
13837
+ return this.parseOpera9(e);
13838
+ } else if (!e.stack) {
13839
+ return this.parseOpera10(e);
13840
+ } else {
13841
+ return this.parseOpera11(e);
13842
+ }
13843
+ },
13844
+ parseOpera9: function parseOpera9(e) {
13845
+ var lineRE = /Line (\d+).*script (?:in )?(\S+)/i;
13846
+ var lines = e.message.split("\n");
13847
+ var result = [];
13848
+ for(var i = 2, len = lines.length; i < len; i += 2){
13849
+ var match = lineRE.exec(lines[i]);
13850
+ if (match) {
13851
+ result.push(new StackFrame({
13852
+ fileName: match[2],
13853
+ lineNumber: parseFloat(match[1])
13854
+ }));
13855
+ }
13856
+ }
13857
+ return result;
13858
+ },
13859
+ parseOpera10: function parseOpera10(e) {
13860
+ var lineRE = /Line (\d+).*script (?:in )?(\S+)(?:: In function (\S+))?$/i;
13861
+ var lines = e.stacktrace.split("\n");
13862
+ var result = [];
13863
+ for(var i = 0, len = lines.length; i < len; i += 2){
13864
+ var match = lineRE.exec(lines[i]);
13865
+ if (match) {
13866
+ result.push(new StackFrame({
13867
+ functionName: match[3] || void 0,
13868
+ fileName: match[2],
13869
+ lineNumber: parseFloat(match[1])
13870
+ }));
13871
+ }
13872
+ }
13873
+ return result;
13874
+ },
13875
+ // Opera 10.65+ Error.stack very similar to FF/Safari
13876
+ parseOpera11: function parseOpera11(error) {
13877
+ var filtered = error.stack.split("\n").filter(function(line) {
13878
+ return !!line.match(FIREFOX_SAFARI_STACK_REGEXP) && !line.match(/^Error created at/);
13879
+ }, this);
13880
+ return filtered.map(function(line) {
13881
+ var tokens = line.split("@");
13882
+ var locationParts = this.extractLocation(tokens.pop());
13883
+ var functionCall = tokens.shift() || "";
13884
+ var functionName = functionCall.replace(/<anonymous function(: (\w+))?>/, "$2").replace(/\([^)]*\)/g, "") || void 0;
13885
+ return new StackFrame({
13886
+ functionName: functionName,
13887
+ fileName: locationParts[0],
13888
+ lineNumber: locationParts[1],
13889
+ columnNumber: locationParts[2]
13890
+ });
13891
+ }, this);
13892
+ }
13893
+ };
13894
+ function pathToSelector(node) {
13895
+ if (!node || !node.outerHTML) {
13896
+ return "";
13897
+ }
13898
+ var path = "";
13899
+ while(node.parentElement){
13900
+ var name = node.localName;
13901
+ if (!name) {
13902
+ break;
13903
+ }
13904
+ name = name.toLowerCase();
13905
+ var parent = node.parentElement;
13906
+ var domSiblings = [];
13907
+ if (parent.children && parent.children.length > 0) {
13908
+ for(var i = 0; i < parent.children.length; i++){
13909
+ var sibling = parent.children[i];
13910
+ if (sibling.localName && sibling.localName.toLowerCase) {
13911
+ if (sibling.localName.toLowerCase() === name) {
13912
+ domSiblings.push(sibling);
13913
+ }
13914
+ }
13915
+ }
13916
+ }
13917
+ if (domSiblings.length > 1) {
13918
+ name += ":eq(" + domSiblings.indexOf(node) + ")";
13919
+ }
13920
+ path = name + (path ? ">" + path : "");
13921
+ node = parent;
13922
+ }
13923
+ return path;
13924
+ }
13925
+ function isObject(obj) {
13926
+ return Object.prototype.toString.call(obj) === "[object Object]";
13927
+ }
13928
+ function isObjTooDeep(obj, limit) {
13929
+ if (limit === 0) {
13930
+ return true;
13931
+ }
13932
+ var keys = Object.keys(obj);
13933
+ for(var _iterator = _create_for_of_iterator_helper_loose(keys), _step; !(_step = _iterator()).done;){
13934
+ var key = _step.value;
13935
+ if (isObject(obj[key]) && isObjTooDeep(obj[key], limit - 1)) {
13936
+ return true;
13937
+ }
13938
+ }
13939
+ return false;
13940
+ }
13941
+ function stringify(obj, stringifyOptions) {
13942
+ var options = {
13943
+ numOfKeysLimit: 50,
13944
+ depthOfLimit: 4
13945
+ };
13946
+ Object.assign(options, stringifyOptions);
13947
+ var stack = [];
13948
+ var keys = [];
13949
+ return JSON.stringify(obj, function(key, value) {
13950
+ if (stack.length > 0) {
13951
+ var thisPos = stack.indexOf(this);
13952
+ ~thisPos ? stack.splice(thisPos + 1) : stack.push(this);
13953
+ ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key);
13954
+ if (~stack.indexOf(value)) {
13955
+ if (stack[0] === value) {
13956
+ value = "[Circular ~]";
13957
+ } else {
13958
+ value = "[Circular ~." + keys.slice(0, stack.indexOf(value)).join(".") + "]";
13959
+ }
13960
+ }
13961
+ } else {
13962
+ stack.push(value);
13963
+ }
13964
+ if (value === null) return value;
13965
+ if (value === void 0) return "undefined";
13966
+ if (shouldIgnore(value)) {
13967
+ return toString(value);
13968
+ }
13969
+ if ((typeof value === "undefined" ? "undefined" : _type_of(value)) === "bigint") {
13970
+ return value.toString() + "n";
13971
+ }
13972
+ if (_instanceof(value, Event)) {
13973
+ var eventResult = {};
13974
+ for(var eventKey in value){
13975
+ var eventValue = value[eventKey];
13976
+ if (Array.isArray(eventValue)) {
13977
+ eventResult[eventKey] = pathToSelector(eventValue.length ? eventValue[0] : null);
13978
+ } else {
13979
+ eventResult[eventKey] = eventValue;
13980
+ }
13981
+ }
13982
+ return eventResult;
13983
+ } else if (_instanceof(value, Node)) {
13984
+ if (_instanceof(value, HTMLElement)) {
13985
+ return value ? value.outerHTML : "";
13986
+ }
13987
+ return value.nodeName;
13988
+ } else if (_instanceof(value, Error)) {
13989
+ return value.stack ? value.stack + "\nEnd of stack for Error object" : value.name + ": " + value.message;
13990
+ }
13991
+ return value;
13992
+ });
13993
+ function shouldIgnore(_obj) {
13994
+ if (isObject(_obj) && Object.keys(_obj).length > options.numOfKeysLimit) {
13995
+ return true;
13996
+ }
13997
+ if (typeof _obj === "function") {
13998
+ return true;
13999
+ }
14000
+ if (isObject(_obj) && isObjTooDeep(_obj, options.depthOfLimit)) {
14001
+ return true;
14002
+ }
14003
+ return false;
14004
+ }
14005
+ function toString(_obj) {
14006
+ var str = _obj.toString();
14007
+ if (options.stringLengthLimit && str.length > options.stringLengthLimit) {
14008
+ str = "" + str.slice(0, options.stringLengthLimit) + "...";
14009
+ }
14010
+ return str;
14011
+ }
14012
+ }
14013
+ var defaultLogOptions = {
14014
+ level: [
14015
+ "assert",
14016
+ "clear",
14017
+ "count",
14018
+ "countReset",
14019
+ "debug",
14020
+ "dir",
14021
+ "dirxml",
14022
+ "error",
14023
+ "group",
14024
+ "groupCollapsed",
14025
+ "groupEnd",
14026
+ "info",
14027
+ "log",
14028
+ "table",
14029
+ "time",
14030
+ "timeEnd",
14031
+ "timeLog",
14032
+ "trace",
14033
+ "warn"
14034
+ ],
14035
+ lengthThreshold: 1e3,
14036
+ logger: "console"
14037
+ };
14038
+ function initLogObserver(cb, win, options) {
14039
+ var logOptions = options ? Object.assign({}, defaultLogOptions, options) : defaultLogOptions;
14040
+ var loggerType = logOptions.logger;
14041
+ if (!loggerType) {
14042
+ return function() {};
14043
+ }
14044
+ var logger;
14045
+ if (typeof loggerType === "string") {
14046
+ logger = win[loggerType];
14047
+ } else {
14048
+ logger = loggerType;
14049
+ }
14050
+ var logCount = 0;
14051
+ var inStack = false;
14052
+ var cancelHandlers = [];
14053
+ if (logOptions.level.includes("error")) {
14054
+ var errorHandler = function(event) {
14055
+ var message = event.message, error = event.error;
14056
+ var trace = ErrorStackParser.parse(error).map(function(stackFrame) {
14057
+ return stackFrame.toString();
14058
+ });
14059
+ var payload = [
14060
+ stringify(message, logOptions.stringifyOptions)
14061
+ ];
14062
+ cb({
14063
+ level: "error",
14064
+ trace: trace,
14065
+ payload: payload
14066
+ });
14067
+ };
14068
+ win.addEventListener("error", errorHandler);
14069
+ cancelHandlers.push(function() {
14070
+ win.removeEventListener("error", errorHandler);
14071
+ });
14072
+ var unhandledrejectionHandler = function(event) {
14073
+ var error;
14074
+ var payload;
14075
+ if (_instanceof(event.reason, Error)) {
14076
+ error = event.reason;
14077
+ payload = [
14078
+ stringify("Uncaught (in promise) " + error.name + ": " + error.message, logOptions.stringifyOptions)
14079
+ ];
14080
+ } else {
14081
+ error = new Error();
14082
+ payload = [
14083
+ stringify("Uncaught (in promise)", logOptions.stringifyOptions),
14084
+ stringify(event.reason, logOptions.stringifyOptions)
14085
+ ];
14086
+ }
14087
+ var trace = ErrorStackParser.parse(error).map(function(stackFrame) {
14088
+ return stackFrame.toString();
14089
+ });
14090
+ cb({
14091
+ level: "error",
14092
+ trace: trace,
14093
+ payload: payload
14094
+ });
14095
+ };
14096
+ win.addEventListener("unhandledrejection", unhandledrejectionHandler);
14097
+ cancelHandlers.push(function() {
14098
+ win.removeEventListener("unhandledrejection", unhandledrejectionHandler);
14099
+ });
14100
+ }
14101
+ for(var _iterator = _create_for_of_iterator_helper_loose(logOptions.level), _step; !(_step = _iterator()).done;){
14102
+ var levelType = _step.value;
14103
+ cancelHandlers.push(replace(logger, levelType));
14104
+ }
14105
+ return function() {
14106
+ cancelHandlers.forEach(function(h) {
14107
+ return h();
14108
+ });
14109
+ };
14110
+ function replace(_logger, level) {
14111
+ var _this = this;
14112
+ if (!_logger[level]) {
14113
+ return function() {};
14114
+ }
14115
+ return patch(_logger, level, function(original) {
14116
+ var _this1 = _this;
14117
+ return function() {
14118
+ for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
14119
+ args[_key] = arguments[_key];
14120
+ }
14121
+ original.apply(_this1, args);
14122
+ if (level === "assert" && !!args[0]) {
14123
+ return;
14124
+ }
14125
+ if (inStack) {
14126
+ return;
14127
+ }
14128
+ inStack = true;
14129
+ try {
14130
+ var trace = ErrorStackParser.parse(new Error()).map(function(stackFrame) {
14131
+ return stackFrame.toString();
14132
+ }).splice(1);
14133
+ var argsForPayload = level === "assert" ? args.slice(1) : args;
14134
+ var payload = argsForPayload.map(function(s) {
14135
+ return stringify(s, logOptions.stringifyOptions);
14136
+ });
14137
+ logCount++;
14138
+ if (logCount < logOptions.lengthThreshold) {
14139
+ cb({
14140
+ level: level,
14141
+ trace: trace,
14142
+ payload: payload
14143
+ });
14144
+ } else if (logCount === logOptions.lengthThreshold) {
14145
+ cb({
14146
+ level: "warn",
14147
+ trace: [],
14148
+ payload: [
14149
+ stringify("The number of log records reached the threshold.")
14150
+ ]
14151
+ });
14152
+ }
14153
+ } catch (error) {
14154
+ original.apply(void 0, [].concat([
14155
+ "rrweb logger error:",
14156
+ error
14157
+ ], args));
14158
+ } finally{
14159
+ inStack = false;
14160
+ }
14161
+ };
14162
+ });
14163
+ }
14164
+ }
14165
+ var PLUGIN_NAME = "rrweb/console@1";
14166
+ var getRecordConsolePlugin = function(options) {
14167
+ return {
14168
+ name: PLUGIN_NAME,
14169
+ observer: initLogObserver,
14170
+ options: options
14171
+ };
14172
+ };
13682
14173
 
13683
14174
  var setImmediate = win['setImmediate'];
13684
14175
  var builtInProp, cycle, schedulingQueue,
@@ -14044,7 +14535,7 @@
14044
14535
 
14045
14536
  var Config = {
14046
14537
  DEBUG: false,
14047
- LIB_VERSION: '2.71.1'
14538
+ LIB_VERSION: '2.73.0'
14048
14539
  };
14049
14540
 
14050
14541
  /* eslint camelcase: "off", eqeqeq: "off" */
@@ -15784,6 +16275,28 @@
15784
16275
  JSONStringify = JSONStringify || _.JSONEncode;
15785
16276
  JSONParse = JSONParse || _.JSONDecode;
15786
16277
 
16278
+ /**
16279
+ * Determines if CompressionStream API should be used.
16280
+ * Returns false for Safari 16.4 and 16.5 which have breaking CompressionStream bugs.
16281
+ * https://bugs.webkit.org/show_bug.cgi?id=254021
16282
+ * fixed in 16.6 https://developer.apple.com/documentation/safari-release-notes/safari-16_6-release-notes
16283
+ */
16284
+ var canUseCompressionStream = function(userAgent, vendor, opera) {
16285
+ if (!win.CompressionStream) {
16286
+ return false;
16287
+ }
16288
+
16289
+ var browser = _.info.browser(userAgent, vendor, opera);
16290
+ var version = _.info.browserVersion(userAgent, vendor, opera);
16291
+ if (browser === 'Safari' || browser === 'Mobile Safari') {
16292
+ if (version >= 16.4 && version < 16.6) {
16293
+ return false;
16294
+ }
16295
+ }
16296
+
16297
+ return true;
16298
+ };
16299
+
15787
16300
  // UNMINIFIED EXPORTS (for closure compiler)
15788
16301
  _['info'] = _.info;
15789
16302
  _['info']['browser'] = _.info.browser;
@@ -17159,6 +17672,7 @@
17159
17672
  * @property {number} idleExpires
17160
17673
  * @property {number} maxExpires
17161
17674
  * @property {number} replayStartTime
17675
+ * @property {number} lastEventTimestamp
17162
17676
  * @property {number} seqNo
17163
17677
  * @property {string} batchStartUrl
17164
17678
  * @property {string} replayId
@@ -17179,6 +17693,7 @@
17179
17693
  * @property {number} idleExpires
17180
17694
  * @property {number} maxExpires
17181
17695
  * @property {number} replayStartTime
17696
+ * @property {number} lastEventTimestamp - the unix timestamp of the last recorded event from rrweb
17182
17697
  * @property {number} seqNo
17183
17698
  * @property {string} batchStartUrl
17184
17699
  * @property {string} replayStartUrl
@@ -17212,6 +17727,7 @@
17212
17727
  this.idleExpires = options.idleExpires || null;
17213
17728
  this.maxExpires = options.maxExpires || null;
17214
17729
  this.replayStartTime = options.replayStartTime || null;
17730
+ this.lastEventTimestamp = options.lastEventTimestamp || null;
17215
17731
  this.seqNo = options.seqNo || 0;
17216
17732
 
17217
17733
  this.idleTimeoutId = null;
@@ -17271,10 +17787,20 @@
17271
17787
 
17272
17788
  SessionRecording.prototype.unloadPersistedData = function () {
17273
17789
  this.batcher.stop();
17274
- return this.batcher.flush()
17275
- .then(function () {
17790
+
17791
+ return this.queueStorage.init().catch(function () {
17792
+ this.reportError('Error initializing IndexedDB storage for unloading persisted data.');
17793
+ }.bind(this)).then(function () {
17794
+ // if the recording is too short, just delete any stored events without flushing
17795
+ if (this.getDurationMs() < this._getRecordMinMs()) {
17276
17796
  return this.queueStorage.removeItem(this.batcherKey);
17277
- }.bind(this));
17797
+ }
17798
+
17799
+ return this.batcher.flush()
17800
+ .then(function () {
17801
+ return this.queueStorage.removeItem(this.batcherKey);
17802
+ }.bind(this));
17803
+ }.bind(this));
17278
17804
  };
17279
17805
 
17280
17806
  SessionRecording.prototype.getConfig = function(configVar) {
@@ -17309,11 +17835,7 @@
17309
17835
  this.maxExpires = new Date().getTime() + this.recordMaxMs;
17310
17836
  }
17311
17837
 
17312
- this.recordMinMs = this.getConfig('record_min_ms');
17313
- if (this.recordMinMs > MAX_VALUE_FOR_MIN_RECORDING_MS) {
17314
- this.recordMinMs = MAX_VALUE_FOR_MIN_RECORDING_MS;
17315
- logger$3.critical('record_min_ms cannot be greater than ' + MAX_VALUE_FOR_MIN_RECORDING_MS + 'ms. Capping value.');
17316
- }
17838
+ this.recordMinMs = this._getRecordMinMs();
17317
17839
 
17318
17840
  if (!this.replayStartTime) {
17319
17841
  this.replayStartTime = new Date().getTime();
@@ -17361,6 +17883,11 @@
17361
17883
  }
17362
17884
  // promise only used to await during tests
17363
17885
  this.__enqueuePromise = this.batcher.enqueue(ev);
17886
+
17887
+ // Capture the timestamp of the last event for duration calculation.
17888
+ if (this.lastEventTimestamp === null || ev.timestamp > this.lastEventTimestamp) {
17889
+ this.lastEventTimestamp = ev.timestamp;
17890
+ }
17364
17891
  }.bind(this),
17365
17892
  'blockClass': this.getConfig('record_block_class'),
17366
17893
  'blockSelector': blockSelector,
@@ -17375,7 +17902,16 @@
17375
17902
  'recordCanvas': this.getConfig('record_canvas'),
17376
17903
  'sampling': {
17377
17904
  'canvas': 15
17378
- }
17905
+ },
17906
+ 'plugins': this.getConfig('record_console') ? [
17907
+ getRecordConsolePlugin({
17908
+ stringifyOptions: {
17909
+ stringLengthLimit: 1000,
17910
+ numOfKeysLimit: 50,
17911
+ depthOfLimit: 2
17912
+ }
17913
+ })
17914
+ ] : []
17379
17915
  });
17380
17916
  } catch (err) {
17381
17917
  this.reportError('Unexpected error when starting rrweb recording.', err);
@@ -17460,6 +17996,7 @@
17460
17996
  'replayStartTime': this.replayStartTime,
17461
17997
  'batchStartUrl': this.batchStartUrl,
17462
17998
  'replayStartUrl': this.replayStartUrl,
17999
+ 'lastEventTimestamp': this.lastEventTimestamp,
17463
18000
  'idleExpires': this.idleExpires,
17464
18001
  'maxExpires': this.maxExpires,
17465
18002
  'tabId': tabId,
@@ -17481,6 +18018,7 @@
17481
18018
  idleExpires: serializedRecording['idleExpires'],
17482
18019
  maxExpires: serializedRecording['maxExpires'],
17483
18020
  replayStartTime: serializedRecording['replayStartTime'],
18021
+ lastEventTimestamp: serializedRecording['lastEventTimestamp'],
17484
18022
  seqNo: serializedRecording['seqNo'],
17485
18023
  sharedLockStorage: options.sharedLockStorage,
17486
18024
  }));
@@ -17571,7 +18109,7 @@
17571
18109
  var eventsJson = JSON.stringify(data);
17572
18110
  Object.assign(reqParams, this.getUserIdInfo());
17573
18111
 
17574
- if (CompressionStream) {
18112
+ if (canUseCompressionStream(userAgent, navigator.vendor, windowOpera)) {
17575
18113
  var jsonStream = new Blob([eventsJson], {type: 'application/json'}).stream();
17576
18114
  var gzipStream = jsonStream.pipeThrough(new CompressionStream('gzip'));
17577
18115
  new Response(gzipStream)
@@ -17600,6 +18138,38 @@
17600
18138
  }
17601
18139
  };
17602
18140
 
18141
+ /**
18142
+ * Calculates the duration of the recording in milliseconds, based on the start time and time of last recorded event.
18143
+ * @returns {number} The duration of the recording in milliseconds. Returns 0 if recording hasn't started.
18144
+ */
18145
+ SessionRecording.prototype.getDurationMs = function() {
18146
+ if (this.replayStartTime === null) {
18147
+ return 0;
18148
+ }
18149
+
18150
+ // If the recording has no events, assume it is in progress and use the current time as the end time.
18151
+ if (this.lastEventTimestamp === null) {
18152
+ return new Date().getTime() - this.replayStartTime;
18153
+ }
18154
+
18155
+ return this.lastEventTimestamp - this.replayStartTime;
18156
+ };
18157
+
18158
+ /**
18159
+ * Lazily loads the minimum recording length config in milliseconds, respecting the maximum limit.
18160
+ * @returns {number} The minimum recording length in milliseconds.
18161
+ */
18162
+ SessionRecording.prototype._getRecordMinMs = function() {
18163
+ var configValue = this.getConfig('record_min_ms');
18164
+
18165
+ if (configValue > MAX_VALUE_FOR_MIN_RECORDING_MS) {
18166
+ logger$3.critical('record_min_ms cannot be greater than ' + MAX_VALUE_FOR_MIN_RECORDING_MS + 'ms. Capping value.');
18167
+ return MAX_VALUE_FOR_MIN_RECORDING_MS;
18168
+ }
18169
+
18170
+ return configValue;
18171
+ };
18172
+
17603
18173
  /**
17604
18174
  * Module for handling the storage and retrieval of recording metadata as well as any active recordings.
17605
18175
  * Makes sure that only one tab can be recording at a time.
@@ -18609,20 +19179,65 @@
18609
19179
  return false;
18610
19180
  }
18611
19181
 
19182
+ /**
19183
+ * Get the composed path of a click event for elements embedded in shadow DOM.
19184
+ * @param {Event} event - event to get the composed path from
19185
+ * @returns {Array} the composed path of the click event
19186
+ */
19187
+ function getClickEventComposedPath(event) {
19188
+ if ('composedPath' in event) {
19189
+ return event['composedPath']();
19190
+ }
19191
+
19192
+ return [];
19193
+ }
19194
+
19195
+ /**
19196
+ * Get the element from a click event, accounting for elements embedded in shadow DOM.
19197
+ * @param {Event} event - event to get the target from
19198
+ * @returns {Element | null} the element that was the target of the click event
19199
+ */
19200
+ function getClickEventTargetElement(event) {
19201
+ var path = getClickEventComposedPath(event);
19202
+
19203
+ if (path && path.length > 0) {
19204
+ return path[0];
19205
+ }
19206
+
19207
+ return event['target'] || event['srcElement'];
19208
+ }
19209
+
18612
19210
  /** @const */ var DEFAULT_RAGE_CLICK_THRESHOLD_PX = 30;
18613
19211
  /** @const */ var DEFAULT_RAGE_CLICK_TIMEOUT_MS = 1000;
18614
19212
  /** @const */ var DEFAULT_RAGE_CLICK_CLICK_COUNT = 4;
19213
+ /** @const */ var DEFAULT_RAGE_CLICK_INTERACTIVE_ELEMENTS_ONLY = false;
18615
19214
 
18616
19215
  function RageClickTracker() {
18617
19216
  this.clicks = [];
18618
19217
  }
18619
19218
 
18620
- RageClickTracker.prototype.isRageClick = function(x, y, options) {
19219
+ /**
19220
+ * Determines if a click event is part of a rage click sequence.
19221
+ * @param {Event} event - the original click event.
19222
+ * @param {import('../index.d.ts').RageClickConfig} options - configuration options for rage click detection.
19223
+ * @returns {boolean} - true if the click is considered a rage click, false otherwise.
19224
+ */
19225
+ RageClickTracker.prototype.isRageClick = function(event, options) {
18621
19226
  options = options || {};
18622
19227
  var thresholdPx = options['threshold_px'] || DEFAULT_RAGE_CLICK_THRESHOLD_PX;
18623
19228
  var timeoutMs = options['timeout_ms'] || DEFAULT_RAGE_CLICK_TIMEOUT_MS;
18624
19229
  var clickCount = options['click_count'] || DEFAULT_RAGE_CLICK_CLICK_COUNT;
19230
+ var interactiveElementsOnly = options['interactive_elements_only'] || DEFAULT_RAGE_CLICK_INTERACTIVE_ELEMENTS_ONLY;
19231
+
19232
+ if (interactiveElementsOnly) {
19233
+ var target = getClickEventTargetElement(event);
19234
+ if (!target || isDefinitelyNonInteractive(target)) {
19235
+ return false;
19236
+ }
19237
+ }
19238
+
18625
19239
  var timestamp = Date.now();
19240
+ var x = event['pageX'], y = event['pageY'];
18626
19241
 
18627
19242
  var lastClick = this.clicks[this.clicks.length - 1];
18628
19243
  if (
@@ -18653,28 +19268,16 @@
18653
19268
  if (!this.observedShadowRoots) {
18654
19269
  return;
18655
19270
  }
18656
- var path = this.getComposedPath(event);
18657
- if (path && path.length) {
18658
- return path[0];
18659
- }
18660
19271
 
18661
- return event['target'] || event['srcElement'];
19272
+ return getClickEventTargetElement(event);
18662
19273
  };
18663
19274
 
18664
-
18665
- ShadowDOMObserver.prototype.getComposedPath = function(event) {
18666
- if ('composedPath' in event) {
18667
- return event['composedPath']();
18668
- }
18669
-
18670
- return [];
18671
- };
18672
19275
  ShadowDOMObserver.prototype.observeFromEvent = function(event) {
18673
19276
  if (!this.observedShadowRoots) {
18674
19277
  return;
18675
19278
  }
18676
19279
 
18677
- var path = this.getComposedPath(event);
19280
+ var path = getClickEventComposedPath(event);
18678
19281
 
18679
19282
  // Check each element in path for shadow roots
18680
19283
  for (var i = 0; i < path.length; i++) {
@@ -19426,7 +20029,7 @@
19426
20029
  return;
19427
20030
  }
19428
20031
 
19429
- if (this._rageClickTracker.isRageClick(ev['pageX'], ev['pageY'], currentRageClickConfig)) {
20032
+ if (this._rageClickTracker.isRageClick(ev, currentRageClickConfig)) {
19430
20033
  this.trackDomEvent(ev, MP_EV_RAGE_CLICK);
19431
20034
  }
19432
20035
  }.bind(this);
@@ -21200,8 +21803,6 @@
21200
21803
  var INIT_MODULE = 0;
21201
21804
  var INIT_SNIPPET = 1;
21202
21805
 
21203
- var IDENTITY_FUNC = function(x) {return x;};
21204
-
21205
21806
  /** @const */ var PRIMARY_INSTANCE_NAME = 'mixpanel';
21206
21807
  /** @const */ var PAYLOAD_TYPE_BASE64 = 'base64';
21207
21808
  /** @const */ var PAYLOAD_TYPE_JSON = 'json';
@@ -21295,6 +21896,7 @@
21295
21896
  'record_block_selector': 'img, video, audio',
21296
21897
  'record_canvas': false,
21297
21898
  'record_collect_fonts': false,
21899
+ 'record_console': true,
21298
21900
  'record_heatmap_data': false,
21299
21901
  'record_idle_timeout_ms': 30 * 60 * 1000, // 30 minutes
21300
21902
  'record_mask_text_class': new RegExp('^(mp-mask|fs-mask|amp-mask|rr-mask|ph-mask)$'),
@@ -21366,6 +21968,17 @@
21366
21968
  // global debug to be true
21367
21969
  Config.DEBUG = Config.DEBUG || instance.get_config('debug');
21368
21970
 
21971
+ var source = init_type === INIT_MODULE ? 'module' : 'snippet';
21972
+ win.dispatchEvent(new win.CustomEvent('$mp_sdk_to_extension_event', {
21973
+ 'detail': {
21974
+ 'instance': instance,
21975
+ 'source': source,
21976
+ 'token': token,
21977
+ 'name': name,
21978
+ 'info': _.info
21979
+ }
21980
+ }));
21981
+
21369
21982
  // if target is not defined, we called init after the lib already
21370
21983
  // loaded, so there won't be an array of things to execute
21371
21984
  if (!_.isUndefined(target) && _.isArray(target)) {
@@ -21436,6 +22049,8 @@
21436
22049
  }
21437
22050
  }
21438
22051
 
22052
+ this.hooks = {};
22053
+
21439
22054
  this.set_config(_.extend({}, DEFAULT_CONFIG, variable_features, config, {
21440
22055
  'name': name,
21441
22056
  'token': token,
@@ -22036,7 +22651,12 @@
22036
22651
  );
22037
22652
  }, this),
22038
22653
  beforeSendHook: _.bind(function(item) {
22039
- return this._run_hook('before_send_' + attrs.type, item);
22654
+ var ret = this._run_hook('before_send_' + attrs.type, item);
22655
+ if (ret) {
22656
+ return ret[0];
22657
+ } else {
22658
+ return null;
22659
+ }
22040
22660
  }, this),
22041
22661
  stopAllBatchingFunc: _.bind(this.stop_batch_senders, this),
22042
22662
  usePersistence: true,
@@ -22129,6 +22749,9 @@
22129
22749
  var send_request_immediately = _.bind(function() {
22130
22750
  if (!send_request_options.skip_hooks) {
22131
22751
  truncated_data = this._run_hook('before_send_' + options.type, truncated_data);
22752
+ if (truncated_data) {
22753
+ truncated_data = truncated_data[0];
22754
+ }
22132
22755
  }
22133
22756
  if (truncated_data) {
22134
22757
  console$1.log('MIXPANEL REQUEST:');
@@ -22183,6 +22806,17 @@
22183
22806
  * with the tracking payload sent to the API server is returned; otherwise false.
22184
22807
  */
22185
22808
  MixpanelLib.prototype.track = addOptOutCheckMixpanelLib(function(event_name, properties, options, callback) {
22809
+ var ret;
22810
+ if (!(options && options.skip_hooks)) {
22811
+ ret = this._run_hook('before_track', event_name, properties);
22812
+ if (ret === null) {
22813
+ return;
22814
+ } else {
22815
+ event_name = ret[0];
22816
+ properties = ret[1];
22817
+ }
22818
+ }
22819
+
22186
22820
  if (!callback && typeof options === 'function') {
22187
22821
  callback = options;
22188
22822
  options = null;
@@ -22252,7 +22886,7 @@
22252
22886
  'event': event_name,
22253
22887
  'properties': properties
22254
22888
  };
22255
- var ret = this._track_or_batch({
22889
+ ret = this._track_or_batch({
22256
22890
  type: 'events',
22257
22891
  data: data,
22258
22892
  endpoint: this.get_api_host('events') + '/' + this.get_config('api_routes')['track'],
@@ -22598,6 +23232,14 @@
22598
23232
  * @param {boolean} [days_or_options.persistent=true] - whether to put in persistent storage (cookie/localStorage)
22599
23233
  */
22600
23234
  MixpanelLib.prototype.register = function(props, days_or_options) {
23235
+ var ret = this._run_hook('before_register', props, days_or_options);
23236
+ if (ret === null) {
23237
+ return;
23238
+ } else {
23239
+ props = ret[0];
23240
+ days_or_options = ret[1];
23241
+ }
23242
+
22601
23243
  var options = options_for_register(days_or_options);
22602
23244
  if (options['persistent']) {
22603
23245
  this['persistence'].register(props, options['days']);
@@ -22634,6 +23276,15 @@
22634
23276
  * @param {boolean} [days_or_options.persistent=true] - whether to put in persistent storage (cookie/localStorage)
22635
23277
  */
22636
23278
  MixpanelLib.prototype.register_once = function(props, default_value, days_or_options) {
23279
+ var ret = this._run_hook('before_register_once', props, default_value, days_or_options);
23280
+ if (ret === null) {
23281
+ return;
23282
+ } else {
23283
+ props = ret[0];
23284
+ default_value = ret[1];
23285
+ days_or_options = ret[2];
23286
+ }
23287
+
22637
23288
  var options = options_for_register(days_or_options);
22638
23289
  if (options['persistent']) {
22639
23290
  this['persistence'].register_once(props, default_value, options['days']);
@@ -22657,6 +23308,14 @@
22657
23308
  * @param {boolean} [options.persistent=true] - whether to look in persistent storage (cookie/localStorage)
22658
23309
  */
22659
23310
  MixpanelLib.prototype.unregister = function(property, options) {
23311
+ var ret = this._run_hook('before_unregister', property, options);
23312
+ if (ret === null) {
23313
+ return;
23314
+ } else {
23315
+ property = ret[0];
23316
+ options = ret[1];
23317
+ }
23318
+
22660
23319
  options = options_for_register(options);
22661
23320
  if (options['persistent']) {
22662
23321
  this['persistence'].unregister(property);
@@ -22705,6 +23364,13 @@
22705
23364
  // _set_once_callback:function A callback to be run if and when the People set_once queue is flushed
22706
23365
  // _union_callback:function A callback to be run if and when the People union queue is flushed
22707
23366
  // _unset_callback:function A callback to be run if and when the People unset queue is flushed
23367
+ var ret = this._run_hook('before_identify', new_distinct_id);
23368
+
23369
+ if (ret === null) {
23370
+ return -1;
23371
+ } else {
23372
+ new_distinct_id = ret[0];
23373
+ }
22708
23374
 
22709
23375
  var previous_distinct_id = this.get_distinct_id();
22710
23376
  if (new_distinct_id && previous_distinct_id !== new_distinct_id) {
@@ -23029,6 +23695,25 @@
23029
23695
  if (('autocapture' in config || 'record_heatmap_data' in config) && this.autocapture) {
23030
23696
  this.autocapture.init();
23031
23697
  }
23698
+
23699
+ if (_.isObject(config['hooks'])) {
23700
+ this.hooks = {};
23701
+ _.each(config['hooks'], function(hook_value, hook_name) {
23702
+ if (_.isFunction(hook_value)) {
23703
+ this.hooks[hook_name] = [hook_value];
23704
+ } else if (_.isArray(hook_value)) {
23705
+ this.hooks[hook_name] = [];
23706
+ for (var i = 0; i < hook_value.length; i++) {
23707
+ if (!_.isFunction(hook_value[i])) {
23708
+ console$1.critical('Invalid hook added. Hook is not a function');
23709
+ }
23710
+ this.hooks[hook_name].push(hook_value[i]);
23711
+ }
23712
+ } else {
23713
+ console$1.critical('Invalid hooks added. Ensure that the hook values passed into config.hooks are functions or arrays of functions.');
23714
+ }
23715
+ }, this);
23716
+ }
23032
23717
  }
23033
23718
  };
23034
23719
 
@@ -23046,12 +23731,26 @@
23046
23731
  * @returns {any|null} return value of user-provided hook, or null if nothing was returned
23047
23732
  */
23048
23733
  MixpanelLib.prototype._run_hook = function(hook_name) {
23049
- var ret = (this['config']['hooks'][hook_name] || IDENTITY_FUNC).apply(this, slice.call(arguments, 1));
23050
- if (typeof ret === 'undefined') {
23051
- this.report_error(hook_name + ' hook did not return a value');
23052
- ret = null;
23053
- }
23054
- return ret;
23734
+ var hook_data = slice.call(arguments, 1);
23735
+ _.each(this.hooks[hook_name], function(hook) {
23736
+ if (hook_data === null) {
23737
+ return null;
23738
+ }
23739
+
23740
+ var ret = hook.apply(this, hook_data);
23741
+
23742
+ if (typeof ret === 'undefined') {
23743
+ this.report_error(hook_name + ' hook did not return a valid value');
23744
+ hook_data = null;
23745
+ } else {
23746
+ if (!_.isArray(ret)) {
23747
+ ret = [ret];
23748
+ }
23749
+ hook_data.splice.apply(hook_data, [0, ret.length].concat(ret));
23750
+ }
23751
+ }, this);
23752
+
23753
+ return hook_data;
23055
23754
  };
23056
23755
 
23057
23756
  /**
@@ -23362,6 +24061,25 @@
23362
24061
  }
23363
24062
  };
23364
24063
 
24064
+ MixpanelLib.prototype.add_hook = function(hook_name, hook_fn) {
24065
+ if (!this.hooks[hook_name]) {
24066
+ this.hooks[hook_name] = [];
24067
+ }
24068
+ this.hooks[hook_name].push(hook_fn);
24069
+ };
24070
+
24071
+ MixpanelLib.prototype.remove_hook = function(hook_name, hook_fn) {
24072
+ var fn_index;
24073
+ if (this.hooks[hook_name]) {
24074
+ fn_index = this.hooks[hook_name].indexOf(hook_fn);
24075
+ if (fn_index !== -1) {
24076
+ this.hooks[hook_name].splice(fn_index, 1);
24077
+ } else {
24078
+ console$1.log('remove_hook failed. Matching hook was not found');
24079
+ }
24080
+ }
24081
+ };
24082
+
23365
24083
  // EXPORTS (for closure compiler)
23366
24084
 
23367
24085
  // MixpanelLib Exports
@@ -23394,6 +24112,8 @@
23394
24112
  MixpanelLib.prototype['set_group'] = MixpanelLib.prototype.set_group;
23395
24113
  MixpanelLib.prototype['add_group'] = MixpanelLib.prototype.add_group;
23396
24114
  MixpanelLib.prototype['remove_group'] = MixpanelLib.prototype.remove_group;
24115
+ MixpanelLib.prototype['add_hook'] = MixpanelLib.prototype.add_hook;
24116
+ MixpanelLib.prototype['remove_hook'] = MixpanelLib.prototype.remove_hook;
23397
24117
  MixpanelLib.prototype['track_with_groups'] = MixpanelLib.prototype.track_with_groups;
23398
24118
  MixpanelLib.prototype['start_batch_senders'] = MixpanelLib.prototype.start_batch_senders;
23399
24119
  MixpanelLib.prototype['stop_batch_senders'] = MixpanelLib.prototype.stop_batch_senders;