@atlaskit/react-ufo 3.13.18 → 3.13.20

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 (34) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/interaction-metrics/index.js +10 -3
  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 +35 -29
  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 +123 -18
  9. package/dist/cjs/vc/vc-observer-new/viewport-observer/index.js +16 -0
  10. package/dist/es2019/interaction-metrics/index.js +10 -3
  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 -33
  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 +96 -16
  17. package/dist/es2019/vc/vc-observer-new/viewport-observer/index.js +16 -0
  18. package/dist/esm/interaction-metrics/index.js +10 -3
  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 +35 -29
  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 +124 -18
  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/vc/vc-observer/getVCRevisionDebugDetails.d.ts +16 -14
  28. package/dist/types/vc/vc-observer/observers/rll-placeholders/index.d.ts +49 -0
  29. package/dist/types/vc/vc-observer-new/types.d.ts +1 -1
  30. package/dist/types-ts4.5/common/vc/types.d.ts +1 -1
  31. package/dist/types-ts4.5/vc/vc-observer/getVCRevisionDebugDetails.d.ts +16 -14
  32. package/dist/types-ts4.5/vc/vc-observer/observers/rll-placeholders/index.d.ts +49 -0
  33. package/dist/types-ts4.5/vc/vc-observer-new/types.d.ts +1 -1
  34. package/package.json +7 -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,9 +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 _window, _window3;
84
- var percentiles, viewportEntries, vcLogs, vcDetails, percentileIndex, entryDataBuffer, _iterator3, _step3, _entry2, time, viewportPercentage, entries, elementNames, previousResult, i, percentile, v3RevisionDebugDetails, _window2, _window2$__ufo_devtoo, _window4, _window4$__on_ufo_vc_;
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_;
85
90
  return _regenerator.default.wrap(function _callee$(_context) {
86
91
  while (1) switch (_context.prev = _context.next) {
87
92
  case 0:
@@ -171,38 +176,138 @@ var AbstractVCCalculatorBase = exports.default = /*#__PURE__*/function () {
171
176
  previousResult = vcDetails["".concat(percentile)];
172
177
  }
173
178
  }
174
- v3RevisionDebugDetails = {
175
- revision: this.revisionNo,
176
- isClean: isVCClean,
177
- abortReason: dirtyReason,
178
- vcLogs: vcLogs,
179
- interactionId: interactionId
180
- }; // Handle devtool callback
181
- if (!isPostInteraction && typeof ((_window = window) === null || _window === void 0 ? void 0 : _window.__ufo_devtool_onVCRevisionReady__) === 'function') {
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
+ }
284
+
285
+ // Handle devtool callback
286
+ if (v3RevisionDebugDetails && typeof ((_window3 = window) === null || _window3 === void 0 ? void 0 : _window3.__ufo_devtool_onVCRevisionReady__) === 'function') {
182
287
  try {
183
- (_window2 = window) === null || _window2 === void 0 || (_window2$__ufo_devtoo = _window2.__ufo_devtool_onVCRevisionReady__) === null || _window2$__ufo_devtoo === void 0 || _window2$__ufo_devtoo.call(_window2, v3RevisionDebugDetails);
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
  }
190
- if (!isPostInteraction && typeof ((_window3 = window) === null || _window3 === void 0 ? void 0 : _window3.__on_ufo_vc_debug_data_ready) === 'function' && (0, _platformFeatureFlags.fg)('platform_ufo_emit_vc_debug_data')) {
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')) {
191
296
  try {
192
- (_window4 = window) === null || _window4 === void 0 || (_window4$__on_ufo_vc_ = _window4.__on_ufo_vc_debug_data_ready) === null || _window4$__on_ufo_vc_ === void 0 || _window4$__on_ufo_vc_.call(_window4, v3RevisionDebugDetails);
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);
193
298
  } catch (e) {
194
299
  // eslint-disable-next-line no-console
195
300
  console.error('Error in onVCRevisionReady', e);
196
301
  }
197
302
  }
198
303
  return _context.abrupt("return", vcDetails);
199
- case 34:
304
+ case 38:
200
305
  case "end":
201
306
  return _context.stop();
202
307
  }
203
308
  }, _callee, this, [[10, 22, 25, 28]]);
204
309
  }));
205
- function calculateWithDebugInfo(_x, _x2, _x3, _x4, _x5, _x6, _x7) {
310
+ function calculateWithDebugInfo(_x, _x2, _x3, _x4, _x5, _x6, _x7, _x8) {
206
311
  return _calculateWithDebugInfo.apply(this, arguments);
207
312
  }
208
313
  return calculateWithDebugInfo;
@@ -237,7 +342,7 @@ var AbstractVCCalculatorBase = exports.default = /*#__PURE__*/function () {
237
342
  });
238
343
  case 7:
239
344
  _context2.next = 9;
240
- return this.calculateWithDebugInfo(filteredEntries, startTime, stopTime, isPostInteraction, isVCClean, interactionId, dirtyReason);
345
+ return this.calculateWithDebugInfo(filteredEntries, startTime, stopTime, isPostInteraction, isVCClean, interactionId, dirtyReason, orderedEntries);
241
346
  case 9:
242
347
  vcDetails = _context2.sent;
