@atlaskit/react-ufo 3.3.2 → 3.4.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 (69) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/assets/index.js +26 -16
  3. package/dist/cjs/assets/utils.js +47 -4
  4. package/dist/cjs/create-payload/index.js +58 -27
  5. package/dist/cjs/interaction-metrics-init/index.js +11 -9
  6. package/dist/cjs/vc/index.js +6 -2
  7. package/dist/cjs/vc/vc-observer-new/get-element-name.js +19 -6
  8. package/dist/cjs/vc/vc-observer-new/index.js +6 -3
  9. package/dist/cjs/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +4 -2
  10. package/dist/cjs/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/canvas-pixel.js +10 -11
  11. package/dist/cjs/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/index.js +23 -30
  12. package/dist/cjs/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/index.js +7 -7
  13. package/dist/cjs/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/index.js +3 -3
  14. package/dist/cjs/vc/vc-observer-new/window-event-observer/index.js +5 -1
  15. package/dist/es2019/assets/index.js +27 -13
  16. package/dist/es2019/assets/utils.js +47 -3
  17. package/dist/es2019/create-payload/index.js +14 -9
  18. package/dist/es2019/interaction-metrics-init/index.js +11 -9
  19. package/dist/es2019/vc/index.js +6 -2
  20. package/dist/es2019/vc/vc-observer-new/get-element-name.js +19 -6
  21. package/dist/es2019/vc/vc-observer-new/index.js +7 -3
  22. package/dist/es2019/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +4 -0
  23. package/dist/es2019/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/canvas-pixel.js +1 -2
  24. package/dist/es2019/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/index.js +15 -12
  25. package/dist/es2019/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/index.js +5 -4
  26. package/dist/es2019/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/index.js +3 -2
  27. package/dist/es2019/vc/vc-observer-new/window-event-observer/index.js +5 -1
  28. package/dist/esm/assets/index.js +27 -17
  29. package/dist/esm/assets/utils.js +46 -3
  30. package/dist/esm/create-payload/index.js +58 -27
  31. package/dist/esm/interaction-metrics-init/index.js +11 -9
  32. package/dist/esm/vc/index.js +6 -2
  33. package/dist/esm/vc/vc-observer-new/get-element-name.js +19 -6
  34. package/dist/esm/vc/vc-observer-new/index.js +6 -3
  35. package/dist/esm/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +4 -2
  36. package/dist/esm/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/canvas-pixel.js +10 -11
  37. package/dist/esm/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/index.js +23 -30
  38. package/dist/esm/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/index.js +7 -7
  39. package/dist/esm/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/index.js +3 -3
  40. package/dist/esm/vc/vc-observer-new/window-event-observer/index.js +5 -1
  41. package/dist/types/assets/index.d.ts +5 -5
  42. package/dist/types/assets/utils.d.ts +4 -1
  43. package/dist/types/common/assets/types.d.ts +14 -8
  44. package/dist/types/common/index.d.ts +11 -1
  45. package/dist/types/config/index.d.ts +6 -0
  46. package/dist/types/create-payload/index.d.ts +769 -1
  47. package/dist/types/resource-timing/common/types.d.ts +1 -1
  48. package/dist/types/vc/vc-observer-new/index.d.ts +3 -2
  49. package/dist/types/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +1 -1
  50. package/dist/types/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/index.d.ts +2 -2
  51. package/dist/types/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/index.d.ts +2 -1
  52. package/dist/types/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/index.d.ts +2 -1
  53. package/dist/types/vc/vc-observer-new/metric-calculator/percentile-calc/types.d.ts +2 -0
  54. package/dist/types/vc/vc-observer-new/metric-calculator/types.d.ts +2 -0
  55. package/dist/types-ts4.5/assets/index.d.ts +5 -5
  56. package/dist/types-ts4.5/assets/utils.d.ts +4 -1
  57. package/dist/types-ts4.5/common/assets/types.d.ts +14 -8
  58. package/dist/types-ts4.5/common/index.d.ts +11 -1
  59. package/dist/types-ts4.5/config/index.d.ts +6 -0
  60. package/dist/types-ts4.5/create-payload/index.d.ts +769 -1
  61. package/dist/types-ts4.5/resource-timing/common/types.d.ts +1 -1
  62. package/dist/types-ts4.5/vc/vc-observer-new/index.d.ts +3 -2
  63. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +1 -1
  64. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/index.d.ts +2 -2
  65. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/index.d.ts +2 -1
  66. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/index.d.ts +2 -1
  67. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/percentile-calc/types.d.ts +2 -0
  68. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/types.d.ts +2 -0
  69. package/package.json +2 -2
@@ -19,22 +19,22 @@ function calculateTTVCPercentiles(_x) {
19
19
  }
