@atlaskit/react-ufo 3.14.6 → 3.14.8

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 (55) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/create-experimental-interaction-metrics-payload/index.js +14 -12
  3. package/dist/cjs/create-payload/utils/get-vc-metrics.js +17 -13
  4. package/dist/cjs/interaction-metrics/index.js +35 -15
  5. package/dist/cjs/interaction-metrics-init/index.js +5 -3
  6. package/dist/cjs/vc/index.js +46 -6
  7. package/dist/cjs/vc/vc-observer/index.js +10 -2
  8. package/dist/cjs/vc/vc-observer/observers/index.js +12 -7
  9. package/dist/cjs/vc/vc-observer/observers/ssr-placeholders/index.js +76 -40
  10. package/dist/cjs/vc/vc-observer-new/index.js +84 -0
  11. package/dist/cjs/vc/vc-observer-new/viewport-observer/index.js +214 -71
  12. package/dist/cjs/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +97 -59
  13. package/dist/es2019/create-experimental-interaction-metrics-payload/index.js +4 -2
  14. package/dist/es2019/create-payload/utils/get-vc-metrics.js +10 -4
  15. package/dist/es2019/interaction-metrics/index.js +36 -16
  16. package/dist/es2019/interaction-metrics-init/index.js +5 -3
  17. package/dist/es2019/vc/index.js +42 -5
  18. package/dist/es2019/vc/vc-observer/index.js +8 -2
  19. package/dist/es2019/vc/vc-observer/observers/index.js +11 -5
  20. package/dist/es2019/vc/vc-observer/observers/ssr-placeholders/index.js +57 -26
  21. package/dist/es2019/vc/vc-observer-new/index.js +67 -1
  22. package/dist/es2019/vc/vc-observer-new/viewport-observer/index.js +87 -22
  23. package/dist/es2019/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +50 -34
  24. package/dist/esm/create-experimental-interaction-metrics-payload/index.js +14 -12
  25. package/dist/esm/create-payload/utils/get-vc-metrics.js +17 -13
  26. package/dist/esm/interaction-metrics/index.js +36 -16
  27. package/dist/esm/interaction-metrics-init/index.js +5 -3
  28. package/dist/esm/vc/index.js +45 -6
  29. package/dist/esm/vc/vc-observer/index.js +10 -2
  30. package/dist/esm/vc/vc-observer/observers/index.js +12 -7
  31. package/dist/esm/vc/vc-observer/observers/ssr-placeholders/index.js +76 -40
  32. package/dist/esm/vc/vc-observer-new/index.js +84 -0
  33. package/dist/esm/vc/vc-observer-new/viewport-observer/index.js +214 -71
  34. package/dist/esm/vc/vc-observer-new/viewport-observer/mutation-observer/index.js +97 -59
  35. package/dist/types/common/common/types.d.ts +4 -1
  36. package/dist/types/vc/index.d.ts +3 -0
  37. package/dist/types/vc/types.d.ts +2 -0
  38. package/dist/types/vc/vc-observer/index.d.ts +1 -0
  39. package/dist/types/vc/vc-observer/observers/index.d.ts +2 -0
  40. package/dist/types/vc/vc-observer/observers/ssr-placeholders/index.d.ts +6 -0
  41. package/dist/types/vc/vc-observer-new/index.d.ts +30 -0
  42. package/dist/types/vc/vc-observer-new/types.d.ts +1 -1
  43. package/dist/types/vc/vc-observer-new/viewport-observer/index.d.ts +5 -1
  44. package/dist/types/vc/vc-observer-new/viewport-observer/mutation-observer/index.d.ts +2 -0
  45. package/dist/types-ts4.5/common/common/types.d.ts +4 -1
  46. package/dist/types-ts4.5/vc/index.d.ts +3 -0
  47. package/dist/types-ts4.5/vc/types.d.ts +2 -0
  48. package/dist/types-ts4.5/vc/vc-observer/index.d.ts +1 -0
  49. package/dist/types-ts4.5/vc/vc-observer/observers/index.d.ts +2 -0
  50. package/dist/types-ts4.5/vc/vc-observer/observers/ssr-placeholders/index.d.ts +6 -0
  51. package/dist/types-ts4.5/vc/vc-observer-new/index.d.ts +30 -0
  52. package/dist/types-ts4.5/vc/vc-observer-new/types.d.ts +1 -1
  53. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/index.d.ts +5 -1
  54. package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/mutation-observer/index.d.ts +2 -0
  55. package/package.json +11 -6
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @atlaskit/ufo-interaction-ignore
2
2
 
