@atlaskit/react-ufo 4.6.0 → 4.6.2
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 +16 -0
- package/dist/cjs/create-post-interaction-log-payload/get-late-mutations.js +15 -3
- package/dist/cjs/create-post-interaction-log-payload/index.js +2 -1
- package/dist/cjs/hidden-timing/index.js +11 -7
- package/dist/cjs/vc/vc-observer-new/index.js +74 -11
- package/dist/cjs/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +101 -60
- package/dist/es2019/create-post-interaction-log-payload/get-late-mutations.js +12 -3
- package/dist/es2019/create-post-interaction-log-payload/index.js +2 -1
- package/dist/es2019/hidden-timing/index.js +11 -7
- package/dist/es2019/vc/vc-observer-new/index.js +67 -10
- package/dist/es2019/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +42 -11
- package/dist/esm/create-post-interaction-log-payload/get-late-mutations.js +15 -3
- package/dist/esm/create-post-interaction-log-payload/index.js +2 -1
- package/dist/esm/hidden-timing/index.js +11 -7
- package/dist/esm/vc/vc-observer-new/index.js +74 -11
- package/dist/esm/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +101 -60
- package/dist/types/common/react-ufo-payload-schema.d.ts +2 -0
- package/dist/types/common/vc/types.d.ts +7 -0
- package/dist/types/create-post-interaction-log-payload/get-late-mutations.d.ts +2 -2
- package/dist/types/vc/vc-observer/getVCRevisionDebugDetails.d.ts +1 -1
- package/dist/types/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +1 -0
- package/dist/types/vc/vc-observer-new/types.d.ts +5 -0
- package/dist/types-ts4.5/common/react-ufo-payload-schema.d.ts +2 -0
- package/dist/types-ts4.5/common/vc/types.d.ts +7 -0
- package/dist/types-ts4.5/create-post-interaction-log-payload/get-late-mutations.d.ts +2 -2
- package/dist/types-ts4.5/vc/vc-observer/getVCRevisionDebugDetails.d.ts +1 -1
- package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +1 -0
- package/dist/types-ts4.5/vc/vc-observer-new/types.d.ts +5 -0
- package/package.json +7 -4
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
2
3
|
import { SSRPlaceholderHandlers } from '../vc-observer/observers/ssr-placeholders';
|
|
3
4
|
import EntriesTimeline from './entries-timeline';
|
|
4
5
|
import getElementName from './get-element-name';
|
|
@@ -61,18 +62,27 @@ export default class VCObserverNew {
|
|
|
61
62
|
if (element) {
|
|
62
63
|
elementName = this.getElementName(element);
|
|
63
64
|
}
|
|
65
|
+
const data = {
|
|
66
|
+
type,
|
|
67
|
+
elementName,
|
|
68
|
+
rect,
|
|
69
|
+
previousRect,
|
|
70
|
+
visible,
|
|
71
|
+
attributeName: mutationData === null || mutationData === void 0 ? void 0 : mutationData.attributeName,
|
|
72
|
+
oldValue: mutationData === null || mutationData === void 0 ? void 0 : mutationData.oldValue,
|
|
73
|
+
newValue: mutationData === null || mutationData === void 0 ? void 0 : mutationData.newValue
|
|
74
|
+
};
|
|
75
|
+
if (element && this.isPostInteraction && fg('platform_ufo_enable_late_mutation_label_stacks')) {
|
|
76
|
+
const labelStacks = getLabelStacks(element);
|
|
77
|
+
if (labelStacks) {
|
|
78
|
+
Object.assign(data, {
|
|
79
|
+
labelStacks
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
64
83
|
this.entriesTimeline.push({
|
|
65
84
|
time,
|
|
66
|
-
data
|
|
67
|
-
type,
|
|
68
|
-
elementName,
|
|
69
|
-
rect,
|
|
70
|
-
previousRect,
|
|
71
|
-
visible,
|
|
72
|
-
attributeName: mutationData === null || mutationData === void 0 ? void 0 : mutationData.attributeName,
|
|
73
|
-
oldValue: mutationData === null || mutationData === void 0 ? void 0 : mutationData.oldValue,
|
|
74
|
-
newValue: mutationData === null || mutationData === void 0 ? void 0 : mutationData.newValue
|
|
75
|
-
}
|
|
85
|
+
data
|
|
76
86
|
});
|
|
77
87
|
},
|
|
78
88
|
// Pass SSR context to ViewportObserver
|
|
@@ -245,4 +255,51 @@ export default class VCObserverNew {
|
|
|
245
255
|
getElementName(element) {
|
|
246
256
|
return getElementName(this.selectorConfig, element);
|
|
247
257
|
}
|
|
258
|
+
}
|
|
259
|
+
function labelStackFromFiber(fiber) {
|
|
260
|
+
var _fiber$child, _fiber$child$memoized;
|
|
261
|
+
const value = fiber === null || fiber === void 0 ? void 0 : (_fiber$child = fiber.child) === null || _fiber$child === void 0 ? void 0 : (_fiber$child$memoized = _fiber$child.memoizedProps) === null || _fiber$child$memoized === void 0 ? void 0 : _fiber$child$memoized.value;
|
|
262
|
+
return Array.isArray(value === null || value === void 0 ? void 0 : value.labelStack) ? value.labelStack : [];
|
|
263
|
+
}
|
|
264
|
+
function labelStackToString(labelStack) {
|
|
265
|
+
return labelStack.map(label => label.name).join('/');
|
|
266
|
+
}
|
|
267
|
+
function labelStackToSegment(labelStack) {
|
|
268
|
+
let segmentIndex = -1;
|
|
269
|
+
for (let i = labelStack.length - 1; i >= 0; i--) {
|
|
270
|
+
if (labelStack[i].segmentId) {
|
|
271
|
+
segmentIndex = i;
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return labelStack.slice(0, segmentIndex + 1).map(label => label.name).join('/');
|
|
276
|
+
}
|
|
277
|
+
function traverseFiber(fiber) {
|
|
278
|
+
let segment = 'unknown';
|
|
279
|
+
let labelStackString = 'unknown';
|
|
280
|
+
let currentFiber = fiber;
|
|
281
|
+
while (currentFiber) {
|
|
282
|
+
if (currentFiber.type) {
|
|
283
|
+
const componentName = currentFiber.type.displayName || currentFiber.type.name;
|
|
284
|
+
if (componentName === 'UFOSegment' || componentName === 'UFOLabel') {
|
|
285
|
+
const labelStack = labelStackFromFiber(currentFiber);
|
|
286
|
+
labelStackString = labelStackToString(labelStack) || 'unknown';
|
|
287
|
+
segment = labelStackToSegment(labelStack) || 'unknown';
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
currentFiber = currentFiber.return;
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
segment,
|
|
295
|
+
labelStack: labelStackString
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
function getLabelStacks(element) {
|
|
299
|
+
const reactFiberKey = Object.keys(element).find(key => key.startsWith('__reactFiber$'));
|
|
300
|
+
if (!reactFiberKey) {
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
const fiber = element[reactFiberKey];
|
|
304
|
+
return fiber ? traverseFiber(fiber) : null;
|
|
248
305
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
2
|
+
import getPageVisibilityUpToTTAI from '../../../create-payload/utils/get-page-visibility-up-to-ttai';
|
|
3
|
+
import { getInteractionId } from '../../../interaction-id-context';
|
|
4
|
+
import { interactions } from '../../../interaction-metrics/common/constants';
|
|
2
5
|
import { cssIssueOccurrence } from '../viewport-observer/utils/track-display-content-occurrence';
|
|
3
6
|
import { calculateTTVCPercentilesWithDebugInfo } from './percentile-calc';
|
|
4
7
|
import getViewportHeight from './utils/get-viewport-height';
|
|
@@ -40,12 +43,21 @@ export default class AbstractVCCalculatorBase {
|
|
|
40
43
|
}
|
|
41
44
|
return ratios;
|
|
42
45
|
}
|
|
46
|
+
getLabelStacks(filteredEntries) {
|
|
47
|
+
const labelStacks = {};
|
|
48
|
+
for (const entry of filteredEntries) {
|
|
49
|
+
if ('elementName' in entry.data && entry.data.labelStacks) {
|
|
50
|
+
labelStacks[entry.data.elementName] = {
|
|
51
|
+
segment: entry.data.labelStacks.segment,
|
|
52
|
+
labelStack: entry.data.labelStacks.labelStack
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return labelStacks;
|
|
57
|
+
}
|
|
43
58
|
async calculateWithDebugInfo(filteredEntries, startTime, stopTime, isPostInteraction, isVCClean, interactionId, dirtyReason, allEntries, include3p) {
|
|
44
59
|
var _window, _window2, _window3, _window5;
|
|
45
|
-
const percentiles = [25, 50, 75, 80, 85, 90, 95, 98, 99];
|
|
46
|
-
if (fg('platform_ufo_send_vc_100')) {
|
|
47
|
-
percentiles.push(100);
|
|
48
|
-
}
|
|
60
|
+
const percentiles = [25, 50, 75, 80, 85, 90, 95, 98, 99, 100];
|
|
49
61
|
const viewportEntries = this.filterViewportEntries(filteredEntries);
|
|
50
62
|
const vcLogs = await calculateTTVCPercentilesWithDebugInfo({
|
|
51
63
|
viewport: {
|
|
@@ -199,13 +211,29 @@ export default class AbstractVCCalculatorBase {
|
|
|
199
211
|
// Only create debug details if callbacks exist
|
|
200
212
|
let v3RevisionDebugDetails = null;
|
|
201
213
|
if (shouldCalculateDebugDetails) {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
214
|
+
if (fg('platform_ufo_unify_abort_status_in_ttvc_debug_data')) {
|
|
215
|
+
var _activeInteractionId$;
|
|
216
|
+
// NOTE: using this instead of directly calling `getActiveInteraction()` to get around circular dependencies
|
|
217
|
+
const activeInteractionId = getInteractionId();
|
|
218
|
+
const activeInteraction = interactions.get((_activeInteractionId$ = activeInteractionId.current) !== null && _activeInteractionId$ !== void 0 ? _activeInteractionId$ : '');
|
|
219
|
+
const pageVisibilityUpToTTAI = activeInteraction ? getPageVisibilityUpToTTAI(activeInteraction) : null;
|
|
220
|
+
const isBackgrounded = pageVisibilityUpToTTAI !== 'visible';
|
|
221
|
+
v3RevisionDebugDetails = {
|
|
222
|
+
revision: this.revisionNo,
|
|
223
|
+
isClean: isVCClean && !(activeInteraction !== null && activeInteraction !== void 0 && activeInteraction.abortReason) && !isBackgrounded,
|
|
224
|
+
abortReason: isBackgrounded ? 'browser_backgrounded' : dirtyReason !== null && dirtyReason !== void 0 ? dirtyReason : activeInteraction === null || activeInteraction === void 0 ? void 0 : activeInteraction.abortReason,
|
|
225
|
+
vcLogs: enhancedVcLogs,
|
|
226
|
+
interactionId
|
|
227
|
+
};
|
|
228
|
+
} else {
|
|
229
|
+
v3RevisionDebugDetails = {
|
|
230
|
+
revision: this.revisionNo,
|
|
231
|
+
isClean: isVCClean,
|
|
232
|
+
abortReason: dirtyReason,
|
|
233
|
+
vcLogs: enhancedVcLogs,
|
|
234
|
+
interactionId
|
|
235
|
+
};
|
|
236
|
+
}
|
|
209
237
|
}
|
|
210
238
|
|
|
211
239
|
// Handle devtool callback
|
|
@@ -275,6 +303,9 @@ export default class AbstractVCCalculatorBase {
|
|
|
275
303
|
vcDetails: vcDetails !== null && vcDetails !== void 0 ? vcDetails : undefined
|
|
276
304
|
};
|
|
277
305
|
result.ratios = this.calculateRatios(filteredEntries);
|
|
306
|
+
if (isPostInteraction) {
|
|
307
|
+
result.labelStacks = this.getLabelStacks(filteredEntries);
|
|
308
|
+
}
|
|
278
309
|
if (fg('platform_ufo_display_content_track_occurrence')) {
|
|
279
310
|
result.displayContentsOccurrence = cssIssueOccurrence;
|
|
280
311
|
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
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; } } }; }
|
|
2
2
|
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; } }
|
|
3
3
|
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
|
-
|
|
4
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
5
|
+
function getLateMutations(vcDetails) {
|
|
6
|
+
var labelStacks = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
7
|
+
var lastInteractionFinish = arguments.length > 2 ? arguments[2] : undefined;
|
|
8
|
+
var postInteractionFinishVCRatios = arguments.length > 3 ? arguments[3] : undefined;
|
|
5
9
|
// Map to track which elements are already seen for each timestamp
|
|
6
10
|
var seen = new Map();
|
|
7
11
|
var result = [];
|
|
@@ -23,11 +27,19 @@ function getLateMutations(vcDetails, lastInteractionFinish, postInteractionFinis
|
|
|
23
27
|
continue;
|
|
24
28
|
}
|
|
25
29
|
seenElements.add(element);
|
|
26
|
-
|
|
30
|
+
var lateMutation = {
|
|
27
31
|
time: details.t,
|
|
28
32
|
element: element,
|
|
29
33
|
viewportHeatmapPercentage: (postInteractionFinishVCRatios === null || postInteractionFinishVCRatios === void 0 ? void 0 : postInteractionFinishVCRatios[element]) || 0
|
|
30
|
-
}
|
|
34
|
+
};
|
|
35
|
+
if (labelStacks && fg('platform_ufo_enable_late_mutation_label_stacks')) {
|
|
36
|
+
var labels = labelStacks[element];
|
|
37
|
+
if (labels) {
|
|
38
|
+
lateMutation.segment = labels.segment;
|
|
39
|
+
lateMutation.labelStack = labels.labelStack;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
result.push(lateMutation);
|
|
31
43
|
}
|
|
32
44
|
} catch (err) {
|
|
33
45
|
_iterator.e(err);
|
|
@@ -183,8 +183,9 @@ function createPostInteractionLogPayload(_ref2) {
|
|
|
183
183
|
revisedVC90 = (_postInteractionFinis = postInteractionFinishRevision['metric:vc90']) !== null && _postInteractionFinis !== void 0 ? _postInteractionFinis : null;
|
|
184
184
|
}
|
|
185
185
|
var vcDetails = postInteractionFinishRevision.vcDetails;
|
|
186
|
+
var labelStacks = postInteractionFinishRevision.labelStacks;
|
|
186
187
|
if (vcDetails) {
|
|
187
|
-
lateMutations = getLateMutations(vcDetails, lastInteractionFinish, postInteractionFinishVCRatios);
|
|
188
|
+
lateMutations = getLateMutations(vcDetails, labelStacks, lastInteractionFinish, postInteractionFinishVCRatios);
|
|
188
189
|
}
|
|
189
190
|
}
|
|
190
191
|
return {
|
|
@@ -57,6 +57,11 @@ export function setupHiddenTimingCapture() {
|
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
export function getPageVisibilityState(start, end) {
|
|
60
|
+
// Input validation - return default for invalid inputs
|
|
61
|
+
if (!Number.isFinite(start) || !Number.isFinite(end)) {
|
|
62
|
+
return 'visible';
|
|
63
|
+
}
|
|
64
|
+
|
|
60
65
|
// Desirable default value is visible
|
|
61
66
|
if (timings.length === 0) {
|
|
62
67
|
return 'visible';
|
|
@@ -69,19 +74,18 @@ export function getPageVisibilityState(start, end) {
|
|
|
69
74
|
// currentSize is capped at SIZE.
|
|
70
75
|
for (var i = 0; i < currentSize; i++) {
|
|
71
76
|
var tmpIdx = (insertIndex + i) % currentSize;
|
|
72
|
-
|
|
77
|
+
// Add bounds checking before accessing array element
|
|
78
|
+
if (timings[tmpIdx] && timings[tmpIdx].time <= end) {
|
|
73
79
|
endIdx = tmpIdx;
|
|
74
80
|
if (timings[tmpIdx].time <= start) {
|
|
75
81
|
startIdx = tmpIdx;
|
|
76
82
|
}
|
|
77
83
|
}
|
|
78
84
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
hiddenState = 'visible';
|
|
84
|
-
}
|
|
85
|
+
|
|
86
|
+
// Add bounds checking before accessing timings array
|
|
87
|
+
if (endIdx - startIdx === 0 && timings[startIdx]) {
|
|
88
|
+
hiddenState = timings[startIdx].hidden ? 'hidden' : 'visible';
|
|
85
89
|
}
|
|
86
90
|
return hiddenState;
|
|
87
91
|
}
|
|
@@ -5,6 +5,7 @@ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
|
5
5
|
import _createClass from "@babel/runtime/helpers/createClass";
|
|
6
6
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
7
7
|
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
8
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
8
9
|
import { SSRPlaceholderHandlers } from '../vc-observer/observers/ssr-placeholders';
|
|
9
10
|
import EntriesTimeline from './entries-timeline';
|
|
10
11
|
import _getElementName from './get-element-name';
|
|
@@ -68,18 +69,27 @@ var VCObserverNew = /*#__PURE__*/function () {
|
|
|
68
69
|
if (element) {
|
|
69
70
|
elementName = _this.getElementName(element);
|
|
70
71
|
}
|
|
72
|
+
var data = {
|
|
73
|
+
type: type,
|
|
74
|
+
elementName: elementName,
|
|
75
|
+
rect: rect,
|
|
76
|
+
previousRect: previousRect,
|
|
77
|
+
visible: visible,
|
|
78
|
+
attributeName: mutationData === null || mutationData === void 0 ? void 0 : mutationData.attributeName,
|
|
79
|
+
oldValue: mutationData === null || mutationData === void 0 ? void 0 : mutationData.oldValue,
|
|
80
|
+
newValue: mutationData === null || mutationData === void 0 ? void 0 : mutationData.newValue
|
|
81
|
+
};
|
|
82
|
+
if (element && _this.isPostInteraction && fg('platform_ufo_enable_late_mutation_label_stacks')) {
|
|
83
|
+
var labelStacks = getLabelStacks(element);
|
|
84
|
+
if (labelStacks) {
|
|
85
|
+
Object.assign(data, {
|
|
86
|
+
labelStacks: labelStacks
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
71
90
|
_this.entriesTimeline.push({
|
|
72
91
|
time: time,
|
|
73
|
-
data:
|
|
74
|
-
type: type,
|
|
75
|
-
elementName: elementName,
|
|
76
|
-
rect: rect,
|
|
77
|
-
previousRect: previousRect,
|
|
78
|
-
visible: visible,
|
|
79
|
-
attributeName: mutationData === null || mutationData === void 0 ? void 0 : mutationData.attributeName,
|
|
80
|
-
oldValue: mutationData === null || mutationData === void 0 ? void 0 : mutationData.oldValue,
|
|
81
|
-
newValue: mutationData === null || mutationData === void 0 ? void 0 : mutationData.newValue
|
|
82
|
-
}
|
|
92
|
+
data: data
|
|
83
93
|
});
|
|
84
94
|
},
|
|
85
95
|
// Pass SSR context to ViewportObserver
|
|
@@ -302,4 +312,57 @@ var VCObserverNew = /*#__PURE__*/function () {
|
|
|
302
312
|
}
|
|
303
313
|
}]);
|
|
304
314
|
}();
|
|
305
|
-
export { VCObserverNew as default };
|
|
315
|
+
export { VCObserverNew as default };
|
|
316
|
+
function labelStackFromFiber(fiber) {
|
|
317
|
+
var _fiber$child;
|
|
318
|
+
var value = fiber === null || fiber === void 0 || (_fiber$child = fiber.child) === null || _fiber$child === void 0 || (_fiber$child = _fiber$child.memoizedProps) === null || _fiber$child === void 0 ? void 0 : _fiber$child.value;
|
|
319
|
+
return Array.isArray(value === null || value === void 0 ? void 0 : value.labelStack) ? value.labelStack : [];
|
|
320
|
+
}
|
|
321
|
+
function labelStackToString(labelStack) {
|
|
322
|
+
return labelStack.map(function (label) {
|
|
323
|
+
return label.name;
|
|
324
|
+
}).join('/');
|
|
325
|
+
}
|
|
326
|
+
function labelStackToSegment(labelStack) {
|
|
327
|
+
var segmentIndex = -1;
|
|
328
|
+
for (var i = labelStack.length - 1; i >= 0; i--) {
|
|
329
|
+
if (labelStack[i].segmentId) {
|
|
330
|
+
segmentIndex = i;
|
|
331
|
+
break;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return labelStack.slice(0, segmentIndex + 1).map(function (label) {
|
|
335
|
+
return label.name;
|
|
336
|
+
}).join('/');
|
|
337
|
+
}
|
|
338
|
+
function traverseFiber(fiber) {
|
|
339
|
+
var segment = 'unknown';
|
|
340
|
+
var labelStackString = 'unknown';
|
|
341
|
+
var currentFiber = fiber;
|
|
342
|
+
while (currentFiber) {
|
|
343
|
+
if (currentFiber.type) {
|
|
344
|
+
var componentName = currentFiber.type.displayName || currentFiber.type.name;
|
|
345
|
+
if (componentName === 'UFOSegment' || componentName === 'UFOLabel') {
|
|
346
|
+
var labelStack = labelStackFromFiber(currentFiber);
|
|
347
|
+
labelStackString = labelStackToString(labelStack) || 'unknown';
|
|
348
|
+
segment = labelStackToSegment(labelStack) || 'unknown';
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
currentFiber = currentFiber.return;
|
|
353
|
+
}
|
|
354
|
+
return {
|
|
355
|
+
segment: segment,
|
|
356
|
+
labelStack: labelStackString
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
function getLabelStacks(element) {
|
|
360
|
+
var reactFiberKey = Object.keys(element).find(function (key) {
|
|
361
|
+
return key.startsWith('__reactFiber$');
|
|
362
|
+
});
|
|
363
|
+
if (!reactFiberKey) {
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
var fiber = element[reactFiberKey];
|
|
367
|
+
return fiber ? traverseFiber(fiber) : null;
|
|
368
|
+
}
|
|
@@ -11,6 +11,9 @@ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol
|
|
|
11
11
|
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; } }
|
|
12
12
|
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; }
|
|
13
13
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
14
|
+
import getPageVisibilityUpToTTAI from '../../../create-payload/utils/get-page-visibility-up-to-ttai';
|
|
15
|
+
import { getInteractionId } from '../../../interaction-id-context';
|
|
16
|
+
import { interactions } from '../../../interaction-metrics/common/constants';
|
|
14
17
|
import { cssIssueOccurrence } from '../viewport-observer/utils/track-display-content-occurrence';
|
|
15
18
|
import { calculateTTVCPercentilesWithDebugInfo } from './percentile-calc';
|
|
16
19
|
import getViewportHeight from './utils/get-viewport-height';
|
|
@@ -76,21 +79,41 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
|
|
|
76
79
|
}
|
|
77
80
|
return ratios;
|
|
78
81
|
}
|
|
82
|
+
}, {
|
|
83
|
+
key: "getLabelStacks",
|
|
84
|
+
value: function getLabelStacks(filteredEntries) {
|
|
85
|
+
var labelStacks = {};
|
|
86
|
+
var _iterator3 = _createForOfIteratorHelper(filteredEntries),
|
|
87
|
+
_step3;
|
|
88
|
+
try {
|
|
89
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
90
|
+
var _entry2 = _step3.value;
|
|
91
|
+
if ('elementName' in _entry2.data && _entry2.data.labelStacks) {
|
|
92
|
+
labelStacks[_entry2.data.elementName] = {
|
|
93
|
+
segment: _entry2.data.labelStacks.segment,
|
|
94
|
+
labelStack: _entry2.data.labelStacks.labelStack
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
} catch (err) {
|
|
99
|
+
_iterator3.e(err);
|
|
100
|
+
} finally {
|
|
101
|
+
_iterator3.f();
|
|
102
|
+
}
|
|
103
|
+
return labelStacks;
|
|
104
|
+
}
|
|
79
105
|
}, {
|
|
80
106
|
key: "calculateWithDebugInfo",
|
|
81
107
|
value: function () {
|
|
82
108
|
var _calculateWithDebugInfo = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(filteredEntries, startTime, stopTime, isPostInteraction, isVCClean, interactionId, dirtyReason, allEntries, include3p) {
|
|
83
109
|
var _window, _window2, _window3, _window5;
|
|
84
|
-
var percentiles, viewportEntries, vcLogs, vcDetails, percentileIndex, entryDataBuffer,
|
|
110
|
+
var percentiles, viewportEntries, vcLogs, vcDetails, percentileIndex, entryDataBuffer, _iterator4, _step4, _entry3, time, viewportPercentage, entries, elementNames, previousResult, i, percentile, enhancedVcLogs, shouldCalculate3p, shouldCalculateDebugDetails, sortedVcLogs, maxViewportPercentageAtTime, maxSoFar, _iterator5, _step5, log, getBiggestPreviousViewportPercentage, ignoredEntriesByTime, _iterator6, _step6, _entry4, _ignoredEntriesByTime, _viewportData$rect, _viewportData$previou, viewportData, timestamp, additionalVcLogs, _iterator7, _step7, _step7$value, _timestamp, ignoredEntries, _viewportPercentage, v3RevisionDebugDetails, _activeInteractionId$, activeInteractionId, activeInteraction, pageVisibilityUpToTTAI, isBackgrounded, _window4, _window4$__ufo_devtoo, _window6, _window6$__on_ufo_vc_;
|
|
85
111
|
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
86
112
|
while (1) switch (_context.prev = _context.next) {
|
|
87
113
|
case 0:
|
|
88
|
-
percentiles = [25, 50, 75, 80, 85, 90, 95, 98, 99];
|
|
89
|
-
if (fg('platform_ufo_send_vc_100')) {
|
|
90
|
-
percentiles.push(100);
|
|
91
|
-
}
|
|
114
|
+
percentiles = [25, 50, 75, 80, 85, 90, 95, 98, 99, 100];
|
|
92
115
|
viewportEntries = this.filterViewportEntries(filteredEntries);
|
|
93
|
-
_context.next =
|
|
116
|
+
_context.next = 4;
|
|
94
117
|
return calculateTTVCPercentilesWithDebugInfo({
|
|
95
118
|
viewport: {
|
|
96
119
|
width: getViewportWidth(),
|
|
@@ -100,31 +123,31 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
|
|
|
100
123
|
stopTime: stopTime,
|
|
101
124
|
orderedEntries: viewportEntries
|
|
102
125
|
});
|
|
103
|
-
case
|
|
126
|
+
case 4:
|
|
104
127
|
vcLogs = _context.sent;
|
|
105
128
|
vcDetails = {};
|
|
106
129
|
percentileIndex = 0;
|
|
107
130
|
entryDataBuffer = new Set();
|
|
108
131
|
if (!vcLogs) {
|
|
109
|
-
_context.next =
|
|
132
|
+
_context.next = 28;
|
|
110
133
|
break;
|
|
111
134
|
}
|
|
112
|
-
|
|
113
|
-
_context.prev =
|
|
114
|
-
|
|
115
|
-
case
|
|
116
|
-
if ((
|
|
117
|
-
_context.next =
|
|
135
|
+
_iterator4 = _createForOfIteratorHelper(vcLogs);
|
|
136
|
+
_context.prev = 10;
|
|
137
|
+
_iterator4.s();
|
|
138
|
+
case 12:
|
|
139
|
+
if ((_step4 = _iterator4.n()).done) {
|
|
140
|
+
_context.next = 20;
|
|
118
141
|
break;
|
|
119
142
|
}
|
|
120
|
-
|
|
121
|
-
time =
|
|
143
|
+
_entry3 = _step4.value;
|
|
144
|
+
time = _entry3.time, viewportPercentage = _entry3.viewportPercentage, entries = _entry3.entries; // Only process entries if we haven't reached all percentiles
|
|
122
145
|
if (!(percentileIndex >= percentiles.length)) {
|
|
123
|
-
_context.next =
|
|
146
|
+
_context.next = 17;
|
|
124
147
|
break;
|
|
125
148
|
}
|
|
126
|
-
return _context.abrupt("break",
|
|
127
|
-
case
|
|
149
|
+
return _context.abrupt("break", 20);
|
|
150
|
+
case 17:
|
|
128
151
|
// Check if this entry matches any checkpoint percentiles
|
|
129
152
|
if (viewportPercentage >= percentiles[percentileIndex]) {
|
|
130
153
|
elementNames = entries.map(function (e) {
|
|
@@ -146,21 +169,21 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
|
|
|
146
169
|
return entryDataBuffer.add(e);
|
|
147
170
|
});
|
|
148
171
|
}
|
|
149
|
-
case
|
|
150
|
-
_context.next =
|
|
172
|
+
case 18:
|
|
173
|
+
_context.next = 12;
|
|
151
174
|
break;
|
|
152
|
-
case
|
|
153
|
-
_context.next =
|
|
175
|
+
case 20:
|
|
176
|
+
_context.next = 25;
|
|
154
177
|
break;
|
|
155
|
-
case
|
|
156
|
-
_context.prev =
|
|
157
|
-
_context.t0 = _context["catch"](
|
|
158
|
-
|
|
159
|
-
case
|
|
160
|
-
_context.prev =
|
|
161
|
-
|
|
162
|
-
return _context.finish(
|
|
163
|
-
case
|
|
178
|
+
case 22:
|
|
179
|
+
_context.prev = 22;
|
|
180
|
+
_context.t0 = _context["catch"](10);
|
|
181
|
+
_iterator4.e(_context.t0);
|
|
182
|
+
case 25:
|
|
183
|
+
_context.prev = 25;
|
|
184
|
+
_iterator4.f();
|
|
185
|
+
return _context.finish(25);
|
|
186
|
+
case 28:
|
|
164
187
|
// Fill in any missing percentiles with the last known values
|
|
165
188
|
previousResult = {
|
|
166
189
|
t: 0,
|
|
@@ -196,10 +219,10 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
|
|
|
196
219
|
}); // Pre-calculate max viewport percentage up to each time for efficient lookups
|
|
197
220
|
maxViewportPercentageAtTime = new Map();
|
|
198
221
|
maxSoFar = 0;
|
|
199
|
-
|
|
222
|
+
_iterator5 = _createForOfIteratorHelper(sortedVcLogs);
|
|
200
223
|
try {
|
|
201
|
-
for (
|
|
202
|
-
log =
|
|
224
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
225
|
+
log = _step5.value;
|
|
203
226
|
if (log.viewportPercentage !== null) {
|
|
204
227
|
maxSoFar = Math.max(maxSoFar, log.viewportPercentage);
|
|
205
228
|
maxViewportPercentageAtTime.set(log.time, maxSoFar);
|
|
@@ -208,9 +231,9 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
|
|
|
208
231
|
|
|
209
232
|
// Helper function to find the biggest previous viewport percentage
|
|
210
233
|
} catch (err) {
|
|
211
|
-
|
|
234
|
+
_iterator5.e(err);
|
|
212
235
|
} finally {
|
|
213
|
-
|
|
236
|
+
_iterator5.f();
|
|
214
237
|
}
|
|
215
238
|
getBiggestPreviousViewportPercentage = function getBiggestPreviousViewportPercentage(targetTime) {
|
|
216
239
|
// Binary search for the largest time <= targetTime
|
|
@@ -229,13 +252,13 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
|
|
|
229
252
|
return result >= 0 ? maxViewportPercentageAtTime.get(sortedVcLogs[result].time) || null : null;
|
|
230
253
|
}; // Group ignored entries by timestamp
|
|
231
254
|
ignoredEntriesByTime = new Map();
|
|
232
|
-
|
|
255
|
+
_iterator6 = _createForOfIteratorHelper(allEntries);
|
|
233
256
|
try {
|
|
234
|
-
for (
|
|
235
|
-
|
|
236
|
-
if ('rect' in
|
|
237
|
-
viewportData =
|
|
238
|
-
timestamp = Math.round(
|
|
257
|
+
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
258
|
+
_entry4 = _step6.value;
|
|
259
|
+
if ('rect' in _entry4.data && !this.isEntryIncluded(_entry4, include3p)) {
|
|
260
|
+
viewportData = _entry4.data;
|
|
261
|
+
timestamp = Math.round(_entry4.time);
|
|
239
262
|
if (!ignoredEntriesByTime.has(timestamp)) {
|
|
240
263
|
ignoredEntriesByTime.set(timestamp, []);
|
|
241
264
|
}
|
|
@@ -250,15 +273,15 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
|
|
|
250
273
|
|
|
251
274
|
// Add ignored entries to vcLogs
|
|
252
275
|
} catch (err) {
|
|
253
|
-
|
|
276
|
+
_iterator6.e(err);
|
|
254
277
|
} finally {
|
|
255
|
-
|
|
278
|
+
_iterator6.f();
|
|
256
279
|
}
|
|
257
280
|
additionalVcLogs = [];
|
|
258
|
-
|
|
281
|
+
_iterator7 = _createForOfIteratorHelper(ignoredEntriesByTime);
|
|
259
282
|
try {
|
|
260
|
-
for (
|
|
261
|
-
|
|
283
|
+
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
|
284
|
+
_step7$value = _slicedToArray(_step7.value, 2), _timestamp = _step7$value[0], ignoredEntries = _step7$value[1];
|
|
262
285
|
if (ignoredEntries.length > 0) {
|
|
263
286
|
_viewportPercentage = getBiggestPreviousViewportPercentage(_timestamp);
|
|
264
287
|
additionalVcLogs.push({
|
|
@@ -271,9 +294,9 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
|
|
|
271
294
|
|
|
272
295
|
// Combine and sort all vcLogs
|
|
273
296
|
} catch (err) {
|
|
274
|
-
|
|
297
|
+
_iterator7.e(err);
|
|
275
298
|
} finally {
|
|
276
|
-
|
|
299
|
+
_iterator7.f();
|
|
277
300
|
}
|
|
278
301
|
enhancedVcLogs = [].concat(_toConsumableArray(enhancedVcLogs), additionalVcLogs).sort(function (a, b) {
|
|
279
302
|
return a.time - b.time;
|
|
@@ -283,13 +306,28 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
|
|
|
283
306
|
// Only create debug details if callbacks exist
|
|
284
307
|
v3RevisionDebugDetails = null;
|
|
285
308
|
if (shouldCalculateDebugDetails) {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
309
|
+
if (fg('platform_ufo_unify_abort_status_in_ttvc_debug_data')) {
|
|
310
|
+
// NOTE: using this instead of directly calling `getActiveInteraction()` to get around circular dependencies
|
|
311
|
+
activeInteractionId = getInteractionId();
|
|
312
|
+
activeInteraction = interactions.get((_activeInteractionId$ = activeInteractionId.current) !== null && _activeInteractionId$ !== void 0 ? _activeInteractionId$ : '');
|
|
313
|
+
pageVisibilityUpToTTAI = activeInteraction ? getPageVisibilityUpToTTAI(activeInteraction) : null;
|
|
314
|
+
isBackgrounded = pageVisibilityUpToTTAI !== 'visible';
|
|
315
|
+
v3RevisionDebugDetails = {
|
|
316
|
+
revision: this.revisionNo,
|
|
317
|
+
isClean: isVCClean && !(activeInteraction !== null && activeInteraction !== void 0 && activeInteraction.abortReason) && !isBackgrounded,
|
|
318
|
+
abortReason: isBackgrounded ? 'browser_backgrounded' : dirtyReason !== null && dirtyReason !== void 0 ? dirtyReason : activeInteraction === null || activeInteraction === void 0 ? void 0 : activeInteraction.abortReason,
|
|
319
|
+
vcLogs: enhancedVcLogs,
|
|
320
|
+
interactionId: interactionId
|
|
321
|
+
};
|
|
322
|
+
} else {
|
|
323
|
+
v3RevisionDebugDetails = {
|
|
324
|
+
revision: this.revisionNo,
|
|
325
|
+
isClean: isVCClean,
|
|
326
|
+
abortReason: dirtyReason,
|
|
327
|
+
vcLogs: enhancedVcLogs,
|
|
328
|
+
interactionId: interactionId
|
|
329
|
+
};
|
|
330
|
+
}
|
|
293
331
|
}
|
|
294
332
|
|
|
295
333
|
// Handle devtool callback
|
|
@@ -320,11 +358,11 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
|
|
|
320
358
|
}
|
|
321
359
|
}
|
|
322
360
|
return _context.abrupt("return", vcDetails);
|
|
323
|
-
case
|
|
361
|
+
case 40:
|
|
324
362
|
case "end":
|
|
325
363
|
return _context.stop();
|
|
326
364
|
}
|
|
327
|
-
}, _callee, this, [[
|
|
365
|
+
}, _callee, this, [[10, 22, 25, 28]]);
|
|
328
366
|
}));
|
|
329
367
|
function calculateWithDebugInfo(_x, _x2, _x3, _x4, _x5, _x6, _x7, _x8, _x9) {
|
|
330
368
|
return _calculateWithDebugInfo.apply(this, arguments);
|
|
@@ -373,11 +411,14 @@ var AbstractVCCalculatorBase = /*#__PURE__*/function () {
|
|
|
373
411
|
vcDetails: vcDetails !== null && vcDetails !== void 0 ? vcDetails : undefined
|
|
374
412
|
};
|
|
375
413
|
result.ratios = this.calculateRatios(filteredEntries);
|
|
414
|
+
if (isPostInteraction) {
|
|
415
|
+
result.labelStacks = this.getLabelStacks(filteredEntries);
|
|
416
|
+
}
|
|
376
417
|
if (fg('platform_ufo_display_content_track_occurrence')) {
|
|
377
418
|
result.displayContentsOccurrence = cssIssueOccurrence;
|
|
378
419
|
}
|
|
379
420
|
return _context2.abrupt("return", result);
|
|
380
|
-
case
|
|
421
|
+
case 15:
|
|
381
422
|
case "end":
|
|
382
423
|
return _context2.stop();
|
|
383
424
|
}
|