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
@@ -21,7 +21,9 @@
21
21
  screen: { width: 0, height: 0 },
22
22
  location: loc,
23
23
  addEventListener: function() {},
24
- removeEventListener: function() {}
24
+ removeEventListener: function() {},
25
+ dispatchEvent: function() {},
26
+ CustomEvent: function () {}
25
27
  };
26
28
  } else {
27
29
  win = window;
@@ -328,30 +330,30 @@
328
330
  };
329
331
  throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
330
332
  }
331
- var __defProp = Object.defineProperty;
332
- var __defNormalProp = function(obj, key, value) {
333
- return key in obj ? __defProp(obj, key, {
333
+ var __defProp$1 = Object.defineProperty;
334
+ var __defNormalProp$1 = function(obj, key, value) {
335
+ return key in obj ? __defProp$1(obj, key, {
334
336
  enumerable: true,
335
337
  configurable: true,
336
338
  writable: true,
337
339
  value: value
338
340
  }) : obj[key] = value;
339
341
  };
340
- var __publicField = function(obj, key, value) {
341
- return __defNormalProp(obj, (typeof key === "undefined" ? "undefined" : _type_of(key)) !== "symbol" ? key + "" : key, value);
342
+ var __publicField$1 = function(obj, key, value) {
343
+ return __defNormalProp$1(obj, (typeof key === "undefined" ? "undefined" : _type_of(key)) !== "symbol" ? key + "" : key, value);
342
344
  };
343
345
  var _a;
344
- var __defProp$1 = Object.defineProperty;
345
- var __defNormalProp$1 = function(obj, key, value) {
346
- return key in obj ? __defProp$1(obj, key, {
346
+ var __defProp$1$1 = Object.defineProperty;
347
+ var __defNormalProp$1$1 = function(obj, key, value) {
348
+ return key in obj ? __defProp$1$1(obj, key, {
347
349
  enumerable: true,
348
350
  configurable: true,
349
351
  writable: true,
350
352
  value: value
351
353
  }) : obj[key] = value;
352
354
  };
353
- var __publicField$1 = function(obj, key, value) {
354
- return __defNormalProp$1(obj, (typeof key === "undefined" ? "undefined" : _type_of(key)) !== "symbol" ? key + "" : key, value);
355
+ var __publicField$1$1 = function(obj, key, value) {
356
+ return __defNormalProp$1$1(obj, (typeof key === "undefined" ? "undefined" : _type_of(key)) !== "symbol" ? key + "" : key, value);
355
357
  };
356
358
  var NodeType$3 = /* @__PURE__ */ function(NodeType2) {
357
359
  NodeType2[NodeType2["Document"] = 0] = "Document";
@@ -621,8 +623,8 @@
621
623
  }
622
624
  var Mirror = /*#__PURE__*/ function() {
623
625
  function Mirror() {
624
- __publicField$1(this, "idNodeMap", /* @__PURE__ */ new Map());
625
- __publicField$1(this, "nodeMetaMap", /* @__PURE__ */ new WeakMap());
626
+ __publicField$1$1(this, "idNodeMap", /* @__PURE__ */ new Map());
627
+ __publicField$1$1(this, "nodeMetaMap", /* @__PURE__ */ new WeakMap());
626
628
  }
627
629
  var _proto = Mirror.prototype;
628
630
  _proto.getId = function getId(n2) {
@@ -2506,7 +2508,8 @@
2506
2508
  return id;
2507
2509
  };
2508
2510
  var nonSecure$1 = {
2509
- nanoid: nanoid$1$1};
2511
+ nanoid: nanoid$1$1
2512
+ };
2510
2513
  var SourceMapConsumer$2$1 = require$$2$1.SourceMapConsumer, SourceMapGenerator$2$1 = require$$2$1.SourceMapGenerator;
2511
2514
  var existsSync$1 = require$$2$1.existsSync, readFileSync$1 = require$$2$1.readFileSync;
2512
2515
  var dirname$1$1 = require$$2$1.dirname, join$1 = require$$2$1.join;
@@ -6657,7 +6660,8 @@
6657
6660
  return id;
6658
6661
  };
6659
6662
  var nonSecure = {
6660
- nanoid: nanoid$1};
6663
+ nanoid: nanoid$1
6664
+ };
6661
6665
  var SourceMapConsumer$2 = require$$2.SourceMapConsumer, SourceMapGenerator$2 = require$$2.SourceMapGenerator;
6662
6666
  var existsSync = require$$2.existsSync, readFileSync = require$$2.readFileSync;
6663
6667
  var dirname$1 = require$$2.dirname, join = require$$2.join;
@@ -9817,7 +9821,7 @@
9817
9821
  var LazyResult22 = lazyResult;
9818
9822
  var Container22 = container;
9819
9823
  var Processor22 = processor;
9820
- var stringify = stringify_1;
9824
+ var stringify$6 = stringify_1;
9821
9825
  var fromJSON = fromJSON_1;
9822
9826
  var Document222 = document$1$2;
9823
9827
  var Warning22 = warning;
@@ -9871,7 +9875,7 @@
9871
9875
  };
9872
9876
  return creator;
9873
9877
  };
9874
- postcss.stringify = stringify;
9878
+ postcss.stringify = stringify$6;
9875
9879
  postcss.parse = parse;
9876
9880
  postcss.fromJSON = fromJSON;
9877
9881
  postcss.list = list;
@@ -10121,7 +10125,7 @@
10121
10125
  function mutationObserverCtor() {
10122
10126
  return getUntaintedPrototype("MutationObserver").constructor;
10123
10127
  }
10124
- function patch(source, name, replacement) {
10128
+ function patch$2(source, name, replacement) {
10125
10129
  try {
10126
10130
  if (!(name in source)) {
10127
10131
  return function() {};
@@ -10158,7 +10162,7 @@
10158
10162
  querySelector: querySelector,
10159
10163
  querySelectorAll: querySelectorAll,
10160
10164
  mutationObserver: mutationObserverCtor,
10161
- patch: patch
10165
+ patch: patch$2
10162
10166
  };
10163
10167
  function on(type, fn, target) {
10164
10168
  if (target === void 0) target = document;
@@ -10353,9 +10357,9 @@
10353
10357
  }
10354
10358
  var StyleSheetMirror = /*#__PURE__*/ function() {
10355
10359
  function StyleSheetMirror() {
10356
- __publicField(this, "id", 1);
10357
- __publicField(this, "styleIDMap", /* @__PURE__ */ new WeakMap());
10358
- __publicField(this, "idStyleMap", /* @__PURE__ */ new Map());
10360
+ __publicField$1(this, "id", 1);
10361
+ __publicField$1(this, "styleIDMap", /* @__PURE__ */ new WeakMap());
10362
+ __publicField$1(this, "idStyleMap", /* @__PURE__ */ new Map());
10359
10363
  }
10360
10364
  var _proto = StyleSheetMirror.prototype;
10361
10365
  _proto.getId = function getId(stylesheet) {
@@ -10491,9 +10495,9 @@
10491
10495
  }
10492
10496
  var DoubleLinkedList = /*#__PURE__*/ function() {
10493
10497
  function DoubleLinkedList() {
10494
- __publicField(this, "length", 0);
10495
- __publicField(this, "head", null);
10496
- __publicField(this, "tail", null);
10498
+ __publicField$1(this, "length", 0);
10499
+ __publicField$1(this, "head", null);
10500
+ __publicField$1(this, "tail", null);
10497
10501
  }
10498
10502
  var _proto = DoubleLinkedList.prototype;
10499
10503
  _proto.get = function get(position) {
@@ -10574,14 +10578,14 @@
10574
10578
  var MutationBuffer = /*#__PURE__*/ function() {
10575
10579
  function MutationBuffer() {
10576
10580
  var _this = this;
10577
- __publicField(this, "frozen", false);
10578
- __publicField(this, "locked", false);
10579
- __publicField(this, "texts", []);
10580
- __publicField(this, "attributes", []);
10581
- __publicField(this, "attributeMap", /* @__PURE__ */ new WeakMap());
10582
- __publicField(this, "removes", []);
10583
- __publicField(this, "mapRemoves", []);
10584
- __publicField(this, "movedMap", {});
10581
+ __publicField$1(this, "frozen", false);
10582
+ __publicField$1(this, "locked", false);
10583
+ __publicField$1(this, "texts", []);
10584
+ __publicField$1(this, "attributes", []);
10585
+ __publicField$1(this, "attributeMap", /* @__PURE__ */ new WeakMap());
10586
+ __publicField$1(this, "removes", []);
10587
+ __publicField$1(this, "mapRemoves", []);
10588
+ __publicField$1(this, "movedMap", {});
10585
10589
  /**
10586
10590
  * the browser MutationObserver emits multiple mutations after
10587
10591
  * a delay for performance reasons, making tracing added nodes hard
@@ -10598,37 +10602,37 @@
10598
10602
  * collect added nodes from the Set which have no duplicate copy. But
10599
10603
  * this also causes newly added nodes will not be serialized with id ASAP,
10600
10604
  * which means all the id related calculation should be lazy too.
10601
- */ __publicField(this, "addedSet", /* @__PURE__ */ new Set());
10602
- __publicField(this, "movedSet", /* @__PURE__ */ new Set());
10603
- __publicField(this, "droppedSet", /* @__PURE__ */ new Set());
10604
- __publicField(this, "removesSubTreeCache", /* @__PURE__ */ new Set());
10605
- __publicField(this, "mutationCb");
10606
- __publicField(this, "blockClass");
10607
- __publicField(this, "blockSelector");
10608
- __publicField(this, "maskTextClass");
10609
- __publicField(this, "maskTextSelector");
10610
- __publicField(this, "inlineStylesheet");
10611
- __publicField(this, "maskInputOptions");
10612
- __publicField(this, "maskTextFn");
10613
- __publicField(this, "maskInputFn");
10614
- __publicField(this, "keepIframeSrcFn");
10615
- __publicField(this, "recordCanvas");
10616
- __publicField(this, "inlineImages");
10617
- __publicField(this, "slimDOMOptions");
10618
- __publicField(this, "dataURLOptions");
10619
- __publicField(this, "doc");
10620
- __publicField(this, "mirror");
10621
- __publicField(this, "iframeManager");
10622
- __publicField(this, "stylesheetManager");
10623
- __publicField(this, "shadowDomManager");
10624
- __publicField(this, "canvasManager");
10625
- __publicField(this, "processedNodeManager");
10626
- __publicField(this, "unattachedDoc");
10627
- __publicField(this, "processMutations", function(mutations) {
10605
+ */ __publicField$1(this, "addedSet", /* @__PURE__ */ new Set());
10606
+ __publicField$1(this, "movedSet", /* @__PURE__ */ new Set());
10607
+ __publicField$1(this, "droppedSet", /* @__PURE__ */ new Set());
10608
+ __publicField$1(this, "removesSubTreeCache", /* @__PURE__ */ new Set());
10609
+ __publicField$1(this, "mutationCb");
10610
+ __publicField$1(this, "blockClass");
10611
+ __publicField$1(this, "blockSelector");
10612
+ __publicField$1(this, "maskTextClass");
10613
+ __publicField$1(this, "maskTextSelector");
10614
+ __publicField$1(this, "inlineStylesheet");
10615
+ __publicField$1(this, "maskInputOptions");
10616
+ __publicField$1(this, "maskTextFn");
10617
+ __publicField$1(this, "maskInputFn");
10618
+ __publicField$1(this, "keepIframeSrcFn");
10619
+ __publicField$1(this, "recordCanvas");
10620
+ __publicField$1(this, "inlineImages");
10621
+ __publicField$1(this, "slimDOMOptions");
10622
+ __publicField$1(this, "dataURLOptions");
10623
+ __publicField$1(this, "doc");
10624
+ __publicField$1(this, "mirror");
10625
+ __publicField$1(this, "iframeManager");
10626
+ __publicField$1(this, "stylesheetManager");
10627
+ __publicField$1(this, "shadowDomManager");
10628
+ __publicField$1(this, "canvasManager");
10629
+ __publicField$1(this, "processedNodeManager");
10630
+ __publicField$1(this, "unattachedDoc");
10631
+ __publicField$1(this, "processMutations", function(mutations) {
10628
10632
  mutations.forEach(_this.processMutation);
10629
10633
  _this.emit();
10630
10634
  });
10631
- __publicField(this, "emit", function() {
10635
+ __publicField$1(this, "emit", function() {
10632
10636
  if (_this.frozen || _this.locked) {
10633
10637
  return;
10634
10638
  }
@@ -10829,7 +10833,7 @@
10829
10833
  _this.movedMap = {};
10830
10834
  _this.mutationCb(payload);
10831
10835
  });
10832
- __publicField(this, "genTextAreaValueMutation", function(textarea) {
10836
+ __publicField$1(this, "genTextAreaValueMutation", function(textarea) {
10833
10837
  var item = _this.attributeMap.get(textarea);
10834
10838
  if (!item) {
10835
10839
  item = {
@@ -10853,7 +10857,7 @@
10853
10857
  maskInputFn: _this.maskInputFn
10854
10858
  });
10855
10859
  });
10856
- __publicField(this, "processMutation", function(m) {
10860
+ __publicField$1(this, "processMutation", function(m) {
10857
10861
  if (isIgnored(m.target, _this.mirror, _this.slimDOMOptions)) {
10858
10862
  return;
10859
10863
  }
@@ -10998,7 +11002,7 @@
10998
11002
  });
10999
11003
  /**
11000
11004
  * Make sure you check if `n`'s parent is blocked before calling this function
11001
- * */ __publicField(this, "genAdds", function(n2, target) {
11005
+ * */ __publicField$1(this, "genAdds", function(n2, target) {
11002
11006
  if (_this.processedNodeManager.inOtherBuffer(n2, _this)) return;
11003
11007
  if (_this.addedSet.has(n2) || _this.movedSet.has(n2)) return;
11004
11008
  if (_this.mirror.hasNode(n2)) {
@@ -11844,7 +11848,7 @@
11844
11848
  });
11845
11849
  return fontFace;
11846
11850
  };
11847
- var restoreHandler = patch(doc.fonts, "add", function(original) {
11851
+ var restoreHandler = patch$2(doc.fonts, "add", function(original) {
11848
11852
  return function(fontFace) {
11849
11853
  setTimeout(callbackWrapper(function() {
11850
11854
  var p = fontMap.get(fontFace);
@@ -11900,7 +11904,7 @@
11900
11904
  var doc = param.doc, customElementCb = param.customElementCb;
11901
11905
  var win = doc.defaultView;
11902
11906
  if (!win || !win.customElements) return function() {};
11903
- var restoreHandler = patch(win.customElements, "define", function(original) {
11907
+ var restoreHandler = patch$2(win.customElements, "define", function(original) {
11904
11908
  return function(name, constructor, options) {
11905
11909
  try {
11906
11910
  customElementCb({
@@ -12127,8 +12131,8 @@
12127
12131
  }
12128
12132
  var CrossOriginIframeMirror = /*#__PURE__*/ function() {
12129
12133
  function CrossOriginIframeMirror(generateIdFn) {
12130
- __publicField(this, "iframeIdToRemoteIdMap", /* @__PURE__ */ new WeakMap());
12131
- __publicField(this, "iframeRemoteIdToIdMap", /* @__PURE__ */ new WeakMap());
12134
+ __publicField$1(this, "iframeIdToRemoteIdMap", /* @__PURE__ */ new WeakMap());
12135
+ __publicField$1(this, "iframeRemoteIdToIdMap", /* @__PURE__ */ new WeakMap());
12132
12136
  this.generateIdFn = generateIdFn;
12133
12137
  }
12134
12138
  var _proto = CrossOriginIframeMirror.prototype;
@@ -12194,17 +12198,17 @@
12194
12198
  }();
12195
12199
  var IframeManager = /*#__PURE__*/ function() {
12196
12200
  function IframeManager(options) {
12197
- __publicField(this, "iframes", /* @__PURE__ */ new WeakMap());
12198
- __publicField(this, "crossOriginIframeMap", /* @__PURE__ */ new WeakMap());
12199
- __publicField(this, "crossOriginIframeMirror", new CrossOriginIframeMirror(genId));
12200
- __publicField(this, "crossOriginIframeStyleMirror");
12201
- __publicField(this, "crossOriginIframeRootIdMap", /* @__PURE__ */ new WeakMap());
12202
- __publicField(this, "mirror");
12203
- __publicField(this, "mutationCb");
12204
- __publicField(this, "wrappedEmit");
12205
- __publicField(this, "loadListener");
12206
- __publicField(this, "stylesheetManager");
12207
- __publicField(this, "recordCrossOriginIframes");
12201
+ __publicField$1(this, "iframes", /* @__PURE__ */ new WeakMap());
12202
+ __publicField$1(this, "crossOriginIframeMap", /* @__PURE__ */ new WeakMap());
12203
+ __publicField$1(this, "crossOriginIframeMirror", new CrossOriginIframeMirror(genId));
12204
+ __publicField$1(this, "crossOriginIframeStyleMirror");
12205
+ __publicField$1(this, "crossOriginIframeRootIdMap", /* @__PURE__ */ new WeakMap());
12206
+ __publicField$1(this, "mirror");
12207
+ __publicField$1(this, "mutationCb");
12208
+ __publicField$1(this, "wrappedEmit");
12209
+ __publicField$1(this, "loadListener");
12210
+ __publicField$1(this, "stylesheetManager");
12211
+ __publicField$1(this, "recordCrossOriginIframes");
12208
12212
  this.mutationCb = options.mutationCb;
12209
12213
  this.wrappedEmit = options.wrappedEmit;
12210
12214
  this.stylesheetManager = options.stylesheetManager;
@@ -12451,12 +12455,12 @@
12451
12455
  }();
12452
12456
  var ShadowDomManager = /*#__PURE__*/ function() {
12453
12457
  function ShadowDomManager(options) {
12454
- __publicField(this, "shadowDoms", /* @__PURE__ */ new WeakSet());
12455
- __publicField(this, "mutationCb");
12456
- __publicField(this, "scrollCb");
12457
- __publicField(this, "bypassOptions");
12458
- __publicField(this, "mirror");
12459
- __publicField(this, "restoreHandlers", []);
12458
+ __publicField$1(this, "shadowDoms", /* @__PURE__ */ new WeakSet());
12459
+ __publicField$1(this, "mutationCb");
12460
+ __publicField$1(this, "scrollCb");
12461
+ __publicField$1(this, "bypassOptions");
12462
+ __publicField$1(this, "mirror");
12463
+ __publicField$1(this, "restoreHandlers", []);
12460
12464
  this.mutationCb = options.mutationCb;
12461
12465
  this.scrollCb = options.scrollCb;
12462
12466
  this.bypassOptions = options.bypassOptions;
@@ -12507,7 +12511,7 @@
12507
12511
  * Patch 'attachShadow' to observe newly added shadow doms.
12508
12512
  */ _proto.patchAttachShadow = function patchAttachShadow(element, doc) {
12509
12513
  var manager = this;
12510
- this.restoreHandlers.push(patch(element.prototype, "attachShadow", function(original) {
12514
+ this.restoreHandlers.push(patch$2(element.prototype, "attachShadow", function(original) {
12511
12515
  return function(option) {
12512
12516
  var sRoot = original.call(this, option);
12513
12517
  var shadowRootEl = index.shadowRoot(this);
@@ -12673,7 +12677,7 @@
12673
12677
  if (typeof win.CanvasRenderingContext2D.prototype[prop] !== "function") {
12674
12678
  return "continue";
12675
12679
  }
12676
- var restoreHandler = patch(win.CanvasRenderingContext2D.prototype, prop, function(original) {
12680
+ var restoreHandler = patch$2(win.CanvasRenderingContext2D.prototype, prop, function(original) {
12677
12681
  return function() {
12678
12682
  var _this = this;
12679
12683
  for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
@@ -12724,7 +12728,7 @@
12724
12728
  function initCanvasContextObserver(win, blockClass, blockSelector, setPreserveDrawingBufferToTrue) {
12725
12729
  var handlers = [];
12726
12730
  try {
12727
- var restoreHandler = patch(win.HTMLCanvasElement.prototype, "getContext", function(original) {
12731
+ var restoreHandler = patch$2(win.HTMLCanvasElement.prototype, "getContext", function(original) {
12728
12732
  return function(contextType) {
12729
12733
  for(var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++){
12730
12734
  args[_key - 1] = arguments[_key];
@@ -12779,7 +12783,7 @@
12779
12783
  if (typeof prototype[prop] !== "function") {
12780
12784
  return "continue";
12781
12785
  }
12782
- var restoreHandler = patch(prototype, prop, function(original) {
12786
+ var restoreHandler = patch$2(prototype, prop, function(original) {
12783
12787
  return function() {
12784
12788
  for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
12785
12789
  args[_key] = arguments[_key];
@@ -12868,17 +12872,17 @@
12868
12872
  var CanvasManager = /*#__PURE__*/ function() {
12869
12873
  function CanvasManager(options) {
12870
12874
  var _this = this;
12871
- __publicField(this, "pendingCanvasMutations", /* @__PURE__ */ new Map());
12872
- __publicField(this, "rafStamps", {
12875
+ __publicField$1(this, "pendingCanvasMutations", /* @__PURE__ */ new Map());
12876
+ __publicField$1(this, "rafStamps", {
12873
12877
  latestId: 0,
12874
12878
  invokeId: null
12875
12879
  });
12876
- __publicField(this, "mirror");
12877
- __publicField(this, "mutationCb");
12878
- __publicField(this, "resetObservers");
12879
- __publicField(this, "frozen", false);
12880
- __publicField(this, "locked", false);
12881
- __publicField(this, "processMutation", function(target, mutation) {
12880
+ __publicField$1(this, "mirror");
12881
+ __publicField$1(this, "mutationCb");
12882
+ __publicField$1(this, "resetObservers");
12883
+ __publicField$1(this, "frozen", false);
12884
+ __publicField$1(this, "locked", false);
12885
+ __publicField$1(this, "processMutation", function(target, mutation) {
12882
12886
  var newFrame = _this.rafStamps.invokeId && _this.rafStamps.latestId !== _this.rafStamps.invokeId;
12883
12887
  if (newFrame || !_this.rafStamps.invokeId) _this.rafStamps.invokeId = _this.rafStamps.latestId;
12884
12888
  if (!_this.pendingCanvasMutations.has(target)) {
@@ -13091,10 +13095,10 @@
13091
13095
  }();
13092
13096
  var StylesheetManager = /*#__PURE__*/ function() {
13093
13097
  function StylesheetManager(options) {
13094
- __publicField(this, "trackedLinkElements", /* @__PURE__ */ new WeakSet());
13095
- __publicField(this, "mutationCb");
13096
- __publicField(this, "adoptedStyleSheetCb");
13097
- __publicField(this, "styleMirror", new StyleSheetMirror());
13098
+ __publicField$1(this, "trackedLinkElements", /* @__PURE__ */ new WeakSet());
13099
+ __publicField$1(this, "mutationCb");
13100
+ __publicField$1(this, "adoptedStyleSheetCb");
13101
+ __publicField$1(this, "styleMirror", new StyleSheetMirror());
13098
13102
  this.mutationCb = options.mutationCb;
13099
13103
  this.adoptedStyleSheetCb = options.adoptedStyleSheetCb;
13100
13104
  }
@@ -13156,8 +13160,8 @@
13156
13160
  }();
13157
13161
  var ProcessedNodeManager = /*#__PURE__*/ function() {
13158
13162
  function ProcessedNodeManager() {
13159
- __publicField(this, "nodeMap", /* @__PURE__ */ new WeakMap());
13160
- __publicField(this, "active", false);
13163
+ __publicField$1(this, "nodeMap", /* @__PURE__ */ new WeakMap());
13164
+ __publicField$1(this, "active", false);
13161
13165
  }
13162
13166
  var _proto = ProcessedNodeManager.prototype;
13163
13167
  _proto.inOtherBuffer = function inOtherBuffer(node2, thisBuffer) {
@@ -13682,6 +13686,493 @@
13682
13686
  record.addCustomEvent;
13683
13687
  record.freezePage;
13684
13688
  record.takeFullSnapshot;
13689
+ var __defProp = Object.defineProperty;
13690
+ var __defNormalProp = function(obj, key, value) {
13691
+ return key in obj ? __defProp(obj, key, {
13692
+ enumerable: true,
13693
+ configurable: true,
13694
+ writable: true,
13695
+ value: value
13696
+ }) : obj[key] = value;
13697
+ };
13698
+ var __publicField = function(obj, key, value) {
13699
+ return __defNormalProp(obj, (typeof key === "undefined" ? "undefined" : _type_of(key)) !== "symbol" ? key + "" : key, value);
13700
+ };
13701
+ function patch(source, name, replacement) {
13702
+ try {
13703
+ if (!(name in source)) {
13704
+ return function() {};
13705
+ }
13706
+ var original = source[name];
13707
+ var wrapped = replacement(original);
13708
+ if (typeof wrapped === "function") {
13709
+ wrapped.prototype = wrapped.prototype || {};
13710
+ Object.defineProperties(wrapped, {
13711
+ __rrweb_original__: {
13712
+ enumerable: false,
13713
+ value: original
13714
+ }
13715
+ });
13716
+ }
13717
+ source[name] = wrapped;
13718
+ return function() {
13719
+ source[name] = original;
13720
+ };
13721
+ } catch (e) {
13722
+ return function() {};
13723
+ }
13724
+ }
13725
+ var StackFrame = /*#__PURE__*/ function() {
13726
+ function StackFrame(obj) {
13727
+ __publicField(this, "fileName");
13728
+ __publicField(this, "functionName");
13729
+ __publicField(this, "lineNumber");
13730
+ __publicField(this, "columnNumber");
13731
+ this.fileName = obj.fileName || "";
13732
+ this.functionName = obj.functionName || "";
13733
+ this.lineNumber = obj.lineNumber;
13734
+ this.columnNumber = obj.columnNumber;
13735
+ }
13736
+ var _proto = StackFrame.prototype;
13737
+ _proto.toString = function toString() {
13738
+ var lineNumber = this.lineNumber || "";
13739
+ var columnNumber = this.columnNumber || "";
13740
+ if (this.functionName) return this.functionName + " (" + this.fileName + ":" + lineNumber + ":" + columnNumber + ")";
13741
+ return this.fileName + ":" + lineNumber + ":" + columnNumber;
13742
+ };
13743
+ return StackFrame;
13744
+ }();
13745
+ var FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\S+:\d+/;
13746
+ var CHROME_IE_STACK_REGEXP = /^\s*at .*(\S+:\d+|\(native\))/m;
13747
+ var SAFARI_NATIVE_CODE_REGEXP = /^(eval@)?(\[native code])?$/;
13748
+ var ErrorStackParser = {
13749
+ /**
13750
+ * Given an Error object, extract the most information from it.
13751
+ */ parse: function parse(error) {
13752
+ if (!error) {
13753
+ return [];
13754
+ }
13755
+ if (// eslint-disable-next-line @typescript-eslint/ban-ts-comment
13756
+ // @ts-ignore
13757
+ typeof error.stacktrace !== "undefined" || // eslint-disable-next-line @typescript-eslint/ban-ts-comment
13758
+ // @ts-ignore
13759
+ typeof error["opera#sourceloc"] !== "undefined") {
13760
+ return this.parseOpera(error);
13761
+ } else if (error.stack && error.stack.match(CHROME_IE_STACK_REGEXP)) {
13762
+ return this.parseV8OrIE(error);
13763
+ } else if (error.stack) {
13764
+ return this.parseFFOrSafari(error);
13765
+ } else {
13766
+ console.warn("[console-record-plugin]: Failed to parse error object:", error);
13767
+ return [];
13768
+ }
13769
+ },
13770
+ // Separate line and column numbers from a string of the form: (URI:Line:Column)
13771
+ extractLocation: function extractLocation(urlLike) {
13772
+ if (urlLike.indexOf(":") === -1) {
13773
+ return [
13774
+ urlLike
13775
+ ];
13776
+ }
13777
+ var regExp = /(.+?)(?::(\d+))?(?::(\d+))?$/;
13778
+ var parts = regExp.exec(urlLike.replace(/[()]/g, ""));
13779
+ if (!parts) throw new Error("Cannot parse given url: " + urlLike);
13780
+ return [
13781
+ parts[1],
13782
+ parts[2] || void 0,
13783
+ parts[3] || void 0
13784
+ ];
13785
+ },
13786
+ parseV8OrIE: function parseV8OrIE(error) {
13787
+ var filtered = error.stack.split("\n").filter(function(line) {
13788
+ return !!line.match(CHROME_IE_STACK_REGEXP);
13789
+ }, this);
13790
+ return filtered.map(function(line) {
13791
+ if (line.indexOf("(eval ") > -1) {
13792
+ line = line.replace(/eval code/g, "eval").replace(/(\(eval at [^()]*)|(\),.*$)/g, "");
13793
+ }
13794
+ var sanitizedLine = line.replace(/^\s+/, "").replace(/\(eval code/g, "(");
13795
+ var location = sanitizedLine.match(/ (\((.+):(\d+):(\d+)\)$)/);
13796
+ sanitizedLine = location ? sanitizedLine.replace(location[0], "") : sanitizedLine;
13797
+ var tokens = sanitizedLine.split(/\s+/).slice(1);
13798
+ var locationParts = this.extractLocation(location ? location[1] : tokens.pop());
13799
+ var functionName = tokens.join(" ") || void 0;
13800
+ var fileName = [
13801
+ "eval",
13802
+ "<anonymous>"
13803
+ ].indexOf(locationParts[0]) > -1 ? void 0 : locationParts[0];
13804
+ return new StackFrame({
13805
+ functionName: functionName,
13806
+ fileName: fileName,
13807
+ lineNumber: locationParts[1],
13808
+ columnNumber: locationParts[2]
13809
+ });
13810
+ }, this);
13811
+ },
13812
+ parseFFOrSafari: function parseFFOrSafari(error) {
13813
+ var filtered = error.stack.split("\n").filter(function(line) {
13814
+ return !line.match(SAFARI_NATIVE_CODE_REGEXP);
13815
+ }, this);
13816
+ return filtered.map(function(line) {
13817
+ if (line.indexOf(" > eval") > -1) {
13818
+ line = line.replace(/ line (\d+)(?: > eval line \d+)* > eval:\d+:\d+/g, ":$1");
13819
+ }
13820
+ if (line.indexOf("@") === -1 && line.indexOf(":") === -1) {
13821
+ return new StackFrame({
13822
+ functionName: line
13823
+ });
13824
+ } else {
13825
+ var functionNameRegex = /((.*".+"[^@]*)?[^@]*)(?:@)/;
13826
+ var matches = line.match(functionNameRegex);
13827
+ var functionName = matches && matches[1] ? matches[1] : void 0;
13828
+ var locationParts = this.extractLocation(line.replace(functionNameRegex, ""));
13829
+ return new StackFrame({
13830
+ functionName: functionName,
13831
+ fileName: locationParts[0],
13832
+ lineNumber: locationParts[1],
13833
+ columnNumber: locationParts[2]
13834
+ });
13835
+ }
13836
+ }, this);
13837
+ },
13838
+ parseOpera: function parseOpera(e) {
13839
+ if (!e.stacktrace || e.message.indexOf("\n") > -1 && e.message.split("\n").length > e.stacktrace.split("\n").length) {
13840
+ return this.parseOpera9(e);
13841
+ } else if (!e.stack) {
13842
+ return this.parseOpera10(e);
13843
+ } else {
13844
+ return this.parseOpera11(e);
13845
+ }
13846
+ },
13847
+ parseOpera9: function parseOpera9(e) {
13848
+ var lineRE = /Line (\d+).*script (?:in )?(\S+)/i;
13849
+ var lines = e.message.split("\n");
13850
+ var result = [];
13851
+ for(var i = 2, len = lines.length; i < len; i += 2){
13852
+ var match = lineRE.exec(lines[i]);
13853
+ if (match) {
13854
+ result.push(new StackFrame({
13855
+ fileName: match[2],
13856
+ lineNumber: parseFloat(match[1])
13857
+ }));
13858
+ }
13859
+ }
13860
+ return result;
13861
+ },
13862
+ parseOpera10: function parseOpera10(e) {
13863
+ var lineRE = /Line (\d+).*script (?:in )?(\S+)(?:: In function (\S+))?$/i;
13864
+ var lines = e.stacktrace.split("\n");
13865
+ var result = [];
13866
+ for(var i = 0, len = lines.length; i < len; i += 2){
13867
+ var match = lineRE.exec(lines[i]);
13868
+ if (match) {
13869
+ result.push(new StackFrame({
13870
+ functionName: match[3] || void 0,
13871
+ fileName: match[2],
13872
+ lineNumber: parseFloat(match[1])
13873
+ }));
13874
+ }
13875
+ }
13876
+ return result;
13877
+ },
13878
+ // Opera 10.65+ Error.stack very similar to FF/Safari
13879
+ parseOpera11: function parseOpera11(error) {
13880
+ var filtered = error.stack.split("\n").filter(function(line) {
13881
+ return !!line.match(FIREFOX_SAFARI_STACK_REGEXP) && !line.match(/^Error created at/);
13882
+ }, this);
13883
+ return filtered.map(function(line) {
13884
+ var tokens = line.split("@");
13885
+ var locationParts = this.extractLocation(tokens.pop());
13886
+ var functionCall = tokens.shift() || "";
13887
+ var functionName = functionCall.replace(/<anonymous function(: (\w+))?>/, "$2").replace(/\([^)]*\)/g, "") || void 0;
13888
+ return new StackFrame({
13889
+ functionName: functionName,
13890
+ fileName: locationParts[0],
13891
+ lineNumber: locationParts[1],
13892
+ columnNumber: locationParts[2]
13893
+ });
13894
+ }, this);
13895
+ }
13896
+ };
13897
+ function pathToSelector(node) {
13898
+ if (!node || !node.outerHTML) {
13899
+ return "";
13900
+ }
13901
+ var path = "";
13902
+ while(node.parentElement){
13903
+ var name = node.localName;
13904
+ if (!name) {
13905
+ break;
13906
+ }
13907
+ name = name.toLowerCase();
13908
+ var parent = node.parentElement;
13909
+ var domSiblings = [];
13910
+ if (parent.children && parent.children.length > 0) {
13911
+ for(var i = 0; i < parent.children.length; i++){
13912
+ var sibling = parent.children[i];
13913
+ if (sibling.localName && sibling.localName.toLowerCase) {
13914
+ if (sibling.localName.toLowerCase() === name) {
13915
+ domSiblings.push(sibling);
13916
+ }
13917
+ }
13918
+ }
13919
+ }
13920
+ if (domSiblings.length > 1) {
13921
+ name += ":eq(" + domSiblings.indexOf(node) + ")";
13922
+ }
13923
+ path = name + (path ? ">" + path : "");
13924
+ node = parent;
13925
+ }
13926
+ return path;
13927
+ }
13928
+ function isObject(obj) {
13929
+ return Object.prototype.toString.call(obj) === "[object Object]";
13930
+ }
13931
+ function isObjTooDeep(obj, limit) {
13932
+ if (limit === 0) {
13933
+ return true;
13934
+ }
13935
+ var keys = Object.keys(obj);
13936
+ for(var _iterator = _create_for_of_iterator_helper_loose(keys), _step; !(_step = _iterator()).done;){
13937
+ var key = _step.value;
13938
+ if (isObject(obj[key]) && isObjTooDeep(obj[key], limit - 1)) {
13939
+ return true;
13940
+ }
13941
+ }
13942
+ return false;
13943
+ }
13944
+ function stringify(obj, stringifyOptions) {
13945
+ var options = {
13946
+ numOfKeysLimit: 50,
13947
+ depthOfLimit: 4
13948
+ };
13949
+ Object.assign(options, stringifyOptions);
13950
+ var stack = [];
13951
+ var keys = [];
13952
+ return JSON.stringify(obj, function(key, value) {
13953
+ if (stack.length > 0) {
13954
+ var thisPos = stack.indexOf(this);
13955
+ ~thisPos ? stack.splice(thisPos + 1) : stack.push(this);
13956
+ ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key);
13957
+ if (~stack.indexOf(value)) {
13958
+ if (stack[0] === value) {
13959
+ value = "[Circular ~]";
13960
+ } else {
13961
+ value = "[Circular ~." + keys.slice(0, stack.indexOf(value)).join(".") + "]";
13962
+ }
13963
+ }
13964
+ } else {
13965
+ stack.push(value);
13966
+ }
13967
+ if (value === null) return value;
13968
+ if (value === void 0) return "undefined";
13969
+ if (shouldIgnore(value)) {
13970
+ return toString(value);
13971
+ }
13972
+ if ((typeof value === "undefined" ? "undefined" : _type_of(value)) === "bigint") {
13973
+ return value.toString() + "n";
13974
+ }
13975
+ if (_instanceof(value, Event)) {
13976
+ var eventResult = {};
13977
+ for(var eventKey in value){
13978
+ var eventValue = value[eventKey];
13979
+ if (Array.isArray(eventValue)) {
13980
+ eventResult[eventKey] = pathToSelector(eventValue.length ? eventValue[0] : null);
13981
+ } else {
13982
+ eventResult[eventKey] = eventValue;
13983
+ }
13984
+ }
13985
+ return eventResult;
13986
+ } else if (_instanceof(value, Node)) {
13987
+ if (_instanceof(value, HTMLElement)) {
13988
+ return value ? value.outerHTML : "";
13989
+ }
13990
+ return value.nodeName;
13991
+ } else if (_instanceof(value, Error)) {
13992
+ return value.stack ? value.stack + "\nEnd of stack for Error object" : value.name + ": " + value.message;
13993
+ }
13994
+ return value;
13995
+ });
13996
+ function shouldIgnore(_obj) {
13997
+ if (isObject(_obj) && Object.keys(_obj).length > options.numOfKeysLimit) {
13998
+ return true;
13999
+ }
14000
+ if (typeof _obj === "function") {
14001
+ return true;
14002
+ }
14003
+ if (isObject(_obj) && isObjTooDeep(_obj, options.depthOfLimit)) {
14004
+ return true;
14005
+ }
14006
+ return false;
14007
+ }
14008
+ function toString(_obj) {
14009
+ var str = _obj.toString();
14010
+ if (options.stringLengthLimit && str.length > options.stringLengthLimit) {
14011
+ str = "" + str.slice(0, options.stringLengthLimit) + "...";
14012
+ }
14013
+ return str;
14014
+ }
14015
+ }
14016
+ var defaultLogOptions = {
14017
+ level: [
14018
+ "assert",
14019
+ "clear",
14020
+ "count",
14021
+ "countReset",
14022
+ "debug",
14023
+ "dir",
14024
+ "dirxml",
14025
+ "error",
14026
+ "group",
14027
+ "groupCollapsed",
14028
+ "groupEnd",
14029
+ "info",
14030
+ "log",
14031
+ "table",
14032
+ "time",
14033
+ "timeEnd",
14034
+ "timeLog",
14035
+ "trace",
14036
+ "warn"
14037
+ ],
14038
+ lengthThreshold: 1e3,
14039
+ logger: "console"
14040
+ };
14041
+ function initLogObserver(cb, win, options) {
14042
+ var logOptions = options ? Object.assign({}, defaultLogOptions, options) : defaultLogOptions;
14043
+ var loggerType = logOptions.logger;
14044
+ if (!loggerType) {
14045
+ return function() {};
14046
+ }
14047
+ var logger;
14048
+ if (typeof loggerType === "string") {
14049
+ logger = win[loggerType];
14050
+ } else {
14051
+ logger = loggerType;
14052
+ }
14053
+ var logCount = 0;
14054
+ var inStack = false;
14055
+ var cancelHandlers = [];
14056
+ if (logOptions.level.includes("error")) {
14057
+ var errorHandler = function(event) {
14058
+ var message = event.message, error = event.error;
14059
+ var trace = ErrorStackParser.parse(error).map(function(stackFrame) {
14060
+ return stackFrame.toString();
14061
+ });
14062
+ var payload = [
14063
+ stringify(message, logOptions.stringifyOptions)
14064
+ ];
14065
+ cb({
14066
+ level: "error",
14067
+ trace: trace,
14068
+ payload: payload
14069
+ });
14070
+ };
14071
+ win.addEventListener("error", errorHandler);
14072
+ cancelHandlers.push(function() {
14073
+ win.removeEventListener("error", errorHandler);
14074
+ });
14075
+ var unhandledrejectionHandler = function(event) {
14076
+ var error;
14077
+ var payload;
14078
+ if (_instanceof(event.reason, Error)) {
14079
+ error = event.reason;
14080
+ payload = [
14081
+ stringify("Uncaught (in promise) " + error.name + ": " + error.message, logOptions.stringifyOptions)
14082
+ ];
14083
+ } else {
14084
+ error = new Error();
14085
+ payload = [
14086
+ stringify("Uncaught (in promise)", logOptions.stringifyOptions),
14087
+ stringify(event.reason, logOptions.stringifyOptions)
14088
+ ];
14089
+ }
14090
+ var trace = ErrorStackParser.parse(error).map(function(stackFrame) {
14091
+ return stackFrame.toString();
14092
+ });
14093
+ cb({
14094
+ level: "error",
14095
+ trace: trace,
14096
+ payload: payload
14097
+ });
14098
+ };
14099
+ win.addEventListener("unhandledrejection", unhandledrejectionHandler);
14100
+ cancelHandlers.push(function() {
14101
+ win.removeEventListener("unhandledrejection", unhandledrejectionHandler);
14102
+ });
14103
+ }
14104
+ for(var _iterator = _create_for_of_iterator_helper_loose(logOptions.level), _step; !(_step = _iterator()).done;){
14105
+ var levelType = _step.value;
14106
+ cancelHandlers.push(replace(logger, levelType));
14107
+ }
14108
+ return function() {
14109
+ cancelHandlers.forEach(function(h) {
14110
+ return h();
14111
+ });
14112
+ };
14113
+ function replace(_logger, level) {
14114
+ var _this = this;
14115
+ if (!_logger[level]) {
14116
+ return function() {};
14117
+ }
14118
+ return patch(_logger, level, function(original) {
14119
+ var _this1 = _this;
14120
+ return function() {
14121
+ for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
14122
+ args[_key] = arguments[_key];
14123
+ }
14124
+ original.apply(_this1, args);
14125
+ if (level === "assert" && !!args[0]) {
14126
+ return;
14127
+ }
14128
+ if (inStack) {
14129
+ return;
14130
+ }
14131
+ inStack = true;
14132
+ try {
14133
+ var trace = ErrorStackParser.parse(new Error()).map(function(stackFrame) {
14134
+ return stackFrame.toString();
14135
+ }).splice(1);
14136
+ var argsForPayload = level === "assert" ? args.slice(1) : args;
14137
+ var payload = argsForPayload.map(function(s) {
14138
+ return stringify(s, logOptions.stringifyOptions);
14139
+ });
14140
+ logCount++;
14141
+ if (logCount < logOptions.lengthThreshold) {
14142
+ cb({
14143
+ level: level,
14144
+ trace: trace,
14145
+ payload: payload
14146
+ });
14147
+ } else if (logCount === logOptions.lengthThreshold) {
14148
+ cb({
14149
+ level: "warn",
14150
+ trace: [],
14151
+ payload: [
14152
+ stringify("The number of log records reached the threshold.")
14153
+ ]
14154
+ });
14155
+ }
14156
+ } catch (error) {
14157
+ original.apply(void 0, [].concat([
14158
+ "rrweb logger error:",
14159
+ error
14160
+ ], args));
14161
+ } finally{
14162
+ inStack = false;
14163
+ }
14164
+ };
14165
+ });
14166
+ }
14167
+ }
14168
+ var PLUGIN_NAME = "rrweb/console@1";
14169
+ var getRecordConsolePlugin = function(options) {
14170
+ return {
14171
+ name: PLUGIN_NAME,
14172
+ observer: initLogObserver,
14173
+ options: options
14174
+ };
14175
+ };
13685
14176
 
13686
14177
  var setImmediate = win['setImmediate'];
13687
14178
  var builtInProp, cycle, schedulingQueue,
@@ -14047,7 +14538,7 @@
14047
14538
 
14048
14539
  var Config = {
14049
14540
  DEBUG: false,
14050
- LIB_VERSION: '2.71.1'
14541
+ LIB_VERSION: '2.73.0'
14051
14542
  };
14052
14543
 
14053
14544
  /* eslint camelcase: "off", eqeqeq: "off" */
@@ -15787,6 +16278,28 @@
15787
16278
  JSONStringify = JSONStringify || _.JSONEncode;
15788
16279
  JSONParse = JSONParse || _.JSONDecode;
15789
16280
 
16281
+ /**
16282
+ * Determines if CompressionStream API should be used.
16283
+ * Returns false for Safari 16.4 and 16.5 which have breaking CompressionStream bugs.
16284
+ * https://bugs.webkit.org/show_bug.cgi?id=254021
16285
+ * fixed in 16.6 https://developer.apple.com/documentation/safari-release-notes/safari-16_6-release-notes
16286
+ */
16287
+ var canUseCompressionStream = function(userAgent, vendor, opera) {
16288
+ if (!win.CompressionStream) {
16289
+ return false;
16290
+ }
16291
+
16292
+ var browser = _.info.browser(userAgent, vendor, opera);
16293
+ var version = _.info.browserVersion(userAgent, vendor, opera);
16294
+ if (browser === 'Safari' || browser === 'Mobile Safari') {
16295
+ if (version >= 16.4 && version < 16.6) {
16296
+ return false;
16297
+ }
16298
+ }
16299
+
16300
+ return true;
16301
+ };
16302
+
15790
16303
  // UNMINIFIED EXPORTS (for closure compiler)
15791
16304
  _['info'] = _.info;
15792
16305
  _['info']['browser'] = _.info.browser;
@@ -17162,6 +17675,7 @@
17162
17675
  * @property {number} idleExpires
17163
17676
  * @property {number} maxExpires
17164
17677
  * @property {number} replayStartTime
17678
+ * @property {number} lastEventTimestamp
17165
17679
  * @property {number} seqNo
17166
17680
  * @property {string} batchStartUrl
17167
17681
  * @property {string} replayId
@@ -17182,6 +17696,7 @@
17182
17696
  * @property {number} idleExpires
17183
17697
  * @property {number} maxExpires
17184
17698
  * @property {number} replayStartTime
17699
+ * @property {number} lastEventTimestamp - the unix timestamp of the last recorded event from rrweb
17185
17700
  * @property {number} seqNo
17186
17701
  * @property {string} batchStartUrl
17187
17702
  * @property {string} replayStartUrl
@@ -17215,6 +17730,7 @@
17215
17730
  this.idleExpires = options.idleExpires || null;
17216
17731
  this.maxExpires = options.maxExpires || null;
17217
17732
  this.replayStartTime = options.replayStartTime || null;
17733
+ this.lastEventTimestamp = options.lastEventTimestamp || null;
17218
17734
  this.seqNo = options.seqNo || 0;
17219
17735
 
17220
17736
  this.idleTimeoutId = null;
@@ -17274,10 +17790,20 @@
17274
17790
 
17275
17791
  SessionRecording.prototype.unloadPersistedData = function () {
17276
17792
  this.batcher.stop();
17277
- return this.batcher.flush()
17278
- .then(function () {
17793
+
17794
+ return this.queueStorage.init().catch(function () {
17795
+ this.reportError('Error initializing IndexedDB storage for unloading persisted data.');
17796
+ }.bind(this)).then(function () {
17797
+ // if the recording is too short, just delete any stored events without flushing
17798
+ if (this.getDurationMs() < this._getRecordMinMs()) {
17279
17799
  return this.queueStorage.removeItem(this.batcherKey);
17280
- }.bind(this));
17800
+ }
17801
+
17802
+ return this.batcher.flush()
17803
+ .then(function () {
17804
+ return this.queueStorage.removeItem(this.batcherKey);
17805
+ }.bind(this));
17806
+ }.bind(this));
17281
17807
  };
17282
17808
 
17283
17809
  SessionRecording.prototype.getConfig = function(configVar) {
@@ -17312,11 +17838,7 @@
17312
17838
  this.maxExpires = new Date().getTime() + this.recordMaxMs;
17313
17839
  }
17314
17840
 
17315
- this.recordMinMs = this.getConfig('record_min_ms');
17316
- if (this.recordMinMs > MAX_VALUE_FOR_MIN_RECORDING_MS) {
17317
- this.recordMinMs = MAX_VALUE_FOR_MIN_RECORDING_MS;
17318
- logger$3.critical('record_min_ms cannot be greater than ' + MAX_VALUE_FOR_MIN_RECORDING_MS + 'ms. Capping value.');
17319
- }
17841
+ this.recordMinMs = this._getRecordMinMs();
17320
17842
 
17321
17843
  if (!this.replayStartTime) {
17322
17844
  this.replayStartTime = new Date().getTime();
@@ -17364,6 +17886,11 @@
17364
17886
  }
17365
17887
  // promise only used to await during tests
17366
17888
  this.__enqueuePromise = this.batcher.enqueue(ev);
17889
+
17890
+ // Capture the timestamp of the last event for duration calculation.
17891
+ if (this.lastEventTimestamp === null || ev.timestamp > this.lastEventTimestamp) {
17892
+ this.lastEventTimestamp = ev.timestamp;
17893
+ }
17367
17894
  }.bind(this),
17368
17895
  'blockClass': this.getConfig('record_block_class'),
17369
17896
  'blockSelector': blockSelector,
@@ -17378,7 +17905,16 @@
17378
17905
  'recordCanvas': this.getConfig('record_canvas'),
17379
17906
  'sampling': {
17380
17907
  'canvas': 15
17381
- }
17908
+ },
17909
+ 'plugins': this.getConfig('record_console') ? [
17910
+ getRecordConsolePlugin({
17911
+ stringifyOptions: {
17912
+ stringLengthLimit: 1000,
17913
+ numOfKeysLimit: 50,
17914
+ depthOfLimit: 2
17915
+ }
17916
+ })
17917
+ ] : []
17382
17918
  });
17383
17919
  } catch (err) {
17384
17920
  this.reportError('Unexpected error when starting rrweb recording.', err);
@@ -17463,6 +17999,7 @@
17463
17999
  'replayStartTime': this.replayStartTime,
17464
18000
  'batchStartUrl': this.batchStartUrl,
17465
18001
  'replayStartUrl': this.replayStartUrl,
18002
+ 'lastEventTimestamp': this.lastEventTimestamp,
17466
18003
  'idleExpires': this.idleExpires,
17467
18004
  'maxExpires': this.maxExpires,
17468
18005
  'tabId': tabId,
@@ -17484,6 +18021,7 @@
17484
18021
  idleExpires: serializedRecording['idleExpires'],
17485
18022
  maxExpires: serializedRecording['maxExpires'],
17486
18023
  replayStartTime: serializedRecording['replayStartTime'],
18024
+ lastEventTimestamp: serializedRecording['lastEventTimestamp'],
17487
18025
  seqNo: serializedRecording['seqNo'],
17488
18026
  sharedLockStorage: options.sharedLockStorage,
17489
18027
  }));
@@ -17574,7 +18112,7 @@
17574
18112
  var eventsJson = JSON.stringify(data);
17575
18113
  Object.assign(reqParams, this.getUserIdInfo());
17576
18114
 
17577
- if (CompressionStream) {
18115
+ if (canUseCompressionStream(userAgent, navigator.vendor, windowOpera)) {
17578
18116
  var jsonStream = new Blob([eventsJson], {type: 'application/json'}).stream();
17579
18117
  var gzipStream = jsonStream.pipeThrough(new CompressionStream('gzip'));
17580
18118
  new Response(gzipStream)
@@ -17603,6 +18141,38 @@
17603
18141
  }
17604
18142
  };
17605
18143
 
18144
+ /**
18145
+ * Calculates the duration of the recording in milliseconds, based on the start time and time of last recorded event.
18146
+ * @returns {number} The duration of the recording in milliseconds. Returns 0 if recording hasn't started.
18147
+ */
18148
+ SessionRecording.prototype.getDurationMs = function() {
18149
+ if (this.replayStartTime === null) {
18150
+ return 0;
18151
+ }
18152
+
18153
+ // If the recording has no events, assume it is in progress and use the current time as the end time.
18154
+ if (this.lastEventTimestamp === null) {
18155
+ return new Date().getTime() - this.replayStartTime;
18156
+ }
18157
+
18158
+ return this.lastEventTimestamp - this.replayStartTime;
18159
+ };
18160
+
18161
+ /**
18162
+ * Lazily loads the minimum recording length config in milliseconds, respecting the maximum limit.
18163
+ * @returns {number} The minimum recording length in milliseconds.
18164
+ */
18165
+ SessionRecording.prototype._getRecordMinMs = function() {
18166
+ var configValue = this.getConfig('record_min_ms');
18167
+
18168
+ if (configValue > MAX_VALUE_FOR_MIN_RECORDING_MS) {
18169
+ logger$3.critical('record_min_ms cannot be greater than ' + MAX_VALUE_FOR_MIN_RECORDING_MS + 'ms. Capping value.');
18170
+ return MAX_VALUE_FOR_MIN_RECORDING_MS;
18171
+ }
18172
+
18173
+ return configValue;
18174
+ };
18175
+
17606
18176
  /**
17607
18177
  * Module for handling the storage and retrieval of recording metadata as well as any active recordings.
17608
18178
  * Makes sure that only one tab can be recording at a time.
@@ -18612,20 +19182,65 @@
18612
19182
  return false;
18613
19183
  }
18614
19184
 
19185
+ /**
19186
+ * Get the composed path of a click event for elements embedded in shadow DOM.
19187
+ * @param {Event} event - event to get the composed path from
19188
+ * @returns {Array} the composed path of the click event
19189
+ */
19190
+ function getClickEventComposedPath(event) {
19191
+ if ('composedPath' in event) {
19192
+ return event['composedPath']();
19193
+ }
19194
+
19195
+ return [];
19196
+ }
19197
+
19198
+ /**
19199
+ * Get the element from a click event, accounting for elements embedded in shadow DOM.
19200
+ * @param {Event} event - event to get the target from
19201
+ * @returns {Element | null} the element that was the target of the click event
19202
+ */
19203
+ function getClickEventTargetElement(event) {
19204
+ var path = getClickEventComposedPath(event);
19205
+
19206
+ if (path && path.length > 0) {
19207
+ return path[0];
19208
+ }
19209
+
19210
+ return event['target'] || event['srcElement'];
19211
+ }
19212
+
18615
19213
  /** @const */ var DEFAULT_RAGE_CLICK_THRESHOLD_PX = 30;
18616
19214
  /** @const */ var DEFAULT_RAGE_CLICK_TIMEOUT_MS = 1000;
18617
19215
  /** @const */ var DEFAULT_RAGE_CLICK_CLICK_COUNT = 4;
19216
+ /** @const */ var DEFAULT_RAGE_CLICK_INTERACTIVE_ELEMENTS_ONLY = false;
18618
19217
 
18619
19218
  function RageClickTracker() {
18620
19219
  this.clicks = [];
18621
19220
  }
18622
19221
 
18623
- RageClickTracker.prototype.isRageClick = function(x, y, options) {
19222
+ /**
19223
+ * Determines if a click event is part of a rage click sequence.
19224
+ * @param {Event} event - the original click event.
19225
+ * @param {import('../index.d.ts').RageClickConfig} options - configuration options for rage click detection.
19226
+ * @returns {boolean} - true if the click is considered a rage click, false otherwise.
19227
+ */
19228
+ RageClickTracker.prototype.isRageClick = function(event, options) {
18624
19229
  options = options || {};
18625
19230
  var thresholdPx = options['threshold_px'] || DEFAULT_RAGE_CLICK_THRESHOLD_PX;
18626
19231
  var timeoutMs = options['timeout_ms'] || DEFAULT_RAGE_CLICK_TIMEOUT_MS;
18627
19232
  var clickCount = options['click_count'] || DEFAULT_RAGE_CLICK_CLICK_COUNT;
19233
+ var interactiveElementsOnly = options['interactive_elements_only'] || DEFAULT_RAGE_CLICK_INTERACTIVE_ELEMENTS_ONLY;
19234
+
19235
+ if (interactiveElementsOnly) {
19236
+ var target = getClickEventTargetElement(event);
19237
+ if (!target || isDefinitelyNonInteractive(target)) {
19238
+ return false;
19239
+ }
19240
+ }
19241
+
18628
19242
  var timestamp = Date.now();
19243
+ var x = event['pageX'], y = event['pageY'];
18629
19244
 
18630
19245
  var lastClick = this.clicks[this.clicks.length - 1];
18631
19246
  if (
@@ -18656,28 +19271,16 @@
18656
19271
  if (!this.observedShadowRoots) {
18657
19272
  return;
18658
19273
  }
18659
- var path = this.getComposedPath(event);
18660
- if (path && path.length) {
18661
- return path[0];
18662
- }
18663
19274
 
18664
- return event['target'] || event['srcElement'];
19275
+ return getClickEventTargetElement(event);
18665
19276
  };
18666
19277
 
18667
-
18668
- ShadowDOMObserver.prototype.getComposedPath = function(event) {
18669
- if ('composedPath' in event) {
18670
- return event['composedPath']();
18671
- }
18672
-
18673
- return [];
18674
- };
18675
19278
  ShadowDOMObserver.prototype.observeFromEvent = function(event) {
18676
19279
  if (!this.observedShadowRoots) {
18677
19280
  return;
18678
19281
  }
18679
19282
 
18680
- var path = this.getComposedPath(event);
19283
+ var path = getClickEventComposedPath(event);
18681
19284
 
18682
19285
  // Check each element in path for shadow roots
18683
19286
  for (var i = 0; i < path.length; i++) {
@@ -19429,7 +20032,7 @@
19429
20032
  return;
19430
20033
  }
19431
20034
 
19432
- if (this._rageClickTracker.isRageClick(ev['pageX'], ev['pageY'], currentRageClickConfig)) {
20035
+ if (this._rageClickTracker.isRageClick(ev, currentRageClickConfig)) {
19433
20036
  this.trackDomEvent(ev, MP_EV_RAGE_CLICK);
19434
20037
  }
19435
20038
  }.bind(this);
@@ -21203,8 +21806,6 @@
21203
21806
  var INIT_MODULE = 0;
21204
21807
  var INIT_SNIPPET = 1;
21205
21808
 
21206
- var IDENTITY_FUNC = function(x) {return x;};
21207
-
21208
21809
  /** @const */ var PRIMARY_INSTANCE_NAME = 'mixpanel';
21209
21810
  /** @const */ var PAYLOAD_TYPE_BASE64 = 'base64';
21210
21811
  /** @const */ var PAYLOAD_TYPE_JSON = 'json';
@@ -21298,6 +21899,7 @@
21298
21899
  'record_block_selector': 'img, video, audio',
21299
21900
  'record_canvas': false,
21300
21901
  'record_collect_fonts': false,
21902
+ 'record_console': true,
21301
21903
  'record_heatmap_data': false,
21302
21904
  'record_idle_timeout_ms': 30 * 60 * 1000, // 30 minutes
21303
21905
  'record_mask_text_class': new RegExp('^(mp-mask|fs-mask|amp-mask|rr-mask|ph-mask)$'),
@@ -21369,6 +21971,17 @@
21369
21971
  // global debug to be true
21370
21972
  Config.DEBUG = Config.DEBUG || instance.get_config('debug');
21371
21973
 
21974
+ var source = init_type === INIT_MODULE ? 'module' : 'snippet';
21975
+ win.dispatchEvent(new win.CustomEvent('$mp_sdk_to_extension_event', {
21976
+ 'detail': {
21977
+ 'instance': instance,
21978
+ 'source': source,
21979
+ 'token': token,
21980
+ 'name': name,
21981
+ 'info': _.info
21982
+ }
21983
+ }));
21984
+
21372
21985
  // if target is not defined, we called init after the lib already
21373
21986
  // loaded, so there won't be an array of things to execute
21374
21987
  if (!_.isUndefined(target) && _.isArray(target)) {
@@ -21439,6 +22052,8 @@
21439
22052
  }
21440
22053
  }
21441
22054
 
22055
+ this.hooks = {};
22056
+
21442
22057
  this.set_config(_.extend({}, DEFAULT_CONFIG, variable_features, config, {
21443
22058
  'name': name,
21444
22059
  'token': token,
@@ -22039,7 +22654,12 @@
22039
22654
  );
22040
22655
  }, this),
22041
22656
  beforeSendHook: _.bind(function(item) {
22042
- return this._run_hook('before_send_' + attrs.type, item);
22657
+ var ret = this._run_hook('before_send_' + attrs.type, item);
22658
+ if (ret) {
22659
+ return ret[0];
22660
+ } else {
22661
+ return null;
22662
+ }
22043
22663
  }, this),
22044
22664
  stopAllBatchingFunc: _.bind(this.stop_batch_senders, this),
22045
22665
  usePersistence: true,
@@ -22132,6 +22752,9 @@
22132
22752
  var send_request_immediately = _.bind(function() {
22133
22753
  if (!send_request_options.skip_hooks) {
22134
22754
  truncated_data = this._run_hook('before_send_' + options.type, truncated_data);
22755
+ if (truncated_data) {
22756
+ truncated_data = truncated_data[0];
22757
+ }
22135
22758
  }
22136
22759
  if (truncated_data) {
22137
22760
  console$1.log('MIXPANEL REQUEST:');
@@ -22186,6 +22809,17 @@
22186
22809
  * with the tracking payload sent to the API server is returned; otherwise false.
22187
22810
  */
22188
22811
  MixpanelLib.prototype.track = addOptOutCheckMixpanelLib(function(event_name, properties, options, callback) {
22812
+ var ret;
22813
+ if (!(options && options.skip_hooks)) {
22814
+ ret = this._run_hook('before_track', event_name, properties);
22815
+ if (ret === null) {
22816
+ return;
22817
+ } else {
22818
+ event_name = ret[0];
22819
+ properties = ret[1];
22820
+ }
22821
+ }
22822
+
22189
22823
  if (!callback && typeof options === 'function') {
22190
22824
  callback = options;
22191
22825
  options = null;
@@ -22255,7 +22889,7 @@
22255
22889
  'event': event_name,
22256
22890
  'properties': properties
22257
22891
  };
22258
- var ret = this._track_or_batch({
22892
+ ret = this._track_or_batch({
22259
22893
  type: 'events',
22260
22894
  data: data,
22261
22895
  endpoint: this.get_api_host('events') + '/' + this.get_config('api_routes')['track'],
@@ -22601,6 +23235,14 @@
22601
23235
  * @param {boolean} [days_or_options.persistent=true] - whether to put in persistent storage (cookie/localStorage)
22602
23236
  */
22603
23237
  MixpanelLib.prototype.register = function(props, days_or_options) {
23238
+ var ret = this._run_hook('before_register', props, days_or_options);
23239
+ if (ret === null) {
23240
+ return;
23241
+ } else {
23242
+ props = ret[0];
23243
+ days_or_options = ret[1];
23244
+ }
23245
+
22604
23246
  var options = options_for_register(days_or_options);
22605
23247
  if (options['persistent']) {
22606
23248
  this['persistence'].register(props, options['days']);
@@ -22637,6 +23279,15 @@
22637
23279
  * @param {boolean} [days_or_options.persistent=true] - whether to put in persistent storage (cookie/localStorage)
22638
23280
  */
22639
23281
  MixpanelLib.prototype.register_once = function(props, default_value, days_or_options) {
23282
+ var ret = this._run_hook('before_register_once', props, default_value, days_or_options);
23283
+ if (ret === null) {
23284
+ return;
23285
+ } else {
23286
+ props = ret[0];
23287
+ default_value = ret[1];
23288
+ days_or_options = ret[2];
23289
+ }
23290
+
22640
23291
  var options = options_for_register(days_or_options);
22641
23292
  if (options['persistent']) {
22642
23293
  this['persistence'].register_once(props, default_value, options['days']);
@@ -22660,6 +23311,14 @@
22660
23311
  * @param {boolean} [options.persistent=true] - whether to look in persistent storage (cookie/localStorage)
22661
23312
  */
22662
23313
  MixpanelLib.prototype.unregister = function(property, options) {
23314
+ var ret = this._run_hook('before_unregister', property, options);
23315
+ if (ret === null) {
23316
+ return;
23317
+ } else {
23318
+ property = ret[0];
23319
+ options = ret[1];
23320
+ }
23321
+
22663
23322
  options = options_for_register(options);
22664
23323
  if (options['persistent']) {
22665
23324
  this['persistence'].unregister(property);
@@ -22708,6 +23367,13 @@
22708
23367
  // _set_once_callback:function A callback to be run if and when the People set_once queue is flushed
22709
23368
  // _union_callback:function A callback to be run if and when the People union queue is flushed
22710
23369
  // _unset_callback:function A callback to be run if and when the People unset queue is flushed
23370
+ var ret = this._run_hook('before_identify', new_distinct_id);
23371
+
23372
+ if (ret === null) {
23373
+ return -1;
23374
+ } else {
23375
+ new_distinct_id = ret[0];
23376
+ }
22711
23377
 
22712
23378
  var previous_distinct_id = this.get_distinct_id();
22713
23379
  if (new_distinct_id && previous_distinct_id !== new_distinct_id) {
@@ -23032,6 +23698,25 @@
23032
23698
  if (('autocapture' in config || 'record_heatmap_data' in config) && this.autocapture) {
23033
23699
  this.autocapture.init();
23034
23700
  }
23701
+
23702
+ if (_.isObject(config['hooks'])) {
23703
+ this.hooks = {};
23704
+ _.each(config['hooks'], function(hook_value, hook_name) {
23705
+ if (_.isFunction(hook_value)) {
23706
+ this.hooks[hook_name] = [hook_value];
23707
+ } else if (_.isArray(hook_value)) {
23708
+ this.hooks[hook_name] = [];
23709
+ for (var i = 0; i < hook_value.length; i++) {
23710
+ if (!_.isFunction(hook_value[i])) {
23711
+ console$1.critical('Invalid hook added. Hook is not a function');
23712
+ }
23713
+ this.hooks[hook_name].push(hook_value[i]);
23714
+ }
23715
+ } else {
23716
+ console$1.critical('Invalid hooks added. Ensure that the hook values passed into config.hooks are functions or arrays of functions.');
23717
+ }
23718
+ }, this);
23719
+ }
23035
23720
  }
23036
23721
  };
23037
23722
 
@@ -23049,12 +23734,26 @@
23049
23734
  * @returns {any|null} return value of user-provided hook, or null if nothing was returned
23050
23735
  */
23051
23736
  MixpanelLib.prototype._run_hook = function(hook_name) {
23052
- var ret = (this['config']['hooks'][hook_name] || IDENTITY_FUNC).apply(this, slice.call(arguments, 1));
23053
- if (typeof ret === 'undefined') {
23054
- this.report_error(hook_name + ' hook did not return a value');
23055
- ret = null;
23056
- }
23057
- return ret;
23737
+ var hook_data = slice.call(arguments, 1);
23738
+ _.each(this.hooks[hook_name], function(hook) {
23739
+ if (hook_data === null) {
23740
+ return null;
23741
+ }
23742
+
23743
+ var ret = hook.apply(this, hook_data);
23744
+
23745
+ if (typeof ret === 'undefined') {
23746
+ this.report_error(hook_name + ' hook did not return a valid value');
23747
+ hook_data = null;
23748
+ } else {
23749
+ if (!_.isArray(ret)) {
23750
+ ret = [ret];
23751
+ }
23752
+ hook_data.splice.apply(hook_data, [0, ret.length].concat(ret));
23753
+ }
23754
+ }, this);
23755
+
23756
+ return hook_data;
23058
23757
  };
23059
23758
 
23060
23759
  /**
@@ -23365,6 +24064,25 @@
23365
24064
  }
23366
24065
  };
23367
24066
 
24067
+ MixpanelLib.prototype.add_hook = function(hook_name, hook_fn) {
24068
+ if (!this.hooks[hook_name]) {
24069
+ this.hooks[hook_name] = [];
24070
+ }
24071
+ this.hooks[hook_name].push(hook_fn);
24072
+ };
24073
+
24074
+ MixpanelLib.prototype.remove_hook = function(hook_name, hook_fn) {
24075
+ var fn_index;
24076
+ if (this.hooks[hook_name]) {
24077
+ fn_index = this.hooks[hook_name].indexOf(hook_fn);
24078
+ if (fn_index !== -1) {
24079
+ this.hooks[hook_name].splice(fn_index, 1);
24080
+ } else {
24081
+ console$1.log('remove_hook failed. Matching hook was not found');
24082
+ }
24083
+ }
24084
+ };
24085
+
23368
24086
  // EXPORTS (for closure compiler)
23369
24087
 
23370
24088
  // MixpanelLib Exports
@@ -23397,6 +24115,8 @@
23397
24115
  MixpanelLib.prototype['set_group'] = MixpanelLib.prototype.set_group;
23398
24116
  MixpanelLib.prototype['add_group'] = MixpanelLib.prototype.add_group;
23399
24117
  MixpanelLib.prototype['remove_group'] = MixpanelLib.prototype.remove_group;
24118
+ MixpanelLib.prototype['add_hook'] = MixpanelLib.prototype.add_hook;
24119
+ MixpanelLib.prototype['remove_hook'] = MixpanelLib.prototype.remove_hook;
23400
24120
  MixpanelLib.prototype['track_with_groups'] = MixpanelLib.prototype.track_with_groups;
23401
24121
  MixpanelLib.prototype['start_batch_senders'] = MixpanelLib.prototype.start_batch_senders;
23402
24122
  MixpanelLib.prototype['stop_batch_senders'] = MixpanelLib.prototype.stop_batch_senders;