@devskin/browser-sdk 1.0.29 → 1.0.31

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.
@@ -334,12 +334,12 @@ class PerformanceCollector {
334
334
  if (this.config.debug) {
335
335
  console.log(`[DevSkin] Web Vital ${metric.name}:`, metric.value);
336
336
  }
337
- // Send metric to backend
337
+ // Send metric to backend - match backend schema
338
338
  this.transport.sendPerformanceMetric({
339
- name: metric.name,
339
+ metricName: metric.name, // Changed from 'name' to 'metricName'
340
340
  value: metric.value,
341
341
  rating: metric.rating,
342
- delta: metric.delta,
342
+ url: window.location.href,
343
343
  timestamp: new Date().toISOString(),
344
344
  });
345
345
  }
@@ -362,19 +362,9 @@ class PerformanceCollector {
362
362
  });
363
363
  }
364
364
  this.transport.sendPerformanceMetric({
365
- name: 'Navigation',
365
+ metricName: 'Navigation',
366
366
  value: windowLoad,
367
- details: {
368
- domLoad,
369
- windowLoad,
370
- navigationType: navigation.type,
371
- redirectCount: navigation.redirectCount,
372
- dns: timing.domainLookupEnd - timing.domainLookupStart,
373
- tcp: timing.connectEnd - timing.connectStart,
374
- request: timing.responseStart - timing.requestStart,
375
- response: timing.responseEnd - timing.responseStart,
376
- dom: timing.domComplete - timing.domLoading,
377
- },
367
+ url: window.location.href,
378
368
  timestamp: new Date().toISOString(),
379
369
  });
380
370
  }, 0);
@@ -408,9 +398,9 @@ class PerformanceCollector {
408
398
  console.log('[DevSkin] Resource Timings:', resourceStats);
409
399
  }
410
400
  this.transport.sendPerformanceMetric({
411
- name: 'Resources',
401
+ metricName: 'Resources',
412
402
  value: resources.length,
413
- details: resourceStats,
403
+ url: window.location.href,
414
404
  timestamp: new Date().toISOString(),
415
405
  });
416
406
  }, 1000);
@@ -427,13 +417,9 @@ class PerformanceCollector {
427
417
  console.log('[DevSkin] Long Task detected:', entry);
428
418
  }
429
419
  this.transport.sendPerformanceMetric({
430
- name: 'LongTask',
420
+ metricName: 'LongTask',
431
421
  value: entry.duration,
432
- details: {
433
- name: entry.name,
434
- entryType: entry.entryType,
435
- startTime: entry.startTime,
436
- },
422
+ url: window.location.href,
437
423
  timestamp: new Date().toISOString(),
438
424
  });
439
425
  }
