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.
- package/README.md +17 -29
- package/dist/browser.js +12 -9
- package/dist/browser.js.map +1 -1
- package/dist/flowgrid-enterprise.flowgrid.chunk.js +2 -0
- package/dist/flowgrid-enterprise.flowgrid.chunk.js.map +1 -0
- package/dist/flowgrid-replay.flowgrid.chunk.js +3 -0
- package/dist/flowgrid-replay.flowgrid.chunk.js.LICENSE.txt +14 -0
- package/dist/flowgrid-replay.flowgrid.chunk.js.map +1 -0
- package/dist/flowgrid-vitals.flowgrid.chunk.js +2 -0
- package/dist/flowgrid-vitals.flowgrid.chunk.js.map +1 -0
- package/dist/flowgrid.min.js +1 -1
- package/dist/flowgrid.min.js.LICENSE.txt +14 -0
- package/dist/flowgrid.min.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +63 -10
- package/dist/index.js.map +1 -1
- package/dist/lib/client/transport.js +5 -1
- package/dist/lib/client/transport.js.map +1 -1
- package/dist/lib/consent/index.js +5 -1
- package/dist/lib/consent/index.js.map +1 -1
- package/dist/lib/consent/manager.js +5 -1
- package/dist/lib/consent/manager.js.map +1 -1
- package/dist/lib/consent/types.js +2 -1
- package/dist/lib/consent/types.js.map +1 -1
- package/dist/lib/features/analytics/attribution.js +11 -7
- package/dist/lib/features/analytics/attribution.js.map +1 -1
- package/dist/lib/features/analytics/events.js +7 -3
- package/dist/lib/features/analytics/events.js.map +1 -1
- package/dist/lib/features/analytics/funnels.js +7 -3
- package/dist/lib/features/analytics/funnels.js.map +1 -1
- package/dist/lib/features/analytics/heatmaps.js +12 -8
- package/dist/lib/features/analytics/heatmaps.js.map +1 -1
- package/dist/lib/features/analytics/identify.js +7 -3
- package/dist/lib/features/analytics/identify.js.map +1 -1
- package/dist/lib/features/analytics/index.js +24 -10
- package/dist/lib/features/analytics/index.js.map +1 -1
- package/dist/lib/features/analytics/page-views.js +12 -8
- package/dist/lib/features/analytics/page-views.js.map +1 -1
- package/dist/lib/features/analytics/performance.js +46 -9
- package/dist/lib/features/analytics/performance.js.map +1 -1
- package/dist/lib/features/analytics/replay.js +46 -9
- package/dist/lib/features/analytics/replay.js.map +1 -1
- package/dist/lib/features/analytics/retention.js +7 -3
- package/dist/lib/features/analytics/retention.js.map +1 -1
- package/dist/lib/features/analytics/sessions.js +12 -8
- package/dist/lib/features/analytics/sessions.js.map +1 -1
- package/dist/lib/features/core/activation.js +7 -3
- package/dist/lib/features/core/activation.js.map +1 -1
- package/dist/lib/features/core/experiment.js +9 -5
- package/dist/lib/features/core/experiment.js.map +1 -1
- package/dist/lib/features/core/index.js +11 -4
- package/dist/lib/features/core/index.js.map +1 -1
- package/dist/lib/features/core/track-feature.js +7 -3
- package/dist/lib/features/core/track-feature.js.map +1 -1
- package/dist/lib/features/core/track-prompt.js +7 -3
- package/dist/lib/features/core/track-prompt.js.map +1 -1
- package/dist/lib/features/ecommerce/cart.js +7 -3
- package/dist/lib/features/ecommerce/cart.js.map +1 -1
- package/dist/lib/features/ecommerce/checkout.js +7 -3
- package/dist/lib/features/ecommerce/checkout.js.map +1 -1
- package/dist/lib/features/ecommerce/index.js +23 -10
- package/dist/lib/features/ecommerce/index.js.map +1 -1
- package/dist/lib/features/ecommerce/ltv.js +7 -3
- package/dist/lib/features/ecommerce/ltv.js.map +1 -1
- package/dist/lib/features/ecommerce/products.js +7 -3
- package/dist/lib/features/ecommerce/products.js.map +1 -1
- package/dist/lib/features/ecommerce/promotions.js +7 -3
- package/dist/lib/features/ecommerce/promotions.js.map +1 -1
- package/dist/lib/features/ecommerce/purchases.js +7 -3
- package/dist/lib/features/ecommerce/purchases.js.map +1 -1
- package/dist/lib/features/ecommerce/refunds.js +7 -3
- package/dist/lib/features/ecommerce/refunds.js.map +1 -1
- package/dist/lib/features/ecommerce/search.js +7 -3
- package/dist/lib/features/ecommerce/search.js.map +1 -1
- package/dist/lib/features/ecommerce/subscriptions.js +7 -3
- package/dist/lib/features/ecommerce/subscriptions.js.map +1 -1
- package/dist/lib/features/ecommerce/wishlist.js +7 -3
- package/dist/lib/features/ecommerce/wishlist.js.map +1 -1
- package/dist/lib/features/enterprise/acquisition.js +16 -7
- package/dist/lib/features/enterprise/acquisition.js.map +1 -1
- package/dist/lib/features/enterprise/alerts.js +18 -8
- package/dist/lib/features/enterprise/alerts.js.map +1 -1
- package/dist/lib/features/enterprise/churn.js +12 -5
- package/dist/lib/features/enterprise/churn.js.map +1 -1
- package/dist/lib/features/enterprise/cohorts.js +10 -4
- package/dist/lib/features/enterprise/cohorts.js.map +1 -1
- package/dist/lib/features/enterprise/engagement.js +19 -12
- package/dist/lib/features/enterprise/engagement.js.map +1 -1
- package/dist/lib/features/enterprise/forecasting.js +18 -8
- package/dist/lib/features/enterprise/forecasting.js.map +1 -1
- package/dist/lib/features/enterprise/index.js +75 -22
- package/dist/lib/features/enterprise/index.js.map +1 -1
- package/dist/lib/features/enterprise/monetization.js +16 -7
- package/dist/lib/features/enterprise/monetization.js.map +1 -1
- package/dist/lib/features/enterprise/multi-path-funnels.js +16 -7
- package/dist/lib/features/enterprise/multi-path-funnels.js.map +1 -1
- package/dist/lib/features/enterprise/paths.js +18 -8
- package/dist/lib/features/enterprise/paths.js.map +1 -1
- package/dist/lib/features/enterprise/security.js +14 -6
- package/dist/lib/features/enterprise/security.js.map +1 -1
- package/dist/lib/features/enterprise/support.js +14 -6
- package/dist/lib/features/enterprise/support.js.map +1 -1
- package/dist/lib/flowgrid.d.ts +734 -10
- package/dist/lib/flowgrid.js +801 -60
- package/dist/lib/flowgrid.js.map +1 -1
- package/dist/lib/tracking/analytics/attribution.d.ts +3 -3
- package/dist/lib/tracking/analytics/attribution.js +5 -1
- package/dist/lib/tracking/analytics/attribution.js.map +1 -1
- package/dist/lib/tracking/analytics/events.d.ts +6 -6
- package/dist/lib/tracking/analytics/events.js +5 -1
- package/dist/lib/tracking/analytics/events.js.map +1 -1
- package/dist/lib/tracking/analytics/funnels.d.ts +4 -4
- package/dist/lib/tracking/analytics/funnels.js +5 -1
- package/dist/lib/tracking/analytics/funnels.js.map +1 -1
- package/dist/lib/tracking/analytics/heatmaps.d.ts +3 -3
- package/dist/lib/tracking/analytics/heatmaps.js +5 -1
- package/dist/lib/tracking/analytics/heatmaps.js.map +1 -1
- package/dist/lib/tracking/analytics/identify.d.ts +4 -4
- package/dist/lib/tracking/analytics/identify.js +5 -1
- package/dist/lib/tracking/analytics/identify.js.map +1 -1
- package/dist/lib/tracking/analytics/index.js +23 -10
- package/dist/lib/tracking/analytics/index.js.map +1 -1
- package/dist/lib/tracking/analytics/page-views.d.ts +4 -4
- package/dist/lib/tracking/analytics/page-views.js +5 -1
- package/dist/lib/tracking/analytics/page-views.js.map +1 -1
- package/dist/lib/tracking/analytics/performance.d.ts +3 -3
- package/dist/lib/tracking/analytics/performance.js +5 -1
- package/dist/lib/tracking/analytics/performance.js.map +1 -1
- package/dist/lib/tracking/analytics/replay.js +5 -1
- package/dist/lib/tracking/analytics/replay.js.map +1 -1
- package/dist/lib/tracking/analytics/retention.d.ts +1 -1
- package/dist/lib/tracking/analytics/retention.js +5 -1
- package/dist/lib/tracking/analytics/retention.js.map +1 -1
- package/dist/lib/tracking/analytics/sessions.d.ts +4 -4
- package/dist/lib/tracking/analytics/sessions.js +5 -1
- package/dist/lib/tracking/analytics/sessions.js.map +1 -1
- package/dist/lib/tracking/core/activation.d.ts +5 -5
- package/dist/lib/tracking/core/activation.js +5 -1
- package/dist/lib/tracking/core/activation.js.map +1 -1
- package/dist/lib/tracking/core/experiment.d.ts +4 -4
- package/dist/lib/tracking/core/experiment.js +5 -1
- package/dist/lib/tracking/core/experiment.js.map +1 -1
- package/dist/lib/tracking/core/feature.d.ts +2 -2
- package/dist/lib/tracking/core/feature.js +5 -1
- package/dist/lib/tracking/core/feature.js.map +1 -1
- package/dist/lib/tracking/core/index.js +11 -4
- package/dist/lib/tracking/core/index.js.map +1 -1
- package/dist/lib/tracking/core/prompt.d.ts +5 -5
- package/dist/lib/tracking/core/prompt.js +5 -1
- package/dist/lib/tracking/core/prompt.js.map +1 -1
- package/dist/lib/tracking/ecommerce/cart.d.ts +4 -4
- package/dist/lib/tracking/ecommerce/cart.js +5 -1
- package/dist/lib/tracking/ecommerce/cart.js.map +1 -1
- package/dist/lib/tracking/ecommerce/checkout.d.ts +4 -4
- package/dist/lib/tracking/ecommerce/checkout.js +5 -1
- package/dist/lib/tracking/ecommerce/checkout.js.map +1 -1
- package/dist/lib/tracking/ecommerce/index.js +23 -10
- package/dist/lib/tracking/ecommerce/index.js.map +1 -1
- package/dist/lib/tracking/ecommerce/ltv.d.ts +2 -2
- package/dist/lib/tracking/ecommerce/ltv.js +5 -1
- package/dist/lib/tracking/ecommerce/ltv.js.map +1 -1
- package/dist/lib/tracking/ecommerce/products.d.ts +3 -3
- package/dist/lib/tracking/ecommerce/products.js +5 -1
- package/dist/lib/tracking/ecommerce/products.js.map +1 -1
- package/dist/lib/tracking/ecommerce/promotions.d.ts +3 -3
- package/dist/lib/tracking/ecommerce/promotions.js +5 -1
- package/dist/lib/tracking/ecommerce/promotions.js.map +1 -1
- package/dist/lib/tracking/ecommerce/purchases.d.ts +1 -1
- package/dist/lib/tracking/ecommerce/purchases.js +5 -1
- package/dist/lib/tracking/ecommerce/purchases.js.map +1 -1
- package/dist/lib/tracking/ecommerce/refunds.d.ts +4 -4
- package/dist/lib/tracking/ecommerce/refunds.js +5 -1
- package/dist/lib/tracking/ecommerce/refunds.js.map +1 -1
- package/dist/lib/tracking/ecommerce/search.d.ts +4 -4
- package/dist/lib/tracking/ecommerce/search.js +5 -1
- package/dist/lib/tracking/ecommerce/search.js.map +1 -1
- package/dist/lib/tracking/ecommerce/subscriptions.d.ts +6 -6
- package/dist/lib/tracking/ecommerce/subscriptions.js +5 -1
- package/dist/lib/tracking/ecommerce/subscriptions.js.map +1 -1
- package/dist/lib/tracking/ecommerce/wishlist.d.ts +5 -5
- package/dist/lib/tracking/ecommerce/wishlist.js +5 -1
- package/dist/lib/tracking/ecommerce/wishlist.js.map +1 -1
- package/dist/lib/tracking/enterprise/acquisition.js +5 -1
- package/dist/lib/tracking/enterprise/acquisition.js.map +1 -1
- package/dist/lib/tracking/enterprise/alerts.js +5 -1
- package/dist/lib/tracking/enterprise/alerts.js.map +1 -1
- package/dist/lib/tracking/enterprise/churn.d.ts +1 -1
- package/dist/lib/tracking/enterprise/churn.js +5 -1
- package/dist/lib/tracking/enterprise/churn.js.map +1 -1
- package/dist/lib/tracking/enterprise/cohorts.d.ts +1 -1
- package/dist/lib/tracking/enterprise/cohorts.js +5 -1
- package/dist/lib/tracking/enterprise/cohorts.js.map +1 -1
- package/dist/lib/tracking/enterprise/engagement.d.ts +4 -4
- package/dist/lib/tracking/enterprise/engagement.js +5 -1
- package/dist/lib/tracking/enterprise/engagement.js.map +1 -1
- package/dist/lib/tracking/enterprise/forecasting.d.ts +4 -4
- package/dist/lib/tracking/enterprise/forecasting.js +5 -1
- package/dist/lib/tracking/enterprise/forecasting.js.map +1 -1
- package/dist/lib/tracking/enterprise/index.js +25 -11
- package/dist/lib/tracking/enterprise/index.js.map +1 -1
- package/dist/lib/tracking/enterprise/monetization.js +5 -1
- package/dist/lib/tracking/enterprise/monetization.js.map +1 -1
- package/dist/lib/tracking/enterprise/multi-path-funnels.js +5 -1
- package/dist/lib/tracking/enterprise/multi-path-funnels.js.map +1 -1
- package/dist/lib/tracking/enterprise/paths.js +5 -1
- package/dist/lib/tracking/enterprise/paths.js.map +1 -1
- package/dist/lib/tracking/enterprise/security.js +5 -1
- package/dist/lib/tracking/enterprise/security.js.map +1 -1
- package/dist/lib/tracking/enterprise/support.js +5 -1
- package/dist/lib/tracking/enterprise/support.js.map +1 -1
- package/dist/lib/tracking/index.js +20 -4
- package/dist/lib/tracking/index.js.map +1 -1
- package/dist/lib/types/analytics.js +2 -1
- package/dist/lib/types/analytics.js.map +1 -1
- package/dist/lib/types/common.js +2 -1
- package/dist/lib/types/common.js.map +1 -1
- package/dist/lib/types/ecommerce.js +2 -1
- package/dist/lib/types/ecommerce.js.map +1 -1
- package/dist/lib/types/index.js +19 -3
- package/dist/lib/types/index.js.map +1 -1
- package/dist/lib/utils/browser.js +10 -4
- package/dist/lib/utils/browser.js.map +1 -1
- package/dist/lib/utils/identity.js +8 -4
- package/dist/lib/utils/identity.js.map +1 -1
- package/dist/lib/utils/storage.js +14 -6
- package/dist/lib/utils/storage.js.map +1 -1
- package/dist/umd/index.js +2 -1
- package/dist/umd/index.js.LICENSE.txt +14 -0
- package/dist/umd/index.js.map +1 -1
- package/package.json +2 -1
package/dist/lib/flowgrid.js
CHANGED
|
@@ -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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
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
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|