@atlaskit/react-ufo 3.13.27 → 3.14.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.
@@ -4,8 +4,62 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
4
4
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
5
5
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
6
6
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
7
+ import { fg } from '@atlaskit/platform-feature-flags';
7
8
  import { getActiveInteraction } from '../interaction-metrics';
9
+ import getElementName from '../vc/vc-observer-new/get-unique-element-name';
8
10
  var performanceEventObserver;
11
+ var selectorConfig = {
12
+ id: true,
13
+ testId: true,
14
+ role: true,
15
+ className: true
16
+ };
17
+ function getTestIdName(memoizedProps) {
18
+ if (memoizedProps['data-testid']) {
19
+ return "[data-testid=".concat(memoizedProps['data-testid'], "]");
20
+ } else if (memoizedProps['data-test-id']) {
21
+ return "[data-test-id=".concat(memoizedProps['data-testid'], "]");
22
+ }
23
+ return null;
24
+ }
25
+ function getReactComponentHierarchy(element) {
26
+ var componentHierarchy = [];
27
+ // Function to traverse up the fiber tree
28
+ function traverseFiber(fiber) {
29
+ var currentFiber = fiber;
30
+ while (currentFiber) {
31
+ if (currentFiber.type) {
32
+ // Check if there's a display name or a function name
33
+ var componentName = currentFiber.type.displayName || currentFiber.type.name;
34
+ // checking when component name is bigger than the minimized name produced by react
35
+ if (componentName && componentName.length > 2 && !componentName.includes('Listener') && !componentName.includes('Provider')) {
36
+ componentHierarchy.push(componentName);
37
+ }
38
+ if (componentName === 'UFOSegment') {
39
+ break;
40
+ }
41
+ }
42
+ if (currentFiber.memoizedProps) {
43
+ var dataIdInfo = getTestIdName(currentFiber.memoizedProps);
44
+ if (dataIdInfo) {
45
+ componentHierarchy.push(dataIdInfo);
46
+ currentFiber = null;
47
+ continue;
48
+ }
49
+ }
50
+ currentFiber = currentFiber.return;
51
+ }
52
+ }
53
+ // Access the reactFiber node from the HTML element
54
+ var reactFiberKey = Object.keys(element).find(function (key) {
55
+ return key.startsWith('__reactFiber$');
56
+ });
57
+ if (reactFiberKey) {
58
+ var fiber = element[reactFiberKey];
59
+ traverseFiber(fiber);
60
+ }
61
+ return componentHierarchy.reverse().join(' > ');
62
+ }
9
63
  export var getPerformanceObserver = function getPerformanceObserver() {
10
64
  performanceEventObserver = performanceEventObserver || new PerformanceObserver(function (entries) {
11
65
  var list = entries.getEntries();
@@ -40,5 +94,12 @@ export var setInteractionPerformanceEvent = function setInteractionPerformanceEv
40
94
  // it means the interaction start time is not accurate, we assign
41
95
  // this value which will match the timestamp in the event
42
96
  interaction.start = Math.min(interaction.start, entry.startTime);
97
+ if (interaction.ufoName === 'unknown' && fg('platform_ufo_enable_unknown_interactions_elements')) {
98
+ if (entry.target) {
99
+ var componentHierarchy = getReactComponentHierarchy(entry.target);
100
+ interaction.unknownElementHierarchy = componentHierarchy;
101
+ }
102
+ interaction.unknownElementName = getElementName(selectorConfig, entry.target);
103
+ }
43
104
  }
44
105
  };
@@ -2,24 +2,35 @@ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
2
  var BUFFER_MAX_LENGTH = 1000; // ensure we don't blow up this buffer
3
3
  var pressureRecordBuffer = [];
4
4
  var pressureObserver = null;
5
+ var memoryRecordBuffer = [];
6
+ var memoryInterval;
5
7
  export function resetPressureRecordBuffer() {
6
8
  pressureRecordBuffer.length = 0;
7
9
  }
8
- export function removeOldBufferRecords(filter) {
10
+ export function resetMemoryRecordBuffer() {
11
+ memoryRecordBuffer.length = 0;
12
+ }
13
+ export function removeOldPressureBufferRecords(filter) {
9
14
  pressureRecordBuffer = pressureRecordBuffer.filter(function (_ref) {
10
15
  var time = _ref.time;
11
16
  return time > filter;
12
17
  });
13
18
  }
19
+ export function removeOldMemoryBufferRecords(filter) {
20
+ memoryRecordBuffer = memoryRecordBuffer.filter(function (_ref2) {
21
+ var time = _ref2.time;
22
+ return time > filter;
23
+ });
24
+ }
14
25
  export function createPressureStateReport(start, end) {
15
26
  try {
16
27
  // To differentiate between the API not available, vs no PressureRecords added
17
28
  if (!('PressureObserver' in globalThis)) {
18
29
  return null;
19
30
  }
20
- var pressureStateCount = pressureRecordBuffer.reduce(function (pressureReport, _ref2) {
21
- var time = _ref2.time,
22
- state = _ref2.state;
31
+ var pressureStateCount = pressureRecordBuffer.reduce(function (pressureReport, _ref3) {
32
+ var time = _ref3.time,
33
+ state = _ref3.state;
23
34
  if (time >= start && time <= end) {
24
35
  pressureReport[state] += 1;
25
36
  }
@@ -33,7 +44,7 @@ export function createPressureStateReport(start, end) {
33
44
  var pressureStateTotal = Object.values(pressureStateCount).reduce(function (total, count) {
34
45
  return total + count;
35
46
  }) || 1;
36
- removeOldBufferRecords(end);
47
+ removeOldPressureBufferRecords(end);
37
48
  return {
38
49
  count: pressureStateCount,
39
50
  percentage: {
@@ -47,24 +58,81 @@ export function createPressureStateReport(start, end) {
47
58
  return null;
48
59
  }
49
60
  }
61
+ function convertBytesToMegabytes(bytes) {
62
+ return Math.round(Math.round(bytes / (1024 * 1024) * 100) / 100);
63
+ }
64
+ export function createMemoryStateReport(start, end) {
65
+ try {
66
+ if (!('memory' in performance)) {
67
+ return null;
68
+ }
69
+ var accumulatedMemoryUsage = memoryRecordBuffer.reduce(function (acc, snapshot) {
70
+ if (snapshot.time >= start && snapshot.time <= end) {
71
+ acc.totalJSHeapSize += snapshot.totalJSHeapSize;
72
+ acc.usedJSHeapSize += snapshot.usedJSHeapSize;
73
+ acc.snapshotCount += 1;
74
+ }
75
+ return acc;
76
+ }, {
77
+ totalJSHeapSize: 0,
78
+ usedJSHeapSize: 0,
79
+ snapshotCount: 0
80
+ });
81
+ var memoryStateReport = {
82
+ jsHeapSizeLimitInMB: convertBytesToMegabytes(memoryRecordBuffer[0].jsHeapSizeLimit),
83
+ // just use the first record, since this value always remains the same over time
84
+ avgTotalJSHeapSizeInMB: convertBytesToMegabytes(accumulatedMemoryUsage.totalJSHeapSize / accumulatedMemoryUsage.snapshotCount),
85
+ avgUsedJSHeapSizeInMB: convertBytesToMegabytes(accumulatedMemoryUsage.usedJSHeapSize / accumulatedMemoryUsage.snapshotCount)
86
+ };
87
+ removeOldMemoryBufferRecords(end);
88
+ return memoryStateReport;
89
+ } catch (_unused2) {
90
+ return null;
91
+ }
92
+ }
50
93
  export function initialisePressureObserver() {
51
94
  try {
52
95
  if ('PressureObserver' in globalThis) {
53
- var _pressureObserver$obs;
54
96
  pressureObserver = new PressureObserver(function (records) {
55
97
  if (pressureRecordBuffer.length + records.length <= BUFFER_MAX_LENGTH) {
56
98
  var _pressureRecordBuffer;
57
99
  (_pressureRecordBuffer = pressureRecordBuffer).push.apply(_pressureRecordBuffer, _toConsumableArray(records));
58
100
  }
59
101
  });
60
- (_pressureObserver$obs = pressureObserver.observe('cpu', {
102
+ pressureObserver.observe('cpu', {
61
103
  sampleInterval: 100
62
- })) === null || _pressureObserver$obs === void 0 || _pressureObserver$obs.catch();
104
+ }).catch();
63
105
  }
64
106
  } catch (err) {
65
107
  /* do nothing, this is a best efforts metric */
66
108
  }
67
109
  }
110
+ export function initialiseMemoryObserver() {
111
+ try {
112
+ // only set up the interval if `performance.memory` is available in the browser
113
+ if ('memory' in performance) {
114
+ memoryInterval = setInterval(function () {
115
+ // another check of `performance.memory` availability to satisfy typescript
116
+ if ('memory' in performance) {
117
+ var memory = performance.memory;
118
+ if (memoryRecordBuffer.length <= BUFFER_MAX_LENGTH) {
119
+ memoryRecordBuffer.push({
120
+ time: performance.now(),
121
+ jsHeapSizeLimit: memory.jsHeapSizeLimit,
122
+ totalJSHeapSize: memory.totalJSHeapSize,
123
+ usedJSHeapSize: memory.usedJSHeapSize
124
+ });
125
+ }
126
+ }
127
+ }, 100);
128
+ }
129
+ } catch (_unused3) {
130
+ /* do nothing, this is a best efforts metric */
131
+ }
132
+ }
133
+ export function disconnectMemoryObserver() {
134
+ clearInterval(memoryInterval);
135
+ }
68
136
  export function disconnectPressureObserver() {
69
137
  var _pressureObserver;
70
138
  (_pressureObserver = pressureObserver) === null || _pressureObserver === void 0 || _pressureObserver.disconnect();
@@ -161,6 +161,8 @@ export interface InteractionMetrics {
161
161
  vc?: VCRawDataType | null;
162
162
  experimentalTTAI?: number;
163
163
  experimentalVC90?: number;
164
+ unknownElementName?: string;
165
+ unknownElementHierarchy?: string;
164
166
  }
165
167
  export type LoadProfilerEventInfo = {
166
168
  identifier: string;