@atlaskit/react-ufo 3.12.4 → 3.13.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 (109) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/create-experimental-interaction-metrics-payload/index.js +2 -1
  3. package/dist/cjs/create-payload/utils/get-vc-metrics.js +2 -1
  4. package/dist/cjs/vc/index.js +4 -2
  5. package/dist/cjs/vc/vc-observer/getVCRevisionDebugDetails.js +41 -0
  6. package/dist/cjs/vc/vc-observer/index.js +63 -33
  7. package/dist/cjs/vc/vc-observer/observers/index.js +3 -2
  8. package/dist/cjs/vc/vc-observer/observers/ssr-placeholders/index.js +38 -12
  9. package/dist/cjs/vc/vc-observer/observers/ssr-placeholders/ssr-scripts/collectSSRPlaceholderDimensions.js +9 -0
  10. package/dist/cjs/vc/vc-observer-new/index.js +13 -7
  11. package/dist/cjs/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +211 -36
  12. package/dist/cjs/vc/vc-observer-new/metric-calculator/fy25_03/index.js +4 -4
  13. package/dist/cjs/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/index.js +94 -4
  14. package/dist/cjs/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/test-with-debug-info.js +108 -0
  15. package/dist/cjs/vc/vc-observer-new/metric-calculator/percentile-calc/index.js +16 -57
  16. package/dist/cjs/vc/vc-observer-new/viewport-observer/index.js +15 -5
  17. package/dist/cjs/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +3 -1
  18. package/dist/es2019/create-experimental-interaction-metrics-payload/index.js +2 -1
  19. package/dist/es2019/create-payload/utils/get-vc-metrics.js +1 -0
  20. package/dist/es2019/vc/index.js +4 -2
  21. package/dist/es2019/vc/vc-observer/getVCRevisionDebugDetails.js +32 -0
  22. package/dist/es2019/vc/vc-observer/index.js +36 -1
  23. package/dist/es2019/vc/vc-observer/observers/index.js +2 -1
  24. package/dist/es2019/vc/vc-observer/observers/ssr-placeholders/index.js +38 -13
  25. package/dist/es2019/vc/vc-observer/observers/ssr-placeholders/ssr-scripts/collectSSRPlaceholderDimensions.js +9 -1
  26. package/dist/es2019/vc/vc-observer-new/index.js +12 -6
  27. package/dist/es2019/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +115 -17
  28. package/dist/es2019/vc/vc-observer-new/metric-calculator/fy25_03/index.js +4 -4
  29. package/dist/es2019/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/index.js +44 -1
  30. package/dist/es2019/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/test-with-debug-info.js +75 -0
  31. package/dist/es2019/vc/vc-observer-new/metric-calculator/percentile-calc/index.js +2 -20
  32. package/dist/es2019/vc/vc-observer-new/viewport-observer/index.js +15 -5
  33. package/dist/es2019/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +3 -1
  34. package/dist/esm/create-experimental-interaction-metrics-payload/index.js +2 -1
  35. package/dist/esm/create-payload/utils/get-vc-metrics.js +2 -1
  36. package/dist/esm/vc/index.js +4 -2
  37. package/dist/esm/vc/vc-observer/getVCRevisionDebugDetails.js +35 -0
  38. package/dist/esm/vc/vc-observer/index.js +63 -33
  39. package/dist/esm/vc/vc-observer/observers/index.js +3 -2
  40. package/dist/esm/vc/vc-observer/observers/ssr-placeholders/index.js +38 -12
  41. package/dist/esm/vc/vc-observer/observers/ssr-placeholders/ssr-scripts/collectSSRPlaceholderDimensions.js +9 -0
  42. package/dist/esm/vc/vc-observer-new/index.js +13 -7
  43. package/dist/esm/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +211 -36
  44. package/dist/esm/vc/vc-observer-new/metric-calculator/fy25_03/index.js +4 -4
  45. package/dist/esm/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/index.js +94 -5
  46. package/dist/esm/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/test-with-debug-info.js +106 -0
  47. package/dist/esm/vc/vc-observer-new/metric-calculator/percentile-calc/index.js +2 -55
  48. package/dist/esm/vc/vc-observer-new/viewport-observer/index.js +15 -5
  49. package/dist/esm/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +3 -1
  50. package/dist/types/config/index.d.ts +1 -0
  51. package/dist/types/vc/types.d.ts +2 -0
  52. package/dist/types/vc/vc-observer/getVCRevisionDebugDetails.d.ts +30 -0
  53. package/dist/types/vc/vc-observer/index.d.ts +1 -1
  54. package/dist/types/vc/vc-observer/observers/index.d.ts +3 -0
  55. package/dist/types/vc/vc-observer/observers/ssr-placeholders/index.d.ts +4 -1
  56. package/dist/types/vc/vc-observer/observers/ssr-placeholders/ssr-scripts/collectSSRPlaceholderDimensions.d.ts +1 -1
  57. package/dist/types/vc/vc-observer-new/index.d.ts +2 -0
  58. package/dist/types/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +4 -1
  59. package/dist/types/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/index.d.ts +5 -1
  60. package/dist/types/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/test-with-debug-info.d.ts +1 -0
  61. package/dist/types/vc/vc-observer-new/metric-calculator/percentile-calc/index.d.ts +2 -4
  62. package/dist/types/vc/vc-observer-new/metric-calculator/percentile-calc/types.d.ts +20 -2
  63. package/dist/types/vc/vc-observer-new/metric-calculator/types.d.ts +2 -0
  64. package/dist/types/vc/vc-observer-new/types.d.ts +5 -1
  65. package/dist/types/vc/vc-observer-new/viewport-observer/mutation-observer/index.d.ts +2 -0
  66. package/dist/types/vc/vc-observer-new/viewport-observer/types.d.ts +2 -0
  67. package/dist/types-ts4.5/config/index.d.ts +1 -0
  68. package/dist/types-ts4.5/vc/types.d.ts +2 -0
  69. package/dist/types-ts4.5/vc/vc-observer/getVCRevisionDebugDetails.d.ts +30 -0
  70. package/dist/types-ts4.5/vc/vc-observer/index.d.ts +1 -1
  71. package/dist/types-ts4.5/vc/vc-observer/observers/index.d.ts +3 -0
  72. package/dist/types-ts4.5/vc/vc-observer/observers/ssr-placeholders/index.d.ts +4 -1
  73. package/dist/types-ts4.5/vc/vc-observer/observers/ssr-placeholders/ssr-scripts/collectSSRPlaceholderDimensions.d.ts +1 -1
  74. package/dist/types-ts4.5/vc/vc-observer-new/index.d.ts +2 -0
  75. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +4 -1
  76. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/index.d.ts +5 -1
  77. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/test-with-debug-info.d.ts +1 -0
  78. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/percentile-calc/index.d.ts +2 -4
  79. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/percentile-calc/types.d.ts +20 -2
  80. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/types.d.ts +2 -0
  81. package/dist/types-ts4.5/vc/vc-observer-new/types.d.ts +5 -1
  82. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/mutation-observer/index.d.ts +2 -0
  83. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/types.d.ts +2 -0
  84. package/package.json +4 -1
  85. package/dist/cjs/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/heatmap.js +0 -367
  86. package/dist/cjs/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/index.js +0 -398
  87. package/dist/cjs/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/types.js +0 -5
  88. package/dist/cjs/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/calc-union-area.js +0 -152
  89. package/dist/cjs/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/index.js +0 -108
  90. package/dist/es2019/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/heatmap.js +0 -248
  91. package/dist/es2019/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/index.js +0 -263
  92. package/dist/es2019/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/types.js +0 -1
  93. package/dist/es2019/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/calc-union-area.js +0 -99
  94. package/dist/es2019/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/index.js +0 -60
  95. package/dist/esm/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/heatmap.js +0 -361
  96. package/dist/esm/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/index.js +0 -391
  97. package/dist/esm/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/types.js +0 -1
  98. package/dist/esm/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/calc-union-area.js +0 -145
  99. package/dist/esm/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/index.js +0 -101
  100. package/dist/types/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/heatmap.d.ts +0 -39
  101. package/dist/types/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/index.d.ts +0 -10
  102. package/dist/types/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/types.d.ts +0 -43
  103. package/dist/types/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/calc-union-area.d.ts +0 -12
  104. package/dist/types/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/index.d.ts +0 -25
  105. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/heatmap.d.ts +0 -39
  106. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/index.d.ts +0 -10
  107. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/types.d.ts +0 -43
  108. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/calc-union-area.d.ts +0 -12
  109. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/index.d.ts +0 -25
