@adobe/spacecat-shared-rum-api-client 2.12.2 → 2.12.3

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,10 @@
1
+ # [@adobe/spacecat-shared-rum-api-client-v2.12.3](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-rum-api-client-v2.12.2...@adobe/spacecat-shared-rum-api-client-v2.12.3) (2024-11-26)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **rum-api-client:** migrate form vitals to rum-distiller ([#451](https://github.com/adobe/spacecat-shared/issues/451)) ([7509143](https://github.com/adobe/spacecat-shared/commit/7509143f9b9a9aa1971ebdcd55aa3b6d221f1812))
7
+
1
8
  # [@adobe/spacecat-shared-rum-api-client-v2.12.2](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-rum-api-client-v2.12.1...@adobe/spacecat-shared-rum-api-client-v2.12.2) (2024-11-25)
2
9
 
3
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/spacecat-shared-rum-api-client",
3
- "version": "2.12.2",
3
+ "version": "2.12.3",
4
4
  "description": "Shared modules of the Spacecat Services - Rum API client",
5
5
  "type": "module",
6
6
  "engines": {
@@ -10,82 +10,68 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
 
13
+ import { DataChunks } from '@adobe/rum-distiller';
14
+ import { generateKey, DELIMITER, loadBundles } from '../utils.js';
15
+
13
16
  const FORM_SOURCE = ['.form', '.marketo', '.marketo-form'];
14
- const BOT = 'bot';
15
- const CHECKPOINT_MAPPING = { formsubmit: 'formsubmit', viewblock: 'formview', click: 'formengagement' };
17
+ const METRICS = ['formview', 'formengagement', 'formsubmit'];
16
18
 
17
- function initializeResult(url, pageViews) {
19
+ function initializeResult(url) {
18
20
  return {
19
21
  url,
20
22
  formsubmit: {},
21
23
  formview: {},
22
24
  formengagement: {},
23
- pageview: pageViews[url],
25
+ pageview: {},
24
26
  };
25
27
  }
26
28
 
27
- function collectFormVitals(bundles, pageViews) {
28
- const results = {};
29
+ const metricFns = {
30
+ formview: (bundle) => {
31
+ const formView = bundle.events.find((e) => e.checkpoint === 'viewblock' && FORM_SOURCE.includes(e.source));
32
+ return formView ? bundle.weight : 0;
33
+ },
34
+ formengagement: (bundle) => {
35
+ const formClick = bundle.events.find((e) => e.checkpoint === 'click' && e.source && /\bform\b/.test(e.source.toLowerCase()));
36
+ return formClick ? bundle.weight : 0;
37
+ },
38
+ formsubmit: (bundle) => {
39
+ const formSubmit = bundle.events.find((e) => e.checkpoint === 'formsubmit');
40
+ return formSubmit ? bundle.weight : 0;
41
+ },
42
+ };
29
43
 
30
- // Helper functions to identify event types
31
- const isFormViewEvent = ({ checkpoint, source }) => checkpoint === 'viewblock' && FORM_SOURCE.includes(source);
32
- const isFormClickEvent = ({ checkpoint, source }) => checkpoint === 'click' && source && /\bform\b/.test(source.toLowerCase());
33
- const isFormSubmitEvent = ({ checkpoint }) => checkpoint === 'formsubmit';
44
+ function containsFormVitals(row) {
45
+ return METRICS.some((metric) => Object.keys(row[metric]).length > 0);
46
+ }
34
47
 
35
- for (const bundle of bundles) {
36
- const {
37
- url, userAgent, weight, events,
38
- } = bundle;
48
+ function handler(bundles) {
49
+ const dataChunks = new DataChunks();
50
+ loadBundles(bundles, dataChunks);
39
51
 
40
- if (userAgent && !userAgent.startsWith(BOT)) {
41
- // Track if each condition has been processed for this event
42
- const processedCheckpoints = {
43
- formsubmit: false,
44
- click: false,
45
- };
52
+ // groups by url and user agent
53
+ dataChunks.addFacet('urlUserAgents', (bundle) => generateKey(bundle.url, bundle.userAgent));
46
54
 
47
- // Process each event within the bundle
48
- for (const event of events) {
49
- const { checkpoint, source } = event;
55
+ // counts metrics per each group
56
+ METRICS.forEach((metric) => dataChunks.addSeries(metric, metricFns[metric]));
50
57
 
51
- // Only process the checkpoint once per event
52
- if (!processedCheckpoints[checkpoint]) {
53
- if (isFormViewEvent({ checkpoint, source })
54
- || isFormSubmitEvent({ checkpoint })
55
- || isFormClickEvent({ checkpoint, source })) {
56
- results[url] = results[url] || initializeResult(url, pageViews);
57
- const key = CHECKPOINT_MAPPING[checkpoint];
58
- const res = results[url];
59
- res[key] = {
60
- ...res[key],
61
- [userAgent]: (res[key][userAgent] || 0) + weight,
62
- };
63
- // Mark this checkpoint as processed - click and formsubmit as processed
64
- if (checkpoint === 'click' || checkpoint === 'formsubmit') {
65
- processedCheckpoints[checkpoint] = true;
66
- }
67
- }
68
- }
69
- }
70
- }
71
- }
72
- return results;
73
- }
58
+ // aggregates metrics per group (url and user agent)
59
+ const formVitals = dataChunks.facets.urlUserAgents.reduce((acc, { value, metrics, weight }) => {
60
+ const [url, userAgent] = value.split(DELIMITER);
61
+
62
+ acc[url] = acc[url] || initializeResult(url);
63
+ acc[url].pageview[userAgent] = weight;
64
+
65
+ METRICS.filter((metric) => metrics[metric].sum) // filter out user-agents with no form vitals
66
+ .forEach((metric) => {
67
+ acc[url][metric][userAgent] = metrics[metric].sum;
68
+ });
74
69
 
75
- function pageviewsByUrlAndUserAgent(bundles) {
76
- return bundles.reduce((acc, cur) => {
77
- const { userAgent } = cur;
78
- if (!userAgent || userAgent.startsWith(BOT)) return acc;
79
- acc[cur.url] = acc[cur.url] || {};
80
- acc[cur.url][userAgent] = (acc[cur.url][userAgent] || 0) + cur.weight;
81
70
  return acc;
82
71
  }, {});
83
- }
84
72
 
85
- function handler(bundles) {
86
- const pageViews = pageviewsByUrlAndUserAgent(bundles);
87
- const formVitals = collectFormVitals(bundles, pageViews);
88
- return Object.values(formVitals);
73
+ return Object.values(formVitals)
74
+ .filter(containsFormVitals); // filter out pages with no form vitals
89
75
  }
90
76
 
91
77
  export default {