flowgrid-sdk 1.4.1 → 1.5.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 (230) hide show
  1. package/README.md +17 -29
  2. package/dist/browser.js +12 -9
  3. package/dist/browser.js.map +1 -1
  4. package/dist/flowgrid-enterprise.flowgrid.chunk.js +2 -0
  5. package/dist/flowgrid-enterprise.flowgrid.chunk.js.map +1 -0
  6. package/dist/flowgrid-replay.flowgrid.chunk.js +3 -0
  7. package/dist/flowgrid-replay.flowgrid.chunk.js.LICENSE.txt +14 -0
  8. package/dist/flowgrid-replay.flowgrid.chunk.js.map +1 -0
  9. package/dist/flowgrid-vitals.flowgrid.chunk.js +2 -0
  10. package/dist/flowgrid-vitals.flowgrid.chunk.js.map +1 -0
  11. package/dist/flowgrid.min.js +1 -1
  12. package/dist/flowgrid.min.js.LICENSE.txt +14 -0
  13. package/dist/flowgrid.min.js.map +1 -1
  14. package/dist/index.d.ts +1 -1
  15. package/dist/index.js +63 -10
  16. package/dist/index.js.map +1 -1
  17. package/dist/lib/client/transport.js +5 -1
  18. package/dist/lib/client/transport.js.map +1 -1
  19. package/dist/lib/consent/index.js +5 -1
  20. package/dist/lib/consent/index.js.map +1 -1
  21. package/dist/lib/consent/manager.js +5 -1
  22. package/dist/lib/consent/manager.js.map +1 -1
  23. package/dist/lib/consent/types.js +2 -1
  24. package/dist/lib/consent/types.js.map +1 -1
  25. package/dist/lib/features/analytics/attribution.js +11 -7
  26. package/dist/lib/features/analytics/attribution.js.map +1 -1
  27. package/dist/lib/features/analytics/events.js +7 -3
  28. package/dist/lib/features/analytics/events.js.map +1 -1
  29. package/dist/lib/features/analytics/funnels.js +7 -3
  30. package/dist/lib/features/analytics/funnels.js.map +1 -1
  31. package/dist/lib/features/analytics/heatmaps.js +12 -8
  32. package/dist/lib/features/analytics/heatmaps.js.map +1 -1
  33. package/dist/lib/features/analytics/identify.js +7 -3
  34. package/dist/lib/features/analytics/identify.js.map +1 -1
  35. package/dist/lib/features/analytics/index.js +24 -10
  36. package/dist/lib/features/analytics/index.js.map +1 -1
  37. package/dist/lib/features/analytics/page-views.js +12 -8
  38. package/dist/lib/features/analytics/page-views.js.map +1 -1
  39. package/dist/lib/features/analytics/performance.js +46 -9
  40. package/dist/lib/features/analytics/performance.js.map +1 -1
  41. package/dist/lib/features/analytics/replay.js +46 -9
  42. package/dist/lib/features/analytics/replay.js.map +1 -1
  43. package/dist/lib/features/analytics/retention.js +7 -3
  44. package/dist/lib/features/analytics/retention.js.map +1 -1
  45. package/dist/lib/features/analytics/sessions.js +12 -8
  46. package/dist/lib/features/analytics/sessions.js.map +1 -1
  47. package/dist/lib/features/core/activation.js +7 -3
  48. package/dist/lib/features/core/activation.js.map +1 -1
  49. package/dist/lib/features/core/experiment.js +9 -5
  50. package/dist/lib/features/core/experiment.js.map +1 -1
  51. package/dist/lib/features/core/index.js +11 -4
  52. package/dist/lib/features/core/index.js.map +1 -1
  53. package/dist/lib/features/core/track-feature.js +7 -3
  54. package/dist/lib/features/core/track-feature.js.map +1 -1
  55. package/dist/lib/features/core/track-prompt.js +7 -3
  56. package/dist/lib/features/core/track-prompt.js.map +1 -1
  57. package/dist/lib/features/ecommerce/cart.js +7 -3
  58. package/dist/lib/features/ecommerce/cart.js.map +1 -1
  59. package/dist/lib/features/ecommerce/checkout.js +7 -3
  60. package/dist/lib/features/ecommerce/checkout.js.map +1 -1
  61. package/dist/lib/features/ecommerce/index.js +23 -10
  62. package/dist/lib/features/ecommerce/index.js.map +1 -1
  63. package/dist/lib/features/ecommerce/ltv.js +7 -3
  64. package/dist/lib/features/ecommerce/ltv.js.map +1 -1
  65. package/dist/lib/features/ecommerce/products.js +7 -3
  66. package/dist/lib/features/ecommerce/products.js.map +1 -1
  67. package/dist/lib/features/ecommerce/promotions.js +7 -3
  68. package/dist/lib/features/ecommerce/promotions.js.map +1 -1
  69. package/dist/lib/features/ecommerce/purchases.js +7 -3
  70. package/dist/lib/features/ecommerce/purchases.js.map +1 -1
  71. package/dist/lib/features/ecommerce/refunds.js +7 -3
  72. package/dist/lib/features/ecommerce/refunds.js.map +1 -1
  73. package/dist/lib/features/ecommerce/search.js +7 -3
  74. package/dist/lib/features/ecommerce/search.js.map +1 -1
  75. package/dist/lib/features/ecommerce/subscriptions.js +7 -3
  76. package/dist/lib/features/ecommerce/subscriptions.js.map +1 -1
  77. package/dist/lib/features/ecommerce/wishlist.js +7 -3
  78. package/dist/lib/features/ecommerce/wishlist.js.map +1 -1
  79. package/dist/lib/features/enterprise/acquisition.js +16 -7
  80. package/dist/lib/features/enterprise/acquisition.js.map +1 -1
  81. package/dist/lib/features/enterprise/alerts.js +18 -8
  82. package/dist/lib/features/enterprise/alerts.js.map +1 -1
  83. package/dist/lib/features/enterprise/churn.js +12 -5
  84. package/dist/lib/features/enterprise/churn.js.map +1 -1
  85. package/dist/lib/features/enterprise/cohorts.js +10 -4
  86. package/dist/lib/features/enterprise/cohorts.js.map +1 -1
  87. package/dist/lib/features/enterprise/engagement.js +19 -12
  88. package/dist/lib/features/enterprise/engagement.js.map +1 -1
  89. package/dist/lib/features/enterprise/forecasting.js +18 -8
  90. package/dist/lib/features/enterprise/forecasting.js.map +1 -1
  91. package/dist/lib/features/enterprise/index.js +75 -22
  92. package/dist/lib/features/enterprise/index.js.map +1 -1
  93. package/dist/lib/features/enterprise/monetization.js +16 -7
  94. package/dist/lib/features/enterprise/monetization.js.map +1 -1
  95. package/dist/lib/features/enterprise/multi-path-funnels.js +16 -7
  96. package/dist/lib/features/enterprise/multi-path-funnels.js.map +1 -1
  97. package/dist/lib/features/enterprise/paths.js +18 -8
  98. package/dist/lib/features/enterprise/paths.js.map +1 -1
  99. package/dist/lib/features/enterprise/security.js +14 -6
  100. package/dist/lib/features/enterprise/security.js.map +1 -1
  101. package/dist/lib/features/enterprise/support.js +14 -6
  102. package/dist/lib/features/enterprise/support.js.map +1 -1
  103. package/dist/lib/flowgrid.d.ts +734 -10
  104. package/dist/lib/flowgrid.js +801 -60
  105. package/dist/lib/flowgrid.js.map +1 -1
  106. package/dist/lib/tracking/analytics/attribution.d.ts +3 -3
  107. package/dist/lib/tracking/analytics/attribution.js +5 -1
  108. package/dist/lib/tracking/analytics/attribution.js.map +1 -1
  109. package/dist/lib/tracking/analytics/events.d.ts +6 -6
  110. package/dist/lib/tracking/analytics/events.js +5 -1
  111. package/dist/lib/tracking/analytics/events.js.map +1 -1
  112. package/dist/lib/tracking/analytics/funnels.d.ts +4 -4
  113. package/dist/lib/tracking/analytics/funnels.js +5 -1
  114. package/dist/lib/tracking/analytics/funnels.js.map +1 -1
  115. package/dist/lib/tracking/analytics/heatmaps.d.ts +3 -3
  116. package/dist/lib/tracking/analytics/heatmaps.js +5 -1
  117. package/dist/lib/tracking/analytics/heatmaps.js.map +1 -1
  118. package/dist/lib/tracking/analytics/identify.d.ts +4 -4
  119. package/dist/lib/tracking/analytics/identify.js +5 -1
  120. package/dist/lib/tracking/analytics/identify.js.map +1 -1
  121. package/dist/lib/tracking/analytics/index.js +23 -10
  122. package/dist/lib/tracking/analytics/index.js.map +1 -1
  123. package/dist/lib/tracking/analytics/page-views.d.ts +4 -4
  124. package/dist/lib/tracking/analytics/page-views.js +5 -1
  125. package/dist/lib/tracking/analytics/page-views.js.map +1 -1
  126. package/dist/lib/tracking/analytics/performance.d.ts +3 -3
  127. package/dist/lib/tracking/analytics/performance.js +5 -1
  128. package/dist/lib/tracking/analytics/performance.js.map +1 -1
  129. package/dist/lib/tracking/analytics/replay.js +5 -1
  130. package/dist/lib/tracking/analytics/replay.js.map +1 -1
  131. package/dist/lib/tracking/analytics/retention.d.ts +1 -1
  132. package/dist/lib/tracking/analytics/retention.js +5 -1
  133. package/dist/lib/tracking/analytics/retention.js.map +1 -1
  134. package/dist/lib/tracking/analytics/sessions.d.ts +4 -4
  135. package/dist/lib/tracking/analytics/sessions.js +5 -1
  136. package/dist/lib/tracking/analytics/sessions.js.map +1 -1
  137. package/dist/lib/tracking/core/activation.d.ts +5 -5
  138. package/dist/lib/tracking/core/activation.js +5 -1
  139. package/dist/lib/tracking/core/activation.js.map +1 -1
  140. package/dist/lib/tracking/core/experiment.d.ts +4 -4
  141. package/dist/lib/tracking/core/experiment.js +5 -1
  142. package/dist/lib/tracking/core/experiment.js.map +1 -1
  143. package/dist/lib/tracking/core/feature.d.ts +2 -2
  144. package/dist/lib/tracking/core/feature.js +5 -1
  145. package/dist/lib/tracking/core/feature.js.map +1 -1
  146. package/dist/lib/tracking/core/index.js +11 -4
  147. package/dist/lib/tracking/core/index.js.map +1 -1
  148. package/dist/lib/tracking/core/prompt.d.ts +5 -5
  149. package/dist/lib/tracking/core/prompt.js +5 -1
  150. package/dist/lib/tracking/core/prompt.js.map +1 -1
  151. package/dist/lib/tracking/ecommerce/cart.d.ts +4 -4
  152. package/dist/lib/tracking/ecommerce/cart.js +5 -1
  153. package/dist/lib/tracking/ecommerce/cart.js.map +1 -1
  154. package/dist/lib/tracking/ecommerce/checkout.d.ts +4 -4
  155. package/dist/lib/tracking/ecommerce/checkout.js +5 -1
  156. package/dist/lib/tracking/ecommerce/checkout.js.map +1 -1
  157. package/dist/lib/tracking/ecommerce/index.js +23 -10
  158. package/dist/lib/tracking/ecommerce/index.js.map +1 -1
  159. package/dist/lib/tracking/ecommerce/ltv.d.ts +2 -2
  160. package/dist/lib/tracking/ecommerce/ltv.js +5 -1
  161. package/dist/lib/tracking/ecommerce/ltv.js.map +1 -1
  162. package/dist/lib/tracking/ecommerce/products.d.ts +3 -3
  163. package/dist/lib/tracking/ecommerce/products.js +5 -1
  164. package/dist/lib/tracking/ecommerce/products.js.map +1 -1
  165. package/dist/lib/tracking/ecommerce/promotions.d.ts +3 -3
  166. package/dist/lib/tracking/ecommerce/promotions.js +5 -1
  167. package/dist/lib/tracking/ecommerce/promotions.js.map +1 -1
  168. package/dist/lib/tracking/ecommerce/purchases.d.ts +1 -1
  169. package/dist/lib/tracking/ecommerce/purchases.js +5 -1
  170. package/dist/lib/tracking/ecommerce/purchases.js.map +1 -1
  171. package/dist/lib/tracking/ecommerce/refunds.d.ts +4 -4
  172. package/dist/lib/tracking/ecommerce/refunds.js +5 -1
  173. package/dist/lib/tracking/ecommerce/refunds.js.map +1 -1
  174. package/dist/lib/tracking/ecommerce/search.d.ts +4 -4
  175. package/dist/lib/tracking/ecommerce/search.js +5 -1
  176. package/dist/lib/tracking/ecommerce/search.js.map +1 -1
  177. package/dist/lib/tracking/ecommerce/subscriptions.d.ts +6 -6
  178. package/dist/lib/tracking/ecommerce/subscriptions.js +5 -1
  179. package/dist/lib/tracking/ecommerce/subscriptions.js.map +1 -1
  180. package/dist/lib/tracking/ecommerce/wishlist.d.ts +5 -5
  181. package/dist/lib/tracking/ecommerce/wishlist.js +5 -1
  182. package/dist/lib/tracking/ecommerce/wishlist.js.map +1 -1
  183. package/dist/lib/tracking/enterprise/acquisition.js +5 -1
  184. package/dist/lib/tracking/enterprise/acquisition.js.map +1 -1
  185. package/dist/lib/tracking/enterprise/alerts.js +5 -1
  186. package/dist/lib/tracking/enterprise/alerts.js.map +1 -1
  187. package/dist/lib/tracking/enterprise/churn.d.ts +1 -1
  188. package/dist/lib/tracking/enterprise/churn.js +5 -1
  189. package/dist/lib/tracking/enterprise/churn.js.map +1 -1
  190. package/dist/lib/tracking/enterprise/cohorts.d.ts +1 -1
  191. package/dist/lib/tracking/enterprise/cohorts.js +5 -1
  192. package/dist/lib/tracking/enterprise/cohorts.js.map +1 -1
  193. package/dist/lib/tracking/enterprise/engagement.d.ts +4 -4
  194. package/dist/lib/tracking/enterprise/engagement.js +5 -1
  195. package/dist/lib/tracking/enterprise/engagement.js.map +1 -1
  196. package/dist/lib/tracking/enterprise/forecasting.d.ts +4 -4
  197. package/dist/lib/tracking/enterprise/forecasting.js +5 -1
  198. package/dist/lib/tracking/enterprise/forecasting.js.map +1 -1
  199. package/dist/lib/tracking/enterprise/index.js +25 -11
  200. package/dist/lib/tracking/enterprise/index.js.map +1 -1
  201. package/dist/lib/tracking/enterprise/monetization.js +5 -1
  202. package/dist/lib/tracking/enterprise/monetization.js.map +1 -1
  203. package/dist/lib/tracking/enterprise/multi-path-funnels.js +5 -1
  204. package/dist/lib/tracking/enterprise/multi-path-funnels.js.map +1 -1
  205. package/dist/lib/tracking/enterprise/paths.js +5 -1
  206. package/dist/lib/tracking/enterprise/paths.js.map +1 -1
  207. package/dist/lib/tracking/enterprise/security.js +5 -1
  208. package/dist/lib/tracking/enterprise/security.js.map +1 -1
  209. package/dist/lib/tracking/enterprise/support.js +5 -1
  210. package/dist/lib/tracking/enterprise/support.js.map +1 -1
  211. package/dist/lib/tracking/index.js +20 -4
  212. package/dist/lib/tracking/index.js.map +1 -1
  213. package/dist/lib/types/analytics.js +2 -1
  214. package/dist/lib/types/analytics.js.map +1 -1
  215. package/dist/lib/types/common.js +2 -1
  216. package/dist/lib/types/common.js.map +1 -1
  217. package/dist/lib/types/ecommerce.js +2 -1
  218. package/dist/lib/types/ecommerce.js.map +1 -1
  219. package/dist/lib/types/index.js +19 -3
  220. package/dist/lib/types/index.js.map +1 -1
  221. package/dist/lib/utils/browser.js +10 -4
  222. package/dist/lib/utils/browser.js.map +1 -1
  223. package/dist/lib/utils/identity.js +8 -4
  224. package/dist/lib/utils/identity.js.map +1 -1
  225. package/dist/lib/utils/storage.js +14 -6
  226. package/dist/lib/utils/storage.js.map +1 -1
  227. package/dist/umd/index.js +2 -1
  228. package/dist/umd/index.js.LICENSE.txt +14 -0
  229. package/dist/umd/index.js.map +1 -1
  230. package/package.json +2 -1
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /**
2
3
  * @fileoverview Unified FlowGrid SDK facade.
3
4
  * @module flowgrid
@@ -29,13 +30,135 @@
29
30
  * fg.events.client.track({ eventName: "x", sessionId: "...", category: "..." });
30
31
  * ```
31
32
  */
