@atlaskit/react-ufo 4.2.2 → 4.2.3

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
+ ## 4.2.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [#199487](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/199487)
8
+ [`65e285a7a4cbc`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/65e285a7a4cbc) -
9
+ Added segments threshold when creating React UFO payload
10
+
3
11
  ## 4.2.2
4
12
 
5
13
  ### Patch Changes
@@ -5,15 +5,25 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.buildSegmentTree = buildSegmentTree;
8
+ exports.getOldSegmentsLabelStack = getOldSegmentsLabelStack;
8
9
  exports.isSegmentLabel = isSegmentLabel;
9
10
  exports.labelStackStartWith = labelStackStartWith;
10
11
  exports.optimizeLabelStack = optimizeLabelStack;
11
12
  exports.sanitizeUfoName = sanitizeUfoName;
12
13
  exports.stringifyLabelStackFully = stringifyLabelStackFully;
14
+ exports.stringifyLabelStackWithoutId = stringifyLabelStackWithoutId;
15
+ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
13
16
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
14
17
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
18
+ var _config = require("../../../config");
19
+ var _getReactUfoPayloadVersion = require("../../utils/get-react-ufo-payload-version");
20
+ var _excluded = ["labelStack"],
21
+ _excluded2 = ["labelStack"];
15
22
  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; }
16
23
  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; }
24
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
25
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
26
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
17
27
  function sanitizeUfoName(name) {
18
28
  return name.replace(/_/g, '-');
19
29
  }
@@ -25,26 +35,72 @@ function buildSegmentTree(labelStacks) {
25
35
  n: 'segment-tree-root',
26
36
  c: {}
27
37
  };
28
- labelStacks.forEach(function (labelStack) {
29
- var currentNode = r;
30
- labelStack.forEach(function (label) {
31
- var name = label.name;
32
- var id = isSegmentLabel(label) ? label.segmentId : undefined;
33
- var key = id !== undefined ? id : name;
34
- var type = isSegmentLabel(label) ? label.type : undefined;
35
- if (!currentNode.c) {
36
- currentNode.c = {};
38
+ var config = (0, _config.getConfig)();
39
+ var segmentThreshold = config === null || config === void 0 ? void 0 : config.segmentsThreshold;
40
+ var addSegmentsMap = new Map();
41
+ if ((0, _platformFeatureFlags.fg)('platform_ufo_add_segments_count_threshold')) {
42
+ labelStacks.forEach(function (labelStack) {
43
+ var stringifiedLabelStack = stringifyLabelStackWithoutId(labelStack);
44
+ var currentNode = r;
45
+ var _iterator = _createForOfIteratorHelper(labelStack),
46
+ _step;
47
+ try {
48
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
49
+ var label = _step.value;
50
+ var isSegment = isSegmentLabel(label);
51
+ var name = label.name;
52
+ if (isSegment && segmentThreshold && segmentThreshold[name]) {
53
+ var threshold = segmentThreshold[name];
54
+ var count = addSegmentsMap.get(stringifiedLabelStack) || 0;
55
+ if (count < threshold) {
56
+ addSegmentsMap.set(stringifiedLabelStack, count + 1);
57
+ } else {
58
+ break;
59
+ }
60
+ }
61
+ var id = isSegment ? label.segmentId : undefined;
62
+ var key = id !== undefined ? id : name;
63
+ var type = isSegment ? label.type : undefined;
64
+ if (!currentNode.c) {
65
+ currentNode.c = {};
66
+ }
67
+ if (!currentNode.c[key]) {
68
+ currentNode.c[key] = _objectSpread({
69
+ n: name
70
+ }, type && (0, _platformFeatureFlags.fg)('platform_ufo_add_type_for_3p_segments') ? {
71
+ t: type
72
+ } : {});
73
+ }
74
+ currentNode = currentNode.c[key];
75
+ }
76
+ } catch (err) {
77
+ _iterator.e(err);
78
+ } finally {
79
+ _iterator.f();
37
80
  }
38
- if (!currentNode.c[key]) {
39
- currentNode.c[key] = _objectSpread({
40
- n: name
41
- }, type && (0, _platformFeatureFlags.fg)('platform_ufo_add_type_for_3p_segments') ? {
42
- t: type
43
- } : {});
44
- }
45
- currentNode = currentNode.c[key];
46
81
  });
47
- });
82
+ } else {
83
+ labelStacks.forEach(function (labelStack) {
84
+ var currentNode = r;
85
+ labelStack.forEach(function (label) {
86
+ var name = label.name;
87
+ var id = isSegmentLabel(label) ? label.segmentId : undefined;
88
+ var key = id !== undefined ? id : name;
89
+ var type = isSegmentLabel(label) ? label.type : undefined;
90
+ if (!currentNode.c) {
91
+ currentNode.c = {};
92
+ }
93
+ if (!currentNode.c[key]) {
94
+ currentNode.c[key] = _objectSpread({
95
+ n: name
96
+ }, type && (0, _platformFeatureFlags.fg)('platform_ufo_add_type_for_3p_segments') ? {
97
+ t: type
98
+ } : {});
99
+ }
100
+ currentNode = currentNode.c[key];
101
+ });
102
+ });
103
+ }
48
104
  return {
49
105
  r: r
50
106
  };
@@ -57,6 +113,14 @@ function stringifyLabelStackFully(labelStack) {
57
113
  return l.name;
58
114
  }).join('/');
59
115
  }