@@ -17,12 +17,14 @@ var DEFAULT_SELECTOR_CONFIG = {
17
17
  };
18
18
  var VCObserverNew = /*#__PURE__*/function () {
19
19
  function VCObserverNew(config) {
20
- var _config$selectorConfi,
20
+ var _config$isPostInterac,
21
+ _config$selectorConfi,
21
22
  _this = this;
22
23
  _classCallCheck(this, VCObserverNew);
23
24
  _defineProperty(this, "viewportObserver", null);
24
25
  _defineProperty(this, "windowEventObserver", null);
25
26
  this.entriesTimeline = new EntriesTimeline();
27
+ this.isPostInteraction = (_config$isPostInterac = config.isPostInteraction) !== null && _config$isPostInterac !== void 0 ? _config$isPostInterac : false;
26
28
  this.selectorConfig = (_config$selectorConfi = config.selectorConfig) !== null && _config$selectorConfi !== void 0 ? _config$selectorConfi : DEFAULT_SELECTOR_CONFIG;
27
29
  this.viewportObserver = new ViewportObserver({
28
30
  onChange: function onChange(onChangeArg) {
@@ -40,13 +42,15 @@ var VCObserverNew = /*#__PURE__*/function () {
40
42
  }
41
43
  _this.entriesTimeline.push({
42
44
  time: time,
43
- type: type,
44
45
  data: {
46
+ type: type,
45
47
  elementName: elementName,
46
48
  rect: rect,
47
49
  previousRect: previousRect,
48
50
  visible: visible,
49
- attributeName: mutationData === null || mutationData === void 0 ? void 0 : mutationData.attributeName
51
+ attributeName: mutationData === null || mutationData === void 0 ? void 0 : mutationData.attributeName,
52
+ oldValue: mutationData === null || mutationData === void 0 ? void 0 : mutationData.oldValue,
53
+ newValue: mutationData === null || mutationData === void 0 ? void 0 : mutationData.newValue
50
54
  }
51
55
  });
52
56
  }
@@ -57,8 +61,8 @@ var VCObserverNew = /*#__PURE__*/function () {
57
61
  type = _ref.type;
58
62
  _this.entriesTimeline.push({
59
63
  time: time,
60
- type: 'window:event',
61
64
  data: {
65
+ type: 'window:event',
62
66
  eventType: type
63
67
  }
64
68
  });
@@ -85,11 +89,11 @@ var VCObserverNew = /*#__PURE__*/function () {
85
89
  key: "getVCResult",
86
90
  value: function () {
87
91
  var _getVCResult = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(param) {
88
- var start, stop, results, calculator_fy25_03, orderedEntries, fy25_03;
92
+ var start, stop, interactionId, results, calculator_fy25_03, orderedEntries, fy25_03;
89
93
  return _regeneratorRuntime.wrap(function _callee$(_context) {
90
94
  while (1) switch (_context.prev = _context.next) {
91
95
  case 0:
92
- start = param.start, stop = param.stop;
96
+ start = param.start, stop = param.stop, interactionId = param.interactionId;
93
97
  results = [];
94
98
  calculator_fy25_03 = new VCCalculator_FY25_03();
95
99
  orderedEntries = this.entriesTimeline.getOrderedEntries({
@@ -100,7 +104,9 @@ var VCObserverNew = /*#__PURE__*/function () {
100
104
  return calculator_fy25_03.calculate({
101
105
  orderedEntries: orderedEntries,
102
106
  startTime: start,
103
- stopTime: stop
107
+ stopTime: stop,
108
+ interactionId: interactionId,
109
+ isPostInteraction: this.isPostInteraction
104
110
  });
105
111
  case 6:
106
112
  fy25_03 = _context.sent;
@@ -1,9 +1,12 @@
1
1
  import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
2
  import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
3
3
  import _createClass from "@babel/runtime/helpers/createClass";
4
+ 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; } } }; }
5
+ 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; } }
6
+ 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; }
4
7
  import _regeneratorRuntime from "@babel/runtime/regenerator";
5
8
  import { fg } from '@atlaskit/platform-feature-flags';
6
- import calculateTTVCPercentiles from './percentile-calc';
9
+ import { calculateTTVCPercentiles, calculateTTVCPercentilesWithDebugInfo } from './percentile-calc';
7
10
  import getViewportHeight from './utils/get-viewport-height';
8
11
  import getViewportWidth from './utils/get-viewport-width';
9
12
  var AbstractVCCalculatorBase = /*#__PURE__*/function () {
@@ -12,76 +15,248 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
12
15
  this.revisionNo = revisionNo;
13
16
  }
14
17
  return _createClass(AbstractVCCalculatorBase, [{
18
+ key: "filterViewportEntries",
19
+ value: function filterViewportEntries(entries) {
20
+ return entries.filter(function (entry) {
21
+ return 'rect' in entry.data;
22
+ });
23
+ }
24
+ }, {
25
+ key: "calculateBasic",
26
+ value: function () {
27
+ var _calculateBasic = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(filteredEntries, startTime, stopTime) {
28
+ var percentiles, viewportEntries, vcLogs;
29
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
30
+ while (1) switch (_context.prev = _context.next) {
31
+ case 0:
32
+ percentiles = [25, 50, 75, 80, 85, 90, 95, 98, 99];
33
+ viewportEntries = this.filterViewportEntries(filteredEntries);
34
+ _context.next = 4;
35
+ return calculateTTVCPercentiles({
36
+ viewport: {
37
+ width: getViewportWidth(),
38
+ height: getViewportHeight()
39
+ },
40
+ startTime: startTime,
41
+ stopTime: stopTime,
42
+ orderedEntries: viewportEntries,
43
+ percentiles: percentiles
44
+ });
45
+ case 4:
46
+ vcLogs = _context.sent;
47
+ return _context.abrupt("return", vcLogs);
48
+ case 6:
49
+ case "end":
50
+ return _context.stop();
51
+ }
52
+ }, _callee, this);
53
+ }));
54
+ function calculateBasic(_x, _x2, _x3) {
55
+ return _calculateBasic.apply(this, arguments);
56
+ }
57
+ return calculateBasic;
58
+ }()
59
+ }, {
60
+ key: "calculateWithDebugInfo",
61
+ value: function () {
62
+ var _calculateWithDebugInfo = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(filteredEntries, startTime, stopTime, isPostInteraction, isVCClean, interactionId, dirtyReason) {
63
+ var percentiles, viewportEntries, vcLogs, vcDetails, percentileIndex, entryDataBuffer, _iterator, _step, _entry, time, viewportPercentage, entries, elementNames, previousResult, i, percentile, _ufo_devtool_onVCRev, _ref;
64
+ return _regeneratorRuntime.wrap(function _callee2$(_context2) {
65
+ while (1) switch (_context2.prev = _context2.next) {
66
+ case 0:
67
+ percentiles = [25, 50, 75, 80, 85, 90, 95, 98, 99];
68
+ viewportEntries = this.filterViewportEntries(filteredEntries);
69
+ _context2.next = 4;
70
+ return calculateTTVCPercentilesWithDebugInfo({
71
+ viewport: {
72
+ width: getViewportWidth(),
73
+ height: getViewportHeight()
74
+ },
75
+ startTime: startTime,
76
+ stopTime: stopTime,
77
+ orderedEntries: viewportEntries
78
+ });
79
+ case 4:
80
+ vcLogs = _context2.sent;
81
+ vcDetails = {};
82
+ percentileIndex = 0;
83
+ entryDataBuffer = new Set();
84
+ if (!vcLogs) {
85
+ _context2.next = 28;
86
+ break;
87
+ }
88
+ _iterator = _createForOfIteratorHelper(vcLogs);
89
+ _context2.prev = 10;
90
+ _iterator.s();
91
+ case 12:
92
+ if ((_step = _iterator.n()).done) {
93
+ _context2.next = 20;
94
+ break;
95
+ }
96
+ _entry = _step.value;
97
+ time = _entry.time, viewportPercentage = _entry.viewportPercentage, entries = _entry.entries; // Only process entries if we haven't reached all percentiles
98
+ if (!(percentileIndex >= percentiles.length)) {
99
+ _context2.next = 17;
100
+ break;
101
+ }
102
+ return _context2.abrupt("break", 20);
103
+ case 17:
104
+ // Check if this entry matches any checkpoint percentiles
105
+ if (viewportPercentage >= percentiles[percentileIndex]) {
106
+ elementNames = entries.map(function (e) {
107
+ return e.elementName;
108
+ }); // Process all matching percentiles in one go
109
+ while (percentileIndex < percentiles.length && viewportPercentage >= percentiles[percentileIndex]) {
110
+ vcDetails["".concat(percentiles[percentileIndex])] = {
111
+ t: Math.round(time),
112
+ e: elementNames
113
+ };
114
+ percentileIndex++;
115
+ }
116
+
117
+ // Clear buffer after processing all matching percentiles
118
+ entryDataBuffer.clear();
119
+ } else {
120
+ // Only add to buffer if we haven't reached all percentiles
121
+ entries.forEach(function (e) {
122
+ return entryDataBuffer.add(e);
123
+ });
124
+ }
125
+ case 18:
126
+ _context2.next = 12;
127
+ break;
128
+ case 20:
129
+ _context2.next = 25;
130
+ break;
131
+ case 22:
132
+ _context2.prev = 22;
133
+ _context2.t0 = _context2["catch"](10);
134
+ _iterator.e(_context2.t0);
135
+ case 25:
136
+ _context2.prev = 25;
137
+ _iterator.f();
138
+ return _context2.finish(25);
139
+ case 28:
140
+ // Fill in any missing percentiles with the last known values
141
+ previousResult = {
142
+ t: 0,
143
+ e: []
144
+ };
145
+ for (i = 0; i < percentiles.length; i++) {
146
+ percentile = percentiles[i];
147
+ if (!(percentile in vcDetails)) {
148
+ vcDetails["".concat(percentile)] = previousResult;
149
+ } else {
150
+ previousResult = vcDetails["".concat(percentile)];
151
+ }
152
+ }
153
+
154
+ // Handle devtool callback
155
+ if (!isPostInteraction && typeof window !== 'undefined' && typeof window.__ufo_devtool_onVCRevisionReady__ === 'function' && fg('platform_ufo_ttvc_v3_devtool')) {
156
+ try {
157
+ (_ufo_devtool_onVCRev = (_ref = window).__ufo_devtool_onVCRevisionReady__) === null || _ufo_devtool_onVCRev === void 0 || _ufo_devtool_onVCRev.call(_ref, {
158
+ revision: this.revisionNo,
159
+ isClean: isVCClean,
160
+ abortReason: dirtyReason,
161
+ vcLogs: vcLogs,
162
+ interactionId: interactionId
163
+ });
164
+ } catch (e) {
165
+ // if any error communicating with devtool, we don't want to break the app
166
+ // eslint-disable-next-line no-console
167
+ console.error('Error in onVCRevisionReady', e);
168
+ }
169
+ }
170
+ return _context2.abrupt("return", vcDetails);
171
+ case 32:
172
+ case "end":
173
+ return _context2.stop();
174
+ }
175
+ }, _callee2, this, [[10, 22, 25, 28]]);
176
+ }));
177
+ function calculateWithDebugInfo(_x4, _x5, _x6, _x7, _x8, _x9, _x10) {
178
+ return _calculateWithDebugInfo.apply(this, arguments);
179
+ }
180
+ return calculateWithDebugInfo;
181
+ }()
182
+ }, {
15
183
  key: "calculate",
16
184
  value: function () {
17
- var _calculate = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref) {
185
+ var _calculate = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(_ref2) {
18
186
  var _this = this,
19
187
  _vcDetails$90$t,
20
188
  _vcDetails$;
21
- var startTime, stopTime, orderedEntries, filteredEntries, _this$getVCCleanStatu, _isVCClean, dirtyReason, _isVCClean2, vcDetails;
22
- return _regeneratorRuntime.wrap(function _callee$(_context) {
23
- while (1) switch (_context.prev = _context.next) {
189
+ var startTime, stopTime, orderedEntries, interactionId, isPostInteraction, filteredEntries, isVCClean, dirtyReason, getVCCleanStatusResult, useDebugInfo, vcDetails;
190
+ return _regeneratorRuntime.wrap(function _callee3$(_context3) {
191
+ while (1) switch (_context3.prev = _context3.next) {
24
192
  case 0:
25
- startTime = _ref.startTime, stopTime = _ref.stopTime, orderedEntries = _ref.orderedEntries;
193
+ startTime = _ref2.startTime, stopTime = _ref2.stopTime, orderedEntries = _ref2.orderedEntries, interactionId = _ref2.interactionId, isPostInteraction = _ref2.isPostInteraction;
26
194
  filteredEntries = orderedEntries.filter(function (entry) {
27
195
  return _this.isEntryIncluded(entry);
28
196
  });
29
197
  if (!fg('platform_ufo_add_vc_abort_reason_by_revisions')) {
30
- _context.next = 8;
198
+ _context3.next = 10;
31
199
  break;
32
200
  }
33
- _this$getVCCleanStatu = this.getVCCleanStatus(filteredEntries), _isVCClean = _this$getVCCleanStatu.isVCClean, dirtyReason = _this$getVCCleanStatu.dirtyReason;
34
- if (_isVCClean) {
35
- _context.next = 6;
201
+ getVCCleanStatusResult = this.getVCCleanStatus(filteredEntries);
202
+ isVCClean = getVCCleanStatusResult.isVCClean;
203
+ dirtyReason = getVCCleanStatusResult.dirtyReason;
204
+ if (isVCClean) {
205
+ _context3.next = 8;
36
206
  break;
37
207
  }
38
- return _context.abrupt("return", {
208
+ return _context3.abrupt("return", {
39
209
  revision: this.revisionNo,
40
210
  'metric:vc90': null,
41
211
  clean: false,
42
212
  abortReason: dirtyReason
43
213
  });
44
- case 6:
45
- _context.next = 11;
46
- break;
47
214
  case 8:
48
- _isVCClean2 = this.isVCClean(filteredEntries);
49
- if (_isVCClean2) {
50
- _context.next = 11;
215
+ _context3.next = 13;
216
+ break;
217
+ case 10:
218
+ isVCClean = this.isVCClean(filteredEntries);
219
+ if (isVCClean) {
220
+ _context3.next = 13;
51
221
  break;
52
222
  }
53
- return _context.abrupt("return", {
223
+ return _context3.abrupt("return", {
54
224
  revision: this.revisionNo,
55
225
  'metric:vc90': null,
56
226
  clean: false
57
227
  });
58
- case 11:
59
- _context.next = 13;
60
- return calculateTTVCPercentiles({
61
- viewport: {
62
- width: getViewportWidth(),
63
- height: getViewportHeight()
64
- },
65
- startTime: startTime,
66
- stopTime: stopTime,
67
- orderedEntries: filteredEntries,
68
- percentiles: [25, 50, 75, 80, 85, 90, 95, 98, 99]
69
- });
70
228
  case 13:
71
- vcDetails = _context.sent;
72
- return _context.abrupt("return", {
229
+ useDebugInfo = fg('platform_ufo_ttvc_v3_devtool');
230
+ if (!useDebugInfo) {
231
+ _context3.next = 20;
232
+ break;
233
+ }
234
+ _context3.next = 17;
235
+ return this.calculateWithDebugInfo(filteredEntries, startTime, stopTime, isPostInteraction, isVCClean, interactionId, dirtyReason);
236
+ case 17:
237
+ _context3.t0 = _context3.sent;
238
+ _context3.next = 23;
239
+ break;
240
+ case 20:
241
+ _context3.next = 22;
242
+ return this.calculateBasic(filteredEntries, startTime, stopTime);
243
+ case 22:
244
+ _context3.t0 = _context3.sent;
245
+ case 23:
246
+ vcDetails = _context3.t0;
247
+ return _context3.abrupt("return", {
73
248
  revision: this.revisionNo,
74
249
  clean: true,
75
250
  'metric:vc90': (_vcDetails$90$t = vcDetails === null || vcDetails === void 0 || (_vcDetails$ = vcDetails['90']) === null || _vcDetails$ === void 0 ? void 0 : _vcDetails$.t) !== null && _vcDetails$90$t !== void 0 ? _vcDetails$90$t : null,
76
251
  vcDetails: vcDetails !== null && vcDetails !== void 0 ? vcDetails : undefined
77
252
  });
78
- case 15:
253
+ case 25:
79
254
  case "end":
80
- return _context.stop();
255
+ return _context3.stop();
81
256
  }
82
- }, _callee, this);
257
+ }, _callee3, this);
83
258
  }));
84
- function calculate(_x) {
259
+ function calculate(_x11) {
85
260
  return _calculate.apply(this, arguments);
86
261
  }
87
262
  return calculate;
@@ -24,10 +24,10 @@ var VCCalculator_FY25_03 = /*#__PURE__*/function (_AbstractVCCalculator) {
24
24
  return _createClass(VCCalculator_FY25_03, [{
25
25
  key: "isEntryIncluded",
26
26
  value: function isEntryIncluded(entry) {
27
- if (!CONSIDERED_ENTRY_TYPE.includes(entry.type)) {
27
+ if (!CONSIDERED_ENTRY_TYPE.includes(entry.data.type)) {
28
28
  return false;
29
29
  }
30
- if (entry.type === 'mutation:attribute') {
30
+ if (entry.data.type === 'mutation:attribute') {
31
31
  var entryData = entry.data;
32
32
  var attributeName = entryData.attributeName;
33
33
  if (!attributeName || KNOWN_ATTRIBUTES_THAT_DOES_NOT_CAUSE_LAYOUT_SHIFTS.includes(attributeName)) {
@@ -44,7 +44,7 @@ var VCCalculator_FY25_03 = /*#__PURE__*/function (_AbstractVCCalculator) {
44
44
  key: "isVCClean",
45
45
  value: function isVCClean(filteredEntries) {
46
46
  var hasAbortEvent = filteredEntries.some(function (entry) {
47
- if (entry.type === 'window:event') {
47
+ if (entry.data.type === 'window:event') {
48
48
  var data = entry.data;
49
49
  if (ABORTING_WINDOW_EVENT.includes(data.eventType)) {
50
50
  return true;
@@ -59,7 +59,7 @@ var VCCalculator_FY25_03 = /*#__PURE__*/function (_AbstractVCCalculator) {
59
59
  value: function getVCCleanStatus(filteredEntries) {
60
60
  var dirtyReason = '';
61
61
  var hasAbortEvent = filteredEntries.some(function (entry) {
62
- if (entry.type === 'window:event') {
62
+ if (entry.data.type === 'window:event') {
63
63
  var data = entry.data;
64
64
  if (ABORTING_WINDOW_EVENT.includes(data.eventType)) {
65
65
  dirtyReason = data.eventType === 'keydown' ? 'keypress' : data.eventType;
@@ -70,6 +70,69 @@ function _calculateTTVCPercentiles() {
70
70
  }));
71
71
  return _calculateTTVCPercentiles.apply(this, arguments);
72
72
  }
73
+ function calculateTTVCPercentilesWithDebugInfo(_x2) {
74
+ return _calculateTTVCPercentilesWithDebugInfo.apply(this, arguments);
75
+ }
76
+ function _calculateTTVCPercentilesWithDebugInfo() {
77
+ _calculateTTVCPercentilesWithDebugInfo = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(_ref2) {
78
+ var viewport, orderedEntries, startTime, canvas, elementMap, _iterator3, _step3, entry, rect, timePixelCounts, canvasDimensions, totalPixels;
79
+ return _regeneratorRuntime.wrap(function _callee2$(_context2) {
80
+ while (1) switch (_context2.prev = _context2.next) {
81
+ case 0:
82
+ viewport = _ref2.viewport, orderedEntries = _ref2.orderedEntries, startTime = _ref2.startTime;
83
+ canvas = new ViewportCanvas(viewport, fg('platform_ufo_canvas_heatmap_full_precision') ? 1 : 0.25);
84
+ elementMap = new Map();
85
+ _iterator3 = _createForOfIteratorHelper(orderedEntries);
86
+ _context2.prev = 4;
87
+ _iterator3.s();
88
+ case 6:
89
+ if ((_step3 = _iterator3.n()).done) {
90
+ _context2.next = 16;
91
+ break;
92
+ }
93
+ entry = _step3.value;
94
+ if ('rect' in entry.data) {
95
+ _context2.next = 10;
96
+ break;
97
+ }
98
+ return _context2.abrupt("continue", 14);
99
+ case 10:
100
+ rect = entry.data.rect;
101
+ canvas.drawRect(rect, entry.time);
102
+ if (!elementMap.has(entry.time)) {
103
+ elementMap.set(entry.time, []);
104
+ }
105
+ elementMap.get(entry.time).push(entry.data);
106
+ case 14:
107
+ _context2.next = 6;
108
+ break;
109
+ case 16:
110
+ _context2.next = 21;
111
+ break;
112
+ case 18:
113
+ _context2.prev = 18;
114
+ _context2.t0 = _context2["catch"](4);
115
+ _iterator3.e(_context2.t0);
116
+ case 21:
117
+ _context2.prev = 21;
118
+ _iterator3.f();
119
+ return _context2.finish(21);
120
+ case 24:
121
+ _context2.next = 26;
122
+ return canvas.getPixelCounts();
123
+ case 26:
124
+ timePixelCounts = _context2.sent;
125
+ canvasDimensions = canvas.getScaledDimensions();
126
+ totalPixels = canvasDimensions.width * canvasDimensions.height;
127
+ return _context2.abrupt("return", calculatePercentilesWithDebugInfo(timePixelCounts, elementMap, totalPixels, startTime));
128
+ case 30:
129
+ case "end":
130
+ return _context2.stop();
131
+ }
132
+ }, _callee2, null, [[4, 18, 21, 24]]);
133
+ }));
134
+ return _calculateTTVCPercentilesWithDebugInfo.apply(this, arguments);
135
+ }
73
136
  export default calculateTTVCPercentiles;
74
137
  export function calculatePercentiles(timePixelCounts, elementMap, unorderedPercentiles, totalPixels, startTime) {
75
138
  var results = {};
@@ -79,11 +142,11 @@ export function calculatePercentiles(timePixelCounts, elementMap, unorderedPerce
79
142
  });
80
143
 
81
144
  // Sort entries by timestamp for consistent processing
82
- var sortedEntries = Array.from(timePixelCounts.entries()).sort(function (_ref2, _ref3) {
83
- var _ref4 = _slicedToArray(_ref2, 1),
84
- timeA = _ref4[0];
145
+ var sortedEntries = Array.from(timePixelCounts.entries()).sort(function (_ref3, _ref4) {
85
146
  var _ref5 = _slicedToArray(_ref3, 1),
86
- timeB = _ref5[0];
147
+ timeA = _ref5[0];
148
+ var _ref6 = _slicedToArray(_ref4, 1),
149
+ timeB = _ref6[0];
87
150
  return Number(timeA) - Number(timeB);
88
151
  });
89
152
  var percentileIndex = 0;
@@ -134,4 +197,30 @@ export function calculatePercentiles(timePixelCounts, elementMap, unorderedPerce
134
197
  previousResult = results["".concat(percentile)];
135
198
  }
136
199
  return results;
137
- }
200
+ }
201
+ export function calculatePercentilesWithDebugInfo(timePixelCounts, elementMap, totalPixels, startTime) {
202
+ var results = new Array(elementMap.size);
203
+ var cumulativePixels = 0;
204
+ var sortedEntries = Array.from(timePixelCounts.entries()).sort(function (_ref7, _ref8) {
205
+ var _ref9 = _slicedToArray(_ref7, 1),
206
+ timeA = _ref9[0];
207
+ var _ref10 = _slicedToArray(_ref8, 1),
208
+ timeB = _ref10[0];
209
+ return Number(timeA) - Number(timeB);
210
+ });
211
+ for (var i = 0; i < sortedEntries.length; i++) {
212
+ var _sortedEntries$i = _slicedToArray(sortedEntries[i], 2),
213
+ time = _sortedEntries$i[0],
214
+ pixelCount = _sortedEntries$i[1];
215
+ cumulativePixels += pixelCount;
216
+ var percentCovered = cumulativePixels / totalPixels * 100;
217
+ var entryDatas = elementMap.get(time) || [];
218
+ results[i] = {
219
+ time: Math.round(Number(time - startTime)),
220
+ viewportPercentage: percentCovered,
221
+ entries: Array.from(entryDatas)
222
+ };
223
+ }
224
+ return results;
225
+ }
226
+ export { calculateTTVCPercentilesWithDebugInfo };
@@ -0,0 +1,106 @@
1
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
2
+ import _createClass from "@babel/runtime/helpers/createClass";
3
+ import { calculatePercentilesWithDebugInfo } from './index';
4
+
5
+ // Test utilities
6
+ var createMockRect = function createMockRect() {
7
+ var x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
8
+ var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
9
+ var width = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 100;
10
+ var height = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 100;
11
+ return new MockDOMRect(x, y, width, height);
12
+ };
13
+ var createViewportEntry = function createViewportEntry(elementName) {
14
+ var rect = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : createMockRect();
15
+ var visible = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
16
+ var type = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'mutation:element';
17
+ return {
18
+ elementName: elementName,
19
+ rect: rect,
20
+ visible: visible,
21
+ type: type
22
+ };
23
+ };
24
+ var createTimePixelCounts = function createTimePixelCounts(counts) {
25
+ return new Map(counts);
26
+ };
27
+ var createElementMap = function createElementMap(entries) {
28
+ return new Map(entries);
29
+ };
30
+ var createExpectedResult = function createExpectedResult(time, viewportPercentage, entries) {
31
+ return {
32
+ time: time,
33
+ viewportPercentage: viewportPercentage,
34
+ entries: entries
35
+ };
36
+ };
37
+ var MockDOMRect = /*#__PURE__*/function () {
38
+ function MockDOMRect(x, y, width, height) {
39
+ _classCallCheck(this, MockDOMRect);
40
+ this.x = x;
41
+ this.y = y;
42
+ this.width = width;
43
+ this.height = height;
44
+ }
45
+ return _createClass(MockDOMRect, [{
46
+ key: "bottom",
47
+ get: function get() {
48
+ return this.y + this.height;
49
+ }
50
+ }, {
51
+ key: "left",
52
+ get: function get() {
53
+ return this.x;
54
+ }
55
+ }, {
56
+ key: "right",
57
+ get: function get() {
58
+ return this.x + this.width;
59
+ }
60
+ }, {
61
+ key: "top",
62
+ get: function get() {
63
+ return this.y;
64
+ }
65
+ }, {
66
+ key: "toJSON",
67
+ value: function toJSON() {
68
+ return {
69
+ x: this.x,
70
+ y: this.y,
71
+ width: this.width,
72
+ height: this.height
73
+ };
74
+ }
75
+ }]);
76
+ }();
77
+ describe('calculatePercentilesWithDebugInfo', function () {
78
+ it('should correctly calculate percentiles with accumulated elements from timestamps', function () {
79
+ var timePixelCounts = createTimePixelCounts([[100, 10], [200, 20], [300, 10], [400, 10]]);
80
+ var elementMap = createElementMap([[100, [createViewportEntry('div'), createViewportEntry('span')]], [200, [createViewportEntry('img')]], [300, [createViewportEntry('p'), createViewportEntry('a')]], [400, [createViewportEntry('img')]]]);
81
+ var expected = [createExpectedResult(100, 20, [createViewportEntry('div'), createViewportEntry('span')]), createExpectedResult(200, 60, [createViewportEntry('img')]), createExpectedResult(300, 80, [createViewportEntry('p'), createViewportEntry('a')]), createExpectedResult(400, 100, [createViewportEntry('img')])];
82
+ var result = calculatePercentilesWithDebugInfo(timePixelCounts, elementMap, 50, 0);
83
+ expect(result).toEqual(expected);
84
+ });
85
+ it('should handle empty entries gracefully', function () {
86
+ var timePixelCounts = new Map();
87
+ var elementMap = new Map();
88
+ var expected = [];
89
+ var result = calculatePercentilesWithDebugInfo(timePixelCounts, elementMap, 100, 0);
90
+ expect(result).toEqual(expected);
91
+ });
92
+ it('should handle non-sequential timestamps', function () {
93
+ var timePixelCounts = createTimePixelCounts([[300, 70], [100, 30]]);
94
+ var elementMap = createElementMap([[300, [createViewportEntry('p'), createViewportEntry('a')]], [100, [createViewportEntry('div')]]]);
95
+ var expected = [createExpectedResult(100, 30, [createViewportEntry('div')]), createExpectedResult(300, 100, [createViewportEntry('p'), createViewportEntry('a')])];
96
+ var result = calculatePercentilesWithDebugInfo(timePixelCounts, elementMap, 100, 0);
97
+ expect(result).toEqual(expected);
98
+ });
99
+ it('should correctly calculate percentiles with startTime offset', function () {
100
+ var timePixelCounts = createTimePixelCounts([[100, 10], [200, 20], [300, 10], [400, 10]]);
101
+ var elementMap = createElementMap([[100, [createViewportEntry('div'), createViewportEntry('span')]], [200, [createViewportEntry('img')]], [300, [createViewportEntry('p'), createViewportEntry('a')]], [400, [createViewportEntry('img')]]]);
102
+ var expected = [createExpectedResult(50, 20, [createViewportEntry('div'), createViewportEntry('span')]), createExpectedResult(150, 60, [createViewportEntry('img')]), createExpectedResult(250, 80, [createViewportEntry('p'), createViewportEntry('a')]), createExpectedResult(350, 100, [createViewportEntry('img')])];
103
+ var result = calculatePercentilesWithDebugInfo(timePixelCounts, elementMap, 50, 50);
104
+ expect(result).toEqual(expected);
105
+ });
106
+ });