@atlaskit/react-ufo 4.14.3 → 4.14.4

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.
Files changed (30) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/cjs/config/index.js +4 -0
  3. package/dist/cjs/create-payload/index.js +22 -2
  4. package/dist/cjs/create-payload/utils/get-vc-metrics.js +10 -6
  5. package/dist/cjs/vc/index.js +4 -3
  6. package/dist/cjs/vc/vc-observer-new/index.js +31 -7
  7. package/dist/cjs/vc/vc-observer-new/raw-data-handler/index.js +237 -0
  8. package/dist/es2019/config/index.js +3 -0
  9. package/dist/es2019/create-payload/index.js +17 -1
  10. package/dist/es2019/create-payload/utils/get-vc-metrics.js +5 -2
  11. package/dist/es2019/vc/index.js +4 -2
  12. package/dist/es2019/vc/vc-observer-new/index.js +20 -1
  13. package/dist/es2019/vc/vc-observer-new/raw-data-handler/index.js +173 -0
  14. package/dist/esm/config/index.js +3 -0
  15. package/dist/esm/create-payload/index.js +22 -2
  16. package/dist/esm/create-payload/utils/get-vc-metrics.js +11 -7
  17. package/dist/esm/vc/index.js +4 -3
  18. package/dist/esm/vc/vc-observer-new/index.js +31 -7
  19. package/dist/esm/vc/vc-observer-new/raw-data-handler/index.js +231 -0
  20. package/dist/types/common/vc/types.d.ts +20 -1
  21. package/dist/types/config/index.d.ts +6 -0
  22. package/dist/types/vc/types.d.ts +1 -0
  23. package/dist/types/vc/vc-observer-new/raw-data-handler/index.d.ts +20 -0
  24. package/dist/types/vc/vc-observer-new/types.d.ts +2 -0
  25. package/dist/types-ts4.5/common/vc/types.d.ts +25 -1
  26. package/dist/types-ts4.5/config/index.d.ts +6 -0
  27. package/dist/types-ts4.5/vc/types.d.ts +1 -0
  28. package/dist/types-ts4.5/vc/vc-observer-new/raw-data-handler/index.d.ts +20 -0
  29. package/dist/types-ts4.5/vc/vc-observer-new/types.d.ts +2 -0
  30. package/package.json +4 -1
