@devskin/browser-sdk 1.0.33 → 1.0.34
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 +41 -13
- package/dist/devskin.cjs.js.map +1 -1
- package/dist/devskin.esm.js +41 -13
- package/dist/devskin.esm.js.map +1 -1
- package/dist/devskin.umd.js +41 -13
- 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
|
});
|
|
@@ -14179,43 +14182,68 @@ class DevSkinSDK {
|
|
|
14179
14182
|
document.addEventListener('visibilitychange', () => {
|
|
14180
14183
|
var _a, _b;
|
|
14181
14184
|
if (document.hidden) {
|
|
14182
|
-
// User switched tabs or minimized - flush
|
|
14185
|
+
// User switched tabs or minimized - update duration and flush
|
|
14186
|
+
this.updateSessionDuration();
|
|
14183
14187
|
(_a = this.rrwebRecorder) === null || _a === void 0 ? void 0 : _a.stop(); // Stop recording and flush
|
|
14184
14188
|
(_b = this.transport) === null || _b === void 0 ? void 0 : _b.flush(true); // Use beacon
|
|
14185
14189
|
}
|
|
14186
14190
|
});
|
|
14187
14191
|
// 2. pagehide - fires when page is being unloaded
|
|
14188
14192
|
window.addEventListener('pagehide', (event) => {
|
|
14189
|
-
var _a, _b
|
|
14193
|
+
var _a, _b;
|
|
14190
14194
|
const isActualClose = !event.persisted;
|
|
14191
14195
|
if (isActualClose) {
|
|
14192
14196
|
// Tab is closing - end session
|
|
14193
14197
|
this.track('page_unload');
|
|
14194
|
-
|
|
14195
|
-
|
|
14196
|
-
|
|
14197
|
-
|
|
14198
|
-
(_a = this.transport) === null || _a === void 0 ? void 0 : _a.startSession(Object.assign({ sessionId: this.sessionId, userId: this.userId || undefined, anonymousId: this.anonymousId, endedAt: endedAt.toISOString(), durationMs: durationMs, platform: 'web' }, this.getContextData()), true); // true = use sendBeacon
|
|
14199
|
-
// Clear session storage since session is ending
|
|
14200
|
-
sessionStorage.removeItem('devskin_session_id');
|
|
14201
|
-
sessionStorage.removeItem('devskin_session_start');
|
|
14202
|
-
}
|
|
14198
|
+
this.updateSessionDuration(true); // true = session ending
|
|
14199
|
+
// Clear session storage since session is ending
|
|
14200
|
+
sessionStorage.removeItem('devskin_session_id');
|
|
14201
|
+
sessionStorage.removeItem('devskin_session_start');
|
|
14203
14202
|
}
|
|
14204
14203
|
else {
|
|
14205
14204
|
// Navigation - track page change
|
|
14206
14205
|
this.track('page_navigation');
|
|
14206
|
+
this.updateSessionDuration();
|
|
14207
14207
|
}
|
|
14208
14208
|
// ALWAYS flush (whether navigation or close)
|
|
14209
|
-
(
|
|
14210
|
-
(
|
|
14209
|
+
(_a = this.rrwebRecorder) === null || _a === void 0 ? void 0 : _a.stop(); // Stop recording and flush remaining events
|
|
14210
|
+
(_b = this.transport) === null || _b === void 0 ? void 0 : _b.flush(true); // Use beacon for reliability
|
|
14211
14211
|
});
|
|
14212
14212
|
// 3. beforeunload - backup for older browsers
|
|
14213
14213
|
window.addEventListener('beforeunload', () => {
|
|
14214
14214
|
var _a, _b;
|
|
14215
|
+
this.updateSessionDuration(true);
|
|
14215
14216
|
(_a = this.rrwebRecorder) === null || _a === void 0 ? void 0 : _a.stop();
|
|
14216
14217
|
(_b = this.transport) === null || _b === void 0 ? void 0 : _b.flush(true);
|
|
14217
14218
|
});
|
|
14218
14219
|
}
|
|
14220
|
+
/**
|
|
14221
|
+
* Start heartbeat to update session duration periodically
|
|
14222
|
+
*/
|
|
14223
|
+
startHeartbeat() {
|
|
14224
|
+
// Update duration every 30 seconds
|
|
14225
|
+
this.heartbeatInterval = setInterval(() => {
|
|
14226
|
+
this.updateSessionDuration();
|
|
14227
|
+
}, 30000); // 30 seconds
|
|
14228
|
+
}
|
|
14229
|
+
/**
|
|
14230
|
+
* Update session duration
|
|
14231
|
+
*/
|
|
14232
|
+
updateSessionDuration(isEnding = false) {
|
|
14233
|
+
var _a, _b;
|
|
14234
|
+
if (!this.sessionId || !this.sessionStartTime)
|
|
14235
|
+
return;
|
|
14236
|
+
const durationMs = Date.now() - this.sessionStartTime;
|
|
14237
|
+
const payload = Object.assign({ sessionId: this.sessionId, userId: this.userId || undefined, anonymousId: this.anonymousId, durationMs: durationMs, platform: 'web' }, this.getContextData());
|
|
14238
|
+
if (isEnding) {
|
|
14239
|
+
payload.endedAt = new Date().toISOString();
|
|
14240
|
+
}
|
|
14241
|
+
// Use beacon if ending, otherwise regular request
|
|
14242
|
+
(_a = this.transport) === null || _a === void 0 ? void 0 : _a.startSession(payload, isEnding);
|
|
14243
|
+
if ((_b = this.config) === null || _b === void 0 ? void 0 : _b.debug) {
|
|
14244
|
+
console.log('[DevSkin] Session duration updated:', durationMs, 'ms', isEnding ? '(ending)' : '');
|
|
14245
|
+
}
|
|
14246
|
+
}
|
|
14219
14247
|
}
|
|
14220
14248
|
// Create singleton instance
|
|
14221
14249
|
const DevSkin = new DevSkinSDK();
|