@atlaskit/react-ufo 2.5.3 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/create-experimental-interaction-metrics-payload/package.json +15 -0
  3. package/dist/cjs/config/index.js +40 -18
  4. package/dist/cjs/create-experimental-interaction-metrics-payload/index.js +100 -0
  5. package/dist/cjs/create-payload/common/utils/index.js +66 -2
  6. package/dist/cjs/create-payload/index.js +55 -78
  7. package/dist/cjs/interaction-metrics/common/constants.js +8 -3
  8. package/dist/cjs/interaction-metrics/common/index.js +151 -0
  9. package/dist/cjs/interaction-metrics/index.js +166 -238
  10. package/dist/cjs/interaction-metrics-init/index.js +31 -9
  11. package/dist/cjs/load-hold/UFOLoadHold.js +5 -3
  12. package/dist/cjs/segment/segment.js +9 -8
  13. package/dist/es2019/config/index.js +22 -0
  14. package/dist/es2019/create-experimental-interaction-metrics-payload/index.js +71 -0
  15. package/dist/es2019/create-payload/common/utils/index.js +68 -1
  16. package/dist/es2019/create-payload/index.js +48 -77
  17. package/dist/es2019/interaction-metrics/common/constants.js +7 -2
  18. package/dist/es2019/interaction-metrics/common/index.js +103 -0
  19. package/dist/es2019/interaction-metrics/index.js +91 -131
  20. package/dist/es2019/interaction-metrics-init/index.js +28 -8
  21. package/dist/es2019/load-hold/UFOLoadHold.js +5 -3
  22. package/dist/es2019/segment/segment.js +8 -11
  23. package/dist/esm/config/index.js +39 -18
  24. package/dist/esm/create-experimental-interaction-metrics-payload/index.js +90 -0
  25. package/dist/esm/create-payload/common/utils/index.js +63 -1
  26. package/dist/esm/create-payload/index.js +53 -78
  27. package/dist/esm/interaction-metrics/common/constants.js +7 -2
  28. package/dist/esm/interaction-metrics/common/index.js +132 -0
  29. package/dist/esm/interaction-metrics/index.js +86 -158
  30. package/dist/esm/interaction-metrics-init/index.js +28 -8
  31. package/dist/esm/load-hold/UFOLoadHold.js +5 -3
  32. package/dist/esm/segment/segment.js +9 -8
  33. package/dist/types/common/common/types.d.ts +6 -4
  34. package/dist/types/config/index.d.ts +7 -0
  35. package/dist/types/create-experimental-interaction-metrics-payload/index.d.ts +16 -0
  36. package/dist/types/create-payload/common/utils/index.d.ts +9 -0
  37. package/dist/types/create-payload/index.d.ts +13 -5660
  38. package/dist/types/interaction-context/index.d.ts +1 -0
  39. package/dist/types/interaction-metrics/common/constants.d.ts +32 -3
  40. package/dist/types/interaction-metrics/common/index.d.ts +16 -0
  41. package/dist/types/interaction-metrics/index.d.ts +1 -17
  42. package/dist/types/load-hold/UFOLoadHold.d.ts +1 -2
  43. package/dist/types-ts4.5/common/common/types.d.ts +6 -4
  44. package/dist/types-ts4.5/config/index.d.ts +7 -0
  45. package/dist/types-ts4.5/create-experimental-interaction-metrics-payload/index.d.ts +16 -0
  46. package/dist/types-ts4.5/create-payload/common/utils/index.d.ts +9 -0
  47. package/dist/types-ts4.5/create-payload/index.d.ts +13 -5660
  48. package/dist/types-ts4.5/interaction-context/index.d.ts +1 -0
  49. package/dist/types-ts4.5/interaction-metrics/common/constants.d.ts +32 -3
  50. package/dist/types-ts4.5/interaction-metrics/common/index.d.ts +16 -0
  51. package/dist/types-ts4.5/interaction-metrics/index.d.ts +1 -17
  52. package/dist/types-ts4.5/load-hold/UFOLoadHold.d.ts +1 -2
  53. package/package.json +3 -2
@@ -10,6 +10,8 @@ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/sli
10
10
  var _scheduler = require("scheduler");
11
11
  var _additionalPayload = require("../additional-payload");
12
12
  var _config = require("../config");
13
+ var _createExperimentalInteractionMetricsPayload = require("../create-experimental-interaction-metrics-payload");
14
+ var _utils = require("../create-payload/common/utils");
13
15
  var _hiddenTiming = require("../hidden-timing");
14
16
  var _interactionMetrics = require("../interaction-metrics");
15
17
  var _vc = require("../vc");
@@ -26,6 +28,16 @@ function sinkInteraction(instance, payloadPackage) {
26
28
  });
