@atlaskit/react-ufo 3.14.8 → 3.14.10

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 (23) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/interactions-performance-observer/index.js +23 -19
  3. package/dist/cjs/trace-interaction/index.js +10 -32
  4. package/dist/cjs/trace-interaction/internal/map-to-interaction-type.js +16 -0
  5. package/dist/cjs/trace-interaction/internal/trace-ufo-interaction.js +46 -0
  6. package/dist/cjs/trace-press/index.js +2 -25
  7. package/dist/es2019/interactions-performance-observer/index.js +24 -20
  8. package/dist/es2019/trace-interaction/index.js +4 -31
  9. package/dist/es2019/trace-interaction/internal/map-to-interaction-type.js +10 -0
  10. package/dist/es2019/trace-interaction/internal/trace-ufo-interaction.js +39 -0
  11. package/dist/es2019/trace-press/index.js +2 -25
  12. package/dist/esm/interactions-performance-observer/index.js +23 -19
  13. package/dist/esm/trace-interaction/index.js +4 -31
  14. package/dist/esm/trace-interaction/internal/map-to-interaction-type.js +10 -0
  15. package/dist/esm/trace-interaction/internal/trace-ufo-interaction.js +39 -0
  16. package/dist/esm/trace-press/index.js +2 -25
  17. package/dist/types/trace-interaction/index.d.ts +1 -0
  18. package/dist/types/trace-interaction/internal/map-to-interaction-type.d.ts +2 -0
  19. package/dist/types/trace-interaction/internal/trace-ufo-interaction.d.ts +3 -0
  20. package/dist/types-ts4.5/trace-interaction/index.d.ts +1 -0
  21. package/dist/types-ts4.5/trace-interaction/internal/map-to-interaction-type.d.ts +2 -0
  22. package/dist/types-ts4.5/trace-interaction/internal/trace-ufo-interaction.d.ts +3 -0
  23. package/package.json +4 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @atlaskit/ufo-interaction-ignore
2
2
 
