@atlaskit/react-ufo 3.11.0 → 3.11.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/create-post-interaction-log-payload/index.js +11 -0
  3. package/dist/cjs/interaction-metrics/post-interaction-log.js +11 -3
  4. package/dist/cjs/vc/index.js +2 -1
  5. package/dist/cjs/vc/vc-observer/index.js +6 -5
  6. package/dist/cjs/vc/vc-observer/observers/index.js +2 -2
  7. package/dist/es2019/create-post-interaction-log-payload/index.js +11 -0
  8. package/dist/es2019/interaction-metrics/post-interaction-log.js +12 -3
  9. package/dist/es2019/vc/index.js +1 -1
  10. package/dist/es2019/vc/vc-observer/index.js +8 -3
  11. package/dist/es2019/vc/vc-observer/observers/index.js +2 -2
  12. package/dist/esm/create-post-interaction-log-payload/index.js +11 -0
  13. package/dist/esm/interaction-metrics/post-interaction-log.js +11 -3
  14. package/dist/esm/vc/index.js +4 -2
  15. package/dist/esm/vc/vc-observer/index.js +6 -5
  16. package/dist/esm/vc/vc-observer/observers/index.js +2 -2
  17. package/dist/types/common/common/types.d.ts +1 -1
  18. package/dist/types/common/react-ufo-payload-schema.d.ts +50 -4
  19. package/dist/types/create-payload/index.d.ts +1 -1
  20. package/dist/types/create-post-interaction-log-payload/get-late-mutations.d.ts +3 -3
  21. package/dist/types/create-post-interaction-log-payload/index.d.ts +2 -1
  22. package/dist/types/interaction-metrics/post-interaction-log.d.ts +3 -4
  23. package/dist/types/vc/index.d.ts +17 -1
  24. package/dist/types/vc/no-op-vc-observer.d.ts +1 -1
  25. package/dist/types/vc/vc-observer/getVCRevisionsData.d.ts +2 -2
  26. package/dist/types/vc/vc-observer-new/index.d.ts +1 -1
  27. package/dist/types/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +1 -1
  28. package/dist/types/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/heatmap.d.ts +1 -1
  29. package/dist/types/vc/vc-observer-new/metric-calculator/types.d.ts +1 -1
  30. package/dist/types-ts4.5/common/common/types.d.ts +1 -1
  31. package/dist/types-ts4.5/common/react-ufo-payload-schema.d.ts +52 -4
  32. package/dist/types-ts4.5/create-payload/index.d.ts +1 -1
  33. package/dist/types-ts4.5/create-post-interaction-log-payload/get-late-mutations.d.ts +3 -3
  34. package/dist/types-ts4.5/create-post-interaction-log-payload/index.d.ts +2 -1
  35. package/dist/types-ts4.5/interaction-metrics/post-interaction-log.d.ts +3 -4
  36. package/dist/types-ts4.5/vc/index.d.ts +17 -1
  37. package/dist/types-ts4.5/vc/no-op-vc-observer.d.ts +1 -1
  38. package/dist/types-ts4.5/vc/vc-observer/getVCRevisionsData.d.ts +2 -2
  39. package/dist/types-ts4.5/vc/vc-observer-new/index.d.ts +1 -1
  40. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/abstract-base-vc-calculator.d.ts +1 -1
  41. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/percentile-calc/heatmap/heatmap.d.ts +1 -1
  42. package/dist/types-ts4.5/vc/vc-observer-new/metric-calculator/types.d.ts +1 -1
  43. package/package.json +4 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @atlaskit/ufo-interaction-ignore
2
2
 
