@atlaskit/react-ufo 2.5.2 → 2.6.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 (56) hide show
  1. package/CHANGELOG.md +21 -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 +65 -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/cjs/vc/vc-observer/observers/ssr-placeholders/index.js +21 -4
  14. package/dist/es2019/config/index.js +22 -0
  15. package/dist/es2019/create-experimental-interaction-metrics-payload/index.js +71 -0
  16. package/dist/es2019/create-payload/common/utils/index.js +67 -1
  17. package/dist/es2019/create-payload/index.js +48 -77
  18. package/dist/es2019/interaction-metrics/common/constants.js +7 -2
  19. package/dist/es2019/interaction-metrics/common/index.js +103 -0
  20. package/dist/es2019/interaction-metrics/index.js +91 -131
  21. package/dist/es2019/interaction-metrics-init/index.js +28 -8
  22. package/dist/es2019/load-hold/UFOLoadHold.js +5 -3
  23. package/dist/es2019/segment/segment.js +8 -11
  24. package/dist/es2019/vc/vc-observer/observers/ssr-placeholders/index.js +21 -4
  25. package/dist/esm/config/index.js +39 -18
  26. package/dist/esm/create-experimental-interaction-metrics-payload/index.js +90 -0
  27. package/dist/esm/create-payload/common/utils/index.js +62 -1
  28. package/dist/esm/create-payload/index.js +53 -78
  29. package/dist/esm/interaction-metrics/common/constants.js +7 -2
  30. package/dist/esm/interaction-metrics/common/index.js +132 -0
  31. package/dist/esm/interaction-metrics/index.js +86 -158
  32. package/dist/esm/interaction-metrics-init/index.js +28 -8
  33. package/dist/esm/load-hold/UFOLoadHold.js +5 -3
  34. package/dist/esm/segment/segment.js +9 -8
  35. package/dist/esm/vc/vc-observer/observers/ssr-placeholders/index.js +21 -4
  36. package/dist/types/common/common/types.d.ts +6 -4
  37. package/dist/types/config/index.d.ts +6 -0
  38. package/dist/types/create-experimental-interaction-metrics-payload/index.d.ts +16 -0
  39. package/dist/types/create-payload/common/utils/index.d.ts +9 -0
  40. package/dist/types/create-payload/index.d.ts +13 -5660
  41. package/dist/types/interaction-context/index.d.ts +1 -0
  42. package/dist/types/interaction-metrics/common/constants.d.ts +32 -3
  43. package/dist/types/interaction-metrics/common/index.d.ts +16 -0
  44. package/dist/types/interaction-metrics/index.d.ts +1 -17
  45. package/dist/types/load-hold/UFOLoadHold.d.ts +1 -2
  46. package/dist/types-ts4.5/common/common/types.d.ts +6 -4
  47. package/dist/types-ts4.5/config/index.d.ts +6 -0
  48. package/dist/types-ts4.5/create-experimental-interaction-metrics-payload/index.d.ts +16 -0
  49. package/dist/types-ts4.5/create-payload/common/utils/index.d.ts +9 -0
  50. package/dist/types-ts4.5/create-payload/index.d.ts +13 -5660
  51. package/dist/types-ts4.5/interaction-context/index.d.ts +1 -0
  52. package/dist/types-ts4.5/interaction-metrics/common/constants.d.ts +32 -3
  53. package/dist/types-ts4.5/interaction-metrics/common/index.d.ts +16 -0
  54. package/dist/types-ts4.5/interaction-metrics/index.d.ts +1 -17
  55. package/dist/types-ts4.5/load-hold/UFOLoadHold.d.ts +1 -2
  56. package/package.json +6 -2
