userlens-session-recorder 2.0.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.js CHANGED
@@ -20673,55 +20673,48 @@ const uploadSessionEvents = async (args) => {
20673
20673
  return "ok";
20674
20674
  };
20675
20675
 
20676
- var _SessionRecorder_instances, _SessionRecorder_trackEventsThrottled, _SessionRecorder_uploading, _SessionRecorder_uploadingMaxTs, _SessionRecorder_log, _SessionRecorder_initRecorder, _SessionRecorder_isUserInteraction, _SessionRecorder_handleEvent, _SessionRecorder_resetSession, _SessionRecorder_createSession, _SessionRecorder_handlePageHide, _SessionRecorder_initListeners, _SessionRecorder_throttle, _SessionRecorder_trackEvents, _SessionRecorder_clearEvents;
20676
+ var _SessionRecorder_instances, _SessionRecorder_uploading, _SessionRecorder_uploadingMaxTs, _SessionRecorder_bufferTimer, _SessionRecorder_log, _SessionRecorder_initRecorder, _SessionRecorder_isUserInteraction, _SessionRecorder_handleEvent, _SessionRecorder_armBufferTimer, _SessionRecorder_flushBuffer, _SessionRecorder_resetSession, _SessionRecorder_createSession, _SessionRecorder_handlePageHide, _SessionRecorder_initListeners, _SessionRecorder_trackEvents, _SessionRecorder_clearEvents;
20677
+ const BUFFER_TIMEOUT_MS = 2000;
20678
+ const MAX_BUFFER_BYTES = 900 * 1024;
20679
+ function estimateEventSize(event) {
20680
+ try {
20681
+ return JSON.stringify(event).length;
20682
+ }
20683
+ catch {
20684
+ return 0;
20685
+ }
20686
+ }
20677
20687
  class SessionRecorder {
20678
20688
  constructor(config) {
20679
20689
  var _a, _b, _c;
20680
20690
  _SessionRecorder_instances.add(this);
20681
20691
  this.sessionEvents = [];
20692
+ this.bufferBytes = 0;
20682
20693
  this.rrwebStop = null;
20683
20694
  this.debug = false;
20684
- _SessionRecorder_trackEventsThrottled.set(this, void 0);
20685
20695
  _SessionRecorder_uploading.set(this, false);
20686
20696
  _SessionRecorder_uploadingMaxTs.set(this, 0);
20697
+ _SessionRecorder_bufferTimer.set(this, null);
20687
20698
  _SessionRecorder_handlePageHide.set(this, () => {
20688
20699
  try {
20689
20700
  if (this.sessionEvents.length === 0)
20690
20701
  return;
20691
- let toUpload;
20702
+ let events;
20692
20703
  if (__classPrivateFieldGet(this, _SessionRecorder_uploading, "f") && __classPrivateFieldGet(this, _SessionRecorder_uploadingMaxTs, "f") > 0) {
20693
- toUpload = this.sessionEvents.filter((e) => e.timestamp > __classPrivateFieldGet(this, _SessionRecorder_uploadingMaxTs, "f"));
20704
+ events = this.sessionEvents.filter((e) => e.timestamp > __classPrivateFieldGet(this, _SessionRecorder_uploadingMaxTs, "f"));
20694
20705
  }
20695
20706
  else {
20696
- toUpload = [...this.sessionEvents];
20707
+ events = [...this.sessionEvents];
20697
20708
  }
20698
- if (toUpload.length === 0)
20709
+ if (events.length === 0)
20699
20710
  return;
20700
- let events;
20701
- if (toUpload[0].type !== 4) {
20702
- let snapshotPair = [];
20703
- for (let i = this.sessionEvents.length - 2; i >= 0; i--) {
20704
- if (this.sessionEvents[i].type === 4 &&
20705
- this.sessionEvents[i + 1].type === 2) {
20706
- snapshotPair = [
20707
- this.sessionEvents[i],
20708
- this.sessionEvents[i + 1],
20709
- ];
20710
- break;
20711
- }
20712
- }
20713
- events = [...snapshotPair, ...toUpload];
20714
- }
20715
- else {
20716
- events = toUpload;
20717
- }
20718
20711
  const state = readSessionState();
20719
20712
  if (!state)
20720
20713
  return;
20721
20714
  const chunk_seq = __classPrivateFieldGet(this, _SessionRecorder_uploading, "f") ? state.chunk_seq + 1 : state.chunk_seq;
20722
20715
  writeSessionState({ ...state, chunk_seq: chunk_seq + 1 });
20723
- const start_ts_ms = toUpload[0].timestamp;
20724
- const end_ts_ms = toUpload[toUpload.length - 1].timestamp;
20716
+ const start_ts_ms = events[0].timestamp;
20717
+ const end_ts_ms = events[events.length - 1].timestamp;
20725
20718
  uploadSessionEvents({
20726
20719
  user_id: this.userId,
20727
20720
  session_uuid: this.sessionUuid,
@@ -20733,6 +20726,7 @@ class SessionRecorder {
20733
20726
  keepalive: true,
20734
20727
  }).catch(() => { });
20735
20728
  this.sessionEvents = [];
20729
+ this.bufferBytes = 0;
20736
20730
  }
20737
20731
  catch (err) {
20738
20732
  __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_log).call(this, "Page hide handling failed", err);
@@ -20765,15 +20759,12 @@ class SessionRecorder {
20765
20759
  saveWriteCode(config.WRITE_CODE);
20766
20760
  this.userId = config.userId;
20767
20761
  const { recordingOptions = {} } = config;
20768
- const { TIMEOUT = 30 * 60 * 1000, BUFFER_SIZE = 10, maskingOptions = ["passwords"], recordCrossOriginIframes = false, } = recordingOptions;
20762
+ const { TIMEOUT = 30 * 60 * 1000, BUFFER_SIZE = 30, maskingOptions = ["passwords"], recordCrossOriginIframes = false, } = recordingOptions;
20769
20763
  this.TIMEOUT = TIMEOUT;
20770
20764
  this.BUFFER_SIZE = BUFFER_SIZE;
20771
20765
  this.maskingOptions = maskingOptions;
20772
20766
  this.recordCrossOriginIframes = recordCrossOriginIframes;
20773
20767
  this.sessionEvents = [];
20774
- __classPrivateFieldSet(this, _SessionRecorder_trackEventsThrottled, __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_throttle).call(this, () => {
20775
- __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_trackEvents).call(this);
20776
- }, 5000), "f");
20777
20768
  __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_initRecorder).call(this);
20778
20769
  }
20779
20770
  catch (err) {
@@ -20800,7 +20791,7 @@ class SessionRecorder {
20800
20791
  }
20801
20792
  }
20802
20793
  }
20803
- _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploading = new WeakMap(), _SessionRecorder_uploadingMaxTs = new WeakMap(), _SessionRecorder_handlePageHide = new WeakMap(), _SessionRecorder_instances = new WeakSet(), _SessionRecorder_log = function _SessionRecorder_log(message, error) {
20794
+ _SessionRecorder_uploading = new WeakMap(), _SessionRecorder_uploadingMaxTs = new WeakMap(), _SessionRecorder_bufferTimer = new WeakMap(), _SessionRecorder_handlePageHide = new WeakMap(), _SessionRecorder_instances = new WeakSet(), _SessionRecorder_log = function _SessionRecorder_log(message, error) {
20804
20795
  if (!this.debug)
20805
20796
  return;
20806
20797
  if (error) {
@@ -20823,6 +20814,7 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
20823
20814
  },
20824
20815
  recordCrossOriginIframes: this.recordCrossOriginIframes,
20825
20816
  plugins: [getRecordConsolePlugin()],
20817
+ checkoutEveryNth: 100,
20826
20818
  });
20827
20819
  __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_initListeners).call(this);
