@atlaskit/react-ufo 3.14.7 → 3.14.9
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.
- package/CHANGELOG.md +16 -0
- package/dist/cjs/create-experimental-interaction-metrics-payload/index.js +14 -12
- package/dist/cjs/create-payload/utils/get-vc-metrics.js +17 -13
- package/dist/cjs/interaction-metrics/index.js +35 -15
- package/dist/cjs/interaction-metrics-init/index.js +5 -3
- package/dist/cjs/trace-interaction/index.js +10 -32
- package/dist/cjs/trace-interaction/internal/map-to-interaction-type.js +16 -0
- package/dist/cjs/trace-interaction/internal/trace-ufo-interaction.js +46 -0
- package/dist/cjs/trace-press/index.js +2 -25
- package/dist/cjs/vc/index.js +7 -0
- package/dist/es2019/create-experimental-interaction-metrics-payload/index.js +4 -2
- package/dist/es2019/create-payload/utils/get-vc-metrics.js +10 -4
- package/dist/es2019/interaction-metrics/index.js +36 -16
- package/dist/es2019/interaction-metrics-init/index.js +5 -3
- package/dist/es2019/trace-interaction/index.js +4 -31
- package/dist/es2019/trace-interaction/internal/map-to-interaction-type.js +10 -0
- package/dist/es2019/trace-interaction/internal/trace-ufo-interaction.js +39 -0
- package/dist/es2019/trace-press/index.js +2 -25
- package/dist/es2019/vc/index.js +5 -0
- package/dist/esm/create-experimental-interaction-metrics-payload/index.js +14 -12
- package/dist/esm/create-payload/utils/get-vc-metrics.js +17 -13
- package/dist/esm/interaction-metrics/index.js +36 -16
- package/dist/esm/interaction-metrics-init/index.js +5 -3
- package/dist/esm/trace-interaction/index.js +4 -31
- package/dist/esm/trace-interaction/internal/map-to-interaction-type.js +10 -0
- package/dist/esm/trace-interaction/internal/trace-ufo-interaction.js +39 -0
- package/dist/esm/trace-press/index.js +2 -25
- package/dist/esm/vc/index.js +6 -0
- package/dist/types/common/common/types.d.ts +4 -1
- package/dist/types/trace-interaction/index.d.ts +1 -0
- package/dist/types/trace-interaction/internal/map-to-interaction-type.d.ts +2 -0
- package/dist/types/trace-interaction/internal/trace-ufo-interaction.d.ts +3 -0
- package/dist/types/vc/index.d.ts +1 -0
- package/dist/types-ts4.5/common/common/types.d.ts +4 -1
- package/dist/types-ts4.5/trace-interaction/index.d.ts +1 -0
- package/dist/types-ts4.5/trace-interaction/internal/map-to-interaction-type.d.ts +2 -0
- package/dist/types-ts4.5/trace-interaction/internal/trace-ufo-interaction.d.ts +3 -0
- package/dist/types-ts4.5/vc/index.d.ts +1 -0
- package/package.json +10 -4
|
@@ -1,18 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
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
|
-
|
|
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 {
|
|
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
|
-
|
|
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;
|
package/dist/es2019/vc/index.js
CHANGED
|
@@ -165,4 +165,9 @@ export function getVCObserver(opts = {}) {
|
|
|
165
165
|
globalThis.__vcObserver = shouldMockVCObserver ? new VCObserverNOOP() : new VCObserverWrapper(opts);
|
|
166
166
|
}
|
|
167
167
|
return globalThis.__vcObserver;
|
|
168
|
+
}
|
|
169
|
+
export function newVCObserver(opts = {}) {
|
|
170
|
+
const shouldMockVCObserver = !isEnvironmentSupported();
|
|
171
|
+
const observer = shouldMockVCObserver ? new VCObserverNOOP() : new VCObserverWrapper(opts);
|
|
172
|
+
return observer;
|
|
168
173
|
}
|
|
@@ -84,17 +84,19 @@ export function getExperimentalVCMetrics(_x) {
|
|
|
84
84
|
}
|
|
85
85
|
function _getExperimentalVCMetrics() {
|
|
86
86
|
_getExperimentalVCMetrics = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(interaction) {
|
|
87
|
-
var _interaction$apdex, prefix, result, VC, pageVisibilityUpToTTAI;
|
|
87
|
+
var vcObserver, _interaction$apdex, prefix, result, VC, pageVisibilityUpToTTAI;
|
|
88
88
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
89
89
|
while (1) switch (_context.prev = _context.next) {
|
|
90
90
|
case 0:
|
|
91
|
-
if
|
|
92
|
-
|
|
91
|
+
// Use per-interaction VC observer if available, otherwise fall back to global experimentalVC
|
|
92
|
+
vcObserver = interaction.experimentalVCObserver || experimentalVC.vcObserver;
|
|
93
|
+
if (!vcObserver) {
|
|
94
|
+
_context.next = 13;
|
|
93
95
|
break;
|
|
94
96
|
}
|
|
95
97
|
prefix = 'ufo-experimental';
|
|
96
|
-
_context.next =
|
|
97
|
-
return
|
|
98
|
+
_context.next = 5;
|
|
99
|
+
return vcObserver.getVCResult({
|
|
98
100
|
start: interaction.start,
|
|
99
101
|
stop: interaction.end,
|
|
100
102
|
tti: (_interaction$apdex = interaction.apdex) === null || _interaction$apdex === void 0 || (_interaction$apdex = _interaction$apdex[0]) === null || _interaction$apdex === void 0 ? void 0 : _interaction$apdex.stopTime,
|
|
@@ -104,28 +106,28 @@ function _getExperimentalVCMetrics() {
|
|
|
104
106
|
experienceKey: interaction.ufoName,
|
|
105
107
|
interactionId: interaction.id
|
|
106
108
|
});
|
|
107
|
-
case
|
|
109
|
+
case 5:
|
|
108
110
|
result = _context.sent;
|
|
109
111
|
VC = result === null || result === void 0 ? void 0 : result['metrics:vc'];
|
|
110
112
|
if (!(!VC || !(result !== null && result !== void 0 && result["".concat(prefix, ":vc:clean")]))) {
|
|
111
|
-
_context.next =
|
|
113
|
+
_context.next = 9;
|
|
112
114
|
break;
|
|
113
115
|
}
|
|
114
116
|
return _context.abrupt("return", result);
|
|
115
|
-
case
|
|
117
|
+
case 9:
|
|
116
118
|
pageVisibilityUpToTTAI = getPageVisibilityState(interaction.start, interaction.end);
|
|
117
119
|
if (!(interaction.abortReason || pageVisibilityUpToTTAI !== 'visible')) {
|
|
118
|
-
_context.next =
|
|
120
|
+
_context.next = 12;
|
|
119
121
|
break;
|
|
120
122
|
}
|
|
121
123
|
return _context.abrupt("return", result);
|
|
122
|
-
case
|
|
124
|
+
case 12:
|
|
123
125
|
return _context.abrupt("return", _objectSpread(_objectSpread({}, result), {}, {
|
|
124
126
|
'metric:experimental:vc90': VC['90']
|
|
125
127
|
}));
|
|
126
|
-
case 12:
|
|
127
|
-
return _context.abrupt("return", null);
|
|
128
128
|
case 13:
|
|
129
|
+
return _context.abrupt("return", null);
|
|
130
|
+
case 14:
|
|
129
131
|
case "end":
|
|
130
132
|
return _context.stop();
|
|
131
133
|
}
|
|
@@ -16,7 +16,7 @@ function getVCMetrics(_x) {
|
|
|
16
16
|
function _getVCMetrics() {
|
|
17
17
|
_getVCMetrics = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(interaction) {
|
|
18
18
|
var _config$vc, _config$vc$ssrWhiteli, _interaction$apdex, _config$vc2, _config$vc3, _config$experimentalI, _result$ufoVcRev;
|
|
19
|
-
var config, interactionStatus, pageVisibilityUpToTTAI, shouldReportVCMetrics, isSSREnabled, ssr, tti, prefix, result, mostRecentVCRevision, mostRecentVCRevisionPayload;
|
|
19
|
+
var config, interactionStatus, pageVisibilityUpToTTAI, shouldReportVCMetrics, observer, isSSREnabled, ssr, tti, prefix, result, mostRecentVCRevision, mostRecentVCRevisionPayload;
|
|
20
20
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
21
21
|
while (1) switch (_context.prev = _context.next) {
|
|
22
22
|
case 0:
|
|
@@ -27,7 +27,7 @@ function _getVCMetrics() {
|
|
|
27
27
|
}
|
|
28
28
|
return _context.abrupt("return", {});
|
|
29
29
|
case 3:
|
|
30
|
-
if (!
|
|
30
|
+
if (!fg('platform_ufo_enable_vc_press_interactions')) {
|
|
31
31
|
_context.next = 8;
|
|
32
32
|
break;
|
|
33
33
|
}
|
|
@@ -48,14 +48,15 @@ function _getVCMetrics() {
|
|
|
48
48
|
case 10:
|
|
49
49
|
interactionStatus = getInteractionStatus(interaction);
|
|
50
50
|
pageVisibilityUpToTTAI = getPageVisibilityUpToTTAI(interaction);
|
|
51
|
-
shouldReportVCMetrics = interactionStatus.originalInteractionStatus === 'SUCCEEDED' && pageVisibilityUpToTTAI === 'visible';
|
|
51
|
+
shouldReportVCMetrics = interactionStatus.originalInteractionStatus === 'SUCCEEDED' && pageVisibilityUpToTTAI === 'visible'; // Use per-interaction VC observer if available, otherwise fall back to global
|
|
52
|
+
observer = interaction.vcObserver || getVCObserver();
|
|
52
53
|
if (!(!shouldReportVCMetrics && fg('platform_ufo_no_vc_on_aborted'))) {
|
|
53
|
-
_context.next =
|
|
54
|
+
_context.next = 17;
|
|
54
55
|
break;
|
|
55
56
|
}
|
|
56
|
-
|
|
57
|
+
observer.stop(interaction.ufoName);
|
|
57
58
|
return _context.abrupt("return", {});
|
|
58
|
-
case
|
|
59
|
+
case 17:
|
|
59
60
|
isSSREnabled = interaction.type === 'page_load' && ((config === null || config === void 0 ? void 0 : config.ssr) || (config === null || config === void 0 || (_config$vc$ssrWhiteli = config.vc.ssrWhitelist) === null || _config$vc$ssrWhiteli === void 0 ? void 0 : _config$vc$ssrWhiteli.includes(interaction.ufoName)));
|
|
60
61
|
ssr = interaction.type === 'page_load' && isSSREnabled ? {
|
|
61
62
|
ssr: getSSRDoneTimeValue(config)
|
|
@@ -63,8 +64,8 @@ function _getVCMetrics() {
|
|
|
63
64
|
postInteractionLog.setVCObserverSSRConfig(ssr);
|
|
64
65
|
tti = (_interaction$apdex = interaction.apdex) === null || _interaction$apdex === void 0 || (_interaction$apdex = _interaction$apdex[0]) === null || _interaction$apdex === void 0 ? void 0 : _interaction$apdex.stopTime;
|
|
65
66
|
prefix = 'ufo';
|
|
66
|
-
_context.next =
|
|
67
|
-
return
|
|
67
|
+
_context.next = 24;
|
|
68
|
+
return observer.getVCResult(_objectSpread({
|
|
68
69
|
start: interaction.start,
|
|
69
70
|
stop: interaction.end,
|
|
70
71
|
tti: tti,
|
|
@@ -76,10 +77,13 @@ function _getVCMetrics() {
|
|
|
76
77
|
interactionId: interaction.id,
|
|
77
78
|
includeSSRRatio: (_config$vc3 = config.vc) === null || _config$vc3 === void 0 ? void 0 : _config$vc3.includeSSRRatio
|
|
78
79
|
}, ssr));
|
|
79
|
-
case
|
|
80
|
+
case 24:
|
|
80
81
|
result = _context.sent;
|
|
82
|
+
if (fg('platform_ufo_enable_vc_observer_per_interaction')) {
|
|
83
|
+
observer.stop(interaction.ufoName);
|
|
84
|
+
}
|
|
81
85
|
if ((_config$experimentalI = config.experimentalInteractionMetrics) !== null && _config$experimentalI !== void 0 && _config$experimentalI.enabled) {
|
|
82
|
-
|
|
86
|
+
observer.stop(interaction.ufoName);
|
|
83
87
|
}
|
|
84
88
|
postInteractionLog.setLastInteractionFinishVCResult(result);
|
|
85
89
|
mostRecentVCRevision = getMostRecentVCRevision(interaction.ufoName);
|
|
@@ -88,15 +92,15 @@ function _getVCMetrics() {
|
|
|
88
92
|
return revision === mostRecentVCRevision;
|
|
89
93
|
});
|
|
90
94
|
if (!(!shouldReportVCMetrics || !(mostRecentVCRevisionPayload !== null && mostRecentVCRevisionPayload !== void 0 && mostRecentVCRevisionPayload.clean))) {
|
|
91
|
-
_context.next =
|
|
95
|
+
_context.next = 32;
|
|
92
96
|
break;
|
|
93
97
|
}
|
|
94
98
|
return _context.abrupt("return", result);
|
|
95
|
-
case
|
|
99
|
+
case 32:
|
|
96
100
|
return _context.abrupt("return", _objectSpread(_objectSpread({}, result), {}, {
|
|
97
101
|
'metric:vc90': mostRecentVCRevisionPayload['metric:vc90']
|
|
98
102
|
}));
|
|
99
|
-
case
|
|
103
|
+
case 33:
|
|
100
104
|
case "end":
|
|
101
105
|
return _context.stop();
|
|
102
106
|
}
|
|
@@ -16,7 +16,7 @@ import { experimentalVC, getExperimentalVCMetrics, onExperimentalInteractionComp
|
|
|
16
16
|
import { clearActiveTrace } from '../experience-trace-id-context';
|
|
17
17
|
import { allFeatureFlagsAccessed, currentFeatureFlagsAccessed } from '../feature-flags-accessed';
|
|
18
18
|
import { getInteractionId } from '../interaction-id-context';
|
|
19
|
-
import { getVCObserver } from '../vc';
|
|
19
|
+
import { getVCObserver, newVCObserver } from '../vc';
|
|
20
20
|
import { interactions } from './common/constants';
|
|
21
21
|
import PostInteractionLog from './post-interaction-log';
|
|
22
22
|
var PreviousInteractionLog = {
|
|
@@ -523,7 +523,9 @@ function finishInteraction(id, data) {
|
|
|
523
523
|
clearActiveTrace();
|
|
524
524
|
callCleanUpCallbacks(data);
|
|
525
525
|
if ((_getConfig4 = getConfig()) !== null && _getConfig4 !== void 0 && (_getConfig4 = _getConfig4.vc) !== null && _getConfig4 !== void 0 && _getConfig4.stopVCAtInteractionFinish) {
|
|
526
|
-
|
|
526
|
+
// Use per-interaction VC observer if available, otherwise fall back to global
|
|
527
|
+
var observer = data.vcObserver || getVCObserver();
|
|
528
|
+
data.vc = observer.getVCRawData();
|
|
527
529
|
}
|
|
528
530
|
if (!((_getConfig5 = getConfig()) !== null && _getConfig5 !== void 0 && (_getConfig5 = _getConfig5.experimentalInteractionMetrics) !== null && _getConfig5 !== void 0 && _getConfig5.enabled)) {
|
|
529
531
|
remove(id);
|
|
@@ -735,6 +737,7 @@ export function addNewInteraction(interactionId, ufoName, type, startTime, rate,
|
|
|
735
737
|
if ((_getConfig11 = getConfig()) !== null && _getConfig11 !== void 0 && (_getConfig11 = _getConfig11.postInteractionLog) !== null && _getConfig11 !== void 0 && _getConfig11.enabled) {
|
|
736
738
|
postInteractionLog.reset();
|
|
737
739
|
}
|
|
740
|
+
var vcObserver;
|
|
738
741
|
var previousTime = startTime;
|
|
739
742
|
var timeoutTime = fg('platform_ufo_enable_timeout_config') ? getInteractionTimeout(ufoName) : CLEANUP_TIMEOUT;
|
|
740
743
|
var timerID = setTimeout(function () {
|
|
@@ -757,6 +760,21 @@ export function addNewInteraction(interactionId, ufoName, type, startTime, rate,
|
|
|
757
760
|
this.timerID = newTimerID;
|
|
758
761
|
}
|
|
759
762
|
var addFeatureFlagsToInteraction = coinflip(getCapabilityRate('feature_flag_access'));
|
|
763
|
+
var config = getConfig();
|
|
764
|
+
if (config && config.vc) {
|
|
765
|
+
var vcOptions = {
|
|
766
|
+
heatmapSize: config.vc.heatmapSize,
|
|
767
|
+
oldDomUpdates: config.vc.oldDomUpdates,
|
|
768
|
+
devToolsEnabled: config.vc.devToolsEnabled,
|
|
769
|
+
selectorConfig: config.vc.selectorConfig,
|
|
770
|
+
ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder,
|
|
771
|
+
disableSizeAndPositionCheck: config.vc.disableSizeAndPositionCheck
|
|
772
|
+
};
|
|
773
|
+
vcObserver = fg('platform_ufo_enable_vc_observer_per_interaction') ? newVCObserver(vcOptions) : undefined;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
// Create per-interaction VC observer when feature flag is enabled
|
|
777
|
+
|
|
760
778
|
var metrics = {
|
|
761
779
|
id: interactionId,
|
|
762
780
|
start: startTime,
|
|
@@ -797,7 +815,8 @@ export function addNewInteraction(interactionId, ufoName, type, startTime, rate,
|
|
|
797
815
|
redirects: [],
|
|
798
816
|
timerID: timerID,
|
|
799
817
|
changeTimeout: changeTimeout,
|
|
800
|
-
trace: trace
|
|
818
|
+
trace: trace,
|
|
819
|
+
vcObserver: vcObserver
|
|
801
820
|
};
|
|
802
821
|
if (addFeatureFlagsToInteraction) {
|
|
803
822
|
currentFeatureFlagsAccessed.clear();
|
|
@@ -816,13 +835,21 @@ export function addNewInteraction(interactionId, ufoName, type, startTime, rate,
|
|
|
816
835
|
metrics.cleanupCallbacks.push(function () {
|
|
817
836
|
clearTimeout(metrics.timerID);
|
|
818
837
|
});
|
|
838
|
+
// Add cleanup for per-interaction VC observer
|
|
839
|
+
if (vcObserver) {
|
|
840
|
+
metrics.cleanupCallbacks.push(function () {
|
|
841
|
+
vcObserver.stop(ufoName);
|
|
842
|
+
});
|
|
843
|
+
}
|
|
819
844
|
var awaitBM3TTIList = getAwaitBM3TTIList();
|
|
820
845
|
if (awaitBM3TTIList.includes(ufoName)) {
|
|
821
846
|
addHoldByID(interactionId, [], ufoName, ufoName, true);
|
|
822
847
|
}
|
|
823
|
-
if (type === 'transition') {
|
|
848
|
+
if (type === 'transition' || type === 'page_load') {
|
|
824
849
|
var _getConfig12;
|
|
825
|
-
|
|
850
|
+
// Use per-interaction VC observer if available, otherwise fall back to global
|
|
851
|
+
var observer = vcObserver || getVCObserver();
|
|
852
|
+
observer.start({
|
|
826
853
|
startTime: startTime,
|
|
827
854
|
experienceKey: ufoName
|
|
828
855
|
});
|
|
@@ -835,20 +862,13 @@ export function addNewInteraction(interactionId, ufoName, type, startTime, rate,
|
|
|
835
862
|
});
|
|
836
863
|
}
|
|
837
864
|
}
|
|
838
|
-
if (type === 'press' &&
|
|
839
|
-
|
|
840
|
-
getVCObserver()
|
|
865
|
+
if (type === 'press' && fg('platform_ufo_enable_vc_press_interactions')) {
|
|
866
|
+
// Use per-interaction VC observer if available, otherwise fall back to global
|
|
867
|
+
var _observer = vcObserver || getVCObserver();
|
|
868
|
+
_observer.start({
|
|
841
869
|
startTime: startTime,
|
|
842
870
|
experienceKey: ufoName
|
|
843
871
|
});
|
|
844
|
-
postInteractionLog.startVCObserver({
|
|
845
|
-
startTime: startTime
|
|
846
|
-
});
|
|
847
|
-
if ((_getConfig13 = getConfig()) !== null && _getConfig13 !== void 0 && (_getConfig13 = _getConfig13.experimentalInteractionMetrics) !== null && _getConfig13 !== void 0 && _getConfig13.enabled) {
|
|
848
|
-
experimentalVC.start({
|
|
849
|
-
startTime: startTime
|
|
850
|
-
});
|
|
851
|
-
}
|
|
852
872
|
}
|
|
853
873
|
}
|
|
854
874
|
export function addBrowserMetricEvent(event) {
|
|
@@ -92,9 +92,11 @@ export function init(analyticsWebClientAsync, config) {
|
|
|
92
92
|
ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder,
|
|
93
93
|
disableSizeAndPositionCheck: config.vc.disableSizeAndPositionCheck
|
|
94
94
|
};
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
if (!fg('platform_ufo_enable_vc_observer_per_interaction')) {
|
|
96
|
+
getVCObserver(vcOptions).start({
|
|
97
|
+
startTime: 0
|
|
98
|
+
});
|
|
99
|
+
}
|
|
98
100
|
postInteractionLog.initializeVCObserver(vcOptions);
|
|
99
101
|
postInteractionLog.startVCObserver({
|
|
100
102
|
startTime: 0
|
|
@@ -1,18 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
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
|
-
|
|
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 {
|
|
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
|
-
|
|
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;
|
package/dist/esm/vc/index.js
CHANGED
|
@@ -234,4 +234,10 @@ export function getVCObserver() {
|
|
|
234
234
|
globalThis.__vcObserver = shouldMockVCObserver ? new VCObserverNOOP() : new VCObserverWrapper(opts);
|
|
235
235
|
}
|
|
236
236
|
return globalThis.__vcObserver;
|
|
237
|
+
}
|
|
238
|
+
export function newVCObserver() {
|
|
239
|
+
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
240
|
+
var shouldMockVCObserver = !isEnvironmentSupported();
|
|
241
|
+
var observer = shouldMockVCObserver ? new VCObserverNOOP() : new VCObserverWrapper(opts);
|
|
242
|
+
return observer;
|
|
237
243
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { TraceIdContext } from '../../experience-trace-id-context';
|
|
2
2
|
import type { LabelStack, UFOInteractionContextType } from '../../interaction-context';
|
|
3
|
+
import type { VCObserverInterface } from '../../vc/types';
|
|
3
4
|
import { type VCRawDataType, type VCResult } from '../vc/types';
|
|
4
5
|
export type LifecycleMarkType = 'render' | 'beforePaint' | 'afterPaint' | 'nextTick' | 'mount' | 'commit';
|
|
5
6
|
export type MarkType = ('placeholder' | 'bm3_stop' | 'bundle_preload' | 'custom') | LifecycleMarkType;
|
|
@@ -113,8 +114,8 @@ export interface InteractionMetrics {
|
|
|
113
114
|
holdInfo: HoldInfo[];
|
|
114
115
|
holdExpInfo: HoldInfo[];
|
|
115
116
|
holdActive: Map<string, HoldActive>;
|
|
116
|
-
holdExpActive: Map<string, HoldActive>;
|
|
117
117
|
reactProfilerTimings: ReactProfilerTiming[];
|
|
118
|
+
holdExpActive: Map<string, HoldActive>;
|
|
118
119
|
measureStart: number;
|
|
119
120
|
rate: number;
|
|
120
121
|
cancelCallbacks: (() => void)[];
|
|
@@ -158,6 +159,8 @@ export interface InteractionMetrics {
|
|
|
158
159
|
changeTimeout: (newTime: number) => void;
|
|
159
160
|
trace: TraceIdContext | null;
|
|
160
161
|
legacyMetrics?: BM3Event[];
|
|
162
|
+
vcObserver?: VCObserverInterface;
|
|
163
|
+
experimentalVCObserver?: VCObserverInterface;
|
|
161
164
|
vc?: VCRawDataType | null;
|
|
162
165
|
experimentalTTAI?: number;
|
|
163
166
|
experimentalVC90?: number;
|
package/dist/types/vc/index.d.ts
CHANGED
|
@@ -24,3 +24,4 @@ export declare class VCObserverWrapper implements VCObserverInterface {
|
|
|
24
24
|
}
|
|
25
25
|
export declare function isEnvironmentSupported(): boolean;
|
|
26
26
|
export declare function getVCObserver(opts?: VCObserverOptions): VCObserverInterface;
|
|
27
|
+
export declare function newVCObserver(opts?: VCObserverOptions): VCObserverInterface;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { TraceIdContext } from '../../experience-trace-id-context';
|
|
2
2
|
import type { LabelStack, UFOInteractionContextType } from '../../interaction-context';
|
|
3
|
+
import type { VCObserverInterface } from '../../vc/types';
|
|
3
4
|
import { type VCRawDataType, type VCResult } from '../vc/types';
|
|
4
5
|
export type LifecycleMarkType = 'render' | 'beforePaint' | 'afterPaint' | 'nextTick' | 'mount' | 'commit';
|
|
5
6
|
export type MarkType = ('placeholder' | 'bm3_stop' | 'bundle_preload' | 'custom') | LifecycleMarkType;
|
|
@@ -113,8 +114,8 @@ export interface InteractionMetrics {
|
|
|
113
114
|
holdInfo: HoldInfo[];
|
|
114
115
|
holdExpInfo: HoldInfo[];
|
|
115
116
|
holdActive: Map<string, HoldActive>;
|
|
116
|
-
holdExpActive: Map<string, HoldActive>;
|
|
117
117
|
reactProfilerTimings: ReactProfilerTiming[];
|
|
118
|
+
holdExpActive: Map<string, HoldActive>;
|
|
118
119
|
measureStart: number;
|
|
119
120
|
rate: number;
|
|
120
121
|
cancelCallbacks: (() => void)[];
|
|
@@ -158,6 +159,8 @@ export interface InteractionMetrics {
|
|
|
158
159
|
changeTimeout: (newTime: number) => void;
|
|
159
160
|
trace: TraceIdContext | null;
|
|
160
161
|
legacyMetrics?: BM3Event[];
|
|
162
|
+
vcObserver?: VCObserverInterface;
|
|
163
|
+
experimentalVCObserver?: VCObserverInterface;
|
|
161
164
|
vc?: VCRawDataType | null;
|
|
162
165
|
experimentalTTAI?: number;
|
|
163
166
|
experimentalVC90?: number;
|
|
@@ -24,3 +24,4 @@ export declare class VCObserverWrapper implements VCObserverInterface {
|
|
|
24
24
|
}
|
|
25
25
|
export declare function isEnvironmentSupported(): boolean;
|
|
26
26
|
export declare function getVCObserver(opts?: VCObserverOptions): VCObserverInterface;
|
|
27
|
+
export declare function newVCObserver(opts?: VCObserverOptions): VCObserverInterface;
|