userlens-session-recorder 1.2.2 → 2.0.1
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/api/index.d.ts +2 -2
- package/dist/index.cjs.js +172 -96
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -4
- package/dist/index.esm.js +172 -96
- package/dist/index.esm.js.map +1 -1
- package/dist/types/index.d.ts +2 -21
- package/dist/userlens-session-recorder.umd.js +172 -96
- package/dist/userlens-session-recorder.umd.js.map +1 -1
- package/dist/utils.d.ts +4 -0
- package/package.json +1 -1
- package/dist/index.js +0 -1
package/dist/types/index.d.ts
CHANGED
|
@@ -1,39 +1,20 @@
|
|
|
1
|
-
import { eventWithTime } from 'rrweb';
|
|
2
|
-
|
|
3
1
|
type MaskingOption = "passwords" | "all";
|
|
4
|
-
type RecorderMode = "auto" | "manual";
|
|
5
2
|
interface SessionRecordingOptions {
|
|
6
3
|
TIMEOUT?: number;
|
|
7
4
|
BUFFER_SIZE?: number;
|
|
8
5
|
maskingOptions?: MaskingOption[];
|
|
9
6
|
recordCrossOriginIframes?: boolean;
|
|
10
7
|
}
|
|
11
|
-
interface
|
|
12
|
-
sessionId: string;
|
|
13
|
-
events: eventWithTime[];
|
|
14
|
-
chunkTimestamp: number;
|
|
15
|
-
}
|
|
16
|
-
type OnEventsCallback = (batch: EventBatch) => void;
|
|
17
|
-
interface AutoModeConfig {
|
|
18
|
-
mode?: "auto";
|
|
8
|
+
interface SessionRecorderConfig {
|
|
19
9
|
WRITE_CODE: string;
|
|
20
10
|
userId: string;
|
|
21
11
|
recordingOptions?: SessionRecordingOptions;
|
|
22
12
|
debug?: boolean;
|
|
23
13
|
}
|
|
24
|
-
interface ManualModeConfig {
|
|
25
|
-
mode: "manual";
|
|
26
|
-
onEvents: OnEventsCallback;
|
|
27
|
-
recordingOptions?: SessionRecordingOptions;
|
|
28
|
-
debug?: boolean;
|
|
29
|
-
}
|
|
30
|
-
type SessionRecorderConfig = AutoModeConfig | ManualModeConfig;
|
|
31
14
|
|
|
32
15
|
declare class SessionRecorder {
|
|
33
16
|
#private;
|
|
34
|
-
private mode;
|
|
35
17
|
private userId?;
|
|
36
|
-
private onEvents?;
|
|
37
18
|
private TIMEOUT;
|
|
38
19
|
private BUFFER_SIZE;
|
|
39
20
|
private maskingOptions;
|
|
@@ -48,4 +29,4 @@ declare class SessionRecorder {
|
|
|
48
29
|
}
|
|
49
30
|
|
|
50
31
|
export { SessionRecorder as default };
|
|
51
|
-
export type {
|
|
32
|
+
export type { MaskingOption, SessionRecorderConfig };
|
|
@@ -20611,48 +20611,71 @@
|
|
|
20611
20611
|
return null;
|
|
20612
20612
|
}
|
|
20613
20613
|
};
|
|
20614
|
+
const STATE_KEY = "userlensSessionRec";
|
|
20615
|
+
function readSessionState() {
|
|
20616
|
+
try {
|
|
20617
|
+
const raw = window.sessionStorage.getItem(STATE_KEY);
|
|
20618
|
+
if (!raw)
|
|
20619
|
+
return null;
|
|
20620
|
+
const parsed = JSON.parse(raw);
|
|
20621
|
+
if (typeof parsed !== "object" || parsed === null ||
|
|
20622
|
+
typeof parsed.session_uuid !== "string" ||
|
|
20623
|
+
typeof parsed.last_active !== "number" ||
|
|
20624
|
+
typeof parsed.chunk_seq !== "number" ||
|
|
20625
|
+
typeof parsed.initial_url !== "string")
|
|
20626
|
+
return null;
|
|
20627
|
+
return parsed;
|
|
20628
|
+
}
|
|
20629
|
+
catch {
|
|
20630
|
+
return null;
|
|
20631
|
+
}
|
|
20632
|
+
}
|
|
20633
|
+
function writeSessionState(state) {
|
|
20634
|
+
try {
|
|
20635
|
+
window.sessionStorage.setItem(STATE_KEY, JSON.stringify(state));
|
|
20636
|
+
}
|
|
20637
|
+
catch { }
|
|
20638
|
+
}
|
|
20639
|
+
function clearSessionState() {
|
|
20640
|
+
try {
|
|
20641
|
+
window.sessionStorage.removeItem(STATE_KEY);
|
|
20642
|
+
}
|
|
20643
|
+
catch { }
|
|
20644
|
+
}
|
|
20614
20645
|
|
|
20615
|
-
const
|
|
20616
|
-
|
|
20617
|
-
|
|
20618
|
-
const jsonStr = JSON.stringify(data);
|
|
20619
|
-
const stream = new Blob([new TextEncoder().encode(jsonStr)])
|
|
20620
|
-
.stream()
|
|
20621
|
-
.pipeThrough(new CompressionStream("gzip"));
|
|
20622
|
-
const buffer = await new Response(stream).arrayBuffer();
|
|
20623
|
-
const bytes = new Uint8Array(buffer);
|
|
20624
|
-
let binary = "";
|
|
20625
|
-
for (let i = 0; i < bytes.length; i++) {
|
|
20626
|
-
binary += String.fromCharCode(bytes[i]);
|
|
20627
|
-
}
|
|
20628
|
-
return btoa(binary);
|
|
20629
|
-
}
|
|
20630
|
-
const uploadSessionEvents = async (userId, sessionUuid, events, chunkTimestamp) => {
|
|
20646
|
+
const INGEST_BASE_URL = "https://ul-ingest.userlens.io";
|
|
20647
|
+
const uploadSessionEvents = async (args) => {
|
|
20648
|
+
var _a;
|
|
20631
20649
|
const writeCode = getWriteCode();
|
|
20632
20650
|
if (!writeCode) {
|
|
20633
20651
|
return;
|
|
20634
20652
|
}
|
|
20635
|
-
|
|
20636
|
-
|
|
20637
|
-
|
|
20638
|
-
|
|
20639
|
-
|
|
20653
|
+
const body = {
|
|
20654
|
+
session_uuid: args.session_uuid,
|
|
20655
|
+
chunk_seq: args.chunk_seq,
|
|
20656
|
+
chunk_start_ts: args.chunk_start_ts,
|
|
20657
|
+
chunk_end_ts: args.chunk_end_ts,
|
|
20658
|
+
user_id: args.user_id,
|
|
20659
|
+
events: args.events,
|
|
20640
20660
|
};
|
|
20641
|
-
|
|
20642
|
-
|
|
20661
|
+
if (args.initial_url !== undefined) {
|
|
20662
|
+
body.initial_url = args.initial_url;
|
|
20663
|
+
}
|
|
20664
|
+
const res = await fetch(`${INGEST_BASE_URL}/session-recording`, {
|
|
20643
20665
|
method: "POST",
|
|
20644
20666
|
headers: {
|
|
20645
|
-
"Content-Type": "
|
|
20667
|
+
"Content-Type": "application/json",
|
|
20646
20668
|
Authorization: `Basic ${writeCode}`,
|
|
20647
20669
|
},
|
|
20648
|
-
body:
|
|
20670
|
+
body: JSON.stringify(body),
|
|
20671
|
+
keepalive: (_a = args.keepalive) !== null && _a !== void 0 ? _a : false,
|
|
20649
20672
|
});
|
|
20650
20673
|
if (!res.ok)
|
|
20651
20674
|
throw new Error("Userlens HTTP error: failed to track");
|
|
20652
20675
|
return "ok";
|
|
20653
20676
|
};
|
|
20654
20677
|
|
|
20655
|
-
var _SessionRecorder_instances, _SessionRecorder_trackEventsThrottled, _SessionRecorder_log, _SessionRecorder_initRecorder, _SessionRecorder_isUserInteraction, _SessionRecorder_handleEvent, _SessionRecorder_resetSession, _SessionRecorder_createSession,
|
|
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;
|
|
20656
20679
|
class SessionRecorder {
|
|
20657
20680
|
constructor(config) {
|
|
20658
20681
|
var _a, _b, _c;
|
|
@@ -20661,65 +20684,88 @@
|
|
|
20661
20684
|
this.rrwebStop = null;
|
|
20662
20685
|
this.debug = false;
|
|
20663
20686
|
_SessionRecorder_trackEventsThrottled.set(this, void 0);
|
|
20664
|
-
|
|
20687
|
+
_SessionRecorder_uploading.set(this, false);
|
|
20688
|
+
_SessionRecorder_uploadingMaxTs.set(this, 0);
|
|
20689
|
+
_SessionRecorder_handlePageHide.set(this, () => {
|
|
20665
20690
|
try {
|
|
20666
|
-
if (
|
|
20667
|
-
|
|
20668
|
-
|
|
20669
|
-
|
|
20670
|
-
|
|
20671
|
-
|
|
20672
|
-
|
|
20691
|
+
if (this.sessionEvents.length === 0)
|
|
20692
|
+
return;
|
|
20693
|
+
let toUpload;
|
|
20694
|
+
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"));
|
|
20696
|
+
}
|
|
20697
|
+
else {
|
|
20698
|
+
toUpload = [...this.sessionEvents];
|
|
20699
|
+
}
|
|
20700
|
+
if (toUpload.length === 0)
|
|
20701
|
+
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
|
+
}
|
|
20673
20714
|
}
|
|
20674
|
-
|
|
20715
|
+
events = [...snapshotPair, ...toUpload];
|
|
20716
|
+
}
|
|
20717
|
+
else {
|
|
20718
|
+
events = toUpload;
|
|
20675
20719
|
}
|
|
20720
|
+
const state = readSessionState();
|
|
20721
|
+
if (!state)
|
|
20722
|
+
return;
|
|
20723
|
+
const chunk_seq = __classPrivateFieldGet(this, _SessionRecorder_uploading, "f") ? state.chunk_seq + 1 : state.chunk_seq;
|
|
20724
|
+
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;
|
|
20727
|
+
uploadSessionEvents({
|
|
20728
|
+
user_id: this.userId,
|
|
20729
|
+
session_uuid: this.sessionUuid,
|
|
20730
|
+
chunk_seq,
|
|
20731
|
+
chunk_start_ts: new Date(start_ts_ms).toISOString(),
|
|
20732
|
+
chunk_end_ts: new Date(end_ts_ms).toISOString(),
|
|
20733
|
+
initial_url: chunk_seq === 0 ? state.initial_url : undefined,
|
|
20734
|
+
events,
|
|
20735
|
+
keepalive: true,
|
|
20736
|
+
}).catch(() => { });
|
|
20737
|
+
this.sessionEvents = [];
|
|
20676
20738
|
}
|
|
20677
20739
|
catch (err) {
|
|
20678
|
-
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_log).call(this, "
|
|
20740
|
+
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_log).call(this, "Page hide handling failed", err);
|
|
20679
20741
|
}
|
|
20680
20742
|
});
|
|
20681
20743
|
try {
|
|
20682
|
-
// Check for browser environment
|
|
20683
20744
|
if (typeof window === "undefined")
|
|
20684
20745
|
return;
|
|
20685
20746
|
if (typeof document === "undefined")
|
|
20686
20747
|
return;
|
|
20687
20748
|
if (typeof localStorage === "undefined")
|
|
20688
20749
|
return;
|
|
20689
|
-
|
|
20690
|
-
if (typeof CompressionStream === "undefined")
|
|
20750
|
+
if (typeof sessionStorage === "undefined")
|
|
20691
20751
|
return;
|
|
20692
20752
|
if (typeof MutationObserver === "undefined")
|
|
20693
20753
|
return;
|
|
20694
|
-
if (typeof TextEncoder === "undefined")
|
|
20695
|
-
return;
|
|
20696
20754
|
if (typeof fetch === "undefined")
|
|
20697
20755
|
return;
|
|
20698
|
-
if (typeof Blob === "undefined")
|
|
20699
|
-
return;
|
|
20700
20756
|
if (typeof crypto === "undefined" || !crypto.getRandomValues)
|
|
20701
20757
|
return;
|
|
20702
|
-
// Check localStorage actually works (can be blocked even if defined)
|
|
20703
20758
|
const testKey = "__userlens_test__";
|
|
20704
20759
|
localStorage.setItem(testKey, "1");
|
|
20705
20760
|
localStorage.removeItem(testKey);
|
|
20706
|
-
|
|
20761
|
+
sessionStorage.setItem(testKey, "1");
|
|
20762
|
+
sessionStorage.removeItem(testKey);
|
|
20707
20763
|
this.debug = (_a = config.debug) !== null && _a !== void 0 ? _a : false;
|
|
20708
|
-
if (config.
|
|
20709
|
-
|
|
20710
|
-
if (!config.onEvents || typeof config.onEvents !== "function") {
|
|
20711
|
-
return;
|
|
20712
|
-
}
|
|
20713
|
-
this.onEvents = config.onEvents;
|
|
20714
|
-
}
|
|
20715
|
-
else {
|
|
20716
|
-
this.mode = "auto";
|
|
20717
|
-
if (!((_b = config.WRITE_CODE) === null || _b === void 0 ? void 0 : _b.trim()) || !((_c = config.userId) === null || _c === void 0 ? void 0 : _c.trim())) {
|
|
20718
|
-
return;
|
|
20719
|
-
}
|
|
20720
|
-
saveWriteCode(config.WRITE_CODE);
|
|
20721
|
-
this.userId = config.userId;
|
|
20764
|
+
if (!((_b = config.WRITE_CODE) === null || _b === void 0 ? void 0 : _b.trim()) || !((_c = config.userId) === null || _c === void 0 ? void 0 : _c.trim())) {
|
|
20765
|
+
return;
|
|
20722
20766
|
}
|
|
20767
|
+
saveWriteCode(config.WRITE_CODE);
|
|
20768
|
+
this.userId = config.userId;
|
|
20723
20769
|
const { recordingOptions = {} } = config;
|
|
20724
20770
|
const { TIMEOUT = 30 * 60 * 1000, BUFFER_SIZE = 10, maskingOptions = ["passwords"], recordCrossOriginIframes = false, } = recordingOptions;
|
|
20725
20771
|
this.TIMEOUT = TIMEOUT;
|
|
@@ -20748,15 +20794,15 @@
|
|
|
20748
20794
|
this.rrwebStop();
|
|
20749
20795
|
this.rrwebStop = null;
|
|
20750
20796
|
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_clearEvents).call(this);
|
|
20751
|
-
|
|
20752
|
-
window.removeEventListener("
|
|
20797
|
+
clearSessionState();
|
|
20798
|
+
window.removeEventListener("pagehide", __classPrivateFieldGet(this, _SessionRecorder_handlePageHide, "f"));
|
|
20753
20799
|
}
|
|
20754
20800
|
catch (err) {
|
|
20755
20801
|
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_log).call(this, "Stop failed", err);
|
|
20756
20802
|
}
|
|
20757
20803
|
}
|
|
20758
20804
|
}
|
|
20759
|
-
_SessionRecorder_trackEventsThrottled = new WeakMap(),
|
|
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) {
|
|
20760
20806
|
if (!this.debug)
|
|
20761
20807
|
return;
|
|
20762
20808
|
if (error) {
|
|
@@ -20779,9 +20825,8 @@
|
|
|
20779
20825
|
},
|
|
20780
20826
|
recordCrossOriginIframes: this.recordCrossOriginIframes,
|
|
20781
20827
|
plugins: [getRecordConsolePlugin()],
|
|
20782
|
-
checkoutEveryNth: 100,
|
|
20783
20828
|
});
|
|
20784
|
-
__classPrivateFieldGet(this, _SessionRecorder_instances, "m",
|
|
20829
|
+
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_initListeners).call(this);
|
|
20785
20830
|
}, _SessionRecorder_isUserInteraction = function _SessionRecorder_isUserInteraction(event) {
|
|
20786
20831
|
var _a;
|
|
20787
20832
|
if (event.type === 3) {
|
|
@@ -20793,15 +20838,16 @@
|
|
|
20793
20838
|
var _a;
|
|
20794
20839
|
try {
|
|
20795
20840
|
const now = Date.now();
|
|
20796
|
-
const
|
|
20797
|
-
|
|
20798
|
-
if (lastActive && now - lastActive > this.TIMEOUT) {
|
|
20841
|
+
const state = readSessionState();
|
|
20842
|
+
if (state && now - state.last_active > this.TIMEOUT) {
|
|
20799
20843
|
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_resetSession).call(this);
|
|
20800
20844
|
takeFullSnapshot(true);
|
|
20801
20845
|
}
|
|
20802
|
-
// only update lastActive on actual user interactions, not DOM mutations
|
|
20803
20846
|
if (__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_isUserInteraction).call(this, event)) {
|
|
20804
|
-
|
|
20847
|
+
const latest = readSessionState();
|
|
20848
|
+
if (latest) {
|
|
20849
|
+
writeSessionState({ ...latest, last_active: now });
|
|
20850
|
+
}
|
|
20805
20851
|
}
|
|
20806
20852
|
this.sessionEvents.push(event);
|
|
20807
20853
|
if (this.sessionEvents.length >= this.BUFFER_SIZE) {
|
|
@@ -20812,24 +20858,29 @@
|
|
|
20812
20858
|
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_log).call(this, "Event handling failed", err);
|
|
20813
20859
|
}
|
|
20814
20860
|
}, _SessionRecorder_resetSession = function _SessionRecorder_resetSession() {
|
|
20815
|
-
|
|
20861
|
+
clearSessionState();
|
|
20816
20862
|
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_clearEvents).call(this);
|
|
20817
20863
|
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_createSession).call(this);
|
|
20818
20864
|
}, _SessionRecorder_createSession = function _SessionRecorder_createSession() {
|
|
20819
20865
|
const now = Date.now();
|
|
20820
|
-
const
|
|
20821
|
-
const
|
|
20822
|
-
|
|
20823
|
-
if (!storedUuid || isExpired) {
|
|
20866
|
+
const state = readSessionState();
|
|
20867
|
+
const isExpired = !state || now - state.last_active > this.TIMEOUT;
|
|
20868
|
+
if (!state || isExpired) {
|
|
20824
20869
|
this.sessionUuid = generateUuid();
|
|
20825
|
-
|
|
20870
|
+
const initial_url = typeof window !== "undefined" ? window.location.href : "";
|
|
20871
|
+
writeSessionState({
|
|
20872
|
+
session_uuid: this.sessionUuid,
|
|
20873
|
+
last_active: now,
|
|
20874
|
+
chunk_seq: 0,
|
|
20875
|
+
initial_url,
|
|
20876
|
+
});
|
|
20826
20877
|
}
|
|
20827
20878
|
else {
|
|
20828
|
-
this.sessionUuid =
|
|
20879
|
+
this.sessionUuid = state.session_uuid;
|
|
20880
|
+
writeSessionState({ ...state, last_active: now });
|
|
20829
20881
|
}
|
|
20830
|
-
|
|
20831
|
-
|
|
20832
|
-
window.addEventListener("visibilitychange", __classPrivateFieldGet(this, _SessionRecorder_handleVisibilityChange, "f"));
|
|
20882
|
+
}, _SessionRecorder_initListeners = function _SessionRecorder_initListeners() {
|
|
20883
|
+
window.addEventListener("pagehide", __classPrivateFieldGet(this, _SessionRecorder_handlePageHide, "f"));
|
|
20833
20884
|
}, _SessionRecorder_throttle = function _SessionRecorder_throttle(func, delay) {
|
|
20834
20885
|
let lastCall = 0;
|
|
20835
20886
|
return (...args) => {
|
|
@@ -20840,34 +20891,59 @@
|
|
|
20840
20891
|
}
|
|
20841
20892
|
};
|
|
20842
20893
|
}, _SessionRecorder_trackEvents = async function _SessionRecorder_trackEvents() {
|
|
20894
|
+
if (__classPrivateFieldGet(this, _SessionRecorder_uploading, "f"))
|
|
20895
|
+
return;
|
|
20896
|
+
if (this.sessionEvents.length === 0)
|
|
20897
|
+
return;
|
|
20898
|
+
__classPrivateFieldSet(this, _SessionRecorder_uploading, true, "f");
|
|
20843
20899
|
try {
|
|
20844
|
-
|
|
20900
|
+
const events = [...this.sessionEvents];
|
|
20901
|
+
const snapshot_count = events.length;
|
|
20902
|
+
__classPrivateFieldSet(this, _SessionRecorder_uploadingMaxTs, events[events.length - 1].timestamp, "f");
|
|
20903
|
+
const start_ts_ms = events[0].timestamp;
|
|
20904
|
+
const end_ts_ms = events[events.length - 1].timestamp;
|
|
20905
|
+
const state = readSessionState();
|
|
20906
|
+
if (!state) {
|
|
20907
|
+
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_log).call(this, "No session state during upload — skipping chunk");
|
|
20845
20908
|
return;
|
|
20846
20909
|
}
|
|
20847
|
-
const
|
|
20848
|
-
|
|
20849
|
-
|
|
20850
|
-
|
|
20851
|
-
|
|
20852
|
-
|
|
20853
|
-
|
|
20854
|
-
|
|
20855
|
-
|
|
20856
|
-
|
|
20857
|
-
|
|
20910
|
+
const chunk_seq = state.chunk_seq;
|
|
20911
|
+
await uploadSessionEvents({
|
|
20912
|
+
user_id: this.userId,
|
|
20913
|
+
session_uuid: this.sessionUuid,
|
|
20914
|
+
chunk_seq,
|
|
20915
|
+
chunk_start_ts: new Date(start_ts_ms).toISOString(),
|
|
20916
|
+
chunk_end_ts: new Date(end_ts_ms).toISOString(),
|
|
20917
|
+
initial_url: chunk_seq === 0 ? state.initial_url : undefined,
|
|
20918
|
+
events,
|
|
20919
|
+
});
|
|
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);
|
|
20858
20930
|
}
|
|
20859
|
-
|
|
20860
|
-
|
|
20931
|
+
const after = readSessionState();
|
|
20932
|
+
if (after &&
|
|
20933
|
+
after.session_uuid === state.session_uuid &&
|
|
20934
|
+
after.chunk_seq === chunk_seq) {
|
|
20935
|
+
writeSessionState({ ...after, chunk_seq: chunk_seq + 1 });
|
|
20861
20936
|
}
|
|
20862
20937
|
}
|
|
20863
20938
|
catch (err) {
|
|
20864
20939
|
__classPrivateFieldGet(this, _SessionRecorder_instances, "m", _SessionRecorder_log).call(this, "Event tracking failed", err);
|
|
20865
20940
|
}
|
|
20941
|
+
finally {
|
|
20942
|
+
__classPrivateFieldSet(this, _SessionRecorder_uploading, false, "f");
|
|
20943
|
+
__classPrivateFieldSet(this, _SessionRecorder_uploadingMaxTs, 0, "f");
|
|
20944
|
+
}
|
|
20866
20945
|
}, _SessionRecorder_clearEvents = function _SessionRecorder_clearEvents() {
|
|
20867
20946
|
this.sessionEvents = [];
|
|
20868
|
-
}, _SessionRecorder_removeLocalSessionData = function _SessionRecorder_removeLocalSessionData() {
|
|
20869
|
-
localStorage.removeItem("userlensSessionUuid");
|
|
20870
|
-
localStorage.removeItem("userlensSessionLastActive");
|
|
20871
20947
|
};
|
|
20872
20948
|
|
|
20873
20949
|
exports.default = SessionRecorder;
|