@atlaskit/react-ufo 2.14.3 → 2.15.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 (50) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/create-payload/index.js +10 -0
  3. package/dist/cjs/experience-trace-id-context/index.js +5 -1
  4. package/dist/cjs/segment/segment.js +7 -1
  5. package/dist/cjs/vc/vc-observer/heatmap/heatmap.js +275 -0
  6. package/dist/cjs/vc/vc-observer/index.js +115 -26
  7. package/dist/cjs/vc/vc-observer/revisions/ViewportUpdateClassifier.js +52 -0
  8. package/dist/cjs/vc/vc-observer/revisions/fy24_01.js +39 -0
  9. package/dist/cjs/vc/vc-observer/revisions/fy25_01.js +39 -0
  10. package/dist/cjs/vc/vc-observer/revisions/revisions.js +23 -0
  11. package/dist/cjs/vc/vc-observer/revisions/types.js +5 -0
  12. package/dist/es2019/create-payload/index.js +10 -0
  13. package/dist/es2019/experience-trace-id-context/index.js +4 -0
  14. package/dist/es2019/segment/segment.js +11 -3
  15. package/dist/es2019/vc/vc-observer/heatmap/heatmap.js +238 -0
  16. package/dist/es2019/vc/vc-observer/index.js +94 -3
  17. package/dist/es2019/vc/vc-observer/revisions/ViewportUpdateClassifier.js +35 -0
  18. package/dist/es2019/vc/vc-observer/revisions/fy24_01.js +21 -0
  19. package/dist/es2019/vc/vc-observer/revisions/fy25_01.js +21 -0
  20. package/dist/es2019/vc/vc-observer/revisions/revisions.js +19 -0
  21. package/dist/es2019/vc/vc-observer/revisions/types.js +1 -0
  22. package/dist/esm/create-payload/index.js +10 -0
  23. package/dist/esm/experience-trace-id-context/index.js +4 -0
  24. package/dist/esm/segment/segment.js +7 -1
  25. package/dist/esm/vc/vc-observer/heatmap/heatmap.js +268 -0
  26. package/dist/esm/vc/vc-observer/index.js +115 -26
  27. package/dist/esm/vc/vc-observer/revisions/ViewportUpdateClassifier.js +45 -0
  28. package/dist/esm/vc/vc-observer/revisions/fy24_01.js +32 -0
  29. package/dist/esm/vc/vc-observer/revisions/fy25_01.js +32 -0
  30. package/dist/esm/vc/vc-observer/revisions/revisions.js +17 -0
  31. package/dist/esm/vc/vc-observer/revisions/types.js +1 -0
  32. package/dist/types/common/vc/types.d.ts +27 -8
  33. package/dist/types/experience-trace-id-context/index.d.ts +1 -0
  34. package/dist/types/vc/vc-observer/heatmap/heatmap.d.ts +75 -0
  35. package/dist/types/vc/vc-observer/index.d.ts +5 -1
  36. package/dist/types/vc/vc-observer/revisions/ViewportUpdateClassifier.d.ts +25 -0
  37. package/dist/types/vc/vc-observer/revisions/fy24_01.d.ts +11 -0
  38. package/dist/types/vc/vc-observer/revisions/fy25_01.d.ts +13 -0
  39. package/dist/types/vc/vc-observer/revisions/revisions.d.ts +2 -0
  40. package/dist/types/vc/vc-observer/revisions/types.d.ts +5 -0
  41. package/dist/types-ts4.5/common/vc/types.d.ts +27 -8
  42. package/dist/types-ts4.5/experience-trace-id-context/index.d.ts +1 -0
  43. package/dist/types-ts4.5/vc/vc-observer/heatmap/heatmap.d.ts +75 -0
  44. package/dist/types-ts4.5/vc/vc-observer/index.d.ts +15 -1
  45. package/dist/types-ts4.5/vc/vc-observer/revisions/ViewportUpdateClassifier.d.ts +25 -0
  46. package/dist/types-ts4.5/vc/vc-observer/revisions/fy24_01.d.ts +11 -0
  47. package/dist/types-ts4.5/vc/vc-observer/revisions/fy25_01.d.ts +13 -0
  48. package/dist/types-ts4.5/vc/vc-observer/revisions/revisions.d.ts +2 -0
  49. package/dist/types-ts4.5/vc/vc-observer/revisions/types.d.ts +5 -0
  50. package/package.json +8 -2
