@atlaskit/react-ufo 5.2.9 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/create-payload/index.js +6 -5
  3. package/dist/cjs/hidden-timing/index.js +52 -0
  4. package/dist/cjs/interaction-metrics/index.js +1 -0
  5. package/dist/cjs/interaction-metrics-init/index.js +2 -1
  6. package/dist/cjs/vc/index.js +4 -2
  7. package/dist/cjs/vc/vc-observer-new/index.js +10 -4
  8. package/dist/cjs/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +84 -29
  9. package/dist/cjs/vc/vc-observer-new/metric-calculator/utils/detect-layout-shift-cause.js +164 -0
  10. package/dist/cjs/vc/vc-observer-new/viewport-observer/index.js +173 -34
  11. package/dist/cjs/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +1 -1
  12. package/dist/cjs/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +2 -1
  13. package/dist/es2019/create-payload/index.js +5 -3
  14. package/dist/es2019/hidden-timing/index.js +51 -0
  15. package/dist/es2019/interaction-metrics/index.js +1 -0
  16. package/dist/es2019/interaction-metrics-init/index.js +2 -1
  17. package/dist/es2019/vc/index.js +4 -2
  18. package/dist/es2019/vc/vc-observer-new/index.js +10 -5
  19. package/dist/es2019/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +61 -7
  20. package/dist/es2019/vc/vc-observer-new/metric-calculator/utils/detect-layout-shift-cause.js +138 -0
  21. package/dist/es2019/vc/vc-observer-new/viewport-observer/index.js +145 -10
  22. package/dist/es2019/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +1 -1
  23. package/dist/es2019/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +2 -1
  24. package/dist/esm/create-payload/index.js +7 -6
  25. package/dist/esm/hidden-timing/index.js +51 -0
  26. package/dist/esm/interaction-metrics/index.js +1 -0
  27. package/dist/esm/interaction-metrics-init/index.js +2 -1
  28. package/dist/esm/vc/index.js +4 -2
  29. package/dist/esm/vc/vc-observer-new/index.js +10 -4
  30. package/dist/esm/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +84 -29
  31. package/dist/esm/vc/vc-observer-new/metric-calculator/utils/detect-layout-shift-cause.js +158 -0
  32. package/dist/esm/vc/vc-observer-new/viewport-observer/index.js +173 -34
  33. package/dist/esm/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +1 -1
  34. package/dist/esm/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +2 -1
  35. package/dist/types/common/react-ufo-payload-schema.d.ts +2 -0
  36. package/dist/types/common/vc/types.d.ts +55 -0
  37. package/dist/types/config/index.d.ts +1 -0
  38. package/dist/types/hidden-timing/index.d.ts +9 -0
  39. package/dist/types/vc/types.d.ts +2 -0
  40. package/dist/types/vc/vc-observer-new/index.d.ts +2 -0
  41. package/dist/types/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +1 -1
  42. package/dist/types/vc/vc-observer-new/metric-calculator/types.d.ts +1 -0
  43. package/dist/types/vc/vc-observer-new/metric-calculator/utils/detect-layout-shift-cause.d.ts +31 -0
  44. package/dist/types/vc/vc-observer-new/types.d.ts +2 -0
  45. package/dist/types/vc/vc-observer-new/viewport-observer/index.d.ts +3 -1
  46. package/dist/types/vc/vc-observer-new/viewport-observer/mutation-observer/index.d.ts +1 -0
  47. package/dist/types/vc/vc-observer-new/viewport-observer/types.d.ts +5 -2
  48. package/dist/types-ts4.5/common/react-ufo-payload-schema.d.ts +2 -0
  49. package/dist/types-ts4.5/common/vc/types.d.ts +55 -0
  50. package/dist/types-ts4.5/config/index.d.ts +1 -0
  51. package/dist/types-ts4.5/hidden-timing/index.d.ts +9 -0
  52. package/dist/types-ts4.5/vc/types.d.ts +2 -0
  53. package/dist/types-ts4.5/vc/vc-observer-new/index.d.ts +2 -0
  54. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +1 -1
  55. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/types.d.ts +1 -0
  56. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/utils/detect-layout-shift-cause.d.ts +31 -0
  57. package/dist/types-ts4.5/vc/vc-observer-new/types.d.ts +2 -0
  58. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/index.d.ts +3 -1
  59. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/mutation-observer/index.d.ts +1 -0
  60. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/types.d.ts +5 -2
  61. package/package.json +4 -1
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.detectLayoutShiftCause = void 0;
7
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
8
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
9
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
10
+ var calculateOffenderState = function calculateOffenderState(current, matchesCurrentEntry) {
11
+ // Once we know it's mixed across entries, we can short-circuit.
12
+ if (current === 'some') {
13
+ return 'some';
14
+ }
15
+ var entryState = matchesCurrentEntry ? 'all' : 'none';
16
+ if (current == null) {
17
+ return entryState;
18
+ }
19
+
20
+ // If the state flips between entries (all <-> none), it's "some".
21
+ if (current !== entryState) {
22
+ return 'some';
23
+ }
24
+ return current;
25
+ };
26
+ var calculateLayoutShiftMovement = function calculateLayoutShiftMovement(layoutShiftEntries) {
27
+ var movements = layoutShiftEntries.map(function (lsEntry) {
28
+ var rect = lsEntry.rect;
29
+ var previousRect = lsEntry.previousRect;
30
+ if (!rect || !previousRect) {
31
+ return null;
32
+ }
33
+ var dx = rect.x - previousRect.x;
34
+ var dy = rect.y - previousRect.y;
35
+ return {
36
+ dx: dx,
37
+ dy: dy,
38
+ movedX: dx !== 0,
39
+ movedY: dy !== 0,
40
+ dirX: Math.sign(dx),
41
+ dirY: Math.sign(dy),
42
+ absDx: Math.abs(dx),
43
+ absDy: Math.abs(dy)
44
+ };
45
+ });
46
+ var hasMovement = function hasMovement(m) {
47
+ return m !== null;
48
+ };
49
+ var validMovements = movements.filter(hasMovement);
50
+ var allHaveRects = layoutShiftEntries.length > 0 && validMovements.length === layoutShiftEntries.length;
51
+ if (!allHaveRects) {
52
+ return {
53
+ allHaveRects: allHaveRects,
54
+ allMovedSameWay: false,
55
+ allMovedSameAmount: false
56
+ };
57
+ }
58
+ var first = validMovements[0];
59
+ var allMovedSameWay = validMovements.every(function (m) {
60
+ return m.movedX === first.movedX && m.movedY === first.movedY && m.dirX === first.dirX && m.dirY === first.dirY;
61
+ });
62
+ var allMovedSameAmount = allMovedSameWay && validMovements.every(function (m) {
63
+ return m.absDx === first.absDx && m.absDy === first.absDy;
64
+ });
65
+ return {
66
+ allHaveRects: allHaveRects,
67
+ allMovedSameWay: allMovedSameWay,
68
+ allMovedSameAmount: allMovedSameAmount,
69
+ deltaX: first.dx,
70
+ deltaY: first.dy
71
+ };
72
+ };
73
+ var detectLayoutShiftCause = exports.detectLayoutShiftCause = function detectLayoutShiftCause(_ref) {
74
+ var viewportEntries = _ref.viewportEntries,
75
+ layoutShiftEntries = _ref.layoutShiftEntries,
76
+ time = _ref.time,
77
+ startTime = _ref.startTime,
78
+ _ref$offenderWindowMs = _ref.offenderWindowMs,
79
+ offenderWindowMs = _ref$offenderWindowMs === void 0 ? 250 : _ref$offenderWindowMs;
80
+ var checkpointTimestamp = startTime + time;
81
+ var filteredLSPotentialOffenders = viewportEntries.filter(function (viewportEntry) {
82
+ return (viewportEntry.time < checkpointTimestamp && viewportEntry.time > checkpointTimestamp - offenderWindowMs || viewportEntry.time > checkpointTimestamp && viewportEntry.time < checkpointTimestamp + offenderWindowMs) && viewportEntry.data.type !== 'layout-shift';
83
+ });
84
+
85
+ // Summarize whether all layout-shift entries moved in a consistent direction and by the same amount.
86
+ var layoutShiftVariables = calculateLayoutShiftMovement(layoutShiftEntries);
87
+
88
+ // Classify each offender against *all* layout-shift entries when the layout shift is consistently moving in a
89
+ // single axis (pure X or pure Y) so we can reason about whether an offender could have caused the movement.
90
+ var layoutShiftOffenders = filteredLSPotentialOffenders.reduce(function (acc, offender) {
91
+ var _offenderData$origina;
92
+ var offenderData = offender.data;
93
+ var offenderRect = offenderData.rect;
94
+ if (!offenderRect) {
95
+ return acc;
96
+ }
97
+ var offenderTimestamp = (_offenderData$origina = offenderData.originalMutationTimestamp) !== null && _offenderData$origina !== void 0 ? _offenderData$origina : offender.time;
98
+ var happenedBefore = offenderTimestamp <= checkpointTimestamp;
99
+ var offenderLeft = offenderRect.x;
100
+ var offenderRight = offenderRect.x + offenderRect.width;
101
+ var offenderTop = offenderRect.y;
102
+ var offenderBottom = offenderRect.y + offenderRect.height;
103
+ var shouldClassifyAgainstAllEntries = layoutShiftVariables.allMovedSameWay && 'deltaX' in layoutShiftVariables && 'deltaY' in layoutShiftVariables && layoutShiftVariables.deltaX === 0 !== (layoutShiftVariables.deltaY === 0);
104
+ var isAbove = null;
105
+ var isLeft = null;
106
+ var isRight = null;
107
+ var hasHorizontalOverlap = null;
108
+ var hasVerticalOverlap = null;
109
+ if (shouldClassifyAgainstAllEntries) {
110
+ var _iterator = _createForOfIteratorHelper(layoutShiftEntries),
111
+ _step;
112
+ try {
113
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
114
+ var lsEntry = _step.value;
115
+ var lsRect = lsEntry.rect;
116
+ if (!lsRect) {
117
+ continue;
118
+ }
119
+ var lsLeft = lsRect.x;
120
+ var lsRight = lsRect.x + lsRect.width;
121
+ var lsTop = lsRect.y;
122
+ var lsBottom = lsRect.y + lsRect.height;
123
+ isAbove = calculateOffenderState(isAbove, offenderBottom <= lsTop);
124
+ isLeft = calculateOffenderState(isLeft, offenderRight <= lsLeft);
125
+ isRight = calculateOffenderState(isRight, offenderLeft >= lsRight);
126
+ hasHorizontalOverlap = calculateOffenderState(hasHorizontalOverlap, offenderLeft < lsRight && offenderRight > lsLeft);
127
+ hasVerticalOverlap = calculateOffenderState(hasVerticalOverlap, offenderTop < lsBottom && offenderBottom > lsTop);
128
+ }
129
+ } catch (err) {
130
+ _iterator.e(err);
131
+ } finally {
132
+ _iterator.f();
133
+ }
134
+ }
135
+ var matchesLayoutShiftDelta = false;
136
+ if (shouldClassifyAgainstAllEntries && layoutShiftVariables.allMovedSameAmount && offenderData.previousRect) {
137
+ var dx = offenderRect.x - offenderData.previousRect.x;
138
+ var dy = offenderRect.y - offenderData.previousRect.y;
139
+ var isPureX = layoutShiftVariables.deltaX !== 0 && layoutShiftVariables.deltaY === 0;
140
+ var isPureY = layoutShiftVariables.deltaY !== 0 && layoutShiftVariables.deltaX === 0;
141
+ if (isPureX) {
142
+ matchesLayoutShiftDelta = dx === layoutShiftVariables.deltaX && dy === 0;
143
+ } else if (isPureY) {
144
+ matchesLayoutShiftDelta = dy === layoutShiftVariables.deltaY && dx === 0;
145
+ }
146
+ }
147
+ acc.push({
148
+ offender: offenderData.elementName,
149
+ happenedBefore: happenedBefore,
150
+ distanceToLS: Math.round(offenderTimestamp - checkpointTimestamp),
151
+ isAbove: isAbove !== null && isAbove !== void 0 ? isAbove : 'none',
152
+ isLeft: isLeft !== null && isLeft !== void 0 ? isLeft : 'none',
153
+ isRight: isRight !== null && isRight !== void 0 ? isRight : 'none',
154
+ hasHorizontalOverlap: hasHorizontalOverlap !== null && hasHorizontalOverlap !== void 0 ? hasHorizontalOverlap : 'none',
155
+ hasVerticalOverlap: hasVerticalOverlap !== null && hasVerticalOverlap !== void 0 ? hasVerticalOverlap : 'none',
156
+ matchesLayoutShiftDelta: matchesLayoutShiftDelta
157
+ });
158
+ return acc;
159
+ }, []);
160
+ return {
161
+ layoutShiftVariables: layoutShiftVariables,
162
+ layoutShiftOffenders: layoutShiftOffenders
163
+ };
164
+ };
@@ -97,22 +97,151 @@ var createElementMutationsWatcher = function createElementMutationsWatcher(remov
97
97
  return 'mutation:element';
98
98
  };
