@atlaskit/react-ufo 3.13.17 → 3.13.19

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 (42) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/ssr/index.js +8 -2
  3. package/dist/cjs/vc/index.js +2 -0
  4. package/dist/cjs/vc/vc-observer/getVCRevisionDebugDetails.js +109 -11
  5. package/dist/cjs/vc/vc-observer/index.js +56 -43
  6. package/dist/cjs/vc/vc-observer/observers/index.js +4 -0
  7. package/dist/cjs/vc/vc-observer/observers/rll-placeholders/index.js +208 -0
  8. package/dist/cjs/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +129 -16
  9. package/dist/cjs/vc/vc-observer-new/viewport-observer/index.js +16 -0
  10. package/dist/es2019/ssr/index.js +5 -1
  11. package/dist/es2019/vc/index.js +2 -0
  12. package/dist/es2019/vc/vc-observer/getVCRevisionDebugDetails.js +71 -9
  13. package/dist/es2019/vc/vc-observer/index.js +39 -22
  14. package/dist/es2019/vc/vc-observer/observers/index.js +4 -0
  15. package/dist/es2019/vc/vc-observer/observers/rll-placeholders/index.js +182 -0
  16. package/dist/es2019/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +102 -11
  17. package/dist/es2019/vc/vc-observer-new/viewport-observer/index.js +16 -0
  18. package/dist/esm/ssr/index.js +8 -2
  19. package/dist/esm/vc/index.js +2 -0
  20. package/dist/esm/vc/vc-observer/getVCRevisionDebugDetails.js +108 -11
  21. package/dist/esm/vc/vc-observer/index.js +56 -43
  22. package/dist/esm/vc/vc-observer/observers/index.js +4 -0
  23. package/dist/esm/vc/vc-observer/observers/rll-placeholders/index.js +201 -0
  24. package/dist/esm/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +130 -16
  25. package/dist/esm/vc/vc-observer-new/viewport-observer/index.js +16 -0
  26. package/dist/types/common/vc/types.d.ts +1 -1
  27. package/dist/types/ssr/index.d.ts +1 -0
  28. package/dist/types/vc/index.d.ts +1 -0
  29. package/dist/types/vc/vc-observer/getVCRevisionDebugDetails.d.ts +19 -18
  30. package/dist/types/vc/vc-observer/index.d.ts +7 -0
  31. package/dist/types/vc/vc-observer/observers/rll-placeholders/index.d.ts +49 -0
  32. package/dist/types/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +7 -0
  33. package/dist/types/vc/vc-observer-new/types.d.ts +1 -1
  34. package/dist/types-ts4.5/common/vc/types.d.ts +1 -1
  35. package/dist/types-ts4.5/ssr/index.d.ts +1 -0
  36. package/dist/types-ts4.5/vc/index.d.ts +1 -0
  37. package/dist/types-ts4.5/vc/vc-observer/getVCRevisionDebugDetails.d.ts +19 -18
  38. package/dist/types-ts4.5/vc/vc-observer/index.d.ts +7 -0
  39. package/dist/types-ts4.5/vc/vc-observer/observers/rll-placeholders/index.d.ts +49 -0
  40. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +7 -0
  41. package/dist/types-ts4.5/vc/vc-observer-new/types.d.ts +1 -1
  42. package/package.json +10 -1
@@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.default = void 0;
8
8
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
10
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
11
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
10
12
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
11
13
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
@@ -14,9 +16,12 @@ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
14
16
  var _percentileCalc = require("./percentile-calc");
15
17
  var _getViewportHeight = _interopRequireDefault(require("./utils/get-viewport-height"));
16
18
  var _getViewportWidth = _interopRequireDefault(require("./utils/get-viewport-width"));
19
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
20
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
17
21
  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; } } }; }
18
22
  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; } }
19
23
  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; }
