@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
@@ -3,7 +3,8 @@ import { ViewportCanvas } from './canvas-pixel';
3
3
  export default async function calculateTTVCPercentiles({
4
4
  viewport,
5
5
  orderedEntries,
6
- percentiles
6
+ percentiles,
7
+ startTime
7
8
  }) {
8
9
  const canvas = new ViewportCanvas(viewport, fg('platform_ufo_canvas_heatmap_full_precision') ? 1 : 0.25);
9
10
  const elementMap = new Map();
@@ -22,10 +23,11 @@ export default async function calculateTTVCPercentiles({
22
23
 
23
24
  // Get pixel counts
24
25
  const timePixelCounts = await canvas.getPixelCounts();
25
- const viewportTotalPixels = viewport.width * viewport.height;
26
- return calculatePercentiles(timePixelCounts, elementMap, percentiles, viewportTotalPixels);
26
+ const canvasDimenstions = canvas.getScaledDimensions();
27
+ const totalPixels = canvasDimenstions.width * canvasDimenstions.height;
28
+ return calculatePercentiles(timePixelCounts, elementMap, percentiles, totalPixels, startTime);
27
29
  }
28
- export function calculatePercentiles(timePixelCounts, elementMap, unorderedPercentiles, totalPixels) {
30
+ export function calculatePercentiles(timePixelCounts, elementMap, unorderedPercentiles, totalPixels, startTime) {
29
31
  const results = {};
30
32
  let cumulativePixels = 0;
31
33
  const percentiles = unorderedPercentiles.sort((a, b) => a - b);
@@ -42,7 +44,7 @@ export function calculatePercentiles(timePixelCounts, elementMap, unorderedPerce
42
44
  let matchesAnyCheckpoints = false;
43
45
  while (percentileIndex < percentiles.length && percentCovered >= percentiles[percentileIndex]) {
44
46
  results[`${percentiles[percentileIndex]}`] = {
45
- t: Number(time),
47
+ t: Math.round(Number(time - startTime)),
46
48
  e: Array.from(domElementsBuffer)
47
49
  };
48
50
  percentileIndex++;
@@ -55,15 +57,16 @@ export function calculatePercentiles(timePixelCounts, elementMap, unorderedPerce
55
57
  break;
56
58
  }
57
59
  }
58
-
59
- // Fill in any missing percentiles
60
- for (const percentile of percentiles) {
60
+ let previousResult = {
61
+ t: 0,
62
+ e: []
63
+ };
64
+ for (let i = 0; i < percentiles.length; i++) {
65
+ const percentile = percentiles[i];
61
66
  if (!(percentile in results)) {
62
- results[`${percentile}`] = {
63
- t: 0,
64
- e: []
65
- };
67
+ results[`${percentile}`] = previousResult;
66
68
  }
69
+ previousResult = results[`${percentile}`];
67
70
  }
68
71
  return results;
69
72
  }
@@ -175,7 +175,7 @@ class Heatmap {
175
175
  }
176
176
  }
177
177
  }
178
- async getVCPercentMetrics(vcPercentCheckpoint) {
178
+ async getVCPercentMetrics(vcPercentCheckpoint, startTime) {
179
179
  const sortedCheckpoints = [...vcPercentCheckpoint].sort((a, b) => a - b);
180
180
  const flattenHeatmap = this.map.flat();
181
181
  const totalCells = flattenHeatmap.length;
@@ -232,7 +232,7 @@ class Heatmap {
232
232
  }
233
233
  matchesAnyCheckpoints = true;
234
234
  result[checkpoint.toString()] = {
235
- t: timestamp,
235
+ t: Math.round(timestamp - startTime),
236
236
  e: domElements
237
237
  };
238
238
  }
@@ -249,13 +249,14 @@ class Heatmap {
249
249
  export default async function calculateTTVCPercentiles({
250
250
  orderedEntries,
251
251
  viewport,
252
- percentiles
252
+ percentiles,
253
+ startTime
253
254
  }) {
254
255
  const heatmap = new Heatmap({
255
256
  viewport,
256
257
  heatmapSize: 200
257
258
  });
258
259
  await heatmap.applyEntriesToHeatmap(orderedEntries);
259
- const vcDetails = await heatmap.getVCPercentMetrics(percentiles);
260
+ const vcDetails = await heatmap.getVCPercentMetrics(percentiles, startTime);
260
261
  return vcDetails;
261
262
  }
@@ -4,7 +4,8 @@ import calculateUnionArea from './calc-union-area';
4
4
  export default async function calculateTTVCPercentiles({
5
5
  orderedEntries,
6
6
  viewport,
7
- percentiles
7
+ percentiles,
8
+ startTime
8
9
  }) {
9
10
  const sortedPercentiles = [...percentiles].sort((a, b) => a - b);
10
11
  const viewportArea = viewport.width * viewport.height;
@@ -43,7 +44,7 @@ export default async function calculateTTVCPercentiles({
43
44
  }
44
45
  matchesAnyCheckpoints = true;
45
46
  checkpoints[checkpoint.toString()] = {
46
- t: iEntry.time,
47
+ t: Math.round(iEntry.time - startTime),
47
48
  e: domElements
48
49
  };
49
50
  }
@@ -9,6 +9,9 @@ export default class WindowEventObserver {
9
9
  const unbindCallback = bind(window, {
10
10
  type,
11
11
  listener: event => {
12
+ if (!event.isTrusted) {
13
+ return;
14
+ }
12
15
  this.onEvent({
13
16
  time: event.timeStamp,
14
17
  type,
@@ -16,7 +19,8 @@ export default class WindowEventObserver {
16
19
  });
17
20
  },
18
21
  options: {
19
- passive: true
22
+ passive: true,
23
+ once: true
20
24
  }
21
25
  });
22
26
  this.unbindFns.push(unbindCallback);
@@ -1,8 +1,7 @@
1
- import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
1
  import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
3
2
  import _createClass from "@babel/runtime/helpers/createClass";
4
3
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
5
- import { calculateTransferType, DISK_KEY, MEMORY_KEY, NETWORK_KEY, round } from './utils';
4
+ import { calculateTransferType, checkIfTimingsAvailable, DISK_KEY, getTypeOfRequest, MEMORY_KEY, NETWORK_KEY, round } from './utils';
6
5
  export var CHRSummary = /*#__PURE__*/function () {
7
6
  function CHRSummary() {
8
7
  _classCallCheck(this, CHRSummary);
@@ -14,9 +13,8 @@ export var CHRSummary = /*#__PURE__*/function () {
14
13
  return _createClass(CHRSummary, [{
15
14
  key: "add",
16
15
  value: function add(asset) {
17
- var size = 'size' in asset ? asset.size : undefined;
18
- var encodedSize = 'encodedSize' in asset ? Number(asset.encodedSize) : 0;
19
- var type = calculateTransferType(asset.type, asset.duration, size);
16
+ var encodedSize = asset.encodedSize || 0;
17
+ var type = calculateTransferType(asset.name, asset.initiatorType, asset.duration, asset.transferSize);
20
18
  if (type === null) {
21
19
  return;
22
20
  }
@@ -47,28 +45,39 @@ export var CHRReporter = /*#__PURE__*/function () {
47
45
  _defineProperty(this, "all", new CHRSummary());
48
46
  _defineProperty(this, "allAtlassian", new CHRSummary());
49
47
  _defineProperty(this, "preloaded", new CHRSummary());
48
+ _defineProperty(this, "defaultAllowedTypes", ['js']);
50
49
  }
51
50
  return _createClass(CHRReporter, [{
52
51
  key: "get",
53
- value: function get(resourceTimings, assetsClassification) {
52
+ value: function get(resourceTimings, assetsConfig, SSRDoneTime) {
54
53
  var _this = this;
55
54
  try {
56
- Object.entries(resourceTimings).map(function (_ref) {
57
- var _ref2 = _slicedToArray(_ref, 2),
58
- label = _ref2[0],
59
- entry = _ref2[1];
60
- if (assetsClassification.all) {
55
+ if (resourceTimings === null) {
56
+ return null;
57
+ }
58
+ resourceTimings.forEach(function (entry) {
59
+ if (!checkIfTimingsAvailable(entry)) {
60
+ return;
61
+ }
62
+ if (entry.encodedSize === entry.decodedSize) {
63
+ // incorrectly reported size
64
+ return;
65
+ }
66
+ var type = getTypeOfRequest(entry);
67
+ if (!(assetsConfig.allowedTypes || _this.defaultAllowedTypes).includes(type)) {
68
+ return;
69
+ }
70
+ if (assetsConfig.classification.all) {
61
71
  _this.all.add(entry);
62
72
  }
63
- if (assetsClassification.allAtlassian({
64
- label: label,
73
+ if (assetsConfig.classification.allAtlassian({
65
74
  entry: entry
66
75
  })) {
67
76
  _this.allAtlassian.add(entry);
68
77
  }
69
- if (assetsClassification.preloaded({
70
- label: label,
71
- entry: entry
78
+ if (assetsConfig.classification.preloaded({
79
+ entry: entry,
80
+ SSRDoneTime: SSRDoneTime
72
81
  })) {
73
82
  _this.preloaded.add(entry);
74
83
  }
@@ -76,11 +85,12 @@ export var CHRReporter = /*#__PURE__*/function () {
76
85
  if (this.all.bundlesCount === 0) {
77
86
  return null;
78
87
  }
79
- return {
88
+ var CHRData = {
80
89
  all: CHRSummary.makePayload(this.all),
81
90
  allAtlassian: CHRSummary.makePayload(this.allAtlassian),
82
91
  preloaded: CHRSummary.makePayload(this.preloaded)
83
92
  };
93
+ return CHRData;
84
94
  } catch (error) {
85
95
  return null;
86
96
  }
@@ -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 var cacheableTypes = ['script', 'link'];
2
+ export var cacheableTypes = ['script', 'link', 'other'];
3
3
  export var MEMORY_KEY = 'mem';
4
4
  export var DISK_KEY = 'disk';
5
5
  export var NETWORK_KEY = 'net';
6
- export var calculateTransferType = function calculateTransferType(type, duration, size) {
7
- if (!cacheableTypes.includes(type)) {
6
+ export var calculateTransferType = function 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,49 @@ export var calculateTransferType = function calculateTransferType(type, duration
18
18
  }
19
19
  return NETWORK_KEY;
20
20
  };
21
+ export var getTypeOfRequest = function getTypeOfRequest(_ref) {
22
+ var name = _ref.name,
23
+ type = _ref.initiatorType;
24
+ var category = 'other';
25
+ var urlWithoutQuery = name.split('?')[0];
26
+ switch (type) {
27
+ case 'script':
28
+ category = 'js';
29
+ break;
30
+ case 'link':
31
+ if (urlWithoutQuery.endsWith('.css')) {
32
+ category = 'css';
33
+ }
34
+ if (urlWithoutQuery.endsWith('.js')) {
35
+ category = 'js';
36
+ }
37
+ break;
38
+ case 'img':
39
+ category = 'image';
40
+ break;
41
+ case 'font':
42
+ category = 'font';
43
+ break;
44
+ default:
45
+ if (urlWithoutQuery.endsWith('.js')) {
46
+ category = 'js';
47
+ } else if (urlWithoutQuery.endsWith('.css')) {
48
+ category = 'css';
49
+ } else if (urlWithoutQuery.match(/\.(woff|woff2|ttf|otf)$/)) {
50
+ category = 'font';
51
+ } else if (urlWithoutQuery.match(/\.(png|jpg|jpeg|gif|svg)$/)) {
52
+ category = 'image';
53
+ }
54
+ break;
55
+ }
56
+ return category;
57
+ };
58
+ export var checkIfTimingsAvailable = function checkIfTimingsAvailable(entry) {
59
+ if (entry.decodedSize === 0 && entry.encodedSize === 0 && entry.requestStart === 0 && entry.responseStart === 0) {
60
+ return false;
61
+ }
62
+ return true;
63
+ };
21
64
  export var round = function round(n) {
22
65
  if (isNaN(n)) {
23
66
  return 0;
@@ -25,6 +25,7 @@ import { getPageVisibilityState } from '../hidden-timing';
25
25
  import * as initialPageLoadExtraTiming from '../initial-page-load-extra-timing';
26
26
  import { interactionSpans as atlaskitInteractionSpans } from '../interaction-metrics';
27
27
  import * as resourceTiming from '../resource-timing';
28
+ import { filterResourceTimings } from '../resource-timing/common/utils/resource-timing-buffer';
28
29
  import { roundEpsilon } from '../round-number';
29
30
  import * as ssr from '../ssr';
30
31
  import { buildSegmentTree, labelStackStartWith, optimizeLabelStack, sanitizeUfoName, stringifyLabelStackFully } from './common/utils';
@@ -246,18 +247,19 @@ function getSSRProperties(type) {
246
247
  'ssr:featureFlags': getSSRFeatureFlags(type)
247
248
  };
248
249
  }
249
- var getAssetsMetrics = function getAssetsMetrics(interaction, resourceTimings) {
250
+ var getAssetsMetrics = function getAssetsMetrics(interaction, SSRDoneTime) {
250
251
  try {
251
252
  var config = getConfig();
252
253
  var type = interaction.type;
253
254
  var allowedTypes = ['page_load', 'transition'];
254
- var assetsClassification = config === null || config === void 0 ? void 0 : config.assetsClassification;
255
- if (!allowedTypes.includes(type) || !assetsClassification) {
255
+ var assetsConfig = config === null || config === void 0 ? void 0 : config.assetsConfig;
256
+ if (!allowedTypes.includes(type) || !assetsConfig) {
256
257
  // Skip if: type not allowed or assetsClassification isn't configured
257
258
  return {};
258
259
  }
259
260
  var reporter = new CHRReporter();
260
- var assets = reporter.get(resourceTimings, assetsClassification);
261
+ var resourceTimings = filterResourceTimings(interaction.start, interaction.end);
262
+ var assets = reporter.get(resourceTimings, assetsConfig, SSRDoneTime);
261
263
  if (assets) {
262
264
  // Only add assets in case it exists
263
265
  return {
@@ -636,7 +638,7 @@ function createInteractionMetricsPayload(_x, _x2, _x3) {
636
638
  function _createInteractionMetricsPayload() {
637
639
  _createInteractionMetricsPayload = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(interaction, interactionId, experimental) {
638
640
  var _window$location, _config$additionalPay;
639
- var interactionPayloadStart, config, end, start, ufoName, knownSegments, rate, type, abortReason, routeName, featureFlags, previousInteractionName, isPreviousInteractionAborted, abortedByInteractionName, pageVisibilityAtTTI, pageVisibilityAtTTAI, segments, segmentTree, isDetailedPayload, isPageLoad, calculatePageVisibilityFromTheStartOfPageLoad, moreAccuratePageVisibilityAtTTI, moreAccuratePageVisibilityAtTTAI, labelStack, getPageLoadInteractionMetrics, getDetailedInteractionMetrics, getPageLoadDetailedInteractionMetrics, newUFOName, resourceTimings, _yield$Promise$all, _yield$Promise$all2, vcMetrics, experimentalMetrics, payload;
641
+ var interactionPayloadStart, config, end, start, ufoName, knownSegments, rate, type, abortReason, routeName, featureFlags, previousInteractionName, isPreviousInteractionAborted, abortedByInteractionName, pageVisibilityAtTTI, pageVisibilityAtTTAI, segments, segmentTree, isDetailedPayload, isPageLoad, calculatePageVisibilityFromTheStartOfPageLoad, moreAccuratePageVisibilityAtTTI, moreAccuratePageVisibilityAtTTAI, labelStack, getInitialPageLoadSSRMetrics, pageLoadInteractionMetrics, getDetailedInteractionMetrics, getPageLoadDetailedInteractionMetrics, newUFOName, resourceTimings, _yield$Promise$all, _yield$Promise$all2, vcMetrics, experimentalMetrics, payload;
640
642
  return _regeneratorRuntime.wrap(function _callee$(_context) {
641
643
  while (1) switch (_context.prev = _context.next) {
642
644
  case 0:
@@ -663,7 +665,7 @@ function _createInteractionMetricsPayload() {
663
665
  labelStack = interaction.labelStack ? {
664
666
  labelStack: optimizeLabelStack(interaction.labelStack, getReactUFOVersion(interaction.type))
665
667
  } : {}; // Page Load
666
- getPageLoadInteractionMetrics = function getPageLoadInteractionMetrics() {
668
+ getInitialPageLoadSSRMetrics = function getInitialPageLoadSSRMetrics() {
667
669
  var _config$ssr;
668
670
  if (!isPageLoad) {
669
671
  return {};
@@ -677,7 +679,8 @@ function _createInteractionMetricsPayload() {
677
679
  isBM3ConfigSSRDoneAsFmp: interaction.metaData.__legacy__bm3ConfigSSRDoneAsFmp,
678
680
  isUFOConfigSSRDoneAsFmp: interaction.metaData.__legacy__bm3ConfigSSRDoneAsFmp || !!(config !== null && config !== void 0 && (_config$ssr = config.ssr) !== null && _config$ssr !== void 0 && _config$ssr.getSSRDoneTime)
679
681
  });
680
- }; // Detailed payload. Page visibility = visible
682
+ };
683
+ pageLoadInteractionMetrics = getInitialPageLoadSSRMetrics(); // Detailed payload. Page visibility = visible
681
684
  getDetailedInteractionMetrics = function getDetailedInteractionMetrics(resourceTimings) {
682
685
  if (experimental || window.__UFO_COMPACT_PAYLOAD__ || !isDetailedPayload) {
683
686
  return {};
@@ -720,9 +723,9 @@ function _createInteractionMetricsPayload() {
720
723
  }
721
724
  newUFOName = sanitizeUfoName(ufoName);
722
725
  resourceTimings = getResourceTimings(start, end);
723
- _context.next = 23;
726
+ _context.next = 24;
724
727
  return Promise.all([getVCMetrics(interaction), experimental ? getExperimentalVCMetrics(interaction) : Promise.resolve(undefined)]);
725
- case 23:
728
+ case 24:
726
729
  _yield$Promise$all = _context.sent;
727
730
  _yield$Promise$all2 = _slicedToArray(_yield$Promise$all, 2);
728
731
  vcMetrics = _yield$Promise$all2[0];
@@ -747,7 +750,7 @@ function _createInteractionMetricsPayload() {
747
750
  'event:region': config.region || 'unknown',
748
751
  'experience:key': experimental ? 'custom.experimental-interaction-metrics' : 'custom.interaction-metrics',
749
752
  'experience:name': newUFOName
750
- }, getBrowserMetadata()), getSSRProperties(type)), getAssetsMetrics(interaction, resourceTimings)), getPPSMetrics(interaction)), getPaintMetrics(type)), getNavigationMetrics(type)), vcMetrics), experimentalMetrics), (_config$additionalPay = config.additionalPayloadData) === null || _config$additionalPay === void 0 ? void 0 : _config$additionalPay.call(config, interaction)), getTracingContextData(interaction)), getStylesheetMetrics()), getErrorCounts(interaction)), {}, {
753
+ }, getBrowserMetadata()), getSSRProperties(type)), getAssetsMetrics(interaction, pageLoadInteractionMetrics === null || pageLoadInteractionMetrics === void 0 ? void 0 : pageLoadInteractionMetrics.SSRDoneTime)), getPPSMetrics(interaction)), getPaintMetrics(type)), getNavigationMetrics(type)), vcMetrics), experimentalMetrics), (_config$additionalPay = config.additionalPayloadData) === null || _config$additionalPay === void 0 ? void 0 : _config$additionalPay.call(config, interaction)), getTracingContextData(interaction)), getStylesheetMetrics()), getErrorCounts(interaction)), {}, {
751
754
  interactionMetrics: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
752
755
  namePrefix: config.namePrefix || '',
753
756
  segmentPrefix: config.segmentPrefix || '',
@@ -779,7 +782,7 @@ function _createInteractionMetricsPayload() {
779
782
  marks: optimizeMarks(interaction.marks, getReactUFOVersion(interaction.type)),
780
783
  customData: optimizeCustomData(interaction),
781
784
  reactProfilerTimings: optimizeReactProfilerTimings(interaction.reactProfilerTimings, start, getReactUFOVersion(interaction.type))
782
- }, labelStack), getPageLoadInteractionMetrics()), getDetailedInteractionMetrics(resourceTimings)), getPageLoadDetailedInteractionMetrics()), getBm3TrackerTimings(interaction)), {}, {
785
+ }, labelStack), pageLoadInteractionMetrics), getDetailedInteractionMetrics(resourceTimings)), getPageLoadDetailedInteractionMetrics()), getBm3TrackerTimings(interaction)), {}, {
783
786
  'metric:ttai': experimental ? regularTTAI || expTTAI : undefined,
784
787
  'metric:experimental:ttai': expTTAI
785
788
  }),
@@ -793,7 +796,7 @@ function _createInteractionMetricsPayload() {
793
796
  }
794
797
  payload.attributes.properties['event:sizeInKb'] = getPayloadSize(payload.attributes.properties);
795
798
  return _context.abrupt("return", payload);
796
- case 31:
799
+ case 32:
797
800
  case "end":
798
801
  return _context.stop();
799
802
  }
@@ -827,19 +830,47 @@ function _createPayloads() {
827
830
  }));
828
831
  return _createPayloads.apply(this, arguments);
829
832
  }
830
- export function createExperimentalMetricsPayload(interactionId, interaction) {
831
- var config = getConfig();
832
- if (!config) {
833
- throw Error('UFO Configuration not provided');
834
- }
835
- var ufoName = sanitizeUfoName(interaction.ufoName);
836
- var rate = getExperimentalInteractionRate(ufoName, interaction.type);
837
- if (!coinflip(rate)) {
838
- return null;
839
- }
840
- var pageVisibilityState = getPageVisibilityState(interaction.start, interaction.end);
841
- if (pageVisibilityState !== 'visible') {
842
- return null;
843
- }
844
- return createInteractionMetricsPayload(interaction, interactionId, true);
833
+ export function createExperimentalMetricsPayload(_x6, _x7) {
834
+ return _createExperimentalMetricsPayload.apply(this, arguments);
835
+ }
836
+ function _createExperimentalMetricsPayload() {
837
+ _createExperimentalMetricsPayload = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(interactionId, interaction) {
838
+ var config, ufoName, rate, pageVisibilityState, result;
839
+ return _regeneratorRuntime.wrap(function _callee3$(_context3) {
840
+ while (1) switch (_context3.prev = _context3.next) {
841
+ case 0:
842
+ config = getConfig();
843
+ if (config) {
844
+ _context3.next = 3;
845
+ break;
846
+ }
847
+ throw Error('UFO Configuration not provided');
848
+ case 3:
849
+ ufoName = sanitizeUfoName(interaction.ufoName);
850
+ rate = getExperimentalInteractionRate(ufoName, interaction.type);
851
+ if (coinflip(rate)) {
852
+ _context3.next = 7;
853
+ break;
854
+ }
855
+ return _context3.abrupt("return", null);
856
+ case 7:
857
+ pageVisibilityState = getPageVisibilityState(interaction.start, interaction.end);
858
+ if (!(pageVisibilityState !== 'visible')) {
859
+ _context3.next = 10;
860
+ break;
861
+ }
862
+ return _context3.abrupt("return", null);
863
+ case 10:
864
+ _context3.next = 12;
865
+ return createInteractionMetricsPayload(interaction, interactionId, true);
866
+ case 12:
867
+ result = _context3.sent;
868
+ return _context3.abrupt("return", result);
869
+ case 14:
870
+ case "end":
871
+ return _context3.stop();
872
+ }
873
+ }, _callee3);
874
+ }));
875
+ return _createExperimentalMetricsPayload.apply(this, arguments);
845
876
  }
@@ -29,17 +29,19 @@ function sinkInteraction(instance, payloadPackage) {
29
29
  function sinkExperimentalInteractionMetrics(instance, payloadPackage) {
30
30
  sinkExperimentalHandler(function (interactionId, interaction) {
31
31
  scheduleCallback(idlePriority, function () {
32
- var payload = payloadPackage.createExperimentalMetricsPayload(interactionId, interaction);
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
- var devToolObserver = globalThis.__ufo_devtool_onUfoPayload;
37
- if (typeof devToolObserver === 'function') {
38
- devToolObserver === null || devToolObserver === void 0 || devToolObserver(payload);
32
+ var payloadPromise = payloadPackage.createExperimentalMetricsPayload(interactionId, interaction);
33
+ payloadPromise.then(function (payload) {
34
+ if (payload) {
35
+ if (fg('enable_ufo_devtools_api_for_extra_events')) {
36
+ // NOTE: This API is used by the UFO DevTool Chrome Extension and Criterion
37
+ var devToolObserver = globalThis.__ufo_devtool_onUfoPayload;
38
+ if (typeof devToolObserver === 'function') {
39
+ devToolObserver === null || devToolObserver === void 0 || devToolObserver(payload);
40
+ }
39
41
  }
42
+ instance.sendOperationalEvent(payload);
40
43
  }
41
- instance.sendOperationalEvent(payload);
42
- }
44
+ });
43
45
  });
44
46
  });
45
47
  }
@@ -7,15 +7,17 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
7
7
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
8
8
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
9
9
  import { fg } from '@atlaskit/platform-feature-flags';
10
+ import { getConfig } from '../config';
10
11
  import { VCObserver } from './vc-observer';
11
12
  import VCObserverNew from './vc-observer-new';
12
13
  var VCObserverWrapper = /*#__PURE__*/function () {
13
14
  function VCObserverWrapper() {
15
+ var _getConfig;
14
16
  var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
15
17
  _classCallCheck(this, VCObserverWrapper);
16
18
  this.oldVCObserver = new VCObserver(opts);
17
19
  this.newVCObserver = null;
18
- var isNewVCObserverEnabled = fg('platform_ufo_vc_observer_new');
20
+ var isNewVCObserverEnabled = fg('platform_ufo_vc_observer_new') || ((_getConfig = getConfig()) === null || _getConfig === void 0 || (_getConfig = _getConfig.vc) === null || _getConfig === void 0 ? void 0 : _getConfig.enableVCObserverNew);
19
21
  if (isNewVCObserverEnabled) {
20
22
  this.newVCObserver = new VCObserverNew({
21
23
  selectorConfig: opts.selectorConfig
@@ -27,7 +29,9 @@ var VCObserverWrapper = /*#__PURE__*/function () {
27
29
  value: function start(startArg) {
28
30
  var _this$oldVCObserver, _this$newVCObserver;
29
31
  (_this$oldVCObserver = this.oldVCObserver) === null || _this$oldVCObserver === void 0 || _this$oldVCObserver.start(startArg);
30
- (_this$newVCObserver = this.newVCObserver) === null || _this$newVCObserver === void 0 || _this$newVCObserver.start();
32
+ (_this$newVCObserver = this.newVCObserver) === null || _this$newVCObserver === void 0 || _this$newVCObserver.start({
33
+ startTime: startArg.startTime
34
+ });
31
35
  }
32
36
  }, {
33
37
  key: "stop",
@@ -4,7 +4,15 @@ function getAttributeSelector(element, attributeName) {
4
4
  if (!attrValue) {
5
5
  return '';
6
6
  }
7
- return "[".concat(attributeName, "=\"").concat(encodeURIComponent(attrValue), "\"]");
7
+ return "[".concat(attributeName, "=\"").concat(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
  var currentElement = element;
14
22
  var parts = [];
15
- while (currentElement && currentElement.localName !== 'body') {
23
+ var MAX_DEPTH = 3;
24
+ var currentDepth = 0;
25
+ while (currentElement && currentElement.localName !== 'body' && currentDepth <= MAX_DEPTH) {
16
26
  var tagName = currentElement.localName;
17
27
  var selectorPart = tagName;
18
- if (selectorConfig.id && currentElement.id) {
19
- selectorPart += "#".concat(encodeURIComponent(currentElement.id));
28
+ if (selectorConfig.id && currentElement.id && isValidSelector("#".concat(currentElement.id))) {
29
+ selectorPart += "#".concat(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
- var classNames = Array.from(currentElement.classList).map(encodeURIComponent).join('.');
37
+ var classNames = Array.from(currentElement.classList).join('.');
28
38
  if (classNames) {
29
- selectorPart += ".".concat(classNames);
39
+ if (isValidSelector(".".concat(classNames))) {
40
+ selectorPart += ".".concat(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
  var potentialSelector = parts.join(' > ').trim();
40
53
  if (!potentialSelector) {
@@ -20,7 +20,6 @@ var VCObserverNew = /*#__PURE__*/function () {
20
20
  var _config$selectorConfi,
21
21
  _this = this;
22
22
  _classCallCheck(this, VCObserverNew);
23
- _defineProperty(this, "startTime", 0);
24
23
  _defineProperty(this, "viewportObserver", null);
25
24
  _defineProperty(this, "windowEventObserver", null);
26
25
  this.entriesTimeline = new EntriesTimeline();
@@ -68,10 +67,12 @@ var VCObserverNew = /*#__PURE__*/function () {
68
67
  }
69
68
  return _createClass(VCObserverNew, [{
70
69
  key: "start",
71
- value: function start() {
70
+ value: function start(_ref2) {
72
71
  var _this$viewportObserve, _this$windowEventObse;
72
+ var startTime = _ref2.startTime;
73
73
  (_this$viewportObserve = this.viewportObserver) === null || _this$viewportObserve === void 0 || _this$viewportObserve.start();
74
74
  (_this$windowEventObse = this.windowEventObserver) === null || _this$windowEventObse === void 0 || _this$windowEventObse.start();
75
+ this.entriesTimeline.clear();
75
76
  }
76
77
  }, {
77
78
  key: "stop",
@@ -97,7 +98,9 @@ var VCObserverNew = /*#__PURE__*/function () {
97
98
  });
98
99
  _context.next = 6;
99
100
  return calculator_fy25_03.calculate({
100
- orderedEntries: orderedEntries
101
+ orderedEntries: orderedEntries,
102
+ startTime: start,
103
+ stopTime: stop
101
104
  });
102
105
  case 6:
103
106
  fy25_03 = _context.sent;
@@ -17,11 +17,11 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
17
17
  var _this = this,
18
18
  _vcDetails$90$t,
19
19
  _vcDetails$;
20
- var orderedEntries, filteredEntries, isVCClean, vcDetails;
20
+ var startTime, stopTime, orderedEntries, filteredEntries, isVCClean, vcDetails;
21
21
  return _regeneratorRuntime.wrap(function _callee$(_context) {
22
22
  while (1) switch (_context.prev = _context.next) {
23
23
  case 0:
24
- orderedEntries = _ref.orderedEntries;
24
+ startTime = _ref.startTime, stopTime = _ref.stopTime, orderedEntries = _ref.orderedEntries;
25
25
  filteredEntries = orderedEntries.filter(function (entry) {
26
26
  return _this.isEntryIncluded(entry);
27
27
  });
@@ -42,6 +42,8 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
42
42
  width: getViewportWidth(),
43
43
  height: getViewportHeight()
44
44
  },
45
+ startTime: startTime,
46
+ stopTime: stopTime,
45
47
  orderedEntries: filteredEntries,
46
48
  percentiles: [25, 50, 75, 80, 85, 90, 95, 98, 99]
47
49
  });