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.
@@ -20,6 +20,7 @@ declare class SessionRecorder {
20
20
  private maskingOptions;
21
21
  private sessionUuid;
22
22
  private sessionEvents;
23
+ private bufferBytes;
23
24
  private rrwebStop;
24
25
  private debug;
25
26
  private recordCrossOriginIframes;
@@ -20675,55 +20675,48 @@
20675
20675
  return "ok";
20676
20676
  };
20677
20677
 
20678
- 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;
20678
+ 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;
20679
+ const BUFFER_TIMEOUT_MS = 2000;
20680
+ const MAX_BUFFER_BYTES = 900 * 1024;
20681
+ function estimateEventSize(event) {
20682
+ try {
20683
+ return JSON.stringify(event).length;
20684
+ }
20685
+ catch {
20686
+ return 0;
20687
+ }
20688
+ }
20679
20689
  class SessionRecorder {
20680
20690
  constructor(config) {
20681
20691
  var _a, _b, _c;
20682
20692
  _SessionRecorder_instances.add(this);
20683
20693
  this.sessionEvents = [];
20694
+ this.bufferBytes = 0;
20684
20695
  this.rrwebStop = null;
20685
20696
  this.debug = false;
20686
- _SessionRecorder_trackEventsThrottled.set(this, void 0);
20687
20697
  _SessionRecorder_uploading.set(this, false);
20688
20698
  _SessionRecorder_uploadingMaxTs.set(this, 0);
20699
+ _SessionRecorder_bufferTimer.set(this, null);
20689
20700
  _SessionRecorder_handlePageHide.set(this, () => {
20690
20701
  try {
20691
20702
  if (this.sessionEvents.length === 0)
20692
20703
  return;
20693
- let toUpload;
20704
+ let events;
20694
20705
  if (__classPrivateFieldGet(this, _SessionRecorder_uploading, "f") && __classPrivateFieldGet(this, _SessionRecorder_uploadingMaxTs, "f") > 0) {
20695
- toUpload = this.sessionEvents.filter((e) => e.timestamp > __classPrivateFieldGet(this, _SessionRecorder_uploadingMaxTs, "f"));
20706
+ events = this.sessionEvents.filter((e) => e.timestamp > __classPrivateFieldGet(this, _SessionRecorder_uploadingMaxTs, "f"));
20696
20707
  }
20697
20708
  else {
20698
- toUpload = [...this.sessionEvents];
20709
+ events = [...this.sessionEvents];
20699
20710
  }
20700
- if (toUpload.length === 0)
20711
+ if (events.length === 0)
20701
20712
  return;
20702
- let events;
20703
- if (toUpload[0].type !== 4) {
20704
- let snapshotPair = [];
20705
- for (let i = this.sessionEvents.length - 2; i >= 0; i--) {
20706
- if (this.sessionEvents[i].type === 4 &&
20707
- this.sessionEvents[i + 1].type === 2) {
20708
- snapshotPair = [
20709
- this.sessionEvents[i],
20710
- this.sessionEvents[i + 1],
20711
- ];
20712
- break;
20713
- }
20714
- }
20715
- events = [...snapshotPair, ...toUpload];
20716
- }
20717
- else {
20718
- events = toUpload;
20719
- }
20720
20713
  const state = readSessionState();
20721
20714
  if (!state)
20722
20715
  return;
20723
20716
  const chunk_seq = __classPrivateFieldGet(this, _SessionRecorder_uploading, "f") ? state.chunk_seq + 1 : state.chunk_seq;
20724
20717
  writeSessionState({ ...state, chunk_seq: chunk_seq + 1 });
20725
- const start_ts_ms = toUpload[0].timestamp;
20726
- const end_ts_ms = toUpload[toUpload.length - 1].timestamp;
20718
+ const start_ts_ms = events[0].timestamp;
20719
+ const end_ts_ms = events[events.length - 1].timestamp;
20727
20720
  uploadSessionEvents({
20728
20721
  user_id: this.userId,
20729
20722
  session_uuid: this.sessionUuid,
@@ -20735,6 +20728,7 @@
20735
20728
  keepalive: true,
20736
20729
  }).catch(() => { });
20737
20730
  this.sessionEvents = [];
20731
+ this.bufferBytes = 0;
20738
20732
  }
20739
20733
  catch (err) {
20740
20734
  __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_log).call(this, "Page hide handling failed", err);
@@ -20767,15 +20761,12 @@
20767
20761
  saveWriteCode(config.WRITE_CODE);
20768
20762
  this.userId = config.userId;
20769
20763
  const { recordingOptions = {} } = config;
20770
- const { TIMEOUT = 30 * 60 * 1000, BUFFER_SIZE = 10, maskingOptions = ["passwords"], recordCrossOriginIframes = false, } = recordingOptions;
20764
+ const { TIMEOUT = 30 * 60 * 1000, BUFFER_SIZE = 30, maskingOptions = ["passwords"], recordCrossOriginIframes = false, } = recordingOptions;
20771
20765
  this.TIMEOUT = TIMEOUT;
20772
20766
  this.BUFFER_SIZE = BUFFER_SIZE;
20773
20767
  this.maskingOptions = maskingOptions;
20774
20768
  this.recordCrossOriginIframes = recordCrossOriginIframes;
20775
20769
  this.sessionEvents = [];
20776
- __classPrivateFieldSet(this, _SessionRecorder_trackEventsThrottled, __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_throttle).call(this, () => {
20777
- __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_trackEvents).call(this);
20778
- }, 5000), "f");
20779
20770
  __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_initRecorder).call(this);
20780
20771
  }
