@atlaskit/react-ufo 4.16.8 → 4.17.1

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 (50) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/cjs/create-payload/index.js +2 -2
  3. package/dist/cjs/interaction-id-context/index.js +2 -2
  4. package/dist/cjs/interaction-metrics/index.js +7 -1
  5. package/dist/cjs/typing-performance-tracing/index.js +29 -6
  6. package/dist/cjs/vc/index.js +2 -1
  7. package/dist/cjs/vc/vc-observer-new/index.js +3 -1
  8. package/dist/cjs/vc/vc-observer-new/metric-calculator/fy25_03/index.js +7 -3
  9. package/dist/cjs/vc/vc-observer-new/metric-calculator/fy26_04/index.js +2 -2
  10. package/dist/cjs/vc/vc-observer-new/viewport-observer/index.js +26 -5
  11. package/dist/cjs/vc/vc-observer-new/viewport-observer/utils/is-contained-within-smart-answers.js +20 -0
  12. package/dist/es2019/create-payload/index.js +2 -2
  13. package/dist/es2019/interaction-id-context/index.js +2 -2
  14. package/dist/es2019/interaction-metrics/index.js +7 -1
  15. package/dist/es2019/typing-performance-tracing/index.js +27 -6
  16. package/dist/es2019/vc/index.js +2 -1
  17. package/dist/es2019/vc/vc-observer-new/index.js +3 -1
  18. package/dist/es2019/vc/vc-observer-new/metric-calculator/fy25_03/index.js +7 -3
  19. package/dist/es2019/vc/vc-observer-new/metric-calculator/fy26_04/index.js +2 -2
  20. package/dist/es2019/vc/vc-observer-new/viewport-observer/index.js +24 -3
  21. package/dist/es2019/vc/vc-observer-new/viewport-observer/utils/is-contained-within-smart-answers.js +14 -0
  22. package/dist/esm/create-payload/index.js +2 -2
  23. package/dist/esm/interaction-id-context/index.js +2 -2
  24. package/dist/esm/interaction-metrics/index.js +7 -1
  25. package/dist/esm/typing-performance-tracing/index.js +29 -6
  26. package/dist/esm/vc/index.js +2 -1
  27. package/dist/esm/vc/vc-observer-new/index.js +3 -1
  28. package/dist/esm/vc/vc-observer-new/metric-calculator/fy25_03/index.js +7 -3
  29. package/dist/esm/vc/vc-observer-new/metric-calculator/fy26_04/index.js +2 -2
  30. package/dist/esm/vc/vc-observer-new/viewport-observer/index.js +26 -5
  31. package/dist/esm/vc/vc-observer-new/viewport-observer/utils/is-contained-within-smart-answers.js +14 -0
  32. package/dist/types/config/index.d.ts +1 -0
  33. package/dist/types/interaction-id-context/index.d.ts +2 -2
  34. package/dist/types/vc/types.d.ts +14 -0
  35. package/dist/types/vc/vc-observer/observers/index.d.ts +2 -0
  36. package/dist/types/vc/vc-observer-new/index.d.ts +2 -0
  37. package/dist/types/vc/vc-observer-new/metric-calculator/fy26_04/index.d.ts +1 -1
  38. package/dist/types/vc/vc-observer-new/types.d.ts +1 -1
  39. package/dist/types/vc/vc-observer-new/viewport-observer/index.d.ts +5 -1
  40. package/dist/types/vc/vc-observer-new/viewport-observer/utils/is-contained-within-smart-answers.d.ts +1 -0
  41. package/dist/types-ts4.5/config/index.d.ts +1 -0
  42. package/dist/types-ts4.5/interaction-id-context/index.d.ts +2 -2
  43. package/dist/types-ts4.5/vc/types.d.ts +14 -0
  44. package/dist/types-ts4.5/vc/vc-observer/observers/index.d.ts +2 -0
  45. package/dist/types-ts4.5/vc/vc-observer-new/index.d.ts +2 -0
  46. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/fy26_04/index.d.ts +1 -1
  47. package/dist/types-ts4.5/vc/vc-observer-new/types.d.ts +1 -1
  48. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/index.d.ts +5 -1
  49. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/utils/is-contained-within-smart-answers.d.ts +1 -0
  50. package/package.json +7 -4
@@ -8,12 +8,13 @@ import { createIntersectionObserver } from './intersection-observer';
8
8
  import createMutationObserver from './mutation-observer';
9
9
  import createPerformanceObserver from './performance-observer';
10
10
  import checkWithinComponent, { cleanupCaches } from './utils/check-within-component';
11
+ import { isContainedWithinSmartAnswers } from './utils/is-contained-within-smart-answers';
11
12
  import { isElementVisible } from './utils/is-element-visible';
12
13
  import isInVCIgnoreIfNoLayoutShiftMarker from './utils/is-in-vc-ignore-if-no-layout-shift-marker';
13
14
  import { isInputNameMutation } from './utils/is-input-name-mutation';
14
15
  import { isSameRectDimensions } from './utils/is-same-rect-dimensions';
15
16
  import { isSameRectSize } from './utils/is-same-rect-size';