116
+ function stringifyLabelStackWithoutId(labelStack) {
117
+ return labelStack.map(function (l) {
118
+ if (isSegmentLabel(l)) {
119
+ return "".concat(l.name, ":segment");
120
+ }
121
+ return l.name;
122
+ }).join('/');
123
+ }
60
124
  function getLabelStackReference(labelStack) {
61
125
  return labelStack.map(function (l) {
62
126
  return isSegmentLabel(l) ? l.segmentId : l.name;
@@ -75,4 +139,55 @@ function optimizeLabelStack(labelStack, reactUFOVersion) {
75
139
  t: ls.type
76
140
  } : {});
77
141
  });
142
+ }
143
+ function getOldSegmentsLabelStack(segments, interactionType) {
144
+ if ((0, _platformFeatureFlags.fg)('platform_ufo_add_segments_count_threshold')) {
145
+ var config = (0, _config.getConfig)();
146
+ var addSegmentsMap = new Map();
147
+ var segmentThreshold = config === null || config === void 0 ? void 0 : config.segmentsThreshold;
148
+ return segments.map(function (_ref) {
149
+ var labelStack = _ref.labelStack,
150
+ others = (0, _objectWithoutProperties2.default)(_ref, _excluded);
151
+ var stringifiedLabelStack = stringifyLabelStackWithoutId(labelStack);
152
+ var segmentsInfo = [];
153
+ var _iterator2 = _createForOfIteratorHelper(labelStack),
154
+ _step2;
155
+ try {
156
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
157
+ var ls = _step2.value;
158
+ var isSegment = isSegmentLabel(ls);
159
+ if (isSegment && segmentThreshold && segmentThreshold[ls.name]) {
160
+ var threshold = segmentThreshold[ls.name];
161
+ var count = addSegmentsMap.get(stringifiedLabelStack) || 0;
162
+ if (count < threshold) {
163
+ addSegmentsMap.set(stringifiedLabelStack, count + 1);
164
+ } else {
165
+ break;
166
+ }
167
+ }
168
+ segmentsInfo.push(_objectSpread(_objectSpread({
169
+ n: ls.name
170
+ }, ls.segmentId ? {
171
+ s: ls.segmentId
172
+ } : {}), ls.type && (0, _platformFeatureFlags.fg)('platform_ufo_add_type_for_3p_segments') ? {
173
+ t: ls.type
174
+ } : {}));
175
+ }
176
+ } catch (err) {
177
+ _iterator2.e(err);
178
+ } finally {
179
+ _iterator2.f();
180
+ }
181
+ return _objectSpread(_objectSpread({}, others), {}, {
182
+ labelStack: segmentsInfo
183
+ });
184
+ });
185
+ }
186
+ return segments.map(function (_ref2) {
187
+ var labelStack = _ref2.labelStack,
188
+ others = (0, _objectWithoutProperties2.default)(_ref2, _excluded2);
189
+ return _objectSpread(_objectSpread({}, others), {}, {
190
+ labelStack: optimizeLabelStack(labelStack, (0, _getReactUfoPayloadVersion.getReactUFOPayloadVersion)(interactionType))
191
+ });
192
+ });
78
193
  }
@@ -47,8 +47,7 @@ var _getTtai = _interopRequireDefault(require("./utils/get-ttai"));
47
47
  var _getVcMetrics = _interopRequireDefault(require("./utils/get-vc-metrics"));
