@antelopejs/dms-marketing 0.3.3 → 0.4.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.
Files changed (287) hide show
  1. package/README.md +18 -15
  2. package/dist/config.d.ts +1 -0
  3. package/dist/config.js +4 -0
  4. package/dist/config.js.map +1 -1
  5. package/dist/data-api/funnels.d.ts +2 -0
  6. package/dist/data-api/funnels.js +8 -1
  7. package/dist/data-api/funnels.js.map +1 -1
  8. package/dist/db/models/funnels.model.d.ts +2 -0
  9. package/dist/db/models/funnels.model.js +9 -0
  10. package/dist/db/models/funnels.model.js.map +1 -1
  11. package/dist/db/models/index.d.ts +1 -0
  12. package/dist/db/models/index.js +1 -0
  13. package/dist/db/models/index.js.map +1 -1
  14. package/dist/db/models/marketing_events.model.d.ts +22 -0
  15. package/dist/db/models/marketing_events.model.js +70 -5
  16. package/dist/db/models/marketing_events.model.js.map +1 -1
  17. package/dist/db/models/marketing_preferences.model.d.ts +25 -0
  18. package/dist/db/models/marketing_preferences.model.js +29 -0
  19. package/dist/db/models/marketing_preferences.model.js.map +1 -0
  20. package/dist/db/models/marketing_sessions.model.d.ts +2 -1
  21. package/dist/db/models/marketing_sessions.model.js +11 -1
  22. package/dist/db/models/marketing_sessions.model.js.map +1 -1
  23. package/dist/db/models/page_snapshots.model.d.ts +2 -1
  24. package/dist/db/models/page_snapshots.model.js +7 -7
  25. package/dist/db/models/page_snapshots.model.js.map +1 -1
  26. package/dist/db/models/website_statistics.model.d.ts +4 -1
  27. package/dist/db/models/website_statistics.model.js +15 -1
  28. package/dist/db/models/website_statistics.model.js.map +1 -1
  29. package/dist/db/tables/index.d.ts +1 -0
  30. package/dist/db/tables/index.js +1 -0
  31. package/dist/db/tables/index.js.map +1 -1
  32. package/dist/db/tables/marketing_preferences.table.d.ts +6 -0
  33. package/dist/db/tables/marketing_preferences.table.js +31 -0
  34. package/dist/db/tables/marketing_preferences.table.js.map +1 -0
  35. package/dist/hooks/index.js +8 -0
  36. package/dist/hooks/index.js.map +1 -1
  37. package/dist/index.js +18 -2
  38. package/dist/index.js.map +1 -1
  39. package/dist/pages/acquisition/page.d.ts +9 -0
  40. package/dist/pages/acquisition/page.js +181 -0
  41. package/dist/pages/acquisition/page.js.map +1 -0
  42. package/dist/pages/all.d.ts +5 -1
  43. package/dist/pages/all.js +5 -1
  44. package/dist/pages/all.js.map +1 -1
  45. package/dist/pages/blocks.d.ts +18 -0
  46. package/dist/pages/blocks.js +56 -0
  47. package/dist/pages/blocks.js.map +1 -0
  48. package/dist/pages/funnel/page.d.ts +9 -0
  49. package/dist/pages/funnel/page.js +36 -0
  50. package/dist/pages/funnel/page.js.map +1 -0
  51. package/dist/pages/funnel-builder/page.d.ts +9 -0
  52. package/dist/pages/funnel-builder/page.js +29 -0
  53. package/dist/pages/funnel-builder/page.js.map +1 -0
  54. package/dist/pages/funnels/page.d.ts +1 -1
  55. package/dist/pages/funnels/page.js +200 -3
  56. package/dist/pages/funnels/page.js.map +1 -1
  57. package/dist/pages/index.d.ts +1 -0
  58. package/dist/pages/index.js +1 -0
  59. package/dist/pages/index.js.map +1 -1
  60. package/dist/pages/{campaigns → install}/page.d.ts +3 -3
  61. package/dist/pages/{campaigns → install}/page.js +14 -12
  62. package/dist/pages/install/page.js.map +1 -0
  63. package/dist/pages/module.d.ts +3 -0
  64. package/dist/pages/module.js +30 -3
  65. package/dist/pages/module.js.map +1 -1
  66. package/dist/pages/overview/page.d.ts +1 -1
  67. package/dist/pages/overview/page.js +122 -3
  68. package/dist/pages/overview/page.js.map +1 -1
  69. package/dist/pages/pages/page.d.ts +1 -1
  70. package/dist/pages/pages/page.js +9 -4
  71. package/dist/pages/pages/page.js.map +1 -1
  72. package/dist/pages/quick-actions.d.ts +1 -0
  73. package/dist/pages/quick-actions.js +25 -0
  74. package/dist/pages/quick-actions.js.map +1 -0
  75. package/dist/pages/settings/form.d.ts +2 -1
  76. package/dist/pages/settings/form.js +62 -20
  77. package/dist/pages/settings/form.js.map +1 -1
  78. package/dist/pages/settings/page.d.ts +4 -1
  79. package/dist/pages/settings/page.js +50 -4
  80. package/dist/pages/settings/page.js.map +1 -1
  81. package/dist/pages/websites/page.d.ts +11 -0
  82. package/dist/pages/websites/page.js +62 -0
  83. package/dist/pages/websites/page.js.map +1 -0
  84. package/dist/routes/blocks.d.ts +50 -0
  85. package/dist/routes/blocks.js +269 -0
  86. package/dist/routes/blocks.js.map +1 -0
  87. package/dist/routes/collect.d.ts +1 -2
  88. package/dist/routes/collect.js +19 -12
  89. package/dist/routes/collect.js.map +1 -1
  90. package/dist/routes/context.d.ts +8 -0
  91. package/dist/routes/context.js +54 -0
  92. package/dist/routes/context.js.map +1 -0
  93. package/dist/routes/experiments.js +2 -1
  94. package/dist/routes/experiments.js.map +1 -1
  95. package/dist/routes/funnels.d.ts +21 -3
  96. package/dist/routes/funnels.js +150 -7
  97. package/dist/routes/funnels.js.map +1 -1
  98. package/dist/routes/index.d.ts +2 -0
  99. package/dist/routes/index.js +2 -0
  100. package/dist/routes/index.js.map +1 -1
  101. package/dist/routes/settings.d.ts +6 -1
  102. package/dist/routes/settings.js +65 -4
  103. package/dist/routes/settings.js.map +1 -1
  104. package/dist/routes/snapshot.d.ts +1 -1
  105. package/dist/routes/snapshot.js +24 -25
  106. package/dist/routes/snapshot.js.map +1 -1
  107. package/dist/routes/stats.d.ts +14 -23
  108. package/dist/routes/stats.js +73 -97
  109. package/dist/routes/stats.js.map +1 -1
  110. package/dist/routes/tracker.js +6 -4
  111. package/dist/routes/tracker.js.map +1 -1
  112. package/dist/routes/websites.d.ts +4 -0
  113. package/dist/routes/websites.js +111 -12
  114. package/dist/routes/websites.js.map +1 -1
  115. package/dist/services/acquisition-report.d.ts +62 -0
  116. package/dist/services/acquisition-report.js +181 -0
  117. package/dist/services/acquisition-report.js.map +1 -0
  118. package/dist/services/acquisition.d.ts +9 -3
  119. package/dist/services/acquisition.js +35 -5
  120. package/dist/services/acquisition.js.map +1 -1
  121. package/dist/services/catalog.d.ts +3 -0
  122. package/dist/services/catalog.js +17 -0
  123. package/dist/services/catalog.js.map +1 -0
  124. package/dist/services/collect.d.ts +1 -2
  125. package/dist/services/collect.js +49 -24
  126. package/dist/services/collect.js.map +1 -1
  127. package/dist/services/composed.d.ts +9 -0
  128. package/dist/services/composed.js +62 -0
  129. package/dist/services/composed.js.map +1 -0
  130. package/dist/services/context.d.ts +20 -0
  131. package/dist/services/context.js +76 -0
  132. package/dist/services/context.js.map +1 -0
  133. package/dist/services/dashboard.d.ts +74 -0
  134. package/dist/services/dashboard.js +343 -0
  135. package/dist/services/dashboard.js.map +1 -0
  136. package/dist/services/experiments/results.d.ts +12 -1
  137. package/dist/services/experiments/results.js +19 -2
  138. package/dist/services/experiments/results.js.map +1 -1
  139. package/dist/services/experiments/stats.d.ts +7 -1
  140. package/dist/services/experiments/stats.js +43 -5
  141. package/dist/services/experiments/stats.js.map +1 -1
  142. package/dist/services/funnel-report.d.ts +64 -0
  143. package/dist/services/funnel-report.js +280 -0
  144. package/dist/services/funnel-report.js.map +1 -0
  145. package/dist/services/funnels/compute.d.ts +2 -0
  146. package/dist/services/funnels/compute.js +25 -13
  147. package/dist/services/funnels/compute.js.map +1 -1
  148. package/dist/services/funnels/results.js +4 -1
  149. package/dist/services/funnels/results.js.map +1 -1
  150. package/dist/services/funnels/step-path.d.ts +4 -0
  151. package/dist/services/funnels/step-path.js +47 -0
  152. package/dist/services/funnels/step-path.js.map +1 -0
  153. package/dist/services/funnels-table.d.ts +31 -0
  154. package/dist/services/funnels-table.js +230 -0
  155. package/dist/services/funnels-table.js.map +1 -0
  156. package/dist/services/heatmap.d.ts +15 -3
  157. package/dist/services/heatmap.js +54 -11
  158. package/dist/services/heatmap.js.map +1 -1
  159. package/dist/services/hourly-traffic.d.ts +4 -0
  160. package/dist/services/hourly-traffic.js +35 -0
  161. package/dist/services/hourly-traffic.js.map +1 -0
  162. package/dist/services/origin-guard.d.ts +9 -1
  163. package/dist/services/origin-guard.js +46 -1
  164. package/dist/services/origin-guard.js.map +1 -1
  165. package/dist/services/period.d.ts +26 -1
  166. package/dist/services/period.js +99 -9
  167. package/dist/services/period.js.map +1 -1
  168. package/dist/services/prune.d.ts +6 -0
  169. package/dist/services/prune.js +35 -0
  170. package/dist/services/prune.js.map +1 -1
  171. package/dist/services/request-body.d.ts +1 -2
  172. package/dist/services/request-body.js +10 -36
  173. package/dist/services/request-body.js.map +1 -1
  174. package/dist/services/request-meta.d.ts +0 -1
  175. package/dist/services/request-meta.js +0 -11
  176. package/dist/services/request-meta.js.map +1 -1
  177. package/dist/services/rollups.d.ts +25 -0
  178. package/dist/services/rollups.js +102 -0
  179. package/dist/services/rollups.js.map +1 -0
  180. package/dist/services/sessionize.d.ts +5 -1
  181. package/dist/services/sessionize.js +52 -10
  182. package/dist/services/sessionize.js.map +1 -1
  183. package/dist/services/settings.d.ts +41 -2
  184. package/dist/services/settings.js +219 -6
  185. package/dist/services/settings.js.map +1 -1
  186. package/dist/services/snapshots.d.ts +3 -2
  187. package/dist/services/snapshots.js +110 -9
  188. package/dist/services/snapshots.js.map +1 -1
  189. package/dist/services/tenant-website.js +1 -0
  190. package/dist/services/tenant-website.js.map +1 -1
  191. package/dist/services/url.js +12 -4
  192. package/dist/services/url.js.map +1 -1
  193. package/dist/services/website-hosts.d.ts +15 -0
  194. package/dist/services/website-hosts.js +67 -0
  195. package/dist/services/website-hosts.js.map +1 -0
  196. package/dist/services/website-report.d.ts +40 -0
  197. package/dist/services/website-report.js +84 -0
  198. package/dist/services/website-report.js.map +1 -0
  199. package/dist/types/constants.d.ts +14 -2
  200. package/dist/types/constants.js +17 -6
  201. package/dist/types/constants.js.map +1 -1
  202. package/dist/types/events.d.ts +221 -68
  203. package/dist/types/events.js +60 -11
  204. package/dist/types/events.js.map +1 -1
  205. package/dist/types/snapshots.d.ts +6 -0
  206. package/dist/types/snapshots.js +2 -0
  207. package/dist/types/snapshots.js.map +1 -1
  208. package/dist/types/statistics.d.ts +2 -1
  209. package/dist/types/statistics.js +9 -2
  210. package/dist/types/statistics.js.map +1 -1
  211. package/dist/utils/experiment-type.js +1 -1
  212. package/dist/utils/experiment-type.js.map +1 -1
  213. package/dist/utils/funnel-steps-type.d.ts +21 -3
  214. package/dist/utils/funnel-steps-type.js +7 -2
  215. package/dist/utils/funnel-steps-type.js.map +1 -1
  216. package/frontend-vue/app/components/ChannelsCard.vue +265 -0
  217. package/frontend-vue/app/components/Context.vue +479 -0
  218. package/frontend-vue/app/components/ExperimentInput.vue +3 -1
  219. package/frontend-vue/app/components/ExperimentReport.vue +736 -0
  220. package/frontend-vue/app/components/FirstRun.vue +60 -0
  221. package/frontend-vue/app/components/FunnelBuilder.vue +1595 -0
  222. package/frontend-vue/app/components/FunnelFigure.vue +640 -0
  223. package/frontend-vue/app/components/FunnelReport.vue +532 -0
  224. package/frontend-vue/app/components/FunnelStepsInput.vue +3 -1
  225. package/frontend-vue/app/components/FunnelTemplates.vue +161 -0
  226. package/frontend-vue/app/components/HeatmapCanvas.vue +11 -4
  227. package/frontend-vue/app/components/InstallGuide.vue +753 -0
  228. package/frontend-vue/app/components/PagePreview.vue +889 -416
  229. package/frontend-vue/app/components/PagesExplorer.vue +552 -0
  230. package/frontend-vue/app/components/ScrollDepthOverlay.vue +48 -20
  231. package/frontend-vue/app/components/TopListTabs.vue +317 -0
  232. package/frontend-vue/app/components/TrackerSnippet.vue +50 -16
  233. package/frontend-vue/app/components/VariationsInput.vue +15 -5
  234. package/frontend-vue/app/components/WebsitesGrid.vue +799 -0
  235. package/frontend-vue/app/composables/useContextLink.ts +16 -0
  236. package/frontend-vue/app/composables/useExperiment.ts +1 -2
  237. package/frontend-vue/app/composables/useFunnelSteps.ts +1 -2
  238. package/frontend-vue/app/composables/useLatestRequest.ts +2 -4
  239. package/frontend-vue/app/composables/useMarketingApi.ts +298 -133
  240. package/frontend-vue/app/composables/useMarketingContext.ts +55 -0
  241. package/frontend-vue/app/composables/useMarketingRoutes.ts +80 -27
  242. package/frontend-vue/app/composables/useSnapshotFrame.ts +26 -4
  243. package/frontend-vue/app/constants.ts +22 -0
  244. package/frontend-vue/app/plugins/funnel-steps-data-type.client.ts +2 -1
  245. package/frontend-vue/app/utils/channels.ts +37 -0
  246. package/frontend-vue/app/utils/format.ts +132 -0
  247. package/frontend-vue/app/utils/funnel-draft.ts +264 -0
  248. package/frontend-vue/app/utils/heatmap.ts +82 -0
  249. package/frontend-vue/app/utils/heatmapPalette.ts +10 -0
  250. package/frontend-vue/app/utils/host-conflict.ts +48 -0
  251. package/frontend-vue/app/utils/sample-size.ts +17 -0
  252. package/frontend-vue/app/utils/snapshotViewportUnits.ts +15 -5
  253. package/frontend-vue/app/utils/snippet.ts +53 -0
  254. package/frontend-vue/app/utils/step-path.ts +32 -0
  255. package/frontend-vue/dms.frontend.ts +4 -3
  256. package/frontend-vue/i18n/locales/marketing-en-GB.json +1083 -316
  257. package/frontend-vue/i18n/locales/marketing-fr-FR.json +1087 -320
  258. package/frontend-vue/package.json +1 -1
  259. package/frontend-vue/tests/drafts.test.ts +3 -3
  260. package/frontend-vue/tests/format.test.ts +73 -0
  261. package/frontend-vue/tests/funnel-draft.test.ts +194 -0
  262. package/frontend-vue/tests/heatmap.test.ts +32 -0
  263. package/frontend-vue/tests/i18n.test.ts +87 -4
  264. package/frontend-vue/tests/latest-request.test.ts +6 -3
  265. package/frontend-vue/tests/locale-typography.test.ts +115 -0
  266. package/frontend-vue/tests/registration.test.ts +21 -11
  267. package/frontend-vue/tests/routes.test.ts +67 -7
  268. package/frontend-vue/tests/server-parity.test.ts +77 -0
  269. package/frontend-vue/tests/stubs/frontend-module.ts +18 -3
  270. package/package.json +9 -7
  271. package/static/snapshot.js +46 -16
  272. package/static/tracker.js +139 -48
  273. package/dist/pages/campaigns/page.js.map +0 -1
  274. package/frontend-vue/app/components/CampaignsView.vue +0 -330
  275. package/frontend-vue/app/components/FunnelDetail.vue +0 -1026
  276. package/frontend-vue/app/components/FunnelsView.vue +0 -493
  277. package/frontend-vue/app/components/NoWebsiteState.vue +0 -18
  278. package/frontend-vue/app/components/OverviewView.vue +0 -493
  279. package/frontend-vue/app/components/PagesView.vue +0 -391
  280. package/frontend-vue/app/components/TextKpiCard.vue +0 -28
  281. package/frontend-vue/app/components/TopListTabsCard.vue +0 -162
  282. package/frontend-vue/app/composables/useChildId.ts +0 -13
  283. package/frontend-vue/app/composables/useMarketingPeriod.ts +0 -65
  284. package/frontend-vue/app/composables/useMarketingWebsiteForm.ts +0 -69
  285. package/frontend-vue/app/composables/useMarketingWebsites.ts +0 -80
  286. package/frontend-vue/app/utils/dmsComponent.ts +0 -18
  287. package/frontend-vue/tests/period.test.ts +0 -35