16
- const createElementMutationsWatcher = (removedNodeRects, isWithinThirdPartySegment, hasSameDeletedNode, timestamp, isTargetReactRoot, getSSRState, getSSRPlaceholderHandler) => ({
17
+ const createElementMutationsWatcher = (removedNodeRects, isWithinThirdPartySegment, isWithinSmartAnswersSegment, hasSameDeletedNode, timestamp, isTargetReactRoot, getSSRState, getSSRPlaceholderHandler) => ({
17
18
  target,
18
19
  rect
19
20
  }) => {
@@ -60,6 +61,9 @@ const createElementMutationsWatcher = (removedNodeRects, isWithinThirdPartySegme
60
61
  if (isWithinThirdPartySegment) {
61
62
  return 'mutation:third-party-element';
62
63
  }
64
+ if (isWithinSmartAnswersSegment) {
65
+ return 'mutation:smart-answers-element';
66
+ }
63
67
  const isInIgnoreLsMarker = isInVCIgnoreIfNoLayoutShiftMarker(target);
64
68
  if (!isInIgnoreLsMarker) {
65
69
  return 'mutation:element';
@@ -80,7 +84,8 @@ export default class ViewportObserver {
80
84
  constructor({
81
85
  onChange,
82
86
  getSSRState,
83
- getSSRPlaceholderHandler
87
+ getSSRPlaceholderHandler,
88
+ searchPageConfig
84
89
  }) {
85
90
  _defineProperty(this, "handleIntersectionEntry", ({
86
91
  target,
@@ -135,8 +140,9 @@ export default class ViewportObserver {
135
140
  const {
136
141
  isWithin: isWithinThirdPartySegment
137
142
  } = checkWithinComponent(addedNode, 'UFOThirdPartySegment', this.mapIs3pResult);
143
+ const isWithinSmartAnswersSegment = Boolean(this.shouldCheckSmartAnswersMutations() && isContainedWithinSmartAnswers(addedNode));
138
144
  const isTargetReactRoot = targetNode === ((_this$getSSRState = this.getSSRState) === null || _this$getSSRState === void 0 ? void 0 : (_this$getSSRState$cal = _this$getSSRState.call(this)) === null || _this$getSSRState$cal === void 0 ? void 0 : _this$getSSRState$cal.reactRootElement);
139
- (_this$intersectionObs = this.intersectionObserver) === null || _this$intersectionObs === void 0 ? void 0 : _this$intersectionObs.watchAndTag(addedNode, createElementMutationsWatcher(removedNodeRects, isWithinThirdPartySegment, !!hasSameDeletedNode, timestamp, isTargetReactRoot, this.getSSRState, this.getSSRPlaceholderHandler));
145
+ (_this$intersectionObs = this.intersectionObserver) === null || _this$intersectionObs === void 0 ? void 0 : _this$intersectionObs.watchAndTag(addedNode, createElementMutationsWatcher(removedNodeRects, isWithinThirdPartySegment, isWithinSmartAnswersSegment, !!hasSameDeletedNode, timestamp, isTargetReactRoot, this.getSSRState, this.getSSRPlaceholderHandler));
140
146
  }
141
147
  });
142
148
  _defineProperty(this, "handleAttributeMutation", ({
@@ -175,6 +181,16 @@ export default class ViewportObserver {
175
181
  };
176
182
  }
177
183
  }
184
+ if (this.shouldCheckSmartAnswersMutations() && isContainedWithinSmartAnswers(target)) {
185
+ return {
186
+ type: 'mutation:smart-answers-attribute',
187
+ mutationData: {
188
+ attributeName,
189
+ oldValue,
190
+ newValue
191
+ }
192
+ };
193
+ }
178
194
  if (isDnDStyleMutation({
179
195
  target,
180
196
  attributeName,
@@ -270,6 +286,10 @@ export default class ViewportObserver {
270
286
  }
271
287
  }
272
288
  });
289
+ _defineProperty(this, "shouldCheckSmartAnswersMutations", () => {
290
+ var _this$searchPageConfi, _this$searchPageConfi2, _window, _window$location;
291
+ return ((_this$searchPageConfi = this.searchPageConfig) === null || _this$searchPageConfi === void 0 ? void 0 : _this$searchPageConfi.enableSmartAnswersMutations) && ((_this$searchPageConfi2 = this.searchPageConfig) === null || _this$searchPageConfi2 === void 0 ? void 0 : _this$searchPageConfi2.searchPageRoute) && ((_window = window) === null || _window === void 0 ? void 0 : (_window$location = _window.location) === null || _window$location === void 0 ? void 0 : _window$location.pathname) && window.location.pathname === this.searchPageConfig.searchPageRoute && fg('rovo_search_page_ttvc_ignoring_smart_answers_fix');
292
+ });
273
293
  this.mapVisibleNodeRects = new WeakMap();
274
294
  this.mapIs3pResult = new WeakMap();
275
295
  this.onChange = onChange;
@@ -281,6 +301,7 @@ export default class ViewportObserver {
281
301
  // Initialize SSR context functions
282
302
  this.getSSRState = getSSRState;
283
303
  this.getSSRPlaceholderHandler = getSSRPlaceholderHandler;
304
+ this.searchPageConfig = searchPageConfig;
284
305
  }
285
306
  initializeObservers() {
286
307
  if (this.isStarted) {
@@ -0,0 +1,14 @@
1
+ import { getDocument } from '@atlaskit/browser-apis';
2
+ export function isContainedWithinSmartAnswers(node) {
3
+ const doc = getDocument();
4
+ if (!doc) {
5
+ return false;
6
+ }
7
+ const smartAnswersElement = doc.getElementById('search-page-smart-answers');
8
+ if (!smartAnswersElement) {
9
+ return false;
10
+ }
11
+
12
+ // When the node is the smart answer element, .contains() still returns true
13
+ return smartAnswersElement.contains(node);
14
+ }
@@ -13,9 +13,9 @@ getPageLoadDetailedInteractionMetrics=function getPageLoadDetailedInteractionMet
13
13
  'event:hostname':((_window$location=window.location)===null||_window$location===void 0?void 0:_window$location.hostname)||'unknown','event:product':config.product,'event:population':config.population,'event:schema':'1.0.0','event:sizeInKb':0,'event:source':{name:'react-ufo/web',version:getReactUFOPayloadVersion(interaction.type)},'event:region':config.region||'unknown','experience:key':experimental?'custom.experimental-interaction-metrics':'custom.interaction-metrics','experience:name':newUFOName,// Include CPU usage monitoring data
14
14
  'event:cpu:usage':createPressureStateReport(interaction.start,interaction.end),'event:memory:usage':createMemoryStateReport(interaction.start,interaction.end)},criticalPayloadCount!==undefined?{'ufo:multipayload':true,'ufo:criticalPayloadCount':criticalPayloadCount}:{}),getBrowserMetadataToLegacyFormat()),batteryInfo),getSSRProperties(type)),getAssetsMetrics(interaction,pageLoadInteractionMetrics===null||pageLoadInteractionMetrics===void 0?void 0:pageLoadInteractionMetrics.SSRDoneTime)),getPPSMetrics(interaction)),paintMetrics),getNavigationMetricsToLegacyFormat(type)),finalVCMetrics),experimentalMetrics),(_config$additionalPay=config.additionalPayloadData)===null||_config$additionalPay===void 0?void 0:_config$additionalPay.call(config,interaction)),getTracingContextData(interaction)),getStylesheetMetrics()),getErrorCounts(interaction)),getReactHydrationStats()),{},{interactionMetrics:_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({namePrefix:config.namePrefix||'',segmentPrefix:config.segmentPrefix||'',interactionId:interactionId,pageVisibilityAtTTI:pageVisibilityAtTTI,pageVisibilityAtTTAI:pageVisibilityAtTTAI,experimental__pageVisibilityAtTTI:moreAccuratePageVisibilityAtTTI,experimental__pageVisibilityAtTTAI:moreAccuratePageVisibilityAtTTAI,// raw interaction metrics
15
15
  rate:rate,routeName:routeName,type:type,abortReason:abortReason,featureFlags:featureFlags,previousInteractionName:previousInteractionName,isPreviousInteractionAborted:isPreviousInteractionAborted,abortedByInteractionName:abortedByInteractionName,// performance
16
- apdex:optimizeApdex(interaction.apdex,getReactUFOPayloadVersion(interaction.type)),end:Math.round(end)},interaction.end3p?{end3p:Math.round(interaction.end3p)}:{}),{},{start:Math.round(start),segments:getReactUFOPayloadVersion(interaction.type)==='2.0.0'?segmentTree:getOldSegmentsLabelStack(segments,interaction.type),marks:optimizeMarks(interaction.marks,getReactUFOPayloadVersion(interaction.type)),customData:optimizeCustomData(interaction),reactProfilerTimings:optimizeReactProfilerTimings(interaction.reactProfilerTimings,start,getReactUFOPayloadVersion(interaction.type)),minorInteractions:interaction.minorInteractions},responsiveness?{responsiveness:responsiveness}:{}),labelStack),pageLoadInteractionMetrics),getDetailedInteractionMetrics(resourceTimings)),getPageLoadDetailedInteractionMetrics()),getBm3TrackerTimings(interaction)),{},{'metric:ttai':experimental?regularTTAI||expTTAI:undefined,'metric:experimental:ttai':expTTAI},unknownElementName?{unknownElementName:unknownElementName}:{}),unknownElementHierarchy?{unknownElementHierarchy:unknownElementHierarchy}:{}),'ufo:payloadTime':roundEpsilon(performance.now()-interactionPayloadStart)})}};if(experimental){regularTTAI=undefined;expTTAI=undefined;}if(fg('platform_ufo_enable_vc_raw_data')){size=getPayloadSize(payload.attributes.properties);vcRev=payload.attributes.properties['ufo:vc:rev'];rawData=vcRev.find(function(item){return item.revision==='raw-handler';});if(rawData){rawDataSize=getPayloadSize(rawData);payload.attributes.properties['ufo:vc:raw:size']=rawDataSize;if(size>MAX_PAYLOAD_SIZE&&Array.isArray(vcRev)&&vcRev.length>0){payload.attributes.properties['ufo:vc:rev']=vcRev.filter(function(item){return item.revision!=='raw-handler';});payload.attributes.properties['ufo:vc:raw:removed']=true;}}payload.attributes.properties['event:sizeInKb']=getPayloadSize(payload.attributes.properties);}else{payload.attributes.properties['event:sizeInKb']=getPayloadSize(payload.attributes.properties);}if(!fg('platform_ufo_enable_trimmed_payload')){_context.next=75;break;}// in order of importance, first one being least important
16
+ apdex:optimizeApdex(interaction.apdex,getReactUFOPayloadVersion(interaction.type)),end:Math.round(end)},interaction.end3p?{end3p:Math.round(interaction.end3p)}:{}),{},{start:Math.round(start),segments:getReactUFOPayloadVersion(interaction.type)==='2.0.0'?segmentTree:getOldSegmentsLabelStack(segments,interaction.type),marks:optimizeMarks(interaction.marks,getReactUFOPayloadVersion(interaction.type)),customData:optimizeCustomData(interaction),reactProfilerTimings:optimizeReactProfilerTimings(interaction.reactProfilerTimings,start,getReactUFOPayloadVersion(interaction.type)),minorInteractions:interaction.minorInteractions},responsiveness?{responsiveness:responsiveness}:{}),labelStack),pageLoadInteractionMetrics),getDetailedInteractionMetrics(resourceTimings)),getPageLoadDetailedInteractionMetrics()),getBm3TrackerTimings(interaction)),{},{'metric:ttai':experimental?regularTTAI||expTTAI:undefined,'metric:experimental:ttai':expTTAI},unknownElementName?{unknownElementName:unknownElementName}:{}),unknownElementHierarchy?{unknownElementHierarchy:unknownElementHierarchy}:{}),'ufo:payloadTime':roundEpsilon(performance.now()-interactionPayloadStart)})}};if(experimental){regularTTAI=undefined;expTTAI=undefined;}if(fg('platform_ufo_enable_vc_raw_data')){size=getPayloadSize(payload.attributes.properties);vcRev=payload.attributes.properties['ufo:vc:rev'];rawData=vcRev.find(function(item){return item.revision==='raw-handler';});if(rawData){rawDataSize=getPayloadSize(rawData);payload.attributes.properties['ufo:vc:raw:size']=rawDataSize;if(size>MAX_PAYLOAD_SIZE&&Array.isArray(vcRev)&&vcRev.length>0){payload.attributes.properties['ufo:vc:rev']=vcRev.filter(function(item){return item.revision!=='raw-handler';});payload.attributes.properties['ufo:vc:raw:removed']=true;}}payload.attributes.properties['event:sizeInKb']=getPayloadSize(payload.attributes.properties);}else{payload.attributes.properties['event:sizeInKb']=getPayloadSize(payload.attributes.properties);}// in order of importance, first one being least important
17
17
  // we can add more fields as necessary