20828
20820
  }, _SessionRecorder_isUserInteraction = function _SessionRecorder_isUserInteraction(event) {
@@ -20833,7 +20825,6 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
20833
20825
  }
20834
20826
  return false;
20835
20827
  }, _SessionRecorder_handleEvent = function _SessionRecorder_handleEvent(event, _isCheckout) {
20836
- var _a;
20837
20828
  try {
20838
20829
  const now = Date.now();
20839
20830
  const state = readSessionState();
@@ -20848,13 +20839,29 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
20848
20839
  }
20849
20840
  }
20850
20841
  this.sessionEvents.push(event);
20851
- if (this.sessionEvents.length >= this.BUFFER_SIZE) {
20852
- (_a = __classPrivateFieldGet(this, _SessionRecorder_trackEventsThrottled, "f")) === null || _a === void 0 ? void 0 : _a.call(this);
20842
+ this.bufferBytes += estimateEventSize(event);
20843
+ __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_armBufferTimer).call(this);
20844
+ if (this.bufferBytes >= MAX_BUFFER_BYTES) {
20845
+ __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_flushBuffer).call(this);
20853
20846
  }
20854
20847
  }
20855
20848
  catch (err) {
20856
20849
  __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_log).call(this, "Event handling failed", err);
20857
20850
  }