24
+ // Create comprehensive debug details including ignored entries
20
25
  var AbstractVCCalculatorBase = exports.default = /*#__PURE__*/function () {
21
26
  function AbstractVCCalculatorBase(revisionNo) {
22
27
  (0, _classCallCheck2.default)(this, AbstractVCCalculatorBase);
@@ -79,8 +84,9 @@ var AbstractVCCalculatorBase = exports.default = /*#__PURE__*/function () {
79
84
  }, {
80
85
  key: "calculateWithDebugInfo",
81
86
  value: function () {
82
- var _calculateWithDebugInfo = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(filteredEntries, startTime, stopTime, isPostInteraction, isVCClean, interactionId, dirtyReason) {
83
- var percentiles, viewportEntries, vcLogs, vcDetails, percentileIndex, entryDataBuffer, _iterator3, _step3, _entry2, time, viewportPercentage, entries, elementNames, previousResult, i, percentile, _ufo_devtool_onVCRev, _ref;
87
+ var _calculateWithDebugInfo = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(filteredEntries, startTime, stopTime, isPostInteraction, isVCClean, interactionId, dirtyReason, allEntries) {
88
+ var _window, _window2, _window3, _window5;
89
+ var percentiles, viewportEntries, vcLogs, vcDetails, percentileIndex, entryDataBuffer, _iterator3, _step3, _entry2, time, viewportPercentage, entries, elementNames, previousResult, i, percentile, enhancedVcLogs, shouldCalculateDebugDetails, sortedVcLogs, maxViewportPercentageAtTime, maxSoFar, _iterator4, _step4, log, getBiggestPreviousViewportPercentage, ignoredEntriesByTime, _iterator5, _step5, _entry3, _ignoredEntriesByTime, viewportData, timestamp, additionalVcLogs, _iterator6, _step6, _step6$value, _timestamp, ignoredEntries, _viewportPercentage, v3RevisionDebugDetails, _window4, _window4$__ufo_devtoo, _window6, _window6$__on_ufo_vc_;
84
90
  return _regenerator.default.wrap(function _callee$(_context) {
85
91
  while (1) switch (_context.prev = _context.next) {
86
92
  case 0:
@@ -170,31 +176,138 @@ var AbstractVCCalculatorBase = exports.default = /*#__PURE__*/function () {
170
176
  previousResult = vcDetails["".concat(percentile)];
171
177
  }
172
178
  }
179
+ enhancedVcLogs = vcLogs ? vcLogs.map(function (log) {
180
+ return _objectSpread(_objectSpread({}, log), {}, {
181
+ viewportPercentage: log.viewportPercentage
182
+ });
183
+ }) : []; // Only calculate enhanced debug details if devtool callbacks exist
184
+ shouldCalculateDebugDetails = !isPostInteraction && (typeof ((_window = window) === null || _window === void 0 ? void 0 : _window.__ufo_devtool_onVCRevisionReady__) === 'function' || typeof ((_window2 = window) === null || _window2 === void 0 ? void 0 : _window2.__on_ufo_vc_debug_data_ready) === 'function' && (0, _platformFeatureFlags.fg)('platform_ufo_emit_vc_debug_data'));
185
+ if (shouldCalculateDebugDetails && allEntries && vcLogs) {
186
+ // Pre-sort vcLogs by time for efficient lookups
187
+ sortedVcLogs = (0, _toConsumableArray2.default)(vcLogs).sort(function (a, b) {
188
+ return a.time - b.time;
189
+ }); // Pre-calculate max viewport percentage up to each time for efficient lookups
190
+ maxViewportPercentageAtTime = new Map();
191
+ maxSoFar = 0;
192
+ _iterator4 = _createForOfIteratorHelper(sortedVcLogs);
193
+ try {
194
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
195
+ log = _step4.value;
196
+ if (log.viewportPercentage !== null) {
197
+ maxSoFar = Math.max(maxSoFar, log.viewportPercentage);
198
+ maxViewportPercentageAtTime.set(log.time, maxSoFar);
199
+ }
200
+ }
201
+
202
+ // Helper function to find the biggest previous viewport percentage
203
+ } catch (err) {
204
+ _iterator4.e(err);
205
+ } finally {
206
+ _iterator4.f();
207
+ }
208
+ getBiggestPreviousViewportPercentage = function getBiggestPreviousViewportPercentage(targetTime) {
209
+ // Binary search for the largest time <= targetTime
210
+ var left = 0;
211
+ var right = sortedVcLogs.length - 1;
212
+ var result = -1;
213
+ while (left <= right) {
214
+ var mid = Math.floor((left + right) / 2);
215
+ if (sortedVcLogs[mid].time <= targetTime) {
216
+ result = mid;
217
+ left = mid + 1;
218
+ } else {
219
+ right = mid - 1;
220
+ }
221
+ }
222
+ return result >= 0 ? maxViewportPercentageAtTime.get(sortedVcLogs[result].time) || null : null;
223
+ }; // Group ignored entries by timestamp
224
+ ignoredEntriesByTime = new Map();
225
+ _iterator5 = _createForOfIteratorHelper(allEntries);
226
+ try {
227
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
228
+ _entry3 = _step5.value;
229
+ if ('rect' in _entry3.data && !this.isEntryIncluded(_entry3)) {
230
+ viewportData = _entry3.data;
231
+ timestamp = Math.round(_entry3.time);
232
+ if (!ignoredEntriesByTime.has(timestamp)) {
233
+ ignoredEntriesByTime.set(timestamp, []);
234
+ }
235
+ (_ignoredEntriesByTime = ignoredEntriesByTime.get(timestamp)) === null || _ignoredEntriesByTime === void 0 || _ignoredEntriesByTime.push(_objectSpread(_objectSpread({}, viewportData), {}, {
236
+ ignoreReason: viewportData.visible ? viewportData.type : 'not-visible'
237
+ }));
238
+ }
239
+ }
240
+
241
+ // Add ignored entries to vcLogs
242
+ } catch (err) {
243
+ _iterator5.e(err);
244
+ } finally {
245
+ _iterator5.f();
246
+ }
247
+ additionalVcLogs = [];
248
+ _iterator6 = _createForOfIteratorHelper(ignoredEntriesByTime);
249
+ try {
250
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
251
+ _step6$value = (0, _slicedToArray2.default)(_step6.value, 2), _timestamp = _step6$value[0], ignoredEntries = _step6$value[1];
252
+ if (ignoredEntries.length > 0) {
253
+ _viewportPercentage = getBiggestPreviousViewportPercentage(_timestamp);
254
+ additionalVcLogs.push({
255
+ time: _timestamp,
256
+ viewportPercentage: _viewportPercentage,
257
+ entries: ignoredEntries
258
+ });
259
+ }
260
+ }
261
+
262
+ // Combine and sort all vcLogs
263
+ } catch (err) {
264
+ _iterator6.e(err);
265
+ } finally {
266
+ _iterator6.f();
267
+ }
268
+ enhancedVcLogs = [].concat((0, _toConsumableArray2.default)(enhancedVcLogs), additionalVcLogs).sort(function (a, b) {
269
+ return a.time - b.time;
270
+ });
271
+ }
272
+
273
+ // Only create debug details if callbacks exist
274
+ v3RevisionDebugDetails = null;
275
+ if (shouldCalculateDebugDetails) {
276
+ v3RevisionDebugDetails = {
277
+ revision: this.revisionNo,
278
+ isClean: isVCClean,
279
+ abortReason: dirtyReason,
280
+ vcLogs: enhancedVcLogs,
281
+ interactionId: interactionId
282
+ };
283
+ }
173
284
 
174
285
  // Handle devtool callback
175
- if (!isPostInteraction && typeof window !== 'undefined' && typeof window.__ufo_devtool_onVCRevisionReady__ === 'function') {
286
+ if (v3RevisionDebugDetails && typeof ((_window3 = window) === null || _window3 === void 0 ? void 0 : _window3.__ufo_devtool_onVCRevisionReady__) === 'function') {
176
287
  try {
177
- (_ufo_devtool_onVCRev = (_ref = window).__ufo_devtool_onVCRevisionReady__) === null || _ufo_devtool_onVCRev === void 0 || _ufo_devtool_onVCRev.call(_ref, {
178
- revision: this.revisionNo,
179
- isClean: isVCClean,
180
- abortReason: dirtyReason,
181
- vcLogs: vcLogs,
182
- interactionId: interactionId
183
- });
288
+ (_window4 = window) === null || _window4 === void 0 || (_window4$__ufo_devtoo = _window4.__ufo_devtool_onVCRevisionReady__) === null || _window4$__ufo_devtoo === void 0 || _window4$__ufo_devtoo.call(_window4, v3RevisionDebugDetails);
184
289
  } catch (e) {
185
290
  // if any error communicating with devtool, we don't want to break the app
186
291
  // eslint-disable-next-line no-console
187
292
  console.error('Error in onVCRevisionReady', e);
188
293
  }
189
294
  }
295
+ if (v3RevisionDebugDetails && typeof ((_window5 = window) === null || _window5 === void 0 ? void 0 : _window5.__on_ufo_vc_debug_data_ready) === 'function' && (0, _platformFeatureFlags.fg)('platform_ufo_emit_vc_debug_data')) {
296
+ try {
297
+ (_window6 = window) === null || _window6 === void 0 || (_window6$__on_ufo_vc_ = _window6.__on_ufo_vc_debug_data_ready) === null || _window6$__on_ufo_vc_ === void 0 || _window6$__on_ufo_vc_.call(_window6, v3RevisionDebugDetails);
298
+ } catch (e) {
299
+ // eslint-disable-next-line no-console
300
+ console.error('Error in onVCRevisionReady', e);
301
+ }
302
+ }
190
303
  return _context.abrupt("return", vcDetails);
191
- case 32:
304
+ case 38:
192
305
  case "end":
193
306
  return _context.stop();
194
307
  }
195
308
  }, _callee, this, [[10, 22, 25, 28]]);
196
309
  }));