@@ -0,0 +1,132 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
3
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
4
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
5
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
6
+ import { getConfig } from '../../config';
7
+ import { interactionQueue, segmentCache, segmentObservers } from './constants';
8
+ export function isPerformanceTracingEnabled() {
9
+ var _getConfig;
10
+ return ((_getConfig = getConfig()) === null || _getConfig === void 0 ? void 0 : _getConfig.enableAdditionalPerformanceMarks) || window.__REACT_UFO_ENABLE_PERF_TRACING || process.env.NODE_ENV !== 'production';
11
+ }
12
+ export function labelStackToString(labelStack, name) {
13
+ var _stack$map;
14
+ var stack = _toConsumableArray(labelStack !== null && labelStack !== void 0 ? labelStack : []);
15
+ if (name) {
16
+ stack.push({
17
+ name: name
18
+ });
19
+ }
20
+ return (_stack$map = stack.map(function (l) {
21
+ return l.name;
22
+ })) === null || _stack$map === void 0 ? void 0 : _stack$map.join('/');
23
+ }
24
+ export function labelStackToIdString(labelStack) {
25
+ var _labelStack$map;
26
+ return labelStack === null || labelStack === void 0 || (_labelStack$map = labelStack.map(function (l) {
27
+ return 'segmentId' in l ? "".concat(l.name, ":").concat(l.segmentId) : "".concat(l.name);
28
+ })) === null || _labelStack$map === void 0 ? void 0 : _labelStack$map.join('/');
29
+ }
30
+ export function addSegmentObserver(observer) {
31
+ segmentObservers.push(observer);
32
+ var _iterator = _createForOfIteratorHelper(segmentCache.values()),
33
+ _step;
34
+ try {
35
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
36
+ var segmentInfo = _step.value;
37
+ observer.onAdd(segmentInfo);
38
+ }
39
+ } catch (err) {
40
+ _iterator.e(err);
41
+ } finally {
42
+ _iterator.f();
43
+ }
44
+ }
45
+ export function removeSegmentObserver(observer) {
46
+ var index = segmentObservers.findIndex(function (obs) {
47
+ return obs === observer;
48
+ });
49
+ if (index !== -1) {
50
+ segmentObservers.splice(index, 1);
51
+ }
52
+ }
53
+ export function addHoldCriterion(id, labelStack, name, startTime) {
54
+ var _window$__CRITERION__;
55
+ if (!((_window$__CRITERION__ = window.__CRITERION__) !== null && _window$__CRITERION__ !== void 0 && _window$__CRITERION__.addUFOHold)) {
56
+ return;
57
+ }
58
+ window.__CRITERION__.addUFOHold(id, labelStackToString(labelStack), name, startTime);
59
+ }
60
+ export function removeHoldCriterion(id) {
61
+ var _window$__CRITERION__2;
62
+ if (!((_window$__CRITERION__2 = window.__CRITERION__) !== null && _window$__CRITERION__2 !== void 0 && _window$__CRITERION__2.removeUFOHold)) {
63
+ return;
64
+ }
65
+ window.__CRITERION__.removeUFOHold(id);
66
+ }
67
+ export var pushToQueue = function pushToQueue(id, data) {
68
+ interactionQueue.push({
69
+ id: id,
70
+ data: data
71
+ });
72
+ };
73
+ export function callCleanUpCallbacks(interaction) {
74
+ interaction.cleanupCallbacks.reverse().forEach(function (cleanUpCallback) {
75
+ cleanUpCallback();
76
+ });
77
+ }
78
+ export function reactProfilerTimingMap(data) {
79
+ var profilerTimingMap = new Map();
80
+ data.reactProfilerTimings.forEach(function (profilerTiming) {
81
+ var labelStackId = labelStackToIdString(profilerTiming.labelStack);
82
+ if (labelStackId) {
83
+ var _profilerTimingMap$ge, _timing$start, _timing$end;
84
+ var timing = (_profilerTimingMap$ge = profilerTimingMap.get(labelStackId)) !== null && _profilerTimingMap$ge !== void 0 ? _profilerTimingMap$ge : {
85
+ labelStack: profilerTiming.labelStack
86
+ };
87
+ timing.start = profilerTiming.startTime < ((_timing$start = timing.start) !== null && _timing$start !== void 0 ? _timing$start : Number.MAX_SAFE_INTEGER) ? profilerTiming.startTime : timing.start;
88
+ timing.end = profilerTiming.commitTime > ((_timing$end = timing.end) !== null && _timing$end !== void 0 ? _timing$end : Number.MIN_SAFE_INTEGER) ? profilerTiming.commitTime : timing.end;
89
+ profilerTimingMap.set(labelStackId, timing);
90
+ }
91
+ });
92
+ try {
93
+ // for Firefox 102 and older
94
+ var _iterator2 = _createForOfIteratorHelper(profilerTimingMap.entries()),
95
+ _step2;
96
+ try {
97
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
98
+ var _step2$value = _slicedToArray(_step2.value, 2),
99
+ _step2$value$ = _step2$value[1],
100
+ labelStack = _step2$value$.labelStack,
101
+ start = _step2$value$.start,
102
+ end = _step2$value$.end;
103
+ performance.measure("\uD83D\uDEF8 ".concat(labelStackToString(labelStack), " [segment_ttai]"), {
104
+ start: start,
105
+ end: end
106
+ });
107
+ }
108
+ } catch (err) {
109
+ _iterator2.e(err);
110
+ } finally {
111
+ _iterator2.f();
112
+ }
113
+ } catch (e) {
114
+ // do nothing
115
+ }
116
+ }
117
+ export function callCancelCallbacks(interaction) {
118
+ interaction.cancelCallbacks.reverse().forEach(function (cancelCallback) {
119
+ cancelCallback();
120
+ });
121
+ }
122
+ export function isSegmentLabel(obj) {
123
+ return obj && typeof obj.name === 'string' && typeof obj.segmentId === 'string';
124
+ }
125
+ export function getSegmentCacheKey(labelStack) {
126
+ return labelStack.map(function (l) {
127
+ if (isSegmentLabel(l)) {
128
+ return "".concat(l.name, "_").concat(l.segmentId);
129
+ }
130
+ return l.name;
131
+ }).join('|');
132
+ }
@@ -1,30 +1,22 @@
1
1
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
2
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
- import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
4
3
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
5
4
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
6
- function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
7
- function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
8
- function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
9
5
  import { v4 as createUUID } from 'uuid';