243
348
  result = {
@@ -256,7 +361,7 @@ var AbstractVCCalculatorBase = exports.default = /*#__PURE__*/function () {
256
361
  }
257
362
  }, _callee2, this);
258
363
  }));
259
- function calculate(_x8) {
364
+ function calculate(_x9) {
260
365
  return _calculate.apply(this, arguments);
261
366
  }
262
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,4 +1,5 @@
1
1
  import { v4 as createUUID } from 'uuid';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
2
3
  import coinflip from '../coinflip';
3
4
  import { getAwaitBM3TTIList, getCapabilityRate, getConfig } from '../config';
4
5
  import { experimentalVC, getExperimentalVCMetrics, onExperimentalInteractionComplete } from '../create-experimental-interaction-metrics-payload';
@@ -739,7 +740,9 @@ export function addBrowserMetricEvent(event) {
739
740
  interaction.legacyMetrics = interaction.legacyMetrics || [];
740
741
  interaction.legacyMetrics.push(event);
741
742
  if ((interaction.type === 'page_load' || interaction.type === 'transition') && ((_event$config = event.config) === null || _event$config === void 0 ? void 0 : _event$config.type) === 'PAGE_LOAD') {
742
- interaction.changeTimeout(CLEANUP_TIMEOUT_AFTER_APDEX);
743
+ if (!fg('platform_ufo_timeout_simplification')) {
744
+ interaction.changeTimeout(CLEANUP_TIMEOUT_AFTER_APDEX);
745
+ }
743
746
  removeHoldByID(interaction.id, interaction.ufoName);
744
747
  }
745
748
  }
@@ -758,7 +761,9 @@ export function addApdexToAll(apdex) {
758
761
  // do nothing
759
762
  }
760
763
  if (interaction.type === 'page_load' || interaction.type === 'transition') {
761
- interaction.changeTimeout(CLEANUP_TIMEOUT_AFTER_APDEX);
764
+ if (!fg('platform_ufo_timeout_simplification')) {
765
+ interaction.changeTimeout(CLEANUP_TIMEOUT_AFTER_APDEX);
766
+ }
762
767
  removeHoldByID(key, interaction.ufoName);
763
768
  }
764
769
  });
@@ -778,7 +783,9 @@ export function addApdex(interactionId, apdexInfo) {
778
783
  // do nothing
779
784
  }
780
785
  if (interaction.type === 'page_load' || interaction.type === 'transition') {
781
- interaction.changeTimeout(CLEANUP_TIMEOUT_AFTER_APDEX);
786
+ if (!fg('platform_ufo_timeout_simplification')) {
787
+ interaction.changeTimeout(CLEANUP_TIMEOUT_AFTER_APDEX);
788
+ }
782
789
  removeHoldByID(interactionId, interaction.ufoName);
783
790
  }
784
791
  }
@@ -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
  }
@@ -282,42 +282,48 @@ export class VCObserver {
282
282
  entries: isTTVCv1Disabled ? vcNext.VCEntries.rel : VCEntries.rel
283
283
  }
284
284
  }));
285
- const v1RevisionDebugDetails = getVCRevisionDebugDetails({
286
- revision: 'fy25.01',
287
- isClean: !abortReasonInfo,
288
- abortReason: abortReason.reason,
289
- VCEntries: VCEntries.rel,
290
- componentsLog,
291
- interactionId
292
- });
293
- const v2RevisionDebugDetails = getVCRevisionDebugDetails({
294
- revision: 'fy25.02',
295
- isClean: !abortReasonInfo,
296
- abortReason: abortReason.reason,
297
- VCEntries: vcNext.VCEntries.rel,
298
- componentsLog,
299
- interactionId
300
- });
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({
299
+ revision: 'fy25.02',
300
+ isClean: !abortReasonInfo,
301
+ abortReason: abortReason.reason,
302
+ VCEntries: vcNext.VCEntries.rel,
303
+ componentsLog,
304
+ interactionId
305
+ });
301
306
 
302
- // Add devtool callback for both v1 and v2
303
- if (typeof window.__ufo_devtool_onVCRevisionReady__ === 'function') {
304
- var _window$__ufo_devtool2, _window2;
305
- // Handle v1 if not disabled
306
- if (!isTTVCv1Disabled) {
307
- var _window$__ufo_devtool, _window;
308
- (_window$__ufo_devtool = (_window = window).__ufo_devtool_onVCRevisionReady__) === null || _window$__ufo_devtool === void 0 ? void 0 : _window$__ufo_devtool.call(_window, v1RevisionDebugDetails);
309
- }
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
+ }
310
315
 
311
- // Handle v2
312
- (_window$__ufo_devtool2 = (_window2 = window).__ufo_devtool_onVCRevisionReady__) === null || _window$__ufo_devtool2 === void 0 ? void 0 : _window$__ufo_devtool2.call(_window2, v2RevisionDebugDetails);
313
- }
314
- if (typeof window.__on_ufo_vc_debug_data_ready === 'function' && fg('platform_ufo_emit_vc_debug_data')) {
315
- var _window$__on_ufo_vc_d2, _window4;
316
- if (!isTTVCv1Disabled) {
317
- var _window$__on_ufo_vc_d, _window3;
318
- (_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);
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);
319
326
  }
320
- (_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);
321
327
  }
322
328
  }
323
329
  } catch (e) {
@@ -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 {