18
- interactionMetricsFieldsToTrim=['requestInfo','featureFlags','resourceTimings'];properties=payload.attributes.properties;interactionMetrics=properties.interactionMetrics;if(!interactionMetrics){_context.next=75;break;}_iterator=_createForOfIteratorHelper(interactionMetricsFieldsToTrim);_context.prev=53;_iterator.s();case 55:if((_step=_iterator.n()).done){_context.next=67;break;}field=_step.value;if(!(getPayloadSize(properties)<=MAX_PAYLOAD_SIZE)){_context.next=59;break;}return _context.abrupt("continue",65);case 59:interactionMetrics[field]=undefined;properties['event:isTrimmed']=true;trimmedFields=properties['event:trimmedFields'];if(!Array.isArray(trimmedFields)){trimmedFields=[];}trimmedFields.push("interactionMetrics.".concat(field));properties['event:trimmedFields']=trimmedFields;case 65:_context.next=55;break;case 67:_context.next=72;break;case 69:_context.prev=69;_context.t7=_context["catch"](53);_iterator.e(_context.t7);case 72:_context.prev=72;_iterator.f();return _context.finish(72);case 75:return _context.abrupt("return",payload);case 76:case"end":return _context.stop();}},_callee,null,[[53,69,72,75]]);}));return _createInteractionMetricsPayload.apply(this,arguments);}export function createPayloads(_x6,_x7){return _createPayloads.apply(this,arguments);}function _createPayloads(){_createPayloads=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(interactionId,interaction){var ufoNameOverride,modifiedInteraction,payloads,isCriticalMetricsEnabled,vcMetrics,criticalMetricsPayloads,criticalPayloadCount,interactionMetricsPayload;return _regeneratorRuntime.wrap(function _callee2$(_context2){while(1)switch(_context2.prev=_context2.next){case 0:ufoNameOverride=getUfoNameOverride(interaction);modifiedInteraction=_objectSpread(_objectSpread({},interaction),{},{ufoName:ufoNameOverride});payloads=[];isCriticalMetricsEnabled=fg('platform_ufo_critical_metrics_payload');// Calculate VC metrics once to avoid duplicate expensive calculations
18
+ interactionMetricsFieldsToTrim=['requestInfo','featureFlags','resourceTimings'];properties=payload.attributes.properties;interactionMetrics=properties.interactionMetrics;if(!interactionMetrics){_context.next=74;break;}_iterator=_createForOfIteratorHelper(interactionMetricsFieldsToTrim);_context.prev=52;_iterator.s();case 54:if((_step=_iterator.n()).done){_context.next=66;break;}field=_step.value;if(!(getPayloadSize(properties)<=MAX_PAYLOAD_SIZE)){_context.next=58;break;}return _context.abrupt("continue",64);case 58:interactionMetrics[field]=undefined;properties['event:isTrimmed']=true;trimmedFields=properties['event:trimmedFields'];if(!Array.isArray(trimmedFields)){trimmedFields=[];}trimmedFields.push("interactionMetrics.".concat(field));properties['event:trimmedFields']=trimmedFields;case 64:_context.next=54;break;case 66:_context.next=71;break;case 68:_context.prev=68;_context.t7=_context["catch"](52);_iterator.e(_context.t7);case 71:_context.prev=71;_iterator.f();return _context.finish(71);case 74:return _context.abrupt("return",payload);case 75:case"end":return _context.stop();}},_callee,null,[[52,68,71,74]]);}));return _createInteractionMetricsPayload.apply(this,arguments);}export function createPayloads(_x6,_x7){return _createPayloads.apply(this,arguments);}function _createPayloads(){_createPayloads=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(interactionId,interaction){var ufoNameOverride,modifiedInteraction,payloads,isCriticalMetricsEnabled,vcMetrics,criticalMetricsPayloads,criticalPayloadCount,interactionMetricsPayload;return _regeneratorRuntime.wrap(function _callee2$(_context2){while(1)switch(_context2.prev=_context2.next){case 0:ufoNameOverride=getUfoNameOverride(interaction);modifiedInteraction=_objectSpread(_objectSpread({},interaction),{},{ufoName:ufoNameOverride});payloads=[];isCriticalMetricsEnabled=fg('platform_ufo_critical_metrics_payload');// Calculate VC metrics once to avoid duplicate expensive calculations
19
19
  _context2.next=6;return getVCMetrics(interaction);case 6:vcMetrics=_context2.sent;if(!isCriticalMetricsEnabled){_context2.next=13;break;}_context2.next=10;return createCriticalMetricsPayloads(interactionId,interaction,vcMetrics);case 10:_context2.t0=_context2.sent;_context2.next=14;break;case 13:_context2.t0=[];case 14:criticalMetricsPayloads=_context2.t0;payloads.push.apply(payloads,_toConsumableArray(criticalMetricsPayloads));criticalPayloadCount=isCriticalMetricsEnabled?criticalMetricsPayloads.length:undefined;_context2.next=19;return createInteractionMetricsPayload(modifiedInteraction,interactionId,undefined,criticalPayloadCount,vcMetrics);case 19:interactionMetricsPayload=_context2.sent;payloads.push(interactionMetricsPayload);return _context2.abrupt("return",payloads.filter(Boolean));case 22:case"end":return _context2.stop();}},_callee2);}));return _createPayloads.apply(this,arguments);}export function createExperimentalMetricsPayload(_x8,_x9){return _createExperimentalMetricsPayload.apply(this,arguments);}function _createExperimentalMetricsPayload(){_createExperimentalMetricsPayload=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(interactionId,interaction){var config,ufoName,rate,pageVisibilityState,result;return _regeneratorRuntime.wrap(function _callee3$(_context3){while(1)switch(_context3.prev=_context3.next){case 0:config=getConfig();if(config){_context3.next=3;break;}throw Error('UFO Configuration not provided');case 3:ufoName=sanitizeUfoName(interaction.ufoName);rate=getExperimentalInteractionRate(ufoName,interaction.type);if(coinflip(rate)){_context3.next=7;break;}return _context3.abrupt("return",null);case 7:pageVisibilityState=getPageVisibilityState(interaction.start,interaction.end);if(!(pageVisibilityState!=='visible')){_context3.next=10;break;}return _context3.abrupt("return",null);case 10:_context3.next=12;return createInteractionMetricsPayload(interaction,interactionId,true);case 12:result=_context3.sent;return _context3.abrupt("return",result);case 14:case"end":return _context3.stop();}},_callee3);}));return _createExperimentalMetricsPayload.apply(this,arguments);}export function createExtraSearchPageInteractionPayload(_x0,_x1){return _createExtraSearchPageInteractionPayload.apply(this,arguments);}function _createExtraSearchPageInteractionPayload(){_createExtraSearchPageInteractionPayload=_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4(interactionId,interaction){var SAIN_HOLD_NAMES,NAME_OVERRIDE,SEARCH_PAGE_SMART_ANSWERS_SEGMENT_LABEL,newInteractionId,newEnd,holdInfo,reactProfilerTimings,lastHold,isLastHoldSAIN,lastFilteredTime,filteredReactProfilerTimings,lastTiming,modifiedInteraction,payloads,vcMetrics,interactionMetricsPayload;return _regeneratorRuntime.wrap(function _callee4$(_context4){while(1)switch(_context4.prev=_context4.next){case 0:SAIN_HOLD_NAMES=['search-ai-dialog-visible-text-loading','search-ai-dialog-all-text-loading'];NAME_OVERRIDE='search-page-ignoring-smart-answers';SEARCH_PAGE_SMART_ANSWERS_SEGMENT_LABEL='search-page-smart-answers';newInteractionId="".concat(interactionId,"-ignoring-smart-answers");// Calculate a new end time which excludes SAIN holds
20
20
  holdInfo=interaction.holdInfo,reactProfilerTimings=interaction.reactProfilerTimings;lastHold=holdInfo.at(-1);isLastHoldSAIN=Boolean(lastHold&&SAIN_HOLD_NAMES.includes(lastHold.name));// A new end time is only calculated if the last hold is a SAIN hold
21
21
  if(isLastHoldSAIN){lastFilteredTime=null;filteredReactProfilerTimings=reactProfilerTimings.filter(function(timing){if(timing.commitTime===lastFilteredTime){return false;}var isTimingSmartAnswersInSearch=timing.labelStack.some(function(label){return label.name===SEARCH_PAGE_SMART_ANSWERS_SEGMENT_LABEL;});if(isTimingSmartAnswersInSearch){lastFilteredTime=timing.commitTime;return false;}return true;});lastTiming=filteredReactProfilerTimings.at(-1);if(lastTiming){newEnd=lastTiming.commitTime;}}modifiedInteraction=_objectSpread(_objectSpread({},interaction),{},{end:newEnd!==null&&newEnd!==void 0?newEnd:interaction.end,holdInfo:[],knownSegments:[],reactProfilerTimings:[],ufoName:NAME_OVERRIDE});payloads=[];_context4.next=12;return getVCMetrics(interaction,false,true);case 12:vcMetrics=_context4.sent;_context4.next=15;return createInteractionMetricsPayload(modifiedInteraction,newInteractionId,undefined,undefined,vcMetrics);case 15:interactionMetricsPayload=_context4.sent;payloads.push(interactionMetricsPayload);return _context4.abrupt("return",payloads.filter(Boolean));case 18:case"end":return _context4.stop();}},_callee4);}));return _createExtraSearchPageInteractionPayload.apply(this,arguments);}
