flowgrid-sdk 1.2.0 → 1.3.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/README.md +224 -250
- package/dist/237.flowgrid.min.js +2 -0
- package/dist/237.flowgrid.min.js.map +1 -0
- package/dist/546.flowgrid.min.js +3 -0
- package/dist/546.flowgrid.min.js.LICENSE.txt +14 -0
- package/dist/546.flowgrid.min.js.map +1 -0
- package/dist/EXAMPLE.d.ts +1 -0
- package/dist/EXAMPLE.js +55 -0
- package/dist/EXAMPLE.js.map +1 -0
- package/dist/browser.d.ts +46 -103
- package/dist/browser.js +102 -0
- package/dist/browser.js.map +1 -0
- package/dist/flowgrid.min.js +1 -1
- package/dist/flowgrid.min.js.map +1 -1
- package/dist/index.d.ts +7 -8
- package/dist/index.js +64 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/client/transport.d.ts +14 -4
- package/dist/lib/client/transport.js +432 -0
- package/dist/lib/client/transport.js.map +1 -0
- package/dist/lib/consent/index.d.ts +0 -5
- package/dist/lib/consent/index.js +32 -0
- package/dist/lib/consent/index.js.map +1 -0
- package/dist/lib/consent/manager.js +336 -0
- package/dist/lib/consent/manager.js.map +1 -0
- package/dist/lib/consent/types.d.ts +3 -20
- package/dist/lib/consent/types.js +10 -0
- package/dist/lib/consent/types.js.map +1 -0
- package/dist/lib/features/analytics/attribution.d.ts +6 -47
- package/dist/lib/features/analytics/attribution.js +181 -0
- package/dist/lib/features/analytics/attribution.js.map +1 -0
- package/dist/lib/features/analytics/events.d.ts +1 -28
- package/dist/lib/features/analytics/events.js +256 -0
- package/dist/lib/features/analytics/events.js.map +1 -0
- package/dist/lib/features/analytics/funnels.js +260 -0
- package/dist/lib/features/analytics/funnels.js.map +1 -0
- package/dist/lib/features/analytics/heatmaps.d.ts +12 -19
- package/dist/lib/features/analytics/heatmaps.js +258 -0
- package/dist/lib/features/analytics/heatmaps.js.map +1 -0
- package/dist/lib/features/analytics/identify.d.ts +1 -21
- package/dist/lib/features/analytics/identify.js +213 -0
- package/dist/lib/features/analytics/identify.js.map +1 -0
- package/dist/lib/features/analytics/index.d.ts +2 -0
- package/dist/lib/features/analytics/index.js +15 -0
- package/dist/lib/features/analytics/index.js.map +1 -0
- package/dist/lib/features/analytics/page-views.d.ts +13 -30
- package/dist/lib/features/analytics/page-views.js +268 -0
- package/dist/lib/features/analytics/page-views.js.map +1 -0
- package/dist/lib/features/analytics/performance.d.ts +18 -24
- package/dist/lib/features/analytics/performance.js +232 -0
- package/dist/lib/features/analytics/performance.js.map +1 -0
- package/dist/lib/features/analytics/replay.d.ts +170 -0
- package/dist/lib/features/analytics/replay.js +381 -0
- package/dist/lib/features/analytics/replay.js.map +1 -0
- package/dist/lib/features/analytics/retention.d.ts +1 -76
- package/dist/lib/features/analytics/retention.js +135 -0
- package/dist/lib/features/analytics/retention.js.map +1 -0
- package/dist/lib/features/analytics/sessions.d.ts +12 -37
- package/dist/lib/features/analytics/sessions.js +213 -0
- package/dist/lib/features/analytics/sessions.js.map +1 -0
- package/dist/lib/features/core/activation.d.ts +1 -24
- package/dist/lib/features/core/activation.js +175 -0
- package/dist/lib/features/core/activation.js.map +1 -0
- package/dist/lib/features/core/experiment.d.ts +53 -21
- package/dist/lib/features/core/experiment.js +554 -0
- package/dist/lib/features/core/experiment.js.map +1 -0
- package/dist/lib/features/core/index.js +9 -0
- package/dist/lib/features/core/index.js.map +1 -0
- package/dist/lib/features/core/track-feature.d.ts +1 -8
- package/dist/lib/features/core/track-feature.js +119 -0
- package/dist/lib/features/core/track-feature.js.map +1 -0
- package/dist/lib/features/core/track-prompt.d.ts +5 -8
- package/dist/lib/features/core/track-prompt.js +181 -0
- package/dist/lib/features/core/track-prompt.js.map +1 -0
- package/dist/lib/features/ecommerce/cart.d.ts +1 -24
- package/dist/lib/features/ecommerce/cart.js +244 -0
- package/dist/lib/features/ecommerce/cart.js.map +1 -0
- package/dist/lib/features/ecommerce/checkout.d.ts +1 -28
- package/dist/lib/features/ecommerce/checkout.js +254 -0
- package/dist/lib/features/ecommerce/checkout.js.map +1 -0
- package/dist/lib/features/ecommerce/index.d.ts +0 -2
- package/dist/lib/features/ecommerce/index.js +15 -0
- package/dist/lib/features/ecommerce/index.js.map +1 -0
- package/dist/lib/features/ecommerce/ltv.d.ts +1 -69
- package/dist/lib/features/ecommerce/ltv.js +114 -0
- package/dist/lib/features/ecommerce/ltv.js.map +1 -0
- package/dist/lib/features/ecommerce/products.d.ts +1 -33
- package/dist/lib/features/ecommerce/products.js +223 -0
- package/dist/lib/features/ecommerce/products.js.map +1 -0
- package/dist/lib/features/ecommerce/promotions.d.ts +1 -30
- package/dist/lib/features/ecommerce/promotions.js +197 -0
- package/dist/lib/features/ecommerce/promotions.js.map +1 -0
- package/dist/lib/features/ecommerce/purchases.d.ts +1 -48
- package/dist/lib/features/ecommerce/purchases.js +193 -0
- package/dist/lib/features/ecommerce/purchases.js.map +1 -0
- package/dist/lib/features/ecommerce/refunds.d.ts +1 -27
- package/dist/lib/features/ecommerce/refunds.js +195 -0
- package/dist/lib/features/ecommerce/refunds.js.map +1 -0
- package/dist/lib/features/ecommerce/search.d.ts +1 -24
- package/dist/lib/features/ecommerce/search.js +156 -0
- package/dist/lib/features/ecommerce/search.js.map +1 -0
- package/dist/lib/features/ecommerce/subscriptions.d.ts +1 -28
- package/dist/lib/features/ecommerce/subscriptions.js +207 -0
- package/dist/lib/features/ecommerce/subscriptions.js.map +1 -0
- package/dist/lib/features/ecommerce/wishlist.d.ts +1 -28
- package/dist/lib/features/ecommerce/wishlist.js +186 -0
- package/dist/lib/features/ecommerce/wishlist.js.map +1 -0
- package/dist/lib/features/enterprise/acquisition.d.ts +2 -57
- package/dist/lib/features/enterprise/acquisition.js +166 -0
- package/dist/lib/features/enterprise/acquisition.js.map +1 -0
- package/dist/lib/features/enterprise/alerts.d.ts +1 -37
- package/dist/lib/features/enterprise/alerts.js +246 -0
- package/dist/lib/features/enterprise/alerts.js.map +1 -0
- package/dist/lib/features/enterprise/churn.d.ts +1 -42
- package/dist/lib/features/enterprise/churn.js +175 -0
- package/dist/lib/features/enterprise/churn.js.map +1 -0
- package/dist/lib/features/enterprise/cohorts.d.ts +1 -37
- package/dist/lib/features/enterprise/cohorts.js +201 -0
- package/dist/lib/features/enterprise/cohorts.js.map +1 -0
- package/dist/lib/features/enterprise/engagement.d.ts +40 -46
- package/dist/lib/features/enterprise/engagement.js +335 -0
- package/dist/lib/features/enterprise/engagement.js.map +1 -0
- package/dist/lib/features/enterprise/forecasting.d.ts +0 -50
- package/dist/lib/features/enterprise/forecasting.js +232 -0
- package/dist/lib/features/enterprise/forecasting.js.map +1 -0
- package/dist/lib/features/enterprise/index.d.ts +1 -1
- package/dist/lib/features/enterprise/index.js +76 -0
- package/dist/lib/features/enterprise/index.js.map +1 -0
- package/dist/lib/features/enterprise/monetization.d.ts +1 -60
- package/dist/lib/features/enterprise/monetization.js +146 -0
- package/dist/lib/features/enterprise/monetization.js.map +1 -0
- package/dist/lib/features/enterprise/multi-path-funnels.d.ts +1 -17
- package/dist/lib/features/enterprise/multi-path-funnels.js +205 -0
- package/dist/lib/features/enterprise/multi-path-funnels.js.map +1 -0
- package/dist/lib/features/enterprise/paths.d.ts +1 -56
- package/dist/lib/features/enterprise/paths.js +149 -0
- package/dist/lib/features/enterprise/paths.js.map +1 -0
- package/dist/lib/features/enterprise/security.d.ts +8 -57
- package/dist/lib/features/enterprise/security.js +202 -0
- package/dist/lib/features/enterprise/security.js.map +1 -0
- package/dist/lib/features/enterprise/support.d.ts +3 -42
- package/dist/lib/features/enterprise/support.js +162 -0
- package/dist/lib/features/enterprise/support.js.map +1 -0
- package/dist/lib/flowgrid.d.ts +278 -0
- package/dist/lib/flowgrid.js +323 -0
- package/dist/lib/flowgrid.js.map +1 -0
- package/dist/lib/frameworks/index.d.ts +13 -6
- package/dist/lib/frameworks/index.js +18 -0
- package/dist/lib/frameworks/index.js.map +1 -0
- package/dist/lib/frameworks/nextjs/client.js +355 -0
- package/dist/lib/frameworks/nextjs/client.js.map +1 -0
- package/dist/lib/frameworks/nextjs/index.js +31 -0
- package/dist/lib/frameworks/nextjs/index.js.map +1 -0
- package/dist/lib/frameworks/nextjs/server.js +259 -0
- package/dist/lib/frameworks/nextjs/server.js.map +1 -0
- package/dist/lib/frameworks/node/index.js +391 -0
- package/dist/lib/frameworks/node/index.js.map +1 -0
- package/dist/lib/frameworks/nuxt/index.js +288 -0
- package/dist/lib/frameworks/nuxt/index.js.map +1 -0
- package/dist/lib/frameworks/react/CookieBanner.js +166 -0
- package/dist/lib/frameworks/react/CookieBanner.js.map +1 -0
- package/dist/lib/frameworks/react/index.d.ts +2 -2
- package/dist/lib/frameworks/react/index.js +271 -0
- package/dist/lib/frameworks/react/index.js.map +1 -0
- package/dist/lib/frameworks/vue/CookieBanner.js +165 -0
- package/dist/lib/frameworks/vue/CookieBanner.js.map +1 -0
- package/dist/lib/frameworks/vue/index.d.ts +2 -2
- package/dist/lib/frameworks/vue/index.js +390 -0
- package/dist/lib/frameworks/vue/index.js.map +1 -0
- package/dist/lib/tracking/analytics/attribution.d.ts +14 -0
- package/dist/lib/tracking/analytics/attribution.js +18 -0
- package/dist/lib/tracking/analytics/attribution.js.map +1 -0
- package/dist/lib/tracking/analytics/events.d.ts +26 -0
- package/dist/lib/tracking/analytics/events.js +30 -0
- package/dist/lib/tracking/analytics/events.js.map +1 -0
- package/dist/lib/tracking/analytics/funnels.d.ts +16 -0
- package/dist/lib/tracking/analytics/funnels.js +22 -0
- package/dist/lib/tracking/analytics/funnels.js.map +1 -0
- package/dist/lib/tracking/analytics/heatmaps.d.ts +27 -0
- package/dist/lib/tracking/analytics/heatmaps.js +22 -0
- package/dist/lib/tracking/analytics/heatmaps.js.map +1 -0
- package/dist/lib/tracking/analytics/identify.d.ts +16 -0
- package/dist/lib/tracking/analytics/identify.js +22 -0
- package/dist/lib/tracking/analytics/identify.js.map +1 -0
- package/dist/lib/tracking/analytics/index.d.ts +10 -0
- package/dist/lib/tracking/analytics/index.js +11 -0
- package/dist/lib/tracking/analytics/index.js.map +1 -0
- package/dist/lib/tracking/analytics/page-views.d.ts +29 -0
- package/dist/lib/tracking/analytics/page-views.js +50 -0
- package/dist/lib/tracking/analytics/page-views.js.map +1 -0
- package/dist/lib/tracking/analytics/performance.d.ts +22 -0
- package/dist/lib/tracking/analytics/performance.js +22 -0
- package/dist/lib/tracking/analytics/performance.js.map +1 -0
- package/dist/lib/tracking/analytics/replay.d.ts +34 -0
- package/dist/lib/tracking/analytics/replay.js +46 -0
- package/dist/lib/tracking/analytics/replay.js.map +1 -0
- package/dist/lib/tracking/analytics/retention.d.ts +10 -0
- package/dist/lib/tracking/analytics/retention.js +10 -0
- package/dist/lib/tracking/analytics/retention.js.map +1 -0
- package/dist/lib/tracking/analytics/sessions.d.ts +20 -0
- package/dist/lib/tracking/analytics/sessions.js +26 -0
- package/dist/lib/tracking/analytics/sessions.js.map +1 -0
- package/dist/lib/tracking/core/activation.d.ts +23 -0
- package/dist/lib/tracking/core/activation.js +33 -0
- package/dist/lib/tracking/core/activation.js.map +1 -0
- package/dist/lib/tracking/core/experiment.d.ts +122 -0
- package/dist/lib/tracking/core/experiment.js +150 -0
- package/dist/lib/tracking/core/experiment.js.map +1 -0
- package/dist/lib/tracking/core/feature.d.ts +13 -0
- package/dist/lib/tracking/core/feature.js +14 -0
- package/dist/lib/tracking/core/feature.js.map +1 -0
- package/dist/lib/tracking/core/index.d.ts +4 -0
- package/dist/lib/tracking/core/index.js +5 -0
- package/dist/lib/tracking/core/index.js.map +1 -0
- package/dist/lib/tracking/core/prompt.d.ts +18 -0
- package/dist/lib/tracking/core/prompt.js +26 -0
- package/dist/lib/tracking/core/prompt.js.map +1 -0
- package/dist/lib/tracking/ecommerce/cart.d.ts +17 -0
- package/dist/lib/tracking/ecommerce/cart.js +22 -0
- package/dist/lib/tracking/ecommerce/cart.js.map +1 -0
- package/dist/lib/tracking/ecommerce/checkout.d.ts +17 -0
- package/dist/lib/tracking/ecommerce/checkout.js +22 -0
- package/dist/lib/tracking/ecommerce/checkout.js.map +1 -0
- package/dist/lib/tracking/ecommerce/index.d.ts +10 -0
- package/dist/lib/tracking/ecommerce/index.js +11 -0
- package/dist/lib/tracking/ecommerce/index.js.map +1 -0
- package/dist/lib/tracking/ecommerce/ltv.d.ts +15 -0
- package/dist/lib/tracking/ecommerce/ltv.js +14 -0
- package/dist/lib/tracking/ecommerce/ltv.js.map +1 -0
- package/dist/lib/tracking/ecommerce/products.d.ts +15 -0
- package/dist/lib/tracking/ecommerce/products.js +18 -0
- package/dist/lib/tracking/ecommerce/products.js.map +1 -0
- package/dist/lib/tracking/ecommerce/promotions.d.ts +14 -0
- package/dist/lib/tracking/ecommerce/promotions.js +25 -0
- package/dist/lib/tracking/ecommerce/promotions.js.map +1 -0
- package/dist/lib/tracking/ecommerce/purchases.d.ts +11 -0
- package/dist/lib/tracking/ecommerce/purchases.js +10 -0
- package/dist/lib/tracking/ecommerce/purchases.js.map +1 -0
- package/dist/lib/tracking/ecommerce/refunds.d.ts +17 -0
- package/dist/lib/tracking/ecommerce/refunds.js +22 -0
- package/dist/lib/tracking/ecommerce/refunds.js.map +1 -0
- package/dist/lib/tracking/ecommerce/search.d.ts +24 -0
- package/dist/lib/tracking/ecommerce/search.js +22 -0
- package/dist/lib/tracking/ecommerce/search.js.map +1 -0
- package/dist/lib/tracking/ecommerce/subscriptions.d.ts +21 -0
- package/dist/lib/tracking/ecommerce/subscriptions.js +38 -0
- package/dist/lib/tracking/ecommerce/subscriptions.js.map +1 -0
- package/dist/lib/tracking/ecommerce/wishlist.d.ts +19 -0
- package/dist/lib/tracking/ecommerce/wishlist.js +26 -0
- package/dist/lib/tracking/ecommerce/wishlist.js.map +1 -0
- package/dist/lib/tracking/enterprise/acquisition.d.ts +25 -0
- package/dist/lib/tracking/enterprise/acquisition.js +22 -0
- package/dist/lib/tracking/enterprise/acquisition.js.map +1 -0
- package/dist/lib/tracking/enterprise/alerts.d.ts +32 -0
- package/dist/lib/tracking/enterprise/alerts.js +30 -0
- package/dist/lib/tracking/enterprise/alerts.js.map +1 -0
- package/dist/lib/tracking/enterprise/churn.d.ts +23 -0
- package/dist/lib/tracking/enterprise/churn.js +22 -0
- package/dist/lib/tracking/enterprise/churn.js.map +1 -0
- package/dist/lib/tracking/enterprise/cohorts.d.ts +18 -0
- package/dist/lib/tracking/enterprise/cohorts.js +18 -0
- package/dist/lib/tracking/enterprise/cohorts.js.map +1 -0
- package/dist/lib/tracking/enterprise/engagement.d.ts +31 -0
- package/dist/lib/tracking/enterprise/engagement.js +44 -0
- package/dist/lib/tracking/enterprise/engagement.js.map +1 -0
- package/dist/lib/tracking/enterprise/forecasting.d.ts +18 -0
- package/dist/lib/tracking/enterprise/forecasting.js +22 -0
- package/dist/lib/tracking/enterprise/forecasting.js.map +1 -0
- package/dist/lib/tracking/enterprise/index.d.ts +11 -0
- package/dist/lib/tracking/enterprise/index.js +12 -0
- package/dist/lib/tracking/enterprise/index.js.map +1 -0
- package/dist/lib/tracking/enterprise/monetization.d.ts +14 -0
- package/dist/lib/tracking/enterprise/monetization.js +10 -0
- package/dist/lib/tracking/enterprise/monetization.js.map +1 -0
- package/dist/lib/tracking/enterprise/multi-path-funnels.d.ts +20 -0
- package/dist/lib/tracking/enterprise/multi-path-funnels.js +18 -0
- package/dist/lib/tracking/enterprise/multi-path-funnels.js.map +1 -0
- package/dist/lib/tracking/enterprise/paths.d.ts +20 -0
- package/dist/lib/tracking/enterprise/paths.js +18 -0
- package/dist/lib/tracking/enterprise/paths.js.map +1 -0
- package/dist/lib/tracking/enterprise/security.d.ts +28 -0
- package/dist/lib/tracking/enterprise/security.js +26 -0
- package/dist/lib/tracking/enterprise/security.js.map +1 -0
- package/dist/lib/tracking/enterprise/support.d.ts +25 -0
- package/dist/lib/tracking/enterprise/support.js +22 -0
- package/dist/lib/tracking/enterprise/support.js.map +1 -0
- package/dist/lib/tracking/index.d.ts +4 -0
- package/dist/lib/tracking/index.js +5 -0
- package/dist/lib/tracking/index.js.map +1 -0
- package/dist/lib/types/analytics.d.ts +10 -2
- package/dist/lib/types/analytics.js +6 -0
- package/dist/lib/types/analytics.js.map +1 -0
- package/dist/lib/types/common.js +6 -0
- package/dist/lib/types/common.js.map +1 -0
- package/dist/lib/types/ecommerce.js +6 -0
- package/dist/lib/types/ecommerce.js.map +1 -0
- package/dist/lib/types/index.js +8 -0
- package/dist/lib/types/index.js.map +1 -0
- package/dist/lib/utils/browser.d.ts +16 -0
- package/dist/lib/utils/browser.js +32 -0
- package/dist/lib/utils/browser.js.map +1 -0
- package/dist/lib/utils/identity.js +346 -0
- package/dist/lib/utils/identity.js.map +1 -0
- package/dist/lib/utils/storage.js +105 -0
- package/dist/lib/utils/storage.js.map +1 -0
- package/dist/umd/237.index.js +2 -0
- package/dist/umd/237.index.js.map +1 -0
- package/dist/umd/546.index.js +3 -0
- package/dist/umd/546.index.js.LICENSE.txt +14 -0
- package/dist/umd/546.index.js.map +1 -0
- package/dist/umd/index.js +2 -0
- package/dist/umd/index.js.map +1 -0
- package/package.json +27 -80
- package/dist/lib/features/ecommerce/inventory.d.ts +0 -219
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Enterprise - Advanced Cohorts & Segmentation
|
|
3
|
+
* @module features/enterprise/cohorts
|
|
4
|
+
*
|
|
5
|
+
* @description
|
|
6
|
+
* Generate behavioral and acquisition cohorts for granular analysis.
|
|
7
|
+
* Segment users by behavior, acquisition source, and custom criteria.
|
|
8
|
+
*
|
|
9
|
+
* @useCases
|
|
10
|
+
* - Create behavior-based cohorts
|
|
11
|
+
* - Segment by acquisition source
|
|
12
|
+
* - Track paid vs free user cohorts
|
|
13
|
+
* - Dynamic segmentation rules
|
|
14
|
+
* - Cohort comparison analysis
|
|
15
|
+
*
|
|
16
|
+
* @metrics
|
|
17
|
+
* - Cohort size
|
|
18
|
+
* - Cohort retention
|
|
19
|
+
* - Cohort conversion
|
|
20
|
+
* - Segment growth rate
|
|
21
|
+
* - Cross-segment behavior
|
|
22
|
+
*
|
|
23
|
+
* @chartData
|
|
24
|
+
* - Bar chart: Cohort sizes
|
|
25
|
+
* - Line chart: Cohort trends
|
|
26
|
+
* - Heatmap: Cohort retention matrix
|
|
27
|
+
* - Comparison: Cohort A vs B
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* const cohorts = new Cohorts(webId, endpoint, apiKey);
|
|
32
|
+
*
|
|
33
|
+
* // Create a behavioral cohort
|
|
34
|
+
* await cohorts.createCohort({
|
|
35
|
+
* name: 'Power Users',
|
|
36
|
+
* type: 'behavioral',
|
|
37
|
+
* rules: [{ attribute: 'sessions_per_week', operator: 'gte', value: 5 }]
|
|
38
|
+
* });
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
import { FlowGridTransport } from "../../client/transport";
|
|
42
|
+
// ============================================================================
|
|
43
|
+
// HELPER FUNCTIONS
|
|
44
|
+
// ============================================================================
|
|
45
|
+
/**
|
|
46
|
+
* Evaluate if a user matches cohort rules.
|
|
47
|
+
*/
|
|
48
|
+
export function evaluateCohortRules(userAttributes, rules) {
|
|
49
|
+
let result = true;
|
|
50
|
+
let currentOperator = 'and';
|
|
51
|
+
for (const rule of rules) {
|
|
52
|
+
const attributeValue = userAttributes[rule.attribute];
|
|
53
|
+
const ruleResult = evaluateRule(attributeValue, rule.operator, rule.value);
|
|
54
|
+
if (currentOperator === 'and') {
|
|
55
|
+
result = result && ruleResult;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
result = result || ruleResult;
|
|
59
|
+
}
|
|
60
|
+
currentOperator = rule.logicalOperator ?? 'and';
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Evaluate a single rule.
|
|
66
|
+
*/
|
|
67
|
+
function evaluateRule(attributeValue, operator, ruleValue) {
|
|
68
|
+
switch (operator) {
|
|
69
|
+
case 'equals':
|
|
70
|
+
return attributeValue === ruleValue;
|
|
71
|
+
case 'not_equals':
|
|
72
|
+
return attributeValue !== ruleValue;
|
|
73
|
+
case 'contains':
|
|
74
|
+
return String(attributeValue).includes(String(ruleValue));
|
|
75
|
+
case 'not_contains':
|
|
76
|
+
return !String(attributeValue).includes(String(ruleValue));
|
|
77
|
+
case 'gt':
|
|
78
|
+
return Number(attributeValue) > Number(ruleValue);
|
|
79
|
+
case 'gte':
|
|
80
|
+
return Number(attributeValue) >= Number(ruleValue);
|
|
81
|
+
case 'lt':
|
|
82
|
+
return Number(attributeValue) < Number(ruleValue);
|
|
83
|
+
case 'lte':
|
|
84
|
+
return Number(attributeValue) <= Number(ruleValue);
|
|
85
|
+
case 'in':
|
|
86
|
+
return Array.isArray(ruleValue) && ruleValue.includes(attributeValue);
|
|
87
|
+
case 'not_in':
|
|
88
|
+
return Array.isArray(ruleValue) && !ruleValue.includes(attributeValue);
|
|
89
|
+
case 'exists':
|
|
90
|
+
return attributeValue !== undefined && attributeValue !== null;
|
|
91
|
+
case 'not_exists':
|
|
92
|
+
return attributeValue === undefined || attributeValue === null;
|
|
93
|
+
case 'between':
|
|
94
|
+
if (Array.isArray(ruleValue) && ruleValue.length === 2) {
|
|
95
|
+
const num = Number(attributeValue);
|
|
96
|
+
return num >= Number(ruleValue[0]) && num <= Number(ruleValue[1]);
|
|
97
|
+
}
|
|
98
|
+
return false;
|
|
99
|
+
default:
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Generate cohort ID from name.
|
|
105
|
+
*/
|
|
106
|
+
export function generateCohortId(name) {
|
|
107
|
+
return name
|
|
108
|
+
.toLowerCase()
|
|
109
|
+
.replace(/[^a-z0-9]+/g, '_')
|
|
110
|
+
.replace(/^_|_$/g, '');
|
|
111
|
+
}
|
|
112
|
+
// ============================================================================
|
|
113
|
+
// MAIN CLASS
|
|
114
|
+
// ============================================================================
|
|
115
|
+
/**
|
|
116
|
+
* Advanced cohorts and segmentation class.
|
|
117
|
+
*/
|
|
118
|
+
export class Cohorts extends FlowGridTransport {
|
|
119
|
+
/**
|
|
120
|
+
* Create a new cohort.
|
|
121
|
+
*/
|
|
122
|
+
async createCohort(definition) {
|
|
123
|
+
const cohortId = definition.cohortId ?? generateCohortId(definition.name);
|
|
124
|
+
return await this.initFeature("cohorts.create", {
|
|
125
|
+
type: "cohorts",
|
|
126
|
+
cohortId,
|
|
127
|
+
name: definition.name,
|
|
128
|
+
description: definition.description,
|
|
129
|
+
cohortType: definition.type,
|
|
130
|
+
rules: definition.rules,
|
|
131
|
+
dynamic: definition.dynamic ?? true,
|
|
132
|
+
timeWindow: definition.timeWindow,
|
|
133
|
+
timestamp: new Date().toISOString()
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Update an existing cohort.
|
|
138
|
+
*/
|
|
139
|
+
async updateCohort(cohortId, updates) {
|
|
140
|
+
const { type: cohortType, ...rest } = updates;
|
|
141
|
+
return await this.initFeature("cohorts.update", {
|
|
142
|
+
type: "cohorts",
|
|
143
|
+
cohortId,
|
|
144
|
+
cohortType,
|
|
145
|
+
...rest,
|
|
146
|
+
timestamp: new Date().toISOString()
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Delete a cohort.
|
|
151
|
+
*/
|
|
152
|
+
async deleteCohort(cohortId) {
|
|
153
|
+
return await this.initFeature("cohorts.delete", {
|
|
154
|
+
type: "cohorts",
|
|
155
|
+
cohortId,
|
|
156
|
+
timestamp: new Date().toISOString()
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* List all cohorts.
|
|
161
|
+
*/
|
|
162
|
+
async listCohorts(filter) {
|
|
163
|
+
return await this.initFeature("cohorts.list", {
|
|
164
|
+
type: "cohorts",
|
|
165
|
+
filter,
|
|
166
|
+
timestamp: new Date().toISOString()
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Check if user belongs to cohort.
|
|
171
|
+
*/
|
|
172
|
+
async isUserInCohort(userId, cohortId) {
|
|
173
|
+
return await this.initFeature("cohorts.check_membership", {
|
|
174
|
+
type: "cohorts",
|
|
175
|
+
userId,
|
|
176
|
+
cohortId,
|
|
177
|
+
timestamp: new Date().toISOString()
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Create a segment.
|
|
182
|
+
*/
|
|
183
|
+
async createSegment(definition) {
|
|
184
|
+
return await this.initFeature("cohorts.create_segment", {
|
|
185
|
+
type: "cohorts",
|
|
186
|
+
...definition,
|
|
187
|
+
timestamp: new Date().toISOString()
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Compare two cohorts.
|
|
192
|
+
*/
|
|
193
|
+
async compareCohorts(config) {
|
|
194
|
+
return await this.initFeature("cohorts.compare", {
|
|
195
|
+
type: "cohorts",
|
|
196
|
+
...config,
|
|
197
|
+
timestamp: new Date().toISOString()
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=cohorts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cohorts.js","sourceRoot":"","sources":["../../../../src/lib/features/enterprise/cohorts.ts"],"names":[],"mappings":"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"}
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
* ```
|
|
40
40
|
*/
|
|
41
41
|
import { FlowGridTransport } from "../../client/transport";
|
|
42
|
-
import { DateRangeFilter, TimeSeriesData
|
|
42
|
+
import { DateRangeFilter, TimeSeriesData } from "../../types";
|
|
43
|
+
import { type Teardown } from "../../utils/browser";
|
|
43
44
|
/**
|
|
44
45
|
* Configuration for tracking feature dwell time.
|
|
45
46
|
*/
|
|
@@ -203,52 +204,45 @@ export declare class Engagement extends FlowGridTransport {
|
|
|
203
204
|
*/
|
|
204
205
|
trackUserActivity(config: UserActivityConfig): Promise<EngagementResponse>;
|
|
205
206
|
/**
|
|
206
|
-
*
|
|
207
|
+
* Auto-accumulate dwell time on a feature while the page is visible. Returns
|
|
208
|
+
* a teardown that emits a single `trackDwellTime` event with the elapsed
|
|
209
|
+
* active milliseconds.
|
|
207
210
|
*/
|
|
208
|
-
|
|
211
|
+
autoTrackDwell(featureId: string, options?: {
|
|
212
|
+
userId?: string;
|
|
213
|
+
sessionId?: string;
|
|
214
|
+
}): Teardown;
|
|
209
215
|
/**
|
|
210
|
-
*
|
|
216
|
+
* Auto-track session-level engagement signals in the browser:
|
|
217
|
+
*
|
|
218
|
+
* - **Session depth** — counts SPA navigations, click/keyboard actions, and
|
|
219
|
+
* total session duration; emits a single `trackSessionDepth` on
|
|
220
|
+
* `pagehide`.
|
|
221
|
+
* - **User activity** — classifies the user as `active` (recent input),
|
|
222
|
+
* `passive` (visible but idle) or `idle` (tab hidden), and emits
|
|
223
|
+
* `trackUserActivity` on every state transition with the time spent in
|
|
224
|
+
* the previous state.
|
|
225
|
+
*
|
|
226
|
+
* The session id is read from the same `sessionStorage` key written by
|
|
227
|
+
* {@link Sessions.autoTrack} (`flowgrid:sessionId`) so the two modules
|
|
228
|
+
* stay correlated. If no session id is present, a synthetic one is
|
|
229
|
+
* generated for the page lifetime.
|
|
230
|
+
*
|
|
231
|
+
* Safe no-op outside the browser.
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* ```ts
|
|
235
|
+
* const stop = fg.engagement.client.autoTrack({ userId: "u_1" });
|
|
236
|
+
* // ...later
|
|
237
|
+
* stop();
|
|
238
|
+
* ```
|
|
211
239
|
*/
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
getTopEngagedUsers(filter?: DateRangeFilter, limit?: number): Promise<Array<{
|
|
221
|
-
userId: string;
|
|
222
|
-
score: number;
|
|
223
|
-
level: string;
|
|
224
|
-
}>>;
|
|
225
|
-
/**
|
|
226
|
-
* Get engagement by feature.
|
|
227
|
-
*/
|
|
228
|
-
getEngagementByFeature(filter?: DateRangeFilter): Promise<Array<{
|
|
229
|
-
featureId: string;
|
|
230
|
-
avgDwellTime: number;
|
|
231
|
-
uniqueUsers: number;
|
|
232
|
-
}>>;
|
|
233
|
-
/**
|
|
234
|
-
* Get active users at any granularity (day, week, month).
|
|
235
|
-
*/
|
|
236
|
-
getActiveUsers(config: ActiveUsersConfig): Promise<ActiveUsersResponse>;
|
|
237
|
-
/**
|
|
238
|
-
* Get daily active users.
|
|
239
|
-
*/
|
|
240
|
-
getDAU(filter?: DateRangeFilter): Promise<ActiveUsersResponse>;
|
|
241
|
-
/**
|
|
242
|
-
* Get weekly active users.
|
|
243
|
-
*/
|
|
244
|
-
getWAU(filter?: DateRangeFilter): Promise<ActiveUsersResponse>;
|
|
245
|
-
/**
|
|
246
|
-
* Get monthly active users.
|
|
247
|
-
*/
|
|
248
|
-
getMAU(filter?: DateRangeFilter): Promise<ActiveUsersResponse>;
|
|
249
|
-
/**
|
|
250
|
-
* Get DAU/WAU/MAU stickiness ratios.
|
|
251
|
-
* Fetches all three in parallel and computes ratios (guards division by zero).
|
|
252
|
-
*/
|
|
253
|
-
getActiveUserRatios(filter?: DateRangeFilter): Promise<ActiveUserRatios>;
|
|
240
|
+
autoTrack(options?: {
|
|
241
|
+
userId?: string;
|
|
242
|
+
sessionId?: string;
|
|
243
|
+
/** Idle threshold (ms) without input before a visible user is "passive". Default 30s. */
|
|
244
|
+
idleAfterMs?: number;
|
|
245
|
+
/** Activity polling interval (ms). Default 5s. */
|
|
246
|
+
pollMs?: number;
|
|
247
|
+
}): Teardown;
|
|
254
248
|
}
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Enterprise - Engagement Analytics
|
|
3
|
+
* @module features/enterprise/engagement
|
|
4
|
+
*
|
|
5
|
+
* @description
|
|
6
|
+
* Track deep user engagement beyond activation including
|
|
7
|
+
* feature dwell time, session depth, and content consumption.
|
|
8
|
+
*
|
|
9
|
+
* @useCases
|
|
10
|
+
* - Measure feature dwell time
|
|
11
|
+
* - Track session depth and engagement
|
|
12
|
+
* - Monitor content consumption patterns
|
|
13
|
+
* - Distinguish active vs passive users
|
|
14
|
+
* - Correlate engagement with retention
|
|
15
|
+
*
|
|
16
|
+
* @metrics
|
|
17
|
+
* - Average engagement time
|
|
18
|
+
* - Feature dwell time
|
|
19
|
+
* - Session depth score
|
|
20
|
+
* - Content consumption rate
|
|
21
|
+
* - Active user ratio
|
|
22
|
+
*
|
|
23
|
+
* @chartData
|
|
24
|
+
* - Line chart: Engagement over time
|
|
25
|
+
* - Bar chart: Engagement by feature
|
|
26
|
+
* - Heatmap: Engagement by time of day
|
|
27
|
+
* - Distribution: User engagement scores
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* const engagement = new Engagement(webId, endpoint, apiKey);
|
|
32
|
+
*
|
|
33
|
+
* // Track feature dwell time
|
|
34
|
+
* await engagement.trackDwellTime({
|
|
35
|
+
* featureId: 'dashboard',
|
|
36
|
+
* userId: 'user_123',
|
|
37
|
+
* dwellTimeMs: 45000
|
|
38
|
+
* });
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
import { FlowGridTransport } from "../../client/transport";
|
|
42
|
+
import { isBrowser, getDocument, getWindow, combineTeardowns } from "../../utils/browser";
|
|
43
|
+
// ============================================================================
|
|
44
|
+
// HELPER FUNCTIONS
|
|
45
|
+
// ============================================================================
|
|
46
|
+
/**
|
|
47
|
+
* Calculate engagement score from multiple factors.
|
|
48
|
+
*/
|
|
49
|
+
export function calculateEngagementScore(dwellTime, sessionDepth, activityRatio, contentCompletion) {
|
|
50
|
+
const weights = {
|
|
51
|
+
dwellTime: 0.25,
|
|
52
|
+
sessionDepth: 0.25,
|
|
53
|
+
activityRatio: 0.30,
|
|
54
|
+
contentCompletion: 0.20
|
|
55
|
+
};
|
|
56
|
+
return Math.round((dwellTime * weights.dwellTime +
|
|
57
|
+
sessionDepth * weights.sessionDepth +
|
|
58
|
+
activityRatio * weights.activityRatio +
|
|
59
|
+
contentCompletion * weights.contentCompletion) * 100) / 100;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Classify user engagement level.
|
|
63
|
+
*/
|
|
64
|
+
export function classifyEngagementLevel(score) {
|
|
65
|
+
if (score < 25)
|
|
66
|
+
return 'low';
|
|
67
|
+
if (score < 50)
|
|
68
|
+
return 'medium';
|
|
69
|
+
if (score < 75)
|
|
70
|
+
return 'high';
|
|
71
|
+
return 'power';
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Calculate session depth score.
|
|
75
|
+
*/
|
|
76
|
+
export function calculateSessionDepthScore(pagesVisited, featuresUsed, actionsTaken) {
|
|
77
|
+
const pageScore = Math.min(pagesVisited / 10, 1) * 30;
|
|
78
|
+
const featureScore = Math.min(featuresUsed / 5, 1) * 40;
|
|
79
|
+
const actionScore = Math.min(actionsTaken / 20, 1) * 30;
|
|
80
|
+
return Math.round(pageScore + featureScore + actionScore);
|
|
81
|
+
}
|
|
82
|
+
// ============================================================================
|
|
83
|
+
// MAIN CLASS
|
|
84
|
+
// ============================================================================
|
|
85
|
+
/**
|
|
86
|
+
* Engagement analytics tracking class.
|
|
87
|
+
*/
|
|
88
|
+
export class Engagement extends FlowGridTransport {
|
|
89
|
+
/**
|
|
90
|
+
* Track feature dwell time.
|
|
91
|
+
*/
|
|
92
|
+
async trackDwellTime(config) {
|
|
93
|
+
return await this.initFeature("engagement.dwell_time", {
|
|
94
|
+
type: "engagement",
|
|
95
|
+
featureId: config.featureId,
|
|
96
|
+
userId: config.userId,
|
|
97
|
+
sessionId: config.sessionId,
|
|
98
|
+
dwellTimeMs: config.dwellTimeMs,
|
|
99
|
+
wasActive: config.wasActive ?? true,
|
|
100
|
+
...config.properties,
|
|
101
|
+
timestamp: new Date().toISOString()
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Track session depth.
|
|
106
|
+
*/
|
|
107
|
+
async trackSessionDepth(config) {
|
|
108
|
+
const depthScore = calculateSessionDepthScore(config.pagesVisited, config.featuresUsed, config.actionsTaken);
|
|
109
|
+
return await this.initFeature("engagement.session_depth", {
|
|
110
|
+
type: "engagement",
|
|
111
|
+
sessionId: config.sessionId,
|
|
112
|
+
userId: config.userId,
|
|
113
|
+
pagesVisited: config.pagesVisited,
|
|
114
|
+
featuresUsed: config.featuresUsed,
|
|
115
|
+
actionsTaken: config.actionsTaken,
|
|
116
|
+
durationMs: config.durationMs,
|
|
117
|
+
depthScore,
|
|
118
|
+
timestamp: new Date().toISOString()
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Track content consumption.
|
|
123
|
+
*/
|
|
124
|
+
async trackContentConsumption(config) {
|
|
125
|
+
return await this.initFeature("engagement.content_consumption", {
|
|
126
|
+
type: "engagement",
|
|
127
|
+
contentId: config.contentId,
|
|
128
|
+
contentType: config.contentType,
|
|
129
|
+
userId: config.userId,
|
|
130
|
+
percentageConsumed: config.percentageConsumed,
|
|
131
|
+
timeSpentMs: config.timeSpentMs,
|
|
132
|
+
completed: config.completed ?? config.percentageConsumed >= 90,
|
|
133
|
+
...config.properties,
|
|
134
|
+
timestamp: new Date().toISOString()
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Track user activity state.
|
|
139
|
+
*/
|
|
140
|
+
async trackUserActivity(config) {
|
|
141
|
+
return await this.initFeature("engagement.user_activity", {
|
|
142
|
+
type: "engagement",
|
|
143
|
+
userId: config.userId,
|
|
144
|
+
activityType: config.activityType,
|
|
145
|
+
durationMs: config.durationMs,
|
|
146
|
+
sessionId: config.sessionId,
|
|
147
|
+
timestamp: new Date().toISOString()
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
// DAU / WAU / MAU
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
/**
|
|
154
|
+
* Auto-accumulate dwell time on a feature while the page is visible. Returns
|
|
155
|
+
* a teardown that emits a single `trackDwellTime` event with the elapsed
|
|
156
|
+
* active milliseconds.
|
|
157
|
+
*/
|
|
158
|
+
autoTrackDwell(featureId, options = {}) {
|
|
159
|
+
if (!isBrowser())
|
|
160
|
+
return () => { };
|
|
161
|
+
const doc = getDocument();
|
|
162
|
+
if (!doc)
|
|
163
|
+
return () => { };
|
|
164
|
+
let activeMs = 0;
|
|
165
|
+
let lastTick = doc.visibilityState === "visible" ? Date.now() : 0;
|
|
166
|
+
const onVisibility = () => {
|
|
167
|
+
const now = Date.now();
|
|
168
|
+
if (doc.visibilityState === "visible") {
|
|
169
|
+
lastTick = now;
|
|
170
|
+
}
|
|
171
|
+
else if (lastTick) {
|
|
172
|
+
activeMs += now - lastTick;
|
|
173
|
+
lastTick = 0;
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
doc.addEventListener("visibilitychange", onVisibility);
|
|
177
|
+
let torndown = false;
|
|
178
|
+
return () => {
|
|
179
|
+
if (torndown)
|
|
180
|
+
return;
|
|
181
|
+
torndown = true;
|
|
182
|
+
doc.removeEventListener("visibilitychange", onVisibility);
|
|
183
|
+
if (lastTick) {
|
|
184
|
+
activeMs += Date.now() - lastTick;
|
|
185
|
+
lastTick = 0;
|
|
186
|
+
}
|
|
187
|
+
if (activeMs > 0) {
|
|
188
|
+
void this.trackDwellTime({
|
|
189
|
+
featureId,
|
|
190
|
+
dwellTimeMs: activeMs,
|
|
191
|
+
userId: options.userId,
|
|
192
|
+
sessionId: options.sessionId,
|
|
193
|
+
wasActive: true,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Auto-track session-level engagement signals in the browser:
|
|
200
|
+
*
|
|
201
|
+
* - **Session depth** — counts SPA navigations, click/keyboard actions, and
|
|
202
|
+
* total session duration; emits a single `trackSessionDepth` on
|
|
203
|
+
* `pagehide`.
|
|
204
|
+
* - **User activity** — classifies the user as `active` (recent input),
|
|
205
|
+
* `passive` (visible but idle) or `idle` (tab hidden), and emits
|
|
206
|
+
* `trackUserActivity` on every state transition with the time spent in
|
|
207
|
+
* the previous state.
|
|
208
|
+
*
|
|
209
|
+
* The session id is read from the same `sessionStorage` key written by
|
|
210
|
+
* {@link Sessions.autoTrack} (`flowgrid:sessionId`) so the two modules
|
|
211
|
+
* stay correlated. If no session id is present, a synthetic one is
|
|
212
|
+
* generated for the page lifetime.
|
|
213
|
+
*
|
|
214
|
+
* Safe no-op outside the browser.
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```ts
|
|
218
|
+
* const stop = fg.engagement.client.autoTrack({ userId: "u_1" });
|
|
219
|
+
* // ...later
|
|
220
|
+
* stop();
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
autoTrack(options = {}) {
|
|
224
|
+
if (!isBrowser())
|
|
225
|
+
return () => { };
|
|
226
|
+
const win = getWindow();
|
|
227
|
+
const doc = getDocument();
|
|
228
|
+
if (!win || !doc)
|
|
229
|
+
return () => { };
|
|
230
|
+
const idleAfterMs = options.idleAfterMs ?? 30000;
|
|
231
|
+
const pollMs = options.pollMs ?? 5000;
|
|
232
|
+
// Resolve session id: prefer the one written by Sessions.autoTrack so
|
|
233
|
+
// depth / activity events line up with the canonical session.
|
|
234
|
+
let sessionId = options.sessionId;
|
|
235
|
+
if (!sessionId) {
|
|
236
|
+
try {
|
|
237
|
+
sessionId = win.sessionStorage.getItem("flowgrid:sessionId") || undefined;
|
|
238
|
+
}
|
|
239
|
+
catch { /* private mode */ }
|
|
240
|
+
}
|
|
241
|
+
if (!sessionId) {
|
|
242
|
+
sessionId = `eng_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
|
|
243
|
+
}
|
|
244
|
+
const startedAt = Date.now();
|
|
245
|
+
let pagesVisited = 1;
|
|
246
|
+
const featuresUsed = new Set();
|
|
247
|
+
let actionsTaken = 0;
|
|
248
|
+
let lastInputAt = Date.now();
|
|
249
|
+
let currentState = doc.visibilityState === "visible" ? "active" : "idle";
|
|
250
|
+
let stateEnteredAt = Date.now();
|
|
251
|
+
// --- SPA navigation count
|
|
252
|
+
const origPush = win.history.pushState;
|
|
253
|
+
const origReplace = win.history.replaceState;
|
|
254
|
+
const onNav = () => { pagesVisited++; };
|
|
255
|
+
win.history.pushState = function (...args) {
|
|
256
|
+
const r = origPush.apply(this, args);
|
|
257
|
+
onNav();
|
|
258
|
+
return r;
|
|
259
|
+
};
|
|
260
|
+
win.history.replaceState = function (...args) {
|
|
261
|
+
const r = origReplace.apply(this, args);
|
|
262
|
+
onNav();
|
|
263
|
+
return r;
|
|
264
|
+
};
|
|
265
|
+
win.addEventListener("popstate", onNav);
|
|
266
|
+
// --- User input → action count + activity ping
|
|
267
|
+
const onInput = (ev) => {
|
|
268
|
+
actionsTaken++;
|
|
269
|
+
lastInputAt = Date.now();
|
|
270
|
+
// Optionally collect feature ids from a `data-flowgrid-feature` attribute.
|
|
271
|
+
const target = ev.target;
|
|
272
|
+
const featureAttr = target?.closest?.("[data-flowgrid-feature]")
|
|
273
|
+
?.getAttribute("data-flowgrid-feature");
|
|
274
|
+
if (featureAttr)
|
|
275
|
+
featuresUsed.add(featureAttr);
|
|
276
|
+
};
|
|
277
|
+
doc.addEventListener("click", onInput, { capture: true });
|
|
278
|
+
doc.addEventListener("keydown", onInput, { capture: true });
|
|
279
|
+
doc.addEventListener("scroll", onInput, { capture: true, passive: true });
|
|
280
|
+
const transition = (next) => {
|
|
281
|
+
if (next === currentState)
|
|
282
|
+
return;
|
|
283
|
+
const now = Date.now();
|
|
284
|
+
const durationMs = now - stateEnteredAt;
|
|
285
|
+
const prev = currentState;
|
|
286
|
+
currentState = next;
|
|
287
|
+
stateEnteredAt = now;
|
|
288
|
+
if (durationMs > 0 && options.userId) {
|
|
289
|
+
void this.trackUserActivity({
|
|
290
|
+
userId: options.userId,
|
|
291
|
+
activityType: prev,
|
|
292
|
+
durationMs,
|
|
293
|
+
sessionId,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
// --- Periodic activity classifier
|
|
298
|
+
const tick = () => {
|
|
299
|
+
const now = Date.now();
|
|
300
|
+
let next;
|
|
301
|
+
if (doc.visibilityState !== "visible")
|
|
302
|
+
next = "idle";
|
|
303
|
+
else if (now - lastInputAt < idleAfterMs)
|
|
304
|
+
next = "active";
|
|
305
|
+
else
|
|
306
|
+
next = "passive";
|
|
307
|
+
transition(next);
|
|
308
|
+
};
|
|
309
|
+
const ticker = win.setInterval(tick, pollMs);
|
|
310
|
+
const onVisibility = () => tick();
|
|
311
|
+
doc.addEventListener("visibilitychange", onVisibility);
|
|
312
|
+
// --- Emit final session depth on pagehide
|
|
313
|
+
let depthSent = false;
|
|
314
|
+
const sendDepth = () => {
|
|
315
|
+
if (depthSent)
|
|
316
|
+
return;
|
|
317
|
+
depthSent = true;
|
|
318
|
+
transition(doc.visibilityState === "visible" ? currentState : "idle");
|
|
319
|
+
const durationMs = Date.now() - startedAt;
|
|
320
|
+
if (durationMs <= 0)
|
|
321
|
+
return;
|
|
322
|
+
void this.trackSessionDepth({
|
|
323
|
+
sessionId: sessionId,
|
|
324
|
+
userId: options.userId,
|
|
325
|
+
pagesVisited,
|
|
326
|
+
featuresUsed: featuresUsed.size,
|
|
327
|
+
actionsTaken,
|
|
328
|
+
durationMs,
|
|
329
|
+
});
|
|
330
|
+
};
|
|
331
|
+
win.addEventListener("pagehide", sendDepth);
|
|
332
|
+
return combineTeardowns(() => win.clearInterval(ticker), () => doc.removeEventListener("visibilitychange", onVisibility), () => doc.removeEventListener("click", onInput, true), () => doc.removeEventListener("keydown", onInput, true), () => doc.removeEventListener("scroll", onInput, true), () => win.removeEventListener("popstate", onNav), () => win.removeEventListener("pagehide", sendDepth), () => { win.history.pushState = origPush; win.history.replaceState = origReplace; }, () => sendDepth());
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
//# sourceMappingURL=engagement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engagement.js","sourceRoot":"","sources":["../../../../src/lib/features/enterprise/engagement.ts"],"names":[],"mappings":"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"}
|