@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.
Files changed (114) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/create-payload/critical-metrics-payload/index.js +38 -0
  3. package/dist/cjs/create-payload/critical-metrics-payload/root-metrics.js +180 -0
  4. package/dist/cjs/create-payload/critical-metrics-payload/segment-metrics/create-segment-metrics.js +251 -0
  5. package/dist/cjs/create-payload/critical-metrics-payload/segment-metrics/get-is-root-segment.js +9 -0
  6. package/dist/cjs/create-payload/critical-metrics-payload/segment-metrics/get-segment-id.js +15 -0
  7. package/dist/cjs/create-payload/critical-metrics-payload/segment-metrics/get-segment-status.js +59 -0
  8. package/dist/cjs/create-payload/critical-metrics-payload/segment-metrics/has-segment-failed.js +17 -0
  9. package/dist/cjs/create-payload/critical-metrics-payload/segment-metrics/is-label-stack-under-segment.js +11 -0
  10. package/dist/cjs/create-payload/critical-metrics-payload/types.js +5 -0
  11. package/dist/cjs/create-payload/index.js +122 -214
  12. package/dist/cjs/create-payload/utils/find-matching-legacy-metric.js +15 -0
  13. package/dist/cjs/create-payload/utils/get-browser-metadata.js +87 -0
  14. package/dist/cjs/create-payload/utils/get-fmp.js +52 -0
  15. package/dist/cjs/create-payload/utils/get-navigation-metrics.js +66 -0
  16. package/dist/cjs/create-payload/utils/get-paint-metrics.js +124 -0
  17. package/dist/cjs/create-payload/utils/get-payload-size.js +17 -0
  18. package/dist/cjs/create-payload/utils/get-react-ufo-payload-version.js +3 -1
  19. package/dist/cjs/create-payload/utils/get-ssr-success.js +15 -0
  20. package/dist/cjs/create-payload/utils/get-ttai.js +14 -0
  21. package/dist/cjs/create-payload/utils/get-tti.js +38 -0
  22. package/dist/cjs/interaction-metrics/index.js +25 -0
  23. package/dist/cjs/vc/vc-observer-new/metric-calculator/fy25_03/index.js +3 -0
  24. package/dist/es2019/create-payload/critical-metrics-payload/index.js +6 -0
  25. package/dist/es2019/create-payload/critical-metrics-payload/root-metrics.js +166 -0
  26. package/dist/es2019/create-payload/critical-metrics-payload/segment-metrics/create-segment-metrics.js +155 -0
  27. package/dist/es2019/create-payload/critical-metrics-payload/segment-metrics/get-is-root-segment.js +3 -0
  28. package/dist/es2019/create-payload/critical-metrics-payload/segment-metrics/get-segment-id.js +9 -0
  29. package/dist/es2019/create-payload/critical-metrics-payload/segment-metrics/get-segment-status.js +40 -0
  30. package/dist/es2019/create-payload/critical-metrics-payload/segment-metrics/has-segment-failed.js +10 -0
  31. package/dist/es2019/create-payload/critical-metrics-payload/segment-metrics/is-label-stack-under-segment.js +5 -0
  32. package/dist/es2019/create-payload/critical-metrics-payload/types.js +1 -0
  33. package/dist/es2019/create-payload/index.js +55 -151
  34. package/dist/es2019/create-payload/utils/find-matching-legacy-metric.js +7 -0
  35. package/dist/es2019/create-payload/utils/get-browser-metadata.js +79 -0
  36. package/dist/es2019/create-payload/utils/get-fmp.js +47 -0
  37. package/dist/es2019/create-payload/utils/get-navigation-metrics.js +59 -0
  38. package/dist/es2019/create-payload/utils/get-paint-metrics.js +78 -0
  39. package/dist/es2019/create-payload/utils/get-payload-size.js +11 -0
  40. package/dist/es2019/create-payload/utils/get-react-ufo-payload-version.js +2 -1
  41. package/dist/es2019/create-payload/utils/get-ssr-success.js +7 -0
  42. package/dist/es2019/create-payload/utils/get-ttai.js +9 -0
  43. package/dist/es2019/create-payload/utils/get-tti.js +35 -0
  44. package/dist/es2019/interaction-metrics/index.js +24 -0
  45. package/dist/es2019/vc/vc-observer-new/metric-calculator/fy25_03/index.js +3 -0
  46. package/dist/esm/create-payload/critical-metrics-payload/index.js +31 -0
  47. package/dist/esm/create-payload/critical-metrics-payload/root-metrics.js +174 -0
  48. package/dist/esm/create-payload/critical-metrics-payload/segment-metrics/create-segment-metrics.js +244 -0
  49. package/dist/esm/create-payload/critical-metrics-payload/segment-metrics/get-is-root-segment.js +3 -0
  50. package/dist/esm/create-payload/critical-metrics-payload/segment-metrics/get-segment-id.js +9 -0
  51. package/dist/esm/create-payload/critical-metrics-payload/segment-metrics/get-segment-status.js +52 -0
  52. package/dist/esm/create-payload/critical-metrics-payload/segment-metrics/has-segment-failed.js +10 -0
  53. package/dist/esm/create-payload/critical-metrics-payload/segment-metrics/is-label-stack-under-segment.js +5 -0
  54. package/dist/esm/create-payload/critical-metrics-payload/types.js +1 -0
  55. package/dist/esm/create-payload/index.js +121 -210
  56. package/dist/esm/create-payload/utils/find-matching-legacy-metric.js +9 -0
  57. package/dist/esm/create-payload/utils/get-browser-metadata.js +79 -0
  58. package/dist/esm/create-payload/utils/get-fmp.js +47 -0
  59. package/dist/esm/create-payload/utils/get-navigation-metrics.js +59 -0
  60. package/dist/esm/create-payload/utils/get-paint-metrics.js +119 -0
  61. package/dist/esm/create-payload/utils/get-payload-size.js +11 -0
  62. package/dist/esm/create-payload/utils/get-react-ufo-payload-version.js +2 -1
  63. package/dist/esm/create-payload/utils/get-ssr-success.js +7 -0
  64. package/dist/esm/create-payload/utils/get-ttai.js +7 -0
  65. package/dist/esm/create-payload/utils/get-tti.js +33 -0
  66. package/dist/esm/interaction-metrics/index.js +24 -0
  67. package/dist/esm/vc/vc-observer-new/metric-calculator/fy25_03/index.js +3 -0
  68. package/dist/types/common/common/types.d.ts +1 -1
  69. package/dist/types/common/react-ufo-payload-schema.d.ts +23 -2
  70. package/dist/types/create-payload/critical-metrics-payload/index.d.ts +6 -0
  71. package/dist/types/create-payload/critical-metrics-payload/root-metrics.d.ts +7 -0
  72. package/dist/types/create-payload/critical-metrics-payload/segment-metrics/create-segment-metrics.d.ts +3 -0
  73. package/dist/types/create-payload/critical-metrics-payload/segment-metrics/get-is-root-segment.d.ts +2 -0
  74. package/dist/types/create-payload/critical-metrics-payload/segment-metrics/get-segment-id.d.ts +2 -0
  75. package/dist/types/create-payload/critical-metrics-payload/segment-metrics/get-segment-status.d.ts +7 -0
  76. package/dist/types/create-payload/critical-metrics-payload/segment-metrics/has-segment-failed.d.ts +2 -0
  77. package/dist/types/create-payload/critical-metrics-payload/segment-metrics/is-label-stack-under-segment.d.ts +2 -0
  78. package/dist/types/create-payload/critical-metrics-payload/types.d.ts +128 -0
  79. package/dist/types/create-payload/index.d.ts +339 -834
  80. package/dist/types/create-payload/utils/find-matching-legacy-metric.d.ts +5 -0
  81. package/dist/types/create-payload/utils/get-browser-metadata.d.ts +21 -0
  82. package/dist/types/create-payload/utils/get-fmp.d.ts +6 -0
  83. package/dist/types/create-payload/utils/get-navigation-metrics.d.ts +29 -0
  84. package/dist/types/create-payload/utils/get-paint-metrics.d.ts +13 -0
  85. package/dist/types/create-payload/utils/get-payload-size.d.ts +1 -0
  86. package/dist/types/create-payload/utils/get-react-ufo-payload-version.d.ts +2 -1
  87. package/dist/types/create-payload/utils/get-ssr-success.d.ts +2 -0
  88. package/dist/types/create-payload/utils/get-ttai.d.ts +2 -0
  89. package/dist/types/create-payload/utils/get-tti.d.ts +7 -0
  90. package/dist/types/interaction-metrics/index.d.ts +1 -0
  91. package/dist/types-ts4.5/common/common/types.d.ts +1 -1
  92. package/dist/types-ts4.5/common/react-ufo-payload-schema.d.ts +23 -2
  93. package/dist/types-ts4.5/create-payload/critical-metrics-payload/index.d.ts +6 -0
  94. package/dist/types-ts4.5/create-payload/critical-metrics-payload/root-metrics.d.ts +7 -0
  95. package/dist/types-ts4.5/create-payload/critical-metrics-payload/segment-metrics/create-segment-metrics.d.ts +3 -0
  96. package/dist/types-ts4.5/create-payload/critical-metrics-payload/segment-metrics/get-is-root-segment.d.ts +2 -0
  97. package/dist/types-ts4.5/create-payload/critical-metrics-payload/segment-metrics/get-segment-id.d.ts +2 -0
  98. package/dist/types-ts4.5/create-payload/critical-metrics-payload/segment-metrics/get-segment-status.d.ts +7 -0
  99. package/dist/types-ts4.5/create-payload/critical-metrics-payload/segment-metrics/has-segment-failed.d.ts +2 -0
  100. package/dist/types-ts4.5/create-payload/critical-metrics-payload/segment-metrics/is-label-stack-under-segment.d.ts +2 -0
  101. package/dist/types-ts4.5/create-payload/critical-metrics-payload/types.d.ts +130 -0
  102. package/dist/types-ts4.5/create-payload/index.d.ts +339 -834
  103. package/dist/types-ts4.5/create-payload/utils/find-matching-legacy-metric.d.ts +5 -0
  104. package/dist/types-ts4.5/create-payload/utils/get-browser-metadata.d.ts +21 -0
  105. package/dist/types-ts4.5/create-payload/utils/get-fmp.d.ts +6 -0
  106. package/dist/types-ts4.5/create-payload/utils/get-navigation-metrics.d.ts +29 -0
  107. package/dist/types-ts4.5/create-payload/utils/get-paint-metrics.d.ts +13 -0
  108. package/dist/types-ts4.5/create-payload/utils/get-payload-size.d.ts +1 -0
  109. package/dist/types-ts4.5/create-payload/utils/get-react-ufo-payload-version.d.ts +2 -1
  110. package/dist/types-ts4.5/create-payload/utils/get-ssr-success.d.ts +2 -0
  111. package/dist/types-ts4.5/create-payload/utils/get-ttai.d.ts +2 -0
  112. package/dist/types-ts4.5/create-payload/utils/get-tti.d.ts +7 -0
  113. package/dist/types-ts4.5/interaction-metrics/index.d.ts +1 -0
  114. package/package.json +8 -1