3
+ ## 3.14.10
4
+
5
+ ### Patch Changes
6
+
7
+ - [#180425](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/180425)
8
+ [`b932e1047acb7`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/b932e1047acb7) -
9
+ Check if responsiveness exists before updating for press interactions
10
+
11
+ ## 3.14.9
12
+
13
+ ### Patch Changes
14
+
15
+ - [#180517](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/180517)
16
+ [`cba15052f7278`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/cba15052f7278) -
17
+ AFO-4101 properly aborting previous interacttion
18
+
3
19
  ## 3.14.8
4
20
 
5
21
  ### Patch Changes
@@ -29,6 +29,12 @@ function getTestIdName(memoizedProps) {
29
29
  }
30
30
  return null;
31
31
  }
32
+ function getUFOSegmentName(componentName, memoizedProps) {
33
+ if (memoizedProps && memoizedProps['name']) {
34
+ return "UFOSegment[name=".concat(memoizedProps['name'], "]");
35
+ }
36
+ return componentName;
37
+ }
32
38
  function getReactComponentHierarchy(element) {
33
39
  var componentHierarchy = [];
34
40
  // Function to traverse up the fiber tree
@@ -40,11 +46,12 @@ function getReactComponentHierarchy(element) {
40
46
  var componentName = currentFiber.type.displayName || currentFiber.type.name;
41
47
  // checking when component name is bigger than the minimized name produced by react
42
48
  if (componentName && componentName.length > 2 && !componentName.includes('Listener') && !componentName.includes('Provider')) {
49
+ if (componentName === 'UFOSegment') {
50
+ componentHierarchy.push(getUFOSegmentName(componentName, currentFiber.memoizedProps));
51
+ break;
52
+ }
43
53
  componentHierarchy.push(componentName);
44
54
  }
45
- if (componentName === 'UFOSegment') {
46
- break;
47
- }
48
55
  }
49
56
  if (currentFiber.memoizedProps) {
50
57
  var dataIdInfo = getTestIdName(currentFiber.memoizedProps);
@@ -90,23 +97,20 @@ var getPerformanceObserver = exports.getPerformanceObserver = function getPerfor
90
97
  var setInteractionPerformanceEvent = exports.setInteractionPerformanceEvent = function setInteractionPerformanceEvent(entry) {
91
98
  var interaction = (0, _interactionMetrics.getActiveInteraction)();
92
99
  if ((interaction === null || interaction === void 0 ? void 0 : interaction.type) === 'press') {
93
- var _interaction$responsi, _interaction$responsi2;
94
- // if happens there is another event interaction that has started after
95
- // the initial one, we don't want to replace the values if they have already been set up
96
- interaction.responsiveness = _objectSpread(_objectSpread({}, interaction.responsiveness), {}, {
97
- experimentalInputToNextPaint: ((_interaction$responsi = interaction.responsiveness) === null || _interaction$responsi === void 0 ? void 0 : _interaction$responsi.experimentalInputToNextPaint) || entry.duration,
98
- inputDelay: ((_interaction$responsi2 = interaction.responsiveness) === null || _interaction$responsi2 === void 0 ? void 0 : _interaction$responsi2.inputDelay) || entry.processingStart - entry.startTime
99
- });
100
- // if the entry start time is lower than the one in the interaction
101
- // it means the interaction start time is not accurate, we assign
102
- // this value which will match the timestamp in the event
103
- interaction.start = Math.min(interaction.start, entry.startTime);
104
- if (interaction.ufoName === 'unknown' && (0, _platformFeatureFlags.fg)('platform_ufo_enable_unknown_interactions_elements')) {
105
- if (entry.target) {
106
- var componentHierarchy = getReactComponentHierarchy(entry.target);
107
- interaction.unknownElementHierarchy = componentHierarchy;
100
+ var _interaction$responsi;
101
+ if (!((_interaction$responsi = interaction.responsiveness) !== null && _interaction$responsi !== void 0 && _interaction$responsi.experimentalInputToNextPaint)) {
102
+ var _interaction$responsi2, _interaction$responsi3;
103
+ interaction.responsiveness = _objectSpread(_objectSpread({}, interaction.responsiveness), {}, {
104
+ experimentalInputToNextPaint: ((_interaction$responsi2 = interaction.responsiveness) === null || _interaction$responsi2 === void 0 ? void 0 : _interaction$responsi2.experimentalInputToNextPaint) || entry.duration,
105
+ inputDelay: ((_interaction$responsi3 = interaction.responsiveness) === null || _interaction$responsi3 === void 0 ? void 0 : _interaction$responsi3.inputDelay) || entry.processingStart - entry.startTime
106
+ });
107
+ if (interaction.ufoName === 'unknown' && (0, _platformFeatureFlags.fg)('platform_ufo_enable_unknown_interactions_elements')) {
108
+ if (entry.target) {
109
+ var componentHierarchy = getReactComponentHierarchy(entry.target);
110
+ interaction.unknownElementHierarchy = componentHierarchy;
111
+ }
112
+ interaction.unknownElementName = (0, _getUniqueElementName.default)(selectorConfig, entry.target);
108
113
  }
109
- interaction.unknownElementName = (0, _getUniqueElementName.default)(selectorConfig, entry.target);
110
114
  }
111
115
  }
112
116
  };
@@ -4,46 +4,24 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.default = void 0;
8
- var _uuid = require("uuid");
9
- var _coinflip = _interopRequireDefault(require("../coinflip"));
10
- var _config = require("../config");
11
- var _interactionIdContext = require("../interaction-id-context");
12
- var _interactionMetrics = require("../interaction-metrics");
13
- var _routeNameContext = _interopRequireDefault(require("../route-name-context"));
14
- function mapToInteractionType(eventType) {
15
- if (eventType === 'click' || eventType === 'dblclick' || eventType === 'mousedown') {
16
- return 'press';
17
- }
18
- if (eventType === 'mouseenter' || eventType === 'mouseover') {
19
- return 'hover';
7
+ Object.defineProperty(exports, "UNSAFE__DO_NOT_USE_traceUFOInteraction", {
8
+ enumerable: true,
9
+ get: function get() {
10
+ return _traceUfoInteraction.default;
20
11
  }
21
- return undefined;
22
- }
12
+ });
13
+ exports.default = void 0;
14
+ var _mapToInteractionType = _interopRequireDefault(require("./internal/map-to-interaction-type"));
15
+ var _traceUfoInteraction = _interopRequireDefault(require("./internal/trace-ufo-interaction"));
23
16
  function traceUFOInteraction(name, event) {
24
17
  if (!event || !event.isTrusted) {
25
18
  return;
26
19
  }
27
- var interactionType = mapToInteractionType(event.type);
20
+ var interactionType = (0, _mapToInteractionType.default)(event.type);
28
21
  if (!interactionType) {
29
22
  // when interactionType is falsy we do not yet support this type of event. should we blow up with throwing error instead?
30
23
  return;
31
24
  }
32
- var rate = (0, _config.getInteractionRate)(name, interactionType);
33
- var pressInteractionsList = (0, _config.getDoNotAbortActivePressInteraction)();
34
- if (pressInteractionsList !== null && pressInteractionsList !== void 0 && pressInteractionsList.includes(name)) {
35
- var interaction = (0, _interactionMetrics.getActiveInteraction)();
36
- if ((interaction === null || interaction === void 0 ? void 0 : interaction.ufoName) !== 'unknown' && (interaction === null || interaction === void 0 ? void 0 : interaction.type) === 'press') {
37
- return;
38
- }
39
- }
40
- if ((0, _coinflip.default)(rate)) {
41
- var _event$timeStamp;
42
- (0, _interactionMetrics.abortAll)('new_interaction', name);
43
- var startTimestamp = (_event$timeStamp = event.timeStamp) !== null && _event$timeStamp !== void 0 ? _event$timeStamp : performance.now();
44
- var newId = (0, _uuid.v4)();
45
- _interactionIdContext.DefaultInteractionID.current = newId;
46
- (0, _interactionMetrics.addNewInteraction)(newId, name, 'press', startTimestamp, rate, [], _routeNameContext.default.current);
47
- }
25
+ return (0, _traceUfoInteraction.default)(name, interactionType, event.timeStamp);
48
26
  }
49
27
  var _default = exports.default = traceUFOInteraction;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ function mapToInteractionType(eventType) {
8
+ if (eventType === 'click' || eventType === 'dblclick' || eventType === 'mousedown') {
9
+ return 'press';
10
+ }
11
+ if (eventType === 'mouseenter' || eventType === 'mouseover') {
12
+ return 'hover';
13
+ }
14
+ return undefined;
15
+ }
16
+ var _default = exports.default = mapToInteractionType;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _uuid = require("uuid");
9
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
10
+ var _coinflip = _interopRequireDefault(require("../../coinflip"));
11
+ var _config = require("../../config");
12
+ var _experienceTraceIdContext = require("../../experience-trace-id-context");
13
+ var _interactionIdContext = require("../../interaction-id-context");
14
+ var _interactionMetrics = require("../../interaction-metrics");
15
+ var _routeNameContext = _interopRequireDefault(require("../../route-name-context"));
16
+ function traceUFOInteraction(name, interactionType, startTime) {
17
+ var rate = (0, _config.getInteractionRate)(name, interactionType);
18
+ var pressInteractionsList = (0, _config.getDoNotAbortActivePressInteraction)();
19
+ if (pressInteractionsList !== null && pressInteractionsList !== void 0 && pressInteractionsList.includes(name)) {
20
+ var interaction = (0, _interactionMetrics.getActiveInteraction)();
21
+ if ((interaction === null || interaction === void 0 ? void 0 : interaction.ufoName) !== 'unknown' && (interaction === null || interaction === void 0 ? void 0 : interaction.type) === 'press') {
22
+ return;
23
+ }
24
+ } else {
25
+ if ((0, _platformFeatureFlags.fg)('platform_ufo_abort_measurement_fix')) {
26
+ // abort any existing interaction regardless if the next interaction's coinflip returns true or false
27
+ (0, _interactionMetrics.abortAll)('new_interaction', name);
28
+ }
29
+ }
30
+ if ((0, _coinflip.default)(rate)) {
31
+ if (!(0, _platformFeatureFlags.fg)('platform_ufo_abort_measurement_fix')) {
32
+ (0, _interactionMetrics.abortAll)('new_interaction', name);
33
+ }
34
+ var startTimestamp = startTime !== null && startTime !== void 0 ? startTime : performance.now();
35
+ var newId = (0, _uuid.v4)();
36
+ _interactionIdContext.DefaultInteractionID.current = newId;
37
+
38
+ // covered experiences with tracing instrumentation:
39
+ // inline-result.inline-card-create-submit
40
+ (0, _experienceTraceIdContext.setInteractionActiveTrace)(newId, interactionType);
41
+ (0, _interactionMetrics.addNewInteraction)(newId, name, interactionType === 'hover' ? 'press' : interactionType,
42
+ // TODO add dedicated type for hover, might change backend though
43
+ startTimestamp, rate, [], _routeNameContext.default.current, (0, _experienceTraceIdContext.getActiveTrace)());
44
+ }
45
+ }
46
+ var _default = exports.default = traceUFOInteraction;
@@ -5,31 +5,8 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.default = void 0;
8
- var _uuid = require("uuid");
9
- var _coinflip = _interopRequireDefault(require("../coinflip"));
10
- var _config = require("../config");
11
- var _experienceTraceIdContext = require("../experience-trace-id-context");
12
- var _interactionIdContext = require("../interaction-id-context");
13
- var _interactionMetrics = require("../interaction-metrics");
14
- var _routeNameContext = _interopRequireDefault(require("../route-name-context"));
8
+ var _traceUfoInteraction = _interopRequireDefault(require("../trace-interaction/internal/trace-ufo-interaction"));
15
9
  function traceUFOPress(name, timestamp) {
16
- var rate = (0, _config.getInteractionRate)(name, 'press');
17
- var pressInteractionsList = (0, _config.getDoNotAbortActivePressInteraction)();
18
- if (pressInteractionsList !== null && pressInteractionsList !== void 0 && pressInteractionsList.includes(name)) {
19
- var interaction = (0, _interactionMetrics.getActiveInteraction)();
20
- if ((interaction === null || interaction === void 0 ? void 0 : interaction.ufoName) !== 'unknown' && (interaction === null || interaction === void 0 ? void 0 : interaction.type) === 'press') {
21
- return;
22
- }
23
- }
24
- if ((0, _coinflip.default)(rate)) {
25
- (0, _interactionMetrics.abortAll)('new_interaction', name);
26
- var startTimestamp = timestamp !== null && timestamp !== void 0 ? timestamp : performance.now();
27
- var newId = (0, _uuid.v4)();
28
- // covered experiences with tracing instrumentation:
29
- // inline-result.inline-card-create-submit
30
- (0, _experienceTraceIdContext.setInteractionActiveTrace)(newId, 'press');
31
- _interactionIdContext.DefaultInteractionID.current = newId;
32
- (0, _interactionMetrics.addNewInteraction)(newId, name, 'press', startTimestamp, rate, [], _routeNameContext.default.current, (0, _experienceTraceIdContext.getActiveTrace)());
33
- }
10
+ return (0, _traceUfoInteraction.default)(name, 'press', timestamp);
34
11
  }
35
12
  var _default = exports.default = traceUFOPress;
@@ -16,6 +16,12 @@ function getTestIdName(memoizedProps) {
16
16
  }
17
17
  return null;
18
18
  }
19
+ function getUFOSegmentName(componentName, memoizedProps) {
20
+ if (memoizedProps && memoizedProps['name']) {
21
+ return `UFOSegment[name=${memoizedProps['name']}]`;
22
+ }
23
+ return componentName;
24
+ }
19
25
  function getReactComponentHierarchy(element) {
20
26
  const componentHierarchy = [];
21
27
  // Function to traverse up the fiber tree
@@ -27,11 +33,12 @@ function getReactComponentHierarchy(element) {
27
33
  const componentName = currentFiber.type.displayName || currentFiber.type.name;
28
34
  // checking when component name is bigger than the minimized name produced by react
29
35
  if (componentName && componentName.length > 2 && !componentName.includes('Listener') && !componentName.includes('Provider')) {
36
+ if (componentName === 'UFOSegment') {
37
+ componentHierarchy.push(getUFOSegmentName(componentName, currentFiber.memoizedProps));
38
+ break;
39
+ }
30
40
  componentHierarchy.push(componentName);
31
41
  }
32
- if (componentName === 'UFOSegment') {
33
- break;
34
- }
35
42
  }
36
43
  if (currentFiber.memoizedProps) {
37
44
  const dataIdInfo = getTestIdName(currentFiber.memoizedProps);
@@ -66,24 +73,21 @@ export const getPerformanceObserver = () => {
66
73
  export const setInteractionPerformanceEvent = entry => {
67
74
  const interaction = getActiveInteraction();
68
75
  if ((interaction === null || interaction === void 0 ? void 0 : interaction.type) === 'press') {
69
- var _interaction$responsi, _interaction$responsi2;
70
- // if happens there is another event interaction that has started after
71
- // the initial one, we don't want to replace the values if they have already been set up
72
- interaction.responsiveness = {
73
- ...interaction.responsiveness,
74
- experimentalInputToNextPaint: ((_interaction$responsi = interaction.responsiveness) === null || _interaction$responsi === void 0 ? void 0 : _interaction$responsi.experimentalInputToNextPaint) || entry.duration,
75
- inputDelay: ((_interaction$responsi2 = interaction.responsiveness) === null || _interaction$responsi2 === void 0 ? void 0 : _interaction$responsi2.inputDelay) || entry.processingStart - entry.startTime
76
- };
77
- // if the entry start time is lower than the one in the interaction
78
- // it means the interaction start time is not accurate, we assign
79
- // this value which will match the timestamp in the event
80
- interaction.start = Math.min(interaction.start, entry.startTime);
81
- if (interaction.ufoName === 'unknown' && fg('platform_ufo_enable_unknown_interactions_elements')) {
82
- if (entry.target) {
83
- const componentHierarchy = getReactComponentHierarchy(entry.target);
84
- interaction.unknownElementHierarchy = componentHierarchy;
76
+ var _interaction$responsi;
77
+ if (!((_interaction$responsi = interaction.responsiveness) !== null && _interaction$responsi !== void 0 && _interaction$responsi.experimentalInputToNextPaint)) {
78
+ var _interaction$responsi2, _interaction$responsi3;
79
+ interaction.responsiveness = {
80
+ ...interaction.responsiveness,
81
+ experimentalInputToNextPaint: ((_interaction$responsi2 = interaction.responsiveness) === null || _interaction$responsi2 === void 0 ? void 0 : _interaction$responsi2.experimentalInputToNextPaint) || entry.duration,
82
+ inputDelay: ((_interaction$responsi3 = interaction.responsiveness) === null || _interaction$responsi3 === void 0 ? void 0 : _interaction$responsi3.inputDelay) || entry.processingStart - entry.startTime
83
+ };
84
+ if (interaction.ufoName === 'unknown' && fg('platform_ufo_enable_unknown_interactions_elements')) {
85
+ if (entry.target) {
86
+ const componentHierarchy = getReactComponentHierarchy(entry.target);
87
+ interaction.unknownElementHierarchy = componentHierarchy;
88
+ }
89
+ interaction.unknownElementName = getElementName(selectorConfig, entry.target);
85
90
  }
86
- interaction.unknownElementName = getElementName(selectorConfig, entry.target);
87
91
  }
88
92
  }
89
93
  };
@@ -1,18 +1,6 @@
1
- import { v4 as createUUID } from 'uuid';
2
- import coinflip from '../coinflip';
3
- import { getDoNotAbortActivePressInteraction, getInteractionRate } from '../config';
4
- import { DefaultInteractionID } from '../interaction-id-context';
5
- import { abortAll, addNewInteraction, getActiveInteraction } from '../interaction-metrics';
6
- import UFORouteName from '../route-name-context';
7
- function mapToInteractionType(eventType) {
8
- if (eventType === 'click' || eventType === 'dblclick' || eventType === 'mousedown') {
9
- return 'press';
10
- }
11
- if (eventType === 'mouseenter' || eventType === 'mouseover') {
12
- return 'hover';
13
- }
14
- return undefined;
15
- }
1
+ import mapToInteractionType from './internal/map-to-interaction-type';
2
+ import internal_traceUFOInteraction from './internal/trace-ufo-interaction';
3
+ export { default as UNSAFE__DO_NOT_USE_traceUFOInteraction } from './internal/trace-ufo-interaction';
16
4
  function traceUFOInteraction(name, event) {
17
5
  if (!event || !event.isTrusted) {
18
6
  return;
@@ -22,21 +10,6 @@ function traceUFOInteraction(name, event) {
22
10
  // when interactionType is falsy we do not yet support this type of event. should we blow up with throwing error instead?
23
11
  return;
24
12
  }
25
- const rate = getInteractionRate(name, interactionType);
26
- const pressInteractionsList = getDoNotAbortActivePressInteraction();
27
- if (pressInteractionsList !== null && pressInteractionsList !== void 0 && pressInteractionsList.includes(name)) {
28
- const interaction = getActiveInteraction();
29
- if ((interaction === null || interaction === void 0 ? void 0 : interaction.ufoName) !== 'unknown' && (interaction === null || interaction === void 0 ? void 0 : interaction.type) === 'press') {
30
- return;
31
- }
32
- }
33
- if (coinflip(rate)) {
34
- var _event$timeStamp;
35
- abortAll('new_interaction', name);
36
- const startTimestamp = (_event$timeStamp = event.timeStamp) !== null && _event$timeStamp !== void 0 ? _event$timeStamp : performance.now();
37
- const newId = createUUID();
38
- DefaultInteractionID.current = newId;
39
- addNewInteraction(newId, name, 'press', startTimestamp, rate, [], UFORouteName.current);
40
- }
13
+ return internal_traceUFOInteraction(name, interactionType, event.timeStamp);
41
14
  }
42
15
  export default traceUFOInteraction;
@@ -0,0 +1,10 @@
1
+ function mapToInteractionType(eventType) {
2
+ if (eventType === 'click' || eventType === 'dblclick' || eventType === 'mousedown') {
3
+ return 'press';
4
+ }
5
+ if (eventType === 'mouseenter' || eventType === 'mouseover') {
6
+ return 'hover';
7
+ }
8
+ return undefined;
9
+ }
10
+ export default mapToInteractionType;
@@ -0,0 +1,39 @@
1
+ import { v4 as createUUID } from 'uuid';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
3
+ import coinflip from '../../coinflip';
4
+ import { getDoNotAbortActivePressInteraction, getInteractionRate } from '../../config';
5
+ import { getActiveTrace, setInteractionActiveTrace } from '../../experience-trace-id-context';
6
+ import { DefaultInteractionID } from '../../interaction-id-context';
7
+ import { abortAll, addNewInteraction, getActiveInteraction } from '../../interaction-metrics';
8
+ import UFORouteName from '../../route-name-context';
9
+ function traceUFOInteraction(name, interactionType, startTime) {
10
+ const rate = getInteractionRate(name, interactionType);
11
+ const pressInteractionsList = getDoNotAbortActivePressInteraction();
12
+ if (pressInteractionsList !== null && pressInteractionsList !== void 0 && pressInteractionsList.includes(name)) {
13
+ const interaction = getActiveInteraction();
14
+ if ((interaction === null || interaction === void 0 ? void 0 : interaction.ufoName) !== 'unknown' && (interaction === null || interaction === void 0 ? void 0 : interaction.type) === 'press') {
15
+ return;
16
+ }
17
+ } else {
18
+ if (fg('platform_ufo_abort_measurement_fix')) {
19
+ // abort any existing interaction regardless if the next interaction's coinflip returns true or false
20
+ abortAll('new_interaction', name);
21
+ }
22
+ }
23
+ if (coinflip(rate)) {
24
+ if (!fg('platform_ufo_abort_measurement_fix')) {
25
+ abortAll('new_interaction', name);
26
+ }
27
+ const startTimestamp = startTime !== null && startTime !== void 0 ? startTime : performance.now();
28
+ const newId = createUUID();
29
+ DefaultInteractionID.current = newId;
30
+
31
+ // covered experiences with tracing instrumentation:
32
+ // inline-result.inline-card-create-submit
33
+ setInteractionActiveTrace(newId, interactionType);
34
+ addNewInteraction(newId, name, interactionType === 'hover' ? 'press' : interactionType,
35
+ // TODO add dedicated type for hover, might change backend though
36
+ startTimestamp, rate, [], UFORouteName.current, getActiveTrace());
37
+ }
38
+ }
39
+ export default traceUFOInteraction;
@@ -1,28 +1,5 @@
1
- import { v4 as createUUID } from 'uuid';
2
- import coinflip from '../coinflip';
3
- import { getDoNotAbortActivePressInteraction, getInteractionRate } from '../config';
4
- import { getActiveTrace, setInteractionActiveTrace } from '../experience-trace-id-context';
5
- import { DefaultInteractionID } from '../interaction-id-context';
6
- import { abortAll, addNewInteraction, getActiveInteraction } from '../interaction-metrics';
7
- import UFORouteName from '../route-name-context';
1
+ import { default as internal_traceUFOInteraction } from '../trace-interaction/internal/trace-ufo-interaction';
8
2
  function traceUFOPress(name, timestamp) {
9
- const rate = getInteractionRate(name, 'press');
10
- const pressInteractionsList = getDoNotAbortActivePressInteraction();
11
- if (pressInteractionsList !== null && pressInteractionsList !== void 0 && pressInteractionsList.includes(name)) {
12
- const interaction = getActiveInteraction();
13
- if ((interaction === null || interaction === void 0 ? void 0 : interaction.ufoName) !== 'unknown' && (interaction === null || interaction === void 0 ? void 0 : interaction.type) === 'press') {
14
- return;
15
- }
16
- }
17
- if (coinflip(rate)) {
18
- abortAll('new_interaction', name);
19
- const startTimestamp = timestamp !== null && timestamp !== void 0 ? timestamp : performance.now();
20
- const newId = createUUID();
21
- // covered experiences with tracing instrumentation:
22
- // inline-result.inline-card-create-submit
23
- setInteractionActiveTrace(newId, 'press');
24
- DefaultInteractionID.current = newId;
25
- addNewInteraction(newId, name, 'press', startTimestamp, rate, [], UFORouteName.current, getActiveTrace());
26
- }
3
+ return internal_traceUFOInteraction(name, 'press', timestamp);
27
4
  }
28
5
  export default traceUFOPress;
@@ -22,6 +22,12 @@ function getTestIdName(memoizedProps) {
22
22
  }
23
23
  return null;
24
24
  }
25
+ function getUFOSegmentName(componentName, memoizedProps) {
26
+ if (memoizedProps && memoizedProps['name']) {
27
+ return "UFOSegment[name=".concat(memoizedProps['name'], "]");
28
+ }
29
+ return componentName;
30
+ }
25
31
  function getReactComponentHierarchy(element) {
26
32
  var componentHierarchy = [];
27
33
  // Function to traverse up the fiber tree
@@ -33,11 +39,12 @@ function getReactComponentHierarchy(element) {
33
39
  var componentName = currentFiber.type.displayName || currentFiber.type.name;
34
40
  // checking when component name is bigger than the minimized name produced by react
35
41
  if (componentName && componentName.length > 2 && !componentName.includes('Listener') && !componentName.includes('Provider')) {
42
+ if (componentName === 'UFOSegment') {
43
+ componentHierarchy.push(getUFOSegmentName(componentName, currentFiber.memoizedProps));
44
+ break;
45
+ }
36
46
  componentHierarchy.push(componentName);
37
47
  }
38
- if (componentName === 'UFOSegment') {
39
- break;
40
- }
41
48
  }
42
49
  if (currentFiber.memoizedProps) {
43
50
  var dataIdInfo = getTestIdName(currentFiber.memoizedProps);
@@ -83,23 +90,20 @@ export var getPerformanceObserver = function getPerformanceObserver() {
83
90
  export var setInteractionPerformanceEvent = function setInteractionPerformanceEvent(entry) {
84
91
  var interaction = getActiveInteraction();
85
92
  if ((interaction === null || interaction === void 0 ? void 0 : interaction.type) === 'press') {
86
- var _interaction$responsi, _interaction$responsi2;
87
- // if happens there is another event interaction that has started after
88
- // the initial one, we don't want to replace the values if they have already been set up
89
- interaction.responsiveness = _objectSpread(_objectSpread({}, interaction.responsiveness), {}, {
90
- experimentalInputToNextPaint: ((_interaction$responsi = interaction.responsiveness) === null || _interaction$responsi === void 0 ? void 0 : _interaction$responsi.experimentalInputToNextPaint) || entry.duration,
91
- inputDelay: ((_interaction$responsi2 = interaction.responsiveness) === null || _interaction$responsi2 === void 0 ? void 0 : _interaction$responsi2.inputDelay) || entry.processingStart - entry.startTime
92
- });
93
- // if the entry start time is lower than the one in the interaction
94
- // it means the interaction start time is not accurate, we assign
95
- // this value which will match the timestamp in the event
96
- interaction.start = Math.min(interaction.start, entry.startTime);
97
- if (interaction.ufoName === 'unknown' && fg('platform_ufo_enable_unknown_interactions_elements')) {
98
- if (entry.target) {
99
- var componentHierarchy = getReactComponentHierarchy(entry.target);
100
- interaction.unknownElementHierarchy = componentHierarchy;
93
+ var _interaction$responsi;
94
+ if (!((_interaction$responsi = interaction.responsiveness) !== null && _interaction$responsi !== void 0 && _interaction$responsi.experimentalInputToNextPaint)) {
95
+ var _interaction$responsi2, _interaction$responsi3;
96
+ interaction.responsiveness = _objectSpread(_objectSpread({}, interaction.responsiveness), {}, {
97
+ experimentalInputToNextPaint: ((_interaction$responsi2 = interaction.responsiveness) === null || _interaction$responsi2 === void 0 ? void 0 : _interaction$responsi2.experimentalInputToNextPaint) || entry.duration,
98
+ inputDelay: ((_interaction$responsi3 = interaction.responsiveness) === null || _interaction$responsi3 === void 0 ? void 0 : _interaction$responsi3.inputDelay) || entry.processingStart - entry.startTime
99
+ });
100
+ if (interaction.ufoName === 'unknown' && fg('platform_ufo_enable_unknown_interactions_elements')) {
101
+ if (entry.target) {
102
+ var componentHierarchy = getReactComponentHierarchy(entry.target);
103
+ interaction.unknownElementHierarchy = componentHierarchy;
104
+ }
105
+ interaction.unknownElementName = getElementName(selectorConfig, entry.target);
101
106
  }
102
- interaction.unknownElementName = getElementName(selectorConfig, entry.target);
103
107
  }
104
108
  }
105
109
  };
@@ -1,18 +1,6 @@
1
- import { v4 as createUUID } from 'uuid';
2
- import coinflip from '../coinflip';
3
- import { getDoNotAbortActivePressInteraction, getInteractionRate } from '../config';
4
- import { DefaultInteractionID } from '../interaction-id-context';
5
- import { abortAll, addNewInteraction, getActiveInteraction } from '../interaction-metrics';
6
- import UFORouteName from '../route-name-context';
7
- function mapToInteractionType(eventType) {
8
- if (eventType === 'click' || eventType === 'dblclick' || eventType === 'mousedown') {
9
- return 'press';
10
- }
11
- if (eventType === 'mouseenter' || eventType === 'mouseover') {
12
- return 'hover';
13
- }
14
- return undefined;
15
- }
1
+ import mapToInteractionType from './internal/map-to-interaction-type';
2
+ import internal_traceUFOInteraction from './internal/trace-ufo-interaction';
3
+ export { default as UNSAFE__DO_NOT_USE_traceUFOInteraction } from './internal/trace-ufo-interaction';
16
4
  function traceUFOInteraction(name, event) {
17
5
  if (!event || !event.isTrusted) {
18
6
  return;
@@ -22,21 +10,6 @@ function traceUFOInteraction(name, event) {
22
10
  // when interactionType is falsy we do not yet support this type of event. should we blow up with throwing error instead?
23
11
  return;
24
12
  }
25
- var rate = getInteractionRate(name, interactionType);
26
- var pressInteractionsList = getDoNotAbortActivePressInteraction();
27
- if (pressInteractionsList !== null && pressInteractionsList !== void 0 && pressInteractionsList.includes(name)) {
28
- var interaction = getActiveInteraction();
29
- if ((interaction === null || interaction === void 0 ? void 0 : interaction.ufoName) !== 'unknown' && (interaction === null || interaction === void 0 ? void 0 : interaction.type) === 'press') {
30
- return;
31
- }
32
- }
33
- if (coinflip(rate)) {
34
- var _event$timeStamp;
35
- abortAll('new_interaction', name);
36
- var startTimestamp = (_event$timeStamp = event.timeStamp) !== null && _event$timeStamp !== void 0 ? _event$timeStamp : performance.now();
37
- var newId = createUUID();
38
- DefaultInteractionID.current = newId;
39
- addNewInteraction(newId, name, 'press', startTimestamp, rate, [], UFORouteName.current);
40
- }
13
+ return internal_traceUFOInteraction(name, interactionType, event.timeStamp);
41
14
  }
42
15
  export default traceUFOInteraction;
@@ -0,0 +1,10 @@
1
+ function mapToInteractionType(eventType) {
2
+ if (eventType === 'click' || eventType === 'dblclick' || eventType === 'mousedown') {
3
+ return 'press';
4
+ }
5
+ if (eventType === 'mouseenter' || eventType === 'mouseover') {
6
+ return 'hover';
7
+ }
8
+ return undefined;
9
+ }
10
+ export default mapToInteractionType;
@@ -0,0 +1,39 @@
1
+ import { v4 as createUUID } from 'uuid';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
3
+ import coinflip from '../../coinflip';
4
+ import { getDoNotAbortActivePressInteraction, getInteractionRate } from '../../config';
5
+ import { getActiveTrace, setInteractionActiveTrace } from '../../experience-trace-id-context';
6
+ import { DefaultInteractionID } from '../../interaction-id-context';
7
+ import { abortAll, addNewInteraction, getActiveInteraction } from '../../interaction-metrics';
8
+ import UFORouteName from '../../route-name-context';
9
+ function traceUFOInteraction(name, interactionType, startTime) {
10
+ var rate = getInteractionRate(name, interactionType);
11
+ var pressInteractionsList = getDoNotAbortActivePressInteraction();
12
+ if (pressInteractionsList !== null && pressInteractionsList !== void 0 && pressInteractionsList.includes(name)) {
13
+ var interaction = getActiveInteraction();
14
+ if ((interaction === null || interaction === void 0 ? void 0 : interaction.ufoName) !== 'unknown' && (interaction === null || interaction === void 0 ? void 0 : interaction.type) === 'press') {
15
+ return;
16
+ }
17
+ } else {
18
+ if (fg('platform_ufo_abort_measurement_fix')) {
19
+ // abort any existing interaction regardless if the next interaction's coinflip returns true or false
20
+ abortAll('new_interaction', name);
21
+ }
22
+ }
23
+ if (coinflip(rate)) {
24
+ if (!fg('platform_ufo_abort_measurement_fix')) {
25
+ abortAll('new_interaction', name);
26
+ }
27
+ var startTimestamp = startTime !== null && startTime !== void 0 ? startTime : performance.now();
28
+ var newId = createUUID();
29
+ DefaultInteractionID.current = newId;
30
+
31
+ // covered experiences with tracing instrumentation:
32
+ // inline-result.inline-card-create-submit
33
+ setInteractionActiveTrace(newId, interactionType);
34
+ addNewInteraction(newId, name, interactionType === 'hover' ? 'press' : interactionType,
35
+ // TODO add dedicated type for hover, might change backend though
36
+ startTimestamp, rate, [], UFORouteName.current, getActiveTrace());
37
+ }
38
+ }
39
+ export default traceUFOInteraction;
@@ -1,28 +1,5 @@
1
- import { v4 as createUUID } from 'uuid';
2
- import coinflip from '../coinflip';
3
- import { getDoNotAbortActivePressInteraction, getInteractionRate } from '../config';
4
- import { getActiveTrace, setInteractionActiveTrace } from '../experience-trace-id-context';
5
- import { DefaultInteractionID } from '../interaction-id-context';
6
- import { abortAll, addNewInteraction, getActiveInteraction } from '../interaction-metrics';
7
- import UFORouteName from '../route-name-context';
1
+ import { default as internal_traceUFOInteraction } from '../trace-interaction/internal/trace-ufo-interaction';
8
2
  function traceUFOPress(name, timestamp) {
9
- var rate = getInteractionRate(name, 'press');
10
- var pressInteractionsList = getDoNotAbortActivePressInteraction();
11
- if (pressInteractionsList !== null && pressInteractionsList !== void 0 && pressInteractionsList.includes(name)) {
12
- var interaction = getActiveInteraction();
13
- if ((interaction === null || interaction === void 0 ? void 0 : interaction.ufoName) !== 'unknown' && (interaction === null || interaction === void 0 ? void 0 : interaction.type) === 'press') {
14
- return;
15
- }
16
- }
17
- if (coinflip(rate)) {
18
- abortAll('new_interaction', name);
19
- var startTimestamp = timestamp !== null && timestamp !== void 0 ? timestamp : performance.now();
20
- var newId = createUUID();
21
- // covered experiences with tracing instrumentation:
22
- // inline-result.inline-card-create-submit
23
- setInteractionActiveTrace(newId, 'press');
24
- DefaultInteractionID.current = newId;
25
- addNewInteraction(newId, name, 'press', startTimestamp, rate, [], UFORouteName.current, getActiveTrace());
26
- }
3
+ return internal_traceUFOInteraction(name, 'press', timestamp);
27
4
  }
28
5
  export default traceUFOPress;
@@ -1,3 +1,4 @@
1
1
  import type { UIEvent } from 'react';
2
+ export { default as UNSAFE__DO_NOT_USE_traceUFOInteraction } from './internal/trace-ufo-interaction';
2
3
  declare function traceUFOInteraction(name: string, event: UIEvent): void;
3
4
  export default traceUFOInteraction;
@@ -0,0 +1,2 @@
1
+ declare function mapToInteractionType(eventType: string): "press" | "hover" | undefined;
2
+ export default mapToInteractionType;
@@ -0,0 +1,3 @@
1
+ type InteractionType = 'press' | 'typing' | 'hover';
2
+ declare function traceUFOInteraction(name: string, interactionType: InteractionType, startTime?: DOMHighResTimeStamp): void;
3
+ export default traceUFOInteraction;
@@ -1,3 +1,4 @@
1
1
  import type { UIEvent } from 'react';
2
+ export { default as UNSAFE__DO_NOT_USE_traceUFOInteraction } from './internal/trace-ufo-interaction';
2
3
  declare function traceUFOInteraction(name: string, event: UIEvent): void;
3
4
  export default traceUFOInteraction;
@@ -0,0 +1,2 @@
1
+ declare function mapToInteractionType(eventType: string): "press" | "hover" | undefined;
2
+ export default mapToInteractionType;
@@ -0,0 +1,3 @@
1
+ type InteractionType = 'press' | 'typing' | 'hover';
2
+ declare function traceUFOInteraction(name: string, interactionType: InteractionType, startTime?: DOMHighResTimeStamp): void;
3
+ export default traceUFOInteraction;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/react-ufo",
3
- "version": "3.14.8",
3
+ "version": "3.14.10",
4
4
  "description": "Parts of React UFO that are publicly available",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -213,6 +213,9 @@
213
213
  },
214
214
  "platform_ufo_enable_vc_observer_per_interaction": {
215
215
  "type": "boolean"
216
+ },
217
+ "platform_ufo_abort_measurement_fix": {
218
+ "type": "boolean"
216
219
  }
217
220
  }
218
221
  }