@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.
Files changed (39) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/create-experimental-interaction-metrics-payload/index.js +14 -12
  3. package/dist/cjs/create-payload/utils/get-vc-metrics.js +17 -13
  4. package/dist/cjs/interaction-metrics/index.js +35 -15
  5. package/dist/cjs/interaction-metrics-init/index.js +5 -3
  6. package/dist/cjs/trace-interaction/index.js +10 -32
  7. package/dist/cjs/trace-interaction/internal/map-to-interaction-type.js +16 -0
  8. package/dist/cjs/trace-interaction/internal/trace-ufo-interaction.js +46 -0
  9. package/dist/cjs/trace-press/index.js +2 -25
  10. package/dist/cjs/vc/index.js +7 -0
  11. package/dist/es2019/create-experimental-interaction-metrics-payload/index.js +4 -2
  12. package/dist/es2019/create-payload/utils/get-vc-metrics.js +10 -4
  13. package/dist/es2019/interaction-metrics/index.js +36 -16
  14. package/dist/es2019/interaction-metrics-init/index.js +5 -3
  15. package/dist/es2019/trace-interaction/index.js +4 -31
  16. package/dist/es2019/trace-interaction/internal/map-to-interaction-type.js +10 -0
  17. package/dist/es2019/trace-interaction/internal/trace-ufo-interaction.js +39 -0
  18. package/dist/es2019/trace-press/index.js +2 -25
  19. package/dist/es2019/vc/index.js +5 -0
  20. package/dist/esm/create-experimental-interaction-metrics-payload/index.js +14 -12
  21. package/dist/esm/create-payload/utils/get-vc-metrics.js +17 -13
  22. package/dist/esm/interaction-metrics/index.js +36 -16
  23. package/dist/esm/interaction-metrics-init/index.js +5 -3
  24. package/dist/esm/trace-interaction/index.js +4 -31
  25. package/dist/esm/trace-interaction/internal/map-to-interaction-type.js +10 -0
  26. package/dist/esm/trace-interaction/internal/trace-ufo-interaction.js +39 -0
  27. package/dist/esm/trace-press/index.js +2 -25
  28. package/dist/esm/vc/index.js +6 -0
  29. package/dist/types/common/common/types.d.ts +4 -1
  30. package/dist/types/trace-interaction/index.d.ts +1 -0
  31. package/dist/types/trace-interaction/internal/map-to-interaction-type.d.ts +2 -0
  32. package/dist/types/trace-interaction/internal/trace-ufo-interaction.d.ts +3 -0
  33. package/dist/types/vc/index.d.ts +1 -0
  34. package/dist/types-ts4.5/common/common/types.d.ts +4 -1
  35. package/dist/types-ts4.5/trace-interaction/index.d.ts +1 -0
  36. package/dist/types-ts4.5/trace-interaction/internal/map-to-interaction-type.d.ts +2 -0
  37. package/dist/types-ts4.5/trace-interaction/internal/trace-ufo-interaction.d.ts +3 -0
  38. package/dist/types-ts4.5/vc/index.d.ts +1 -0
  39. package/package.json +10 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @atlaskit/ufo-interaction-ignore
2
2
 
