@adobe/spacecat-shared-rum-api-client 2.22.6 → 2.23.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 +14 -0
- package/package.json +1 -1
- package/src/functions/form-vitals.js +73 -51
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [@adobe/spacecat-shared-rum-api-client-v2.23.1](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-rum-api-client-v2.23.0...@adobe/spacecat-shared-rum-api-client-v2.23.1) (2025-04-25)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* eliminating unnecessary data from forms vitals ([#704](https://github.com/adobe/spacecat-shared/issues/704)) ([29be01e](https://github.com/adobe/spacecat-shared/commit/29be01e5d77d41b728a013a4b5532d06a08f7b2c))
|
|
7
|
+
|
|
8
|
+
# [@adobe/spacecat-shared-rum-api-client-v2.23.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-rum-api-client-v2.22.6...@adobe/spacecat-shared-rum-api-client-v2.23.0) (2025-04-16)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* formsource wise segregation of audit result ([#692](https://github.com/adobe/spacecat-shared/issues/692)) ([0f4f503](https://github.com/adobe/spacecat-shared/commit/0f4f503facbd81538a0d445a462735766e7bfffa))
|
|
14
|
+
|
|
1
15
|
# [@adobe/spacecat-shared-rum-api-client-v2.22.6](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-rum-api-client-v2.22.5...@adobe/spacecat-shared-rum-api-client-v2.22.6) (2025-04-15)
|
|
2
16
|
|
|
3
17
|
|
package/package.json
CHANGED
|
@@ -11,11 +11,9 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { DataChunks } from '@adobe/rum-distiller';
|
|
14
|
-
import trafficAcquisition from './traffic-acquisition.js';
|
|
15
14
|
import { generateKey, DELIMITER, loadBundles } from '../utils.js';
|
|
16
15
|
|
|
17
|
-
const
|
|
18
|
-
const METRICS = ['formview', 'formengagement', 'formsubmit', 'formbuttonclick'];
|
|
16
|
+
const METRICS = ['formview', 'formengagement', 'formsubmit'];
|
|
19
17
|
const CHECKPOINTS = ['viewblock', 'click', 'fill', 'formsubmit', 'navigate'];
|
|
20
18
|
const KEYWORDS_TO_FILTER = ['search'];
|
|
21
19
|
|
|
@@ -25,7 +23,6 @@ function initializeResult(url) {
|
|
|
25
23
|
formsubmit: {},
|
|
26
24
|
formview: {},
|
|
27
25
|
formengagement: {},
|
|
28
|
-
formbuttonclick: {},
|
|
29
26
|
pageview: {},
|
|
30
27
|
forminternalnavigation: [],
|
|
31
28
|
};
|
|
@@ -51,39 +48,48 @@ function filterEvents(bundles) {
|
|
|
51
48
|
}));
|
|
52
49
|
}
|
|
53
50
|
|
|
51
|
+
function isFormSource(source, eventSource) {
|
|
52
|
+
const excludeSrc = ['form.', 'form#'];
|
|
53
|
+
if (source === 'unknown') {
|
|
54
|
+
return /\bform\b/.test(eventSource?.toLowerCase()) && !excludeSrc.some((exclude) => eventSource?.includes(exclude));
|
|
55
|
+
} else {
|
|
56
|
+
return eventSource?.includes(source);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
54
60
|
const metricFns = {
|
|
55
|
-
formview: (bundle) => {
|
|
56
|
-
const formView = bundle.events.find((e) => e.checkpoint === 'viewblock' &&
|
|
61
|
+
formview: (source) => (bundle) => {
|
|
62
|
+
const formView = bundle.events.find((e) => e.checkpoint === 'viewblock' && isFormSource(source, e.source));
|
|
57
63
|
return formView ? bundle.weight : 0;
|
|
58
64
|
},
|
|
59
|
-
formengagement: (bundle) => {
|
|
60
|
-
const formClick = bundle.events.find((e) => e.checkpoint === 'click'
|
|
65
|
+
formengagement: (source) => (bundle) => {
|
|
66
|
+
const formClick = bundle.events.find((e) => (e.checkpoint === 'click' || e.checkpoint === 'fill') && isFormSource(source, e.source));
|
|
61
67
|
return formClick ? bundle.weight : 0;
|
|
62
68
|
},
|
|
63
|
-
formsubmit: (bundle) => {
|
|
64
|
-
const formSubmit = bundle.events.find((e) => e.checkpoint === 'formsubmit');
|
|
69
|
+
formsubmit: (source) => (bundle) => {
|
|
70
|
+
const formSubmit = bundle.events.find((e) => e.checkpoint === 'formsubmit' && isFormSource(source, e.source));
|
|
65
71
|
return formSubmit ? bundle.weight : 0;
|
|
66
72
|
},
|
|
67
|
-
formbuttonclick: (bundle) => {
|
|
68
|
-
const formButtonClick = bundle.events.find((e) => e.checkpoint === 'click' && e.source
|
|
69
|
-
&& /\bform\b/.test(e.source.toLowerCase())
|
|
70
|
-
&& /\bbutton\b/.test(e.source.toLowerCase()));
|
|
71
|
-
return formButtonClick ? bundle.weight : 0;
|
|
72
|
-
},
|
|
73
73
|
};
|
|
74
74
|
|
|
75
|
+
function findByUrl(formVitals, url) {
|
|
76
|
+
return Object.values(formVitals).find((item) => item.url === url);
|
|
77
|
+
}
|
|
78
|
+
|
|
75
79
|
function populateFormsInternalNavigation(bundles, formVitals) {
|
|
76
80
|
const dataChunks = new DataChunks();
|
|
77
81
|
loadBundles(bundles, dataChunks);
|
|
78
82
|
dataChunks.filter = { checkpoint: ['navigate'] };
|
|
79
83
|
dataChunks.filtered.forEach((bundle) => {
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
const formInternalNav = bundle.events.find((e) => e.checkpoint === 'navigate');
|
|
85
|
+
const formVital = findByUrl(formVitals, bundle.url);
|
|
86
|
+
if (formInternalNav && formVital
|
|
87
|
+
&& !formVital.forminternalnavigation
|
|
88
|
+
.some((e) => e.url === formInternalNav.source)) {
|
|
89
|
+
const fv = findByUrl(formVitals, formInternalNav.source);
|
|
90
|
+
formVital.forminternalnavigation.push({
|
|
91
|
+
url: formInternalNav.source,
|
|
92
|
+
pageview: fv?.pageview,
|
|
87
93
|
});
|
|
88
94
|
}
|
|
89
95
|
});
|
|
@@ -134,34 +140,50 @@ function handler(bundles) {
|
|
|
134
140
|
const dataChunks = new DataChunks();
|
|
135
141
|
loadBundles(bundlesWithFilteredEvents, dataChunks);
|
|
136
142
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
143
|
+
const formViewdataChunks = new DataChunks();
|
|
144
|
+
loadBundles(bundlesWithFilteredEvents, formViewdataChunks);
|
|
145
|
+
const formSourceMap = {};
|
|
146
|
+
const globalFormSourceSet = new Set();
|
|
147
|
+
formViewdataChunks.filter = { checkpoint: ['viewblock'] };
|
|
148
|
+
formViewdataChunks.filtered.forEach(({ url, events }) => {
|
|
149
|
+
formSourceMap[url] = formSourceMap[url] || new Set();
|
|
150
|
+
events.forEach(({ checkpoint, source }) => {
|
|
151
|
+
if (checkpoint === 'viewblock' && source) {
|
|
152
|
+
formSourceMap[url].add(source);
|
|
153
|
+
globalFormSourceSet.add(source);
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
// traffic acquisition data per url - uncomment this when required
|
|
158
|
+
// const trafficByUrl = trafficAcquisition.handler(bundles);
|
|
159
|
+
// const trafficByUrlMap = Object.fromEntries(
|
|
160
|
+
// trafficByUrl.map(({ url, ...item }) => [url, item]),
|
|
161
|
+
// );
|
|
162
|
+
const formVitals = {};
|
|
163
|
+
|
|
164
|
+
globalFormSourceSet.forEach((source) => {
|
|
165
|
+
// counts metrics per each group
|
|
166
|
+
const match = source.match(/form[#.](\w+)/);
|
|
167
|
+
const formsource = match ? match[1] : 'unknown';
|
|
168
|
+
// groups by url and user agent
|
|
169
|
+
dataChunks.addFacet('urlUserAgents', (bundle) => generateKey(bundle.url, bundle.userAgent));
|
|
170
|
+
METRICS.forEach((metric) => dataChunks.addSeries(metric, metricFns[metric](formsource)));
|
|
171
|
+
// aggregates metrics per group (url and user agent)
|
|
172
|
+
dataChunks.facets.urlUserAgents.reduce((acc, { value, metrics, weight }) => {
|
|
173
|
+
const [url, userAgent] = value.split(DELIMITER);
|
|
174
|
+
const key = formSourceMap[url].has(source) ? generateKey(url, source) : url;
|
|
175
|
+
acc[key] = acc[key] || initializeResult(url);
|
|
176
|
+
acc[key].pageview[userAgent] = acc[key].pageview[userAgent] || weight;
|
|
177
|
+
// Enable traffic acquisition for persistence by uncommenting this line
|
|
178
|
+
// acc[key].trafficacquisition = trafficByUrlMap[url];
|
|
179
|
+
acc[key].formsource = source;
|
|
180
|
+
METRICS.filter((metric) => metrics[metric].sum) // filter out user-agents with no form vitals
|
|
181
|
+
.forEach((metric) => {
|
|
182
|
+
acc[key][metric][userAgent] = metrics[metric].sum;
|
|
183
|
+
});
|
|
184
|
+
return acc;
|
|
185
|
+
}, formVitals);
|
|
186
|
+
});
|
|
165
187
|
// populate internal navigation data
|
|
166
188
|
populateFormsInternalNavigation(bundles, formVitals);
|
|
167
189
|
// filter out pages with no form vitals
|