20851
+ }, _SessionRecorder_armBufferTimer = function _SessionRecorder_armBufferTimer() {
20852
+ if (__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f") !== null) {
20853
+ clearTimeout(__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f"));
20854
+ }
20855
+ __classPrivateFieldSet(this, _SessionRecorder_bufferTimer, setTimeout(() => {
20856
+ __classPrivateFieldSet(this, _SessionRecorder_bufferTimer, null, "f");
20857
+ __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_flushBuffer).call(this);
20858
+ }, BUFFER_TIMEOUT_MS), "f");
20859
+ }, _SessionRecorder_flushBuffer = function _SessionRecorder_flushBuffer() {
20860
+ if (__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f") !== null) {
20861
+ clearTimeout(__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f"));
20862
+ __classPrivateFieldSet(this, _SessionRecorder_bufferTimer, null, "f");
20863
+ }
20864
+ void __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_trackEvents).call(this);
20858
20865
  }, _SessionRecorder_resetSession = function _SessionRecorder_resetSession() {
20859
20866
  clearSessionState();
20860
20867
  __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_clearEvents).call(this);
@@ -20879,15 +20886,6 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
20879
20886
  }
20880
20887
  }, _SessionRecorder_initListeners = function _SessionRecorder_initListeners() {
20881
20888
  window.addEventListener("pagehide", __classPrivateFieldGet(this, _SessionRecorder_handlePageHide, "f"));
20882
- }, _SessionRecorder_throttle = function _SessionRecorder_throttle(func, delay) {
20883
- let lastCall = 0;
20884
- return (...args) => {
20885
- const now = Date.now();
20886
- if (now - lastCall >= delay) {
20887
- lastCall = now;
20888
- func.apply(this, args);
20889
- }
20890
- };
20891
20889
  }, _SessionRecorder_trackEvents = async function _SessionRecorder_trackEvents() {
20892
20890
  if (__classPrivateFieldGet(this, _SessionRecorder_uploading, "f"))
20893
20891
  return;
@@ -20915,17 +20913,9 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
20915
20913
  initial_url: chunk_seq === 0 ? state.initial_url : undefined,
20916
20914
  events,
20917
20915
  });
20918
- const remaining = this.sessionEvents.slice(snapshot_count);
20919
- this.sessionEvents = [];
20920
- try {
20921
- takeFullSnapshot(true);
20922
- }
20923
- catch (err) {
20924
- __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_log).call(this, "takeFullSnapshot failed", err);
20925
- }
20926
- if (remaining.length > 0) {
20927
- this.sessionEvents.push(...remaining);
20928
- }
20916
+ const removedBytes = events.reduce((sum, e) => sum + estimateEventSize(e), 0);
20917
+ this.sessionEvents = this.sessionEvents.slice(snapshot_count);
20918
+ this.bufferBytes = Math.max(0, this.bufferBytes - removedBytes);
20929
20919
  const after = readSessionState();
20930
20920
  if (after &&
20931
20921
  after.session_uuid === state.session_uuid &&
@@ -20942,6 +20932,11 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
20942
20932
  }
20943
20933
  }, _SessionRecorder_clearEvents = function _SessionRecorder_clearEvents() {
20944
20934
  this.sessionEvents = [];
20935
+ this.bufferBytes = 0;
20936
+ if (__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f") !== null) {
20937
+ clearTimeout(__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f"));
20938
+ __classPrivateFieldSet(this, _SessionRecorder_bufferTimer, null, "f");
20939
+ }
20945
20940
  };
20946
20941
 
20947
20942
  exports.default = SessionRecorder;