@@ -0,0 +1,19 @@
1
+ import { revFY24_01Classifier } from './fy24_01';
2
+ import { revFY25_01Classifier } from './fy25_01';
3
+ const Revisions = [{
4
+ name: 'fy24.01',
5
+ classifier: revFY24_01Classifier
6
+ }, {
7
+ name: 'fy25.01',
8
+ classifier: revFY25_01Classifier
9
+ }];
10
+ let revisionResultCache = null;
11
+ export const getRevisions = () => {
12
+ if (revisionResultCache !== null) {
13
+ return revisionResultCache;
14
+ }
15
+ revisionResultCache = [...Revisions
16
+ //...(fg('next_available') ? [{name: 'next', classifier:NEXT}] : [])
17
+ ];
18
+ return revisionResultCache;
19
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -211,6 +211,16 @@ var getVCMetrics = function getVCMetrics(interaction) {
211
211
  if (interactionStatus.originalInteractionStatus !== 'SUCCEEDED' || pageVisibilityUpToTTAI !== 'visible') {
212
212
  return result;
213
213
  }
214
+ if (fg('ufo_vc_multiheatmap')) {
215
+ var _result;
216
+ (_result = result["".concat(prefix, ":vc:rev")]) === null || _result === void 0 || _result.forEach(function (element) {
217
+ var _element$vcDetails;
218
+ if ((_element$vcDetails = element.vcDetails) !== null && _element$vcDetails !== void 0 && (_element$vcDetails = _element$vcDetails['90']) !== null && _element$vcDetails !== void 0 && _element$vcDetails.t) {
219
+ var _element$vcDetails$;
220
+ element['metric:vc90'] = (_element$vcDetails$ = element.vcDetails['90']) === null || _element$vcDetails$ === void 0 ? void 0 : _element$vcDetails$.t;
221
+ }
222
+ });
223
+ }
214
224
  return _objectSpread(_objectSpread({}, result), {}, {
215
225
  'metric:vc90': VC['90']
216
226
  });
@@ -31,4 +31,8 @@ export var getActiveTraceHttpRequestHeaders = function getActiveTraceHttpRequest
31
31
  traceId = _state$context.traceId,
32
32
  spanId = _state$context.spanId;
33
33
  return makeTraceHttpRequestHeaders(traceId, spanId);
34
+ };
35
+ export var getActiveTraceAsQueryParams = function getActiveTraceAsQueryParams(_url) {
36
+ var traceHeaders = getActiveTraceHttpRequestHeaders(_url);
37
+ return traceHeaders ? new URLSearchParams(traceHeaders).toString().toLowerCase() : null;
34
38
  };
@@ -5,6 +5,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
5
5
  import React, { lazy, Profiler, Suspense, useCallback, useContext, useEffect, useMemo, useRef } from 'react';
6
6
  import { unstable_NormalPriority as NormalPriority, unstable_scheduleCallback as scheduleCallback } from 'scheduler';
7
7
  import { v4 as createUUID } from 'uuid';
8
+ import { fg } from '@atlaskit/platform-feature-flags';
8
9
  import coinflip from '../coinflip';
9
10
  import { getConfig, getInteractionRate } from '../config';
10
11
  import { getActiveTrace, setInteractionActiveTrace } from '../experience-trace-id-context';
@@ -42,7 +43,9 @@ export default function UFOSegment(_ref) {
42
43
  }, [parentContext, segmentName, segmentId]);
43
44
  var interactionId = useContext(UFOInteractionIDContext);
