@atlaskit/react-ufo 4.15.1 → 4.15.2

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 (58) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/cjs/create-payload/index.js +18 -791
  3. package/dist/cjs/create-payload/utils/get-visibility-state-from-performance.js +1 -0
  4. package/dist/cjs/interaction-id-context/index.js +2 -1
  5. package/dist/cjs/vc/vc-observer-new/metric-calculator/fy25_03/index.js +1 -1
  6. package/dist/es2019/create-payload/index.js +20 -712
  7. package/dist/es2019/create-payload/utils/get-visibility-state-from-performance.js +1 -0
  8. package/dist/es2019/interaction-id-context/index.js +2 -1
  9. package/dist/es2019/vc/vc-observer-new/metric-calculator/fy25_03/index.js +1 -1
  10. package/dist/esm/create-payload/index.js +18 -783
  11. package/dist/esm/create-payload/utils/get-visibility-state-from-performance.js +1 -0
  12. package/dist/esm/interaction-id-context/index.js +2 -1
  13. package/dist/esm/vc/vc-observer-new/metric-calculator/fy25_03/index.js +1 -1
  14. package/dist/types/assets/utils.d.ts +1 -1
  15. package/dist/types/create-experimental-interaction-metrics-payload/index.d.ts +2 -1
  16. package/dist/types/create-interaction-extra-metrics-payload/index.d.ts +17 -14
  17. package/dist/types/create-payload/index.d.ts +8598 -8594
  18. package/dist/types/create-payload/utils/get-more-accurate-page-visibility-up-to-ttai.d.ts +2 -1
  19. package/dist/types/create-payload/utils/get-page-visibility-up-to-ttai.d.ts +2 -1
  20. package/dist/types/create-payload/utils/get-react-ufo-payload-version.d.ts +1 -1
  21. package/dist/types/create-payload/utils/optimize-apdex.d.ts +2 -1
  22. package/dist/types/create-payload/utils/optimize-marks.d.ts +4 -3
  23. package/dist/types/create-post-interaction-log-payload/index.d.ts +5 -4
  24. package/dist/types/experience-trace-id-context/index.d.ts +2 -1
  25. package/dist/types/ignore-holds/index.d.ts +1 -1
  26. package/dist/types/interaction-id-context/index.d.ts +3 -2
  27. package/dist/types/label/UFOLabel.d.ts +1 -1
  28. package/dist/types/load-hold/UFOLoadHold.d.ts +1 -1
  29. package/dist/types/placeholder/loosely-lazy/wait-context.d.ts +2 -1
  30. package/dist/types/report-error/index.d.ts +1 -1
  31. package/dist/types/trace-interaction/internal/map-to-interaction-type.d.ts +1 -1
  32. package/dist/types/typing-performance-tracing/index.d.ts +2 -1
  33. package/dist/types/vc/vc-observer/media-wrapper/MediaWrapper.d.ts +1 -1
  34. package/dist/types/vc/vc-observer/observers/ssr-placeholders/index.d.ts +3 -3
  35. package/dist/types/vc/vc-observer-new/viewport-observer/performance-observer/index.d.ts +1 -1
  36. package/dist/types-ts4.5/assets/utils.d.ts +1 -1
  37. package/dist/types-ts4.5/create-experimental-interaction-metrics-payload/index.d.ts +2 -1
  38. package/dist/types-ts4.5/create-interaction-extra-metrics-payload/index.d.ts +17 -14
  39. package/dist/types-ts4.5/create-payload/index.d.ts +8598 -8594
  40. package/dist/types-ts4.5/create-payload/utils/get-more-accurate-page-visibility-up-to-ttai.d.ts +2 -1
  41. package/dist/types-ts4.5/create-payload/utils/get-page-visibility-up-to-ttai.d.ts +2 -1
  42. package/dist/types-ts4.5/create-payload/utils/get-react-ufo-payload-version.d.ts +1 -1
  43. package/dist/types-ts4.5/create-payload/utils/optimize-apdex.d.ts +2 -1
  44. package/dist/types-ts4.5/create-payload/utils/optimize-marks.d.ts +4 -3
  45. package/dist/types-ts4.5/create-post-interaction-log-payload/index.d.ts +5 -4
  46. package/dist/types-ts4.5/experience-trace-id-context/index.d.ts +2 -1
  47. package/dist/types-ts4.5/ignore-holds/index.d.ts +1 -1
  48. package/dist/types-ts4.5/interaction-id-context/index.d.ts +3 -2
  49. package/dist/types-ts4.5/label/UFOLabel.d.ts +1 -1
  50. package/dist/types-ts4.5/load-hold/UFOLoadHold.d.ts +1 -1
  51. package/dist/types-ts4.5/placeholder/loosely-lazy/wait-context.d.ts +2 -1
  52. package/dist/types-ts4.5/report-error/index.d.ts +1 -1
  53. package/dist/types-ts4.5/trace-interaction/internal/map-to-interaction-type.d.ts +1 -1
  54. package/dist/types-ts4.5/typing-performance-tracing/index.d.ts +2 -1
  55. package/dist/types-ts4.5/vc/vc-observer/media-wrapper/MediaWrapper.d.ts +1 -1
  56. package/dist/types-ts4.5/vc/vc-observer/observers/ssr-placeholders/index.d.ts +3 -3
  57. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/performance-observer/index.d.ts +1 -1
  58. package/package.json +1 -1
