@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.
@@ -340,12 +340,12 @@
340
340
  if (this.config.debug) {
341
341
  console.log(`[DevSkin] Web Vital ${metric.name}:`, metric.value);
342
342
  }
343
- // Send metric to backend
343
+ // Send metric to backend - match backend schema
344
344
  this.transport.sendPerformanceMetric({
345
- name: metric.name,
345
+ metricName: metric.name, // Changed from 'name' to 'metricName'
346
346
  value: metric.value,
347
347
  rating: metric.rating,
348
- delta: metric.delta,
348
+ url: window.location.href,
349
349
  timestamp: new Date().toISOString(),
350
350
  });
351
351
  }
@@ -368,19 +368,9 @@
368
368
  });
369
369
  }
370
370
  this.transport.sendPerformanceMetric({
371
- name: 'Navigation',
371
+ metricName: 'Navigation',
372
372
  value: windowLoad,
373
- details: {
374
- domLoad,
375
- windowLoad,
376
- navigationType: navigation.type,
377
- redirectCount: navigation.redirectCount,
378
- dns: timing.domainLookupEnd - timing.domainLookupStart,
379
- tcp: timing.connectEnd - timing.connectStart,
380
- request: timing.responseStart - timing.requestStart,
381
- response: timing.responseEnd - timing.responseStart,
382
- dom: timing.domComplete - timing.domLoading,
383
- },
373
+ url: window.location.href,
384
374
  timestamp: new Date().toISOString(),
385
375
  });
386
376
  }, 0);
@@ -414,9 +404,9 @@
414
404
  console.log('[DevSkin] Resource Timings:', resourceStats);
415
405
  }
416
406
  this.transport.sendPerformanceMetric({
417
- name: 'Resources',
407
+ metricName: 'Resources',
418
408
  value: resources.length,
419
- details: resourceStats,
409
+ url: window.location.href,
420
410
  timestamp: new Date().toISOString(),
421
411
  });
422
412
  }, 1000);
@@ -433,13 +423,9 @@
433
423
  console.log('[DevSkin] Long Task detected:', entry);
434
424
  }
435
425
  this.transport.sendPerformanceMetric({
436
- name: 'LongTask',
426
+ metricName: 'LongTask',
437
427
  value: entry.duration,
438
- details: {
439
- name: entry.name,
440
- entryType: entry.entryType,
441
- startTime: entry.startTime,
442
- },
428
+ url: window.location.href,
443
429
  timestamp: new Date().toISOString(),
444
430
  });
445
431
  }
@@ -679,7 +665,7 @@
679
665
  return;
680
666
  const originalFetch = window.fetch;
