@atlaskit/react-ufo 4.15.3 → 4.15.4

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,12 @@
1
1
  # @atlaskit/ufo-interaction-ignore
2
2
 
3
+ ## 4.15.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [`81a0f341fac4f`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/81a0f341fac4f) -
8
+ Platformise Jira's SSR Render Profiler timings
9
+
3
10
  ## 4.15.3
4
11
 
5
12
  ### Patch Changes
@@ -11,6 +11,7 @@ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers
11
11
  var _react = _interopRequireWildcard(require("react"));
12
12
  var _scheduler = require("scheduler");
13
13
  var _uuid = require("uuid");
14
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
14
15
  var _coinflip = _interopRequireDefault(require("../coinflip"));
15
16
  var _config = require("../config");
16
17
  var _experienceTraceIdContext = require("../experience-trace-id-context");
@@ -20,6 +21,7 @@ var _interactionMetrics = require("../interaction-metrics");
20
21
  var _routeNameContext = _interopRequireDefault(require("../route-name-context"));
21
22
  var _shortId = _interopRequireDefault(require("../short-id"));
22
23
  var _scheduleOnPaint = _interopRequireDefault(require("./schedule-on-paint"));
24
+ var _ssrRenderProfiler = _interopRequireDefault(require("./ssr-render-profiler"));
23
25
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
24
26
  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; }
25
27
  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) { (0, _defineProperty2.default)(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; } // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
@@ -277,11 +279,18 @@ function UFOSegment(_ref) {
277
279
  return l.name;
278
280
  }).join('/');
279
281
  }, [labelStack]);