44
45
  var interactionContext = useMemo(function () {
45
- addSegment(labelStack);
46
+ if (!fg('platform-ufo-add-segment-use-effect')) {
47
+ addSegment(labelStack);
48
+ }
46
49
  var lastCompleteEndTime = 0;
47
50
  function complete() {
48
51
  var endTime = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : performance.now();
@@ -221,6 +224,9 @@ export default function UFOSegment(_ref) {
221
224
  }
222
225
  }, [interactionContext]);
223
226
  useEffect(function () {
227
+ if (fg('platform-ufo-add-segment-use-effect')) {
228
+ addSegment(labelStack);
229
+ }
224
230
  return function () {
225
231
  removeSegment(labelStack);
226
232
  };
@@ -0,0 +1,268 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import _objectDestructuringEmpty from "@babel/runtime/helpers/objectDestructuringEmpty";
3
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
4
+ import _createClass from "@babel/runtime/helpers/createClass";
5
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
6
+ var UNUSED_SECTOR = 0;
7
+ export var MultiRevisionHeatmap = /*#__PURE__*/function () {
8
+ function MultiRevisionHeatmap(_ref) {
9
+ var _this = this;
10
+ var viewport = _ref.viewport,
11
+ revisions = _ref.revisions,
12
+ arraySize = _ref.arraySize,
13
+ devToolsEnabled = _ref.devToolsEnabled;
14
+ _classCallCheck(this, MultiRevisionHeatmap);
15
+ _defineProperty(this, "arraySize", {
16
+ w: 200,
17
+ h: 200
18
+ });
19
+ _defineProperty(this, "mapPixelsToHeatmap", function (left, top, width, height) {
20
+ var _this$viewport = _this.viewport,
21
+ w = _this$viewport.w,
22
+ h = _this$viewport.h;
23
+ var l = Math.floor(left / w * _this.arraySize.w);
24
+ var t = Math.floor(top / h * _this.arraySize.h);
25
+ var r = Math.ceil((left + width) / w * _this.arraySize.w);
26
+ var b = Math.ceil((top + height) / h * _this.arraySize.h);
27
+
28
+ // correct values to min - 0, max - arraySize
29
+ var result = {
30
+ l: Math.max(0, l),
31
+ t: Math.max(0, t),
32
+ r: Math.min(_this.arraySize.w, r),
33
+ b: Math.min(_this.arraySize.h, b)
34
+ };
35
+ return result;
36
+ });
37
+ _defineProperty(this, "getElementRatio", function (mappedValues) {
38
+ var r = mappedValues.r,
39
+ l = mappedValues.l,
40
+ b = mappedValues.b,
41
+ t = mappedValues.t;
42
+ return (r - l) * (b - t) / (_this.arraySize.w * _this.arraySize.h);
43
+ });
44
+ this.viewport = viewport;
45
+ this.revisions = revisions;
46
+ if (arraySize) {
47
+ this.arraySize = arraySize;
48
+ }
49
+ this.heatmaps = new Array(revisions.length);
50
+ this.componentsLogs = new Array(revisions.length);
51
+ this.vcRatios = new Array(revisions.length);
52
+ this.devToolsEnabled = devToolsEnabled || false;
53
+ revisions.forEach(function (_ref2, i) {
54
+ _objectDestructuringEmpty(_ref2);
55
+ _this.heatmaps[i] = _this.getCleanHeatmap();
56
+ _this.componentsLogs[i] = {};
57
+ _this.vcRatios[i] = {};
58
+ });
59
+ }
60
+ return _createClass(MultiRevisionHeatmap, [{
61
+ key: "handleUpdate",
62
+ value: function handleUpdate(_ref3) {
63
+ var _this2 = this;
64
+ var time = _ref3.time,
65
+ type = _ref3.type,
66
+ classification = _ref3.classification,
67
+ intersectionRect = _ref3.intersectionRect,
68
+ element = _ref3.element,
69
+ targetName = _ref3.targetName,
70
+ ignoreReason = _ref3.ignoreReason,
71
+ onError = _ref3.onError;
72
+ var mappedValues = this.mapPixelsToHeatmap(intersectionRect.left, intersectionRect.top, intersectionRect.width, intersectionRect.height);
73
+ var result = this.applyChangesToHeatMap(mappedValues, time, classification);
74
+ if (result !== true) {
75
+ onError(result);
76
+ }
77
+ var componentRatio = this.getElementRatio(mappedValues);
78
+ this.revisions.forEach(function (_, i) {
79
+ if (classification[i]) {
80
+ _this2.vcRatios[i][targetName] = componentRatio;
81
+ }
82
+ if (!_this2.componentsLogs[i][time]) {
83
+ _this2.componentsLogs[i][time] = [];
84
+ }
85
+ _this2.componentsLogs[i][time].push({
86
+ __debug__element: _this2.devToolsEnabled ? new WeakRef(element) : null,
87
+ intersectionRect: intersectionRect,
88
+ targetName: targetName,
89
+ ignoreReason: ignoreReason
90
+ });
91
+ });
92
+ }
93
+ }, {
94
+ key: "getData",
95
+ value: function getData() {
96
+ return {
97
+ heatmaps: this.heatmaps
98
+ };
99
+ }
100
+ }, {
101
+ key: "getPayloadShapedData",
102
+ value: function getPayloadShapedData(args) {
103
+ var result = this.processData(args);
104
+ var payload = this.revisions.map(function (rev, i) {
105
+ var vcDetails = {};
106
+ args.VCParts.forEach(function (VCPart) {
107
+ vcDetails[VCPart] = {
108
+ t: result[i].VC[VCPart] || 0,
109
+ e: Array.from(result[i].VCBox[VCPart] || [])
110
+ };
111
+ });
112
+ return {
113
+ revision: rev.name,
114
+ vcDetails: vcDetails,
115
+ clean: args.clean,
116
+ 'metric:vc90': null // will be set or not in the payload generator
117
+ };
118
+ });
119
+ return payload;
120
+ }
121
+ }, {
122
+ key: "processData",
123
+ value: function processData(_ref4) {
124
+ var _this3 = this;
125
+ var VCParts = _ref4.VCParts,
126
+ _ref4$ssr = _ref4.ssr,
127
+ ssr = _ref4$ssr === void 0 ? UNUSED_SECTOR : _ref4$ssr;
128
+ return this.heatmaps.map(function (heatmap, i) {
129
+ var lastUpdate = {};
130
+ var totalPainted = 0;
131
+ var componentsLog = _this3.componentsLogs[i];
132
+ if (ssr !== UNUSED_SECTOR) {
133
+ var _window$document;
134
+ var element = {
135
+ __debug__element: new WeakRef((_window$document = window.document) === null || _window$document === void 0 ? void 0 : _window$document.body),
136
+ intersectionRect: {
137
+ top: 0,
138
+ left: 0,
139
+ right: 0,
140
+ bottom: 0,
141
+ x: 0,
142
+ y: 0,
143
+ width: _this3.viewport.w,
144
+ height: _this3.viewport.h,
145
+ toJSON: function toJSON() {
146
+ return {};
147
+ }
148
+ },
149
+ targetName: 'SSR'
150
+ };
151
+ if (!componentsLog[ssr]) {
152
+ componentsLog[ssr] = [];
153
+ }
154
+ componentsLog[ssr].push(element);
155
+ }
156
+ for (var _i = 0; _i < heatmap.length; _i++) {
157
+ var rounded = Math.floor(heatmap[_i] === UNUSED_SECTOR && ssr !== UNUSED_SECTOR ? ssr : heatmap[_i]);
158
+ totalPainted += rounded !== UNUSED_SECTOR ? 1 : 0;
159
+ if (rounded !== UNUSED_SECTOR) {
160
+ lastUpdate[rounded] = lastUpdate[rounded] ? lastUpdate[rounded] + 1 : 1;
161
+ }
162
+ }
163
+ var entries = Object.entries(lastUpdate).map(function (a) {
164
+ return [parseInt(a[0], 10), a[1]];
165
+ }).sort(function (a, b) {
166
+ return a[0] > b[0] ? 1 : -1;
167
+ });
168
+ var VC = MultiRevisionHeatmap.makeVCReturnObj(VCParts);
169
+ var VCBox = MultiRevisionHeatmap.makeVCReturnObj(VCParts);
170
+ entries.reduce(function () {
171
+ var acc = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
172
+ var v = arguments.length > 1 ? arguments[1] : undefined;
173
+ var VCRatio = v[1] / totalPainted + acc;
174
+ var time = v[0];
175
+ VCParts.forEach(function (value) {
176
+ if ((VC[value] === null || VC[value] === undefined) && VCRatio >= value / 100) {
177
+ var _componentsLog$time;
178
+ VC[value] = time;
179
+ VCBox[value] = new Set();
180
+ (_componentsLog$time = componentsLog[time]) === null || _componentsLog$time === void 0 || _componentsLog$time.forEach(function (v) {
181
+ var _VCBox$value;
182
+ return (_VCBox$value = VCBox[value]) === null || _VCBox$value === void 0 ? void 0 : _VCBox$value.add(v.targetName);
183
+ });
184
+ }
185
+ });
186
+ return VCRatio;
187
+ }, 0);
188
+ var VCEntries = entries.reduce(function (acc, _ref5, i) {
189
+ var _acc$abs, _componentsLog$timest;
190
+ var _ref6 = _slicedToArray(_ref5, 2),
191
+ timestamp = _ref6[0],
192
+ entryPainted = _ref6[1];
193
+ var currentlyPainted = entryPainted + (((_acc$abs = acc.abs[i - 1]) === null || _acc$abs === void 0 ? void 0 : _acc$abs[1]) || 0);
194
+ var currentlyPaintedRatio = Math.round(currentlyPainted / totalPainted * 1000) / 10;
195
+ var logEntry = (_componentsLog$timest = componentsLog[timestamp]) === null || _componentsLog$timest === void 0 ? void 0 : _componentsLog$timest.map(function (v) {
196
+ return v.targetName;
197
+ });
198
+ acc.abs.push([timestamp, currentlyPainted]);
199
+ acc.rel.push({
200
+ time: timestamp,
201
+ vc: currentlyPaintedRatio,
202
+ elements: logEntry
203
+ });
204
+ return acc;
205
+ }, {
206
+ abs: [],
207
+ rel: []
208
+ });
209
+ return {
210
+ VC: VC,
211
+ VCBox: VCBox,
212
+ VCEntries: VCEntries,
213
+ totalPainted: totalPainted
214
+ };
215
+ });
216
+ }
217
+ }, {
218
+ key: "applyChangesToHeatMap",
219
+ value: function applyChangesToHeatMap(a, time, classification) {
220
+ var l = a.l,
221
+ t = a.t,
222
+ r = a.r,
223
+ b = a.b;
224
+ var size = classification.length;
225
+ for (var row = t; row < b; row++) {
226
+ if (this.heatmaps[0][row] === undefined) {
227
+ try {
228
+ return {
229
+ error: "index - ".concat(row),
230
+ time: time
231
+ };
232
+ } catch (e) {
233
+ return {
234
+ error: 'row error',
235
+ time: time
236
+ };
237
+ }
238
+ } else {
239
+ for (var heatmapIndex = 0; heatmapIndex < size; heatmapIndex++) {
240
+ if (classification[heatmapIndex]) {
241
+ this.heatmaps[heatmapIndex].fill(time, this.getIndex(l, row), this.getIndex(r, row));
242
+ }
243
+ }
244
+ }
245
+ }
246
+ return true;
247
+ }
248
+ }, {
249
+ key: "getIndex",
250
+ value: function getIndex(x, y) {
251
+ return x + this.arraySize.w * y;
252
+ }
253
+ }, {
254
+ key: "getCleanHeatmap",
255
+ value: function getCleanHeatmap() {
256
+ return new Uint32Array(this.arraySize.w * this.arraySize.h);
257
+ }
258
+ }], [{
259
+ key: "makeVCReturnObj",
260
+ value: function makeVCReturnObj(VCParts) {
261
+ var vc = {};
262
+ VCParts.forEach(function (v) {
263
+ vc[v] = null;
264
+ });
265
+ return vc;
266
+ }
267
+ }]);
268
+ }();
@@ -9,7 +9,9 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
9
9
  import { fg } from '@atlaskit/platform-feature-flags';
10
10
  import { attachAbortListeners } from './attachAbortListeners';
11
11
  import { getViewportHeight, getViewportWidth } from './getViewport';
12
+ import { MultiRevisionHeatmap } from './heatmap/heatmap';
12
13
  import { Observers } from './observers';
14
+ import { getRevisions } from './revisions/revisions';
13
15
  var abortReason = {
14
16
  scroll: 'scroll',
15
17
  keypress: 'keypress',
@@ -47,6 +49,7 @@ export var VCObserver = /*#__PURE__*/function () {
47
49
  });
48
50
  /* heatmap */
49
51
  _defineProperty(this, "arraySize", 0);
52
+ _defineProperty(this, "multiHeatmap", null);
50
53
  _defineProperty(this, "componentsLog", {});
51
54
  _defineProperty(this, "vcRatios", {});
52
55
  _defineProperty(this, "active", false);
@@ -78,6 +81,7 @@ export var VCObserver = /*#__PURE__*/function () {
78
81
  abortReason: _objectSpread({}, _this.abortReason),
79
82
  heatmap: _this.heatmap,
80
83
  heatmapNext: _this.heatmapNext,
84
+ multiHeatmap: _this.multiHeatmap,
81
85
  outOfBoundaryInfo: _this.outOfBoundaryInfo,
82
86
  totalTime: Math.round(_this.totalTime + _this.observers.getTotalTime()),
83
87
  componentsLog: _objectSpread({}, _this.componentsLog),
@@ -110,7 +114,8 @@ export var VCObserver = /*#__PURE__*/function () {
110
114
  componentsLog = rawData.componentsLog,
111
115
  viewport = rawData.viewport,
112
116
  devToolsEnabled = rawData.devToolsEnabled,
113
- ratios = rawData.ratios;
117
+ ratios = rawData.ratios,
118
+ multiHeatmap = rawData.multiHeatmap;
114
119
  if (abortReasonInfo !== null && abortReason.blocking) {
115
120
  // exposing data to devtools
116
121
  try {
@@ -146,6 +151,7 @@ export var VCObserver = /*#__PURE__*/function () {
146
151
  /* empty */
147
152
  }
148
153
  var _componentsLog = {};
154
+ // eslint-disable-next-line @atlaskit/platform/ensure-feature-flag-prefix
149
155
  if (fg('ufo-remove-vc-component-observations-after-ttai')) {
150
156
  Object.entries(_this.componentsLog).forEach(function (_ref5) {
151
157
  var _ref6 = _slicedToArray(_ref5, 2),
@@ -202,9 +208,30 @@ export var VCObserver = /*#__PURE__*/function () {
202
208
  tti: tti,
203
209
  ttai: stop - start
204
210
  },
211
+ start: start,
212
+ stop: stop,
205
213
  heatmap: heatmap,
206
214
  ratios: ratios
207
215
  };
216
+ window.__vcNext = {
217
+ entries: vcNext.VCEntries.rel,
218
+ log: componentsLog,
219
+ metrics: {
220
+ '75': vcNext.VC['75'],
221
+ '80': vcNext.VC['80'],
222
+ '85': vcNext.VC['85'],
223
+ '90': vcNext.VC['90'],
224
+ '95': vcNext.VC['95'],
225
+ '98': vcNext.VC['98'],
226
+ '99': vcNext.VC['99'],
227
+ tti: tti,
228
+ ttai: stop - start
229
+ },
230
+ start: start,
231
+ stop: stop,
232
+ heatmap: heatmapNext,
233
+ ratios: ratios
234
+ };
208
235
 
209
236
  // Emitting a custom event to make it available in the Chrome extension
210
237
  window.dispatchEvent(new CustomEvent('vcReady', {
@@ -217,13 +244,36 @@ export var VCObserver = /*#__PURE__*/function () {
217
244
  } catch (e) {
218
245
  /* do nothing */
219
246
  }
247
+ var isMultiHeatmapEnabled = fg('ufo_vc_multiheatmap');
248
+ var revisionsData = isMultiHeatmapEnabled && multiHeatmap !== null ? _defineProperty({}, "".concat(fullPrefix, "vc:rev"), multiHeatmap.getPayloadShapedData({
249
+ VCParts: VCObserver.VCParts.map(function (v) {
250
+ return parseInt(v);
251
+ }),
252
+ ssr: ssr,
253
+ clean: !abortReasonInfo
254
+ })) : null;
255
+ // eslint-disable-next-line @atlaskit/platform/ensure-feature-flag-prefix
220
256
  var isCalcSpeedIndexEnabled = fg('ufo-calc-speed-index');
221
- return _objectSpread(_objectSpread(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({
257
+ return _objectSpread(_objectSpread(_objectSpread(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({
222
258
  'metrics:vc': VC
223
- }, "".concat(fullPrefix, "vc:state"), true), "".concat(fullPrefix, "vc:clean"), !abortReasonInfo), "".concat(fullPrefix, "vc:dom"), VCBox), "".concat(fullPrefix, "vc:updates"), VCEntries.rel.slice(0, 50)), "".concat(fullPrefix, "vc:size"), viewport), "".concat(fullPrefix, "vc:time"), Math.round(totalTime + (stopTime - startTime))), "".concat(fullPrefix, "vc:total"), totalPainted), "".concat(fullPrefix, "vc:ratios"), ratios), outOfBoundary), {}, _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, "".concat(fullPrefix, "vc:next"), vcNext.VC), "".concat(fullPrefix, "vc:next:updates"), vcNext.VCEntries.rel.slice(0, 50)), "".concat(fullPrefix, "vc:next:dom"), vcNext.VCBox), "".concat(fullPrefix, "vc:ignored"), _this.getIgnoredElements(componentsLog)), "ufo:speedIndex", isCalcSpeedIndexEnabled ? VCEntries.speedIndex : undefined), "ufo:next:speedIndex", isCalcSpeedIndexEnabled ? vcNext.VCEntries.speedIndex : undefined));
259
+ }, "".concat(fullPrefix, "vc:state"), true), "".concat(fullPrefix, "vc:clean"), !abortReasonInfo), "".concat(fullPrefix, "vc:dom"), VCBox), "".concat(fullPrefix, "vc:updates"), VCEntries.rel.slice(0, 50)), "".concat(fullPrefix, "vc:size"), viewport), "".concat(fullPrefix, "vc:time"), Math.round(totalTime + (stopTime - startTime))), "".concat(fullPrefix, "vc:total"), totalPainted), "".concat(fullPrefix, "vc:ratios"), ratios), outOfBoundary), {}, _defineProperty(_defineProperty(_defineProperty(_defineProperty({}, "".concat(fullPrefix, "vc:next"), vcNext.VC), "".concat(fullPrefix, "vc:next:updates"), vcNext.VCEntries.rel.slice(0, 50)), "".concat(fullPrefix, "vc:next:dom"), vcNext.VCBox), "".concat(fullPrefix, "vc:ignored"), _this.getIgnoredElements(componentsLog)), revisionsData), {}, _defineProperty(_defineProperty({}, "ufo:speedIndex", isCalcSpeedIndexEnabled ? VCEntries.speedIndex : undefined), "ufo:next:speedIndex", isCalcSpeedIndexEnabled ? vcNext.VCEntries.speedIndex : undefined));
224
260
  });