48
48
  var _excluded = ["labelStack", "time"],
49
49
  _excluded2 = ["stopTime", "labelStack"],
50
- _excluded3 = ["labelStack"],
51
- _excluded4 = ["labelStack"];
50
+ _excluded3 = ["labelStack"];
52
51
  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); }
53
52
  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; }
54
53
  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; } // Import common utilities
@@ -756,13 +755,7 @@ function _createInteractionMetricsPayload() {
756
755
  apdex: optimizeApdex(interaction.apdex, (0, _getReactUfoPayloadVersion.getReactUFOPayloadVersion)(interaction.type)),
757
756
  end: Math.round(end),
758
757
  start: Math.round(start),
759
- segments: (0, _getReactUfoPayloadVersion.getReactUFOPayloadVersion)(interaction.type) === '2.0.0' ? segmentTree : segments.map(function (_ref7) {
760
- var labelStack = _ref7.labelStack,
761
- others = (0, _objectWithoutProperties2.default)(_ref7, _excluded4);
762
- return _objectSpread(_objectSpread({}, others), {}, {
763
- labelStack: (0, _utils.optimizeLabelStack)(labelStack, (0, _getReactUfoPayloadVersion.getReactUFOPayloadVersion)(interaction.type))
764
- });
765
- }),
758
+ segments: (0, _getReactUfoPayloadVersion.getReactUFOPayloadVersion)(interaction.type) === '2.0.0' ? segmentTree : (0, _utils.getOldSegmentsLabelStack)(segments, interaction.type),
766
759
  marks: optimizeMarks(interaction.marks, (0, _getReactUfoPayloadVersion.getReactUFOPayloadVersion)(interaction.type)),
767
760
  customData: optimizeCustomData(interaction),
768
761
  reactProfilerTimings: optimizeReactProfilerTimings(interaction.reactProfilerTimings, start, (0, _getReactUfoPayloadVersion.getReactUFOPayloadVersion)(interaction.type))
@@ -1,4 +1,6 @@
1
1
  import { fg } from '@atlaskit/platform-feature-flags';
2
+ import { getConfig } from '../../../config';
3
+ import { getReactUFOPayloadVersion } from '../../utils/get-react-ufo-payload-version';
2
4
  export function sanitizeUfoName(name) {
3
5
  return name.replace(/_/g, '-');
4
6
  }
@@ -10,27 +12,65 @@ export function buildSegmentTree(labelStacks) {
10
12
  n: 'segment-tree-root',
11
13
  c: {}
12
14
  };
13
- labelStacks.forEach(labelStack => {
14
- let currentNode = r;
15
- labelStack.forEach(label => {
16
- const name = label.name;
17
- const id = isSegmentLabel(label) ? label.segmentId : undefined;
18
- const key = id !== undefined ? id : name;
19
- const type = isSegmentLabel(label) ? label.type : undefined;
20
- if (!currentNode.c) {
21
- currentNode.c = {};
15
+ const config = getConfig();
16
+ const segmentThreshold = config === null || config === void 0 ? void 0 : config.segmentsThreshold;
17
+ const addSegmentsMap = new Map();
18
+ if (fg('platform_ufo_add_segments_count_threshold')) {
19
+ labelStacks.forEach(labelStack => {
20
+ const stringifiedLabelStack = stringifyLabelStackWithoutId(labelStack);
21
+ let currentNode = r;
22
+ for (const label of labelStack) {
23
+ const isSegment = isSegmentLabel(label);
24
+ const name = label.name;
25
+ if (isSegment && segmentThreshold && segmentThreshold[name]) {
26
+ const threshold = segmentThreshold[name];
27
+ const count = addSegmentsMap.get(stringifiedLabelStack) || 0;
28
+ if (count < threshold) {
29
+ addSegmentsMap.set(stringifiedLabelStack, count + 1);
30
+ } else {
31
+ break;
32
+ }
33
+ }
34
+ const id = isSegment ? label.segmentId : undefined;
35
+ const key = id !== undefined ? id : name;
36
+ const type = isSegment ? label.type : undefined;
37
+ if (!currentNode.c) {
38
+ currentNode.c = {};
39
+ }
40
+ if (!currentNode.c[key]) {
41
+ currentNode.c[key] = {
42
+ n: name,
43
+ ...(type && fg('platform_ufo_add_type_for_3p_segments') ? {
44
+ t: type
45
+ } : {})
46
+ };
47
+ }
48
+ currentNode = currentNode.c[key];
22
49
  }
23
- if (!currentNode.c[key]) {
24
- currentNode.c[key] = {
25
- n: name,
26
- ...(type && fg('platform_ufo_add_type_for_3p_segments') ? {
27
- t: type
28
- } : {})
29
- };
30
- }
31
- currentNode = currentNode.c[key];
32
50
  });
33
- });
51
+ } else {
52
+ labelStacks.forEach(labelStack => {
53
+ let currentNode = r;
54
+ labelStack.forEach(label => {
55
+ const name = label.name;
56
+ const id = isSegmentLabel(label) ? label.segmentId : undefined;
57
+ const key = id !== undefined ? id : name;
58
+ const type = isSegmentLabel(label) ? label.type : undefined;
59
+ if (!currentNode.c) {
60
+ currentNode.c = {};
61
+ }
62
+ if (!currentNode.c[key]) {
63
+ currentNode.c[key] = {
64
+ n: name,
65
+ ...(type && fg('platform_ufo_add_type_for_3p_segments') ? {
66
+ t: type
67
+ } : {})
68
+ };
69
+ }
70
+ currentNode = currentNode.c[key];
71
+ });
72
+ });
73
+ }
34
74
  return {
35
75
  r
36
76
  };
@@ -43,6 +83,14 @@ export function stringifyLabelStackFully(labelStack) {
43
83
  return l.name;
44
84
  }).join('/');
45
85
  }
86
+ export function stringifyLabelStackWithoutId(labelStack) {
87
+ return labelStack.map(l => {
88
+ if (isSegmentLabel(l)) {
89
+ return `${l.name}:segment`;
90
+ }
91
+ return l.name;
92
+ }).join('/');
93
+ }
46
94
  function getLabelStackReference(labelStack) {
47
95
  return labelStack.map(l => isSegmentLabel(l) ? l.segmentId : l.name).join('/');
48
96
  }
@@ -59,4 +107,50 @@ export function optimizeLabelStack(labelStack, reactUFOVersion) {
59
107
  t: ls.type
60
108
  } : {})
61
109
  }));
