userlens-session-recorder 2.0.0 → 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,21 +20673,41 @@ const uploadSessionEvents = async (args) => {
20673
20673
  return "ok";
20674
20674
  };
20675
20675
 
20676
- var _SessionRecorder_instances, _SessionRecorder_trackEventsThrottled, _SessionRecorder_uploading, _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);
20696
+ _SessionRecorder_uploadingMaxTs.set(this, 0);
20697
+ _SessionRecorder_bufferTimer.set(this, null);
20686
20698
  _SessionRecorder_handlePageHide.set(this, () => {
20687
20699
  try {
20688
20700
  if (this.sessionEvents.length === 0)
20689
20701
  return;
20690
- const events = [...this.sessionEvents];
20702
+ let events;
20703
+ if (__classPrivateFieldGet(this, _SessionRecorder_uploading, "f") && __classPrivateFieldGet(this, _SessionRecorder_uploadingMaxTs, "f") > 0) {
20704
+ events = this.sessionEvents.filter((e) => e.timestamp > __classPrivateFieldGet(this, _SessionRecorder_uploadingMaxTs, "f"));
20705
+ }
20706
+ else {
20707
+ events = [...this.sessionEvents];
20708
+ }
20709
+ if (events.length === 0)
20710
+ return;
20691
20711
  const state = readSessionState();
20692
20712
  if (!state)
20693
20713
  return;
@@ -20706,6 +20726,7 @@ class SessionRecorder {
20706
20726
  keepalive: true,
20707
20727
  }).catch(() => { });
20708
20728
  this.sessionEvents = [];
20729
+ this.bufferBytes = 0;
20709
20730
  }
20710
20731
  catch (err) {
20711
20732
  __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_log).call(this, "Page hide handling failed", err);
@@ -20738,15 +20759,12 @@ class SessionRecorder {
20738
20759
  saveWriteCode(config.WRITE_CODE);
20739
20760
  this.userId = config.userId;
20740
20761
  const { recordingOptions = {} } = config;
20741
- 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;
20742
20763
  this.TIMEOUT = TIMEOUT;
20743
20764
  this.BUFFER_SIZE = BUFFER_SIZE;
20744
20765
  this.maskingOptions = maskingOptions;
20745
20766
  this.recordCrossOriginIframes = recordCrossOriginIframes;
20746
20767
  this.sessionEvents = [];
20747
- __classPrivateFieldSet(this, _SessionRecorder_trackEventsThrottled, __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_throttle).call(this, () => {
20748
- __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_trackEvents).call(this);
20749
- }, 5000), "f");
20750
20768
  __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_initRecorder).call(this);
20751
20769
  }
20752
20770
  catch (err) {
@@ -20773,7 +20791,7 @@ class SessionRecorder {
20773
20791
  }
20774
20792
  }
20775
20793
  }
20776
- _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploading = 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) {
20777
20795
  if (!this.debug)
20778
20796
  return;
20779
20797
  if (error) {
@@ -20807,7 +20825,6 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
20807
20825
  }
20808
20826
  return false;
20809
20827
  }, _SessionRecorder_handleEvent = function _SessionRecorder_handleEvent(event, _isCheckout) {
20810
- var _a;
20811
20828
  try {
20812
20829
  const now = Date.now();
20813
20830
  const state = readSessionState();
@@ -20822,13 +20839,29 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
20822
20839
  }
20823
20840
  }
20824
20841
  this.sessionEvents.push(event);
20825
- if (this.sessionEvents.length >= this.BUFFER_SIZE) {
20826
- (_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);
20827
20846
  }
20828
20847
  }
20829
20848
  catch (err) {
20830
20849
  __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_log).call(this, "Event handling failed", err);
20831
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);
20832
20865
  }, _SessionRecorder_resetSession = function _SessionRecorder_resetSession() {
20833
20866
  clearSessionState();
20834
20867
  __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_clearEvents).call(this);
@@ -20853,15 +20886,6 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
20853
20886
  }
20854
20887
  }, _SessionRecorder_initListeners = function _SessionRecorder_initListeners() {
20855
20888
  window.addEventListener("pagehide", __classPrivateFieldGet(this, _SessionRecorder_handlePageHide, "f"));
20856
- }, _SessionRecorder_throttle = function _SessionRecorder_throttle(func, delay) {
20857
- let lastCall = 0;
20858
- return (...args) => {
20859
- const now = Date.now();
20860
- if (now - lastCall >= delay) {
20861
- lastCall = now;
20862
- func.apply(this, args);
20863
- }
20864
- };
20865
20889
  }, _SessionRecorder_trackEvents = async function _SessionRecorder_trackEvents() {
20866
20890
  if (__classPrivateFieldGet(this, _SessionRecorder_uploading, "f"))
20867
20891
  return;
@@ -20871,6 +20895,7 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
20871
20895
  try {
20872
20896
  const events = [...this.sessionEvents];
20873
20897
  const snapshot_count = events.length;
20898
+ __classPrivateFieldSet(this, _SessionRecorder_uploadingMaxTs, events[events.length - 1].timestamp, "f");
20874
20899
  const start_ts_ms = events[0].timestamp;
20875
20900
  const end_ts_ms = events[events.length - 1].timestamp;
20876
20901
  const state = readSessionState();
@@ -20888,10 +20913,14 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
20888
20913
  initial_url: chunk_seq === 0 ? state.initial_url : undefined,
20889
20914
  events,
20890
20915
  });
20916
+ const removedBytes = events.reduce((sum, e) => sum + estimateEventSize(e), 0);
20891
20917
  this.sessionEvents = this.sessionEvents.slice(snapshot_count);
20918
+ this.bufferBytes = Math.max(0, this.bufferBytes - removedBytes);
20892
20919
  const after = readSessionState();
20893
- if (after && after.session_uuid === state.session_uuid) {
20894
- writeSessionState({ ...after, chunk_seq: after.chunk_seq + 1 });
20920
+ if (after &&
20921
+ after.session_uuid === state.session_uuid &&
20922
+ after.chunk_seq === chunk_seq) {
20923
+ writeSessionState({ ...after, chunk_seq: chunk_seq + 1 });
20895
20924
  }
20896
20925
  }
20897
20926
  catch (err) {
@@ -20899,9 +20928,15 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
20899
20928
  }
20900
20929
  finally {
20901
20930
  __classPrivateFieldSet(this, _SessionRecorder_uploading, false, "f");
20931
+ __classPrivateFieldSet(this, _SessionRecorder_uploadingMaxTs, 0, "f");
20902
20932
  }
20903
20933
  }, _SessionRecorder_clearEvents = function _SessionRecorder_clearEvents() {
20904
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
+ }
20905
20940
  };
20906
20941
 
20907
20942
  exports.default = SessionRecorder;