@devskin/browser-sdk 1.0.2 → 1.0.4

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.
@@ -637,11 +637,16 @@ class ErrorCollector {
637
637
  console[level] = (...args) => {
638
638
  // Call original
639
639
  original.apply(console, args);
640
- // Add breadcrumb
640
+ // Add breadcrumb (skip DevSkin internal logs to avoid infinite loop)
641
641
  if (level === 'warn' || level === 'error') {
642
+ const message = args.map((arg) => String(arg)).join(' ');
643
+ // Skip DevSkin internal messages
644
+ if (message.startsWith('[DevSkin]')) {
645
+ return;
646
+ }
642
647
  this.addBreadcrumb({
643
648
  category: 'console',
644
- message: args.map((arg) => String(arg)).join(' '),
649
+ message: message,
645
650
  level: level === 'warn' ? 'warning' : 'error',
646
651
  data: { arguments: args },
647
652
  });
@@ -4978,6 +4983,7 @@ class RRWebRecorder {
4978
4983
  this.events = [];
4979
4984
  this.onEventsReady = null;
4980
4985
  this.flushInterval = null;
4986
+ this.hasFullSnapshot = false;
4981
4987
  this.sessionId = sessionId;
4982
4988
  this.config = config;
4983
4989
  this.onEventsReady = onEventsReady;
@@ -4995,9 +5001,15 @@ class RRWebRecorder {
4995
5001
  console.log('[RRWeb] Starting session recording:', this.sessionId);
4996
5002
  this.stopFn = record({
4997
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
+ }
4998
5009
  this.events.push(event);
4999
- // Flush events periodically to avoid memory buildup
5000
- if (this.events.length >= 50) {
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) {
5001
5013
  this.flush();
5002
5014
  }
5003
5015
  },
@@ -5037,8 +5049,9 @@ class RRWebRecorder {
5037
5049
  recordCrossOriginIframes: false, // Security: don't record cross-origin iframes
5038
5050
  });
5039
5051
  // Set up periodic flush (every 10 seconds)
5052
+ // Only flush if we have FullSnapshot to ensure first batch is complete
5040
5053
  this.flushInterval = window.setInterval(() => {
5041
- if (this.events.length > 0) {
5054
+ if (this.hasFullSnapshot && this.events.length > 0) {
5042
5055
  this.flush();
5043
5056
  }
5044
5057
  }, 10000);
@@ -5058,8 +5071,11 @@ class RRWebRecorder {
5058
5071
  clearInterval(this.flushInterval);
5059
5072
  this.flushInterval = null;
5060
5073
  }
5061
- // Flush remaining events
5074
+ // Flush remaining events (even without FullSnapshot, to not lose data)
5062
5075
  if (this.events.length > 0) {
5076
+ if (!this.hasFullSnapshot) {
5077
+ console.warn('[RRWeb] Flushing events without FullSnapshot - recording may not replay correctly');
5078
+ }
5063
5079
  this.flush();
5064
5080
  }
5065
5081
  }
@@ -5124,6 +5140,13 @@ class Transport {
5124
5140
  this.enqueue('performance', metric);
5125
5141
  }
5126
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 })));
5127
5150
  // Recording events can be large, send immediately
5128
5151
  this.sendToBackend('/v1/rum/recordings', {
5129
5152
  session_id: sessionId,