@@ -0,0 +1,173 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import getViewportHeight from '../metric-calculator/utils/get-viewport-height';
3
+ import getViewportWidth from '../metric-calculator/utils/get-viewport-width';
4
+ const ABORTING_WINDOW_EVENT = ['wheel', 'scroll', 'keydown', 'resize'];
5
+ const MAX_OBSERVATIONS = 100;
6
+ export default class RawDataHandler {
7
+ constructor() {
8
+ _defineProperty(this, "revisionNo", 'raw-handler');
9
+ }
10
+ getVCCleanStatus(filteredEntries) {
11
+ let dirtyReason = '';
12
+ let abortTimestamp = -1;
13
+ const hasAbortEvent = filteredEntries.some(entry => {
14
+ if (entry.data.type === 'window:event') {
15
+ const data = entry.data;
16
+ if (ABORTING_WINDOW_EVENT.includes(data.eventType)) {
17
+ dirtyReason = data.eventType === 'keydown' ? 'keypress' : data.eventType;
18
+ abortTimestamp = Math.round(entry.time);
19
+ return true;
20
+ }
21
+ }
22
+ return false;
23
+ });
24
+ if (hasAbortEvent && dirtyReason) {
25
+ return {
26
+ isVCClean: false,
27
+ dirtyReason,
28
+ abortTimestamp
29
+ };
30
+ }
31
+ return {
32
+ isVCClean: true
33
+ };
34
+ }
35
+ async getRawData({
36
+ entries,
37
+ startTime,
38
+ stopTime,
39
+ isPageVisible
40
+ }) {
41
+ var _rawObservations;
42
+ let isVCClean;
43
+ let dirtyReason;
44
+ const getVCCleanStatusResult = this.getVCCleanStatus(entries);
45
+ isVCClean = getVCCleanStatusResult.isVCClean;
46
+ dirtyReason = getVCCleanStatusResult.dirtyReason;
47
+ if (!isPageVisible) {
48
+ return {
49
+ revision: this.revisionNo,
50
+ clean: false,
51
+ 'metric:vc90': null,
52
+ abortReason: 'browser_backgrounded',
53
+ abortTimestamp: -1,
54
+ viewport: {
55
+ w: getViewportWidth(),
56
+ h: getViewportHeight()
57
+ }
58
+ };
59
+ }
60
+ const viewportEntries = entries.filter(entry => {
61
+ return entry.time >= startTime && entry.time <= stopTime && entry.data && entry.data.visible;
62
+ });
63
+ const targetNameToIdMap = new Map();
64
+ const elementMapEntriesMap = {};
65
+ let nextElementId = 1;
66
+ const typeMap = new Map();
67
+ const typeMapEntriesMap = {};
68
+ let nextTypeId = 1;
69
+ const attributeMap = new Map();
70
+ const attributeEntriesMap = {};
71
+ let nextAttributeId = 1;
72
+ let rawObservations = viewportEntries.map(entry => {
73
+ const viewportEntry = entry.data;
74
+ const targetName = viewportEntry.elementName || '';
75
+ const type = viewportEntry.type || '';
76
+ const rect = viewportEntry.rect;
77
+ const attributeName = viewportEntry.attributeName || '';
78
+ let eid = targetNameToIdMap.get(viewportEntry.elementName || '') || 0;
79
+ if (eid === 0) {
80
+ eid = nextElementId;
81
+ nextElementId += 1;
82
+ targetNameToIdMap.set(targetName, eid);
83
+ elementMapEntriesMap[eid] = targetName;
84
+ }
85
+ let chg = typeMap.get(type || '') || 0;
86
+ if (chg === 0) {
87
+ chg = nextTypeId;
88
+ nextTypeId += 1;
89
+ typeMap.set(type, chg);
90
+ typeMapEntriesMap[chg] = type;
91
+ }
92
+ let att = 0;
93
+ if (attributeName) {
94
+ att = attributeMap.get(attributeName) || 0;
95
+ if (att === 0) {
96
+ att = nextAttributeId;
97
+ nextAttributeId += 1;
98
+ attributeMap.set(attributeName, att);
99
+ attributeEntriesMap[att] = attributeName;
100
+ }
101
+ }
102
+ const observation = {
103
+ t: Math.round(entry.time),
104
+ r: [Math.round(rect.left * 10) / 10, Math.round(rect.top * 10) / 10, Math.round(rect.right * 10) / 10, Math.round(rect.bottom * 10) / 10],
105
+ chg,
106
+ eid: eid || 0,
107
+ ...(att > 0 ? {
108
+ att
109
+ } : {})
110
+ };
111
+ return observation;
112
+ });
113
+ // If the number of observations is greater than the maximum allowed, we need to trim the observations to the maximum allowed.
114
+ // We do this by keeping the first observation and the last MAX_OBSERVATIONS observations.
115
+ // We then collect the referenced IDs from the remaining observations and remove the unreferenced entries from the maps
116
+ if (rawObservations.length > MAX_OBSERVATIONS) {
117
+ const firstObservation = rawObservations[0];
118
+ const lastObservations = rawObservations.slice(-MAX_OBSERVATIONS);
119
+ rawObservations = [firstObservation, ...lastObservations];
120
+
121
+ // Collect referenced IDs from remaining observations
122
+ const referencedEids = new Set();
123
+ const referencedChgs = new Set();
124
+ const referencedAtts = new Set();
125
+ for (const observation of rawObservations) {
126
+ if (observation.eid > 0) {
127
+ referencedEids.add(observation.eid);
128
+ }
129
+ if (typeof observation.chg === 'number' && observation.chg > 0) {
130
+ referencedChgs.add(observation.chg);
131
+ }
132
+ if (observation.att !== undefined && observation.att > 0) {
133
+ referencedAtts.add(observation.att);
134
+ }
135
+ }
136
+
137
+ // Remove unreferenced entries from maps
138
+ for (const eid of Object.keys(elementMapEntriesMap).map(Number)) {
139
+ if (!referencedEids.has(eid)) {
140
+ delete elementMapEntriesMap[eid];
141
+ }
142
+ }
143
+ for (const chg of Object.keys(typeMapEntriesMap).map(Number)) {
144
+ if (!referencedChgs.has(chg)) {
145
+ delete typeMapEntriesMap[chg];
146
+ }
147
+ }
148
+ for (const att of Object.keys(attributeEntriesMap).map(Number)) {
149
+ if (!referencedAtts.has(att)) {
150
+ delete attributeEntriesMap[att];
151
+ }
152
+ }
153
+ }
154
+ const result = {
155
+ revision: this.revisionNo,
156
+ clean: isVCClean,
157
+ 'metric:vc90': null,
158
+ rawData: {
159
+ obs: (_rawObservations = rawObservations) !== null && _rawObservations !== void 0 ? _rawObservations : undefined,
160
+ eid: elementMapEntriesMap !== null && elementMapEntriesMap !== void 0 ? elementMapEntriesMap : undefined,
161
+ chg: typeMapEntriesMap !== null && typeMapEntriesMap !== void 0 ? typeMapEntriesMap : undefined,
162
+ att: attributeEntriesMap !== null && attributeEntriesMap !== void 0 ? attributeEntriesMap : undefined
163
+ },
164
+ abortReason: dirtyReason,
165
+ abortTimestamp: getVCCleanStatusResult.abortTimestamp,
166
+ viewport: {
167
+ w: getViewportWidth(),
168
+ h: getViewportHeight()
169
+ }
170
+ };
171
+ return result;
172
+ }
173
+ }
@@ -167,6 +167,9 @@ export function getExperimentalInteractionRate(name, interactionType) {
167
167
  return 0;
168
168
  }