10
6
  import coinflip from '../coinflip';
11
7
  import { getAwaitBM3TTIList, getCapabilityRate, getConfig } from '../config';
8
+ import { experimentalVC, getExperimentalVCMetrics, onExperimentalInteractionComplete } from '../create-experimental-interaction-metrics-payload';
9
+ import { getTTAI, postInteractionLog } from '../create-payload/common/utils';
12
10
  import { clearActiveTrace } from '../experience-trace-id-context';
13
11
  import { allFeatureFlagsAccessed, currentFeatureFlagsAccessed } from '../feature-flags-accessed';
14
12
  import { getInteractionId } from '../interaction-id-context';
15
13
  import { getVCObserver } from '../vc';
16
- import interactions from './common/constants';
17
- import PostInteractionLog from './post-interaction-log';
14
+ import { addHoldCriterion, addSegmentObserver, callCancelCallbacks, callCleanUpCallbacks, getSegmentCacheKey, isPerformanceTracingEnabled, labelStackToString, pushToQueue, reactProfilerTimingMap, removeHoldCriterion, removeSegmentObserver } from './common';
15
+ import { CLEANUP_TIMEOUT, CLEANUP_TIMEOUT_AFTER_APDEX, interactionQueue, interactions, moduleLoadingRequests, segmentCache, segmentObservers } from './common/constants';
18
16
  var PreviousInteractionLog = {
19
17
  name: undefined,
20
18
  isAborted: undefined
21
19
  };
22
- export var postInteractionLog = new PostInteractionLog();
23
- var interactionQueue = [];
24
- var segmentCache = new Map();
25
- var CLEANUP_TIMEOUT = 60 * 1000;
26
- var CLEANUP_TIMEOUT_AFTER_APDEX = 15 * 1000;
27
- var segmentObservers = [];
28
20
  export function getActiveInteraction() {
29
21
  var interactionId = getInteractionId();
30
22
  if (!interactionId.current) {
@@ -32,51 +24,6 @@ export function getActiveInteraction() {
32
24
  }
33
25
  return interactions.get(interactionId.current);
34
26
  }
35
- function isPerformanceTracingEnabled() {
36
- var _getConfig;
37
- return ((_getConfig = getConfig()) === null || _getConfig === void 0 ? void 0 : _getConfig.enableAdditionalPerformanceMarks) || window.__REACT_UFO_ENABLE_PERF_TRACING || process.env.NODE_ENV !== 'production';
38
- }
39
- function labelStackToString(labelStack, name) {
40
- var _stack$map;
41
- var stack = _toConsumableArray(labelStack !== null && labelStack !== void 0 ? labelStack : []);
42
- if (name) {
43
- stack.push({
44
- name: name
45
- });
46
- }
47
- return (_stack$map = stack.map(function (l) {
48
- return l.name;
49
- })) === null || _stack$map === void 0 ? void 0 : _stack$map.join('/');
50
- }
51
- function labelStackToIdString(labelStack) {
52
- var _labelStack$map;
53
- return labelStack === null || labelStack === void 0 || (_labelStack$map = labelStack.map(function (l) {
54
- return 'segmentId' in l ? "".concat(l.name, ":").concat(l.segmentId) : "".concat(l.name);
55
- })) === null || _labelStack$map === void 0 ? void 0 : _labelStack$map.join('/');
56
- }
57
- function addSegmentObserver(observer) {
58
- segmentObservers.push(observer);
59
- var _iterator = _createForOfIteratorHelper(segmentCache.values()),
60
- _step;
61
- try {
62
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
63
- var segmentInfo = _step.value;
64
- observer.onAdd(segmentInfo);
65
- }
66
- } catch (err) {
67
- _iterator.e(err);
68
- } finally {
69
- _iterator.f();
70
- }
71
- }
72
- function removeSegmentObserver(observer) {
73
- var index = segmentObservers.findIndex(function (obs) {
74
- return obs === observer;
75
- });
76
- if (index !== -1) {
77
- segmentObservers.splice(index, 1);
78
- }
79
- }
80
27
  export function remove(interactionId) {
81
28
  interactions.delete(interactionId);
82
29
  }