280
- return /*#__PURE__*/_react.default.createElement(_interactionContext.default.Provider, {
282
+ var ufoSegment = /*#__PURE__*/_react.default.createElement(_interactionContext.default.Provider, {
281
283
  value: interactionContext
282
284
  }, /*#__PURE__*/_react.default.createElement(_react.Profiler, {
283
285
  id: reactProfilerId,
284
286
  onRender: onRender
285
287
  }, children));
288
+ if ((0, _platformFeatureFlags.fg)('platform_ufo_ssr_render_profiler')) {
289
+ return /*#__PURE__*/_react.default.createElement(_ssrRenderProfiler.default, {
290
+ labelStack: labelStack,
291
+ onRender: interactionContext.onRender
292
+ }, ufoSegment);
293
+ }
294
+ return ufoSegment;
286
295
  }
287
296
  UFOSegment.displayName = 'UFOSegment';
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+
3
+ var _typeof = require("@babel/runtime/helpers/typeof");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = exports.SsrRenderProfilerInner = void 0;
8
+ var _react = _interopRequireWildcard(require("react"));
9
+ var _interactionMetrics = require("../interaction-metrics");
10
+ var _process;
11
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
12
+ // These are stored outside react context to be resilient to concurrent mode
13
+ // restarting the start marker from a suspense and losing the initial render
14
+ var startTimes = new Map();
15
+ // Keep track of the last interaction id and reset the start timers if it ever changes.
16
+ // This is to allow multi-step ssr to track the render timers from different "interaction"s seperately
17
+ var lastActiveInteraction;
18
+ function checkActiveInteractionAndResetStartMarksIfSet() {
19
+ var _getActiveInteraction;
20
+ var activeInteractionId = (_getActiveInteraction = (0, _interactionMetrics.getActiveInteraction)()) === null || _getActiveInteraction === void 0 ? void 0 : _getActiveInteraction.id;
21
+ if (!!lastActiveInteraction && lastActiveInteraction !== activeInteractionId) {
22
+ startTimes.clear();
23
+ }
24
+ lastActiveInteraction = activeInteractionId;
25
+ }
26
+ var onStartRender = function onStartRender(id) {
27
+ var _startTimes$get;
28
+ if (!startTimes.has(id)) {
29
+ startTimes.set(id, []);
30
+ }
31
+ (_startTimes$get = startTimes.get(id)) === null || _startTimes$get === void 0 || _startTimes$get.push(performance.now());
32
+ };
33
+ var isInSSR = Boolean(globalThis === null || globalThis === void 0 ? void 0 : globalThis.__SERVER__) || typeof process !== 'undefined' && Boolean(((_process = process) === null || _process === void 0 || (_process = _process.env) === null || _process === void 0 ? void 0 : _process.REACT_SSR) || false);
34
+ var ProfilerMarker = function ProfilerMarker(_ref) {
35
+ var onRender = _ref.onRender;
36
+ if (isInSSR) {
37
+ onRender === null || onRender === void 0 || onRender();
38
+ }
39
+ return null;
40
+ };
41
+ var SsrRenderProfilerInner = exports.SsrRenderProfilerInner = function SsrRenderProfilerInner(_ref2) {
42
+ var children = _ref2.children,
43
+ labelStack = _ref2.labelStack,
44
+ _onRender = _ref2.onRender;
45
+ var reactProfilerId = (0, _react.useMemo)(function () {
46
+ return labelStack.map(function (l) {
47
+ return l.name;
48
+ }).join('/');
49
+ }, [labelStack]);
50
+ checkActiveInteractionAndResetStartMarksIfSet();
51
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(ProfilerMarker, {
52
+ onRender: function onRender() {
53
+ return onStartRender(reactProfilerId);
54
+ }
55
+ }), children, /*#__PURE__*/_react.default.createElement(ProfilerMarker, {
56
+ onRender: function onRender() {
57
+ var startTimesForId = startTimes.get(reactProfilerId);
58
+ if (startTimesForId !== null && startTimesForId !== void 0 && startTimesForId.length) {
59
+ var endTime = performance.now();
60
+ var firstStartTime = startTimesForId[0];
61
+ var lastStartTime = startTimesForId[startTimesForId.length - 1];
62
+ var baseDuration = endTime - lastStartTime;
63
+ var actualDuration = endTime - firstStartTime;
64
+ _onRender('mount',
65
+ // this is incorrect, but on the server there is no mount phase
66
+ actualDuration, baseDuration, firstStartTime, endTime);
67
+ }
68
+ }
69
+ }));
70
+ };
71
+ var SsrRenderProfiler = function SsrRenderProfiler(props) {
72
+ if (isInSSR) {
73
+ return /*#__PURE__*/_react.default.createElement(SsrRenderProfilerInner, props);
74
+ }
75
+
76
+ // ensure structure similar to SSR implementation
77
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(ProfilerMarker, null), props.children);
78
+ };
79
+ var _default = exports.default = SsrRenderProfiler;
@@ -2,6 +2,7 @@ import React, { Profiler, useCallback, useContext, useEffect, useMemo, useRef }
2
2
  import { unstable_NormalPriority as NormalPriority, unstable_scheduleCallback as scheduleCallback } from 'scheduler';
3
3
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
4
4
  import { v4 as createUUID } from 'uuid';
5
+ import { fg } from '@atlaskit/platform-feature-flags';
5
6
  import coinflip from '../coinflip';
6
7
  import { getConfig, getDoNotAbortActivePressInteraction, getInteractionRate, getMinorInteractions } from '../config';
7
8
  import { getActiveTrace, setInteractionActiveTrace } from '../experience-trace-id-context';
@@ -11,6 +12,7 @@ import { abortByNewInteraction, addApdex, addCustomData, addCustomTiming, addHol
11
12
  import UFORouteName from '../route-name-context';
12
13
  import generateId from '../short-id';
13
14
  import scheduleOnPaint from './schedule-on-paint';
15
+ import SsrRenderProfiler from './ssr-render-profiler';
14
16
  let tryCompleteHandle;
15
17
  let hasMarkedFirstSegmentLoad = false;
16
18
 
@@ -255,11 +257,18 @@ export default function UFOSegment({
255
257
  };
256
258
  }, [interactionId, parentContext, interactionContext, labelStack]);
257
259
  const reactProfilerId = useMemo(() => labelStack.map(l => l.name).join('/'), [labelStack]);