32
- import { FlowGridTransport } from "./client/transport";
33
- import { IdentityManager } from "./utils/identity";
34
- import { Activation, TrackFeature, TrackPrompt, Experiment } from "./features/core";
35
- import { PageViews, Sessions, Events, Identify, Funnels, Retention, Attribution, Heatmaps, PerformanceTracking, SessionReplay, } from "./features/analytics";
36
- import { Products, CartTracking, Checkout, Purchases, Refunds, Promotions, WishlistTracking, CustomerLTV, SearchAnalytics, Subscriptions, } from "./features/ecommerce";
37
- import { Engagement, Cohorts, ChurnAnalytics, Monetization, MultiPathFunnels, SupportAnalytics, AcquisitionAnalytics, PathAnalytics, AlertsAnalytics, SecurityAnalytics, Forecasting, } from "./features/enterprise";
38
- import { ActivationTracker, ExperimentTracker, FeatureTracker, PromptTracker, EventTracker, PageViewTracker, SessionTracker, IdentifyTracker, FunnelTracker, RetentionTracker, AttributionTracker, HeatmapTracker, PerformanceTracker, ReplayTracker, ProductTracker, CartTracker, CheckoutTracker, PurchaseTracker, RefundTracker, PromotionTracker, WishlistTracker, SubscriptionTracker, LTVTracker, SearchTracker, EngagementTracker, CohortTracker, ChurnTracker, MonetizationTracker, MultiPathFunnelTracker, SupportTracker, AcquisitionTracker, PathTracker, AlertTracker, SecurityTracker, ForecastingTracker, } from "./tracking";
33
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
34
+ if (k2 === undefined) k2 = k;
35
+ var desc = Object.getOwnPropertyDescriptor(m, k);
36
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
37
+ desc = { enumerable: true, get: function() { return m[k]; } };
38
+ }
39
+ Object.defineProperty(o, k2, desc);
40
+ }) : (function(o, m, k, k2) {
41
+ if (k2 === undefined) k2 = k;
42
+ o[k2] = m[k];
43
+ }));
44
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
45
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
46
+ }) : function(o, v) {
47
+ o["default"] = v;
48
+ });
49
+ var __importStar = (this && this.__importStar) || (function () {
50
+ var ownKeys = function(o) {
51
+ ownKeys = Object.getOwnPropertyNames || function (o) {
52
+ var ar = [];
53
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
54
+ return ar;
55
+ };
56
+ return ownKeys(o);
57
+ };
58
+ return function (mod) {
59
+ if (mod && mod.__esModule) return mod;
60
+ var result = {};
61
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
62
+ __setModuleDefault(result, mod);
63
+ return result;
64
+ };
65
+ })();
66
+ Object.defineProperty(exports, "__esModule", { value: true });
67
+ exports.FlowGrid = void 0;
68
+ const transport_1 = require("./client/transport");
69
+ const identity_1 = require("./utils/identity");
70
+ const core_1 = require("./features/core");
71
+ const analytics_1 = require("./features/analytics");
72
+ const ecommerce_1 = require("./features/ecommerce");
73
+ // Import directly from sub-barrels (not the top-level ./tracking barrel) so
74
+ // the static module graph never reaches ./tracking/enterprise and its
75
+ // dependencies can be tree-shaken / placed only in the async chunk.
76
+ const core_2 = require("./tracking/core");
77
+ const analytics_2 = require("./tracking/analytics");
78
+ const ecommerce_2 = require("./tracking/ecommerce");
79
+ // ---- Enterprise lazy-load state (module-level singleton) ----
80
+ let _enterpriseFeatures = null;
81
+ let _enterpriseTracking = null;
82
+ function loadEnterpriseModules() {
83
+ if (_enterpriseFeatures && _enterpriseTracking)
84
+ return Promise.resolve();
85
+ return Promise.all([
86
+ Promise.resolve().then(() => __importStar(require(/* webpackChunkName: "flowgrid-enterprise" */ "./features/enterprise"))),
87
+ Promise.resolve().then(() => __importStar(require(/* webpackChunkName: "flowgrid-enterprise" */ "./tracking/enterprise"))),
88
+ ]).then(([features, tracking]) => {
89
+ _enterpriseFeatures = features;
90
+ _enterpriseTracking = tracking;
91
+ });
92
+ }
93
+ const UNHANDLED_TRACK = { handled: false };
94
+ const PRODUCT_KEYS = [
95
+ "productId",
96
+ "name",
97
+ "brand",
98
+ "category",
99
+ "variant",
100
+ "price",
101
+ "currency",
102
+ "quantity",
103
+ "discount",
104
+ "coupon",
105
+ "position",
106
+ "url",
107
+ "imageUrl",
108
+ "rating",
109
+ "reviewCount",
110
+ "stockStatus",
111
+ "attributes",
112
+ ];
113
+ function handled(value) {
114
+ return { handled: true, value };
115
+ }
116
+ function isRecord(value) {
117
+ return typeof value === "object" && value !== null && !Array.isArray(value);
118
+ }
119
+ function stringValue(props, key) {
120
+ const value = props[key];
121
+ return typeof value === "string" && value.length > 0 ? value : undefined;
122
+ }
123
+ function numberValue(props, key) {
124
+ const value = props[key];
125
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
126
+ }
127
+ function booleanValue(props, key) {
128
+ const value = props[key];
129
+ return typeof value === "boolean" ? value : undefined;
130
+ }
131
+ function recordValue(props, key) {
132
+ const value = props[key];
133
+ return isRecord(value) ? value : undefined;
134
+ }
135
+ function hasValue(props, key) {
136
+ const value = props[key];
137
+ return value !== undefined && value !== null && !(typeof value === "string" && value.length === 0);
138
+ }
139
+ function omitProperties(props, keys) {
140
+ const next = {};
141
+ const blocked = new Set([...keys, "domain"]);
142
+ for (const [key, value] of Object.entries(props)) {
143
+ if (!blocked.has(key))
144
+ next[key] = value;
145
+ }
146
+ return next;
147
+ }
148
+ function productFrom(props) {
149
+ const nested = recordValue(props, "product");
150
+ if (nested)
151
+ return { ...nested, currency: nested.currency ?? "USD" };
152
+ if (!hasValue(props, "productId") || !hasValue(props, "name") || !hasValue(props, "price")) {
153
+ return undefined;
154
+ }
155
+ const product = { currency: "USD" };
156
+ for (const key of PRODUCT_KEYS) {
157
+ if (props[key] !== undefined)
158
+ product[key] = props[key];
159
+ }
160
+ return product;
161
+ }
39
162
  const DEFAULT_ENDPOINT = "https://core.flow-grid.xyz";
