@atlaskit/react-ufo 3.13.28 → 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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @atlaskit/ufo-interaction-ignore
2
2
 
3
+ ## 3.14.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#176314](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/176314)
8
+ [`9c32e96190532`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/9c32e96190532) -
9
+ report memory usage via UFO
10
+
3
11
  ## 3.13.28
4
12
 
5
13
  ### Patch Changes
@@ -809,7 +809,7 @@ function _createInteractionMetricsPayload() {
809
809
  source: 'measured',
810
810
  tags: ['observability'],
811
811
  attributes: {
812
- properties: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
812
+ properties: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
813
813
  // basic
814
814
  'event:hostname': ((_window$location = window.location) === null || _window$location === void 0 ? void 0 : _window$location.hostname) || 'unknown',
815
815
  'event:product': config.product,
@@ -824,6 +824,8 @@ function _createInteractionMetricsPayload() {
824
824
  'experience:name': newUFOName
825
825
  }, (0, _platformFeatureFlags.fg)('platform_ufo_report_cpu_usage') ? {
826
826
  'event:cpu:usage': (0, _machineUtilisation.createPressureStateReport)(interaction.start, interaction.end)
827
+ } : {}), (0, _platformFeatureFlags.fg)('platform_ufo_report_memory_usage') ? {
828
+ 'event:memory:usage': (0, _machineUtilisation.createMemoryStateReport)(interaction.start, interaction.end)
827
829
  } : {}), getBrowserMetadata()), getSSRProperties(type)), getAssetsMetrics(interaction, pageLoadInteractionMetrics === null || pageLoadInteractionMetrics === void 0 ? void 0 : pageLoadInteractionMetrics.SSRDoneTime)), getPPSMetrics(interaction)), paintMetrics), 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)), {}, {
828
830
  interactionMetrics: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
829
831
  namePrefix: config.namePrefix || '',
@@ -87,6 +87,9 @@ function init(analyticsWebClientAsync, config) {
87
87
  if ((0, _platformFeatureFlags.fg)('platform_ufo_report_cpu_usage')) {
88
88
  (0, _machineUtilisation.initialisePressureObserver)();
89
89
  }
90
+ if ((0, _platformFeatureFlags.fg)('platform_ufo_report_memory_usage')) {
91
+ (0, _machineUtilisation.initialiseMemoryObserver)();
92
+ }
90
93
  (0, _config.setUFOConfig)(config);
91
94
  if ((_config$vc = config.vc) !== null && _config$vc !== void 0 && _config$vc.enabled) {
92
95
  var _config$experimentalI;
@@ -4,33 +4,49 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
+ exports.createMemoryStateReport = createMemoryStateReport;
7
8
  exports.createPressureStateReport = createPressureStateReport;
9
+ exports.disconnectMemoryObserver = disconnectMemoryObserver;
8
10
  exports.disconnectPressureObserver = disconnectPressureObserver;
11
+ exports.initialiseMemoryObserver = initialiseMemoryObserver;
9
12
  exports.initialisePressureObserver = initialisePressureObserver;
10
- exports.removeOldBufferRecords = removeOldBufferRecords;
13
+ exports.removeOldMemoryBufferRecords = removeOldMemoryBufferRecords;
14
+ exports.removeOldPressureBufferRecords = removeOldPressureBufferRecords;
15
+ exports.resetMemoryRecordBuffer = resetMemoryRecordBuffer;
11
16
  exports.resetPressureRecordBuffer = resetPressureRecordBuffer;
12
17
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
13
18
  var BUFFER_MAX_LENGTH = 1000; // ensure we don't blow up this buffer
14
19
  var pressureRecordBuffer = [];
15
20
  var pressureObserver = null;
21
+ var memoryRecordBuffer = [];
22
+ var memoryInterval;
16
23
  function resetPressureRecordBuffer() {
17
24
  pressureRecordBuffer.length = 0;
18
25
  }
19
- function removeOldBufferRecords(filter) {
26
+ function resetMemoryRecordBuffer() {
27
+ memoryRecordBuffer.length = 0;
28
+ }
29
+ function removeOldPressureBufferRecords(filter) {
20
30
  pressureRecordBuffer = pressureRecordBuffer.filter(function (_ref) {
21
31
  var time = _ref.time;
22
32
  return time > filter;
23
33
  });
24
34
  }
35
+ function removeOldMemoryBufferRecords(filter) {
36
+ memoryRecordBuffer = memoryRecordBuffer.filter(function (_ref2) {
37
+ var time = _ref2.time;
38
+ return time > filter;
39
+ });
40
+ }
25
41
  function createPressureStateReport(start, end) {
26
42
  try {
27
43
  // To differentiate between the API not available, vs no PressureRecords added
28
44
  if (!('PressureObserver' in globalThis)) {
29
45
  return null;
30
46
  }
31
- var pressureStateCount = pressureRecordBuffer.reduce(function (pressureReport, _ref2) {
32
- var time = _ref2.time,
33
- state = _ref2.state;
47
+ var pressureStateCount = pressureRecordBuffer.reduce(function (pressureReport, _ref3) {
48
+ var time = _ref3.time,
49
+ state = _ref3.state;
34
50
  if (time >= start && time <= end) {
35
51
  pressureReport[state] += 1;
36
52
  }
@@ -44,7 +60,7 @@ function createPressureStateReport(start, end) {
44
60
  var pressureStateTotal = Object.values(pressureStateCount).reduce(function (total, count) {
45
61
  return total + count;
46
62
  }) || 1;
47
- removeOldBufferRecords(end);
63
+ removeOldPressureBufferRecords(end);
48
64
  return {
49
65
  count: pressureStateCount,
50
66
  percentage: {
@@ -58,24 +74,81 @@ function createPressureStateReport(start, end) {
58
74
  return null;
59
75
  }
60
76
  }
77
+ function convertBytesToMegabytes(bytes) {
78
+ return Math.round(Math.round(bytes / (1024 * 1024) * 100) / 100);
79
+ }
80
+ function createMemoryStateReport(start, end) {
81
+ try {
82
+ if (!('memory' in performance)) {
83
+ return null;
84
+ }
85
+ var accumulatedMemoryUsage = memoryRecordBuffer.reduce(function (acc, snapshot) {
86
+ if (snapshot.time >= start && snapshot.time <= end) {
87
+ acc.totalJSHeapSize += snapshot.totalJSHeapSize;
88
+ acc.usedJSHeapSize += snapshot.usedJSHeapSize;
89
+ acc.snapshotCount += 1;
90
+ }
91
+ return acc;
92
+ }, {
93
+ totalJSHeapSize: 0,
94
+ usedJSHeapSize: 0,
95
+ snapshotCount: 0
96
+ });
97
+ var memoryStateReport = {
98
+ jsHeapSizeLimitInMB: convertBytesToMegabytes(memoryRecordBuffer[0].jsHeapSizeLimit),
99
+ // just use the first record, since this value always remains the same over time
100
+ avgTotalJSHeapSizeInMB: convertBytesToMegabytes(accumulatedMemoryUsage.totalJSHeapSize / accumulatedMemoryUsage.snapshotCount),
101
+ avgUsedJSHeapSizeInMB: convertBytesToMegabytes(accumulatedMemoryUsage.usedJSHeapSize / accumulatedMemoryUsage.snapshotCount)
102
+ };
103
+ removeOldMemoryBufferRecords(end);
104
+ return memoryStateReport;
105
+ } catch (_unused2) {
106
+ return null;
107
+ }
108
+ }
61
109
  function initialisePressureObserver() {
62
110
  try {
63
111
  if ('PressureObserver' in globalThis) {
64
- var _pressureObserver$obs;
65
112
  pressureObserver = new PressureObserver(function (records) {
66
113
  if (pressureRecordBuffer.length + records.length <= BUFFER_MAX_LENGTH) {
67
114
  var _pressureRecordBuffer;
68
115
  (_pressureRecordBuffer = pressureRecordBuffer).push.apply(_pressureRecordBuffer, (0, _toConsumableArray2.default)(records));
69
116
  }
70
117
  });
71
- (_pressureObserver$obs = pressureObserver.observe('cpu', {
118
+ pressureObserver.observe('cpu', {
72
119
  sampleInterval: 100
73
- })) === null || _pressureObserver$obs === void 0 || _pressureObserver$obs.catch();
120
+ }).catch();
74
121
  }
75
122
  } catch (err) {
76
123
  /* do nothing, this is a best efforts metric */
77
124
  }
78
125
  }
126
+ function initialiseMemoryObserver() {
127
+ try {
128
+ // only set up the interval if `performance.memory` is available in the browser
129
+ if ('memory' in performance) {
130
+ memoryInterval = setInterval(function () {
131
+ // another check of `performance.memory` availability to satisfy typescript
132
+ if ('memory' in performance) {
133
+ var memory = performance.memory;
134
+ if (memoryRecordBuffer.length <= BUFFER_MAX_LENGTH) {
135
+ memoryRecordBuffer.push({
136
+ time: performance.now(),
137
+ jsHeapSizeLimit: memory.jsHeapSizeLimit,
138
+ totalJSHeapSize: memory.totalJSHeapSize,
139
+ usedJSHeapSize: memory.usedJSHeapSize
140
+ });
141
+ }
142
+ }
143
+ }, 100);
144
+ }
145
+ } catch (_unused3) {
146
+ /* do nothing, this is a best efforts metric */
147
+ }
148
+ }
149
+ function disconnectMemoryObserver() {
150
+ clearInterval(memoryInterval);
151
+ }
79
152
  function disconnectPressureObserver() {
80
153
  var _pressureObserver;
81
154
  (_pressureObserver = pressureObserver) === null || _pressureObserver === void 0 || _pressureObserver.disconnect();
@@ -11,7 +11,7 @@ import { getGlobalErrorCount } from '../global-error-handler';
11
11
  import { getPageVisibilityState } from '../hidden-timing';
12
12
  import * as initialPageLoadExtraTiming from '../initial-page-load-extra-timing';
13
13
  import { interactionSpans as atlaskitInteractionSpans } from '../interaction-metrics';
14
- import { createPressureStateReport } from '../machine-utilisation';
14
+ import { createMemoryStateReport, createPressureStateReport } from '../machine-utilisation';
15
15
  import * as resourceTiming from '../resource-timing';
16
16
  import { filterResourceTimings } from '../resource-timing/common/utils/resource-timing-buffer';
17
17
  import { roundEpsilon } from '../round-number';
@@ -803,6 +803,9 @@ async function createInteractionMetricsPayload(interaction, interactionId, exper
803
803
  ...(fg('platform_ufo_report_cpu_usage') ? {
804
804
  'event:cpu:usage': createPressureStateReport(interaction.start, interaction.end)
805
805
  } : {}),
806
+ ...(fg('platform_ufo_report_memory_usage') ? {
807
+ 'event:memory:usage': createMemoryStateReport(interaction.start, interaction.end)
808
+ } : {}),
806
809
  // root
807
810
  ...getBrowserMetadata(),
808
811
  ...getSSRProperties(type),
@@ -5,7 +5,7 @@ import { experimentalVC, sinkExperimentalHandler } from '../create-experimental-
5
5
  import { setupHiddenTimingCapture } from '../hidden-timing';
6
6
  import { postInteractionLog, sinkInteractionHandler, sinkPostInteractionLogHandler } from '../interaction-metrics';
7
7
  import { getPerformanceObserver } from '../interactions-performance-observer';
8
- import { initialisePressureObserver } from '../machine-utilisation';
8
+ import { initialiseMemoryObserver, initialisePressureObserver } from '../machine-utilisation';
9
9
  import { getVCObserver } from '../vc';
10
10
  import scheduleIdleCallback from './schedule-idle-callback';
11
11
  let initialized = false;
@@ -77,6 +77,9 @@ export function init(analyticsWebClientAsync, config) {
77
77
  if (fg('platform_ufo_report_cpu_usage')) {
78
78
  initialisePressureObserver();
79
79
  }
80
+ if (fg('platform_ufo_report_memory_usage')) {
81
+ initialiseMemoryObserver();
82
+ }
80
83
  setUFOConfig(config);
81
84
  if ((_config$vc = config.vc) !== null && _config$vc !== void 0 && _config$vc.enabled) {
82
85
  var _config$experimentalI;
@@ -1,14 +1,24 @@
1
1
  const BUFFER_MAX_LENGTH = 1000; // ensure we don't blow up this buffer
2
2
  let pressureRecordBuffer = [];
3
3
  let pressureObserver = null;
4
+ let memoryRecordBuffer = [];
5
+ let memoryInterval;
4
6
  export function resetPressureRecordBuffer() {
5
7
  pressureRecordBuffer.length = 0;
6
8
  }
7
- export function removeOldBufferRecords(filter) {
9
+ export function resetMemoryRecordBuffer() {
10
+ memoryRecordBuffer.length = 0;
11
+ }
12
+ export function removeOldPressureBufferRecords(filter) {
8
13
  pressureRecordBuffer = pressureRecordBuffer.filter(({
9
14
  time
10
15
  }) => time > filter);
11
16
  }
17
+ export function removeOldMemoryBufferRecords(filter) {
18
+ memoryRecordBuffer = memoryRecordBuffer.filter(({
19
+ time
20
+ }) => time > filter);
21
+ }
12
22
  export function createPressureStateReport(start, end) {
13
23
  try {
14
24
  // To differentiate between the API not available, vs no PressureRecords added
@@ -30,7 +40,7 @@ export function createPressureStateReport(start, end) {
30
40
  critical: 0
31
41
  });
32
42
  const pressureStateTotal = Object.values(pressureStateCount).reduce((total, count) => total + count) || 1;
33
- removeOldBufferRecords(end);
43
+ removeOldPressureBufferRecords(end);
34
44
  return {
35
45
  count: pressureStateCount,
36
46
  percentage: {
@@ -44,23 +54,80 @@ export function createPressureStateReport(start, end) {
44
54
  return null;
45
55
  }
46
56
  }
57
+ function convertBytesToMegabytes(bytes) {
58
+ return Math.round(Math.round(bytes / (1024 * 1024) * 100) / 100);
59
+ }
60
+ export function createMemoryStateReport(start, end) {
61
+ try {
62
+ if (!('memory' in performance)) {
63
+ return null;
64
+ }
65
+ const accumulatedMemoryUsage = memoryRecordBuffer.reduce((acc, snapshot) => {
66
+ if (snapshot.time >= start && snapshot.time <= end) {
67
+ acc.totalJSHeapSize += snapshot.totalJSHeapSize;
68
+ acc.usedJSHeapSize += snapshot.usedJSHeapSize;
69
+ acc.snapshotCount += 1;
70
+ }
71
+ return acc;
72
+ }, {
73
+ totalJSHeapSize: 0,
74
+ usedJSHeapSize: 0,
75
+ snapshotCount: 0
76
+ });
77
+ const memoryStateReport = {
78
+ jsHeapSizeLimitInMB: convertBytesToMegabytes(memoryRecordBuffer[0].jsHeapSizeLimit),
79
+ // just use the first record, since this value always remains the same over time
80
+ avgTotalJSHeapSizeInMB: convertBytesToMegabytes(accumulatedMemoryUsage.totalJSHeapSize / accumulatedMemoryUsage.snapshotCount),
81
+ avgUsedJSHeapSizeInMB: convertBytesToMegabytes(accumulatedMemoryUsage.usedJSHeapSize / accumulatedMemoryUsage.snapshotCount)
82
+ };
83
+ removeOldMemoryBufferRecords(end);
84
+ return memoryStateReport;
85
+ } catch {
86
+ return null;
87
+ }
88
+ }
47
89
  export function initialisePressureObserver() {
48
90
  try {
49
91
  if ('PressureObserver' in globalThis) {
50
- var _pressureObserver$obs;
51
92
  pressureObserver = new PressureObserver(records => {
52
93
  if (pressureRecordBuffer.length + records.length <= BUFFER_MAX_LENGTH) {
53
94
  pressureRecordBuffer.push(...records);
54
95
  }
55
96
  });
56
- (_pressureObserver$obs = pressureObserver.observe('cpu', {
97
+ pressureObserver.observe('cpu', {
57
98
  sampleInterval: 100
58
- })) === null || _pressureObserver$obs === void 0 ? void 0 : _pressureObserver$obs.catch();
99
+ }).catch();
59
100
  }
60
101
  } catch (err) {
61
102
  /* do nothing, this is a best efforts metric */
62
103
  }
63
104
  }
105
+ export function initialiseMemoryObserver() {
106
+ try {
107
+ // only set up the interval if `performance.memory` is available in the browser
108
+ if ('memory' in performance) {
109
+ memoryInterval = setInterval(() => {
110
+ // another check of `performance.memory` availability to satisfy typescript
111
+ if ('memory' in performance) {
112
+ const memory = performance.memory;
113
+ if (memoryRecordBuffer.length <= BUFFER_MAX_LENGTH) {
114
+ memoryRecordBuffer.push({
115
+ time: performance.now(),
116
+ jsHeapSizeLimit: memory.jsHeapSizeLimit,
117
+ totalJSHeapSize: memory.totalJSHeapSize,
118
+ usedJSHeapSize: memory.usedJSHeapSize
119
+ });
120
+ }
121
+ }
122
+ }, 100);
123
+ }
124
+ } catch {
125
+ /* do nothing, this is a best efforts metric */
126
+ }
127
+ }
128
+ export function disconnectMemoryObserver() {
129
+ clearInterval(memoryInterval);
130
+ }
64
131
  export function disconnectPressureObserver() {
65
132
  var _pressureObserver;
66
133
  (_pressureObserver = pressureObserver) === null || _pressureObserver === void 0 ? void 0 : _pressureObserver.disconnect();
@@ -23,7 +23,7 @@ import { getGlobalErrorCount } from '../global-error-handler';
23
23
  import { getPageVisibilityState } from '../hidden-timing';
24
24
  import * as initialPageLoadExtraTiming from '../initial-page-load-extra-timing';
25
25
  import { interactionSpans as atlaskitInteractionSpans } from '../interaction-metrics';
26
- import { createPressureStateReport } from '../machine-utilisation';
26
+ import { createMemoryStateReport, createPressureStateReport } from '../machine-utilisation';
27
27
  import * as resourceTiming from '../resource-timing';
28
28
  import { filterResourceTimings } from '../resource-timing/common/utils/resource-timing-buffer';
29
29
  import { roundEpsilon } from '../round-number';
@@ -799,7 +799,7 @@ function _createInteractionMetricsPayload() {
799
799
  source: 'measured',
800
800
  tags: ['observability'],
801
801
  attributes: {
802
- properties: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
802
+ properties: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
803
803
  // basic
804
804
  'event:hostname': ((_window$location = window.location) === null || _window$location === void 0 ? void 0 : _window$location.hostname) || 'unknown',
805
805
  'event:product': config.product,
@@ -814,6 +814,8 @@ function _createInteractionMetricsPayload() {
814
814
  'experience:name': newUFOName
815
815
  }, fg('platform_ufo_report_cpu_usage') ? {
816
816
  'event:cpu:usage': createPressureStateReport(interaction.start, interaction.end)
817
+ } : {}), fg('platform_ufo_report_memory_usage') ? {
818
+ 'event:memory:usage': createMemoryStateReport(interaction.start, interaction.end)
817
819
  } : {}), getBrowserMetadata()), getSSRProperties(type)), getAssetsMetrics(interaction, pageLoadInteractionMetrics === null || pageLoadInteractionMetrics === void 0 ? void 0 : pageLoadInteractionMetrics.SSRDoneTime)), getPPSMetrics(interaction)), paintMetrics), 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)), {}, {
818
820
  interactionMetrics: _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
819
821
  namePrefix: config.namePrefix || '',
@@ -6,7 +6,7 @@ import { experimentalVC, sinkExperimentalHandler } from '../create-experimental-
6
6
  import { setupHiddenTimingCapture } from '../hidden-timing';
7
7
  import { postInteractionLog, sinkInteractionHandler, sinkPostInteractionLogHandler } from '../interaction-metrics';
8
8
  import { getPerformanceObserver } from '../interactions-performance-observer';
9
- import { initialisePressureObserver } from '../machine-utilisation';
9
+ import { initialiseMemoryObserver, initialisePressureObserver } from '../machine-utilisation';
10
10
  import { getVCObserver } from '../vc';
11
11
  import scheduleIdleCallback from './schedule-idle-callback';
12
12
  var initialized = false;
@@ -78,6 +78,9 @@ export function init(analyticsWebClientAsync, config) {
78
78
  if (fg('platform_ufo_report_cpu_usage')) {
79
79
  initialisePressureObserver();
80
80
  }
81
+ if (fg('platform_ufo_report_memory_usage')) {
82
+ initialiseMemoryObserver();
83
+ }
81
84
  setUFOConfig(config);
82
85
  if ((_config$vc = config.vc) !== null && _config$vc !== void 0 && _config$vc.enabled) {
83
86
  var _config$experimentalI;
@@ -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();