197
- function calculateWithDebugInfo(_x, _x2, _x3, _x4, _x5, _x6, _x7) {
310
+ function calculateWithDebugInfo(_x, _x2, _x3, _x4, _x5, _x6, _x7, _x8) {
198
311
  return _calculateWithDebugInfo.apply(this, arguments);
199
312
  }
200
313
  return calculateWithDebugInfo;
@@ -202,7 +315,7 @@ var AbstractVCCalculatorBase = exports.default = /*#__PURE__*/function () {
202
315
  }, {
203
316
  key: "calculate",
204
317
  value: function () {
205
- var _calculate = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(_ref2) {
318
+ var _calculate = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(_ref) {
206
319
  var _this = this,
207
320
  _vcDetails$90$t,
208
321
  _vcDetails$;
@@ -210,7 +323,7 @@ var AbstractVCCalculatorBase = exports.default = /*#__PURE__*/function () {
210
323
  return _regenerator.default.wrap(function _callee2$(_context2) {
211
324
  while (1) switch (_context2.prev = _context2.next) {
212
325
  case 0:
213
- startTime = _ref2.startTime, stopTime = _ref2.stopTime, orderedEntries = _ref2.orderedEntries, interactionId = _ref2.interactionId, isPostInteraction = _ref2.isPostInteraction;
326
+ startTime = _ref.startTime, stopTime = _ref.stopTime, orderedEntries = _ref.orderedEntries, interactionId = _ref.interactionId, isPostInteraction = _ref.isPostInteraction;
214
327
  filteredEntries = orderedEntries.filter(function (entry) {
215
328
  return _this.isEntryIncluded(entry);
216
329
  });
@@ -229,7 +342,7 @@ var AbstractVCCalculatorBase = exports.default = /*#__PURE__*/function () {
229
342
  });
230
343
  case 7:
231
344
  _context2.next = 9;
232
- return this.calculateWithDebugInfo(filteredEntries, startTime, stopTime, isPostInteraction, isVCClean, interactionId, dirtyReason);
345
+ return this.calculateWithDebugInfo(filteredEntries, startTime, stopTime, isPostInteraction, isVCClean, interactionId, dirtyReason, orderedEntries);
233
346
  case 9:
234
347
  vcDetails = _context2.sent;
235
348
  result = {
@@ -248,7 +361,7 @@ var AbstractVCCalculatorBase = exports.default = /*#__PURE__*/function () {
248
361
  }
249
362
  }, _callee2, this);
250
363
  }));
251
- function calculate(_x8) {
364
+ function calculate(_x9) {
252
365
  return _calculate.apply(this, arguments);
253
366
  }
254
367
  return calculate;
@@ -10,6 +10,7 @@ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/creat
10
10
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
11
  var _vcUtils = require("../../vc-observer/media-wrapper/vc-utils");
12
12
  var _isNonVisualStyleMutation = _interopRequireDefault(require("../../vc-observer/observers/non-visual-styles/is-non-visual-style-mutation"));
13
+ var _rllPlaceholders = require("../../vc-observer/observers/rll-placeholders");
13
14
  var _intersectionObserver = require("./intersection-observer");
14
15
  var _mutationObserver = _interopRequireDefault(require("./mutation-observer"));
15
16
  var _performanceObserver = _interopRequireDefault(require("./performance-observer"));
@@ -48,6 +49,10 @@ function sameRectDimensions(a, b) {
48
49
  var createElementMutationsWatcher = function createElementMutationsWatcher(removedNodeRects) {
49
50
  return function (_ref) {
50
51
  var rect = _ref.rect;
52
+ var isRLLPlaceholder = _rllPlaceholders.RLLPlaceholderHandlers.getInstance().isRLLPlaceholderHydration(rect);
53
+ if (isRLLPlaceholder) {
54
+ return 'mutation:rll-placeholder';
55
+ }
51
56
  var wasDeleted = removedNodeRects.some(function (nr) {
52
57
  return sameRectDimensions(nr, rect);
53
58
  });
@@ -153,6 +158,17 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
153
158
  }
154
159
  };
155
160
  }
161
+ var isRLLPlaceholder = _rllPlaceholders.RLLPlaceholderHandlers.getInstance().isRLLPlaceholderHydration(rect);
162
+ if (isRLLPlaceholder) {
163
+ return {
164
+ type: 'mutation:rll-placeholder',
165
+ mutationData: {
166
+ attributeName: attributeName,
167
+ oldValue: oldValue,
168
+ newValue: newValue
169
+ }
170
+ };
171
+ }
156
172
  var lastElementRect = _this.mapVisibleNodeRects.get(target);
157
173
  if (lastElementRect && sameRectSize(rect, lastElementRect)) {
158
174
  return {
@@ -1,3 +1,4 @@
1
+ import { fg } from '@atlaskit/platform-feature-flags';
1
2
  const NESTED_METRIC_SEPARATOR = '/';
2
3
  function filterEntry(entry) {
3
4
  return !(!entry || typeof entry !== 'object' || entry.startTime < 0 || entry.duration < 0);
@@ -5,7 +6,10 @@ function filterEntry(entry) {
5
6
  function mapEntry(entry) {
6
7
  return {
7
8
  startTime: Math.round(entry.startTime),
8
- duration: Math.round(entry.duration)
9
+ duration: Math.round(entry.duration),
10
+ ...(entry.size && fg('platform_ufo_ssr_size_field') ? {
11
+ size: Math.round(entry.size)
12
+ } : {})
9
13
  };
10
14
  }
11
15
  const SSR_PREFIX = 'ssr';
@@ -3,6 +3,7 @@ import { isVCRevisionEnabled } from '../config';
3
3
  import { VCObserverNOOP } from './no-op-vc-observer';
4
4
  import { VCObserver } from './vc-observer';
5
5
  import VCObserverNew from './vc-observer-new';
6
+ import { RLLPlaceholderHandlers } from './vc-observer/observers/rll-placeholders';
6
7
  export class VCObserverWrapper {
7
8
  constructor(opts = {}) {
8
9
  this.newVCObserver = null;
@@ -66,6 +67,7 @@ export class VCObserverWrapper {
66
67
  var _this$newVCObserver2;
67
68
  (_this$newVCObserver2 = this.newVCObserver) === null || _this$newVCObserver2 === void 0 ? void 0 : _this$newVCObserver2.stop();
68
69
  }
70
+ RLLPlaceholderHandlers.getInstance().reset();
69
71
  }
70
72
  getVCRawData() {
71
73
  var _this$oldVCObserver$g, _this$oldVCObserver3;
@@ -6,16 +6,44 @@ export function getVCRevisionDebugDetails({
6
6
  componentsLog,
7
7
  interactionId
8
8
  }) {
9
- return {
10
- revision,
11
- isClean,
12
- abortReason,
13
- vcLogs: VCEntries.map(entry => ({
9
+ // Pre-sort VCEntries by time for efficient lookups
10
+ const sortedVCEntries = [...VCEntries].sort((a, b) => a.time - b.time);
11
+
12
+ // Pre-calculate max viewport percentage up to each time for efficient lookups
13
+ const maxViewportPercentageAtTime = new Map();
14
+ let maxSoFar = 0;
15
+ for (const entry of sortedVCEntries) {
16
+ maxSoFar = Math.max(maxSoFar, entry.vc);
17
+ maxViewportPercentageAtTime.set(entry.time, maxSoFar);
18
+ }
19
+
20
+ // Helper function to find the biggest previous viewport percentage
21
+ const getBiggestPreviousViewportPercentage = targetTime => {
22
+ // Binary search for the largest time <= targetTime
23
+ let left = 0;
24
+ let right = sortedVCEntries.length - 1;
25
+ let result = -1;
26
+ while (left <= right) {
27
+ const mid = Math.floor((left + right) / 2);
28
+ if (sortedVCEntries[mid].time <= targetTime) {
29
+ result = mid;
30
+ left = mid + 1;
31
+ } else {
32
+ right = mid - 1;
33
+ }
34
+ }
35
+ return result >= 0 ? maxViewportPercentageAtTime.get(sortedVCEntries[result].time) || null : null;
36
+ };
37
+ const allVcLogs = [];
38
+
39
+ // Add regular VC entries
40
+ for (const entry of VCEntries) {
41
+ const timeLogEntries = componentsLog[entry.time];
42
+ allVcLogs.push({
14
43
  time: entry.time,
15
44
  viewportPercentage: entry.vc,
16
45
  entries: entry.elements.map(element => {
17
- var _componentsLog$entry$;
18
- const logEntry = (_componentsLog$entry$ = componentsLog[entry.time]) === null || _componentsLog$entry$ === void 0 ? void 0 : _componentsLog$entry$.find(log => log.targetName === element);
46
+ const logEntry = timeLogEntries === null || timeLogEntries === void 0 ? void 0 : timeLogEntries.find(log => log.targetName === element);
19
47
  return {
20
48
  elementName: element,
21
49
  type: logEntry === null || logEntry === void 0 ? void 0 : logEntry.type,
@@ -23,10 +51,44 @@ export function getVCRevisionDebugDetails({
23
51
  visible: true,
24
52
  attributeName: logEntry === null || logEntry === void 0 ? void 0 : logEntry.attributeName,
25
53
  oldValue: logEntry === null || logEntry === void 0 ? void 0 : logEntry.oldValue,
26
- newValue: logEntry === null || logEntry === void 0 ? void 0 : logEntry.newValue
54
+ newValue: logEntry === null || logEntry === void 0 ? void 0 : logEntry.newValue,
55
+ ignoreReason: logEntry === null || logEntry === void 0 ? void 0 : logEntry.ignoreReason
27
56
  };
28
57
  })
29
- })),
58
+ });
59
+ }
60
+
61
+ // Add ignored elements - only process timestamps that have ignored elements
62
+ for (const [timestamp, timeLogEntries] of Object.entries(componentsLog)) {
63
+ const ignoredElements = timeLogEntries.filter(log => log.ignoreReason);
64
+ if (ignoredElements.length === 0) {
65
+ continue;
66
+ }
67
+ const time = Number(timestamp);
68
+ const viewportPercentage = getBiggestPreviousViewportPercentage(time);
69
+ allVcLogs.push({
70
+ time,
71
+ viewportPercentage,
72
+ entries: ignoredElements.map(logEntry => ({
73
+ elementName: logEntry.targetName,
74
+ type: logEntry.type,
75
+ rect: logEntry.intersectionRect,
76
+ visible: false,
77
+ attributeName: logEntry.attributeName,
78
+ oldValue: logEntry.oldValue,
79
+ newValue: logEntry.newValue,
80
+ ignoreReason: logEntry.ignoreReason
81
+ }))
82
+ });
83
+ }
84
+
85
+ // Sort once at the end
86
+ allVcLogs.sort((a, b) => a.time - b.time);
87
+ return {
88
+ revision,
89
+ isClean,
90
+ abortReason,
91
+ vcLogs: allVcLogs,
30
92
  interactionId
31
93
  };
32
94
  }
@@ -1,4 +1,5 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import { fg } from '@atlaskit/platform-feature-flags';
2
3
  import { isVCRevisionEnabled } from '../../config';
3
4
  import { getActiveInteraction } from '../../interaction-metrics';
4
5
  import { attachAbortListeners } from './attachAbortListeners';
@@ -281,32 +282,48 @@ export class VCObserver {
281
282
  entries: isTTVCv1Disabled ? vcNext.VCEntries.rel : VCEntries.rel
282
283
  }
283
284
  }));
284
-
285
- // Add devtool callback for both v1 and v2
286
- if (typeof window.__ufo_devtool_onVCRevisionReady__ === 'function') {
287
- var _ufo_devtool_onVCRev2, _ref2;
288
- // Handle v1 if not disabled
289
- if (!isTTVCv1Disabled) {
290
- var _ufo_devtool_onVCRev, _ref;
291
- (_ufo_devtool_onVCRev = (_ref = window).__ufo_devtool_onVCRevisionReady__) === null || _ufo_devtool_onVCRev === void 0 ? void 0 : _ufo_devtool_onVCRev.call(_ref, getVCRevisionDebugDetails({
292
- revision: 'fy25.01',
293
- isClean: !abortReasonInfo,
294
- abortReason: abortReason.reason,
295
- VCEntries: VCEntries.rel,
296
- componentsLog,
297
- interactionId
298
- }));
299
- }
300
-
301
- // Handle v2
302
- (_ufo_devtool_onVCRev2 = (_ref2 = window).__ufo_devtool_onVCRevisionReady__) === null || _ufo_devtool_onVCRev2 === void 0 ? void 0 : _ufo_devtool_onVCRev2.call(_ref2, getVCRevisionDebugDetails({
285
+ }
286
+ if (!this.isPostInteraction) {
287
+ // Only create revision debug details if callbacks exist
288
+ const shouldCreateDebugDetails = typeof window.__ufo_devtool_onVCRevisionReady__ === 'function' || typeof window.__on_ufo_vc_debug_data_ready === 'function' && fg('platform_ufo_emit_vc_debug_data');
289
+ if (shouldCreateDebugDetails) {
290
+ const v1RevisionDebugDetails = getVCRevisionDebugDetails({
291
+ revision: 'fy25.01',
292
+ isClean: !abortReasonInfo,
293
+ abortReason: abortReason.reason,
294
+ VCEntries: VCEntries.rel,
295
+ componentsLog,
296
+ interactionId
297
+ });
298
+ const v2RevisionDebugDetails = getVCRevisionDebugDetails({
303
299
  revision: 'fy25.02',
304
300
  isClean: !abortReasonInfo,
305
301
  abortReason: abortReason.reason,
306
302
  VCEntries: vcNext.VCEntries.rel,
307
303
  componentsLog,
308
304
  interactionId
309
- }));
305
+ });
306
+
307
+ // Add devtool callback for both v1 and v2
308
+ if (typeof window.__ufo_devtool_onVCRevisionReady__ === 'function') {
309
+ var _window$__ufo_devtool2, _window2;
310
+ // Handle v1 if not disabled
311
+ if (!isTTVCv1Disabled) {
312
+ var _window$__ufo_devtool, _window;
313
+ (_window$__ufo_devtool = (_window = window).__ufo_devtool_onVCRevisionReady__) === null || _window$__ufo_devtool === void 0 ? void 0 : _window$__ufo_devtool.call(_window, v1RevisionDebugDetails);
314
+ }
315
+
316
+ // Handle v2
317
+ (_window$__ufo_devtool2 = (_window2 = window).__ufo_devtool_onVCRevisionReady__) === null || _window$__ufo_devtool2 === void 0 ? void 0 : _window$__ufo_devtool2.call(_window2, v2RevisionDebugDetails);
318
+ }
319
+ if (typeof window.__on_ufo_vc_debug_data_ready === 'function' && fg('platform_ufo_emit_vc_debug_data')) {
320
+ var _window$__on_ufo_vc_d2, _window4;
321
+ if (!isTTVCv1Disabled) {
322
+ var _window$__on_ufo_vc_d, _window3;
323
+ (_window$__on_ufo_vc_d = (_window3 = window).__on_ufo_vc_debug_data_ready) === null || _window$__on_ufo_vc_d === void 0 ? void 0 : _window$__on_ufo_vc_d.call(_window3, v1RevisionDebugDetails);
324
+ }
325
+ (_window$__on_ufo_vc_d2 = (_window4 = window).__on_ufo_vc_debug_data_ready) === null || _window$__on_ufo_vc_d2 === void 0 ? void 0 : _window$__on_ufo_vc_d2.call(_window4, v2RevisionDebugDetails);
326
+ }
310
327
  }
311
328
  }
312
329
  } catch (e) {
@@ -461,10 +478,10 @@ export class VCObserver {
461
478
  }
462
479
  });
463
480
  _defineProperty(this, "attachAbortListeners", () => {
464
- var _window;
481
+ var _window5;
465
482
  this.detachAbortListeners();
466
483
  let unbinds = attachAbortListeners(window, this.viewport, this.abortReasonCallback);
467
- if ((_window = window) !== null && _window !== void 0 && _window.__SSR_ABORT_LISTENERS__) {
484
+ if ((_window5 = window) !== null && _window5 !== void 0 && _window5.__SSR_ABORT_LISTENERS__) {
468
485
  Object.entries(window.__SSR_ABORT_LISTENERS__.aborts).forEach(([key, time]) => {
469
486
  if (time) {
470
487
  this.abortReasonCallback(key, time);
@@ -1,6 +1,7 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import { isContainedWithinMediaWrapper } from '../media-wrapper/vc-utils';
3
3
  import isNonVisualStyleMutation from './non-visual-styles/is-non-visual-style-mutation';
4
+ import { RLLPlaceholderHandlers } from './rll-placeholders';
4
5
  import { SSRPlaceholderHandlers } from './ssr-placeholders';
5
6
  const state = {
6
7
  normal: 1,
@@ -244,6 +245,9 @@ export class Observers {
244
245
  if (!isElementVisible(target)) {
245
246
  data.ignoreReason = 'not-visible';
246
247
  }
248
+ if (RLLPlaceholderHandlers.getInstance().isRLLPlaceholderHydration(ir)) {
249
+ data.ignoreReason = 'rll-placeholder';
250
+ }
247
251
  this.callbacks.forEach(callback => {
248
252
  let elementName;
249
253
  try {