110
+ }
111
+ export function getOldSegmentsLabelStack(segments, interactionType) {
112
+ if (fg('platform_ufo_add_segments_count_threshold')) {
113
+ const config = getConfig();
114
+ const addSegmentsMap = new Map();
115
+ const segmentThreshold = config === null || config === void 0 ? void 0 : config.segmentsThreshold;
116
+ return segments.map(({
117
+ labelStack,
118
+ ...others
119
+ }) => {
120
+ const stringifiedLabelStack = stringifyLabelStackWithoutId(labelStack);
121
+ const segmentsInfo = [];
122
+ for (const ls of labelStack) {
123
+ const isSegment = isSegmentLabel(ls);
124
+ if (isSegment && segmentThreshold && segmentThreshold[ls.name]) {
125
+ const threshold = segmentThreshold[ls.name];
126
+ const count = addSegmentsMap.get(stringifiedLabelStack) || 0;
127
+ if (count < threshold) {
128
+ addSegmentsMap.set(stringifiedLabelStack, count + 1);
129
+ } else {
130
+ break;
131
+ }
132
+ }
133
+ segmentsInfo.push({
134
+ n: ls.name,
135
+ ...(ls.segmentId ? {
136
+ s: ls.segmentId
137
+ } : {}),
138
+ ...(ls.type && fg('platform_ufo_add_type_for_3p_segments') ? {
139
+ t: ls.type
140
+ } : {})
141
+ });
142
+ }
143
+ return {
144
+ ...others,
145
+ labelStack: segmentsInfo
146
+ };
147
+ });
148
+ }
149
+ return segments.map(({
150
+ labelStack,
151
+ ...others
152
+ }) => ({
153
+ ...others,
154
+ labelStack: optimizeLabelStack(labelStack, getReactUFOPayloadVersion(interactionType))
155
+ }));
62
156
  }
@@ -19,7 +19,7 @@ import * as resourceTiming from '../resource-timing';
19
19
  import { filterResourceTimings } from '../resource-timing/common/utils/resource-timing-buffer';
20
20
  import { roundEpsilon } from '../round-number';