27
29
  });
28
30
  }
31
+ function sinkExperimentalInteractionMetrics(instance, payloadPackage) {
32
+ (0, _createExperimentalInteractionMetricsPayload.sinkExperimentalHandler)(function (interactionId, interaction) {
33
+ (0, _scheduler.unstable_scheduleCallback)(_scheduler.unstable_IdlePriority, function () {
34
+ var payload = payloadPackage.createExperimentalMetricsPayload(interactionId, interaction);
35
+ if (payload) {
36
+ instance.sendOperationalEvent(payload);
37
+ }
38
+ });
39
+ });
40
+ }
29
41
  function sinkPostInteractionLog(instance, createPostInteractionLogPayload) {
30
42
  (0, _interactionMetrics.sinkPostInteractionLogHandler)(function (logOutput) {
31
43
  (0, _scheduler.unstable_scheduleCallback)(_scheduler.unstable_IdlePriority, function () {
@@ -43,6 +55,7 @@ var init = exports.init = function init(analyticsWebClientAsync, config) {
43
55
  }
44
56
  (0, _config.setUFOConfig)(config);
45
57
  if ((_config$vc = config.vc) !== null && _config$vc !== void 0 && _config$vc.enabled) {
58
+ var _config$experimentalI;
46
59
  var vcOptions = {
47
60
  heatmapSize: config.vc.heatmapSize,
48
61
  oldDomUpdates: config.vc.oldDomUpdates,
@@ -52,20 +65,23 @@ var init = exports.init = function init(analyticsWebClientAsync, config) {
52
65
  (0, _vc.getVCObserver)(vcOptions).start({
53
66
  startTime: 0
54
67
  });
55
- _interactionMetrics.postInteractionLog.initializeVCObserver(vcOptions);
56
- _interactionMetrics.postInteractionLog.startVCObserver({
68
+ _utils.postInteractionLog.initializeVCObserver(vcOptions);
69
+ _utils.postInteractionLog.startVCObserver({
57
70
  startTime: 0
58
71
  });
72
+ if (config !== null && config !== void 0 && (_config$experimentalI = config.experimentalInteractionMetrics) !== null && _config$experimentalI !== void 0 && _config$experimentalI.enabled) {
73
+ _createExperimentalInteractionMetricsPayload.experimentalVC.initialize(vcOptions).start({
74
+ startTime: 0
75
+ });
76
+ }
59
77
  }
60
78
  (0, _hiddenTiming.setupHiddenTimingCapture)();
61
79
  (0, _additionalPayload.startLighthouseObserver)();
62
80
  initialized = true;
63
- Promise.all([analyticsWebClientAsync, // eslint-disable-next-line import/dynamic-import-chunkname
64
- Promise.resolve().then(function () {
81
+ Promise.all([analyticsWebClientAsync, Promise.resolve().then(function () {
65
82
  return _interopRequireWildcard(require( /* webpackChunkName: "create-payloads" */'../create-payload'));
66
- }), // eslint-disable-next-line import/dynamic-import-chunkname
67
- Promise.resolve().then(function () {
68
- return _interopRequireWildcard(require( /* webpackChunkName: "create-post-intreaction-log-payload" */'../create-post-interaction-log-payload'));
83
+ }), Promise.resolve().then(function () {
84
+ return _interopRequireWildcard(require( /* webpackChunkName: "create-post-interaction-log-payload" */'../create-post-interaction-log-payload'));
69
85
  })]).then(function (_ref) {
70
86
  var _ref2 = (0, _slicedToArray2.default)(_ref, 3),
71
87
  awc = _ref2[0],
@@ -73,16 +89,22 @@ var init = exports.init = function init(analyticsWebClientAsync, config) {
73
89
  createPostInteractionLogPayloadPackage = _ref2[2];
74
90
  if (awc.getAnalyticsWebClientPromise) {
75
91
  awc.getAnalyticsWebClientPromise().then(function (client) {
76
- var _config$postInteracti;
92
+ var _config$experimentalI2, _config$postInteracti;
77
93
  var instance = client.getInstance();
78
94
  sinkInteraction(instance, payloadPackage);
95
+ if (config !== null && config !== void 0 && (_config$experimentalI2 = config.experimentalInteractionMetrics) !== null && _config$experimentalI2 !== void 0 && _config$experimentalI2.enabled) {
96
+ sinkExperimentalInteractionMetrics(instance, payloadPackage);
97
+ }
79
98
  if ((_config$postInteracti = config.postInteractionLog) !== null && _config$postInteracti !== void 0 && _config$postInteracti.enabled) {
80
99
  sinkPostInteractionLog(instance, createPostInteractionLogPayloadPackage.default);
81
100
  }
82
101
  });
83
102
  } else if (awc.sendOperationalEvent) {
84
- var _config$postInteracti2;
103
+ var _config$experimentalI3, _config$postInteracti2;
85
104
  sinkInteraction(awc, payloadPackage);
105
+ if (config !== null && config !== void 0 && (_config$experimentalI3 = config.experimentalInteractionMetrics) !== null && _config$experimentalI3 !== void 0 && _config$experimentalI3.enabled) {
106
+ sinkExperimentalInteractionMetrics(awc, payloadPackage);
107
+ }
86
108
  if ((_config$postInteracti2 = config.postInteractionLog) !== null && _config$postInteracti2 !== void 0 && _config$postInteracti2.enabled) {
87
109
  sinkPostInteractionLog(awc, createPostInteractionLogPayloadPackage.default);
88
110
  }
@@ -32,8 +32,7 @@ var useLayoutEffectSAFE = typeof window === 'undefined' ? _react.useEffect : _re
32
32
  * return (
33
33
  * <>
34
34
  * <Skeleton />
35
- * <UFOLoadHold name="card">
36
- * </UFOLoadHold>
35
+ * <UFOLoadHold name="card" />
37
36
  * )
38
37
  * }
39
38
  * ```
@@ -68,7 +67,10 @@ function UFOLoadHold(_ref) {
68
67
  // react-18: useId instead
69
68
  var context = (0, _react.useContext)(_interactionContext.default);
70
69
  useLayoutEffectSAFE(function () {
71
- if (hold && !experimental && context != null) {
70
+ if (hold && context != null) {
71
+ if (experimental && context.holdExperimental) {
72
+ return context.holdExperimental(name);
73
+ }
72
74
  return context.hold(name);
73
75
  }
74
76
  }, [hold, context, name]);
@@ -91,15 +91,14 @@ function UFOSegment(_ref) {
91
91
  }
92
92
  }
93
93
  }
94
- function _internalHold(labelStack, name
95
- // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
96
- ) {
94
+ function _internalHold(labelStack, name) {
95
+ var experimental = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
97
96
  if (interactionId.current != null) {
98
97
  if (parentContext) {
99
- return parentContext._internalHold(labelStack, name);
98
+ return parentContext._internalHold(labelStack, name, experimental);
100
99
  } else {
101
100
  var capturedInteractionId = interactionId.current;
102
- var disposeHold = (0, _interactionMetrics.addHold)(interactionId.current, labelStack, name);
101
+ var disposeHold = (0, _interactionMetrics.addHold)(interactionId.current, labelStack, name, experimental);
103
102
  return function () {
104
103
  if (capturedInteractionId === interactionId.current) {
105
104
  disposeHold();
@@ -108,9 +107,7 @@ function UFOSegment(_ref) {
108
107
  }
109
108
  }
110
109
  }
111
- function _internalHoldByID(labelStack, id, name, remove
112
- // eslint-disable-next-line @typescript-eslint/no-invalid-void-type
113
- ) {
110
+ function _internalHoldByID(labelStack, id, name, remove) {
114
111
  if (interactionId.current != null) {
115
112
  if (parentContext) {
116
113
  parentContext._internalHoldByID(labelStack, name, id, remove);
@@ -135,6 +132,10 @@ function UFOSegment(_ref) {
135
132
  var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'unknown';
136
133
  return this._internalHold(this.labelStack, name);
137
134
  },
135
+ holdExperimental: function holdExperimental() {
136
+ var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'unknown';
137
+ return this._internalHold(this.labelStack, name, true);
138
+ },
138
139
  addHoldByID: function addHoldByID(labelStack, id) {
139
140
  var name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'unknown';
140
141
  this._internalHoldByID(labelStack, id, name, false);
@@ -67,6 +67,28 @@ export function getInteractionRate(name, interactionKind) {
67
67
  return 0;
68
68
  }
69
69
  }
70
+ export function getExperimentalInteractionRate(name, interactionType) {
71
+ try {
72
+ if (!config) {
73
+ return 0;
74
+ }
75
+ const {
76
+ experimentalInteractionMetrics
77
+ } = config;
78
+ if (!(experimentalInteractionMetrics !== null && experimentalInteractionMetrics !== void 0 && experimentalInteractionMetrics.enabled)) {
79
+ return 0;
80
+ }
81
+ if (experimentalInteractionMetrics.rates && typeof experimentalInteractionMetrics.rates[name] === 'number') {
82
+ return experimentalInteractionMetrics.rates[name];
83
+ }
84
+ if (experimentalInteractionMetrics.kind && typeof experimentalInteractionMetrics.kind[interactionType] === 'number') {
85
+ return experimentalInteractionMetrics.kind[interactionType];
86
+ }
87
+ return 0;
88
+ } catch (e) {
89
+ return 0;
90
+ }
91
+ }
70
92
  export function getPostInteractionRate(name, interactionType) {
71
93
  try {
72
94
  if (!config) {
@@ -0,0 +1,71 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import { calculateVCMetrics } from '../create-payload/common/utils';
3
+ import { VCObserver } from '../vc/vc-observer';
4
+ const interactionBuffer = [];
5
+ let bufferInteractionData = (interactionId, data) => {
6
+ interactionBuffer.push({
7
+ interactionId,
8
+ data
9
+ });
10
+ };
11
+ function clearInteractionBuffer() {
12
+ interactionBuffer.length = 0;
13
+ }
14
+ function appendInteractionData(interactionId, data) {
15
+ bufferInteractionData(interactionId, data);
16
+ }
17
+ export function installInteractionSink(handler) {
18
+ for (const {
19
+ interactionId,
20
+ data
21
+ } of interactionBuffer) {
22
+ handler(interactionId, data);
23
+ }
24
+ clearInteractionBuffer();
25
+ bufferInteractionData = handler;
26
+ }
27
+ export function sinkExperimentalHandler(sinkFn) {
28
+ installInteractionSink(sinkFn);
29
+ }
30
+ export function onExperimentalInteractionComplete(interactionId, data, endTime = performance.now()) {
31
+ if (data.ufoName) {
32
+ data.end = endTime;
33
+ appendInteractionData(interactionId, data);
34
+ clearInteractionBuffer();
35
+ }
36
+ }
37
+ export class ExperimentalVCMetrics {
38
+ constructor() {
39
+ _defineProperty(this, "vcObserver", null);
40
+ }
41
+ initialize(options) {
42
+ if (this.vcObserver === null) {
43
+ this.vcObserver = new VCObserver({
44
+ ...options,
45
+ isPostInteraction: true
46
+ });
47
+ }
48
+ return this;
49
+ }
50
+ start({
51
+ startTime
52
+ }) {
53
+ var _this$vcObserver;
54
+ (_this$vcObserver = this.vcObserver) === null || _this$vcObserver === void 0 ? void 0 : _this$vcObserver.start({
55
+ startTime
56
+ });
57
+ }
58
+ }
59
+ export const experimentalVC = new ExperimentalVCMetrics();
60
+ export const getExperimentalVCMetrics = interaction => {
61
+ if (experimentalVC.vcObserver) {
62
+ var _result$metricsVc;
63
+ const result = calculateVCMetrics(interaction, 'ufo-experimental', experimentalVC.vcObserver.getVCResult);
64
+ experimentalVC.vcObserver.stop();
65
+ return {
66
+ ...result,
67
+ 'metric:experimental:vc90': result === null || result === void 0 ? void 0 : (_result$metricsVc = result['metrics:vc']) === null || _result$metricsVc === void 0 ? void 0 : _result$metricsVc['90']
68
+ };
69
+ }
70
+ return null;
71
+ };
@@ -1,5 +1,12 @@
1
1
  /* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */
2
+
2
3
  import { REACT_UFO_VERSION } from '../../../common/constants';
4
+ import { getConfig } from '../../../config';
5
+ import { getPageVisibilityState } from '../../../hidden-timing';
6
+ import PostInteractionLog from '../../../interaction-metrics/post-interaction-log';
7
+ import { getSSRDoneTime } from '../../../ssr';
8
+ import { getVCObserver } from '../../../vc';
9
+ export const postInteractionLog = new PostInteractionLog();
3
10
  export const sanitizeUfoName = name => {
4
11
  return name.replace(/_/g, '-');
5
12
  };
@@ -53,4 +60,64 @@ export function optimizeLabelStack(labelStack) {
53
60
  s: ls.segmentId
54
61
  } : {})
55
62
  }));
56
- }
63
+ }
64
+ export const getPageVisibilityUpToTTAI = interaction => {
65
+ const {
66
+ start,
67
+ end
68
+ } = interaction;
69
+ return getPageVisibilityState(start, end);
70
+ };
71
+ export const calculateVCMetrics = (interaction, prefix, getVCResultFn) => {
72
+ var _interaction$apdex, _interaction$apdex$;
73
+ const result = getVCResultFn({
74
+ start: interaction.start,
75
+ stop: interaction.end,
76
+ 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,
77
+ prefix,
78
+ vc: interaction.vc
79
+ });
80
+ const VC = result === null || result === void 0 ? void 0 : result['metrics:vc'];
81
+ if (!VC || !(result !== null && result !== void 0 && result[`${prefix}:vc:clean`])) {
82
+ return result;
83
+ }
84
+ const pageVisibilityUpToTTAI = getPageVisibilityUpToTTAI(interaction);
85
+ if (interaction.abortReason || pageVisibilityUpToTTAI !== 'visible') {
86
+ return result;
87
+ }
88
+ return result;
89
+ };
90
+ export function getSSRDoneTimeValue(config) {
91
+ var _config$ssr, _config$ssr2;
92
+ return config !== null && config !== void 0 && (_config$ssr = config.ssr) !== null && _config$ssr !== void 0 && _config$ssr.getSSRDoneTime ? config === null || config === void 0 ? void 0 : (_config$ssr2 = config.ssr) === null || _config$ssr2 === void 0 ? void 0 : _config$ssr2.getSSRDoneTime() : getSSRDoneTime();
93
+ }
94
+ export const getVCMetrics = interaction => {
95
+ var _config$vc, _config$vc$ssrWhiteli, _result$metricsVc;
96
+ const config = getConfig();
97
+ if (!(config !== null && config !== void 0 && (_config$vc = config.vc) !== null && _config$vc !== void 0 && _config$vc.enabled)) {
98
+ return {};
99
+ }
100
+ if (interaction.type !== 'page_load' && interaction.type !== 'transition') {
101
+ return {};
102
+ }
103
+ const isSSREnabled = (config === null || config === void 0 ? void 0 : config.ssr) || (config === null || config === void 0 ? void 0 : (_config$vc$ssrWhiteli = config.vc.ssrWhitelist) === null || _config$vc$ssrWhiteli === void 0 ? void 0 : _config$vc$ssrWhiteli.includes(interaction.ufoName));
104
+ const ssr = interaction.type === 'page_load' && isSSREnabled ? {
105
+ ssr: getSSRDoneTimeValue(config)
106
+ } : null;
107
+ postInteractionLog.setVCObserverSSRConfig(ssr);
108
+ const result = calculateVCMetrics(interaction, 'ufo', getVCObserver().getVCResult);
109
+ getVCObserver().stop();
110
+ postInteractionLog.setLastInteractionFinishVCResult(result);
111
+ return {
112
+ ...result,
113
+ 'metric:vc90': result === null || result === void 0 ? void 0 : (_result$metricsVc = result['metrics:vc']) === null || _result$metricsVc === void 0 ? void 0 : _result$metricsVc['90']
114
+ };
115
+ };
116
+ export const getTTAI = interaction => {
117
+ const {
118
+ start,
119
+ end
120
+ } = interaction;
121
+ const pageVisibilityUpToTTAI = getPageVisibilityUpToTTAI(interaction);
122
+ return !interaction.abortReason && pageVisibilityUpToTTAI === 'visible' ? Math.round(end - start) : undefined;
123
+ };
@@ -2,19 +2,20 @@ import Bowser from 'bowser-ultralight';
2
2
  import { fg } from '@atlaskit/platform-feature-flags';
3
3
  import { getLighthouseMetrics } from '../additional-payload';
4
4
  import * as bundleEvalTiming from '../bundle-eval-timing';
5
+ import coinflip from '../coinflip';
5
6
  import { REACT_UFO_VERSION } from '../common/constants';
6
- import { getConfig, getUfoNameOverrides } from '../config';
7
+ import { getConfig, getExperimentalInteractionRate, getUfoNameOverrides } from '../config';
8
+ import { getExperimentalVCMetrics } from '../create-experimental-interaction-metrics-payload';
7
9
  import { getBm3Timings } from '../custom-timings';
8
10
  import { getGlobalErrorCount } from '../global-error-handler';
9
11
  import { getPageVisibilityState } from '../hidden-timing';
10
12
  import * as initialPageLoadExtraTiming from '../initial-page-load-extra-timing';
11
- import { interactionSpans as atlaskitInteractionSpans, postInteractionLog } from '../interaction-metrics';
13
+ import { interactionSpans as atlaskitInteractionSpans } from '../interaction-metrics';
12
14
  import * as resourceTiming from '../resource-timing';
13
15
  import { roundEpsilon } from '../round-number';
14
16
  import * as ssr from '../ssr';
15
- import { getVCObserver } from '../vc';
16
- import { buildSegmentTree, labelStackStartWith, optimizeLabelStack, sanitizeUfoName, stringifyLabelStackFully } from './common/utils';
17
- function getUfoNameOverride(interaction) {
17
+ import { buildSegmentTree, getPageVisibilityUpToTTAI, getSSRDoneTimeValue, getTTAI, getVCMetrics, labelStackStartWith, optimizeLabelStack, sanitizeUfoName, stringifyLabelStackFully } from './common/utils';
18
+ export function getUfoNameOverride(interaction) {
18
19
  const {
19
20
  ufoName,
20
21
  apdex
@@ -28,7 +29,6 @@ function getUfoNameOverride(interaction) {
28
29
  }
29
30
  }
30
31
  return ufoName;
31
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
32
32
  } catch (e) {
33
33
  return ufoName;
34
34
  }
@@ -63,13 +63,6 @@ const getPageVisibilityUpToTTI = interaction => {
63
63
  const bm3EndTimeOrInteractionEndTime = getBm3EndTimeOrFallbackValue(interaction);
64
64
  return getPageVisibilityState(start, bm3EndTimeOrInteractionEndTime);
65
65
  };
66
- const getPageVisibilityUpToTTAI = interaction => {
67
- const {
68
- start,
69
- end
70
- } = interaction;
71
- return getPageVisibilityState(start, end);
72
- };
73
66
  const getVisibilityStateFromPerformance = stop => {
74
67
  try {
75
68
  const results = performance.getEntriesByType('visibility-state');
@@ -124,15 +117,6 @@ const getMoreAccuratePageVisibilityUpToTTAI = interaction => {
124
117
  }
125
118
  return old;
126
119
  };
127
- const getInteractionStatus = interaction => {
128
- const originalInteractionStatus = interaction.abortReason ? 'ABORTED' : 'SUCCEEDED';
129
- const hasBm3TTI = interaction.apdex.length > 0;
130
- const overrideStatus = hasBm3TTI ? 'SUCCEEDED' : originalInteractionStatus;
131
- return {
132
- originalInteractionStatus,
133
- overrideStatus
134
- };
135
- };
136
120
  const getResourceTimings = (start, end) => {
137
121
  var _resourceTiming$getRe;
138
122
  return (_resourceTiming$getRe = resourceTiming.getResourceTimings(start, end)) !== null && _resourceTiming$getRe !== void 0 ? _resourceTiming$getRe : undefined;
@@ -155,44 +139,6 @@ const getPaintMetrics = type => {
155
139
  });
156
140
  return metrics;
157
141
  };
158
- const getVCMetrics = interaction => {
159
- var _config$vc, _interaction$apdex, _interaction$apdex$;
160
- const config = getConfig();
161
- if (!(config !== null && config !== void 0 && (_config$vc = config.vc) !== null && _config$vc !== void 0 && _config$vc.enabled)) {
162
- return {};
163
- }
164
- if (interaction.type !== 'page_load' && interaction.type !== 'transition') {
165
- return {};
166
- }
167
- const ssr = interaction.type === 'page_load' && config !== null && config !== void 0 && config.ssr ? {
168
- ssr: getSSRDoneTimeValue(config)
169
- } : null;
170
- postInteractionLog.setVCObserverSSRConfig(ssr);
171
- 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;
172
- const prefix = 'ufo';
173
- const result = getVCObserver().getVCResult({
174
- start: interaction.start,
175
- stop: interaction.end,
176
- tti,
177
- prefix,
178
- vc: interaction.vc,
179
- ...ssr
180
- });
181
- postInteractionLog.setLastInteractionFinishVCResult(result);
182
- const VC = result === null || result === void 0 ? void 0 : result['metrics:vc'];
183
- if (!VC || !(result !== null && result !== void 0 && result[`${prefix}:vc:clean`])) {
184
- return result;
185
- }
186
- const interactionStatus = getInteractionStatus(interaction);
187
- const pageVisibilityUpToTTAI = getPageVisibilityUpToTTAI(interaction);
188
- if (interactionStatus.originalInteractionStatus !== 'SUCCEEDED' || pageVisibilityUpToTTAI !== 'visible') {
189
- return result;
190
- }
191
- return {
192
- ...result,
193
- 'metric:vc90': VC['90']
194
- };
195
- };
196
142
  const getNavigationMetrics = type => {
197
143
  if (type !== 'page_load') {
198
144
  return {};
@@ -240,16 +186,15 @@ const getNavigationMetrics = type => {
240
186
  };
241
187
  };
242
188
  const getPPSMetrics = interaction => {
243
- var _interaction$apdex2, _interaction$apdex2$;
189
+ var _interaction$apdex, _interaction$apdex$;
244
190
  const {
245
191
  start,
246
192
  end
247
193
  } = interaction;
248
194
  const config = getConfig();
249
- const interactionStatus = getInteractionStatus(interaction);
250
195
  const pageVisibilityUpToTTAI = getPageVisibilityUpToTTAI(interaction);
251
- const tti = (_interaction$apdex2 = interaction.apdex) === null || _interaction$apdex2 === void 0 ? void 0 : (_interaction$apdex2$ = _interaction$apdex2[0]) === null || _interaction$apdex2$ === void 0 ? void 0 : _interaction$apdex2$.stopTime;
252
- const ttai = interactionStatus.originalInteractionStatus === 'SUCCEEDED' && pageVisibilityUpToTTAI === 'visible' ? Math.round(end - start) : undefined;
196
+ 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;
197
+ const ttai = !interaction.abortReason && pageVisibilityUpToTTAI === 'visible' ? Math.round(end - start) : undefined;
253
198
  const PPSMetricsAtTTI = tti !== undefined ? getLighthouseMetrics({
254
199
  start,
255
200
  stop: tti
@@ -594,10 +539,6 @@ function getBm3TrackerTimings(interaction) {
594
539
  legacyMetrics
595
540
  };
596
541
  }
597
- function getSSRDoneTimeValue(config) {
598
- var _config$ssr, _config$ssr2;
599
- return config !== null && config !== void 0 && (_config$ssr = config.ssr) !== null && _config$ssr !== void 0 && _config$ssr.getSSRDoneTime ? config === null || config === void 0 ? void 0 : (_config$ssr2 = config.ssr) === null || _config$ssr2 === void 0 ? void 0 : _config$ssr2.getSSRDoneTime() : ssr.getSSRDoneTime();
600
- }
601
542
  function getPayloadSize(payload) {
602
543
  return Math.round(new TextEncoder().encode(JSON.stringify(payload)).length / 1024);
603
544
  }
@@ -640,13 +581,15 @@ function getStylesheetMetrics() {
640
581
  return {};
641
582
  }
642
583
  }
584
+ let regularTTAI;
585
+ let expTTAI;
643
586
  function getErrorCounts(interaction) {
644
587
  return {
645
588
  'ufo:errors:globalCount': getGlobalErrorCount(),
646
589
  'ufo:errors:count': interaction.errors.length
647
590
  };
648
591
  }
649
- function createInteractionMetricsPayload(interaction, interactionId) {
592
+ function createInteractionMetricsPayload(interaction, interactionId, experimental) {
650
593
  var _window$location, _config$additionalPay;
651
594
  const interactionPayloadStart = performance.now();
652
595
  const config = getConfig();
@@ -681,7 +624,7 @@ function createInteractionMetricsPayload(interaction, interactionId) {
681
624
  } : {};
682
625
  // Page Load
683
626
  const getPageLoadInteractionMetrics = () => {
684
- var _config$ssr3;
627
+ var _config$ssr;
685
628
  if (!isPageLoad) {
686
629
  return {};
687
630
  }
@@ -693,12 +636,12 @@ function createInteractionMetricsPayload(interaction, interactionId) {
693
636
  return {
694
637
  ...SSRDoneTime,
695
638
  isBM3ConfigSSRDoneAsFmp: interaction.metaData.__legacy__bm3ConfigSSRDoneAsFmp,
696
- isUFOConfigSSRDoneAsFmp: interaction.metaData.__legacy__bm3ConfigSSRDoneAsFmp || !!(config !== null && config !== void 0 && (_config$ssr3 = config.ssr) !== null && _config$ssr3 !== void 0 && _config$ssr3.getSSRDoneTime)
639
+ isUFOConfigSSRDoneAsFmp: interaction.metaData.__legacy__bm3ConfigSSRDoneAsFmp || !!(config !== null && config !== void 0 && (_config$ssr = config.ssr) !== null && _config$ssr !== void 0 && _config$ssr.getSSRDoneTime)
697
640
  };
698
641
  };
699
642
  // Detailed payload. Page visibility = visible
700
643
  const getDetailedInteractionMetrics = () => {
701
- if (window.__UFO_COMPACT_PAYLOAD__ || !isDetailedPayload) {
644
+ if (experimental || window.__UFO_COMPACT_PAYLOAD__ || !isDetailedPayload) {
702
645
  return {};
703
646
  }
704
647
  const spans = [...interaction.spans, ...atlaskitInteractionSpans];
@@ -713,7 +656,7 @@ function createInteractionMetricsPayload(interaction, interactionId) {
713
656
  })),
714
657
  holdActive: [...interaction.holdActive.values()],
715
658
  redirects: optimizeRedirects(interaction.redirects, start),
716
- holdInfo: optimizeHoldInfo(interaction.holdInfo, start),
659
+ holdInfo: optimizeHoldInfo(experimental ? interaction.holdExpInfo : interaction.holdInfo, start),
717
660
  spans: optimizeSpans(spans, start),
718
661
  requestInfo: optimizeRequestInfo(interaction.requestInfo, start),
719
662
  customTimings: optimizeCustomTimings(interaction.customTimings, start),
@@ -723,16 +666,21 @@ function createInteractionMetricsPayload(interaction, interactionId) {
723
666
  };
724
667
  // Page load & detailed payload
725
668
  const getPageLoadDetailedInteractionMetrics = () => {
726
- var _config$ssr4;
669
+ var _config$ssr2;
727
670
  if (!isPageLoad || !isDetailedPayload) {
728
671
  return {};
729
672
  }
730
673
  const config = getConfig();
731
674
  return {
732
675
  initialPageLoadExtraTimings: objectToArray(initialPageLoadExtraTiming.getTimings()),
733
- SSRTimings: config !== null && config !== void 0 && (_config$ssr4 = config.ssr) !== null && _config$ssr4 !== void 0 && _config$ssr4.getSSRTimings ? config.ssr.getSSRTimings() : objectToArray(ssr.getSSRTimings())
676
+ SSRTimings: config !== null && config !== void 0 && (_config$ssr2 = config.ssr) !== null && _config$ssr2 !== void 0 && _config$ssr2.getSSRTimings ? config.ssr.getSSRTimings() : objectToArray(ssr.getSSRTimings())
734
677
  };
735
678
  };
679
+ if (experimental) {
680
+ expTTAI = getTTAI(interaction);
681
+ } else {
682
+ regularTTAI = getTTAI(interaction);
683
+ }
736
684
  const newUFOName = sanitizeUfoName(ufoName);
737
685
  const payload = {
738
686
  actionSubject: 'experience',
@@ -753,7 +701,7 @@ function createInteractionMetricsPayload(interaction, interactionId) {
753
701
  payloadSource: 'platform'
754
702
  },
755
703
  'event:region': config.region || 'unknown',
756
- 'experience:key': 'custom.interaction-metrics',
704
+ 'experience:key': experimental ? 'custom.experimental-interaction-metrics' : 'custom.interaction-metrics',
757
705
  'experience:name': newUFOName,
758
706
  // root
759
707
  ...getBrowserMetadata(),
@@ -762,6 +710,7 @@ function createInteractionMetricsPayload(interaction, interactionId) {
762
710
  ...getPaintMetrics(type),
763
711
  ...getNavigationMetrics(type),
764
712
  ...getVCMetrics(interaction),
713
+ ...(experimental ? getExperimentalVCMetrics(interaction) : undefined),
765
714
  ...((_config$additionalPay = config.additionalPayloadData) === null || _config$additionalPay === void 0 ? void 0 : _config$additionalPay.call(config, interaction)),
766
715
  ...getTracingContextData(interaction),
767
716
  ...getStylesheetMetrics(),
@@ -801,12 +750,18 @@ function createInteractionMetricsPayload(interaction, interactionId) {
801
750
  ...getPageLoadInteractionMetrics(),
802
751
  ...getDetailedInteractionMetrics(),
803
752
  ...getPageLoadDetailedInteractionMetrics(),
804
- ...getBm3TrackerTimings(interaction)
753
+ ...getBm3TrackerTimings(interaction),
754
+ 'metric:ttai': experimental ? regularTTAI || expTTAI : undefined,
755
+ 'metric:experimental:ttai': expTTAI
805
756
  },
806
757
  'ufo:payloadTime': roundEpsilon(performance.now() - interactionPayloadStart)
807
758
  }
808
759
  }
809
760
  };
761
+ if (experimental) {
762
+ regularTTAI = undefined;
763
+ expTTAI = undefined;
764
+ }
810
765
  payload.attributes.properties['event:sizeInKb'] = getPayloadSize(payload.attributes.properties);
811
766
  return payload;
812
767
  }
@@ -818,4 +773,20 @@ export function createPayloads(interactionId, interaction) {
818
773
  };
819
774
  const interactionMetricsPayload = createInteractionMetricsPayload(modifiedInteraction, interactionId);
820
775
  return [interactionMetricsPayload];
776
+ }
777
+ export function createExperimentalMetricsPayload(interactionId, interaction) {
778
+ const config = getConfig();
779
+ if (!config) {
780
+ throw Error('UFO Configuration not provided');
781
+ }
782
+ const ufoName = sanitizeUfoName(interaction.ufoName);
783
+ const rate = getExperimentalInteractionRate(ufoName, interaction.type);
784
+ if (!coinflip(rate)) {
785
+ return null;
786
+ }
787
+ const pageVisibilityState = getPageVisibilityState(interaction.start, interaction.end);
788
+ if (pageVisibilityState !== 'visible') {
789
+ return null;
790
+ }
791
+ return createInteractionMetricsPayload(interaction, interactionId, true);
821
792
  }
@@ -1,2 +1,7 @@
1
- const interactions = new Map();
2
- export default interactions;
1
+ export const interactions = new Map();
2
+ export const CLEANUP_TIMEOUT = 60 * 1000;
3
+ export const CLEANUP_TIMEOUT_AFTER_APDEX = 15 * 1000;
4
+ export const interactionQueue = [];
5
+ export const segmentCache = new Map();
6
+ export const segmentObservers = [];
7
+ export const moduleLoadingRequests = {};