258
- return /*#__PURE__*/React.createElement(UFOInteractionContext.Provider, {
260
+ const ufoSegment = /*#__PURE__*/React.createElement(UFOInteractionContext.Provider, {
259
261
  value: interactionContext
260
262
  }, /*#__PURE__*/React.createElement(Profiler, {
261
263
  id: reactProfilerId,
262
264
  onRender: onRender
263
265
  }, children));
266
+ if (fg('platform_ufo_ssr_render_profiler')) {
267
+ return /*#__PURE__*/React.createElement(SsrRenderProfiler, {
268
+ labelStack: labelStack,
269
+ onRender: interactionContext.onRender
270
+ }, ufoSegment);
271
+ }
272
+ return ufoSegment;
264
273
  }
265
274
  UFOSegment.displayName = 'UFOSegment';
@@ -0,0 +1,68 @@
1
+ var _process, _process$env;
2
+ import React, { useMemo } from 'react';
3
+ import { getActiveInteraction } from '../interaction-metrics';
4
+
5
+ // These are stored outside react context to be resilient to concurrent mode
6
+ // restarting the start marker from a suspense and losing the initial render
7
+ const startTimes = new Map();
8
+ // Keep track of the last interaction id and reset the start timers if it ever changes.
9
+ // This is to allow multi-step ssr to track the render timers from different "interaction"s seperately
10
+ let lastActiveInteraction;
11
+ function checkActiveInteractionAndResetStartMarksIfSet() {
12
+ var _getActiveInteraction;
13
+ const activeInteractionId = (_getActiveInteraction = getActiveInteraction()) === null || _getActiveInteraction === void 0 ? void 0 : _getActiveInteraction.id;
14
+ if (!!lastActiveInteraction && lastActiveInteraction !== activeInteractionId) {
15
+ startTimes.clear();
16
+ }
17
+ lastActiveInteraction = activeInteractionId;
18
+ }
19
+ const onStartRender = id => {
20
+ var _startTimes$get;
21
+ if (!startTimes.has(id)) {
22
+ startTimes.set(id, []);
23
+ }
24
+ (_startTimes$get = startTimes.get(id)) === null || _startTimes$get === void 0 ? void 0 : _startTimes$get.push(performance.now());
25
+ };
26
+ const isInSSR = Boolean(globalThis === null || globalThis === void 0 ? void 0 : globalThis.__SERVER__) || typeof process !== 'undefined' && Boolean(((_process = process) === null || _process === void 0 ? void 0 : (_process$env = _process.env) === null || _process$env === void 0 ? void 0 : _process$env.REACT_SSR) || false);
27
+ const ProfilerMarker = ({
28
+ onRender
29
+ }) => {
30
+ if (isInSSR) {
31
+ onRender === null || onRender === void 0 ? void 0 : onRender();
32
+ }
33
+ return null;
34
+ };
35
+ export const SsrRenderProfilerInner = ({
36
+ children,
37
+ labelStack,
38
+ onRender
39
+ }) => {
40
+ const reactProfilerId = useMemo(() => labelStack.map(l => l.name).join('/'), [labelStack]);
41
+ checkActiveInteractionAndResetStartMarksIfSet();
42
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ProfilerMarker, {
43
+ onRender: () => onStartRender(reactProfilerId)
44
+ }), children, /*#__PURE__*/React.createElement(ProfilerMarker, {
45
+ onRender: () => {
46
+ const startTimesForId = startTimes.get(reactProfilerId);
47
+ if (startTimesForId !== null && startTimesForId !== void 0 && startTimesForId.length) {
48
+ const endTime = performance.now();
49
+ const firstStartTime = startTimesForId[0];
50
+ const lastStartTime = startTimesForId[startTimesForId.length - 1];
51
+ const baseDuration = endTime - lastStartTime;
52
+ const actualDuration = endTime - firstStartTime;
53
+ onRender('mount',
54
+ // this is incorrect, but on the server there is no mount phase
55
+ actualDuration, baseDuration, firstStartTime, endTime);
56
+ }
57
+ }
58
+ }));
59
+ };
60
+ const SsrRenderProfiler = props => {
61
+ if (isInSSR) {
62
+ return /*#__PURE__*/React.createElement(SsrRenderProfilerInner, props);
63
+ }
64
+
65
+ // ensure structure similar to SSR implementation
66
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ProfilerMarker, null), props.children);
67
+ };
68
+ export default SsrRenderProfiler;
@@ -6,6 +6,7 @@ import React, { Profiler, useCallback, useContext, useEffect, useMemo, useRef }
6
6
  import { unstable_NormalPriority as NormalPriority, unstable_scheduleCallback as scheduleCallback } from 'scheduler';
