@atlaskit/react-ufo 2.4.6 → 2.4.7
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 +14 -0
- package/create-experimental-interaction-metrics-payload/package.json +15 -0
- package/dist/cjs/config/index.js +40 -18
- package/dist/cjs/create-experimental-interaction-metrics-payload/index.js +89 -0
- package/dist/cjs/create-payload/common/utils/index.js +85 -1
- package/dist/cjs/create-payload/index.js +37 -77
- package/dist/cjs/create-post-interaction-log-payload/index.js +1 -4
- package/dist/cjs/interaction-metrics/common/constants.js +7 -1
- package/dist/cjs/interaction-metrics/common/index.js +151 -0
- package/dist/cjs/interaction-metrics/index.js +139 -204
- package/dist/cjs/interaction-metrics/post-interaction-log.js +6 -2
- package/dist/cjs/interaction-metrics-init/index.js +27 -9
- package/dist/cjs/load-hold/UFOLoadHold.js +3 -4
- package/dist/cjs/segment/segment.js +7 -9
- package/dist/cjs/trace-pageload/index.js +2 -1
- package/dist/es2019/config/index.js +22 -0
- package/dist/es2019/create-experimental-interaction-metrics-payload/index.js +67 -0
- package/dist/es2019/create-payload/common/utils/index.js +86 -1
- package/dist/es2019/create-payload/index.js +28 -74
- package/dist/es2019/create-post-interaction-log-payload/index.js +1 -4
- package/dist/es2019/interaction-metrics/common/constants.js +6 -0
- package/dist/es2019/interaction-metrics/common/index.js +103 -0
- package/dist/es2019/interaction-metrics/index.js +92 -129
- package/dist/es2019/interaction-metrics/post-interaction-log.js +6 -2
- package/dist/es2019/interaction-metrics-init/index.js +21 -8
- package/dist/es2019/load-hold/UFOLoadHold.js +3 -4
- package/dist/es2019/segment/segment.js +6 -12
- package/dist/es2019/trace-pageload/index.js +1 -1
- package/dist/esm/config/index.js +39 -18
- package/dist/esm/create-experimental-interaction-metrics-payload/index.js +81 -0
- package/dist/esm/create-payload/common/utils/index.js +80 -1
- package/dist/esm/create-payload/index.js +33 -75
- package/dist/esm/create-post-interaction-log-payload/index.js +1 -4
- package/dist/esm/interaction-metrics/common/constants.js +6 -0
- package/dist/esm/interaction-metrics/common/index.js +132 -0
- package/dist/esm/interaction-metrics/index.js +87 -156
- package/dist/esm/interaction-metrics/post-interaction-log.js +6 -2
- package/dist/esm/interaction-metrics-init/index.js +24 -10
- package/dist/esm/load-hold/UFOLoadHold.js +3 -4
- package/dist/esm/segment/segment.js +7 -9
- package/dist/esm/trace-pageload/index.js +1 -1
- package/dist/types/common/common/types.d.ts +9 -5
- package/dist/types/config/index.d.ts +6 -0
- package/dist/types/create-experimental-interaction-metrics-payload/index.d.ts +31 -0
- package/dist/types/create-payload/common/utils/index.d.ts +12 -0
- package/dist/types/create-payload/index.d.ts +13 -5660
- package/dist/types/create-post-interaction-log-payload/index.d.ts +2 -0
- package/dist/types/interaction-metrics/common/constants.d.ts +31 -1
- package/dist/types/interaction-metrics/common/index.d.ts +16 -0
- package/dist/types/interaction-metrics/index.d.ts +4 -15
- package/dist/types/interaction-metrics/post-interaction-log.d.ts +1 -1
- package/dist/types/load-hold/UFOLoadHold.d.ts +1 -2
- package/dist/types/trace-pageload/index.d.ts +1 -0
- package/dist/types-ts4.5/common/common/types.d.ts +9 -5
- package/dist/types-ts4.5/config/index.d.ts +6 -0
- package/dist/types-ts4.5/create-experimental-interaction-metrics-payload/index.d.ts +31 -0
- package/dist/types-ts4.5/create-payload/common/utils/index.d.ts +12 -0
- package/dist/types-ts4.5/create-payload/index.d.ts +13 -5660
- package/dist/types-ts4.5/create-post-interaction-log-payload/index.d.ts +2 -0
- package/dist/types-ts4.5/interaction-metrics/common/constants.d.ts +31 -1
- package/dist/types-ts4.5/interaction-metrics/common/index.d.ts +16 -0
- package/dist/types-ts4.5/interaction-metrics/index.d.ts +4 -15
- package/dist/types-ts4.5/interaction-metrics/post-interaction-log.d.ts +1 -1
- package/dist/types-ts4.5/load-hold/UFOLoadHold.d.ts +1 -2
- package/dist/types-ts4.5/trace-pageload/index.d.ts +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { getConfig } from '../../config';
|
|
2
|
+
import { interactionQueue, segmentCache, segmentObservers } from './constants';
|
|
3
|
+
export function isPerformanceTracingEnabled() {
|
|
4
|
+
var _getConfig;
|
|
5
|
+
return ((_getConfig = getConfig()) === null || _getConfig === void 0 ? void 0 : _getConfig.enableAdditionalPerformanceMarks) || window.__REACT_UFO_ENABLE_PERF_TRACING || process.env.NODE_ENV !== 'production';
|
|
6
|
+
}
|
|
7
|
+
export function labelStackToString(labelStack, name) {
|
|
8
|
+
var _stack$map;
|
|
9
|
+
const stack = [...(labelStack !== null && labelStack !== void 0 ? labelStack : [])];
|
|
10
|
+
if (name) {
|
|
11
|
+
stack.push({
|
|
12
|
+
name
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
return (_stack$map = stack.map(l => l.name)) === null || _stack$map === void 0 ? void 0 : _stack$map.join('/');
|
|
16
|
+
}
|
|
17
|
+
export function labelStackToIdString(labelStack) {
|
|
18
|
+
var _labelStack$map;
|
|
19
|
+
return labelStack === null || labelStack === void 0 ? void 0 : (_labelStack$map = labelStack.map(l => 'segmentId' in l ? `${l.name}:${l.segmentId}` : `${l.name}`)) === null || _labelStack$map === void 0 ? void 0 : _labelStack$map.join('/');
|
|
20
|
+
}
|
|
21
|
+
export function addSegmentObserver(observer) {
|
|
22
|
+
segmentObservers.push(observer);
|
|
23
|
+
for (const segmentInfo of segmentCache.values()) {
|
|
24
|
+
observer.onAdd(segmentInfo);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export function removeSegmentObserver(observer) {
|
|
28
|
+
const index = segmentObservers.findIndex(obs => obs === observer);
|
|
29
|
+
if (index !== -1) {
|
|
30
|
+
segmentObservers.splice(index, 1);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export function addHoldCriterion(id, labelStack, name, startTime) {
|
|
34
|
+
var _window$__CRITERION__;
|
|
35
|
+
if (!((_window$__CRITERION__ = window.__CRITERION__) !== null && _window$__CRITERION__ !== void 0 && _window$__CRITERION__.addUFOHold)) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
window.__CRITERION__.addUFOHold(id, labelStackToString(labelStack), name, startTime);
|
|
39
|
+
}
|
|
40
|
+
export function removeHoldCriterion(id) {
|
|
41
|
+
var _window$__CRITERION__2;
|
|
42
|
+
if (!((_window$__CRITERION__2 = window.__CRITERION__) !== null && _window$__CRITERION__2 !== void 0 && _window$__CRITERION__2.removeUFOHold)) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
window.__CRITERION__.removeUFOHold(id);
|
|
46
|
+
}
|
|
47
|
+
export const pushToQueue = (id, data) => {
|
|
48
|
+
interactionQueue.push({
|
|
49
|
+
id,
|
|
50
|
+
data
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
export function callCleanUpCallbacks(interaction) {
|
|
54
|
+
interaction.cleanupCallbacks.reverse().forEach(cleanUpCallback => {
|
|
55
|
+
cleanUpCallback();
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
export function reactProfilerTimingMap(data) {
|
|
59
|
+
const profilerTimingMap = new Map();
|
|
60
|
+
data.reactProfilerTimings.forEach(profilerTiming => {
|
|
61
|
+
const labelStackId = labelStackToIdString(profilerTiming.labelStack);
|
|
62
|
+
if (labelStackId) {
|
|
63
|
+
var _profilerTimingMap$ge, _timing$start, _timing$end;
|
|
64
|
+
const timing = (_profilerTimingMap$ge = profilerTimingMap.get(labelStackId)) !== null && _profilerTimingMap$ge !== void 0 ? _profilerTimingMap$ge : {
|
|
65
|
+
labelStack: profilerTiming.labelStack
|
|
66
|
+
};
|
|
67
|
+
timing.start = profilerTiming.startTime < ((_timing$start = timing.start) !== null && _timing$start !== void 0 ? _timing$start : Number.MAX_SAFE_INTEGER) ? profilerTiming.startTime : timing.start;
|
|
68
|
+
timing.end = profilerTiming.commitTime > ((_timing$end = timing.end) !== null && _timing$end !== void 0 ? _timing$end : Number.MIN_SAFE_INTEGER) ? profilerTiming.commitTime : timing.end;
|
|
69
|
+
profilerTimingMap.set(labelStackId, timing);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
try {
|
|
73
|
+
// for Firefox 102 and older
|
|
74
|
+
for (const [, {
|
|
75
|
+
labelStack,
|
|
76
|
+
start,
|
|
77
|
+
end
|
|
78
|
+
}] of profilerTimingMap.entries()) {
|
|
79
|
+
performance.measure(`🛸 ${labelStackToString(labelStack)} [segment_ttai]`, {
|
|
80
|
+
start,
|
|
81
|
+
end
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
} catch (e) {
|
|
85
|
+
// do nothing
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export function callCancelCallbacks(interaction) {
|
|
89
|
+
interaction.cancelCallbacks.reverse().forEach(cancelCallback => {
|
|
90
|
+
cancelCallback();
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
export function isSegmentLabel(obj) {
|
|
94
|
+
return obj && typeof obj.name === 'string' && typeof obj.segmentId === 'string';
|
|
95
|
+
}
|
|
96
|
+
export function getSegmentCacheKey(labelStack) {
|
|
97
|
+
return labelStack.map(l => {
|
|
98
|
+
if (isSegmentLabel(l)) {
|
|
99
|
+
return `${l.name}_${l.segmentId}`;
|
|
100
|
+
}
|
|
101
|
+
return l.name;
|
|
102
|
+
}).join('|');
|
|
103
|
+
}
|
|
@@ -1,22 +1,21 @@
|
|
|
1
1
|
import { v4 as createUUID } from 'uuid';
|
|
2
2
|
import coinflip from '../coinflip';
|
|
3
3
|
import { getAwaitBM3TTIList, getCapabilityRate, getConfig } from '../config';
|
|
4
|
+
import { ExperimentalInteractionMetrics } from '../create-experimental-interaction-metrics-payload';
|
|
5
|
+
import { getExperimentalVCMetrics, getTTAI } from '../create-payload/common/utils';
|
|
4
6
|
import { clearActiveTrace } from '../experience-trace-id-context';
|
|
5
7
|
import { allFeatureFlagsAccessed, currentFeatureFlagsAccessed } from '../feature-flags-accessed';
|
|
6
8
|
import { getInteractionId } from '../interaction-id-context';
|
|
7
9
|
import { getVCObserver } from '../vc';
|
|
8
|
-
import
|
|
10
|
+
import { addHoldCriterion, addSegmentObserver, callCancelCallbacks, callCleanUpCallbacks, getSegmentCacheKey, isPerformanceTracingEnabled, labelStackToString, pushToQueue, reactProfilerTimingMap, removeHoldCriterion, removeSegmentObserver } from './common';
|
|
11
|
+
import interactions, { CLEANUP_TIMEOUT, CLEANUP_TIMEOUT_AFTER_APDEX, interactionQueue, moduleLoadingRequests, segmentCache, segmentObservers } from './common/constants';
|
|
9
12
|
import PostInteractionLog from './post-interaction-log';
|
|
10
13
|
const PreviousInteractionLog = {
|
|
11
14
|
name: undefined,
|
|
12
15
|
isAborted: undefined
|
|
13
16
|
};
|
|
14
17
|
export const postInteractionLog = new PostInteractionLog();
|
|
15
|
-
const
|
|
16
|
-
const segmentCache = new Map();
|
|
17
|
-
const CLEANUP_TIMEOUT = 60 * 1000;
|
|
18
|
-
const CLEANUP_TIMEOUT_AFTER_APDEX = 15 * 1000;
|
|
19
|
-
const segmentObservers = [];
|
|
18
|
+
export const experimentalInteractionLog = new ExperimentalInteractionMetrics();
|
|
20
19
|
export function getActiveInteraction() {
|
|
21
20
|
const interactionId = getInteractionId();
|
|
22
21
|
if (!interactionId.current) {
|
|
@@ -24,36 +23,6 @@ export function getActiveInteraction() {
|
|
|
24
23
|
}
|
|
25
24
|
return interactions.get(interactionId.current);
|
|
26
25
|
}
|
|
27
|
-
function isPerformanceTracingEnabled() {
|
|
28
|
-
var _getConfig;
|
|
29
|
-
return ((_getConfig = getConfig()) === null || _getConfig === void 0 ? void 0 : _getConfig.enableAdditionalPerformanceMarks) || window.__REACT_UFO_ENABLE_PERF_TRACING || process.env.NODE_ENV !== 'production';
|
|
30
|
-
}
|
|
31
|
-
function labelStackToString(labelStack, name) {
|
|
32
|
-
var _stack$map;
|
|
33
|
-
const stack = [...(labelStack !== null && labelStack !== void 0 ? labelStack : [])];
|
|
34
|
-
if (name) {
|
|
35
|
-
stack.push({
|
|
36
|
-
name
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
return (_stack$map = stack.map(l => l.name)) === null || _stack$map === void 0 ? void 0 : _stack$map.join('/');
|
|
40
|
-
}
|
|
41
|
-
function labelStackToIdString(labelStack) {
|
|
42
|
-
var _labelStack$map;
|
|
43
|
-
return labelStack === null || labelStack === void 0 ? void 0 : (_labelStack$map = labelStack.map(l => 'segmentId' in l ? `${l.name}:${l.segmentId}` : `${l.name}`)) === null || _labelStack$map === void 0 ? void 0 : _labelStack$map.join('/');
|
|
44
|
-
}
|
|
45
|
-
function addSegmentObserver(observer) {
|
|
46
|
-
segmentObservers.push(observer);
|
|
47
|
-
for (const segmentInfo of segmentCache.values()) {
|
|
48
|
-
observer.onAdd(segmentInfo);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
function removeSegmentObserver(observer) {
|
|
52
|
-
const index = segmentObservers.findIndex(obs => obs === observer);
|
|
53
|
-
if (index !== -1) {
|
|
54
|
-
segmentObservers.splice(index, 1);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
26
|
export function remove(interactionId) {
|
|
58
27
|
interactions.delete(interactionId);
|
|
59
28
|
}
|
|
@@ -196,7 +165,6 @@ export function addPreload(moduleId, timestamp) {
|
|
|
196
165
|
export function addLoad(identifier, start, end) {
|
|
197
166
|
addSpanToAll('bundle_load', identifier, null, start, end - start);
|
|
198
167
|
}
|
|
199
|
-
const moduleLoadingRequests = {};
|
|
200
168
|
export function extractModuleName(input) {
|
|
201
169
|
let result = input !== null && input !== void 0 ? input : '';
|
|
202
170
|
result = result.replace(/^\.\/src\/packages\//, '');
|
|
@@ -204,30 +172,29 @@ export function extractModuleName(input) {
|
|
|
204
172
|
result = result.replace(/(\/src)?\/(index|main)\.(tsx|ts|js|jsx)$/, '');
|
|
205
173
|
return result;
|
|
206
174
|
}
|
|
207
|
-
function
|
|
208
|
-
var _window$__CRITERION__;
|
|
209
|
-
if (!((_window$__CRITERION__ = window.__CRITERION__) !== null && _window$__CRITERION__ !== void 0 && _window$__CRITERION__.addUFOHold)) {
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
window.__CRITERION__.addUFOHold(id, labelStackToString(labelStack), name, startTime);
|
|
213
|
-
}
|
|
214
|
-
function removeHoldCriterion(id) {
|
|
215
|
-
var _window$__CRITERION__2;
|
|
216
|
-
if (!((_window$__CRITERION__2 = window.__CRITERION__) !== null && _window$__CRITERION__2 !== void 0 && _window$__CRITERION__2.removeUFOHold)) {
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
window.__CRITERION__.removeUFOHold(id);
|
|
220
|
-
}
|
|
221
|
-
export function addHold(interactionId, labelStack, name) {
|
|
175
|
+
export function addHold(interactionId, labelStack, name, experimental) {
|
|
222
176
|
const interaction = interactions.get(interactionId);
|
|
223
177
|
const id = createUUID();
|
|
224
178
|
if (interaction != null) {
|
|
225
|
-
|
|
226
|
-
|
|
179
|
+
var _getConfig, _getConfig$experiment;
|
|
180
|
+
const holdActive = {
|
|
227
181
|
labelStack,
|
|
228
182
|
name,
|
|
229
|
-
start
|
|
230
|
-
}
|
|
183
|
+
start: 0
|
|
184
|
+
};
|
|
185
|
+
const start = performance.now();
|
|
186
|
+
if ((_getConfig = getConfig()) !== null && _getConfig !== void 0 && (_getConfig$experiment = _getConfig.experimentalInteractionMetrics) !== null && _getConfig$experiment !== void 0 && _getConfig$experiment.enabled && experimental) {
|
|
187
|
+
interaction.holdExpActive.set(id, {
|
|
188
|
+
...holdActive,
|
|
189
|
+
start
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
if (!experimental) {
|
|
193
|
+
interaction.holdActive.set(id, {
|
|
194
|
+
...holdActive,
|
|
195
|
+
start
|
|
196
|
+
});
|
|
197
|
+
}
|
|
231
198
|
addHoldCriterion(id, labelStack, name, start);
|
|
232
199
|
return () => {
|
|
233
200
|
const end = performance.now();
|
|
@@ -245,12 +212,22 @@ export function addHold(interactionId, labelStack, name) {
|
|
|
245
212
|
removeHoldCriterion(id);
|
|
246
213
|
const currentInteraction = interactions.get(interactionId);
|
|
247
214
|
const currentHold = interaction.holdActive.get(id);
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
215
|
+
const expHold = interaction.holdExpActive.get(id);
|
|
216
|
+
if (currentInteraction != null) {
|
|
217
|
+
if (currentHold != null) {
|
|
218
|
+
currentInteraction.holdInfo.push({
|
|
219
|
+
...currentHold,
|
|
220
|
+
end
|
|
221
|
+
});
|
|
222
|
+
interaction.holdActive.delete(id);
|
|
223
|
+
}
|
|
224
|
+
if (expHold != null) {
|
|
225
|
+
currentInteraction.holdExpInfo.push({
|
|
226
|
+
...expHold,
|
|
227
|
+
end
|
|
228
|
+
});
|
|
229
|
+
interaction.holdExpActive.delete(id);
|
|
230
|
+
}
|
|
254
231
|
}
|
|
255
232
|
};
|
|
256
233
|
}
|
|
@@ -379,21 +356,9 @@ export const addProfilerTimings = (interactionId, labelStack, type, actualDurati
|
|
|
379
356
|
postInteractionLog.addProfilerTimings(labelStack, type, actualDuration, baseDuration, startTime, commitTime);
|
|
380
357
|
}
|
|
381
358
|
};
|
|
382
|
-
const pushToQueue = (id, data) => {
|
|
383
|
-
interactionQueue.push({
|
|
384
|
-
id,
|
|
385
|
-
data
|
|
386
|
-
});
|
|
387
|
-
};
|
|
388
359
|
let handleInteraction = pushToQueue;
|
|
389
|
-
function callCleanUpCallbacks(interaction) {
|
|
390
|
-
interaction.cleanupCallbacks.reverse().forEach(cleanUpCallback => {
|
|
391
|
-
cleanUpCallback();
|
|
392
|
-
});
|
|
393
|
-
}
|
|
394
360
|
const finishInteraction = (id, data, endTime = performance.now()) => {
|
|
395
361
|
var _getConfig3, _getConfig3$vc;
|
|
396
|
-
// eslint-disable-next-line no-param-reassign
|
|
397
362
|
data.end = endTime;
|
|
398
363
|
try {
|
|
399
364
|
// for Firefox 102 and older
|
|
@@ -405,7 +370,6 @@ const finishInteraction = (id, data, endTime = performance.now()) => {
|
|
|
405
370
|
// do nothing
|
|
406
371
|
}
|
|
407
372
|
if (data.featureFlags) {
|
|
408
|
-
// eslint-disable-next-line no-param-reassign
|
|
409
373
|
data.featureFlags.during = Object.fromEntries(currentFeatureFlagsAccessed);
|
|
410
374
|
}
|
|
411
375
|
clearActiveTrace();
|
|
@@ -413,41 +377,13 @@ const finishInteraction = (id, data, endTime = performance.now()) => {
|
|
|
413
377
|
if ((_getConfig3 = getConfig()) !== null && _getConfig3 !== void 0 && (_getConfig3$vc = _getConfig3.vc) !== null && _getConfig3$vc !== void 0 && _getConfig3$vc.stopVCAtInteractionFinish) {
|
|
414
378
|
data.vc = getVCObserver().getVCRawData();
|
|
415
379
|
}
|
|
416
|
-
remove(id);
|
|
417
380
|
PreviousInteractionLog.name = data.ufoName || 'unknown';
|
|
418
381
|
PreviousInteractionLog.isAborted = data.abortReason != null;
|
|
419
382
|
if (data.ufoName) {
|
|
420
383
|
handleInteraction(id, data);
|
|
421
384
|
}
|
|
422
385
|
if (isPerformanceTracingEnabled()) {
|
|
423
|
-
|
|
424
|
-
data.reactProfilerTimings.forEach(profilerTiming => {
|
|
425
|
-
const labelStackId = labelStackToIdString(profilerTiming.labelStack);
|
|
426
|
-
if (labelStackId) {
|
|
427
|
-
var _profilerTimingMap$ge, _timing$start, _timing$end;
|
|
428
|
-
const timing = (_profilerTimingMap$ge = profilerTimingMap.get(labelStackId)) !== null && _profilerTimingMap$ge !== void 0 ? _profilerTimingMap$ge : {
|
|
429
|
-
labelStack: profilerTiming.labelStack
|
|
430
|
-
};
|
|
431
|
-
timing.start = profilerTiming.startTime < ((_timing$start = timing.start) !== null && _timing$start !== void 0 ? _timing$start : Number.MAX_SAFE_INTEGER) ? profilerTiming.startTime : timing.start;
|
|
432
|
-
timing.end = profilerTiming.commitTime > ((_timing$end = timing.end) !== null && _timing$end !== void 0 ? _timing$end : Number.MIN_SAFE_INTEGER) ? profilerTiming.commitTime : timing.end;
|
|
433
|
-
profilerTimingMap.set(labelStackId, timing);
|
|
434
|
-
}
|
|
435
|
-
});
|
|
436
|
-
try {
|
|
437
|
-
// for Firefox 102 and older
|
|
438
|
-
for (const [, {
|
|
439
|
-
labelStack,
|
|
440
|
-
start,
|
|
441
|
-
end
|
|
442
|
-
}] of profilerTimingMap.entries()) {
|
|
443
|
-
performance.measure(`🛸 ${labelStackToString(labelStack)} [segment_ttai]`, {
|
|
444
|
-
start,
|
|
445
|
-
end
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
} catch (e) {
|
|
449
|
-
// do nothing
|
|
450
|
-
}
|
|
386
|
+
reactProfilerTimingMap(data);
|
|
451
387
|
}
|
|
452
388
|
try {
|
|
453
389
|
// dispatch a global window event to notify the measure is completed
|
|
@@ -467,57 +403,93 @@ export const sinkInteractionHandler = sinkFn => {
|
|
|
467
403
|
interactionQueue.length = 0;
|
|
468
404
|
}
|
|
469
405
|
};
|
|
406
|
+
export const sinkExperimentalHandler = sinkFn => {
|
|
407
|
+
experimentalInteractionLog.sinkHandler(sinkFn);
|
|
408
|
+
};
|
|
470
409
|
export const sinkPostInteractionLogHandler = sinkFn => {
|
|
471
410
|
postInteractionLog.sinkHandler(sinkFn);
|
|
472
411
|
};
|
|
412
|
+
|
|
413
|
+
// a flag to prevent mutliple submittions
|
|
414
|
+
let activeSubmitted = false;
|
|
473
415
|
export function tryComplete(interactionId, endTime) {
|
|
474
416
|
const interaction = interactions.get(interactionId);
|
|
475
417
|
if (interaction != null) {
|
|
476
|
-
const
|
|
477
|
-
|
|
418
|
+
const noMoreActiveHolds = interaction.holdActive.size === 0;
|
|
419
|
+
const noMoreExpHolds = interaction.holdExpActive.size === 0;
|
|
420
|
+
const postInteraction = () => {
|
|
478
421
|
var _getConfig4, _getConfig4$postInter;
|
|
479
|
-
finishInteraction(interactionId, interaction, endTime);
|
|
480
422
|
if ((_getConfig4 = getConfig()) !== null && _getConfig4 !== void 0 && (_getConfig4$postInter = _getConfig4.postInteractionLog) !== null && _getConfig4$postInter !== void 0 && _getConfig4$postInter.enabled) {
|
|
481
|
-
|
|
423
|
+
var _getExperimentalVCMet;
|
|
424
|
+
const experimentalVC90 = (_getExperimentalVCMet = getExperimentalVCMetrics(interaction)) === null || _getExperimentalVCMet === void 0 ? void 0 : _getExperimentalVCMet['metric:experimental:vc90'];
|
|
425
|
+
const experimentalTTAI = getTTAI(interaction);
|
|
426
|
+
postInteractionLog.onInteractionComplete({
|
|
427
|
+
...interaction,
|
|
428
|
+
experimentalTTAI,
|
|
429
|
+
experimentalVC90
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
remove(interactionId);
|
|
433
|
+
activeSubmitted = false;
|
|
434
|
+
};
|
|
435
|
+
if (noMoreActiveHolds) {
|
|
436
|
+
if (!activeSubmitted) {
|
|
437
|
+
finishInteraction(interactionId, interaction, endTime);
|
|
438
|
+
activeSubmitted = true;
|
|
439
|
+
}
|
|
440
|
+
if (noMoreExpHolds) {
|
|
441
|
+
var _getConfig5, _getConfig5$experimen;
|
|
442
|
+
if ((_getConfig5 = getConfig()) !== null && _getConfig5 !== void 0 && (_getConfig5$experimen = _getConfig5.experimentalInteractionMetrics) !== null && _getConfig5$experimen !== void 0 && _getConfig5$experimen.enabled) {
|
|
443
|
+
experimentalInteractionLog.onInteractionComplete(interactionId, interaction, endTime);
|
|
444
|
+
}
|
|
445
|
+
postInteraction();
|
|
482
446
|
}
|
|
483
447
|
}
|
|
484
448
|
}
|
|
485
449
|
}
|
|
486
|
-
function callCancelCallbacks(interaction) {
|
|
487
|
-
interaction.cancelCallbacks.reverse().forEach(cancelCallback => {
|
|
488
|
-
cancelCallback();
|
|
489
|
-
});
|
|
490
|
-
}
|
|
491
450
|
export function abort(interactionId, abortReason) {
|
|
492
451
|
const interaction = interactions.get(interactionId);
|
|
493
452
|
if (interaction != null) {
|
|
453
|
+
var _getConfig6, _getConfig6$experimen;
|
|
494
454
|
callCancelCallbacks(interaction);
|
|
495
455
|
interaction.abortReason = abortReason;
|
|
496
456
|
finishInteraction(interactionId, interaction);
|
|
457
|
+
if ((_getConfig6 = getConfig()) !== null && _getConfig6 !== void 0 && (_getConfig6$experimen = _getConfig6.experimentalInteractionMetrics) !== null && _getConfig6$experimen !== void 0 && _getConfig6$experimen.enabled) {
|
|
458
|
+
experimentalInteractionLog.onInteractionComplete(interactionId, interaction);
|
|
459
|
+
}
|
|
460
|
+
remove(interactionId);
|
|
497
461
|
}
|
|
498
462
|
}
|
|
499
463
|
export function abortByNewInteraction(interactionId, interactionName) {
|
|
500
464
|
const interaction = interactions.get(interactionId);
|
|
501
465
|
if (interaction != null) {
|
|
466
|
+
var _getConfig7, _getConfig7$experimen;
|
|
502
467
|
callCancelCallbacks(interaction);
|
|
503
468
|
interaction.abortReason = 'new_interaction';
|
|
504
469
|
interaction.abortedByInteractionName = interactionName;
|
|
505
470
|
finishInteraction(interactionId, interaction);
|
|
471
|
+
if ((_getConfig7 = getConfig()) !== null && _getConfig7 !== void 0 && (_getConfig7$experimen = _getConfig7.experimentalInteractionMetrics) !== null && _getConfig7$experimen !== void 0 && _getConfig7$experimen.enabled) {
|
|
472
|
+
experimentalInteractionLog.onInteractionComplete(interactionId, interaction);
|
|
473
|
+
}
|
|
474
|
+
remove(interactionId);
|
|
506
475
|
}
|
|
507
476
|
}
|
|
508
477
|
export function abortAll(abortReason, abortedByInteractionName) {
|
|
509
478
|
interactions.forEach((interaction, interactionId) => {
|
|
479
|
+
var _getConfig8, _getConfig8$experimen;
|
|
510
480
|
const noMoreHolds = interaction.holdActive.size === 0;
|
|
511
481
|
if (!noMoreHolds) {
|
|
512
482
|
callCancelCallbacks(interaction);
|
|
513
|
-
// eslint-disable-next-line no-param-reassign
|
|
514
483
|
interaction.abortReason = abortReason;
|
|
515
484
|
if (abortedByInteractionName != null) {
|
|
516
|
-
// eslint-disable-next-line no-param-reassign
|
|
517
485
|
interaction.abortedByInteractionName = abortedByInteractionName;
|
|
518
486
|
}
|
|
519
487
|
}
|
|
520
488
|
finishInteraction(interactionId, interaction);
|
|
489
|
+
if ((_getConfig8 = getConfig()) !== null && _getConfig8 !== void 0 && (_getConfig8$experimen = _getConfig8.experimentalInteractionMetrics) !== null && _getConfig8$experimen !== void 0 && _getConfig8$experimen.enabled) {
|
|
490
|
+
experimentalInteractionLog.onInteractionComplete(interactionId, interaction);
|
|
491
|
+
}
|
|
492
|
+
remove(interactionId);
|
|
521
493
|
});
|
|
522
494
|
}
|
|
523
495
|
export function addOnCancelCallback(id, cancelCallback) {
|
|
@@ -525,8 +497,8 @@ export function addOnCancelCallback(id, cancelCallback) {
|
|
|
525
497
|
interaction === null || interaction === void 0 ? void 0 : interaction.cancelCallbacks.push(cancelCallback);
|
|
526
498
|
}
|
|
527
499
|
export function addNewInteraction(interactionId, ufoName, type, startTime, rate, labelStack, routeName, trace = null) {
|
|
528
|
-
var
|
|
529
|
-
if ((
|
|
500
|
+
var _getConfig9, _getConfig9$postInter;
|
|
501
|
+
if ((_getConfig9 = getConfig()) !== null && _getConfig9 !== void 0 && (_getConfig9$postInter = _getConfig9.postInteractionLog) !== null && _getConfig9$postInter !== void 0 && _getConfig9$postInter.enabled) {
|
|
530
502
|
postInteractionLog.reset();
|
|
531
503
|
}
|
|
532
504
|
let previousTime = startTime;
|
|
@@ -566,9 +538,11 @@ export function addNewInteraction(interactionId, ufoName, type, startTime, rate,
|
|
|
566
538
|
requestInfo: [],
|
|
567
539
|
reactProfilerTimings: [],
|
|
568
540
|
holdInfo: [],
|
|
541
|
+
holdExpInfo: [],
|
|
569
542
|
holdActive: new Map(),
|
|
543
|
+
holdExpActive: new Map(),
|
|
570
544
|
// measure when we execute this code
|
|
571
|
-
// from this we can measure the input delay -
|
|
545
|
+
// from this, we can measure the input delay -
|
|
572
546
|
// how long the browser took to hand execution back to JS)
|
|
573
547
|
measureStart: performance.now(),
|
|
574
548
|
rate,
|
|
@@ -680,17 +654,6 @@ export function addRequestInfo(interactionId, labelStack, requestInfo) {
|
|
|
680
654
|
});
|
|
681
655
|
}
|
|
682
656
|
}
|
|
683
|
-
function isSegmentLabel(obj) {
|
|
684
|
-
return obj && typeof obj.name === 'string' && typeof obj.segmentId === 'string';
|
|
685
|
-
}
|
|
686
|
-
function getSegmentCacheKey(labelStack) {
|
|
687
|
-
return labelStack.map(l => {
|
|
688
|
-
if (isSegmentLabel(l)) {
|
|
689
|
-
return `${l.name}_${l.segmentId}`;
|
|
690
|
-
}
|
|
691
|
-
return l.name;
|
|
692
|
-
}).join('|');
|
|
693
|
-
}
|
|
694
657
|
export function addSegment(labelStack) {
|
|
695
658
|
const key = getSegmentCacheKey(labelStack);
|
|
696
659
|
const existingSegment = segmentCache.get(key);
|
|
@@ -121,7 +121,9 @@ export default class PostInteractionLog {
|
|
|
121
121
|
abortReason,
|
|
122
122
|
abortedByInteractionName,
|
|
123
123
|
routeName,
|
|
124
|
-
type
|
|
124
|
+
type,
|
|
125
|
+
experimentalTTAI,
|
|
126
|
+
experimentalVC90
|
|
125
127
|
}) {
|
|
126
128
|
var _getConfig;
|
|
127
129
|
this.lastInteractionFinish = {
|
|
@@ -132,7 +134,9 @@ export default class PostInteractionLog {
|
|
|
132
134
|
abortReason,
|
|
133
135
|
abortedByInteractionName,
|
|
134
136
|
routeName,
|
|
135
|
-
type
|
|
137
|
+
type,
|
|
138
|
+
experimentalTTAI,
|
|
139
|
+
experimentalVC90
|
|
136
140
|
};
|
|
137
141
|
const timeout = ((_getConfig = getConfig()) === null || _getConfig === void 0 ? void 0 : _getConfig.timeWindowForLateMutationsInMilliseconds) || POST_INTERACTION_LOG_SEND_DEFAULT_TIMEOUT;
|
|
138
142
|
this.sinkTimeoutId = window.setTimeout(() => {
|
|
@@ -2,7 +2,7 @@ import { unstable_IdlePriority as idlePriority, unstable_scheduleCallback as sch
|
|
|
2
2
|
import { startLighthouseObserver } from '../additional-payload';
|
|
3
3
|
import { setUFOConfig } from '../config';
|
|
4
4
|
import { setupHiddenTimingCapture } from '../hidden-timing';
|
|
5
|
-
import { postInteractionLog, sinkInteractionHandler, sinkPostInteractionLogHandler } from '../interaction-metrics';
|
|
5
|
+
import { experimentalInteractionLog, postInteractionLog, sinkExperimentalHandler, sinkInteractionHandler, sinkPostInteractionLogHandler } from '../interaction-metrics';
|
|
6
6
|
import { getVCObserver } from '../vc';
|
|
7
7
|
let initialized = false;
|
|
8
8
|
function sinkInteraction(instance, payloadPackage) {
|
|
@@ -15,6 +15,14 @@ function sinkInteraction(instance, payloadPackage) {
|
|
|
15
15
|
});
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
|
+
function sinkExperimentalInteractionMetrics(instance, payloadPackage) {
|
|
19
|
+
sinkExperimentalHandler((interactionId, interaction) => {
|
|
20
|
+
scheduleCallback(idlePriority, () => {
|
|
21
|
+
const payload = payloadPackage.createExperimentalInteractionMetricsPayload(interactionId, interaction);
|
|
22
|
+
instance.sendOperationalEvent(payload);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
18
26
|
function sinkPostInteractionLog(instance, createPostInteractionLogPayload) {
|
|
19
27
|
sinkPostInteractionLogHandler(logOutput => {
|
|
20
28
|
scheduleCallback(idlePriority, () => {
|
|
@@ -45,27 +53,32 @@ export const init = (analyticsWebClientAsync, config) => {
|
|
|
45
53
|
postInteractionLog.startVCObserver({
|
|
46
54
|
startTime: 0
|
|
47
55
|
});
|
|
56
|
+
experimentalInteractionLog.initializeVCObserver(vcOptions).startVCObserver({
|
|
57
|
+
startTime: 0
|
|
58
|
+
});
|
|
48
59
|
}
|
|
49
60
|
setupHiddenTimingCapture();
|
|
50
61
|
startLighthouseObserver();
|
|
51
62
|
initialized = true;
|
|
52
|
-
Promise.all([analyticsWebClientAsync,
|
|
53
|
-
// eslint-disable-next-line import/dynamic-import-chunkname
|
|
54
|
-
import( /* webpackChunkName: "create-payloads" */'../create-payload'),
|
|
55
|
-
// eslint-disable-next-line import/dynamic-import-chunkname
|
|
56
|
-
import( /* webpackChunkName: "create-post-intreaction-log-payload" */'../create-post-interaction-log-payload')]).then(([awc, payloadPackage, createPostInteractionLogPayloadPackage]) => {
|
|
63
|
+
Promise.all([analyticsWebClientAsync, import( /* webpackChunkName: "create-payloads" */'../create-payload'), import( /* webpackChunkName: "create-experimental-interaction-metrics-payload" */'../create-experimental-interaction-metrics-payload'), import( /* webpackChunkName: "create-post-interaction-log-payload" */'../create-post-interaction-log-payload')]).then(([awc, payloadPackage, createExperimentalInteractionMetricsPayload, createPostInteractionLogPayloadPackage]) => {
|
|
57
64
|
if (awc.getAnalyticsWebClientPromise) {
|
|
58
65
|
awc.getAnalyticsWebClientPromise().then(client => {
|
|
59
|
-
var _config$postInteracti;
|
|
66
|
+
var _config$experimentalI, _config$postInteracti;
|
|
60
67
|
const instance = client.getInstance();
|
|
61
68
|
sinkInteraction(instance, payloadPackage);
|
|
69
|
+
if (config !== null && config !== void 0 && (_config$experimentalI = config.experimentalInteractionMetrics) !== null && _config$experimentalI !== void 0 && _config$experimentalI.enabled) {
|
|
70
|
+
sinkExperimentalInteractionMetrics(instance, createExperimentalInteractionMetricsPayload);
|
|
71
|
+
}
|
|
62
72
|
if ((_config$postInteracti = config.postInteractionLog) !== null && _config$postInteracti !== void 0 && _config$postInteracti.enabled) {
|
|
63
73
|
sinkPostInteractionLog(instance, createPostInteractionLogPayloadPackage.default);
|
|
64
74
|
}
|
|
65
75
|
});
|
|
66
76
|
} else if (awc.sendOperationalEvent) {
|
|
67
|
-
var _config$postInteracti2;
|
|
77
|
+
var _config$experimentalI2, _config$postInteracti2;
|
|
68
78
|
sinkInteraction(awc, payloadPackage);
|
|
79
|
+
if (config !== null && config !== void 0 && (_config$experimentalI2 = config.experimentalInteractionMetrics) !== null && _config$experimentalI2 !== void 0 && _config$experimentalI2.enabled) {
|
|
80
|
+
sinkExperimentalInteractionMetrics(awc, createExperimentalInteractionMetricsPayload);
|
|
81
|
+
}
|
|
69
82
|
if ((_config$postInteracti2 = config.postInteractionLog) !== null && _config$postInteracti2 !== void 0 && _config$postInteracti2.enabled) {
|
|
70
83
|
sinkPostInteractionLog(awc, createPostInteractionLogPayloadPackage.default);
|
|
71
84
|
}
|
|
@@ -22,8 +22,7 @@ const useLayoutEffectSAFE = typeof window === 'undefined' ? useEffect : useLayou
|
|
|
22
22
|
* return (
|
|
23
23
|
* <>
|
|
24
24
|
* <Skeleton />
|
|
25
|
-
* <UFOLoadHold name="card"
|
|
26
|
-
* </UFOLoadHold>
|
|
25
|
+
* <UFOLoadHold name="card" />
|
|
27
26
|
* )
|
|
28
27
|
* }
|
|
29
28
|
* ```
|
|
@@ -57,8 +56,8 @@ export default function UFOLoadHold({
|
|
|
57
56
|
// react-18: useId instead
|
|
58
57
|
const context = useContext(UFOInteractionContext);
|
|
59
58
|
useLayoutEffectSAFE(() => {
|
|
60
|
-
if (hold &&
|
|
61
|
-
return context.hold(name);
|
|
59
|
+
if (hold && context != null) {
|
|
60
|
+
return context.hold(name, experimental);
|
|
62
61
|
}
|
|
63
62
|
}, [hold, context, name]);
|
|
64
63
|
|
|
@@ -67,15 +67,13 @@ export default function UFOSegment({
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
-
function _internalHold(labelStack, name
|
|
71
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
|
72
|
-
) {
|
|
70
|
+
function _internalHold(labelStack, name, experimental = false) {
|
|
73
71
|
if (interactionId.current != null) {
|
|
74
72
|
if (parentContext) {
|
|
75
|
-
return parentContext._internalHold(labelStack, name);
|
|
73
|
+
return parentContext._internalHold(labelStack, name, experimental);
|
|
76
74
|
} else {
|
|
77
75
|
const capturedInteractionId = interactionId.current;
|
|
78
|
-
const disposeHold = addHold(interactionId.current, labelStack, name);
|
|
76
|
+
const disposeHold = addHold(interactionId.current, labelStack, name, experimental);
|
|
79
77
|
return () => {
|
|
80
78
|
if (capturedInteractionId === interactionId.current) {
|
|
81
79
|
disposeHold();
|
|
@@ -84,9 +82,7 @@ export default function UFOSegment({
|
|
|
84
82
|
}
|
|
85
83
|
}
|
|
86
84
|
}
|
|
87
|
-
function _internalHoldByID(labelStack, id, name, remove
|
|
88
|
-
// eslint-disable-next-line @typescript-eslint/no-invalid-void-type
|
|
89
|
-
) {
|
|
85
|
+
function _internalHoldByID(labelStack, id, name, remove) {
|
|
90
86
|
if (interactionId.current != null) {
|
|
91
87
|
if (parentContext) {
|
|
92
88
|
parentContext._internalHoldByID(labelStack, name, id, remove);
|
|
@@ -108,10 +104,8 @@ export default function UFOSegment({
|
|
|
108
104
|
}
|
|
109
105
|
return {
|
|
110
106
|
labelStack,
|
|
111
|
-
hold(name = 'unknown'
|
|
112
|
-
|
|
113
|
-
) {
|
|
114
|
-
return this._internalHold(this.labelStack, name);
|
|
107
|
+
hold(name = 'unknown', experimental) {
|
|
108
|
+
return this._internalHold(this.labelStack, name, experimental);
|
|
115
109
|
},
|
|
116
110
|
addHoldByID(labelStack, id, name = 'unknown') {
|
|
117
111
|
this._internalHoldByID(labelStack, id, name, false);
|
|
@@ -5,7 +5,7 @@ import { getActiveTrace } from '../experience-trace-id-context';
|
|
|
5
5
|
import { DefaultInteractionID } from '../interaction-id-context';
|
|
6
6
|
import { abort, addHoldByID, addNewInteraction, getActiveInteraction, removeHoldByID, updatePageLoadInteractionName } from '../interaction-metrics';
|
|
7
7
|
import UFORouteName from '../route-name-context';
|
|
8
|
-
const AWAITING_PAGELOAD_NAME = 'awaiting_pageload_name';
|
|
8
|
+
export const AWAITING_PAGELOAD_NAME = 'awaiting_pageload_name';
|
|
9
9
|
export default function traceUFOPageLoad(ufoName, routeName = ufoName) {
|
|
10
10
|
const activeInteraction = getActiveInteraction();
|
|
11
11
|
if (activeInteraction && !ufoName) {
|