userlens-session-recorder 2.0.1 → 2.1.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.
- package/dist/index.cjs.js +117 -75
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.esm.js +117 -75
- package/dist/index.esm.js.map +1 -1
- package/dist/types/index.d.ts +26 -2
- package/dist/userlens-session-recorder.umd.js +117 -75
- package/dist/userlens-session-recorder.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -20673,66 +20673,81 @@ const uploadSessionEvents = async (args) => {
|
|
|
20673
20673
|
return "ok";
|
|
20674
20674
|
};
|
|
20675
20675
|
|
|
20676
|
-
var _SessionRecorder_instances,
|
|
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
|
|
20702
|
+
let events;
|
|
20692
20703
|
if (__classPrivateFieldGet(this, _SessionRecorder_uploading, "f") && __classPrivateFieldGet(this, _SessionRecorder_uploadingMaxTs, "f") > 0) {
|
|
20693
|
-
|
|
20704
|
+
events = this.sessionEvents.filter((e) => e.timestamp > __classPrivateFieldGet(this, _SessionRecorder_uploadingMaxTs, "f"));
|
|
20694
20705
|
}
|
|
20695
20706
|
else {
|
|
20696
|
-
|
|
20707
|
+
events = [...this.sessionEvents];
|
|
20697
20708
|
}
|
|
20698
|
-
if (
|
|
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 =
|
|
20724
|
-
const end_ts_ms =
|
|
20725
|
-
|
|
20726
|
-
|
|
20727
|
-
|
|
20728
|
-
|
|
20729
|
-
|
|
20730
|
-
|
|
20731
|
-
|
|
20732
|
-
|
|
20733
|
-
|
|
20734
|
-
|
|
20716
|
+
const start_ts_ms = events[0].timestamp;
|
|
20717
|
+
const end_ts_ms = events[events.length - 1].timestamp;
|
|
20718
|
+
const initial_url = chunk_seq === 0 ? state.initial_url : undefined;
|
|
20719
|
+
const chunk_start_ts = new Date(start_ts_ms).toISOString();
|
|
20720
|
+
const chunk_end_ts = new Date(end_ts_ms).toISOString();
|
|
20721
|
+
if (this.mode === "manual") {
|
|
20722
|
+
try {
|
|
20723
|
+
void this.onEvents({
|
|
20724
|
+
session_uuid: this.sessionUuid,
|
|
20725
|
+
chunk_seq,
|
|
20726
|
+
chunk_start_ts,
|
|
20727
|
+
chunk_end_ts,
|
|
20728
|
+
initial_url,
|
|
20729
|
+
events,
|
|
20730
|
+
keepalive: true,
|
|
20731
|
+
});
|
|
20732
|
+
}
|
|
20733
|
+
catch {
|
|
20734
|
+
// ignore
|
|
20735
|
+
}
|
|
20736
|
+
}
|
|
20737
|
+
else {
|
|
20738
|
+
uploadSessionEvents({
|
|
20739
|
+
user_id: this.userId,
|
|
20740
|
+
session_uuid: this.sessionUuid,
|
|
20741
|
+
chunk_seq,
|
|
20742
|
+
chunk_start_ts,
|
|
20743
|
+
chunk_end_ts,
|
|
20744
|
+
initial_url,
|
|
20745
|
+
events,
|
|
20746
|
+
keepalive: true,
|
|
20747
|
+
}).catch(() => { });
|
|
20748
|
+
}
|
|
20735
20749
|
this.sessionEvents = [];
|
|
20750
|
+
this.bufferBytes = 0;
|
|
20736
20751
|
}
|
|
20737
20752
|
catch (err) {
|
|
20738
20753
|
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_log).call(this, "Page hide handling failed", err);
|
|
@@ -20759,21 +20774,29 @@ class SessionRecorder {
|
|
|
20759
20774
|
sessionStorage.setItem(testKey, "1");
|
|
20760
20775
|
sessionStorage.removeItem(testKey);
|
|
20761
20776
|
this.debug = (_a = config.debug) !== null && _a !== void 0 ? _a : false;
|
|
20762
|
-
if (
|
|
20763
|
-
|
|
20777
|
+
if (config.mode === "manual") {
|
|
20778
|
+
this.mode = "manual";
|
|
20779
|
+
if (!config.onEvents || typeof config.onEvents !== "function") {
|
|
20780
|
+
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_log).call(this, "onEvents callback is required in manual mode");
|
|
20781
|
+
return;
|
|
20782
|
+
}
|
|
20783
|
+
this.onEvents = config.onEvents;
|
|
20784
|
+
}
|
|
20785
|
+
else {
|
|
20786
|
+
this.mode = "auto";
|
|
20787
|
+
if (!((_b = config.WRITE_CODE) === null || _b === void 0 ? void 0 : _b.trim()) || !((_c = config.userId) === null || _c === void 0 ? void 0 : _c.trim())) {
|
|
20788
|
+
return;
|
|
20789
|
+
}
|
|
20790
|
+
saveWriteCode(config.WRITE_CODE);
|
|
20791
|
+
this.userId = config.userId;
|
|
20764
20792
|
}
|
|
20765
|
-
saveWriteCode(config.WRITE_CODE);
|
|
20766
|
-
this.userId = config.userId;
|
|
20767
20793
|
const { recordingOptions = {} } = config;
|
|
20768
|
-
const { TIMEOUT = 30 * 60 * 1000, BUFFER_SIZE =
|
|
20794
|
+
const { TIMEOUT = 30 * 60 * 1000, BUFFER_SIZE = 30, maskingOptions = ["passwords"], recordCrossOriginIframes = false, } = recordingOptions;
|
|
20769
20795
|
this.TIMEOUT = TIMEOUT;
|
|
20770
20796
|
this.BUFFER_SIZE = BUFFER_SIZE;
|
|
20771
20797
|
this.maskingOptions = maskingOptions;
|
|
20772
20798
|
this.recordCrossOriginIframes = recordCrossOriginIframes;
|
|
20773
20799
|
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
20800
|
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_initRecorder).call(this);
|
|
20778
20801
|
}
|
|
20779
20802
|
catch (err) {
|
|
@@ -20800,7 +20823,7 @@ class SessionRecorder {
|
|
|
20800
20823
|
}
|
|
20801
20824
|
}
|
|
20802
20825
|
}
|
|
20803
|
-
|
|
20826
|
+
_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
20827
|
if (!this.debug)
|
|
20805
20828
|
return;
|
|
20806
20829
|
if (error) {
|
|
@@ -20823,6 +20846,7 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
|
|
|
20823
20846
|
},
|
|
20824
20847
|
recordCrossOriginIframes: this.recordCrossOriginIframes,
|
|
20825
20848
|
plugins: [getRecordConsolePlugin()],
|
|
20849
|
+
checkoutEveryNth: 100,
|
|
20826
20850
|
});
|
|
20827
20851
|
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_initListeners).call(this);
|
|
20828
20852
|
}, _SessionRecorder_isUserInteraction = function _SessionRecorder_isUserInteraction(event) {
|
|
@@ -20833,7 +20857,6 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
|
|
|
20833
20857
|
}
|
|
20834
20858
|
return false;
|
|
20835
20859
|
}, _SessionRecorder_handleEvent = function _SessionRecorder_handleEvent(event, _isCheckout) {
|
|
20836
|
-
var _a;
|
|
20837
20860
|
try {
|
|
20838
20861
|
const now = Date.now();
|
|
20839
20862
|
const state = readSessionState();
|
|
@@ -20848,13 +20871,29 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
|
|
|
20848
20871
|
}
|
|
20849
20872
|
}
|
|
20850
20873
|
this.sessionEvents.push(event);
|
|
20851
|
-
|
|
20852
|
-
|
|
20874
|
+
this.bufferBytes += estimateEventSize(event);
|
|
20875
|
+
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_armBufferTimer).call(this);
|
|
20876
|
+
if (this.bufferBytes >= MAX_BUFFER_BYTES) {
|
|
20877
|
+
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_flushBuffer).call(this);
|
|
20853
20878
|
}
|
|
20854
20879
|
}
|
|
20855
20880
|
catch (err) {
|
|
20856
20881
|
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_log).call(this, "Event handling failed", err);
|
|
20857
20882
|
}
|
|
20883
|
+
}, _SessionRecorder_armBufferTimer = function _SessionRecorder_armBufferTimer() {
|
|
20884
|
+
if (__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f") !== null) {
|
|
20885
|
+
clearTimeout(__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f"));
|
|
20886
|
+
}
|
|
20887
|
+
__classPrivateFieldSet(this, _SessionRecorder_bufferTimer, setTimeout(() => {
|
|
20888
|
+
__classPrivateFieldSet(this, _SessionRecorder_bufferTimer, null, "f");
|
|
20889
|
+
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_flushBuffer).call(this);
|
|
20890
|
+
}, BUFFER_TIMEOUT_MS), "f");
|
|
20891
|
+
}, _SessionRecorder_flushBuffer = function _SessionRecorder_flushBuffer() {
|
|
20892
|
+
if (__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f") !== null) {
|
|
20893
|
+
clearTimeout(__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f"));
|
|
20894
|
+
__classPrivateFieldSet(this, _SessionRecorder_bufferTimer, null, "f");
|
|
20895
|
+
}
|
|
20896
|
+
void __classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_trackEvents).call(this);
|
|
20858
20897
|
}, _SessionRecorder_resetSession = function _SessionRecorder_resetSession() {
|
|
20859
20898
|
clearSessionState();
|
|
20860
20899
|
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_clearEvents).call(this);
|
|
@@ -20879,15 +20918,6 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
|
|
|
20879
20918
|
}
|
|
20880
20919
|
}, _SessionRecorder_initListeners = function _SessionRecorder_initListeners() {
|
|
20881
20920
|
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
20921
|
}, _SessionRecorder_trackEvents = async function _SessionRecorder_trackEvents() {
|
|
20892
20922
|
if (__classPrivateFieldGet(this, _SessionRecorder_uploading, "f"))
|
|
20893
20923
|
return;
|
|
@@ -20906,26 +20936,33 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
|
|
|
20906
20936
|
return;
|
|
20907
20937
|
}
|
|
20908
20938
|
const chunk_seq = state.chunk_seq;
|
|
20909
|
-
|
|
20910
|
-
|
|
20911
|
-
|
|
20912
|
-
|
|
20913
|
-
|
|
20914
|
-
|
|
20915
|
-
|
|
20916
|
-
|
|
20917
|
-
|
|
20918
|
-
|
|
20919
|
-
|
|
20920
|
-
|
|
20921
|
-
takeFullSnapshot(true);
|
|
20922
|
-
}
|
|
20923
|
-
catch (err) {
|
|
20924
|
-
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_log).call(this, "takeFullSnapshot failed", err);
|
|
20939
|
+
const initial_url = chunk_seq === 0 ? state.initial_url : undefined;
|
|
20940
|
+
const chunk_start_ts = new Date(start_ts_ms).toISOString();
|
|
20941
|
+
const chunk_end_ts = new Date(end_ts_ms).toISOString();
|
|
20942
|
+
if (this.mode === "manual") {
|
|
20943
|
+
await this.onEvents({
|
|
20944
|
+
session_uuid: this.sessionUuid,
|
|
20945
|
+
chunk_seq,
|
|
20946
|
+
chunk_start_ts,
|
|
20947
|
+
chunk_end_ts,
|
|
20948
|
+
initial_url,
|
|
20949
|
+
events,
|
|
20950
|
+
});
|
|
20925
20951
|
}
|
|
20926
|
-
|
|
20927
|
-
|
|
20952
|
+
else {
|
|
20953
|
+
await uploadSessionEvents({
|
|
20954
|
+
user_id: this.userId,
|
|
20955
|
+
session_uuid: this.sessionUuid,
|
|
20956
|
+
chunk_seq,
|
|
20957
|
+
chunk_start_ts,
|
|
20958
|
+
chunk_end_ts,
|
|
20959
|
+
initial_url,
|
|
20960
|
+
events,
|
|
20961
|
+
});
|
|
20928
20962
|
}
|
|
20963
|
+
const removedBytes = events.reduce((sum, e) => sum + estimateEventSize(e), 0);
|
|
20964
|
+
this.sessionEvents = this.sessionEvents.slice(snapshot_count);
|
|
20965
|
+
this.bufferBytes = Math.max(0, this.bufferBytes - removedBytes);
|
|
20929
20966
|
const after = readSessionState();
|
|
20930
20967
|
if (after &&
|
|
20931
20968
|
after.session_uuid === state.session_uuid &&
|
|
@@ -20942,6 +20979,11 @@ _SessionRecorder_trackEventsThrottled = new WeakMap(), _SessionRecorder_uploadin
|
|
|
20942
20979
|
}
|
|
20943
20980
|
}, _SessionRecorder_clearEvents = function _SessionRecorder_clearEvents() {
|
|
20944
20981
|
this.sessionEvents = [];
|
|
20982
|
+
this.bufferBytes = 0;
|
|
20983
|
+
if (__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f") !== null) {
|
|
20984
|
+
clearTimeout(__classPrivateFieldGet(this, _SessionRecorder_bufferTimer, "f"));
|
|
20985
|
+
__classPrivateFieldSet(this, _SessionRecorder_bufferTimer, null, "f");
|
|
20986
|
+
}
|
|
20945
20987
|
};
|
|
20946
20988
|
|
|
20947
20989
|
exports.default = SessionRecorder;
|