@adobe/spacecat-shared-rum-api-client 2.5.1 → 2.5.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,17 @@
1
+ # [@adobe/spacecat-shared-rum-api-client-v2.5.3](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-rum-api-client-v2.5.2...@adobe/spacecat-shared-rum-api-client-v2.5.3) (2024-07-31)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * work-around for bamboos custom exp engine ([#308](https://github.com/adobe/spacecat-shared/issues/308)) ([56b3b62](https://github.com/adobe/spacecat-shared/commit/56b3b62ea4c330d3d1003ab82e8c90ae890914f8))
7
+
8
+ # [@adobe/spacecat-shared-rum-api-client-v2.5.2](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-rum-api-client-v2.5.1...@adobe/spacecat-shared-rum-api-client-v2.5.2) (2024-07-30)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * updating inferred start and end dates to reflect old and latest from RUM bundles ([#303](https://github.com/adobe/spacecat-shared/issues/303)) ([92852bd](https://github.com/adobe/spacecat-shared/commit/92852bd5e5f033fbc568c70cc7d6f5d5eda50deb))
14
+
1
15
  # [@adobe/spacecat-shared-rum-api-client-v2.5.1](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-rum-api-client-v2.5.0...@adobe/spacecat-shared-rum-api-client-v2.5.1) (2024-07-27)
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.5.1",
3
+ "version": "2.5.3",
4
4
  "description": "Shared modules of the Spacecat Services - Rum API client",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -55,31 +55,20 @@ function updateInferredStartAndEndDate(experimentObject, time) {
55
55
  const bundleDate = new Date(bundleTime);
56
56
  bundleDate.setHours(0, 0, 0, 0);
57
57
  if (!experimentObject.inferredStartDate && !experimentObject.inferredEndDate) {
58
- // adding the inferredStartDate and inferredEndDate properties for the first time
59
58
  // eslint-disable-next-line no-param-reassign
60
59
  experimentObject.inferredStartDate = time;
61
- // check if bundleTime is before yesterday
62
- if (bundleDate < yesterday) {
63
- // RUM data is delayed by a day, so if we don't have
64
- // any RUM data for yesterday, so we can infer the endDate
65
- // eslint-disable-next-line no-param-reassign
66
- experimentObject.inferredEndDate = time;
67
- } else {
68
- // eslint-disable-next-line no-param-reassign
69
- experimentObject.inferredEndDate = null;
70
- }
60
+ // eslint-disable-next-line no-param-reassign
61
+ experimentObject.inferredEndDate = time;
71
62
  } else {
72
63
  const inferredStartDateObj = new Date(experimentObject.inferredStartDate);
64
+ const inferredEndDateObj = new Date(experimentObject.inferredEndDate);
73
65
  if (bundleTime < inferredStartDateObj) {
74
66
  // eslint-disable-next-line no-param-reassign
75
67
  experimentObject.inferredStartDate = time;
76
68
  }
77
- if (bundleDate < yesterday) {
78
- if (!experimentObject.inferredEndDate
79
- || (bundleTime > new Date(experimentObject.inferredEndDate))) {
80
- // eslint-disable-next-line no-param-reassign
81
- experimentObject.inferredEndDate = time;
82
- }
69
+ if (bundleTime > inferredEndDateObj) {
70
+ // eslint-disable-next-line no-param-reassign
71
+ experimentObject.inferredEndDate = time;
83
72
  }
84
73
  }
85
74
  }
@@ -11,6 +11,7 @@
11
11
  */
12
12
 
13
13
  import { classifyTrafficSource } from '../common/traffic.js';
14
+ import { fetch } from '../utils.js';
14
15
 
15
16
  function extractHints(bundle) {
16
17
  const findEvent = (checkpoint, source = '') => bundle.events.find((e) => e.checkpoint === checkpoint && (!source || e.source === source)) || {};
@@ -47,8 +48,81 @@ function transformFormat(trafficSources) {
47
48
  }));
48
49
  }
49
50
 
50
- function handler(bundles) {
51
- const trafficSources = bundles
51
+ /* c8 ignore start */
52
+ /*
53
+ * throw-away code for a single customer who customized the experimentation engine
54
+ * this code will be removed once they start using the default exp engine
55
+ *
56
+ * this function fetches experiment manifests, then merges variants data into controls data
57
+ *
58
+ * ie:
59
+ *
60
+ * if the customer runs for an experiment where variants are as following:
61
+ * control: /
62
+ * challenger-1: /a1/
63
+ * challenger-2: /a2/
64
+ *
65
+ * then data for the `/a1/` and `/a2` are counted towards `/`'s data
66
+ */
67
+ async function mergeBundlesWithSameId(bundles) {
68
+ if (!bundles[0]?.url.includes('bamboohr.com')) return bundles;
69
+ const manifestUrls = [
70
+ ...new Set(bundles.flatMap((bundle) => bundle.events
71
+ .filter((e) => e.checkpoint === 'experiment')
72
+ .map((e) => e.source))),
73
+ ].map((experiment) => fetch(`https://www.bamboohr.com/experiments/${experiment}/manifest.json`));
74
+
75
+ const experiments = await Promise.all(manifestUrls);
76
+ const variants = (await Promise.all(experiments.map((e) => e.json().catch(() => {}))))
77
+ .filter((json) => json && Object.keys(json).length > 0)
78
+ .flatMap((json) => json.experiences?.data ?? [])
79
+ .filter((data) => data.Name === 'Pages');
80
+
81
+ const mapping = variants.reduce((acc, cur) => {
82
+ Object.entries(cur)
83
+ .filter(([k]) => !['Name', 'Control'].includes(k))
84
+ .forEach(([, v]) => {
85
+ acc[new URL(v).pathname] = new URL(cur.Control).pathname;
86
+ });
87
+ return acc;
88
+ }, {});
89
+
90
+ const variantPaths = Object.keys(mapping);
91
+
92
+ const getControlPath = (url) => {
93
+ const path = new URL(url).pathname;
94
+ if (variantPaths.includes(path)) return mapping[path];
95
+ return path;
96
+ };
97
+
98
+ const byIdAndPath = bundles.reduce((acc, cur) => {
99
+ const controlPath = getControlPath(cur.url);
100
+ const key = `${cur.id}-${controlPath}`;
101
+ if (!acc[key]) acc[key] = [];
102
+ if (variantPaths.includes(new URL(cur.url).pathname)) {
103
+ // eslint-disable-next-line no-param-reassign
104
+ cur.url = new URL(controlPath, cur.url).href;
105
+ }
106
+ acc[key].push(cur);
107
+ return acc;
108
+ }, {});
109
+
110
+ const merged = Object.entries(byIdAndPath).flatMap(([, v]) => {
111
+ let value = v;
112
+ if (v.length > 1) {
113
+ v[0].events.push(...v.slice(1).flatMap((bundle) => bundle.events));
114
+ value = [v[0]];
115
+ }
116
+ return value;
117
+ });
118
+
119
+ return Object.values(merged);
120
+ }
121
+ /* c8 ignore end */
122
+
123
+ async function handler(bundles) {
124
+ const merged = await mergeBundlesWithSameId(bundles);
125
+ const trafficSources = merged
52
126
  .map(extractHints)
53
127
  .map((row) => {
54
128
  const {
@@ -69,5 +143,5 @@ function handler(bundles) {
69
143
 
70
144
  export default {
71
145
  handler,
72
- checkpoints: ['email', 'enter', 'paid', 'utm'],
146
+ checkpoints: ['email', 'enter', 'paid', 'utm', 'experiment'],
73
147
  };