225
261
  _defineProperty(this, "handleUpdate", function (rawTime, intersectionRect, targetName, element, type, ignoreReason) {
226
262
  _this.measureStart();
263
+ _this.legacyHandleUpdate(rawTime, intersectionRect, targetName, element, type, ignoreReason);
264
+ if (fg('ufo_vc_multiheatmap')) {
265
+ _this.onViewportChangeDetected({
266
+ timestamp: rawTime,
267
+ intersectionRect: intersectionRect,
268
+ targetName: targetName,
269
+ element: element,
270
+ type: type,
271
+ ignoreReason: ignoreReason
272
+ });
273
+ }
274
+ _this.measureStop();
275
+ });
276
+ _defineProperty(this, "legacyHandleUpdate", function (rawTime, intersectionRect, targetName, element, type, ignoreReason) {
227
277
  if (_this.abortReason.reason === null || _this.abortReason.blocking === false) {
228
278
  var time = Math.round(rawTime - _this.startTime);
229
279
  var mappedValues = _this.mapPixelsToHeatmap(intersectionRect.left, intersectionRect.top, intersectionRect.width, intersectionRect.height);
@@ -244,8 +294,38 @@ export var VCObserver = /*#__PURE__*/function () {
244
294
  ignoreReason: ignoreReason
245
295
  });
246
296
  }
247
- // devtools export
248
- _this.measureStop();
297
+ });
298
+ _defineProperty(this, "onViewportChangeDetected", function (_ref9) {
299
+ var element = _ref9.element,
300
+ type = _ref9.type,
301
+ ignoreReason = _ref9.ignoreReason,
302
+ timestamp = _ref9.timestamp,
303
+ targetName = _ref9.targetName,
304
+ intersectionRect = _ref9.intersectionRect;
305
+ if (_this.multiHeatmap === null) {
306
+ return;
307
+ }
308
+ // @todo add abort reason handling
309
+ var time = Math.round(timestamp - _this.startTime);
310
+ var revisions = getRevisions();
311
+ var revisionsClassification = revisions.map(function (revision) {
312
+ return revision.classifier.classifyUpdate({
313
+ element: element,
314
+ type: type,
315
+ ignoreReason: ignoreReason
316
+ });
317
+ }, []);
318
+ _this.multiHeatmap.handleUpdate({
319
+ time: time,
320
+ targetName: targetName,
321
+ intersectionRect: intersectionRect,
322
+ type: type,
323
+ element: element,
324
+ classification: revisionsClassification,
325
+ onError: function onError(error) {
326
+ _this.setAbortReason(abortReason.error, error.time, error.error);
327
+ }
328
+ });
249
329
  });