@@ -0,0 +1,280 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unseenStepOf = unseenStepOf;
4
+ exports.experimentVerdict = experimentVerdict;
5
+ exports.funnelResultsIn = funnelResultsIn;
6
+ exports.readsPeriod = readsPeriod;
7
+ exports.rawCoverageStart = rawCoverageStart;
8
+ exports.coversWindow = coversWindow;
9
+ exports.summarizeFunnel = summarizeFunnel;
10
+ exports.funnelSuggestions = funnelSuggestions;
11
+ exports.funnelTemplates = funnelTemplates;
12
+ const interface_database_decorators_1 = require("@antelopejs/interface-database-decorators");
13
+ const config_1 = require("@/config");
14
+ const db_1 = require("@/db");
15
+ const constants_1 = require("@/types/constants");
16
+ const bounded_cache_1 = require("./bounded-cache");
17
+ const funnels_1 = require("./funnels");
18
+ const rollups_1 = require("./rollups");
19
+ function endToEnd(results) {
20
+ const steps = results.computation.steps;
21
+ return {
22
+ entered: steps[0]?.sessions ?? 0,
23
+ completed: steps.at(-1)?.sessions ?? 0,
24
+ };
25
+ }
26
+ function conversionOf(results) {
27
+ if (!results) {
28
+ return null;
29
+ }
30
+ const { entered, completed } = endToEnd(results);
31
+ return entered > 0 ? (completed / entered) * 100 : null;
32
+ }
33
+ function unseenStepOf(results) {
34
+ const computation = results.computation;
35
+ if (computation.events === 0 || results.truncated) {
36
+ return null;
37
+ }
38
+ return (computation.steps.find((step) => step.matches === 0)?.step.value ?? null);
39
+ }
40
+ function pickLeader(arms) {
41
+ let best = -1;
42
+ arms.forEach((arm, index) => {
43
+ if (index === 0 || arm.pValue === null) {
44
+ return;
45
+ }
46
+ if (best === -1 || arm.conversionRate > arms[best].conversionRate) {
47
+ best = index;
48
+ }
49
+ });
50
+ return best;
51
+ }
52
+ function experimentVerdict(results) {
53
+ const read = results.experiment;
54
+ if (!read) {
55
+ return null;
56
+ }
57
+ const arms = read.variations;
58
+ const index = pickLeader(arms);
59
+ const leader = index === -1 ? null : index;
60
+ const unscored = arms.slice(1).every((arm) => arm.significant === null);
61
+ const best = leader === null ? undefined : arms[leader];
62
+ let kind;
63
+ if (results.truncated || read.srm.mismatch || unscored || !best) {
64
+ kind = "withheld";
65
+ }
66
+ else if (!best.significant) {
67
+ kind = "flat";
68
+ }
69
+ else if (!read.decision.ready) {
70
+ kind = "early";
71
+ }
72
+ else {
73
+ kind = (best.uplift ?? 0) > 0 ? "winner" : "loser";
74
+ }
75
+ return { kind, leader };
76
+ }
77
+ function leaderOf(arms, verdict) {
78
+ const index = verdict?.leader ?? null;
79
+ const best = index === null ? null : arms[index];
80
+ if (index === null || !best || best.uplift === null) {
81
+ return null;
82
+ }
83
+ return {
84
+ key: best.key,
85
+ index,
86
+ uplift: best.uplift * 100,
87
+ significant: best.significant === true,
88
+ };
89
+ }
90
+ function percentOrNull(ratio) {
91
+ return ratio === null || ratio === undefined ? null : ratio * 100;
92
+ }
93
+ function experimentSummary(funnel, results) {
94
+ const experiment = funnel.experiment;
95
+ if (!experiment) {
96
+ return null;
97
+ }
98
+ const started = experiment.runs.length > 0;
99
+ const read = started ? results.experiment : undefined;
100
+ const arms = read?.variations ?? [];
101
+ const verdict = read ? experimentVerdict(results) : null;
102
+ const leader = leaderOf(arms, verdict);
103
+ const best = leader ? arms[leader.index] : undefined;
104
+ return {
105
+ key: experiment.key,
106
+ status: experiment.status,
107
+ variations: experiment.variations.length,
108
+ since: started ? results.window.since : null,
109
+ until: experiment.status === "stopped" ? results.window.until : null,
110
+ leader,
111
+ exposed: arms.reduce((sum, arm) => sum + arm.exposedSessions, 0),
112
+ ready: verdict?.kind === "winner",
113
+ upliftLow: percentOrNull(best?.upliftLow),
114
+ upliftHigh: percentOrNull(best?.upliftHigh),
115
+ days: read?.decision.days ?? 0,
116
+ };
117
+ }
118
+ async function funnelResultsIn(funnel, tenantId, window) {
119
+ return (0, funnels_1.computeFunnelResults)((0, interface_database_decorators_1.GetModel)(db_1.MarketingEventsModel, tenantId), funnel, window.since, window.until);
120
+ }
121
+ function readsPeriod(funnel) {
122
+ return !funnel.experiment || funnel.experiment.status === "draft";
123
+ }
124
+ const coverageCache = new bounded_cache_1.BoundedCache(constants_1.RAW_COVERAGE_CACHE_TTL_MS);
125
+ async function rawCoverageStart(tenantId, websiteId) {
126
+ const key = `${tenantId}:${websiteId}`;
127
+ const hit = coverageCache.get(key);
128
+ if (hit) {
129
+ return hit.value;
130
+ }
131
+ const now = Date.now();
132
+ const [first] = await (0, interface_database_decorators_1.GetModel)(db_1.MarketingEventsModel, tenantId).queryRange({
133
+ websiteIds: [websiteId],
134
+ since: new Date(now - (0, config_1.getConfig)().rawEventsRetention),
135
+ until: new Date(now),
136
+ limit: 1,
137
+ fields: [],
138
+ });
139
+ const start = first ? first.timestamp.getTime() : null;
140
+ coverageCache.set(key, start);
141
+ return start;
142
+ }
143
+ function coversWindow(window, coverage) {
144
+ return coverage !== null && window.since.getTime() + constants_1.MS_PER_DAY > coverage;
145
+ }
146
+ const summaryCache = new bounded_cache_1.BoundedCache(constants_1.FUNNEL_SUMMARY_CACHE_TTL_MS);
147
+ function summaryKey(funnel, tenantId, window, compare) {
148
+ return JSON.stringify([
149
+ tenantId,
150
+ funnel._id,
151
+ funnel.name,
152
+ funnel.steps,
153
+ funnel.conversionWindowMs,
154
+ funnel.experiment,
155
+ window.firstDay,
156
+ window.lastDay,
157
+ compare?.firstDay ?? null,
158
+ compare?.lastDay ?? null,
159
+ ]);
160
+ }
161
+ function summarizeFunnel(funnel, tenantId, window, compare) {
162
+ const key = summaryKey(funnel, tenantId, window, compare);
163
+ const hit = summaryCache.get(key);
164
+ if (hit) {
165
+ return hit.value;
166
+ }
167
+ const pending = computeSummary(funnel, tenantId, window, compare);
168
+ summaryCache.set(key, pending);
169
+ pending.catch(() => summaryCache.delete(key));
170
+ return pending;
171
+ }
172
+ async function computeSummary(funnel, tenantId, window, compare) {
173
+ const [results, previous] = await Promise.all([
174
+ funnelResultsIn(funnel, tenantId, window),
175
+ compare && readsPeriod(funnel)
176
+ ? funnelResultsIn(funnel, tenantId, compare)
177
+ : Promise.resolve(null),
178
+ ]);
179
+ const { entered, completed } = endToEnd(results);
180
+ const conversion = conversionOf(results);
181
+ const before = conversionOf(previous);
182
+ return {
183
+ id: funnel._id,
184
+ name: funnel.name,
185
+ kind: funnel.experiment ? "ab" : "funnel",
186
+ steps: funnel.steps,
187
+ windowHours: Math.round(funnel.conversionWindowMs / constants_1.MS_PER_HOUR),
188
+ createdAt: funnel.createdAt ? new Date(funnel.createdAt).getTime() : null,
189
+ entered,
190
+ completed,
191
+ conversion,
192
+ deltaPoints: conversion !== null && before !== null ? conversion - before : null,
193
+ unseenStep: unseenStepOf(results),
194
+ experiment: experimentSummary(funnel, results),
195
+ };
196
+ }
197
+ const MAX_SUGGESTIONS = 50;
198
+ async function funnelSuggestions(website, window) {
199
+ const rows = await (0, rollups_1.readRollups)(website, window);
200
+ const toSuggestion = ({ key, value }) => ({
201
+ value: key,
202
+ count: value,
203
+ });
204
+ return {
205
+ pages: (0, rollups_1.rankEntries)((0, rollups_1.mergeDimension)(rows, "topPages"), MAX_SUGGESTIONS).map(toSuggestion),
206
+ events: (0, rollups_1.rankEntries)((0, rollups_1.mergeDimension)(rows, "topEvents"), MAX_SUGGESTIONS).map(toSuggestion),
207
+ };
208
+ }
209
+ const MAX_TEMPLATES = 2;
210
+ function increment(counts, key) {
211
+ counts.set(key, (counts.get(key) ?? 0) + 1);
212
+ }
213
+ function mostFrequent(counts) {
214
+ let best = null;
215
+ for (const [key, count] of counts) {
216
+ if (best === null || count > (counts.get(best) ?? 0)) {
217
+ best = key;
218
+ }
219
+ }
220
+ return best;
221
+ }
222
+ async function funnelTemplates(website, window) {
223
+ const events = (await (0, interface_database_decorators_1.GetModel)(db_1.MarketingEventsModel, website.tenantId).queryRange({
224
+ websiteIds: [website._id],
225
+ since: window.since,
226
+ until: window.until,
227
+ kinds: ["pageview", "custom"],
228
+ limit: constants_1.MAX_FUNNEL_EVENTS,
229
+ fields: ["sessionId", "kind", "url", "name"],
230
+ }));
231
+ const sessions = [...(0, funnels_1.groupBySession)(events).values()];
232
+ const sessionsByEvent = new Map();
233
+ const sessionsByPage = new Map();
234
+ for (const session of sessions) {
235
+ const names = new Set();
236
+ const pages = new Set();
237
+ for (const event of session) {
238
+ if (event.kind === "custom" && event.name) {
239
+ names.add(event.name);
240
+ }
241
+ else if (event.kind === "pageview") {
242
+ pages.add(event.url);
243
+ }
244
+ }
245
+ names.forEach((name) => increment(sessionsByEvent, name));
246
+ pages.forEach((page) => increment(sessionsByPage, page));
247
+ }
248
+ const topEvents = [...sessionsByEvent.entries()]
249
+ .sort((a, b) => b[1] - a[1])
250
+ .slice(0, MAX_TEMPLATES)
251
+ .map(([name]) => name);
252
+ return topEvents.map((name) => {
253
+ const before = new Map();
254
+ for (const session of sessions) {
255
+ const at = session.findIndex((event) => event.kind === "custom" && event.name === name);
256
+ if (at <= 0) {
257
+ continue;
258
+ }
259
+ const pages = new Set(session
260
+ .slice(0, at)
261
+ .filter((event) => event.kind === "pageview")
262
+ .map((event) => event.url));
263
+ pages.forEach((page) => increment(before, page));
264
+ }
265
+ const page = mostFrequent(before);
266
+ return page
267
+ ? {
268
+ steps: [
269
+ { kind: "url", value: page },
270
+ { kind: "custom", value: name },
271
+ ],
272
+ entering: sessionsByPage.get(page) ?? 0,
273
+ }
274
+ : {
275
+ steps: [{ kind: "custom", value: name }],
276
+ entering: sessionsByEvent.get(name) ?? 0,
277
+ };
278
+ });
279
+ }
280
+ //# sourceMappingURL=funnel-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"funnel-report.js","sourceRoot":"","sources":["../../src/services/funnel-report.ts"],"names":[],"mappings":";;AAoGA,oCAQC;AA6CD,8CAuBC;AAqDD,0CAWC;AAID,kCAEC;AAcD,4CAoBC;AAOD,oCAKC;AAqCD,0CAeC;AAiDD,8CAiBC;AA+BD,0CAkEC;AA3fD,6FAAqE;AACrE,qCAAqC;AACrC,6BAA4C;AAG5C,iDAM2B;AAC3B,mDAA+C;AAC/C,uCAKmB;AAEnB,uCAKmB;AAqDnB,SAAS,QAAQ,CAAC,OAAsB;IACtC,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC;IACxC,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,IAAI,CAAC;QAChC,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,IAAI,CAAC;KACvC,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,OAA6B;IACjD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IACjD,OAAO,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1D,CAAC;AAQD,SAAgB,YAAY,CAAC,OAAsB;IACjD,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IACxC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QAClD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,CACL,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CACzE,CAAC;AACJ,CAAC;AAQD,SAAS,UAAU,CAAC,IAAiB;IACnC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC;IACd,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;QAC1B,IAAI,KAAK,KAAK,CAAC,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YACvC,OAAO;QACT,CAAC;QACD,IAAI,IAAI,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,CAAC;YAClE,IAAI,GAAG,KAAK,CAAC;QACf,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC;AACd,CAAC;AA0BD,SAAgB,iBAAiB,CAC/B,OAAsB;IAEtB,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC;IAChC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC;IAC7B,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC;IACxE,MAAM,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACxD,IAAI,IAA2B,CAAC;IAChC,IAAI,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAChE,IAAI,GAAG,UAAU,CAAC;IACpB,CAAC;SAAM,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAC7B,IAAI,GAAG,MAAM,CAAC;IAChB,CAAC;SAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,GAAG,OAAO,CAAC;IACjB,CAAC;SAAM,CAAC;QACN,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;IACrD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC1B,CAAC;AAED,SAAS,QAAQ,CACf,IAAiB,EACjB,OAAiC;IAEjC,MAAM,KAAK,GAAG,OAAO,EAAE,MAAM,IAAI,IAAI,CAAC;IACtC,MAAM,IAAI,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjD,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO;QACL,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,KAAK;QACL,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,GAAG;QACzB,WAAW,EAAE,IAAI,CAAC,WAAW,KAAK,IAAI;KACvC,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,KAAgC;IACrD,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC;AACpE,CAAC;AAED,SAAS,iBAAiB,CACxB,MAAc,EACd,OAAsB;IAEtB,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IACrC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;IACtD,MAAM,IAAI,GAAG,IAAI,EAAE,UAAU,IAAI,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACzD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACrD,OAAO;QACL,GAAG,EAAE,UAAU,CAAC,GAAG;QACnB,MAAM,EAAE,UAAU,CAAC,MAAM;QACzB,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC,MAAM;QACxC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;QAC5C,KAAK,EAAE,UAAU,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;QACpE,MAAM;QACN,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC;QAEhE,KAAK,EAAE,OAAO,EAAE,IAAI,KAAK,QAAQ;QACjC,SAAS,EAAE,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC;QACzC,UAAU,EAAE,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC;QAC3C,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC;KAC/B,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,eAAe,CACnC,MAAc,EACd,QAAgB,EAChB,MAAmB;IAEnB,OAAO,IAAA,8BAAoB,EACzB,IAAA,wCAAQ,EAAC,yBAAoB,EAAE,QAAQ,CAAC,EACxC,MAAM,EACN,MAAM,CAAC,KAAK,EACZ,MAAM,CAAC,KAAK,CACb,CAAC;AACJ,CAAC;AAID,SAAgB,WAAW,CAAC,MAAc;IACxC,OAAO,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,OAAO,CAAC;AACpE,CAAC;AAID,MAAM,aAAa,GAAG,IAAI,4BAAY,CACpC,qCAAyB,CAC1B,CAAC;AAQK,KAAK,UAAU,gBAAgB,CACpC,QAAgB,EAChB,SAAiB;IAEjB,MAAM,GAAG,GAAG,GAAG,QAAQ,IAAI,SAAS,EAAE,CAAC;IACvC,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,GAAG,CAAC,KAAK,CAAC;IACnB,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,IAAA,wCAAQ,EAAC,yBAAoB,EAAE,QAAQ,CAAC,CAAC,UAAU,CAAC;QACxE,UAAU,EAAE,CAAC,SAAS,CAAC;QACvB,KAAK,EAAE,IAAI,IAAI,CAAC,GAAG,GAAG,IAAA,kBAAS,GAAE,CAAC,kBAAkB,CAAC;QACrD,KAAK,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC;QACpB,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,EAAE;KACX,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACvD,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC9B,OAAO,KAAK,CAAC;AACf,CAAC;AAOD,SAAgB,YAAY,CAC1B,MAAmB,EACnB,QAAuB;IAEvB,OAAO,QAAQ,KAAK,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,sBAAU,GAAG,QAAQ,CAAC;AAC7E,CAAC;AASD,MAAM,YAAY,GAAG,IAAI,4BAAY,CACnC,uCAA2B,CAC5B,CAAC;AAEF,SAAS,UAAU,CACjB,MAAc,EACd,QAAgB,EAChB,MAAmB,EACnB,OAA2B;IAE3B,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,QAAQ;QACR,MAAM,CAAC,GAAG;QACV,MAAM,CAAC,IAAI;QACX,MAAM,CAAC,KAAK;QACZ,MAAM,CAAC,kBAAkB;QACzB,MAAM,CAAC,UAAU;QACjB,MAAM,CAAC,QAAQ;QACf,MAAM,CAAC,OAAO;QACd,OAAO,EAAE,QAAQ,IAAI,IAAI;QACzB,OAAO,EAAE,OAAO,IAAI,IAAI;KACzB,CAAC,CAAC;AACL,CAAC;AAMD,SAAgB,eAAe,CAC7B,MAAc,EACd,QAAgB,EAChB,MAAmB,EACnB,OAA2B;IAE3B,MAAM,GAAG,GAAG,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1D,MAAM,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,GAAG,EAAE,CAAC;QACR,OAAO,GAAG,CAAC,KAAK,CAAC;IACnB,CAAC;IACD,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAClE,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC/B,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9C,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,MAAc,EACd,QAAgB,EAChB,MAAmB,EACnB,OAA2B;IAE3B,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC5C,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC;QACzC,OAAO,IAAI,WAAW,CAAC,MAAM,CAAC;YAC5B,CAAC,CAAC,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC;YAC5C,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;KAC1B,CAAC,CAAC;IACH,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IACjD,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACtC,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,GAAG;QACd,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ;QACzC,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,kBAAkB,GAAG,uBAAW,CAAC;QAChE,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI;QACzE,OAAO;QACP,SAAS;QACT,UAAU;QACV,WAAW,EACT,UAAU,KAAK,IAAI,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI;QACrE,UAAU,EAAE,YAAY,CAAC,OAAO,CAAC;QACjC,UAAU,EAAE,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC;KAC/C,CAAC;AACJ,CAAC;AAcD,MAAM,eAAe,GAAG,EAAE,CAAC;AAGpB,KAAK,UAAU,iBAAiB,CACrC,OAAgB,EAChB,MAAmB;IAEnB,MAAM,IAAI,GAAG,MAAM,IAAA,qBAAW,EAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,YAAY,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,EAAe,EAAoB,EAAE,CAAC,CAAC;QACvE,KAAK,EAAE,GAAG;QACV,KAAK,EAAE,KAAK;KACb,CAAC,CAAC;IACH,OAAO;QACL,KAAK,EAAE,IAAA,qBAAW,EAAC,IAAA,wBAAc,EAAC,IAAI,EAAE,UAAU,CAAC,EAAE,eAAe,CAAC,CAAC,GAAG,CACvE,YAAY,CACb;QACD,MAAM,EAAE,IAAA,qBAAW,EAAC,IAAA,wBAAc,EAAC,IAAI,EAAE,WAAW,CAAC,EAAE,eAAe,CAAC,CAAC,GAAG,CACzE,YAAY,CACb;KACF,CAAC;AACJ,CAAC;AASD,MAAM,aAAa,GAAG,CAAC,CAAC;AAExB,SAAS,SAAS,CAAC,MAA2B,EAAE,GAAW;IACzD,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,YAAY,CAAC,MAA2B;IAC/C,IAAI,IAAI,GAAkB,IAAI,CAAC;IAC/B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;QAClC,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YACrD,IAAI,GAAG,GAAG,CAAC;QACb,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAQM,KAAK,UAAU,eAAe,CACnC,OAAgB,EAChB,MAAmB;IAEnB,MAAM,MAAM,GAAG,CAAC,MAAM,IAAA,wCAAQ,EAC5B,yBAAoB,EACpB,OAAO,CAAC,QAAQ,CACjB,CAAC,UAAU,CAAC;QACX,UAAU,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;QACzB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC;QAC7B,KAAK,EAAE,6BAAiB;QACxB,MAAM,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC;KAC7C,CAAC,CAAkB,CAAC;IACrB,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAA,wBAAc,EAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IACtD,MAAM,eAAe,GAAG,IAAI,GAAG,EAAkB,CAAC;IAClD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAC;IACjD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;QAChC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;QAChC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBAC1C,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACxB,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBACrC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC,CAAC;QAC1D,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC;IAC3D,CAAC;IACD,MAAM,SAAS,GAAG,CAAC,GAAG,eAAe,CAAC,OAAO,EAAE,CAAC;SAC7C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;SAC3B,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC;SACvB,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;IACzB,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QAC5B,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;QACzC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,CAC1B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,CAC1D,CAAC;YACF,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;gBACZ,SAAS;YACX,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,GAAG,CACnB,OAAO;iBACJ,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;iBACZ,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC;iBAC5C,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAC7B,CAAC;YACF,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;QACnD,CAAC;QACD,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAClC,OAAO,IAAI;YACT,CAAC,CAAC;gBACE,KAAK,EAAE;oBACL,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE;oBAC5B,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE;iBAChC;gBACD,QAAQ,EAAE,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;aACxC;YACH,CAAC,CAAC;gBACE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;gBACxC,QAAQ,EAAE,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;aACzC,CAAC;IACR,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -5,9 +5,11 @@ interface FunnelStepResult {
5
5
  step: FunnelStep;