681
667
  window.fetch = (...args) => __awaiter$1(this, void 0, void 0, function* () {
682
- var _a, _b, _c;
668
+ var _a, _b;
683
669
  const [resource, config] = args;
684
670
  const url = typeof resource === 'string'
685
671
  ? resource
@@ -705,26 +691,18 @@
705
691
  const networkRequest = {
706
692
  url,
707
693
  method,
708
- status: response.status,
709
- duration,
710
- size: yield this.getResponseSize(clonedResponse),
711
- type: 'fetch',
694
+ statusCode: response.status,
695
+ durationMs: duration,
696
+ responseSize: yield this.getResponseSize(clonedResponse),
712
697
  timestamp: new Date().toISOString(),
713
- failed: !response.ok,
714
698
  };
715
699
  // Capture headers if enabled
716
700
  if ((_b = this.config.networkRequestOptions) === null || _b === void 0 ? void 0 : _b.captureHeaders) {
717
- networkRequest.headers = this.headersToObject(response.headers);
701
+ networkRequest.responseHeaders = this.headersToObject(response.headers);
718
702
  }
719
- // Capture body if enabled (only for failed requests to avoid performance issues)
720
- if (((_c = this.config.networkRequestOptions) === null || _c === void 0 ? void 0 : _c.captureBody) && !response.ok) {
721
- try {
722
- const text = yield clonedResponse.text();
723
- networkRequest.body = text.substring(0, 10000); // Limit to 10KB
724
- }
725
- catch (error) {
726
- // Body might not be readable
727
- }
703
+ // Capture error message for failed requests
704
+ if (!response.ok) {
705
+ networkRequest.errorMessage = `HTTP ${response.status} ${response.statusText}`;
728
706
  }
729
707
  if (this.config.debug) {
730
708
  console.log('[DevSkin] Network request tracked:', networkRequest);
@@ -738,10 +716,9 @@
738
716
  const networkRequest = {
739
717
  url,
740
718
  method,
741
- duration,
742
- type: 'fetch',
719
+ durationMs: duration,
743
720
  timestamp: new Date().toISOString(),
744
- failed: true,
721
+ errorMessage: error instanceof Error ? error.message : 'Network request failed',
745
722
  };
746
723
  if (this.config.debug) {
747
724
  console.log('[DevSkin] Network request failed:', networkRequest);
@@ -780,7 +757,7 @@
780
757
  const collector = window.__devskinNetworkCollector;
781
758
  // Track when request completes
782
759
  const handleLoad = () => {
783
- var _a, _b, _c, _d;
760
+ var _a, _b;
784
761
  const duration = Date.now() - devskin.startTime;
785
762
  // Check if should be ignored
786
763
  if (collector === null || collector === void 0 ? void 0 : collector.shouldIgnoreUrl(devskin.url)) {
@@ -795,25 +772,17 @@
795
772
  const networkRequest = {
796
773
  url: devskin.url,
797
774
  method: devskin.method,
798
- status: xhr.status,
799
- duration,
800
- type: 'xhr',
775
+ statusCode: xhr.status,
776
+ durationMs: duration,
801
777
  timestamp: new Date().toISOString(),
802
- failed: xhr.status === 0 || xhr.status >= 400,
803
778
  };
804
779
  // Capture headers if enabled
805
780
  if ((_b = collector === null || collector === void 0 ? void 0 : collector.config.networkRequestOptions) === null || _b === void 0 ? void 0 : _b.captureHeaders) {
806
- networkRequest.headers = collector.parseResponseHeaders(xhr.getAllResponseHeaders());
781
+ networkRequest.responseHeaders = collector.parseResponseHeaders(xhr.getAllResponseHeaders());
807
782
  }
808
- // Capture body if enabled (only for failed requests)
809
- if (((_c = collector === null || collector === void 0 ? void 0 : collector.config.networkRequestOptions) === null || _c === void 0 ? void 0 : _c.captureBody) &&
810
- networkRequest.failed) {
811
- try {
812
- networkRequest.body = (_d = xhr.responseText) === null || _d === void 0 ? void 0 : _d.substring(0, 10000);
813
- }
814
- catch (error) {
815
- // Response might not be readable
816
- }
783
+ // Capture error message for failed requests
784
+ if (xhr.status === 0 || xhr.status >= 400) {
785
+ networkRequest.errorMessage = `HTTP ${xhr.status} ${xhr.statusText}`;
817
786
  }
818
787
  if (collector === null || collector === void 0 ? void 0 : collector.config.debug) {
819
788
  console.log('[DevSkin] XHR request tracked:', networkRequest);
@@ -826,10 +795,9 @@
826
795
  const networkRequest = {
827
796
  url: devskin.url,
828
797
  method: devskin.method,
829
- duration,
830
- type: 'xhr',
798
+ durationMs: duration,
831
799
  timestamp: new Date().toISOString(),
832
- failed: true,
800
+ errorMessage: 'XHR request failed',
833
801
  };
834
802
  if (collector === null || collector === void 0 ? void 0 : collector.config.debug) {
835
803
  console.log('[DevSkin] XHR request failed:', networkRequest);
@@ -13592,6 +13560,7 @@
13592
13560
  this.flushInterval = null;
13593
13561
  this.maxQueueSize = 20; // Reduced from 50
13594
13562
  this.flushIntervalMs = 2000; // 2 seconds (reduced from 5s)
13563
+ this.sessionId = null;
13595
13564
  this.apiUrl = config.apiUrl || 'https://api.devskin.com';
13596
13565
  // Start periodic flush
13597
13566
  this.startPeriodicFlush();
@@ -13608,6 +13577,9 @@
13608
13577
  });
13609
13578
  }
13610
13579
  }
13580
+ setSessionId(sessionId) {
13581
+ this.sessionId = sessionId;
13582
+ }
13611
13583
  sendEvent(event) {
13612
13584
  this.enqueue('event', event);
13613
13585
  }
@@ -13698,7 +13670,7 @@
13698
13670
  }
13699
13671
  const items = [...this.queue];
13700
13672
  this.queue = [];
13701
- // Group items by type
13673
+ // Group by type
13702
13674
  const grouped = {};
13703
13675
  items.forEach((item) => {
13704
13676
  if (!grouped[item.type]) {
@@ -13706,19 +13678,39 @@
13706
13678
  }
13707
13679
  grouped[item.type].push(item.data);
13708
13680
  });
13709
- // Send each group
13710
- Object.entries(grouped).forEach(([type, data]) => {
13681
+ // Send each type appropriately
13682
+ Object.entries(grouped).forEach(([type, dataArray]) => {
13711
13683
  const endpoint = this.getEndpointForType(type);
13712
- this.sendToBackend(endpoint, { [type + 's']: data }, useBeacon);
13684
+ if (type === 'event' && dataArray.length > 1) {
13685
+ // Events with batch support
13686
+ this.sendToBackend('/v1/rum/events/batch', { events: dataArray }, useBeacon);
13687
+ }
13688
+ else if (type === 'heatmap') {
13689
+ // Heatmap expects array format
13690
+ this.sendToBackend(endpoint, { heatmaps: dataArray }, useBeacon);
13691
+ }
13692
+ else {
13693
+ // Send each item individually (network, performance, error)
13694
+ dataArray.forEach((data) => {
13695
+ this.sendToBackend(endpoint, data, useBeacon);
13696
+ });
13697
+ }
13713
13698
  });
13714
13699
  if (this.config.debug) {
13715
13700
  console.log(`[DevSkin] Flushed ${items.length} items to backend`);
13716
13701
  }
13717
13702
  }
13718
13703
  enqueue(type, data) {
13719
- // Add applicationId to RUM events (event, error, network, performance)
13704
+ // Add applicationId and sessionId to RUM events (event, error, network, performance)
13720
13705
  // Heatmap uses apiKey/appId in payload root instead
13721
- const enrichedData = type !== 'heatmap' ? Object.assign(Object.assign({}, data), { applicationId: this.config.appId }) : data;
13706
+ let enrichedData = data;
13707
+ if (type !== 'heatmap') {
13708
+ enrichedData = Object.assign(Object.assign({}, data), { applicationId: this.config.appId });
13709
+ // Add sessionId to network and performance requests (required by backend)
13710
+ if ((type === 'network' || type === 'performance') && this.sessionId) {
13711
+ enrichedData.sessionId = this.sessionId;
13712
+ }
13713
+ }
13722
13714
  this.queue.push({
13723
13715
  type,
13724
13716
  data: enrichedData,
@@ -14092,7 +14084,7 @@
14092
14084
  * Private methods
14093
14085
  */
14094
14086
  startSession() {
14095
- var _a, _b, _c;
14087
+ var _a, _b, _c, _d, _e;
14096
14088
  // Check if there's an active session (stored in sessionStorage to persist across page navigations)
14097
14089
  const existingSessionId = sessionStorage.getItem('devskin_session_id');
14098
14090
  const existingSessionStart = sessionStorage.getItem('devskin_session_start');
@@ -14100,7 +14092,9 @@
14100
14092
  // Resume existing session
14101
14093
  this.sessionId = existingSessionId;
14102
14094
  this.sessionStartTime = parseInt(existingSessionStart, 10);
14103
- if ((_a = this.config) === null || _a === void 0 ? void 0 : _a.debug) {
14095
+ // Set sessionId in transport so it can be added to network/performance requests
14096
+ (_a = this.transport) === null || _a === void 0 ? void 0 : _a.setSessionId(this.sessionId);
14097
+ if ((_b = this.config) === null || _b === void 0 ? void 0 : _b.debug) {
14104
14098
  console.log('[DevSkin] Resuming existing session:', this.sessionId);
14105
14099
  }
14106
14100
  // Send page view but DON'T create a new session
@@ -14113,9 +14107,11 @@
14113
14107
  // Store in sessionStorage (persists across page navigations in same tab)
14114
14108
  sessionStorage.setItem('devskin_session_id', this.sessionId);
14115
14109
  sessionStorage.setItem('devskin_session_start', this.sessionStartTime.toString());
14110
+ // Set sessionId in transport so it can be added to network/performance requests
14111
+ (_c = this.transport) === null || _c === void 0 ? void 0 : _c.setSessionId(this.sessionId);
14116
14112
  const sessionData = Object.assign({ sessionId: this.sessionId, userId: this.userId || undefined, anonymousId: this.anonymousId, startedAt: new Date().toISOString(), platform: 'web' }, this.getContextData());
14117
- (_b = this.transport) === null || _b === void 0 ? void 0 : _b.startSession(sessionData);
14118
- if ((_c = this.config) === null || _c === void 0 ? void 0 : _c.debug) {
14113
+ (_d = this.transport) === null || _d === void 0 ? void 0 : _d.startSession(sessionData);
14114
+ if ((_e = this.config) === null || _e === void 0 ? void 0 : _e.debug) {
14119
14115
  console.log('[DevSkin] New session created:', this.sessionId);
14120
14116
  }
14121
14117
  }