@@ -225,7 +172,6 @@ export function addPreload(moduleId, timestamp) {
225
172
  export function addLoad(identifier, start, end) {
226
173
  addSpanToAll('bundle_load', identifier, null, start, end - start);
227
174
  }
228
- var moduleLoadingRequests = {};
229
175
  export function extractModuleName(input) {
230
176
  var result = input !== null && input !== void 0 ? input : '';
231
177
  result = result.replace(/^\.\/src\/packages\//, '');
@@ -233,30 +179,27 @@ export function extractModuleName(input) {
233
179
  result = result.replace(/(\/src)?\/(index|main)\.(tsx|ts|js|jsx)$/, '');
234
180
  return result;
235
181
  }
236
- function addHoldCriterion(id, labelStack, name, startTime) {
237
- var _window$__CRITERION__;
238
- if (!((_window$__CRITERION__ = window.__CRITERION__) !== null && _window$__CRITERION__ !== void 0 && _window$__CRITERION__.addUFOHold)) {
239
- return;
240
- }
241
- window.__CRITERION__.addUFOHold(id, labelStackToString(labelStack), name, startTime);
242
- }
243
- function removeHoldCriterion(id) {
244
- var _window$__CRITERION__2;
245
- if (!((_window$__CRITERION__2 = window.__CRITERION__) !== null && _window$__CRITERION__2 !== void 0 && _window$__CRITERION__2.removeUFOHold)) {
246
- return;
247
- }
248
- window.__CRITERION__.removeUFOHold(id);
249
- }
250
- export function addHold(interactionId, labelStack, name) {
182
+ export function addHold(interactionId, labelStack, name, experimental) {
251
183
  var interaction = interactions.get(interactionId);
252
184
  var id = createUUID();
253
185
  if (interaction != null) {
254
- var start = performance.now();
255
- interaction.holdActive.set(id, {
186
+ var _getConfig;
187
+ var holdActive = {
256
188
  labelStack: labelStack,
257
189
  name: name,
258
- start: start
259
- });
190
+ start: 0
191
+ };
192
+ var start = performance.now();
193
+ if ((_getConfig = getConfig()) !== null && _getConfig !== void 0 && (_getConfig = _getConfig.experimentalInteractionMetrics) !== null && _getConfig !== void 0 && _getConfig.enabled && experimental) {
194
+ interaction.holdExpActive.set(id, _objectSpread(_objectSpread({}, holdActive), {}, {
195
+ start: start
196
+ }));
197
+ }
198
+ if (!experimental) {
199
+ interaction.holdActive.set(id, _objectSpread(_objectSpread({}, holdActive), {}, {
200
+ start: start
201
+ }));
202
+ }
260
203
  addHoldCriterion(id, labelStack, name, start);
261
204
  return function () {
262
205
  var end = performance.now();
@@ -274,11 +217,20 @@ export function addHold(interactionId, labelStack, name) {
274
217
  removeHoldCriterion(id);
275
218
  var currentInteraction = interactions.get(interactionId);
276
219
  var currentHold = interaction.holdActive.get(id);
277
- if (currentInteraction != null && currentHold != null) {
278
- currentInteraction.holdInfo.push(_objectSpread(_objectSpread({}, currentHold), {}, {
279
- end: end
280
- }));
281
- interaction.holdActive.delete(id);
220
+ var expHold = interaction.holdExpActive.get(id);
221
+ if (currentInteraction != null) {
222
+ if (currentHold != null) {
223
+ currentInteraction.holdInfo.push(_objectSpread(_objectSpread({}, currentHold), {}, {
224
+ end: end
225
+ }));
226
+ interaction.holdActive.delete(id);
227
+ }
228
+ if (expHold != null) {
229
+ currentInteraction.holdExpInfo.push(_objectSpread(_objectSpread({}, expHold), {}, {
230
+ end: end
231
+ }));
232
+ interaction.holdExpActive.delete(id);
233
+ }
282
234
  }
283
235
  };
284
236
  }
@@ -406,22 +358,10 @@ export var addProfilerTimings = function addProfilerTimings(interactionId, label
406
358
  postInteractionLog.addProfilerTimings(labelStack, type, actualDuration, baseDuration, startTime, commitTime);
407
359
  }
408
360
  };
409
- var pushToQueue = function pushToQueue(id, data) {
410
- interactionQueue.push({
411
- id: id,
412
- data: data
413
- });
414
- };
415
361
  var handleInteraction = pushToQueue;
416
- function callCleanUpCallbacks(interaction) {
417
- interaction.cleanupCallbacks.reverse().forEach(function (cleanUpCallback) {
418
- cleanUpCallback();
419
- });
420
- }
421
362
  var finishInteraction = function finishInteraction(id, data) {
422
363
  var _getConfig3;
423
364
  var endTime = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : performance.now();
424
- // eslint-disable-next-line no-param-reassign
425
365
  data.end = endTime;
426
366
  try {
427
367
  // for Firefox 102 and older
@@ -433,7 +373,6 @@ var finishInteraction = function finishInteraction(id, data) {
433
373
  // do nothing
434
374
  }
435
375
  if (data.featureFlags) {
436
- // eslint-disable-next-line no-param-reassign
437
376
  data.featureFlags.during = Object.fromEntries(currentFeatureFlagsAccessed);
438
377
  }
439
378
  clearActiveTrace();
@@ -441,50 +380,13 @@ var finishInteraction = function finishInteraction(id, data) {
441
380
  if ((_getConfig3 = getConfig()) !== null && _getConfig3 !== void 0 && (_getConfig3 = _getConfig3.vc) !== null && _getConfig3 !== void 0 && _getConfig3.stopVCAtInteractionFinish) {
442
381
  data.vc = getVCObserver().getVCRawData();
443
382
  }
444
- remove(id);
445
383
  PreviousInteractionLog.name = data.ufoName || 'unknown';
446
384
  PreviousInteractionLog.isAborted = data.abortReason != null;
447
385
  if (data.ufoName) {
448
386
  handleInteraction(id, data);
449
387
  }
450
388
  if (isPerformanceTracingEnabled()) {
451
- var profilerTimingMap = new Map();
452
- data.reactProfilerTimings.forEach(function (profilerTiming) {
453
- var labelStackId = labelStackToIdString(profilerTiming.labelStack);
454
- if (labelStackId) {
455
- var _profilerTimingMap$ge, _timing$start, _timing$end;
456
- var timing = (_profilerTimingMap$ge = profilerTimingMap.get(labelStackId)) !== null && _profilerTimingMap$ge !== void 0 ? _profilerTimingMap$ge : {
457
- labelStack: profilerTiming.labelStack
458
- };
459
- timing.start = profilerTiming.startTime < ((_timing$start = timing.start) !== null && _timing$start !== void 0 ? _timing$start : Number.MAX_SAFE_INTEGER) ? profilerTiming.startTime : timing.start;
460
- timing.end = profilerTiming.commitTime > ((_timing$end = timing.end) !== null && _timing$end !== void 0 ? _timing$end : Number.MIN_SAFE_INTEGER) ? profilerTiming.commitTime : timing.end;
461
- profilerTimingMap.set(labelStackId, timing);
462
- }
463
- });
464
- try {
465
- // for Firefox 102 and older
466
- var _iterator2 = _createForOfIteratorHelper(profilerTimingMap.entries()),
467
- _step2;
468
- try {
469
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
470
- var _step2$value = _slicedToArray(_step2.value, 2),
471
- _step2$value$ = _step2$value[1],
472
- labelStack = _step2$value$.labelStack,
473
- start = _step2$value$.start,
474
- end = _step2$value$.end;
475
- performance.measure("\uD83D\uDEF8 ".concat(labelStackToString(labelStack), " [segment_ttai]"), {
476
- start: start,
477
- end: end
478
- });
479
- }
480
- } catch (err) {
481
- _iterator2.e(err);
482
- } finally {
483
- _iterator2.f();
484
- }
485
- } catch (e) {
486
- // do nothing
487
- }
389
+ reactProfilerTimingMap(data);
488
390
  }
489
391
  try {
490
392
  // dispatch a global window event to notify the measure is completed
@@ -507,54 +409,85 @@ export var sinkInteractionHandler = function sinkInteractionHandler(sinkFn) {
507
409
  export var sinkPostInteractionLogHandler = function sinkPostInteractionLogHandler(sinkFn) {
508
410
  postInteractionLog.sinkHandler(sinkFn);
509
411
  };
412
+
413
+ // a flag to prevent multiple submitting
414
+ var activeSubmitted = false;
510
415
  export function tryComplete(interactionId, endTime) {
511
416
  var interaction = interactions.get(interactionId);
512
417
  if (interaction != null) {
513
- var noMoreHolds = interaction.holdActive.size === 0;
514
- if (noMoreHolds) {
418
+ var noMoreActiveHolds = interaction.holdActive.size === 0;
419
+ var noMoreExpHolds = interaction.holdExpActive.size === 0;
420
+ var postInteraction = function postInteraction() {
515
421
  var _getConfig4;
516
- finishInteraction(interactionId, interaction, endTime);
517
422
  if ((_getConfig4 = getConfig()) !== null && _getConfig4 !== void 0 && (_getConfig4 = _getConfig4.postInteractionLog) !== null && _getConfig4 !== void 0 && _getConfig4.enabled) {
518
- postInteractionLog.onInteractionComplete(interaction);
423
+ var _getExperimentalVCMet;
424
+ var experimentalVC90 = (_getExperimentalVCMet = getExperimentalVCMetrics(interaction)) === null || _getExperimentalVCMet === void 0 ? void 0 : _getExperimentalVCMet['metric:experimental:vc90'];
425
+ var experimentalTTAI = getTTAI(interaction);
426
+ postInteractionLog.onInteractionComplete(_objectSpread(_objectSpread({}, interaction), {}, {
427
+ experimentalTTAI: experimentalTTAI,
428
+ experimentalVC90: experimentalVC90
429
+ }));
430
+ }
431
+ remove(interactionId);
432
+ };
433
+ if (noMoreActiveHolds) {
434
+ if (!activeSubmitted) {
435
+ finishInteraction(interactionId, interaction, endTime);
436
+ activeSubmitted = true;
437
+ }
438
+ if (noMoreExpHolds) {
439
+ var _getConfig5;
440
+ if ((_getConfig5 = getConfig()) !== null && _getConfig5 !== void 0 && (_getConfig5 = _getConfig5.experimentalInteractionMetrics) !== null && _getConfig5 !== void 0 && _getConfig5.enabled) {
441
+ onExperimentalInteractionComplete(interactionId, interaction, endTime);
442
+ }
443
+ postInteraction();
519
444
  }
520
445
  }
521
446
  }
522
447
  }
523
- function callCancelCallbacks(interaction) {
524
- interaction.cancelCallbacks.reverse().forEach(function (cancelCallback) {
525
- cancelCallback();
526
- });
527
- }
528
448
  export function abort(interactionId, abortReason) {
529
449
  var interaction = interactions.get(interactionId);
530
450
  if (interaction != null) {
451
+ var _getConfig6;
531
452
  callCancelCallbacks(interaction);
532
453
  interaction.abortReason = abortReason;
533
454
  finishInteraction(interactionId, interaction);
455
+ if ((_getConfig6 = getConfig()) !== null && _getConfig6 !== void 0 && (_getConfig6 = _getConfig6.experimentalInteractionMetrics) !== null && _getConfig6 !== void 0 && _getConfig6.enabled) {
456
+ onExperimentalInteractionComplete(interactionId, interaction);
457
+ }
458
+ remove(interactionId);
534
459
  }
535
460
  }
536
461
  export function abortByNewInteraction(interactionId, interactionName) {
537
462
  var interaction = interactions.get(interactionId);
538
463
  if (interaction != null) {
464
+ var _getConfig7;
539
465
  callCancelCallbacks(interaction);
540
466
  interaction.abortReason = 'new_interaction';
541
467
  interaction.abortedByInteractionName = interactionName;
542
468
  finishInteraction(interactionId, interaction);
469
+ if ((_getConfig7 = getConfig()) !== null && _getConfig7 !== void 0 && (_getConfig7 = _getConfig7.experimentalInteractionMetrics) !== null && _getConfig7 !== void 0 && _getConfig7.enabled) {
470
+ onExperimentalInteractionComplete(interactionId, interaction);
471
+ }
472
+ remove(interactionId);
543
473
  }
544
474
  }
545
475
  export function abortAll(abortReason, abortedByInteractionName) {
546
476
  interactions.forEach(function (interaction, interactionId) {
477
+ var _getConfig8;
547
478
  var noMoreHolds = interaction.holdActive.size === 0;
548
479
  if (!noMoreHolds) {
549
480
  callCancelCallbacks(interaction);
550
- // eslint-disable-next-line no-param-reassign
551
481
  interaction.abortReason = abortReason;
552
482
  if (abortedByInteractionName != null) {
553
- // eslint-disable-next-line no-param-reassign
554
483
  interaction.abortedByInteractionName = abortedByInteractionName;
555
484
  }
556
485
  }
557
486
  finishInteraction(interactionId, interaction);
487
+ if ((_getConfig8 = getConfig()) !== null && _getConfig8 !== void 0 && (_getConfig8 = _getConfig8.experimentalInteractionMetrics) !== null && _getConfig8 !== void 0 && _getConfig8.enabled) {
488
+ onExperimentalInteractionComplete(interactionId, interaction);
489
+ }
490
+ remove(interactionId);
558
491
  });
559
492
  }
560
493
  export function addOnCancelCallback(id, cancelCallback) {
@@ -562,9 +495,9 @@ export function addOnCancelCallback(id, cancelCallback) {
562
495
  interaction === null || interaction === void 0 || interaction.cancelCallbacks.push(cancelCallback);
563
496
  }
564
497
  export function addNewInteraction(interactionId, ufoName, type, startTime, rate, labelStack, routeName) {
565
- var _getConfig5;
498
+ var _getConfig9;
566
499
  var trace = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : null;
567
- if ((_getConfig5 = getConfig()) !== null && _getConfig5 !== void 0 && (_getConfig5 = _getConfig5.postInteractionLog) !== null && _getConfig5 !== void 0 && _getConfig5.enabled) {
500
+ if ((_getConfig9 = getConfig()) !== null && _getConfig9 !== void 0 && (_getConfig9 = _getConfig9.postInteractionLog) !== null && _getConfig9 !== void 0 && _getConfig9.enabled) {
568
501
  postInteractionLog.reset();
569
502
  }
570
503
  var previousTime = startTime;
@@ -604,9 +537,11 @@ export function addNewInteraction(interactionId, ufoName, type, startTime, rate,
604
537
  requestInfo: [],
605
538
  reactProfilerTimings: [],
606
539
  holdInfo: [],
540
+ holdExpInfo: [],
607
541
  holdActive: new Map(),
542
+ holdExpActive: new Map(),
608
543
  // measure when we execute this code
609
- // from this we can measure the input delay -
544
+ // from this, we can measure the input delay -
610
545
  // how long the browser took to hand execution back to JS)
611
546
  measureStart: performance.now(),
612
547
  rate: rate,
@@ -656,6 +591,10 @@ export function addNewInteraction(interactionId, ufoName, type, startTime, rate,
656
591
  postInteractionLog.startVCObserver({
657
592
  startTime: startTime
658
593
  });
594
+ experimentalVC.start({
595
+ startTime: startTime
596
+ });
597
+ activeSubmitted = false;
659
598
  }
660
599
  }
661
600
  export function addBrowserMetricEvent(event) {
@@ -717,17 +656,6 @@ export function addRequestInfo(interactionId, labelStack, requestInfo) {
717
656
  }, requestInfo));
718
657
  }
719
658
  }
720
- function isSegmentLabel(obj) {
721
- return obj && typeof obj.name === 'string' && typeof obj.segmentId === 'string';
722
- }
723
- function getSegmentCacheKey(labelStack) {
724
- return labelStack.map(function (l) {
725
- if (isSegmentLabel(l)) {
726
- return "".concat(l.name, "_").concat(l.segmentId);
727
- }
728
- return l.name;
729
- }).join('|');
730
- }
731
659
  export function addSegment(labelStack) {
732
660
  var key = getSegmentCacheKey(labelStack);
733
661
  var existingSegment = segmentCache.get(key);
@@ -2,8 +2,10 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
2
  import { unstable_IdlePriority as idlePriority, unstable_scheduleCallback as scheduleCallback } from 'scheduler';
3
3
  import { startLighthouseObserver } from '../additional-payload';
4
4
  import { setUFOConfig } from '../config';
5
+ import { experimentalVC, sinkExperimentalHandler } from '../create-experimental-interaction-metrics-payload';
6
+ import { postInteractionLog } from '../create-payload/common/utils';
5
7
  import { setupHiddenTimingCapture } from '../hidden-timing';
6
- import { postInteractionLog, sinkInteractionHandler, sinkPostInteractionLogHandler } from '../interaction-metrics';
8
+ import { sinkInteractionHandler, sinkPostInteractionLogHandler } from '../interaction-metrics';
7
9
  import { getVCObserver } from '../vc';
8
10
  var initialized = false;
9
11
  function sinkInteraction(instance, payloadPackage) {
@@ -16,6 +18,16 @@ function sinkInteraction(instance, payloadPackage) {
16
18
  });
17
19
  });
18
20
  }
21
+ function sinkExperimentalInteractionMetrics(instance, payloadPackage) {
22
+ sinkExperimentalHandler(function (interactionId, interaction) {
23
+ scheduleCallback(idlePriority, function () {
24
+ var payload = payloadPackage.createExperimentalMetricsPayload(interactionId, interaction);
25
+ if (payload) {
26
+ instance.sendOperationalEvent(payload);
27
+ }
28
+ });
29
+ });
30
+ }
19
31
  function sinkPostInteractionLog(instance, createPostInteractionLogPayload) {
20
32
  sinkPostInteractionLogHandler(function (logOutput) {
21
33
  scheduleCallback(idlePriority, function () {
@@ -33,6 +45,7 @@ export var init = function init(analyticsWebClientAsync, config) {
33
45
  }
34
46
  setUFOConfig(config);
35
47
  if ((_config$vc = config.vc) !== null && _config$vc !== void 0 && _config$vc.enabled) {
48
+ var _config$experimentalI;
36
49
  var vcOptions = {
37
50
  heatmapSize: config.vc.heatmapSize,
38
51
  oldDomUpdates: config.vc.oldDomUpdates,
@@ -46,31 +59,38 @@ export var init = function init(analyticsWebClientAsync, config) {
46
59
  postInteractionLog.startVCObserver({
47
60
  startTime: 0
48
61
  });
62
+ if (config !== null && config !== void 0 && (_config$experimentalI = config.experimentalInteractionMetrics) !== null && _config$experimentalI !== void 0 && _config$experimentalI.enabled) {
63
+ experimentalVC.initialize(vcOptions).start({
64
+ startTime: 0
65
+ });
66
+ }
49
67
  }
50
68
  setupHiddenTimingCapture();
51
69
  startLighthouseObserver();
52
70
  initialized = true;
53
- Promise.all([analyticsWebClientAsync,
54
- // eslint-disable-next-line import/dynamic-import-chunkname
55
- import( /* webpackChunkName: "create-payloads" */'../create-payload'),
56
- // eslint-disable-next-line import/dynamic-import-chunkname
57
- import( /* webpackChunkName: "create-post-intreaction-log-payload" */'../create-post-interaction-log-payload')]).then(function (_ref) {
71
+ Promise.all([analyticsWebClientAsync, import( /* webpackChunkName: "create-payloads" */'../create-payload'), import( /* webpackChunkName: "create-post-interaction-log-payload" */'../create-post-interaction-log-payload')]).then(function (_ref) {
58
72
  var _ref2 = _slicedToArray(_ref, 3),
59
73
  awc = _ref2[0],
60
74
  payloadPackage = _ref2[1],
61
75
  createPostInteractionLogPayloadPackage = _ref2[2];
62
76
  if (awc.getAnalyticsWebClientPromise) {
63
77
  awc.getAnalyticsWebClientPromise().then(function (client) {
64
- var _config$postInteracti;
78
+ var _config$experimentalI2, _config$postInteracti;
65
79
  var instance = client.getInstance();
66
80
  sinkInteraction(instance, payloadPackage);
81
+ if (config !== null && config !== void 0 && (_config$experimentalI2 = config.experimentalInteractionMetrics) !== null && _config$experimentalI2 !== void 0 && _config$experimentalI2.enabled) {
82
+ sinkExperimentalInteractionMetrics(instance, payloadPackage);
83
+ }
67
84
  if ((_config$postInteracti = config.postInteractionLog) !== null && _config$postInteracti !== void 0 && _config$postInteracti.enabled) {
68
85
  sinkPostInteractionLog(instance, createPostInteractionLogPayloadPackage.default);
69
86
  }
70
87
  });
71
88
  } else if (awc.sendOperationalEvent) {
72
- var _config$postInteracti2;
89
+ var _config$experimentalI3, _config$postInteracti2;
73
90
  sinkInteraction(awc, payloadPackage);
91
+ if (config !== null && config !== void 0 && (_config$experimentalI3 = config.experimentalInteractionMetrics) !== null && _config$experimentalI3 !== void 0 && _config$experimentalI3.enabled) {
92
+ sinkExperimentalInteractionMetrics(awc, payloadPackage);
93
+ }
74
94
  if ((_config$postInteracti2 = config.postInteractionLog) !== null && _config$postInteracti2 !== void 0 && _config$postInteracti2.enabled) {
75
95
  sinkPostInteractionLog(awc, createPostInteractionLogPayloadPackage.default);
76
96
  }
@@ -22,8 +22,7 @@ var useLayoutEffectSAFE = typeof window === 'undefined' ? useEffect : useLayoutE
22
22
  * return (
23
23
  * <>
24
24
  * <Skeleton />
25
- * <UFOLoadHold name="card">
26
- * </UFOLoadHold>
25
+ * <UFOLoadHold name="card" />
27
26
  * )
28
27
  * }
29
28
  * ```
@@ -58,7 +57,10 @@ export default function UFOLoadHold(_ref) {
58
57
  // react-18: useId instead
59
58
  var context = useContext(UFOInteractionContext);
60
59
  useLayoutEffectSAFE(function () {
61
- if (hold && !experimental && context != null) {
60
+ if (hold && context != null) {
61
+ if (experimental && context.holdExperimental) {
62
+ return context.holdExperimental(name);
63
+ }
62
64
  return context.hold(name);
63
65
  }
64
66
  }, [hold, context, name]);