3
+ ## 3.14.8
4
+
5
+ ### Patch Changes
6
+
7
+ - [#179381](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/179381)
8
+ [`05fa3d08ecda9`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/05fa3d08ecda9) -
9
+ User vc observer per interaction
10
+
11
+ ## 3.14.7
12
+
13
+ ### Patch Changes
14
+
15
+ - [#179438](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/179438)
16
+ [`b0d336b1f78b3`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/b0d336b1f78b3) -
17
+ AFO-4081 support ssr-placeholder for ttvc v3
18
+
3
19
  ## 3.14.6
4
20
 
5
21
  ### Patch Changes
@@ -95,17 +95,19 @@ function getExperimentalVCMetrics(_x) {
95
95
  }
96
96
  function _getExperimentalVCMetrics() {
97
97
  _getExperimentalVCMetrics = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(interaction) {
98
- var _interaction$apdex, prefix, result, VC, pageVisibilityUpToTTAI;
98
+ var vcObserver, _interaction$apdex, prefix, result, VC, pageVisibilityUpToTTAI;
99
99
  return _regenerator.default.wrap(function _callee$(_context) {
100
100
  while (1) switch (_context.prev = _context.next) {
101
101
  case 0:
102
- if (!experimentalVC.vcObserver) {
103
- _context.next = 12;
102
+ // Use per-interaction VC observer if available, otherwise fall back to global experimentalVC
103
+ vcObserver = interaction.experimentalVCObserver || experimentalVC.vcObserver;
104
+ if (!vcObserver) {
105
+ _context.next = 13;
104
106
  break;
105
107
  }
106
108
  prefix = 'ufo-experimental';
107
- _context.next = 4;
108
- return experimentalVC.vcObserver.getVCResult({
109
+ _context.next = 5;
110
+ return vcObserver.getVCResult({
109
111
  start: interaction.start,
110
112
  stop: interaction.end,
111
113
  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,
@@ -115,28 +117,28 @@ function _getExperimentalVCMetrics() {
115
117
  experienceKey: interaction.ufoName,
116
118
  interactionId: interaction.id
117
119
  });
118
- case 4:
120
+ case 5:
119
121
  result = _context.sent;
120
122
  VC = result === null || result === void 0 ? void 0 : result['metrics:vc'];
121
123
  if (!(!VC || !(result !== null && result !== void 0 && result["".concat(prefix, ":vc:clean")]))) {
122
- _context.next = 8;
124
+ _context.next = 9;
123
125
  break;
124
126
  }
125
127
  return _context.abrupt("return", result);
126
- case 8:
128
+ case 9:
127
129
  pageVisibilityUpToTTAI = (0, _hiddenTiming.getPageVisibilityState)(interaction.start, interaction.end);
128
130
  if (!(interaction.abortReason || pageVisibilityUpToTTAI !== 'visible')) {
129
- _context.next = 11;
131
+ _context.next = 12;
130
132
  break;
131
133
  }
132
134
  return _context.abrupt("return", result);
133
- case 11:
135
+ case 12:
134
136
  return _context.abrupt("return", _objectSpread(_objectSpread({}, result), {}, {
135
137
  'metric:experimental:vc90': VC['90']
136
138
  }));
137
- case 12:
138
- return _context.abrupt("return", null);
139
139
  case 13:
140
+ return _context.abrupt("return", null);
141
+ case 14:
140
142
  case "end":
141
143
  return _context.stop();
142
144
  }
@@ -23,7 +23,7 @@ function getVCMetrics(_x) {
23
23
  function _getVCMetrics() {
24
24
  _getVCMetrics = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(interaction) {
25
25
  var _config$vc, _config$vc$ssrWhiteli, _interaction$apdex, _config$vc2, _config$vc3, _config$experimentalI, _result$ufoVcRev;
26
- var config, interactionStatus, pageVisibilityUpToTTAI, shouldReportVCMetrics, isSSREnabled, ssr, tti, prefix, result, mostRecentVCRevision, mostRecentVCRevisionPayload;
26
+ var config, interactionStatus, pageVisibilityUpToTTAI, shouldReportVCMetrics, observer, isSSREnabled, ssr, tti, prefix, result, mostRecentVCRevision, mostRecentVCRevisionPayload;
27
27
  return _regenerator.default.wrap(function _callee$(_context) {
28
28
  while (1) switch (_context.prev = _context.next) {
29
29
  case 0:
@@ -34,7 +34,7 @@ function _getVCMetrics() {
34
34
  }
35
35
  return _context.abrupt("return", {});
36
36
  case 3:
37
- if (!((0, _platformFeatureFlags.fg)('platform_ufo_enable_interactions_vc') || (0, _platformFeatureFlags.fg)('platform_ufo_enable_interactivity_jsm'))) {
37
+ if (!(0, _platformFeatureFlags.fg)('platform_ufo_enable_vc_press_interactions')) {
38
38
  _context.next = 8;
39
39
  break;
40
40
  }
@@ -55,14 +55,15 @@ function _getVCMetrics() {
55
55
  case 10:
56
56
  interactionStatus = (0, _getInteractionStatus.default)(interaction);
57
57
  pageVisibilityUpToTTAI = (0, _getPageVisibilityUpToTtai.default)(interaction);
58
- shouldReportVCMetrics = interactionStatus.originalInteractionStatus === 'SUCCEEDED' && pageVisibilityUpToTTAI === 'visible';
58
+ shouldReportVCMetrics = interactionStatus.originalInteractionStatus === 'SUCCEEDED' && pageVisibilityUpToTTAI === 'visible'; // Use per-interaction VC observer if available, otherwise fall back to global
59
+ observer = interaction.vcObserver || (0, _vc.getVCObserver)();
59
60
  if (!(!shouldReportVCMetrics && (0, _platformFeatureFlags.fg)('platform_ufo_no_vc_on_aborted'))) {
60
- _context.next = 16;
61
+ _context.next = 17;
61
62
  break;
62
63
  }
63
- (0, _vc.getVCObserver)().stop(interaction.ufoName);
64
+ observer.stop(interaction.ufoName);
64
65
  return _context.abrupt("return", {});
65
- case 16:
66
+ case 17:
66
67
  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)));
67
68
  ssr = interaction.type === 'page_load' && isSSREnabled ? {
68
69
  ssr: (0, _getSsrDoneTimeValue.default)(config)
@@ -70,8 +71,8 @@ function _getVCMetrics() {
70
71
  _interactionMetrics.postInteractionLog.setVCObserverSSRConfig(ssr);
71
72
  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;
72
73
  prefix = 'ufo';
73
- _context.next = 23;
74
- return (0, _vc.getVCObserver)().getVCResult(_objectSpread({
74
+ _context.next = 24;
75
+ return observer.getVCResult(_objectSpread({
75
76
  start: interaction.start,
76
77
  stop: interaction.end,
77
78
  tti: tti,
@@ -83,10 +84,13 @@ function _getVCMetrics() {
83
84
  interactionId: interaction.id,
84
85
  includeSSRRatio: (_config$vc3 = config.vc) === null || _config$vc3 === void 0 ? void 0 : _config$vc3.includeSSRRatio
85
86
  }, ssr));
86
- case 23:
87
+ case 24:
87
88
  result = _context.sent;
89
+ if ((0, _platformFeatureFlags.fg)('platform_ufo_enable_vc_observer_per_interaction')) {
90
+ observer.stop(interaction.ufoName);
91
+ }
88
92
  if ((_config$experimentalI = config.experimentalInteractionMetrics) !== null && _config$experimentalI !== void 0 && _config$experimentalI.enabled) {
89
- (0, _vc.getVCObserver)().stop(interaction.ufoName);
93
+ observer.stop(interaction.ufoName);
90
94
  }
91
95
  _interactionMetrics.postInteractionLog.setLastInteractionFinishVCResult(result);
92
96
  mostRecentVCRevision = (0, _config.getMostRecentVCRevision)(interaction.ufoName);
@@ -95,15 +99,15 @@ function _getVCMetrics() {
95
99
  return revision === mostRecentVCRevision;
96
100
  });
97
101
  if (!(!shouldReportVCMetrics || !(mostRecentVCRevisionPayload !== null && mostRecentVCRevisionPayload !== void 0 && mostRecentVCRevisionPayload.clean))) {
98
- _context.next = 30;
102
+ _context.next = 32;
99
103
  break;
100
104
  }
101
105
  return _context.abrupt("return", result);
102
- case 30:
106
+ case 32:
103
107
  return _context.abrupt("return", _objectSpread(_objectSpread({}, result), {}, {
104
108
  'metric:vc90': mostRecentVCRevisionPayload['metric:vc90']
105
109
  }));
106
- case 31:
110
+ case 33:
107
111
  case "end":
108
112
  return _context.stop();
109
113
  }
@@ -569,7 +569,9 @@ function finishInteraction(id, data) {
569
569
  (0, _experienceTraceIdContext.clearActiveTrace)();
570
570
  callCleanUpCallbacks(data);
571
571
  if ((_getConfig4 = (0, _config.getConfig)()) !== null && _getConfig4 !== void 0 && (_getConfig4 = _getConfig4.vc) !== null && _getConfig4 !== void 0 && _getConfig4.stopVCAtInteractionFinish) {
572
- data.vc = (0, _vc.getVCObserver)().getVCRawData();
572
+ // Use per-interaction VC observer if available, otherwise fall back to global
573
+ var observer = data.vcObserver || (0, _vc.getVCObserver)();
574
+ data.vc = observer.getVCRawData();
573
575
  }
574
576
  if (!((_getConfig5 = (0, _config.getConfig)()) !== null && _getConfig5 !== void 0 && (_getConfig5 = _getConfig5.experimentalInteractionMetrics) !== null && _getConfig5 !== void 0 && _getConfig5.enabled)) {
575
577
  remove(id);
@@ -781,6 +783,7 @@ function addNewInteraction(interactionId, ufoName, type, startTime, rate, labelS
781
783
  if ((_getConfig11 = (0, _config.getConfig)()) !== null && _getConfig11 !== void 0 && (_getConfig11 = _getConfig11.postInteractionLog) !== null && _getConfig11 !== void 0 && _getConfig11.enabled) {
782
784
  postInteractionLog.reset();
783
785
  }
786
+ var vcObserver;
784
787
  var previousTime = startTime;
785
788
  var timeoutTime = (0, _platformFeatureFlags.fg)('platform_ufo_enable_timeout_config') ? (0, _config.getInteractionTimeout)(ufoName) : CLEANUP_TIMEOUT;
786
789
  var timerID = setTimeout(function () {
@@ -803,6 +806,21 @@ function addNewInteraction(interactionId, ufoName, type, startTime, rate, labelS
803
806
  this.timerID = newTimerID;
804
807
  }
805
808
  var addFeatureFlagsToInteraction = (0, _coinflip.default)((0, _config.getCapabilityRate)('feature_flag_access'));
809
+ var config = (0, _config.getConfig)();
810
+ if (config && config.vc) {
811
+ var vcOptions = {
812
+ heatmapSize: config.vc.heatmapSize,
813
+ oldDomUpdates: config.vc.oldDomUpdates,
814
+ devToolsEnabled: config.vc.devToolsEnabled,
815
+ selectorConfig: config.vc.selectorConfig,
816
+ ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder,
817
+ disableSizeAndPositionCheck: config.vc.disableSizeAndPositionCheck
818
+ };
819
+ vcObserver = (0, _platformFeatureFlags.fg)('platform_ufo_enable_vc_observer_per_interaction') ? (0, _vc.newVCObserver)(vcOptions) : undefined;
820
+ }
821
+
822
+ // Create per-interaction VC observer when feature flag is enabled
823
+
806
824
  var metrics = {
807
825
  id: interactionId,
808
826
  start: startTime,
@@ -843,7 +861,8 @@ function addNewInteraction(interactionId, ufoName, type, startTime, rate, labelS
843
861
  redirects: [],
844
862
  timerID: timerID,
845
863
  changeTimeout: changeTimeout,
846
- trace: trace
864
+ trace: trace,
865
+ vcObserver: vcObserver
847
866
  };
848
867
  if (addFeatureFlagsToInteraction) {
849
868
  _featureFlagsAccessed.currentFeatureFlagsAccessed.clear();
@@ -862,13 +881,21 @@ function addNewInteraction(interactionId, ufoName, type, startTime, rate, labelS
862
881
  metrics.cleanupCallbacks.push(function () {
863
882
  clearTimeout(metrics.timerID);
864
883
  });
884
+ // Add cleanup for per-interaction VC observer
885
+ if (vcObserver) {
886
+ metrics.cleanupCallbacks.push(function () {
887
+ vcObserver.stop(ufoName);
888
+ });
889
+ }
865
890
  var awaitBM3TTIList = (0, _config.getAwaitBM3TTIList)();
866
891
  if (awaitBM3TTIList.includes(ufoName)) {
867
892
  addHoldByID(interactionId, [], ufoName, ufoName, true);
868
893
  }
869
- if (type === 'transition') {
894
+ if (type === 'transition' || type === 'page_load') {
870
895
  var _getConfig12;
871
- (0, _vc.getVCObserver)().start({
896
+ // Use per-interaction VC observer if available, otherwise fall back to global
897
+ var observer = vcObserver || (0, _vc.getVCObserver)();
898
+ observer.start({
872
899
  startTime: startTime,
873
900
  experienceKey: ufoName
874
901
  });
@@ -881,20 +908,13 @@ function addNewInteraction(interactionId, ufoName, type, startTime, rate, labelS
881
908
  });
882
909
  }
883
910
  }
884
- if (type === 'press' && ((0, _platformFeatureFlags.fg)('platform_ufo_enable_interactions_vc') || (0, _platformFeatureFlags.fg)('platform_ufo_enable_interactivity_jsm'))) {
885
- var _getConfig13;
886
- (0, _vc.getVCObserver)().start({
911
+ if (type === 'press' && (0, _platformFeatureFlags.fg)('platform_ufo_enable_vc_press_interactions')) {
912
+ // Use per-interaction VC observer if available, otherwise fall back to global
913
+ var _observer = vcObserver || (0, _vc.getVCObserver)();
914
+ _observer.start({
887
915
  startTime: startTime,
888
916
  experienceKey: ufoName
889
917
  });
890
- postInteractionLog.startVCObserver({
891
- startTime: startTime
892
- });
893
- if ((_getConfig13 = (0, _config.getConfig)()) !== null && _getConfig13 !== void 0 && (_getConfig13 = _getConfig13.experimentalInteractionMetrics) !== null && _getConfig13 !== void 0 && _getConfig13.enabled) {
894
- _createExperimentalInteractionMetricsPayload.experimentalVC.start({
895
- startTime: startTime
896
- });
897
- }
898
918
  }
899
919
  }
900
920
  function addBrowserMetricEvent(event) {
@@ -101,9 +101,11 @@ function init(analyticsWebClientAsync, config) {
101
101
  ssrEnablePageLayoutPlaceholder: config.vc.ssrEnablePageLayoutPlaceholder,
102
102
  disableSizeAndPositionCheck: config.vc.disableSizeAndPositionCheck
103
103
  };
104
- (0, _vc.getVCObserver)(vcOptions).start({
105
- startTime: 0
106
- });
104
+ if (!(0, _platformFeatureFlags.fg)('platform_ufo_enable_vc_observer_per_interaction')) {
105
+ (0, _vc.getVCObserver)(vcOptions).start({
106
+ startTime: 0
107
+ });
108
+ }
107
109
  _interactionMetrics.postInteractionLog.initializeVCObserver(vcOptions);
108
110
  _interactionMetrics.postInteractionLog.startVCObserver({
109
111
  startTime: 0
@@ -7,10 +7,11 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.VCObserverWrapper = void 0;
8
8
  exports.getVCObserver = getVCObserver;
9
9
  exports.isEnvironmentSupported = isEnvironmentSupported;
10
+ exports.newVCObserver = newVCObserver;
10
11
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
12
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
12
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
13
13
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
14
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
14
15
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
15
16
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
16
17
  var _config = require("../config");
@@ -18,22 +19,45 @@ var _noOpVcObserver = require("./no-op-vc-observer");
18
19
  var _vcObserver = require("./vc-observer");
19
20
  var _vcObserverNew = _interopRequireDefault(require("./vc-observer-new"));
20
21
  var _rllPlaceholders = require("./vc-observer/observers/rll-placeholders");
22
+ var _ssrPlaceholders = require("./vc-observer/observers/ssr-placeholders");
21
23
  var _process;
22
24
  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; }
23
25
  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; }
24
26
  var VCObserverWrapper = exports.VCObserverWrapper = /*#__PURE__*/function () {
25
27
  function VCObserverWrapper() {
28
+ var _opts$ssrEnablePageLa, _opts$disableSizeAndP;
26
29
  var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
27
30
  (0, _classCallCheck2.default)(this, VCObserverWrapper);
28
31
  this.newVCObserver = null;
29
32
  this.oldVCObserver = null;
33
+
34
+ // Initialize SSR placeholder handler once
35
+ this.ssrPlaceholderHandler = new _ssrPlaceholders.SSRPlaceholderHandlers({
36
+ enablePageLayoutPlaceholder: (_opts$ssrEnablePageLa = opts.ssrEnablePageLayoutPlaceholder) !== null && _opts$ssrEnablePageLa !== void 0 ? _opts$ssrEnablePageLa : false,
37
+ disableSizeAndPositionCheck: (_opts$disableSizeAndP = opts.disableSizeAndPositionCheck) !== null && _opts$disableSizeAndP !== void 0 ? _opts$disableSizeAndP : {
38
+ v: false,
39
+ h: false
40
+ }
41
+ });
30
42
  if ((0, _config.isVCRevisionEnabled)('fy25.03')) {
43
+ var _opts$ssrEnablePageLa2, _opts$disableSizeAndP2;
31
44
  this.newVCObserver = new _vcObserverNew.default({
32
- selectorConfig: opts.selectorConfig
45
+ selectorConfig: opts.selectorConfig,
46
+ isPostInteraction: opts.isPostInteraction,
47
+ SSRConfig: {
48
+ enablePageLayoutPlaceholder: (_opts$ssrEnablePageLa2 = opts.ssrEnablePageLayoutPlaceholder) !== null && _opts$ssrEnablePageLa2 !== void 0 ? _opts$ssrEnablePageLa2 : false,
49
+ disableSizeAndPositionCheck: (_opts$disableSizeAndP2 = opts.disableSizeAndPositionCheck) !== null && _opts$disableSizeAndP2 !== void 0 ? _opts$disableSizeAndP2 : {
50
+ v: false,
51
+ h: false
52
+ }
53
+ },
54
+ ssrPlaceholderHandler: this.ssrPlaceholderHandler
33
55
  });
34
56
  }
35
57
  if ((0, _config.isVCRevisionEnabled)('fy25.01') || (0, _config.isVCRevisionEnabled)('fy25.02')) {
36
- this.oldVCObserver = new _vcObserver.VCObserver(opts);
58
+ this.oldVCObserver = new _vcObserver.VCObserver(_objectSpread(_objectSpread({}, opts), {}, {
59
+ ssrPlaceholderHandler: this.ssrPlaceholderHandler
60
+ }));
37
61
  }
38
62
  }
39
63
 
@@ -92,6 +116,8 @@ var VCObserverWrapper = exports.VCObserverWrapper = /*#__PURE__*/function () {
92
116
  (_this$newVCObserver2 = this.newVCObserver) === null || _this$newVCObserver2 === void 0 || _this$newVCObserver2.stop();
93
117
  }
94
118
  _rllPlaceholders.RLLPlaceholderHandlers.getInstance().reset();
119
+ // Clear shared SSR placeholder handler
120
+ this.ssrPlaceholderHandler.clear();
95
121
  }
96
122
  }, {
97
123
  key: "getVCRawData",
@@ -165,20 +191,28 @@ var VCObserverWrapper = exports.VCObserverWrapper = /*#__PURE__*/function () {
165
191
  }, {
166
192
  key: "setSSRElement",
167
193
  value: function setSSRElement(element) {
168
- var _this$oldVCObserver5;
194
+ var _this$oldVCObserver5, _this$newVCObserver4;
169
195
  (_this$oldVCObserver5 = this.oldVCObserver) === null || _this$oldVCObserver5 === void 0 || _this$oldVCObserver5.setSSRElement(element);
196
+ (_this$newVCObserver4 = this.newVCObserver) === null || _this$newVCObserver4 === void 0 || _this$newVCObserver4.setReactRootElement(element);
170
197
  }
171
198
  }, {
172
199
  key: "setReactRootRenderStart",
173
200
  value: function setReactRootRenderStart(startTime) {
174
- var _this$oldVCObserver6;
201
+ var _this$oldVCObserver6, _this$newVCObserver5;
175
202
  (_this$oldVCObserver6 = this.oldVCObserver) === null || _this$oldVCObserver6 === void 0 || _this$oldVCObserver6.setReactRootRenderStart(startTime || performance.now());
203
+ (_this$newVCObserver5 = this.newVCObserver) === null || _this$newVCObserver5 === void 0 || _this$newVCObserver5.setReactRootRenderStart(startTime || performance.now());
176
204
  }
177
205
  }, {
178
206
  key: "setReactRootRenderStop",
179
207
  value: function setReactRootRenderStop(stopTime) {
180
- var _this$oldVCObserver7;
208
+ var _this$oldVCObserver7, _this$newVCObserver6;
181
209
  (_this$oldVCObserver7 = this.oldVCObserver) === null || _this$oldVCObserver7 === void 0 || _this$oldVCObserver7.setReactRootRenderStop(stopTime || performance.now());
210
+ (_this$newVCObserver6 = this.newVCObserver) === null || _this$newVCObserver6 === void 0 || _this$newVCObserver6.setReactRootRenderStop(stopTime || performance.now());
211
+ }
212
+ }, {
213
+ key: "collectSSRPlaceholders",
214
+ value: function collectSSRPlaceholders() {
215
+ this.ssrPlaceholderHandler.collectExistingPlaceholders();
182
216
  }
183
217
  }]);
184
218
  }(); // Some products set this variable to indicate it is running in SSR
@@ -208,4 +242,10 @@ function getVCObserver() {
208
242
  globalThis.__vcObserver = shouldMockVCObserver ? new _noOpVcObserver.VCObserverNOOP() : new VCObserverWrapper(opts);
209
243
  }
210
244
  return globalThis.__vcObserver;
245
+ }
246
+ function newVCObserver() {
247
+ var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
248
+ var shouldMockVCObserver = !isEnvironmentSupported();
249
+ var observer = shouldMockVCObserver ? new _noOpVcObserver.VCObserverNOOP() : new VCObserverWrapper(opts);
250
+ return observer;
211
251
  }
@@ -455,7 +455,8 @@ var VCObserver = exports.VCObserver = /*#__PURE__*/function () {
455
455
  this.devToolsEnabled = options.devToolsEnabled || false;
456
456
  this.oldDomUpdatesEnabled = options.oldDomUpdates || false;
457
457
  var ssrEnablePageLayoutPlaceholder = options.ssrEnablePageLayoutPlaceholder,
458
- disableSizeAndPositionCheck = options.disableSizeAndPositionCheck;
458
+ disableSizeAndPositionCheck = options.disableSizeAndPositionCheck,
459
+ ssrPlaceholderHandler = options.ssrPlaceholderHandler;
459
460
  this.observers = new _observers.Observers({
460
461
  selectorConfig: options.selectorConfig || {
461
462
  id: false,
@@ -467,7 +468,8 @@ var VCObserver = exports.VCObserver = /*#__PURE__*/function () {
467
468
  SSRConfig: {
468
469
  enablePageLayoutPlaceholder: ssrEnablePageLayoutPlaceholder || false,
469
470
  disableSizeAndPositionCheck: disableSizeAndPositionCheck
470
- }
471
+ },
472
+ ssrPlaceholderHandler: ssrPlaceholderHandler
471
473
  });
472
474
  this.heatmap = !(0, _config.isVCRevisionEnabled)('fy25.01') ? [] : this.getCleanHeatmap();
473
475
  this.heatmapNext = this.getCleanHeatmap();
@@ -527,6 +529,12 @@ var VCObserver = exports.VCObserver = /*#__PURE__*/function () {
527
529
  var stopTime = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : performance.now();
528
530
  this.observers.setReactRootRenderStop(stopTime);
529
531
  }
532
+ }, {
533
+ key: "collectSSRPlaceholders",
534
+ value: function collectSSRPlaceholders() {
535
+ // This is handled by the shared SSRPlaceholderHandlers in VCObserverWrapper
536
+ // Individual observers don't need to implement this
537
+ }
530
538
  }, {
531
539
  key: "setAbortReason",
532
540
  value: function setAbortReason(abort, timestamp) {
@@ -32,9 +32,7 @@ function isElementVisible(target) {
32
32
  }
33
33
  var Observers = exports.Observers = /*#__PURE__*/function () {
34
34
  function Observers(opts) {
35
- var _this = this,
36
- _opts$SSRConfig,
37
- _opts$SSRConfig2;
35
+ var _this = this;
38
36
  (0, _classCallCheck2.default)(this, Observers);
39
37
  (0, _defineProperty2.default)(this, "observedMutations", new WeakMap());
40
38
  (0, _defineProperty2.default)(this, "elementsInView", new Set());
@@ -74,10 +72,17 @@ var Observers = exports.Observers = /*#__PURE__*/function () {
74
72
  this.selectorConfig = _objectSpread(_objectSpread({}, this.selectorConfig), opts.selectorConfig);
75
73
  this.intersectionObserver = this.getIntersectionObserver();
76
74
  this.mutationObserver = this.getMutationObserver();
77
- this.ssrPlaceholderHandler = new _ssrPlaceholders.SSRPlaceholderHandlers({
78
- enablePageLayoutPlaceholder: (_opts$SSRConfig = opts.SSRConfig) === null || _opts$SSRConfig === void 0 ? void 0 : _opts$SSRConfig.enablePageLayoutPlaceholder,
79
- disableSizeAndPositionCheck: (_opts$SSRConfig2 = opts.SSRConfig) === null || _opts$SSRConfig2 === void 0 ? void 0 : _opts$SSRConfig2.disableSizeAndPositionCheck
80
- });
75
+
76
+ // Use shared SSR placeholder handler if provided, otherwise create new one
77
+ if (opts.ssrPlaceholderHandler) {
78
+ this.ssrPlaceholderHandler = opts.ssrPlaceholderHandler;
79
+ } else {
80
+ var _opts$SSRConfig, _opts$SSRConfig2;
81
+ this.ssrPlaceholderHandler = new _ssrPlaceholders.SSRPlaceholderHandlers({
82
+ enablePageLayoutPlaceholder: (_opts$SSRConfig = opts.SSRConfig) === null || _opts$SSRConfig === void 0 ? void 0 : _opts$SSRConfig.enablePageLayoutPlaceholder,
83
+ disableSizeAndPositionCheck: (_opts$SSRConfig2 = opts.SSRConfig) === null || _opts$SSRConfig2 === void 0 ? void 0 : _opts$SSRConfig2.disableSizeAndPositionCheck
84
+ });
85
+ }
81
86
  }
82
87
  return (0, _createClass2.default)(Observers, [{
83
88
  key: "isBrowserSupported",
@@ -111,32 +111,8 @@ var SSRPlaceholderHandlers = exports.SSRPlaceholderHandlers = /*#__PURE__*/funct
111
111
  this.disableSizeAndPositionCheck = disableSizeAndPositionCheck;
112
112
  if (window.document) {
113
113
  try {
114
- var selector = this.enablePageLayoutPlaceholder ? '[data-ssr-placeholder],[data-testid="page-layout.root"]' : '[data-ssr-placeholder]';
115
- var existingElements = document.querySelectorAll(selector);
116
- existingElements.forEach(function (el) {
117
- var placeholderId = el instanceof HTMLElement && _this.getPlaceholderId(el);
118
- if (placeholderId) {
119
- var _window$__SSR_PLACEHO, _this$intersectionObs2;
120
- var width = -1;
121
- var height = -1;
122
- var x = -1;
123
- var y = -1;
124
- var boundingClientRect = (_window$__SSR_PLACEHO = window.__SSR_PLACEHOLDERS_DIMENSIONS__) === null || _window$__SSR_PLACEHO === void 0 ? void 0 : _window$__SSR_PLACEHO[placeholderId];
125
- if (boundingClientRect) {
126
- width = boundingClientRect.width;
127
- height = boundingClientRect.height;
128
- x = boundingClientRect.x;
129
- y = boundingClientRect.y;
130
- }
131
- _this.staticPlaceholders.set(placeholderId, {
132
- width: width,
133
- height: height,
134
- x: x,
135
- y: y
136
- });
137
- (_this$intersectionObs2 = _this.intersectionObserver) === null || _this$intersectionObs2 === void 0 || _this$intersectionObs2.observe(el);
138
- }
139
- });
114
+ // Collect initial placeholders using SSR dimensions
115
+ this.collectPlaceholdersInternal();
140
116
  } catch (e) {} finally {
141
117
  delete window.__SSR_PLACEHOLDERS_DIMENSIONS__;
142
118
  }
@@ -150,6 +126,66 @@ var SSRPlaceholderHandlers = exports.SSRPlaceholderHandlers = /*#__PURE__*/funct
150
126
  this.getSizeCallbacks = new Map();
151
127
  this.reactValidateCallbacks = new Map();
152
128
  }
129
+ }, {
130
+ key: "collectPlaceholdersInternal",
131
+ value: function collectPlaceholdersInternal() {
132
+ var _this2 = this;
133
+ var selector = this.enablePageLayoutPlaceholder ? '[data-ssr-placeholder],[data-testid="page-layout.root"]' : '[data-ssr-placeholder]';
134
+ var existingElements = document.querySelectorAll(selector);
135
+ existingElements.forEach(function (el) {
136
+ var placeholderId = el instanceof HTMLElement && _this2.getPlaceholderId(el);
137
+ if (placeholderId && !_this2.staticPlaceholders.has(placeholderId)) {
138
+ var _window$__SSR_PLACEHO, _this2$intersectionOb;
139
+ var width = -1;
140
+ var height = -1;
141
+ var x = -1;
142
+ var y = -1;
143
+
144
+ // Use SSR dimensions from window global if available
145
+ var boundingClientRect = (_window$__SSR_PLACEHO = window.__SSR_PLACEHOLDERS_DIMENSIONS__) === null || _window$__SSR_PLACEHO === void 0 ? void 0 : _window$__SSR_PLACEHO[placeholderId];
146
+ if (boundingClientRect) {
147
+ width = boundingClientRect.width;
148
+ height = boundingClientRect.height;
149
+ x = boundingClientRect.x;
150
+ y = boundingClientRect.y;
151
+ } else {
152
+ // Fallback to current bounding rect if SSR dimensions not available
153
+ var rect = el.getBoundingClientRect();
154
+ width = rect.width;
155
+ height = rect.height;
156
+ x = rect.x;
157
+ y = rect.y;
158
+ }
159
+ _this2.staticPlaceholders.set(placeholderId, {
160
+ width: width,
161
+ height: height,
162
+ x: x,
163
+ y: y
164
+ });
165
+ (_this2$intersectionOb = _this2.intersectionObserver) === null || _this2$intersectionOb === void 0 || _this2$intersectionOb.observe(el);
166
+ }
167
+ });
168
+ }
169
+
170
+ /**
171
+ * Added this method to be utilised for testing purposes.
172
+ * In production it collection placeholder should only happens on constructor
173
+ */
174
+ }, {
175
+ key: "collectExistingPlaceholders",
176
+ value: function collectExistingPlaceholders() {
177
+ if (!window.document) {
178
+ return;
179
+ }
180
+ try {
181
+ // Collect placeholders using SSR dimensions or fallback to live dimensions
182
+ this.collectPlaceholdersInternal();
183
+ } catch (e) {
184
+ // Silently fail if there are any issues
185
+ } finally {
186
+ delete window.__SSR_PLACEHOLDERS_DIMENSIONS__;
187
+ }
188
+ }
153
189
  }, {
154
190
  key: "isPlaceholder",
155
191
  value: function isPlaceholder(element) {
@@ -186,44 +222,44 @@ var SSRPlaceholderHandlers = exports.SSRPlaceholderHandlers = /*#__PURE__*/funct
186
222
  }, {
187
223
  key: "checkIfExistedAndSizeMatching",
188
224
  value: function checkIfExistedAndSizeMatching(el) {
189
- var _this2 = this;
225
+ var _this3 = this;
190
226
  el = this.findNearestPlaceholderContainerIfIgnored(el);
191
227
  var id = this.getPlaceholderId(el);
192
228
  return new Promise(function (resolve) {
193
- if (!_this2.staticPlaceholders.has(id)) {
229
+ if (!_this3.staticPlaceholders.has(id)) {
194
230
  resolve(false);
195
231
  return;
196
232
  } else {
197
- var _this2$intersectionOb;
198
- _this2.callbacks.set(id, resolve);
199
- (_this2$intersectionOb = _this2.intersectionObserver) === null || _this2$intersectionOb === void 0 || _this2$intersectionOb.observe(el);
233
+ var _this3$intersectionOb;
234
+ _this3.callbacks.set(id, resolve);
235
+ (_this3$intersectionOb = _this3.intersectionObserver) === null || _this3$intersectionOb === void 0 || _this3$intersectionOb.observe(el);
200
236
  }
201
237
  });
202
238
  }
203
239
  }, {
204
240
  key: "getSize",
205
241
  value: function getSize(el) {
206
- var _this3 = this;
242
+ var _this4 = this;
207
243
  return new Promise(function (resolve) {
208
- var _this3$intersectionOb;
209
- _this3.getSizeCallbacks.set(_this3.getPlaceholderId(el), resolve);
210
- (_this3$intersectionOb = _this3.intersectionObserver) === null || _this3$intersectionOb === void 0 || _this3$intersectionOb.observe(el);
244
+ var _this4$intersectionOb;
245
+ _this4.getSizeCallbacks.set(_this4.getPlaceholderId(el), resolve);
246
+ (_this4$intersectionOb = _this4.intersectionObserver) === null || _this4$intersectionOb === void 0 || _this4$intersectionOb.observe(el);
211
247
  });
212
248
  }
213
249
  }, {
214
250
  key: "validateReactComponentMatchToPlaceholder",
215
251
  value: function validateReactComponentMatchToPlaceholder(el) {
216
- var _this4 = this;
252
+ var _this5 = this;
217
253
  el = this.findNearestPlaceholderContainerIfIgnored(el);
218
254
  var id = this.getPlaceholderReplacementId(el);
219
255
  return new Promise(function (resolve) {
220
- if (!_this4.staticPlaceholders.has(id)) {
256
+ if (!_this5.staticPlaceholders.has(id)) {
221
257
  resolve(false);
222
258
  return;
223
259
  } else {
224
- var _this4$intersectionOb;
225
- _this4.reactValidateCallbacks.set(id, resolve);
226
- (_this4$intersectionOb = _this4.intersectionObserver) === null || _this4$intersectionOb === void 0 || _this4$intersectionOb.observe(el);
260
+ var _this5$intersectionOb;
261
+ _this5.reactValidateCallbacks.set(id, resolve);
262
+ (_this5$intersectionOb = _this5.intersectionObserver) === null || _this5$intersectionOb === void 0 || _this5$intersectionOb.observe(el);
227
263
  }
228
264
  });
229
265
  }