@@ -63,8 +63,8 @@ export var subscribeToInteractionIdChanges = function subscribeToInteractionIdCh
63
63
  };
64
64
 
65
65
  // We use a context to allow modals to have their own lifecycle
66
- var _default_1 = /*#__PURE__*/createContext(DefaultInteractionID);
67
- export default _default_1;
66
+ var interactionContext = /*#__PURE__*/createContext(DefaultInteractionID);
67
+ export default interactionContext;
68
68
  export var getInteractionId = function getInteractionId() {
69
69
  return DefaultInteractionID;
70
70
  };
@@ -1100,6 +1100,7 @@ export function addOnCancelCallback(id, cancelCallback) {
1100
1100
  interaction === null || interaction === void 0 || interaction.cancelCallbacks.push(cancelCallback);
1101
1101
  }
1102
1102
  export function addNewInteraction(interactionId, ufoName, type, startTime, rate, labelStack, routeName) {
1103
+ var _config$extraSearchPa, _config$extraSearchPa2;
1103
1104
  var trace = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : null;
1104
1105
  interactionExtraMetrics.reset();
1105
1106
  postInteractionLog.reset();
@@ -1127,13 +1128,18 @@ export function addNewInteraction(interactionId, ufoName, type, startTime, rate,
1127
1128
  }
1128
1129
  var addFeatureFlagsToInteraction = coinflip(getCapabilityRate('feature_flag_access'));
1129
1130
  var config = getConfig();
1131
+ var searchPageConfig = fg('rovo_search_page_ttvc_ignoring_smart_answers_fix') ? {
1132
+ enableSmartAnswersMutations: config === null || config === void 0 || (_config$extraSearchPa = config.extraSearchPageInteraction) === null || _config$extraSearchPa === void 0 ? void 0 : _config$extraSearchPa.enabled,
1133
+ searchPageRoute: config === null || config === void 0 || (_config$extraSearchPa2 = config.extraSearchPageInteraction) === null || _config$extraSearchPa2 === void 0 ? void 0 : _config$extraSearchPa2.searchPageRoute
1134
+ } : undefined;
1130
1135
  if (config && config.vc) {
1131
1136
  var vcOptions = {
1132
1137
  heatmapSize: config.vc.heatmapSize,
1133
1138
  oldDomUpdates: config.vc.oldDomUpdates,
1134
1139
  devToolsEnabled: config.vc.devToolsEnabled,
1135
1140
  selectorConfig: config.vc.selectorConfig,
1136
- ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder
1141
+ ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder,
1142
+ searchPageConfig: searchPageConfig
1137
1143
  };
1138
1144
  vcObserver = newVCObserver(vcOptions);
1139
1145
  }
@@ -2,6 +2,7 @@ import { useEffect, useRef } from 'react';
2
2
  import { unstable_IdlePriority as idlePriority, unstable_scheduleCallback as scheduleCallback } from 'scheduler';
3
3
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
4
4
  import { v4 as createUUID } from 'uuid';
5
+ import { fg } from '@atlaskit/platform-feature-flags';
5
6
  import coinflip from '../coinflip';
6
7
  import { getInteractionRate, getTypingPerformanceTracingMethod } from '../config';
7
8
  import { addMetadata, addNewInteraction, tryComplete } from '../interaction-metrics';
@@ -72,10 +73,15 @@ function typingPerformanceTracingTimeout(element, name, rate) {
72
73
  tsubmit = setTimeout(end, 2000); // debounce
73
74
  }, 0);