99
99
  };
100
+ var createElementMutationsWatcherNew = function createElementMutationsWatcherNew(removedNodeRects, isWithinThirdPartySegment, isWithinSmartAnswersSegment, hasSameDeletedNode, timestamp, isTargetReactRoot, getSSRState, getSSRPlaceholderHandler) {
101
+ return function (_ref2) {
102
+ var target = _ref2.target,
103
+ rect = _ref2.rect;
104
+ if (getSSRState) {
105
+ var ssrState = getSSRState();
106
+ var SSRStateEnum = {
107
+ normal: 1,
108
+ waitingForFirstRender: 2,
109
+ ignoring: 3
110
+ };
111
+ if (ssrState.state === SSRStateEnum.waitingForFirstRender && timestamp > ssrState.renderStart && isTargetReactRoot) {
112
+ ssrState.state = SSRStateEnum.ignoring;
113
+ if (ssrState.renderStop === -1) {
114
+ // arbitrary 500ms DOM update window
115
+ ssrState.renderStop = timestamp + 500;
116
+ }
117
+ return {
118
+ type: 'ssr-hydration',
119
+ mutationData: {
120
+ timestamp: timestamp
121
+ }
122
+ };
123
+ }
124
+ if (ssrState.state === SSRStateEnum.ignoring && timestamp > ssrState.renderStart && isTargetReactRoot) {
125
+ if (timestamp <= ssrState.renderStop) {
126
+ return {
127
+ type: 'ssr-hydration',
128
+ mutationData: {
129
+ timestamp: timestamp
130
+ }
131
+ };
132
+ } else {
133
+ ssrState.state = SSRStateEnum.normal;
134
+ }
135
+ }
136
+ }
137
+ if (getSSRPlaceholderHandler) {
138
+ var ssrPlaceholderHandler = getSSRPlaceholderHandler();
139
+ if (ssrPlaceholderHandler) {
140
+ if ((ssrPlaceholderHandler.isPlaceholderV4(target) || ssrPlaceholderHandler.isPlaceholderIgnored(target)) && ssrPlaceholderHandler.checkIfExistedAndSizeMatchingV3(target)) {
141
+ return {
142
+ type: 'mutation:ssr-placeholder',
143
+ mutationData: {
144
+ timestamp: timestamp
145
+ }
146
+ };
147
+ }
148
+ if ((ssrPlaceholderHandler.isPlaceholderReplacementV4(target) || ssrPlaceholderHandler.isPlaceholderIgnored(target)) && ssrPlaceholderHandler.validateReactComponentMatchToPlaceholderV4(target)) {
149
+ return {
150
+ type: 'mutation:ssr-placeholder',
151
+ mutationData: {
152
+ timestamp: timestamp
153
+ }
154
+ };
155
+ }
156
+ }
157
+ }
158
+ if (hasSameDeletedNode && (0, _isInVcIgnoreIfNoLayoutShiftMarker.default)(target)) {
159
+ return {
160
+ type: 'mutation:remount',
161
+ mutationData: {
162
+ timestamp: timestamp
163
+ }
164
+ };
165
+ }
166
+ if ((0, _vcUtils.isContainedWithinMediaWrapper)(target)) {
167
+ return {
168
+ type: 'mutation:media',
169
+ mutationData: {
170
+ timestamp: timestamp
171
+ }
172
+ };
173
+ }
174
+ if (isWithinThirdPartySegment) {
175
+ return {
176
+ type: 'mutation:third-party-element',
177
+ mutationData: {
178
+ timestamp: timestamp
179
+ }
180
+ };
181
+ }
182
+ if (isWithinSmartAnswersSegment) {
183
+ return {
184
+ type: 'mutation:smart-answers-element',
185
+ mutationData: {
186
+ timestamp: timestamp
187
+ }
188
+ };
189
+ }
190
+ var isInIgnoreLsMarker = (0, _isInVcIgnoreIfNoLayoutShiftMarker.default)(target);
191
+ if (!isInIgnoreLsMarker) {
192
+ return {
193
+ type: 'mutation:element',
194
+ mutationData: {
195
+ timestamp: timestamp
196
+ }
197
+ };
198
+ }
199
+ var isRLLPlaceholder = _rllPlaceholders.RLLPlaceholderHandlers.getInstance().isRLLPlaceholderHydration(rect);
200
+ if (isRLLPlaceholder && isInIgnoreLsMarker) {
201
+ return {
202
+ type: 'mutation:rll-placeholder',
203
+ mutationData: {
204
+ timestamp: timestamp
205
+ }
206
+ };
207
+ }
208
+ var wasDeleted = removedNodeRects.some(function (nr) {
209
+ return (0, _isSameRectDimensions.isSameRectDimensions)(nr, rect);
210
+ });
211
+ if (wasDeleted && isInIgnoreLsMarker) {
212
+ return {
213
+ type: 'mutation:element-replacement',
214
+ mutationData: {
215
+ timestamp: timestamp
216
+ }
217
+ };
218
+ }
219
+ return {
220
+ type: 'mutation:element',
221
+ mutationData: {
222
+ timestamp: timestamp
223
+ }
224
+ };
225
+ };
226
+ };
100
227
  var ViewportObserver = exports.default = /*#__PURE__*/function () {
101
228
  // SSR context functions
102
229
 
103
- function ViewportObserver(_ref2) {
230
+ function ViewportObserver(_ref3) {
104
231
  var _this = this;
105
- var onChange = _ref2.onChange,
106
- getSSRState = _ref2.getSSRState,
107
- getSSRPlaceholderHandler = _ref2.getSSRPlaceholderHandler,
108
- searchPageConfig = _ref2.searchPageConfig;
232
+ var onChange = _ref3.onChange,
233
+ getSSRState = _ref3.getSSRState,
234
+ getSSRPlaceholderHandler = _ref3.getSSRPlaceholderHandler,
235
+ _ref3$trackLayoutShif = _ref3.trackLayoutShiftOffenders,
236
+ trackLayoutShiftOffenders = _ref3$trackLayoutShif === void 0 ? false : _ref3$trackLayoutShif,
237
+ searchPageConfig = _ref3.searchPageConfig;
109
238
  (0, _classCallCheck2.default)(this, ViewportObserver);
110
- (0, _defineProperty2.default)(this, "handleIntersectionEntry", function (_ref3) {
111
- var target = _ref3.target,
112
- rect = _ref3.rect,
113
- time = _ref3.time,
114
- type = _ref3.type,
115
- mutationData = _ref3.mutationData;
239
+ (0, _defineProperty2.default)(this, "handleIntersectionEntry", function (_ref4) {
240
+ var target = _ref4.target,
241
+ rect = _ref4.rect,
242
+ time = _ref4.time,
243
+ type = _ref4.type,
244
+ mutationData = _ref4.mutationData;
116
245
  if (!target) {
117
246
  return;
118
247
  }
@@ -130,12 +259,12 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
130
259
  });
131
260
  });
132
261
  (0, _defineProperty2.default)(this, "handleChildListMutation", /*#__PURE__*/function () {
133
- var _ref5 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref4) {
262
+ var _ref6 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref5) {
134
263
  var target, addedNodes, removedNodes, timestamp, removedNodeRects, targetNode, _iterator, _step, _loop;
135
264
  return _regenerator.default.wrap(function _callee$(_context2) {
136
265
  while (1) switch (_context2.prev = _context2.next) {
137
266
  case 0:
138
- target = _ref4.target, addedNodes = _ref4.addedNodes, removedNodes = _ref4.removedNodes, timestamp = _ref4.timestamp;
267
+ target = _ref5.target, addedNodes = _ref5.addedNodes, removedNodes = _ref5.removedNodes, timestamp = _ref5.timestamp;
139
268
  removedNodeRects = removedNodes.map(function (ref) {
140
269
  var n = ref.deref();
141
270
  if (!n) {
@@ -170,7 +299,7 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
170
299
  _checkWithinComponent = (0, _checkWithinComponent3.default)(addedNode, 'UFOThirdPartySegment', _this.mapIs3pResult), isWithinThirdPartySegment = _checkWithinComponent.isWithin;
171
300
  isWithinSmartAnswersSegment = Boolean(_this.shouldCheckSmartAnswersMutations() && (0, _isContainedWithinSmartAnswers.isContainedWithinSmartAnswers)(addedNode));
172
301
  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);
173
- (_this$intersectionObs = _this.intersectionObserver) === null || _this$intersectionObs === void 0 || _this$intersectionObs.watchAndTag(addedNode, createElementMutationsWatcher(removedNodeRects, isWithinThirdPartySegment, isWithinSmartAnswersSegment, !!hasSameDeletedNode, timestamp, isTargetReactRoot, _this.getSSRState, _this.getSSRPlaceholderHandler));
302
+ (_this$intersectionObs = _this.intersectionObserver) === null || _this$intersectionObs === void 0 || _this$intersectionObs.watchAndTag(addedNode, (_this.trackLayoutShiftOffenders ? createElementMutationsWatcherNew : createElementMutationsWatcher)(removedNodeRects, isWithinThirdPartySegment, isWithinSmartAnswersSegment, !!hasSameDeletedNode, timestamp, isTargetReactRoot, _this.getSSRState, _this.getSSRPlaceholderHandler));
174
303
  case 9:
175
304
  case "end":
176
305
  return _context.stop();
@@ -211,25 +340,27 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
211
340
  }, _callee, null, [[4, 15, 18, 21]]);
212
341
  }));
213
342
  return function (_x) {
214
- return _ref5.apply(this, arguments);
343
+ return _ref6.apply(this, arguments);
215
344
  };
216
345
  }());
217
- (0, _defineProperty2.default)(this, "handleAttributeMutation", function (_ref6) {
346
+ (0, _defineProperty2.default)(this, "handleAttributeMutation", function (_ref7) {
218
347
  var _this$intersectionObs2;
219
- var target = _ref6.target,
220
- attributeName = _ref6.attributeName,
221
- oldValue = _ref6.oldValue,
222
- newValue = _ref6.newValue;
223
- (_this$intersectionObs2 = _this.intersectionObserver) === null || _this$intersectionObs2 === void 0 || _this$intersectionObs2.watchAndTag(target, function (_ref7) {
224
- var target = _ref7.target,
225
- rect = _ref7.rect;
348
+ var target = _ref7.target,
349
+ attributeName = _ref7.attributeName,
350
+ oldValue = _ref7.oldValue,
351
+ newValue = _ref7.newValue,
352
+ timestamp = _ref7.timestamp;
353
+ (_this$intersectionObs2 = _this.intersectionObserver) === null || _this$intersectionObs2 === void 0 || _this$intersectionObs2.watchAndTag(target, function (_ref8) {
354
+ var target = _ref8.target,
355
+ rect = _ref8.rect;
226
356
  if ((0, _vcUtils.isContainedWithinMediaWrapper)(target)) {
227
357
  return {
228
358
  type: 'mutation:media',
229
359
  mutationData: {
230
360
  attributeName: attributeName,
231
361
  oldValue: oldValue,
232
- newValue: newValue
362
+ newValue: newValue,
363
+ timestamp: timestamp
233
364
  }
234
365
  };
235
366
  }
@@ -242,7 +373,8 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
242
373
  mutationData: {
243
374
  attributeName: attributeName,
244
375
  oldValue: oldValue,
245
- newValue: newValue
376
+ newValue: newValue,
377
+ timestamp: timestamp
246
378
  }
247
379
  };
248
380
  }
@@ -268,7 +400,8 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
268
400
  mutationData: {
269
401
  attributeName: attributeName,
270
402
  oldValue: oldValue,
271
- newValue: newValue
403
+ newValue: newValue,
404
+ timestamp: timestamp
272
405
  }
273
406
  };
274
407
  }
@@ -282,7 +415,8 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
282
415
  mutationData: {
283
416
  attributeName: attributeName,
284
417
  oldValue: oldValue,
285
- newValue: newValue
418
+ newValue: newValue,
419
+ timestamp: timestamp
286
420
  }
287
421
  };
288
422
  }
@@ -297,7 +431,8 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
297
431
  mutationData: {
298
432
  attributeName: attributeName,
299
433
  oldValue: oldValue,
300
- newValue: newValue
434
+ newValue: newValue,
435
+ timestamp: timestamp
301
436
  }
302
437
  };
303
438
  }
@@ -308,7 +443,8 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
308
443
  mutationData: {
309
444
  attributeName: attributeName,
310
445
  oldValue: oldValue,
311
- newValue: newValue
446
+ newValue: newValue,
447
+ timestamp: timestamp
312
448
  }
313
449
  };
314
450
  }
@@ -319,7 +455,8 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
319
455
  mutationData: {
320
456
  attributeName: attributeName,
321
457
  oldValue: oldValue,
322
- newValue: newValue
458
+ newValue: newValue,
459
+ timestamp: timestamp
323
460
  }
324
461
  };