169
169
  }
170
+ export function getVCRawDataInteractionRate(name, interactionType) {
171
+ return getConfigRate(name, interactionType, 'enableVCRawDataRates');
172
+ }
170
173
  export function getPostInteractionRate(name, interactionType) {
171
174
  return getConfigRate(name, interactionType, 'postInteractionLog');
172
175
  }
@@ -52,6 +52,7 @@ import { optimizeMarks } from './utils/optimize-marks';
52
52
  import { optimizeReactProfilerTimings } from './utils/optimize-react-profiler-timings';
53
53
  import { optimizeRequestInfo } from './utils/optimize-request-info';
54
54
  import { optimizeSpans } from './utils/optimize-spans';
55
+ var MAX_PAYLOAD_SIZE = 250;
55
56
  function getUfoNameOverride(interaction) {
56
57
  var ufoName = interaction.ufoName,
57
58
  apdex = interaction.apdex;
@@ -390,7 +391,7 @@ function createInteractionMetricsPayload(_x, _x2, _x3, _x4, _x5) {
390
391
  function _createInteractionMetricsPayload() {
391
392
  _createInteractionMetricsPayload = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(interaction, interactionId, experimental, criticalPayloadCount, vcMetrics) {
392
393
  var _window$location, _config$additionalPay;
393
- var interactionPayloadStart, config, end, start, ufoName, knownSegments, rate, type, abortReason, routeName, featureFlags, previousInteractionName, isPreviousInteractionAborted, abortedByInteractionName, responsiveness, unknownElementName, unknownElementHierarchy, hydration, pageVisibilityAtTTI, pageVisibilityAtTTAI, segments, segmentTree, isDetailedPayload, isPageLoad, calculatePageVisibilityFromTheStartOfPageLoad, moreAccuratePageVisibilityAtTTI, moreAccuratePageVisibilityAtTTAI, labelStack, getInitialPageLoadSSRMetrics, pageLoadInteractionMetrics, getDetailedInteractionMetrics, getPageLoadDetailedInteractionMetrics, newUFOName, resourceTimings, _yield$Promise$all, _yield$Promise$all2, finalVCMetrics, experimentalMetrics, paintMetrics, batteryInfo, getReactHydrationStats, payload;
394
+ var interactionPayloadStart, config, end, start, ufoName, knownSegments, rate, type, abortReason, routeName, featureFlags, previousInteractionName, isPreviousInteractionAborted, abortedByInteractionName, responsiveness, unknownElementName, unknownElementHierarchy, hydration, pageVisibilityAtTTI, pageVisibilityAtTTAI, segments, segmentTree, isDetailedPayload, isPageLoad, calculatePageVisibilityFromTheStartOfPageLoad, moreAccuratePageVisibilityAtTTI, moreAccuratePageVisibilityAtTTAI, labelStack, getInitialPageLoadSSRMetrics, pageLoadInteractionMetrics, getDetailedInteractionMetrics, getPageLoadDetailedInteractionMetrics, newUFOName, resourceTimings, _yield$Promise$all, _yield$Promise$all2, finalVCMetrics, experimentalMetrics, paintMetrics, batteryInfo, getReactHydrationStats, payload, size, vcRev, rawData, rawDataSize;
394
395
  return _regeneratorRuntime.wrap(function _callee$(_context) {
395
396
  while (1) switch (_context.prev = _context.next) {
396
397
  case 0:
@@ -596,7 +597,26 @@ function _createInteractionMetricsPayload() {
596
597
  regularTTAI = undefined;
597
598
  expTTAI = undefined;
598
599
  }
599
- payload.attributes.properties['event:sizeInKb'] = getPayloadSize(payload.attributes.properties);
600
+ if (fg('platform_ufo_enable_vc_raw_data')) {
601
+ size = getPayloadSize(payload.attributes.properties);
602
+ vcRev = payload.attributes.properties['ufo:vc:rev'];
603
+ rawData = vcRev.find(function (item) {
604
+ return item.revision === 'raw-handler';
605
+ });
606
+ if (rawData) {
607
+ rawDataSize = getPayloadSize(rawData);
608
+ payload.attributes.properties['ufo:vc:raw:size'] = rawDataSize;
609
+ if (size > MAX_PAYLOAD_SIZE && Array.isArray(vcRev) && vcRev.length > 0) {
610
+ payload.attributes.properties['ufo:vc:rev'] = vcRev.filter(function (item) {
611
+ return item.revision !== 'raw-handler';
612
+ });
613
+ payload.attributes.properties['ufo:vc:raw:removed'] = true;
614
+ }
615
+ }
616
+ payload.attributes.properties['event:sizeInKb'] = getPayloadSize(payload.attributes.properties);
617
+ } else {
618
+ payload.attributes.properties['event:sizeInKb'] = getPayloadSize(payload.attributes.properties);
619
+ }
600
620
  return _context.abrupt("return", payload);
601
621
  case 47:
602
622
  case "end":
@@ -3,7 +3,8 @@ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
3
  import _regeneratorRuntime from "@babel/runtime/regenerator";
4
4
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
5
5
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
6
- import { getConfig, getMostRecentVCRevision } from '../../config';
6
+ import coinflip from '../../coinflip';
7
+ import { getConfig, getMostRecentVCRevision, getVCRawDataInteractionRate } from '../../config';
7
8
  import { interactionExtraMetrics, postInteractionLog } from '../../interaction-metrics';
8
9
  import getInteractionStatus from './get-interaction-status';
9
10
  import getPageVisibilityUpToTTAI from './get-page-visibility-up-to-ttai';
@@ -22,6 +23,7 @@ function _getVCMetrics() {
22
23
  isPageVisible,
23
24
  shouldReportVCMetrics,
24
25
  observer,
26
+ includeRawData,
25
27
  isSSREnabled,
26
28
  ssr,
27
29
  tti,
@@ -59,6 +61,7 @@ function _getVCMetrics() {
59
61
  }
60
62
  return _context.abrupt("return", {});
61
63
  case 14:
64
+ includeRawData = coinflip(getVCRawDataInteractionRate(interaction.ufoName, interaction.type));
62
65
  isSSREnabled = interaction.type === 'page_load' && ((config === null || config === void 0 ? void 0 : config.ssr) || (config === null || config === void 0 || (_config$vc$ssrWhiteli = config.vc.ssrWhitelist) === null || _config$vc$ssrWhiteli === void 0 ? void 0 : _config$vc$ssrWhiteli.includes(interaction.ufoName)));
63
66
  ssr = interaction.type === 'page_load' && isSSREnabled ? {
64
67
  ssr: getSSRDoneTimeValue(config)
@@ -66,7 +69,7 @@ function _getVCMetrics() {
66
69
  postInteractionLog.setVCObserverSSRConfig(ssr);
67
70
  tti = (_interaction$apdex = interaction.apdex) === null || _interaction$apdex === void 0 || (_interaction$apdex = _interaction$apdex[0]) === null || _interaction$apdex === void 0 ? void 0 : _interaction$apdex.stopTime;
68
71
  prefix = 'ufo';
69
- _context.next = 21;
72
+ _context.next = 22;
70
73
  return observer.getVCResult(_objectSpread(_objectSpread({
71
74
  start: interaction.start,
72
75
  stop: interaction.end,
@@ -82,9 +85,10 @@ function _getVCMetrics() {
82
85
  include3p: include3p,
83
86
  excludeSmartAnswersInSearch: excludeSmartAnswersInSearch,
84
87
  interactionType: interaction.type,
85
- isPageVisible: isPageVisible
88
+ isPageVisible: isPageVisible,
89
+ includeRawData: includeRawData
86
90
  }));
87
- case 21:
91
+ case 22:
88
92
  result = _context.sent;
89
93
  observer.stop(interaction.ufoName);
90
94
  if (!include3p) {
@@ -98,15 +102,15 @@ function _getVCMetrics() {
98
102
  return revision === mostRecentVCRevision;
99
103
  });
100
104
  if (!(!shouldReportVCMetrics || !(mostRecentVCRevisionPayload !== null && mostRecentVCRevisionPayload !== void 0 && mostRecentVCRevisionPayload.clean))) {
101
- _context.next = 28;
105
+ _context.next = 29;
102
106
  break;
103
107
  }
104
108
  return _context.abrupt("return", result);
105
- case 28:
109
+ case 29:
106
110
  return _context.abrupt("return", _objectSpread(_objectSpread({}, result), {}, {
107
111
  'metric:vc90': mostRecentVCRevisionPayload['metric:vc90']
108
112
  }));
109
- case 29:
113
+ case 30:
110
114
  case "end":
111
115
  return _context.stop();
112
116
  }
@@ -112,11 +112,11 @@ export var VCObserverWrapper = /*#__PURE__*/function () {
112
112
  value: function () {
113
113
  var _getVCResult = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(param) {
114
114
  var _this$oldVCObserver4, _this$newVCObserver3, _ref2;
115
- var experienceKey, include3p, excludeSmartAnswersInSearch, includeSSRRatio, v1v2Result, v3Result, ssrRatio;
115
+ var experienceKey, include3p, excludeSmartAnswersInSearch, includeSSRRatio, includeRawData, v1v2Result, v3Result, ssrRatio;
116
116
  return _regeneratorRuntime.wrap(function _callee$(_context) {
117
117
  while (1) switch (_context.prev = _context.next) {
118
118
  case 0:
119
- experienceKey = param.experienceKey, include3p = param.include3p, excludeSmartAnswersInSearch = param.excludeSmartAnswersInSearch, includeSSRRatio = param.includeSSRRatio;
119
+ experienceKey = param.experienceKey, include3p = param.include3p, excludeSmartAnswersInSearch = param.excludeSmartAnswersInSearch, includeSSRRatio = param.includeSSRRatio, includeRawData = param.includeRawData;
120
120
  if (!(isVCRevisionEnabled('fy25.01', experienceKey) || isVCRevisionEnabled('fy25.02', experienceKey))) {
121
121
  _context.next = 7;
122
122
  break;
@@ -146,7 +146,8 @@ export var VCObserverWrapper = /*#__PURE__*/function () {
146
146
  includeSSRRatio: includeSSRRatio,
147
147
  interactionType: param.interactionType,
148
148
  isPageVisible: param.isPageVisible,
149
- interactionAbortReason: param.interactionAbortReason
149
+ interactionAbortReason: param.interactionAbortReason,
150
+ includeRawData: includeRawData
150
151
  });
151
152
  case 12:
152
153
  _context.t1 = _context.sent;
@@ -13,6 +13,7 @@ import VCCalculator_FY25_03 from './metric-calculator/fy25_03';
13
13
  import getViewportHeight from './metric-calculator/utils/get-viewport-height';
14
14
  import getViewportWidth from './metric-calculator/utils/get-viewport-width';
15
15
  import VCNextCalculator from './metric-calculator/vcnext';
16
+ import RawDataHandler from './raw-data-handler';
16
17
  import ViewportObserver from './viewport-observer';
17
18
  import WindowEventObserver from './window-event-observer';
18
19
  var SSRState = {
@@ -231,13 +232,14 @@ var VCObserverNew = /*#__PURE__*/function () {
231
232
  key: "getVCResult",
232
233
  value: function () {
233
234
  var _getVCResult = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(param) {
234
- var start, stop, interactionId, interactionType, interactionAbortReason, isPageVisible, include3p, includeSSRRatio, excludeSmartAnswersInSearch, results, calculator_fy25_03, orderedEntries, fy25_03, calculator_next, vcNext;
235
+ var start, stop, interactionId, interactionType, interactionAbortReason, isPageVisible, include3p, includeSSRRatio, excludeSmartAnswersInSearch, includeRawData, results, feVCCalculationStartTime, calculator_fy25_03, orderedEntries, fy25_03, calculator_next, vcNext, feVCCalculationEndTime, rawVCCalculationStartTime, rawHandler, raw;
235
236
  return _regeneratorRuntime.wrap(function _callee$(_context) {
236
237
  while (1) switch (_context.prev = _context.next) {
237
238
  case 0:
238
- start = param.start, stop = param.stop, interactionId = param.interactionId, interactionType = param.interactionType, interactionAbortReason = param.interactionAbortReason, isPageVisible = param.isPageVisible, include3p = param.include3p, includeSSRRatio = param.includeSSRRatio, excludeSmartAnswersInSearch = param.excludeSmartAnswersInSearch;
239
+ start = param.start, stop = param.stop, interactionId = param.interactionId, interactionType = param.interactionType, interactionAbortReason = param.interactionAbortReason, isPageVisible = param.isPageVisible, include3p = param.include3p, includeSSRRatio = param.includeSSRRatio, excludeSmartAnswersInSearch = param.excludeSmartAnswersInSearch, includeRawData = param.includeRawData;
239
240
  results = [];
240
241
  this.addStartEntry(start);
242
+ feVCCalculationStartTime = performance.now();
241
243
  calculator_fy25_03 = new VCCalculator_FY25_03();
242
244
  if (param.ssr) {
243
245
  this.addSSR(param.ssr);
@@ -246,7 +248,7 @@ var VCObserverNew = /*#__PURE__*/function () {
246
248
  start: start,
247
249
  stop: stop
248
250
  });
249
- _context.next = 8;
251
+ _context.next = 9;
250
252
  return calculator_fy25_03.calculate({
251
253
  orderedEntries: orderedEntries,
252
254
  startTime: start,
@@ -260,7 +262,7 @@ var VCObserverNew = /*#__PURE__*/function () {
260
262
  isPageVisible: isPageVisible,
261
263
  interactionAbortReason: interactionAbortReason
262
264
  });
263
- case 8:
265
+ case 9:
264
266
  fy25_03 = _context.sent;
265
267
  if (fy25_03) {
266
268
  results.push(fy25_03);
@@ -268,7 +270,7 @@ var VCObserverNew = /*#__PURE__*/function () {
268
270
 
269
271
  // TODO on cleanup: put behind `enabledVCRevisions` config
270
272
  calculator_next = new VCNextCalculator();
271
- _context.next = 13;
273
+ _context.next = 14;
272
274
  return calculator_next.calculate({
273
275
  orderedEntries: orderedEntries,
274
276
  startTime: start,
@@ -281,13 +283,35 @@ var VCObserverNew = /*#__PURE__*/function () {
281
283
  isPageVisible: isPageVisible,
282
284
  interactionAbortReason: interactionAbortReason
283
285
  });
284
- case 13:
286
+ case 14:
285
287
  vcNext = _context.sent;
286
288
  if (vcNext) {
287
289
  results.push(vcNext);
288
290
  }
291
+ feVCCalculationEndTime = performance.now();
292
+ if (!(includeRawData && fg('platform_ufo_enable_vc_raw_data'))) {
293
+ _context.next = 24;
294
+ break;
295
+ }
296
+ rawVCCalculationStartTime = performance.now();
297
+ rawHandler = new RawDataHandler();
298
+ _context.next = 22;
299
+ return rawHandler.getRawData({
300
+ entries: orderedEntries,
301
+ startTime: start,
302
+ stopTime: stop,
303
+ isPageVisible: isPageVisible
304
+ });
305
+ case 22:
306
+ raw = _context.sent;
307
+ if (raw) {
308
+ raw.rawVCTime = Number((performance.now() - rawVCCalculationStartTime).toFixed(2));
309
+ raw.feVCTime = Number((feVCCalculationEndTime - feVCCalculationStartTime).toFixed(2));
310
+ results.push(raw);
311
+ }
312
+ case 24:
289
313
  return _context.abrupt("return", results);
290
- case 16:
314
+ case 25:
291
315
  case "end":
292
316
  return _context.stop();
293
317
  }
@@ -0,0 +1,231 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
+ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
4
+ import _createClass from "@babel/runtime/helpers/createClass";
5
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
6
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
7
+ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
8
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
9
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
10
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
11
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
12
+ import getViewportHeight from '../metric-calculator/utils/get-viewport-height';
13
+ import getViewportWidth from '../metric-calculator/utils/get-viewport-width';
14
+ var ABORTING_WINDOW_EVENT = ['wheel', 'scroll', 'keydown', 'resize'];
15
+ var MAX_OBSERVATIONS = 100;
16
+ var RawDataHandler = /*#__PURE__*/function () {
17
+ function RawDataHandler() {
18
+ _classCallCheck(this, RawDataHandler);
19
+ _defineProperty(this, "revisionNo", 'raw-handler');
20
+ }
21
+ return _createClass(RawDataHandler, [{
22
+ key: "getVCCleanStatus",
23
+ value: function getVCCleanStatus(filteredEntries) {
24
+ var dirtyReason = '';
25
+ var abortTimestamp = -1;
26
+ var hasAbortEvent = filteredEntries.some(function (entry) {
27
+ if (entry.data.type === 'window:event') {
28
+ var data = entry.data;
29
+ if (ABORTING_WINDOW_EVENT.includes(data.eventType)) {
30
+ dirtyReason = data.eventType === 'keydown' ? 'keypress' : data.eventType;
31
+ abortTimestamp = Math.round(entry.time);
32
+ return true;
33
+ }
34
+ }
35
+ return false;
36
+ });
37
+ if (hasAbortEvent && dirtyReason) {
38
+ return {
39
+ isVCClean: false,
40
+ dirtyReason: dirtyReason,
41
+ abortTimestamp: abortTimestamp
42
+ };
43
+ }
44
+ return {
45
+ isVCClean: true
46
+ };
47
+ }
48
+ }, {
49
+ key: "getRawData",
50
+ value: function () {
51
+ var _getRawData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref) {
52
+ var entries, startTime, stopTime, isPageVisible, isVCClean, dirtyReason, getVCCleanStatusResult, viewportEntries, targetNameToIdMap, elementMapEntriesMap, nextElementId, typeMap, typeMapEntriesMap, nextTypeId, attributeMap, attributeEntriesMap, nextAttributeId, rawObservations, firstObservation, lastObservations, referencedEids, referencedChgs, referencedAtts, _iterator, _step, observation, _iterator2, _step2, eid, _iterator3, _step3, chg, _iterator4, _step4, att, result;
53
+ return _regeneratorRuntime.wrap(function _callee$(_context) {
54
+ while (1) switch (_context.prev = _context.next) {
55
+ case 0:
56
+ entries = _ref.entries, startTime = _ref.startTime, stopTime = _ref.stopTime, isPageVisible = _ref.isPageVisible;
57
+ getVCCleanStatusResult = this.getVCCleanStatus(entries);
58
+ isVCClean = getVCCleanStatusResult.isVCClean;
59
+ dirtyReason = getVCCleanStatusResult.dirtyReason;
60
+ if (isPageVisible) {
61
+ _context.next = 6;
62
+ break;
63
+ }
64
+ return _context.abrupt("return", {
65
+ revision: this.revisionNo,
66
+ clean: false,
67
+ 'metric:vc90': null,
68
+ abortReason: 'browser_backgrounded',
69
+ abortTimestamp: -1,
70
+ viewport: {
71
+ w: getViewportWidth(),
72
+ h: getViewportHeight()
73
+ }
74
+ });
75
+ case 6:
76
+ viewportEntries = entries.filter(function (entry) {
77
+ return entry.time >= startTime && entry.time <= stopTime && entry.data && entry.data.visible;
78
+ });
79
+ targetNameToIdMap = new Map();
80
+ elementMapEntriesMap = {};
81
+ nextElementId = 1;
82
+ typeMap = new Map();
83
+ typeMapEntriesMap = {};
84
+ nextTypeId = 1;
85
+ attributeMap = new Map();
86
+ attributeEntriesMap = {};
87
+ nextAttributeId = 1;
88
+ rawObservations = viewportEntries.map(function (entry) {
89
+ var viewportEntry = entry.data;
90
+ var targetName = viewportEntry.elementName || '';
91
+ var type = viewportEntry.type || '';
92
+ var rect = viewportEntry.rect;
93
+ var attributeName = viewportEntry.attributeName || '';
94
+ var eid = targetNameToIdMap.get(viewportEntry.elementName || '') || 0;
95
+ if (eid === 0) {
96
+ eid = nextElementId;
97
+ nextElementId += 1;
98
+ targetNameToIdMap.set(targetName, eid);
99
+ elementMapEntriesMap[eid] = targetName;
100
+ }
101
+ var chg = typeMap.get(type || '') || 0;
102
+ if (chg === 0) {
103
+ chg = nextTypeId;
104
+ nextTypeId += 1;
105
+ typeMap.set(type, chg);
106
+ typeMapEntriesMap[chg] = type;
107
+ }
108
+ var att = 0;
109
+ if (attributeName) {
110
+ att = attributeMap.get(attributeName) || 0;
111
+ if (att === 0) {
112
+ att = nextAttributeId;
113
+ nextAttributeId += 1;
114
+ attributeMap.set(attributeName, att);
115
+ attributeEntriesMap[att] = attributeName;
116
+ }
117
+ }
118
+ var observation = _objectSpread({
119
+ t: Math.round(entry.time),
120
+ r: [Math.round(rect.left * 10) / 10, Math.round(rect.top * 10) / 10, Math.round(rect.right * 10) / 10, Math.round(rect.bottom * 10) / 10],
121
+ chg: chg,
122
+ eid: eid || 0
123
+ }, att > 0 ? {
124
+ att: att
125
+ } : {});
126
+ return observation;
127
+ }); // If the number of observations is greater than the maximum allowed, we need to trim the observations to the maximum allowed.
128
+ // We do this by keeping the first observation and the last MAX_OBSERVATIONS observations.
129
+ // We then collect the referenced IDs from the remaining observations and remove the unreferenced entries from the maps
130
+ if (rawObservations.length > MAX_OBSERVATIONS) {
131
+ firstObservation = rawObservations[0];
132
+ lastObservations = rawObservations.slice(-MAX_OBSERVATIONS);
133
+ rawObservations = [firstObservation].concat(_toConsumableArray(lastObservations));
134
+
135
+ // Collect referenced IDs from remaining observations
136
+ referencedEids = new Set();
137
+ referencedChgs = new Set();
138
+ referencedAtts = new Set();
139
+ _iterator = _createForOfIteratorHelper(rawObservations);
140
+ try {
141
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
142
+ observation = _step.value;
143
+ if (observation.eid > 0) {
144
+ referencedEids.add(observation.eid);
145
+ }
146
+ if (typeof observation.chg === 'number' && observation.chg > 0) {
147
+ referencedChgs.add(observation.chg);
148
+ }
149
+ if (observation.att !== undefined && observation.att > 0) {
150
+ referencedAtts.add(observation.att);
151
+ }
152
+ }
153
+
154
+ // Remove unreferenced entries from maps
155
+ } catch (err) {
156
+ _iterator.e(err);
157
+ } finally {
158
+ _iterator.f();
159
+ }
160
+ _iterator2 = _createForOfIteratorHelper(Object.keys(elementMapEntriesMap).map(Number));
161
+ try {
162
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
163
+ eid = _step2.value;
164
+ if (!referencedEids.has(eid)) {
165
+ delete elementMapEntriesMap[eid];
166
+ }
167
+ }
168
+ } catch (err) {
169
+ _iterator2.e(err);
170
+ } finally {
171
+ _iterator2.f();
172
+ }
173
+ _iterator3 = _createForOfIteratorHelper(Object.keys(typeMapEntriesMap).map(Number));
174
+ try {
175
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
176
+ chg = _step3.value;
177
+ if (!referencedChgs.has(chg)) {
178
+ delete typeMapEntriesMap[chg];
179
+ }
180
+ }
181
+ } catch (err) {
182
+ _iterator3.e(err);
183
+ } finally {
184
+ _iterator3.f();
185
+ }
186
+ _iterator4 = _createForOfIteratorHelper(Object.keys(attributeEntriesMap).map(Number));
187
+ try {
188
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
189
+ att = _step4.value;
190
+ if (!referencedAtts.has(att)) {
191
+ delete attributeEntriesMap[att];
192
+ }
193
+ }
194
+ } catch (err) {
195
+ _iterator4.e(err);
196
+ } finally {
197
+ _iterator4.f();
198
+ }
199
+ }
200
+ result = {
201
+ revision: this.revisionNo,
202
+ clean: isVCClean,
203
+ 'metric:vc90': null,
204
+ rawData: {
205
+ obs: rawObservations !== null && rawObservations !== void 0 ? rawObservations : undefined,
206
+ eid: elementMapEntriesMap !== null && elementMapEntriesMap !== void 0 ? elementMapEntriesMap : undefined,
207
+ chg: typeMapEntriesMap !== null && typeMapEntriesMap !== void 0 ? typeMapEntriesMap : undefined,
208
+ att: attributeEntriesMap !== null && attributeEntriesMap !== void 0 ? attributeEntriesMap : undefined
209
+ },
210
+ abortReason: dirtyReason,
211
+ abortTimestamp: getVCCleanStatusResult.abortTimestamp,
212
+ viewport: {
213
+ w: getViewportWidth(),
214
+ h: getViewportHeight()
215
+ }
216
+ };
217
+ return _context.abrupt("return", result);
218
+ case 20:
219
+ case "end":
220
+ return _context.stop();
221
+ }
222
+ }, _callee, this);
223
+ }));
224
+ function getRawData(_x) {
225
+ return _getRawData.apply(this, arguments);
226
+ }
227
+ return getRawData;
228
+ }()
229
+ }]);
230
+ }();
231
+ export { RawDataHandler as default };