21
21
  import * as ssr from '../ssr';
22
- import { buildSegmentTree, labelStackStartWith, optimizeLabelStack, sanitizeUfoName, stringifyLabelStackFully } from './common/utils';
22
+ import { buildSegmentTree, getOldSegmentsLabelStack, labelStackStartWith, optimizeLabelStack, sanitizeUfoName, stringifyLabelStackFully } from './common/utils';
23
23
  import { createCriticalMetricsPayloads } from './critical-metrics-payload';
24
24
  import { addPerformanceMeasures } from './utils/add-performance-measures';
25
25
  import { getBrowserMetadataToLegacyFormat } from './utils/get-browser-metadata';
@@ -754,13 +754,7 @@ async function createInteractionMetricsPayload(interaction, interactionId, exper
754
754
  apdex: optimizeApdex(interaction.apdex, getReactUFOPayloadVersion(interaction.type)),
755
755
  end: Math.round(end),
756
756
  start: Math.round(start),
757
- segments: getReactUFOPayloadVersion(interaction.type) === '2.0.0' ? segmentTree : segments.map(({
758
- labelStack,
759
- ...others
760
- }) => ({
761
- ...others,
762
- labelStack: optimizeLabelStack(labelStack, getReactUFOPayloadVersion(interaction.type))
763
- })),
757
+ segments: getReactUFOPayloadVersion(interaction.type) === '2.0.0' ? segmentTree : getOldSegmentsLabelStack(segments, interaction.type),
764
758
  marks: optimizeMarks(interaction.marks, getReactUFOPayloadVersion(interaction.type)),
765
759
  customData: optimizeCustomData(interaction),
766
760
  reactProfilerTimings: optimizeReactProfilerTimings(interaction.reactProfilerTimings, start, getReactUFOPayloadVersion(interaction.type)),
@@ -1,7 +1,15 @@
1
+ import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
1
2
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
+ var _excluded = ["labelStack"],
4
+ _excluded2 = ["labelStack"];
2
5
  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; }
3
6
  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; }
7
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
8
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
9
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
4
10
  import { fg } from '@atlaskit/platform-feature-flags';
11
+ import { getConfig } from '../../../config';
12
+ import { getReactUFOPayloadVersion } from '../../utils/get-react-ufo-payload-version';
5
13
  export function sanitizeUfoName(name) {
6
14
  return name.replace(/_/g, '-');
7
15
  }
@@ -13,26 +21,72 @@ export function buildSegmentTree(labelStacks) {
13
21
  n: 'segment-tree-root',
14
22
  c: {}
15
23
  };