325
462
  }
@@ -328,14 +465,15 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
328
465
  mutationData: {
329
466
  attributeName: attributeName,
330
467
  oldValue: oldValue,
331
- newValue: newValue
468
+ newValue: newValue,
469
+ timestamp: timestamp
332
470
  }
333
471
  };
334
472
  });
335
473
  });
336
- (0, _defineProperty2.default)(this, "handleLayoutShift", function (_ref8) {
337
- var time = _ref8.time,
338
- changedRects = _ref8.changedRects;
474
+ (0, _defineProperty2.default)(this, "handleLayoutShift", function (_ref9) {
475
+ var time = _ref9.time,
476
+ changedRects = _ref9.changedRects;
339
477
  var _iterator2 = _createForOfIteratorHelper(changedRects),
340
478
  _step2;
341
479
  try {
@@ -371,6 +509,7 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
371
509
  this.intersectionObserver = null;
372
510
  this.mutationObserver = null;
373
511
  this.performanceObserver = null;
512
+ this.trackLayoutShiftOffenders = trackLayoutShiftOffenders;
374
513
 
375
514
  // Initialize SSR context functions
376
515
  this.getSSRState = getSSRState;
@@ -36,7 +36,7 @@ function createIntersectionObserver(_ref) {
36
36
  }
37
37
 
38
38
  // override as display-contents mutation
39
- if (tagOrCallbackResult && typeof tagOrCallbackResult !== 'string' && tagOrCallbackResult.type === 'mutation:attribute') {
39
+ if (tagOrCallbackResult && typeof tagOrCallbackResult !== 'string' && tagOrCallbackResult.type === 'mutation:attribute' && 'oldValue' in tagOrCallbackResult.mutationData) {
40
40
  var _tagOrCallbackResult$ = tagOrCallbackResult.mutationData,
41
41
  attributeName = _tagOrCallbackResult$.attributeName,
42
42
  oldValue = _tagOrCallbackResult$.oldValue,
@@ -58,7 +58,8 @@ function createMutationObserver(_ref) {
58
58
  target: mut.target,
59
59
  attributeName: (_mut$attributeName = mut.attributeName) !== null && _mut$attributeName !== void 0 ? _mut$attributeName : 'unknown',
60
60
  oldValue: oldValue,
61
- newValue: newValue
61
+ newValue: newValue,
62
+ timestamp: mut.timestamp || performance.now()
62
63
  });
63
64
  }
64
65
  return 0; // continue
@@ -1,5 +1,5 @@
1
1
  import{getDocument}from'@atlaskit/browser-apis';import{fg}from'@atlaskit/platform-feature-flags';// Import common utilities
2
- import{getLighthouseMetrics}from'../additional-payload';import{CHRReporter}from'../assets';import*as bundleEvalTiming from'../bundle-eval-timing';import coinflip from'../coinflip';import{getConfig,getExperimentalInteractionRate,getUfoNameOverrides,shouldUseRawDataThirdPartyBehavior}from'../config';import{getExperimentalVCMetrics}from'../create-experimental-interaction-metrics-payload';import{getBm3Timings}from'../custom-timings';import{getGlobalErrorCount}from'../global-error-handler';import{getEarliestHiddenTiming,getHasHiddenTimingBeforeSetup,getPageVisibilityState,isOpenedInBackground,isTabThrottled}from'../hidden-timing';import*as initialPageLoadExtraTiming from'../initial-page-load-extra-timing';import{interactionSpans as atlaskitInteractionSpans}from'../interaction-metrics';import{createMemoryStateReport,createPressureStateReport}from'../machine-utilisation';import*as resourceTiming from'../resource-timing';import{filterResourceTimings}from'../resource-timing/common/utils/resource-timing-buffer';import{roundEpsilon}from'../round-number';import*as ssr from'../ssr';import{getHasAbortingEventDuringSSR}from'../vc/vc-observer-new';import{buildSegmentTree,getOldSegmentsLabelStack,labelStackStartWith,optimizeLabelStack,sanitizeUfoName,stringifyLabelStackFully}from'./common/utils';import{createCriticalMetricsPayloads}from'./critical-metrics-payload';import{addPerformanceMeasures}from'./utils/add-performance-measures';import{getBatteryInfoToLegacyFormat}from'./utils/get-battery-info';import{getBrowserMetadataToLegacyFormat}from'./utils/get-browser-metadata';import getInteractionStatus from'./utils/get-interaction-status';import{getMoreAccuratePageVisibilityUpToTTAI}from'./utils/get-more-accurate-page-visibility-up-to-ttai';import{getNavigationMetricsToLegacyFormat}from'./utils/get-navigation-metrics';import getPageVisibilityUpToTTAI from'./utils/get-page-visibility-up-to-ttai';import{getPaintMetricsToLegacyFormat}from'./utils/get-paint-metrics';import getPayloadSize from'./utils/get-payload-size';import{getReactUFOPayloadVersion}from'./utils/get-react-ufo-payload-version';import getSSRDoneTimeValue from'./utils/get-ssr-done-time-value';import getSSRSuccessUtil from'./utils/get-ssr-success';import getTTAI from'./utils/get-ttai';import getVCMetrics from'./utils/get-vc-metrics';import{getVisibilityStateFromPerformance}from'./utils/get-visibility-state-from-performance';import{optimizeApdex}from'./utils/optimize-apdex';import{optimizeCustomTimings}from'./utils/optimize-custom-timings';import{optimizeHoldInfo}from'./utils/optimize-hold-info';import{optimizeMarks}from'./utils/optimize-marks';import{optimizeReactProfilerTimings}from'./utils/optimize-react-profiler-timings';import{optimizeRequestInfo}from'./utils/optimize-request-info';import{optimizeSpans}from'./utils/optimize-spans';import{trimVcDebugData}from'./utils/trim-vc-debug-data';const MAX_PAYLOAD_SIZE=230;function getUfoNameOverride(interaction){const{ufoName,apdex}=interaction;try{const ufoNameOverrides=getUfoNameOverrides();if(ufoNameOverrides!=null){const metricKey=apdex.length>0?apdex[0].key:'';if(ufoNameOverrides[ufoName][metricKey]){return ufoNameOverrides[ufoName][metricKey];}}return ufoName;}catch{return ufoName;}}function getEarliestLegacyStopTime(interaction,labelStack){let earliestLegacyStopTime=null;interaction.apdex.forEach(a=>{var _a$labelStack,_earliestLegacyStopTi;if(!(a!==null&&a!==void 0&&a.stopTime)){return;}if(!labelStackStartWith((_a$labelStack=a.labelStack)!==null&&_a$labelStack!==void 0?_a$labelStack:[],labelStack)){return;}if(a.stopTime>interaction.start&&((_earliestLegacyStopTi=earliestLegacyStopTime)!==null&&_earliestLegacyStopTi!==void 0?_earliestLegacyStopTi:a.stopTime)>=a.stopTime){earliestLegacyStopTime=a.stopTime;}});return earliestLegacyStopTime;}function getBm3EndTimeOrFallbackValue(interaction,labelStack=[],fallbackValue=interaction.end){var _getEarliestLegacySto;if(interaction.type==='press'){return fallbackValue;}return(_getEarliestLegacySto=getEarliestLegacyStopTime(interaction,labelStack))!==null&&_getEarliestLegacySto!==void 0?_getEarliestLegacySto:fallbackValue;}function getPageVisibilityUpToTTI(interaction){const{start}=interaction;const bm3EndTimeOrInteractionEndTime=getBm3EndTimeOrFallbackValue(interaction);return getPageVisibilityState(start,bm3EndTimeOrInteractionEndTime);}function getMoreAccuratePageVisibilityUpToTTI(interaction){const old=getPageVisibilityUpToTTI(interaction);const tti=getEarliestLegacyStopTime(interaction,[]);if(!tti){return old;}const buffered=getVisibilityStateFromPerformance(tti);if(!buffered){return old;}if(buffered!==old){return'mixed';}return old;}function getResourceTimings(start,end){var _resourceTiming$getRe;return(_resourceTiming$getRe=resourceTiming.getResourceTimings(start,end))!==null&&_resourceTiming$getRe!==void 0?_resourceTiming$getRe:undefined;}function getBundleEvalTimings(start){return bundleEvalTiming.getBundleEvalTimings(start);}function getSSRPhaseSuccess(type){return type==='page_load'?ssr.getSSRPhaseSuccess():undefined;}function getSSRFeatureFlags(type){return type==='page_load'?ssr.getSSRFeatureFlags():undefined;}function getPPSMetrics(interaction){var _interaction$apdex,_interaction$apdex$;const{start,end}=interaction;const config=getConfig();const interactionStatus=getInteractionStatus(interaction);const pageVisibilityUpToTTAI=getPageVisibilityUpToTTAI(interaction);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;const ttai=interactionStatus.originalInteractionStatus==='SUCCEEDED'&&pageVisibilityUpToTTAI==='visible'?Math.round(end-start):undefined;const PPSMetricsAtTTI=tti!==undefined?getLighthouseMetrics({start,stop:tti}):null;const PPSMetricsAtTTAI=ttai!==undefined?getLighthouseMetrics({start,stop:interaction.end}):null;if(fg('platform_ufo_remove_deprecated_config_fields')){if(PPSMetricsAtTTAI!==null){return PPSMetricsAtTTAI;}}else{if(config!==null&&config!==void 0&&config.shouldCalculateLighthouseMetricsFromTTAI&&PPSMetricsAtTTAI!==null){return PPSMetricsAtTTAI;}if(PPSMetricsAtTTI!==null){return{...PPSMetricsAtTTI,'metrics@ttai':PPSMetricsAtTTAI};}}return{};}function getSSRProperties(type){const ssrPhases=getSSRPhaseSuccess(type);return{'ssr:success':(ssrPhases===null||ssrPhases===void 0?void 0:ssrPhases.done)!=null?ssrPhases.done:getSSRSuccessUtil(type),'ssr:featureFlags':getSSRFeatureFlags(type),...((ssrPhases===null||ssrPhases===void 0?void 0:ssrPhases.earlyFlush)!=null?{'ssr:earlyflush:success':ssrPhases.earlyFlush}:null),...((ssrPhases===null||ssrPhases===void 0?void 0:ssrPhases.prefetch)!=null?{'ssr:prefetch:success':ssrPhases.prefetch}:null)};}function getAssetsMetrics(interaction,SSRDoneTime){try{const config=getConfig();const{type}=interaction;const allowedTypes=['page_load'];const assetsConfig=config===null||config===void 0?void 0:config.assetsConfig;if(!allowedTypes.includes(type)||!assetsConfig){// Skip if: type not allowed or assetsClassification isn't configured
2
+ import{getLighthouseMetrics}from'../additional-payload';import{CHRReporter}from'../assets';import*as bundleEvalTiming from'../bundle-eval-timing';import coinflip from'../coinflip';import{getConfig,getExperimentalInteractionRate,getUfoNameOverrides,shouldUseRawDataThirdPartyBehavior}from'../config';import{getExperimentalVCMetrics}from'../create-experimental-interaction-metrics-payload';import{getBm3Timings}from'../custom-timings';import{getGlobalErrorCount}from'../global-error-handler';import{getEarliestHiddenTiming,getHasHiddenTimingBeforeSetup,getPageVisibilityState,getPageVisibilityTimeline,isOpenedInBackground,isTabThrottled}from'../hidden-timing';import*as initialPageLoadExtraTiming from'../initial-page-load-extra-timing';import{interactionSpans as atlaskitInteractionSpans}from'../interaction-metrics';import{createMemoryStateReport,createPressureStateReport}from'../machine-utilisation';import*as resourceTiming from'../resource-timing';import{filterResourceTimings}from'../resource-timing/common/utils/resource-timing-buffer';import{roundEpsilon}from'../round-number';import*as ssr from'../ssr';import{getHasAbortingEventDuringSSR}from'../vc/vc-observer-new';import{buildSegmentTree,getOldSegmentsLabelStack,labelStackStartWith,optimizeLabelStack,sanitizeUfoName,stringifyLabelStackFully}from'./common/utils';import{createCriticalMetricsPayloads}from'./critical-metrics-payload';import{addPerformanceMeasures}from'./utils/add-performance-measures';import{getBatteryInfoToLegacyFormat}from'./utils/get-battery-info';import{getBrowserMetadataToLegacyFormat}from'./utils/get-browser-metadata';import getInteractionStatus from'./utils/get-interaction-status';import{getMoreAccuratePageVisibilityUpToTTAI}from'./utils/get-more-accurate-page-visibility-up-to-ttai';import{getNavigationMetricsToLegacyFormat}from'./utils/get-navigation-metrics';import getPageVisibilityUpToTTAI from'./utils/get-page-visibility-up-to-ttai';import{getPaintMetricsToLegacyFormat}from'./utils/get-paint-metrics';import getPayloadSize from'./utils/get-payload-size';import{getReactUFOPayloadVersion}from'./utils/get-react-ufo-payload-version';import getSSRDoneTimeValue from'./utils/get-ssr-done-time-value';import getSSRSuccessUtil from'./utils/get-ssr-success';import getTTAI from'./utils/get-ttai';import getVCMetrics from'./utils/get-vc-metrics';import{getVisibilityStateFromPerformance}from'./utils/get-visibility-state-from-performance';import{optimizeApdex}from'./utils/optimize-apdex';import{optimizeCustomTimings}from'./utils/optimize-custom-timings';import{optimizeHoldInfo}from'./utils/optimize-hold-info';import{optimizeMarks}from'./utils/optimize-marks';import{optimizeReactProfilerTimings}from'./utils/optimize-react-profiler-timings';import{optimizeRequestInfo}from'./utils/optimize-request-info';import{optimizeSpans}from'./utils/optimize-spans';import{trimVcDebugData}from'./utils/trim-vc-debug-data';const MAX_PAYLOAD_SIZE=230;function getUfoNameOverride(interaction){const{ufoName,apdex}=interaction;try{const ufoNameOverrides=getUfoNameOverrides();if(ufoNameOverrides!=null){const metricKey=apdex.length>0?apdex[0].key:'';if(ufoNameOverrides[ufoName][metricKey]){return ufoNameOverrides[ufoName][metricKey];}}return ufoName;}catch{return ufoName;}}function getEarliestLegacyStopTime(interaction,labelStack){let earliestLegacyStopTime=null;interaction.apdex.forEach(a=>{var _a$labelStack,_earliestLegacyStopTi;if(!(a!==null&&a!==void 0&&a.stopTime)){return;}if(!labelStackStartWith((_a$labelStack=a.labelStack)!==null&&_a$labelStack!==void 0?_a$labelStack:[],labelStack)){return;}if(a.stopTime>interaction.start&&((_earliestLegacyStopTi=earliestLegacyStopTime)!==null&&_earliestLegacyStopTi!==void 0?_earliestLegacyStopTi:a.stopTime)>=a.stopTime){earliestLegacyStopTime=a.stopTime;}});return earliestLegacyStopTime;}function getBm3EndTimeOrFallbackValue(interaction,labelStack=[],fallbackValue=interaction.end){var _getEarliestLegacySto;if(interaction.type==='press'){return fallbackValue;}return(_getEarliestLegacySto=getEarliestLegacyStopTime(interaction,labelStack))!==null&&_getEarliestLegacySto!==void 0?_getEarliestLegacySto:fallbackValue;}function getPageVisibilityUpToTTI(interaction){const{start}=interaction;const bm3EndTimeOrInteractionEndTime=getBm3EndTimeOrFallbackValue(interaction);return getPageVisibilityState(start,bm3EndTimeOrInteractionEndTime);}function getMoreAccuratePageVisibilityUpToTTI(interaction){const old=getPageVisibilityUpToTTI(interaction);const tti=getEarliestLegacyStopTime(interaction,[]);if(!tti){return old;}const buffered=getVisibilityStateFromPerformance(tti);if(!buffered){return old;}if(buffered!==old){return'mixed';}return old;}function getResourceTimings(start,end){var _resourceTiming$getRe;return(_resourceTiming$getRe=resourceTiming.getResourceTimings(start,end))!==null&&_resourceTiming$getRe!==void 0?_resourceTiming$getRe:undefined;}function getBundleEvalTimings(start){return bundleEvalTiming.getBundleEvalTimings(start);}function getSSRPhaseSuccess(type){return type==='page_load'?ssr.getSSRPhaseSuccess():undefined;}function getSSRFeatureFlags(type){return type==='page_load'?ssr.getSSRFeatureFlags():undefined;}function getPPSMetrics(interaction){var _interaction$apdex,_interaction$apdex$;const{start,end}=interaction;const config=getConfig();const interactionStatus=getInteractionStatus(interaction);const pageVisibilityUpToTTAI=getPageVisibilityUpToTTAI(interaction);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;const ttai=interactionStatus.originalInteractionStatus==='SUCCEEDED'&&pageVisibilityUpToTTAI==='visible'?Math.round(end-start):undefined;const PPSMetricsAtTTI=tti!==undefined?getLighthouseMetrics({start,stop:tti}):null;const PPSMetricsAtTTAI=ttai!==undefined?getLighthouseMetrics({start,stop:interaction.end}):null;if(fg('platform_ufo_remove_deprecated_config_fields')){if(PPSMetricsAtTTAI!==null){return PPSMetricsAtTTAI;}}else{if(config!==null&&config!==void 0&&config.shouldCalculateLighthouseMetricsFromTTAI&&PPSMetricsAtTTAI!==null){return PPSMetricsAtTTAI;}if(PPSMetricsAtTTI!==null){return{...PPSMetricsAtTTI,'metrics@ttai':PPSMetricsAtTTAI};}}return{};}function getSSRProperties(type){const ssrPhases=getSSRPhaseSuccess(type);return{'ssr:success':(ssrPhases===null||ssrPhases===void 0?void 0:ssrPhases.done)!=null?ssrPhases.done:getSSRSuccessUtil(type),'ssr:featureFlags':getSSRFeatureFlags(type),...((ssrPhases===null||ssrPhases===void 0?void 0:ssrPhases.earlyFlush)!=null?{'ssr:earlyflush:success':ssrPhases.earlyFlush}:null),...((ssrPhases===null||ssrPhases===void 0?void 0:ssrPhases.prefetch)!=null?{'ssr:prefetch:success':ssrPhases.prefetch}:null)};}function getAssetsMetrics(interaction,SSRDoneTime){try{const config=getConfig();const{type}=interaction;const allowedTypes=['page_load'];const assetsConfig=config===null||config===void 0?void 0:config.assetsConfig;if(!allowedTypes.includes(type)||!assetsConfig){// Skip if: type not allowed or assetsClassification isn't configured
3
3
  return{};}const reporter=new CHRReporter();const resourceTimings=filterResourceTimings(interaction.start,interaction.end);const assets=reporter.get(resourceTimings,assetsConfig,SSRDoneTime);if(assets){// Only add assets in case it exists
4
4
  return{'event:assets':assets};}return{};}catch{// Skip CHR in case of error
5
5
  return{};}}function getTracingContextData(interaction){const{trace,start}=interaction;let tracingContextData={};if(trace){tracingContextData={'ufo:tracingContext':{'X-B3-TraceId':trace.traceId,'X-B3-SpanId':trace.spanId,// eslint-disable-next-line compat/compat
@@ -11,12 +11,14 @@ const getDetailedInteractionMetrics=resourceTimings=>{if(experimental||window.__
11
11
  if(shouldInclude3pHolds){var _interaction$hold3pIn;return{...basePayload,hold3pActive:interaction.hold3pActive?[...interaction.hold3pActive.values()]:[],hold3pInfo:optimizeHoldInfo((_interaction$hold3pIn=interaction.hold3pInfo)!==null&&_interaction$hold3pIn!==void 0?_interaction$hold3pIn:[],start,getReactUFOPayloadVersion(interaction.type))};}return basePayload;};// Page load & detailed payload
12
12
  const getPageLoadDetailedInteractionMetrics=()=>{var _config$ssr2,_config$ssr2$getSSRTi;if(!isPageLoad||!isDetailedPayload){return{};}const initialPageLoadExtraTimings=objectToArray(initialPageLoadExtraTiming.getTimings());const config=getConfig();const defaultSSRTimings=objectToArray(ssr.getSSRTimings());const ssrTimingsFromConfig=config===null||config===void 0?void 0:(_config$ssr2=config.ssr)===null||_config$ssr2===void 0?void 0:(_config$ssr2$getSSRTi=_config$ssr2.getSSRTimings)===null||_config$ssr2$getSSRTi===void 0?void 0:_config$ssr2$getSSRTi.call(_config$ssr2);return{initialPageLoadExtraTimings,SSRTimings:ssrTimingsFromConfig?[...ssrTimingsFromConfig,...defaultSSRTimings]:defaultSSRTimings};};if(experimental){expTTAI=getTTAI(interaction);}else{regularTTAI=getTTAI(interaction);}const newUFOName=sanitizeUfoName(ufoName);const resourceTimings=getResourceTimings(start,end);const[finalVCMetrics,experimentalMetrics,paintMetrics,batteryInfo]=await Promise.all([vcMetrics||(await getVCMetrics(interaction)),experimental?getExperimentalVCMetrics(interaction):Promise.resolve(undefined),getPaintMetricsToLegacyFormat(type,end),getBatteryInfoToLegacyFormat()]);if(!experimental){addPerformanceMeasures(interaction.start,[...((finalVCMetrics===null||finalVCMetrics===void 0?void 0:finalVCMetrics['ufo:vc:rev'])||[])]);}const getReactHydrationStats=()=>{if(!hydration){return{};}return{hydration};};const payload={actionSubject:'experience',action:'measured',eventType:'operational',source:'measured',tags:['observability'],attributes:{properties:{// basic
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
- 'event:cpu:usage':createPressureStateReport(interaction.start,interaction.end),'event:memory:usage':createMemoryStateReport(interaction.start,interaction.end),...(criticalPayloadCount!==undefined?{'ufo:multipayload':true,'ufo:criticalPayloadCount':criticalPayloadCount}:{}),'ufo:pageVisibilityHiddenTimestamp':getEarliestHiddenTiming(interaction.start,interaction.end),'ufo:wasPageHiddenBeforeInit':getHasHiddenTimingBeforeSetup(),'ufo:isOpenedInBackground':isOpenedInBackground(interaction.type),'ufo:isTabThrottled':isTabThrottled(start,end),...(fg('ufo_detect_aborting_interaction_during_ssr')?{'ufo:hasAbortingInteractionDuringSSR':getHasAbortingEventDuringSSR()}:{}),// root
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}:{}),'ufo:pageVisibilityHiddenTimestamp':getEarliestHiddenTiming(interaction.start,interaction.end),'ufo:wasPageHiddenBeforeInit':getHasHiddenTimingBeforeSetup(),'ufo:isOpenedInBackground':isOpenedInBackground(interaction.type),'ufo:isTabThrottled':isTabThrottled(start,end),...(fg('platform_ufo_page_visibility_timeline')?{'ufo:pageVisibilityTimeline':getPageVisibilityTimeline(start,end)}:{}),...(fg('ufo_detect_aborting_interaction_during_ssr')?{'ufo:hasAbortingInteractionDuringSSR':getHasAbortingEventDuringSSR()}:{}),// root
15
15
  ...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:{namePrefix:config.namePrefix||'',segmentPrefix:config.segmentPrefix||'',interactionId,pageVisibilityAtTTI,pageVisibilityAtTTAI,experimental__pageVisibilityAtTTI:moreAccuratePageVisibilityAtTTI,experimental__pageVisibilityAtTTAI:moreAccuratePageVisibilityAtTTAI,// raw interaction metrics
16
16
  rate,routeName,type,abortReason,featureFlags,previousInteractionName,isPreviousInteractionAborted,abortedByInteractionName,// performance
17
17
  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}:{}),...labelStack,...pageLoadInteractionMetrics,...getDetailedInteractionMetrics(resourceTimings),...getPageLoadDetailedInteractionMetrics(),...getBm3TrackerTimings(interaction),'metric:ttai':experimental?regularTTAI||expTTAI:undefined,'metric:experimental:ttai':expTTAI,...(unknownElementName?{unknownElementName}:{}),...(unknownElementHierarchy?{unknownElementHierarchy}:{})},'ufo:payloadTime':roundEpsilon(performance.now()-interactionPayloadStart)}}};if(experimental){regularTTAI=undefined;expTTAI=undefined;}if(fg('platform_ufo_enable_vc_raw_data')){const size=getPayloadSize(payload.attributes.properties);const vcRev=payload.attributes.properties['ufo:vc:rev'];const rawData=vcRev.find(item=>item.revision==='raw-handler');if(rawData){const 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(item=>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
18
18
  // we can add more fields as necessary
19
- const interactionMetricsFieldsToTrim=fg('ufo_remove_featureflags_from_trimmed_fields')?['requestInfo','resourceTimings']:['requestInfo','featureFlags','resourceTimings'];const properties=payload.attributes.properties;const interactionMetrics=properties.interactionMetrics;if(interactionMetrics){for(const field of interactionMetricsFieldsToTrim){if(getPayloadSize(properties)<=MAX_PAYLOAD_SIZE){continue;}interactionMetrics[field]=undefined;properties['event:isTrimmed']=true;let trimmedFields=properties['event:trimmedFields'];if(!Array.isArray(trimmedFields)){trimmedFields=[];}trimmedFields.push(`interactionMetrics.${field}`);properties['event:trimmedFields']=trimmedFields;}}// If the payload size continues to exceed the limit and interactionMetrics is already trimmed,
19
+ const interactionMetricsFieldsToTrim=fg('ufo_remove_featureflags_from_trimmed_fields')?['requestInfo','resourceTimings']:['requestInfo','featureFlags','resourceTimings'];// Top-level properties that can be trimmed if payload exceeds size limit
20
+ const topLevelFieldsToTrim=['ufo:pageVisibilityTimeline'];const properties=payload.attributes.properties;const interactionMetrics=properties.interactionMetrics;if(interactionMetrics){for(const field of interactionMetricsFieldsToTrim){if(getPayloadSize(properties)<=MAX_PAYLOAD_SIZE){continue;}interactionMetrics[field]=undefined;properties['event:isTrimmed']=true;let trimmedFields=properties['event:trimmedFields'];if(!Array.isArray(trimmedFields)){trimmedFields=[];}trimmedFields.push(`interactionMetrics.${field}`);properties['event:trimmedFields']=trimmedFields;}}// Trim top-level properties if payload still exceeds the limit
21
+ for(const field of topLevelFieldsToTrim){if(getPayloadSize(properties)<=MAX_PAYLOAD_SIZE){continue;}properties[field]=undefined;properties['event:isTrimmed']=true;let trimmedFields=properties['event:trimmedFields'];if(!Array.isArray(trimmedFields)){trimmedFields=[];}trimmedFields.push(field);properties['event:trimmedFields']=trimmedFields;}// If the payload size continues to exceed the limit and interactionMetrics is already trimmed,
20
22
  // trim VC debug data (early viewport checkpoints). PIR-30543 - AFO-5033
21
23
  const isVCRevisionTrimEnabled=fg('ufo_vc_revision_trim_enabled');trimVcDebugData(properties,getPayloadSize(properties),MAX_PAYLOAD_SIZE,isVCRevisionTrimEnabled);return payload;}export async function createPayloads(interactionId,interaction){const ufoNameOverride=getUfoNameOverride(interaction);const modifiedInteraction={...interaction,ufoName:ufoNameOverride};const payloads=[];const isCriticalMetricsEnabled=fg('platform_ufo_critical_metrics_payload');// Calculate VC metrics once to avoid duplicate expensive calculations
22
24
  const vcMetrics=await getVCMetrics(interaction);// typeof Promise<CriticalMetricsPayload[]>
@@ -271,6 +271,57 @@ export function __injectThrottleMeasurementForTesting(measurement) {
271
271
  throttleInsertIndex = (throttleInsertIndex + 1) % THROTTLE_BUFFER_SIZE;
272
272
  }
273
273
 
274
+ /**
275
+ * Returns the page visibility timeline entries within the specified time window.
276
+ * Each entry contains the time (relative to startTime) and whether the page was hidden.
277
+ *
278
+ * @param startTime - The start timestamp of the window (DOMHighResTimeStamp)
279
+ * @param endTime - The end timestamp of the window (DOMHighResTimeStamp)
280
+ * @returns Array of HiddenTimingItem entries within the time window, with times relative to startTime
281
+ */
282
+ export function getPageVisibilityTimeline(startTime, endTime) {
283
+ // Input validation
284
+ if (!Number.isFinite(startTime) || !Number.isFinite(endTime) || startTime >= endTime) {
285
+ return [];
286
+ }
287
+ if (timings.length === 0) {
288
+ return [];
289
+ }
290
+ const result = [];
291
+
292
+ // Find the most recent entry at or before startTime to establish initial state
293
+ let initialEntry;
294
+ const currentSize = timings.length;
295
+ for (let i = 0; i < currentSize; i++) {
296
+ const idx = (insertIndex + i) % currentSize;
297
+ const entry = timings[idx];
298
+ if (entry && entry.time <= startTime) {
299
+ initialEntry = entry;
300
+ }
301
+ }
302
+
303
+ // Add the initial visibility state at the start of the window
304
+ if (initialEntry) {
305
+ result.push({
306
+ time: 0,
307
+ hidden: initialEntry.hidden
308
+ });
309
+ }
310
+
311
+ // Add all entries within the time window
312
+ for (let i = 0; i < currentSize; i++) {
313
+ const idx = (insertIndex + i) % currentSize;
314
+ const entry = timings[idx];
315
+ if (entry && entry.time > startTime && entry.time <= endTime) {
316
+ result.push({
317
+ time: Math.round(entry.time - startTime),
318
+ hidden: entry.hidden
319
+ });
320
+ }
321
+ }
322
+ return result;
323
+ }
324
+
274
325
  // Expose testing API on window for integration tests
275
326
  if (typeof window !== 'undefined') {
276
327
  window.__reactUfoHiddenTiming = {
@@ -1072,6 +1072,7 @@ export function addNewInteraction(interactionId, ufoName, type, startTime, rate,
1072
1072
  devToolsEnabled: config.vc.devToolsEnabled,
1073
1073
  selectorConfig: config.vc.selectorConfig,
1074
1074
  ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder,
1075
+ trackLayoutShiftOffenders: config.vc.trackLayoutShiftOffenders,
1075
1076
  searchPageConfig
1076
1077
  };
1077
1078
  vcObserver = newVCObserver(vcOptions);
@@ -158,7 +158,8 @@ export function init(analyticsWebClientAsync, config) {
158
158
  oldDomUpdates: config.vc.oldDomUpdates,
159
159
  devToolsEnabled: config.vc.devToolsEnabled,
160
160
  selectorConfig: config.vc.selectorConfig,
161
- ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder
161
+ ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder,
162
+ trackLayoutShiftOffenders: config.vc.trackLayoutShiftOffenders
162
163
  };
163
164
  postInteractionLog.initializeVCObserver(vcOptions);
164
165
  if (config !== null && config !== void 0 && (_config$experimentalI = config.experimentalInteractionMetrics) !== null && _config$experimentalI !== void 0 && _config$experimentalI.enabled) {