@@ -1,712 +1,20 @@
1
- import { getDocument } from '@atlaskit/browser-apis';
2
- import { fg } from '@atlaskit/platform-feature-flags';
3
-
4
- // Import common utilities
5
-
6
- import { getLighthouseMetrics } from '../additional-payload';
7
- import { CHRReporter } from '../assets';
8
- import * as bundleEvalTiming from '../bundle-eval-timing';
9
- import coinflip from '../coinflip';
10
- import { getConfig, getExperimentalInteractionRate, getUfoNameOverrides } from '../config';
11
- import { getExperimentalVCMetrics } from '../create-experimental-interaction-metrics-payload';
12
- import { getBm3Timings } from '../custom-timings';
13
- import { getGlobalErrorCount } from '../global-error-handler';
14
- import { getPageVisibilityState } from '../hidden-timing';
15
- import * as initialPageLoadExtraTiming from '../initial-page-load-extra-timing';
16
- import { interactionSpans as atlaskitInteractionSpans } from '../interaction-metrics';
17
- import { createMemoryStateReport, createPressureStateReport } from '../machine-utilisation';
18
- import * as resourceTiming from '../resource-timing';
19
- import { filterResourceTimings } from '../resource-timing/common/utils/resource-timing-buffer';
20
- import { roundEpsilon } from '../round-number';
21
- import * as ssr from '../ssr';
22
- import { buildSegmentTree, getOldSegmentsLabelStack, labelStackStartWith, optimizeLabelStack, sanitizeUfoName, stringifyLabelStackFully } from './common/utils';
23
- import { createCriticalMetricsPayloads } from './critical-metrics-payload';
24
- import { addPerformanceMeasures } from './utils/add-performance-measures';
25
- import { getBatteryInfoToLegacyFormat } from './utils/get-battery-info';
26
- import { getBrowserMetadataToLegacyFormat } from './utils/get-browser-metadata';
27
- import getInteractionStatus from './utils/get-interaction-status';
28
- import { getMoreAccuratePageVisibilityUpToTTAI } from './utils/get-more-accurate-page-visibility-up-to-ttai';
29
- import { getNavigationMetricsToLegacyFormat } from './utils/get-navigation-metrics';
30
- import getPageVisibilityUpToTTAI from './utils/get-page-visibility-up-to-ttai';
31
- import { getPaintMetricsToLegacyFormat } from './utils/get-paint-metrics';
32
- import getPayloadSize from './utils/get-payload-size';
33
- import { getReactUFOPayloadVersion } from './utils/get-react-ufo-payload-version';
34
- import getSSRDoneTimeValue from './utils/get-ssr-done-time-value';
35
- import getSSRSuccessUtil from './utils/get-ssr-success';
36
- import getTTAI from './utils/get-ttai';
37
- import getVCMetrics from './utils/get-vc-metrics';
38
- import { getVisibilityStateFromPerformance } from './utils/get-visibility-state-from-performance';
39
- import { optimizeApdex } from './utils/optimize-apdex';
40
- import { optimizeCustomTimings } from './utils/optimize-custom-timings';
41
- import { optimizeHoldInfo } from './utils/optimize-hold-info';
42
- import { optimizeMarks } from './utils/optimize-marks';
43
- import { optimizeReactProfilerTimings } from './utils/optimize-react-profiler-timings';
44
- import { optimizeRequestInfo } from './utils/optimize-request-info';
45
- import { optimizeSpans } from './utils/optimize-spans';
46
- const MAX_PAYLOAD_SIZE = 250;
47
- function getUfoNameOverride(interaction) {
48
- const {
49
- ufoName,
50
- apdex
51
- } = interaction;
52
- try {
53
- const ufoNameOverrides = getUfoNameOverrides();
54
- if (ufoNameOverrides != null) {
55
- const metricKey = apdex.length > 0 ? apdex[0].key : '';
56
- if (ufoNameOverrides[ufoName][metricKey]) {
57
- return ufoNameOverrides[ufoName][metricKey];
58
- }
59
- }
60
- return ufoName;
61
- } catch (e) {
62
- return ufoName;
63
- }
64
- }
65
- function getEarliestLegacyStopTime(interaction, labelStack) {
66
- let earliestLegacyStopTime = null;
67
- interaction.apdex.forEach(a => {
68
- var _a$labelStack, _earliestLegacyStopTi;
69
- if (!(a !== null && a !== void 0 && a.stopTime)) {
70
- return;
71
- }
72
- if (!labelStackStartWith((_a$labelStack = a.labelStack) !== null && _a$labelStack !== void 0 ? _a$labelStack : [], labelStack)) {
73
- return;
74
- }
75
- if (a.stopTime > interaction.start && ((_earliestLegacyStopTi = earliestLegacyStopTime) !== null && _earliestLegacyStopTi !== void 0 ? _earliestLegacyStopTi : a.stopTime) >= a.stopTime) {
76
- earliestLegacyStopTime = a.stopTime;
77
- }
78
- });
79
- return earliestLegacyStopTime;
80
- }
81
- function getBm3EndTimeOrFallbackValue(interaction, labelStack = [], fallbackValue = interaction.end) {
82
- var _getEarliestLegacySto;
83
- if (interaction.type === 'press') {
84
- return fallbackValue;
85
- }
86
- return (_getEarliestLegacySto = getEarliestLegacyStopTime(interaction, labelStack)) !== null && _getEarliestLegacySto !== void 0 ? _getEarliestLegacySto : fallbackValue;
87
- }
88
- function getPageVisibilityUpToTTI(interaction) {
89
- const {
90
- start
91
- } = interaction;
92
- const bm3EndTimeOrInteractionEndTime = getBm3EndTimeOrFallbackValue(interaction);
93
- return getPageVisibilityState(start, bm3EndTimeOrInteractionEndTime);
94
- }
95
- function getMoreAccuratePageVisibilityUpToTTI(interaction) {
96
- const old = getPageVisibilityUpToTTI(interaction);
97
- const tti = getEarliestLegacyStopTime(interaction, []);
98
- if (!tti) {
99
- return old;
100
- }
101
- const buffered = getVisibilityStateFromPerformance(tti);
102
- if (!buffered) {
103
- return old;
104
- }
105
- if (buffered !== old) {
106
- return 'mixed';
107
- }
108
- return old;
109
- }
110
- function getResourceTimings(start, end) {
111
- var _resourceTiming$getRe;
112
- return (_resourceTiming$getRe = resourceTiming.getResourceTimings(start, end)) !== null && _resourceTiming$getRe !== void 0 ? _resourceTiming$getRe : undefined;
113
- }
114
- function getBundleEvalTimings(start) {
115
- return bundleEvalTiming.getBundleEvalTimings(start);
116
- }
117
- function getSSRPhaseSuccess(type) {
118
- return type === 'page_load' ? ssr.getSSRPhaseSuccess() : undefined;
119
- }
120
- function getSSRFeatureFlags(type) {
121
- return type === 'page_load' ? ssr.getSSRFeatureFlags() : undefined;
122
- }
123
- function getPPSMetrics(interaction) {
124
- var _interaction$apdex, _interaction$apdex$;
125
- const {
126
- start,
127
- end
128
- } = interaction;
129
- const config = getConfig();
130
- const interactionStatus = getInteractionStatus(interaction);
131
- const pageVisibilityUpToTTAI = getPageVisibilityUpToTTAI(interaction);
132
- const tti = (_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;
133
- const ttai = interactionStatus.originalInteractionStatus === 'SUCCEEDED' && pageVisibilityUpToTTAI === 'visible' ? Math.round(end - start) : undefined;
134
- const PPSMetricsAtTTI = tti !== undefined ? getLighthouseMetrics({
135
- start,
136
- stop: tti
137
- }) : null;
138
- const PPSMetricsAtTTAI = ttai !== undefined ? getLighthouseMetrics({
139
- start,
140
- stop: interaction.end
141
- }) : null;
142
- if (fg('platform_ufo_remove_deprecated_config_fields')) {
143
- if (PPSMetricsAtTTAI !== null) {
144
- return PPSMetricsAtTTAI;
145
- }
146
- } else {
147
- if (config !== null && config !== void 0 && config.shouldCalculateLighthouseMetricsFromTTAI && PPSMetricsAtTTAI !== null) {
148
- return PPSMetricsAtTTAI;
149
- }
150
- if (PPSMetricsAtTTI !== null) {
151
- return {
152
- ...PPSMetricsAtTTI,
153
- 'metrics@ttai': PPSMetricsAtTTAI
154
- };
155
- }
156
- }
157
- return {};
158
- }
159
- function getSSRProperties(type) {
160
- const ssrPhases = getSSRPhaseSuccess(type);
161
- return {
162
- 'ssr:success': (ssrPhases === null || ssrPhases === void 0 ? void 0 : ssrPhases.done) != null ? ssrPhases.done : getSSRSuccessUtil(type),
163
- 'ssr:featureFlags': getSSRFeatureFlags(type),
164
- ...((ssrPhases === null || ssrPhases === void 0 ? void 0 : ssrPhases.earlyFlush) != null ? {
165
- 'ssr:earlyflush:success': ssrPhases.earlyFlush
166
- } : null),
167
- ...((ssrPhases === null || ssrPhases === void 0 ? void 0 : ssrPhases.prefetch) != null ? {
168
- 'ssr:prefetch:success': ssrPhases.prefetch
169
- } : null)
170
- };
171
- }
172
- function getAssetsMetrics(interaction, SSRDoneTime) {
173
- try {
174
- const config = getConfig();
175
- const {
176
- type
177
- } = interaction;
178
- const allowedTypes = ['page_load'];
179
- const assetsConfig = config === null || config === void 0 ? void 0 : config.assetsConfig;
180
- if (!allowedTypes.includes(type) || !assetsConfig) {
181
- // Skip if: type not allowed or assetsClassification isn't configured
182
- return {};
183
- }
184
- const reporter = new CHRReporter();
185
- const resourceTimings = filterResourceTimings(interaction.start, interaction.end);
186
- const assets = reporter.get(resourceTimings, assetsConfig, SSRDoneTime);
187
- if (assets) {
188
- // Only add assets in case it exists
189
- return {
190
- 'event:assets': assets
191
- };
192
- }
193
- return {};
194
- } catch (error) {
195
- // Skip CHR in case of error
196
- return {};
197
- }
198
- }
199
- function getTracingContextData(interaction) {
200
- const {
201
- trace,
202
- start
203
- } = interaction;
204
- let tracingContextData = {};
205
- if (trace) {
206
- tracingContextData = {
207
- 'ufo:tracingContext': {
208
- 'X-B3-TraceId': trace.traceId,
209
- 'X-B3-SpanId': trace.spanId,
210
- // eslint-disable-next-line compat/compat
211
- browserTimeOrigin: +(performance.timeOrigin + start).toFixed(2)
212
- }
213
- };
214
- }
215
- return tracingContextData;
216
- }
217
- function optimizeCustomData(interaction) {
218
- const {
219
- customData,
220
- cohortingCustomData,
221
- legacyMetrics
222
- } = interaction;
223
- const customDataMap = customData.reduce((result, {
224
- labelStack,
225
- data
226
- }) => {
227
- var _result$get$data, _result$get;
228
- const label = stringifyLabelStackFully(labelStack);
229
- const value = (_result$get$data = (_result$get = result.get(label)) === null || _result$get === void 0 ? void 0 : _result$get.data) !== null && _result$get$data !== void 0 ? _result$get$data : {};
230
- result.set(label, {
231
- labelStack: optimizeLabelStack(labelStack, getReactUFOPayloadVersion(interaction.type)),
232
- data: Object.assign(value, data)
233
- });
234
- return result;
235
- }, new Map());
236
-
237
- // Merge cohorting custom data into the same map
238
- if (cohortingCustomData && cohortingCustomData.size > 0) {
239
- var _interaction$labelSta, _customDataMap$get$da, _customDataMap$get, _interaction$labelSta2;
240
- const label = stringifyLabelStackFully((_interaction$labelSta = interaction.labelStack) !== null && _interaction$labelSta !== void 0 ? _interaction$labelSta : []);
241
- const value = (_customDataMap$get$da = (_customDataMap$get = customDataMap.get(label)) === null || _customDataMap$get === void 0 ? void 0 : _customDataMap$get.data) !== null && _customDataMap$get$da !== void 0 ? _customDataMap$get$da : {};
242
- customDataMap.set(label, {
243
- labelStack: optimizeLabelStack((_interaction$labelSta2 = interaction.labelStack) !== null && _interaction$labelSta2 !== void 0 ? _interaction$labelSta2 : [], getReactUFOPayloadVersion(interaction.type)),
244
- data: Object.assign(value, Object.fromEntries(cohortingCustomData))
245
- });
246
- }
247
- if (legacyMetrics) {
248
- const legacyMetricsFiltered = legacyMetrics.filter(item => item.type === 'PAGE_LOAD').reduce((result, currentValue) => {
249
- for (const [key, value] of Object.entries(currentValue.custom || {})) {
250
- var _result$get$data2, _result$get2;
251
- const label = stringifyLabelStackFully([]);
252
- const labelValue = (_result$get$data2 = (_result$get2 = result.get(label)) === null || _result$get2 === void 0 ? void 0 : _result$get2.data) !== null && _result$get$data2 !== void 0 ? _result$get$data2 : {};
253
- result.set(label, {
254
- labelStack: optimizeLabelStack([], getReactUFOPayloadVersion(interaction.type)),
255
- data: Object.assign(labelValue, {
256
- [key]: value
257
- })
258
- });
259
- }
260
- return result;
261
- }, new Map());
262
- return [...customDataMap.values(), ...legacyMetricsFiltered.values()];
263
- }
264
- return [...customDataMap.values()];
265
- }
266
- function optimizeRedirects(redirects, interactionStart) {
267
- let lastRedirectTime = interactionStart;
268
- const updatedRedirects = redirects.sort((a, b) => a.time - b.time).reduce((result, redirect) => {
269
- const {
270
- fromInteractionName,
271
- time
272
- } = redirect;
273
- if (lastRedirectTime >= interactionStart) {
274
- result.push({
275
- labelStack: [{
276
- n: fromInteractionName
277
- }],
278
- startTime: Math.round(lastRedirectTime),
279
- endTime: Math.round(time)
280
- });
281
- }
282
- lastRedirectTime = time;
283
- return result;
284
- }, []);
285
- return updatedRedirects;
286
- }
287
- function objectToArray(obj = {}) {
288
- return Object.keys(obj).reduce((result, key) => {
289
- result.push({
290
- label: key,
291
- data: obj[key]
292
- });
293
- return result;
294
- }, []);
295
- }
296
- function getBM3SubmetricsTimings(submetrics) {
297
- if (!submetrics) {
298
- return null;
299
- }
300
- const submetricsTimings = submetrics.filter(item => {
301
- return typeof item.stop === 'number' && !!item.key && typeof item.start === 'number';
302
- }).map(item => {
303
- let childSubmetrics;
304
- const newKey = `include/${item.key}`;
305
- if (item.submetrics) {
306
- childSubmetrics = getBM3SubmetricsTimings(item.submetrics);
307
- }
308
- return {
309
- [newKey]: {
310
- endTime: item.stop - item.start,
311
- startTime: item.start
312
- },
313
- ...(childSubmetrics ? childSubmetrics : {})
314
- };
315
- });
316
- return submetricsTimings;
317
- }
318
- function getBm3TrackerTimings(interaction) {
319
- const interactionLegacyMetrics = interaction.legacyMetrics;
320
- if (!interactionLegacyMetrics) {
321
- return {};
322
- }
323
- const legacyMetrics = interactionLegacyMetrics.map(item => {
324
- var _item$config, _item$config2, _item$marks;
325
- return {
326
- key: item.key,
327
- startTime: item.start,
328
- stopTime: item.stop,
329
- type: (_item$config = item.config) === null || _item$config === void 0 ? void 0 : _item$config.type,
330
- reactUFOName: (_item$config2 = item.config) === null || _item$config2 === void 0 ? void 0 : _item$config2.reactUFOName,
331
- fmp: ((_item$marks = item.marks) === null || _item$marks === void 0 ? void 0 : _item$marks['fmp']) || item.stop,
332
- source: 'bm3',
333
- timings: getBm3Timings(item.marks, item.config.timings),
334
- submetrics: getBM3SubmetricsTimings(item.submetrics),
335
- pageVisibleState: item.pageVisibleState
336
- };
337
- }).filter(item => !!item.type);
338
- return {
339
- legacyMetrics
340
- };
341
- }
342
- function getStylesheetMetrics() {
343
- try {
344
- const doc = getDocument();
345
- if (!doc) {
346
- return {};
347
- }
348
- const stylesheets = Array.from(doc.styleSheets);
349
- const stylesheetCount = stylesheets.length;
350
- const cssrules = Array.from(doc.styleSheets).reduce((acc, item) => {
351
- // Other domain stylesheets throw a SecurityError
352
- try {
353
- return acc + item.cssRules.length;
354
- } catch (e) {
355
- return acc;
356
- }
357
- }, 0);
358
- const styleElements = doc.querySelectorAll('style').length;
359
- const styleProps = doc.querySelectorAll('[style]');
360
- const styleDeclarations = Array.from(doc.querySelectorAll('[style]')).reduce((acc, item) => {
361
- try {
362
- if ('style' in item) {
363
- return acc + item.style.length;
364
- } else {
365
- return acc;
366
- }
367
- } catch (e) {
368
- return acc;
369
- }
370
- }, 0);
371
- return {
372
- 'ufo:stylesheets': stylesheetCount,
373
- 'ufo:styleElements': styleElements,
374
- 'ufo:styleProps': styleProps.length,
375
- 'ufo:styleDeclarations': styleDeclarations,
376
- 'ufo:cssrules': cssrules
377
- };
378
- } catch (e) {
379
- return {};
380
- }
381
- }
382
- let regularTTAI;
383
- let expTTAI;
384
- function getErrorCounts(interaction) {
385
- return {
386
- 'ufo:errors:globalCount': getGlobalErrorCount(),
387
- 'ufo:errors:count': interaction.errors.length
388
- };
389
- }
390
- async function createInteractionMetricsPayload(interaction, interactionId, experimental, criticalPayloadCount, vcMetrics) {
391
- var _window$location, _config$additionalPay;
392
- const interactionPayloadStart = performance.now();
393
- const config = getConfig();
394
- if (!config) {
395
- throw Error('UFO Configuration not provided');
396
- }
397
- const {
398
- end,
399
- start,
400
- ufoName,
401
- knownSegments,
402
- rate,
403
- type,
404
- abortReason,
405
- routeName,
406
- featureFlags,
407
- previousInteractionName,
408
- isPreviousInteractionAborted,
409
- abortedByInteractionName,
410
- responsiveness,
411
- unknownElementName,
412
- unknownElementHierarchy,
413
- hydration
414
- } = interaction;
415
- const pageVisibilityAtTTI = getPageVisibilityUpToTTI(interaction);
416
- const pageVisibilityAtTTAI = getPageVisibilityUpToTTAI(interaction);
417
- const segments = !fg('platform_ufo_remove_deprecated_config_fields') && config.killswitchNestedSegments ? [] : knownSegments;
418
- const segmentTree = getReactUFOPayloadVersion(interaction.type) === '2.0.0' ? buildSegmentTree(segments.map(segment => segment.labelStack)) : {};
419
- const isDetailedPayload = pageVisibilityAtTTAI === 'visible';
420
- const isPageLoad = type === 'page_load';
421
- const calculatePageVisibilityFromTheStartOfPageLoad = config.enableBetterPageVisibilityApi && isPageLoad;
422
- const moreAccuratePageVisibilityAtTTI = calculatePageVisibilityFromTheStartOfPageLoad ? getMoreAccuratePageVisibilityUpToTTI(interaction) : null;
423
- const moreAccuratePageVisibilityAtTTAI = calculatePageVisibilityFromTheStartOfPageLoad ? getMoreAccuratePageVisibilityUpToTTAI(interaction) : null;
424
- const labelStack = interaction.labelStack ? {
425
- labelStack: optimizeLabelStack(interaction.labelStack, getReactUFOPayloadVersion(interaction.type))
426
- } : {};
427
- // Page Load
428
- const getInitialPageLoadSSRMetrics = () => {
429
- var _config$ssr;
430
- if (!isPageLoad) {
431
- return {};
432
- }
433
- const config = getConfig();
434
- const SSRDoneTimeValue = getSSRDoneTimeValue(config);
435
- const SSRDoneTime = SSRDoneTimeValue !== undefined ? {
436
- SSRDoneTime: Math.round(SSRDoneTimeValue)
437
- } : {};
438
- const isBM3ConfigSSRDoneAsFmp = interaction.metaData.__legacy__bm3ConfigSSRDoneAsFmp;
439
- const isUFOConfigSSRDoneAsFmp = interaction.metaData.__legacy__bm3ConfigSSRDoneAsFmp || !!(config !== null && config !== void 0 && (_config$ssr = config.ssr) !== null && _config$ssr !== void 0 && _config$ssr.getSSRDoneTime);
440
- if (!experimental && (isBM3ConfigSSRDoneAsFmp || isUFOConfigSSRDoneAsFmp) && SSRDoneTimeValue !== undefined) {
441
- try {
442
- performance.mark(`FMP`, {
443
- startTime: SSRDoneTimeValue,
444
- detail: {
445
- devtools: {
446
- dataType: 'marker'
447
- }
448
- }
449
- });
450
- } catch (e) {}
451
- }
452
- return {
453
- ...SSRDoneTime,
454
- isBM3ConfigSSRDoneAsFmp,
455
- isUFOConfigSSRDoneAsFmp
456
- };
457
- };
458
- const pageLoadInteractionMetrics = getInitialPageLoadSSRMetrics();
459
-
460
- // Detailed payload. Page visibility = visible
461
- const getDetailedInteractionMetrics = resourceTimings => {
462
- if (experimental || window.__UFO_COMPACT_PAYLOAD__ || !isDetailedPayload) {
463
- return {};
464
- }
465
- const spans = [...interaction.spans, ...atlaskitInteractionSpans];
466
- atlaskitInteractionSpans.length = 0;
467
- return {
468
- errors: interaction.errors.map(({
469
- labelStack,
470
- ...others
471
- }) => ({
472
- ...others,
473
- labelStack: labelStack && optimizeLabelStack(labelStack, getReactUFOPayloadVersion(interaction.type))
474
- })),
475
- holdActive: [...interaction.holdActive.values()],
476
- redirects: optimizeRedirects(interaction.redirects, start),
477
- holdInfo: optimizeHoldInfo(experimental ? interaction.holdExpInfo : interaction.holdInfo, start, getReactUFOPayloadVersion(interaction.type)),
478
- spans: optimizeSpans(spans, start, getReactUFOPayloadVersion(interaction.type)),
479
- requestInfo: optimizeRequestInfo(interaction.requestInfo, start, getReactUFOPayloadVersion(interaction.type)),
480
- customTimings: optimizeCustomTimings(interaction.customTimings, start),
481
- bundleEvalTimings: objectToArray(getBundleEvalTimings(start)),
482
- resourceTimings: objectToArray(resourceTimings)
483
- };
484
- };
485
- // Page load & detailed payload
486
- const getPageLoadDetailedInteractionMetrics = () => {
487
- var _config$ssr2;
488
- if (!isPageLoad || !isDetailedPayload) {
489
- return {};
490
- }
491
- const config = getConfig();
492
- return {
493
- initialPageLoadExtraTimings: objectToArray(initialPageLoadExtraTiming.getTimings()),
494
- SSRTimings: config !== null && config !== void 0 && (_config$ssr2 = config.ssr) !== null && _config$ssr2 !== void 0 && _config$ssr2.getSSRTimings ? config.ssr.getSSRTimings() : objectToArray(ssr.getSSRTimings())
495
- };
496
- };
497
- if (experimental) {
498
- expTTAI = getTTAI(interaction);
499
- } else {
500
- regularTTAI = getTTAI(interaction);
501
- }
502
- const newUFOName = sanitizeUfoName(ufoName);
503
- const resourceTimings = getResourceTimings(start, end);
504
- const [finalVCMetrics, experimentalMetrics, paintMetrics, batteryInfo] = await Promise.all([vcMetrics || (await getVCMetrics(interaction)), experimental ? getExperimentalVCMetrics(interaction) : Promise.resolve(undefined), getPaintMetricsToLegacyFormat(type, end), getBatteryInfoToLegacyFormat()]);
505
- if (!experimental) {
506
- addPerformanceMeasures(interaction.start, [...((finalVCMetrics === null || finalVCMetrics === void 0 ? void 0 : finalVCMetrics['ufo:vc:rev']) || [])]);
507
- }
508
- const getReactHydrationStats = () => {
509
- if (!hydration) {
510
- return {};
511
- }
512
- return {
513
- hydration
514
- };
515
- };
516
- const payload = {
517
- actionSubject: 'experience',
518
- action: 'measured',
519
- eventType: 'operational',
520
- source: 'measured',
521
- tags: ['observability'],
522
- attributes: {
523
- properties: {
524
- // basic
525
- 'event:hostname': ((_window$location = window.location) === null || _window$location === void 0 ? void 0 : _window$location.hostname) || 'unknown',
526
- 'event:product': config.product,
527
- 'event:schema': '1.0.0',
528
- 'event:sizeInKb': 0,
529
- 'event:source': {
530
- name: 'react-ufo/web',
531
- version: getReactUFOPayloadVersion(interaction.type)
532
- },
533
- 'event:region': config.region || 'unknown',
534
- 'experience:key': experimental ? 'custom.experimental-interaction-metrics' : 'custom.interaction-metrics',
535
- 'experience:name': newUFOName,
536
- // Include CPU usage monitoring data
537
- 'event:cpu:usage': createPressureStateReport(interaction.start, interaction.end),
538
- 'event:memory:usage': createMemoryStateReport(interaction.start, interaction.end),
539
- ...(criticalPayloadCount !== undefined ? {
540
- 'ufo:multipayload': true,
541
- 'ufo:criticalPayloadCount': criticalPayloadCount
542
- } : {}),
543
- // root
544
- ...getBrowserMetadataToLegacyFormat(),
545
- ...batteryInfo,
546
- ...getSSRProperties(type),
547
- ...getAssetsMetrics(interaction, pageLoadInteractionMetrics === null || pageLoadInteractionMetrics === void 0 ? void 0 : pageLoadInteractionMetrics.SSRDoneTime),
548
- ...getPPSMetrics(interaction),
549
- ...paintMetrics,
550
- ...getNavigationMetricsToLegacyFormat(type),
551
- ...finalVCMetrics,
552
- ...experimentalMetrics,
553
- ...((_config$additionalPay = config.additionalPayloadData) === null || _config$additionalPay === void 0 ? void 0 : _config$additionalPay.call(config, interaction)),
554
- ...getTracingContextData(interaction),
555
- ...getStylesheetMetrics(),
556
- ...getErrorCounts(interaction),
557
- ...getReactHydrationStats(),
558
- interactionMetrics: {
559
- namePrefix: config.namePrefix || '',
560
- segmentPrefix: config.segmentPrefix || '',
561
- interactionId,
562
- pageVisibilityAtTTI,
563
- pageVisibilityAtTTAI,
564
- experimental__pageVisibilityAtTTI: moreAccuratePageVisibilityAtTTI,
565
- experimental__pageVisibilityAtTTAI: moreAccuratePageVisibilityAtTTAI,
566
- // raw interaction metrics
567
- rate,
568
- routeName,
569
- type,
570
- abortReason,
571
- featureFlags,
572
- previousInteractionName,
573
- isPreviousInteractionAborted,
574
- abortedByInteractionName,
575
- // performance
576
- apdex: optimizeApdex(interaction.apdex, getReactUFOPayloadVersion(interaction.type)),
577
- end: Math.round(end),
578
- start: Math.round(start),
579
- segments: getReactUFOPayloadVersion(interaction.type) === '2.0.0' ? segmentTree : getOldSegmentsLabelStack(segments, interaction.type),
580
- marks: optimizeMarks(interaction.marks, getReactUFOPayloadVersion(interaction.type)),
581
- customData: optimizeCustomData(interaction),
582
- reactProfilerTimings: optimizeReactProfilerTimings(interaction.reactProfilerTimings, start, getReactUFOPayloadVersion(interaction.type)),
583
- minorInteractions: interaction.minorInteractions,
584
- ...(responsiveness ? {
585
- responsiveness
586
- } : {}),
587
- ...labelStack,
588
- ...pageLoadInteractionMetrics,
589
- ...getDetailedInteractionMetrics(resourceTimings),
590
- ...getPageLoadDetailedInteractionMetrics(),
591
- ...getBm3TrackerTimings(interaction),
592
- 'metric:ttai': experimental ? regularTTAI || expTTAI : undefined,
593
- 'metric:experimental:ttai': expTTAI,
594
- ...(unknownElementName ? {
595
- unknownElementName
596
- } : {}),
597
- ...(unknownElementHierarchy ? {
598
- unknownElementHierarchy
599
- } : {})
600
- },
601
- 'ufo:payloadTime': roundEpsilon(performance.now() - interactionPayloadStart)
602
- }
603
- }
604
- };
605
- if (experimental) {
606
- regularTTAI = undefined;
607
- expTTAI = undefined;
608
- }
609
- if (fg('platform_ufo_enable_vc_raw_data')) {
610
- const size = getPayloadSize(payload.attributes.properties);
611
- const vcRev = payload.attributes.properties['ufo:vc:rev'];
612
- const rawData = vcRev.find(item => item.revision === 'raw-handler');
613
- if (rawData) {
614
- const rawDataSize = getPayloadSize(rawData);
615
- payload.attributes.properties['ufo:vc:raw:size'] = rawDataSize;
616
- if (size > MAX_PAYLOAD_SIZE && Array.isArray(vcRev) && vcRev.length > 0) {
617
- payload.attributes.properties['ufo:vc:rev'] = vcRev.filter(item => item.revision !== 'raw-handler');
618
- payload.attributes.properties['ufo:vc:raw:removed'] = true;
619
- }
620
- }
621
- payload.attributes.properties['event:sizeInKb'] = getPayloadSize(payload.attributes.properties);
622
- } else {
623
- payload.attributes.properties['event:sizeInKb'] = getPayloadSize(payload.attributes.properties);
624
- }
625
- return payload;
626
- }
627
- export async function createPayloads(interactionId, interaction) {
628
- const ufoNameOverride = getUfoNameOverride(interaction);
629
- const modifiedInteraction = {
630
- ...interaction,
631
- ufoName: ufoNameOverride
632
- };
633
- const payloads = [];
634
- const isCriticalMetricsEnabled = fg('platform_ufo_critical_metrics_payload');
635
-
636
- // Calculate VC metrics once to avoid duplicate expensive calculations
637
- const vcMetrics = await getVCMetrics(interaction);
638
-
639
- // typeof Promise<CriticalMetricsPayload[]>
640
- const criticalMetricsPayloads = isCriticalMetricsEnabled ? await createCriticalMetricsPayloads(interactionId, interaction, vcMetrics) : [];
641
- payloads.push(...criticalMetricsPayloads);
642
- const criticalPayloadCount = isCriticalMetricsEnabled ? criticalMetricsPayloads.length : undefined;
643
- const interactionMetricsPayload = await createInteractionMetricsPayload(modifiedInteraction, interactionId, undefined, criticalPayloadCount, vcMetrics);
644
- payloads.push(interactionMetricsPayload);
645
- return payloads.filter(Boolean);
646
- }
647
- export async function createExperimentalMetricsPayload(interactionId, interaction) {
648
- const config = getConfig();
649
- if (!config) {
650
- throw Error('UFO Configuration not provided');
651
- }
652
- const ufoName = sanitizeUfoName(interaction.ufoName);
653
- const rate = getExperimentalInteractionRate(ufoName, interaction.type);
654
- if (!coinflip(rate)) {
655
- return null;
656
- }
657
- const pageVisibilityState = getPageVisibilityState(interaction.start, interaction.end);
658
- if (pageVisibilityState !== 'visible') {
659
- return null;
660
- }
661
- const result = await createInteractionMetricsPayload(interaction, interactionId, true);
662
- return result;
663
- }
664
- export async function createExtraSearchPageInteractionPayload(interactionId, interaction) {
665
- var _newEnd;
666
- const SAIN_HOLD_NAMES = ['search-ai-dialog-visible-text-loading', 'search-ai-dialog-all-text-loading'];
667
- const NAME_OVERRIDE = 'search-page-ignoring-smart-answers';
668
- const SEARCH_PAGE_SMART_ANSWERS_SEGMENT_LABEL = 'search-page-smart-answers';
669
- const newInteractionId = `${interactionId}-ignoring-smart-answers`;
670
-
671
- // Calculate a new end time which excludes SAIN holds
672
- let newEnd;
673
- const {
674
- holdInfo,
675
- reactProfilerTimings
676
- } = interaction;
677
- const lastHold = holdInfo.at(-1);
678
- const isLastHoldSAIN = Boolean(lastHold && SAIN_HOLD_NAMES.includes(lastHold.name));
679
-
680
- // A new end time is only calculated if the last hold is a SAIN hold
681
- if (isLastHoldSAIN) {
682
- let lastFilteredTime = null;
683
- const filteredReactProfilerTimings = reactProfilerTimings.filter(timing => {
684
- if (timing.commitTime === lastFilteredTime) {
685
- return false;
686
- }
687
- const isTimingSmartAnswersInSearch = timing.labelStack.some(label => label.name === SEARCH_PAGE_SMART_ANSWERS_SEGMENT_LABEL);
688
- if (isTimingSmartAnswersInSearch) {
689
- lastFilteredTime = timing.commitTime;
690
- return false;
691
- }
692
- return true;
693
- });
694
- const lastTiming = filteredReactProfilerTimings.at(-1);
695
- if (lastTiming) {
696
- newEnd = lastTiming.commitTime;
697
- }
698
- }
699
- const modifiedInteraction = {
700
- ...interaction,
701
- end: (_newEnd = newEnd) !== null && _newEnd !== void 0 ? _newEnd : interaction.end,
702
- holdInfo: [],
703
- knownSegments: [],
704
- reactProfilerTimings: [],
705
- ufoName: NAME_OVERRIDE
706
- };
707
- const payloads = [];
708
- const vcMetrics = await getVCMetrics(interaction, false, true);
709
- const interactionMetricsPayload = await createInteractionMetricsPayload(modifiedInteraction, newInteractionId, undefined, undefined, vcMetrics);
710
- payloads.push(interactionMetricsPayload);
711
- return payloads.filter(Boolean);
712
- }
1
+ import{getDocument}from'@atlaskit/browser-apis';import{fg}from'@atlaskit/platform-feature-flags';// Import common utilities
2
+ import{getLighthouseMetrics}from'../additional-payload';import{CHRReporter}from'../assets';import*as bundleEvalTiming from'../bundle-eval-timing';import coinflip from'../coinflip';import{getConfig,getExperimentalInteractionRate,getUfoNameOverrides}from'../config';import{getExperimentalVCMetrics}from'../create-experimental-interaction-metrics-payload';import{getBm3Timings}from'../custom-timings';import{getGlobalErrorCount}from'../global-error-handler';import{getPageVisibilityState}from'../hidden-timing';import*as initialPageLoadExtraTiming from'../initial-page-load-extra-timing';import{interactionSpans as atlaskitInteractionSpans}from'../interaction-metrics';import{createMemoryStateReport,createPressureStateReport}from'../machine-utilisation';import*as resourceTiming from'../resource-timing';import{filterResourceTimings}from'../resource-timing/common/utils/resource-timing-buffer';import{roundEpsilon}from'../round-number';import*as ssr from'../ssr';import{buildSegmentTree,getOldSegmentsLabelStack,labelStackStartWith,optimizeLabelStack,sanitizeUfoName,stringifyLabelStackFully}from'./common/utils';import{createCriticalMetricsPayloads}from'./critical-metrics-payload';import{addPerformanceMeasures}from'./utils/add-performance-measures';import{getBatteryInfoToLegacyFormat}from'./utils/get-battery-info';import{getBrowserMetadataToLegacyFormat}from'./utils/get-browser-metadata';import getInteractionStatus from'./utils/get-interaction-status';import{getMoreAccuratePageVisibilityUpToTTAI}from'./utils/get-more-accurate-page-visibility-up-to-ttai';import{getNavigationMetricsToLegacyFormat}from'./utils/get-navigation-metrics';import getPageVisibilityUpToTTAI from'./utils/get-page-visibility-up-to-ttai';import{getPaintMetricsToLegacyFormat}from'./utils/get-paint-metrics';import getPayloadSize from'./utils/get-payload-size';import{getReactUFOPayloadVersion}from'./utils/get-react-ufo-payload-version';import getSSRDoneTimeValue from'./utils/get-ssr-done-time-value';import getSSRSuccessUtil from'./utils/get-ssr-success';import getTTAI from'./utils/get-ttai';import getVCMetrics from'./utils/get-vc-metrics';import{getVisibilityStateFromPerformance}from'./utils/get-visibility-state-from-performance';import{optimizeApdex}from'./utils/optimize-apdex';import{optimizeCustomTimings}from'./utils/optimize-custom-timings';import{optimizeHoldInfo}from'./utils/optimize-hold-info';import{optimizeMarks}from'./utils/optimize-marks';import{optimizeReactProfilerTimings}from'./utils/optimize-react-profiler-timings';import{optimizeRequestInfo}from'./utils/optimize-request-info';import{optimizeSpans}from'./utils/optimize-spans';const MAX_PAYLOAD_SIZE=250;function getUfoNameOverride(interaction){const{ufoName,apdex}=interaction;try{const ufoNameOverrides=getUfoNameOverrides();if(ufoNameOverrides!=null){const metricKey=apdex.length>0?apdex[0].key:'';if(ufoNameOverrides[ufoName][metricKey]){return ufoNameOverrides[ufoName][metricKey];}}return ufoName;}catch(e){return ufoName;}}function getEarliestLegacyStopTime(interaction,labelStack){let earliestLegacyStopTime=null;interaction.apdex.forEach(a=>{var _a$labelStack,_earliestLegacyStopTi;if(!(a!==null&&a!==void 0&&a.stopTime)){return;}if(!labelStackStartWith((_a$labelStack=a.labelStack)!==null&&_a$labelStack!==void 0?_a$labelStack:[],labelStack)){return;}if(a.stopTime>interaction.start&&((_earliestLegacyStopTi=earliestLegacyStopTime)!==null&&_earliestLegacyStopTi!==void 0?_earliestLegacyStopTi:a.stopTime)>=a.stopTime){earliestLegacyStopTime=a.stopTime;}});return earliestLegacyStopTime;}function getBm3EndTimeOrFallbackValue(interaction,labelStack=[],fallbackValue=interaction.end){var _getEarliestLegacySto;if(interaction.type==='press'){return fallbackValue;}return(_getEarliestLegacySto=getEarliestLegacyStopTime(interaction,labelStack))!==null&&_getEarliestLegacySto!==void 0?_getEarliestLegacySto:fallbackValue;}function getPageVisibilityUpToTTI(interaction){const{start}=interaction;const bm3EndTimeOrInteractionEndTime=getBm3EndTimeOrFallbackValue(interaction);return getPageVisibilityState(start,bm3EndTimeOrInteractionEndTime);}function getMoreAccuratePageVisibilityUpToTTI(interaction){const old=getPageVisibilityUpToTTI(interaction);const tti=getEarliestLegacyStopTime(interaction,[]);if(!tti){return old;}const buffered=getVisibilityStateFromPerformance(tti);if(!buffered){return old;}if(buffered!==old){return'mixed';}return old;}function getResourceTimings(start,end){var _resourceTiming$getRe;return(_resourceTiming$getRe=resourceTiming.getResourceTimings(start,end))!==null&&_resourceTiming$getRe!==void 0?_resourceTiming$getRe:undefined;}function getBundleEvalTimings(start){return bundleEvalTiming.getBundleEvalTimings(start);}function getSSRPhaseSuccess(type){return type==='page_load'?ssr.getSSRPhaseSuccess():undefined;}function getSSRFeatureFlags(type){return type==='page_load'?ssr.getSSRFeatureFlags():undefined;}function getPPSMetrics(interaction){var _interaction$apdex,_interaction$apdex$;const{start,end}=interaction;const config=getConfig();const interactionStatus=getInteractionStatus(interaction);const pageVisibilityUpToTTAI=getPageVisibilityUpToTTAI(interaction);const tti=(_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;const ttai=interactionStatus.originalInteractionStatus==='SUCCEEDED'&&pageVisibilityUpToTTAI==='visible'?Math.round(end-start):undefined;const PPSMetricsAtTTI=tti!==undefined?getLighthouseMetrics({start,stop:tti}):null;const PPSMetricsAtTTAI=ttai!==undefined?getLighthouseMetrics({start,stop:interaction.end}):null;if(fg('platform_ufo_remove_deprecated_config_fields')){if(PPSMetricsAtTTAI!==null){return PPSMetricsAtTTAI;}}else{if(config!==null&&config!==void 0&&config.shouldCalculateLighthouseMetricsFromTTAI&&PPSMetricsAtTTAI!==null){return PPSMetricsAtTTAI;}if(PPSMetricsAtTTI!==null){return{...PPSMetricsAtTTI,'metrics@ttai':PPSMetricsAtTTAI};}}return{};}function getSSRProperties(type){const ssrPhases=getSSRPhaseSuccess(type);return{'ssr:success':(ssrPhases===null||ssrPhases===void 0?void 0:ssrPhases.done)!=null?ssrPhases.done:getSSRSuccessUtil(type),'ssr:featureFlags':getSSRFeatureFlags(type),...((ssrPhases===null||ssrPhases===void 0?void 0:ssrPhases.earlyFlush)!=null?{'ssr:earlyflush:success':ssrPhases.earlyFlush}:null),...((ssrPhases===null||ssrPhases===void 0?void 0:ssrPhases.prefetch)!=null?{'ssr:prefetch:success':ssrPhases.prefetch}:null)};}function getAssetsMetrics(interaction,SSRDoneTime){try{const config=getConfig();const{type}=interaction;const allowedTypes=['page_load'];const assetsConfig=config===null||config===void 0?void 0:config.assetsConfig;if(!allowedTypes.includes(type)||!assetsConfig){// Skip if: type not allowed or assetsClassification isn't configured
3
+ return{};}const reporter=new CHRReporter();const resourceTimings=filterResourceTimings(interaction.start,interaction.end);const assets=reporter.get(resourceTimings,assetsConfig,SSRDoneTime);if(assets){// Only add assets in case it exists
4
+ return{'event:assets':assets};}return{};}catch(error){// Skip CHR in case of error
5
+ return{};}}function getTracingContextData(interaction){const{trace,start}=interaction;let tracingContextData={};if(trace){tracingContextData={'ufo:tracingContext':{'X-B3-TraceId':trace.traceId,'X-B3-SpanId':trace.spanId,// eslint-disable-next-line compat/compat
6
+ browserTimeOrigin:+(performance.timeOrigin+start).toFixed(2)}};}return tracingContextData;}function optimizeCustomData(interaction){const{customData,cohortingCustomData,legacyMetrics}=interaction;const customDataMap=customData.reduce((result,{labelStack,data})=>{var _result$get$data,_result$get;const label=stringifyLabelStackFully(labelStack);const value=(_result$get$data=(_result$get=result.get(label))===null||_result$get===void 0?void 0:_result$get.data)!==null&&_result$get$data!==void 0?_result$get$data:{};result.set(label,{labelStack:optimizeLabelStack(labelStack,getReactUFOPayloadVersion(interaction.type)),data:Object.assign(value,data)});return result;},new Map());// Merge cohorting custom data into the same map
7
+ if(cohortingCustomData&&cohortingCustomData.size>0){var _interaction$labelSta,_customDataMap$get$da,_customDataMap$get,_interaction$labelSta2;const label=stringifyLabelStackFully((_interaction$labelSta=interaction.labelStack)!==null&&_interaction$labelSta!==void 0?_interaction$labelSta:[]);const value=(_customDataMap$get$da=(_customDataMap$get=customDataMap.get(label))===null||_customDataMap$get===void 0?void 0:_customDataMap$get.data)!==null&&_customDataMap$get$da!==void 0?_customDataMap$get$da:{};customDataMap.set(label,{labelStack:optimizeLabelStack((_interaction$labelSta2=interaction.labelStack)!==null&&_interaction$labelSta2!==void 0?_interaction$labelSta2:[],getReactUFOPayloadVersion(interaction.type)),data:Object.assign(value,Object.fromEntries(cohortingCustomData))});}if(legacyMetrics){const legacyMetricsFiltered=legacyMetrics.filter(item=>item.type==='PAGE_LOAD').reduce((result,currentValue)=>{for(const[key,value]of Object.entries(currentValue.custom||{})){var _result$get$data2,_result$get2;const label=stringifyLabelStackFully([]);const labelValue=(_result$get$data2=(_result$get2=result.get(label))===null||_result$get2===void 0?void 0:_result$get2.data)!==null&&_result$get$data2!==void 0?_result$get$data2:{};result.set(label,{labelStack:optimizeLabelStack([],getReactUFOPayloadVersion(interaction.type)),data:Object.assign(labelValue,{[key]:value})});}return result;},new Map());return[...customDataMap.values(),...legacyMetricsFiltered.values()];}return[...customDataMap.values()];}function optimizeRedirects(redirects,interactionStart){let lastRedirectTime=interactionStart;const updatedRedirects=redirects.sort((a,b)=>a.time-b.time).reduce((result,redirect)=>{const{fromInteractionName,time}=redirect;if(lastRedirectTime>=interactionStart){result.push({labelStack:[{n:fromInteractionName}],startTime:Math.round(lastRedirectTime),endTime:Math.round(time)});}lastRedirectTime=time;return result;},[]);return updatedRedirects;}function objectToArray(obj={}){return Object.keys(obj).reduce((result,key)=>{result.push({label:key,data:obj[key]});return result;},[]);}function getBM3SubmetricsTimings(submetrics){if(!submetrics){return null;}const submetricsTimings=submetrics.filter(item=>{return typeof item.stop==='number'&&!!item.key&&typeof item.start==='number';}).map(item=>{let childSubmetrics;const newKey=`include/${item.key}`;if(item.submetrics){childSubmetrics=getBM3SubmetricsTimings(item.submetrics);}return{[newKey]:{endTime:item.stop-item.start,startTime:item.start},...(childSubmetrics?childSubmetrics:{})};});return submetricsTimings;}function getBm3TrackerTimings(interaction){const interactionLegacyMetrics=interaction.legacyMetrics;if(!interactionLegacyMetrics){return{};}const legacyMetrics=interactionLegacyMetrics.map(item=>{var _item$config,_item$config2,_item$marks;return{key:item.key,startTime:item.start,stopTime:item.stop,type:(_item$config=item.config)===null||_item$config===void 0?void 0:_item$config.type,reactUFOName:(_item$config2=item.config)===null||_item$config2===void 0?void 0:_item$config2.reactUFOName,fmp:((_item$marks=item.marks)===null||_item$marks===void 0?void 0:_item$marks['fmp'])||item.stop,source:'bm3',timings:getBm3Timings(item.marks,item.config.timings),submetrics:getBM3SubmetricsTimings(item.submetrics),pageVisibleState:item.pageVisibleState};}).filter(item=>!!item.type);return{legacyMetrics};}function getStylesheetMetrics(){try{const doc=getDocument();if(!doc){return{};}const stylesheets=Array.from(doc.styleSheets);const stylesheetCount=stylesheets.length;const cssrules=Array.from(doc.styleSheets).reduce((acc,item)=>{// Other domain stylesheets throw a SecurityError
8
+ try{return acc+item.cssRules.length;}catch(e){return acc;}},0);const styleElements=doc.querySelectorAll('style').length;const styleProps=doc.querySelectorAll('[style]');const styleDeclarations=Array.from(doc.querySelectorAll('[style]')).reduce((acc,item)=>{try{if('style'in item){return acc+item.style.length;}else{return acc;}}catch(e){return acc;}},0);return{'ufo:stylesheets':stylesheetCount,'ufo:styleElements':styleElements,'ufo:styleProps':styleProps.length,'ufo:styleDeclarations':styleDeclarations,'ufo:cssrules':cssrules};}catch(e){return{};}}let regularTTAI;let expTTAI;function getErrorCounts(interaction){return{'ufo:errors:globalCount':getGlobalErrorCount(),'ufo:errors:count':interaction.errors.length};}async function createInteractionMetricsPayload(interaction,interactionId,experimental,criticalPayloadCount,vcMetrics){var _window$location,_config$additionalPay;const interactionPayloadStart=performance.now();const config=getConfig();if(!config){throw Error('UFO Configuration not provided');}const{end,start,ufoName,knownSegments,rate,type,abortReason,routeName,featureFlags,previousInteractionName,isPreviousInteractionAborted,abortedByInteractionName,responsiveness,unknownElementName,unknownElementHierarchy,hydration}=interaction;const pageVisibilityAtTTI=getPageVisibilityUpToTTI(interaction);const pageVisibilityAtTTAI=getPageVisibilityUpToTTAI(interaction);const segments=!fg('platform_ufo_remove_deprecated_config_fields')&&config.killswitchNestedSegments?[]:knownSegments;const segmentTree=getReactUFOPayloadVersion(interaction.type)==='2.0.0'?buildSegmentTree(segments.map(segment=>segment.labelStack)):{};const isDetailedPayload=pageVisibilityAtTTAI==='visible';const isPageLoad=type==='page_load';const calculatePageVisibilityFromTheStartOfPageLoad=config.enableBetterPageVisibilityApi&&isPageLoad;const moreAccuratePageVisibilityAtTTI=calculatePageVisibilityFromTheStartOfPageLoad?getMoreAccuratePageVisibilityUpToTTI(interaction):null;const moreAccuratePageVisibilityAtTTAI=calculatePageVisibilityFromTheStartOfPageLoad?getMoreAccuratePageVisibilityUpToTTAI(interaction):null;const labelStack=interaction.labelStack?{labelStack:optimizeLabelStack(interaction.labelStack,getReactUFOPayloadVersion(interaction.type))}:{};// Page Load
9
+ const getInitialPageLoadSSRMetrics=()=>{var _config$ssr;if(!isPageLoad){return{};}const config=getConfig();const SSRDoneTimeValue=getSSRDoneTimeValue(config);const SSRDoneTime=SSRDoneTimeValue!==undefined?{SSRDoneTime:Math.round(SSRDoneTimeValue)}:{};const isBM3ConfigSSRDoneAsFmp=interaction.metaData.__legacy__bm3ConfigSSRDoneAsFmp;const isUFOConfigSSRDoneAsFmp=interaction.metaData.__legacy__bm3ConfigSSRDoneAsFmp||!!(config!==null&&config!==void 0&&(_config$ssr=config.ssr)!==null&&_config$ssr!==void 0&&_config$ssr.getSSRDoneTime);if(!experimental&&(isBM3ConfigSSRDoneAsFmp||isUFOConfigSSRDoneAsFmp)&&SSRDoneTimeValue!==undefined){try{performance.mark(`FMP`,{startTime:SSRDoneTimeValue,detail:{devtools:{dataType:'marker'}}});}catch(e){}}return{...SSRDoneTime,isBM3ConfigSSRDoneAsFmp,isUFOConfigSSRDoneAsFmp};};const pageLoadInteractionMetrics=getInitialPageLoadSSRMetrics();// Detailed payload. Page visibility = visible
10
+ const getDetailedInteractionMetrics=resourceTimings=>{if(experimental||window.__UFO_COMPACT_PAYLOAD__||!isDetailedPayload){return{};}const spans=[...interaction.spans,...atlaskitInteractionSpans];atlaskitInteractionSpans.length=0;return{errors:interaction.errors.map(({labelStack,...others})=>({...others,labelStack:labelStack&&optimizeLabelStack(labelStack,getReactUFOPayloadVersion(interaction.type))})),holdActive:[...interaction.holdActive.values()],redirects:optimizeRedirects(interaction.redirects,start),holdInfo:optimizeHoldInfo(experimental?interaction.holdExpInfo:interaction.holdInfo,start,getReactUFOPayloadVersion(interaction.type)),spans:optimizeSpans(spans,start,getReactUFOPayloadVersion(interaction.type)),requestInfo:optimizeRequestInfo(interaction.requestInfo,start,getReactUFOPayloadVersion(interaction.type)),customTimings:optimizeCustomTimings(interaction.customTimings,start),bundleEvalTimings:objectToArray(getBundleEvalTimings(start)),resourceTimings:objectToArray(resourceTimings)};};// Page load & detailed payload
11
+ const getPageLoadDetailedInteractionMetrics=()=>{var _config$ssr2;if(!isPageLoad||!isDetailedPayload){return{};}const config=getConfig();return{initialPageLoadExtraTimings:objectToArray(initialPageLoadExtraTiming.getTimings()),SSRTimings:config!==null&&config!==void 0&&(_config$ssr2=config.ssr)!==null&&_config$ssr2!==void 0&&_config$ssr2.getSSRTimings?config.ssr.getSSRTimings():objectToArray(ssr.getSSRTimings())};};if(experimental){expTTAI=getTTAI(interaction);}else{regularTTAI=getTTAI(interaction);}const newUFOName=sanitizeUfoName(ufoName);const resourceTimings=getResourceTimings(start,end);const[finalVCMetrics,experimentalMetrics,paintMetrics,batteryInfo]=await Promise.all([vcMetrics||(await getVCMetrics(interaction)),experimental?getExperimentalVCMetrics(interaction):Promise.resolve(undefined),getPaintMetricsToLegacyFormat(type,end),getBatteryInfoToLegacyFormat()]);if(!experimental){addPerformanceMeasures(interaction.start,[...((finalVCMetrics===null||finalVCMetrics===void 0?void 0:finalVCMetrics['ufo:vc:rev'])||[])]);}const getReactHydrationStats=()=>{if(!hydration){return{};}return{hydration};};const payload={actionSubject:'experience',action:'measured',eventType:'operational',source:'measured',tags:['observability'],attributes:{properties:{// basic
12
+ 'event:hostname':((_window$location=window.location)===null||_window$location===void 0?void 0:_window$location.hostname)||'unknown','event:product':config.product,'event:schema':'1.0.0','event:sizeInKb':0,'event:source':{name:'react-ufo/web',version:getReactUFOPayloadVersion(interaction.type)},'event:region':config.region||'unknown','experience:key':experimental?'custom.experimental-interaction-metrics':'custom.interaction-metrics','experience:name':newUFOName,// Include CPU usage monitoring data
13
+ 'event:cpu:usage':createPressureStateReport(interaction.start,interaction.end),'event:memory:usage':createMemoryStateReport(interaction.start,interaction.end),...(criticalPayloadCount!==undefined?{'ufo:multipayload':true,'ufo:criticalPayloadCount':criticalPayloadCount}:{}),// root
14
+ ...getBrowserMetadataToLegacyFormat(),...batteryInfo,...getSSRProperties(type),...getAssetsMetrics(interaction,pageLoadInteractionMetrics===null||pageLoadInteractionMetrics===void 0?void 0:pageLoadInteractionMetrics.SSRDoneTime),...getPPSMetrics(interaction),...paintMetrics,...getNavigationMetricsToLegacyFormat(type),...finalVCMetrics,...experimentalMetrics,...((_config$additionalPay=config.additionalPayloadData)===null||_config$additionalPay===void 0?void 0:_config$additionalPay.call(config,interaction)),...getTracingContextData(interaction),...getStylesheetMetrics(),...getErrorCounts(interaction),...getReactHydrationStats(),interactionMetrics:{namePrefix:config.namePrefix||'',segmentPrefix:config.segmentPrefix||'',interactionId,pageVisibilityAtTTI,pageVisibilityAtTTAI,experimental__pageVisibilityAtTTI:moreAccuratePageVisibilityAtTTI,experimental__pageVisibilityAtTTAI:moreAccuratePageVisibilityAtTTAI,// raw interaction metrics
15
+ rate,routeName,type,abortReason,featureFlags,previousInteractionName,isPreviousInteractionAborted,abortedByInteractionName,// performance
16
+ apdex:optimizeApdex(interaction.apdex,getReactUFOPayloadVersion(interaction.type)),end:Math.round(end),start:Math.round(start),segments:getReactUFOPayloadVersion(interaction.type)==='2.0.0'?segmentTree:getOldSegmentsLabelStack(segments,interaction.type),marks:optimizeMarks(interaction.marks,getReactUFOPayloadVersion(interaction.type)),customData:optimizeCustomData(interaction),reactProfilerTimings:optimizeReactProfilerTimings(interaction.reactProfilerTimings,start,getReactUFOPayloadVersion(interaction.type)),minorInteractions:interaction.minorInteractions,...(responsiveness?{responsiveness}:{}),...labelStack,...pageLoadInteractionMetrics,...getDetailedInteractionMetrics(resourceTimings),...getPageLoadDetailedInteractionMetrics(),...getBm3TrackerTimings(interaction),'metric:ttai':experimental?regularTTAI||expTTAI:undefined,'metric:experimental:ttai':expTTAI,...(unknownElementName?{unknownElementName}:{}),...(unknownElementHierarchy?{unknownElementHierarchy}:{})},'ufo:payloadTime':roundEpsilon(performance.now()-interactionPayloadStart)}}};if(experimental){regularTTAI=undefined;expTTAI=undefined;}if(fg('platform_ufo_enable_vc_raw_data')){const size=getPayloadSize(payload.attributes.properties);const vcRev=payload.attributes.properties['ufo:vc:rev'];const rawData=vcRev.find(item=>item.revision==='raw-handler');if(rawData){const rawDataSize=getPayloadSize(rawData);payload.attributes.properties['ufo:vc:raw:size']=rawDataSize;if(size>MAX_PAYLOAD_SIZE&&Array.isArray(vcRev)&&vcRev.length>0){payload.attributes.properties['ufo:vc:rev']=vcRev.filter(item=>item.revision!=='raw-handler');payload.attributes.properties['ufo:vc:raw:removed']=true;}}payload.attributes.properties['event:sizeInKb']=getPayloadSize(payload.attributes.properties);}else{payload.attributes.properties['event:sizeInKb']=getPayloadSize(payload.attributes.properties);}return payload;}export async function createPayloads(interactionId,interaction){const ufoNameOverride=getUfoNameOverride(interaction);const modifiedInteraction={...interaction,ufoName:ufoNameOverride};const payloads=[];const isCriticalMetricsEnabled=fg('platform_ufo_critical_metrics_payload');// Calculate VC metrics once to avoid duplicate expensive calculations
17
+ const vcMetrics=await getVCMetrics(interaction);// typeof Promise<CriticalMetricsPayload[]>
18
+ const criticalMetricsPayloads=isCriticalMetricsEnabled?await createCriticalMetricsPayloads(interactionId,interaction,vcMetrics):[];payloads.push(...criticalMetricsPayloads);const criticalPayloadCount=isCriticalMetricsEnabled?criticalMetricsPayloads.length:undefined;const interactionMetricsPayload=await createInteractionMetricsPayload(modifiedInteraction,interactionId,undefined,criticalPayloadCount,vcMetrics);payloads.push(interactionMetricsPayload);return payloads.filter(Boolean);}export async function createExperimentalMetricsPayload(interactionId,interaction){const config=getConfig();if(!config){throw Error('UFO Configuration not provided');}const ufoName=sanitizeUfoName(interaction.ufoName);const rate=getExperimentalInteractionRate(ufoName,interaction.type);if(!coinflip(rate)){return null;}const pageVisibilityState=getPageVisibilityState(interaction.start,interaction.end);if(pageVisibilityState!=='visible'){return null;}const result=await createInteractionMetricsPayload(interaction,interactionId,true);return result;}export async function createExtraSearchPageInteractionPayload(interactionId,interaction){var _newEnd;const SAIN_HOLD_NAMES=['search-ai-dialog-visible-text-loading','search-ai-dialog-all-text-loading'];const NAME_OVERRIDE='search-page-ignoring-smart-answers';const SEARCH_PAGE_SMART_ANSWERS_SEGMENT_LABEL='search-page-smart-answers';const newInteractionId=`${interactionId}-ignoring-smart-answers`;// Calculate a new end time which excludes SAIN holds
19
+ let newEnd;const{holdInfo,reactProfilerTimings}=interaction;const lastHold=holdInfo.at(-1);const isLastHoldSAIN=Boolean(lastHold&&SAIN_HOLD_NAMES.includes(lastHold.name));// A new end time is only calculated if the last hold is a SAIN hold
20
+ if(isLastHoldSAIN){let lastFilteredTime=null;const filteredReactProfilerTimings=reactProfilerTimings.filter(timing=>{if(timing.commitTime===lastFilteredTime){return false;}const isTimingSmartAnswersInSearch=timing.labelStack.some(label=>label.name===SEARCH_PAGE_SMART_ANSWERS_SEGMENT_LABEL);if(isTimingSmartAnswersInSearch){lastFilteredTime=timing.commitTime;return false;}return true;});const lastTiming=filteredReactProfilerTimings.at(-1);if(lastTiming){newEnd=lastTiming.commitTime;}}const modifiedInteraction={...interaction,end:(_newEnd=newEnd)!==null&&_newEnd!==void 0?_newEnd:interaction.end,holdInfo:[],knownSegments:[],reactProfilerTimings:[],ufoName:NAME_OVERRIDE};const payloads=[];const vcMetrics=await getVCMetrics(interaction,false,true);const interactionMetricsPayload=await createInteractionMetricsPayload(modifiedInteraction,newInteractionId,undefined,undefined,vcMetrics);payloads.push(interactionMetricsPayload);return payloads.filter(Boolean);}