@atlaskit/react-ufo 4.16.6 → 4.16.8

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,19 @@
1
1
  # @atlaskit/ufo-interaction-ignore
2
2
 
3
+ ## 4.16.8
4
+
5
+ ### Patch Changes
6
+
7
+ - [`4272868869ef8`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/4272868869ef8) -
8
+ Updated threshold for observations and keep SSR entry
9
+
10
+ ## 4.16.7
11
+
12
+ ### Patch Changes
13
+
14
+ - [`b59c796cf683e`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/b59c796cf683e) -
15
+ Aborting post-interaction logs also when original event is already finished
16
+
3
17
  ## 4.16.6
4
18
 
5
19
  ### Patch Changes
@@ -61,6 +61,7 @@ var _utils = require("../create-payload/common/utils");
61
61
  var _experienceTraceIdContext = require("../experience-trace-id-context");
62
62
  var _featureFlagsAccessed = require("../feature-flags-accessed");
63
63
  var _interactionIdContext = require("../interaction-id-context");
64
+ var _ssrRenderProfiler = require("../segment/ssr-render-profiler");
64
65
  var _vc = require("../vc");
65
66
  var _constants = require("./common/constants");
66
67
  var _interactionExtraMetrics = _interopRequireDefault(require("./interaction-extra-metrics"));
@@ -717,6 +718,7 @@ function finishInteraction(id, data) {
717
718
  }
718
719
  (0, _experienceTraceIdContext.clearActiveTrace)();
719
720
  callCleanUpCallbacks(data);
721
+ (0, _ssrRenderProfiler.flushSsrRenderProfilerTraces)();
720
722
  if ((_getConfig4 = (0, _config.getConfig)()) !== null && _getConfig4 !== void 0 && (_getConfig4 = _getConfig4.vc) !== null && _getConfig4 !== void 0 && _getConfig4.stopVCAtInteractionFinish) {
721
723
  // Use per-interaction VC observer if available, otherwise fall back to global
722
724
  var observer = data.vcObserver;
@@ -1084,6 +1086,12 @@ function abortByNewInteraction(interactionId, interactionName) {
1084
1086
  (0, _createExperimentalInteractionMetricsPayload.onExperimentalInteractionComplete)(interactionId, interaction);
1085
1087
  remove(interactionId);
1086
1088
  }
1089
+ } else {
1090
+ if ((0, _platformFeatureFlags.fg)('platform_reset_post_interaction_on_new_interaction')) {
1091
+ // post-interaction log is active after interaction is aborted by new one
1092
+ postInteractionLog.reset();
1093
+ postInteractionLog.stopVCObserver();
1094
+ }
1087
1095
  }
1088
1096
  }