40
163
  /**
41
164
  * Unified FlowGrid SDK client. Instantiate once, use everywhere.
@@ -43,7 +166,7 @@ const DEFAULT_ENDPOINT = "https://core.flow-grid.xyz";
43
166
  * Each feature is exposed as a lazily-initialised shortcut wrapper, so the
44
167
  * SDK has zero overhead for unused features.
45
168
  */
46
- export class FlowGrid {
169
+ class FlowGrid {
47
170
  /**
48
171
  * One-line init. Idempotent — calling twice returns the same instance and
49
172
  * logs a warning instead of starting auto-instrumentation again.
@@ -78,6 +201,9 @@ export class FlowGrid {
78
201
  }
79
202
  const fg = new FlowGrid(config.webId, config.endpoint ?? DEFAULT_ENDPOINT, config.apiKey, config.visitorId, config.identityManager, config.transport);
80
203
  FlowGrid._instance = fg;
204
+ // Pre-fetch the enterprise chunk immediately so getters are ready by the
205
+ // time user code first accesses them (typically well after init returns).
206
+ void loadEnterpriseModules();
81
207
  // Identify the user before auto-instrumentation so the very first events
82
208
  // (session_start, page_view) carry the userId.
83
209
  if (config.user?.userId) {
@@ -101,6 +227,15 @@ export class FlowGrid {
101
227
  static instance() {
102
228
  return FlowGrid._instance;
103
229
  }
230
+ /**
231
+ * Await the enterprise feature chunk. Call this before accessing any
232
+ * enterprise namespace (`fg.engagement`, `fg.churn`, etc.) if you need
233
+ * guaranteed availability rather than relying on the background pre-fetch
234
+ * started by `init()`.
235
+ */
236
+ static loadEnterprise() {
237
+ return loadEnterpriseModules();
238
+ }
104
239
  /**
105
240
  * Reset the singleton — primarily for tests / hot-reload. Tears down any
106
241
  * active auto-instrumentation.
@@ -127,7 +262,7 @@ export class FlowGrid {
127
262
  this.endpoint = endpoint;
128
263
  this.apiKey = apiKey;
129
264
  this.visitorId = visitorId;
130
- this.identityManager = identityManager ?? new IdentityManager(visitorId ? { visitorId } : undefined);
265
+ this.identityManager = identityManager ?? new identity_1.IdentityManager(visitorId ? { visitorId } : undefined);
131
266
  this.config = config;
132
267
  }
133
268
  raw(key, Klass) {
@@ -147,58 +282,648 @@ export class FlowGrid {
147
282
  return instance;
148
283
  }
149
284
  // ---- Core ----
150
- get activation() { return this.wrap("activation", Activation, ActivationTracker); }
151
- get features() { return this.wrap("features", TrackFeature, FeatureTracker); }
152
- get prompts() { return this.wrap("prompts", TrackPrompt, PromptTracker); }
153
- get experiments() { return this.wrap("experiments", Experiment, ExperimentTracker); }
285
+ get activation() { return this.wrap("activation", core_1.Activation, core_2.ActivationTracker); }
286
+ get features() { return this.wrap("features", core_1.TrackFeature, core_2.FeatureTracker); }
287
+ get prompts() { return this.wrap("prompts", core_1.TrackPrompt, core_2.PromptTracker); }
288
+ get experiments() { return this.wrap("experiments", core_1.Experiment, core_2.ExperimentTracker); }
154
289
  // ---- Analytics ----
155
- get pageViews() { return this.wrap("pageViews", PageViews, PageViewTracker); }
156
- get sessions() { return this.wrap("sessions", Sessions, SessionTracker); }
157
- get events() { return this.wrap("events", Events, EventTracker); }
158
- get identify() { return this.wrap("identify", Identify, IdentifyTracker); }
159
- get funnels() { return this.wrap("funnels", Funnels, FunnelTracker); }
160
- get retention() { return this.wrap("retention", Retention, RetentionTracker); }
161
- get attribution() { return this.wrap("attribution", Attribution, AttributionTracker); }
162
- get heatmaps() { return this.wrap("heatmaps", Heatmaps, HeatmapTracker); }
163
- get performance() { return this.wrap("performance", PerformanceTracking, PerformanceTracker); }
164
- get replay() { return this.wrap("replay", SessionReplay, ReplayTracker); }
290
+ get pageViews() { return this.wrap("pageViews", analytics_1.PageViews, analytics_2.PageViewTracker); }
291
+ get sessions() { return this.wrap("sessions", analytics_1.Sessions, analytics_2.SessionTracker); }
292
+ get events() { return this.wrap("events", analytics_1.Events, analytics_2.EventTracker); }
293
+ get identify() { return this.wrap("identify", analytics_1.Identify, analytics_2.IdentifyTracker); }
294
+ get funnels() { return this.wrap("funnels", analytics_1.Funnels, analytics_2.FunnelTracker); }
295
+ get retention() { return this.wrap("retention", analytics_1.Retention, analytics_2.RetentionTracker); }
296
+ get attribution() { return this.wrap("attribution", analytics_1.Attribution, analytics_2.AttributionTracker); }
297
+ get heatmaps() { return this.wrap("heatmaps", analytics_1.Heatmaps, analytics_2.HeatmapTracker); }
298
+ get performance() { return this.wrap("performance", analytics_1.PerformanceTracking, analytics_2.PerformanceTracker); }
299
+ get replay() { return this.wrap("replay", analytics_1.SessionReplay, analytics_2.ReplayTracker); }
165
300
  // ---- Ecommerce ----
166
- get products() { return this.wrap("products", Products, ProductTracker); }
167
- get cart() { return this.wrap("cart", CartTracking, CartTracker); }
168
- get checkout() { return this.wrap("checkout", Checkout, CheckoutTracker); }
169
- get purchases() { return this.wrap("purchases", Purchases, PurchaseTracker); }
170
- get refunds() { return this.wrap("refunds", Refunds, RefundTracker); }
171
- get promotions() { return this.wrap("promotions", Promotions, PromotionTracker); }
172
- get wishlist() { return this.wrap("wishlist", WishlistTracking, WishlistTracker); }
173
- get ltv() { return this.wrap("ltv", CustomerLTV, LTVTracker); }
174
- get search() { return this.wrap("search", SearchAnalytics, SearchTracker); }
175
- get subscriptions() { return this.wrap("subscriptions", Subscriptions, SubscriptionTracker); }
301
+ get products() { return this.wrap("products", ecommerce_1.Products, ecommerce_2.ProductTracker); }
302
+ get cart() { return this.wrap("cart", ecommerce_1.CartTracking, ecommerce_2.CartTracker); }
303
+ get checkout() { return this.wrap("checkout", ecommerce_1.Checkout, ecommerce_2.CheckoutTracker); }
304
+ get purchases() { return this.wrap("purchases", ecommerce_1.Purchases, ecommerce_2.PurchaseTracker); }
305
+ get refunds() { return this.wrap("refunds", ecommerce_1.Refunds, ecommerce_2.RefundTracker); }
306
+ get promotions() { return this.wrap("promotions", ecommerce_1.Promotions, ecommerce_2.PromotionTracker); }
307
+ get wishlist() { return this.wrap("wishlist", ecommerce_1.WishlistTracking, ecommerce_2.WishlistTracker); }
308
+ get ltv() { return this.wrap("ltv", ecommerce_1.CustomerLTV, ecommerce_2.LTVTracker); }
309
+ get search() { return this.wrap("search", ecommerce_1.SearchAnalytics, ecommerce_2.SearchTracker); }
310
+ get subscriptions() { return this.wrap("subscriptions", ecommerce_1.Subscriptions, ecommerce_2.SubscriptionTracker); }
176
311
  // ---- Enterprise ----
177
- get engagement() { return this.wrap("engagement", Engagement, EngagementTracker); }
178
- get cohorts() { return this.wrap("cohorts", Cohorts, CohortTracker); }
179
- get churn() { return this.wrap("churn", ChurnAnalytics, ChurnTracker); }
180
- get monetization() { return this.wrap("monetization", Monetization, MonetizationTracker); }
181
- get multiPathFunnels() { return this.wrap("multiPathFunnels", MultiPathFunnels, MultiPathFunnelTracker); }
182
- get support() { return this.wrap("support", SupportAnalytics, SupportTracker); }
183
- get acquisition() { return this.wrap("acquisition", AcquisitionAnalytics, AcquisitionTracker); }
184
- get paths() { return this.wrap("paths", PathAnalytics, PathTracker); }
185
- get alerts() { return this.wrap("alerts", AlertsAnalytics, AlertTracker); }
186
- get security() { return this.wrap("security", SecurityAnalytics, SecurityTracker); }
187
- get forecasting() { return this.wrap("forecasting", Forecasting, ForecastingTracker); }
188
- // ==========================================================================
189
- // TOP-LEVEL SHORTCUTS — the 80% case
190
- // ==========================================================================
191
- /**
192
- * Track a custom event.
193
- *
194
- * @example
195
- * ```ts
196
- * fg.track("signup_completed", { plan: "pro" });
197
- * ```
198
- */
199
- track(eventName, properties, options) {
312
+ // These getters pull classes from the lazily-loaded enterprise chunk.
313
+ // The chunk is pre-fetched by init() so it's almost always ready by the
314
+ // time user code accesses these properties. loadEnterprise() is available
315
+ // for the rare case where callers need to await readiness explicitly.
316
+ _requireEnterprise() {
317
+ const ent = _enterpriseFeatures;
318
+ const entT = _enterpriseTracking;
319
+ if (!ent || !entT) {
320
+ throw new Error("[FlowGrid] Enterprise features are still loading. " +
321
+ "await FlowGrid.loadEnterprise() before accessing enterprise namespaces directly.");
322
+ }
323
+ return { ent, entT };
324
+ }
325
+ get engagement() { const { ent, entT } = this._requireEnterprise(); return this.wrap("engagement", ent.Engagement, entT.EngagementTracker); }
326
+ get cohorts() { const { ent, entT } = this._requireEnterprise(); return this.wrap("cohorts", ent.Cohorts, entT.CohortTracker); }
327
+ get churn() { const { ent, entT } = this._requireEnterprise(); return this.wrap("churn", ent.ChurnAnalytics, entT.ChurnTracker); }
328
+ get monetization() { const { ent, entT } = this._requireEnterprise(); return this.wrap("monetization", ent.Monetization, entT.MonetizationTracker); }
329
+ get multiPathFunnels() { const { ent, entT } = this._requireEnterprise(); return this.wrap("multiPathFunnels", ent.MultiPathFunnels, entT.MultiPathFunnelTracker); }
330
+ get support() { const { ent, entT } = this._requireEnterprise(); return this.wrap("support", ent.SupportAnalytics, entT.SupportTracker); }
331
+ get acquisition() { const { ent, entT } = this._requireEnterprise(); return this.wrap("acquisition", ent.AcquisitionAnalytics, entT.AcquisitionTracker); }
332
+ get paths() { const { ent, entT } = this._requireEnterprise(); return this.wrap("paths", ent.PathAnalytics, entT.PathTracker); }
333
+ get alerts() { const { ent, entT } = this._requireEnterprise(); return this.wrap("alerts", ent.AlertsAnalytics, entT.AlertTracker); }
334
+ get security() { const { ent, entT } = this._requireEnterprise(); return this.wrap("security", ent.SecurityAnalytics, entT.SecurityTracker); }
335
+ get forecasting() { const { ent, entT } = this._requireEnterprise(); return this.wrap("forecasting", ent.Forecasting, entT.ForecastingTracker); }
336
+ track(eventName, properties = {}, options = {}) {
337
+ const contextualProperties = this.withTrackContext(properties, options);
338
+ const routed = this.dispatchTrack(eventName, contextualProperties, Boolean(options.domain), options.domain);
339
+ if (routed.handled)
340
+ return routed.value;
200
341
  return this.events.track(eventName, properties, options);
201
342
  }
343
+ withTrackContext(properties, options) {
344
+ return {
345
+ ...properties,
346
+ ...(options.userId !== undefined && properties.userId === undefined ? { userId: options.userId } : {}),
347
+ ...(options.sessionId !== undefined && properties.sessionId === undefined ? { sessionId: options.sessionId } : {}),
348
+ };
349
+ }
350
+ requireTrackProperties(eventName, properties, keys, strict) {
351
+ const missing = keys.filter(key => !hasValue(properties, key));
352
+ if (missing.length === 0)
353
+ return true;
354
+ if (strict) {
355
+ throw new Error(`FlowGrid.track("${eventName}") missing required properties: ${missing.join(", ")}`);
356
+ }
357
+ return false;
358
+ }
359
+ dispatchTrack(eventName, properties, strict, domain) {
360
+ const dispatchers = [];
361
+ if (!domain || domain === "activation")
362
+ dispatchers.push(() => this.dispatchActivationTrack(eventName, properties, strict));
363
+ if (!domain || domain === "feature")
364
+ dispatchers.push(() => this.dispatchFeatureTrack(eventName, properties, strict));
365
+ if (!domain || domain === "prompt")
366
+ dispatchers.push(() => this.dispatchPromptTrack(eventName, properties, strict));
367
+ if (!domain || domain === "experiment")
368
+ dispatchers.push(() => this.dispatchExperimentTrack(eventName, properties, strict));
369
+ if (!domain || domain === "analytics" || domain === "funnel" || domain === "retention" || domain === "attribution") {
370
+ dispatchers.push(() => this.dispatchAnalyticsTrack(eventName, properties, strict, domain));
371
+ }
372
+ if (!domain || domain === "ecommerce")
373
+ dispatchers.push(() => this.dispatchEcommerceTrack(eventName, properties, strict));
374
+ if (!domain ||
375
+ domain === "engagement" ||
376
+ domain === "churn" ||
377
+ domain === "monetization" ||
378
+ domain === "support" ||
379
+ domain === "acquisition" ||
380
+ domain === "paths" ||
381
+ domain === "security" ||
382
+ domain === "multiPathFunnels") {
383
+ dispatchers.push(() => this.dispatchEnterpriseTrack(eventName, properties, strict, domain));
384
+ }
385
+ for (const dispatch of dispatchers) {
386
+ const result = dispatch();
387
+ if (result.handled)
388
+ return result;
389
+ }
390
+ return UNHANDLED_TRACK;
391
+ }
392
+ dispatchActivationTrack(eventName, properties, strict) {
393
+ switch (eventName) {
394
+ case "signup_completed": {
395
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "method"], strict))
396
+ return UNHANDLED_TRACK;
397
+ return handled(this.activation.signup(stringValue(properties, "userId"), stringValue(properties, "method"), stringValue(properties, "source"), omitProperties(properties, ["userId", "method", "source"])));
398
+ }
399
+ case "onboarding_step": {
400
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "stepId", "stepName", "stepOrder", "totalSteps"], strict))
401
+ return UNHANDLED_TRACK;
402
+ return handled(this.activation.onboardingStep(stringValue(properties, "userId"), stringValue(properties, "stepId"), stringValue(properties, "stepName"), numberValue(properties, "stepOrder"), numberValue(properties, "totalSteps"), {
403
+ skipped: booleanValue(properties, "skipped"),
404
+ timeSpent: numberValue(properties, "timeSpent"),
405
+ properties: omitProperties(properties, ["userId", "stepId", "stepName", "stepOrder", "totalSteps", "skipped", "timeSpent"]),
406
+ }));
407
+ }
408
+ case "onboarding_completed": {
409
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "totalTimeSpent", "stepsCompleted"], strict))
410
+ return UNHANDLED_TRACK;
411
+ return handled(this.activation.onboardingComplete(stringValue(properties, "userId"), numberValue(properties, "totalTimeSpent"), numberValue(properties, "stepsCompleted"), numberValue(properties, "stepsSkipped") ?? 0));
412
+ }
413
+ case "first_action": {
414
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "actionName", "timeSinceSignup"], strict))
415
+ return UNHANDLED_TRACK;
416
+ return handled(this.activation.firstAction(stringValue(properties, "userId"), stringValue(properties, "actionName"), numberValue(properties, "timeSinceSignup"), omitProperties(properties, ["userId", "actionName", "timeSinceSignup"])));
417
+ }
418
+ default:
419
+ if (strict)
420
+ return handled(this.activation.event(eventName, properties));
421
+ return UNHANDLED_TRACK;
422
+ }
423
+ }
424
+ dispatchFeatureTrack(eventName, properties, strict) {
425
+ const actions = {
426
+ feature_viewed: "viewed",
427
+ feature_used: "used",
428
+ feature_completed: "completed",
429
+ feature_abandoned: "abandoned",
430
+ };
431
+ const action = actions[eventName] ?? (eventName === "feature_usage"
432
+ ? properties.action : undefined);
433
+ if (eventName === "feature_usage" || action) {
434
+ if (!this.requireTrackProperties(eventName, properties, ["featureId", "featureName"], strict))
435
+ return UNHANDLED_TRACK;
436
+ return handled(this.features.client.trackUsage({
437
+ ...properties,
438
+ action: typeof action === "string" ? action : "used",
439
+ }));
440
+ }
441
+ if (strict) {
442
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "featureName"], true))
443
+ return UNHANDLED_TRACK;
444
+ return handled(this.features.create(stringValue(properties, "userId"), eventName, stringValue(properties, "featureName"), omitProperties(properties, ["userId", "featureName"])));
445
+ }
446
+ return UNHANDLED_TRACK;
447
+ }
448
+ dispatchPromptTrack(eventName, properties, strict) {
449
+ switch (eventName) {
450
+ case "prompt_submitted":
451
+ if (!this.requireTrackProperties(eventName, properties, ["promptId", "promptType"], strict))
452
+ return UNHANDLED_TRACK;
453
+ return handled(this.prompts.client.trackSubmission(properties));
454
+ case "prompt_response":
455
+ if (!this.requireTrackProperties(eventName, properties, ["promptId", "responseTime", "completed"], strict))
456
+ return UNHANDLED_TRACK;
457
+ return handled(this.prompts.client.trackResponse(properties));
458
+ case "prompt_feedback":
459
+ if (!this.requireTrackProperties(eventName, properties, ["promptId", "feedbackType"], strict))
460
+ return UNHANDLED_TRACK;
461
+ return handled(this.prompts.client.trackFeedback(properties));
462
+ case "prompt_conversation":
463
+ if (!this.requireTrackProperties(eventName, properties, ["conversationId", "userId", "turnCount", "totalDuration"], strict))
464
+ return UNHANDLED_TRACK;
465
+ return handled(this.prompts.conversation(stringValue(properties, "conversationId"), stringValue(properties, "userId"), numberValue(properties, "turnCount"), numberValue(properties, "totalDuration")));
466
+ default:
467
+ if (strict || eventName.startsWith("prompt_"))
468
+ return handled(this.prompts.event(eventName, properties));
469
+ return UNHANDLED_TRACK;
470
+ }
471
+ }
472
+ dispatchExperimentTrack(eventName, properties, strict) {
473
+ switch (eventName) {
474
+ case "experiment_assignment":
475
+ if (!this.requireTrackProperties(eventName, properties, ["experimentId", "userId", "variantId"], strict))
476
+ return UNHANDLED_TRACK;
477
+ return handled(this.experiments.client.assign(properties));
478
+ case "experiment_exposure":
479
+ if (!this.requireTrackProperties(eventName, properties, ["experimentId", "userId", "variantId"], strict))
480
+ return UNHANDLED_TRACK;
481
+ return handled(this.experiments.exposure(stringValue(properties, "experimentId"), stringValue(properties, "userId"), stringValue(properties, "variantId")));
482
+ case "experiment_conversion":
483
+ if (!this.requireTrackProperties(eventName, properties, ["experimentId", "userId", "variantId", "metricName"], strict))
484
+ return UNHANDLED_TRACK;
485
+ return handled(this.experiments.client.trackConversion({
486
+ ...properties,
487
+ value: numberValue(properties, "value") ?? 1,
488
+ }));
489
+ default:
490
+ if (strict || eventName.startsWith("experiment_")) {
491
+ if (!this.requireTrackProperties(eventName, properties, ["variant"], strict))
492
+ return UNHANDLED_TRACK;
493
+ return handled(this.experiments.client.track({
494
+ eventName,
495
+ variant: stringValue(properties, "variant"),
496
+ properties: omitProperties(properties, ["variant"]),
497
+ }));
498
+ }
499
+ return UNHANDLED_TRACK;
500
+ }
501
+ }
502
+ dispatchAnalyticsTrack(eventName, properties, strict, domain) {
503
+ switch (eventName) {
504
+ case "click_event":
505
+ if (!this.requireTrackProperties(eventName, properties, ["elementId", "elementText"], strict))
506
+ return UNHANDLED_TRACK;
507
+ return handled(this.events.client.trackClick(properties));
508
+ case "form_event":
509
+ if (!this.requireTrackProperties(eventName, properties, ["formId", "formName"], strict))
510
+ return UNHANDLED_TRACK;
511
+ return handled(this.events.client.trackForm(properties));
512
+ case "search_event":
513
+ if (!this.requireTrackProperties(eventName, properties, ["query", "category"], strict))
514
+ return UNHANDLED_TRACK;
515
+ return handled(this.events.client.trackSearch(properties));
516
+ case "error_event":
517
+ if (!this.requireTrackProperties(eventName, properties, ["message", "type"], strict))
518
+ return UNHANDLED_TRACK;
519
+ return handled(this.events.client.trackError(properties));
520
+ case "funnel_step":
521
+ if (!this.requireTrackProperties(eventName, properties, ["funnelId", "step", "stepNumber"], strict))
522
+ return UNHANDLED_TRACK;
523
+ return handled(this.funnels.client.trackStep(properties));
524
+ case "funnel_complete":
525
+ if (!this.requireTrackProperties(eventName, properties, ["funnelId"], strict))
526
+ return UNHANDLED_TRACK;
527
+ return handled(this.funnels.complete(stringValue(properties, "funnelId"), stringValue(properties, "userId"), omitProperties(properties, ["funnelId", "userId"])));
528
+ case "funnel_abandon":
529
+ if (!this.requireTrackProperties(eventName, properties, ["funnelId", "lastStep"], strict))
530
+ return UNHANDLED_TRACK;
531
+ return handled(this.funnels.abandon(stringValue(properties, "funnelId"), stringValue(properties, "lastStep"), stringValue(properties, "userId"), stringValue(properties, "reason")));
532
+ case "user_activity":
533
+ if (domain && domain !== "retention")
534
+ return UNHANDLED_TRACK;
535
+ if (!this.requireTrackProperties(eventName, properties, ["userId"], strict))
536
+ return UNHANDLED_TRACK;
537
+ return handled(this.retention.client.trackActivity(properties));
538
+ case "attribution_touchpoint":
539
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "channel"], strict))
540
+ return UNHANDLED_TRACK;
541
+ return handled(this.attribution.client.trackTouchpoint(properties));
542
+ case "attribution_conversion":
543
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "conversionType"], strict))
544
+ return UNHANDLED_TRACK;
545
+ return handled(this.attribution.client.recordConversion(properties));
546
+ default:
547
+ return UNHANDLED_TRACK;
548
+ }
549
+ }
550
+ dispatchEcommerceTrack(eventName, properties, strict) {
551
+ switch (eventName) {
552
+ case "product_view": {
553
+ const product = productFrom(properties);
554
+ if (!product) {
555
+ if (strict)
556
+ throw new Error(`FlowGrid.track("${eventName}") missing required properties: product or productId, name, price`);
557
+ return UNHANDLED_TRACK;
558
+ }
559
+ return handled(this.products.client.view({
560
+ ...product,
561
+ ...omitProperties(properties, ["product", ...PRODUCT_KEYS]),
562
+ }));
563
+ }
564
+ case "product_impression":
565
+ if (!this.requireTrackProperties(eventName, properties, ["list"], strict))
566
+ return UNHANDLED_TRACK;
567
+ return handled(this.products.client.impression(properties));
568
+ case "product_click": {
569
+ const product = productFrom(properties);
570
+ if (!product || !this.requireTrackProperties(eventName, properties, ["listId", "position"], strict))
571
+ return UNHANDLED_TRACK;
572
+ return handled(this.products.client.click({
573
+ ...properties,
574
+ product,
575
+ }));
576
+ }
577
+ case "add_to_cart":
578
+ case "remove_from_cart": {
579
+ const product = productFrom(properties);
580
+ if (!product) {
581
+ if (strict)
582
+ throw new Error(`FlowGrid.track("${eventName}") missing required properties: product or productId, name, price`);
583
+ return UNHANDLED_TRACK;
584
+ }
585
+ const config = {
586
+ ...omitProperties(properties, ["product", ...PRODUCT_KEYS]),
587
+ product,
588
+ quantity: numberValue(properties, "quantity") ?? 1,
589
+ };
590
+ return handled(eventName === "add_to_cart"
591
+ ? this.cart.client.addItem(config)
592
+ : this.cart.client.removeItem(config));
593
+ }
594
+ case "update_cart_item": {
595
+ const product = productFrom(properties);
596
+ if (!product || !this.requireTrackProperties(eventName, properties, ["previousQuantity", "newQuantity"], strict))
597
+ return UNHANDLED_TRACK;
598
+ return handled(this.cart.client.updateItem({
599
+ ...omitProperties(properties, ["product", ...PRODUCT_KEYS]),
600
+ product,
601
+ }));
602
+ }
603
+ case "view_cart":
604
+ if (!this.requireTrackProperties(eventName, properties, ["cart"], strict))
605
+ return UNHANDLED_TRACK;
606
+ return handled(this.cart.client.view(properties));
607
+ case "begin_checkout":
608
+ if (!this.requireTrackProperties(eventName, properties, ["cart"], strict))
609
+ return UNHANDLED_TRACK;
610
+ return handled(this.checkout.client.begin(properties));
611
+ case "checkout_step":
612
+ if (!this.requireTrackProperties(eventName, properties, ["step", "stepNumber", "cart"], strict))
613
+ return UNHANDLED_TRACK;
614
+ return handled(this.checkout.client.step(properties));
615
+ case "add_shipping_info":
616
+ if (!this.requireTrackProperties(eventName, properties, ["cart", "shipping"], strict))
617
+ return UNHANDLED_TRACK;
618
+ return handled(this.checkout.client.addShipping(properties));
619
+ case "add_payment_info":
620
+ if (!this.requireTrackProperties(eventName, properties, ["cart", "payment"], strict))
621
+ return UNHANDLED_TRACK;
622
+ return handled(this.checkout.client.addPayment(properties));
623
+ case "purchase":
624
+ if (!this.requireTrackProperties(eventName, properties, ["order"], strict))
625
+ return UNHANDLED_TRACK;
626
+ return handled(this.purchases.client.track(properties));
627
+ case "refund":
628
+ if (!this.requireTrackProperties(eventName, properties, ["orderId", "refundId", "amount", "currency"], strict))
629
+ return UNHANDLED_TRACK;
630
+ return handled(this.refunds.client.track(properties));
631
+ case "refund_requested":
632
+ if (!this.requireTrackProperties(eventName, properties, ["orderId"], strict))
633
+ return UNHANDLED_TRACK;
634
+ return handled(this.refunds.client.request(stringValue(properties, "orderId"), properties.items, stringValue(properties, "reason")));
635
+ case "refund_approved":
636
+ if (!this.requireTrackProperties(eventName, properties, ["refundId", "approvedAmount"], strict))
637
+ return UNHANDLED_TRACK;
638
+ return handled(this.refunds.client.approve(stringValue(properties, "refundId"), numberValue(properties, "approvedAmount")));
639
+ case "refund_denied":
640
+ if (!this.requireTrackProperties(eventName, properties, ["refundId", "reason"], strict))
641
+ return UNHANDLED_TRACK;
642
+ return handled(this.refunds.client.deny(stringValue(properties, "refundId"), stringValue(properties, "reason")));
643
+ case "refund_completed":
644
+ if (!this.requireTrackProperties(eventName, properties, ["refundId", "processedAmount"], strict))
645
+ return UNHANDLED_TRACK;
646
+ return handled(this.refunds.client.complete(stringValue(properties, "refundId"), numberValue(properties, "processedAmount")));
647
+ case "promotion_view":
648
+ if (!this.requireTrackProperties(eventName, properties, ["promotionId", "name", "creative", "position"], strict))
649
+ return UNHANDLED_TRACK;
650
+ return handled(this.promotions.client.view(properties));
651
+ case "promotion_click":
652
+ if (!this.requireTrackProperties(eventName, properties, ["promotionId", "name", "creative", "position"], strict))
653
+ return UNHANDLED_TRACK;
654
+ return handled(this.promotions.client.click(properties));
655
+ case "coupon_used":
656
+ if (!this.requireTrackProperties(eventName, properties, ["code", "orderId", "discountValue", "discountType", "orderValueBefore", "orderValueAfter"], strict))
657
+ return UNHANDLED_TRACK;
658
+ return handled(this.promotions.client.couponUsed(properties));
659
+ case "add_to_wishlist":
660
+ case "remove_from_wishlist": {
661
+ const product = productFrom(properties);
662
+ if (!product) {
663
+ if (strict)
664
+ throw new Error(`FlowGrid.track("${eventName}") missing required properties: product or productId, name, price`);
665
+ return UNHANDLED_TRACK;
666
+ }
667
+ const config = { ...omitProperties(properties, ["product", ...PRODUCT_KEYS]), product };
668
+ return handled(eventName === "add_to_wishlist"
669
+ ? this.wishlist.client.add(config)
670
+ : this.wishlist.client.remove(config));
671
+ }
672
+ case "view_wishlist":
673
+ if (!this.requireTrackProperties(eventName, properties, ["wishlist"], strict))
674
+ return UNHANDLED_TRACK;
675
+ return handled(this.wishlist.client.view(recordValue(properties, "wishlist")));
676
+ case "wishlist_to_cart": {
677
+ const product = productFrom(properties);
678
+ if (!product) {
679
+ if (strict)
680
+ throw new Error(`FlowGrid.track("${eventName}") missing required properties: product or productId, name, price`);
681
+ return UNHANDLED_TRACK;
682
+ }
683
+ return handled(this.wishlist.client.moveToCart(product, stringValue(properties, "wishlistId")));
684
+ }
685
+ case "share_wishlist":
686
+ if (!this.requireTrackProperties(eventName, properties, ["wishlistId", "method"], strict))
687
+ return UNHANDLED_TRACK;
688
+ return handled(this.wishlist.client.share(stringValue(properties, "wishlistId"), stringValue(properties, "method")));
689
+ case "subscription_start":
690
+ if (!this.requireTrackProperties(eventName, properties, ["subscriptionId", "userId", "plan", "mrr", "billingCycle"], strict))
691
+ return UNHANDLED_TRACK;
692
+ return handled(this.subscriptions.client.start(properties));
693
+ case "subscription_change":
694
+ if (!this.requireTrackProperties(eventName, properties, ["subscriptionId", "userId", "previousPlan", "newPlan", "previousMrr", "newMrr", "changeType"], strict))
695
+ return UNHANDLED_TRACK;
696
+ return handled(this.subscriptions.client.change(properties));
697
+ case "subscription_cancel":
698
+ if (!this.requireTrackProperties(eventName, properties, ["subscriptionId", "userId", "plan", "lostMrr"], strict))
699
+ return UNHANDLED_TRACK;
700
+ return handled(this.subscriptions.client.cancel(properties));
701
+ case "subscription_renew":
702
+ if (!this.requireTrackProperties(eventName, properties, ["subscriptionId", "userId", "mrr"], strict))
703
+ return UNHANDLED_TRACK;
704
+ return handled(this.subscriptions.client.renew(stringValue(properties, "subscriptionId"), stringValue(properties, "userId"), recordValue(properties, "mrr")));
705
+ case "trial_converted":
706
+ if (!this.requireTrackProperties(eventName, properties, ["subscriptionId", "userId", "plan", "mrr"], strict))
707
+ return UNHANDLED_TRACK;
708
+ return handled(this.subscriptions.client.trialConverted(stringValue(properties, "subscriptionId"), stringValue(properties, "userId"), stringValue(properties, "plan"), recordValue(properties, "mrr")));
709
+ case "trial_expired":
710
+ if (!this.requireTrackProperties(eventName, properties, ["subscriptionId", "userId"], strict))
711
+ return UNHANDLED_TRACK;
712
+ return handled(this.subscriptions.client.trialExpired(stringValue(properties, "subscriptionId"), stringValue(properties, "userId")));
713
+ case "record_acquisition_cost":
714
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "cost", "channel"], strict))
715
+ return UNHANDLED_TRACK;
716
+ return handled(this.ltv.client.recordAcquisitionCost(properties));
717
+ case "update_customer_segment":
718
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "newSegment"], strict))
719
+ return UNHANDLED_TRACK;
720
+ return handled(this.ltv.client.updateSegment(stringValue(properties, "userId"), stringValue(properties, "newSegment")));
721
+ case "site_search":
722
+ if (!this.requireTrackProperties(eventName, properties, ["query", "resultsCount"], strict))
723
+ return UNHANDLED_TRACK;
724
+ return handled(this.search.client.track(properties));
725
+ case "search_result_click": {
726
+ const product = productFrom(properties);
727
+ if (!product || !this.requireTrackProperties(eventName, properties, ["query", "position"], strict))
728
+ return UNHANDLED_TRACK;
729
+ return handled(this.search.client.trackClick({ ...properties, product }));
730
+ }
731
+ case "search_refinement":
732
+ if (!this.requireTrackProperties(eventName, properties, ["originalQuery", "refinedQuery", "refinementType"], strict))
733
+ return UNHANDLED_TRACK;
734
+ return handled(this.search.client.trackRefinement(stringValue(properties, "originalQuery"), stringValue(properties, "refinedQuery"), stringValue(properties, "refinementType")));
735
+ case "search_suggestion":
736
+ if (!this.requireTrackProperties(eventName, properties, ["partialQuery", "selectedSuggestion", "suggestionPosition"], strict))
737
+ return UNHANDLED_TRACK;
738
+ return handled(this.search.client.trackSuggestion(stringValue(properties, "partialQuery"), stringValue(properties, "selectedSuggestion"), numberValue(properties, "suggestionPosition")));
739
+ default:
740
+ return UNHANDLED_TRACK;
741
+ }
742
+ }
743
+ dispatchEnterpriseTrack(eventName, properties, strict, domain) {
744
+ // Enterprise chunk not yet loaded — let the event fall through to events.track().
745
+ if (!_enterpriseFeatures || !_enterpriseTracking)
746
+ return UNHANDLED_TRACK;
747
+ switch (eventName) {
748
+ case "engagement.dwell_time":
749
+ case "engagement_dwell_time":
750
+ if (domain && domain !== "engagement")
751
+ return UNHANDLED_TRACK;
752
+ if (!this.requireTrackProperties(eventName, properties, ["featureId", "dwellTimeMs"], strict))
753
+ return UNHANDLED_TRACK;
754
+ return handled(this.engagement.client.trackDwellTime(properties));
755
+ case "engagement.session_depth":
756
+ case "engagement_session_depth":
757
+ if (domain && domain !== "engagement")
758
+ return UNHANDLED_TRACK;
759
+ if (!this.requireTrackProperties(eventName, properties, ["sessionId", "pagesVisited", "featuresUsed", "actionsTaken", "durationMs"], strict))
760
+ return UNHANDLED_TRACK;
761
+ return handled(this.engagement.client.trackSessionDepth(properties));
762
+ case "engagement.content_consumption":
763
+ case "engagement_content_consumption":
764
+ if (domain && domain !== "engagement")
765
+ return UNHANDLED_TRACK;
766
+ if (!this.requireTrackProperties(eventName, properties, ["contentId", "contentType", "percentageConsumed", "timeSpentMs"], strict))
767
+ return UNHANDLED_TRACK;
768
+ return handled(this.engagement.client.trackContentConsumption(properties));
769
+ case "engagement.user_activity":
770
+ case "engagement_user_activity":
771
+ if (domain && domain !== "engagement")
772
+ return UNHANDLED_TRACK;
773
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "activityType", "durationMs"], strict))
774
+ return UNHANDLED_TRACK;
775
+ return handled(this.engagement.client.trackUserActivity(properties));
776
+ case "churn.usage_decay":
777
+ case "churn_usage_decay":
778
+ if (domain && domain !== "churn")
779
+ return UNHANDLED_TRACK;
780
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "metric", "periods"], strict))
781
+ return UNHANDLED_TRACK;
782
+ return handled(this.churn.client.trackUsageDecay(properties));
783
+ case "churn.nps":
784
+ case "churn_nps":
785
+ if (domain && domain !== "churn")
786
+ return UNHANDLED_TRACK;
787
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "score"], strict))
788
+ return UNHANDLED_TRACK;
789
+ return handled(this.churn.client.trackNPS(properties));
790
+ case "churn.churn_event":
791
+ case "churn_churn_event":
792
+ if (domain && domain !== "churn")
793
+ return UNHANDLED_TRACK;
794
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "churnType"], strict))
795
+ return UNHANDLED_TRACK;
796
+ return handled(this.churn.client.trackChurn(properties));
797
+ case "churn.prevention_action":
798
+ case "churn_prevention_action":
799
+ if (domain && domain !== "churn")
800
+ return UNHANDLED_TRACK;
801
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "actionType"], strict))
802
+ return UNHANDLED_TRACK;
803
+ return handled(this.churn.client.trackPreventionAction(properties));
804
+ case "monetization.revenue":
805
+ case "monetization_revenue":
806
+ if (domain && domain !== "monetization")
807
+ return UNHANDLED_TRACK;
808
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "amount", "currency", "type"], strict))
809
+ return UNHANDLED_TRACK;
810
+ return handled(this.monetization.client.trackRevenue(properties));
811
+ case "support.ticket_created":
812
+ case "support_ticket_created":
813
+ if (domain && domain !== "support")
814
+ return UNHANDLED_TRACK;
815
+ if (!this.requireTrackProperties(eventName, properties, ["ticketId", "userId", "subject", "category", "priority", "channel"], strict))
816
+ return UNHANDLED_TRACK;
817
+ return handled(this.support.client.trackTicket(properties));
818
+ case "support.ticket_updated":
819
+ case "support_ticket_updated":
820
+ if (domain && domain !== "support")
821
+ return UNHANDLED_TRACK;
822
+ if (!this.requireTrackProperties(eventName, properties, ["ticketId", "status"], strict))
823
+ return UNHANDLED_TRACK;
824
+ return handled(this.support.client.updateTicket(properties));
825
+ case "support.csat":
826
+ case "support_csat":
827
+ if (domain && domain !== "support")
828
+ return UNHANDLED_TRACK;
829
+ if (!this.requireTrackProperties(eventName, properties, ["ticketId", "userId", "score"], strict))
830
+ return UNHANDLED_TRACK;
831
+ return handled(this.support.client.trackCSAT(properties));
832
+ case "support.feature_complaint":
833
+ case "support_feature_complaint":
834
+ if (domain && domain !== "support")
835
+ return UNHANDLED_TRACK;
836
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "featureId", "complaintType", "severity"], strict))
837
+ return UNHANDLED_TRACK;
838
+ return handled(this.support.client.trackFeatureComplaint(properties));
839
+ case "acquisition.acquired":
840
+ case "acquisition_acquired":
841
+ if (domain && domain !== "acquisition")
842
+ return UNHANDLED_TRACK;
843
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "source"], strict))
844
+ return UNHANDLED_TRACK;
845
+ return handled(this.acquisition.client.trackAcquisition(properties));
846
+ case "acquisition.lifecycle_transition":
847
+ case "acquisition_lifecycle_transition":
848
+ if (domain && domain !== "acquisition")
849
+ return UNHANDLED_TRACK;
850
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "fromStage", "toStage"], strict))
851
+ return UNHANDLED_TRACK;
852
+ return handled(this.acquisition.client.trackLifecycleTransition(properties));
853
+ case "acquisition.campaign_spend":
854
+ case "acquisition_campaign_spend":
855
+ if (domain && domain !== "acquisition")
856
+ return UNHANDLED_TRACK;
857
+ if (!this.requireTrackProperties(eventName, properties, ["campaignId", "amount", "date"], strict))
858
+ return UNHANDLED_TRACK;
859
+ return handled(this.acquisition.client.trackCampaignSpend(properties));
860
+ case "paths.transition":
861
+ case "paths_transition":
862
+ if (domain && domain !== "paths")
863
+ return UNHANDLED_TRACK;
864
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "fromScreen", "toScreen"], strict))
865
+ return UNHANDLED_TRACK;
866
+ return handled(this.paths.client.trackTransition(properties));
867
+ case "paths.feature_sequence":
868
+ case "paths_feature_sequence":
869
+ if (domain && domain !== "paths")
870
+ return UNHANDLED_TRACK;
871
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "feature", "order"], strict))
872
+ return UNHANDLED_TRACK;
873
+ return handled(this.paths.client.trackFeatureSequence(properties));
874
+ case "security.login_attempt":
875
+ case "security_login_attempt":
876
+ if (domain && domain !== "security")
877
+ return UNHANDLED_TRACK;
878
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "success"], strict))
879
+ return UNHANDLED_TRACK;
880
+ return handled(this.security.client.trackLoginAttempt(properties));
881
+ case "security.role_change":
882
+ case "security_role_change":
883
+ if (domain && domain !== "security")
884
+ return UNHANDLED_TRACK;
885
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "changedBy", "previousRole", "newRole"], strict))
886
+ return UNHANDLED_TRACK;
887
+ return handled(this.security.client.trackRoleChange(properties));
888
+ case "security.permission_change":
889
+ case "security_permission_change":
890
+ if (domain && domain !== "security")
891
+ return UNHANDLED_TRACK;
892
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "changedBy", "permission", "action"], strict))
893
+ return UNHANDLED_TRACK;
894
+ return handled(this.security.client.trackPermissionChange(properties));
895
+ case "security.data_access":
896
+ case "security_data_access":
897
+ if (domain && domain !== "security")
898
+ return UNHANDLED_TRACK;
899
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "resourceType", "accessType"], strict))
900
+ return UNHANDLED_TRACK;
901
+ return handled(this.security.client.trackDataAccess(properties));
902
+ case "security.compliance_event":
903
+ case "security_compliance_event":
904
+ if (domain && domain !== "security")
905
+ return UNHANDLED_TRACK;
906
+ if (!this.requireTrackProperties(eventName, properties, ["userId", "eventType"], strict))
907
+ return UNHANDLED_TRACK;
908
+ return handled(this.security.client.trackComplianceEvent(properties));
909
+ case "multi_path_funnels.track_step":
910
+ case "multi_path_funnels_track_step":
911
+ if (domain && domain !== "multiPathFunnels")
912
+ return UNHANDLED_TRACK;
913
+ if (!this.requireTrackProperties(eventName, properties, ["funnelId", "step", "userId"], strict))
914
+ return UNHANDLED_TRACK;
915
+ return handled(this.multiPathFunnels.client.trackStep(properties));
916
+ case "multi_path_funnels.track_micro_conversion":
917
+ case "multi_path_funnels_track_micro_conversion":
918
+ if (domain && domain !== "multiPathFunnels")
919
+ return UNHANDLED_TRACK;
920
+ if (!this.requireTrackProperties(eventName, properties, ["conversionId", "userId"], strict))
921
+ return UNHANDLED_TRACK;
922
+ return handled(this.multiPathFunnels.client.trackMicroConversion(properties));
923
+ default:
924
+ return UNHANDLED_TRACK;
925
+ }
926
+ }
202
927
  /**
203
928
  * Record an experiment exposure for a user.
204
929
  *
@@ -274,7 +999,22 @@ export class FlowGrid {
274
999
  }
275
1000
  if (options.engagement !== false) {
276
1001
  const engOpts = typeof options.engagement === "object" ? options.engagement : {};
277
- teardowns.push(this.engagement.client.autoTrack({ ...engOpts, userId: ctx.userId }));
1002
+ // Engagement lives in the enterprise chunk — start async (mirrors replay pattern).
1003
+ let resolvedEngStop = null;
1004
+ let engStopRequested = false;
1005
+ void loadEnterpriseModules().then(() => {
1006
+ if (engStopRequested)
1007
+ return;
1008
+ resolvedEngStop = this.engagement.client.autoTrack({ ...engOpts, userId: ctx.userId });
1009
+ });
1010
+ teardowns.push(() => {
1011
+ engStopRequested = true;
1012
+ if (resolvedEngStop)
1013
+ try {
1014
+ resolvedEngStop();
1015
+ }
1016
+ catch { /* noop */ }
1017
+ });
278
1018
  }
279
1019
  if (options.attribution !== false && ctx.userId) {
280
1020
  this.attribution.captureFromUrl(ctx.userId);
@@ -314,10 +1054,11 @@ export class FlowGrid {
314
1054
  } };
315
1055
  }
316
1056
  }
1057
+ exports.FlowGrid = FlowGrid;
317
1058
  /** Singleton created by {@link FlowGrid.init}. */
318
1059
  FlowGrid._instance = null;
319
1060
  // ---- Consent passthrough (static on transport) ----
320
- FlowGrid.setConsent = FlowGridTransport.setConsent.bind(FlowGridTransport);
321
- FlowGrid.hasConsent = FlowGridTransport.hasConsent.bind(FlowGridTransport);
322
- export default FlowGrid;
1061
+ FlowGrid.setConsent = transport_1.FlowGridTransport.setConsent.bind(transport_1.FlowGridTransport);
1062
+ FlowGrid.hasConsent = transport_1.FlowGridTransport.hasConsent.bind(transport_1.FlowGridTransport);
1063
+ exports.default = FlowGrid;
323
1064
  //# sourceMappingURL=flowgrid.js.map