@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.esm.js
CHANGED
|
@@ -13856,6 +13856,7 @@ class DevSkinSDK {
|
|
|
13856
13856
|
this.anonymousId = null;
|
|
13857
13857
|
this.sessionStartTime = 0;
|
|
13858
13858
|
this.initialized = false;
|
|
13859
|
+
this.heartbeatInterval = null;
|
|
13859
13860
|
// Collectors
|
|
13860
13861
|
this.deviceCollector = null;
|
|
13861
13862
|
this.locationCollector = null;
|
|
@@ -13956,6 +13957,8 @@ class DevSkinSDK {
|
|
|
13956
13957
|
}
|
|
13957
13958
|
// Track initial page view
|
|
13958
13959
|
this.trackPageView();
|
|
13960
|
+
// Start heartbeat to update session duration every 30 seconds
|
|
13961
|
+
this.startHeartbeat();
|
|
13959
13962
|
}).catch((err) => {
|
|
13960
13963
|
console.error('[DevSkin] Failed to create session:', err);
|
|
13961
13964
|
});
|
|
@@ -14175,43 +14178,68 @@ class DevSkinSDK {
|
|
|
14175
14178
|
document.addEventListener('visibilitychange', () => {
|
|
14176
14179
|
var _a, _b;
|
|
14177
14180
|
if (document.hidden) {
|
|
14178
|
-
// User switched tabs or minimized - flush
|
|
14181
|
+
// User switched tabs or minimized - update duration and flush
|
|
14182
|
+
this.updateSessionDuration();
|
|
14179
14183
|
(_a = this.rrwebRecorder) === null || _a === void 0 ? void 0 : _a.stop(); // Stop recording and flush
|
|
14180
14184
|
(_b = this.transport) === null || _b === void 0 ? void 0 : _b.flush(true); // Use beacon
|
|
14181
14185
|
}
|
|
14182
14186
|
});
|
|
14183
14187
|
// 2. pagehide - fires when page is being unloaded
|
|
14184
14188
|
window.addEventListener('pagehide', (event) => {
|
|
14185
|
-
var _a, _b
|
|
14189
|
+
var _a, _b;
|
|
14186
14190
|
const isActualClose = !event.persisted;
|
|
14187
14191
|
if (isActualClose) {
|
|
14188
14192
|
// Tab is closing - end session
|
|
14189
14193
|
this.track('page_unload');
|
|
14190
|
-
|
|
14191
|
-
|
|
14192
|
-
|
|
14193
|
-
|
|
14194
|
-
(_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
|
|
14195
|
-
// Clear session storage since session is ending
|
|
14196
|
-
sessionStorage.removeItem('devskin_session_id');
|
|
14197
|
-
sessionStorage.removeItem('devskin_session_start');
|
|
14198
|
-
}
|
|
14194
|
+
this.updateSessionDuration(true); // true = session ending
|
|
14195
|
+
// Clear session storage since session is ending
|
|
14196
|
+
sessionStorage.removeItem('devskin_session_id');
|
|
14197
|
+
sessionStorage.removeItem('devskin_session_start');
|
|
14199
14198
|
}
|
|
14200
14199
|
else {
|
|
14201
14200
|
// Navigation - track page change
|
|
14202
14201
|
this.track('page_navigation');
|
|
14202
|
+
this.updateSessionDuration();
|
|
14203
14203
|
}
|
|
14204
14204
|
// ALWAYS flush (whether navigation or close)
|
|
14205
|
-
(
|
|
14206
|
-
(
|
|
14205
|
+
(_a = this.rrwebRecorder) === null || _a === void 0 ? void 0 : _a.stop(); // Stop recording and flush remaining events
|
|
14206
|
+
(_b = this.transport) === null || _b === void 0 ? void 0 : _b.flush(true); // Use beacon for reliability
|
|
14207
14207
|
});
|
|
14208
14208
|
// 3. beforeunload - backup for older browsers
|
|
14209
14209
|
window.addEventListener('beforeunload', () => {
|
|
14210
14210
|
var _a, _b;
|
|
14211
|
+
this.updateSessionDuration(true);
|
|
14211
14212
|
(_a = this.rrwebRecorder) === null || _a === void 0 ? void 0 : _a.stop();
|
|
14212
14213
|
(_b = this.transport) === null || _b === void 0 ? void 0 : _b.flush(true);
|
|
14213
14214
|
});
|
|
14214
14215
|
}
|
|
14216
|
+
/**
|
|
14217
|
+
* Start heartbeat to update session duration periodically
|
|
14218
|
+
*/
|
|
14219
|
+
startHeartbeat() {
|
|
14220
|
+
// Update duration every 30 seconds
|
|
14221
|
+
this.heartbeatInterval = setInterval(() => {
|
|
14222
|
+
this.updateSessionDuration();
|
|
14223
|
+
}, 30000); // 30 seconds
|
|
14224
|
+
}
|
|
14225
|
+
/**
|
|
14226
|
+
* Update session duration
|
|
14227
|
+
*/
|
|
14228
|
+
updateSessionDuration(isEnding = false) {
|
|
14229
|
+
var _a, _b;
|
|
14230
|
+
if (!this.sessionId || !this.sessionStartTime)
|
|
14231
|
+
return;
|
|
14232
|
+
const durationMs = Date.now() - this.sessionStartTime;
|
|
14233
|
+
const payload = Object.assign({ sessionId: this.sessionId, userId: this.userId || undefined, anonymousId: this.anonymousId, durationMs: durationMs, platform: 'web' }, this.getContextData());
|
|
14234
|
+
if (isEnding) {
|
|
14235
|
+
payload.endedAt = new Date().toISOString();
|
|
14236
|
+
}
|
|
14237
|
+
// Use beacon if ending, otherwise regular request
|
|
14238
|
+
(_a = this.transport) === null || _a === void 0 ? void 0 : _a.startSession(payload, isEnding);
|
|
14239
|
+
if ((_b = this.config) === null || _b === void 0 ? void 0 : _b.debug) {
|
|
14240
|
+
console.log('[DevSkin] Session duration updated:', durationMs, 'ms', isEnding ? '(ending)' : '');
|
|
14241
|
+
}
|
|
14242
|
+
}
|
|
14215
14243
|
}
|
|
14216
14244
|
// Create singleton instance
|
|
14217
14245
|
const DevSkin = new DevSkinSDK();
|