@atlaskit/react-ufo 3.10.3 → 3.11.0

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 (49) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/config/index.js +51 -5
  3. package/dist/cjs/create-experimental-interaction-metrics-payload/index.js +2 -1
  4. package/dist/cjs/create-payload/utils/get-vc-metrics.js +41 -20
  5. package/dist/cjs/interaction-metrics/index.js +2 -1
  6. package/dist/cjs/interaction-metrics/post-interaction-log.js +4 -2
  7. package/dist/cjs/vc/index.js +123 -35
  8. package/dist/cjs/vc/vc-observer/getVCRevisionsData.js +48 -23
  9. package/dist/cjs/vc/vc-observer/index.js +17 -6
  10. package/dist/cjs/vc/vc-observer-new/entries-timeline/index.js +1 -3
  11. package/dist/cjs/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/canvas-pixel.js +25 -7
  12. package/dist/cjs/vc/vc-observer-new/viewport-observer/index.js +136 -115
  13. package/dist/es2019/config/index.js +49 -6
  14. package/dist/es2019/create-experimental-interaction-metrics-payload/index.js +2 -1
  15. package/dist/es2019/create-payload/utils/get-vc-metrics.js +36 -19
  16. package/dist/es2019/interaction-metrics/index.js +2 -1
  17. package/dist/es2019/interaction-metrics/post-interaction-log.js +2 -1
  18. package/dist/es2019/vc/index.js +98 -35
  19. package/dist/es2019/vc/vc-observer/getVCRevisionsData.js +52 -25
  20. package/dist/es2019/vc/vc-observer/index.js +18 -6
  21. package/dist/es2019/vc/vc-observer-new/entries-timeline/index.js +1 -3
  22. package/dist/es2019/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/canvas-pixel.js +23 -7
  23. package/dist/es2019/vc/vc-observer-new/viewport-observer/index.js +122 -103
  24. package/dist/esm/config/index.js +49 -5
  25. package/dist/esm/create-experimental-interaction-metrics-payload/index.js +2 -1
  26. package/dist/esm/create-payload/utils/get-vc-metrics.js +42 -21
  27. package/dist/esm/interaction-metrics/index.js +2 -1
  28. package/dist/esm/interaction-metrics/post-interaction-log.js +4 -2
  29. package/dist/esm/vc/index.js +123 -35
  30. package/dist/esm/vc/vc-observer/getVCRevisionsData.js +48 -23
  31. package/dist/esm/vc/vc-observer/index.js +17 -6
  32. package/dist/esm/vc/vc-observer-new/entries-timeline/index.js +1 -3
  33. package/dist/esm/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/canvas-pixel.js +25 -7
  34. package/dist/esm/vc/vc-observer-new/viewport-observer/index.js +136 -115
  35. package/dist/types/config/index.d.ts +14 -3
  36. package/dist/types/create-post-interaction-log-payload/index.d.ts +2 -2
  37. package/dist/types/vc/types.d.ts +3 -1
  38. package/dist/types/vc/vc-observer/getVCRevisionsData.d.ts +5 -3
  39. package/dist/types/vc/vc-observer/index.d.ts +1 -1
  40. package/dist/types/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/canvas-pixel.d.ts +8 -3
  41. package/dist/types/vc/vc-observer-new/viewport-observer/index.d.ts +8 -1
  42. package/dist/types-ts4.5/config/index.d.ts +14 -3
  43. package/dist/types-ts4.5/create-post-interaction-log-payload/index.d.ts +2 -2
  44. package/dist/types-ts4.5/vc/types.d.ts +3 -1
  45. package/dist/types-ts4.5/vc/vc-observer/getVCRevisionsData.d.ts +5 -3
  46. package/dist/types-ts4.5/vc/vc-observer/index.d.ts +1 -1
  47. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/percentile-calc/canvas-heatmap/canvas-pixel.d.ts +8 -3
  48. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/index.d.ts +8 -1
  49. package/package.json +7 -1
@@ -103,7 +103,8 @@ export default class PostInteractionLog {
103
103
  // no need for TTI value here
104
104
  isEventAborted: !!this.lastInteractionFinish.abortReason,
105
105
  prefix: 'ufo',
106
- ...this.vcObserverSSRConfig
106
+ ...this.vcObserverSSRConfig,
107
+ experienceKey: this.lastInteractionFinish.ufoName
107
108
  }));