74
75
  };
75
-
76
+ if (typeof (element === null || element === void 0 ? void 0 : element.addEventListener) !== 'function' && fg('jfp-magma-ufo-event-listener-error')) {
77
+ return;
78
+ }
76
79
  // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
77
80
  element.addEventListener('keypress', onKeyPressHandler);
78
81
  return function () {
82
+ if (typeof (element === null || element === void 0 ? void 0 : element.removeEventListener) !== 'function' && fg('jfp-magma-ufo-event-listener-error')) {
83
+ return;
84
+ }
79
85
  // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
80
86
  element.removeEventListener('keypress', onKeyPressHandler);
81
87
  };
@@ -144,10 +150,15 @@ function typingPerformanceTracingTimeoutNoAlloc(element, name, rate) {
144
150
  tsubmit = setTimeout(end, 2000); // debounce
145
151
  }, 0);
146
152
  };
147
-
153
+ if (typeof (element === null || element === void 0 ? void 0 : element.addEventListener) !== 'function' && fg('jfp-magma-ufo-event-listener-error')) {
154
+ return;
155
+ }
148
156
  // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
149
157
  element.addEventListener('keypress', onKeyPressHandler);
150
158
  return function () {
159
+ if (typeof (element === null || element === void 0 ? void 0 : element.removeEventListener) !== 'function' && fg('jfp-magma-ufo-event-listener-error')) {
160
+ return;
161
+ }
151
162
  // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
152
163
  element.removeEventListener('keypress', onKeyPressHandler);
153
164
  };
@@ -232,13 +243,25 @@ function typingPerformanceTracingMutationObserver(element, name, rate) {
232
243
  childList: true,
233
244
  subtree: true
234
245
  });
235
-
246
+ if (typeof (element === null || element === void 0 ? void 0 : element.addEventListener) !== 'function' && fg('jfp-magma-ufo-event-listener-error')) {
247
+ return function () {
248
+ return mo.disconnect();
249
+ };
250
+ }
236
251
  // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
237
252
  element.addEventListener('keypress', onKeyPressHandler);
238
253
  return function () {
239
- // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
240
- element.removeEventListener('keypress', onKeyPressHandler);
241
- mo.disconnect();
254
+ if (fg('jfp-magma-ufo-event-listener-error')) {
255
+ if (typeof (element === null || element === void 0 ? void 0 : element.removeEventListener) === 'function') {
256
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
257
+ element.removeEventListener('keypress', onKeyPressHandler);
258
+ }
259
+ mo.disconnect();
260
+ } else {
261
+ // eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
262
+ element.removeEventListener('keypress', onKeyPressHandler);
263
+ mo.disconnect();
264
+ }
242
265
  };
243
266
  }
244
267
  var typingPerformanceTracingMethods = {
@@ -35,7 +35,8 @@ export var VCObserverWrapper = /*#__PURE__*/function () {
35
35
  SSRConfig: {
36
36
  enablePageLayoutPlaceholder: (_opts$ssrEnablePageLa2 = opts.ssrEnablePageLayoutPlaceholder) !== null && _opts$ssrEnablePageLa2 !== void 0 ? _opts$ssrEnablePageLa2 : false
37
37
  },
38
- ssrPlaceholderHandler: this.ssrPlaceholderHandler
38
+ ssrPlaceholderHandler: this.ssrPlaceholderHandler,
39
+ searchPageConfig: opts.searchPageConfig
39
40
  });
40
41
  }
41
42
  if (isVCRevisionEnabled('fy25.01') || isVCRevisionEnabled('fy25.02')) {
@@ -102,7 +102,8 @@ var VCObserverNew = /*#__PURE__*/function () {
102
102
  },
103
103
  getSSRPlaceholderHandler: function getSSRPlaceholderHandler() {
104
104
  return _this.getSSRPlaceholderHandler();
105
- }
105
+ },
106
+ searchPageConfig: config.searchPageConfig
106
107
  });
