@adobe/spacecat-shared-utils 1.29.0 → 1.30.0
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 +7 -0
- package/package.json +2 -2
- package/src/formcalc.js +98 -0
- package/src/index.d.ts +16 -0
- package/src/index.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [@adobe/spacecat-shared-utils-v1.30.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-utils-v1.29.0...@adobe/spacecat-shared-utils-v1.30.0) (2025-02-06)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* adding more opportunities utils for forms ([#580](https://github.com/adobe/spacecat-shared/issues/580)) ([4cb7d5d](https://github.com/adobe/spacecat-shared/commit/4cb7d5d94ff887932809416b3cf918fc3b56a58d))
|
|
7
|
+
|
|
1
8
|
# [@adobe/spacecat-shared-utils-v1.29.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-utils-v1.28.4...@adobe/spacecat-shared-utils-v1.29.0) (2025-02-03)
|
|
2
9
|
|
|
3
10
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adobe/spacecat-shared-utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.30.0",
|
|
4
4
|
"description": "Shared modules of the Spacecat Services - utils",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"chai": "5.1.2",
|
|
40
40
|
"chai-as-promised": "8.0.1",
|
|
41
41
|
"husky": "9.1.7",
|
|
42
|
-
"nock": "
|
|
42
|
+
"nock": "14.0.0",
|
|
43
43
|
"sinon": "19.0.2",
|
|
44
44
|
"sinon-chai": "4.0.0"
|
|
45
45
|
},
|
package/src/formcalc.js
CHANGED
|
@@ -68,6 +68,16 @@ function hasLowerConversionRate(formSubmit, formViews) {
|
|
|
68
68
|
return formSubmit / formViews < CR_THRESHOLD_RATIO;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
function hasLowFormViews(pageViews, formViews) {
|
|
72
|
+
return formViews > 0 && (formViews / pageViews) < 0.7;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function hasHighPageViewLowFormCtr(ctaPageViews, ctaClicks, ctaPageTotalClicks, formPageViews) {
|
|
76
|
+
return ctaPageTotalClicks > 0
|
|
77
|
+
&& (ctaClicks / ctaPageTotalClicks) < 0.4
|
|
78
|
+
&& (formPageViews / ctaPageViews) < 0.1;
|
|
79
|
+
}
|
|
80
|
+
|
|
71
81
|
/**
|
|
72
82
|
* Returns the form urls with high form views and low conversion rate
|
|
73
83
|
*
|
|
@@ -96,3 +106,91 @@ export function getHighFormViewsLowConversionMetrics(formVitalsCollection, inter
|
|
|
96
106
|
});
|
|
97
107
|
return urls;
|
|
98
108
|
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Returns the form urls with high page views and low form views
|
|
112
|
+
*
|
|
113
|
+
* @param resultMap
|
|
114
|
+
* @returns {*[]}
|
|
115
|
+
*/
|
|
116
|
+
export function getHighPageViewsLowFormViewsMetrics(formVitalsCollection, interval) {
|
|
117
|
+
const urls = [];
|
|
118
|
+
const resultMap = aggregateFormVitalsByDevice(formVitalsCollection);
|
|
119
|
+
resultMap.forEach((metrics, url) => {
|
|
120
|
+
const { total: pageViews } = metrics.pageview;
|
|
121
|
+
const { total: formViews } = metrics.formview;
|
|
122
|
+
const { total: formEngagement } = metrics.formengagement;
|
|
123
|
+
|
|
124
|
+
if (hasHighPageViews(interval, pageViews) && hasLowFormViews(pageViews, formViews)) {
|
|
125
|
+
urls.push({
|
|
126
|
+
url,
|
|
127
|
+
pageViews,
|
|
128
|
+
formViews,
|
|
129
|
+
formEngagement,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
return urls;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Returns the form urls with high page views containing ctr and low form views
|
|
138
|
+
* @param formVitalsCollection
|
|
139
|
+
* @param formVitalsByDevice
|
|
140
|
+
* @returns {*[]}
|
|
141
|
+
*/
|
|
142
|
+
export function getHighPageViewsLowFormCtrMetrics(formVitalsCollection, interval) {
|
|
143
|
+
const urls = [];
|
|
144
|
+
const formVitalsByDevice = aggregateFormVitalsByDevice(formVitalsCollection);
|
|
145
|
+
formVitalsCollection.forEach((entry) => {
|
|
146
|
+
const { forminternalnavigation, pageview } = entry;
|
|
147
|
+
// Calculate `x`: sum of pageview for the URL with the highest sum
|
|
148
|
+
let x = 0;
|
|
149
|
+
let maxPageviewUrl = null;
|
|
150
|
+
if (forminternalnavigation) {
|
|
151
|
+
forminternalnavigation.forEach((nav) => {
|
|
152
|
+
if (nav.pageview) {
|
|
153
|
+
const pageviewSum = Object.values(nav.pageview).reduce((sum, val) => sum + val, 0);
|
|
154
|
+
if (pageviewSum > x) {
|
|
155
|
+
x = pageviewSum;
|
|
156
|
+
maxPageviewUrl = nav;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Skip entry if no valid maxPageviewUrl is found
|
|
163
|
+
if (!maxPageviewUrl) return;
|
|
164
|
+
|
|
165
|
+
// Calculate `y`: find the CTA with the highest clicks and include the source
|
|
166
|
+
const y = maxPageviewUrl.CTAs.reduce((maxCta, cta) => {
|
|
167
|
+
if (cta.clicks > (maxCta.clicks || 0)) {
|
|
168
|
+
return cta;
|
|
169
|
+
}
|
|
170
|
+
return maxCta;
|
|
171
|
+
}, { clicks: 0, source: '' });
|
|
172
|
+
|
|
173
|
+
// Get `z`: totalClicksOnPage for the matched URL
|
|
174
|
+
const z = maxPageviewUrl.totalClicksOnPage || 0;
|
|
175
|
+
// Calculate `f`: sum of `pageview` for `formengagement`
|
|
176
|
+
const f = Object.values(pageview).reduce((sum, val) => sum + val, 0);
|
|
177
|
+
|
|
178
|
+
// Evaluate conditions and add URL to the result if all are met
|
|
179
|
+
if (hasHighPageViews(interval, x) && hasHighPageViewLowFormCtr(x, y.clicks, z, f)) {
|
|
180
|
+
const deviceData = formVitalsByDevice.get(entry.url);
|
|
181
|
+
if (deviceData != null) {
|
|
182
|
+
urls.push({
|
|
183
|
+
url: entry.url,
|
|
184
|
+
pageViews: deviceData.pageview.total,
|
|
185
|
+
formViews: deviceData.formview.total,
|
|
186
|
+
formEngagement: deviceData.formengagement.total,
|
|
187
|
+
CTA: {
|
|
188
|
+
url: maxPageviewUrl.url,
|
|
189
|
+
source: y.source,
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
return urls;
|
|
196
|
+
}
|
package/src/index.d.ts
CHANGED
|
@@ -174,6 +174,22 @@ declare function getPrompt(placeholders: object, filename: string, log: object):
|
|
|
174
174
|
declare function getHighFormViewsLowConversionMetrics(formVitals: object[], interval: number):
|
|
175
175
|
object[];
|
|
176
176
|
|
|
177
|
+
/**
|
|
178
|
+
* Retrieves the high-page-view-low-form-view metrics from the provided array of form vitals.
|
|
179
|
+
* @param {Object[]} formVitals - An array of form vitals.
|
|
180
|
+
* @returns {Object[]} - An array of high-page-view-low-form-view metrics.
|
|
181
|
+
*/
|
|
182
|
+
declare function getHighPageViewsLowFormViewsMetrics(formVitals: object[], interval: number):
|
|
183
|
+
object[];
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Retrieves the high-page-view-low-form-ctr metrics from the provided array of form vitals.
|
|
187
|
+
* @param {Object[]} formVitals - An array of form vitals.
|
|
188
|
+
* @returns {Object[]} - An array of high-page-view-low-form-ctr metrics.
|
|
189
|
+
*/
|
|
190
|
+
declare function getHighPageViewsLowFormCtrMetrics(formVitals: object[], interval: number):
|
|
191
|
+
object[];
|
|
192
|
+
|
|
177
193
|
/**
|
|
178
194
|
* Retrieves stored metrics from S3.
|
|
179
195
|
* @param config - Configuration object
|
package/src/index.js
CHANGED
|
@@ -61,4 +61,4 @@ export { s3Wrapper } from './s3.js';
|
|
|
61
61
|
|
|
62
62
|
export { fetch } from './adobe-fetch.js';
|
|
63
63
|
export { tracingFetch } from './tracing-fetch.js';
|
|
64
|
-
export { getHighFormViewsLowConversionMetrics } from './formcalc.js';
|
|
64
|
+
export { getHighFormViewsLowConversionMetrics, getHighPageViewsLowFormViewsMetrics, getHighPageViewsLowFormCtrMetrics } from './formcalc.js';
|