3
+ ## 3.11.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#153697](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/153697)
8
+ [`e513d2cda4042`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/e513d2cda4042) -
9
+ AFO-3823 improve VCObserver stop() performance
10
+
11
+ ## 3.11.1
12
+
13
+ ### Patch Changes
14
+
15
+ - [#154164](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/154164)
16
+ [`59249901f5291`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/59249901f5291) -
17
+ align logic for UFO events and watchdog event
18
+
3
19
  ## 3.11.0
4
20
 
5
21
  ### Minor Changes
@@ -133,6 +133,17 @@ function createPostInteractionLogPayload(_ref2) {
133
133
  if (pageVisibilityState !== 'visible') {
134
134
  return null;
135
135
  }
136
+
137
+ // Align post-interaction-logs closer to UFO event behaviour,
138
+ // e.g. also check for aborted or failed events
139
+ if ((0, _platformFeatureFlags.fg)('platform_ufo_vc_align_revisions_on_watchdog_event')) {
140
+ if (lastInteractionFinish.abortReason) {
141
+ return null;
142
+ }
143
+ if (lastInteractionFinish.errors.length > 0) {
144
+ return null;
145
+ }
146
+ }
136
147
  var maxEndTimeFromProfiler = reactProfilerTimings ? Math.max.apply(Math, (0, _toConsumableArray2.default)(reactProfilerTimings.map(function (t) {
137
148
  return t.commitTime;
138
149
  }))) : lastInteractionFinish.end;
@@ -10,7 +10,9 @@ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/
10
10
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
11
11
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
12
12
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
13
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
13
14
  var _config = require("../config");
15
+ var _vc = require("../vc");
14
16
  var _vcObserver = require("../vc/vc-observer");
15
17
  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; }
16
18
  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) { (0, _defineProperty2.default)(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; }
@@ -43,7 +45,11 @@ var PostInteractionLog = exports.default = /*#__PURE__*/function () {
43
45
  return (0, _createClass2.default)(PostInteractionLog, [{
44
46
  key: "initializeVCObserver",
45
47
  value: function initializeVCObserver(options) {
46
- if (this.vcObserver === null) {
48
+ if ((0, _platformFeatureFlags.fg)('platform_ufo_vc_align_revisions_on_watchdog_event')) {
49
+ this.vcObserver = new _vc.VCObserverWrapper(_objectSpread(_objectSpread({}, options), {}, {
50
+ isPostInteraction: true
51
+ }));
52
+ } else if (this.vcObserver === null) {
47
53
  this.vcObserver = new _vcObserver.VCObserver(_objectSpread(_objectSpread({}, options), {}, {
48
54
  isPostInteraction: true
49
55
  }));
@@ -186,7 +192,8 @@ var PostInteractionLog = exports.default = /*#__PURE__*/function () {
186
192
  routeName = _ref2.routeName,
187
193
  type = _ref2.type,
188
194
  experimentalTTAI = _ref2.experimentalTTAI,
189
- experimentalVC90 = _ref2.experimentalVC90;
195
+ experimentalVC90 = _ref2.experimentalVC90,
196
+ errors = _ref2.errors;
190
197
  this.lastInteractionFinish = {
191
198
  ufoName: ufoName,
192
199
  start: start,
@@ -197,7 +204,8 @@ var PostInteractionLog = exports.default = /*#__PURE__*/function () {
197
204
  routeName: routeName,
198
205
  type: type,
199
206
  experimentalTTAI: experimentalTTAI,
200
- experimentalVC90: experimentalVC90
207
+ experimentalVC90: experimentalVC90,
208
+ errors: errors
201
209
  };
202
210
  var timeout = ((_getConfig3 = (0, _config.getConfig)()) === null || _getConfig3 === void 0 ? void 0 : _getConfig3.timeWindowForLateMutationsInMilliseconds) || POST_INTERACTION_LOG_SEND_DEFAULT_TIMEOUT;
203
211
  this.sinkTimeoutId = window.setTimeout( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
@@ -4,6 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
+ exports.VCObserverWrapper = void 0;
7
8
  exports.getVCObserver = getVCObserver;
8
9
  exports.isEnvironmentSupported = isEnvironmentSupported;
9
10
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
@@ -20,7 +21,7 @@ var _vcObserverNew = _interopRequireDefault(require("./vc-observer-new"));
20
21
  var _process;
21
22
  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; }
22
23
  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) { (0, _defineProperty2.default)(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; }
23
- var VCObserverWrapper = /*#__PURE__*/function () {
24
+ var VCObserverWrapper = exports.VCObserverWrapper = /*#__PURE__*/function () {
24
25
  function VCObserverWrapper() {
25
26
  var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
26
27
  (0, _classCallCheck2.default)(this, VCObserverWrapper);
@@ -644,11 +644,12 @@ var VCObserver = exports.VCObserver = /*#__PURE__*/function () {
644
644
  }, {
645
645
  key: "detachAbortListeners",
646
646
  value: function detachAbortListeners() {
647
- if (Array.isArray(this.unbind)) {
648
- this.unbind.forEach(function (fn) {
649
- return fn();
650
- });
651
- this.unbind = [];
647
+ if (this.unbind) {
648
+ var unbind = this.unbind;
649
+ for (var i = 0; i < unbind.length; i++) {
650
+ unbind[i]();
651
+ }
652
+ this.unbind.length = 0;
652
653
  }
653
654
  }
654
655
  }, {
@@ -104,8 +104,8 @@ var Observers = exports.Observers = /*#__PURE__*/function () {
104
104
  (_this$mutationObserve2 = this.mutationObserver) === null || _this$mutationObserve2 === void 0 || _this$mutationObserve2.disconnect();
105
105
  (_this$intersectionObs2 = this.intersectionObserver) === null || _this$intersectionObs2 === void 0 || _this$intersectionObs2.disconnect();
106
106
  this.observedMutations = new WeakMap();
107
- this.elementsInView = new Set();
108
- this.callbacks = new Set();
107
+ this.elementsInView.clear();
108
+ this.callbacks.clear();
109
109
  this.ssr.reactRootElement = null;
110
110
  this.ssrPlaceholderHandler.clear();
111
111
  }
@@ -120,6 +120,17 @@ function createPostInteractionLogPayload({
120
120
  if (pageVisibilityState !== 'visible') {
121
121
  return null;
122
122
  }
123
+
124
+ // Align post-interaction-logs closer to UFO event behaviour,
125
+ // e.g. also check for aborted or failed events
126
+ if (fg('platform_ufo_vc_align_revisions_on_watchdog_event')) {
127
+ if (lastInteractionFinish.abortReason) {
128
+ return null;
129
+ }
130
+ if (lastInteractionFinish.errors.length > 0) {
131
+ return null;
132
+ }
133
+ }
123
134
  const maxEndTimeFromProfiler = reactProfilerTimings ? Math.max(...reactProfilerTimings.map(t => t.commitTime)) : lastInteractionFinish.end;
124
135
  const revisedEndTime = Math.round(maxEndTimeFromProfiler);
125
136
  const revisedTtai = Math.round(maxEndTimeFromProfiler - lastInteractionFinish.start);
@@ -1,5 +1,7 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import { fg } from '@atlaskit/platform-feature-flags';
2
3
  import { getConfig } from '../config';
4
+ import { VCObserverWrapper } from '../vc';
3
5
  import { VCObserver } from '../vc/vc-observer';
4
6
  const POST_INTERACTION_LOG_SEND_DEFAULT_TIMEOUT = 3000;
5
7
  export default class PostInteractionLog {
@@ -27,7 +29,12 @@ export default class PostInteractionLog {
27
29
  _defineProperty(this, "sinkHandlerFn", () => {});
28
30
  }
29
31
  initializeVCObserver(options) {
30
- if (this.vcObserver === null) {
32
+ if (fg('platform_ufo_vc_align_revisions_on_watchdog_event')) {
33
+ this.vcObserver = new VCObserverWrapper({
34
+ ...options,
35
+ isPostInteraction: true
36
+ });
37
+ } else if (this.vcObserver === null) {
31
38
  this.vcObserver = new VCObserver({
32
39
  ...options,
33
40
  isPostInteraction: true
@@ -135,7 +142,8 @@ export default class PostInteractionLog {
135
142
  routeName,
136
143
  type,
137
144
  experimentalTTAI,
138
- experimentalVC90
145
+ experimentalVC90,
146
+ errors
139
147
  }) {
140
148
  var _getConfig3;
141
149
  this.lastInteractionFinish = {
@@ -148,7 +156,8 @@ export default class PostInteractionLog {
148
156
  routeName,
149
157
  type,
150
158
  experimentalTTAI,
151
- experimentalVC90
159
+ experimentalVC90,
160
+ errors
152
161
  };
153
162
  const timeout = ((_getConfig3 = getConfig()) === null || _getConfig3 === void 0 ? void 0 : _getConfig3.timeWindowForLateMutationsInMilliseconds) || POST_INTERACTION_LOG_SEND_DEFAULT_TIMEOUT;
154
163
  this.sinkTimeoutId = window.setTimeout(async () => {
@@ -4,7 +4,7 @@ import { isVCRevisionEnabled } from '../config';
4
4
  import { VCObserverNOOP } from './no-op-vc-observer';
5
5
  import { VCObserver } from './vc-observer';
6
6
  import VCObserverNew from './vc-observer-new';
7
- class VCObserverWrapper {
7
+ export class VCObserverWrapper {
8
8
  constructor(opts = {}) {
9
9
  this.newVCObserver = null;
10
10
  if (fg('platform_ufo_vc_enable_revisions_by_experience')) {
@@ -739,9 +739,14 @@ export class VCObserver {
739
739
  return vc;
740
740
  }
741
741
  detachAbortListeners() {
742
- if (Array.isArray(this.unbind)) {
743
- this.unbind.forEach(fn => fn());
744
- this.unbind = [];
742
+ if (this.unbind) {
743
+ const {
744
+ unbind
745
+ } = this;
746
+ for (let i = 0; i < unbind.length; i++) {
747
+ unbind[i]();
748
+ }
749
+ this.unbind.length = 0;
745
750
  }
746
751
  }
747
752
  measureStart() {
@@ -86,8 +86,8 @@ export class Observers {
86
86
  (_this$mutationObserve2 = this.mutationObserver) === null || _this$mutationObserve2 === void 0 ? void 0 : _this$mutationObserve2.disconnect();
87
87
  (_this$intersectionObs2 = this.intersectionObserver) === null || _this$intersectionObs2 === void 0 ? void 0 : _this$intersectionObs2.disconnect();
88
88
  this.observedMutations = new WeakMap();
89
- this.elementsInView = new Set();
90
- this.callbacks = new Set();
89
+ this.elementsInView.clear();
90
+ this.callbacks.clear();
91
91
  this.ssr.reactRootElement = null;
92
92
  this.ssrPlaceholderHandler.clear();
93
93
  }
@@ -126,6 +126,17 @@ function createPostInteractionLogPayload(_ref2) {
126
126
  if (pageVisibilityState !== 'visible') {
127
127
  return null;
128
128
  }
129
+
130
+ // Align post-interaction-logs closer to UFO event behaviour,
131
+ // e.g. also check for aborted or failed events
132
+ if (fg('platform_ufo_vc_align_revisions_on_watchdog_event')) {
133
+ if (lastInteractionFinish.abortReason) {
134
+ return null;
135
+ }
136
+ if (lastInteractionFinish.errors.length > 0) {
137
+ return null;
138
+ }
139
+ }
129
140
  var maxEndTimeFromProfiler = reactProfilerTimings ? Math.max.apply(Math, _toConsumableArray(reactProfilerTimings.map(function (t) {
130
141
  return t.commitTime;
131
142
  }))) : lastInteractionFinish.end;
@@ -5,7 +5,9 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
5
5
  import _regeneratorRuntime from "@babel/runtime/regenerator";
6
6
  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; }
7
7
  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; }
8
+ import { fg } from '@atlaskit/platform-feature-flags';
8
9
  import { getConfig } from '../config';
10
+ import { VCObserverWrapper } from '../vc';
9
11
  import { VCObserver } from '../vc/vc-observer';
10
12
  var POST_INTERACTION_LOG_SEND_DEFAULT_TIMEOUT = 3000;
11
13
  var PostInteractionLog = /*#__PURE__*/function () {
@@ -36,7 +38,11 @@ var PostInteractionLog = /*#__PURE__*/function () {
36
38
  return _createClass(PostInteractionLog, [{
37
39
  key: "initializeVCObserver",
38
40
  value: function initializeVCObserver(options) {
39
- if (this.vcObserver === null) {
41
+ if (fg('platform_ufo_vc_align_revisions_on_watchdog_event')) {
42
+ this.vcObserver = new VCObserverWrapper(_objectSpread(_objectSpread({}, options), {}, {
43
+ isPostInteraction: true
44
+ }));
45
+ } else if (this.vcObserver === null) {
40
46
  this.vcObserver = new VCObserver(_objectSpread(_objectSpread({}, options), {}, {
41
47
  isPostInteraction: true
42
48
  }));
@@ -179,7 +185,8 @@ var PostInteractionLog = /*#__PURE__*/function () {
179
185
  routeName = _ref2.routeName,
180
186
  type = _ref2.type,
181
187
  experimentalTTAI = _ref2.experimentalTTAI,
182
- experimentalVC90 = _ref2.experimentalVC90;
188
+ experimentalVC90 = _ref2.experimentalVC90,
189
+ errors = _ref2.errors;
183
190
  this.lastInteractionFinish = {
184
191
  ufoName: ufoName,
185
192
  start: start,
@@ -190,7 +197,8 @@ var PostInteractionLog = /*#__PURE__*/function () {
190
197
  routeName: routeName,
191
198
  type: type,
192
199
  experimentalTTAI: experimentalTTAI,
193
- experimentalVC90: experimentalVC90
200
+ experimentalVC90: experimentalVC90,
201
+ errors: errors
194
202
  };
195
203
  var timeout = ((_getConfig3 = getConfig()) === null || _getConfig3 === void 0 ? void 0 : _getConfig3.timeWindowForLateMutationsInMilliseconds) || POST_INTERACTION_LOG_SEND_DEFAULT_TIMEOUT;
196
204
  this.sinkTimeoutId = window.setTimeout( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
@@ -12,7 +12,7 @@ import { isVCRevisionEnabled } from '../config';
12
12
  import { VCObserverNOOP } from './no-op-vc-observer';
13
13
  import { VCObserver } from './vc-observer';
14
14
  import VCObserverNew from './vc-observer-new';
15
- var VCObserverWrapper = /*#__PURE__*/function () {
15
+ export var VCObserverWrapper = /*#__PURE__*/function () {
16
16
  function VCObserverWrapper() {
17
17
  var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
18
18
  _classCallCheck(this, VCObserverWrapper);
@@ -192,7 +192,9 @@ var VCObserverWrapper = /*#__PURE__*/function () {
192
192
  (_this$oldVCObserver10 = this.oldVCObserver) === null || _this$oldVCObserver10 === void 0 || _this$oldVCObserver10.setReactRootRenderStop(stopTime || performance.now());
193
193
  }
194
194
  }]);
195
- }(); // Some products set this variable to indicate it is running in SSR
195
+ }();
196
+
197
+ // Some products set this variable to indicate it is running in SSR
196
198
  var isServer = Boolean(globalThis === null || globalThis === void 0 ? void 0 : globalThis.__SERVER__);
197
199
  // Other products set this other variable to indicate it is running in SSR
198
200
  var isReactSSR = typeof process !== 'undefined' && Boolean(((_process = process) === null || _process === void 0 || (_process = _process.env) === null || _process === void 0 ? void 0 : _process.REACT_SSR) || false);
@@ -637,11 +637,12 @@ export var VCObserver = /*#__PURE__*/function () {
637
637
  }, {
638
638
  key: "detachAbortListeners",
639
639
  value: function detachAbortListeners() {
640
- if (Array.isArray(this.unbind)) {
641
- this.unbind.forEach(function (fn) {
642
- return fn();
643
- });
644
- this.unbind = [];
640
+ if (this.unbind) {
641
+ var unbind = this.unbind;
642
+ for (var i = 0; i < unbind.length; i++) {
643
+ unbind[i]();
644
+ }
645
+ this.unbind.length = 0;
645
646
  }
646
647
  }
647
648
  }, {
@@ -97,8 +97,8 @@ export var Observers = /*#__PURE__*/function () {
97
97
  (_this$mutationObserve2 = this.mutationObserver) === null || _this$mutationObserve2 === void 0 || _this$mutationObserve2.disconnect();
98
98
  (_this$intersectionObs2 = this.intersectionObserver) === null || _this$intersectionObs2 === void 0 || _this$intersectionObs2.disconnect();
99
99
  this.observedMutations = new WeakMap();
100
- this.elementsInView = new Set();
101
- this.callbacks = new Set();
100
+ this.elementsInView.clear();
101
+ this.callbacks.clear();
102
102
  this.ssr.reactRootElement = null;
103
103
  this.ssrPlaceholderHandler.clear();
104
104
  }
@@ -202,7 +202,7 @@ export type BM3Event = {
202
202
  pageVisibleState?: string;
203
203
  type: string;
204
204
  };
205
- export type LastInteractionFinishInfo = Pick<InteractionMetrics, 'ufoName' | 'start' | 'end' | 'id' | 'abortReason' | 'abortedByInteractionName' | 'routeName' | 'type' | 'experimentalVC90' | 'experimentalTTAI'>;
205
+ export type LastInteractionFinishInfo = Pick<InteractionMetrics, 'ufoName' | 'start' | 'end' | 'id' | 'abortReason' | 'abortedByInteractionName' | 'routeName' | 'type' | 'experimentalVC90' | 'experimentalTTAI' | 'errors'>;
206
206
  export type PostInteractionLogOutput = {
207
207
  lastInteractionFinish: LastInteractionFinishInfo;
208
208
  reactProfilerTimings?: ReactProfilerTiming[];
@@ -1,7 +1,7 @@
1
1
  import { createPayloads } from '../create-payload';
2
- import { LabelStack } from '../interaction-context';
2
+ import { type LabelStack } from '../interaction-context';
3
3
  import { VCObserver } from '../vc/vc-observer';
4
- import type { AbortReasonType, ApdexType, InteractionType, SegmentInfo } from './common/types';
4
+ import type { AbortReasonType, ApdexType, InteractionError, InteractionType, SegmentInfo } from './common/types';
5
5
  import type { RevisionPayload } from './vc/types';
6
6
  type ExtractPromise<T> = T extends Promise<infer U> ? U : never;
7
7
  export type PageVisibility = 'hidden' | 'mixed' | 'visible';
@@ -135,6 +135,7 @@ export type ReactUFOPayload = {
135
135
  segments: SegmentInfo[] | RootSegment;
136
136
  reactProfilerTimings: ReactProfilerTiming[];
137
137
  holdInfo: HoldInfo[];
138
+ errors: InteractionError[];
138
139
  };
139
140
  'ufo:vc:rev': RevisionPayload;
140
141
  'ufo:vc:ratios': Record<string, number>;
@@ -143,6 +144,8 @@ export type ReactUFOPayload = {
143
144
  h: number;
144
145
  };
145
146
  'ufo:vc:time': number;
147
+ 'ufo:speedIndex'?: number;
148
+ 'ufo:vc:ignored'?: string[];
146
149
  'ufo:vc:abort:reason'?: string;
147
150
  'ufo:vc:state'?: boolean;
148
151
  'ufo:vc:clean'?: boolean;
@@ -161,9 +164,7 @@ export type ReactUFOPayload = {
161
164
  elements: string[];
162
165
  }>;
163
166
  'ufo:vc:next:dom'?: Record<VCParts, string[]>;
164
- 'ufo:vc:ignored'?: string[];
165
167
  'metric:vc90'?: number;
166
- 'ufo:speedIndex'?: number;
167
168
  'ufo:next:speedIndex'?: number;
168
169
  'ufo:vc:updates:next'?: Array<{
169
170
  time: number;
@@ -173,4 +174,49 @@ export type ReactUFOPayload = {
173
174
  };
174
175
  };
175
176
  };
177
+ type LateElement = {
178
+ time: number;
179
+ element: string;
180
+ viewportHeatmapPercentage: number;
181
+ };
182
+ export type PostInteractionLogPayload = {
183
+ actionSubject: 'experience';
184
+ action: 'measured';
185
+ eventType: 'operational';
186
+ source: 'measured';
187
+ tags: ['observability'];
188
+ attributes: {
189
+ properties: {
190
+ 'event:hostname': string;
191
+ 'event:product': string;
192
+ 'event:schema': '1.0.0';
193
+ 'event:source': {
194
+ name: 'react-ufo/web';
195
+ version: '1.0.1';
196
+ };
197
+ 'event:region': string;
198
+ 'experience:key': 'custom.post-interaction-logs';
199
+ postInteractionLog: {
200
+ lastInteractionFinish: {
201
+ ufoName: string;
202
+ start: number;
203
+ end: number;
204
+ id: string;
205
+ routeName: string;
206
+ type: InteractionType;
207
+ errors: InteractionError[];
208
+ ttai: number;
209
+ vc90: number;
210
+ vcClean: boolean;
211
+ };
212
+ revisedEndTime: number;
213
+ revisedTtai: number;
214
+ revisedVC90: number;
215
+ vcClean: boolean;
216
+ lateMutations: LateElement[];
217
+ reactProfilerTimings: ReactProfilerTiming[];
218
+ };
219
+ };
220
+ };
221
+ };
176
222
  export {};
@@ -1,5 +1,5 @@
1
1
  import type { InteractionMetrics, InteractionType } from '../common';
2
- import { ResourceTiming } from '../common/react-ufo-payload-schema';
2
+ import { type ResourceTiming } from '../common/react-ufo-payload-schema';
3
3
  import * as ssr from '../ssr';
4
4
  import type { OptimizedLabelStack } from './common/types';
5
5
  export declare function createPayloads(interactionId: string, interaction: InteractionMetrics): Promise<{
@@ -1,5 +1,5 @@
1
- import { LastInteractionFinishInfo } from '../common';
2
- import { RevisionPayloadVCDetails } from '../common/vc/types';
3
- import { LateMutation } from './types';
1
+ import type { LastInteractionFinishInfo } from '../common';
2
+ import type { RevisionPayloadVCDetails } from '../common/vc/types';
3
+ import type { LateMutation } from './types';
4
4
  declare function getLateMutations(vcDetails: RevisionPayloadVCDetails, lastInteractionFinish: LastInteractionFinishInfo, postInteractionFinishVCRatios: Record<string, number>): LateMutation[];
5
5
  export default getLateMutations;
@@ -1,5 +1,5 @@
1
1
  import { type PostInteractionLogOutput } from '../common';
2
- import { LateMutation } from './types';
2
+ import type { LateMutation } from './types';
3
3
  declare function createPostInteractionLogPayload({ lastInteractionFinish, reactProfilerTimings, lastInteractionFinishVCResult, postInteractionFinishVCResult, }: PostInteractionLogOutput): {
4
4
  actionSubject: string;
5
5
  action: string;
@@ -32,6 +32,7 @@ declare function createPostInteractionLogPayload({ lastInteractionFinish, reactP
32
32
  routeName: string | null;
33
33
  experimentalVC90?: number | undefined;
34
34
  experimentalTTAI?: number | undefined;
35
+ errors: import("../common").InteractionError[];
35
36
  };
36
37
  revisedEndTime: number;
37
38
  revisedTtai: number;
@@ -1,8 +1,7 @@
1
1
  import { type LastInteractionFinishInfo, type PostInteractionLogOutput, type ReactProfilerTiming } from '../common/common/types';
2
2
  import type { VCResult } from '../common/vc/types';
3
3
  import type { LabelStack } from '../interaction-context';
4
- import type { VCObserverOptions } from '../vc/types';
5
- import { VCObserver } from '../vc/vc-observer';
4
+ import type { VCObserverInterface, VCObserverOptions } from '../vc/types';
6
5
  export default class PostInteractionLog {
7
6
  /**
8
7
  * Basic info about interaction that has just finished
@@ -19,7 +18,7 @@ export default class PostInteractionLog {
19
18
  /**
20
19
  * independent VC observer, that observes until `custom.post-interaction-logs` event is sent
21
20
  */
22
- vcObserver: VCObserver | null;
21
+ vcObserver: VCObserverInterface | null;
23
22
  vcObserverSSRConfig: {
24
23
  ssr: number | undefined;
25
24
  } | null;
@@ -62,7 +61,7 @@ export default class PostInteractionLog {
62
61
  * Basic details about the finished interaction will be recorded
63
62
  * A timeout will be setup to send the post interaction observation after some time.
64
63
  */
65
- onInteractionComplete({ ufoName, start, end, id, abortReason, abortedByInteractionName, routeName, type, experimentalTTAI, experimentalVC90, }: LastInteractionFinishInfo): void;
64
+ onInteractionComplete({ ufoName, start, end, id, abortReason, abortedByInteractionName, routeName, type, experimentalTTAI, experimentalVC90, errors, }: LastInteractionFinishInfo): void;
66
65
  /**
67
66
  * This fn should be invoked when a React render happens after interaction has finished
68
67
  */
@@ -1,6 +1,22 @@
1
- import type { VCObserverInterface, VCObserverOptions } from './types';
1
+ import type { VCRawDataType, VCResult } from '../common/vc/types';
2
+ import type { GetVCResultType, VCObserverInterface, VCObserverOptions } from './types';
2
3
  declare global {
3
4
  var __vcObserver: VCObserverInterface;
4
5
  }
6
+ export declare class VCObserverWrapper implements VCObserverInterface {
7
+ private oldVCObserver;
8
+ private newVCObserver;
9
+ constructor(opts?: VCObserverOptions);
10
+ start({ startTime, experienceKey }: {
11
+ startTime: number;
12
+ experienceKey: string;
13
+ }): void;
14
+ stop(experienceKey?: string): void;
15
+ getVCRawData(): VCRawDataType | null;
16
+ getVCResult(param: GetVCResultType): Promise<VCResult>;
17
+ setSSRElement(element: HTMLElement): void;
18
+ setReactRootRenderStart(startTime: number): void;
19
+ setReactRootRenderStop(stopTime: number): void;
20
+ }
5
21
  export declare function isEnvironmentSupported(): boolean;
6
22
  export declare function getVCObserver(opts?: VCObserverOptions): VCObserverInterface;
@@ -1,4 +1,4 @@
1
- import { VCResult } from '../common/vc/types';
1
+ import type { VCResult } from '../common/vc/types';
2
2
  import type { GetVCResultType, VCObserverInterface } from './types';
3
3
  export declare class VCObserverNOOP implements VCObserverInterface {
4
4
  start(startArg: {
@@ -1,5 +1,5 @@
1
- import { InteractionMetrics } from '../../common/common/types';
2
- import { RevisionPayload } from '../../common/vc/types';
1
+ import type { InteractionMetrics } from '../../common/common/types';
2
+ import type { RevisionPayload } from '../../common/vc/types';
3
3
  import type { MultiRevisionHeatmap } from './heatmap/heatmap';
4
4
  type CalculatedVC = {
5
5
  VC: {
@@ -1,4 +1,4 @@
1
- import { RevisionPayloadEntry } from '../../common/vc/types';
1
+ import { type RevisionPayloadEntry } from '../../common/vc/types';
2
2
  import { type SelectorConfig } from './get-element-name';
3
3
  import type { VCObserverGetVCResultParam } from './types';
4
4
  export type VCObserverNewConfig = {
@@ -1,4 +1,4 @@
1
- import { RevisionPayloadEntry, VCAbortReason } from '../../../common/vc/types';
1
+ import type { RevisionPayloadEntry, VCAbortReason } from '../../../common/vc/types';
2
2
  import type { VCObserverEntry } from '../types';
3
3
  import type { VCCalculator, VCCalculatorParam } from './types';
4
4
  export default abstract class AbstractVCCalculatorBase implements VCCalculator {
@@ -1,5 +1,5 @@
1
1
  import type { VCObserverEntry } from '../../../types';
2
- import { HeatmapCheckpointMetrics, HeatmapEntry, HeatmapOptions } from './types';
2
+ import type { HeatmapCheckpointMetrics, HeatmapEntry, HeatmapOptions } from './types';
3
3
  export default class Heatmap {
4
4
  private viewport;
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { RevisionPayloadEntry } from '../../../common/vc/types';
1
+ import type { RevisionPayloadEntry } from '../../../common/vc/types';
2
2
  import type { VCObserverEntry } from '../types';
3
3
  export type VCCalculatorParam = {
4
4
  startTime: DOMHighResTimeStamp;
@@ -202,7 +202,7 @@ export type BM3Event = {
202
202
  pageVisibleState?: string;
203
203
  type: string;
204
204
  };
205
- export type LastInteractionFinishInfo = Pick<InteractionMetrics, 'ufoName' | 'start' | 'end' | 'id' | 'abortReason' | 'abortedByInteractionName' | 'routeName' | 'type' | 'experimentalVC90' | 'experimentalTTAI'>;
205
+ export type LastInteractionFinishInfo = Pick<InteractionMetrics, 'ufoName' | 'start' | 'end' | 'id' | 'abortReason' | 'abortedByInteractionName' | 'routeName' | 'type' | 'experimentalVC90' | 'experimentalTTAI' | 'errors'>;
206
206
  export type PostInteractionLogOutput = {
207
207
  lastInteractionFinish: LastInteractionFinishInfo;
208
208
  reactProfilerTimings?: ReactProfilerTiming[];
@@ -1,7 +1,7 @@
1
1
  import { createPayloads } from '../create-payload';
2
- import { LabelStack } from '../interaction-context';
2
+ import { type LabelStack } from '../interaction-context';
3
3
  import { VCObserver } from '../vc/vc-observer';
4
- import type { AbortReasonType, ApdexType, InteractionType, SegmentInfo } from './common/types';
4
+ import type { AbortReasonType, ApdexType, InteractionError, InteractionType, SegmentInfo } from './common/types';
5
5
  import type { RevisionPayload } from './vc/types';
6
6
  type ExtractPromise<T> = T extends Promise<infer U> ? U : never;
7
7
  export type PageVisibility = 'hidden' | 'mixed' | 'visible';
@@ -137,6 +137,7 @@ export type ReactUFOPayload = {
137
137
  segments: SegmentInfo[] | RootSegment;
138
138
  reactProfilerTimings: ReactProfilerTiming[];
139
139
  holdInfo: HoldInfo[];
140
+ errors: InteractionError[];
140
141
  };
141
142
  'ufo:vc:rev': RevisionPayload;
142
143
  'ufo:vc:ratios': Record<string, number>;
@@ -145,6 +146,8 @@ export type ReactUFOPayload = {
145
146
  h: number;
146
147
  };
147
148
  'ufo:vc:time': number;
149
+ 'ufo:speedIndex'?: number;
150
+ 'ufo:vc:ignored'?: string[];
148
151
  'ufo:vc:abort:reason'?: string;
149
152
  'ufo:vc:state'?: boolean;
150
153
  'ufo:vc:clean'?: boolean;
@@ -163,9 +166,7 @@ export type ReactUFOPayload = {
163
166
  elements: string[];
164
167
  }>;
165
168
  'ufo:vc:next:dom'?: Record<VCParts, string[]>;
166
- 'ufo:vc:ignored'?: string[];
167
169
  'metric:vc90'?: number;
168
- 'ufo:speedIndex'?: number;
169
170
  'ufo:next:speedIndex'?: number;
170
171
  'ufo:vc:updates:next'?: Array<{
171
172
  time: number;
@@ -175,4 +176,51 @@ export type ReactUFOPayload = {
175
176
  };
176
177
  };
177
178
  };
179
+ type LateElement = {
180
+ time: number;
181
+ element: string;
182
+ viewportHeatmapPercentage: number;
183
+ };
184
+ export type PostInteractionLogPayload = {
185
+ actionSubject: 'experience';
186
+ action: 'measured';
187
+ eventType: 'operational';
188
+ source: 'measured';
189
+ tags: [
190
+ 'observability'
191
+ ];
192
+ attributes: {
193
+ properties: {
194
+ 'event:hostname': string;
195
+ 'event:product': string;
196
+ 'event:schema': '1.0.0';
197
+ 'event:source': {
198
+ name: 'react-ufo/web';
199
+ version: '1.0.1';
200
+ };
201
+ 'event:region': string;
202
+ 'experience:key': 'custom.post-interaction-logs';
203
+ postInteractionLog: {
204
+ lastInteractionFinish: {
205
+ ufoName: string;
206
+ start: number;
207
+ end: number;
208
+ id: string;
209
+ routeName: string;
210
+ type: InteractionType;
211
+ errors: InteractionError[];
212
+ ttai: number;
213
+ vc90: number;
214
+ vcClean: boolean;
215
+ };
216
+ revisedEndTime: number;
217
+ revisedTtai: number;
218
+ revisedVC90: number;
219
+ vcClean: boolean;
220
+ lateMutations: LateElement[];
221
+ reactProfilerTimings: ReactProfilerTiming[];
222
+ };
223
+ };
224
+ };
225
+ };
178
226
  export {};
@@ -1,5 +1,5 @@
1
1
  import type { InteractionMetrics, InteractionType } from '../common';
2
- import { ResourceTiming } from '../common/react-ufo-payload-schema';
2
+ import { type ResourceTiming } from '../common/react-ufo-payload-schema';
3
3
  import * as ssr from '../ssr';
4
4
  import type { OptimizedLabelStack } from './common/types';
5
5
  export declare function createPayloads(interactionId: string, interaction: InteractionMetrics): Promise<{
@@ -1,5 +1,5 @@
1
- import { LastInteractionFinishInfo } from '../common';
2
- import { RevisionPayloadVCDetails } from '../common/vc/types';
3
- import { LateMutation } from './types';
1
+ import type { LastInteractionFinishInfo } from '../common';
2
+ import type { RevisionPayloadVCDetails } from '../common/vc/types';
3
+ import type { LateMutation } from './types';
4
4
  declare function getLateMutations(vcDetails: RevisionPayloadVCDetails, lastInteractionFinish: LastInteractionFinishInfo, postInteractionFinishVCRatios: Record<string, number>): LateMutation[];
5
5
  export default getLateMutations;
@@ -1,5 +1,5 @@
1
1
  import { type PostInteractionLogOutput } from '../common';
2
- import { LateMutation } from './types';
2
+ import type { LateMutation } from './types';
3
3
  declare function createPostInteractionLogPayload({ lastInteractionFinish, reactProfilerTimings, lastInteractionFinishVCResult, postInteractionFinishVCResult, }: PostInteractionLogOutput): {
4
4
  actionSubject: string;
5
5
  action: string;
@@ -32,6 +32,7 @@ declare function createPostInteractionLogPayload({ lastInteractionFinish, reactP
32
32
  routeName: string | null;
33
33
  experimentalVC90?: number | undefined;
34
34
  experimentalTTAI?: number | undefined;
35
+ errors: import("../common").InteractionError[];
35
36
  };
36
37
  revisedEndTime: number;
37
38
  revisedTtai: number;
@@ -1,8 +1,7 @@
1
1
  import { type LastInteractionFinishInfo, type PostInteractionLogOutput, type ReactProfilerTiming } from '../common/common/types';
2
2
  import type { VCResult } from '../common/vc/types';
3
3
  import type { LabelStack } from '../interaction-context';
4
- import type { VCObserverOptions } from '../vc/types';
5
- import { VCObserver } from '../vc/vc-observer';
4
+ import type { VCObserverInterface, VCObserverOptions } from '../vc/types';
6
5
  export default class PostInteractionLog {
7
6
  /**
8
7
  * Basic info about interaction that has just finished
@@ -19,7 +18,7 @@ export default class PostInteractionLog {
19
18
  /**
20
19
  * independent VC observer, that observes until `custom.post-interaction-logs` event is sent
21
20
  */
22
- vcObserver: VCObserver | null;
21
+ vcObserver: VCObserverInterface | null;
23
22
  vcObserverSSRConfig: {
24
23
  ssr: number | undefined;
25
24
  } | null;
@@ -62,7 +61,7 @@ export default class PostInteractionLog {
62
61
  * Basic details about the finished interaction will be recorded
63
62
  * A timeout will be setup to send the post interaction observation after some time.
64
63
  */
65
- onInteractionComplete({ ufoName, start, end, id, abortReason, abortedByInteractionName, routeName, type, experimentalTTAI, experimentalVC90, }: LastInteractionFinishInfo): void;
64
+ onInteractionComplete({ ufoName, start, end, id, abortReason, abortedByInteractionName, routeName, type, experimentalTTAI, experimentalVC90, errors, }: LastInteractionFinishInfo): void;
66
65
  /**
67
66
  * This fn should be invoked when a React render happens after interaction has finished
68
67
  */
@@ -1,6 +1,22 @@
1
- import type { VCObserverInterface, VCObserverOptions } from './types';
1
+ import type { VCRawDataType, VCResult } from '../common/vc/types';
2
+ import type { GetVCResultType, VCObserverInterface, VCObserverOptions } from './types';
2
3
  declare global {
3
4
  var __vcObserver: VCObserverInterface;
4
5
  }
6
+ export declare class VCObserverWrapper implements VCObserverInterface {
7
+ private oldVCObserver;
8
+ private newVCObserver;
9
+ constructor(opts?: VCObserverOptions);
10
+ start({ startTime, experienceKey }: {
11
+ startTime: number;
12
+ experienceKey: string;
13
+ }): void;
14
+ stop(experienceKey?: string): void;
15
+ getVCRawData(): VCRawDataType | null;
16
+ getVCResult(param: GetVCResultType): Promise<VCResult>;
17
+ setSSRElement(element: HTMLElement): void;
18
+ setReactRootRenderStart(startTime: number): void;
19
+ setReactRootRenderStop(stopTime: number): void;
20
+ }
5
21
  export declare function isEnvironmentSupported(): boolean;
6
22
  export declare function getVCObserver(opts?: VCObserverOptions): VCObserverInterface;
@@ -1,4 +1,4 @@
1
- import { VCResult } from '../common/vc/types';
1
+ import type { VCResult } from '../common/vc/types';
2
2
  import type { GetVCResultType, VCObserverInterface } from './types';
3
3
  export declare class VCObserverNOOP implements VCObserverInterface {
4
4
  start(startArg: {
@@ -1,5 +1,5 @@
1
- import { InteractionMetrics } from '../../common/common/types';
2
- import { RevisionPayload } from '../../common/vc/types';
1
+ import type { InteractionMetrics } from '../../common/common/types';
2
+ import type { RevisionPayload } from '../../common/vc/types';
3
3
  import type { MultiRevisionHeatmap } from './heatmap/heatmap';
4
4
  type CalculatedVC = {
5
5
  VC: {
@@ -1,4 +1,4 @@
1
- import { RevisionPayloadEntry } from '../../common/vc/types';
1
+ import { type RevisionPayloadEntry } from '../../common/vc/types';
2
2
  import { type SelectorConfig } from './get-element-name';
3
3
  import type { VCObserverGetVCResultParam } from './types';
4
4
  export type VCObserverNewConfig = {
@@ -1,4 +1,4 @@
1
- import { RevisionPayloadEntry, VCAbortReason } from '../../../common/vc/types';
1
+ import type { RevisionPayloadEntry, VCAbortReason } from '../../../common/vc/types';
2
2
  import type { VCObserverEntry } from '../types';
3
3
  import type { VCCalculator, VCCalculatorParam } from './types';
4
4
  export default abstract class AbstractVCCalculatorBase implements VCCalculator {
@@ -1,5 +1,5 @@
1
1
  import type { VCObserverEntry } from '../../../types';
2
- import { HeatmapCheckpointMetrics, HeatmapEntry, HeatmapOptions } from './types';
2
+ import type { HeatmapCheckpointMetrics, HeatmapEntry, HeatmapOptions } from './types';
3
3
  export default class Heatmap {
4
4
  private viewport;
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { RevisionPayloadEntry } from '../../../common/vc/types';
1
+ import type { RevisionPayloadEntry } from '../../../common/vc/types';
2
2
  import type { VCObserverEntry } from '../types';
3
3
  export type VCCalculatorParam = {
4
4
  startTime: DOMHighResTimeStamp;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/react-ufo",
3
- "version": "3.11.0",
3
+ "version": "3.11.2",
4
4
  "description": "Parts of React UFO that are publicly available",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -130,6 +130,9 @@
130
130
  "platform_ufo_use_offscreen_canvas": {
131
131
  "type": "boolean"
132
132
  },
133
+ "platform_ufo_vc_align_revisions_on_watchdog_event": {
134
+ "type": "boolean"
135
+ },
133
136
  "platform_ufo_canvas_heatmap_full_precision": {
134
137
  "type": "boolean"
135
138
  },