20
20
  function _calculateTTVCPercentiles() {
21
21
  _calculateTTVCPercentiles = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref) {
22
- var viewport, orderedEntries, percentiles, canvas, elementMap, _iterator3, _step3, entry, rect, elementName, timePixelCounts, viewportTotalPixels;
22
+ var viewport, orderedEntries, percentiles, startTime, canvas, elementMap, _iterator2, _step2, entry, rect, elementName, timePixelCounts, canvasDimenstions, totalPixels;
23
23
  return _regenerator.default.wrap(function _callee$(_context) {
24
24
  while (1) switch (_context.prev = _context.next) {
25
25
  case 0:
26
- viewport = _ref.viewport, orderedEntries = _ref.orderedEntries, percentiles = _ref.percentiles;
26
+ viewport = _ref.viewport, orderedEntries = _ref.orderedEntries, percentiles = _ref.percentiles, startTime = _ref.startTime;
27
27
  canvas = new _canvasPixel.ViewportCanvas(viewport, (0, _platformFeatureFlags.fg)('platform_ufo_canvas_heatmap_full_precision') ? 1 : 0.25);
28
28
  elementMap = new Map();
29
- _iterator3 = _createForOfIteratorHelper(orderedEntries);
29
+ _iterator2 = _createForOfIteratorHelper(orderedEntries);
30
30
  _context.prev = 4;
31
- _iterator3.s();
31
+ _iterator2.s();
32
32
  case 6:
33
- if ((_step3 = _iterator3.n()).done) {
33
+ if ((_step2 = _iterator2.n()).done) {
34
34
  _context.next = 17;
35
35
  break;
36
36
  }
37
- entry = _step3.value;
37
+ entry = _step2.value;
38
38
  if ('rect' in entry.data) {
39
39
  _context.next = 10;
40
40
  break;
@@ -57,19 +57,20 @@ function _calculateTTVCPercentiles() {
57
57
  case 19:
58
58
  _context.prev = 19;
59
59
  _context.t0 = _context["catch"](4);
60
- _iterator3.e(_context.t0);
60
+ _iterator2.e(_context.t0);
61
61
  case 22:
62
62
  _context.prev = 22;
63
- _iterator3.f();
63
+ _iterator2.f();
64
64
  return _context.finish(22);
65
65
  case 25:
66
66
  _context.next = 27;
67
67
  return canvas.getPixelCounts();
68
68
  case 27:
69
69
  timePixelCounts = _context.sent;
70
- viewportTotalPixels = viewport.width * viewport.height;
71
- return _context.abrupt("return", calculatePercentiles(timePixelCounts, elementMap, percentiles, viewportTotalPixels));
72
- case 30:
70
+ canvasDimenstions = canvas.getScaledDimensions();
71
+ totalPixels = canvasDimenstions.width * canvasDimenstions.height;
72
+ return _context.abrupt("return", calculatePercentiles(timePixelCounts, elementMap, percentiles, totalPixels, startTime));
73
+ case 31:
73
74
  case "end":
74
75
  return _context.stop();
75
76
  }
@@ -77,7 +78,7 @@ function _calculateTTVCPercentiles() {
77
78
  }));
78
79
  return _calculateTTVCPercentiles.apply(this, arguments);
79
80
  }
80
- function calculatePercentiles(timePixelCounts, elementMap, unorderedPercentiles, totalPixels) {
81
+ function calculatePercentiles(timePixelCounts, elementMap, unorderedPercentiles, totalPixels, startTime) {
81
82
  var results = {};
82
83
  var cumulativePixels = 0;
83
84
  var percentiles = unorderedPercentiles.sort(function (a, b) {
@@ -110,7 +111,7 @@ function calculatePercentiles(timePixelCounts, elementMap, unorderedPercentiles,
110
111
  var matchesAnyCheckpoints = false;
111
112
  while (percentileIndex < percentiles.length && percentCovered >= percentiles[percentileIndex]) {
112
113
  results["".concat(percentiles[percentileIndex])] = {
113
- t: Number(time),
114
+ t: Math.round(Number(time - startTime)),
114
115
  e: Array.from(domElementsBuffer)
115
116
  };
116
117
  percentileIndex++;
@@ -123,29 +124,21 @@ function calculatePercentiles(timePixelCounts, elementMap, unorderedPercentiles,
123
124
  break;
124
125
  }
125
126
  }
126
-
127
- // Fill in any missing percentiles
128
127
  } catch (err) {
129
128
  _iterator.e(err);
130
129
  } finally {
131
130
  _iterator.f();
132
131
  }
133
- var _iterator2 = _createForOfIteratorHelper(percentiles),
134
- _step2;
135
- try {
136
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
137
- var percentile = _step2.value;
138
- if (!(percentile in results)) {
139
- results["".concat(percentile)] = {
140
- t: 0,
141
- e: []
142
- };
143
- }
132
+ var previousResult = {
133
+ t: 0,
134
+ e: []
135
+ };
136
+ for (var i = 0; i < percentiles.length; i++) {
137
+ var percentile = percentiles[i];
138
+ if (!(percentile in results)) {
139
+ results["".concat(percentile)] = previousResult;
144
140
  }
145
- } catch (err) {
146
- _iterator2.e(err);
147
- } finally {
148
- _iterator2.f();
141
+ previousResult = results["".concat(percentile)];
149
142
  }
150
143
  return results;
151
144
  }
@@ -243,7 +243,7 @@ var Heatmap = /*#__PURE__*/function () {
243
243
  }, {
244
244
  key: "getVCPercentMetrics",
245
245
  value: function () {
246
- var _getVCPercentMetrics = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(vcPercentCheckpoint) {
246
+ var _getVCPercentMetrics = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(vcPercentCheckpoint, startTime) {
247
247
  var sortedCheckpoints, flattenHeatmap, totalCells, timestampMap, i, _cellHead$time, _timestampMap$get, cell, cellHead, timestamp, elementName, curr, sortedTimings, totalCellPainted, result, domElementsBuffer, _i, _timestamp, timestampInfo, cellCount, domElements, currVCRatio, currVCPercent, matchesAnyCheckpoints, checkpoint, _domElements;
248
248
  return _regenerator.default.wrap(function _callee2$(_context2) {
249
249
  while (1) switch (_context2.prev = _context2.next) {
@@ -331,7 +331,7 @@ var Heatmap = /*#__PURE__*/function () {
331
331
  case 41:
332
332
  matchesAnyCheckpoints = true;
333
333
  result[checkpoint.toString()] = {
334
- t: _timestamp,
334
+ t: Math.round(_timestamp - startTime),
335
335
  e: _domElements
336
336
  };
337
337
  _context2.next = 36;
@@ -358,23 +358,23 @@ var Heatmap = /*#__PURE__*/function () {
358
358
  }
359
359
  }, _callee2, this);
360
360
  }));
361
- function getVCPercentMetrics(_x2) {
361
+ function getVCPercentMetrics(_x2, _x3) {
362
362
  return _getVCPercentMetrics.apply(this, arguments);
363
363
  }
364
364
  return getVCPercentMetrics;
365
365
  }()
366
366
  }]);
367
367
  }();
368
- function calculateTTVCPercentiles(_x3) {
368
+ function calculateTTVCPercentiles(_x4) {
369
369
  return _calculateTTVCPercentiles.apply(this, arguments);
370
370
  }
371
371
  function _calculateTTVCPercentiles() {
372
372
  _calculateTTVCPercentiles = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(_ref2) {
373
- var orderedEntries, viewport, percentiles, heatmap, vcDetails;
373
+ var orderedEntries, viewport, percentiles, startTime, heatmap, vcDetails;
374
374
  return _regenerator.default.wrap(function _callee3$(_context3) {
375
375
  while (1) switch (_context3.prev = _context3.next) {
376
376
  case 0:
377
- orderedEntries = _ref2.orderedEntries, viewport = _ref2.viewport, percentiles = _ref2.percentiles;
377
+ orderedEntries = _ref2.orderedEntries, viewport = _ref2.viewport, percentiles = _ref2.percentiles, startTime = _ref2.startTime;
378
378
  heatmap = new Heatmap({
379
379
  viewport: viewport,
380
380
  heatmapSize: 200
@@ -383,7 +383,7 @@ function _calculateTTVCPercentiles() {
383
383
  return heatmap.applyEntriesToHeatmap(orderedEntries);
384
384
  case 4:
385
385
  _context3.next = 6;
386
- return heatmap.getVCPercentMetrics(percentiles);
386
+ return heatmap.getVCPercentMetrics(percentiles, startTime);
387
387
  case 6:
388
388
  vcDetails = _context3.sent;
389
389
  return _context3.abrupt("return", vcDetails);
@@ -16,11 +16,11 @@ function calculateTTVCPercentiles(_x) {
16
16
  }
17
17
  function _calculateTTVCPercentiles() {
18
18
  _calculateTTVCPercentiles = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref) {
19
- var orderedEntries, viewport, percentiles, sortedPercentiles, viewportArea, checkpoints, activeRects, removeActiveRect, domElementsBuffer, i, iEntry, iEntryData, rect, elementName, exclusionArea, currentArea, currVCPercent, matchesAnyCheckpoints, _checkpoint, domElements;
19
+ var orderedEntries, viewport, percentiles, startTime, sortedPercentiles, viewportArea, checkpoints, activeRects, removeActiveRect, domElementsBuffer, i, iEntry, iEntryData, rect, elementName, exclusionArea, currentArea, currVCPercent, matchesAnyCheckpoints, _checkpoint, domElements;
20
20
  return _regenerator.default.wrap(function _callee$(_context) {
21
21
  while (1) switch (_context.prev = _context.next) {
22
22
  case 0:
23
- orderedEntries = _ref.orderedEntries, viewport = _ref.viewport, percentiles = _ref.percentiles;
23
+ orderedEntries = _ref.orderedEntries, viewport = _ref.viewport, percentiles = _ref.percentiles, startTime = _ref.startTime;
24
24
  sortedPercentiles = (0, _toConsumableArray2.default)(percentiles).sort(function (a, b) {
25
25
  return a - b;
26
26
  });
@@ -76,7 +76,7 @@ function _calculateTTVCPercentiles() {
76
76
  case 25:
77
77
  matchesAnyCheckpoints = true;
78
78
  checkpoints[_checkpoint.toString()] = {
79
- t: iEntry.time,
79
+ t: Math.round(iEntry.time - startTime),
80
80
  e: domElements
81
81
  };
82
82
  _context.next = 20;
@@ -22,6 +22,9 @@ var WindowEventObserver = exports.default = /*#__PURE__*/function () {
22
22
  var unbindCallback = (0, _bindEventListener.bind)(window, {
23
23
  type: type,
24
24
  listener: function listener(event) {
25
+ if (!event.isTrusted) {
26
+ return;
27
+ }
25
28
  _this.onEvent({
26
29
  time: event.timeStamp,
27
30
  type: type,
@@ -29,7 +32,8 @@ var WindowEventObserver = exports.default = /*#__PURE__*/function () {
29
32
  });
30
33
  },
31
34
  options: {
32
- passive: true
35
+ passive: true,
36
+ once: true
33
37
  }
34
38
  });
35
39
  this.unbindFns.push(unbindCallback);
@@ -1,5 +1,5 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- import { calculateTransferType, DISK_KEY, MEMORY_KEY, NETWORK_KEY, round } from './utils';
2
+ import { calculateTransferType, checkIfTimingsAvailable, DISK_KEY, getTypeOfRequest, MEMORY_KEY, NETWORK_KEY, round } from './utils';
3
3
  export class CHRSummary {
4
4
  constructor() {
5
5
  _defineProperty(this, "bundles", {
@@ -16,9 +16,8 @@ export class CHRSummary {
16
16
  _defineProperty(this, "sizeTotal", 0);
17
17
  }
18
18
  add(asset) {
19
- const size = 'size' in asset ? asset.size : undefined;
20
- const encodedSize = 'encodedSize' in asset ? Number(asset.encodedSize) : 0;
21
- const type = calculateTransferType(asset.type, asset.duration, size);
19
+ const encodedSize = asset.encodedSize || 0;
20
+ const type = calculateTransferType(asset.name, asset.initiatorType, asset.duration, asset.transferSize);
22
21
  if (type === null) {
23
22
  return;
24
23
  }
@@ -47,22 +46,36 @@ export class CHRReporter {
47
46
  _defineProperty(this, "all", new CHRSummary());
48
47
  _defineProperty(this, "allAtlassian", new CHRSummary());
49
48
  _defineProperty(this, "preloaded", new CHRSummary());
49
+ _defineProperty(this, "defaultAllowedTypes", ['js']);
50
50
  }
51
- get(resourceTimings, assetsClassification) {
51
+ get(resourceTimings, assetsConfig, SSRDoneTime) {
52
52
  try {
53
- Object.entries(resourceTimings).map(([label, entry]) => {
54
- if (assetsClassification.all) {
53
+ if (resourceTimings === null) {
54
+ return null;
55
+ }
56
+ resourceTimings.forEach(entry => {
57
+ if (!checkIfTimingsAvailable(entry)) {
58
+ return;
59
+ }
60
+ if (entry.encodedSize === entry.decodedSize) {
61
+ // incorrectly reported size
62
+ return;
63
+ }
64
+ const type = getTypeOfRequest(entry);
65
+ if (!(assetsConfig.allowedTypes || this.defaultAllowedTypes).includes(type)) {
66
+ return;
67
+ }
68
+ if (assetsConfig.classification.all) {
55
69
  this.all.add(entry);
56
70
  }
57
- if (assetsClassification.allAtlassian({
58
- label,
71
+ if (assetsConfig.classification.allAtlassian({
59
72
  entry
60
73
  })) {
61
74
  this.allAtlassian.add(entry);
62
75
  }
63
- if (assetsClassification.preloaded({
64
- label,
65
- entry
76
+ if (assetsConfig.classification.preloaded({
77
+ entry,
78
+ SSRDoneTime
66
79
  })) {
67
80
  this.preloaded.add(entry);
68
81
  }
@@ -70,11 +83,12 @@ export class CHRReporter {
70
83
  if (this.all.bundlesCount === 0) {
71
84
  return null;
72
85
  }
73
- return {
86
+ const CHRData = {
74
87
  all: CHRSummary.makePayload(this.all),
75
88
  allAtlassian: CHRSummary.makePayload(this.allAtlassian),
76
89
  preloaded: CHRSummary.makePayload(this.preloaded)
77
90
  };
91
+ return CHRData;
78
92
  } catch (error) {
79
93
  return null;
80
94
  }
@@ -1,10 +1,10 @@
1
1
  /* Borrowed from https://bitbucket.org/atlassian/atlassian-frontend/src/master/packages/performance/browser-metrics/src/plugins/timings/resource.ts */
2
- export const cacheableTypes = ['script', 'link'];
2
+ export const cacheableTypes = ['script', 'link', 'other'];
3
3
  export const MEMORY_KEY = 'mem';
4
4
  export const DISK_KEY = 'disk';
5
5
  export const NETWORK_KEY = 'net';
6
- export const calculateTransferType = (type, duration, size) => {
7
- if (!cacheableTypes.includes(type)) {
6
+ export const calculateTransferType = (name, type, duration, size) => {
7
+ if (!cacheableTypes.includes(type) && !(type === 'other' && name.includes('.js'))) {
8
8
  return null;
9
9
  }
10
10
  if ((size === undefined || size === 0) && duration === 0) {
@@ -18,6 +18,50 @@ export const calculateTransferType = (type, duration, size) => {
18
18
  }
19
19
  return NETWORK_KEY;
20
20
  };
21
+ export const getTypeOfRequest = ({
22
+ name,
23
+ initiatorType: type
24
+ }) => {
25
+ let category = 'other';
26
+ const urlWithoutQuery = name.split('?')[0];
27
+ switch (type) {
28
+ case 'script':
29
+ category = 'js';
30
+ break;
31
+ case 'link':
32
+ if (urlWithoutQuery.endsWith('.css')) {
33
+ category = 'css';
34
+ }
35
+ if (urlWithoutQuery.endsWith('.js')) {
36
+ category = 'js';
37
+ }
38
+ break;
39
+ case 'img':
40
+ category = 'image';
41
+ break;
42
+ case 'font':
43
+ category = 'font';
44
+ break;
45
+ default:
46
+ if (urlWithoutQuery.endsWith('.js')) {
47
+ category = 'js';
48
+ } else if (urlWithoutQuery.endsWith('.css')) {
49
+ category = 'css';
50
+ } else if (urlWithoutQuery.match(/\.(woff|woff2|ttf|otf)$/)) {
51
+ category = 'font';
52
+ } else if (urlWithoutQuery.match(/\.(png|jpg|jpeg|gif|svg)$/)) {
53
+ category = 'image';
54
+ }
55
+ break;
56
+ }
57
+ return category;
58
+ };
59
+ export const checkIfTimingsAvailable = entry => {
60
+ if (entry.decodedSize === 0 && entry.encodedSize === 0 && entry.requestStart === 0 && entry.responseStart === 0) {
61
+ return false;
62
+ }
63
+ return true;
64
+ };
21
65
  export const round = n => {
22
66
  if (isNaN(n)) {
23
67
  return 0;
@@ -13,6 +13,7 @@ import { getPageVisibilityState } from '../hidden-timing';
13
13
  import * as initialPageLoadExtraTiming from '../initial-page-load-extra-timing';
14
14
  import { interactionSpans as atlaskitInteractionSpans } from '../interaction-metrics';
15
15
  import * as resourceTiming from '../resource-timing';
16
+ import { filterResourceTimings } from '../resource-timing/common/utils/resource-timing-buffer';
16
17
  import { roundEpsilon } from '../round-number';
17
18
  import * as ssr from '../ssr';
18
19
  import { buildSegmentTree, labelStackStartWith, optimizeLabelStack, sanitizeUfoName, stringifyLabelStackFully } from './common/utils';
@@ -234,20 +235,21 @@ function getSSRProperties(type) {
234
235
  'ssr:featureFlags': getSSRFeatureFlags(type)
235
236
  };
236
237
  }
237
- const getAssetsMetrics = (interaction, resourceTimings) => {
238
+ const getAssetsMetrics = (interaction, SSRDoneTime) => {
238
239
  try {
239
240
  const config = getConfig();
240
241
  const {
241
242
  type
242
243
  } = interaction;
243
244
  const allowedTypes = ['page_load', 'transition'];
244
- const assetsClassification = config === null || config === void 0 ? void 0 : config.assetsClassification;
245
- if (!allowedTypes.includes(type) || !assetsClassification) {
245
+ const assetsConfig = config === null || config === void 0 ? void 0 : config.assetsConfig;
246
+ if (!allowedTypes.includes(type) || !assetsConfig) {
246
247
  // Skip if: type not allowed or assetsClassification isn't configured
247
248
  return {};
248
249
  }
249
250
  const reporter = new CHRReporter();
250
- const assets = reporter.get(resourceTimings, assetsClassification);
251
+ const resourceTimings = filterResourceTimings(interaction.start, interaction.end);
252
+ const assets = reporter.get(resourceTimings, assetsConfig, SSRDoneTime);
251
253
  if (assets) {
252
254
  // Only add assets in case it exists
253
255
  return {
@@ -664,7 +666,7 @@ async function createInteractionMetricsPayload(interaction, interactionId, exper
664
666
  labelStack: optimizeLabelStack(interaction.labelStack, getReactUFOVersion(interaction.type))
665
667
  } : {};
666
668
  // Page Load
667
- const getPageLoadInteractionMetrics = () => {
669
+ const getInitialPageLoadSSRMetrics = () => {
668
670
  var _config$ssr;
669
671
  if (!isPageLoad) {
670
672
  return {};
@@ -680,6 +682,8 @@ async function createInteractionMetricsPayload(interaction, interactionId, exper
680
682
  isUFOConfigSSRDoneAsFmp: interaction.metaData.__legacy__bm3ConfigSSRDoneAsFmp || !!(config !== null && config !== void 0 && (_config$ssr = config.ssr) !== null && _config$ssr !== void 0 && _config$ssr.getSSRDoneTime)
681
683
  };
682
684
  };
685
+ const pageLoadInteractionMetrics = getInitialPageLoadSSRMetrics();
686
+
683
687
  // Detailed payload. Page visibility = visible
684
688
  const getDetailedInteractionMetrics = resourceTimings => {
685
689
  if (experimental || window.__UFO_COMPACT_PAYLOAD__ || !isDetailedPayload) {
@@ -748,7 +752,7 @@ async function createInteractionMetricsPayload(interaction, interactionId, exper
748
752
  // root
749
753
  ...getBrowserMetadata(),
750
754
  ...getSSRProperties(type),
751
- ...getAssetsMetrics(interaction, resourceTimings),
755
+ ...getAssetsMetrics(interaction, pageLoadInteractionMetrics === null || pageLoadInteractionMetrics === void 0 ? void 0 : pageLoadInteractionMetrics.SSRDoneTime),
752
756
  ...getPPSMetrics(interaction),
753
757
  ...getPaintMetrics(type),
754
758
  ...getNavigationMetrics(type),
@@ -790,7 +794,7 @@ async function createInteractionMetricsPayload(interaction, interactionId, exper
790
794
  customData: optimizeCustomData(interaction),
791
795
  reactProfilerTimings: optimizeReactProfilerTimings(interaction.reactProfilerTimings, start, getReactUFOVersion(interaction.type)),
792
796
  ...labelStack,
793
- ...getPageLoadInteractionMetrics(),
797
+ ...pageLoadInteractionMetrics,
794
798
  ...getDetailedInteractionMetrics(resourceTimings),
795
799
  ...getPageLoadDetailedInteractionMetrics(),
796
800
  ...getBm3TrackerTimings(interaction),
@@ -817,7 +821,7 @@ export async function createPayloads(interactionId, interaction) {
817
821
  const interactionMetricsPayload = await createInteractionMetricsPayload(modifiedInteraction, interactionId);
818
822
  return [interactionMetricsPayload];
819
823
  }
820
- export function createExperimentalMetricsPayload(interactionId, interaction) {
824
+ export async function createExperimentalMetricsPayload(interactionId, interaction) {
821
825
  const config = getConfig();
822
826
  if (!config) {
823
827
  throw Error('UFO Configuration not provided');
@@ -831,5 +835,6 @@ export function createExperimentalMetricsPayload(interactionId, interaction) {
831
835
  if (pageVisibilityState !== 'visible') {
832
836
  return null;
833
837
  }
834
- return createInteractionMetricsPayload(interaction, interactionId, true);
838
+ const result = await createInteractionMetricsPayload(interaction, interactionId, true);
839
+ return result;
835
840
  }
@@ -28,17 +28,19 @@ function sinkInteraction(instance, payloadPackage) {
28
28
  function sinkExperimentalInteractionMetrics(instance, payloadPackage) {
29
29
  sinkExperimentalHandler((interactionId, interaction) => {
30
30
  scheduleCallback(idlePriority, () => {
31
- const payload = payloadPackage.createExperimentalMetricsPayload(interactionId, interaction);
32
- if (payload) {
33
- if (fg('enable_ufo_devtools_api_for_extra_events')) {
34
- // NOTE: This API is used by the UFO DevTool Chrome Extension and Criterion
35
- const devToolObserver = globalThis.__ufo_devtool_onUfoPayload;
36
- if (typeof devToolObserver === 'function') {
37
- devToolObserver === null || devToolObserver === void 0 ? void 0 : devToolObserver(payload);
31
+ const payloadPromise = payloadPackage.createExperimentalMetricsPayload(interactionId, interaction);
32
+ payloadPromise.then(payload => {
33
+ if (payload) {
34
+ if (fg('enable_ufo_devtools_api_for_extra_events')) {
35
+ // NOTE: This API is used by the UFO DevTool Chrome Extension and Criterion
36
+ const devToolObserver = globalThis.__ufo_devtool_onUfoPayload;
37
+ if (typeof devToolObserver === 'function') {
38
+ devToolObserver === null || devToolObserver === void 0 ? void 0 : devToolObserver(payload);
39
+ }
38
40
  }
41
+ instance.sendOperationalEvent(payload);
39
42
  }
40
- instance.sendOperationalEvent(payload);
41
- }
43
+ });
42
44
  });
43
45
  });
44
46
  }
@@ -1,11 +1,13 @@
1
1
  import { fg } from '@atlaskit/platform-feature-flags';
2
+ import { getConfig } from '../config';
2
3
  import { VCObserver } from './vc-observer';
3
4
  import VCObserverNew from './vc-observer-new';
4
5
  class VCObserverWrapper {
5
6
  constructor(opts = {}) {
7
+ var _getConfig, _getConfig$vc;
6
8
  this.oldVCObserver = new VCObserver(opts);
7
9
  this.newVCObserver = null;
8
- const isNewVCObserverEnabled = fg('platform_ufo_vc_observer_new');
10
+ const isNewVCObserverEnabled = fg('platform_ufo_vc_observer_new') || ((_getConfig = getConfig()) === null || _getConfig === void 0 ? void 0 : (_getConfig$vc = _getConfig.vc) === null || _getConfig$vc === void 0 ? void 0 : _getConfig$vc.enableVCObserverNew);
9
11
  if (isNewVCObserverEnabled) {
10
12
  this.newVCObserver = new VCObserverNew({
11
13
  selectorConfig: opts.selectorConfig
@@ -15,7 +17,9 @@ class VCObserverWrapper {
15
17
  start(startArg) {
16
18
  var _this$oldVCObserver, _this$newVCObserver;
17
19
  (_this$oldVCObserver = this.oldVCObserver) === null || _this$oldVCObserver === void 0 ? void 0 : _this$oldVCObserver.start(startArg);
18
- (_this$newVCObserver = this.newVCObserver) === null || _this$newVCObserver === void 0 ? void 0 : _this$newVCObserver.start();
20
+ (_this$newVCObserver = this.newVCObserver) === null || _this$newVCObserver === void 0 ? void 0 : _this$newVCObserver.start({
21
+ startTime: startArg.startTime
22
+ });
19
23
  }
20
24
  stop() {
21
25
  var _this$oldVCObserver2, _this$newVCObserver2;
@@ -4,7 +4,15 @@ function getAttributeSelector(element, attributeName) {
4
4
  if (!attrValue) {
5
5
  return '';
6
6
  }
7
- return `[${attributeName}="${encodeURIComponent(attrValue)}"]`;
7
+ return `[${attributeName}="${attrValue}"]`;
8
+ }
9
+ function isValidSelector(selector) {
10
+ try {
11
+ document.querySelector(selector);
12
+ return true;
13
+ } catch (err) {
14
+ return false;
15
+ }
8
16
  }
9
17
  function isSelectorUnique(selector) {
10
18
  return document.querySelectorAll(selector).length === 1;
@@ -12,11 +20,13 @@ function isSelectorUnique(selector) {
12
20
  function getUniqueSelector(selectorConfig, element) {
13
21
  let currentElement = element;
14
22
  const parts = [];
15
- while (currentElement && currentElement.localName !== 'body') {
23
+ const MAX_DEPTH = 3;
24
+ let currentDepth = 0;
25
+ while (currentElement && currentElement.localName !== 'body' && currentDepth <= MAX_DEPTH) {
16
26
  const tagName = currentElement.localName;
17
27
  let selectorPart = tagName;
18
- if (selectorConfig.id && currentElement.id) {
19
- selectorPart += `#${encodeURIComponent(currentElement.id)}`;
28
+ if (selectorConfig.id && currentElement.id && isValidSelector(`#${currentElement.id}`)) {
29
+ selectorPart += `#${currentElement.id}`;
20
30
  } else if (selectorConfig.dataVC) {
21
31
  selectorPart += getAttributeSelector(currentElement, 'data-vc');
22
32
  } else if (selectorConfig.testId) {
@@ -24,9 +34,11 @@ function getUniqueSelector(selectorConfig, element) {
24
34
  } else if (selectorConfig.role) {
25
35
  selectorPart += getAttributeSelector(currentElement, 'role');
26
36
  } else if (selectorConfig.className && currentElement.className) {
27
- const classNames = Array.from(currentElement.classList).map(encodeURIComponent).join('.');
37
+ const classNames = Array.from(currentElement.classList).join('.');
28
38
  if (classNames) {
29
- selectorPart += `.${classNames}`;
39
+ if (isValidSelector(`.${classNames}`)) {
40
+ selectorPart += `.${classNames}`;
41
+ }
30
42
  }
31
43
  }
32
44
  parts.unshift(selectorPart);
@@ -35,6 +47,7 @@ function getUniqueSelector(selectorConfig, element) {
35
47
  return potentialSelector;
36
48
  }
37
49
  currentElement = currentElement.parentElement;
50
+ currentDepth++;
38
51
  }
39
52
  const potentialSelector = parts.join(' > ').trim();
40
53
  if (!potentialSelector) {
@@ -14,7 +14,6 @@ const DEFAULT_SELECTOR_CONFIG = {
14
14
  export default class VCObserverNew {
15
15
  constructor(config) {
16
16
  var _config$selectorConfi;
17
- _defineProperty(this, "startTime", 0);
18
17
  _defineProperty(this, "viewportObserver", null);
19
18
  _defineProperty(this, "windowEventObserver", null);
20
19
  this.entriesTimeline = new EntriesTimeline();
@@ -63,10 +62,13 @@ export default class VCObserverNew {
63
62
  }
64
63
  });
65
64
  }
66
- start() {
65
+ start({
66
+ startTime
67
+ }) {
67
68
  var _this$viewportObserve, _this$windowEventObse;
68
69
  (_this$viewportObserve = this.viewportObserver) === null || _this$viewportObserve === void 0 ? void 0 : _this$viewportObserve.start();
69
70
  (_this$windowEventObse = this.windowEventObserver) === null || _this$windowEventObse === void 0 ? void 0 : _this$windowEventObse.start();
71
+ this.entriesTimeline.clear();
70
72
  }
71
73
  stop() {
72
74
  var _this$viewportObserve2, _this$windowEventObse2;
@@ -85,7 +87,9 @@ export default class VCObserverNew {
85
87
  stop
86
88
  });
87
89
  const fy25_03 = await calculator_fy25_03.calculate({
88
- orderedEntries
90
+ orderedEntries,
91
+ startTime: start,
92
+ stopTime: stop
89
93
  });
90
94
  if (fy25_03) {
91
95
  results.push(fy25_03);
@@ -6,6 +6,8 @@ export default class AbstractVCCalculatorBase {
6
6
  this.revisionNo = revisionNo;
7
7
  }
8
8
  async calculate({
9
+ startTime,
10
+ stopTime,
9
11
  orderedEntries
10
12
  }) {
11
13
  var _vcDetails$90$t, _vcDetails$;
@@ -25,6 +27,8 @@ export default class AbstractVCCalculatorBase {
25
27
  width: getViewportWidth(),
26
28
  height: getViewportHeight()
27
29
  },
30
+ startTime,
31
+ stopTime,
28
32
  orderedEntries: filteredEntries,
29
33
  percentiles: [25, 50, 75, 80, 85, 90, 95, 98, 99]
30
34
  });
@@ -172,7 +172,6 @@ export function getRGBComponents(n) {
172
172
  */
173
173
  export async function calculateDrawnPixelsRaw(imageData, scaleFactor, arraySize) {
174
174
  const data = imageData.data;
175
- const scaleCompensation = Math.round(1 / (scaleFactor * scaleFactor));
176
175
  const arr = new Uint32Array(arraySize);
177
176
  for (let i = 0; i < data.length; i += 4) {
178
177
  // Check alpha
@@ -184,7 +183,7 @@ export async function calculateDrawnPixelsRaw(imageData, scaleFactor, arraySize)
184
183
  // The | operator combines all bits together
185
184
  const color = data[i] << 16 | data[i + 1] << 8 | data[i + 2];
186
185
  const colorIndex = color - 1;
187
- arr[colorIndex] = (arr[colorIndex] || 0) + scaleCompensation;
186
+ arr[colorIndex] = (arr[colorIndex] || 0) + 1;
188
187
  }
189
188
  if (i % 10000 === 0) {
190
189
  await taskYield();