1089
1097
  function abortAll(abortReason, abortedByInteractionName) {
@@ -10,7 +10,6 @@ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/
10
10
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
11
11
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
12
12
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
13
- var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
14
13
  var _config = require("../config");
15
14
  var _hiddenTiming = require("../hidden-timing");
16
15
  var _vc = require("../vc");
@@ -129,7 +128,7 @@ var PostInteractionLog = exports.default = /*#__PURE__*/function () {
129
128
  return _regenerator.default.wrap(function _callee$(_context) {
130
129
  while (1) switch (_context.prev = _context.next) {
131
130
  case 0:
132
- if (!(!this.lastInteractionFinish || !this.sinkHandlerFn || !this.hasData() && !(0, _platformFeatureFlags.fg)('platform_ufo_always_send_post_interaction_log'))) {
131
+ if (!(!this.lastInteractionFinish || !this.sinkHandlerFn)) {
133
132
  _context.next = 4;
134
133
  break;
135
134
  }
@@ -11,6 +11,13 @@ Object.defineProperty(exports, "UFOThirdPartySegment", {
11
11
  }
12
12
  });
13
13
  exports.default = void 0;
14
+ Object.defineProperty(exports, "flushSsrRenderProfilerTraces", {
15
+ enumerable: true,
16
+ get: function get() {
17
+ return _ssrRenderProfiler.flushSsrRenderProfilerTraces;
18
+ }
19
+ });
14
20
  var _segment = _interopRequireDefault(require("./segment"));
15
21
  var _thirdPartySegment = require("./third-party-segment");
22
+ var _ssrRenderProfiler = require("./ssr-render-profiler");
16
23
  var _default = exports.default = _segment.default;
@@ -4,14 +4,20 @@ var _typeof = require("@babel/runtime/helpers/typeof");
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.default = exports.SsrRenderProfilerInner = void 0;
7
+ exports.flushSsrRenderProfilerTraces = exports.default = exports.clearState = exports.SsrRenderProfilerInner = void 0;
8
8
  var _react = _interopRequireWildcard(require("react"));
9
+ var _config = require("../config");
9
10
  var _interactionMetrics = require("../interaction-metrics");
10
11
  var _process;
11
12
  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
13
  // These are stored outside react context to be resilient to concurrent mode
13
14
  // restarting the start marker from a suspense and losing the initial render
14
15
  var startTimes = new Map();
16
+ var spanStates = new Map();
17
+ var clearState = exports.clearState = function clearState() {
18
+ startTimes.clear();
19
+ spanStates.clear();
20
+ };
15
21
  // Keep track of the last interaction id and reset the start timers if it ever changes.
16
22
  // This is to allow multi-step ssr to track the render timers from different "interaction"s seperately
17
23
  var lastActiveInteraction;
@@ -19,26 +25,55 @@ function checkActiveInteractionAndResetStartMarksIfSet() {
19
25
  var _getActiveInteraction;
20
26
  var activeInteractionId = (_getActiveInteraction = (0, _interactionMetrics.getActiveInteraction)()) === null || _getActiveInteraction === void 0 ? void 0 : _getActiveInteraction.id;
21
27
  if (!!lastActiveInteraction && lastActiveInteraction !== activeInteractionId) {
22
- startTimes.clear();
28
+ clearState();
23
29
  }
24
30
  lastActiveInteraction = activeInteractionId;
25
31
  }
26
- var onStartRender = function onStartRender(id) {
27
- var _startTimes$get;
32
+ var getIsNativeTracingEnabled = function getIsNativeTracingEnabled() {
33
+ var _getConfig$ssr$enable, _getConfig;
34
+ return (_getConfig$ssr$enable = (_getConfig = (0, _config.getConfig)()) === null || _getConfig === void 0 || (_getConfig = _getConfig.ssr) === null || _getConfig === void 0 ? void 0 : _getConfig.enableNativeTracing) !== null && _getConfig$ssr$enable !== void 0 ? _getConfig$ssr$enable : false;
35
+ };
36
+ var onStartRender = function onStartRender(id, currentSegmentName, parentContext) {
37
+ var _startTimes$get, _vm_internals__, _spanStates$get;
28
38
  if (!startTimes.has(id)) {
29
39
  startTimes.set(id, []);
30
40
  }
31
41
  (_startTimes$get = startTimes.get(id)) === null || _startTimes$get === void 0 || _startTimes$get.push(performance.now());
42
+ if (!getIsNativeTracingEnabled()) {
43
+ return null;
44
+ }
45
+ var startSpan = (_vm_internals__ = globalThis.__vm_internals__) === null || _vm_internals__ === void 0 || (_vm_internals__ = _vm_internals__.telemetry) === null || _vm_internals__ === void 0 ? void 0 : _vm_internals__.startSpan;
46
+ var spanState = (_spanStates$get = spanStates.get(id)) !== null && _spanStates$get !== void 0 ? _spanStates$get : null;
47
+ if (!spanState && startSpan) {
48
+ var span = startSpan(currentSegmentName, {
49
+ parentSpanId: parentContext === null || parentContext === void 0 ? void 0 : parentContext.spanId
50
+ });
51
+ spanState = {
52
+ span: span
53
+ };
54
+ spanStates.set(id, spanState);
55
+ }
56
+ return spanState;
32
57
  };
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);
58
+ var isInSSR = typeof __SERVER__ !== 'undefined' && __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
59
  var ProfilerMarker = function ProfilerMarker(_ref) {
35
60
  var onRender = _ref.onRender;
36
- if (isInSSR) {
37
- onRender === null || onRender === void 0 || onRender();
38
- }
61
+ onRender === null || onRender === void 0 || onRender();
39
62
  return null;
40
63
  };
64
+ var ParentSpanContext = /*#__PURE__*/(0, _react.createContext)(null);
65
+
66
+ // For profiler spans in SSR, we 'end' any with their latest end times set, we need to do this at UFO-interaction-end since until then the component could rerender/remount again and spans fundamentally don't use the last 'end' but the first
67
+ var flushSsrRenderProfilerTraces = exports.flushSsrRenderProfilerTraces = function flushSsrRenderProfilerTraces() {
68
+ spanStates.forEach(function (spanState) {
69
+ if (spanState.latestEndTime != null) {
70
+ spanState.span.end(spanState.latestEndTime);
71
+ }
72
+ });
73
+ spanStates.clear();
74
+ };
41
75
  var SsrRenderProfilerInner = exports.SsrRenderProfilerInner = function SsrRenderProfilerInner(_ref2) {
76
+ var _currentSpanState$spa;
42
77
  var children = _ref2.children,
43
78
  labelStack = _ref2.labelStack,
44
79
  _onRender = _ref2.onRender;
@@ -48,25 +83,29 @@ var SsrRenderProfilerInner = exports.SsrRenderProfilerInner = function SsrRender
48
83
  }).join('/');
49
84
  }, [labelStack]);
50
85
  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, {
86
+ var parentSpan = (0, _react.useContext)(ParentSpanContext);
87
+ var currentSpanState = onStartRender(reactProfilerId, labelStack[labelStack.length - 1].name, parentSpan);
88
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(ParentSpanContext.Provider, {
89
+ value: (_currentSpanState$spa = currentSpanState === null || currentSpanState === void 0 ? void 0 : currentSpanState.span.getSpanContext()) !== null && _currentSpanState$spa !== void 0 ? _currentSpanState$spa : null
90
+ }, children, /*#__PURE__*/_react.default.createElement(ProfilerMarker, {
56
91
  onRender: function onRender() {
57
92
  var startTimesForId = startTimes.get(reactProfilerId);
58
93
  if (startTimesForId !== null && startTimesForId !== void 0 && startTimesForId.length) {
59
- var endTime = performance.now();
94
+ var _endTime = performance.now();
60
95
  var firstStartTime = startTimesForId[0];
61
96
  var lastStartTime = startTimesForId[startTimesForId.length - 1];
62
- var baseDuration = endTime - lastStartTime;
63
- var actualDuration = endTime - firstStartTime;
97
+ var baseDuration = _endTime - lastStartTime;
98
+ var actualDuration = _endTime - firstStartTime;
64
99
  _onRender('mount',
65
100
  // this is incorrect, but on the server there is no mount phase
66
- actualDuration, baseDuration, firstStartTime, endTime);
101
+ actualDuration, baseDuration, firstStartTime, _endTime);
102
+ }
103
+ var spanState = spanStates.get(reactProfilerId);
104
+ if (spanState) {
105
+ spanState.latestEndTime = performance.now();
67
106
  }
68
107
  }
69
- }));
108
+ })));
70
109
  };
71
110
  var SsrRenderProfiler = function SsrRenderProfiler(props) {
72
111
  if (isInSSR) {
@@ -19,7 +19,7 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
19
19
  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; }
20
20
  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; }
21
21
  var ABORTING_WINDOW_EVENT = ['wheel', 'scroll', 'keydown', 'resize'];
22
- var MAX_OBSERVATIONS = 100;
22
+ var MAX_OBSERVATIONS = 200;
23
23
  function isWindowEventEntryData(data) {
24
24
  return data.type === 'window:event' && 'eventType' in data;
25
25
  }
