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.d.ts CHANGED
@@ -8,6 +8,7 @@ export default class SessionRecorder {
8
8
  private maskingOptions;
9
9
  private sessionUuid;
10
10
  private sessionEvents;
11
+ private bufferBytes;
11
12
  private rrwebStop;
12
13
  private debug;
13
14
  private recordCrossOriginIframes;
package/dist/index.esm.js CHANGED
@@ -20669,21 +20669,41 @@ const uploadSessionEvents = async (args) => {
20669
20669
  return "ok";
20670
20670
  };
20671
20671
 
20672
- 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;
20672
+ 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;
20673
+ const BUFFER_TIMEOUT_MS = 2000;
20674
+ const MAX_BUFFER_BYTES = 900 * 1024;
20675
+ function estimateEventSize(event) {
20676
+ try {
20677
+ return JSON.stringify(event).length;
20678
+ }
20679
+ catch {
20680
+ return 0;
20681
+ }
20682
+ }
20673
20683
  class SessionRecorder {
20674
20684
  constructor(config) {
20675
20685
  var _a, _b, _c;
20676
20686
  _SessionRecorder_instances.add(this);
20677
20687
  this.sessionEvents = [];
20688
+ this.bufferBytes = 0;
20678
20689
  this.rrwebStop = null;
20679
20690
  this.debug = false;
20680
- _SessionRecorder_trackEventsThrottled.set(this, void 0);
20681
20691
  _SessionRecorder_uploading.set(this, false);
20692
+ _SessionRecorder_uploadingMaxTs.set(this, 0);
20693
+ _SessionRecorder_bufferTimer.set(this, null);
20682
20694
  _SessionRecorder_handlePageHide.set(this, () => {
20683
20695
  try {
20684
20696
  if (this.sessionEvents.length === 0)
20685
20697
  return;
20686
- const events = [...this.sessionEvents];
20698
+ let events;
20699
+ if (__classPrivateFieldGet(this, _SessionRecorder_uploading, "f") && __classPrivateFieldGet(this, _SessionRecorder_uploadingMaxTs, "f") > 0) {
20700
+ events = this.sessionEvents.filter((e) => e.timestamp > __classPrivateFieldGet(this, _SessionRecorder_uploadingMaxTs, "f"));
20701
+ }
20702
+ else {
20703
+ events = [...this.sessionEvents];
20704
+ }
20705
+ if (events.length === 0)
20706
+ return;
20687
20707
  const state = readSessionState();
20688
20708
  if (!state)
20689
20709
  return;
@@ -20702,6 +20722,7 @@ class SessionRecorder {
20702
20722
  keepalive: true,
20703
20723
  }).catch(() => { });
20704
20724
  this.sessionEvents = [];
20725
+ this.bufferBytes = 0;
20705
20726
  }
20706
20727
  catch (err) {
20707
20728
  __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_log).call(this, "Page hide handling failed", err);
@@ -20734,15 +20755,12 @@ class SessionRecorder {
20734
20755
  saveWriteCode(config.WRITE_CODE);
20735
20756
  this.userId = config.userId;
20736
20757
  const { recordingOptions = {} } = config;
20737
- const { TIMEOUT = 30 * 60 * 1000, BUFFER_SIZE = 10, maskingOptions = ["passwords"], recordCrossOriginIframes = false, } = recordingOptions;
20758
+ const { TIMEOUT = 30 * 60 * 1000, BUFFER_SIZE = 30, maskingOptions = ["passwords"], recordCrossOriginIframes = false, } = recordingOptions;
20738
20759
  this.TIMEOUT = TIMEOUT;
20739
20760
  this.BUFFER_SIZE = BUFFER_SIZE;
20740
20761
  this.maskingOptions = maskingOptions;
20741
20762
  this.recordCrossOriginIframes = recordCrossOriginIframes;
20742
20763
  this.sessionEvents = [];
20743
- __classPrivateFieldSet(this, _SessionRecorder_trackEventsThrottled, __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_throttle).call(this, () => {
20744
- __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_trackEvents).call(this);
20745
- }, 5000), "f");
20746
20764
  __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_initRecorder).call(this);
20747
20765
  }
20748
20766
  catch (err) {
@@ -20769,7 +20787,7 @@ class SessionRecorder {
20769
20787
  }
20770
20788
  }
20771
20789
  }
20772
- _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploading = new WeakMap(), _SessionRecorder_handlePageHide = new WeakMap(), _SessionRecorder_instances = new WeakSet(), _SessionRecorder_log = function _SessionRecorder_log(message, error) {
20790
+ _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) {
20773
20791
  if (!this.debug)
20774
20792
  return;
20775
20793
  if (error) {
@@ -20803,7 +20821,6 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
20803
20821
  }
20804
20822
  return false;
20805
20823
  }, _SessionRecorder_handleEvent = function _SessionRecorder_handleEvent(event, _isCheckout) {
20806
- var _a;
20807
20824
  try {
20808
20825
  const now = Date.now();
20809
20826
  const state = readSessionState();
@@ -20818,13 +20835,29 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
20818
20835
  }
20819
20836
  }
