flowgrid-sdk 1.6.7 → 1.6.9

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 CHANGED
@@ -34,6 +34,8 @@ await fg.track("add_to_cart", { productId: "sku_1", name: "T-Shirt", price: 29,
34
34
  ## Highlights
35
35
 
36
36
  - **One class, every feature** — `new FlowGrid(...)` exposes analytics, ecommerce, experiments, and enterprise modules as lazy properties.
37
+ - **Feature usage, explicit** — `fg.track("feature_usage", { featureId, featureName })`. You say what happened; the SDK just sends it.
38
+ - **Passive identity** — opt in with `autoTrack({ passiveIdentity: true })` to recognise anonymous visitors from any form (PII hashed in the browser).
37
39
  - **Framework-agnostic** — zero peer dependencies. Works with React, Vue, Next.js, Nuxt, Svelte, Astro, plain Node, Cloudflare Workers, etc.
38
40
  - **Tree-shake-friendly** — also export individual modules (`Events`, `Products`, `Experiment`, …) for minimal bundles.
39
41
  - **Privacy & consent built-in** — DNT/GPC support, `ConsentManager`, bot filtering.
@@ -73,6 +75,9 @@ const fg = FlowGrid.init({
73
75
  // Plain custom events still work.
74
76
  await fg.track("cta_click", { id: "hero" }, { userId: "u_1" });
75
77
 
78
+ // Feature usage — a plain event.
79
+ fg.track("feature_usage", { featureId: "data_export", featureName: "Data Export" });
80
+
76
81
  // Recognized event names route to the matching feature module.
77
82
  await fg.track("feature_used", { featureId: "export", featureName: "Data Export", userId: "u_1" });
78
83
  await fg.track("prompt_submitted", { promptId: "p_1", promptType: "chat", userId: "u_1" });
@@ -111,16 +116,19 @@ await events.track({ eventName: "signup", properties: { plan: "pro" } });
111
116
 
112
117
  FlowGrid.track("signup_clicked", { placement: "hero" });
113
118
  FlowGrid.identify("user_123", { plan: "pro" });
119
+ FlowGrid.track("feature_usage", { featureId: "ai_agent_builder", featureName: "AI Agent Builder" });
114
120
  FlowGrid.productView({ productId: "sku_1", name: "T-Shirt", price: 29 });
115
121
  FlowGrid.addToCart({ productId: "sku_1", name: "T-Shirt", price: 29 }, 1);
116
122
  </script>
117
123
  ```
118
124
 
119
125
  The script-tag API is intentionally small: `init`, `track`, `page`, `identify`,
120
- `experiment`, `productView`, `addToCart`, `purchase`, consent helpers, and
121
- `instance()` for the full SDK. `FlowGrid.init()` auto-instruments sessions, page
122
- views, SPA route changes, scroll depth, time on page, performance, heatmaps,
123
- and attribution by default; session replay is opt-in with `replay: true`.
126
+ `feature`, `experiment`, `productView`, `addToCart`, `purchase`, `autoTrack`,
127
+ consent helpers (`setConsent` / `hasConsent`), `reset`, and `instance()` for the
128
+ full SDK. `FlowGrid.init()` auto-instruments sessions, page views, SPA route
129
+ changes, scroll depth, time on page, performance, heatmaps, and attribution by
130
+ default; session replay is opt-in with `replay: true`, and passive identity
131
+ capture with `autoTrack({ passiveIdentity: true })`.
124
132
 
125
133
  ---
126
134
 
@@ -163,6 +171,82 @@ Each replay chunk includes the core ingestion fields `web_id`, `visitor_id`, `se
163
171
 
164
172
  ---
165
173
 
174
+ ## Feature Usage
175
+
176
+ Track product feature usage with a plain event — `featureId` and `featureName`
177
+ are the only required props:
178
+
179
+ ```ts
180
+ fg.track("feature_usage", { featureId: "ai_agent_builder", featureName: "AI Agent Builder" });
181
+
182
+ // Optional: an action ("viewed" | "used" | "completed" | "abandoned"), a category, a known user.
183
+ fg.track("feature_usage", {
184
+ featureId: "ai_agent_builder",
185
+ featureName: "AI Agent Builder",
186
+ action: "completed",
187
+ category: "automation",
188
+ userId: "u_1",
189
+ });
190
+ // script tag: FlowGrid.track("feature_usage", { featureId: "ai_agent_builder", featureName: "AI Agent Builder" })
191
+ ```
192
+
193
+ `action` defaults to `"used"`. No `userId` or `category` is required — it works
194
+ for anonymous visitors out of the box (the backend defaults `userId` to the
195
+ visitor and `category` to `"general"`). The event routes through the unified
196
+ `.track()` router, so it shares routing/consent/transport with every other event.
197
+
198
+ ### Helpers
199
+
200
+ Don't want to hand-write `track("feature_usage", …)` and repeat the id/name?
201
+ Bind a feature once with **`fg.defineFeature`** and call the verb that describes
202
+ what happened — each maps to a lifecycle stage the dashboard funnel understands
203
+ (a *viewed* feature is Discovered, a *used* one is Adopted):
204
+
205
+ ```ts
206
+ const agent = fg.defineFeature("ai-agent-builder", "AI Agent Builder", { category: "automation" });
207
+
208
+ agent.viewed(); // action: "viewed" → Discovered + Viewed
209
+ agent.used({ model: "opus" }); // action: "used" → Adopted
210
+ agent.completed(); // action: "completed" → Completed
211
+ agent.abandoned(); // action: "abandoned" → Abandonment
212
+ // script tag: FlowGrid.defineFeature("ai-agent-builder", "AI Agent Builder").used()
213
+ ```
214
+
215
+ Each call is a thin, explicit wrapper over `track("feature_usage", …)` — no
216
+ hidden state, no lifecycle guessing; you send exactly the action you name. The
217
+ same verbs exist on `fg.features.viewed/used/completed/abandoned(id, name)` for
218
+ one-off calls, and `fg.features.record(id, name, action)` for a dynamic action.
219
+
220
+ ---
221
+
222
+ ## Passive Identity Capture
223
+
224
+ Recognise anonymous visitors automatically: when a visitor types their email /
225
+ name / phone into **any** form, FlowGrid classifies the field, hashes PII in the
226
+ browser, and links the identity to their `visitor_id` — so the dashboard shows
227
+ them by name (and, with a CRM connected, matches them to the contact). No
228
+ per-form instrumentation.
229
+
230
+ It's **opt-in** in the SDK (the `flowgrid.js` snippet runs it by default) and
231
+ requires `analytics` consent:
232
+
233
+ ```ts
234
+ const fg = FlowGrid.init({ webId: "...", apiKey: "..." });
235
+ FlowGrid.setConsent({ analytics: true });
236
+
237
+ const stop = fg.autoTrack({ passiveIdentity: true });
238
+ // or with options:
239
+ fg.autoTrack({ passiveIdentity: { debounceMs: 800, excludePath: /\/(checkout|admin)/i } });
240
+ ```
241
+
242
+ Never reads `password`/`hidden`/card/cvv/ssn/pin fields, anything marked
243
+ `data-analytics="ignore"` or `.no-track`, free-text (message/comment/search), or
244
+ sensitive paths (`/checkout`, `/account/settings`, `/admin`). Raw email goes only
245
+ to the server-side identity store; the event stream sees hashes. Full guide:
246
+ `vission_manager/docs/PASSIVE_IDENTITY_DEVELOPER_GUIDE.md`.
247
+
248
+ ---
249
+
166
250
  ## Server-side / Edge Usage
167
251
 
168
252
  Works in any JavaScript runtime that supports `fetch` — Node, Bun, Deno, Cloudflare Workers, Vercel Edge, etc.
package/dist/browser.d.ts CHANGED
@@ -44,6 +44,7 @@ type BrowserFacade = {
44
44
  track: FlowGrid["track"];
45
45
  page: FlowGrid["page"];
46
46
  identify: FlowGrid["identifyUser"];
47
+ defineFeature: FlowGrid["defineFeature"];
47
48
  experiment: FlowGrid["experiment"];
48
49
  productView(product: BrowserProduct, properties?: Record<string, unknown>): ReturnType<FlowGrid["products"]["view"]>;
49
50
  addToCart(product: BrowserProduct, quantity?: number, cartId?: string): ReturnType<FlowGrid["cart"]["add"]>;
package/dist/browser.js CHANGED
@@ -84,6 +84,9 @@ const browserFlowGrid = {
84
84
  identify(userId, traits, anonymousId) {
85
85
  return getInstance().identifyUser(userId, traits, anonymousId);
86
86
  },
87
+ defineFeature(featureId, featureName, opts) {
88
+ return getInstance().defineFeature(featureId, featureName, opts);
89
+ },
87
90
  experiment(experimentId, options) {
88
91
  return getInstance().experiment(experimentId, options);
89
92
  },
@@ -1 +1 @@
1
- {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"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"}