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