@@ -0,0 +1,59 @@
1
+ export default function getNavigationMetrics(type) {
2
+ if (type !== 'page_load') {
3
+ return null;
4
+ }
5
+ try {
6
+ var entries = performance.getEntriesByType('navigation');
7
+ if (entries.length === 0) {
8
+ return null;
9
+ }
10
+ var navigation = entries[0];
11
+ return {
12
+ // From https://www.w3.org/TR/resource-timing/
13
+ redirectStart: Math.round(navigation.redirectStart),
14
+ redirectEnd: Math.round(navigation.redirectEnd),
15
+ fetchStart: Math.round(navigation.fetchStart),
16
+ domainLookupStart: Math.round(navigation.domainLookupStart),
17
+ domainLookupEnd: Math.round(navigation.domainLookupEnd),
18
+ connectStart: Math.round(navigation.connectStart),
19
+ connectEnd: Math.round(navigation.connectEnd),
20
+ secureConnectionStart: Math.round(navigation.secureConnectionStart),
21
+ requestStart: Math.round(navigation.requestStart),
22
+ responseStart: Math.round(navigation.responseStart),
23
+ responseEnd: Math.round(navigation.responseEnd),
24
+ encodedBodySize: Math.round(navigation.encodedBodySize),
25
+ decodedBodySize: Math.round(navigation.decodedBodySize),
26
+ transferSize: Math.round(navigation.transferSize),
27
+ // From https://www.w3.org/TR/navigation-timing-2/
28
+ redirectCount: navigation.redirectCount,
29
+ type: navigation.type,
30
+ unloadEventEnd: Math.round(navigation.unloadEventEnd),
31
+ unloadEventStart: Math.round(navigation.unloadEventStart),
32
+ workerStart: Math.round(navigation.workerStart),
33
+ nextHopProtocol: navigation.nextHopProtocol
34
+
35
+ // The following properties are ignored because they provided limited value on a modern stack (e.g. the content
36
+ // is usually rendered and interactive before the dom is fully parsed, don't play well with streamed content...)
37
+ // * domComplete
38
+ // * domContentLoadedEventEnd
39
+ // * domContentLoadedEventStart
40
+ // * domInteractive
41
+ // * loadEventEnd
42
+ // * loadEventStart
43
+ };
44
+ } catch (error) {
45
+ // Return null if there's any error accessing navigation timing
46
+ return null;
47
+ }
48
+ }
49
+
50
+ // Helper function to get navigation metrics in legacy format for backward compatibility
51
+ export function getNavigationMetricsToLegacyFormat(type) {
52
+ var navigationMetrics = getNavigationMetrics(type);
53
+ if (!navigationMetrics) {
54
+ return {};
55
+ }
56
+ return {
57
+ 'metrics:navigation': navigationMetrics
58
+ };
59
+ }
@@ -0,0 +1,119 @@
1
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
3
+ // Type definitions for paint metrics
4
+
5
+ // Main function returns compact nested format
6
+ export default function getPaintMetrics(_x, _x2) {
7
+ return _getPaintMetrics.apply(this, arguments);
8
+ }
9
+
10
+ // Helper function to get paint metrics in legacy colon format for backward compatibility
11
+ function _getPaintMetrics() {
12
+ _getPaintMetrics = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(type, end) {
13
+ var paint, paintEntries, lcp;
14
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
15
+ while (1) switch (_context.prev = _context.next) {
16
+ case 0:
17
+ if (!(type !== 'page_load')) {
18
+ _context.next = 2;
19
+ break;
20
+ }
21
+ return _context.abrupt("return", {});
22
+ case 2:
23
+ paint = {};
24
+ paintEntries = performance.getEntriesByType('paint');
25
+ paintEntries.forEach(function (entry) {
26
+ if (entry.name === 'first-paint') {
27
+ paint.fp = Math.round(entry.startTime);
28
+ }
29
+ if (entry.name === 'first-contentful-paint') {
30
+ paint.fcp = Math.round(entry.startTime);
31
+ }
32
+ });
33
+
34
+ // Get LCP using PerformanceObserver
35
+ _context.next = 7;
36
+ return new Promise(function (resolve) {
37
+ // Check if we already have LCP entries
38
+ var existingEntries = performance.getEntriesByType('largest-contentful-paint');
39
+ var lastEntry = existingEntries.reduce(function (agg, entry) {
40
+ if (entry.startTime <= end && (agg === null || agg.startTime < entry.startTime)) {
41
+ return entry;
42
+ }
43
+ return agg;
44
+ }, null);
45
+ if (lastEntry) {
46
+ resolve(lastEntry.startTime);
47
+ return;
48
+ }
49
+ var observer = new PerformanceObserver(function (list) {
50
+ var entries = Array.from(list.getEntries());
51
+ var lastEntry = entries.reduce(function (agg, entry) {
52
+ if (entry.startTime <= end && (agg === null || agg.startTime < entry.startTime)) {
53
+ return entry;
54
+ }
55
+ return agg;
56
+ }, null);
57
+ clearTimeout(timeoutId);
58
+ observer.disconnect();
59
+ if (lastEntry) {
60
+ resolve(lastEntry.startTime);
61
+ } else {
62
+ resolve(null);
63
+ }
64
+ });
65
+ observer.observe({
66
+ type: 'largest-contentful-paint',
67
+ buffered: true
68
+ });
69
+ var timeoutId = setTimeout(function () {
70
+ observer.disconnect();
71
+ resolve(null);
72
+ }, 200);
73
+ });
74
+ case 7:
75
+ lcp = _context.sent;
76
+ if (lcp) {
77
+ paint.lcp = Math.round(lcp);
78
+ }
79
+ return _context.abrupt("return", paint);
80
+ case 10:
81
+ case "end":
82
+ return _context.stop();
83
+ }
84
+ }, _callee);
85
+ }));
86
+ return _getPaintMetrics.apply(this, arguments);
87
+ }
88
+ export function getPaintMetricsToLegacyFormat(_x3, _x4) {
89
+ return _getPaintMetricsToLegacyFormat.apply(this, arguments);
90
+ }
91
+ function _getPaintMetricsToLegacyFormat() {
92
+ _getPaintMetricsToLegacyFormat = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(type, end) {
93
+ var paint, legacyFormat;
94
+ return _regeneratorRuntime.wrap(function _callee2$(_context2) {
95
+ while (1) switch (_context2.prev = _context2.next) {
96
+ case 0:
97
+ _context2.next = 2;
98
+ return getPaintMetrics(type, end);
99
+ case 2:
100
+ paint = _context2.sent;
101
+ legacyFormat = {};
102
+ if (paint.fp !== undefined) {
103
+ legacyFormat['metric:fp'] = paint.fp;
104
+ }
105
+ if (paint.fcp !== undefined) {
106
+ legacyFormat['metric:fcp'] = paint.fcp;
107
+ }
108
+ if (paint.lcp !== undefined) {
109
+ legacyFormat['metric:lcp'] = paint.lcp;
110
+ }
111
+ return _context2.abrupt("return", legacyFormat);
112
+ case 8:
113
+ case "end":
114
+ return _context2.stop();
115
+ }
116
+ }, _callee2);
117
+ }));
118
+ return _getPaintMetricsToLegacyFormat.apply(this, arguments);
119
+ }
@@ -0,0 +1,11 @@
1
+ // Reusable TextEncoder instance to avoid creating new instances
2
+ var textEncoder = new TextEncoder();
3
+ export default function getPayloadSize(payload) {
4
+ // Early return for null/undefined to avoid unnecessary processing
5
+ if (!payload) {
6
+ return 0;
7
+ }
8
+
9
+ // Use the reusable encoder instance
10
+ return Math.round(textEncoder.encode(JSON.stringify(payload)).length / 1024);
11
+ }
@@ -1,3 +1,4 @@
1
+ export var LATEST_REACT_UFO_PAYLOAD_VERSION = '2.0.0';
1
2
  export function getReactUFOPayloadVersion(interactionType, isPostInteractionLog) {
2
3
  if (isPostInteractionLog) {
3
4
  return '1.0.1';
@@ -5,5 +6,5 @@ export function getReactUFOPayloadVersion(interactionType, isPostInteractionLog)
5
6
  if (interactionType !== 'page_load' && interactionType !== 'transition') {
6
7
  return '1.0.1';
7
8
  }
8
- return '2.0.0';
9
+ return LATEST_REACT_UFO_PAYLOAD_VERSION;
9
10
  }
@@ -0,0 +1,7 @@
1
+ import * as ssr from '../../ssr';
2
+ export default function getSSRSuccess(type) {
3
+ if (type !== 'page_load') {
4
+ return undefined;
5
+ }
6
+ return ssr.getSSRSuccess();
7
+ }
@@ -0,0 +1,7 @@
1
+ import getPageVisibilityUpToTTAI from './get-page-visibility-up-to-ttai';
2
+ export default function getTTAI(interaction) {
3
+ var start = interaction.start,
4
+ end = interaction.end;
5
+ var pageVisibilityUpToTTAI = getPageVisibilityUpToTTAI(interaction);
6
+ return !interaction.abortReason && pageVisibilityUpToTTAI === 'visible' ? Math.round(end - start) : undefined;
7
+ }
@@ -0,0 +1,33 @@
1
+ import { findMatchingLegacyMetric } from './find-matching-legacy-metric';
2
+
3
+ /**
4
+ * Calculate TTI (Time to Interactive) based on server-side logic
5
+ * TTI is the time from interaction start to the end of the first matching legacy metric,
6
+ * or falls back to apdex/UFO end time if no legacy metrics exist
7
+ */
8
+ export function getTTI(interaction, experienceName) {
9
+ var _apdex$;
10
+ var start = interaction.start,
11
+ end = interaction.end,
12
+ apdex = interaction.apdex;
13
+
14
+ // Find matching legacy metric
15
+ var matchingLegacyMetric = findMatchingLegacyMetric(interaction, experienceName);
16
+
17
+ // Get end times in priority order (following server-side logic)
18
+ var apdexEndTime = apdex === null || apdex === void 0 || (_apdex$ = apdex[0]) === null || _apdex$ === void 0 ? void 0 : _apdex$.stopTime;
19
+ var legacyMetricsEndTime = matchingLegacyMetric === null || matchingLegacyMetric === void 0 ? void 0 : matchingLegacyMetric.stop;
20
+ var ufoEndTime = end;
21
+ var ttiEndTime;
22
+ if (matchingLegacyMetric && legacyMetricsEndTime) {
23
+ // Use legacy metrics end time if we have a matching legacy metric
24
+ ttiEndTime = legacyMetricsEndTime;
25
+ } else if (apdexEndTime) {
26
+ // Fall back to apdex end time if no matching legacy metrics
27
+ ttiEndTime = apdexEndTime;
28
+ } else {
29
+ // Final fallback to UFO end time
30
+ ttiEndTime = ufoEndTime;
31
+ }
32
+ return ttiEndTime ? Math.round(ttiEndTime - start) : undefined;
33
+ }
@@ -151,6 +151,29 @@ export function addCustomData(interactionId, labelStack, data) {
151
151
  });