6
6
  sessions: number;
7
7
  conversionRate: number;
8
+ matches: number;
8
9
  }
9
10
  export interface FunnelComputation {
10
11
  totalSessions: number;
12
+ events: number;
11
13
  steps: FunnelStepResult[];
12
14
  }
13
15
  export type FunnelEvent = Pick<MarketingEvent, "sessionId" | "kind" | "url" | "name" | "timestamp">;
@@ -2,12 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.groupBySession = groupBySession;
4
4
  exports.computeFunnelOverSessions = computeFunnelOverSessions;
5
- const STEP_MATCHERS = {
6
- url: (event, value) => event.kind === "pageview" && event.url === value,
7
- custom: (event, value) => event.kind === "custom" && event.name === value,
8
- };
9
- function eventMatchesStep(event, step) {
10
- return STEP_MATCHERS[step.kind](event, step.value);
5
+ const step_path_1 = require("./step-path");
6
+ function stepMatcher(step) {
7
+ if (step.kind === "custom") {
8
+ return (event) => event.kind === "custom" && event.name === step.value;
9
+ }
10
+ const matchesPath = (0, step_path_1.stepPathMatcher)(step.value);
11
+ return (event) => event.kind === "pageview" && matchesPath(event.url);
11
12
  }
12
13
  function groupBySession(events) {
13
14
  const sessions = new Map();
@@ -22,7 +23,7 @@ function groupBySession(events) {
22
23
  }
23
24
  return sessions;
24
25
  }
25
- function sessionProgress(events, funnel) {
26
+ function sessionProgress(events, funnel, matchers) {
26
27
  let reached = 0;
27
28
  let enteredAt;
28
29
  for (const event of events) {
@@ -33,7 +34,7 @@ function sessionProgress(events, funnel) {
33
34
  event.timestamp.getTime() - enteredAt > funnel.conversionWindowMs) {
34
35
  break;
35
36
  }
36
- if (eventMatchesStep(event, funnel.steps[reached])) {
37
+ if (matchers[reached](event)) {
37
38
  if (reached === 0) {
38
39
  enteredAt = event.timestamp.getTime();
39
40
  }
@@ -44,24 +45,35 @@ function sessionProgress(events, funnel) {
44
45
  }
45
46
  function computeFunnelOverSessions(funnel, sessions) {
46
47
  if (funnel.steps.length === 0) {
47
- return { totalSessions: 0, steps: [] };
48
+ return { totalSessions: 0, events: 0, steps: [] };
48
49
  }
49
- const reachedCounts = Array.from({
50
- length: funnel.steps.length,
51
- }).fill(0);
50
+ const matchers = funnel.steps.map(stepMatcher);
51
+ const reachedCounts = funnel.steps.map(() => 0);
52
+ const matchCounts = funnel.steps.map(() => 0);
53
+ let events = 0;
52
54
  for (const sessionEvents of sessions) {
53
- const reached = sessionProgress(sessionEvents, funnel);
55
+ const reached = sessionProgress(sessionEvents, funnel, matchers);
54
56
  for (let i = 0; i < reached; i++) {
55
57
  reachedCounts[i]++;
56
58
  }
59
+ events += sessionEvents.length;
60
+ for (const event of sessionEvents) {
61
+ matchers.forEach((matches, i) => {
62
+ if (matches(event)) {
63
+ matchCounts[i]++;
64
+ }
65
+ });
66
+ }
57
67
  }
58
68
  const entered = reachedCounts[0] ?? 0;
59
69
  return {
60
70
  totalSessions: entered,
71
+ events,
61
72
  steps: funnel.steps.map((step, i) => ({
62
73
  step,
63
74
  sessions: reachedCounts[i],
64
75
  conversionRate: entered > 0 ? reachedCounts[i] / entered : 0,
76
+ matches: matchCounts[i],
65
77
  })),
66
78
  };
67
79
  }
@@ -1 +1 @@
1
- {"version":3,"file":"compute.js","sourceRoot":"","sources":["../../../src/services/funnels/compute.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compute.js","sourceRoot":"","sources":["../../../src/services/funnels/compute.ts"],"names":[],"mappings":"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"}
@@ -42,6 +42,9 @@ function coveredWindow(runs) {
42
42
  until: new Date(Math.max(...runs.map((run) => run.until.getTime()))),
43
43
  };
44
44
  }
45
+ function servedMs(runs) {
46
+ return runs.reduce((sum, run) => sum + Math.max(0, run.until.getTime() - run.since.getTime()), 0);
47
+ }
45
48
  async function computeFunnelResults(eventsModel, funnel, since, until) {
46
49
  const experiment = funnel.experiment;
47
50
  const runs = experiment ? runWindows(experiment, until) : null;
@@ -60,7 +63,7 @@ async function computeFunnelResults(eventsModel, funnel, since, until) {
60
63
  return {
61
64
  computation: (0, compute_1.computeFunnelOverSessions)(funnel, (0, compute_1.groupBySession)(usable).values()),
62
65
  experiment: runs && experiment
63
- ? (0, results_1.computeExperimentResults)(usable, funnel, experiment, truncated)
66
+ ? (0, results_1.computeExperimentResults)(usable, funnel, experiment, truncated, servedMs(runs))
64
67
  : undefined,
65
68
  truncated,
66
69
  window: {
@@ -1 +1 @@
1
- {"version":3,"file":"results.js","sourceRoot":"","sources":["../../../src/services/funnels/results.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"results.js","sourceRoot":"","sources":["../../../src/services/funnels/results.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare const STEP_PREFIX_WILDCARD = "*";
2
+ export declare function normalizeStepPath(raw: string): string;
3
+ export declare function pathKey(path: string): string;
4
+ export declare function stepPathMatcher(value: string): (path: string) => boolean;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.STEP_PREFIX_WILDCARD = void 0;
4
+ exports.normalizeStepPath = normalizeStepPath;
5
+ exports.pathKey = pathKey;
6
+ exports.stepPathMatcher = stepPathMatcher;
7
+ const PATH_BASE = "http://step.invalid";
8
+ exports.STEP_PREFIX_WILDCARD = "*";
9
+ const SCHEME_PATTERN = /^[a-z][a-z\d+.-]*:\/\//i;
10
+ const BARE_HOST_PATTERN = /^[^/\s?#]+\.[^/\s?#]+\//;
11
+ function normalizeStepPath(raw) {
12
+ const value = raw.trim();
13
+ const prefix = value.endsWith(exports.STEP_PREFIX_WILDCARD);
14
+ const body = prefix ? value.slice(0, -exports.STEP_PREFIX_WILDCARD.length) : value;
15
+ const absolute = SCHEME_PATTERN.test(body)
16
+ ? body
17
+ : BARE_HOST_PATTERN.test(body)
18
+ ? `https://${body}`
19
+ : `${PATH_BASE}${body.startsWith("/") ? "" : "/"}${body}`;
20
+ let path;
21
+ try {
22
+ path = new URL(absolute).pathname;
23
+ }
24
+ catch {
25
+ return value;
26
+ }
27
+ if (prefix) {
28
+ return `${path}${exports.STEP_PREFIX_WILDCARD}`;
29
+ }
30
+ return path.length > 1 && path.endsWith("/") ? path.slice(0, -1) : path;
31
+ }
32
+ function pathKey(path) {
33
+ const lower = path.toLowerCase();
34
+ return lower.length > 1 && lower.endsWith("/") ? lower.slice(0, -1) : lower;
35
+ }
36
+ function stepPathMatcher(value) {
37
+ const normalized = normalizeStepPath(value);
38
+ if (normalized.endsWith(exports.STEP_PREFIX_WILDCARD)) {
39
+ const prefix = normalized
40
+ .slice(0, -exports.STEP_PREFIX_WILDCARD.length)
41
+ .toLowerCase();
42
+ return (path) => path.toLowerCase().startsWith(prefix);
43
+ }
44
+ const key = pathKey(normalized);
45
+ return (path) => pathKey(path) === key;
46
+ }
47
+ //# sourceMappingURL=step-path.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-path.js","sourceRoot":"","sources":["../../../src/services/funnels/step-path.ts"],"names":[],"mappings":";;;AAiBA,8CAmBC;AAGD,0BAGC;AAGD,0CAUC;AAtDD,MAAM,SAAS,GAAG,qBAAqB,CAAC;AAG3B,QAAA,oBAAoB,GAAG,GAAG,CAAC;AAExC,MAAM,cAAc,GAAG,yBAAyB,CAAC;AAEjD,MAAM,iBAAiB,GAAG,yBAAyB,CAAC;AASpD,SAAgB,iBAAiB,CAAC,GAAW;IAC3C,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACzB,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,4BAAoB,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,4BAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC3E,MAAM,QAAQ,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;QACxC,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;YAC5B,CAAC,CAAC,WAAW,IAAI,EAAE;YACnB,CAAC,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,EAAE,CAAC;IAC9D,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,GAAG,IAAI,GAAG,4BAAoB,EAAE,CAAC;IAC1C,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1E,CAAC;AAGD,SAAgB,OAAO,CAAC,IAAY;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AAC9E,CAAC;AAGD,SAAgB,eAAe,CAAC,KAAa;IAC3C,MAAM,UAAU,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAC5C,IAAI,UAAU,CAAC,QAAQ,CAAC,4BAAoB,CAAC,EAAE,CAAC;QAC9C,MAAM,MAAM,GAAG,UAAU;aACtB,KAAK,CAAC,CAAC,EAAE,CAAC,4BAAoB,CAAC,MAAM,CAAC;aACtC,WAAW,EAAE,CAAC;QACjB,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACzD,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAChC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC;AACzC,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { BannerContent } from "@antelopejs/interface-dms/base/banner";
2
+ import type { CellSubline, DefaultDisplays } from "@antelopejs/interface-dms/base/table-view/column-display";
3
+ import type { ComposedText } from "@antelopejs/interface-dms/base/types/composed-text";
4
+ import type { ConfirmDialog } from "@antelopejs/interface-dms/base/types/confirm-dialog";
5
+ import type { Funnel } from "@/db/tables/funnels.table";
6
+ import type { FunnelSummaryRow } from "./funnel-report";
7
+ export interface FunnelTableRow {
8
+ _id: string;
9
+ name: string;
10
+ icon: string;
11
+ detail: CellSubline;
12
+ steps: DefaultDisplays.PillItem[];
13
+ kind: FunnelSummaryRow["kind"];
14
+ entered: number;
15
+ completed: number;
16
+ conversion: number | null;
17
+ conversionText: ComposedText | string;
18
+ comparison: CellSubline | null;
19
+ status: string | null;
20
+ }
21
+ export declare function funnelTablePayload(rows: FunnelSummaryRow[], kind: string | undefined): {
22
+ results: FunnelTableRow[];
23
+ total: number;
24
+ };
25
+ export interface FunnelCoverage {
26
+ since: number | null;
27
+ period: boolean;
28
+ previous: boolean;
29
+ }
30
+ export declare function winnerBanner(rows: FunnelSummaryRow[], coverage?: FunnelCoverage): BannerContent | null;
31
+ export declare function funnelDeleteConfirmation(funnel: Funnel): ConfirmDialog;