@atlaskit/react-ufo 3.14.3 → 3.14.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/cjs/create-payload/critical-metrics-payload/index.js +38 -0
- package/dist/cjs/create-payload/critical-metrics-payload/root-metrics.js +180 -0
- package/dist/cjs/create-payload/critical-metrics-payload/segment-metrics/create-segment-metrics.js +251 -0
- package/dist/cjs/create-payload/critical-metrics-payload/segment-metrics/get-is-root-segment.js +9 -0
- package/dist/cjs/create-payload/critical-metrics-payload/segment-metrics/get-segment-id.js +15 -0
- package/dist/cjs/create-payload/critical-metrics-payload/segment-metrics/get-segment-status.js +59 -0
- package/dist/cjs/create-payload/critical-metrics-payload/segment-metrics/has-segment-failed.js +17 -0
- package/dist/cjs/create-payload/critical-metrics-payload/segment-metrics/is-label-stack-under-segment.js +11 -0
- package/dist/cjs/create-payload/critical-metrics-payload/types.js +5 -0
- package/dist/cjs/create-payload/index.js +122 -214
- package/dist/cjs/create-payload/utils/find-matching-legacy-metric.js +15 -0
- package/dist/cjs/create-payload/utils/get-browser-metadata.js +87 -0
- package/dist/cjs/create-payload/utils/get-fmp.js +52 -0
- package/dist/cjs/create-payload/utils/get-navigation-metrics.js +66 -0
- package/dist/cjs/create-payload/utils/get-paint-metrics.js +124 -0
- package/dist/cjs/create-payload/utils/get-payload-size.js +17 -0
- package/dist/cjs/create-payload/utils/get-react-ufo-payload-version.js +3 -1
- package/dist/cjs/create-payload/utils/get-ssr-success.js +15 -0
- package/dist/cjs/create-payload/utils/get-ttai.js +14 -0
- package/dist/cjs/create-payload/utils/get-tti.js +38 -0
- package/dist/cjs/interaction-metrics/index.js +25 -0
- package/dist/cjs/vc/vc-observer-new/metric-calculator/fy25_03/index.js +3 -0
- package/dist/es2019/create-payload/critical-metrics-payload/index.js +6 -0
- package/dist/es2019/create-payload/critical-metrics-payload/root-metrics.js +166 -0
- package/dist/es2019/create-payload/critical-metrics-payload/segment-metrics/create-segment-metrics.js +155 -0
- package/dist/es2019/create-payload/critical-metrics-payload/segment-metrics/get-is-root-segment.js +3 -0
- package/dist/es2019/create-payload/critical-metrics-payload/segment-metrics/get-segment-id.js +9 -0
- package/dist/es2019/create-payload/critical-metrics-payload/segment-metrics/get-segment-status.js +40 -0
- package/dist/es2019/create-payload/critical-metrics-payload/segment-metrics/has-segment-failed.js +10 -0
- package/dist/es2019/create-payload/critical-metrics-payload/segment-metrics/is-label-stack-under-segment.js +5 -0
- package/dist/es2019/create-payload/critical-metrics-payload/types.js +1 -0
- package/dist/es2019/create-payload/index.js +55 -151
- package/dist/es2019/create-payload/utils/find-matching-legacy-metric.js +7 -0
- package/dist/es2019/create-payload/utils/get-browser-metadata.js +79 -0
- package/dist/es2019/create-payload/utils/get-fmp.js +47 -0
- package/dist/es2019/create-payload/utils/get-navigation-metrics.js +59 -0
- package/dist/es2019/create-payload/utils/get-paint-metrics.js +78 -0
- package/dist/es2019/create-payload/utils/get-payload-size.js +11 -0
- package/dist/es2019/create-payload/utils/get-react-ufo-payload-version.js +2 -1
- package/dist/es2019/create-payload/utils/get-ssr-success.js +7 -0
- package/dist/es2019/create-payload/utils/get-ttai.js +9 -0
- package/dist/es2019/create-payload/utils/get-tti.js +35 -0
- package/dist/es2019/interaction-metrics/index.js +24 -0
- package/dist/es2019/vc/vc-observer-new/metric-calculator/fy25_03/index.js +3 -0
- package/dist/esm/create-payload/critical-metrics-payload/index.js +31 -0
- package/dist/esm/create-payload/critical-metrics-payload/root-metrics.js +174 -0
- package/dist/esm/create-payload/critical-metrics-payload/segment-metrics/create-segment-metrics.js +244 -0
- package/dist/esm/create-payload/critical-metrics-payload/segment-metrics/get-is-root-segment.js +3 -0
- package/dist/esm/create-payload/critical-metrics-payload/segment-metrics/get-segment-id.js +9 -0
- package/dist/esm/create-payload/critical-metrics-payload/segment-metrics/get-segment-status.js +52 -0
- package/dist/esm/create-payload/critical-metrics-payload/segment-metrics/has-segment-failed.js +10 -0
- package/dist/esm/create-payload/critical-metrics-payload/segment-metrics/is-label-stack-under-segment.js +5 -0
- package/dist/esm/create-payload/critical-metrics-payload/types.js +1 -0
- package/dist/esm/create-payload/index.js +121 -210
- package/dist/esm/create-payload/utils/find-matching-legacy-metric.js +9 -0
- package/dist/esm/create-payload/utils/get-browser-metadata.js +79 -0
- package/dist/esm/create-payload/utils/get-fmp.js +47 -0
- package/dist/esm/create-payload/utils/get-navigation-metrics.js +59 -0
- package/dist/esm/create-payload/utils/get-paint-metrics.js +119 -0
- package/dist/esm/create-payload/utils/get-payload-size.js +11 -0
- package/dist/esm/create-payload/utils/get-react-ufo-payload-version.js +2 -1
- package/dist/esm/create-payload/utils/get-ssr-success.js +7 -0
- package/dist/esm/create-payload/utils/get-ttai.js +7 -0
- package/dist/esm/create-payload/utils/get-tti.js +33 -0
- package/dist/esm/interaction-metrics/index.js +24 -0
- package/dist/esm/vc/vc-observer-new/metric-calculator/fy25_03/index.js +3 -0
- package/dist/types/common/common/types.d.ts +1 -1
- package/dist/types/common/react-ufo-payload-schema.d.ts +23 -2
- package/dist/types/create-payload/critical-metrics-payload/index.d.ts +6 -0
- package/dist/types/create-payload/critical-metrics-payload/root-metrics.d.ts +7 -0
- package/dist/types/create-payload/critical-metrics-payload/segment-metrics/create-segment-metrics.d.ts +3 -0
- package/dist/types/create-payload/critical-metrics-payload/segment-metrics/get-is-root-segment.d.ts +2 -0
- package/dist/types/create-payload/critical-metrics-payload/segment-metrics/get-segment-id.d.ts +2 -0
- package/dist/types/create-payload/critical-metrics-payload/segment-metrics/get-segment-status.d.ts +7 -0
- package/dist/types/create-payload/critical-metrics-payload/segment-metrics/has-segment-failed.d.ts +2 -0
- package/dist/types/create-payload/critical-metrics-payload/segment-metrics/is-label-stack-under-segment.d.ts +2 -0
- package/dist/types/create-payload/critical-metrics-payload/types.d.ts +128 -0
- package/dist/types/create-payload/index.d.ts +339 -834
- package/dist/types/create-payload/utils/find-matching-legacy-metric.d.ts +5 -0
- package/dist/types/create-payload/utils/get-browser-metadata.d.ts +21 -0
- package/dist/types/create-payload/utils/get-fmp.d.ts +6 -0
- package/dist/types/create-payload/utils/get-navigation-metrics.d.ts +29 -0
- package/dist/types/create-payload/utils/get-paint-metrics.d.ts +13 -0
- package/dist/types/create-payload/utils/get-payload-size.d.ts +1 -0
- package/dist/types/create-payload/utils/get-react-ufo-payload-version.d.ts +2 -1
- package/dist/types/create-payload/utils/get-ssr-success.d.ts +2 -0
- package/dist/types/create-payload/utils/get-ttai.d.ts +2 -0
- package/dist/types/create-payload/utils/get-tti.d.ts +7 -0
- package/dist/types/interaction-metrics/index.d.ts +1 -0
- package/dist/types-ts4.5/common/common/types.d.ts +1 -1
- package/dist/types-ts4.5/common/react-ufo-payload-schema.d.ts +23 -2
- package/dist/types-ts4.5/create-payload/critical-metrics-payload/index.d.ts +6 -0
- package/dist/types-ts4.5/create-payload/critical-metrics-payload/root-metrics.d.ts +7 -0
- package/dist/types-ts4.5/create-payload/critical-metrics-payload/segment-metrics/create-segment-metrics.d.ts +3 -0
- package/dist/types-ts4.5/create-payload/critical-metrics-payload/segment-metrics/get-is-root-segment.d.ts +2 -0
- package/dist/types-ts4.5/create-payload/critical-metrics-payload/segment-metrics/get-segment-id.d.ts +2 -0
- package/dist/types-ts4.5/create-payload/critical-metrics-payload/segment-metrics/get-segment-status.d.ts +7 -0
- package/dist/types-ts4.5/create-payload/critical-metrics-payload/segment-metrics/has-segment-failed.d.ts +2 -0
- package/dist/types-ts4.5/create-payload/critical-metrics-payload/segment-metrics/is-label-stack-under-segment.d.ts +2 -0
- package/dist/types-ts4.5/create-payload/critical-metrics-payload/types.d.ts +130 -0
- package/dist/types-ts4.5/create-payload/index.d.ts +339 -834
- package/dist/types-ts4.5/create-payload/utils/find-matching-legacy-metric.d.ts +5 -0
- package/dist/types-ts4.5/create-payload/utils/get-browser-metadata.d.ts +21 -0
- package/dist/types-ts4.5/create-payload/utils/get-fmp.d.ts +6 -0
- package/dist/types-ts4.5/create-payload/utils/get-navigation-metrics.d.ts +29 -0
- package/dist/types-ts4.5/create-payload/utils/get-paint-metrics.d.ts +13 -0
- package/dist/types-ts4.5/create-payload/utils/get-payload-size.d.ts +1 -0
- package/dist/types-ts4.5/create-payload/utils/get-react-ufo-payload-version.d.ts +2 -1
- package/dist/types-ts4.5/create-payload/utils/get-ssr-success.d.ts +2 -0
- package/dist/types-ts4.5/create-payload/utils/get-ttai.d.ts +2 -0
- package/dist/types-ts4.5/create-payload/utils/get-tti.d.ts +7 -0
- package/dist/types-ts4.5/interaction-metrics/index.d.ts +1 -0
- package/package.json +8 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getFMP = getFMP;
|
|
7
|
+
var _config = require("../../config");
|
|
8
|
+
var _findMatchingLegacyMetric = require("./find-matching-legacy-metric");
|
|
9
|
+
/**
|
|
10
|
+
* Calculate FMP (First Meaningful Paint) based on interaction type and configuration
|
|
11
|
+
* FMP is calculated based on legacy metrics or marks depending on interaction type and configuration
|
|
12
|
+
*/
|
|
13
|
+
function getFMP(interaction, experienceName) {
|
|
14
|
+
var _config$ssr, _config$ssr$getSSRDon, _config$ssr2;
|
|
15
|
+
var start = interaction.start,
|
|
16
|
+
type = interaction.type,
|
|
17
|
+
marks = interaction.marks;
|
|
18
|
+
var config = (0, _config.getConfig)();
|
|
19
|
+
var ssrDoneTime = config === null || config === void 0 || (_config$ssr = config.ssr) === null || _config$ssr === void 0 || (_config$ssr$getSSRDon = _config$ssr.getSSRDoneTime) === null || _config$ssr$getSSRDon === void 0 ? void 0 : _config$ssr$getSSRDon.call(_config$ssr);
|
|
20
|
+
var isBM3ConfigSSRDoneAsFmp = interaction.metaData.__legacy__bm3ConfigSSRDoneAsFmp;
|
|
21
|
+
var isUFOConfigSSRDoneAsFmp = interaction.metaData.__legacy__bm3ConfigSSRDoneAsFmp || !!(config !== null && config !== void 0 && (_config$ssr2 = config.ssr) !== null && _config$ssr2 !== void 0 && _config$ssr2.getSSRDoneTime);
|
|
22
|
+
|
|
23
|
+
// Find matching legacy metric
|
|
24
|
+
var matchingLegacyMetric = (0, _findMatchingLegacyMetric.findMatchingLegacyMetric)(interaction, experienceName);
|
|
25
|
+
var fmp;
|
|
26
|
+
if (type === 'page_load' || type === 'transition') {
|
|
27
|
+
if (interaction.legacyMetrics && matchingLegacyMetric) {
|
|
28
|
+
// Check if legacy metric has FMP
|
|
29
|
+
var legacyFmp = matchingLegacyMetric.fmp; // BM3Event doesn't have fmp in types, but it might exist
|
|
30
|
+
if (legacyFmp) {
|
|
31
|
+
fmp = Math.round(legacyFmp - start);
|
|
32
|
+
}
|
|
33
|
+
// If no FMP in legacy metric, return undefined (don't calculate fallback)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (type === 'page_load' && fmp === undefined) {
|
|
37
|
+
if (isBM3ConfigSSRDoneAsFmp || isUFOConfigSSRDoneAsFmp) {
|
|
38
|
+
var _marks$find;
|
|
39
|
+
var foundMark = marks === null || marks === void 0 || (_marks$find = marks.find(function (mark) {
|
|
40
|
+
return mark.name === 'fmp';
|
|
41
|
+
})) === null || _marks$find === void 0 ? void 0 : _marks$find.time;
|
|
42
|
+
if (foundMark) {
|
|
43
|
+
fmp = Math.round(foundMark - start);
|
|
44
|
+
} else if (ssrDoneTime) {
|
|
45
|
+
fmp = Math.round(ssrDoneTime - start);
|
|
46
|
+
}
|
|
47
|
+
// If no FMP mark and no SSR done time, fmp remains undefined
|
|
48
|
+
}
|
|
49
|
+
// If not using SSR config, fmp remains undefined for page_load without legacy metrics
|
|
50
|
+
}
|
|
51
|
+
return fmp;
|
|
52
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = getNavigationMetrics;
|
|
7
|
+
exports.getNavigationMetricsToLegacyFormat = getNavigationMetricsToLegacyFormat;
|
|
8
|
+
function getNavigationMetrics(type) {
|
|
9
|
+
if (type !== 'page_load') {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
var entries = performance.getEntriesByType('navigation');
|
|
14
|
+
if (entries.length === 0) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
var navigation = entries[0];
|
|
18
|
+
return {
|
|
19
|
+
// From https://www.w3.org/TR/resource-timing/
|
|
20
|
+
redirectStart: Math.round(navigation.redirectStart),
|
|
21
|
+
redirectEnd: Math.round(navigation.redirectEnd),
|
|
22
|
+
fetchStart: Math.round(navigation.fetchStart),
|
|
23
|
+
domainLookupStart: Math.round(navigation.domainLookupStart),
|
|
24
|
+
domainLookupEnd: Math.round(navigation.domainLookupEnd),
|
|
25
|
+
connectStart: Math.round(navigation.connectStart),
|
|
26
|
+
connectEnd: Math.round(navigation.connectEnd),
|
|
27
|
+
secureConnectionStart: Math.round(navigation.secureConnectionStart),
|
|
28
|
+
requestStart: Math.round(navigation.requestStart),
|
|
29
|
+
responseStart: Math.round(navigation.responseStart),
|
|
30
|
+
responseEnd: Math.round(navigation.responseEnd),
|
|
31
|
+
encodedBodySize: Math.round(navigation.encodedBodySize),
|
|
32
|
+
decodedBodySize: Math.round(navigation.decodedBodySize),
|
|
33
|
+
transferSize: Math.round(navigation.transferSize),
|
|
34
|
+
// From https://www.w3.org/TR/navigation-timing-2/
|
|
35
|
+
redirectCount: navigation.redirectCount,
|
|
36
|
+
type: navigation.type,
|
|
37
|
+
unloadEventEnd: Math.round(navigation.unloadEventEnd),
|
|
38
|
+
unloadEventStart: Math.round(navigation.unloadEventStart),
|
|
39
|
+
workerStart: Math.round(navigation.workerStart),
|
|
40
|
+
nextHopProtocol: navigation.nextHopProtocol
|
|
41
|
+
|
|
42
|
+
// The following properties are ignored because they provided limited value on a modern stack (e.g. the content
|
|
43
|
+
// is usually rendered and interactive before the dom is fully parsed, don't play well with streamed content...)
|
|
44
|
+
// * domComplete
|
|
45
|
+
// * domContentLoadedEventEnd
|
|
46
|
+
// * domContentLoadedEventStart
|
|
47
|
+
// * domInteractive
|
|
48
|
+
// * loadEventEnd
|
|
49
|
+
// * loadEventStart
|
|
50
|
+
};
|
|
51
|
+
} catch (error) {
|
|
52
|
+
// Return null if there's any error accessing navigation timing
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Helper function to get navigation metrics in legacy format for backward compatibility
|
|
58
|
+
function getNavigationMetricsToLegacyFormat(type) {
|
|
59
|
+
var navigationMetrics = getNavigationMetrics(type);
|
|
60
|
+
if (!navigationMetrics) {
|
|
61
|
+
return {};
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
'metrics:navigation': navigationMetrics
|
|
65
|
+
};
|
|
66
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = getPaintMetrics;
|
|
8
|
+
exports.getPaintMetricsToLegacyFormat = getPaintMetricsToLegacyFormat;
|
|
9
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
10
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
11
|
+
// Type definitions for paint metrics
|
|
12
|
+
// Main function returns compact nested format
|
|
13
|
+
function getPaintMetrics(_x, _x2) {
|
|
14
|
+
return _getPaintMetrics.apply(this, arguments);
|
|
15
|
+
} // Helper function to get paint metrics in legacy colon format for backward compatibility
|
|
16
|
+
function _getPaintMetrics() {
|
|
17
|
+
_getPaintMetrics = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(type, end) {
|
|
18
|
+
var paint, paintEntries, lcp;
|
|
19
|
+
return _regenerator.default.wrap(function _callee$(_context) {
|
|
20
|
+
while (1) switch (_context.prev = _context.next) {
|
|
21
|
+
case 0:
|
|
22
|
+
if (!(type !== 'page_load')) {
|
|
23
|
+
_context.next = 2;
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
return _context.abrupt("return", {});
|
|
27
|
+
case 2:
|
|
28
|
+
paint = {};
|
|
29
|
+
paintEntries = performance.getEntriesByType('paint');
|
|
30
|
+
paintEntries.forEach(function (entry) {
|
|
31
|
+
if (entry.name === 'first-paint') {
|
|
32
|
+
paint.fp = Math.round(entry.startTime);
|
|
33
|
+
}
|
|
34
|
+
if (entry.name === 'first-contentful-paint') {
|
|
35
|
+
paint.fcp = Math.round(entry.startTime);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Get LCP using PerformanceObserver
|
|
40
|
+
_context.next = 7;
|
|
41
|
+
return new Promise(function (resolve) {
|
|
42
|
+
// Check if we already have LCP entries
|
|
43
|
+
var existingEntries = performance.getEntriesByType('largest-contentful-paint');
|
|
44
|
+
var lastEntry = existingEntries.reduce(function (agg, entry) {
|
|
45
|
+
if (entry.startTime <= end && (agg === null || agg.startTime < entry.startTime)) {
|
|
46
|
+
return entry;
|
|
47
|
+
}
|
|
48
|
+
return agg;
|
|
49
|
+
}, null);
|
|
50
|
+
if (lastEntry) {
|
|
51
|
+
resolve(lastEntry.startTime);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
var observer = new PerformanceObserver(function (list) {
|
|
55
|
+
var entries = Array.from(list.getEntries());
|
|
56
|
+
var lastEntry = entries.reduce(function (agg, entry) {
|
|
57
|
+
if (entry.startTime <= end && (agg === null || agg.startTime < entry.startTime)) {
|
|
58
|
+
return entry;
|
|
59
|
+
}
|
|
60
|
+
return agg;
|
|
61
|
+
}, null);
|
|
62
|
+
clearTimeout(timeoutId);
|
|
63
|
+
observer.disconnect();
|
|
64
|
+
if (lastEntry) {
|
|
65
|
+
resolve(lastEntry.startTime);
|
|
66
|
+
} else {
|
|
67
|
+
resolve(null);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
observer.observe({
|
|
71
|
+
type: 'largest-contentful-paint',
|
|
72
|
+
buffered: true
|
|
73
|
+
});
|
|
74
|
+
var timeoutId = setTimeout(function () {
|
|
75
|
+
observer.disconnect();
|
|
76
|
+
resolve(null);
|
|
77
|
+
}, 200);
|
|
78
|
+
});
|
|
79
|
+
case 7:
|
|
80
|
+
lcp = _context.sent;
|
|
81
|
+
if (lcp) {
|
|
82
|
+
paint.lcp = Math.round(lcp);
|
|
83
|
+
}
|
|
84
|
+
return _context.abrupt("return", paint);
|
|
85
|
+
case 10:
|
|
86
|
+
case "end":
|
|
87
|
+
return _context.stop();
|
|
88
|
+
}
|
|
89
|
+
}, _callee);
|
|
90
|
+
}));
|
|
91
|
+
return _getPaintMetrics.apply(this, arguments);
|
|
92
|
+
}
|
|
93
|
+
function getPaintMetricsToLegacyFormat(_x3, _x4) {
|
|
94
|
+
return _getPaintMetricsToLegacyFormat.apply(this, arguments);
|
|
95
|
+
}
|
|
96
|
+
function _getPaintMetricsToLegacyFormat() {
|
|
97
|
+
_getPaintMetricsToLegacyFormat = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(type, end) {
|
|
98
|
+
var paint, legacyFormat;
|
|
99
|
+
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
100
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
101
|
+
case 0:
|
|
102
|
+
_context2.next = 2;
|
|
103
|
+
return getPaintMetrics(type, end);
|
|
104
|
+
case 2:
|
|
105
|
+
paint = _context2.sent;
|
|
106
|
+
legacyFormat = {};
|
|
107
|
+
if (paint.fp !== undefined) {
|
|
108
|
+
legacyFormat['metric:fp'] = paint.fp;
|
|
109
|
+
}
|
|
110
|
+
if (paint.fcp !== undefined) {
|
|
111
|
+
legacyFormat['metric:fcp'] = paint.fcp;
|
|
112
|
+
}
|
|
113
|
+
if (paint.lcp !== undefined) {
|
|
114
|
+
legacyFormat['metric:lcp'] = paint.lcp;
|
|
115
|
+
}
|
|
116
|
+
return _context2.abrupt("return", legacyFormat);
|
|
117
|
+
case 8:
|
|
118
|
+
case "end":
|
|
119
|
+
return _context2.stop();
|
|
120
|
+
}
|
|
121
|
+
}, _callee2);
|
|
122
|
+
}));
|
|
123
|
+
return _getPaintMetricsToLegacyFormat.apply(this, arguments);
|
|
124
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = getPayloadSize;
|
|
7
|
+
// Reusable TextEncoder instance to avoid creating new instances
|
|
8
|
+
var textEncoder = new TextEncoder();
|
|
9
|
+
function getPayloadSize(payload) {
|
|
10
|
+
// Early return for null/undefined to avoid unnecessary processing
|
|
11
|
+
if (!payload) {
|
|
12
|
+
return 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Use the reusable encoder instance
|
|
16
|
+
return Math.round(textEncoder.encode(JSON.stringify(payload)).length / 1024);
|
|
17
|
+
}
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.LATEST_REACT_UFO_PAYLOAD_VERSION = void 0;
|
|
6
7
|
exports.getReactUFOPayloadVersion = getReactUFOPayloadVersion;
|
|
8
|
+
var LATEST_REACT_UFO_PAYLOAD_VERSION = exports.LATEST_REACT_UFO_PAYLOAD_VERSION = '2.0.0';
|
|
7
9
|
function getReactUFOPayloadVersion(interactionType, isPostInteractionLog) {
|
|
8
10
|
if (isPostInteractionLog) {
|
|
9
11
|
return '1.0.1';
|
|
@@ -11,5 +13,5 @@ function getReactUFOPayloadVersion(interactionType, isPostInteractionLog) {
|
|
|
11
13
|
if (interactionType !== 'page_load' && interactionType !== 'transition') {
|
|
12
14
|
return '1.0.1';
|
|
13
15
|
}
|
|
14
|
-
return
|
|
16
|
+
return LATEST_REACT_UFO_PAYLOAD_VERSION;
|
|
15
17
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = getSSRSuccess;
|
|
8
|
+
var ssr = _interopRequireWildcard(require("../../ssr"));
|
|
9
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
10
|
+
function getSSRSuccess(type) {
|
|
11
|
+
if (type !== 'page_load') {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
return ssr.getSSRSuccess();
|
|
15
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = getTTAI;
|
|
8
|
+
var _getPageVisibilityUpToTtai = _interopRequireDefault(require("./get-page-visibility-up-to-ttai"));
|
|
9
|
+
function getTTAI(interaction) {
|
|
10
|
+
var start = interaction.start,
|
|
11
|
+
end = interaction.end;
|
|
12
|
+
var pageVisibilityUpToTTAI = (0, _getPageVisibilityUpToTtai.default)(interaction);
|
|
13
|
+
return !interaction.abortReason && pageVisibilityUpToTTAI === 'visible' ? Math.round(end - start) : undefined;
|
|
14
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getTTI = getTTI;
|
|
7
|
+
var _findMatchingLegacyMetric = require("./find-matching-legacy-metric");
|
|
8
|
+
/**
|
|
9
|
+
* Calculate TTI (Time to Interactive) based on server-side logic
|
|
10
|
+
* TTI is the time from interaction start to the end of the first matching legacy metric,
|
|
11
|
+
* or falls back to apdex/UFO end time if no legacy metrics exist
|
|
12
|
+
*/
|
|
13
|
+
function getTTI(interaction, experienceName) {
|
|
14
|
+
var _apdex$;
|
|
15
|
+
var start = interaction.start,
|
|
16
|
+
end = interaction.end,
|
|
17
|
+
apdex = interaction.apdex;
|
|
18
|
+
|
|
19
|
+
// Find matching legacy metric
|
|
20
|
+
var matchingLegacyMetric = (0, _findMatchingLegacyMetric.findMatchingLegacyMetric)(interaction, experienceName);
|
|
21
|
+
|
|
22
|
+
// Get end times in priority order (following server-side logic)
|
|
23
|
+
var apdexEndTime = apdex === null || apdex === void 0 || (_apdex$ = apdex[0]) === null || _apdex$ === void 0 ? void 0 : _apdex$.stopTime;
|
|
24
|
+
var legacyMetricsEndTime = matchingLegacyMetric === null || matchingLegacyMetric === void 0 ? void 0 : matchingLegacyMetric.stop;
|
|
25
|
+
var ufoEndTime = end;
|
|
26
|
+
var ttiEndTime;
|
|
27
|
+
if (matchingLegacyMetric && legacyMetricsEndTime) {
|
|
28
|
+
// Use legacy metrics end time if we have a matching legacy metric
|
|
29
|
+
ttiEndTime = legacyMetricsEndTime;
|
|
30
|
+
} else if (apdexEndTime) {
|
|
31
|
+
// Fall back to apdex end time if no matching legacy metrics
|
|
32
|
+
ttiEndTime = apdexEndTime;
|
|
33
|
+
} else {
|
|
34
|
+
// Final fallback to UFO end time
|
|
35
|
+
ttiEndTime = ufoEndTime;
|
|
36
|
+
}
|
|
37
|
+
return ttiEndTime ? Math.round(ttiEndTime - start) : undefined;
|
|
38
|
+
}
|
|
@@ -11,6 +11,7 @@ exports.abortByNewInteraction = abortByNewInteraction;
|
|
|
11
11
|
exports.addApdex = addApdex;
|
|
12
12
|
exports.addApdexToAll = addApdexToAll;
|
|
13
13
|
exports.addBrowserMetricEvent = addBrowserMetricEvent;
|
|
14
|
+
exports.addCohortingCustomData = addCohortingCustomData;
|
|
14
15
|
exports.addCustomData = addCustomData;
|
|
15
16
|
exports.addCustomSpans = addCustomSpans;
|
|
16
17
|
exports.addCustomTiming = addCustomTiming;
|
|
@@ -196,6 +197,29 @@ function addCustomData(interactionId, labelStack, data) {
|
|
|
196
197
|
});
|
|
197
198
|
}
|
|
198
199
|
}
|
|
200
|
+
function addCohortingCustomData(interactionId, key, value) {
|
|
201
|
+
var interaction = _constants.interactions.get(interactionId);
|
|
202
|
+
if (interaction == null) {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Allow null and undefined values
|
|
207
|
+
if (value === null || value === undefined) {
|
|
208
|
+
interaction.cohortingCustomData.set(key, value);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Validate that the value is a primitive (number, boolean, or string)
|
|
213
|
+
if (typeof value !== 'number' && typeof value !== 'boolean' && typeof value !== 'string') {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Validate string length (max 50 characters)
|
|
218
|
+
if (typeof value === 'string' && value.length > 50) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
interaction.cohortingCustomData.set(key, value);
|
|
222
|
+
}
|
|
199
223
|
function addCustomTiming(interactionId, labelStack, data) {
|
|
200
224
|
var interaction = _constants.interactions.get(interactionId);
|
|
201
225
|
if (interaction != null) {
|
|
@@ -789,6 +813,7 @@ function addNewInteraction(interactionId, ufoName, type, startTime, rate, labelS
|
|
|
789
813
|
isPreviousInteractionAborted: PreviousInteractionLog.isAborted === true,
|
|
790
814
|
marks: [],
|
|
791
815
|
customData: [],
|
|
816
|
+
cohortingCustomData: new Map(),
|
|
792
817
|
customTimings: [],
|
|
793
818
|
spans: [],
|
|
794
819
|
requestInfo: [],
|
|
@@ -25,6 +25,9 @@ var getConsideredEntryTypes = function getConsideredEntryTypes() {
|
|
|
25
25
|
if (!(0, _platformFeatureFlags.fg)('platform_ufo_exclude_3p_elements_from_ttvc')) {
|
|
26
26
|
entryTypes.push('mutation:third-party-element');
|
|
27
27
|
}
|
|
28
|
+
if ((0, _platformFeatureFlags.fg)('platform_ufo_enable_media_for_ttvc_v3')) {
|
|
29
|
+
entryTypes.push('mutation:media');
|
|
30
|
+
}
|
|
28
31
|
return entryTypes;
|
|
29
32
|
};
|
|
30
33
|
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { createRootCriticalMetricsPayload } from './root-metrics';
|
|
2
|
+
import { createSegmentMetricsPayloads } from './segment-metrics/create-segment-metrics';
|
|
3
|
+
export async function createCriticalMetricsPayloads(interactionId, interaction, vcMetrics) {
|
|
4
|
+
const [rootPayload, segmentPayloads] = await Promise.all([createRootCriticalMetricsPayload(interactionId, interaction, vcMetrics), createSegmentMetricsPayloads(interactionId, interaction)]);
|
|
5
|
+
return [rootPayload, ...segmentPayloads];
|
|
6
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { getLighthouseMetrics } from '../../additional-payload';
|
|
2
|
+
import { getConfig } from '../../config';
|
|
3
|
+
import { getPageVisibilityState } from '../../hidden-timing';
|
|
4
|
+
import { sanitizeUfoName } from '../common/utils';
|
|
5
|
+
import getBrowserMetadata from '../utils/get-browser-metadata';
|
|
6
|
+
import { getFMP } from '../utils/get-fmp';
|
|
7
|
+
import getInteractionStatus from '../utils/get-interaction-status';
|
|
8
|
+
import getNavigationMetrics from '../utils/get-navigation-metrics';
|
|
9
|
+
import getPageVisibilityUpToTTAI from '../utils/get-page-visibility-up-to-ttai';
|
|
10
|
+
import getPaintMetrics from '../utils/get-paint-metrics';
|
|
11
|
+
import { LATEST_REACT_UFO_PAYLOAD_VERSION } from '../utils/get-react-ufo-payload-version';
|
|
12
|
+
import getSSRSuccess from '../utils/get-ssr-success';
|
|
13
|
+
import getTTAI from '../utils/get-ttai';
|
|
14
|
+
import { getTTI } from '../utils/get-tti';
|
|
15
|
+
import getVCMetrics from '../utils/get-vc-metrics';
|
|
16
|
+
|
|
17
|
+
// Re-export types for convenience
|
|
18
|
+
|
|
19
|
+
// Local utility functions
|
|
20
|
+
function getPageVisibilityUpToTTI(interaction) {
|
|
21
|
+
var _interaction$apdex$0$, _interaction$apdex, _interaction$apdex$;
|
|
22
|
+
const {
|
|
23
|
+
start
|
|
24
|
+
} = interaction;
|
|
25
|
+
const bm3EndTimeOrInteractionEndTime = (_interaction$apdex$0$ = (_interaction$apdex = interaction.apdex) === null || _interaction$apdex === void 0 ? void 0 : (_interaction$apdex$ = _interaction$apdex[0]) === null || _interaction$apdex$ === void 0 ? void 0 : _interaction$apdex$.stopTime) !== null && _interaction$apdex$0$ !== void 0 ? _interaction$apdex$0$ : interaction.end;
|
|
26
|
+
return getPageVisibilityState(start, bm3EndTimeOrInteractionEndTime);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// TODO Write tests for this function
|
|
30
|
+
export async function createRootCriticalMetricsPayload(interactionId, interaction, vcMetrics) {
|
|
31
|
+
var _finalVCMetrics$ufoV, _interaction$cohortin, _window$location;
|
|
32
|
+
const config = getConfig();
|
|
33
|
+
if (!config) {
|
|
34
|
+
throw Error('UFO Configuration not provided');
|
|
35
|
+
}
|
|
36
|
+
const {
|
|
37
|
+
end,
|
|
38
|
+
start,
|
|
39
|
+
ufoName,
|
|
40
|
+
rate,
|
|
41
|
+
type,
|
|
42
|
+
abortReason,
|
|
43
|
+
routeName,
|
|
44
|
+
previousInteractionName,
|
|
45
|
+
isPreviousInteractionAborted,
|
|
46
|
+
abortedByInteractionName,
|
|
47
|
+
holdInfo,
|
|
48
|
+
responsiveness
|
|
49
|
+
} = interaction;
|
|
50
|
+
const pageVisibilityAtTTI = getPageVisibilityUpToTTI(interaction);
|
|
51
|
+
const pageVisibilityAtTTAI = getPageVisibilityUpToTTAI(interaction);
|
|
52
|
+
const interactionStatus = getInteractionStatus(interaction);
|
|
53
|
+
const newUFOName = sanitizeUfoName(ufoName);
|
|
54
|
+
|
|
55
|
+
// Get performance metrics
|
|
56
|
+
const ttai = getTTAI(interaction);
|
|
57
|
+
const paintMetrics = await getPaintMetrics(type, end);
|
|
58
|
+
const navigationMetrics = getNavigationMetrics(type);
|
|
59
|
+
const ssrSuccess = getSSRSuccess(type);
|
|
60
|
+
|
|
61
|
+
// Calculate BM3 metrics (TTI and FMP) directly
|
|
62
|
+
const tti = getTTI(interaction, newUFOName);
|
|
63
|
+
const fmp = getFMP(interaction, newUFOName);
|
|
64
|
+
|
|
65
|
+
// Get browser metadata (using compact nested format)
|
|
66
|
+
const browserMetadata = getBrowserMetadata();
|
|
67
|
+
const lighthouseMetrics = getLighthouseMetrics({
|
|
68
|
+
start,
|
|
69
|
+
stop: end
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Use provided vcMetrics or calculate if not provided
|
|
73
|
+
const finalVCMetrics = vcMetrics || (await getVCMetrics(interaction));
|
|
74
|
+
const ttvc = (_finalVCMetrics$ufoV = finalVCMetrics['ufo:vc:rev']) === null || _finalVCMetrics$ufoV === void 0 ? void 0 : _finalVCMetrics$ufoV.map(revision => {
|
|
75
|
+
if (revision['metric:vc90'] === null || revision.clean !== true) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
revision: revision.revision,
|
|
80
|
+
vc90: revision['metric:vc90']
|
|
81
|
+
};
|
|
82
|
+
}).filter(revision => revision != null);
|
|
83
|
+
|
|
84
|
+
// find earliest hold
|
|
85
|
+
const earliestHold = holdInfo === null || holdInfo === void 0 ? void 0 : holdInfo.reduce((a, b) => {
|
|
86
|
+
if (a && a.start < b.start) {
|
|
87
|
+
return a;
|
|
88
|
+
}
|
|
89
|
+
return b;
|
|
90
|
+
}, null);
|
|
91
|
+
|
|
92
|
+
// Process cohorting custom data
|
|
93
|
+
const cohortingCustomData = (_interaction$cohortin = interaction.cohortingCustomData) !== null && _interaction$cohortin !== void 0 && _interaction$cohortin.size ? Object.fromEntries(interaction.cohortingCustomData) : undefined;
|
|
94
|
+
const properties = {
|
|
95
|
+
// Basic metadata
|
|
96
|
+
'event:hostname': ((_window$location = window.location) === null || _window$location === void 0 ? void 0 : _window$location.hostname) || 'unknown',
|
|
97
|
+
'event:product': config.product,
|
|
98
|
+
'event:schema': '1.0.0',
|
|
99
|
+
'event:region': config.region || 'unknown',
|
|
100
|
+
'event:source': {
|
|
101
|
+
name: 'react-ufo/web',
|
|
102
|
+
version: LATEST_REACT_UFO_PAYLOAD_VERSION
|
|
103
|
+
},
|
|
104
|
+
'experience:key': 'custom.ufo.critical-metrics',
|
|
105
|
+
'experience:name': newUFOName,
|
|
106
|
+
// Browser metadata (compact nested format)
|
|
107
|
+
browser: browserMetadata.browser,
|
|
108
|
+
device: browserMetadata.device,
|
|
109
|
+
network: browserMetadata.network,
|
|
110
|
+
time: browserMetadata.time,
|
|
111
|
+
metrics: {
|
|
112
|
+
fp: paintMetrics.fp,
|
|
113
|
+
fcp: paintMetrics.fcp,
|
|
114
|
+
lcp: paintMetrics.lcp,
|
|
115
|
+
ttai,
|
|
116
|
+
tti,
|
|
117
|
+
fmp,
|
|
118
|
+
tbt: lighthouseMetrics['metric:tbt'],
|
|
119
|
+
tbtObserved: lighthouseMetrics['metric:tbt:observed'],
|
|
120
|
+
cls: lighthouseMetrics['metric:cls'],
|
|
121
|
+
ttvc: ttvc !== null && ttvc !== void 0 ? ttvc : undefined,
|
|
122
|
+
earliestHoldStart: earliestHold !== null && earliestHold !== void 0 && earliestHold.start ? Math.round(earliestHold.start - start) : undefined,
|
|
123
|
+
// for interaction response
|
|
124
|
+
inputDelay: responsiveness !== null && responsiveness !== void 0 && responsiveness.inputDelay ? Math.round(responsiveness.inputDelay) : undefined,
|
|
125
|
+
inp: responsiveness !== null && responsiveness !== void 0 && responsiveness.experimentalInputToNextPaint ? Math.round(responsiveness.experimentalInputToNextPaint) : undefined,
|
|
126
|
+
...(navigationMetrics && {
|
|
127
|
+
navigation: navigationMetrics
|
|
128
|
+
})
|
|
129
|
+
},
|
|
130
|
+
...(ssrSuccess !== undefined && {
|
|
131
|
+
ssrSuccess
|
|
132
|
+
}),
|
|
133
|
+
interactionId,
|
|
134
|
+
type,
|
|
135
|
+
rate,
|
|
136
|
+
routeName: routeName !== null && routeName !== void 0 ? routeName : undefined,
|
|
137
|
+
// Performance timings
|
|
138
|
+
start: Math.round(start),
|
|
139
|
+
end: Math.round(end),
|
|
140
|
+
// Status and outcome
|
|
141
|
+
status: interactionStatus.originalInteractionStatus,
|
|
142
|
+
abortReason,
|
|
143
|
+
previousInteractionName,
|
|
144
|
+
isPreviousInteractionAborted,
|
|
145
|
+
abortedByInteractionName,
|
|
146
|
+
pageVisibilityAtTTI: pageVisibilityAtTTI !== null && pageVisibilityAtTTI !== void 0 ? pageVisibilityAtTTI : undefined,
|
|
147
|
+
pageVisibilityAtTTAI,
|
|
148
|
+
// Basic error count (not detailed error count)
|
|
149
|
+
errorCount: interaction.errors.length,
|
|
150
|
+
// Cohorting custom data
|
|
151
|
+
...(Object.keys(cohortingCustomData || {}).length > 0 && {
|
|
152
|
+
cohortingCustomData
|
|
153
|
+
})
|
|
154
|
+
};
|
|
155
|
+
const payload = {
|
|
156
|
+
actionSubject: 'experience',
|
|
157
|
+
action: 'measured',
|
|
158
|
+
eventType: 'operational',
|
|
159
|
+
source: 'measured',
|
|
160
|
+
tags: ['observability'],
|
|
161
|
+
attributes: {
|
|
162
|
+
properties: properties
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
return payload;
|
|
166
|
+
}
|