@@ -673,7 +659,7 @@ class NetworkCollector {
673
659
  return;
674
660
  const originalFetch = window.fetch;
675
661
  window.fetch = (...args) => __awaiter$1(this, void 0, void 0, function* () {
676
- var _a, _b, _c;
662
+ var _a, _b;
677
663
  const [resource, config] = args;
678
664
  const url = typeof resource === 'string'
679
665
  ? resource
@@ -699,26 +685,18 @@ class NetworkCollector {
699
685
  const networkRequest = {
700
686
  url,
701
687
  method,
702
- status: response.status,
703
- duration,
704
- size: yield this.getResponseSize(clonedResponse),
705
- type: 'fetch',
688
+ statusCode: response.status,
689
+ durationMs: duration,
690
+ responseSize: yield this.getResponseSize(clonedResponse),
706
691
  timestamp: new Date().toISOString(),
707
- failed: !response.ok,
708
692
  };
709
693
  // Capture headers if enabled
710
694
  if ((_b = this.config.networkRequestOptions) === null || _b === void 0 ? void 0 : _b.captureHeaders) {
711
- networkRequest.headers = this.headersToObject(response.headers);
695
+ networkRequest.responseHeaders = this.headersToObject(response.headers);
712
696
  }
713
- // Capture body if enabled (only for failed requests to avoid performance issues)
714
- if (((_c = this.config.networkRequestOptions) === null || _c === void 0 ? void 0 : _c.captureBody) && !response.ok) {
715
- try {
716
- const text = yield clonedResponse.text();
717
- networkRequest.body = text.substring(0, 10000); // Limit to 10KB
718
- }
719
- catch (error) {
720
- // Body might not be readable
721
- }
697
+ // Capture error message for failed requests
698
+ if (!response.ok) {
699
+ networkRequest.errorMessage = `HTTP ${response.status} ${response.statusText}`;
722
700
  }
723
701
  if (this.config.debug) {
724
702
  console.log('[DevSkin] Network request tracked:', networkRequest);
@@ -732,10 +710,9 @@ class NetworkCollector {
732
710
  const networkRequest = {
733
711
  url,
734
712
  method,
735
- duration,
736
- type: 'fetch',
713
+ durationMs: duration,
737
714
  timestamp: new Date().toISOString(),
738
- failed: true,
715
+ errorMessage: error instanceof Error ? error.message : 'Network request failed',
739
716
  };
740
717
  if (this.config.debug) {
741
718
  console.log('[DevSkin] Network request failed:', networkRequest);
@@ -774,7 +751,7 @@ class NetworkCollector {
774
751
  const collector = window.__devskinNetworkCollector;
775
752
  // Track when request completes
776
753
  const handleLoad = () => {
777
- var _a, _b, _c, _d;
754
+ var _a, _b;
778
755
  const duration = Date.now() - devskin.startTime;
779
756
  // Check if should be ignored
780
757
  if (collector === null || collector === void 0 ? void 0 : collector.shouldIgnoreUrl(devskin.url)) {
@@ -789,25 +766,17 @@ class NetworkCollector {
789
766
  const networkRequest = {
790
767
  url: devskin.url,
791
768
  method: devskin.method,
792
- status: xhr.status,
793
- duration,
794
- type: 'xhr',
769
+ statusCode: xhr.status,
770
+ durationMs: duration,
795
771
  timestamp: new Date().toISOString(),
796
- failed: xhr.status === 0 || xhr.status >= 400,
797
772
  };
798
773
  // Capture headers if enabled
799
774
  if ((_b = collector === null || collector === void 0 ? void 0 : collector.config.networkRequestOptions) === null || _b === void 0 ? void 0 : _b.captureHeaders) {
800
- networkRequest.headers = collector.parseResponseHeaders(xhr.getAllResponseHeaders());
775
+ networkRequest.responseHeaders = collector.parseResponseHeaders(xhr.getAllResponseHeaders());
801
776
  }
802
- // Capture body if enabled (only for failed requests)
803
- if (((_c = collector === null || collector === void 0 ? void 0 : collector.config.networkRequestOptions) === null || _c === void 0 ? void 0 : _c.captureBody) &&
804
- networkRequest.failed) {
805
- try {
806
- networkRequest.body = (_d = xhr.responseText) === null || _d === void 0 ? void 0 : _d.substring(0, 10000);
807
- }
808
- catch (error) {
809
- // Response might not be readable
810
- }
777
+ // Capture error message for failed requests
778
+ if (xhr.status === 0 || xhr.status >= 400) {
779
+ networkRequest.errorMessage = `HTTP ${xhr.status} ${xhr.statusText}`;
811
780
  }
812
781
  if (collector === null || collector === void 0 ? void 0 : collector.config.debug) {
813
782
  console.log('[DevSkin] XHR request tracked:', networkRequest);
@@ -820,10 +789,9 @@ class NetworkCollector {
820
789
  const networkRequest = {
821
790
  url: devskin.url,
822
791
  method: devskin.method,
823
- duration,
824
- type: 'xhr',
792
+ durationMs: duration,
825
793
  timestamp: new Date().toISOString(),
826
- failed: true,
794
+ errorMessage: 'XHR request failed',
827
795
  };
828
796
  if (collector === null || collector === void 0 ? void 0 : collector.config.debug) {
829
797
  console.log('[DevSkin] XHR request failed:', networkRequest);
@@ -13586,6 +13554,7 @@ class Transport {
13586
13554
  this.flushInterval = null;
13587
13555
  this.maxQueueSize = 20; // Reduced from 50
13588
13556
  this.flushIntervalMs = 2000; // 2 seconds (reduced from 5s)
13557
+ this.sessionId = null;
13589
13558
  this.apiUrl = config.apiUrl || 'https://api.devskin.com';
13590
13559
  // Start periodic flush
13591
13560
  this.startPeriodicFlush();
@@ -13602,6 +13571,9 @@ class Transport {
13602
13571
  });
13603
13572
  }
13604
13573
  }
13574
+ setSessionId(sessionId) {
13575
+ this.sessionId = sessionId;
13576
+ }
13605
13577
  sendEvent(event) {
13606
13578
  this.enqueue('event', event);
13607
13579
  }
@@ -13692,7 +13664,7 @@ class Transport {
13692
13664
  }
13693
13665
  const items = [...this.queue];
13694
13666
  this.queue = [];
13695
- // Group items by type
13667
+ // Group by type
13696
13668
  const grouped = {};
13697
13669
  items.forEach((item) => {
13698
13670
  if (!grouped[item.type]) {
@@ -13700,19 +13672,39 @@ class Transport {
13700
13672
  }
13701
13673
  grouped[item.type].push(item.data);
13702
13674
  });
13703
- // Send each group
13704
- Object.entries(grouped).forEach(([type, data]) => {
13675
+ // Send each type appropriately
13676
+ Object.entries(grouped).forEach(([type, dataArray]) => {
13705
13677
  const endpoint = this.getEndpointForType(type);
13706
- this.sendToBackend(endpoint, { [type + 's']: data }, useBeacon);
13678
+ if (type === 'event' && dataArray.length > 1) {
13679
+ // Events with batch support
13680
+ this.sendToBackend('/v1/rum/events/batch', { events: dataArray }, useBeacon);
13681
+ }
13682
+ else if (type === 'heatmap') {
13683
+ // Heatmap expects array format
13684
+ this.sendToBackend(endpoint, { heatmaps: dataArray }, useBeacon);
13685
+ }
13686
+ else {
13687
+ // Send each item individually (network, performance, error)
13688
+ dataArray.forEach((data) => {
13689
+ this.sendToBackend(endpoint, data, useBeacon);
13690
+ });
13691
+ }
13707
13692
  });
13708
13693
  if (this.config.debug) {
13709
13694
  console.log(`[DevSkin] Flushed ${items.length} items to backend`);
13710
13695
  }
13711
13696
  }
13712
13697
  enqueue(type, data) {
13713
- // Add applicationId to RUM events (event, error, network, performance)
13698
+ // Add applicationId and sessionId to RUM events (event, error, network, performance)
13714
13699
  // Heatmap uses apiKey/appId in payload root instead
13715
- const enrichedData = type !== 'heatmap' ? Object.assign(Object.assign({}, data), { applicationId: this.config.appId }) : data;
13700
+ let enrichedData = data;
13701
+ if (type !== 'heatmap') {
13702
+ enrichedData = Object.assign(Object.assign({}, data), { applicationId: this.config.appId });
13703
+ // Add sessionId to network and performance requests (required by backend)
13704
+ if ((type === 'network' || type === 'performance') && this.sessionId) {
13705
+ enrichedData.sessionId = this.sessionId;
13706
+ }
13707
+ }
13716
13708
  this.queue.push({
13717
13709
  type,
13718
13710
  data: enrichedData,
@@ -14086,7 +14078,7 @@ class DevSkinSDK {
14086
14078
  * Private methods
14087
14079
  */
14088
14080
  startSession() {
14089
- var _a, _b, _c;
14081
+ var _a, _b, _c, _d, _e;
14090
14082
  // Check if there's an active session (stored in sessionStorage to persist across page navigations)
14091
14083
  const existingSessionId = sessionStorage.getItem('devskin_session_id');
14092
14084
  const existingSessionStart = sessionStorage.getItem('devskin_session_start');
@@ -14094,7 +14086,9 @@ class DevSkinSDK {
14094
14086
  // Resume existing session
14095
14087
  this.sessionId = existingSessionId;
14096
14088
  this.sessionStartTime = parseInt(existingSessionStart, 10);
14097
- if ((_a = this.config) === null || _a === void 0 ? void 0 : _a.debug) {
14089
+ // Set sessionId in transport so it can be added to network/performance requests
14090
+ (_a = this.transport) === null || _a === void 0 ? void 0 : _a.setSessionId(this.sessionId);
14091
+ if ((_b = this.config) === null || _b === void 0 ? void 0 : _b.debug) {
14098
14092
  console.log('[DevSkin] Resuming existing session:', this.sessionId);
14099
14093
  }
14100
14094
  // Send page view but DON'T create a new session
@@ -14107,9 +14101,11 @@ class DevSkinSDK {
14107
14101
  // Store in sessionStorage (persists across page navigations in same tab)
14108
14102
  sessionStorage.setItem('devskin_session_id', this.sessionId);
14109
14103
  sessionStorage.setItem('devskin_session_start', this.sessionStartTime.toString());
14104
+ // Set sessionId in transport so it can be added to network/performance requests
14105
+ (_c = this.transport) === null || _c === void 0 ? void 0 : _c.setSessionId(this.sessionId);
14110
14106
  const sessionData = Object.assign({ sessionId: this.sessionId, userId: this.userId || undefined, anonymousId: this.anonymousId, startedAt: new Date().toISOString(), platform: 'web' }, this.getContextData());
14111
- (_b = this.transport) === null || _b === void 0 ? void 0 : _b.startSession(sessionData);
14112
- if ((_c = this.config) === null || _c === void 0 ? void 0 : _c.debug) {
14107
+ (_d = this.transport) === null || _d === void 0 ? void 0 : _d.startSession(sessionData);
14108
+ if ((_e = this.config) === null || _e === void 0 ? void 0 : _e.debug) {
14113
14109
  console.log('[DevSkin] New session created:', this.sessionId);
14114
14110
  }
14115
14111
  }