@grafana/faro-web-sdk 1.7.2 → 1.8.0
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/bundle/faro-web-sdk.iife.js +1 -1
- package/dist/bundle/types/instrumentations/console/instrumentation.d.ts +1 -1
- package/dist/bundle/types/instrumentations/errors/instrumentation.d.ts +1 -1
- package/dist/bundle/types/instrumentations/instrumentationConstants.d.ts +1 -0
- package/dist/bundle/types/instrumentations/performance/instrumentation.d.ts +1 -1
- package/dist/bundle/types/instrumentations/performance/performanceConstants.d.ts +0 -1
- package/dist/bundle/types/instrumentations/performance/performanceUtils.d.ts +3 -0
- package/dist/bundle/types/instrumentations/session/instrumentation.d.ts +1 -1
- package/dist/bundle/types/instrumentations/session/sessionManager/sessionConstants.d.ts +3 -0
- package/dist/bundle/types/instrumentations/session/sessionManager/sessionManagerUtils.d.ts +7 -2
- package/dist/bundle/types/instrumentations/session/sessionManager/types.d.ts +3 -0
- package/dist/bundle/types/instrumentations/view/instrumentation.d.ts +1 -1
- package/dist/bundle/types/instrumentations/webVitals/instrumentation.d.ts +2 -9
- package/dist/bundle/types/instrumentations/webVitals/webVitalsBasic.d.ts +14 -0
- package/dist/bundle/types/instrumentations/webVitals/webVitalsWithAttribution.d.ts +16 -0
- package/dist/bundle/types/transports/console/transport.d.ts +1 -1
- package/dist/bundle/types/transports/fetch/transport.d.ts +2 -1
- package/dist/cjs/config/makeCoreConfig.js +8 -6
- package/dist/cjs/config/makeCoreConfig.js.map +1 -1
- package/dist/cjs/instrumentations/instrumentationConstants.js +5 -0
- package/dist/cjs/instrumentations/instrumentationConstants.js.map +1 -0
- package/dist/cjs/instrumentations/performance/navigation.js +7 -4
- package/dist/cjs/instrumentations/performance/navigation.js.map +1 -1
- package/dist/cjs/instrumentations/performance/performanceConstants.js +1 -2
- package/dist/cjs/instrumentations/performance/performanceConstants.js.map +1 -1
- package/dist/cjs/instrumentations/performance/performanceUtils.js +21 -1
- package/dist/cjs/instrumentations/performance/performanceUtils.js.map +1 -1
- package/dist/cjs/instrumentations/performance/performanceUtilsTestData.js +12 -1
- package/dist/cjs/instrumentations/performance/performanceUtilsTestData.js.map +1 -1
- package/dist/cjs/instrumentations/performance/resource.js +2 -1
- package/dist/cjs/instrumentations/performance/resource.js.map +1 -1
- package/dist/cjs/instrumentations/session/instrumentation.js +1 -2
- package/dist/cjs/instrumentations/session/instrumentation.js.map +1 -1
- package/dist/cjs/instrumentations/session/sessionManager/sessionConstants.js +4 -1
- package/dist/cjs/instrumentations/session/sessionManager/sessionConstants.js.map +1 -1
- package/dist/cjs/instrumentations/session/sessionManager/sessionManagerUtils.js +12 -6
- package/dist/cjs/instrumentations/session/sessionManager/sessionManagerUtils.js.map +1 -1
- package/dist/cjs/instrumentations/session/sessionManager/types.js.map +1 -1
- package/dist/cjs/instrumentations/webVitals/instrumentation.js +9 -21
- package/dist/cjs/instrumentations/webVitals/instrumentation.js.map +1 -1
- package/dist/cjs/instrumentations/webVitals/webVitalsBasic.js +35 -0
- package/dist/cjs/instrumentations/webVitals/webVitalsBasic.js.map +1 -0
- package/dist/cjs/instrumentations/webVitals/webVitalsWithAttribution.js +136 -0
- package/dist/cjs/instrumentations/webVitals/webVitalsWithAttribution.js.map +1 -0
- package/dist/cjs/metas/browser/meta.js +2 -0
- package/dist/cjs/metas/browser/meta.js.map +1 -1
- package/dist/cjs/transports/fetch/transport.js +32 -9
- package/dist/cjs/transports/fetch/transport.js.map +1 -1
- package/dist/esm/config/makeCoreConfig.js +9 -7
- package/dist/esm/config/makeCoreConfig.js.map +1 -1
- package/dist/esm/instrumentations/instrumentationConstants.js +2 -0
- package/dist/esm/instrumentations/instrumentationConstants.js.map +1 -0
- package/dist/esm/instrumentations/performance/navigation.js +7 -4
- package/dist/esm/instrumentations/performance/navigation.js.map +1 -1
- package/dist/esm/instrumentations/performance/performanceConstants.js +0 -1
- package/dist/esm/instrumentations/performance/performanceConstants.js.map +1 -1
- package/dist/esm/instrumentations/performance/performanceUtils.js +17 -0
- package/dist/esm/instrumentations/performance/performanceUtils.js.map +1 -1
- package/dist/esm/instrumentations/performance/performanceUtilsTestData.js +12 -1
- package/dist/esm/instrumentations/performance/performanceUtilsTestData.js.map +1 -1
- package/dist/esm/instrumentations/performance/resource.js +3 -2
- package/dist/esm/instrumentations/performance/resource.js.map +1 -1
- package/dist/esm/instrumentations/session/instrumentation.js +2 -3
- package/dist/esm/instrumentations/session/instrumentation.js.map +1 -1
- package/dist/esm/instrumentations/session/sessionManager/sessionConstants.js +4 -1
- package/dist/esm/instrumentations/session/sessionManager/sessionConstants.js.map +1 -1
- package/dist/esm/instrumentations/session/sessionManager/sessionManagerUtils.js +7 -3
- package/dist/esm/instrumentations/session/sessionManager/sessionManagerUtils.js.map +1 -1
- package/dist/esm/instrumentations/session/sessionManager/types.js.map +1 -1
- package/dist/esm/instrumentations/webVitals/instrumentation.js +10 -19
- package/dist/esm/instrumentations/webVitals/instrumentation.js.map +1 -1
- package/dist/esm/instrumentations/webVitals/webVitalsBasic.js +27 -0
- package/dist/esm/instrumentations/webVitals/webVitalsBasic.js.map +1 -0
- package/dist/esm/instrumentations/webVitals/webVitalsWithAttribution.js +124 -0
- package/dist/esm/instrumentations/webVitals/webVitalsWithAttribution.js.map +1 -0
- package/dist/esm/metas/browser/meta.js +2 -0
- package/dist/esm/metas/browser/meta.js.map +1 -1
- package/dist/esm/transports/fetch/transport.js +23 -3
- package/dist/esm/transports/fetch/transport.js.map +1 -1
- package/dist/types/instrumentations/console/instrumentation.d.ts +1 -1
- package/dist/types/instrumentations/errors/instrumentation.d.ts +1 -1
- package/dist/types/instrumentations/instrumentationConstants.d.ts +1 -0
- package/dist/types/instrumentations/performance/instrumentation.d.ts +1 -1
- package/dist/types/instrumentations/performance/performanceConstants.d.ts +0 -1
- package/dist/types/instrumentations/performance/performanceUtils.d.ts +3 -0
- package/dist/types/instrumentations/session/instrumentation.d.ts +1 -1
- package/dist/types/instrumentations/session/sessionManager/sessionConstants.d.ts +3 -0
- package/dist/types/instrumentations/session/sessionManager/sessionManagerUtils.d.ts +7 -2
- package/dist/types/instrumentations/session/sessionManager/types.d.ts +3 -0
- package/dist/types/instrumentations/view/instrumentation.d.ts +1 -1
- package/dist/types/instrumentations/webVitals/instrumentation.d.ts +2 -9
- package/dist/types/instrumentations/webVitals/webVitalsBasic.d.ts +14 -0
- package/dist/types/instrumentations/webVitals/webVitalsWithAttribution.d.ts +16 -0
- package/dist/types/transports/console/transport.d.ts +1 -1
- package/dist/types/transports/fetch/transport.d.ts +2 -1
- package/package.json +4 -4
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WebVitalsWithAttribution = void 0;
|
|
4
|
+
var attribution_1 = require("web-vitals/attribution");
|
|
5
|
+
var utils_1 = require("../../utils");
|
|
6
|
+
var instrumentationConstants_1 = require("../instrumentationConstants");
|
|
7
|
+
// duplicate keys saved in variables to save bundle size
|
|
8
|
+
// refs: https://github.com/grafana/faro-web-sdk/pull/595#discussion_r1615833968
|
|
9
|
+
var loadStateKey = 'load_state';
|
|
10
|
+
var timeToFirstByteKey = 'time_to_first_byte';
|
|
11
|
+
var WebVitalsWithAttribution = /** @class */ (function () {
|
|
12
|
+
function WebVitalsWithAttribution(corePushMeasurement) {
|
|
13
|
+
this.corePushMeasurement = corePushMeasurement;
|
|
14
|
+
}
|
|
15
|
+
WebVitalsWithAttribution.prototype.initialize = function () {
|
|
16
|
+
this.measureCLS();
|
|
17
|
+
this.measureFCP();
|
|
18
|
+
this.measureFID();
|
|
19
|
+
this.measureINP();
|
|
20
|
+
this.measureLCP();
|
|
21
|
+
this.measureTTFB();
|
|
22
|
+
};
|
|
23
|
+
WebVitalsWithAttribution.prototype.measureCLS = function () {
|
|
24
|
+
var _this = this;
|
|
25
|
+
(0, attribution_1.onCLS)(function (metric) {
|
|
26
|
+
var _a = metric.attribution, loadState = _a.loadState, largestShiftValue = _a.largestShiftValue, largestShiftTime = _a.largestShiftTime, largestShiftTarget = _a.largestShiftTarget;
|
|
27
|
+
var values = _this.buildInitialValues(metric);
|
|
28
|
+
_this.addIfPresent(values, 'largest_shift_value', largestShiftValue);
|
|
29
|
+
_this.addIfPresent(values, 'largest_shift_time', largestShiftTime);
|
|
30
|
+
var context = _this.buildInitialContext(metric);
|
|
31
|
+
_this.addIfPresent(context, loadStateKey, loadState);
|
|
32
|
+
_this.addIfPresent(context, 'largest_shift_target', largestShiftTarget);
|
|
33
|
+
_this.pushMeasurement(values, context);
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
WebVitalsWithAttribution.prototype.measureFCP = function () {
|
|
37
|
+
var _this = this;
|
|
38
|
+
(0, attribution_1.onFCP)(function (metric) {
|
|
39
|
+
var _a = metric.attribution, firstByteToFCP = _a.firstByteToFCP, timeToFirstByte = _a.timeToFirstByte, loadState = _a.loadState;
|
|
40
|
+
var values = _this.buildInitialValues(metric);
|
|
41
|
+
_this.addIfPresent(values, 'first_byte_to_fcp', firstByteToFCP);
|
|
42
|
+
_this.addIfPresent(values, timeToFirstByteKey, timeToFirstByte);
|
|
43
|
+
var context = _this.buildInitialContext(metric);
|
|
44
|
+
_this.addIfPresent(context, loadStateKey, loadState);
|
|
45
|
+
_this.pushMeasurement(values, context);
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
WebVitalsWithAttribution.prototype.measureFID = function () {
|
|
49
|
+
var _this = this;
|
|
50
|
+
(0, attribution_1.onFID)(function (metric) {
|
|
51
|
+
var _a = metric.attribution, eventTime = _a.eventTime, eventTarget = _a.eventTarget, eventType = _a.eventType, loadState = _a.loadState;
|
|
52
|
+
var values = _this.buildInitialValues(metric);
|
|
53
|
+
_this.addIfPresent(values, 'event_time', eventTime);
|
|
54
|
+
var context = _this.buildInitialContext(metric);
|
|
55
|
+
_this.addIfPresent(context, 'event_target', eventTarget);
|
|
56
|
+
_this.addIfPresent(context, 'event_type', eventType);
|
|
57
|
+
_this.addIfPresent(context, loadStateKey, loadState);
|
|
58
|
+
_this.pushMeasurement(values, context);
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
WebVitalsWithAttribution.prototype.measureINP = function () {
|
|
62
|
+
var _this = this;
|
|
63
|
+
(0, attribution_1.onINP)(function (metric) {
|
|
64
|
+
var _a = metric.attribution, interactionTime = _a.interactionTime, presentationDelay = _a.presentationDelay, inputDelay = _a.inputDelay, processingDuration = _a.processingDuration, nextPaintTime = _a.nextPaintTime, loadState = _a.loadState, interactionTarget = _a.interactionTarget, interactionType = _a.interactionType;
|
|
65
|
+
var values = _this.buildInitialValues(metric);
|
|
66
|
+
_this.addIfPresent(values, 'interaction_time', interactionTime);
|
|
67
|
+
_this.addIfPresent(values, 'presentation_delay', presentationDelay);
|
|
68
|
+
_this.addIfPresent(values, 'input_delay', inputDelay);
|
|
69
|
+
_this.addIfPresent(values, 'processing_duration', processingDuration);
|
|
70
|
+
_this.addIfPresent(values, 'next_paint_time', nextPaintTime);
|
|
71
|
+
var context = _this.buildInitialContext(metric);
|
|
72
|
+
_this.addIfPresent(context, loadStateKey, loadState);
|
|
73
|
+
_this.addIfPresent(context, 'interaction_target', interactionTarget);
|
|
74
|
+
_this.addIfPresent(context, 'interaction_type', interactionType);
|
|
75
|
+
_this.pushMeasurement(values, context);
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
WebVitalsWithAttribution.prototype.measureLCP = function () {
|
|
79
|
+
var _this = this;
|
|
80
|
+
(0, attribution_1.onLCP)(function (metric) {
|
|
81
|
+
var _a = metric.attribution, elementRenderDelay = _a.elementRenderDelay, resourceLoadDelay = _a.resourceLoadDelay, resourceLoadDuration = _a.resourceLoadDuration, timeToFirstByte = _a.timeToFirstByte, element = _a.element;
|
|
82
|
+
var values = _this.buildInitialValues(metric);
|
|
83
|
+
_this.addIfPresent(values, 'element_render_delay', elementRenderDelay);
|
|
84
|
+
_this.addIfPresent(values, 'resource_load_delay', resourceLoadDelay);
|
|
85
|
+
_this.addIfPresent(values, 'resource_load_duration', resourceLoadDuration);
|
|
86
|
+
_this.addIfPresent(values, timeToFirstByteKey, timeToFirstByte);
|
|
87
|
+
var context = _this.buildInitialContext(metric);
|
|
88
|
+
_this.addIfPresent(context, 'element', element);
|
|
89
|
+
_this.pushMeasurement(values, context);
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
WebVitalsWithAttribution.prototype.measureTTFB = function () {
|
|
93
|
+
var _this = this;
|
|
94
|
+
(0, attribution_1.onTTFB)(function (metric) {
|
|
95
|
+
var _a = metric.attribution, dnsDuration = _a.dnsDuration, connectionDuration = _a.connectionDuration, requestDuration = _a.requestDuration, waitingDuration = _a.waitingDuration, cacheDuration = _a.cacheDuration;
|
|
96
|
+
var values = _this.buildInitialValues(metric);
|
|
97
|
+
_this.addIfPresent(values, 'dns_duration', dnsDuration);
|
|
98
|
+
_this.addIfPresent(values, 'connection_duration', connectionDuration);
|
|
99
|
+
_this.addIfPresent(values, 'request_duration', requestDuration);
|
|
100
|
+
_this.addIfPresent(values, 'waiting_duration', waitingDuration);
|
|
101
|
+
_this.addIfPresent(values, 'cache_duration', cacheDuration);
|
|
102
|
+
var context = _this.buildInitialContext(metric);
|
|
103
|
+
_this.pushMeasurement(values, context);
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
WebVitalsWithAttribution.prototype.buildInitialValues = function (metric) {
|
|
107
|
+
var _a;
|
|
108
|
+
var indicator = metric.name.toLowerCase();
|
|
109
|
+
return _a = {},
|
|
110
|
+
_a[indicator] = metric.value,
|
|
111
|
+
_a.delta = metric.delta,
|
|
112
|
+
_a;
|
|
113
|
+
};
|
|
114
|
+
WebVitalsWithAttribution.prototype.buildInitialContext = function (metric) {
|
|
115
|
+
var _a;
|
|
116
|
+
var navigationEntryId = (_a = (0, utils_1.getItem)(instrumentationConstants_1.NAVIGATION_ID_STORAGE_KEY, utils_1.webStorageType.session)) !== null && _a !== void 0 ? _a : 'unknown';
|
|
117
|
+
return {
|
|
118
|
+
id: metric.id,
|
|
119
|
+
rating: metric.rating,
|
|
120
|
+
navigation_type: metric.navigationType,
|
|
121
|
+
navigation_entry_id: navigationEntryId,
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
WebVitalsWithAttribution.prototype.pushMeasurement = function (values, context) {
|
|
125
|
+
var type = 'web-vitals';
|
|
126
|
+
this.corePushMeasurement({ type: type, values: values }, { context: context });
|
|
127
|
+
};
|
|
128
|
+
WebVitalsWithAttribution.prototype.addIfPresent = function (source, key, metric) {
|
|
129
|
+
if (metric) {
|
|
130
|
+
source[key] = metric;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
return WebVitalsWithAttribution;
|
|
134
|
+
}());
|
|
135
|
+
exports.WebVitalsWithAttribution = WebVitalsWithAttribution;
|
|
136
|
+
//# sourceMappingURL=webVitalsWithAttribution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webVitalsWithAttribution.js","sourceRoot":"","sources":["../../../../src/instrumentations/webVitals/webVitalsWithAttribution.ts"],"names":[],"mappings":"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","sourcesContent":["import { onCLS, onFCP, onFID, onINP, onLCP, onTTFB } from 'web-vitals/attribution';\nimport type { Metric } from 'web-vitals/attribution';\n\nimport type { MeasurementEvent, MeasurementsAPI, PushMeasurementOptions } from '@grafana/faro-core';\n\nimport { getItem, webStorageType } from '../../utils';\nimport { NAVIGATION_ID_STORAGE_KEY } from '../instrumentationConstants';\n\ntype Values = MeasurementEvent['values'];\ntype Context = Required<PushMeasurementOptions>['context'];\n\n// duplicate keys saved in variables to save bundle size\n// refs: https://github.com/grafana/faro-web-sdk/pull/595#discussion_r1615833968\nconst loadStateKey = 'load_state';\nconst timeToFirstByteKey = 'time_to_first_byte';\n\nexport class WebVitalsWithAttribution {\n constructor(private corePushMeasurement: MeasurementsAPI['pushMeasurement']) {}\n\n initialize(): void {\n this.measureCLS();\n this.measureFCP();\n this.measureFID();\n this.measureINP();\n this.measureLCP();\n this.measureTTFB();\n }\n\n private measureCLS(): void {\n onCLS((metric) => {\n const { loadState, largestShiftValue, largestShiftTime, largestShiftTarget } = metric.attribution;\n\n const values = this.buildInitialValues(metric);\n this.addIfPresent(values, 'largest_shift_value', largestShiftValue);\n this.addIfPresent(values, 'largest_shift_time', largestShiftTime);\n\n const context = this.buildInitialContext(metric);\n this.addIfPresent(context, loadStateKey, loadState);\n this.addIfPresent(context, 'largest_shift_target', largestShiftTarget);\n\n this.pushMeasurement(values, context);\n });\n }\n\n private measureFCP(): void {\n onFCP((metric) => {\n const { firstByteToFCP, timeToFirstByte, loadState } = metric.attribution;\n\n const values = this.buildInitialValues(metric);\n this.addIfPresent(values, 'first_byte_to_fcp', firstByteToFCP);\n this.addIfPresent(values, timeToFirstByteKey, timeToFirstByte);\n\n const context = this.buildInitialContext(metric);\n this.addIfPresent(context, loadStateKey, loadState);\n\n this.pushMeasurement(values, context);\n });\n }\n\n private measureFID(): void {\n onFID((metric) => {\n const { eventTime, eventTarget, eventType, loadState } = metric.attribution;\n\n const values = this.buildInitialValues(metric);\n this.addIfPresent(values, 'event_time', eventTime);\n\n const context = this.buildInitialContext(metric);\n this.addIfPresent(context, 'event_target', eventTarget);\n this.addIfPresent(context, 'event_type', eventType);\n this.addIfPresent(context, loadStateKey, loadState);\n\n this.pushMeasurement(values, context);\n });\n }\n\n private measureINP(): void {\n onINP((metric) => {\n const {\n interactionTime,\n presentationDelay,\n inputDelay,\n processingDuration,\n nextPaintTime,\n loadState,\n interactionTarget,\n interactionType,\n } = metric.attribution;\n\n const values = this.buildInitialValues(metric);\n this.addIfPresent(values, 'interaction_time', interactionTime);\n this.addIfPresent(values, 'presentation_delay', presentationDelay);\n this.addIfPresent(values, 'input_delay', inputDelay);\n this.addIfPresent(values, 'processing_duration', processingDuration);\n this.addIfPresent(values, 'next_paint_time', nextPaintTime);\n\n const context = this.buildInitialContext(metric);\n this.addIfPresent(context, loadStateKey, loadState);\n this.addIfPresent(context, 'interaction_target', interactionTarget);\n this.addIfPresent(context, 'interaction_type', interactionType);\n\n this.pushMeasurement(values, context);\n });\n }\n\n private measureLCP(): void {\n onLCP((metric) => {\n const { elementRenderDelay, resourceLoadDelay, resourceLoadDuration, timeToFirstByte, element } =\n metric.attribution;\n\n const values = this.buildInitialValues(metric);\n this.addIfPresent(values, 'element_render_delay', elementRenderDelay);\n this.addIfPresent(values, 'resource_load_delay', resourceLoadDelay);\n this.addIfPresent(values, 'resource_load_duration', resourceLoadDuration);\n this.addIfPresent(values, timeToFirstByteKey, timeToFirstByte);\n\n const context = this.buildInitialContext(metric);\n this.addIfPresent(context, 'element', element);\n\n this.pushMeasurement(values, context);\n });\n }\n\n private measureTTFB(): void {\n onTTFB((metric) => {\n const { dnsDuration, connectionDuration, requestDuration, waitingDuration, cacheDuration } = metric.attribution;\n\n const values = this.buildInitialValues(metric);\n this.addIfPresent(values, 'dns_duration', dnsDuration);\n this.addIfPresent(values, 'connection_duration', connectionDuration);\n this.addIfPresent(values, 'request_duration', requestDuration);\n this.addIfPresent(values, 'waiting_duration', waitingDuration);\n this.addIfPresent(values, 'cache_duration', cacheDuration);\n\n const context = this.buildInitialContext(metric);\n\n this.pushMeasurement(values, context);\n });\n }\n\n private buildInitialValues(metric: Metric): Values {\n const indicator = metric.name.toLowerCase();\n return {\n [indicator]: metric.value,\n delta: metric.delta,\n };\n }\n\n private buildInitialContext(metric: Metric): Context {\n const navigationEntryId = getItem(NAVIGATION_ID_STORAGE_KEY, webStorageType.session) ?? 'unknown';\n\n return {\n id: metric.id,\n rating: metric.rating,\n navigation_type: metric.navigationType,\n navigation_entry_id: navigationEntryId,\n };\n }\n\n private pushMeasurement(values: Values, context: Context): void {\n const type = 'web-vitals';\n this.corePushMeasurement({ type, values }, { context });\n }\n\n private addIfPresent(source: Values | Context, key: string, metric?: number | string): void {\n if (metric) {\n source[key] = metric;\n }\n }\n}\n"]}
|
|
@@ -20,6 +20,8 @@ var browserMeta = function () {
|
|
|
20
20
|
language: language !== null && language !== void 0 ? language : unknown,
|
|
21
21
|
mobile: mobile,
|
|
22
22
|
brands: brands !== null && brands !== void 0 ? brands : unknown,
|
|
23
|
+
viewportWidth: "".concat(window.innerWidth),
|
|
24
|
+
viewportHeight: "".concat(window.innerHeight),
|
|
23
25
|
},
|
|
24
26
|
};
|
|
25
27
|
function getBrands() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meta.js","sourceRoot":"","sources":["../../../../src/metas/browser/meta.ts"],"names":[],"mappings":";;;AAAA,6CAAwC;AAIjC,IAAM,WAAW,GAAoC;IAC1D,IAAM,MAAM,GAAG,IAAI,uBAAQ,EAAE,CAAC;IACxB,IAAA,KAAoB,MAAM,CAAC,UAAU,EAAE,EAArC,IAAI,UAAA,EAAE,OAAO,aAAwB,CAAC;IACxC,IAAA,KAAuC,MAAM,CAAC,KAAK,EAAE,EAA7C,MAAM,UAAA,EAAW,SAAS,aAAmB,CAAC;IAC5D,IAAM,SAAS,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IACjC,IAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC;IACpC,IAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACpD,IAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,IAAM,OAAO,GAAG,SAAS,CAAC;IAE1B,OAAO;QACL,OAAO,EAAE;YACP,IAAI,EAAE,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,OAAO;YACrB,OAAO,EAAE,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,OAAO;YAC3B,EAAE,EAAE,UAAG,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,OAAO,cAAI,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,OAAO,CAAE;YAClD,SAAS,EAAE,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,OAAO;YAC/B,QAAQ,EAAE,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,OAAO;YAC7B,MAAM,QAAA;YACN,MAAM,EAAE,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,OAAO;
|
|
1
|
+
{"version":3,"file":"meta.js","sourceRoot":"","sources":["../../../../src/metas/browser/meta.ts"],"names":[],"mappings":";;;AAAA,6CAAwC;AAIjC,IAAM,WAAW,GAAoC;IAC1D,IAAM,MAAM,GAAG,IAAI,uBAAQ,EAAE,CAAC;IACxB,IAAA,KAAoB,MAAM,CAAC,UAAU,EAAE,EAArC,IAAI,UAAA,EAAE,OAAO,aAAwB,CAAC;IACxC,IAAA,KAAuC,MAAM,CAAC,KAAK,EAAE,EAA7C,MAAM,UAAA,EAAW,SAAS,aAAmB,CAAC;IAC5D,IAAM,SAAS,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IACjC,IAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC;IACpC,IAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACpD,IAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,IAAM,OAAO,GAAG,SAAS,CAAC;IAE1B,OAAO;QACL,OAAO,EAAE;YACP,IAAI,EAAE,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,OAAO;YACrB,OAAO,EAAE,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,OAAO;YAC3B,EAAE,EAAE,UAAG,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,OAAO,cAAI,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,OAAO,CAAE;YAClD,SAAS,EAAE,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,OAAO;YAC/B,QAAQ,EAAE,QAAQ,aAAR,QAAQ,cAAR,QAAQ,GAAI,OAAO;YAC7B,MAAM,QAAA;YACN,MAAM,EAAE,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,OAAO;YACzB,aAAa,EAAE,UAAG,MAAM,CAAC,UAAU,CAAE;YACrC,cAAc,EAAE,UAAG,MAAM,CAAC,WAAW,CAAE;SACxC;KACF,CAAC;IAEF,SAAS,SAAS;QAChB,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE;YACrB,OAAO,SAAS,CAAC;SAClB;QAED,IAAI,eAAe,IAAI,SAAS,IAAI,SAAS,CAAC,aAAa,EAAE;YAC3D,iHAAiH;YACjH,OAAQ,SAAiB,CAAC,aAAa,CAAC,MAAM,CAAC;SAChD;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC,CAAC;AApCW,QAAA,WAAW,eAoCtB","sourcesContent":["import { UAParser } from 'ua-parser-js';\n\nimport type { Meta, MetaBrowser, MetaItem } from '@grafana/faro-core';\n\nexport const browserMeta: MetaItem<Pick<Meta, 'browser'>> = () => {\n const parser = new UAParser();\n const { name, version } = parser.getBrowser();\n const { name: osName, version: osVersion } = parser.getOS();\n const userAgent = parser.getUA();\n const language = navigator.language;\n const mobile = navigator.userAgent.includes('Mobi');\n const brands = getBrands();\n const unknown = 'unknown';\n\n return {\n browser: {\n name: name ?? unknown,\n version: version ?? unknown,\n os: `${osName ?? unknown} ${osVersion ?? unknown}`,\n userAgent: userAgent ?? unknown,\n language: language ?? unknown,\n mobile,\n brands: brands ?? unknown,\n viewportWidth: `${window.innerWidth}`,\n viewportHeight: `${window.innerHeight}`,\n },\n };\n\n function getBrands(): MetaBrowser['brands'] | undefined {\n if (!name || !version) {\n return undefined;\n }\n\n if ('userAgentData' in navigator && navigator.userAgentData) {\n // userAgentData in experimental (only Chrome supports it) thus TS does not ship the respective type declarations\n return (navigator as any).userAgentData.brands;\n }\n\n return undefined;\n }\n};\n"]}
|
|
@@ -75,11 +75,13 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
75
75
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
76
76
|
exports.FetchTransport = void 0;
|
|
77
77
|
var faro_core_1 = require("@grafana/faro-core");
|
|
78
|
+
var sessionManagerUtils_1 = require("../../instrumentations/session/sessionManager/sessionManagerUtils");
|
|
78
79
|
var DEFAULT_BUFFER_SIZE = 30;
|
|
79
80
|
var DEFAULT_CONCURRENCY = 5; // chrome supports 10 total, firefox 17
|
|
80
81
|
var DEFAULT_RATE_LIMIT_BACKOFF_MS = 5000;
|
|
81
82
|
var BEACON_BODY_SIZE_LIMIT = 60000;
|
|
82
83
|
var TOO_MANY_REQUESTS = 429;
|
|
84
|
+
var ACCEPTED = 202;
|
|
83
85
|
var FetchTransport = /** @class */ (function (_super) {
|
|
84
86
|
__extends(FetchTransport, _super);
|
|
85
87
|
function FetchTransport(options) {
|
|
@@ -120,15 +122,24 @@ var FetchTransport = /** @class */ (function (_super) {
|
|
|
120
122
|
sessionId = sessionMeta.id;
|
|
121
123
|
}
|
|
122
124
|
return fetch(url, __assign({ method: 'POST', headers: __assign(__assign(__assign({ 'Content-Type': 'application/json' }, (headers !== null && headers !== void 0 ? headers : {})), (apiKey ? { 'x-api-key': apiKey } : {})), (sessionId ? { 'x-faro-session-id': sessionId } : {})), body: body, keepalive: body.length <= BEACON_BODY_SIZE_LIMIT }, (restOfRequestOptions !== null && restOfRequestOptions !== void 0 ? restOfRequestOptions : {})))
|
|
123
|
-
.then(function (response) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
125
|
+
.then(function (response) { return __awaiter(_this, void 0, void 0, function () {
|
|
126
|
+
var sessionExpired;
|
|
127
|
+
return __generator(this, function (_a) {
|
|
128
|
+
if (response.status === ACCEPTED) {
|
|
129
|
+
sessionExpired = response.headers.get('X-Faro-Session-Status') === 'invalid';
|
|
130
|
+
if (sessionExpired) {
|
|
131
|
+
this.extendFaroSession(this.config, this.logDebug);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (response.status === TOO_MANY_REQUESTS) {
|
|
135
|
+
this.disabledUntil = this.getRetryAfterDate(response);
|
|
136
|
+
this.logWarn("Too many requests, backing off until ".concat(this.disabledUntil));
|
|
137
|
+
}
|
|
138
|
+
// read the body so the connection can be closed
|
|
139
|
+
response.text().catch(faro_core_1.noop);
|
|
140
|
+
return [2 /*return*/, response];
|
|
141
|
+
});
|
|
142
|
+
}); })
|
|
132
143
|
.catch(function (err) {
|
|
133
144
|
_this.logError('Failed sending payload to the receiver\n', JSON.parse(body), err);
|
|
134
145
|
});
|
|
@@ -167,6 +178,18 @@ var FetchTransport = /** @class */ (function (_super) {
|
|
|
167
178
|
}
|
|
168
179
|
return new Date(now + this.rateLimitBackoffMs);
|
|
169
180
|
};
|
|
181
|
+
FetchTransport.prototype.extendFaroSession = function (config, logDebug) {
|
|
182
|
+
var SessionExpiredString = "Session expired";
|
|
183
|
+
var sessionTrackingConfig = config.sessionTracking;
|
|
184
|
+
if (sessionTrackingConfig === null || sessionTrackingConfig === void 0 ? void 0 : sessionTrackingConfig.enabled) {
|
|
185
|
+
var _a = (0, sessionManagerUtils_1.getSessionManagerByConfig)(sessionTrackingConfig), fetchUserSession = _a.fetchUserSession, storeUserSession = _a.storeUserSession;
|
|
186
|
+
(0, sessionManagerUtils_1.getUserSessionUpdater)({ fetchUserSession: fetchUserSession, storeUserSession: storeUserSession })({ forceSessionExtend: true });
|
|
187
|
+
logDebug("".concat(SessionExpiredString, " created new session."));
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
logDebug("".concat(SessionExpiredString, "."));
|
|
191
|
+
}
|
|
192
|
+
};
|
|
170
193
|
return FetchTransport;
|
|
171
194
|
}(faro_core_1.BaseTransport));
|
|
172
195
|
exports.FetchTransport = FetchTransport;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../../src/transports/fetch/transport.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../../src/transports/fetch/transport.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gDAQ4B;AAG5B,yGAG2E;AAI3E,IAAM,mBAAmB,GAAG,EAAE,CAAC;AAC/B,IAAM,mBAAmB,GAAG,CAAC,CAAC,CAAC,uCAAuC;AACtE,IAAM,6BAA6B,GAAG,IAAI,CAAC;AAE3C,IAAM,sBAAsB,GAAG,KAAK,CAAC;AACrC,IAAM,iBAAiB,GAAG,GAAG,CAAC;AAC9B,IAAM,QAAQ,GAAG,GAAG,CAAC;AAErB;IAAoC,kCAAa;IAU/C,wBAAoB,OAA8B;QAAlD,iBAUC;;gBATC,iBAAO;QADW,aAAO,GAAP,OAAO,CAAuB;QATzC,UAAI,GAAG,uCAAuC,CAAC;QAC/C,aAAO,GAAG,mBAAO,CAAC;QAMnB,mBAAa,GAAS,IAAI,IAAI,EAAE,CAAC;QAKvC,KAAI,CAAC,kBAAkB,GAAG,MAAA,OAAO,CAAC,yBAAyB,mCAAI,6BAA6B,CAAC;QAC7F,KAAI,CAAC,MAAM,GAAG,MAAA,OAAO,CAAC,MAAM,mCAAI,CAAC,cAAM,OAAA,IAAI,CAAC,GAAG,EAAE,EAAV,CAAU,CAAC,CAAC;QAEnD,KAAI,CAAC,aAAa,GAAG,IAAA,+BAAmB,EAAC;YACvC,IAAI,EAAE,MAAA,OAAO,CAAC,UAAU,mCAAI,mBAAmB;YAC/C,WAAW,EAAE,MAAA,OAAO,CAAC,WAAW,mCAAI,mBAAmB;SACxD,CAAC,CAAC;;IACL,CAAC;IAEK,6BAAI,GAAV,UAAW,KAAsB;;;;;;;;wBAE7B,IAAI,IAAI,CAAC,aAAa,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE;4BAChD,IAAI,CAAC,OAAO,CAAC,0EAAmE,IAAI,CAAC,aAAa,CAAE,CAAC,CAAC;4BAEtG,sBAAO,OAAO,CAAC,OAAO,EAAE,EAAC;yBAC1B;wBAED,qBAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC;gCAC3B,IAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAA,4BAAgB,EAAC,KAAK,CAAC,CAAC,CAAC;gCAE/C,IAAA,KAAkC,KAAI,CAAC,OAAO,EAA5C,GAAG,SAAA,EAAE,cAAc,oBAAA,EAAE,MAAM,YAAiB,CAAC;gCAErD,IAAM,KAAuC,cAAc,aAAd,cAAc,cAAd,cAAc,GAAI,EAAE,EAAzD,OAAO,aAAA,EAAK,oBAAoB,cAAlC,WAAoC,CAAuB,CAAC;gCAElE,IAAI,SAAS,CAAC;gCACd,IAAM,WAAW,GAAG,KAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;gCAC7C,IAAI,WAAW,IAAI,IAAI,EAAE;oCACvB,SAAS,GAAG,WAAW,CAAC,EAAE,CAAC;iCAC5B;gCAED,OAAO,KAAK,CAAC,GAAG,aACd,MAAM,EAAE,MAAM,EACd,OAAO,+BACL,cAAc,EAAE,kBAAkB,IAC/B,CAAC,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,EAAE,CAAC,GACf,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GACvC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,mBAAmB,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAE1D,IAAI,MAAA,EACJ,SAAS,EAAE,IAAI,CAAC,MAAM,IAAI,sBAAsB,IAC7C,CAAC,oBAAoB,aAApB,oBAAoB,cAApB,oBAAoB,GAAI,EAAE,CAAC,EAC/B;qCACC,IAAI,CAAC,UAAO,QAAQ;;;wCACnB,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ,EAAE;4CAC1B,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,KAAK,SAAS,CAAC;4CAEnF,IAAI,cAAc,EAAE;gDAClB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;6CACpD;yCACF;wCAED,IAAI,QAAQ,CAAC,MAAM,KAAK,iBAAiB,EAAE;4CACzC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;4CACtD,IAAI,CAAC,OAAO,CAAC,+CAAwC,IAAI,CAAC,aAAa,CAAE,CAAC,CAAC;yCAC5E;wCAED,gDAAgD;wCAChD,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,gBAAI,CAAC,CAAC;wCAC5B,sBAAO,QAAQ,EAAC;;qCACjB,CAAC;qCACD,KAAK,CAAC,UAAC,GAAG;oCACT,KAAI,CAAC,QAAQ,CAAC,0CAA0C,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;gCACnF,CAAC,CAAC,CAAC;4BACP,CAAC,CAAC,EAAA;;wBA9CF,SA8CE,CAAC;;;;wBAEH,IAAI,CAAC,QAAQ,CAAC,KAAG,CAAC,CAAC;;;;;;KAEtB;IAEQ,sCAAa,GAAtB;;QACE,OAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAc,CAAC,MAAM,CAAC,MAAA,IAAI,CAAC,MAAM,CAAC,UAAU,mCAAI,EAAE,CAAC,CAAC;IAC/E,CAAC;IAEQ,kCAAS,GAAlB;QACE,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,0CAAiB,GAAzB,UAA0B,QAAkB;QAC1C,IAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC1B,IAAM,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAE7D,IAAI,gBAAgB,EAAE;YACpB,IAAM,KAAK,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;YAEvC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;gBACjB,OAAO,IAAI,IAAI,CAAC,KAAK,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC;aACrC;YAED,IAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;YAE1C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;gBAChB,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;aACvB;SACF;QAED,OAAO,IAAI,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,kBAAkB,CAAC,CAAC;IACjD,CAAC;IAEO,0CAAiB,GAAzB,UAA0B,MAAc,EAAE,QAAmC;QAC3E,IAAM,oBAAoB,GAAG,iBAAiB,CAAC;QAE/C,IAAM,qBAAqB,GAAG,MAAM,CAAC,eAAe,CAAC;QAErD,IAAI,qBAAqB,aAArB,qBAAqB,uBAArB,qBAAqB,CAAE,OAAO,EAAE;YAC5B,IAAA,KAAyC,IAAA,+CAAyB,EAAC,qBAAqB,CAAC,EAAvF,gBAAgB,sBAAA,EAAE,gBAAgB,sBAAqD,CAAC;YAEhG,IAAA,2CAAqB,EAAC,EAAE,gBAAgB,kBAAA,EAAE,gBAAgB,kBAAA,EAAE,CAAC,CAAC,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,CAAC;YAE5F,QAAQ,CAAC,UAAG,oBAAoB,0BAAuB,CAAC,CAAC;SAC1D;aAAM;YACL,QAAQ,CAAC,UAAG,oBAAoB,MAAG,CAAC,CAAC;SACtC;IACH,CAAC;IACH,qBAAC;AAAD,CAAC,AA9HD,CAAoC,yBAAa,GA8HhD;AA9HY,wCAAc","sourcesContent":["import {\n BaseExtension,\n BaseTransport,\n createPromiseBuffer,\n getTransportBody,\n noop,\n PromiseBuffer,\n VERSION,\n} from '@grafana/faro-core';\nimport type { Config, Patterns, TransportItem } from '@grafana/faro-core';\n\nimport {\n getSessionManagerByConfig,\n getUserSessionUpdater,\n} from '../../instrumentations/session/sessionManager/sessionManagerUtils';\n\nimport type { FetchTransportOptions } from './types';\n\nconst DEFAULT_BUFFER_SIZE = 30;\nconst DEFAULT_CONCURRENCY = 5; // chrome supports 10 total, firefox 17\nconst DEFAULT_RATE_LIMIT_BACKOFF_MS = 5000;\n\nconst BEACON_BODY_SIZE_LIMIT = 60000;\nconst TOO_MANY_REQUESTS = 429;\nconst ACCEPTED = 202;\n\nexport class FetchTransport extends BaseTransport {\n readonly name = '@grafana/faro-web-sdk:transport-fetch';\n readonly version = VERSION;\n\n promiseBuffer: PromiseBuffer<Response | void>;\n\n private readonly rateLimitBackoffMs: number;\n private readonly getNow: () => number;\n private disabledUntil: Date = new Date();\n\n constructor(private options: FetchTransportOptions) {\n super();\n\n this.rateLimitBackoffMs = options.defaultRateLimitBackoffMs ?? DEFAULT_RATE_LIMIT_BACKOFF_MS;\n this.getNow = options.getNow ?? (() => Date.now());\n\n this.promiseBuffer = createPromiseBuffer({\n size: options.bufferSize ?? DEFAULT_BUFFER_SIZE,\n concurrency: options.concurrency ?? DEFAULT_CONCURRENCY,\n });\n }\n\n async send(items: TransportItem[]): Promise<void> {\n try {\n if (this.disabledUntil > new Date(this.getNow())) {\n this.logWarn(`Dropping transport item due to too many requests. Backoff until ${this.disabledUntil}`);\n\n return Promise.resolve();\n }\n\n await this.promiseBuffer.add(() => {\n const body = JSON.stringify(getTransportBody(items));\n\n const { url, requestOptions, apiKey } = this.options;\n\n const { headers, ...restOfRequestOptions } = requestOptions ?? {};\n\n let sessionId;\n const sessionMeta = this.metas.value.session;\n if (sessionMeta != null) {\n sessionId = sessionMeta.id;\n }\n\n return fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(headers ?? {}),\n ...(apiKey ? { 'x-api-key': apiKey } : {}),\n ...(sessionId ? { 'x-faro-session-id': sessionId } : {}),\n },\n body,\n keepalive: body.length <= BEACON_BODY_SIZE_LIMIT,\n ...(restOfRequestOptions ?? {}),\n })\n .then(async (response) => {\n if (response.status === ACCEPTED) {\n const sessionExpired = response.headers.get('X-Faro-Session-Status') === 'invalid';\n\n if (sessionExpired) {\n this.extendFaroSession(this.config, this.logDebug);\n }\n }\n\n if (response.status === TOO_MANY_REQUESTS) {\n this.disabledUntil = this.getRetryAfterDate(response);\n this.logWarn(`Too many requests, backing off until ${this.disabledUntil}`);\n }\n\n // read the body so the connection can be closed\n response.text().catch(noop);\n return response;\n })\n .catch((err) => {\n this.logError('Failed sending payload to the receiver\\n', JSON.parse(body), err);\n });\n });\n } catch (err) {\n this.logError(err);\n }\n }\n\n override getIgnoreUrls(): Patterns {\n return ([this.options.url] as Patterns).concat(this.config.ignoreUrls ?? []);\n }\n\n override isBatched(): boolean {\n return true;\n }\n\n private getRetryAfterDate(response: Response): Date {\n const now = this.getNow();\n const retryAfterHeader = response.headers.get('Retry-After');\n\n if (retryAfterHeader) {\n const delay = Number(retryAfterHeader);\n\n if (!isNaN(delay)) {\n return new Date(delay * 1000 + now);\n }\n\n const date = Date.parse(retryAfterHeader);\n\n if (!isNaN(date)) {\n return new Date(date);\n }\n }\n\n return new Date(now + this.rateLimitBackoffMs);\n }\n\n private extendFaroSession(config: Config, logDebug: BaseExtension['logDebug']) {\n const SessionExpiredString = `Session expired`;\n\n const sessionTrackingConfig = config.sessionTracking;\n\n if (sessionTrackingConfig?.enabled) {\n const { fetchUserSession, storeUserSession } = getSessionManagerByConfig(sessionTrackingConfig);\n\n getUserSessionUpdater({ fetchUserSession, storeUserSession })({ forceSessionExtend: true });\n\n logDebug(`${SessionExpiredString} created new session.`);\n } else {\n logDebug(`${SessionExpiredString}.`);\n }\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createInternalLogger, defaultBatchingConfig, defaultGlobalObjectKey, defaultInternalLoggerLevel, defaultUnpatchedConsole, isObject, } from '@grafana/faro-core';
|
|
1
|
+
import { createInternalLogger, defaultBatchingConfig, defaultGlobalObjectKey, defaultInternalLoggerLevel, defaultLogArgsSerializer, defaultUnpatchedConsole, isObject, } from '@grafana/faro-core';
|
|
2
2
|
import { defaultEventDomain } from '../consts';
|
|
3
3
|
import { parseStacktrace } from '../instrumentations';
|
|
4
4
|
import { defaultSessionTrackingConfig } from '../instrumentations/session';
|
|
@@ -7,7 +7,7 @@ import { k6Meta } from '../metas/k6';
|
|
|
7
7
|
import { FetchTransport } from '../transports';
|
|
8
8
|
import { getWebInstrumentations } from './getWebInstrumentations';
|
|
9
9
|
export function makeCoreConfig(browserConfig) {
|
|
10
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
10
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
11
11
|
const transports = [];
|
|
12
12
|
const internalLogger = createInternalLogger(browserConfig.unpatchedConsole, browserConfig.internalLoggerLevel);
|
|
13
13
|
if (browserConfig.transports) {
|
|
@@ -44,20 +44,22 @@ export function makeCoreConfig(browserConfig) {
|
|
|
44
44
|
instrumentations: (_b = browserConfig.instrumentations) !== null && _b !== void 0 ? _b : getWebInstrumentations(),
|
|
45
45
|
internalLoggerLevel: (_c = browserConfig.internalLoggerLevel) !== null && _c !== void 0 ? _c : defaultInternalLoggerLevel,
|
|
46
46
|
isolate: (_d = browserConfig.isolate) !== null && _d !== void 0 ? _d : false,
|
|
47
|
+
logArgsSerializer: (_e = browserConfig.logArgsSerializer) !== null && _e !== void 0 ? _e : defaultLogArgsSerializer,
|
|
47
48
|
metas: createMetas(),
|
|
48
49
|
parseStacktrace,
|
|
49
|
-
paused: (
|
|
50
|
-
preventGlobalExposure: (
|
|
50
|
+
paused: (_f = browserConfig.paused) !== null && _f !== void 0 ? _f : false,
|
|
51
|
+
preventGlobalExposure: (_g = browserConfig.preventGlobalExposure) !== null && _g !== void 0 ? _g : false,
|
|
51
52
|
transports,
|
|
52
|
-
unpatchedConsole: (
|
|
53
|
+
unpatchedConsole: (_h = browserConfig.unpatchedConsole) !== null && _h !== void 0 ? _h : defaultUnpatchedConsole,
|
|
53
54
|
beforeSend: browserConfig.beforeSend,
|
|
54
|
-
eventDomain: (
|
|
55
|
+
eventDomain: (_j = browserConfig.eventDomain) !== null && _j !== void 0 ? _j : defaultEventDomain,
|
|
55
56
|
ignoreErrors: browserConfig.ignoreErrors,
|
|
56
57
|
ignoreUrls: browserConfig.ignoreUrls,
|
|
57
58
|
sessionTracking: Object.assign(Object.assign({}, defaultSessionTrackingConfig), browserConfig.sessionTracking),
|
|
58
59
|
user: browserConfig.user,
|
|
59
|
-
view: (
|
|
60
|
+
view: (_k = browserConfig.view) !== null && _k !== void 0 ? _k : defaultViewMeta,
|
|
60
61
|
trackResources: browserConfig.trackResources,
|
|
62
|
+
trackWebVitalsAttribution: browserConfig.trackWebVitalsAttribution,
|
|
61
63
|
};
|
|
62
64
|
return config;
|
|
63
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"makeCoreConfig.js","sourceRoot":"","sources":["../../../src/config/makeCoreConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,uBAAuB,EACvB,QAAQ,GACT,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,MAAM,UAAU,cAAc,CAAC,aAA4B;;IACzD,MAAM,UAAU,GAAgB,EAAE,CAAC;IAEnC,MAAM,cAAc,GAAG,oBAAoB,CAAC,aAAa,CAAC,gBAAgB,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAE/G,IAAI,aAAa,CAAC,UAAU,EAAE;QAC5B,IAAI,aAAa,CAAC,GAAG,IAAI,aAAa,CAAC,MAAM,EAAE;YAC7C,cAAc,CAAC,KAAK,CAAC,sEAAsE,CAAC,CAAC;SAC9F;QAED,UAAU,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;KAC9C;SAAM,IAAI,aAAa,CAAC,GAAG,EAAE;QAC5B,UAAU,CAAC,IAAI,CACb,IAAI,cAAc,CAAC;YACjB,GAAG,EAAE,aAAa,CAAC,GAAG;YACtB,MAAM,EAAE,aAAa,CAAC,MAAM;SAC7B,CAAC,CACH,CAAC;KACH;SAAM;QACL,cAAc,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;KACtE;IAED,SAAS,WAAW;QAClB,MAAM,YAAY,GAAG,YAAY,CAAC;QAElC,IAAI,aAAa,CAAC,KAAK,EAAE;YACvB,YAAY,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;SAC3C;QAED,MAAM,kBAAkB,GAAG,QAAQ,CAAE,MAAc,CAAC,EAAE,CAAC,CAAC;QAExD,IAAI,kBAAkB,EAAE;YACtB,OAAO,CAAC,GAAG,YAAY,EAAE,MAAM,CAAC,CAAC;SAClC;QAED,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,MAAM,MAAM,GAAW;QACrB,GAAG,EAAE,aAAa,CAAC,GAAG;QACtB,QAAQ,kCACH,qBAAqB,GACrB,aAAa,CAAC,QAAQ,CAC1B;QACD,MAAM,EAAE,MAAA,aAAa,CAAC,MAAM,mCAAI,IAAI;QACpC,eAAe,EAAE,aAAa,CAAC,eAAe,IAAI,sBAAsB;QACxE,gBAAgB,EAAE,MAAA,aAAa,CAAC,gBAAgB,mCAAI,sBAAsB,EAAE;QAC5E,mBAAmB,EAAE,MAAA,aAAa,CAAC,mBAAmB,mCAAI,0BAA0B;QACpF,OAAO,EAAE,MAAA,aAAa,CAAC,OAAO,mCAAI,KAAK;QACvC,KAAK,EAAE,WAAW,EAAE;QACpB,eAAe;QACf,MAAM,EAAE,MAAA,aAAa,CAAC,MAAM,mCAAI,KAAK;QACrC,qBAAqB,EAAE,MAAA,aAAa,CAAC,qBAAqB,mCAAI,KAAK;QACnE,UAAU;QACV,gBAAgB,EAAE,MAAA,aAAa,CAAC,gBAAgB,mCAAI,uBAAuB;QAE3E,UAAU,EAAE,aAAa,CAAC,UAAU;QACpC,WAAW,EAAE,MAAA,aAAa,CAAC,WAAW,mCAAI,kBAAkB;QAC5D,YAAY,EAAE,aAAa,CAAC,YAAY;QACxC,UAAU,EAAE,aAAa,CAAC,UAAU;QAEpC,eAAe,kCACV,4BAA4B,GAC5B,aAAa,CAAC,eAAe,CACjC;QAED,IAAI,EAAE,aAAa,CAAC,IAAI;QACxB,IAAI,EAAE,MAAA,aAAa,CAAC,IAAI,mCAAI,eAAe;QAC3C,cAAc,EAAE,aAAa,CAAC,cAAc;
|
|
1
|
+
{"version":3,"file":"makeCoreConfig.js","sourceRoot":"","sources":["../../../src/config/makeCoreConfig.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createInternalLogger,\n defaultBatchingConfig,\n defaultGlobalObjectKey,\n defaultInternalLoggerLevel,\n defaultLogArgsSerializer,\n defaultUnpatchedConsole,\n isObject,\n} from '@grafana/faro-core';\nimport type { Config, MetaItem, Transport } from '@grafana/faro-core';\n\nimport { defaultEventDomain } from '../consts';\nimport { parseStacktrace } from '../instrumentations';\nimport { defaultSessionTrackingConfig } from '../instrumentations/session';\nimport { defaultMetas, defaultViewMeta } from '../metas';\nimport { k6Meta } from '../metas/k6';\nimport { FetchTransport } from '../transports';\n\nimport { getWebInstrumentations } from './getWebInstrumentations';\nimport type { BrowserConfig } from './types';\n\nexport function makeCoreConfig(browserConfig: BrowserConfig): Config | undefined {\n const transports: Transport[] = [];\n\n const internalLogger = createInternalLogger(browserConfig.unpatchedConsole, browserConfig.internalLoggerLevel);\n\n if (browserConfig.transports) {\n if (browserConfig.url || browserConfig.apiKey) {\n internalLogger.error('if \"transports\" is defined, \"url\" and \"apiKey\" should not be defined');\n }\n\n transports.push(...browserConfig.transports);\n } else if (browserConfig.url) {\n transports.push(\n new FetchTransport({\n url: browserConfig.url,\n apiKey: browserConfig.apiKey,\n })\n );\n } else {\n internalLogger.error('either \"url\" or \"transports\" must be defined');\n }\n\n function createMetas(): MetaItem[] {\n const initialMetas = defaultMetas;\n\n if (browserConfig.metas) {\n initialMetas.push(...browserConfig.metas);\n }\n\n const isK6BrowserSession = isObject((window as any).k6);\n\n if (isK6BrowserSession) {\n return [...initialMetas, k6Meta];\n }\n\n return initialMetas;\n }\n\n const config: Config = {\n app: browserConfig.app,\n batching: {\n ...defaultBatchingConfig,\n ...browserConfig.batching,\n },\n dedupe: browserConfig.dedupe ?? true,\n globalObjectKey: browserConfig.globalObjectKey || defaultGlobalObjectKey,\n instrumentations: browserConfig.instrumentations ?? getWebInstrumentations(),\n internalLoggerLevel: browserConfig.internalLoggerLevel ?? defaultInternalLoggerLevel,\n isolate: browserConfig.isolate ?? false,\n logArgsSerializer: browserConfig.logArgsSerializer ?? defaultLogArgsSerializer,\n metas: createMetas(),\n parseStacktrace,\n paused: browserConfig.paused ?? false,\n preventGlobalExposure: browserConfig.preventGlobalExposure ?? false,\n transports,\n unpatchedConsole: browserConfig.unpatchedConsole ?? defaultUnpatchedConsole,\n\n beforeSend: browserConfig.beforeSend,\n eventDomain: browserConfig.eventDomain ?? defaultEventDomain,\n ignoreErrors: browserConfig.ignoreErrors,\n ignoreUrls: browserConfig.ignoreUrls,\n\n sessionTracking: {\n ...defaultSessionTrackingConfig,\n ...browserConfig.sessionTracking,\n },\n\n user: browserConfig.user,\n view: browserConfig.view ?? defaultViewMeta,\n trackResources: browserConfig.trackResources,\n trackWebVitalsAttribution: browserConfig.trackWebVitalsAttribution,\n };\n\n return config;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instrumentationConstants.js","sourceRoot":"","sources":["../../../src/instrumentations/instrumentationConstants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,yBAAyB,GAAG,mCAAmC,CAAC","sourcesContent":["export const NAVIGATION_ID_STORAGE_KEY = 'com.grafana.faro.lastNavigationId';\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { genShortID } from '@grafana/faro-core';
|
|
2
2
|
import { getItem, setItem, webStorageType } from '../../utils';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { NAVIGATION_ID_STORAGE_KEY } from '../instrumentationConstants';
|
|
4
|
+
import { NAVIGATION_ENTRY } from './performanceConstants';
|
|
5
|
+
import { createFaroNavigationTiming, entryUrlIsIgnored, getSpanContextFromServerTiming } from './performanceUtils';
|
|
5
6
|
export function getNavigationTimings(pushEvent, ignoredUrls) {
|
|
6
7
|
let faroNavigationEntryResolve;
|
|
7
8
|
const faroNavigationEntryPromise = new Promise((resolve) => {
|
|
@@ -13,10 +14,12 @@ export function getNavigationTimings(pushEvent, ignoredUrls) {
|
|
|
13
14
|
if (navigationEntryRaw == null || entryUrlIsIgnored(ignoredUrls, navigationEntryRaw.name)) {
|
|
14
15
|
return;
|
|
15
16
|
}
|
|
17
|
+
const navEntryJson = navigationEntryRaw.toJSON();
|
|
18
|
+
let spanContext = getSpanContextFromServerTiming(navEntryJson === null || navEntryJson === void 0 ? void 0 : navEntryJson.serverTiming);
|
|
16
19
|
const faroPreviousNavigationId = (_a = getItem(NAVIGATION_ID_STORAGE_KEY, webStorageType.session)) !== null && _a !== void 0 ? _a : 'unknown';
|
|
17
|
-
const faroNavigationEntry = Object.assign(Object.assign({}, createFaroNavigationTiming(
|
|
20
|
+
const faroNavigationEntry = Object.assign(Object.assign({}, createFaroNavigationTiming(navEntryJson)), { faroNavigationId: genShortID(), faroPreviousNavigationId });
|
|
18
21
|
setItem(NAVIGATION_ID_STORAGE_KEY, faroNavigationEntry.faroNavigationId, webStorageType.session);
|
|
19
|
-
pushEvent('faro.performance.navigation', faroNavigationEntry);
|
|
22
|
+
pushEvent('faro.performance.navigation', faroNavigationEntry, undefined, { spanContext });
|
|
20
23
|
faroNavigationEntryResolve(faroNavigationEntry);
|
|
21
24
|
});
|
|
22
25
|
observer.observe({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/navigation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAExE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,iBAAiB,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AAKnH,MAAM,UAAU,oBAAoB,CAClC,SAAiC,EACjC,WAAmC;IAEnC,IAAI,0BAA+D,CAAC;IACpE,MAAM,0BAA0B,GAAG,IAAI,OAAO,CAAqB,CAAC,OAAO,EAAE,EAAE;QAC7E,0BAA0B,GAAG,OAAO,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,IAAI,mBAAmB,CAAC,CAAC,eAAe,EAAE,EAAE;;QAC3D,MAAM,CAAC,kBAAkB,CAAC,GAAG,eAAe,CAAC,UAAU,EAAE,CAAC;QAE1D,IAAI,kBAAkB,IAAI,IAAI,IAAI,iBAAiB,CAAC,WAAW,EAAE,kBAAkB,CAAC,IAAI,CAAC,EAAE;YACzF,OAAO;SACR;QAED,MAAM,YAAY,GAAG,kBAAkB,CAAC,MAAM,EAAE,CAAC;QAEjD,IAAI,WAAW,GAAgB,8BAA8B,CAAC,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,YAAY,CAAC,CAAC;QAE1F,MAAM,wBAAwB,GAAG,MAAA,OAAO,CAAC,yBAAyB,EAAE,cAAc,CAAC,OAAO,CAAC,mCAAI,SAAS,CAAC;QAEzG,MAAM,mBAAmB,mCACpB,0BAA0B,CAAC,YAAY,CAAC,KAC3C,gBAAgB,EAAE,UAAU,EAAE,EAC9B,wBAAwB,GACzB,CAAC;QAEF,OAAO,CAAC,yBAAyB,EAAE,mBAAmB,CAAC,gBAAgB,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;QAEjG,SAAS,CAAC,6BAA6B,EAAE,mBAAmB,EAAE,SAAS,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;QAE1F,0BAA0B,CAAC,mBAAmB,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,OAAO,CAAC;QACf,IAAI,EAAE,gBAAgB;QACtB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IAEH,OAAO,0BAA0B,CAAC;AACpC,CAAC","sourcesContent":["import { genShortID } from '@grafana/faro-core';\nimport type { EventsAPI, PushEventOptions } from '@grafana/faro-core';\n\nimport { getItem, setItem, webStorageType } from '../../utils';\nimport { NAVIGATION_ID_STORAGE_KEY } from '../instrumentationConstants';\n\nimport { NAVIGATION_ENTRY } from './performanceConstants';\nimport { createFaroNavigationTiming, entryUrlIsIgnored, getSpanContextFromServerTiming } from './performanceUtils';\nimport type { FaroNavigationItem } from './types';\n\ntype SpanContext = PushEventOptions['spanContext'];\n\nexport function getNavigationTimings(\n pushEvent: EventsAPI['pushEvent'],\n ignoredUrls: Array<string | RegExp>\n): Promise<FaroNavigationItem> {\n let faroNavigationEntryResolve: (value: FaroNavigationItem) => void;\n const faroNavigationEntryPromise = new Promise<FaroNavigationItem>((resolve) => {\n faroNavigationEntryResolve = resolve;\n });\n\n const observer = new PerformanceObserver((observedEntries) => {\n const [navigationEntryRaw] = observedEntries.getEntries();\n\n if (navigationEntryRaw == null || entryUrlIsIgnored(ignoredUrls, navigationEntryRaw.name)) {\n return;\n }\n\n const navEntryJson = navigationEntryRaw.toJSON();\n\n let spanContext: SpanContext = getSpanContextFromServerTiming(navEntryJson?.serverTiming);\n\n const faroPreviousNavigationId = getItem(NAVIGATION_ID_STORAGE_KEY, webStorageType.session) ?? 'unknown';\n\n const faroNavigationEntry: FaroNavigationItem = {\n ...createFaroNavigationTiming(navEntryJson),\n faroNavigationId: genShortID(),\n faroPreviousNavigationId,\n };\n\n setItem(NAVIGATION_ID_STORAGE_KEY, faroNavigationEntry.faroNavigationId, webStorageType.session);\n\n pushEvent('faro.performance.navigation', faroNavigationEntry, undefined, { spanContext });\n\n faroNavigationEntryResolve(faroNavigationEntry);\n });\n\n observer.observe({\n type: NAVIGATION_ENTRY,\n buffered: true,\n });\n\n return faroNavigationEntryPromise;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"performanceConstants.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/performanceConstants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"performanceConstants.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/performanceConstants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC;AAC7C,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAC","sourcesContent":["export const NAVIGATION_ENTRY = 'navigation';\nexport const RESOURCE_ENTRY = 'resource';\n"]}
|
|
@@ -1,4 +1,21 @@
|
|
|
1
1
|
import { isArray } from '@grafana/faro-core';
|
|
2
|
+
const w3cTraceparentFormat = /^00-[a-f0-9]{32}-[a-f0-9]{16}-[0-9]{1,2}$/;
|
|
3
|
+
// Extract traceparent from serverTiming, if present
|
|
4
|
+
export function getSpanContextFromServerTiming(serverTimings = []) {
|
|
5
|
+
for (const serverEntry of serverTimings) {
|
|
6
|
+
if (serverEntry.name === 'traceparent') {
|
|
7
|
+
if (!w3cTraceparentFormat.test(serverEntry.description)) {
|
|
8
|
+
continue;
|
|
9
|
+
}
|
|
10
|
+
const [, traceId, spanId] = serverEntry.description.split('-');
|
|
11
|
+
if (traceId != null && spanId != null) {
|
|
12
|
+
return { traceId, spanId };
|
|
13
|
+
}
|
|
14
|
+
break;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
2
19
|
export function performanceObserverSupported() {
|
|
3
20
|
return 'PerformanceObserver' in window;
|
|
4
21
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"performanceUtils.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/performanceUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import { isArray } from '@grafana/faro-core';\n\nimport type { CacheType, FaroNavigationTiming, FaroResourceTiming } from './types';\n\nexport function performanceObserverSupported(): boolean {\n return 'PerformanceObserver' in window;\n}\n\nexport function entryUrlIsIgnored(ignoredUrls: Array<string | RegExp> = [], entryName: string): boolean {\n return ignoredUrls.some((url) => url && entryName.match(url) != null);\n}\n\nexport function onDocumentReady(handleReady: () => void) {\n if (document.readyState === 'complete') {\n handleReady();\n } else {\n const readyStateCompleteHandler = () => {\n if (document.readyState === 'complete') {\n handleReady();\n document.removeEventListener('readystatechange', readyStateCompleteHandler);\n }\n };\n\n document.addEventListener('readystatechange', readyStateCompleteHandler);\n }\n}\n\ntype PerformanceEntryAllowProperties = Record<string, Array<string | number> | string | number>;\n\nexport function includePerformanceEntry(\n performanceEntryJSON: Record<string, any>,\n allowProps: PerformanceEntryAllowProperties = {}\n): boolean {\n for (const [allowPropKey, allowPropValue] of Object.entries(allowProps)) {\n const perfEntryPropVal = performanceEntryJSON[allowPropKey];\n\n if (perfEntryPropVal == null) {\n return false;\n }\n\n if (isArray(allowPropValue)) {\n return allowPropValue.includes(perfEntryPropVal);\n }\n\n return perfEntryPropVal === allowPropValue;\n }\n\n // empty object allows all\n return true;\n}\n\nexport function createFaroResourceTiming(resourceEntryRaw: PerformanceResourceTiming): FaroResourceTiming {\n const {\n connectEnd,\n connectStart,\n decodedBodySize,\n domainLookupEnd,\n domainLookupStart,\n duration,\n encodedBodySize,\n fetchStart,\n initiatorType,\n name,\n nextHopProtocol,\n redirectEnd,\n redirectStart,\n // @ts-expect-error the renderBlockingStatus property is not available in all browsers\n renderBlockingStatus: rbs,\n requestStart,\n responseEnd,\n responseStart,\n // @ts-expect-error the renderBlockingStatus property is not available in all browsers\n responseStatus,\n secureConnectionStart,\n transferSize,\n workerStart,\n } = resourceEntryRaw;\n\n return {\n name: name,\n duration: toFaroPerformanceTimingString(duration),\n tcpHandshakeTime: toFaroPerformanceTimingString(connectEnd - connectStart),\n dnsLookupTime: toFaroPerformanceTimingString(domainLookupEnd - domainLookupStart),\n tlsNegotiationTime: toFaroPerformanceTimingString(requestStart - secureConnectionStart),\n responseStatus: toFaroPerformanceTimingString(responseStatus),\n redirectTime: toFaroPerformanceTimingString(redirectEnd - redirectStart),\n requestTime: toFaroPerformanceTimingString(responseStart - requestStart),\n responseTime: toFaroPerformanceTimingString(responseEnd - responseStart),\n fetchTime: toFaroPerformanceTimingString(responseEnd - fetchStart),\n serviceWorkerTime: toFaroPerformanceTimingString(fetchStart - workerStart),\n decodedBodySize: toFaroPerformanceTimingString(decodedBodySize),\n encodedBodySize: toFaroPerformanceTimingString(encodedBodySize),\n cacheHitStatus: getCacheType(),\n renderBlockingStatus: toFaroPerformanceTimingString(rbs) as FaroResourceTiming['renderBlockingStatus'],\n protocol: nextHopProtocol,\n initiatorType: initiatorType,\n\n // TODO: add in future iteration, ideally after nested objects are supported by the collector.\n // serverTiming: resourceEntryRaw.serverTiming,\n };\n\n function getCacheType(): CacheType {\n let cacheType: CacheType = 'fullLoad';\n if (transferSize === 0) {\n if (decodedBodySize > 0) {\n cacheType = 'cache';\n }\n } else {\n if (responseStatus != null) {\n if (responseStatus === 304) {\n cacheType = 'conditionalFetch';\n }\n } else if (encodedBodySize > 0 && transferSize < encodedBodySize) {\n cacheType = 'conditionalFetch';\n }\n }\n return cacheType;\n }\n}\n\nexport function createFaroNavigationTiming(navigationEntryRaw: PerformanceNavigationTiming): FaroNavigationTiming {\n const {\n activationStart,\n domComplete,\n domContentLoadedEventEnd,\n domContentLoadedEventStart,\n domInteractive,\n fetchStart,\n loadEventEnd,\n loadEventStart,\n responseStart,\n type,\n } = navigationEntryRaw;\n\n const parserStart = getDocumentParsingTime();\n\n return {\n visibilityState: document.visibilityState,\n pageLoadTime: toFaroPerformanceTimingString(domComplete - fetchStart),\n documentParsingTime: toFaroPerformanceTimingString(parserStart ? domInteractive - parserStart : null),\n domProcessingTime: toFaroPerformanceTimingString(domComplete - domInteractive),\n domContentLoadHandlerTime: toFaroPerformanceTimingString(domContentLoadedEventEnd - domContentLoadedEventStart),\n onLoadTime: toFaroPerformanceTimingString(loadEventEnd - loadEventStart),\n\n // For more accuracy on prerendered pages page we calculate relative top the activationStart instead of the start of the navigation.\n // clamp to 0 if activationStart occurs after first byte is received.\n ttfb: toFaroPerformanceTimingString(Math.max(responseStart - (activationStart ?? 0), 0)),\n\n type: type,\n\n ...createFaroResourceTiming(navigationEntryRaw),\n };\n}\n\nfunction getDocumentParsingTime(): number | null {\n if (performance.timing?.domLoading != null) {\n // the browser is about to start parsing the first received bytes of the HTML document.\n // This property is deprecated but there isn't a really good alternative atm.\n // For now we stick with domLoading and keep researching a better alternative.\n return performance.timing.domLoading - performance.timeOrigin;\n }\n\n return null;\n}\n\nfunction toFaroPerformanceTimingString(v: unknown): string {\n if (v == null) {\n return 'unknown';\n }\n\n if (typeof v === 'number') {\n return Math.round(v).toString();\n }\n\n return v.toString();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"performanceUtils.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/performanceUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import { isArray, type PushEventOptions } from '@grafana/faro-core';\n\nimport type { CacheType, FaroNavigationTiming, FaroResourceTiming } from './types';\n\nconst w3cTraceparentFormat = /^00-[a-f0-9]{32}-[a-f0-9]{16}-[0-9]{1,2}$/;\n\ntype SpanContext = PushEventOptions['spanContext'];\n\n// Extract traceparent from serverTiming, if present\nexport function getSpanContextFromServerTiming(serverTimings: PerformanceServerTiming[] = []): SpanContext | undefined {\n for (const serverEntry of serverTimings) {\n if (serverEntry.name === 'traceparent') {\n if (!w3cTraceparentFormat.test(serverEntry.description)) {\n continue;\n }\n\n const [, traceId, spanId] = serverEntry.description.split('-');\n if (traceId != null && spanId != null) {\n return { traceId, spanId };\n }\n\n break;\n }\n }\n\n return undefined;\n}\n\nexport function performanceObserverSupported(): boolean {\n return 'PerformanceObserver' in window;\n}\n\nexport function entryUrlIsIgnored(ignoredUrls: Array<string | RegExp> = [], entryName: string): boolean {\n return ignoredUrls.some((url) => url && entryName.match(url) != null);\n}\n\nexport function onDocumentReady(handleReady: () => void) {\n if (document.readyState === 'complete') {\n handleReady();\n } else {\n const readyStateCompleteHandler = () => {\n if (document.readyState === 'complete') {\n handleReady();\n document.removeEventListener('readystatechange', readyStateCompleteHandler);\n }\n };\n\n document.addEventListener('readystatechange', readyStateCompleteHandler);\n }\n}\n\ntype PerformanceEntryAllowProperties = Record<string, Array<string | number> | string | number>;\n\nexport function includePerformanceEntry(\n performanceEntryJSON: Record<string, any>,\n allowProps: PerformanceEntryAllowProperties = {}\n): boolean {\n for (const [allowPropKey, allowPropValue] of Object.entries(allowProps)) {\n const perfEntryPropVal = performanceEntryJSON[allowPropKey];\n\n if (perfEntryPropVal == null) {\n return false;\n }\n\n if (isArray(allowPropValue)) {\n return allowPropValue.includes(perfEntryPropVal);\n }\n\n return perfEntryPropVal === allowPropValue;\n }\n\n // empty object allows all\n return true;\n}\n\nexport function createFaroResourceTiming(resourceEntryRaw: PerformanceResourceTiming): FaroResourceTiming {\n const {\n connectEnd,\n connectStart,\n decodedBodySize,\n domainLookupEnd,\n domainLookupStart,\n duration,\n encodedBodySize,\n fetchStart,\n initiatorType,\n name,\n nextHopProtocol,\n redirectEnd,\n redirectStart,\n // @ts-expect-error the renderBlockingStatus property is not available in all browsers\n renderBlockingStatus: rbs,\n requestStart,\n responseEnd,\n responseStart,\n // @ts-expect-error the renderBlockingStatus property is not available in all browsers\n responseStatus,\n secureConnectionStart,\n transferSize,\n workerStart,\n } = resourceEntryRaw;\n\n return {\n name: name,\n duration: toFaroPerformanceTimingString(duration),\n tcpHandshakeTime: toFaroPerformanceTimingString(connectEnd - connectStart),\n dnsLookupTime: toFaroPerformanceTimingString(domainLookupEnd - domainLookupStart),\n tlsNegotiationTime: toFaroPerformanceTimingString(requestStart - secureConnectionStart),\n responseStatus: toFaroPerformanceTimingString(responseStatus),\n redirectTime: toFaroPerformanceTimingString(redirectEnd - redirectStart),\n requestTime: toFaroPerformanceTimingString(responseStart - requestStart),\n responseTime: toFaroPerformanceTimingString(responseEnd - responseStart),\n fetchTime: toFaroPerformanceTimingString(responseEnd - fetchStart),\n serviceWorkerTime: toFaroPerformanceTimingString(fetchStart - workerStart),\n decodedBodySize: toFaroPerformanceTimingString(decodedBodySize),\n encodedBodySize: toFaroPerformanceTimingString(encodedBodySize),\n cacheHitStatus: getCacheType(),\n renderBlockingStatus: toFaroPerformanceTimingString(rbs) as FaroResourceTiming['renderBlockingStatus'],\n protocol: nextHopProtocol,\n initiatorType: initiatorType,\n\n // TODO: add in future iteration, ideally after nested objects are supported by the collector.\n // serverTiming: resourceEntryRaw.serverTiming,\n };\n\n function getCacheType(): CacheType {\n let cacheType: CacheType = 'fullLoad';\n if (transferSize === 0) {\n if (decodedBodySize > 0) {\n cacheType = 'cache';\n }\n } else {\n if (responseStatus != null) {\n if (responseStatus === 304) {\n cacheType = 'conditionalFetch';\n }\n } else if (encodedBodySize > 0 && transferSize < encodedBodySize) {\n cacheType = 'conditionalFetch';\n }\n }\n return cacheType;\n }\n}\n\nexport function createFaroNavigationTiming(navigationEntryRaw: PerformanceNavigationTiming): FaroNavigationTiming {\n const {\n activationStart,\n domComplete,\n domContentLoadedEventEnd,\n domContentLoadedEventStart,\n domInteractive,\n fetchStart,\n loadEventEnd,\n loadEventStart,\n responseStart,\n type,\n } = navigationEntryRaw;\n\n const parserStart = getDocumentParsingTime();\n\n return {\n visibilityState: document.visibilityState,\n pageLoadTime: toFaroPerformanceTimingString(domComplete - fetchStart),\n documentParsingTime: toFaroPerformanceTimingString(parserStart ? domInteractive - parserStart : null),\n domProcessingTime: toFaroPerformanceTimingString(domComplete - domInteractive),\n domContentLoadHandlerTime: toFaroPerformanceTimingString(domContentLoadedEventEnd - domContentLoadedEventStart),\n onLoadTime: toFaroPerformanceTimingString(loadEventEnd - loadEventStart),\n\n // For more accuracy on prerendered pages page we calculate relative top the activationStart instead of the start of the navigation.\n // clamp to 0 if activationStart occurs after first byte is received.\n ttfb: toFaroPerformanceTimingString(Math.max(responseStart - (activationStart ?? 0), 0)),\n\n type: type,\n\n ...createFaroResourceTiming(navigationEntryRaw),\n };\n}\n\nfunction getDocumentParsingTime(): number | null {\n if (performance.timing?.domLoading != null) {\n // the browser is about to start parsing the first received bytes of the HTML document.\n // This property is deprecated but there isn't a really good alternative atm.\n // For now we stick with domLoading and keep researching a better alternative.\n return performance.timing.domLoading - performance.timeOrigin;\n }\n\n return null;\n}\n\nfunction toFaroPerformanceTimingString(v: unknown): string {\n if (v == null) {\n return 'unknown';\n }\n\n if (typeof v === 'number') {\n return Math.round(v).toString();\n }\n\n return v.toString();\n}\n"]}
|
|
@@ -22,7 +22,13 @@ export const performanceNavigationEntry = {
|
|
|
22
22
|
transferSize: 127601,
|
|
23
23
|
encodedBodySize: 126111,
|
|
24
24
|
decodedBodySize: 530675,
|
|
25
|
-
serverTiming: [
|
|
25
|
+
serverTiming: [
|
|
26
|
+
{
|
|
27
|
+
name: 'traceparent',
|
|
28
|
+
duration: 0,
|
|
29
|
+
description: '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01',
|
|
30
|
+
},
|
|
31
|
+
],
|
|
26
32
|
unloadEventStart: 0,
|
|
27
33
|
unloadEventEnd: 0,
|
|
28
34
|
domInteractive: 1247,
|
|
@@ -58,6 +64,11 @@ export const performanceResourceEntry = {
|
|
|
58
64
|
encodedBodySize: 10526,
|
|
59
65
|
decodedBodySize: 10526,
|
|
60
66
|
serverTiming: [
|
|
67
|
+
{
|
|
68
|
+
name: 'traceparent',
|
|
69
|
+
duration: 0,
|
|
70
|
+
description: '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01',
|
|
71
|
+
},
|
|
61
72
|
{
|
|
62
73
|
name: 'foo',
|
|
63
74
|
duration: 0,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"performanceUtilsTestData.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/performanceUtilsTestData.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,IAAI,EAAE,oBAAoB;IAC1B,SAAS,EAAE,YAAY;IACvB,SAAS,EAAE,CAAC;IACZ,QAAQ,EAAE,IAAI;IACd,aAAa,EAAE,YAAY;IAC3B,eAAe,EAAE,IAAI;IACrB,WAAW,EAAE,CAAC;IACd,aAAa,EAAE,CAAC;IAChB,WAAW,EAAE,CAAC;IACd,UAAU,EAAE,GAAG;IACf,iBAAiB,EAAE,GAAG;IACtB,eAAe,EAAE,GAAG;IACpB,YAAY,EAAE,GAAG;IACjB,UAAU,EAAE,GAAG;IACf,qBAAqB,EAAE,GAAG;IAC1B,YAAY,EAAE,GAAG;IACjB,aAAa,EAAE,GAAG;IAClB,cAAc,EAAE,GAAG;IACnB,WAAW,EAAE,GAAG;IAChB,YAAY,EAAE,MAAM;IACpB,eAAe,EAAE,MAAM;IACvB,eAAe,EAAE,MAAM;IACvB,YAAY,EAAE,EAAE;
|
|
1
|
+
{"version":3,"file":"performanceUtilsTestData.js","sourceRoot":"","sources":["../../../../src/instrumentations/performance/performanceUtilsTestData.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,IAAI,EAAE,oBAAoB;IAC1B,SAAS,EAAE,YAAY;IACvB,SAAS,EAAE,CAAC;IACZ,QAAQ,EAAE,IAAI;IACd,aAAa,EAAE,YAAY;IAC3B,eAAe,EAAE,IAAI;IACrB,WAAW,EAAE,CAAC;IACd,aAAa,EAAE,CAAC;IAChB,WAAW,EAAE,CAAC;IACd,UAAU,EAAE,GAAG;IACf,iBAAiB,EAAE,GAAG;IACtB,eAAe,EAAE,GAAG;IACpB,YAAY,EAAE,GAAG;IACjB,UAAU,EAAE,GAAG;IACf,qBAAqB,EAAE,GAAG;IAC1B,YAAY,EAAE,GAAG;IACjB,aAAa,EAAE,GAAG;IAClB,cAAc,EAAE,GAAG;IACnB,WAAW,EAAE,GAAG;IAChB,YAAY,EAAE,MAAM;IACpB,eAAe,EAAE,MAAM;IACvB,eAAe,EAAE,MAAM;IACvB,YAAY,EAAE;QACZ;YACE,IAAI,EAAE,aAAa;YACnB,QAAQ,EAAE,CAAC;YACX,WAAW,EAAE,yDAAyD;SACvE;KACF;IACD,gBAAgB,EAAE,CAAC;IACnB,cAAc,EAAE,CAAC;IACjB,cAAc,EAAE,IAAI;IACpB,0BAA0B,EAAE,IAAI;IAChC,wBAAwB,EAAE,IAAI;IAC9B,WAAW,EAAE,IAAI;IACjB,cAAc,EAAE,IAAI;IACpB,YAAY,EAAE,IAAI;IAClB,IAAI,EAAE,UAAU;IAChB,aAAa,EAAE,CAAC;CACyB,CAAC;AAE5C,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,IAAI,EAAE,kCAAkC;IACxC,SAAS,EAAE,UAAU;IACrB,SAAS,EAAE,GAAG;IACd,QAAQ,EAAE,GAAG;IACb,aAAa,EAAE,KAAK;IACpB,eAAe,EAAE,IAAI;IACrB,WAAW,EAAE,CAAC;IACd,aAAa,EAAE,CAAC;IAChB,WAAW,EAAE,CAAC;IACd,UAAU,EAAE,GAAG;IACf,iBAAiB,EAAE,GAAG;IACtB,eAAe,EAAE,GAAG;IACpB,YAAY,EAAE,GAAG;IACjB,UAAU,EAAE,GAAG;IACf,qBAAqB,EAAE,GAAG;IAC1B,YAAY,EAAE,GAAG;IACjB,aAAa,EAAE,IAAI;IACnB,cAAc,EAAE,KAAK;IACrB,WAAW,EAAE,IAAI;IACjB,YAAY,EAAE,KAAK;IACnB,eAAe,EAAE,KAAK;IACtB,eAAe,EAAE,KAAK;IACtB,YAAY,EAAE;QACZ;YACE,IAAI,EAAE,aAAa;YACnB,QAAQ,EAAE,CAAC;YACX,WAAW,EAAE,yDAAyD;SACvE;QACD;YACE,IAAI,EAAE,KAAK;YACX,QAAQ,EAAE,CAAC;YACX,WAAW,EAAE,KAAK;SACnB;KACF;CACsC,CAAC;AAE1C,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,kCAAkC;CACD,CAAC;AAE1C,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,6BAA6B;CACI,CAAC","sourcesContent":["// the values of this timings are contrived for testing.They do not necessarily reflect reality.\nexport const performanceNavigationEntry = {\n name: 'http://example.com',\n entryType: 'navigation',\n startTime: 0,\n duration: 2700,\n initiatorType: 'navigation',\n nextHopProtocol: 'h2',\n workerStart: 0,\n redirectStart: 1,\n redirectEnd: 2,\n fetchStart: 237,\n domainLookupStart: 241,\n domainLookupEnd: 380,\n connectStart: 380,\n connectEnd: 433,\n secureConnectionStart: 400,\n requestStart: 433,\n responseStart: 542,\n responseStatus: 200,\n responseEnd: 542,\n transferSize: 127601,\n encodedBodySize: 126111,\n decodedBodySize: 530675,\n serverTiming: [\n {\n name: 'traceparent',\n duration: 0,\n description: '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01',\n },\n ],\n unloadEventStart: 0,\n unloadEventEnd: 0,\n domInteractive: 1247,\n domContentLoadedEventStart: 1247,\n domContentLoadedEventEnd: 1250,\n domComplete: 2678,\n loadEventStart: 2678,\n loadEventEnd: 2700,\n type: 'navigate',\n redirectCount: 0,\n} as unknown as PerformanceNavigationTiming;\n\nexport const performanceResourceEntry = {\n name: 'http://example.com/awesome-image',\n entryType: 'resource',\n startTime: 778,\n duration: 370,\n initiatorType: 'img',\n nextHopProtocol: 'h2',\n workerStart: 0,\n redirectStart: 0,\n redirectEnd: 0,\n fetchStart: 778,\n domainLookupStart: 778,\n domainLookupEnd: 778,\n connectStart: 778,\n connectEnd: 778,\n secureConnectionStart: 778,\n requestStart: 789,\n responseStart: 1148,\n responseStatus: '200',\n responseEnd: 1148,\n transferSize: 11459,\n encodedBodySize: 10526,\n decodedBodySize: 10526,\n serverTiming: [\n {\n name: 'traceparent',\n duration: 0,\n description: '00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01',\n },\n {\n name: 'foo',\n duration: 0,\n description: 'bar',\n },\n ],\n} as unknown as PerformanceResourceTiming;\n\nexport const analyticsEntry1 = {\n name: 'http://example.com/foo-analytics',\n} as unknown as PerformanceResourceTiming;\n\nexport const analyticsEntry2 = {\n name: 'http://analytics.com/beacon',\n} as unknown as PerformanceResourceTiming;\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { faro, genShortID } from '@grafana/faro-core';
|
|
2
2
|
import { RESOURCE_ENTRY } from './performanceConstants';
|
|
3
|
-
import { createFaroResourceTiming, entryUrlIsIgnored, includePerformanceEntry } from './performanceUtils';
|
|
3
|
+
import { createFaroResourceTiming, entryUrlIsIgnored, getSpanContextFromServerTiming, includePerformanceEntry, } from './performanceUtils';
|
|
4
4
|
const DEFAULT_TRACK_RESOURCES = { initiatorType: ['xmlhttprequest', 'fetch'] };
|
|
5
5
|
export function observeResourceTimings(faroNavigationId, pushEvent, ignoredUrls) {
|
|
6
6
|
const trackResources = faro.config.trackResources;
|
|
@@ -11,10 +11,11 @@ export function observeResourceTimings(faroNavigationId, pushEvent, ignoredUrls)
|
|
|
11
11
|
return;
|
|
12
12
|
}
|
|
13
13
|
const resourceEntryRawJSON = resourceEntryRaw.toJSON();
|
|
14
|
+
let spanContext = getSpanContextFromServerTiming(resourceEntryRawJSON === null || resourceEntryRawJSON === void 0 ? void 0 : resourceEntryRawJSON.serverTiming);
|
|
14
15
|
if ((trackResources == null && includePerformanceEntry(resourceEntryRawJSON, DEFAULT_TRACK_RESOURCES)) ||
|
|
15
16
|
trackResources) {
|
|
16
17
|
const faroResourceEntry = Object.assign(Object.assign({}, createFaroResourceTiming(resourceEntryRawJSON)), { faroNavigationId, faroResourceId: genShortID() });
|
|
17
|
-
pushEvent('faro.performance.resource', faroResourceEntry);
|
|
18
|
+
pushEvent('faro.performance.resource', faroResourceEntry, undefined, { spanContext });
|
|
18
19
|
}
|
|
19
20
|
}
|
|
20
21
|
});
|