20781
20772
  catch (err) {
@@ -20802,7 +20793,7 @@
20802
20793
  }
20803
20794
  }
20804
20795
  }
20805
- _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) {
20796
+ _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) {
20806
20797
  if (!this.debug)
20807
20798
  return;
20808
20799
  if (error) {
@@ -20825,6 +20816,7 @@
20825
20816
  },
20826
20817
  recordCrossOriginIframes: this.recordCrossOriginIframes,
20827
20818
  plugins: [getRecordConsolePlugin()],
20819
+ checkoutEveryNth: 100,
20828
20820
  });
20829
20821
  __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_initListeners).call(this);
20830
20822
  }, _SessionRecorder_isUserInteraction = function _SessionRecorder_isUserInteraction(event) {
@@ -20835,7 +20827,6 @@
20835
20827
  }
20836
20828
  return false;
20837
20829
  }, _SessionRecorder_handleEvent = function _SessionRecorder_handleEvent(event, _isCheckout) {
20838
- var _a;
20839
20830
  try {
20840
20831
  const now = Date.now();
20841
20832
  const state = readSessionState();
@@ -20850,13 +20841,29 @@
20850
20841
  }
20851
20842
  }
20852
20843
  this.sessionEvents.push(event);
20853
- if (this.sessionEvents.length >= this.BUFFER_SIZE) {
20854
- (_a = __classPrivateFieldGet(this, _SessionRecorder_trackEventsThrottled, "f")) === null || _a === void 0 ? void 0 : _a.call(this);
20844
+ this.bufferBytes += estimateEventSize(event);
20845
+ __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_armBufferTimer).call(this);
20846
+ if (this.bufferBytes >= MAX_BUFFER_BYTES) {
20847
+ __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_flushBuffer).call(this);
20855
20848
  }
20856
20849
  }
20857
20850
  catch (err) {
20858
20851
  __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_log).call(this, "Event handling failed", err);
20859
20852
  }
20853
+ }, _SessionRecorder_armBufferTimer = function _SessionRecorder_armBufferTimer() {
20854
+ if (__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f") !== null) {
20855
+ clearTimeout(__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f"));
20856
+ }
20857
+ __classPrivateFieldSet(this, _SessionRecorder_bufferTimer, setTimeout(() => {
20858
+ __classPrivateFieldSet(this, _SessionRecorder_bufferTimer, null, "f");
20859
+ __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_flushBuffer).call(this);
20860
+ }, BUFFER_TIMEOUT_MS), "f");
20861
+ }, _SessionRecorder_flushBuffer = function _SessionRecorder_flushBuffer() {
20862
+ if (__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f") !== null) {
20863
+ clearTimeout(__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f"));
20864
+ __classPrivateFieldSet(this, _SessionRecorder_bufferTimer, null, "f");
20865
+ }
20866
+ void __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_trackEvents).call(this);
20860
20867
  }, _SessionRecorder_resetSession = function _SessionRecorder_resetSession() {
20861
20868
  clearSessionState();
20862
20869
  __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_clearEvents).call(this);
@@ -20881,15 +20888,6 @@
20881
20888
  }
20882
20889
  }, _SessionRecorder_initListeners = function _SessionRecorder_initListeners() {
20883
20890
  window.addEventListener("pagehide", __classPrivateFieldGet(this, _SessionRecorder_handlePageHide, "f"));
20884
- }, _SessionRecorder_throttle = function _SessionRecorder_throttle(func, delay) {
20885
- let lastCall = 0;
20886
- return (...args) => {
20887
- const now = Date.now();
20888
- if (now - lastCall >= delay) {
20889
- lastCall = now;
20890
- func.apply(this, args);
20891
- }
20892
- };
20893
20891
  }, _SessionRecorder_trackEvents = async function _SessionRecorder_trackEvents() {
20894
20892
  if (__classPrivateFieldGet(this, _SessionRecorder_uploading, "f"))
20895
20893
  return;
@@ -20917,17 +20915,9 @@
20917
20915
  initial_url: chunk_seq === 0 ? state.initial_url : undefined,
20918
20916
  events,
20919
20917
  });
20920
- const remaining = this.sessionEvents.slice(snapshot_count);
20921
- this.sessionEvents = [];
20922
- try {
20923
- takeFullSnapshot(true);
20924
- }
20925
- catch (err) {
20926
- __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_log).call(this, "takeFullSnapshot failed", err);
20927
- }
20928
- if (remaining.length > 0) {
20929
- this.sessionEvents.push(...remaining);
20930
- }
20918
+ const removedBytes = events.reduce((sum, e) => sum + estimateEventSize(e), 0);
20919
+ this.sessionEvents = this.sessionEvents.slice(snapshot_count);
20920
+ this.bufferBytes = Math.max(0, this.bufferBytes - removedBytes);
20931
20921
  const after = readSessionState();
20932
20922
  if (after &&
20933
20923
  after.session_uuid === state.session_uuid &&
@@ -20944,6 +20934,11 @@
20944
20934
  }
20945
20935
  }, _SessionRecorder_clearEvents = function _SessionRecorder_clearEvents() {
20946
20936
  this.sessionEvents = [];
20937
+ this.bufferBytes = 0;
20938
+ if (__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f") !== null) {
20939
+ clearTimeout(__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f"));
20940
+ __classPrivateFieldSet(this, _SessionRecorder_bufferTimer, null, "f");
20941
+ }
20947
20942
  };
20948
20943
 
20949
20944
  exports.default = SessionRecorder;