16
- labelStacks.forEach(function (labelStack) {
17
- var currentNode = r;
18
- labelStack.forEach(function (label) {
19
- var name = label.name;
20
- var id = isSegmentLabel(label) ? label.segmentId : undefined;
21
- var key = id !== undefined ? id : name;
22
- var type = isSegmentLabel(label) ? label.type : undefined;
23
- if (!currentNode.c) {
24
- currentNode.c = {};
24
+ var config = getConfig();
25
+ var segmentThreshold = config === null || config === void 0 ? void 0 : config.segmentsThreshold;
26
+ var addSegmentsMap = new Map();
27
+ if (fg('platform_ufo_add_segments_count_threshold')) {
28
+ labelStacks.forEach(function (labelStack) {
29
+ var stringifiedLabelStack = stringifyLabelStackWithoutId(labelStack);
30
+ var currentNode = r;
31
+ var _iterator = _createForOfIteratorHelper(labelStack),
32
+ _step;
33
+ try {
34
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
35
+ var label = _step.value;
36
+ var isSegment = isSegmentLabel(label);
37
+ var name = label.name;
38
+ if (isSegment && segmentThreshold && segmentThreshold[name]) {
39
+ var threshold = segmentThreshold[name];
40
+ var count = addSegmentsMap.get(stringifiedLabelStack) || 0;
41
+ if (count < threshold) {
42
+ addSegmentsMap.set(stringifiedLabelStack, count + 1);
43
+ } else {
44
+ break;
45
+ }
46
+ }
47
+ var id = isSegment ? label.segmentId : undefined;
48
+ var key = id !== undefined ? id : name;
49
+ var type = isSegment ? label.type : undefined;
50
+ if (!currentNode.c) {
51
+ currentNode.c = {};
52
+ }
53
+ if (!currentNode.c[key]) {
54
+ currentNode.c[key] = _objectSpread({
55
+ n: name
56
+ }, type && fg('platform_ufo_add_type_for_3p_segments') ? {
57
+ t: type
58
+ } : {});
59
+ }
60
+ currentNode = currentNode.c[key];
61
+ }
62
+ } catch (err) {
63
+ _iterator.e(err);
64
+ } finally {
65
+ _iterator.f();
25
66
  }
26
- if (!currentNode.c[key]) {
27
- currentNode.c[key] = _objectSpread({
28
- n: name
29
- }, type && fg('platform_ufo_add_type_for_3p_segments') ? {
30
- t: type
31
- } : {});
32
- }
33
- currentNode = currentNode.c[key];
34
67
  });
35
- });
68
+ } else {
69
+ labelStacks.forEach(function (labelStack) {
70
+ var currentNode = r;
71
+ labelStack.forEach(function (label) {
72
+ var name = label.name;
73
+ var id = isSegmentLabel(label) ? label.segmentId : undefined;
74
+ var key = id !== undefined ? id : name;
75
+ var type = isSegmentLabel(label) ? label.type : undefined;
76
+ if (!currentNode.c) {
77
+ currentNode.c = {};
78
+ }
79
+ if (!currentNode.c[key]) {
80
+ currentNode.c[key] = _objectSpread({
81
+ n: name
82
+ }, type && fg('platform_ufo_add_type_for_3p_segments') ? {
83
+ t: type
84
+ } : {});
85
+ }
86
+ currentNode = currentNode.c[key];
87
+ });
88
+ });
89
+ }
36
90
  return {
37
91
  r: r
38
92
  };
@@ -45,6 +99,14 @@ export function stringifyLabelStackFully(labelStack) {
45
99
  return l.name;
46
100
  }).join('/');
47
101
  }
102
+ export function stringifyLabelStackWithoutId(labelStack) {
103
+ return labelStack.map(function (l) {
104
+ if (isSegmentLabel(l)) {
105
+ return "".concat(l.name, ":segment");
106
+ }
107
+ return l.name;
108
+ }).join('/');
109
+ }
48
110
  function getLabelStackReference(labelStack) {
49
111
  return labelStack.map(function (l) {
50
112
  return isSegmentLabel(l) ? l.segmentId : l.name;
@@ -63,4 +125,55 @@ export function optimizeLabelStack(labelStack, reactUFOVersion) {
63
125
  t: ls.type
64
126
  } : {});
65
127
  });
128
+ }
129
+ export function getOldSegmentsLabelStack(segments, interactionType) {
130
+ if (fg('platform_ufo_add_segments_count_threshold')) {
131
+ var config = getConfig();
132
+ var addSegmentsMap = new Map();
133
+ var segmentThreshold = config === null || config === void 0 ? void 0 : config.segmentsThreshold;
134
+ return segments.map(function (_ref) {
135
+ var labelStack = _ref.labelStack,
136
+ others = _objectWithoutProperties(_ref, _excluded);
137
+ var stringifiedLabelStack = stringifyLabelStackWithoutId(labelStack);
138
+ var segmentsInfo = [];
139
+ var _iterator2 = _createForOfIteratorHelper(labelStack),
140
+ _step2;
141
+ try {
142
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
143
+ var ls = _step2.value;
144
+ var isSegment = isSegmentLabel(ls);
145
+ if (isSegment && segmentThreshold && segmentThreshold[ls.name]) {
146
+ var threshold = segmentThreshold[ls.name];
147
+ var count = addSegmentsMap.get(stringifiedLabelStack) || 0;
148
+ if (count < threshold) {
149
+ addSegmentsMap.set(stringifiedLabelStack, count + 1);
150
+ } else {
151
+ break;
152
+ }
153
+ }
154
+ segmentsInfo.push(_objectSpread(_objectSpread({
155
+ n: ls.name
156
+ }, ls.segmentId ? {
157
+ s: ls.segmentId
158
+ } : {}), ls.type && fg('platform_ufo_add_type_for_3p_segments') ? {
159
+ t: ls.type
160
+ } : {}));
161
+ }
162
+ } catch (err) {
163
+ _iterator2.e(err);
164
+ } finally {
165
+ _iterator2.f();
166
+ }
167
+ return _objectSpread(_objectSpread({}, others), {}, {
168
+ labelStack: segmentsInfo
169
+ });
170
+ });
171
+ }
172
+ return segments.map(function (_ref2) {
173
+ var labelStack = _ref2.labelStack,
174
+ others = _objectWithoutProperties(_ref2, _excluded2);
175
+ return _objectSpread(_objectSpread({}, others), {}, {
176
+ labelStack: optimizeLabelStack(labelStack, getReactUFOPayloadVersion(interactionType))
177
+ });
178
+ });
66
179
  }
