@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.esm.js
CHANGED
|
@@ -4983,6 +4983,7 @@ class RRWebRecorder {
|
|
|
4983
4983
|
this.events = [];
|
|
4984
4984
|
this.onEventsReady = null;
|
|
4985
4985
|
this.flushInterval = null;
|
|
4986
|
+
this.hasFullSnapshot = false;
|
|
4986
4987
|
this.sessionId = sessionId;
|
|
4987
4988
|
this.config = config;
|
|
4988
4989
|
this.onEventsReady = onEventsReady;
|
|
@@ -5000,9 +5001,15 @@ class RRWebRecorder {
|
|
|
5000
5001
|
console.log('[RRWeb] Starting session recording:', this.sessionId);
|
|
5001
5002
|
this.stopFn = record({
|
|
5002
5003
|
emit: (event) => {
|
|
5004
|
+
// Check if this is a FullSnapshot (type 2)
|
|
5005
|
+
if (event.type === 2) {
|
|
5006
|
+
this.hasFullSnapshot = true;
|
|
5007
|
+
console.log('[RRWeb] FullSnapshot captured! Recording is ready.');
|
|
5008
|
+
}
|
|
5003
5009
|
this.events.push(event);
|
|
5004
|
-
//
|
|
5005
|
-
|
|
5010
|
+
// Only flush if we have the FullSnapshot
|
|
5011
|
+
// This ensures the first batch always contains the full DOM
|
|
5012
|
+
if (this.hasFullSnapshot && this.events.length >= 50) {
|
|
5006
5013
|
this.flush();
|
|
5007
5014
|
}
|
|
5008
5015
|
},
|
|
@@ -5042,8 +5049,9 @@ class RRWebRecorder {
|
|
|
5042
5049
|
recordCrossOriginIframes: false, // Security: don't record cross-origin iframes
|
|
5043
5050
|
});
|
|
5044
5051
|
// Set up periodic flush (every 10 seconds)
|
|
5052
|
+
// Only flush if we have FullSnapshot to ensure first batch is complete
|
|
5045
5053
|
this.flushInterval = window.setInterval(() => {
|
|
5046
|
-
if (this.events.length > 0) {
|
|
5054
|
+
if (this.hasFullSnapshot && this.events.length > 0) {
|
|
5047
5055
|
this.flush();
|
|
5048
5056
|
}
|
|
5049
5057
|
}, 10000);
|
|
@@ -5063,8 +5071,11 @@ class RRWebRecorder {
|
|
|
5063
5071
|
clearInterval(this.flushInterval);
|
|
5064
5072
|
this.flushInterval = null;
|
|
5065
5073
|
}
|
|
5066
|
-
// Flush remaining events
|
|
5074
|
+
// Flush remaining events (even without FullSnapshot, to not lose data)
|
|
5067
5075
|
if (this.events.length > 0) {
|
|
5076
|
+
if (!this.hasFullSnapshot) {
|
|
5077
|
+
console.warn('[RRWeb] Flushing events without FullSnapshot - recording may not replay correctly');
|
|
5078
|
+
}
|
|
5068
5079
|
this.flush();
|
|
5069
5080
|
}
|
|
5070
5081
|
}
|
|
@@ -5129,6 +5140,13 @@ class Transport {
|
|
|
5129
5140
|
this.enqueue('performance', metric);
|
|
5130
5141
|
}
|
|
5131
5142
|
sendRecordingEvents(sessionId, events) {
|
|
5143
|
+
// DEBUG: Log event types being sent
|
|
5144
|
+
const eventTypes = events.reduce((acc, e) => {
|
|
5145
|
+
acc[e.type] = (acc[e.type] || 0) + 1;
|
|
5146
|
+
return acc;
|
|
5147
|
+
}, {});
|
|
5148
|
+
console.log(`[DevSkin SDK] Sending ${events.length} recording events:`, eventTypes);
|
|
5149
|
+
console.log(`[DevSkin SDK] First 3 events:`, events.slice(0, 3).map(e => ({ type: e.type, timestamp: e.timestamp })));
|
|
5132
5150
|
// Recording events can be large, send immediately
|
|
5133
5151
|
this.sendToBackend('/v1/rum/recordings', {
|
|
5134
5152
|
session_id: sessionId,
|
|
@@ -5258,6 +5276,7 @@ class DevSkinSDK {
|
|
|
5258
5276
|
this.sessionId = null;
|
|
5259
5277
|
this.userId = null;
|
|
5260
5278
|
this.anonymousId = null;
|
|
5279
|
+
this.sessionStartTime = 0;
|
|
5261
5280
|
this.initialized = false;
|
|
5262
5281
|
// Collectors
|
|
5263
5282
|
this.deviceCollector = null;
|
|
@@ -5287,12 +5306,12 @@ class DevSkinSDK {
|
|
|
5287
5306
|
this.transport = new Transport(this.config);
|
|
5288
5307
|
// Generate anonymous ID if not exists
|
|
5289
5308
|
this.anonymousId = this.getOrCreateAnonymousId();
|
|
5290
|
-
//
|
|
5291
|
-
this.startSession();
|
|
5292
|
-
// Initialize collectors
|
|
5309
|
+
// Initialize collectors BEFORE starting session (so getContextData works)
|
|
5293
5310
|
this.deviceCollector = new DeviceCollector(this.config);
|
|
5294
5311
|
this.locationCollector = new LocationCollector(this.config);
|
|
5295
5312
|
this.browserCollector = new BrowserCollector(this.config);
|
|
5313
|
+
// Start session (will now include device/browser/location data)
|
|
5314
|
+
this.startSession();
|
|
5296
5315
|
if (this.config.captureWebVitals) {
|
|
5297
5316
|
this.performanceCollector = new PerformanceCollector(this.config, this.transport);
|
|
5298
5317
|
this.performanceCollector.start();
|
|
@@ -5452,6 +5471,7 @@ class DevSkinSDK {
|
|
|
5452
5471
|
startSession() {
|
|
5453
5472
|
var _a;
|
|
5454
5473
|
this.sessionId = this.generateId();
|
|
5474
|
+
this.sessionStartTime = Date.now();
|
|
5455
5475
|
const sessionData = Object.assign({ session_id: this.sessionId, user_id: this.userId || undefined, anonymous_id: this.anonymousId, started_at: new Date().toISOString() }, this.getContextData());
|
|
5456
5476
|
(_a = this.transport) === null || _a === void 0 ? void 0 : _a.startSession(sessionData);
|
|
5457
5477
|
}
|
|
@@ -5491,10 +5511,20 @@ class DevSkinSDK {
|
|
|
5491
5511
|
}
|
|
5492
5512
|
setupUnloadTracking() {
|
|
5493
5513
|
window.addEventListener('beforeunload', () => {
|
|
5494
|
-
var _a;
|
|
5514
|
+
var _a, _b;
|
|
5495
5515
|
this.track('page_unload');
|
|
5516
|
+
// Send session end update with duration
|
|
5517
|
+
if (this.sessionId && this.sessionStartTime) {
|
|
5518
|
+
const endedAt = new Date();
|
|
5519
|
+
const durationMs = Date.now() - this.sessionStartTime;
|
|
5520
|
+
(_a = this.transport) === null || _a === void 0 ? void 0 : _a.startSession({
|
|
5521
|
+
session_id: this.sessionId,
|
|
5522
|
+
ended_at: endedAt.toISOString(),
|
|
5523
|
+
duration_ms: durationMs,
|
|
5524
|
+
});
|
|
5525
|
+
}
|
|
5496
5526
|
// Send any pending data
|
|
5497
|
-
(
|
|
5527
|
+
(_b = this.transport) === null || _b === void 0 ? void 0 : _b.flush(true); // Use beacon for reliability
|
|
5498
5528
|
});
|
|
5499
5529
|
}
|
|
5500
5530
|
}
|