108
109
  if ((_getConfig2 = getConfig()) !== null && _getConfig2 !== void 0 && (_getConfig2$experimen = _getConfig2.experimentalInteractionMetrics) !== null && _getConfig2$experimen !== void 0 && _getConfig2$experimen.enabled) {
109
110
  var _this$vcObserver4;
@@ -1,4 +1,5 @@
1
1
  var _process, _process$env;
2
+ import { fg } from '@atlaskit/platform-feature-flags';
2
3
  import { isVCRevisionEnabled } from '../config';
3
4
  import { VCObserverNOOP } from './no-op-vc-observer';
4
5
  import { VCObserver } from './vc-observer';
@@ -6,55 +7,117 @@ import VCObserverNew from './vc-observer-new';
6
7
  class VCObserverWrapper {
7
8
  constructor(opts = {}) {
8
9
  this.newVCObserver = null;
9
- if (isVCRevisionEnabled('fy25.03')) {
10
- this.newVCObserver = new VCObserverNew({
11
- selectorConfig: opts.selectorConfig
12
- });
10
+ if (fg('platform_ufo_vc_enable_revisions_by_experience')) {
11
+ this.oldVCObserver = null;
12
+ if (isVCRevisionEnabled('fy25.03')) {
13
+ this.newVCObserver = new VCObserverNew({
14
+ selectorConfig: opts.selectorConfig
15
+ });
16
+ }
17
+ if (isVCRevisionEnabled('fy25.01') || isVCRevisionEnabled('fy25.02')) {
18
+ this.oldVCObserver = new VCObserver(opts);
19
+ }
20
+ } else {
21
+ if (isVCRevisionEnabled('fy25.03')) {
22
+ this.newVCObserver = new VCObserverNew({
23
+ selectorConfig: opts.selectorConfig
24
+ });
25
+ }
26
+ this.oldVCObserver = new VCObserver(opts);
13
27
  }
14
- this.oldVCObserver = new VCObserver(opts);
15
28
  }
16
- start(startArg) {
17
- var _this$oldVCObserver, _this$newVCObserver;
18
- (_this$oldVCObserver = this.oldVCObserver) === null || _this$oldVCObserver === void 0 ? void 0 : _this$oldVCObserver.start(startArg);
19
- (_this$newVCObserver = this.newVCObserver) === null || _this$newVCObserver === void 0 ? void 0 : _this$newVCObserver.start({
20
- startTime: startArg.startTime
21
- });
29
+ start({
30
+ startTime,
31
+ experienceKey
32
+ }) {
33
+ if (fg('platform_ufo_vc_enable_revisions_by_experience')) {
34
+ if (isVCRevisionEnabled('fy25.01', experienceKey) || isVCRevisionEnabled('fy25.02', experienceKey)) {
35
+ var _this$oldVCObserver;
36
+ (_this$oldVCObserver = this.oldVCObserver) === null || _this$oldVCObserver === void 0 ? void 0 : _this$oldVCObserver.start({
37
+ startTime
38
+ });
39
+ }
40
+ if (isVCRevisionEnabled('fy25.03', experienceKey)) {
41
+ var _this$newVCObserver;
42
+ (_this$newVCObserver = this.newVCObserver) === null || _this$newVCObserver === void 0 ? void 0 : _this$newVCObserver.start({
43
+ startTime
44
+ });
45
+ }
46
+ } else {
47
+ var _this$oldVCObserver2, _this$newVCObserver2;
48
+ (_this$oldVCObserver2 = this.oldVCObserver) === null || _this$oldVCObserver2 === void 0 ? void 0 : _this$oldVCObserver2.start({
49
+ startTime
50
+ });
51
+ (_this$newVCObserver2 = this.newVCObserver) === null || _this$newVCObserver2 === void 0 ? void 0 : _this$newVCObserver2.start({
52
+ startTime
53
+ });
54
+ }
22
55
  }
23
- stop() {
24
- var _this$oldVCObserver2, _this$newVCObserver2;
25
- (_this$oldVCObserver2 = this.oldVCObserver) === null || _this$oldVCObserver2 === void 0 ? void 0 : _this$oldVCObserver2.stop();
26
- (_this$newVCObserver2 = this.newVCObserver) === null || _this$newVCObserver2 === void 0 ? void 0 : _this$newVCObserver2.stop();
56
+ stop(experienceKey) {
57
+ if (fg('platform_ufo_vc_enable_revisions_by_experience')) {
58
+ if (isVCRevisionEnabled('fy25.01', experienceKey) || isVCRevisionEnabled('fy25.02', experienceKey)) {
59
+ var _this$oldVCObserver3;
60
+ (_this$oldVCObserver3 = this.oldVCObserver) === null || _this$oldVCObserver3 === void 0 ? void 0 : _this$oldVCObserver3.stop();
61
+ }
62
+ if (isVCRevisionEnabled('fy25.03', experienceKey)) {
63
+ var _this$newVCObserver3;
64
+ (_this$newVCObserver3 = this.newVCObserver) === null || _this$newVCObserver3 === void 0 ? void 0 : _this$newVCObserver3.stop();
65
+ }
66
+ } else {
67
+ var _this$oldVCObserver4, _this$newVCObserver4;
68
+ (_this$oldVCObserver4 = this.oldVCObserver) === null || _this$oldVCObserver4 === void 0 ? void 0 : _this$oldVCObserver4.stop();
69
+ (_this$newVCObserver4 = this.newVCObserver) === null || _this$newVCObserver4 === void 0 ? void 0 : _this$newVCObserver4.stop();
70
+ }
27
71
  }
28
72
  getVCRawData() {
29
- var _this$oldVCObserver$g, _this$oldVCObserver3;
30
- return (_this$oldVCObserver$g = (_this$oldVCObserver3 = this.oldVCObserver) === null || _this$oldVCObserver3 === void 0 ? void 0 : _this$oldVCObserver3.getVCRawData()) !== null && _this$oldVCObserver$g !== void 0 ? _this$oldVCObserver$g : null;
73
+ var _this$oldVCObserver$g, _this$oldVCObserver5;
74
+ return (_this$oldVCObserver$g = (_this$oldVCObserver5 = this.oldVCObserver) === null || _this$oldVCObserver5 === void 0 ? void 0 : _this$oldVCObserver5.getVCRawData()) !== null && _this$oldVCObserver$g !== void 0 ? _this$oldVCObserver$g : null;
31
75
  }
32
76
  async getVCResult(param) {
33
- var _this$oldVCObserver4, _this$newVCObserver3, _ref;
34
- const oldResult = await ((_this$oldVCObserver4 = this.oldVCObserver) === null || _this$oldVCObserver4 === void 0 ? void 0 : _this$oldVCObserver4.getVCResult(param));
35
- const newResult = await ((_this$newVCObserver3 = this.newVCObserver) === null || _this$newVCObserver3 === void 0 ? void 0 : _this$newVCObserver3.getVCResult({
36
- start: param.start,
37
- stop: param.stop
38
- }));
39
- if (oldResult && !newResult) {
40
- return oldResult;
77
+ if (fg('platform_ufo_vc_enable_revisions_by_experience')) {
78
+ var _this$oldVCObserver6, _this$newVCObserver5, _ref;
79
+ const {
80
+ experienceKey
81
+ } = param;
82
+ const v1v2Result = isVCRevisionEnabled('fy25.01', experienceKey) || isVCRevisionEnabled('fy25.02', experienceKey) ? await ((_this$oldVCObserver6 = this.oldVCObserver) === null || _this$oldVCObserver6 === void 0 ? void 0 : _this$oldVCObserver6.getVCResult(param)) : {};
83
+ const v3Result = isVCRevisionEnabled('fy25.03', experienceKey) ? await ((_this$newVCObserver5 = this.newVCObserver) === null || _this$newVCObserver5 === void 0 ? void 0 : _this$newVCObserver5.getVCResult({
84
+ start: param.start,
85
+ stop: param.stop
86
+ })) : [];
87
+ if (!v3Result) {
88
+ return v1v2Result !== null && v1v2Result !== void 0 ? v1v2Result : {};
89
+ }
90
+ return {
91
+ ...v1v2Result,
92
+ 'ufo:vc:rev': [...((_ref = v1v2Result === null || v1v2Result === void 0 ? void 0 : v1v2Result['ufo:vc:rev']) !== null && _ref !== void 0 ? _ref : []), ...(v3Result !== null && v3Result !== void 0 ? v3Result : [])]
93
+ };
94
+ } else {
95
+ var _this$oldVCObserver7, _this$newVCObserver6, _ref2;
96
+ const oldResult = await ((_this$oldVCObserver7 = this.oldVCObserver) === null || _this$oldVCObserver7 === void 0 ? void 0 : _this$oldVCObserver7.getVCResult(param));
97
+ const newResult = await ((_this$newVCObserver6 = this.newVCObserver) === null || _this$newVCObserver6 === void 0 ? void 0 : _this$newVCObserver6.getVCResult({
98
+ start: param.start,
99
+ stop: param.stop
100
+ }));
101
+ if (oldResult && !newResult) {
102
+ return oldResult;
103
+ }
104
+ return {
105
+ ...(oldResult !== null && oldResult !== void 0 ? oldResult : {}),
106
+ 'ufo:vc:rev': [...((_ref2 = oldResult === null || oldResult === void 0 ? void 0 : oldResult['ufo:vc:rev']) !== null && _ref2 !== void 0 ? _ref2 : []), ...(newResult !== null && newResult !== void 0 ? newResult : [])]
107
+ };
41
108
  }
42
- return {
43
- ...(oldResult !== null && oldResult !== void 0 ? oldResult : {}),
44
- 'ufo:vc:rev': [...((_ref = oldResult === null || oldResult === void 0 ? void 0 : oldResult['ufo:vc:rev']) !== null && _ref !== void 0 ? _ref : []), ...(newResult !== null && newResult !== void 0 ? newResult : [])]
45
- };
46
109
  }
47
110
  setSSRElement(element) {
48
- var _this$oldVCObserver5;
49
- (_this$oldVCObserver5 = this.oldVCObserver) === null || _this$oldVCObserver5 === void 0 ? void 0 : _this$oldVCObserver5.setSSRElement(element);
111
+ var _this$oldVCObserver8;
112
+ (_this$oldVCObserver8 = this.oldVCObserver) === null || _this$oldVCObserver8 === void 0 ? void 0 : _this$oldVCObserver8.setSSRElement(element);
50
113
  }
51
114
  setReactRootRenderStart(startTime) {
52
- var _this$oldVCObserver6;
53
- (_this$oldVCObserver6 = this.oldVCObserver) === null || _this$oldVCObserver6 === void 0 ? void 0 : _this$oldVCObserver6.setReactRootRenderStart(startTime || performance.now());
115
+ var _this$oldVCObserver9;
116
+ (_this$oldVCObserver9 = this.oldVCObserver) === null || _this$oldVCObserver9 === void 0 ? void 0 : _this$oldVCObserver9.setReactRootRenderStart(startTime || performance.now());
54
117
  }
55
118
  setReactRootRenderStop(stopTime) {
56
- var _this$oldVCObserver7;
57
- (_this$oldVCObserver7 = this.oldVCObserver) === null || _this$oldVCObserver7 === void 0 ? void 0 : _this$oldVCObserver7.setReactRootRenderStop(stopTime || performance.now());
119
+ var _this$oldVCObserver10;
120
+ (_this$oldVCObserver10 = this.oldVCObserver) === null || _this$oldVCObserver10 === void 0 ? void 0 : _this$oldVCObserver10.setReactRootRenderStop(stopTime || performance.now());
58
121
  }
59
122
  }
60
123
 
@@ -1,3 +1,4 @@
1
+ import { fg } from '@atlaskit/platform-feature-flags';
1
2
  import { isVCRevisionEnabled } from '../../config';
2
3
  import { getPageVisibilityState } from '../../hidden-timing';
3
4
  import { getRevisions } from './revisions/revisions';
@@ -19,7 +20,7 @@ function createVCDetails(calculatedVC, shouldHaveVCmetric) {
19
20
 
20
21
  for (const key of VCParts) {
21
22
  details[key] = {
22
- t: VC[key],
23
+ t: VC[key] || -1,
23
24
  e: VCBox[key] || READONLY_EMPTY_ARRAY
24
25
  };
25
26
  }
@@ -35,9 +36,14 @@ export function getVCRevisionsData({
35
36
  multiHeatmap,
36
37
  ssr,
37
38
  calculatedVC,
38
- calculatedVCNext
39
+ calculatedVCNext,
40
+ experienceKey
39
41
  }) {
40
- if (!isVCRevisionEnabled('fy25.03')) {
42
+ const isTTVCv3Enabled = fg('platform_ufo_vc_enable_revisions_by_experience') ? isVCRevisionEnabled('fy25.03', experienceKey) : isVCRevisionEnabled('fy25.03');
43
+
44
+ // As part of `platform_ufo_vc_enable_revisions_by_experience`, we are looking to turn off the `multiHeatmap` branch of code
45
+ // for calculating TTVC, and instead rely on existing values already available, e.g. `calculatedVC` and `calculatedVCNext`
46
+ if (!isTTVCv3Enabled && !fg('platform_ufo_vc_enable_revisions_by_experience')) {
41
47
  if (!multiHeatmap) {
42
48
  return null;
43
49
  }
@@ -58,33 +64,54 @@ export function getVCRevisionsData({
58
64
  })
59
65
  };
60
66
  }
61
-
62
- // Calculate these conditions once
63
67
  const pageVisibilityUpToTTAI = getPageVisibilityState(interaction.start, interaction.end);
64
68
  const isVisiblePageVisibleUpToTTAI = pageVisibilityUpToTTAI === 'visible';
65
69
  const shouldHaveVCmetric = isVCClean && !isEventAborted && isVisiblePageVisibleUpToTTAI;
70
+ if (fg('platform_ufo_vc_enable_revisions_by_experience')) {
71
+ const availableVCRevisionPayloads = [];
72
+ if (isVCRevisionEnabled('fy25.01', experienceKey)) {
73
+ availableVCRevisionPayloads.push({
74
+ revision: 'fy25.01',
75
+ clean: isVCClean,
76
+ 'metric:vc90': shouldHaveVCmetric ? calculatedVC.VC['90'] : null,
77
+ vcDetails: createVCDetails(calculatedVC, shouldHaveVCmetric)
78
+ });
79
+ }
80
+ if (isVCRevisionEnabled('fy25.02', experienceKey)) {
81
+ availableVCRevisionPayloads.push({
82
+ revision: 'fy25.02',
83
+ clean: isVCClean,
84
+ 'metric:vc90': shouldHaveVCmetric ? calculatedVCNext.VC['90'] : null,
85
+ vcDetails: createVCDetails(calculatedVCNext, shouldHaveVCmetric)
86
+ });
87
+ }
88
+ return {
89
+ [`${fullPrefix}vc:rev`]: availableVCRevisionPayloads
90
+ };
91
+ } else {
92
+ // Create the V2 revision object which is always needed
93
+ const ttvcV2Revision = {
94
+ revision: 'fy25.02',
95
+ clean: isVCClean,
96
+ 'metric:vc90': shouldHaveVCmetric ? calculatedVCNext.VC['90'] : null,
97
+ vcDetails: createVCDetails(calculatedVCNext, shouldHaveVCmetric)
98
+ };
99
+ const isTTVCv1Disabled = !isVCRevisionEnabled('fy25.01');
100
+ if (isTTVCv1Disabled) {
101
+ return {
102
+ [`${fullPrefix}vc:rev`]: [ttvcV2Revision]
103
+ };
104
+ }
66
105
 
67
- // Create the V2 revision object which is always needed
68
- const ttvcV2Revision = {
69
- revision: 'fy25.02',
70
- clean: isVCClean,
71
- 'metric:vc90': shouldHaveVCmetric ? calculatedVCNext.VC['90'] : null,
72
- vcDetails: createVCDetails(calculatedVCNext, shouldHaveVCmetric)
73
- };
74
- if (!isVCRevisionEnabled('fy25.01')) {
106
+ // Only create ttvcV1Revision when we're actually going to use it
107
+ const ttvcV1Revision = {
108
+ revision: 'fy25.01',
109
+ clean: isVCClean,
110
+ 'metric:vc90': shouldHaveVCmetric ? calculatedVC.VC['90'] : null,
111
+ vcDetails: createVCDetails(calculatedVC, shouldHaveVCmetric)
112
+ };
75
113
  return {
76
- [`${fullPrefix}vc:rev`]: [ttvcV2Revision]
114
+ [`${fullPrefix}vc:rev`]: [ttvcV1Revision, ttvcV2Revision]
77
115
  };
78
116
  }
79
-
80
- // Only create ttvcV1Revision when we're actually going to use it
81
- const ttvcV1Revision = {
82
- revision: 'fy25.01',
83
- clean: isVCClean,
84
- 'metric:vc90': shouldHaveVCmetric ? calculatedVC.VC['90'] : null,
85
- vcDetails: createVCDetails(calculatedVC, shouldHaveVCmetric)
86
- };
87
- return {
88
- [`${fullPrefix}vc:rev`]: [ttvcV1Revision, ttvcV2Revision]
89
- };
90
117
  }
@@ -1,6 +1,7 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import { fg } from '@atlaskit/platform-feature-flags';
3
3
  import { isVCRevisionEnabled } from '../../config';
4
+ import { getActiveInteraction } from '../../interaction-metrics';
4
5
  import { attachAbortListeners } from './attachAbortListeners';
5
6
  import { getVCRevisionsData } from './getVCRevisionsData';
6
7
  import { getViewportHeight, getViewportWidth } from './getViewport';
@@ -94,7 +95,8 @@ export class VCObserver {
94
95
  prefix,
95
96
  ssr,
96
97
  vc,
97
- isEventAborted
98
+ isEventAborted,
99
+ experienceKey
98
100
  }) => {
99
101
  const startTime = performance.now();
100
102
  // add local measurement
@@ -116,7 +118,7 @@ export class VCObserver {
116
118
  ratios,
117
119
  multiHeatmap
118
120
  } = rawData;
119
- const isTTVCv1Disabled = !isVCRevisionEnabled('fy25.01');
121
+ const isTTVCv1Disabled = fg('platform_ufo_vc_enable_revisions_by_experience') ? !isVCRevisionEnabled('fy25.01', experienceKey) : !isVCRevisionEnabled('fy25.01');
120
122
 
121
123
  // NOTE: as part of platform_ufo_add_vc_abort_reason_by_revisions feature,
122
124
  // we want to report abort by scroll events the same way as other abort reasons
@@ -318,7 +320,8 @@ export class VCObserver {
318
320
  VC: vcNext.VC,
319
321
  VCBox: vcNext.VCBox
320
322
  },
321
- isEventAborted
323
+ isEventAborted,
324
+ experienceKey
322
325
  });
323
326
  const speedIndex = {
324
327
  [`ufo:speedIndex`]: isTTVCv1Disabled ? vcNext.VCEntries.speedIndex : VCEntries.speedIndex,
@@ -335,7 +338,7 @@ export class VCObserver {
335
338
  ...speedIndex
336
339
  };
337
340
  }
338
- const isTTVCv3Enabled = isVCRevisionEnabled('fy25.03');
341
+ const isTTVCv3Enabled = fg('platform_ufo_vc_enable_revisions_by_experience') ? isVCRevisionEnabled('fy25.03', experienceKey) : isVCRevisionEnabled('fy25.03');
339
342
  return {
340
343
  'metrics:vc': VC,
341
344
  [`${fullPrefix}vc:state`]: true,
@@ -360,7 +363,12 @@ export class VCObserver {
360
363
  _defineProperty(this, "handleUpdate", (rawTime, intersectionRect, targetName, element, type, ignoreReason, attributeName, oldValue, newValue) => {
361
364
  this.measureStart();
362
365
  this.legacyHandleUpdate(rawTime, intersectionRect, targetName, element, type, ignoreReason, attributeName, oldValue, newValue);
363
- if (!isVCRevisionEnabled('fy25.03')) {
366
+ let isTTVCv3Disabled = !isVCRevisionEnabled('fy25.03');
367
+ if (fg('platform_ufo_vc_enable_revisions_by_experience')) {
368
+ const interaction = getActiveInteraction();
369
+ isTTVCv3Disabled = !isVCRevisionEnabled('fy25.03', interaction === null || interaction === void 0 ? void 0 : interaction.ufoName);
370
+ }
371
+ if (isTTVCv3Disabled) {
364
372
  this.onViewportChangeDetected({
365
373
  timestamp: rawTime,
366
374
  intersectionRect,
@@ -383,7 +391,11 @@ export class VCObserver {
383
391
  if (!ignoreReason) {
384
392
  this.applyChangesToHeatMap(mappedValues, time, this.heatmapNext);
385
393
  }
386
- const isTTVCv1Disabled = !isVCRevisionEnabled('fy25.01');
394
+ let isTTVCv1Disabled = !isVCRevisionEnabled('fy25.01');
395
+ if (fg('platform_ufo_vc_enable_revisions_by_experience')) {
396
+ const interaction = getActiveInteraction();
397
+ isTTVCv1Disabled = !isVCRevisionEnabled('fy25.01', interaction === null || interaction === void 0 ? void 0 : interaction.ufoName);
398
+ }
387
399
  if (!isTTVCv1Disabled && (!ignoreReason || ignoreReason === 'not-visible') && type !== 'attr') {
388
400
  this.applyChangesToHeatMap(mappedValues, time, this.heatmap);
389
401
  }
@@ -1,9 +1,7 @@
1
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
1
  export default class EntriesTimeline {
3
2
  constructor() {
4
- _defineProperty(this, "unorderedEntries", []);
5
- _defineProperty(this, "sortedEntriesCache", new Map());
6
3
  this.unorderedEntries = [];
4
+ this.sortedEntriesCache = new Map();
7
5
  }
8
6
  push(entry) {
9
7
  this.unorderedEntries.push(entry);
@@ -1,14 +1,15 @@
1
+ import { fg } from '@atlaskit/platform-feature-flags';
1
2
  import taskYield from '../../utils/task-yield';
2
3
 
3
4
  // 24-bit color value
4
5
 
5
6
  /**
6
7
  * Class responsible for managing a scaled canvas and tracking pixel drawing operations.
7
- * It uses an OffscreenCanvas for better performance and maintains a mapping between
8
- * colors and timestamps for pixel counting purposes.
8
+ * It uses either an OffscreenCanvas (if available) or a regular HTML Canvas for better performance
9
+ * and maintains a mapping between colors and timestamps for pixel counting purposes.
9
10
  */
10
11
  export class ViewportCanvas {
11
- /** The underlying OffscreenCanvas instance */
12
+ /** The underlying Canvas instance (either OffscreenCanvas or HTMLCanvasElement) */
12
13
 
13
14
  /** The 2D rendering context of the canvas */
14
15
 
@@ -37,10 +38,8 @@ export class ViewportCanvas {
37
38
  this.scaleX = this.scaledWidth / safeViewportWidth;
38
39
  this.scaleY = this.scaledHeight / safeViewportHeight;
39
40
 
40
- // Initialize OffscreenCanvas with scaled dimensions
41
- this.canvas = document.createElement('canvas');
42
- this.canvas.width = this.scaledWidth;
43
- this.canvas.height = this.scaledHeight;
41
+ // Initialize canvas with scaled dimensions
42
+ this.canvas = this.createCanvas(this.scaledWidth, this.scaledHeight);
44
43
  const ctx = this.canvas.getContext('2d', {
45
44
  alpha: false,
46
45
  // Disable alpha channel for better performance
@@ -53,8 +52,25 @@ export class ViewportCanvas {
53
52
  }
54
53
  this.ctx = ctx;
55
54
  this.ctx.globalCompositeOperation = 'source-over';
55
+ if (fg('platform_ufo_use_offscreen_canvas')) {
56
+ this.ctx.imageSmoothingEnabled = false; // Disable image smoothing for better performance
57
+ }
56
58
  this.clear();
57
59
  }
60
+
61
+ /**
62
+ * Creates a canvas instance, falling back to HTMLCanvasElement if OffscreenCanvas is not available
63
+ * or if the feature flag is disabled
64
+ */
65
+ createCanvas(width, height) {
66
+ if (typeof OffscreenCanvas !== 'undefined' && fg('platform_ufo_use_offscreen_canvas')) {
67
+ return new OffscreenCanvas(width, height);
68
+ }
69
+ const canvas = document.createElement('canvas');
70
+ canvas.width = width;
71
+ canvas.height = height;
72
+ return canvas;
73
+ }
58
74
  getScaledDimensions() {
59
75
  return {
60
76
  width: this.scaledWidth,