@@ -5,8 +5,7 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
5
5
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
6
6
  var _excluded = ["labelStack", "time"],
7
7
  _excluded2 = ["stopTime", "labelStack"],
8
- _excluded3 = ["labelStack"],
9
- _excluded4 = ["labelStack"];
8
+ _excluded3 = ["labelStack"];
10
9
  import _regeneratorRuntime from "@babel/runtime/regenerator";
11
10
  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; }
12
11
  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; }
@@ -31,7 +30,7 @@ import * as resourceTiming from '../resource-timing';
31
30
  import { filterResourceTimings } from '../resource-timing/common/utils/resource-timing-buffer';
32
31
  import { roundEpsilon } from '../round-number';
33
32
  import * as ssr from '../ssr';
34
- import { buildSegmentTree, labelStackStartWith, optimizeLabelStack, sanitizeUfoName, stringifyLabelStackFully } from './common/utils';
33
+ import { buildSegmentTree, getOldSegmentsLabelStack, labelStackStartWith, optimizeLabelStack, sanitizeUfoName, stringifyLabelStackFully } from './common/utils';
35
34
  import { createCriticalMetricsPayloads } from './critical-metrics-payload';
36
35
  import { addPerformanceMeasures } from './utils/add-performance-measures';
37
36
  import { getBrowserMetadataToLegacyFormat } from './utils/get-browser-metadata';
