@adobe/spacecat-shared-rum-api-client 2.18.9 → 2.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # [@adobe/spacecat-shared-rum-api-client-v2.19.1](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-rum-api-client-v2.19.0...@adobe/spacecat-shared-rum-api-client-v2.19.1) (2025-01-31)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **deps:** update dependency @adobe/rum-distiller to v1.16.2 ([#568](https://github.com/adobe/spacecat-shared/issues/568)) ([bfaa326](https://github.com/adobe/spacecat-shared/commit/bfaa3266e5760a031f3234b1bd60c95844cf17b6)), closes [#8203](https://github.com/adobe/spacecat-shared/issues/8203)
7
+
8
+ # [@adobe/spacecat-shared-rum-api-client-v2.19.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-rum-api-client-v2.18.9...@adobe/spacecat-shared-rum-api-client-v2.19.0) (2025-01-30)
9
+
10
+
11
+ ### Features
12
+
13
+ * introduce navigation and traffic acquisition data in form audit ([#544](https://github.com/adobe/spacecat-shared/issues/544)) ([550f917](https://github.com/adobe/spacecat-shared/commit/550f9174b21c346938a353feef347d160e194e70))
14
+
1
15
  # [@adobe/spacecat-shared-rum-api-client-v2.18.9](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-rum-api-client-v2.18.8...@adobe/spacecat-shared-rum-api-client-v2.18.9) (2025-01-30)
2
16
 
3
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/spacecat-shared-rum-api-client",
3
- "version": "2.18.9",
3
+ "version": "2.19.1",
4
4
  "description": "Shared modules of the Spacecat Services - Rum API client",
5
5
  "type": "module",
6
6
  "engines": {
@@ -39,7 +39,7 @@
39
39
  "@adobe/helix-shared-wrap": "2.0.2",
40
40
  "@adobe/helix-universal": "5.0.8",
41
41
  "@adobe/spacecat-shared-utils": "1.26.4",
42
- "@adobe/rum-distiller": "1.16.1",
42
+ "@adobe/rum-distiller": "1.16.2",
43
43
  "aws4": "1.13.2",
44
44
  "urijs": "1.19.11"
45
45
  },
@@ -11,6 +11,7 @@
11
11
  */
12
12
 
13
13
  import { DataChunks } from '@adobe/rum-distiller';
14
+ import trafficAcquisition from './traffic-acquisition.js';
14
15
  import { generateKey, DELIMITER, loadBundles } from '../utils.js';
15
16
 
16
17
  const FORM_SOURCE = ['.form', '.marketo', '.marketo-form'];
@@ -24,6 +25,7 @@ function initializeResult(url) {
24
25
  formengagement: {},
25
26
  formbuttonclick: {},
26
27
  pageview: {},
28
+ forminternalnavigation: [],
27
29
  };
28
30
  }
29
31
 
@@ -48,6 +50,57 @@ const metricFns = {
48
50
  },
49
51
  };
50
52
 
53
+ function populateFormsInternalNavigation(bundles, formVitals) {
54
+ const dataChunks = new DataChunks();
55
+ loadBundles(bundles, dataChunks);
56
+ dataChunks.filter = { checkpoint: ['navigate'] };
57
+ dataChunks.filtered.forEach((bundle) => {
58
+ const forminternalnavigation = bundle.events.find((e) => e.checkpoint === 'navigate');
59
+ if (forminternalnavigation && formVitals[bundle.url]
60
+ && !formVitals[bundle.url].forminternalnavigation
61
+ .some((e) => e.url === forminternalnavigation.source)) {
62
+ formVitals[bundle.url].forminternalnavigation.push({
63
+ url: forminternalnavigation.source,
64
+ pageview: formVitals[forminternalnavigation.source]?.pageview || null,
65
+ });
66
+ }
67
+ });
68
+ }
69
+
70
+ function findFormCTAForInternalNavigation(bundles, formVitals) {
71
+ formVitals.forEach((item) => {
72
+ const { url, forminternalnavigation } = item;
73
+ if (forminternalnavigation && Array.isArray(forminternalnavigation)) {
74
+ forminternalnavigation.forEach((nav) => {
75
+ if (nav.url) {
76
+ let totalClickOnPage = 0;
77
+ const CTAs = new Map();
78
+ const clickCheckpointBundles = bundles.filter((bundle) => bundle.url === nav.url && bundle.events.find((e) => e.checkpoint === 'click'));
79
+ clickCheckpointBundles.forEach((bundle) => {
80
+ totalClickOnPage += bundle.weight;
81
+ const clickCheckpoint = bundle.events.find((e) => e.checkpoint === 'click' && e.target === url);
82
+
83
+ if (clickCheckpoint) {
84
+ const { source } = clickCheckpoint;
85
+ // Retrieves the existing CTA object if it exists; otherwise,
86
+ // initializes a new one with default values.
87
+ const existingCTA = CTAs.get(source) || { source, clicks: 0 };
88
+ existingCTA.clicks += bundle.weight;
89
+ CTAs.set(source, existingCTA);
90
+ }
91
+ });
92
+
93
+ // Convert CTAs Map to an array and store it in the nav object
94
+ // eslint-disable-next-line no-param-reassign
95
+ nav.CTAs = Array.from(CTAs.values());
96
+ // eslint-disable-next-line no-param-reassign
97
+ nav.totalClicksOnPage = totalClickOnPage;
98
+ }
99
+ });
100
+ }
101
+ });
102
+ }
103
+
51
104
  function containsFormVitals(row) {
52
105
  return METRICS.some((metric) => Object.keys(row[metric]).length > 0);
53
106
  }
@@ -62,12 +115,19 @@ function handler(bundles) {
62
115
  // counts metrics per each group
63
116
  METRICS.forEach((metric) => dataChunks.addSeries(metric, metricFns[metric]));
64
117
 
118
+ // traffic acquisition data per url
119
+ const trafficByUrl = trafficAcquisition.handler(bundles);
120
+ const trafficByUrlMap = Object.fromEntries(
121
+ trafficByUrl.map(({ url, ...item }) => [url, item]),
122
+ );
123
+
65
124
  // aggregates metrics per group (url and user agent)
66
125
  const formVitals = dataChunks.facets.urlUserAgents.reduce((acc, { value, metrics, weight }) => {
67
126
  const [url, userAgent] = value.split(DELIMITER);
68
127
 
69
128
  acc[url] = acc[url] || initializeResult(url);
70
129
  acc[url].pageview[userAgent] = weight;
130
+ acc[url].trafficacquisition = trafficByUrlMap[url];
71
131
 
72
132
  METRICS.filter((metric) => metrics[metric].sum) // filter out user-agents with no form vitals
73
133
  .forEach((metric) => {
@@ -77,11 +137,15 @@ function handler(bundles) {
77
137
  return acc;
78
138
  }, {});
79
139
 
80
- return Object.values(formVitals)
81
- .filter(containsFormVitals); // filter out pages with no form vitals
140
+ // populate internal navigation data
141
+ populateFormsInternalNavigation(bundles, formVitals);
142
+ // filter out pages with no form vitals
143
+ const filteredFormVitals = Object.values(formVitals).filter(containsFormVitals);
144
+ findFormCTAForInternalNavigation(bundles, filteredFormVitals);
145
+ return filteredFormVitals;
82
146
  }
83
147
 
84
148
  export default {
85
149
  handler,
86
- checkpoints: ['viewblock', 'formsubmit', 'click'],
150
+ checkpoints: ['viewblock', 'formsubmit', 'click', 'navigate'],
87
151
  };