@devskin/browser-sdk 1.0.33 → 1.0.35
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/devskin.cjs.js +46 -24
- package/dist/devskin.cjs.js.map +1 -1
- package/dist/devskin.esm.js +46 -24
- package/dist/devskin.esm.js.map +1 -1
- package/dist/devskin.umd.js +46 -24
- package/dist/devskin.umd.js.map +1 -1
- package/dist/devskin.umd.min.js +1 -1
- package/dist/devskin.umd.min.js.map +1 -1
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/devskin.cjs.js
CHANGED
|
@@ -13860,6 +13860,7 @@ class DevSkinSDK {
|
|
|
13860
13860
|
this.anonymousId = null;
|
|
13861
13861
|
this.sessionStartTime = 0;
|
|
13862
13862
|
this.initialized = false;
|
|
13863
|
+
this.heartbeatInterval = null;
|
|
13863
13864
|
// Collectors
|
|
13864
13865
|
this.deviceCollector = null;
|
|
13865
13866
|
this.locationCollector = null;
|
|
@@ -13960,6 +13961,8 @@ class DevSkinSDK {
|
|
|
13960
13961
|
}
|
|
13961
13962
|
// Track initial page view
|
|
13962
13963
|
this.trackPageView();
|
|
13964
|
+
// Start heartbeat to update session duration every 30 seconds
|
|
13965
|
+
this.startHeartbeat();
|
|
13963
13966
|
}).catch((err) => {
|
|
13964
13967
|
console.error('[DevSkin] Failed to create session:', err);
|
|
13965
13968
|
});
|
|
@@ -14175,47 +14178,66 @@ class DevSkinSDK {
|
|
|
14175
14178
|
}
|
|
14176
14179
|
setupUnloadTracking() {
|
|
14177
14180
|
// CRITICAL: Flush data BEFORE page unloads to avoid losing final events
|
|
14181
|
+
// IMPORTANT: NEVER clear sessionStorage - it expires naturally when tab closes
|
|
14178
14182
|
// 1. visibilitychange - fires when tab is hidden (most reliable)
|
|
14179
14183
|
document.addEventListener('visibilitychange', () => {
|
|
14180
14184
|
var _a, _b;
|
|
14181
14185
|
if (document.hidden) {
|
|
14182
|
-
// User switched tabs or minimized - flush
|
|
14186
|
+
// User switched tabs or minimized - update duration and flush
|
|
14187
|
+
this.updateSessionDuration();
|
|
14183
14188
|
(_a = this.rrwebRecorder) === null || _a === void 0 ? void 0 : _a.stop(); // Stop recording and flush
|
|
14184
14189
|
(_b = this.transport) === null || _b === void 0 ? void 0 : _b.flush(true); // Use beacon
|
|
14185
14190
|
}
|
|
14186
14191
|
});
|
|
14187
14192
|
// 2. pagehide - fires when page is being unloaded
|
|
14188
|
-
window.addEventListener('pagehide', (
|
|
14189
|
-
var _a, _b
|
|
14190
|
-
|
|
14191
|
-
|
|
14192
|
-
|
|
14193
|
-
|
|
14194
|
-
|
|
14195
|
-
|
|
14196
|
-
|
|
14197
|
-
|
|
14198
|
-
|
|
14199
|
-
// Clear session storage since session is ending
|
|
14200
|
-
sessionStorage.removeItem('devskin_session_id');
|
|
14201
|
-
sessionStorage.removeItem('devskin_session_start');
|
|
14202
|
-
}
|
|
14203
|
-
}
|
|
14204
|
-
else {
|
|
14205
|
-
// Navigation - track page change
|
|
14206
|
-
this.track('page_navigation');
|
|
14207
|
-
}
|
|
14208
|
-
// ALWAYS flush (whether navigation or close)
|
|
14209
|
-
(_b = this.rrwebRecorder) === null || _b === void 0 ? void 0 : _b.stop(); // Stop recording and flush remaining events
|
|
14210
|
-
(_c = this.transport) === null || _c === void 0 ? void 0 : _c.flush(true); // Use beacon for reliability
|
|
14193
|
+
window.addEventListener('pagehide', () => {
|
|
14194
|
+
var _a, _b;
|
|
14195
|
+
// Track navigation (we can't distinguish between page navigation and tab close reliably)
|
|
14196
|
+
this.track('page_navigation');
|
|
14197
|
+
// Update duration but DON'T mark as ending (let heartbeat timeout handle session expiry)
|
|
14198
|
+
this.updateSessionDuration(false);
|
|
14199
|
+
// NEVER clear sessionStorage - it persists across navigations in same tab
|
|
14200
|
+
// and expires automatically when tab actually closes
|
|
14201
|
+
// Flush data before page unloads
|
|
14202
|
+
(_a = this.rrwebRecorder) === null || _a === void 0 ? void 0 : _a.stop(); // Stop recording and flush remaining events
|
|
14203
|
+
(_b = this.transport) === null || _b === void 0 ? void 0 : _b.flush(true); // Use beacon for reliability
|
|
14211
14204
|
});
|
|
14212
14205
|
// 3. beforeunload - backup for older browsers
|
|
14213
14206
|
window.addEventListener('beforeunload', () => {
|
|
14214
14207
|
var _a, _b;
|
|
14208
|
+
// Update duration but DON'T mark as ending
|
|
14209
|
+
this.updateSessionDuration(false);
|
|
14215
14210
|
(_a = this.rrwebRecorder) === null || _a === void 0 ? void 0 : _a.stop();
|
|
14216
14211
|
(_b = this.transport) === null || _b === void 0 ? void 0 : _b.flush(true);
|
|
14217
14212
|
});
|
|
14218
14213
|
}
|
|
14214
|
+
/**
|
|
14215
|
+
* Start heartbeat to update session duration periodically
|
|
14216
|
+
*/
|
|
14217
|
+
startHeartbeat() {
|
|
14218
|
+
// Update duration every 30 seconds
|
|
14219
|
+
this.heartbeatInterval = setInterval(() => {
|
|
14220
|
+
this.updateSessionDuration();
|
|
14221
|
+
}, 30000); // 30 seconds
|
|
14222
|
+
}
|
|
14223
|
+
/**
|
|
14224
|
+
* Update session duration
|
|
14225
|
+
*/
|
|
14226
|
+
updateSessionDuration(isEnding = false) {
|
|
14227
|
+
var _a, _b;
|
|
14228
|
+
if (!this.sessionId || !this.sessionStartTime)
|
|
14229
|
+
return;
|
|
14230
|
+
const durationMs = Date.now() - this.sessionStartTime;
|
|
14231
|
+
const payload = Object.assign({ sessionId: this.sessionId, userId: this.userId || undefined, anonymousId: this.anonymousId, durationMs: durationMs, platform: 'web' }, this.getContextData());
|
|
14232
|
+
if (isEnding) {
|
|
14233
|
+
payload.endedAt = new Date().toISOString();
|
|
14234
|
+
}
|
|
14235
|
+
// Use beacon if ending, otherwise regular request
|
|
14236
|
+
(_a = this.transport) === null || _a === void 0 ? void 0 : _a.startSession(payload, isEnding);
|
|
14237
|
+
if ((_b = this.config) === null || _b === void 0 ? void 0 : _b.debug) {
|
|
14238
|
+
console.log('[DevSkin] Session duration updated:', durationMs, 'ms', isEnding ? '(ending)' : '');
|
|
14239
|
+
}
|
|
14240
|
+
}
|
|
14219
14241
|
}
|
|
14220
14242
|
// Create singleton instance
|
|
14221
14243
|
const DevSkin = new DevSkinSDK();
|