@devskin/browser-sdk 1.0.3 → 1.0.5
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 +39 -9
- package/dist/devskin.cjs.js.map +1 -1
- package/dist/devskin.esm.js +39 -9
- package/dist/devskin.esm.js.map +1 -1
- package/dist/devskin.umd.js +39 -9
- 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 +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/recorder/rrweb.d.ts +1 -0
- package/dist/recorder/rrweb.d.ts.map +1 -1
- package/dist/transport.d.ts.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/devskin.cjs.js
CHANGED
|
@@ -4987,6 +4987,7 @@ class RRWebRecorder {
|
|
|
4987
4987
|
this.events = [];
|
|
4988
4988
|
this.onEventsReady = null;
|
|
4989
4989
|
this.flushInterval = null;
|
|
4990
|
+
this.hasFullSnapshot = false;
|
|
4990
4991
|
this.sessionId = sessionId;
|
|
4991
4992
|
this.config = config;
|
|
4992
4993
|
this.onEventsReady = onEventsReady;
|
|
@@ -5004,9 +5005,15 @@ class RRWebRecorder {
|
|
|
5004
5005
|
console.log('[RRWeb] Starting session recording:', this.sessionId);
|
|
5005
5006
|
this.stopFn = record({
|
|
5006
5007
|
emit: (event) => {
|
|
5008
|
+
// Check if this is a FullSnapshot (type 2)
|
|
5009
|
+
if (event.type === 2) {
|
|
5010
|
+
this.hasFullSnapshot = true;
|
|
5011
|
+
console.log('[RRWeb] FullSnapshot captured! Recording is ready.');
|
|
5012
|
+
}
|
|
5007
5013
|
this.events.push(event);
|
|
5008
|
-
//
|
|
5009
|
-
|
|
5014
|
+
// Only flush if we have the FullSnapshot
|
|
5015
|
+
// This ensures the first batch always contains the full DOM
|
|
5016
|
+
if (this.hasFullSnapshot && this.events.length >= 50) {
|
|
5010
5017
|
this.flush();
|
|
5011
5018
|
}
|
|
5012
5019
|
},
|
|
@@ -5046,8 +5053,9 @@ class RRWebRecorder {
|
|
|
5046
5053
|
recordCrossOriginIframes: false, // Security: don't record cross-origin iframes
|
|
5047
5054
|
});
|
|
5048
5055
|
// Set up periodic flush (every 10 seconds)
|
|
5056
|
+
// Only flush if we have FullSnapshot to ensure first batch is complete
|
|
5049
5057
|
this.flushInterval = window.setInterval(() => {
|
|
5050
|
-
if (this.events.length > 0) {
|
|
5058
|
+
if (this.hasFullSnapshot && this.events.length > 0) {
|
|
5051
5059
|
this.flush();
|
|
5052
5060
|
}
|
|
5053
5061
|
}, 10000);
|
|
@@ -5067,8 +5075,11 @@ class RRWebRecorder {
|
|
|
5067
5075
|
clearInterval(this.flushInterval);
|
|
5068
5076
|
this.flushInterval = null;
|
|
5069
5077
|
}
|
|
5070
|
-
// Flush remaining events
|
|
5078
|
+
// Flush remaining events (even without FullSnapshot, to not lose data)
|
|
5071
5079
|
if (this.events.length > 0) {
|
|
5080
|
+
if (!this.hasFullSnapshot) {
|
|
5081
|
+
console.warn('[RRWeb] Flushing events without FullSnapshot - recording may not replay correctly');
|
|
5082
|
+
}
|
|
5072
5083
|
this.flush();
|
|
5073
5084
|
}
|
|
5074
5085
|
}
|
|
@@ -5133,6 +5144,13 @@ class Transport {
|
|
|
5133
5144
|
this.enqueue('performance', metric);
|
|
5134
5145
|
}
|
|
5135
5146
|
sendRecordingEvents(sessionId, events) {
|
|
5147
|
+
// DEBUG: Log event types being sent
|
|
5148
|
+
const eventTypes = events.reduce((acc, e) => {
|
|
5149
|
+
acc[e.type] = (acc[e.type] || 0) + 1;
|
|
5150
|
+
return acc;
|
|
5151
|
+
}, {});
|
|
5152
|
+
console.log(`[DevSkin SDK] Sending ${events.length} recording events:`, eventTypes);
|
|
5153
|
+
console.log(`[DevSkin SDK] First 3 events:`, events.slice(0, 3).map(e => ({ type: e.type, timestamp: e.timestamp })));
|
|
5136
5154
|
// Recording events can be large, send immediately
|
|
5137
5155
|
this.sendToBackend('/v1/rum/recordings', {
|
|
5138
5156
|
session_id: sessionId,
|
|
@@ -5262,6 +5280,7 @@ class DevSkinSDK {
|
|
|
5262
5280
|
this.sessionId = null;
|
|
5263
5281
|
this.userId = null;
|
|
5264
5282
|
this.anonymousId = null;
|
|
5283
|
+
this.sessionStartTime = 0;
|
|
5265
5284
|
this.initialized = false;
|
|
5266
5285
|
// Collectors
|
|
5267
5286
|
this.deviceCollector = null;
|
|
@@ -5291,12 +5310,12 @@ class DevSkinSDK {
|
|
|
5291
5310
|
this.transport = new Transport(this.config);
|
|
5292
5311
|
// Generate anonymous ID if not exists
|
|
5293
5312
|
this.anonymousId = this.getOrCreateAnonymousId();
|
|
5294
|
-
//
|
|
5295
|
-
this.startSession();
|
|
5296
|
-
// Initialize collectors
|
|
5313
|
+
// Initialize collectors BEFORE starting session (so getContextData works)
|
|
5297
5314
|
this.deviceCollector = new DeviceCollector(this.config);
|
|
5298
5315
|
this.locationCollector = new LocationCollector(this.config);
|
|
5299
5316
|
this.browserCollector = new BrowserCollector(this.config);
|
|
5317
|
+
// Start session (will now include device/browser/location data)
|
|
5318
|
+
this.startSession();
|
|
5300
5319
|
if (this.config.captureWebVitals) {
|
|
5301
5320
|
this.performanceCollector = new PerformanceCollector(this.config, this.transport);
|
|
5302
5321
|
this.performanceCollector.start();
|
|
@@ -5456,6 +5475,7 @@ class DevSkinSDK {
|
|
|
5456
5475
|
startSession() {
|
|
5457
5476
|
var _a;
|
|
5458
5477
|
this.sessionId = this.generateId();
|
|
5478
|
+
this.sessionStartTime = Date.now();
|
|
5459
5479
|
const sessionData = Object.assign({ session_id: this.sessionId, user_id: this.userId || undefined, anonymous_id: this.anonymousId, started_at: new Date().toISOString() }, this.getContextData());
|
|
5460
5480
|
(_a = this.transport) === null || _a === void 0 ? void 0 : _a.startSession(sessionData);
|
|
5461
5481
|
}
|
|
@@ -5495,10 +5515,20 @@ class DevSkinSDK {
|
|
|
5495
5515
|
}
|
|
5496
5516
|
setupUnloadTracking() {
|
|
5497
5517
|
window.addEventListener('beforeunload', () => {
|
|
5498
|
-
var _a;
|
|
5518
|
+
var _a, _b;
|
|
5499
5519
|
this.track('page_unload');
|
|
5520
|
+
// Send session end update with duration
|
|
5521
|
+
if (this.sessionId && this.sessionStartTime) {
|
|
5522
|
+
const endedAt = new Date();
|
|
5523
|
+
const durationMs = Date.now() - this.sessionStartTime;
|
|
5524
|
+
(_a = this.transport) === null || _a === void 0 ? void 0 : _a.startSession({
|
|
5525
|
+
session_id: this.sessionId,
|
|
5526
|
+
ended_at: endedAt.toISOString(),
|
|
5527
|
+
duration_ms: durationMs,
|
|
5528
|
+
});
|
|
5529
|
+
}
|
|
5500
5530
|
// Send any pending data
|
|
5501
|
-
(
|
|
5531
|
+
(_b = this.transport) === null || _b === void 0 ? void 0 : _b.flush(true); // Use beacon for reliability
|
|
5502
5532
|
});
|
|
5503
5533
|
}
|
|
5504
5534
|
}
|