@devskin/browser-sdk 1.0.25 → 1.0.27
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 +96 -24
- package/dist/devskin.cjs.js.map +1 -1
- package/dist/devskin.esm.js +96 -24
- package/dist/devskin.esm.js.map +1 -1
- package/dist/devskin.umd.js +96 -24
- package/dist/devskin.umd.js.map +1 -1
- package/dist/devskin.umd.min.js +2 -2
- package/dist/devskin.umd.min.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/transport.d.ts +1 -0
- package/dist/transport.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/recorder/session.d.ts +0 -18
- package/dist/recorder/session.d.ts.map +0 -1
package/dist/devskin.umd.js
CHANGED
|
@@ -13486,8 +13486,8 @@
|
|
|
13486
13486
|
// Send immediately to ensure FullSnapshot reaches backend first
|
|
13487
13487
|
this.flush();
|
|
13488
13488
|
}
|
|
13489
|
-
else if (this.hasFullSnapshot && this.events.length >=
|
|
13490
|
-
// After FullSnapshot, batch other events
|
|
13489
|
+
else if (this.hasFullSnapshot && this.events.length >= 20) {
|
|
13490
|
+
// After FullSnapshot, batch other events (reduced from 50 to 20)
|
|
13491
13491
|
this.flush();
|
|
13492
13492
|
}
|
|
13493
13493
|
},
|
|
@@ -13526,13 +13526,13 @@
|
|
|
13526
13526
|
// Capture iframe content
|
|
13527
13527
|
recordCrossOriginIframes: false, // Security: don't record cross-origin iframes
|
|
13528
13528
|
});
|
|
13529
|
-
// Set up periodic flush (every
|
|
13529
|
+
// Set up periodic flush (every 2 seconds)
|
|
13530
13530
|
// Only flush if we have FullSnapshot to ensure first batch is complete
|
|
13531
13531
|
this.flushInterval = window.setInterval(() => {
|
|
13532
13532
|
if (this.hasFullSnapshot && this.events.length > 0) {
|
|
13533
13533
|
this.flush();
|
|
13534
13534
|
}
|
|
13535
|
-
},
|
|
13535
|
+
}, 2000); // Reduced from 10s to 2s
|
|
13536
13536
|
// Safety check: After 2 seconds, force a full snapshot if none captured
|
|
13537
13537
|
setTimeout(() => {
|
|
13538
13538
|
if (!this.hasFullSnapshot) {
|
|
@@ -13590,8 +13590,8 @@
|
|
|
13590
13590
|
this.config = config;
|
|
13591
13591
|
this.queue = [];
|
|
13592
13592
|
this.flushInterval = null;
|
|
13593
|
-
this.maxQueueSize = 50
|
|
13594
|
-
this.flushIntervalMs =
|
|
13593
|
+
this.maxQueueSize = 20; // Reduced from 50
|
|
13594
|
+
this.flushIntervalMs = 2000; // 2 seconds (reduced from 5s)
|
|
13595
13595
|
this.apiUrl = config.apiUrl || 'https://api.devskin.com';
|
|
13596
13596
|
// Start periodic flush
|
|
13597
13597
|
this.startPeriodicFlush();
|
|
@@ -13616,8 +13616,8 @@
|
|
|
13616
13616
|
this.sendToBackend('/v1/analytics/identify', user);
|
|
13617
13617
|
}
|
|
13618
13618
|
startSession(session) {
|
|
13619
|
-
// Send session start immediately
|
|
13620
|
-
this.sendToBackend('/v1/
|
|
13619
|
+
// Send session start immediately to RUM endpoint
|
|
13620
|
+
this.sendToBackend('/v1/rum/sessions', session);
|
|
13621
13621
|
}
|
|
13622
13622
|
sendError(error) {
|
|
13623
13623
|
this.enqueue('error', error);
|
|
@@ -13628,6 +13628,12 @@
|
|
|
13628
13628
|
sendPerformanceMetric(metric) {
|
|
13629
13629
|
this.enqueue('performance', metric);
|
|
13630
13630
|
}
|
|
13631
|
+
sendPageView(pageViewData) {
|
|
13632
|
+
return __awaiter$1(this, void 0, void 0, function* () {
|
|
13633
|
+
// Send page view immediately to RUM endpoint (don't queue)
|
|
13634
|
+
this.sendToBackend('/v1/rum/page-views', pageViewData);
|
|
13635
|
+
});
|
|
13636
|
+
}
|
|
13631
13637
|
sendRecordingEvents(sessionId, events) {
|
|
13632
13638
|
return __awaiter$1(this, void 0, void 0, function* () {
|
|
13633
13639
|
// Calculate payload size
|
|
@@ -13728,17 +13734,17 @@
|
|
|
13728
13734
|
getEndpointForType(type) {
|
|
13729
13735
|
switch (type) {
|
|
13730
13736
|
case 'event':
|
|
13731
|
-
return '/v1/
|
|
13737
|
+
return '/v1/rum/events';
|
|
13732
13738
|
case 'error':
|
|
13733
|
-
return '/v1/
|
|
13739
|
+
return '/v1/errors/errors';
|
|
13734
13740
|
case 'network':
|
|
13735
|
-
return '/v1/
|
|
13741
|
+
return '/v1/rum/network-requests';
|
|
13736
13742
|
case 'performance':
|
|
13737
|
-
return '/v1/
|
|
13743
|
+
return '/v1/rum/web-vitals';
|
|
13738
13744
|
case 'heatmap':
|
|
13739
13745
|
return '/v1/sdk/heatmap';
|
|
13740
13746
|
default:
|
|
13741
|
-
return '/v1/
|
|
13747
|
+
return '/v1/rum/events';
|
|
13742
13748
|
}
|
|
13743
13749
|
}
|
|
13744
13750
|
sendToBackendXHR(endpoint, data) {
|
|
@@ -13997,7 +14003,24 @@
|
|
|
13997
14003
|
* Track a page view
|
|
13998
14004
|
*/
|
|
13999
14005
|
trackPageView(properties) {
|
|
14006
|
+
var _a, _b;
|
|
14007
|
+
if (!this.initialized) {
|
|
14008
|
+
console.warn('[DevSkin] SDK not initialized. Call init() first.');
|
|
14009
|
+
return;
|
|
14010
|
+
}
|
|
14011
|
+
// Generate unique page view ID
|
|
14012
|
+
const pageViewId = this.generateId();
|
|
14013
|
+
// Send to RUM page-views endpoint
|
|
14014
|
+
(_a = this.transport) === null || _a === void 0 ? void 0 : _a.sendPageView(Object.assign({ sessionId: this.sessionId, pageViewId: pageViewId, url: window.location.href, path: window.location.pathname, queryParams: window.location.search, referrer: document.referrer, title: document.title, timestamp: new Date().toISOString() }, properties));
|
|
14015
|
+
// Also track as analytics event for backwards compatibility
|
|
14000
14016
|
this.track('page_view', Object.assign({ path: window.location.pathname, search: window.location.search, hash: window.location.hash, referrer: document.referrer }, properties));
|
|
14017
|
+
if ((_b = this.config) === null || _b === void 0 ? void 0 : _b.debug) {
|
|
14018
|
+
console.log('[DevSkin] Page view tracked:', {
|
|
14019
|
+
sessionId: this.sessionId,
|
|
14020
|
+
pageViewId: pageViewId,
|
|
14021
|
+
url: window.location.href,
|
|
14022
|
+
});
|
|
14023
|
+
}
|
|
14001
14024
|
}
|
|
14002
14025
|
/**
|
|
14003
14026
|
* Identify a user
|
|
@@ -14066,11 +14089,32 @@
|
|
|
14066
14089
|
* Private methods
|
|
14067
14090
|
*/
|
|
14068
14091
|
startSession() {
|
|
14069
|
-
var _a;
|
|
14092
|
+
var _a, _b, _c;
|
|
14093
|
+
// Check if there's an active session (stored in sessionStorage to persist across page navigations)
|
|
14094
|
+
const existingSessionId = sessionStorage.getItem('devskin_session_id');
|
|
14095
|
+
const existingSessionStart = sessionStorage.getItem('devskin_session_start');
|
|
14096
|
+
if (existingSessionId && existingSessionStart) {
|
|
14097
|
+
// Resume existing session
|
|
14098
|
+
this.sessionId = existingSessionId;
|
|
14099
|
+
this.sessionStartTime = parseInt(existingSessionStart, 10);
|
|
14100
|
+
if ((_a = this.config) === null || _a === void 0 ? void 0 : _a.debug) {
|
|
14101
|
+
console.log('[DevSkin] Resuming existing session:', this.sessionId);
|
|
14102
|
+
}
|
|
14103
|
+
// Send page view but DON'T create a new session
|
|
14104
|
+
// The session is already created, just continue it
|
|
14105
|
+
return;
|
|
14106
|
+
}
|
|
14107
|
+
// Create new session
|
|
14070
14108
|
this.sessionId = this.generateId();
|
|
14071
14109
|
this.sessionStartTime = Date.now();
|
|
14110
|
+
// Store in sessionStorage (persists across page navigations in same tab)
|
|
14111
|
+
sessionStorage.setItem('devskin_session_id', this.sessionId);
|
|
14112
|
+
sessionStorage.setItem('devskin_session_start', this.sessionStartTime.toString());
|
|
14072
14113
|
const sessionData = Object.assign({ session_id: this.sessionId, user_id: this.userId || undefined, anonymous_id: this.anonymousId, started_at: new Date().toISOString() }, this.getContextData());
|
|
14073
|
-
(
|
|
14114
|
+
(_b = this.transport) === null || _b === void 0 ? void 0 : _b.startSession(sessionData);
|
|
14115
|
+
if ((_c = this.config) === null || _c === void 0 ? void 0 : _c.debug) {
|
|
14116
|
+
console.log('[DevSkin] New session created:', this.sessionId);
|
|
14117
|
+
}
|
|
14074
14118
|
}
|
|
14075
14119
|
getContextData() {
|
|
14076
14120
|
const context = {};
|
|
@@ -14107,17 +14151,45 @@
|
|
|
14107
14151
|
});
|
|
14108
14152
|
}
|
|
14109
14153
|
setupUnloadTracking() {
|
|
14110
|
-
|
|
14154
|
+
// CRITICAL: Flush data BEFORE page unloads to avoid losing final events
|
|
14155
|
+
// 1. visibilitychange - fires when tab is hidden (most reliable)
|
|
14156
|
+
document.addEventListener('visibilitychange', () => {
|
|
14111
14157
|
var _a, _b;
|
|
14112
|
-
|
|
14113
|
-
|
|
14114
|
-
|
|
14115
|
-
|
|
14116
|
-
|
|
14117
|
-
|
|
14158
|
+
if (document.hidden) {
|
|
14159
|
+
// User switched tabs or minimized - flush immediately
|
|
14160
|
+
(_a = this.rrwebRecorder) === null || _a === void 0 ? void 0 : _a.stop(); // Stop recording and flush
|
|
14161
|
+
(_b = this.transport) === null || _b === void 0 ? void 0 : _b.flush(true); // Use beacon
|
|
14162
|
+
}
|
|
14163
|
+
});
|
|
14164
|
+
// 2. pagehide - fires when page is being unloaded
|
|
14165
|
+
window.addEventListener('pagehide', (event) => {
|
|
14166
|
+
var _a, _b, _c;
|
|
14167
|
+
const isActualClose = !event.persisted;
|
|
14168
|
+
if (isActualClose) {
|
|
14169
|
+
// Tab is closing - end session
|
|
14170
|
+
this.track('page_unload');
|
|
14171
|
+
if (this.sessionId && this.sessionStartTime) {
|
|
14172
|
+
const endedAt = new Date();
|
|
14173
|
+
const durationMs = Date.now() - this.sessionStartTime;
|
|
14174
|
+
(_a = this.transport) === null || _a === void 0 ? void 0 : _a.startSession(Object.assign({ session_id: this.sessionId, user_id: this.userId || undefined, anonymous_id: this.anonymousId, ended_at: endedAt.toISOString(), duration_ms: durationMs }, this.getContextData()));
|
|
14175
|
+
// Clear session storage since session is ending
|
|
14176
|
+
sessionStorage.removeItem('devskin_session_id');
|
|
14177
|
+
sessionStorage.removeItem('devskin_session_start');
|
|
14178
|
+
}
|
|
14179
|
+
}
|
|
14180
|
+
else {
|
|
14181
|
+
// Navigation - track page change
|
|
14182
|
+
this.track('page_navigation');
|
|
14118
14183
|
}
|
|
14119
|
-
//
|
|
14120
|
-
(_b = this.
|
|
14184
|
+
// ALWAYS flush (whether navigation or close)
|
|
14185
|
+
(_b = this.rrwebRecorder) === null || _b === void 0 ? void 0 : _b.stop(); // Stop recording and flush remaining events
|
|
14186
|
+
(_c = this.transport) === null || _c === void 0 ? void 0 : _c.flush(true); // Use beacon for reliability
|
|
14187
|
+
});
|
|
14188
|
+
// 3. beforeunload - backup for older browsers
|
|
14189
|
+
window.addEventListener('beforeunload', () => {
|
|
14190
|
+
var _a, _b;
|
|
14191
|
+
(_a = this.rrwebRecorder) === null || _a === void 0 ? void 0 : _a.stop();
|
|
14192
|
+
(_b = this.transport) === null || _b === void 0 ? void 0 : _b.flush(true);
|
|
14121
14193
|
});
|
|
14122
14194
|
}
|
|
14123
14195
|
}
|