20820
20837
  this.sessionEvents.push(event);
20821
- if (this.sessionEvents.length >= this.BUFFER_SIZE) {
20822
- (_a = __classPrivateFieldGet(this, _SessionRecorder_trackEventsThrottled, "f")) === null || _a === void 0 ? void 0 : _a.call(this);
20838
+ this.bufferBytes += estimateEventSize(event);
20839
+ __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_armBufferTimer).call(this);
20840
+ if (this.bufferBytes >= MAX_BUFFER_BYTES) {
20841
+ __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_flushBuffer).call(this);
20823
20842
  }
20824
20843
  }
20825
20844
  catch (err) {
20826
20845
  __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_log).call(this, "Event handling failed", err);
20827
20846
  }
20847
+ }, _SessionRecorder_armBufferTimer = function _SessionRecorder_armBufferTimer() {
20848
+ if (__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f") !== null) {
20849
+ clearTimeout(__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f"));
20850
+ }
20851
+ __classPrivateFieldSet(this, _SessionRecorder_bufferTimer, setTimeout(() => {
20852
+ __classPrivateFieldSet(this, _SessionRecorder_bufferTimer, null, "f");
20853
+ __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_flushBuffer).call(this);
20854
+ }, BUFFER_TIMEOUT_MS), "f");
20855
+ }, _SessionRecorder_flushBuffer = function _SessionRecorder_flushBuffer() {
20856
+ if (__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f") !== null) {
20857
+ clearTimeout(__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f"));
20858
+ __classPrivateFieldSet(this, _SessionRecorder_bufferTimer, null, "f");
20859
+ }
20860
+ void __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_trackEvents).call(this);
20828
20861
  }, _SessionRecorder_resetSession = function _SessionRecorder_resetSession() {
20829
20862
  clearSessionState();
20830
20863
  __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_clearEvents).call(this);
@@ -20849,15 +20882,6 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
20849
20882
  }
20850
20883
  }, _SessionRecorder_initListeners = function _SessionRecorder_initListeners() {
20851
20884
  window.addEventListener("pagehide", __classPrivateFieldGet(this, _SessionRecorder_handlePageHide, "f"));
20852
- }, _SessionRecorder_throttle = function _SessionRecorder_throttle(func, delay) {
20853
- let lastCall = 0;
20854
- return (...args) => {
20855
- const now = Date.now();
20856
- if (now - lastCall >= delay) {
20857
- lastCall = now;
20858
- func.apply(this, args);
20859
- }
20860
- };
20861
20885
  }, _SessionRecorder_trackEvents = async function _SessionRecorder_trackEvents() {
20862
20886
  if (__classPrivateFieldGet(this, _SessionRecorder_uploading, "f"))
20863
20887
  return;
@@ -20867,6 +20891,7 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
20867
20891
  try {
20868
20892
  const events = [...this.sessionEvents];
20869
20893
  const snapshot_count = events.length;
20894
+ __classPrivateFieldSet(this, _SessionRecorder_uploadingMaxTs, events[events.length - 1].timestamp, "f");
20870
20895
  const start_ts_ms = events[0].timestamp;
20871
20896
  const end_ts_ms = events[events.length - 1].timestamp;
20872
20897
  const state = readSessionState();
@@ -20884,10 +20909,14 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
20884
20909
  initial_url: chunk_seq === 0 ? state.initial_url : undefined,
20885
20910
  events,
20886
20911
  });
20912
+ const removedBytes = events.reduce((sum, e) => sum + estimateEventSize(e), 0);
20887
20913
  this.sessionEvents = this.sessionEvents.slice(snapshot_count);
20914
+ this.bufferBytes = Math.max(0, this.bufferBytes - removedBytes);
20888
20915
  const after = readSessionState();
20889
- if (after && after.session_uuid === state.session_uuid) {
20890
- writeSessionState({ ...after, chunk_seq: after.chunk_seq + 1 });
20916
+ if (after &&
20917
+ after.session_uuid === state.session_uuid &&
20918
+ after.chunk_seq === chunk_seq) {
20919
+ writeSessionState({ ...after, chunk_seq: chunk_seq + 1 });
20891
20920
  }
20892
20921
  }
20893
20922
  catch (err) {
@@ -20895,9 +20924,15 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
20895
20924
  }
20896
20925
  finally {
20897
20926
  __classPrivateFieldSet(this, _SessionRecorder_uploading, false, "f");
20927
+ __classPrivateFieldSet(this, _SessionRecorder_uploadingMaxTs, 0, "f");
20898
20928
  }
20899
20929
  }, _SessionRecorder_clearEvents = function _SessionRecorder_clearEvents() {
20900
20930
  this.sessionEvents = [];
20931
+ this.bufferBytes = 0;
20932
+ if (__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f") !== null) {
20933
+ clearTimeout(__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f"));
20934
+ __classPrivateFieldSet(this, _SessionRecorder_bufferTimer, null, "f");
20935
+ }
20901
20936
  };
20902
20937
 
20903
20938
  export { SessionRecorder as default };