@@ -59,7 +59,7 @@ var RawDataHandler = exports.default = /*#__PURE__*/function () {
59
59
  key: "getRawData",
60
60
  value: function () {
61
61
  var _getRawData = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref) {
62
- var entries, startTime, stopTime, isPageVisible, isVCClean, dirtyReason, getVCCleanStatusResult, viewportEntries, windowEventEntries, targetNameToIdMap, elementMapEntriesMap, nextElementId, typeMap, typeMapEntriesMap, nextTypeId, attributeMap, attributeEntriesMap, nextAttributeId, eventTypeMap, eventTypeMapEntriesMap, nextEventTypeId, rawObservations, rawEventObservations, firstObservation, lastObservations, referencedEids, referencedChgs, referencedAtts, _iterator, _step, observation, _iterator2, _step2, eid, _iterator3, _step3, chg, _iterator4, _step4, att, firstEventObservation, lastEventObservations, referencedEvts, _iterator5, _step5, _observation, _iterator6, _step6, evt, result;
62
+ var entries, startTime, stopTime, isPageVisible, isVCClean, dirtyReason, getVCCleanStatusResult, viewportEntries, windowEventEntries, targetNameToIdMap, elementMapEntriesMap, nextElementId, typeMap, typeMapEntriesMap, nextTypeId, attributeMap, attributeEntriesMap, nextAttributeId, eventTypeMap, eventTypeMapEntriesMap, nextEventTypeId, rawObservations, rawEventObservations, firstObservation, lastObservations, ssrEid, ssrObservation, ssrAlreadyIncluded, referencedEids, referencedChgs, referencedAtts, _iterator, _step, observation, _iterator2, _step2, eid, _iterator3, _step3, chg, _iterator4, _step4, att, firstEventObservation, lastEventObservations, referencedEvts, _iterator5, _step5, _observation, _iterator6, _step6, evt, result;
63
63
  return _regenerator.default.wrap(function _callee$(_context) {
64
64
  while (1) switch (_context.prev = _context.next) {
65
65
  case 0:
@@ -157,12 +157,19 @@ var RawDataHandler = exports.default = /*#__PURE__*/function () {
157
157
  };
158
158
  return eventObservation;
159
159
  }); // If the number of observations is greater than the maximum allowed, we need to trim the observations to the maximum allowed.
160
- // We do this by keeping the first observation and the last MAX_OBSERVATIONS observations.
160
+ // We do this by keeping the first observation, the SSR observation (if present), and the last MAX_OBSERVATIONS observations.
161
161
  // We then collect the referenced IDs from the remaining observations and remove the unreferenced entries from the maps
162
162
  if (rawObservations.length > MAX_OBSERVATIONS) {
163
163
  firstObservation = rawObservations[0];
164
- lastObservations = rawObservations.slice(-MAX_OBSERVATIONS);
165
- rawObservations = [firstObservation].concat((0, _toConsumableArray2.default)(lastObservations));
164
+ lastObservations = rawObservations.slice(-MAX_OBSERVATIONS); // Find the SSR observation by looking up the eid that corresponds to 'SSR' element name
165
+ ssrEid = targetNameToIdMap.get('SSR');
166
+ ssrObservation = ssrEid ? rawObservations.find(function (obs) {
167
+ return obs.eid === ssrEid && obs !== firstObservation;
168
+ }) : undefined; // Include SSR observation if it exists and is not already in the kept observations
169
+ ssrAlreadyIncluded = ssrObservation && lastObservations.some(function (obs) {
170
+ return obs === ssrObservation;
171
+ });
172
+ rawObservations = [firstObservation].concat((0, _toConsumableArray2.default)(ssrObservation && !ssrAlreadyIncluded ? [ssrObservation] : []), (0, _toConsumableArray2.default)(lastObservations));
166
173
 
167
174
  // Collect referenced IDs from remaining observations
168
175
  referencedEids = new Set();
@@ -9,6 +9,7 @@ import { sanitizeUfoName, stringifyLabelStackFully } from '../create-payload/com
9
9
  import { clearActiveTrace } from '../experience-trace-id-context';
10
10
  import { allFeatureFlagsAccessed, currentFeatureFlagsAccessed } from '../feature-flags-accessed';
11
11
  import { getInteractionId } from '../interaction-id-context';
12
+ import { flushSsrRenderProfilerTraces } from '../segment/ssr-render-profiler';
12
13
  import { newVCObserver } from '../vc';
13
14
  import { interactions } from './common/constants';
14
15
  import InteractionExtraMetrics from './interaction-extra-metrics';
@@ -633,6 +634,7 @@ function finishInteraction(id, data, endTime = performance.now()) {
633
634
  }
634
635
  clearActiveTrace();
635
636
  callCleanUpCallbacks(data);
637
+ flushSsrRenderProfilerTraces();
636
638
  if ((_getConfig4 = getConfig()) !== null && _getConfig4 !== void 0 && (_getConfig4$vc = _getConfig4.vc) !== null && _getConfig4$vc !== void 0 && _getConfig4$vc.stopVCAtInteractionFinish) {
637
639
  // Use per-interaction VC observer if available, otherwise fall back to global
638
640
  const observer = data.vcObserver;
@@ -963,6 +965,12 @@ export function abortByNewInteraction(interactionId, interactionName) {
963
965
  onExperimentalInteractionComplete(interactionId, interaction);
964
966
  remove(interactionId);
965
967
  }
968
+ } else {
969
+ if (fg('platform_reset_post_interaction_on_new_interaction')) {
970
+ // post-interaction log is active after interaction is aborted by new one
971
+ postInteractionLog.reset();
972
+ postInteractionLog.stopVCObserver();
973
+ }
966
974
  }
967
975
  }
968
976
  export function abortAll(abortReason, abortedByInteractionName) {
@@ -1,5 +1,4 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
- import { fg } from '@atlaskit/platform-feature-flags';
3
2
  import { getConfig } from '../config';
4
3
  import { getPageVisibilityState } from '../hidden-timing';
5
4
  import { VCObserverWrapper } from '../vc';
@@ -93,7 +92,7 @@ export default class PostInteractionLog {
93
92
  */
94
93
  async sendPostInteractionLog() {
95
94
  var _this$vcObserver4, _config$vc, _config$vc2, _this$vcObserver5;
96
- if (!this.lastInteractionFinish || !this.sinkHandlerFn || !this.hasData() && !fg('platform_ufo_always_send_post_interaction_log')) {
95
+ if (!this.lastInteractionFinish || !this.sinkHandlerFn) {
97
96
  var _this$vcObserver3;
98
97
  this.reset();
99
98
  (_this$vcObserver3 = this.vcObserver) === null || _this$vcObserver3 === void 0 ? void 0 : _this$vcObserver3.stop();
@@ -1,3 +1,4 @@
1
1
  import UFOSegment from './segment';
2
2
  export default UFOSegment;
3
- export { UFOThirdPartySegment } from './third-party-segment';
3
+ export { UFOThirdPartySegment } from './third-party-segment';
4
+ export { flushSsrRenderProfilerTraces } from './ssr-render-profiler';
@@ -1,10 +1,15 @@
1
1
  var _process, _process$env;
2
- import React, { useMemo } from 'react';
2
+ import React, { createContext, useContext, useMemo } from 'react';
3
+ import { getConfig } from '../config';
3
4
  import { getActiveInteraction } from '../interaction-metrics';
4
-
5
5
  // These are stored outside react context to be resilient to concurrent mode
6
6
  // restarting the start marker from a suspense and losing the initial render
7
7
  const startTimes = new Map();
8
+ const spanStates = new Map();
9
+ export const clearState = () => {
10
+ startTimes.clear();
11
+ spanStates.clear();
12
+ };
8
13
  // Keep track of the last interaction id and reset the start timers if it ever changes.
9
14
  // This is to allow multi-step ssr to track the render timers from different "interaction"s seperately
10
15
  let lastActiveInteraction;
@@ -12,36 +17,67 @@ function checkActiveInteractionAndResetStartMarksIfSet() {
12
17
  var _getActiveInteraction;
13
18
  const activeInteractionId = (_getActiveInteraction = getActiveInteraction()) === null || _getActiveInteraction === void 0 ? void 0 : _getActiveInteraction.id;
14
19
  if (!!lastActiveInteraction && lastActiveInteraction !== activeInteractionId) {
15
- startTimes.clear();
20
+ clearState();
16
21
  }
17
22
  lastActiveInteraction = activeInteractionId;
18
23
  }
19
- const onStartRender = id => {
20
- var _startTimes$get;
24
+ const getIsNativeTracingEnabled = () => {
25
+ var _getConfig$ssr$enable, _getConfig, _getConfig$ssr;
26
+ return (_getConfig$ssr$enable = (_getConfig = getConfig()) === null || _getConfig === void 0 ? void 0 : (_getConfig$ssr = _getConfig.ssr) === null || _getConfig$ssr === void 0 ? void 0 : _getConfig$ssr.enableNativeTracing) !== null && _getConfig$ssr$enable !== void 0 ? _getConfig$ssr$enable : false;
27
+ };
28
+ const onStartRender = (id, currentSegmentName, parentContext) => {
29
+ var _startTimes$get, _vm_internals__, _vm_internals__$telem, _spanStates$get;
21
30
  if (!startTimes.has(id)) {
22
31
  startTimes.set(id, []);
23
32
  }
24
33
  (_startTimes$get = startTimes.get(id)) === null || _startTimes$get === void 0 ? void 0 : _startTimes$get.push(performance.now());
34
+ if (!getIsNativeTracingEnabled()) {
35
+ return null;
36
+ }
37
+ const startSpan = (_vm_internals__ = globalThis.__vm_internals__) === null || _vm_internals__ === void 0 ? void 0 : (_vm_internals__$telem = _vm_internals__.telemetry) === null || _vm_internals__$telem === void 0 ? void 0 : _vm_internals__$telem.startSpan;
38
+ let spanState = (_spanStates$get = spanStates.get(id)) !== null && _spanStates$get !== void 0 ? _spanStates$get : null;
39
+ if (!spanState && startSpan) {
40
+ const span = startSpan(currentSegmentName, {
41
+ parentSpanId: parentContext === null || parentContext === void 0 ? void 0 : parentContext.spanId
42
+ });
43
+ spanState = {
44
+ span
45
+ };
46
+ spanStates.set(id, spanState);
47
+ }
48
+ return spanState;
25
49
  };
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);
50
+ const isInSSR = typeof __SERVER__ !== 'undefined' && __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
51
  const ProfilerMarker = ({
28
52
  onRender
29
53
  }) => {
30
- if (isInSSR) {
31
- onRender === null || onRender === void 0 ? void 0 : onRender();
32
- }
54
+ onRender === null || onRender === void 0 ? void 0 : onRender();
33
55
  return null;
34
56
  };
57
+ const ParentSpanContext = /*#__PURE__*/createContext(null);
58
+
59
+ // For profiler spans in SSR, we 'end' any with their latest end times set, we need to do this at UFO-interaction-end since until then the component could rerender/remount again and spans fundamentally don't use the last 'end' but the first
60
+ export const flushSsrRenderProfilerTraces = () => {
61
+ spanStates.forEach(spanState => {
62
+ if (spanState.latestEndTime != null) {
63
+ spanState.span.end(spanState.latestEndTime);
64
+ }
65
+ });
66
+ spanStates.clear();
67
+ };
35
68
  export const SsrRenderProfilerInner = ({
36
69
  children,
37
70
  labelStack,
38
71
  onRender
39
72
  }) => {
73
+ var _currentSpanState$spa;
40
74
  const reactProfilerId = useMemo(() => labelStack.map(l => l.name).join('/'), [labelStack]);
41
75
  checkActiveInteractionAndResetStartMarksIfSet();
42
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ProfilerMarker, {
43
- onRender: () => onStartRender(reactProfilerId)
44
- }), children, /*#__PURE__*/React.createElement(ProfilerMarker, {
76
+ const parentSpan = useContext(ParentSpanContext);
77
+ const currentSpanState = onStartRender(reactProfilerId, labelStack[labelStack.length - 1].name, parentSpan);
78
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ParentSpanContext.Provider, {
79
+ value: (_currentSpanState$spa = currentSpanState === null || currentSpanState === void 0 ? void 0 : currentSpanState.span.getSpanContext()) !== null && _currentSpanState$spa !== void 0 ? _currentSpanState$spa : null
80
+ }, children, /*#__PURE__*/React.createElement(ProfilerMarker, {
45
81
  onRender: () => {
46
82
  const startTimesForId = startTimes.get(reactProfilerId);
47
83
  if (startTimesForId !== null && startTimesForId !== void 0 && startTimesForId.length) {
@@ -54,8 +90,12 @@ export const SsrRenderProfilerInner = ({
54
90
  // this is incorrect, but on the server there is no mount phase
55
91
  actualDuration, baseDuration, firstStartTime, endTime);
56
92
  }
93
+ const spanState = spanStates.get(reactProfilerId);
94
+ if (spanState) {
95
+ spanState.latestEndTime = performance.now();
96
+ }
57
97
  }
58
- }));
98
+ })));
59
99
  };
60
100
  const SsrRenderProfiler = props => {
61
101
  if (isInSSR) {
@@ -2,7 +2,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import getViewportHeight from '../metric-calculator/utils/get-viewport-height';
3
3
  import getViewportWidth from '../metric-calculator/utils/get-viewport-width';
4
4
  const ABORTING_WINDOW_EVENT = ['wheel', 'scroll', 'keydown', 'resize'];
5
- const MAX_OBSERVATIONS = 100;
5
+ const MAX_OBSERVATIONS = 200;
6
6
  function isWindowEventEntryData(data) {
7
7
  return data.type === 'window:event' && 'eventType' in data;
8
8
  }
@@ -137,12 +137,19 @@ export default class RawDataHandler {
137
137
  });
138
138
 
139
139
  // If the number of observations is greater than the maximum allowed, we need to trim the observations to the maximum allowed.
140
- // We do this by keeping the first observation and the last MAX_OBSERVATIONS observations.
140
+ // We do this by keeping the first observation, the SSR observation (if present), and the last MAX_OBSERVATIONS observations.
141
141
  // We then collect the referenced IDs from the remaining observations and remove the unreferenced entries from the maps
142
142
  if (rawObservations.length > MAX_OBSERVATIONS) {
143
143
  const firstObservation = rawObservations[0];
144
144
  const lastObservations = rawObservations.slice(-MAX_OBSERVATIONS);
145
- rawObservations = [firstObservation, ...lastObservations];
145
+
146
+ // Find the SSR observation by looking up the eid that corresponds to 'SSR' element name
147
+ const ssrEid = targetNameToIdMap.get('SSR');
148
+ const ssrObservation = ssrEid ? rawObservations.find(obs => obs.eid === ssrEid && obs !== firstObservation) : undefined;
149
+
150
+ // Include SSR observation if it exists and is not already in the kept observations
151
+ const ssrAlreadyIncluded = ssrObservation && lastObservations.some(obs => obs === ssrObservation);
152
+ rawObservations = [firstObservation, ...(ssrObservation && !ssrAlreadyIncluded ? [ssrObservation] : []), ...lastObservations];
146
153
 
147
154
  // Collect referenced IDs from remaining observations
148
155
  const referencedEids = new Set();
@@ -19,6 +19,7 @@ import { sanitizeUfoName, stringifyLabelStackFully } from '../create-payload/com
19
19
  import { clearActiveTrace } from '../experience-trace-id-context';
20
20
  import { allFeatureFlagsAccessed, currentFeatureFlagsAccessed } from '../feature-flags-accessed';
21
21
  import { getInteractionId } from '../interaction-id-context';
22
+ import { flushSsrRenderProfilerTraces } from '../segment/ssr-render-profiler';
22
23
  import { newVCObserver } from '../vc';
23
24
  import { interactions } from './common/constants';
24
25
  import InteractionExtraMetrics from './interaction-extra-metrics';
@@ -670,6 +671,7 @@ function finishInteraction(id, data) {
670
671
  }
671
672
  clearActiveTrace();
672
673
  callCleanUpCallbacks(data);
674
+ flushSsrRenderProfilerTraces();
673
675
  if ((_getConfig4 = getConfig()) !== null && _getConfig4 !== void 0 && (_getConfig4 = _getConfig4.vc) !== null && _getConfig4 !== void 0 && _getConfig4.stopVCAtInteractionFinish) {
674
676
  // Use per-interaction VC observer if available, otherwise fall back to global
675
677
  var observer = data.vcObserver;
@@ -1037,6 +1039,12 @@ export function abortByNewInteraction(interactionId, interactionName) {
1037
1039
  onExperimentalInteractionComplete(interactionId, interaction);
1038
1040
  remove(interactionId);
1039
1041
  }
1042
+ } else {
1043
+ if (fg('platform_reset_post_interaction_on_new_interaction')) {
1044
+ // post-interaction log is active after interaction is aborted by new one
1045
+ postInteractionLog.reset();
1046
+ postInteractionLog.stopVCObserver();
1047
+ }
1040
1048
  }
1041
1049
  }
1042
1050
  export function abortAll(abortReason, abortedByInteractionName) {
@@ -5,7 +5,6 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
5
5
  import _regeneratorRuntime from "@babel/runtime/regenerator";
6
6
  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; }
7
7
  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; }
8
- import { fg } from '@atlaskit/platform-feature-flags';
9
8
  import { getConfig } from '../config';
10
9
  import { getPageVisibilityState } from '../hidden-timing';
11
10
  import { VCObserverWrapper } from '../vc';
@@ -122,7 +121,7 @@ var PostInteractionLog = /*#__PURE__*/function () {
122
121
  return _regeneratorRuntime.wrap(function _callee$(_context) {
123
122
  while (1) switch (_context.prev = _context.next) {
124
123
  case 0:
125
- if (!(!this.lastInteractionFinish || !this.sinkHandlerFn || !this.hasData() && !fg('platform_ufo_always_send_post_interaction_log'))) {
124
+ if (!(!this.lastInteractionFinish || !this.sinkHandlerFn)) {
126
125
  _context.next = 4;
127
126
  break;
128
127
  }
@@ -1,3 +1,4 @@
1
1
  import UFOSegment from './segment';
2
2
  export default UFOSegment;
3
- export { UFOThirdPartySegment } from './third-party-segment';
3
+ export { UFOThirdPartySegment } from './third-party-segment';
4
+ export { flushSsrRenderProfilerTraces } from './ssr-render-profiler';
@@ -1,10 +1,15 @@
1
1
  var _process;
2
- import React, { useMemo } from 'react';
2
+ import React, { createContext, useContext, useMemo } from 'react';
3
+ import { getConfig } from '../config';
3
4
  import { getActiveInteraction } from '../interaction-metrics';
4
-
5
5
  // These are stored outside react context to be resilient to concurrent mode
6
6
  // restarting the start marker from a suspense and losing the initial render
7
7
  var startTimes = new Map();
8
+ var spanStates = new Map();
9
+ export var clearState = function clearState() {
10
+ startTimes.clear();
11
+ spanStates.clear();
12
+ };
8
13
  // Keep track of the last interaction id and reset the start timers if it ever changes.
9
14
  // This is to allow multi-step ssr to track the render timers from different "interaction"s seperately
10
15
  var lastActiveInteraction;
@@ -12,26 +17,55 @@ function checkActiveInteractionAndResetStartMarksIfSet() {
12
17
  var _getActiveInteraction;
13
18
  var activeInteractionId = (_getActiveInteraction = getActiveInteraction()) === null || _getActiveInteraction === void 0 ? void 0 : _getActiveInteraction.id;
14
19
  if (!!lastActiveInteraction && lastActiveInteraction !== activeInteractionId) {
15
- startTimes.clear();
20
+ clearState();
16
21
  }
17
22
  lastActiveInteraction = activeInteractionId;
18
23
  }
19
- var onStartRender = function onStartRender(id) {
20
- var _startTimes$get;
24
+ var getIsNativeTracingEnabled = function getIsNativeTracingEnabled() {
25
+ var _getConfig$ssr$enable, _getConfig;
26
+ return (_getConfig$ssr$enable = (_getConfig = getConfig()) === null || _getConfig === void 0 || (_getConfig = _getConfig.ssr) === null || _getConfig === void 0 ? void 0 : _getConfig.enableNativeTracing) !== null && _getConfig$ssr$enable !== void 0 ? _getConfig$ssr$enable : false;
27
+ };
28
+ var onStartRender = function onStartRender(id, currentSegmentName, parentContext) {
29
+ var _startTimes$get, _vm_internals__, _spanStates$get;
21
30
  if (!startTimes.has(id)) {
22
31
  startTimes.set(id, []);
23
32
  }
24
33
  (_startTimes$get = startTimes.get(id)) === null || _startTimes$get === void 0 || _startTimes$get.push(performance.now());
34
+ if (!getIsNativeTracingEnabled()) {
35
+ return null;
36
+ }
37
+ var startSpan = (_vm_internals__ = globalThis.__vm_internals__) === null || _vm_internals__ === void 0 || (_vm_internals__ = _vm_internals__.telemetry) === null || _vm_internals__ === void 0 ? void 0 : _vm_internals__.startSpan;
38
+ var spanState = (_spanStates$get = spanStates.get(id)) !== null && _spanStates$get !== void 0 ? _spanStates$get : null;
39
+ if (!spanState && startSpan) {
40
+ var span = startSpan(currentSegmentName, {
41
+ parentSpanId: parentContext === null || parentContext === void 0 ? void 0 : parentContext.spanId
42
+ });
43
+ spanState = {
44
+ span: span
45
+ };
46
+ spanStates.set(id, spanState);
47
+ }
48
+ return spanState;
25
49
  };
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);
50
+ var isInSSR = typeof __SERVER__ !== 'undefined' && __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
51
  var ProfilerMarker = function ProfilerMarker(_ref) {
28
52
  var onRender = _ref.onRender;
29
- if (isInSSR) {
30
- onRender === null || onRender === void 0 || onRender();
31
- }
53
+ onRender === null || onRender === void 0 || onRender();
32
54
  return null;
33
55
  };
56
+ var ParentSpanContext = /*#__PURE__*/createContext(null);
57
+
58
+ // For profiler spans in SSR, we 'end' any with their latest end times set, we need to do this at UFO-interaction-end since until then the component could rerender/remount again and spans fundamentally don't use the last 'end' but the first
59
+ export var flushSsrRenderProfilerTraces = function flushSsrRenderProfilerTraces() {
60
+ spanStates.forEach(function (spanState) {
61
+ if (spanState.latestEndTime != null) {
62
+ spanState.span.end(spanState.latestEndTime);
63
+ }
64
+ });
65
+ spanStates.clear();
66
+ };
34
67
  export var SsrRenderProfilerInner = function SsrRenderProfilerInner(_ref2) {
68
+ var _currentSpanState$spa;
35
69
  var children = _ref2.children,
36
70
  labelStack = _ref2.labelStack,
37
71
  _onRender = _ref2.onRender;
@@ -41,25 +75,29 @@ export var SsrRenderProfilerInner = function SsrRenderProfilerInner(_ref2) {
41
75
  }).join('/');
42
76
  }, [labelStack]);
43
77
  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, {
78
+ var parentSpan = useContext(ParentSpanContext);
79
+ var currentSpanState = onStartRender(reactProfilerId, labelStack[labelStack.length - 1].name, parentSpan);
80
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ParentSpanContext.Provider, {
81
+ value: (_currentSpanState$spa = currentSpanState === null || currentSpanState === void 0 ? void 0 : currentSpanState.span.getSpanContext()) !== null && _currentSpanState$spa !== void 0 ? _currentSpanState$spa : null
82
+ }, children, /*#__PURE__*/React.createElement(ProfilerMarker, {
49
83
  onRender: function onRender() {
50
84
  var startTimesForId = startTimes.get(reactProfilerId);
51
85
  if (startTimesForId !== null && startTimesForId !== void 0 && startTimesForId.length) {
52
- var endTime = performance.now();
86
+ var _endTime = performance.now();
53
87
  var firstStartTime = startTimesForId[0];
54
88
  var lastStartTime = startTimesForId[startTimesForId.length - 1];
55
- var baseDuration = endTime - lastStartTime;
56
- var actualDuration = endTime - firstStartTime;
89
+ var baseDuration = _endTime - lastStartTime;
90
+ var actualDuration = _endTime - firstStartTime;
57
91
  _onRender('mount',
58
92
  // this is incorrect, but on the server there is no mount phase
59
- actualDuration, baseDuration, firstStartTime, endTime);
93
+ actualDuration, baseDuration, firstStartTime, _endTime);
94
+ }
95
+ var spanState = spanStates.get(reactProfilerId);
96
+ if (spanState) {
97
+ spanState.latestEndTime = performance.now();
60
98
  }
61
99
  }
62
- }));
100
+ })));
63
101
  };
64
102
  var SsrRenderProfiler = function SsrRenderProfiler(props) {
65
103
  if (isInSSR) {
@@ -12,7 +12,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
12
12
  import getViewportHeight from '../metric-calculator/utils/get-viewport-height';
13
13
  import getViewportWidth from '../metric-calculator/utils/get-viewport-width';
14
14
  var ABORTING_WINDOW_EVENT = ['wheel', 'scroll', 'keydown', 'resize'];
15
- var MAX_OBSERVATIONS = 100;
15
+ var MAX_OBSERVATIONS = 200;
16
16
  function isWindowEventEntryData(data) {
17
17
  return data.type === 'window:event' && 'eventType' in data;
18
18
  }
@@ -52,7 +52,7 @@ var RawDataHandler = /*#__PURE__*/function () {
52
52
  key: "getRawData",
53
53
  value: function () {
54
54
  var _getRawData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref) {
55
- var entries, startTime, stopTime, isPageVisible, isVCClean, dirtyReason, getVCCleanStatusResult, viewportEntries, windowEventEntries, targetNameToIdMap, elementMapEntriesMap, nextElementId, typeMap, typeMapEntriesMap, nextTypeId, attributeMap, attributeEntriesMap, nextAttributeId, eventTypeMap, eventTypeMapEntriesMap, nextEventTypeId, rawObservations, rawEventObservations, firstObservation, lastObservations, referencedEids, referencedChgs, referencedAtts, _iterator, _step, observation, _iterator2, _step2, eid, _iterator3, _step3, chg, _iterator4, _step4, att, firstEventObservation, lastEventObservations, referencedEvts, _iterator5, _step5, _observation, _iterator6, _step6, evt, result;
55
+ var entries, startTime, stopTime, isPageVisible, isVCClean, dirtyReason, getVCCleanStatusResult, viewportEntries, windowEventEntries, targetNameToIdMap, elementMapEntriesMap, nextElementId, typeMap, typeMapEntriesMap, nextTypeId, attributeMap, attributeEntriesMap, nextAttributeId, eventTypeMap, eventTypeMapEntriesMap, nextEventTypeId, rawObservations, rawEventObservations, firstObservation, lastObservations, ssrEid, ssrObservation, ssrAlreadyIncluded, referencedEids, referencedChgs, referencedAtts, _iterator, _step, observation, _iterator2, _step2, eid, _iterator3, _step3, chg, _iterator4, _step4, att, firstEventObservation, lastEventObservations, referencedEvts, _iterator5, _step5, _observation, _iterator6, _step6, evt, result;
56
56
  return _regeneratorRuntime.wrap(function _callee$(_context) {
57
57
  while (1) switch (_context.prev = _context.next) {
58
58
  case 0:
@@ -150,12 +150,19 @@ var RawDataHandler = /*#__PURE__*/function () {
150
150
  };
151
151
  return eventObservation;
152
152
  }); // If the number of observations is greater than the maximum allowed, we need to trim the observations to the maximum allowed.
153
- // We do this by keeping the first observation and the last MAX_OBSERVATIONS observations.
153
+ // We do this by keeping the first observation, the SSR observation (if present), and the last MAX_OBSERVATIONS observations.
154
154
  // We then collect the referenced IDs from the remaining observations and remove the unreferenced entries from the maps
155
155
  if (rawObservations.length > MAX_OBSERVATIONS) {
156
156
  firstObservation = rawObservations[0];
157
- lastObservations = rawObservations.slice(-MAX_OBSERVATIONS);
158
- rawObservations = [firstObservation].concat(_toConsumableArray(lastObservations));
157
+ lastObservations = rawObservations.slice(-MAX_OBSERVATIONS); // Find the SSR observation by looking up the eid that corresponds to 'SSR' element name
158
+ ssrEid = targetNameToIdMap.get('SSR');
159
+ ssrObservation = ssrEid ? rawObservations.find(function (obs) {
160
+ return obs.eid === ssrEid && obs !== firstObservation;
161
+ }) : undefined; // Include SSR observation if it exists and is not already in the kept observations
162
+ ssrAlreadyIncluded = ssrObservation && lastObservations.some(function (obs) {
163
+ return obs === ssrObservation;
164
+ });
165
+ rawObservations = [firstObservation].concat(_toConsumableArray(ssrObservation && !ssrAlreadyIncluded ? [ssrObservation] : []), _toConsumableArray(lastObservations));
159
166
 
160
167
  // Collect referenced IDs from remaining observations
161
168
  referencedEids = new Set();
@@ -107,6 +107,7 @@ export type Config = {
107
107
  readonly ssr?: {
108
108
  readonly getSSRTimings?: () => SSRTiming[];
109
109
  readonly getSSRDoneTime?: () => number | undefined;
110
+ readonly enableNativeTracing?: boolean;
110
111
  };
111
112
  readonly assetsConfig?: AssetsConfig;
112
113
  readonly enableBetterPageVisibilityApi?: boolean;
@@ -1,3 +1,4 @@
1
1
  import UFOSegment from './segment';
2
2
  export default UFOSegment;
3
3
  export { UFOThirdPartySegment } from './third-party-segment';
4
+ export { flushSsrRenderProfilerTraces } from './ssr-render-profiler';
@@ -1,5 +1,7 @@
1
1
  import React, { type ReactNode } from 'react';
2
2
  import type { EnhancedUFOInteractionContextType, ReactProfilerTiming } from '../common';
3
+ export declare const clearState: () => void;
4
+ export declare const flushSsrRenderProfilerTraces: () => void;
3
5
  export declare const SsrRenderProfilerInner: ({ children, labelStack, onRender, }: {
4
6
  children?: ReactNode | undefined;
5
7
  labelStack: ReactProfilerTiming["labelStack"];
@@ -7,3 +9,53 @@ export declare const SsrRenderProfilerInner: ({ children, labelStack, onRender,
7
9
  }) => React.JSX.Element;
8
10
  declare const SsrRenderProfiler: (props: Parameters<typeof SsrRenderProfilerInner>[0]) => React.JSX.Element;
9
11
  export default SsrRenderProfiler;
12
+ interface SpanContext {
13
+ /** 16-character hex string representing the span ID */
14
+ readonly spanId: string;
15
+ /** 32-character hex string representing the trace ID */
16
+ readonly traceId: string;
17
+ /** Whether this span context is sampled */
18
+ readonly isSampled: boolean;
19
+ /** Whether this span context is from a remote service */
20
+ readonly isRemote: boolean;
21
+ }
22
+ interface SpanOptions {
23
+ /**
24
+ * Optional parent span ID for explicit parent specification.
25
+ * If not provided, the span will use the root span as its parent.
26
+ **/
27
+ parentSpanId?: string;
28
+ /** Optional start time - MUST BE a performance.now() timsestamp */
29
+ startTime?: number;
30
+ /** Optional attributes to set on the span at creation time */
31
+ attributes?: Record<string, string | number | boolean>;
32
+ /** Override the parent's sampled parameter. Generally should only be used to silence noisy spans and their children.
33
+ * Be VERY careful not to cause performance issues if setting to true */
34
+ sampledOverride?: boolean;
35
+ }
36
+ export interface Span {
37
+ /** End the span, optionally with a custom end time in milliseconds since epoch */
38
+ end(endTime?: number): void;
39
+ /** Set an attribute on the span */
40
+ setAttribute(key: string, value: string | number | boolean): void;
41
+ /** Add an event to the span */
42
+ addEvent(name: string): void;
43
+ /** Get the span context containing span ID, trace ID, and flags */
44
+ getSpanContext(): SpanContext | null;
45
+ }
46
+ export type TesseractTelemetryAPI = {
47
+ /**
48
+ * Start a new span with OpenTelemetry-like API
49
+ * Unlike typical openTelemetry, the parent span is not automatically inferred from context.
50
+ * You must explicitly provide a parentSpanId in options if desired.
51
+ * Otherwise, the span will use the root as its parent.
52
+ **/
53
+ startSpan(name: string, options?: SpanOptions): Span;
54
+ forceFlush(): void;
55
+ };
56
+ export type SnapVmInternals = {
57
+ telemetry?: TesseractTelemetryAPI;
58
+ };
59
+ export type GlobalThis = {
60
+ __vm_internals__?: SnapVmInternals;
61
+ };
@@ -107,6 +107,7 @@ export type Config = {
107
107
  readonly ssr?: {
108
108
  readonly getSSRTimings?: () => SSRTiming[];
109
109
  readonly getSSRDoneTime?: () => number | undefined;
110
+ readonly enableNativeTracing?: boolean;
110
111
  };
111
112
  readonly assetsConfig?: AssetsConfig;
112
113
  readonly enableBetterPageVisibilityApi?: boolean;
@@ -1,3 +1,4 @@
1
1
  import UFOSegment from './segment';
2
2
  export default UFOSegment;
3
3
  export { UFOThirdPartySegment } from './third-party-segment';
4
+ export { flushSsrRenderProfilerTraces } from './ssr-render-profiler';
@@ -1,5 +1,7 @@
1
1
  import React, { type ReactNode } from 'react';
2
2
  import type { EnhancedUFOInteractionContextType, ReactProfilerTiming } from '../common';
3
+ export declare const clearState: () => void;
4
+ export declare const flushSsrRenderProfilerTraces: () => void;
3
5
  export declare const SsrRenderProfilerInner: ({ children, labelStack, onRender, }: {
4
6
  children?: ReactNode | undefined;
5
7
  labelStack: ReactProfilerTiming["labelStack"];
@@ -7,3 +9,53 @@ export declare const SsrRenderProfilerInner: ({ children, labelStack, onRender,
7
9
  }) => React.JSX.Element;
8
10
  declare const SsrRenderProfiler: (props: Parameters<typeof SsrRenderProfilerInner>[0]) => React.JSX.Element;
9
11
  export default SsrRenderProfiler;
12
+ interface SpanContext {
13
+ /** 16-character hex string representing the span ID */
14
+ readonly spanId: string;
15
+ /** 32-character hex string representing the trace ID */
16
+ readonly traceId: string;
17
+ /** Whether this span context is sampled */
18
+ readonly isSampled: boolean;
19
+ /** Whether this span context is from a remote service */
20
+ readonly isRemote: boolean;
21
+ }
22
+ interface SpanOptions {
23
+ /**
24
+ * Optional parent span ID for explicit parent specification.
25
+ * If not provided, the span will use the root span as its parent.
26
+ **/
27
+ parentSpanId?: string;
28
+ /** Optional start time - MUST BE a performance.now() timsestamp */
29
+ startTime?: number;
30
+ /** Optional attributes to set on the span at creation time */
31
+ attributes?: Record<string, string | number | boolean>;
32
+ /** Override the parent's sampled parameter. Generally should only be used to silence noisy spans and their children.
33
+ * Be VERY careful not to cause performance issues if setting to true */
34
+ sampledOverride?: boolean;
35
+ }
36
+ export interface Span {
37
+ /** End the span, optionally with a custom end time in milliseconds since epoch */
38
+ end(endTime?: number): void;
39
+ /** Set an attribute on the span */
40
+ setAttribute(key: string, value: string | number | boolean): void;
41
+ /** Add an event to the span */
42
+ addEvent(name: string): void;
43
+ /** Get the span context containing span ID, trace ID, and flags */
44
+ getSpanContext(): SpanContext | null;
45
+ }
46
+ export type TesseractTelemetryAPI = {
47
+ /**
48
+ * Start a new span with OpenTelemetry-like API
49
+ * Unlike typical openTelemetry, the parent span is not automatically inferred from context.
50
+ * You must explicitly provide a parentSpanId in options if desired.
51
+ * Otherwise, the span will use the root as its parent.
52
+ **/
53
+ startSpan(name: string, options?: SpanOptions): Span;
54
+ forceFlush(): void;
55
+ };
56
+ export type SnapVmInternals = {
57
+ telemetry?: TesseractTelemetryAPI;
58
+ };
59
+ export type GlobalThis = {
60
+ __vm_internals__?: SnapVmInternals;
61
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/react-ufo",
3
- "version": "4.16.6",
3
+ "version": "4.16.8",
4
4
  "description": "Parts of React UFO that are publicly available",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -168,9 +168,6 @@
168
168
  "platform_ufo_enable_finish_interaction_transition": {
169
169
  "type": "boolean"
170
170
  },
171
- "platform_ufo_always_send_post_interaction_log": {
172
- "type": "boolean"
173
- },
174
171
  "platform_ufo_drop_prior_fg_interactions": {
175
172
  "type": "boolean"
176
173
  },
@@ -207,6 +204,9 @@
207
204
  "platform_ufo_raw_data_thirdparty": {
208
205
  "type": "boolean"
209
206
  },
207
+ "platform_reset_post_interaction_on_new_interaction": {
208
+ "type": "boolean"
209
+ },
210
210
  "platform_enable_better_page_visibility": {
211
211
  "type": "boolean"
212
212
  }