7
7
  // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
8
8
  import { v4 as createUUID } from 'uuid';
9
+ import { fg } from '@atlaskit/platform-feature-flags';
9
10
  import coinflip from '../coinflip';
10
11
  import { getConfig, getDoNotAbortActivePressInteraction, getInteractionRate, getMinorInteractions } from '../config';
11
12
  import { getActiveTrace, setInteractionActiveTrace } from '../experience-trace-id-context';
@@ -15,6 +16,7 @@ import { abortByNewInteraction, addApdex as _addApdex, addCustomData as _addCust
15
16
  import UFORouteName from '../route-name-context';
16
17
  import generateId from '../short-id';
17
18
  import scheduleOnPaint from './schedule-on-paint';
19
+ import SsrRenderProfiler from './ssr-render-profiler';
18
20
  var tryCompleteHandle;
19
21
  var hasMarkedFirstSegmentLoad = false;
20
22
 
@@ -269,11 +271,18 @@ export default function UFOSegment(_ref) {
269
271
  return l.name;
270
272
  }).join('/');
271
273
  }, [labelStack]);
272
- return /*#__PURE__*/React.createElement(UFOInteractionContext.Provider, {
274
+ var ufoSegment = /*#__PURE__*/React.createElement(UFOInteractionContext.Provider, {
273
275
  value: interactionContext
274
276
  }, /*#__PURE__*/React.createElement(Profiler, {
275
277
  id: reactProfilerId,
276
278
  onRender: onRender
277
279
  }, children));
280
+ if (fg('platform_ufo_ssr_render_profiler')) {
281
+ return /*#__PURE__*/React.createElement(SsrRenderProfiler, {
282
+ labelStack: labelStack,
283
+ onRender: interactionContext.onRender
284
+ }, ufoSegment);
285
+ }
286
+ return ufoSegment;
278
287
  }
279
288
  UFOSegment.displayName = 'UFOSegment';
@@ -0,0 +1,72 @@
1
+ var _process;
2
+ import React, { useMemo } from 'react';
3
+ import { getActiveInteraction } from '../interaction-metrics';
4
+
5
+ // These are stored outside react context to be resilient to concurrent mode
6
+ // restarting the start marker from a suspense and losing the initial render
7
+ var startTimes = new Map();
8
+ // Keep track of the last interaction id and reset the start timers if it ever changes.
9
+ // This is to allow multi-step ssr to track the render timers from different "interaction"s seperately
10
+ var lastActiveInteraction;
11
+ function checkActiveInteractionAndResetStartMarksIfSet() {
12
+ var _getActiveInteraction;
13
+ var activeInteractionId = (_getActiveInteraction = getActiveInteraction()) === null || _getActiveInteraction === void 0 ? void 0 : _getActiveInteraction.id;
14
+ if (!!lastActiveInteraction && lastActiveInteraction !== activeInteractionId) {
15
+ startTimes.clear();
16
+ }
17
+ lastActiveInteraction = activeInteractionId;
18
+ }
19
+ var onStartRender = function onStartRender(id) {
20
+ var _startTimes$get;
21
+ if (!startTimes.has(id)) {
22
+ startTimes.set(id, []);
23
+ }
24
+ (_startTimes$get = startTimes.get(id)) === null || _startTimes$get === void 0 || _startTimes$get.push(performance.now());
25
+ };
26
+ var isInSSR = Boolean(globalThis === null || globalThis === void 0 ? void 0 : globalThis.__SERVER__) || typeof process !== 'undefined' && Boolean(((_process = process) === null || _process === void 0 || (_process = _process.env) === null || _process === void 0 ? void 0 : _process.REACT_SSR) || false);
27
+ var ProfilerMarker = function ProfilerMarker(_ref) {
28
+ var onRender = _ref.onRender;
29
+ if (isInSSR) {
30
+ onRender === null || onRender === void 0 || onRender();
31
+ }
32
+ return null;
33
+ };
34
+ export var SsrRenderProfilerInner = function SsrRenderProfilerInner(_ref2) {
35
+ var children = _ref2.children,
36
+ labelStack = _ref2.labelStack,
37
+ _onRender = _ref2.onRender;
38
+ var reactProfilerId = useMemo(function () {
39
+ return labelStack.map(function (l) {
40
+ return l.name;
41
+ }).join('/');
42
+ }, [labelStack]);
43
+ checkActiveInteractionAndResetStartMarksIfSet();
44
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ProfilerMarker, {
45
+ onRender: function onRender() {
46
+ return onStartRender(reactProfilerId);
47
+ }
48
+ }), children, /*#__PURE__*/React.createElement(ProfilerMarker, {
49
+ onRender: function onRender() {
50
+ var startTimesForId = startTimes.get(reactProfilerId);
51
+ if (startTimesForId !== null && startTimesForId !== void 0 && startTimesForId.length) {
52
+ var endTime = performance.now();
53
+ var firstStartTime = startTimesForId[0];
54
+ var lastStartTime = startTimesForId[startTimesForId.length - 1];
55
+ var baseDuration = endTime - lastStartTime;
56
+ var actualDuration = endTime - firstStartTime;
57
+ _onRender('mount',
58
+ // this is incorrect, but on the server there is no mount phase
59
+ actualDuration, baseDuration, firstStartTime, endTime);
60
+ }
61
+ }
62
+ }));
63
+ };
64
+ var SsrRenderProfiler = function SsrRenderProfiler(props) {
65
+ if (isInSSR) {
66
+ return /*#__PURE__*/React.createElement(SsrRenderProfilerInner, props);
67
+ }
68
+
69
+ // ensure structure similar to SSR implementation
70
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ProfilerMarker, null), props.children);
71
+ };
72
+ export default SsrRenderProfiler;
@@ -0,0 +1,9 @@
1
+ import React, { type ReactNode } from 'react';
2
+ import type { EnhancedUFOInteractionContextType, ReactProfilerTiming } from '../common';
3
+ export declare const SsrRenderProfilerInner: ({ children, labelStack, onRender, }: {
4
+ children?: ReactNode | undefined;
5
+ labelStack: ReactProfilerTiming["labelStack"];
6
+ onRender: EnhancedUFOInteractionContextType["onRender"];
7
+ }) => React.JSX.Element;
8
+ declare const SsrRenderProfiler: (props: Parameters<typeof SsrRenderProfilerInner>[0]) => React.JSX.Element;
9
+ export default SsrRenderProfiler;
@@ -0,0 +1,9 @@
1
+ import React, { type ReactNode } from 'react';
2
+ import type { EnhancedUFOInteractionContextType, ReactProfilerTiming } from '../common';
3
+ export declare const SsrRenderProfilerInner: ({ children, labelStack, onRender, }: {
4
+ children?: ReactNode | undefined;
5
+ labelStack: ReactProfilerTiming["labelStack"];
6
+ onRender: EnhancedUFOInteractionContextType["onRender"];
7
+ }) => React.JSX.Element;
8
+ declare const SsrRenderProfiler: (props: Parameters<typeof SsrRenderProfilerInner>[0]) => React.JSX.Element;
9
+ export default SsrRenderProfiler;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/react-ufo",
3
- "version": "4.15.3",
3
+ "version": "4.15.4",
4
4
  "description": "Parts of React UFO that are publicly available",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -149,6 +149,9 @@
149
149
  "platform_editor_exclude_dnd_anchor_name_from_ttvc": {
150
150
  "type": "boolean"
151
151
  },
152
+ "platform_ufo_ssr_render_profiler": {
153
+ "type": "boolean"
154
+ },
152
155
  "platform_ufo_enable_finish_interaction_transition": {
153
156
  "type": "boolean"
154
157
  },