flowgrid-sdk 1.6.8 → 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,33 +171,51 @@ Each replay chunk includes the core ingestion fields `web_id`, `visitor_id`, `se
163
171
 
164
172
  ---
165
173
 
166
- ## Feature Usage (one-liner)
174
+ ## Feature Usage
167
175
 
168
- Track product feature adoption with a **single call**the SDK derives the whole
169
- lifecycle so you don't hand-emit each stage:
176
+ Track product feature usage with a plain event`featureId` and `featureName`
177
+ are the only required props:
170
178
 
171
179
  ```ts
172
- fg.feature("ai-agent-builder"); // auto: discovered viewed adopted
173
- fg.feature("ai-agent-builder", { completed: true }); // finished the job
174
- fg.feature("ai-agent-builder", { abandoned: true }); // started, gave up
175
- // script tag: FlowGrid.feature("ai-agent-builder")
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()
176
213
  ```
177
214
 
178
- Per visitor, the SDK records first-ever use as **discovered** (+ viewed),
179
- subsequent uses as **viewed**, and emits **adopted** once after repeated use
180
- (default ≥2 distinct days or ≥5 uses; tune via `adoptionDays`/`adoptionUses`).
181
- Stages map 1:1 to the dashboard's adoption funnel. Display name is humanised from
182
- the id unless you pass `{ name }`; add `{ category }` to group features.
183
-
184
- No `userId` or `category` is required — it works for anonymous visitors out of
185
- the box (the backend defaults `userId` to the visitor and `category` to
186
- `"general"`). Provide them only to attribute usage to a known user / group features.
187
-
188
- Each derived stage is emitted through the unified **`.track("feature_usage", …)`**
189
- router (so it shares routing/consent/transport with every other event). Lifecycle
190
- state is kept in `localStorage` per visitor; if it's unavailable the call still
191
- records a `viewed`. The low-level `fg.features.used(id, name, stage)` remains for
192
- explicit-stage control.
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.
193
219
 
194
220
  ---
195
221
 
package/dist/browser.d.ts CHANGED
@@ -44,7 +44,7 @@ type BrowserFacade = {
44
44
  track: FlowGrid["track"];
45
45
  page: FlowGrid["page"];
46
46
  identify: FlowGrid["identifyUser"];
47
- feature: FlowGrid["feature"];
47
+ defineFeature: FlowGrid["defineFeature"];
48
48
  experiment: FlowGrid["experiment"];
49
49
  productView(product: BrowserProduct, properties?: Record<string, unknown>): ReturnType<FlowGrid["products"]["view"]>;
50
50
  addToCart(product: BrowserProduct, quantity?: number, cartId?: string): ReturnType<FlowGrid["cart"]["add"]>;
package/dist/browser.js CHANGED
@@ -84,8 +84,8 @@ const browserFlowGrid = {
84
84
  identify(userId, traits, anonymousId) {
85
85
  return getInstance().identifyUser(userId, traits, anonymousId);
86
86
  },
87
- feature(featureId, opts) {
88
- return getInstance().feature(featureId, opts);
87
+ defineFeature(featureId, featureName, opts) {
88
+ return getInstance().defineFeature(featureId, featureName, opts);
89
89
  },
90
90
  experiment(experimentId, options) {
91
91
  return getInstance().experiment(experimentId, options);
@@ -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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"}