107
108
  this.windowEventObserver = new WindowEventObserver({
108
109
  onEvent: function onEvent(_ref) {
@@ -311,6 +312,7 @@ var VCObserverNew = /*#__PURE__*/function () {
311
312
  interactionType: interactionType,
312
313
  isPostInteraction: this.isPostInteraction,
313
314
  include3p: include3p,
315
+ excludeSmartAnswersInSearch: excludeSmartAnswersInSearch,
314
316
  includeSSRRatio: includeSSRRatio,
315
317
  isPageVisible: isPageVisible,
316
318
  interactionAbortReason: interactionAbortReason
@@ -14,7 +14,7 @@ import { isEntrySmartAnswersInSearch } from '../utils/is-entry-smart-answers-in-
14
14
  import isViewportEntryData from '../utils/is-viewport-entry-data';
15
15
  var ABORTING_WINDOW_EVENT = ['wheel', 'scroll', 'keydown', 'resize'];
16
16
  var REVISION_NO = 'fy25.03';
17
- var getConsideredEntryTypes = function getConsideredEntryTypes(include3p) {
17
+ var getConsideredEntryTypes = function getConsideredEntryTypes(include3p, excludeSmartAnswersInSearch) {
18
18
  var entryTypes = ['mutation:child-element', 'mutation:element', 'mutation:attribute', 'layout-shift', 'layout-shift:same-rect', 'window:event'];
19
19
 
20
20
  // If not exclude 3p elements from ttvc,
@@ -23,6 +23,10 @@ var getConsideredEntryTypes = function getConsideredEntryTypes(include3p) {
23
23
  entryTypes.push('mutation:third-party-element');
24
24
  entryTypes.push('mutation:third-party-attribute');
25
25
  }
26
+ if (!excludeSmartAnswersInSearch && fg('rovo_search_page_ttvc_ignoring_smart_answers_fix')) {
27
+ entryTypes.push('mutation:smart-answers-element');
28
+ entryTypes.push('mutation:smart-answers-attribute');
29
+ }
26
30
  if (fg('platform_ufo_enable_media_for_ttvc_v3')) {
27
31
  entryTypes.push('mutation:media');
28
32
  }
@@ -40,10 +44,10 @@ var VCCalculator_FY25_03 = /*#__PURE__*/function (_AbstractVCCalculator) {
40
44
  return _createClass(VCCalculator_FY25_03, [{
41
45
  key: "isEntryIncluded",
42
46
  value: function isEntryIncluded(entry, include3p, excludeSmartAnswersInSearch) {
43
- if (!getConsideredEntryTypes(include3p).includes(entry.data.type)) {
47
+ if (!getConsideredEntryTypes(include3p, excludeSmartAnswersInSearch).includes(entry.data.type)) {
44
48
  return false;
45
49
  }
46
- if (excludeSmartAnswersInSearch && isEntrySmartAnswersInSearch(entry)) {
50
+ if (excludeSmartAnswersInSearch && isEntrySmartAnswersInSearch(entry) && !fg('rovo_search_page_ttvc_ignoring_smart_answers_fix')) {
47
51
  return false;
48
52
  }
49
53
  if (entry.data.type === 'mutation:media' && fg('media-perf-uplift-mutation-fix')) {
@@ -32,8 +32,8 @@ var VCCalculator_FY26_04 = /*#__PURE__*/function (_VCCalculator_FY25_) {
32
32
  _inherits(VCCalculator_FY26_04, _VCCalculator_FY25_);
33
33
  return _createClass(VCCalculator_FY26_04, [{
34
34
  key: "isEntryIncluded",
35
- value: function isEntryIncluded(entry, include3p) {
36
- var isEntryIncludedInV3 = _superPropGet(VCCalculator_FY26_04, "isEntryIncluded", this, 3)([entry, include3p]);
35
+ value: function isEntryIncluded(entry, include3p, excludeSmartAnswersInSearch) {
36
+ var isEntryIncludedInV3 = _superPropGet(VCCalculator_FY26_04, "isEntryIncluded", this, 3)([entry, include3p, excludeSmartAnswersInSearch]);
37
37
  if (isEntryIncludedInV3 && !getExcludedEntryTypes().includes(entry.data.type)) {
38
38
  return true;
39
39
  }
@@ -15,12 +15,13 @@ import { createIntersectionObserver } from './intersection-observer';
15
15
  import createMutationObserver from './mutation-observer';
16
16
  import createPerformanceObserver from './performance-observer';
17
17
  import checkWithinComponent, { cleanupCaches } from './utils/check-within-component';
18
+ import { isContainedWithinSmartAnswers } from './utils/is-contained-within-smart-answers';
18
19
  import { isElementVisible } from './utils/is-element-visible';
19
20
  import isInVCIgnoreIfNoLayoutShiftMarker from './utils/is-in-vc-ignore-if-no-layout-shift-marker';
20
21
  import { isInputNameMutation } from './utils/is-input-name-mutation';
21
22
  import { isSameRectDimensions } from './utils/is-same-rect-dimensions';
22
23
  import { isSameRectSize } from './utils/is-same-rect-size';
23
- var createElementMutationsWatcher = function createElementMutationsWatcher(removedNodeRects, isWithinThirdPartySegment, hasSameDeletedNode, timestamp, isTargetReactRoot, getSSRState, getSSRPlaceholderHandler) {
24
+ var createElementMutationsWatcher = function createElementMutationsWatcher(removedNodeRects, isWithinThirdPartySegment, isWithinSmartAnswersSegment, hasSameDeletedNode, timestamp, isTargetReactRoot, getSSRState, getSSRPlaceholderHandler) {
24
25
  return function (_ref) {
25
26
  var target = _ref.target,
26
27
  rect = _ref.rect;
@@ -67,6 +68,9 @@ var createElementMutationsWatcher = function createElementMutationsWatcher(remov
67
68
  if (isWithinThirdPartySegment) {
68
69
  return 'mutation:third-party-element';
69
70
  }
71
+ if (isWithinSmartAnswersSegment) {
72
+ return 'mutation:smart-answers-element';
73
+ }
70
74
  var isInIgnoreLsMarker = isInVCIgnoreIfNoLayoutShiftMarker(target);
71
75
  if (!isInIgnoreLsMarker) {
72
76
  return 'mutation:element';
@@ -91,7 +95,8 @@ var ViewportObserver = /*#__PURE__*/function () {
91
95
  var _this = this;
92
96
  var onChange = _ref2.onChange,
93
97
  getSSRState = _ref2.getSSRState,
94
- getSSRPlaceholderHandler = _ref2.getSSRPlaceholderHandler;
98
+ getSSRPlaceholderHandler = _ref2.getSSRPlaceholderHandler,
99
+ searchPageConfig = _ref2.searchPageConfig;
95
100
  _classCallCheck(this, ViewportObserver);
96
101
  _defineProperty(this, "handleIntersectionEntry", function (_ref3) {
97
102
  var target = _ref3.target,
@@ -134,7 +139,7 @@ var ViewportObserver = /*#__PURE__*/function () {
134
139
  _context2.prev = 4;
135
140
  _loop = /*#__PURE__*/_regeneratorRuntime.mark(function _loop() {
136
141
  var _this$getSSRState, _this$intersectionObs;
137
- var addedNodeRef, addedNode, hasSameDeletedNode, _checkWithinComponent, isWithinThirdPartySegment, isTargetReactRoot;
142
+ var addedNodeRef, addedNode, hasSameDeletedNode, _checkWithinComponent, isWithinThirdPartySegment, isWithinSmartAnswersSegment, isTargetReactRoot;
138
143
  return _regeneratorRuntime.wrap(function _loop$(_context) {
139
144
  while (1) switch (_context.prev = _context.next) {
140
145
  case 0:
@@ -154,9 +159,10 @@ var ViewportObserver = /*#__PURE__*/function () {
154
159
  return n.isEqualNode(addedNode);
155
160
  });
156
161
  _checkWithinComponent = checkWithinComponent(addedNode, 'UFOThirdPartySegment', _this.mapIs3pResult), isWithinThirdPartySegment = _checkWithinComponent.isWithin;
162
+ isWithinSmartAnswersSegment = Boolean(_this.shouldCheckSmartAnswersMutations() && isContainedWithinSmartAnswers(addedNode));
157
163
  isTargetReactRoot = targetNode === ((_this$getSSRState = _this.getSSRState) === null || _this$getSSRState === void 0 || (_this$getSSRState = _this$getSSRState.call(_this)) === null || _this$getSSRState === void 0 ? void 0 : _this$getSSRState.reactRootElement);
158
- (_this$intersectionObs = _this.intersectionObserver) === null || _this$intersectionObs === void 0 || _this$intersectionObs.watchAndTag(addedNode, createElementMutationsWatcher(removedNodeRects, isWithinThirdPartySegment, !!hasSameDeletedNode, timestamp, isTargetReactRoot, _this.getSSRState, _this.getSSRPlaceholderHandler));
159
- case 8:
164
+ (_this$intersectionObs = _this.intersectionObserver) === null || _this$intersectionObs === void 0 || _this$intersectionObs.watchAndTag(addedNode, createElementMutationsWatcher(removedNodeRects, isWithinThirdPartySegment, isWithinSmartAnswersSegment, !!hasSameDeletedNode, timestamp, isTargetReactRoot, _this.getSSRState, _this.getSSRPlaceholderHandler));
165
+ case 9:
160
166
  case "end":
161
167
  return _context.stop();
162
168
  }
@@ -232,6 +238,16 @@ var ViewportObserver = /*#__PURE__*/function () {
232
238
  };
233
239
  }
234
240
  }
241
+ if (_this.shouldCheckSmartAnswersMutations() && isContainedWithinSmartAnswers(target)) {
242
+ return {
243
+ type: 'mutation:smart-answers-attribute',
244
+ mutationData: {
245
+ attributeName: attributeName,
246
+ oldValue: oldValue,
247
+ newValue: newValue
248
+ }
249
+ };
250
+ }
235
251
  if (isDnDStyleMutation({
236
252
  target: target,
237
253
  attributeName: attributeName,
@@ -335,6 +351,10 @@ var ViewportObserver = /*#__PURE__*/function () {
335
351
  _iterator2.f();
336
352
  }
337
353
  });
354
+ _defineProperty(this, "shouldCheckSmartAnswersMutations", function () {
355
+ var _this$searchPageConfi, _this$searchPageConfi2, _window;
356
+ return ((_this$searchPageConfi = _this.searchPageConfig) === null || _this$searchPageConfi === void 0 ? void 0 : _this$searchPageConfi.enableSmartAnswersMutations) && ((_this$searchPageConfi2 = _this.searchPageConfig) === null || _this$searchPageConfi2 === void 0 ? void 0 : _this$searchPageConfi2.searchPageRoute) && ((_window = window) === null || _window === void 0 || (_window = _window.location) === null || _window === void 0 ? void 0 : _window.pathname) && window.location.pathname === _this.searchPageConfig.searchPageRoute && fg('rovo_search_page_ttvc_ignoring_smart_answers_fix');
357
+ });
338
358
  this.mapVisibleNodeRects = new WeakMap();
339
359
  this.mapIs3pResult = new WeakMap();
340
360
  this.onChange = onChange;
@@ -346,6 +366,7 @@ var ViewportObserver = /*#__PURE__*/function () {
346
366
  // Initialize SSR context functions
347
367
  this.getSSRState = getSSRState;
348
368
  this.getSSRPlaceholderHandler = getSSRPlaceholderHandler;
369
+ this.searchPageConfig = searchPageConfig;
349
370
  }
350
371
  return _createClass(ViewportObserver, [{
351
372
  key: "initializeObservers",
@@ -0,0 +1,14 @@
1
+ import { getDocument } from '@atlaskit/browser-apis';
2
+ export function isContainedWithinSmartAnswers(node) {
3
+ var doc = getDocument();
4
+ if (!doc) {
5
+ return false;
6
+ }
7
+ var smartAnswersElement = doc.getElementById('search-page-smart-answers');
8
+ if (!smartAnswersElement) {
9
+ return false;
10
+ }
11
+
12
+ // When the node is the smart answer element, .contains() still returns true
13
+ return smartAnswersElement.contains(node);
14
+ }
@@ -174,6 +174,7 @@ export type Config = {
174
174
  readonly extraSearchPageInteraction?: {
175
175
  readonly enabled: boolean;
176
176
  readonly searchPageMetricName: string;
177
+ readonly searchPageRoute: string;
177
178
  };
178
179
  readonly enableVCRawDataRates?: {
179
180
  readonly enabled?: boolean;
@@ -8,7 +8,7 @@ declare global {
8
8
  }
9
9
  export declare const DefaultInteractionID: InteractionIDContextType;
10
10
  export declare const subscribeToInteractionIdChanges: (listener: InteractionIDListener) => (() => void);
11
- declare const _default_1: Context<InteractionIDContextType>;
12
- export default _default_1;
11
+ declare const interactionContext: Context<InteractionIDContextType>;
12
+ export default interactionContext;
13
13
  export declare const getInteractionId: () => InteractionIDContextType;
14
14
  export declare const useInteractionId: () => InteractionIDContextType;
@@ -27,6 +27,19 @@ export type SelectorConfig = {
27
27
  className: boolean;
28
28
  dataVC?: boolean;
29
29
  };
30
+ export type SearchPageConfig = {
31
+ /**
32
+ * Whether to enable detection of smart answers mutations
33
+ */
34
+ enableSmartAnswersMutations?: boolean;
35
+ /**
36
+ * Route of the search page. If this is not specified, then all other VC
37
+ * configurations related to the search page will be ignored. This is
38
+ * done to ensure that search page specific computations are not performed
39
+ * for non-search page interactions.
40
+ */
41
+ searchPageRoute?: string;
42
+ };
30
43
  export type VCObserverOptions = {
31
44
  heatmapSize?: number | undefined;
32
45
  oldDomUpdates?: boolean | undefined;
@@ -35,6 +48,7 @@ export type VCObserverOptions = {
35
48
  isPostInteraction?: boolean;
36
49
  ssrEnablePageLayoutPlaceholder?: boolean;
37
50
  ssrPlaceholderHandler?: any;
51
+ searchPageConfig?: SearchPageConfig;
38
52
  };
39
53
  export interface VCObserverInterface {
40
54
  start(startArg: {
@@ -1,3 +1,4 @@
1
+ import type { SearchPageConfig } from '../../types';
1
2
  import { SSRPlaceholderHandlers } from './ssr-placeholders';
2
3
  import type { BrowserObservers, Callback } from './types';
3
4
  export type { ObservedMutationType } from './types';
@@ -14,6 +15,7 @@ type ConstructorOptions = {
14
15
  enablePageLayoutPlaceholder: boolean;
15
16
  };
16
17
  ssrPlaceholderHandler?: SSRPlaceholderHandlers | null;
18
+ searchPageConfig?: SearchPageConfig;
17
19
  };
18
20
  export declare class Observers implements BrowserObservers {
19
21
  private intersectionObserver;
@@ -1,4 +1,5 @@
1
1
  import { type RevisionPayloadEntry } from '../../common/vc/types';
2
+ import type { SearchPageConfig } from '../types';
2
3
  import { SSRPlaceholderHandlers } from '../vc-observer/observers/ssr-placeholders';
3
4
  import { type SelectorConfig } from './get-element-name';
4
5
  import type { VCObserverGetVCResultParam } from './types';
@@ -9,6 +10,7 @@ export type VCObserverNewConfig = {
9
10
  enablePageLayoutPlaceholder?: boolean;
10
11
  };
11
12
  ssrPlaceholderHandler?: SSRPlaceholderHandlers | null;
13
+ searchPageConfig?: SearchPageConfig;
12
14
  };
13
15
  declare const SSRState: {
14
16
  readonly normal: 1;
@@ -2,5 +2,5 @@ import type { VCObserverEntry } from '../../types';
2
2
  import VCCalculator_FY25_03 from '../fy25_03';
3
3
  export default class VCCalculator_FY26_04 extends VCCalculator_FY25_03 {
4
4
  constructor();
5
- protected isEntryIncluded(entry: VCObserverEntry, include3p?: boolean): boolean;
5
+ protected isEntryIncluded(entry: VCObserverEntry, include3p?: boolean, excludeSmartAnswersInSearch?: boolean): boolean;
6
6
  }
@@ -1,6 +1,6 @@
1
1
  import type { AbortReasonType, InteractionType } from '../../common/common/types';
2
2
  import type { ObservedWindowEvent } from './window-event-observer';
3
- export type VCObserverEntryType = 'mutation:child-element' | 'mutation:remount' | 'mutation:element' | 'mutation:element-replacement' | 'mutation:display-contents-children-element' | 'mutation:display-contents-children-attribute' | 'mutation:attribute:no-layout-shift' | 'mutation:attribute:non-visual-style' | 'mutation:attribute:non-visual-input-name' | 'mutation:attribute' | 'mutation:media' | 'mutation:rll-placeholder' | 'mutation:third-party-element' | 'mutation:third-party-attribute' | 'mutation:ssr-placeholder' | 'layout-shift' | 'layout-shift:same-rect' | 'window:event' | 'ssr-hydration' | 'unknown';
3
+ export type VCObserverEntryType = 'mutation:child-element' | 'mutation:remount' | 'mutation:element' | 'mutation:element-replacement' | 'mutation:display-contents-children-element' | 'mutation:display-contents-children-attribute' | 'mutation:attribute:no-layout-shift' | 'mutation:attribute:non-visual-style' | 'mutation:attribute:non-visual-input-name' | 'mutation:attribute' | 'mutation:media' | 'mutation:rll-placeholder' | 'mutation:third-party-element' | 'mutation:third-party-attribute' | 'mutation:smart-answers-element' | 'mutation:smart-answers-attribute' | 'mutation:ssr-placeholder' | 'layout-shift' | 'layout-shift:same-rect' | 'window:event' | 'ssr-hydration' | 'unknown';
4
4
  export type ViewportEntryData = {
5
5
  readonly type: VCObserverEntryType;
6
6
  readonly elementName: string;
@@ -1,3 +1,4 @@
1
+ import type { SearchPageConfig } from '../../types';
1
2
  import { type VCObserverEntryType } from '../types';
2
3
  import { type MutationData } from './types';
3
4
  export type ViewPortObserverConstructorArgs = {
@@ -12,6 +13,7 @@ export type ViewPortObserverConstructorArgs = {
12
13
  }): void;
13
14
  getSSRState?: () => any;
14
15
  getSSRPlaceholderHandler?: () => any;
16
+ searchPageConfig?: SearchPageConfig;
15
17
  };
16
18
  export default class ViewportObserver {
17
19
  private intersectionObserver;
@@ -21,14 +23,16 @@ export default class ViewportObserver {
21
23
  private mapIs3pResult;
22
24
  private onChange;
23
25
  private isStarted;
26
+ private searchPageConfig;
24
27
  private getSSRState?;
25
28
  private getSSRPlaceholderHandler?;
26
- constructor({ onChange, getSSRState, getSSRPlaceholderHandler, }: ViewPortObserverConstructorArgs);
29
+ constructor({ onChange, getSSRState, getSSRPlaceholderHandler, searchPageConfig, }: ViewPortObserverConstructorArgs);
27
30
  private handleIntersectionEntry;
28
31
  private handleChildListMutation;
29
32
  private handleAttributeMutation;
30
33
  private handleLayoutShift;
31
34
  private initializeObservers;
35
+ private shouldCheckSmartAnswersMutations;
32
36
  start(): void;
33
37
  stop(): void;
34
38
  }
@@ -0,0 +1 @@
1
+ export declare function isContainedWithinSmartAnswers(node: HTMLElement): boolean;
@@ -174,6 +174,7 @@ export type Config = {
174
174
  readonly extraSearchPageInteraction?: {
175
175
  readonly enabled: boolean;
176
176
  readonly searchPageMetricName: string;
177
+ readonly searchPageRoute: string;
177
178
  };
178
179
  readonly enableVCRawDataRates?: {
179
180
  readonly enabled?: boolean;
@@ -8,7 +8,7 @@ declare global {
8
8
  }
9
9
  export declare const DefaultInteractionID: InteractionIDContextType;
10
10
  export declare const subscribeToInteractionIdChanges: (listener: InteractionIDListener) => (() => void);
11
- declare const _default_1: Context<InteractionIDContextType>;
12
- export default _default_1;
11
+ declare const interactionContext: Context<InteractionIDContextType>;
12
+ export default interactionContext;
13
13
  export declare const getInteractionId: () => InteractionIDContextType;
14
14
  export declare const useInteractionId: () => InteractionIDContextType;
@@ -27,6 +27,19 @@ export type SelectorConfig = {
27
27
  className: boolean;
28
28
  dataVC?: boolean;
29
29
  };
30
+ export type SearchPageConfig = {
31
+ /**
32
+ * Whether to enable detection of smart answers mutations
33
+ */
34
+ enableSmartAnswersMutations?: boolean;
35
+ /**
36
+ * Route of the search page. If this is not specified, then all other VC
37
+ * configurations related to the search page will be ignored. This is
38
+ * done to ensure that search page specific computations are not performed
39
+ * for non-search page interactions.
40
+ */
41
+ searchPageRoute?: string;
42
+ };
30
43
  export type VCObserverOptions = {
31
44
  heatmapSize?: number | undefined;
32
45
  oldDomUpdates?: boolean | undefined;
@@ -35,6 +48,7 @@ export type VCObserverOptions = {
35
48
  isPostInteraction?: boolean;
36
49
  ssrEnablePageLayoutPlaceholder?: boolean;
37
50
  ssrPlaceholderHandler?: any;
51
+ searchPageConfig?: SearchPageConfig;
38
52
  };
39
53
  export interface VCObserverInterface {
40
54
  start(startArg: {
@@ -1,3 +1,4 @@
1
+ import type { SearchPageConfig } from '../../types';
1
2
  import { SSRPlaceholderHandlers } from './ssr-placeholders';
2
3
  import type { BrowserObservers, Callback } from './types';
3
4
  export type { ObservedMutationType } from './types';
@@ -14,6 +15,7 @@ type ConstructorOptions = {
14
15
  enablePageLayoutPlaceholder: boolean;
15
16
  };
16
17
  ssrPlaceholderHandler?: SSRPlaceholderHandlers | null;
18
+ searchPageConfig?: SearchPageConfig;
17
19
  };
18
20
  export declare class Observers implements BrowserObservers {
19
21
  private intersectionObserver;