@adobe/spacecat-shared-utils 1.28.4 → 1.29.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 +1 -1
- package/src/formcalc.js +98 -0
- package/src/index.d.ts +14 -5
- package/src/index.js +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [@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
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* add utility api for forms metrics ([#566](https://github.com/adobe/spacecat-shared/issues/566)) ([a7365b6](https://github.com/adobe/spacecat-shared/commit/a7365b6eaabf6178a7febd2f25a4083e60d0156b))
|
|
7
|
+
|
|
1
8
|
# [@adobe/spacecat-shared-utils-v1.28.4](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-utils-v1.28.3...@adobe/spacecat-shared-utils-v1.28.4) (2025-02-03)
|
|
2
9
|
|
|
3
10
|
|
package/package.json
CHANGED
package/src/formcalc.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Adobe. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const DAILY_PAGEVIEW_THRESHOLD = 200;
|
|
14
|
+
const CR_THRESHOLD_RATIO = 0.2;
|
|
15
|
+
const MOBILE = 'mobile';
|
|
16
|
+
const DESKTOP = 'desktop';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Aggregates the form vitals by device type.
|
|
20
|
+
*
|
|
21
|
+
* @param {*} formVitalsCollection - form vitals collection
|
|
22
|
+
* @returns {object} - aggregated form vitals by device type
|
|
23
|
+
*/
|
|
24
|
+
function aggregateFormVitalsByDevice(formVitalsCollection) {
|
|
25
|
+
const resultMap = new Map();
|
|
26
|
+
|
|
27
|
+
formVitalsCollection.forEach((item) => {
|
|
28
|
+
const {
|
|
29
|
+
url, formview = {}, formengagement = {}, pageview = {}, formsubmit = {},
|
|
30
|
+
} = item;
|
|
31
|
+
|
|
32
|
+
const totals = {
|
|
33
|
+
formview: { total: 0, desktop: 0, mobile: 0 },
|
|
34
|
+
formengagement: { total: 0, desktop: 0, mobile: 0 },
|
|
35
|
+
pageview: { total: 0, desktop: 0, mobile: 0 },
|
|
36
|
+
formsubmit: { total: 0, desktop: 0, mobile: 0 },
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const calculateSums = (metric, initialTarget) => {
|
|
40
|
+
const updatedTarget = { ...initialTarget }; // Create a new object to store the updated totals
|
|
41
|
+
Object.entries(metric).forEach(([key, value]) => {
|
|
42
|
+
updatedTarget.total += value;
|
|
43
|
+
if (key.startsWith(DESKTOP)) {
|
|
44
|
+
updatedTarget.desktop += value;
|
|
45
|
+
} else if (key.startsWith(MOBILE)) {
|
|
46
|
+
updatedTarget.mobile += value;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
return updatedTarget; // Return the updated target
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
totals.formview = calculateSums(formview, totals.formview);
|
|
53
|
+
totals.formengagement = calculateSums(formengagement, totals.formengagement);
|
|
54
|
+
totals.pageview = calculateSums(pageview, totals.pageview);
|
|
55
|
+
totals.formsubmit = calculateSums(formsubmit, totals.formsubmit);
|
|
56
|
+
|
|
57
|
+
resultMap.set(url, totals);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
return resultMap;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function hasHighPageViews(interval, pageViews) {
|
|
64
|
+
return pageViews > DAILY_PAGEVIEW_THRESHOLD * interval;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function hasLowerConversionRate(formSubmit, formViews) {
|
|
68
|
+
return formSubmit / formViews < CR_THRESHOLD_RATIO;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Returns the form urls with high form views and low conversion rate
|
|
73
|
+
*
|
|
74
|
+
* @param {*} formVitalsCollection - form vitals collection
|
|
75
|
+
* @returns {Array} - urls with high form views and low conversion rate
|
|
76
|
+
*/
|
|
77
|
+
export function getHighFormViewsLowConversionMetrics(formVitalsCollection, interval) {
|
|
78
|
+
const resultMap = aggregateFormVitalsByDevice(formVitalsCollection);
|
|
79
|
+
const urls = [];
|
|
80
|
+
resultMap.forEach((metrics, url) => {
|
|
81
|
+
const pageViews = metrics.pageview.total;
|
|
82
|
+
// Default to pageViews if formViews are not available
|
|
83
|
+
const formViews = metrics.formview.total || pageViews;
|
|
84
|
+
const formEngagement = metrics.formengagement.total;
|
|
85
|
+
const formSubmit = metrics.formsubmit.total || formEngagement;
|
|
86
|
+
|
|
87
|
+
if (hasHighPageViews(interval, pageViews) && hasLowerConversionRate(formSubmit, formViews)) {
|
|
88
|
+
urls.push({
|
|
89
|
+
url,
|
|
90
|
+
pageViews,
|
|
91
|
+
formViews,
|
|
92
|
+
formEngagement,
|
|
93
|
+
formSubmit,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
return urls;
|
|
98
|
+
}
|
package/src/index.d.ts
CHANGED
|
@@ -163,7 +163,16 @@ declare function replacePlaceholders(content: string, placeholders: object): str
|
|
|
163
163
|
* or null if an error occurs.
|
|
164
164
|
*/
|
|
165
165
|
declare function getPrompt(placeholders: object, filename: string, log: object):
|
|
166
|
-
Promise<string|null>;
|
|
166
|
+
Promise<string | null>;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Retrieves the high-form-view-low-form-conversion metrics from the provided array of form vitals.
|
|
170
|
+
* @param {Object[]} formVitals - An array of form vitals.
|
|
171
|
+
* @param {number} interval - The interval in days.
|
|
172
|
+
* @returns {Object[]} - An array of high-form-view-low-form-conversion metrics.
|
|
173
|
+
*/
|
|
174
|
+
declare function getHighFormViewsLowConversionMetrics(formVitals: object[], interval: number):
|
|
175
|
+
object[];
|
|
167
176
|
|
|
168
177
|
/**
|
|
169
178
|
* Retrieves stored metrics from S3.
|
|
@@ -179,7 +188,7 @@ declare function getPrompt(placeholders: object, filename: string, log: object):
|
|
|
179
188
|
* @returns {Promise<any|*[]>} - The stored metrics
|
|
180
189
|
*/
|
|
181
190
|
export function getStoredMetrics(config: object, context: object):
|
|
182
|
-
|
|
191
|
+
Promise<Array<object>>;
|
|
183
192
|
|
|
184
193
|
/**
|
|
185
194
|
* Stores metrics in S3.
|
|
@@ -198,8 +207,8 @@ export function getStoredMetrics(config: object, context: object):
|
|
|
198
207
|
export function storeMetrics(content: object, config: object, context: object): Promise<string>;
|
|
199
208
|
|
|
200
209
|
export function s3Wrapper(fn: (request: object, context: object) => Promise<Response>):
|
|
201
|
-
|
|
210
|
+
(request: object, context: object) => Promise<Response>;
|
|
202
211
|
|
|
203
|
-
export function fetch(url: string|Request, options?: RequestOptions): Promise<Response>;
|
|
212
|
+
export function fetch(url: string | Request, options?: RequestOptions): Promise<Response>;
|
|
204
213
|
|
|
205
|
-
export function tracingFetch(url: string|Request, options?: RequestOptions): Promise<Response>;
|
|
214
|
+
export function tracingFetch(url: string | Request, options?: RequestOptions): Promise<Response>;
|
package/src/index.js
CHANGED