@@ -749,13 +748,7 @@ function _createInteractionMetricsPayload() {
749
748
  apdex: optimizeApdex(interaction.apdex, getReactUFOPayloadVersion(interaction.type)),
750
749
  end: Math.round(end),
751
750
  start: Math.round(start),
752
- segments: getReactUFOPayloadVersion(interaction.type) === '2.0.0' ? segmentTree : segments.map(function (_ref7) {
753
- var labelStack = _ref7.labelStack,
754
- others = _objectWithoutProperties(_ref7, _excluded4);
755
- return _objectSpread(_objectSpread({}, others), {}, {
756
- labelStack: optimizeLabelStack(labelStack, getReactUFOPayloadVersion(interaction.type))
757
- });
758
- }),
751
+ segments: getReactUFOPayloadVersion(interaction.type) === '2.0.0' ? segmentTree : getOldSegmentsLabelStack(segments, interaction.type),
759
752
  marks: optimizeMarks(interaction.marks, getReactUFOPayloadVersion(interaction.type)),
760
753
  customData: optimizeCustomData(interaction),
761
754
  reactProfilerTimings: optimizeReactProfilerTimings(interaction.reactProfilerTimings, start, getReactUFOPayloadVersion(interaction.type))
@@ -24,6 +24,9 @@ type SelectorConfig = {
24
24
  className: boolean;
25
25
  dataVC?: boolean;
26
26
  };
27
+ type SegmentThreshold = {
28
+ readonly [key: string]: number;
29
+ };
27
30
  type Rates = {
28
31
  readonly [key: string]: number;
29
32
  };
@@ -68,6 +71,7 @@ export type Config = {
68
71
  };
69
72
  readonly assetsConfig?: AssetsConfig;
70
73
  readonly enableBetterPageVisibilityApi?: boolean;
74
+ readonly segmentsThreshold?: SegmentThreshold;
71
75
  readonly vc?: {
72
76
  readonly enabled?: boolean;
73
77
  readonly heatmapSize?: number;
@@ -1,6 +1,7 @@
1
+ import type { InteractionType, SegmentInfo } from '../../../common';
1
2
  import type { LabelStack, SegmentLabel } from '../../../interaction-context';
2
3
  import { type UFOSegmentType } from '../../../segment/segment';
3
- import { type getReactUFOPayloadVersion } from '../../utils/get-react-ufo-payload-version';
4
+ import { getReactUFOPayloadVersion } from '../../utils/get-react-ufo-payload-version';
4
5
  export type SegmentItem = {
5
6
  n: string;
6
7
  c?: Record<string, SegmentItem>;
@@ -13,9 +14,19 @@ export declare function sanitizeUfoName(name: string): string;
13
14
  export declare function isSegmentLabel(obj: any): obj is SegmentLabel;
14
15
  export declare function buildSegmentTree(labelStacks: LabelStack[]): SegmentTree;
15
16
  export declare function stringifyLabelStackFully(labelStack: LabelStack): string;
17
+ export declare function stringifyLabelStackWithoutId(labelStack: LabelStack): string;
16
18
  export declare function labelStackStartWith(labelStack: LabelStack, startWith: LabelStack): boolean;
17
19
  export declare function optimizeLabelStack(labelStack: LabelStack, reactUFOVersion: ReturnType<typeof getReactUFOPayloadVersion>): string | {
18
20
  t?: UFOSegmentType | undefined;
19
21
  s?: string | undefined;
20
22
  n: string;
21
23
  }[];
24
+ export declare function getOldSegmentsLabelStack(segments: SegmentInfo[], interactionType: InteractionType): {
25
+ labelStack: any[];
26
+ }[] | {
27
+ labelStack: string | {
28
+ t?: UFOSegmentType | undefined;
29
+ s?: string | undefined;
30
+ n: string;
31
+ }[];
32
+ }[];
@@ -24,6 +24,9 @@ type SelectorConfig = {
24
24
  className: boolean;
25
25
  dataVC?: boolean;
26
26
  };
27
+ type SegmentThreshold = {
28
+ readonly [key: string]: number;
29
+ };
27
30
  type Rates = {
28
31
  readonly [key: string]: number;
29
32
  };
@@ -68,6 +71,7 @@ export type Config = {
68
71
  };
69
72
  readonly assetsConfig?: AssetsConfig;
70
73
  readonly enableBetterPageVisibilityApi?: boolean;
74
+ readonly segmentsThreshold?: SegmentThreshold;
71
75
  readonly vc?: {
72
76
  readonly enabled?: boolean;
73
77
  readonly heatmapSize?: number;
@@ -1,6 +1,7 @@
1
+ import type { InteractionType, SegmentInfo } from '../../../common';
1
2
  import type { LabelStack, SegmentLabel } from '../../../interaction-context';
2
3
  import { type UFOSegmentType } from '../../../segment/segment';
3
- import { type getReactUFOPayloadVersion } from '../../utils/get-react-ufo-payload-version';
4
+ import { getReactUFOPayloadVersion } from '../../utils/get-react-ufo-payload-version';
4
5
  export type SegmentItem = {
5
6
  n: string;
6
7
  c?: Record<string, SegmentItem>;
@@ -13,9 +14,19 @@ export declare function sanitizeUfoName(name: string): string;
13
14
  export declare function isSegmentLabel(obj: any): obj is SegmentLabel;
14
15
  export declare function buildSegmentTree(labelStacks: LabelStack[]): SegmentTree;
15
16
  export declare function stringifyLabelStackFully(labelStack: LabelStack): string;
17
+ export declare function stringifyLabelStackWithoutId(labelStack: LabelStack): string;
16
18
  export declare function labelStackStartWith(labelStack: LabelStack, startWith: LabelStack): boolean;
17
19
  export declare function optimizeLabelStack(labelStack: LabelStack, reactUFOVersion: ReturnType<typeof getReactUFOPayloadVersion>): string | {
18
20
  t?: UFOSegmentType | undefined;
19
21
  s?: string | undefined;
20
22
  n: string;
21
23
  }[];
24
+ export declare function getOldSegmentsLabelStack(segments: SegmentInfo[], interactionType: InteractionType): {
25
+ labelStack: any[];
26
+ }[] | {
27
+ labelStack: string | {
28
+ t?: UFOSegmentType | undefined;
29
+ s?: string | undefined;
30
+ n: string;
31
+ }[];
32
+ }[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/react-ufo",
3
- "version": "4.2.2",
3
+ "version": "4.2.3",
4
4
  "description": "Parts of React UFO that are publicly available",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -197,6 +197,9 @@
197
197
  },
198
198
  "platform_ufo_report_non_htmlelement_selectors": {
199
199
  "type": "boolean"
200
+ },
201
+ "platform_ufo_add_segments_count_threshold": {
202
+ "type": "boolean"
200
203
  }
201
204
  }
202
205
  }