@atlaskit/react-ufo 3.3.1 → 3.3.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 +16 -0
- package/dist/cjs/create-payload/index.js +106 -163
- package/dist/cjs/create-payload/utils/get-interaction-status.js +37 -0
- package/dist/cjs/create-payload/utils/get-page-visibility-up-to-ttai.js +12 -0
- package/dist/cjs/create-payload/utils/get-ssr-done-time-value.js +14 -0
- package/dist/cjs/create-payload/utils/get-vc-metrics.js +96 -0
- package/dist/cjs/interaction-metrics-init/index.js +11 -9
- package/dist/cjs/vc/index.js +6 -2
- package/dist/cjs/vc/vc-observer-new/get-element-name.js +19 -6
- package/dist/cjs/vc/vc-observer-new/index.js +6 -3
- package/dist/cjs/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +4 -2
- package/dist/cjs/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/canvas-pixel.js +10 -11
- package/dist/cjs/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/index.js +23 -30
- package/dist/cjs/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/index.js +7 -7
- package/dist/cjs/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/index.js +3 -3
- package/dist/cjs/vc/vc-observer-new/window-event-observer/index.js +5 -1
- package/dist/es2019/create-payload/index.js +14 -73
- package/dist/es2019/create-payload/utils/get-interaction-status.js +31 -0
- package/dist/es2019/create-payload/utils/get-page-visibility-up-to-ttai.js +8 -0
- package/dist/es2019/create-payload/utils/get-ssr-done-time-value.js +5 -0
- package/dist/es2019/create-payload/utils/get-vc-metrics.js +53 -0
- package/dist/es2019/interaction-metrics-init/index.js +11 -9
- package/dist/es2019/vc/index.js +6 -2
- package/dist/es2019/vc/vc-observer-new/get-element-name.js +19 -6
- package/dist/es2019/vc/vc-observer-new/index.js +7 -3
- package/dist/es2019/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +4 -0
- package/dist/es2019/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/canvas-pixel.js +1 -2
- package/dist/es2019/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/index.js +15 -12
- package/dist/es2019/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/index.js +5 -4
- package/dist/es2019/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/index.js +3 -2
- package/dist/es2019/vc/vc-observer-new/window-event-observer/index.js +5 -1
- package/dist/esm/create-payload/index.js +99 -156
- package/dist/esm/create-payload/utils/get-interaction-status.js +31 -0
- package/dist/esm/create-payload/utils/get-page-visibility-up-to-ttai.js +6 -0
- package/dist/esm/create-payload/utils/get-ssr-done-time-value.js +5 -0
- package/dist/esm/create-payload/utils/get-vc-metrics.js +89 -0
- package/dist/esm/interaction-metrics-init/index.js +11 -9
- package/dist/esm/vc/index.js +6 -2
- package/dist/esm/vc/vc-observer-new/get-element-name.js +19 -6
- package/dist/esm/vc/vc-observer-new/index.js +6 -3
- package/dist/esm/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.js +4 -2
- package/dist/esm/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/canvas-pixel.js +10 -11
- package/dist/esm/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/index.js +23 -30
- package/dist/esm/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/index.js +7 -7
- package/dist/esm/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/index.js +3 -3
- package/dist/esm/vc/vc-observer-new/window-event-observer/index.js +5 -1
- package/dist/types/config/index.d.ts +1 -0
- package/dist/types/create-payload/index.d.ts +1 -1
- package/dist/types/create-payload/utils/get-interaction-status.d.ts +27 -0
- package/dist/types/create-payload/utils/get-page-visibility-up-to-ttai.d.ts +2 -0
- package/dist/types/create-payload/utils/get-ssr-done-time-value.d.ts +2 -0
- package/dist/types/create-payload/utils/get-vc-metrics.d.ts +5 -0
- package/dist/types/vc/vc-observer-new/index.d.ts +3 -2
- package/dist/types/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +1 -1
- package/dist/types/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/index.d.ts +2 -2
- package/dist/types/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/index.d.ts +2 -1
- package/dist/types/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/index.d.ts +2 -1
- package/dist/types/vc/vc-observer-new/metric-calculator/percentile-calc/types.d.ts +2 -0
- package/dist/types/vc/vc-observer-new/metric-calculator/types.d.ts +2 -0
- package/dist/types-ts4.5/config/index.d.ts +1 -0
- package/dist/types-ts4.5/create-payload/index.d.ts +1 -1
- package/dist/types-ts4.5/create-payload/utils/get-interaction-status.d.ts +27 -0
- package/dist/types-ts4.5/create-payload/utils/get-page-visibility-up-to-ttai.d.ts +2 -0
- package/dist/types-ts4.5/create-payload/utils/get-ssr-done-time-value.d.ts +2 -0
- package/dist/types-ts4.5/create-payload/utils/get-vc-metrics.d.ts +5 -0
- package/dist/types-ts4.5/vc/vc-observer-new/index.d.ts +3 -2
- package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +1 -1
- package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/index.d.ts +2 -2
- package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/index.d.ts +2 -1
- package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/index.d.ts +2 -1
- package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/percentile-calc/types.d.ts +2 -0
- package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/types.d.ts +2 -0
- package/package.json +5 -2
|
@@ -11,12 +11,15 @@ import { getBm3Timings } from '../custom-timings';
|
|
|
11
11
|
import { getGlobalErrorCount } from '../global-error-handler';
|
|
12
12
|
import { getPageVisibilityState } from '../hidden-timing';
|
|
13
13
|
import * as initialPageLoadExtraTiming from '../initial-page-load-extra-timing';
|
|
14
|
-
import { interactionSpans as atlaskitInteractionSpans
|
|
14
|
+
import { interactionSpans as atlaskitInteractionSpans } from '../interaction-metrics';
|
|
15
15
|
import * as resourceTiming from '../resource-timing';
|
|
16
16
|
import { roundEpsilon } from '../round-number';
|
|
17
17
|
import * as ssr from '../ssr';
|
|
18
|
-
import { getVCObserver } from '../vc';
|
|
19
18
|
import { buildSegmentTree, labelStackStartWith, optimizeLabelStack, sanitizeUfoName, stringifyLabelStackFully } from './common/utils';
|
|
19
|
+
import getInteractionStatus from './utils/get-interaction-status';
|
|
20
|
+
import getPageVisibilityUpToTTAI from './utils/get-page-visibility-up-to-ttai';
|
|
21
|
+
import getSSRDoneTimeValue from './utils/get-ssr-done-time-value';
|
|
22
|
+
import getVCMetrics from './utils/get-vc-metrics';
|
|
20
23
|
function getUfoNameOverride(interaction) {
|
|
21
24
|
const {
|
|
22
25
|
ufoName,
|
|
@@ -65,13 +68,6 @@ const getPageVisibilityUpToTTI = interaction => {
|
|
|
65
68
|
const bm3EndTimeOrInteractionEndTime = getBm3EndTimeOrFallbackValue(interaction);
|
|
66
69
|
return getPageVisibilityState(start, bm3EndTimeOrInteractionEndTime);
|
|
67
70
|
};
|
|
68
|
-
const getPageVisibilityUpToTTAI = interaction => {
|
|
69
|
-
const {
|
|
70
|
-
start,
|
|
71
|
-
end
|
|
72
|
-
} = interaction;
|
|
73
|
-
return getPageVisibilityState(start, end);
|
|
74
|
-
};
|
|
75
71
|
const getVisibilityStateFromPerformance = stop => {
|
|
76
72
|
try {
|
|
77
73
|
const results = performance.getEntriesByType('visibility-state');
|
|
@@ -126,15 +122,6 @@ const getMoreAccuratePageVisibilityUpToTTAI = interaction => {
|
|
|
126
122
|
}
|
|
127
123
|
return old;
|
|
128
124
|
};
|
|
129
|
-
const getInteractionStatus = interaction => {
|
|
130
|
-
const originalInteractionStatus = interaction.abortReason ? 'ABORTED' : 'SUCCEEDED';
|
|
131
|
-
const hasBm3TTI = interaction.apdex.length > 0;
|
|
132
|
-
const overrideStatus = hasBm3TTI ? 'SUCCEEDED' : originalInteractionStatus;
|
|
133
|
-
return {
|
|
134
|
-
originalInteractionStatus,
|
|
135
|
-
overrideStatus
|
|
136
|
-
};
|
|
137
|
-
};
|
|
138
125
|
const getResourceTimings = (start, end) => {
|
|
139
126
|
var _resourceTiming$getRe;
|
|
140
127
|
return (_resourceTiming$getRe = resourceTiming.getResourceTimings(start, end)) !== null && _resourceTiming$getRe !== void 0 ? _resourceTiming$getRe : undefined;
|
|
@@ -165,49 +152,6 @@ const getTTAI = interaction => {
|
|
|
165
152
|
const pageVisibilityUpToTTAI = getPageVisibilityUpToTTAI(interaction);
|
|
166
153
|
return !interaction.abortReason && pageVisibilityUpToTTAI === 'visible' ? Math.round(end - start) : undefined;
|
|
167
154
|
};
|
|
168
|
-
const getVCMetrics = async interaction => {
|
|
169
|
-
var _config$vc, _config$vc$ssrWhiteli, _interaction$apdex, _interaction$apdex$, _config$experimentalI;
|
|
170
|
-
const config = getConfig();
|
|
171
|
-
if (!(config !== null && config !== void 0 && (_config$vc = config.vc) !== null && _config$vc !== void 0 && _config$vc.enabled)) {
|
|
172
|
-
return {};
|
|
173
|
-
}
|
|
174
|
-
if (interaction.type !== 'page_load' && interaction.type !== 'transition') {
|
|
175
|
-
return {};
|
|
176
|
-
}
|
|
177
|
-
const isSSREnabled = (config === null || config === void 0 ? void 0 : config.ssr) || (config === null || config === void 0 ? void 0 : (_config$vc$ssrWhiteli = config.vc.ssrWhitelist) === null || _config$vc$ssrWhiteli === void 0 ? void 0 : _config$vc$ssrWhiteli.includes(interaction.ufoName));
|
|
178
|
-
const ssr = interaction.type === 'page_load' && isSSREnabled ? {
|
|
179
|
-
ssr: getSSRDoneTimeValue(config)
|
|
180
|
-
} : null;
|
|
181
|
-
postInteractionLog.setVCObserverSSRConfig(ssr);
|
|
182
|
-
const tti = (_interaction$apdex = interaction.apdex) === null || _interaction$apdex === void 0 ? void 0 : (_interaction$apdex$ = _interaction$apdex[0]) === null || _interaction$apdex$ === void 0 ? void 0 : _interaction$apdex$.stopTime;
|
|
183
|
-
const prefix = 'ufo';
|
|
184
|
-
const interactionStatus = getInteractionStatus(interaction);
|
|
185
|
-
const pageVisibilityUpToTTAI = getPageVisibilityUpToTTAI(interaction);
|
|
186
|
-
const result = await getVCObserver().getVCResult({
|
|
187
|
-
start: interaction.start,
|
|
188
|
-
stop: interaction.end,
|
|
189
|
-
tti,
|
|
190
|
-
prefix,
|
|
191
|
-
vc: interaction.vc,
|
|
192
|
-
isEventAborted: interactionStatus.originalInteractionStatus !== 'SUCCEEDED',
|
|
193
|
-
...ssr
|
|
194
|
-
});
|
|
195
|
-
if ((_config$experimentalI = config.experimentalInteractionMetrics) !== null && _config$experimentalI !== void 0 && _config$experimentalI.enabled) {
|
|
196
|
-
getVCObserver().stop();
|
|
197
|
-
}
|
|
198
|
-
postInteractionLog.setLastInteractionFinishVCResult(result);
|
|
199
|
-
const VC = result === null || result === void 0 ? void 0 : result['metrics:vc'];
|
|
200
|
-
if (!VC || !(result !== null && result !== void 0 && result[`${prefix}:vc:clean`])) {
|
|
201
|
-
return result;
|
|
202
|
-
}
|
|
203
|
-
if (interactionStatus.originalInteractionStatus !== 'SUCCEEDED' || pageVisibilityUpToTTAI !== 'visible') {
|
|
204
|
-
return result;
|
|
205
|
-
}
|
|
206
|
-
return {
|
|
207
|
-
...result,
|
|
208
|
-
'metric:vc90': VC['90']
|
|
209
|
-
};
|
|
210
|
-
};
|
|
211
155
|
const getNavigationMetrics = type => {
|
|
212
156
|
if (type !== 'page_load') {
|
|
213
157
|
return {};
|
|
@@ -255,7 +199,7 @@ const getNavigationMetrics = type => {
|
|
|
255
199
|
};
|
|
256
200
|
};
|
|
257
201
|
const getPPSMetrics = interaction => {
|
|
258
|
-
var _interaction$
|
|
202
|
+
var _interaction$apdex, _interaction$apdex$;
|
|
259
203
|
const {
|
|
260
204
|
start,
|
|
261
205
|
end
|
|
@@ -263,7 +207,7 @@ const getPPSMetrics = interaction => {
|
|
|
263
207
|
const config = getConfig();
|
|
264
208
|
const interactionStatus = getInteractionStatus(interaction);
|
|
265
209
|
const pageVisibilityUpToTTAI = getPageVisibilityUpToTTAI(interaction);
|
|
266
|
-
const tti = (_interaction$
|
|
210
|
+
const tti = (_interaction$apdex = interaction.apdex) === null || _interaction$apdex === void 0 ? void 0 : (_interaction$apdex$ = _interaction$apdex[0]) === null || _interaction$apdex$ === void 0 ? void 0 : _interaction$apdex$.stopTime;
|
|
267
211
|
const ttai = interactionStatus.originalInteractionStatus === 'SUCCEEDED' && pageVisibilityUpToTTAI === 'visible' ? Math.round(end - start) : undefined;
|
|
268
212
|
const PPSMetricsAtTTI = tti !== undefined ? getLighthouseMetrics({
|
|
269
213
|
start,
|
|
@@ -635,10 +579,6 @@ function getBm3TrackerTimings(interaction) {
|
|
|
635
579
|
legacyMetrics
|
|
636
580
|
};
|
|
637
581
|
}
|
|
638
|
-
function getSSRDoneTimeValue(config) {
|
|
639
|
-
var _config$ssr, _config$ssr2;
|
|
640
|
-
return config !== null && config !== void 0 && (_config$ssr = config.ssr) !== null && _config$ssr !== void 0 && _config$ssr.getSSRDoneTime ? config === null || config === void 0 ? void 0 : (_config$ssr2 = config.ssr) === null || _config$ssr2 === void 0 ? void 0 : _config$ssr2.getSSRDoneTime() : ssr.getSSRDoneTime();
|
|
641
|
-
}
|
|
642
582
|
function getPayloadSize(payload) {
|
|
643
583
|
return Math.round(new TextEncoder().encode(JSON.stringify(payload)).length / 1024);
|
|
644
584
|
}
|
|
@@ -725,7 +665,7 @@ async function createInteractionMetricsPayload(interaction, interactionId, exper
|
|
|
725
665
|
} : {};
|
|
726
666
|
// Page Load
|
|
727
667
|
const getPageLoadInteractionMetrics = () => {
|
|
728
|
-
var _config$
|
|
668
|
+
var _config$ssr;
|
|
729
669
|
if (!isPageLoad) {
|
|
730
670
|
return {};
|
|
731
671
|
}
|
|
@@ -737,7 +677,7 @@ async function createInteractionMetricsPayload(interaction, interactionId, exper
|
|
|
737
677
|
return {
|
|
738
678
|
...SSRDoneTime,
|
|
739
679
|
isBM3ConfigSSRDoneAsFmp: interaction.metaData.__legacy__bm3ConfigSSRDoneAsFmp,
|
|
740
|
-
isUFOConfigSSRDoneAsFmp: interaction.metaData.__legacy__bm3ConfigSSRDoneAsFmp || !!(config !== null && config !== void 0 && (_config$
|
|
680
|
+
isUFOConfigSSRDoneAsFmp: interaction.metaData.__legacy__bm3ConfigSSRDoneAsFmp || !!(config !== null && config !== void 0 && (_config$ssr = config.ssr) !== null && _config$ssr !== void 0 && _config$ssr.getSSRDoneTime)
|
|
741
681
|
};
|
|
742
682
|
};
|
|
743
683
|
// Detailed payload. Page visibility = visible
|
|
@@ -767,14 +707,14 @@ async function createInteractionMetricsPayload(interaction, interactionId, exper
|
|
|
767
707
|
};
|
|
768
708
|
// Page load & detailed payload
|
|
769
709
|
const getPageLoadDetailedInteractionMetrics = () => {
|
|
770
|
-
var _config$
|
|
710
|
+
var _config$ssr2;
|
|
771
711
|
if (!isPageLoad || !isDetailedPayload) {
|
|
772
712
|
return {};
|
|
773
713
|
}
|
|
774
714
|
const config = getConfig();
|
|
775
715
|
return {
|
|
776
716
|
initialPageLoadExtraTimings: objectToArray(initialPageLoadExtraTiming.getTimings()),
|
|
777
|
-
SSRTimings: config !== null && config !== void 0 && (_config$
|
|
717
|
+
SSRTimings: config !== null && config !== void 0 && (_config$ssr2 = config.ssr) !== null && _config$ssr2 !== void 0 && _config$ssr2.getSSRTimings ? config.ssr.getSSRTimings() : objectToArray(ssr.getSSRTimings())
|
|
778
718
|
};
|
|
779
719
|
};
|
|
780
720
|
if (experimental) {
|
|
@@ -877,7 +817,7 @@ export async function createPayloads(interactionId, interaction) {
|
|
|
877
817
|
const interactionMetricsPayload = await createInteractionMetricsPayload(modifiedInteraction, interactionId);
|
|
878
818
|
return [interactionMetricsPayload];
|
|
879
819
|
}
|
|
880
|
-
export function createExperimentalMetricsPayload(interactionId, interaction) {
|
|
820
|
+
export async function createExperimentalMetricsPayload(interactionId, interaction) {
|
|
881
821
|
const config = getConfig();
|
|
882
822
|
if (!config) {
|
|
883
823
|
throw Error('UFO Configuration not provided');
|
|
@@ -891,5 +831,6 @@ export function createExperimentalMetricsPayload(interactionId, interaction) {
|
|
|
891
831
|
if (pageVisibilityState !== 'visible') {
|
|
892
832
|
return null;
|
|
893
833
|
}
|
|
894
|
-
|
|
834
|
+
const result = await createInteractionMetricsPayload(interaction, interactionId, true);
|
|
835
|
+
return result;
|
|
895
836
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Determines the interaction status based on abort reason and BM3 TTI presence.
|
|
3
|
+
*
|
|
4
|
+
* @param {InteractionMetrics} interaction - The interaction metrics object containing abort reason and apdex data
|
|
5
|
+
* @returns {{
|
|
6
|
+
* originalInteractionStatus: 'ABORTED' | 'SUCCEEDED',
|
|
7
|
+
* overrideStatus: 'ABORTED' | 'SUCCEEDED'
|
|
8
|
+
* }} An object containing both the original and override status
|
|
9
|
+
*
|
|
10
|
+
* @description
|
|
11
|
+
* This function evaluates the interaction status in two ways:
|
|
12
|
+
* 1. originalInteractionStatus: Based on whether there's an abort reason
|
|
13
|
+
* 2. overrideStatus: Based on the presence of BM3 TTI (apdex data)
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const interaction = {
|
|
17
|
+
* abortReason: null,
|
|
18
|
+
* apdex: [1, 2, 3]
|
|
19
|
+
* };
|
|
20
|
+
* const result = getInteractionStatus(interaction);
|
|
21
|
+
* // Returns: { originalInteractionStatus: 'SUCCEEDED', overrideStatus: 'SUCCEEDED' }
|
|
22
|
+
*/
|
|
23
|
+
export default function getInteractionStatus(interaction) {
|
|
24
|
+
const originalInteractionStatus = interaction.abortReason ? 'ABORTED' : 'SUCCEEDED';
|
|
25
|
+
const hasBm3TTI = interaction.apdex.length > 0;
|
|
26
|
+
const overrideStatus = hasBm3TTI ? 'SUCCEEDED' : originalInteractionStatus;
|
|
27
|
+
return {
|
|
28
|
+
originalInteractionStatus,
|
|
29
|
+
overrideStatus
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import * as ssr from '../../ssr';
|
|
2
|
+
export default function getSSRDoneTimeValue(config) {
|
|
3
|
+
var _config$ssr, _config$ssr2;
|
|
4
|
+
return config !== null && config !== void 0 && (_config$ssr = config.ssr) !== null && _config$ssr !== void 0 && _config$ssr.getSSRDoneTime ? config === null || config === void 0 ? void 0 : (_config$ssr2 = config.ssr) === null || _config$ssr2 === void 0 ? void 0 : _config$ssr2.getSSRDoneTime() : ssr.getSSRDoneTime();
|
|
5
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
2
|
+
import { getConfig } from '../../config';
|
|
3
|
+
import { postInteractionLog } from '../../interaction-metrics';
|
|
4
|
+
import { getVCObserver } from '../../vc';
|
|
5
|
+
import getInteractionStatus from './get-interaction-status';
|
|
6
|
+
import getPageVisibilityUpToTTAI from './get-page-visibility-up-to-ttai';
|
|
7
|
+
import getSSRDoneTimeValue from './get-ssr-done-time-value';
|
|
8
|
+
export default async function getVCMetrics(interaction) {
|
|
9
|
+
var _config$vc, _config$vc$ssrWhiteli, _interaction$apdex, _interaction$apdex$, _config$experimentalI;
|
|
10
|
+
const config = getConfig();
|
|
11
|
+
if (!(config !== null && config !== void 0 && (_config$vc = config.vc) !== null && _config$vc !== void 0 && _config$vc.enabled)) {
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
if (interaction.type !== 'page_load' && interaction.type !== 'transition') {
|
|
15
|
+
return {};
|
|
16
|
+
}
|
|
17
|
+
const interactionStatus = getInteractionStatus(interaction);
|
|
18
|
+
const pageVisibilityUpToTTAI = getPageVisibilityUpToTTAI(interaction);
|
|
19
|
+
if ((interactionStatus.originalInteractionStatus !== 'SUCCEEDED' || pageVisibilityUpToTTAI !== 'visible') && fg('platform_ufo_no_vc_on_aborted')) {
|
|
20
|
+
return {};
|
|
21
|
+
}
|
|
22
|
+
const isSSREnabled = (config === null || config === void 0 ? void 0 : config.ssr) || (config === null || config === void 0 ? void 0 : (_config$vc$ssrWhiteli = config.vc.ssrWhitelist) === null || _config$vc$ssrWhiteli === void 0 ? void 0 : _config$vc$ssrWhiteli.includes(interaction.ufoName));
|
|
23
|
+
const ssr = interaction.type === 'page_load' && isSSREnabled ? {
|
|
24
|
+
ssr: getSSRDoneTimeValue(config)
|
|
25
|
+
} : null;
|
|
26
|
+
postInteractionLog.setVCObserverSSRConfig(ssr);
|
|
27
|
+
const tti = (_interaction$apdex = interaction.apdex) === null || _interaction$apdex === void 0 ? void 0 : (_interaction$apdex$ = _interaction$apdex[0]) === null || _interaction$apdex$ === void 0 ? void 0 : _interaction$apdex$.stopTime;
|
|
28
|
+
const prefix = 'ufo';
|
|
29
|
+
const result = await getVCObserver().getVCResult({
|
|
30
|
+
start: interaction.start,
|
|
31
|
+
stop: interaction.end,
|
|
32
|
+
tti,
|
|
33
|
+
prefix,
|
|
34
|
+
vc: interaction.vc,
|
|
35
|
+
isEventAborted: interactionStatus.originalInteractionStatus !== 'SUCCEEDED',
|
|
36
|
+
...ssr
|
|
37
|
+
});
|
|
38
|
+
if ((_config$experimentalI = config.experimentalInteractionMetrics) !== null && _config$experimentalI !== void 0 && _config$experimentalI.enabled) {
|
|
39
|
+
getVCObserver().stop();
|
|
40
|
+
}
|
|
41
|
+
postInteractionLog.setLastInteractionFinishVCResult(result);
|
|
42
|
+
const VC = result === null || result === void 0 ? void 0 : result['metrics:vc'];
|
|
43
|
+
if (!VC || !(result !== null && result !== void 0 && result[`${prefix}:vc:clean`])) {
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
if (interactionStatus.originalInteractionStatus !== 'SUCCEEDED' || pageVisibilityUpToTTAI !== 'visible') {
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
...result,
|
|
51
|
+
'metric:vc90': VC['90']
|
|
52
|
+
};
|
|
53
|
+
}
|
|
@@ -28,17 +28,19 @@ function sinkInteraction(instance, payloadPackage) {
|
|
|
28
28
|
function sinkExperimentalInteractionMetrics(instance, payloadPackage) {
|
|
29
29
|
sinkExperimentalHandler((interactionId, interaction) => {
|
|
30
30
|
scheduleCallback(idlePriority, () => {
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
if (
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
const payloadPromise = payloadPackage.createExperimentalMetricsPayload(interactionId, interaction);
|
|
32
|
+
payloadPromise.then(payload => {
|
|
33
|
+
if (payload) {
|
|
34
|
+
if (fg('enable_ufo_devtools_api_for_extra_events')) {
|
|
35
|
+
// NOTE: This API is used by the UFO DevTool Chrome Extension and Criterion
|
|
36
|
+
const devToolObserver = globalThis.__ufo_devtool_onUfoPayload;
|
|
37
|
+
if (typeof devToolObserver === 'function') {
|
|
38
|
+
devToolObserver === null || devToolObserver === void 0 ? void 0 : devToolObserver(payload);
|
|
39
|
+
}
|
|
38
40
|
}
|
|
41
|
+
instance.sendOperationalEvent(payload);
|
|
39
42
|
}
|
|
40
|
-
|
|
41
|
-
}
|
|
43
|
+
});
|
|
42
44
|
});
|
|
43
45
|
});
|
|
44
46
|
}
|
package/dist/es2019/vc/index.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
2
|
+
import { getConfig } from '../config';
|
|
2
3
|
import { VCObserver } from './vc-observer';
|
|
3
4
|
import VCObserverNew from './vc-observer-new';
|
|
4
5
|
class VCObserverWrapper {
|
|
5
6
|
constructor(opts = {}) {
|
|
7
|
+
var _getConfig, _getConfig$vc;
|
|
6
8
|
this.oldVCObserver = new VCObserver(opts);
|
|
7
9
|
this.newVCObserver = null;
|
|
8
|
-
const isNewVCObserverEnabled = fg('platform_ufo_vc_observer_new');
|
|
10
|
+
const isNewVCObserverEnabled = fg('platform_ufo_vc_observer_new') || ((_getConfig = getConfig()) === null || _getConfig === void 0 ? void 0 : (_getConfig$vc = _getConfig.vc) === null || _getConfig$vc === void 0 ? void 0 : _getConfig$vc.enableVCObserverNew);
|
|
9
11
|
if (isNewVCObserverEnabled) {
|
|
10
12
|
this.newVCObserver = new VCObserverNew({
|
|
11
13
|
selectorConfig: opts.selectorConfig
|
|
@@ -15,7 +17,9 @@ class VCObserverWrapper {
|
|
|
15
17
|
start(startArg) {
|
|
16
18
|
var _this$oldVCObserver, _this$newVCObserver;
|
|
17
19
|
(_this$oldVCObserver = this.oldVCObserver) === null || _this$oldVCObserver === void 0 ? void 0 : _this$oldVCObserver.start(startArg);
|
|
18
|
-
(_this$newVCObserver = this.newVCObserver) === null || _this$newVCObserver === void 0 ? void 0 : _this$newVCObserver.start(
|
|
20
|
+
(_this$newVCObserver = this.newVCObserver) === null || _this$newVCObserver === void 0 ? void 0 : _this$newVCObserver.start({
|
|
21
|
+
startTime: startArg.startTime
|
|
22
|
+
});
|
|
19
23
|
}
|
|
20
24
|
stop() {
|
|
21
25
|
var _this$oldVCObserver2, _this$newVCObserver2;
|
|
@@ -4,7 +4,15 @@ function getAttributeSelector(element, attributeName) {
|
|
|
4
4
|
if (!attrValue) {
|
|
5
5
|
return '';
|
|
6
6
|
}
|
|
7
|
-
return `[${attributeName}="${
|
|
7
|
+
return `[${attributeName}="${attrValue}"]`;
|
|
8
|
+
}
|
|
9
|
+
function isValidSelector(selector) {
|
|
10
|
+
try {
|
|
11
|
+
document.querySelector(selector);
|
|
12
|
+
return true;
|
|
13
|
+
} catch (err) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
8
16
|
}
|
|
9
17
|
function isSelectorUnique(selector) {
|
|
10
18
|
return document.querySelectorAll(selector).length === 1;
|
|
@@ -12,11 +20,13 @@ function isSelectorUnique(selector) {
|
|
|
12
20
|
function getUniqueSelector(selectorConfig, element) {
|
|
13
21
|
let currentElement = element;
|
|
14
22
|
const parts = [];
|
|
15
|
-
|
|
23
|
+
const MAX_DEPTH = 3;
|
|
24
|
+
let currentDepth = 0;
|
|
25
|
+
while (currentElement && currentElement.localName !== 'body' && currentDepth <= MAX_DEPTH) {
|
|
16
26
|
const tagName = currentElement.localName;
|
|
17
27
|
let selectorPart = tagName;
|
|
18
|
-
if (selectorConfig.id && currentElement.id) {
|
|
19
|
-
selectorPart += `#${
|
|
28
|
+
if (selectorConfig.id && currentElement.id && isValidSelector(`#${currentElement.id}`)) {
|
|
29
|
+
selectorPart += `#${currentElement.id}`;
|
|
20
30
|
} else if (selectorConfig.dataVC) {
|
|
21
31
|
selectorPart += getAttributeSelector(currentElement, 'data-vc');
|
|
22
32
|
} else if (selectorConfig.testId) {
|
|
@@ -24,9 +34,11 @@ function getUniqueSelector(selectorConfig, element) {
|
|
|
24
34
|
} else if (selectorConfig.role) {
|
|
25
35
|
selectorPart += getAttributeSelector(currentElement, 'role');
|
|
26
36
|
} else if (selectorConfig.className && currentElement.className) {
|
|
27
|
-
const classNames = Array.from(currentElement.classList).
|
|
37
|
+
const classNames = Array.from(currentElement.classList).join('.');
|
|
28
38
|
if (classNames) {
|
|
29
|
-
|
|
39
|
+
if (isValidSelector(`.${classNames}`)) {
|
|
40
|
+
selectorPart += `.${classNames}`;
|
|
41
|
+
}
|
|
30
42
|
}
|
|
31
43
|
}
|
|
32
44
|
parts.unshift(selectorPart);
|
|
@@ -35,6 +47,7 @@ function getUniqueSelector(selectorConfig, element) {
|
|
|
35
47
|
return potentialSelector;
|
|
36
48
|
}
|
|
37
49
|
currentElement = currentElement.parentElement;
|
|
50
|
+
currentDepth++;
|
|
38
51
|
}
|
|
39
52
|
const potentialSelector = parts.join(' > ').trim();
|
|
40
53
|
if (!potentialSelector) {
|
|
@@ -14,7 +14,6 @@ const DEFAULT_SELECTOR_CONFIG = {
|
|
|
14
14
|
export default class VCObserverNew {
|
|
15
15
|
constructor(config) {
|
|
16
16
|
var _config$selectorConfi;
|
|
17
|
-
_defineProperty(this, "startTime", 0);
|
|
18
17
|
_defineProperty(this, "viewportObserver", null);
|
|
19
18
|
_defineProperty(this, "windowEventObserver", null);
|
|
20
19
|
this.entriesTimeline = new EntriesTimeline();
|
|
@@ -63,10 +62,13 @@ export default class VCObserverNew {
|
|
|
63
62
|
}
|
|
64
63
|
});
|
|
65
64
|
}
|
|
66
|
-
start(
|
|
65
|
+
start({
|
|
66
|
+
startTime
|
|
67
|
+
}) {
|
|
67
68
|
var _this$viewportObserve, _this$windowEventObse;
|
|
68
69
|
(_this$viewportObserve = this.viewportObserver) === null || _this$viewportObserve === void 0 ? void 0 : _this$viewportObserve.start();
|
|
69
70
|
(_this$windowEventObse = this.windowEventObserver) === null || _this$windowEventObse === void 0 ? void 0 : _this$windowEventObse.start();
|
|
71
|
+
this.entriesTimeline.clear();
|
|
70
72
|
}
|
|
71
73
|
stop() {
|
|
72
74
|
var _this$viewportObserve2, _this$windowEventObse2;
|
|
@@ -85,7 +87,9 @@ export default class VCObserverNew {
|
|
|
85
87
|
stop
|
|
86
88
|
});
|
|
87
89
|
const fy25_03 = await calculator_fy25_03.calculate({
|
|
88
|
-
orderedEntries
|
|
90
|
+
orderedEntries,
|
|
91
|
+
startTime: start,
|
|
92
|
+
stopTime: stop
|
|
89
93
|
});
|
|
90
94
|
if (fy25_03) {
|
|
91
95
|
results.push(fy25_03);
|
|
@@ -6,6 +6,8 @@ export default class AbstractVCCalculatorBase {
|
|
|
6
6
|
this.revisionNo = revisionNo;
|
|
7
7
|
}
|
|
8
8
|
async calculate({
|
|
9
|
+
startTime,
|
|
10
|
+
stopTime,
|
|
9
11
|
orderedEntries
|
|
10
12
|
}) {
|
|
11
13
|
var _vcDetails$90$t, _vcDetails$;
|
|
@@ -25,6 +27,8 @@ export default class AbstractVCCalculatorBase {
|
|
|
25
27
|
width: getViewportWidth(),
|
|
26
28
|
height: getViewportHeight()
|
|
27
29
|
},
|
|
30
|
+
startTime,
|
|
31
|
+
stopTime,
|
|
28
32
|
orderedEntries: filteredEntries,
|
|
29
33
|
percentiles: [25, 50, 75, 80, 85, 90, 95, 98, 99]
|
|
30
34
|
});
|
|
@@ -172,7 +172,6 @@ export function getRGBComponents(n) {
|
|
|
172
172
|
*/
|
|
173
173
|
export async function calculateDrawnPixelsRaw(imageData, scaleFactor, arraySize) {
|
|
174
174
|
const data = imageData.data;
|
|
175
|
-
const scaleCompensation = Math.round(1 / (scaleFactor * scaleFactor));
|
|
176
175
|
const arr = new Uint32Array(arraySize);
|
|
177
176
|
for (let i = 0; i < data.length; i += 4) {
|
|
178
177
|
// Check alpha
|
|
@@ -184,7 +183,7 @@ export async function calculateDrawnPixelsRaw(imageData, scaleFactor, arraySize)
|
|
|
184
183
|
// The | operator combines all bits together
|
|
185
184
|
const color = data[i] << 16 | data[i + 1] << 8 | data[i + 2];
|
|
186
185
|
const colorIndex = color - 1;
|
|
187
|
-
arr[colorIndex] = (arr[colorIndex] || 0) +
|
|
186
|
+
arr[colorIndex] = (arr[colorIndex] || 0) + 1;
|
|
188
187
|
}
|
|
189
188
|
if (i % 10000 === 0) {
|
|
190
189
|
await taskYield();
|
package/dist/es2019/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/index.js
CHANGED
|
@@ -3,7 +3,8 @@ import { ViewportCanvas } from './canvas-pixel';
|
|
|
3
3
|
export default async function calculateTTVCPercentiles({
|
|
4
4
|
viewport,
|
|
5
5
|
orderedEntries,
|
|
6
|
-
percentiles
|
|
6
|
+
percentiles,
|
|
7
|
+
startTime
|
|
7
8
|
}) {
|
|
8
9
|
const canvas = new ViewportCanvas(viewport, fg('platform_ufo_canvas_heatmap_full_precision') ? 1 : 0.25);
|
|
9
10
|
const elementMap = new Map();
|
|
@@ -22,10 +23,11 @@ export default async function calculateTTVCPercentiles({
|
|
|
22
23
|
|
|
23
24
|
// Get pixel counts
|
|
24
25
|
const timePixelCounts = await canvas.getPixelCounts();
|
|
25
|
-
const
|
|
26
|
-
|
|
26
|
+
const canvasDimenstions = canvas.getScaledDimensions();
|
|
27
|
+
const totalPixels = canvasDimenstions.width * canvasDimenstions.height;
|
|
28
|
+
return calculatePercentiles(timePixelCounts, elementMap, percentiles, totalPixels, startTime);
|
|
27
29
|
}
|
|
28
|
-
export function calculatePercentiles(timePixelCounts, elementMap, unorderedPercentiles, totalPixels) {
|
|
30
|
+
export function calculatePercentiles(timePixelCounts, elementMap, unorderedPercentiles, totalPixels, startTime) {
|
|
29
31
|
const results = {};
|
|
30
32
|
let cumulativePixels = 0;
|
|
31
33
|
const percentiles = unorderedPercentiles.sort((a, b) => a - b);
|
|
@@ -42,7 +44,7 @@ export function calculatePercentiles(timePixelCounts, elementMap, unorderedPerce
|
|
|
42
44
|
let matchesAnyCheckpoints = false;
|
|
43
45
|
while (percentileIndex < percentiles.length && percentCovered >= percentiles[percentileIndex]) {
|
|
44
46
|
results[`${percentiles[percentileIndex]}`] = {
|
|
45
|
-
t: Number(time),
|
|
47
|
+
t: Math.round(Number(time - startTime)),
|
|
46
48
|
e: Array.from(domElementsBuffer)
|
|
47
49
|
};
|
|
48
50
|
percentileIndex++;
|
|
@@ -55,15 +57,16 @@ export function calculatePercentiles(timePixelCounts, elementMap, unorderedPerce
|
|
|
55
57
|
break;
|
|
56
58
|
}
|
|
57
59
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
let previousResult = {
|
|
61
|
+
t: 0,
|
|
62
|
+
e: []
|
|
63
|
+
};
|
|
64
|
+
for (let i = 0; i < percentiles.length; i++) {
|
|
65
|
+
const percentile = percentiles[i];
|
|
61
66
|
if (!(percentile in results)) {
|
|
62
|
-
results[`${percentile}`] =
|
|
63
|
-
t: 0,
|
|
64
|
-
e: []
|
|
65
|
-
};
|
|
67
|
+
results[`${percentile}`] = previousResult;
|
|
66
68
|
}
|
|
69
|
+
previousResult = results[`${percentile}`];
|
|
67
70
|
}
|
|
68
71
|
return results;
|
|
69
72
|
}
|
|
@@ -175,7 +175,7 @@ class Heatmap {
|
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
|
-
async getVCPercentMetrics(vcPercentCheckpoint) {
|
|
178
|
+
async getVCPercentMetrics(vcPercentCheckpoint, startTime) {
|
|
179
179
|
const sortedCheckpoints = [...vcPercentCheckpoint].sort((a, b) => a - b);
|
|
180
180
|
const flattenHeatmap = this.map.flat();
|
|
181
181
|
const totalCells = flattenHeatmap.length;
|
|
@@ -232,7 +232,7 @@ class Heatmap {
|
|
|
232
232
|
}
|
|
233
233
|
matchesAnyCheckpoints = true;
|
|
234
234
|
result[checkpoint.toString()] = {
|
|
235
|
-
t: timestamp,
|
|
235
|
+
t: Math.round(timestamp - startTime),
|
|
236
236
|
e: domElements
|
|
237
237
|
};
|
|
238
238
|
}
|
|
@@ -249,13 +249,14 @@ class Heatmap {
|
|
|
249
249
|
export default async function calculateTTVCPercentiles({
|
|
250
250
|
orderedEntries,
|
|
251
251
|
viewport,
|
|
252
|
-
percentiles
|
|
252
|
+
percentiles,
|
|
253
|
+
startTime
|
|
253
254
|
}) {
|
|
254
255
|
const heatmap = new Heatmap({
|
|
255
256
|
viewport,
|
|
256
257
|
heatmapSize: 200
|
|
257
258
|
});
|
|
258
259
|
await heatmap.applyEntriesToHeatmap(orderedEntries);
|
|
259
|
-
const vcDetails = await heatmap.getVCPercentMetrics(percentiles);
|
|
260
|
+
const vcDetails = await heatmap.getVCPercentMetrics(percentiles, startTime);
|
|
260
261
|
return vcDetails;
|
|
261
262
|
}
|
package/dist/es2019/vc/vc-observer-new/metric-calculator/percentile-calc/rect-sweeping-line/index.js
CHANGED
|
@@ -4,7 +4,8 @@ import calculateUnionArea from './calc-union-area';
|
|
|
4
4
|
export default async function calculateTTVCPercentiles({
|
|
5
5
|
orderedEntries,
|
|
6
6
|
viewport,
|
|
7
|
-
percentiles
|
|
7
|
+
percentiles,
|
|
8
|
+
startTime
|
|
8
9
|
}) {
|
|
9
10
|
const sortedPercentiles = [...percentiles].sort((a, b) => a - b);
|
|
10
11
|
const viewportArea = viewport.width * viewport.height;
|
|
@@ -43,7 +44,7 @@ export default async function calculateTTVCPercentiles({
|
|
|
43
44
|
}
|
|
44
45
|
matchesAnyCheckpoints = true;
|
|
45
46
|
checkpoints[checkpoint.toString()] = {
|
|
46
|
-
t: iEntry.time,
|
|
47
|
+
t: Math.round(iEntry.time - startTime),
|
|
47
48
|
e: domElements
|
|
48
49
|
};
|
|
49
50
|
}
|
|
@@ -9,6 +9,9 @@ export default class WindowEventObserver {
|
|
|
9
9
|
const unbindCallback = bind(window, {
|
|
10
10
|
type,
|
|
11
11
|
listener: event => {
|
|
12
|
+
if (!event.isTrusted) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
12
15
|
this.onEvent({
|
|
13
16
|
time: event.timeStamp,
|
|
14
17
|
type,
|
|
@@ -16,7 +19,8 @@ export default class WindowEventObserver {
|
|
|
16
19
|
});
|
|
17
20
|
},
|
|
18
21
|
options: {
|
|
19
|
-
passive: true
|
|
22
|
+
passive: true,
|
|
23
|
+
once: true
|
|
20
24
|
}
|
|
21
25
|
});
|
|
22
26
|
this.unbindFns.push(unbindCallback);
|