152
152
  }
153
153
  }
154
+ export function addCohortingCustomData(interactionId, key, value) {
155
+ var interaction = interactions.get(interactionId);
156
+ if (interaction == null) {
157
+ return;
158
+ }
159
+
160
+ // Allow null and undefined values
161
+ if (value === null || value === undefined) {
162
+ interaction.cohortingCustomData.set(key, value);
163
+ return;
164
+ }
165
+
166
+ // Validate that the value is a primitive (number, boolean, or string)
167
+ if (typeof value !== 'number' && typeof value !== 'boolean' && typeof value !== 'string') {
168
+ return;
169
+ }
170
+
171
+ // Validate string length (max 50 characters)
172
+ if (typeof value === 'string' && value.length > 50) {
173
+ return;
174
+ }
175
+ interaction.cohortingCustomData.set(key, value);
176
+ }
154
177
  export function addCustomTiming(interactionId, labelStack, data) {
155
178
  var interaction = interactions.get(interactionId);
156
179
  if (interaction != null) {
@@ -744,6 +767,7 @@ export function addNewInteraction(interactionId, ufoName, type, startTime, rate,
744
767
  isPreviousInteractionAborted: PreviousInteractionLog.isAborted === true,
745
768
  marks: [],
746
769
  customData: [],
770
+ cohortingCustomData: new Map(),
747
771
  customTimings: [],
748
772
  spans: [],
749
773
  requestInfo: [],
@@ -18,6 +18,9 @@ var getConsideredEntryTypes = function getConsideredEntryTypes() {
18
18
  if (!fg('platform_ufo_exclude_3p_elements_from_ttvc')) {
19
19
  entryTypes.push('mutation:third-party-element');
20
20
  }
21
+ if (fg('platform_ufo_enable_media_for_ttvc_v3')) {
22
+ entryTypes.push('mutation:media');
23
+ }
21
24
  return entryTypes;
22
25
  };
23
26
 
@@ -101,6 +101,7 @@ export interface InteractionMetrics {
101
101
  labelStack: LabelStack;
102
102
  data: CustomData;
103
103
  }[];
104
+ cohortingCustomData: Map<string, number | boolean | string | null | undefined>;
104
105
  customTimings: {
105
106
  labelStack: LabelStack;
106
107
  data: CustomTiming;
@@ -142,7 +143,6 @@ export interface InteractionMetrics {
142
143
  * { name: 'issue-navigator', segmentId: 'xxx' },
143
144
  * { name: 'ui', segmentId: 'xxx' }
144
145
  * ]
145
- * ```
146
146
  */
147
147
  responsiveness?: ResponsivenessMetric;
148
148
  labelStack: LabelStack | null;
@@ -1,7 +1,7 @@
1
1
  import { createPayloads } from '../create-payload';
2
2
  import { type LabelStack } from '../interaction-context';
3
3
  import { VCObserver } from '../vc/vc-observer';
4
- import type { AbortReasonType, ApdexType, InteractionError, InteractionType, SegmentInfo } from './common/types';
4
+ import type { AbortReasonType, ApdexType, HoldActive, InteractionError, InteractionType, SegmentInfo } from './common/types';
5
5
  import type { RevisionPayload } from './vc/types';
6
6
  type ExtractPromise<T> = T extends Promise<infer U> ? U : never;
7
7
  export type PageVisibility = 'hidden' | 'mixed' | 'visible';
@@ -36,6 +36,11 @@ export type HoldInfo = {
36
36
  startTime: number;
37
37
  endTime: number;
38
38
  };
39
+ export type OptimizedHoldInfo = {
40
+ labelStack: string;
41
+ startTime: number;
42
+ endTime: number;
43
+ };
39
44
  export type VCParts = (typeof VCObserver.VCParts)[number];
40
45
  export type LeafSegment = {
41
46
  n: string;
@@ -107,6 +112,7 @@ export type ReactUFOPayload = {
107
112
  };
108
113
  'ufo:errors:globalCount': number;
109
114
  'ufo:errors:count': number;
115
+ 'ufo:payloadTime'?: number;
110
116
  interactionMetrics: {
111
117
  namePrefix: string;
112
118
  segmentPrefix: string;
@@ -134,8 +140,23 @@ export type ReactUFOPayload = {
134
140
  resourceTimings: ResourceTiming[];
135
141
  segments: SegmentInfo[] | RootSegment;
136
142
  reactProfilerTimings: ReactProfilerTiming[];
137
- holdInfo: HoldInfo[];
143
+ holdInfo: OptimizedHoldInfo[];
138
144
  errors: InteractionError[];
145
+ responsiveness?: {
146
+ inputDelay?: number;
147
+ experimentalInputToNextPaint?: number;
148
+ };
149
+ customData: Array<{
150
+ labelStack: LabelStack;
151
+ data: any;
152
+ }>;
153
+ SSRTimings: Array<{
154
+ label: string;
155
+ data: any;
156
+ }>;
157
+ holdActive: HoldActive[];
158
+ unknownElementName?: string;
159
+ unknownElementHierarchy?: string;
139
160
  };
140
161
  'ufo:vc:rev': RevisionPayload;
141
162
  'ufo:vc:ratios': Record<string, number>;
@@ -0,0 +1,6 @@
1
+ import type { InteractionMetrics } from '../../common';
2
+ import type { VCResult } from '../../common/vc/types';
3
+ import { CriticalMetricsPayload } from './types';
4
+ export declare function createCriticalMetricsPayloads(interactionId: string, interaction: InteractionMetrics, vcMetrics?: VCResult & {
5
+ 'metric:vc90'?: number | null;
6
+ }): Promise<CriticalMetricsPayload[]>;
@@ -0,0 +1,7 @@
1
+ import type { InteractionMetrics } from '../../common';
2
+ import type { VCResult } from '../../common/vc/types';
3
+ import type { CriticalMetricsPayload } from './types';
4
+ export type { CriticalMetricsPayload, CriticalMetricsPayloadProperties } from './types';
5
+ export declare function createRootCriticalMetricsPayload(interactionId: string, interaction: InteractionMetrics, vcMetrics?: VCResult & {
6
+ 'metric:vc90'?: number | null;
7
+ }): Promise<CriticalMetricsPayload>;
@@ -0,0 +1,3 @@
1
+ import { InteractionMetrics } from '../../../common';
2
+ import { CriticalMetricsPayload } from '../types';
3
+ export declare function createSegmentMetricsPayloads(interactionId: string, interaction: InteractionMetrics): Promise<CriticalMetricsPayload[]>;
@@ -0,0 +1,2 @@
1
+ import type { LabelStack } from '../../../interaction-context';
2
+ export default function getIsRootSegment(labelStack: LabelStack): boolean;
@@ -0,0 +1,2 @@
1
+ import type { LabelStack } from '../../../interaction-context';
2
+ export default function getSegmentId(labelStack: LabelStack): string | undefined;
@@ -0,0 +1,7 @@
1
+ import type { InteractionMetrics, LabelStack } from '../../../common';
2
+ export default function getSegmentStatus(interaction: InteractionMetrics, segment: {
3
+ labelStack: LabelStack;
4
+ }): {
5
+ status: string;
6
+ abortReason: string | undefined;
7
+ };
@@ -0,0 +1,2 @@
1
+ import type { InteractionMetrics } from '../../../common';
2
+ export default function hasSegmentFailed(errors: InteractionMetrics['errors'], segmentId: string): boolean;
@@ -0,0 +1,2 @@
1
+ import type { LabelStack } from '../../../interaction-context';
2
+ export default function isLabelStackUnderSegment(labelStack: LabelStack, segmentId: string): boolean;
@@ -0,0 +1,128 @@
1
+ import type { InteractionType } from '../../common';
2
+ import { NavigationMetrics } from '../utils/get-navigation-metrics';
3
+ export interface CriticalMetricsPayloadProperties {
4
+ 'event:hostname': string;
5
+ 'event:product': string;
6
+ 'event:schema': string;
7
+ 'event:region': string;
8
+ 'event:source': {
9
+ name: string;
10
+ version: string;
11
+ };
12
+ 'experience:key': string;
13
+ 'experience:name': string;
14
+ browser?: {
15
+ name: string;
16
+ version: string;
17
+ };
18
+ device?: {
19
+ cpus?: number;
20
+ memory?: number;
21
+ };
22
+ network?: {
23
+ effectiveType: string;
24
+ rtt: number;
25
+ downlink: number;
26
+ };
27
+ time: {
28
+ localHour: number;
29
+ localDayOfWeek: number;
30
+ localTimezoneOffset: number;
31
+ };
32
+ metrics: {
33
+ /**
34
+ * First Paint
35
+ */
36
+ fp?: number;
37
+ /**
38
+ * First Contentful Paint
39
+ */
40
+ fcp?: number;
41
+ /**
42
+ * Largest Contentful Paint
43
+ */
44
+ lcp?: number;
45
+ /**
46
+ * Time to App Idle
47
+ */
48
+ ttai?: number;
49
+ /**
50
+ * Time to Interactive
51
+ * This is legacy metric, that was marked manually by the team
52
+ */
53
+ tti?: number;
54
+ /**
55
+ * First Meaningful Paint
56
+ */
57
+ fmp?: number;
58
+ /**
59
+ * Total Blocking Time
60
+ */
61
+ tbt?: number;
62
+ /**
63
+ * Total Blocking Time Observed
64
+ */
65
+ tbtObserved?: number;
66
+ /**
67
+ * Cumulative Layout Shift
68
+ */
69
+ cls?: number;
70
+ /**
71
+ * Time to Visually Complete
72
+ * Contains array of multiple versions of the metric
73
+ */
74
+ ttvc?: {
75
+ /**
76
+ * Revision of the metric. e.g. 'fy25.02'
77
+ */
78
+ revision: string;
79
+ /**
80
+ * Time to Visually Complete 90% of the view port
81
+ */
82
+ vc90: number;
83
+ }[];
84
+ /**
85
+ * Earliest Hold Start, for Interaction Response
86
+ */
87
+ earliestHoldStart?: number;
88
+ /**
89
+ * Input Delay
90
+ */
91
+ inputDelay?: number;
92
+ /**
93
+ * Input to Next Paint
94
+ */
95
+ inp?: number;
96
+ /**
97
+ * Navigation metrics, only valid for initial page load from:
98
+ * https://www.w3.org/TR/resource-timing/
99
+ * https://www.w3.org/TR/navigation-timing-2/
100
+ */
101
+ navigation?: NavigationMetrics;
102
+ };
103
+ interactionId: string;
104
+ type: InteractionType | 'page_segment_load';
105
+ rate: number;
106
+ routeName?: string;
107
+ start: number;
108
+ end: number;
109
+ status: string;
110
+ abortReason?: string;
111
+ previousInteractionName?: string;
112
+ isPreviousInteractionAborted?: boolean;
113
+ abortedByInteractionName?: string;
114
+ pageVisibilityAtTTAI?: string;
115
+ pageVisibilityAtTTI?: string;
116
+ errorCount: number;
117
+ cohortingCustomData?: Record<string, number | boolean | string | null | undefined>;
118
+ }
119
+ export interface CriticalMetricsPayload {
120
+ actionSubject: 'experience';
121
+ action: 'measured';
122
+ eventType: 'operational';
123
+ source: 'measured';
124
+ tags: ['observability'];
125
+ attributes: {
126
+ properties: CriticalMetricsPayloadProperties;
127
+ };
128
+ }