250
330
  _defineProperty(this, "mapPixelsToHeatmap", function (left, top, width, height) {
251
331
  var _this$viewport = _this.viewport,
@@ -303,10 +383,10 @@ export var VCObserver = /*#__PURE__*/function () {
303
383
  var unbinds = attachAbortListeners(window, _this.viewport, _this.abortReasonCallback);
304
384
  if ((_window = window) !== null && _window !== void 0 && _window.__SSR_ABORT_LISTENERS__) {
305
385
  var _window2;
306
- Object.entries(window.__SSR_ABORT_LISTENERS__.aborts).forEach(function (_ref8) {
307
- var _ref9 = _slicedToArray(_ref8, 2),
308
- key = _ref9[0],
309
- time = _ref9[1];
386
+ Object.entries(window.__SSR_ABORT_LISTENERS__.aborts).forEach(function (_ref10) {
387
+ var _ref11 = _slicedToArray(_ref10, 2),
388
+ key = _ref11[0],
389
+ time = _ref11[1];
310
390
  if (time) {
311
391
  _this.abortReasonCallback(key, time);
312
392
  }
@@ -330,12 +410,19 @@ export var VCObserver = /*#__PURE__*/function () {
330
410
  });
331
411
  this.heatmap = this.getCleanHeatmap();
332
412
  this.heatmapNext = this.getCleanHeatmap();
413
+ if (fg('ufo_vc_multiheatmap')) {
414
+ this.multiHeatmap = new MultiRevisionHeatmap({
415
+ viewport: this.viewport,
416
+ revisions: getRevisions(),
417
+ devToolsEnabled: this.devToolsEnabled
418
+ });
419
+ }
333
420
  this.isPostInteraction = options.isPostInteraction || false;
334
421
  }
335
422
  return _createClass(VCObserver, [{
336
423
  key: "start",
337
- value: function start(_ref10) {
338
- var startTime = _ref10.startTime;
424
+ value: function start(_ref12) {
425
+ var startTime = _ref12.startTime;
339
426
  this.active = true;
340
427
  if (this.observers.isBrowserSupported()) {
341
428
  this.setViewportSize();
@@ -357,12 +444,12 @@ export var VCObserver = /*#__PURE__*/function () {
357
444
  }, {
358
445
  key: "getIgnoredElements",
359
446
  value: function getIgnoredElements(componentsLog) {
360
- return Object.values(componentsLog).flat().filter(function (_ref11) {
361
- var ignoreReason = _ref11.ignoreReason;
447
+ return Object.values(componentsLog).flat().filter(function (_ref13) {
448
+ var ignoreReason = _ref13.ignoreReason;
362
449
  return Boolean(ignoreReason);
363
- }).map(function (_ref12) {
364
- var targetName = _ref12.targetName,
365
- ignoreReason = _ref12.ignoreReason;
450
+ }).map(function (_ref14) {
451
+ var targetName = _ref14.targetName,
452
+ ignoreReason = _ref14.ignoreReason;
366
453
  return {
367
454
  targetName: targetName,
368
455
  ignoreReason: ignoreReason
@@ -483,12 +570,12 @@ export var VCObserver = /*#__PURE__*/function () {
483
570
  }
484
571
  }], [{
485
572
  key: "calculateVC",
486
- value: function calculateVC(_ref13) {
487
- var heatmap = _ref13.heatmap,
488
- _ref13$ssr = _ref13.ssr,
489
- ssr = _ref13$ssr === void 0 ? UNUSED_SECTOR : _ref13$ssr,
490
- componentsLog = _ref13.componentsLog,
491
- viewport = _ref13.viewport;
573
+ value: function calculateVC(_ref15) {
574
+ var heatmap = _ref15.heatmap,
575
+ _ref15$ssr = _ref15.ssr,
576
+ ssr = _ref15$ssr === void 0 ? UNUSED_SECTOR : _ref15$ssr,
577
+ componentsLog = _ref15.componentsLog,
578
+ viewport = _ref15.viewport;
492
579
  var lastUpdate = {};
493
580
  var totalPainted = 0;
494
581
  if (ssr !== UNUSED_SECTOR) {
@@ -531,6 +618,8 @@ export var VCObserver = /*#__PURE__*/function () {
531
618
  });
532
619
  var VC = VCObserver.makeVCReturnObj();
533
620
  var VCBox = VCObserver.makeVCReturnObj();
621
+
622
+ // eslint-disable-next-line @atlaskit/platform/ensure-feature-flag-prefix
534
623
  var isCalcSpeedIndexEnabled = fg('ufo-calc-speed-index');
535
624
  entries.reduce(function () {
536
625
  var acc = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
@@ -555,11 +644,11 @@ export var VCObserver = /*#__PURE__*/function () {
555
644
  });
556
645
  return VCRatio;
557
646
  }, 0);
558
- var VCEntries = entries.reduce(function (acc, _ref14, i) {
647
+ var VCEntries = entries.reduce(function (acc, _ref16, i) {
559
648
  var _acc$abs, _componentsLog$timest, _acc$rel$vc, _acc$rel;
560
- var _ref15 = _slicedToArray(_ref14, 2),
561
- timestamp = _ref15[0],
562
- entryPainted = _ref15[1];
649
+ var _ref17 = _slicedToArray(_ref16, 2),
650
+ timestamp = _ref17[0],
651
+ entryPainted = _ref17[1];
563
652
  var currentlyPainted = entryPainted + (((_acc$abs = acc.abs[i - 1]) === null || _acc$abs === void 0 ? void 0 : _acc$abs[1]) || 0);
564
653
  var currentlyPaintedRatio = Math.round(currentlyPainted / totalPainted * 1000) / 10;
565
654
  var logEntry = (_componentsLog$timest = componentsLog[timestamp]) === null || _componentsLog$timest === void 0 ? void 0 : _componentsLog$timest.map(function (v) {
@@ -0,0 +1,45 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
3
+ import _createClass from "@babel/runtime/helpers/createClass";
4
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
5
+ export var ViewportUpdateClassifier = /*#__PURE__*/function () {
6
+ function ViewportUpdateClassifier() {
7
+ _classCallCheck(this, ViewportUpdateClassifier);
8
+ _defineProperty(this, "types", []);
9
+ _defineProperty(this, "filters", []);
10
+ _defineProperty(this, "removedFilters", []);
11
+ _defineProperty(this, "__combinedTypes", []);
12
+ _defineProperty(this, "__combinedFilters", []);
13
+ }
14
+ return _createClass(ViewportUpdateClassifier, [{
15
+ key: "mergeConfig",
16
+ value: function mergeConfig() {
17
+ var _this = this;
18
+ this.__combinedTypes = [].concat(_toConsumableArray(this.types), _toConsumableArray((this === null || this === void 0 ? void 0 : this.__combinedTypes) || []));
19
+ var previousFilters = this.removedFilters.length === 0 ? this.__combinedFilters : this.__combinedFilters.filter(function (filter) {
20
+ return !_this.removedFilters.includes(filter.name);
21
+ });
22
+ this.__combinedFilters = [].concat(_toConsumableArray(this.filters), _toConsumableArray(previousFilters));
23
+ }
24
+ }, {
25
+ key: "classifyUpdate",
26
+ value: function classifyUpdate(_ref) {
27
+ var element = _ref.element,
28
+ type = _ref.type,
29
+ tags = _ref.tags,
30
+ ignoreReason = _ref.ignoreReason;
31
+ if (!this.__combinedTypes.includes(type)) {
32
+ return false;
33
+ }
34
+ return this.__combinedFilters.every(function (_ref2) {
35
+ var filter = _ref2.filter,
36
+ name = _ref2.name;
37
+ return filter({
38
+ type: type,
39
+ tags: tags,
40
+ ignoreReason: ignoreReason
41
+ });
42
+ });
43
+ }
44
+ }]);
45
+ }();
@@ -0,0 +1,32 @@
1
+ import _createClass from "@babel/runtime/helpers/createClass";
2
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
3
+ import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
4
+ import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
5
+ import _inherits from "@babel/runtime/helpers/inherits";
6
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
7
+ function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
8
+ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
9
+ import { ViewportUpdateClassifier } from './ViewportUpdateClassifier';
10
+ var legacyIgnoreReasons = ['image', 'ssr-hydration', 'editor-lazy-node-view', 'editor-container-mutation'];
11
+ export var FY24_01Classifier = /*#__PURE__*/function (_ViewportUpdateClassi) {
12
+ function FY24_01Classifier() {
13
+ var _this;
14
+ _classCallCheck(this, FY24_01Classifier);
15
+ _this = _callSuper(this, FY24_01Classifier);
16
+ _defineProperty(_this, "revision", 'fy24.01');
17
+ _defineProperty(_this, "types", ['html', 'text']);
18
+ _defineProperty(_this, "filters", [{
19
+ name: 'default-ignore-reasons',
20
+ filter: function filter(_ref) {
21
+ var type = _ref.type,
22
+ ignoreReason = _ref.ignoreReason;
23
+ return !ignoreReason || !legacyIgnoreReasons.includes(ignoreReason);
24
+ }
25
+ }]);
26
+ _this.mergeConfig();
27
+ return _this;
28
+ }
29
+ _inherits(FY24_01Classifier, _ViewportUpdateClassi);
30
+ return _createClass(FY24_01Classifier);
31
+ }(ViewportUpdateClassifier);
32
+ export var revFY24_01Classifier = new FY24_01Classifier();