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.
Files changed (314) hide show
  1. package/README.md +224 -250
  2. package/dist/237.flowgrid.min.js +2 -0
  3. package/dist/237.flowgrid.min.js.map +1 -0
  4. package/dist/546.flowgrid.min.js +3 -0
  5. package/dist/546.flowgrid.min.js.LICENSE.txt +14 -0
  6. package/dist/546.flowgrid.min.js.map +1 -0
  7. package/dist/EXAMPLE.d.ts +1 -0
  8. package/dist/EXAMPLE.js +55 -0
  9. package/dist/EXAMPLE.js.map +1 -0
  10. package/dist/browser.d.ts +46 -103
  11. package/dist/browser.js +102 -0
  12. package/dist/browser.js.map +1 -0
  13. package/dist/flowgrid.min.js +1 -1
  14. package/dist/flowgrid.min.js.map +1 -1
  15. package/dist/index.d.ts +7 -8
  16. package/dist/index.js +64 -1
  17. package/dist/index.js.map +1 -1
  18. package/dist/lib/client/transport.d.ts +14 -4
  19. package/dist/lib/client/transport.js +432 -0
  20. package/dist/lib/client/transport.js.map +1 -0
  21. package/dist/lib/consent/index.d.ts +0 -5
  22. package/dist/lib/consent/index.js +32 -0
  23. package/dist/lib/consent/index.js.map +1 -0
  24. package/dist/lib/consent/manager.js +336 -0
  25. package/dist/lib/consent/manager.js.map +1 -0
  26. package/dist/lib/consent/types.d.ts +3 -20
  27. package/dist/lib/consent/types.js +10 -0
  28. package/dist/lib/consent/types.js.map +1 -0
  29. package/dist/lib/features/analytics/attribution.d.ts +6 -47
  30. package/dist/lib/features/analytics/attribution.js +181 -0
  31. package/dist/lib/features/analytics/attribution.js.map +1 -0
  32. package/dist/lib/features/analytics/events.d.ts +1 -28
  33. package/dist/lib/features/analytics/events.js +256 -0
  34. package/dist/lib/features/analytics/events.js.map +1 -0
  35. package/dist/lib/features/analytics/funnels.js +260 -0
  36. package/dist/lib/features/analytics/funnels.js.map +1 -0
  37. package/dist/lib/features/analytics/heatmaps.d.ts +12 -19
  38. package/dist/lib/features/analytics/heatmaps.js +258 -0
  39. package/dist/lib/features/analytics/heatmaps.js.map +1 -0
  40. package/dist/lib/features/analytics/identify.d.ts +1 -21
  41. package/dist/lib/features/analytics/identify.js +213 -0
  42. package/dist/lib/features/analytics/identify.js.map +1 -0
  43. package/dist/lib/features/analytics/index.d.ts +2 -0
  44. package/dist/lib/features/analytics/index.js +15 -0
  45. package/dist/lib/features/analytics/index.js.map +1 -0
  46. package/dist/lib/features/analytics/page-views.d.ts +13 -30
  47. package/dist/lib/features/analytics/page-views.js +268 -0
  48. package/dist/lib/features/analytics/page-views.js.map +1 -0
  49. package/dist/lib/features/analytics/performance.d.ts +18 -24
  50. package/dist/lib/features/analytics/performance.js +232 -0
  51. package/dist/lib/features/analytics/performance.js.map +1 -0
  52. package/dist/lib/features/analytics/replay.d.ts +170 -0
  53. package/dist/lib/features/analytics/replay.js +381 -0
  54. package/dist/lib/features/analytics/replay.js.map +1 -0
  55. package/dist/lib/features/analytics/retention.d.ts +1 -76
  56. package/dist/lib/features/analytics/retention.js +135 -0
  57. package/dist/lib/features/analytics/retention.js.map +1 -0
  58. package/dist/lib/features/analytics/sessions.d.ts +12 -37
  59. package/dist/lib/features/analytics/sessions.js +213 -0
  60. package/dist/lib/features/analytics/sessions.js.map +1 -0
  61. package/dist/lib/features/core/activation.d.ts +1 -24
  62. package/dist/lib/features/core/activation.js +175 -0
  63. package/dist/lib/features/core/activation.js.map +1 -0
  64. package/dist/lib/features/core/experiment.d.ts +53 -21
  65. package/dist/lib/features/core/experiment.js +554 -0
  66. package/dist/lib/features/core/experiment.js.map +1 -0
  67. package/dist/lib/features/core/index.js +9 -0
  68. package/dist/lib/features/core/index.js.map +1 -0
  69. package/dist/lib/features/core/track-feature.d.ts +1 -8
  70. package/dist/lib/features/core/track-feature.js +119 -0
  71. package/dist/lib/features/core/track-feature.js.map +1 -0
  72. package/dist/lib/features/core/track-prompt.d.ts +5 -8
  73. package/dist/lib/features/core/track-prompt.js +181 -0
  74. package/dist/lib/features/core/track-prompt.js.map +1 -0
  75. package/dist/lib/features/ecommerce/cart.d.ts +1 -24
  76. package/dist/lib/features/ecommerce/cart.js +244 -0
  77. package/dist/lib/features/ecommerce/cart.js.map +1 -0
  78. package/dist/lib/features/ecommerce/checkout.d.ts +1 -28
  79. package/dist/lib/features/ecommerce/checkout.js +254 -0
  80. package/dist/lib/features/ecommerce/checkout.js.map +1 -0
  81. package/dist/lib/features/ecommerce/index.d.ts +0 -2
  82. package/dist/lib/features/ecommerce/index.js +15 -0
  83. package/dist/lib/features/ecommerce/index.js.map +1 -0
  84. package/dist/lib/features/ecommerce/ltv.d.ts +1 -69
  85. package/dist/lib/features/ecommerce/ltv.js +114 -0
  86. package/dist/lib/features/ecommerce/ltv.js.map +1 -0
  87. package/dist/lib/features/ecommerce/products.d.ts +1 -33
  88. package/dist/lib/features/ecommerce/products.js +223 -0
  89. package/dist/lib/features/ecommerce/products.js.map +1 -0
  90. package/dist/lib/features/ecommerce/promotions.d.ts +1 -30
  91. package/dist/lib/features/ecommerce/promotions.js +197 -0
  92. package/dist/lib/features/ecommerce/promotions.js.map +1 -0
  93. package/dist/lib/features/ecommerce/purchases.d.ts +1 -48
  94. package/dist/lib/features/ecommerce/purchases.js +193 -0
  95. package/dist/lib/features/ecommerce/purchases.js.map +1 -0
  96. package/dist/lib/features/ecommerce/refunds.d.ts +1 -27
  97. package/dist/lib/features/ecommerce/refunds.js +195 -0
  98. package/dist/lib/features/ecommerce/refunds.js.map +1 -0
  99. package/dist/lib/features/ecommerce/search.d.ts +1 -24
  100. package/dist/lib/features/ecommerce/search.js +156 -0
  101. package/dist/lib/features/ecommerce/search.js.map +1 -0
  102. package/dist/lib/features/ecommerce/subscriptions.d.ts +1 -28
  103. package/dist/lib/features/ecommerce/subscriptions.js +207 -0
  104. package/dist/lib/features/ecommerce/subscriptions.js.map +1 -0
  105. package/dist/lib/features/ecommerce/wishlist.d.ts +1 -28
  106. package/dist/lib/features/ecommerce/wishlist.js +186 -0
  107. package/dist/lib/features/ecommerce/wishlist.js.map +1 -0
  108. package/dist/lib/features/enterprise/acquisition.d.ts +2 -57
  109. package/dist/lib/features/enterprise/acquisition.js +166 -0
  110. package/dist/lib/features/enterprise/acquisition.js.map +1 -0
  111. package/dist/lib/features/enterprise/alerts.d.ts +1 -37
  112. package/dist/lib/features/enterprise/alerts.js +246 -0
  113. package/dist/lib/features/enterprise/alerts.js.map +1 -0
  114. package/dist/lib/features/enterprise/churn.d.ts +1 -42
  115. package/dist/lib/features/enterprise/churn.js +175 -0
  116. package/dist/lib/features/enterprise/churn.js.map +1 -0
  117. package/dist/lib/features/enterprise/cohorts.d.ts +1 -37
  118. package/dist/lib/features/enterprise/cohorts.js +201 -0
  119. package/dist/lib/features/enterprise/cohorts.js.map +1 -0
  120. package/dist/lib/features/enterprise/engagement.d.ts +40 -46
  121. package/dist/lib/features/enterprise/engagement.js +335 -0
  122. package/dist/lib/features/enterprise/engagement.js.map +1 -0
  123. package/dist/lib/features/enterprise/forecasting.d.ts +0 -50
  124. package/dist/lib/features/enterprise/forecasting.js +232 -0
  125. package/dist/lib/features/enterprise/forecasting.js.map +1 -0
  126. package/dist/lib/features/enterprise/index.d.ts +1 -1
  127. package/dist/lib/features/enterprise/index.js +76 -0
  128. package/dist/lib/features/enterprise/index.js.map +1 -0
  129. package/dist/lib/features/enterprise/monetization.d.ts +1 -60
  130. package/dist/lib/features/enterprise/monetization.js +146 -0
  131. package/dist/lib/features/enterprise/monetization.js.map +1 -0
  132. package/dist/lib/features/enterprise/multi-path-funnels.d.ts +1 -17
  133. package/dist/lib/features/enterprise/multi-path-funnels.js +205 -0
  134. package/dist/lib/features/enterprise/multi-path-funnels.js.map +1 -0
  135. package/dist/lib/features/enterprise/paths.d.ts +1 -56
  136. package/dist/lib/features/enterprise/paths.js +149 -0
  137. package/dist/lib/features/enterprise/paths.js.map +1 -0
  138. package/dist/lib/features/enterprise/security.d.ts +8 -57
  139. package/dist/lib/features/enterprise/security.js +202 -0
  140. package/dist/lib/features/enterprise/security.js.map +1 -0
  141. package/dist/lib/features/enterprise/support.d.ts +3 -42
  142. package/dist/lib/features/enterprise/support.js +162 -0
  143. package/dist/lib/features/enterprise/support.js.map +1 -0
  144. package/dist/lib/flowgrid.d.ts +278 -0
  145. package/dist/lib/flowgrid.js +323 -0
  146. package/dist/lib/flowgrid.js.map +1 -0
  147. package/dist/lib/frameworks/index.d.ts +13 -6
  148. package/dist/lib/frameworks/index.js +18 -0
  149. package/dist/lib/frameworks/index.js.map +1 -0
  150. package/dist/lib/frameworks/nextjs/client.js +355 -0
  151. package/dist/lib/frameworks/nextjs/client.js.map +1 -0
  152. package/dist/lib/frameworks/nextjs/index.js +31 -0
  153. package/dist/lib/frameworks/nextjs/index.js.map +1 -0
  154. package/dist/lib/frameworks/nextjs/server.js +259 -0
  155. package/dist/lib/frameworks/nextjs/server.js.map +1 -0
  156. package/dist/lib/frameworks/node/index.js +391 -0
  157. package/dist/lib/frameworks/node/index.js.map +1 -0
  158. package/dist/lib/frameworks/nuxt/index.js +288 -0
  159. package/dist/lib/frameworks/nuxt/index.js.map +1 -0
  160. package/dist/lib/frameworks/react/CookieBanner.js +166 -0
  161. package/dist/lib/frameworks/react/CookieBanner.js.map +1 -0
  162. package/dist/lib/frameworks/react/index.d.ts +2 -2
  163. package/dist/lib/frameworks/react/index.js +271 -0
  164. package/dist/lib/frameworks/react/index.js.map +1 -0
  165. package/dist/lib/frameworks/vue/CookieBanner.js +165 -0
  166. package/dist/lib/frameworks/vue/CookieBanner.js.map +1 -0
  167. package/dist/lib/frameworks/vue/index.d.ts +2 -2
  168. package/dist/lib/frameworks/vue/index.js +390 -0
  169. package/dist/lib/frameworks/vue/index.js.map +1 -0
  170. package/dist/lib/tracking/analytics/attribution.d.ts +14 -0
  171. package/dist/lib/tracking/analytics/attribution.js +18 -0
  172. package/dist/lib/tracking/analytics/attribution.js.map +1 -0
  173. package/dist/lib/tracking/analytics/events.d.ts +26 -0
  174. package/dist/lib/tracking/analytics/events.js +30 -0
  175. package/dist/lib/tracking/analytics/events.js.map +1 -0
  176. package/dist/lib/tracking/analytics/funnels.d.ts +16 -0
  177. package/dist/lib/tracking/analytics/funnels.js +22 -0
  178. package/dist/lib/tracking/analytics/funnels.js.map +1 -0
  179. package/dist/lib/tracking/analytics/heatmaps.d.ts +27 -0
  180. package/dist/lib/tracking/analytics/heatmaps.js +22 -0
  181. package/dist/lib/tracking/analytics/heatmaps.js.map +1 -0
  182. package/dist/lib/tracking/analytics/identify.d.ts +16 -0
  183. package/dist/lib/tracking/analytics/identify.js +22 -0
  184. package/dist/lib/tracking/analytics/identify.js.map +1 -0
  185. package/dist/lib/tracking/analytics/index.d.ts +10 -0
  186. package/dist/lib/tracking/analytics/index.js +11 -0
  187. package/dist/lib/tracking/analytics/index.js.map +1 -0
  188. package/dist/lib/tracking/analytics/page-views.d.ts +29 -0
  189. package/dist/lib/tracking/analytics/page-views.js +50 -0
  190. package/dist/lib/tracking/analytics/page-views.js.map +1 -0
  191. package/dist/lib/tracking/analytics/performance.d.ts +22 -0
  192. package/dist/lib/tracking/analytics/performance.js +22 -0
  193. package/dist/lib/tracking/analytics/performance.js.map +1 -0
  194. package/dist/lib/tracking/analytics/replay.d.ts +34 -0
  195. package/dist/lib/tracking/analytics/replay.js +46 -0
  196. package/dist/lib/tracking/analytics/replay.js.map +1 -0
  197. package/dist/lib/tracking/analytics/retention.d.ts +10 -0
  198. package/dist/lib/tracking/analytics/retention.js +10 -0
  199. package/dist/lib/tracking/analytics/retention.js.map +1 -0
  200. package/dist/lib/tracking/analytics/sessions.d.ts +20 -0
  201. package/dist/lib/tracking/analytics/sessions.js +26 -0
  202. package/dist/lib/tracking/analytics/sessions.js.map +1 -0
  203. package/dist/lib/tracking/core/activation.d.ts +23 -0
  204. package/dist/lib/tracking/core/activation.js +33 -0
  205. package/dist/lib/tracking/core/activation.js.map +1 -0
  206. package/dist/lib/tracking/core/experiment.d.ts +122 -0
  207. package/dist/lib/tracking/core/experiment.js +150 -0
  208. package/dist/lib/tracking/core/experiment.js.map +1 -0
  209. package/dist/lib/tracking/core/feature.d.ts +13 -0
  210. package/dist/lib/tracking/core/feature.js +14 -0
  211. package/dist/lib/tracking/core/feature.js.map +1 -0
  212. package/dist/lib/tracking/core/index.d.ts +4 -0
  213. package/dist/lib/tracking/core/index.js +5 -0
  214. package/dist/lib/tracking/core/index.js.map +1 -0
  215. package/dist/lib/tracking/core/prompt.d.ts +18 -0
  216. package/dist/lib/tracking/core/prompt.js +26 -0
  217. package/dist/lib/tracking/core/prompt.js.map +1 -0
  218. package/dist/lib/tracking/ecommerce/cart.d.ts +17 -0
  219. package/dist/lib/tracking/ecommerce/cart.js +22 -0
  220. package/dist/lib/tracking/ecommerce/cart.js.map +1 -0
  221. package/dist/lib/tracking/ecommerce/checkout.d.ts +17 -0
  222. package/dist/lib/tracking/ecommerce/checkout.js +22 -0
  223. package/dist/lib/tracking/ecommerce/checkout.js.map +1 -0
  224. package/dist/lib/tracking/ecommerce/index.d.ts +10 -0
  225. package/dist/lib/tracking/ecommerce/index.js +11 -0
  226. package/dist/lib/tracking/ecommerce/index.js.map +1 -0
  227. package/dist/lib/tracking/ecommerce/ltv.d.ts +15 -0
  228. package/dist/lib/tracking/ecommerce/ltv.js +14 -0
  229. package/dist/lib/tracking/ecommerce/ltv.js.map +1 -0
  230. package/dist/lib/tracking/ecommerce/products.d.ts +15 -0
  231. package/dist/lib/tracking/ecommerce/products.js +18 -0
  232. package/dist/lib/tracking/ecommerce/products.js.map +1 -0
  233. package/dist/lib/tracking/ecommerce/promotions.d.ts +14 -0
  234. package/dist/lib/tracking/ecommerce/promotions.js +25 -0
  235. package/dist/lib/tracking/ecommerce/promotions.js.map +1 -0
  236. package/dist/lib/tracking/ecommerce/purchases.d.ts +11 -0
  237. package/dist/lib/tracking/ecommerce/purchases.js +10 -0
  238. package/dist/lib/tracking/ecommerce/purchases.js.map +1 -0
  239. package/dist/lib/tracking/ecommerce/refunds.d.ts +17 -0
  240. package/dist/lib/tracking/ecommerce/refunds.js +22 -0
  241. package/dist/lib/tracking/ecommerce/refunds.js.map +1 -0
  242. package/dist/lib/tracking/ecommerce/search.d.ts +24 -0
  243. package/dist/lib/tracking/ecommerce/search.js +22 -0
  244. package/dist/lib/tracking/ecommerce/search.js.map +1 -0
  245. package/dist/lib/tracking/ecommerce/subscriptions.d.ts +21 -0
  246. package/dist/lib/tracking/ecommerce/subscriptions.js +38 -0
  247. package/dist/lib/tracking/ecommerce/subscriptions.js.map +1 -0
  248. package/dist/lib/tracking/ecommerce/wishlist.d.ts +19 -0
  249. package/dist/lib/tracking/ecommerce/wishlist.js +26 -0
  250. package/dist/lib/tracking/ecommerce/wishlist.js.map +1 -0
  251. package/dist/lib/tracking/enterprise/acquisition.d.ts +25 -0
  252. package/dist/lib/tracking/enterprise/acquisition.js +22 -0
  253. package/dist/lib/tracking/enterprise/acquisition.js.map +1 -0
  254. package/dist/lib/tracking/enterprise/alerts.d.ts +32 -0
  255. package/dist/lib/tracking/enterprise/alerts.js +30 -0
  256. package/dist/lib/tracking/enterprise/alerts.js.map +1 -0
  257. package/dist/lib/tracking/enterprise/churn.d.ts +23 -0
  258. package/dist/lib/tracking/enterprise/churn.js +22 -0
  259. package/dist/lib/tracking/enterprise/churn.js.map +1 -0
  260. package/dist/lib/tracking/enterprise/cohorts.d.ts +18 -0
  261. package/dist/lib/tracking/enterprise/cohorts.js +18 -0
  262. package/dist/lib/tracking/enterprise/cohorts.js.map +1 -0
  263. package/dist/lib/tracking/enterprise/engagement.d.ts +31 -0
  264. package/dist/lib/tracking/enterprise/engagement.js +44 -0
  265. package/dist/lib/tracking/enterprise/engagement.js.map +1 -0
  266. package/dist/lib/tracking/enterprise/forecasting.d.ts +18 -0
  267. package/dist/lib/tracking/enterprise/forecasting.js +22 -0
  268. package/dist/lib/tracking/enterprise/forecasting.js.map +1 -0
  269. package/dist/lib/tracking/enterprise/index.d.ts +11 -0
  270. package/dist/lib/tracking/enterprise/index.js +12 -0
  271. package/dist/lib/tracking/enterprise/index.js.map +1 -0
  272. package/dist/lib/tracking/enterprise/monetization.d.ts +14 -0
  273. package/dist/lib/tracking/enterprise/monetization.js +10 -0
  274. package/dist/lib/tracking/enterprise/monetization.js.map +1 -0
  275. package/dist/lib/tracking/enterprise/multi-path-funnels.d.ts +20 -0
  276. package/dist/lib/tracking/enterprise/multi-path-funnels.js +18 -0
  277. package/dist/lib/tracking/enterprise/multi-path-funnels.js.map +1 -0
  278. package/dist/lib/tracking/enterprise/paths.d.ts +20 -0
  279. package/dist/lib/tracking/enterprise/paths.js +18 -0
  280. package/dist/lib/tracking/enterprise/paths.js.map +1 -0
  281. package/dist/lib/tracking/enterprise/security.d.ts +28 -0
  282. package/dist/lib/tracking/enterprise/security.js +26 -0
  283. package/dist/lib/tracking/enterprise/security.js.map +1 -0
  284. package/dist/lib/tracking/enterprise/support.d.ts +25 -0
  285. package/dist/lib/tracking/enterprise/support.js +22 -0
  286. package/dist/lib/tracking/enterprise/support.js.map +1 -0
  287. package/dist/lib/tracking/index.d.ts +4 -0
  288. package/dist/lib/tracking/index.js +5 -0
  289. package/dist/lib/tracking/index.js.map +1 -0
  290. package/dist/lib/types/analytics.d.ts +10 -2
  291. package/dist/lib/types/analytics.js +6 -0
  292. package/dist/lib/types/analytics.js.map +1 -0
  293. package/dist/lib/types/common.js +6 -0
  294. package/dist/lib/types/common.js.map +1 -0
  295. package/dist/lib/types/ecommerce.js +6 -0
  296. package/dist/lib/types/ecommerce.js.map +1 -0
  297. package/dist/lib/types/index.js +8 -0
  298. package/dist/lib/types/index.js.map +1 -0
  299. package/dist/lib/utils/browser.d.ts +16 -0
  300. package/dist/lib/utils/browser.js +32 -0
  301. package/dist/lib/utils/browser.js.map +1 -0
  302. package/dist/lib/utils/identity.js +346 -0
  303. package/dist/lib/utils/identity.js.map +1 -0
  304. package/dist/lib/utils/storage.js +105 -0
  305. package/dist/lib/utils/storage.js.map +1 -0
  306. package/dist/umd/237.index.js +2 -0
  307. package/dist/umd/237.index.js.map +1 -0
  308. package/dist/umd/546.index.js +3 -0
  309. package/dist/umd/546.index.js.LICENSE.txt +14 -0
  310. package/dist/umd/546.index.js.map +1 -0
  311. package/dist/umd/index.js +2 -0
  312. package/dist/umd/index.js.map +1 -0
  313. package/package.json +27 -80
  314. 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, TimeGranularity, ActiveUsersConfig, ActiveUsersResponse, ActiveUserRatios } from "../../types";
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
- * Get engagement score for a user.
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
- getEngagementScore(config: EngagementScoreConfig): Promise<EngagementScore>;
211
+ autoTrackDwell(featureId: string, options?: {
212
+ userId?: string;
213
+ sessionId?: string;
214
+ }): Teardown;
209
215
  /**
210
- * Get engagement analytics.
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
- getAnalytics(filter?: EngagementAnalyticsFilter): Promise<EngagementAnalytics>;
213
- /**
214
- * Get engagement trend over time.
215
- */
216
- getEngagementTrend(filter?: DateRangeFilter, granularity?: TimeGranularity): Promise<TimeSeriesData>;
217
- /**
218
- * Get top engaged users.
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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"}