3
+ ## 3.14.9
4
+
5
+ ### Patch Changes
6
+
7
+ - [#180517](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/180517)
8
+ [`cba15052f7278`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/cba15052f7278) -
9
+ AFO-4101 properly aborting previous interacttion
10
+
11
+ ## 3.14.8
12
+
13
+ ### Patch Changes
14
+
15
+ - [#179381](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/179381)
16
+ [`05fa3d08ecda9`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/05fa3d08ecda9) -
17
+ User vc observer per interaction
18
+
3
19
  ## 3.14.7
4
20
 
5
21
  ### Patch Changes
@@ -95,17 +95,19 @@ function getExperimentalVCMetrics(_x) {
95
95
  }
96
96
  function _getExperimentalVCMetrics() {
97
97
  _getExperimentalVCMetrics = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(interaction) {
98
- var _interaction$apdex, prefix, result, VC, pageVisibilityUpToTTAI;
98
+ var vcObserver, _interaction$apdex, prefix, result, VC, pageVisibilityUpToTTAI;
99
99
  return _regenerator.default.wrap(function _callee$(_context) {
100
100
  while (1) switch (_context.prev = _context.next) {
101
101
  case 0:
102
- if (!experimentalVC.vcObserver) {
103
- _context.next = 12;
102
+ // Use per-interaction VC observer if available, otherwise fall back to global experimentalVC
103
+ vcObserver = interaction.experimentalVCObserver || experimentalVC.vcObserver;
104
+ if (!vcObserver) {
105
+ _context.next = 13;
104
106
  break;
105
107
  }
106
108
  prefix = 'ufo-experimental';
107
- _context.next = 4;
108
- return experimentalVC.vcObserver.getVCResult({
109
+ _context.next = 5;
110
+ return vcObserver.getVCResult({
109
111
  start: interaction.start,
110
112
  stop: interaction.end,
111
113
  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,
@@ -115,28 +117,28 @@ function _getExperimentalVCMetrics() {
115
117
  experienceKey: interaction.ufoName,
116
118
  interactionId: interaction.id
117
119
  });
118
- case 4:
120
+ case 5:
119
121
  result = _context.sent;
120
122
  VC = result === null || result === void 0 ? void 0 : result['metrics:vc'];
121
123
  if (!(!VC || !(result !== null && result !== void 0 && result["".concat(prefix, ":vc:clean")]))) {
122
- _context.next = 8;
124
+ _context.next = 9;
123
125
  break;
124
126
  }
125
127
  return _context.abrupt("return", result);
126
- case 8:
128
+ case 9:
127
129
  pageVisibilityUpToTTAI = (0, _hiddenTiming.getPageVisibilityState)(interaction.start, interaction.end);
128
130
  if (!(interaction.abortReason || pageVisibilityUpToTTAI !== 'visible')) {
129
- _context.next = 11;
131
+ _context.next = 12;
130
132
  break;
131
133
  }
132
134
  return _context.abrupt("return", result);
133
- case 11:
135
+ case 12:
134
136
  return _context.abrupt("return", _objectSpread(_objectSpread({}, result), {}, {
135
137
  'metric:experimental:vc90': VC['90']
136
138
  }));
137
- case 12:
138
- return _context.abrupt("return", null);
139
139
  case 13:
140
+ return _context.abrupt("return", null);
141
+ case 14:
140
142
  case "end":
141
143
  return _context.stop();
142
144
  }
@@ -23,7 +23,7 @@ function getVCMetrics(_x) {
23
23
  function _getVCMetrics() {
24
24
  _getVCMetrics = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(interaction) {
25
25
  var _config$vc, _config$vc$ssrWhiteli, _interaction$apdex, _config$vc2, _config$vc3, _config$experimentalI, _result$ufoVcRev;
26
- var config, interactionStatus, pageVisibilityUpToTTAI, shouldReportVCMetrics, isSSREnabled, ssr, tti, prefix, result, mostRecentVCRevision, mostRecentVCRevisionPayload;
26
+ var config, interactionStatus, pageVisibilityUpToTTAI, shouldReportVCMetrics, observer, isSSREnabled, ssr, tti, prefix, result, mostRecentVCRevision, mostRecentVCRevisionPayload;
27
27
  return _regenerator.default.wrap(function _callee$(_context) {
28
28
  while (1) switch (_context.prev = _context.next) {
29
29
  case 0:
@@ -34,7 +34,7 @@ function _getVCMetrics() {
34
34
  }
35
35
  return _context.abrupt("return", {});
36
36
  case 3:
37
- if (!((0, _platformFeatureFlags.fg)('platform_ufo_enable_interactions_vc') || (0, _platformFeatureFlags.fg)('platform_ufo_enable_interactivity_jsm'))) {
37
+ if (!(0, _platformFeatureFlags.fg)('platform_ufo_enable_vc_press_interactions')) {
38
38
  _context.next = 8;
39
39
  break;
40
40
  }
@@ -55,14 +55,15 @@ function _getVCMetrics() {
55
55
  case 10:
56
56
  interactionStatus = (0, _getInteractionStatus.default)(interaction);
57
57
  pageVisibilityUpToTTAI = (0, _getPageVisibilityUpToTtai.default)(interaction);
58
- shouldReportVCMetrics = interactionStatus.originalInteractionStatus === 'SUCCEEDED' && pageVisibilityUpToTTAI === 'visible';
58
+ shouldReportVCMetrics = interactionStatus.originalInteractionStatus === 'SUCCEEDED' && pageVisibilityUpToTTAI === 'visible'; // Use per-interaction VC observer if available, otherwise fall back to global
59
+ observer = interaction.vcObserver || (0, _vc.getVCObserver)();
59
60
  if (!(!shouldReportVCMetrics && (0, _platformFeatureFlags.fg)('platform_ufo_no_vc_on_aborted'))) {
60
- _context.next = 16;
61
+ _context.next = 17;
61
62
  break;
62
63
  }
63
- (0, _vc.getVCObserver)().stop(interaction.ufoName);
64
+ observer.stop(interaction.ufoName);
64
65
  return _context.abrupt("return", {});
65
- case 16:
66
+ case 17:
66
67
  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)));
67
68
  ssr = interaction.type === 'page_load' && isSSREnabled ? {
68
69
  ssr: (0, _getSsrDoneTimeValue.default)(config)
@@ -70,8 +71,8 @@ function _getVCMetrics() {
70
71
  _interactionMetrics.postInteractionLog.setVCObserverSSRConfig(ssr);
71
72
  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;
72
73
  prefix = 'ufo';
73
- _context.next = 23;
74
- return (0, _vc.getVCObserver)().getVCResult(_objectSpread({
74
+ _context.next = 24;
75
+ return observer.getVCResult(_objectSpread({
75
76
  start: interaction.start,
76
77
  stop: interaction.end,
77
78
  tti: tti,
@@ -83,10 +84,13 @@ function _getVCMetrics() {
83
84
  interactionId: interaction.id,
84
85
  includeSSRRatio: (_config$vc3 = config.vc) === null || _config$vc3 === void 0 ? void 0 : _config$vc3.includeSSRRatio
85
86
  }, ssr));
86
- case 23:
87
+ case 24:
87
88
  result = _context.sent;
89
+ if ((0, _platformFeatureFlags.fg)('platform_ufo_enable_vc_observer_per_interaction')) {
90
+ observer.stop(interaction.ufoName);
91
+ }
88
92
  if ((_config$experimentalI = config.experimentalInteractionMetrics) !== null && _config$experimentalI !== void 0 && _config$experimentalI.enabled) {
89
- (0, _vc.getVCObserver)().stop(interaction.ufoName);
93
+ observer.stop(interaction.ufoName);
90
94
  }
91
95
  _interactionMetrics.postInteractionLog.setLastInteractionFinishVCResult(result);
92
96
  mostRecentVCRevision = (0, _config.getMostRecentVCRevision)(interaction.ufoName);
@@ -95,15 +99,15 @@ function _getVCMetrics() {
95
99
  return revision === mostRecentVCRevision;
96
100
  });
97
101
  if (!(!shouldReportVCMetrics || !(mostRecentVCRevisionPayload !== null && mostRecentVCRevisionPayload !== void 0 && mostRecentVCRevisionPayload.clean))) {
98
- _context.next = 30;
102
+ _context.next = 32;
99
103
  break;
100
104
  }
101
105
  return _context.abrupt("return", result);
102
- case 30:
106
+ case 32:
103
107
  return _context.abrupt("return", _objectSpread(_objectSpread({}, result), {}, {
104
108
  'metric:vc90': mostRecentVCRevisionPayload['metric:vc90']
105
109
  }));
106
- case 31:
110
+ case 33:
107
111
  case "end":
108
112
  return _context.stop();
109
113
  }
@@ -569,7 +569,9 @@ function finishInteraction(id, data) {
569
569
  (0, _experienceTraceIdContext.clearActiveTrace)();
570
570
  callCleanUpCallbacks(data);
571
571
  if ((_getConfig4 = (0, _config.getConfig)()) !== null && _getConfig4 !== void 0 && (_getConfig4 = _getConfig4.vc) !== null && _getConfig4 !== void 0 && _getConfig4.stopVCAtInteractionFinish) {
572
- data.vc = (0, _vc.getVCObserver)().getVCRawData();
572
+ // Use per-interaction VC observer if available, otherwise fall back to global
573
+ var observer = data.vcObserver || (0, _vc.getVCObserver)();
574
+ data.vc = observer.getVCRawData();
573
575
  }
574
576
  if (!((_getConfig5 = (0, _config.getConfig)()) !== null && _getConfig5 !== void 0 && (_getConfig5 = _getConfig5.experimentalInteractionMetrics) !== null && _getConfig5 !== void 0 && _getConfig5.enabled)) {
575
577
  remove(id);
@@ -781,6 +783,7 @@ function addNewInteraction(interactionId, ufoName, type, startTime, rate, labelS
781
783
  if ((_getConfig11 = (0, _config.getConfig)()) !== null && _getConfig11 !== void 0 && (_getConfig11 = _getConfig11.postInteractionLog) !== null && _getConfig11 !== void 0 && _getConfig11.enabled) {
782
784
  postInteractionLog.reset();
783
785
  }
786
+ var vcObserver;
784
787
  var previousTime = startTime;
785
788
  var timeoutTime = (0, _platformFeatureFlags.fg)('platform_ufo_enable_timeout_config') ? (0, _config.getInteractionTimeout)(ufoName) : CLEANUP_TIMEOUT;
786
789
  var timerID = setTimeout(function () {
@@ -803,6 +806,21 @@ function addNewInteraction(interactionId, ufoName, type, startTime, rate, labelS
803
806
  this.timerID = newTimerID;
804
807
  }
805
808
  var addFeatureFlagsToInteraction = (0, _coinflip.default)((0, _config.getCapabilityRate)('feature_flag_access'));
809
+ var config = (0, _config.getConfig)();
810
+ if (config && config.vc) {
811
+ var vcOptions = {
812
+ heatmapSize: config.vc.heatmapSize,
813
+ oldDomUpdates: config.vc.oldDomUpdates,
814
+ devToolsEnabled: config.vc.devToolsEnabled,
815
+ selectorConfig: config.vc.selectorConfig,
816
+ ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder,
817
+ disableSizeAndPositionCheck: config.vc.disableSizeAndPositionCheck
818
+ };
819
+ vcObserver = (0, _platformFeatureFlags.fg)('platform_ufo_enable_vc_observer_per_interaction') ? (0, _vc.newVCObserver)(vcOptions) : undefined;
820
+ }
821
+
822
+ // Create per-interaction VC observer when feature flag is enabled
823
+
806
824
  var metrics = {
807
825
  id: interactionId,
808
826
  start: startTime,
@@ -843,7 +861,8 @@ function addNewInteraction(interactionId, ufoName, type, startTime, rate, labelS
843
861
  redirects: [],
844
862
  timerID: timerID,
845
863
  changeTimeout: changeTimeout,
846
- trace: trace
864
+ trace: trace,
865
+ vcObserver: vcObserver
847
866
  };
848
867
  if (addFeatureFlagsToInteraction) {
849
868
  _featureFlagsAccessed.currentFeatureFlagsAccessed.clear();
@@ -862,13 +881,21 @@ function addNewInteraction(interactionId, ufoName, type, startTime, rate, labelS
862
881
  metrics.cleanupCallbacks.push(function () {
863
882
  clearTimeout(metrics.timerID);
864
883
  });
884
+ // Add cleanup for per-interaction VC observer
885
+ if (vcObserver) {
886
+ metrics.cleanupCallbacks.push(function () {
887
+ vcObserver.stop(ufoName);
888
+ });
889
+ }
865
890
  var awaitBM3TTIList = (0, _config.getAwaitBM3TTIList)();
866
891
  if (awaitBM3TTIList.includes(ufoName)) {
867
892
  addHoldByID(interactionId, [], ufoName, ufoName, true);
868
893
  }
869
- if (type === 'transition') {
894
+ if (type === 'transition' || type === 'page_load') {
870
895
  var _getConfig12;
871
- (0, _vc.getVCObserver)().start({
896
+ // Use per-interaction VC observer if available, otherwise fall back to global
897
+ var observer = vcObserver || (0, _vc.getVCObserver)();
898
+ observer.start({
872
899
  startTime: startTime,
873
900
  experienceKey: ufoName
874
901
  });
@@ -881,20 +908,13 @@ function addNewInteraction(interactionId, ufoName, type, startTime, rate, labelS
881
908
  });
882
909
  }
883
910
  }
884
- if (type === 'press' && ((0, _platformFeatureFlags.fg)('platform_ufo_enable_interactions_vc') || (0, _platformFeatureFlags.fg)('platform_ufo_enable_interactivity_jsm'))) {
885
- var _getConfig13;
886
- (0, _vc.getVCObserver)().start({
911
+ if (type === 'press' && (0, _platformFeatureFlags.fg)('platform_ufo_enable_vc_press_interactions')) {
912
+ // Use per-interaction VC observer if available, otherwise fall back to global
913
+ var _observer = vcObserver || (0, _vc.getVCObserver)();
914
+ _observer.start({
887
915
  startTime: startTime,
888
916
  experienceKey: ufoName
889
917
  });
890
- postInteractionLog.startVCObserver({
891
- startTime: startTime
892
- });
893
- if ((_getConfig13 = (0, _config.getConfig)()) !== null && _getConfig13 !== void 0 && (_getConfig13 = _getConfig13.experimentalInteractionMetrics) !== null && _getConfig13 !== void 0 && _getConfig13.enabled) {
894
- _createExperimentalInteractionMetricsPayload.experimentalVC.start({
895
- startTime: startTime
896
- });
897
- }
898
918
  }
899
919
  }
900
920
  function addBrowserMetricEvent(event) {
@@ -101,9 +101,11 @@ function init(analyticsWebClientAsync, config) {
101
101
  ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder,
102
102
  disableSizeAndPositionCheck: config.vc.disableSizeAndPositionCheck
103
103
  };
104
- (0, _vc.getVCObserver)(vcOptions).start({
105
- startTime: 0
106
- });
104
+ if (!(0, _platformFeatureFlags.fg)('platform_ufo_enable_vc_observer_per_interaction')) {
105
+ (0, _vc.getVCObserver)(vcOptions).start({
106
+ startTime: 0
107
+ });
108
+ }
107
109
  _interactionMetrics.postInteractionLog.initializeVCObserver(vcOptions);
108
110
  _interactionMetrics.postInteractionLog.startVCObserver({
109
111
  startTime: 0
@@ -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;
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.VCObserverWrapper = void 0;
8
8
  exports.getVCObserver = getVCObserver;
9
9
  exports.isEnvironmentSupported = isEnvironmentSupported;
10
+ exports.newVCObserver = newVCObserver;
10
11
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
12
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
12
13
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
@@ -241,4 +242,10 @@ function getVCObserver() {
241
242
  globalThis.__vcObserver = shouldMockVCObserver ? new _noOpVcObserver.VCObserverNOOP() : new VCObserverWrapper(opts);
242
243
  }
243
244
  return globalThis.__vcObserver;
245
+ }
246
+ function newVCObserver() {
247
+ var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
248
+ var shouldMockVCObserver = !isEnvironmentSupported();
249
+ var observer = shouldMockVCObserver ? new _noOpVcObserver.VCObserverNOOP() : new VCObserverWrapper(opts);
250
+ return observer;
244
251
  }
@@ -58,10 +58,12 @@ export class ExperimentalVCMetrics {
58
58
  }
59
59
  export const experimentalVC = new ExperimentalVCMetrics();
60
60
  export async function getExperimentalVCMetrics(interaction) {
61
- if (experimentalVC.vcObserver) {
61
+ // Use per-interaction VC observer if available, otherwise fall back to global experimentalVC
62
+ const vcObserver = interaction.experimentalVCObserver || experimentalVC.vcObserver;
63
+ if (vcObserver) {
62
64
  var _interaction$apdex, _interaction$apdex$;
63
65
  const prefix = 'ufo-experimental';
64
- const result = await experimentalVC.vcObserver.getVCResult({
66
+ const result = await vcObserver.getVCResult({
65
67
  start: interaction.start,
66
68
  stop: interaction.end,
67
69
  tti: (_interaction$apdex = interaction.apdex) === null || _interaction$apdex === void 0 ? void 0 : (_interaction$apdex$ = _interaction$apdex[0]) === null || _interaction$apdex$ === void 0 ? void 0 : _interaction$apdex$.stopTime,
@@ -11,7 +11,7 @@ async function getVCMetrics(interaction) {
11
11
  if (!(config !== null && config !== void 0 && (_config$vc = config.vc) !== null && _config$vc !== void 0 && _config$vc.enabled)) {
12
12
  return {};
13
13
  }
14
- if (fg('platform_ufo_enable_interactions_vc') || fg('platform_ufo_enable_interactivity_jsm')) {
14
+ if (fg('platform_ufo_enable_vc_press_interactions')) {
15
15
  if (interaction.type !== 'page_load' && interaction.type !== 'transition' && interaction.type !== 'press') {
16
16
  return {};
17
17
  }
@@ -23,8 +23,11 @@ async function getVCMetrics(interaction) {
23
23
  const interactionStatus = getInteractionStatus(interaction);
24
24
  const pageVisibilityUpToTTAI = getPageVisibilityUpToTTAI(interaction);
25
25
  const shouldReportVCMetrics = interactionStatus.originalInteractionStatus === 'SUCCEEDED' && pageVisibilityUpToTTAI === 'visible';
26
+
27
+ // Use per-interaction VC observer if available, otherwise fall back to global
28
+ const observer = interaction.vcObserver || getVCObserver();
26
29
  if (!shouldReportVCMetrics && fg('platform_ufo_no_vc_on_aborted')) {
27
- getVCObserver().stop(interaction.ufoName);
30
+ observer.stop(interaction.ufoName);
28
31
  return {};
29
32
  }
30
33
  const isSSREnabled = interaction.type === 'page_load' && ((config === null || config === void 0 ? void 0 : config.ssr) || (config === null || config === void 0 ? void 0 : (_config$vc$ssrWhiteli = config.vc.ssrWhitelist) === null || _config$vc$ssrWhiteli === void 0 ? void 0 : _config$vc$ssrWhiteli.includes(interaction.ufoName)));
@@ -34,7 +37,7 @@ async function getVCMetrics(interaction) {
34
37
  postInteractionLog.setVCObserverSSRConfig(ssr);
35
38
  const tti = (_interaction$apdex = interaction.apdex) === null || _interaction$apdex === void 0 ? void 0 : (_interaction$apdex$ = _interaction$apdex[0]) === null || _interaction$apdex$ === void 0 ? void 0 : _interaction$apdex$.stopTime;
36
39
  const prefix = 'ufo';
37
- const result = await getVCObserver().getVCResult({
40
+ const result = await observer.getVCResult({
38
41
  start: interaction.start,
39
42
  stop: interaction.end,
40
43
  tti,
@@ -47,8 +50,11 @@ async function getVCMetrics(interaction) {
47
50
  includeSSRRatio: (_config$vc3 = config.vc) === null || _config$vc3 === void 0 ? void 0 : _config$vc3.includeSSRRatio,
48
51
  ...ssr
49
52
  });
53
+ if (fg('platform_ufo_enable_vc_observer_per_interaction')) {
54
+ observer.stop(interaction.ufoName);
55
+ }
50
56
  if ((_config$experimentalI = config.experimentalInteractionMetrics) !== null && _config$experimentalI !== void 0 && _config$experimentalI.enabled) {
51
- getVCObserver().stop(interaction.ufoName);
57
+ observer.stop(interaction.ufoName);
52
58
  }
53
59
  postInteractionLog.setLastInteractionFinishVCResult(result);
54
60
  const mostRecentVCRevision = getMostRecentVCRevision(interaction.ufoName);
@@ -6,7 +6,7 @@ import { experimentalVC, getExperimentalVCMetrics, onExperimentalInteractionComp
6
6
  import { clearActiveTrace } from '../experience-trace-id-context';
7
7
  import { allFeatureFlagsAccessed, currentFeatureFlagsAccessed } from '../feature-flags-accessed';
8
8
  import { getInteractionId } from '../interaction-id-context';
9
- import { getVCObserver } from '../vc';
9
+ import { getVCObserver, newVCObserver } from '../vc';
10
10
  import { interactions } from './common/constants';
11
11
  import PostInteractionLog from './post-interaction-log';
12
12
  const PreviousInteractionLog = {
@@ -487,7 +487,9 @@ function finishInteraction(id, data, endTime = performance.now()) {
487
487
  clearActiveTrace();
488
488
  callCleanUpCallbacks(data);
489
489
  if ((_getConfig4 = getConfig()) !== null && _getConfig4 !== void 0 && (_getConfig4$vc = _getConfig4.vc) !== null && _getConfig4$vc !== void 0 && _getConfig4$vc.stopVCAtInteractionFinish) {
490
- data.vc = getVCObserver().getVCRawData();
490
+ // Use per-interaction VC observer if available, otherwise fall back to global
491
+ const observer = data.vcObserver || getVCObserver();
492
+ data.vc = observer.getVCRawData();
491
493
  }
492
494
  if (!((_getConfig5 = getConfig()) !== null && _getConfig5 !== void 0 && (_getConfig5$experimen = _getConfig5.experimentalInteractionMetrics) !== null && _getConfig5$experimen !== void 0 && _getConfig5$experimen.enabled)) {
493
495
  remove(id);
@@ -656,6 +658,7 @@ export function addNewInteraction(interactionId, ufoName, type, startTime, rate,
656
658
  if ((_getConfig11 = getConfig()) !== null && _getConfig11 !== void 0 && (_getConfig11$postInte = _getConfig11.postInteractionLog) !== null && _getConfig11$postInte !== void 0 && _getConfig11$postInte.enabled) {
657
659
  postInteractionLog.reset();
658
660
  }
661
+ let vcObserver;
659
662
  let previousTime = startTime;
660
663
  let timeoutTime = fg('platform_ufo_enable_timeout_config') ? getInteractionTimeout(ufoName) : CLEANUP_TIMEOUT;
661
664
  const timerID = setTimeout(() => {
@@ -678,6 +681,21 @@ export function addNewInteraction(interactionId, ufoName, type, startTime, rate,
678
681
  this.timerID = newTimerID;
679
682
  }
680
683
  const addFeatureFlagsToInteraction = coinflip(getCapabilityRate('feature_flag_access'));
684
+ const config = getConfig();
685
+ if (config && config.vc) {
686
+ const vcOptions = {
687
+ heatmapSize: config.vc.heatmapSize,
688
+ oldDomUpdates: config.vc.oldDomUpdates,
689
+ devToolsEnabled: config.vc.devToolsEnabled,
690
+ selectorConfig: config.vc.selectorConfig,
691
+ ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder,
692
+ disableSizeAndPositionCheck: config.vc.disableSizeAndPositionCheck
693
+ };
694
+ vcObserver = fg('platform_ufo_enable_vc_observer_per_interaction') ? newVCObserver(vcOptions) : undefined;
695
+ }
696
+
697
+ // Create per-interaction VC observer when feature flag is enabled
698
+
681
699
  const metrics = {
682
700
  id: interactionId,
683
701
  start: startTime,
@@ -718,7 +736,8 @@ export function addNewInteraction(interactionId, ufoName, type, startTime, rate,
718
736
  redirects: [],
719
737
  timerID,
720
738
  changeTimeout,
721
- trace
739
+ trace,
740
+ vcObserver
722
741
  };
723
742
  if (addFeatureFlagsToInteraction) {
724
743
  currentFeatureFlagsAccessed.clear();
@@ -737,13 +756,21 @@ export function addNewInteraction(interactionId, ufoName, type, startTime, rate,
737
756
  metrics.cleanupCallbacks.push(() => {
738
757
  clearTimeout(metrics.timerID);
739
758
  });
759
+ // Add cleanup for per-interaction VC observer
760
+ if (vcObserver) {
761
+ metrics.cleanupCallbacks.push(() => {
762
+ vcObserver.stop(ufoName);
763
+ });
764
+ }
740
765
  const awaitBM3TTIList = getAwaitBM3TTIList();
741
766
  if (awaitBM3TTIList.includes(ufoName)) {
742
767
  addHoldByID(interactionId, [], ufoName, ufoName, true);
743
768
  }
744
- if (type === 'transition') {
769
+ if (type === 'transition' || type === 'page_load') {
745
770
  var _getConfig12, _getConfig12$experime;
746
- getVCObserver().start({
771
+ // Use per-interaction VC observer if available, otherwise fall back to global
772
+ const observer = vcObserver || getVCObserver();
773
+ observer.start({
747
774
  startTime,
748
775
  experienceKey: ufoName
749
776
  });
@@ -756,20 +783,13 @@ export function addNewInteraction(interactionId, ufoName, type, startTime, rate,
756
783
  });
757
784
  }
758
785
  }
759
- if (type === 'press' && (fg('platform_ufo_enable_interactions_vc') || fg('platform_ufo_enable_interactivity_jsm'))) {
760
- var _getConfig13, _getConfig13$experime;
761
- getVCObserver().start({
786
+ if (type === 'press' && fg('platform_ufo_enable_vc_press_interactions')) {
787
+ // Use per-interaction VC observer if available, otherwise fall back to global
788
+ const observer = vcObserver || getVCObserver();
789
+ observer.start({
762
790
  startTime,
763
791
  experienceKey: ufoName
764
792
  });
765
- postInteractionLog.startVCObserver({
766
- startTime
767
- });
768
- if ((_getConfig13 = getConfig()) !== null && _getConfig13 !== void 0 && (_getConfig13$experime = _getConfig13.experimentalInteractionMetrics) !== null && _getConfig13$experime !== void 0 && _getConfig13$experime.enabled) {
769
- experimentalVC.start({
770
- startTime
771
- });
772
- }
773
793
  }
774
794
  }
775
795
  export function addBrowserMetricEvent(event) {
@@ -91,9 +91,11 @@ export function init(analyticsWebClientAsync, config) {
91
91
  ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder,
92
92
  disableSizeAndPositionCheck: config.vc.disableSizeAndPositionCheck
93
93
  };
94
- getVCObserver(vcOptions).start({
95
- startTime: 0
96
- });
94
+ if (!fg('platform_ufo_enable_vc_observer_per_interaction')) {
95
+ getVCObserver(vcOptions).start({
96
+ startTime: 0
97
+ });
98
+ }
97
99
  postInteractionLog.initializeVCObserver(vcOptions);
98
100
  postInteractionLog.startVCObserver({
99
101
  startTime: 0