alphana-sdk 1.0.0 → 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.
@@ -49,19 +49,34 @@ interface TrackerConfig {
49
49
  */
50
50
  trackLogs?: boolean;
51
51
  /**
52
- * List of page paths for which heatmap data should be captured.
53
- * Only paths registered here will be tracked. If empty or undefined, the SDK
54
- * will send data for all pages (the backend enforces limits at ingest time).
52
+ * List of page paths for which heatmap data should be captured client-side.
53
+ * Paths should match the dashboard "Heatmap pages" list (decoded Unicode is
54
+ * fine the SDK normalizes percent-encoding vs `window.location` mismatches).
55
55
  *
56
- * Obtain the list of registered paths from the alphana dashboard under
57
- * "Heatmap Pages" for your app, then pass them here.
56
+ * If empty or undefined, the SDK may still collect moves locally, but the
57
+ * backend only persists points when the app has at least one registered
58
+ * heatmap page and the path matches.
58
59
  *
59
60
  * Example: `heatmapPages: ["/", "/pricing", "/dashboard"]`
60
61
  */
61
62
  heatmapPages?: string[];
63
+ /**
64
+ * When true, records DOM mutations with rrweb and sends `session_replay` events
65
+ * for pixel-accurate session replay in the dashboard (requires plan + platform).
66
+ * @default false
67
+ */
68
+ sessionReplay?: boolean;
69
+ /** rrweb full snapshot interval in ms. @default 600000 (10 min) */
70
+ sessionReplayCheckoutEveryNms?: number;
71
+ /** Max rrweb events per batch before an immediate flush. @default 48 */
72
+ sessionReplayMaxEventsPerBatch?: number;
73
+ /** Periodic flush of buffered rrweb events (ms). @default 4000 */
74
+ sessionReplayFlushIntervalMs?: number;
62
75
  /** Called synchronously for every emitted event. */
63
76
  onEvent?: (event: TrackerEvent) => void;
64
77
  }
78
+ /** Assigned variant key per running A/B experiment (`null` = not in experiment). */
79
+ type AbVariantsMap = Record<string, string | null>;
65
80
  interface GeoLocation {
66
81
  /** ISO 3166-1 alpha-2 country code, e.g. "US" */
67
82
  country: string;
@@ -72,12 +87,32 @@ interface GeoLocation {
72
87
  latitude?: number;
73
88
  longitude?: number;
74
89
  }
90
+ interface UtmParams {
91
+ source?: string;
92
+ medium?: string;
93
+ campaign?: string;
94
+ term?: string;
95
+ content?: string;
96
+ }
97
+ interface AttributionContext {
98
+ landingPage: string;
99
+ referrer?: string;
100
+ referrerHost?: string;
101
+ utm?: UtmParams;
102
+ clickIds?: Record<string, string>;
103
+ capturedAt: number;
104
+ }
75
105
  interface PageView {
76
106
  path: string;
77
107
  title: string;
78
108
  timestamp: number;
79
109
  sessionId: string;
80
110
  referrer?: string;
111
+ utm?: UtmParams;
112
+ attribution?: {
113
+ firstTouch?: AttributionContext;
114
+ lastTouch?: AttributionContext;
115
+ };
81
116
  }
82
117
  interface TimeSpent {
83
118
  path: string;
@@ -124,6 +159,97 @@ interface UTurn {
124
159
  timestamp: number;
125
160
  sessionId: string;
126
161
  }
162
+ type UserProperties = Record<string, string>;
163
+ interface IdentifyEvent {
164
+ properties: UserProperties;
165
+ visitorId: string;
166
+ timestamp: number;
167
+ }
168
+ type RevenueEventStatus = "pending" | "paid" | "refunded" | "cancelled" | "failed";
169
+ interface RevenueLineItem {
170
+ id?: string;
171
+ name?: string;
172
+ category?: string;
173
+ quantity?: number;
174
+ price?: number;
175
+ }
176
+ interface RevenueEventPayload {
177
+ eventName?: "purchase" | "subscription" | "renewal" | "upgrade" | "refund" | string;
178
+ amount: number;
179
+ currency: string;
180
+ transactionId?: string;
181
+ orderId?: string;
182
+ productId?: string;
183
+ planId?: string;
184
+ coupon?: string;
185
+ status?: RevenueEventStatus;
186
+ items?: RevenueLineItem[];
187
+ metadata?: Record<string, string | number | boolean | null>;
188
+ }
189
+ interface RevenueEvent extends RevenueEventPayload {
190
+ sessionId: string;
191
+ visitorId: string;
192
+ timestamp: number;
193
+ attribution?: {
194
+ firstTouch?: AttributionContext;
195
+ lastTouch?: AttributionContext;
196
+ };
197
+ }
198
+ interface GoalEventPayload {
199
+ key: string;
200
+ name?: string;
201
+ value?: number;
202
+ currency?: string;
203
+ metadata?: Record<string, string | number | boolean | null>;
204
+ }
205
+ interface GoalEvent extends GoalEventPayload {
206
+ sessionId: string;
207
+ visitorId: string;
208
+ path: string;
209
+ timestamp: number;
210
+ }
211
+ interface JourneyStepEventPayload {
212
+ key: string;
213
+ label?: string;
214
+ path?: string;
215
+ metadata?: Record<string, string | number | boolean | null>;
216
+ }
217
+ interface JourneyStepEvent extends JourneyStepEventPayload {
218
+ sessionId: string;
219
+ visitorId: string;
220
+ path: string;
221
+ timestamp: number;
222
+ }
223
+ /**
224
+ * One-time (or rare) snapshot of the client environment for a session.
225
+ * Lets the backend align device / OS / browser with what the browser reports
226
+ * (useful vs. reduced User-Agent strings) and store locale / viewport context
227
+ * for session replay catalog rows.
228
+ */
229
+ interface ClientContext {
230
+ sessionId: string;
231
+ timestamp: number;
232
+ device: "desktop" | "mobile" | "tablet";
233
+ os: string;
234
+ browser: string;
235
+ language: string;
236
+ languages: string[];
237
+ /** `prefers-color-scheme` when available */
238
+ colorScheme: "" | "light" | "dark";
239
+ screenWidth: number;
240
+ screenHeight: number;
241
+ viewportWidth: number;
242
+ viewportHeight: number;
243
+ devicePixelRatio: number;
244
+ /** IANA time zone from `Intl`, e.g. `Asia/Tehran` */
245
+ timeZone: string;
246
+ sdkVersion: string;
247
+ }
248
+ /** One batch of rrweb `eventWithTime` payloads for the backend. */
249
+ interface SessionReplayBatch {
250
+ seq: number;
251
+ events: unknown[];
252
+ }
127
253
  type TrackerEvent = {
128
254
  type: "pageview";
129
255
  data: PageView;
@@ -139,6 +265,24 @@ type TrackerEvent = {
139
265
  } | {
140
266
  type: "uturn";
141
267
  data: UTurn;
268
+ } | {
269
+ type: "identify";
270
+ data: IdentifyEvent;
271
+ } | {
272
+ type: "revenue";
273
+ data: RevenueEvent;
274
+ } | {
275
+ type: "goal";
276
+ data: GoalEvent;
277
+ } | {
278
+ type: "journey_step";
279
+ data: JourneyStepEvent;
280
+ } | {
281
+ type: "client_context";
282
+ data: ClientContext;
283
+ } | {
284
+ type: "session_replay";
285
+ data: SessionReplayBatch;
142
286
  };
143
287
  interface SessionData {
144
288
  id: string;
@@ -150,6 +294,13 @@ interface SessionData {
150
294
  timeSpent: Record<string, number>;
151
295
  /** Collected points per path */
152
296
  heatmap: Record<string, HeatmapPoint[]>;
297
+ /** Latest properties supplied through identify(). */
298
+ userProperties: UserProperties;
299
+ /** First and latest marketing touchpoints captured for this visitor. */
300
+ attribution?: {
301
+ firstTouch?: AttributionContext;
302
+ lastTouch?: AttributionContext;
303
+ };
153
304
  /** Approximate visitor location resolved from IP (filled asynchronously) */
154
305
  location?: GeoLocation;
155
306
  }
@@ -221,12 +372,14 @@ declare class LogCapture {
221
372
 
222
373
  type SubscriberFn = (event: TrackerEvent) => void;
223
374
  type FlagSubscriberFn = (flags: Record<string, boolean>) => void;
375
+ type AbTestSubscriberFn = (variants: AbVariantsMap) => void;
224
376
  declare class UserTracker {
225
377
  private readonly cfg;
226
378
  private session;
227
379
  private navigation?;
228
380
  private time?;
229
381
  private heatmap?;
382
+ private sessionReplay?;
230
383
  /** Public so consumers can call logCapture.capture() for manual log entries. */
231
384
  logCapture?: LogCapture;
232
385
  private initialized;
@@ -238,7 +391,11 @@ declare class UserTracker {
238
391
  private userProperties;
239
392
  private flags;
240
393
  private readonly flagSubscribers;
394
+ private abVariants;
395
+ private readonly abTestSubscribers;
241
396
  constructor(config?: TrackerConfig);
397
+ private updateAttributionForPageView;
398
+ private currentAttribution;
242
399
  /**
243
400
  * Attach event listeners and start tracking.
244
401
  * Safe to call during SSR — returns `this` immediately if `window` is
@@ -283,6 +440,16 @@ declare class UserTracker {
283
440
  * ```
284
441
  */
285
442
  trackPageView(path?: string): void;
443
+ /**
444
+ * Track a monetary conversion such as a purchase, subscription, renewal,
445
+ * upgrade, or refund. Revenue events include the current attribution context
446
+ * so the backend can credit campaigns without recomputing browser state.
447
+ */
448
+ trackRevenue(payload: RevenueEventPayload): void;
449
+ /** Track a business goal such as signup, trial_start, lead, or checkout_start. */
450
+ trackGoal(payload: GoalEventPayload): void;
451
+ /** Track a named product journey milestone beyond automatic pageviews. */
452
+ trackJourneyStep(payload: JourneyStepEventPayload): void;
286
453
  /**
287
454
  * Identify the current user with a set of properties.
288
455
  * Properties are merged with any previously set ones and used for feature
@@ -315,6 +482,34 @@ declare class UserTracker {
315
482
  onFlagsChange(fn: FlagSubscriberFn): () => void;
316
483
  /** Fetch (or re-fetch) flags from the backend evaluate endpoint. */
317
484
  fetchFlags(): Promise<void>;
485
+ /**
486
+ * Returns variant keys assigned to this visitor for each running experiment.
487
+ * Fetched on `init()` and after `fetchAbTests()`.
488
+ *
489
+ * ```ts
490
+ * const variants = tracker.getAbVariants();
491
+ * // { 'checkout-cta-test': 'variant-b' }
492
+ * ```
493
+ */
494
+ getAbVariants(): AbVariantsMap;
495
+ /**
496
+ * Returns the assigned variant key for one experiment, or `null` if the
497
+ * experiment is not running or not found.
498
+ */
499
+ getAbVariant(experimentKey: string): string | null;
500
+ /**
501
+ * Returns `true` when the visitor is assigned to the given variant key.
502
+ */
503
+ isAbVariant(experimentKey: string, variantKey: string): boolean;
504
+ /**
505
+ * Subscribe to A/B assignment updates. Returns an unsubscribe function.
506
+ */
507
+ onAbTestsChange(fn: AbTestSubscriberFn): () => void;
508
+ /**
509
+ * Fetch (or re-fetch) variant assignments from `/ab-tests/evaluate`.
510
+ * @param keys When set, only these experiment keys are evaluated and merged.
511
+ */
512
+ fetchAbTests(keys?: string[]): Promise<void>;
318
513
  /** A read-only snapshot of the current session. */
319
514
  getSession(): Readonly<SessionData>;
320
515
  /** All page views recorded so far. */
@@ -380,6 +575,9 @@ declare function useHeatmapData(path?: string, refreshMs?: number): HeatmapPoint
380
575
  * Returns a live array of all page views recorded in the current session.
381
576
  */
382
577
  declare function usePageViews(): PageView[];
578
+ declare function useTrackRevenue(): (payload: RevenueEventPayload) => void;
579
+ declare function useTrackGoal(): (payload: GoalEventPayload) => void;
580
+ declare function useTrackJourneyStep(): (payload: JourneyStepEventPayload) => void;
383
581
  /**
384
582
  * Returns a live record of cumulative milliseconds spent per path.
385
583
  */
@@ -398,5 +596,29 @@ declare function useFeatureFlags(): Record<string, boolean>;
398
596
  * ```
399
597
  */
400
598
  declare function useFeatureFlagEnabled(flagKey: string): boolean;
599
+ /**
600
+ * Returns all assigned A/B variants as `{ [experimentKey]: variantKey | null }`.
601
+ * Re-renders when assignments are fetched (on `init()` or `fetchAbTests()`).
602
+ */
603
+ declare function useAbTests(): Record<string, string | null>;
604
+ /**
605
+ * Returns the assigned variant key for one running experiment, or `null`
606
+ * while loading / when the experiment is inactive.
607
+ *
608
+ * ```tsx
609
+ * const variant = useAbVariant('checkout-cta-test');
610
+ * if (variant === 'variant-b') return <BlueCta />;
611
+ * return <GreenCta />;
612
+ * ```
613
+ */
614
+ declare function useAbVariant(experimentKey: string): string | null;
615
+ /**
616
+ * Returns `true` when the visitor is assigned to the given variant key.
617
+ *
618
+ * ```tsx
619
+ * const isVariantB = useIsAbVariant('checkout-cta-test', 'variant-b');
620
+ * ```
621
+ */
622
+ declare function useIsAbVariant(experimentKey: string, variantKey: string): boolean;
401
623
 
402
- export { UserTrackerProvider, type UserTrackerProviderProps, useFeatureFlagEnabled, useFeatureFlags, useHeatmapData, usePageView, usePageViews, useTimeSpent, useTracker };
624
+ export { UserTrackerProvider, type UserTrackerProviderProps, useAbTests, useAbVariant, useFeatureFlagEnabled, useFeatureFlags, useHeatmapData, useIsAbVariant, usePageView, usePageViews, useTimeSpent, useTrackGoal, useTrackJourneyStep, useTrackRevenue, useTracker };
@@ -49,19 +49,34 @@ interface TrackerConfig {
49
49
  */
50
50
  trackLogs?: boolean;
51
51
  /**
52
- * List of page paths for which heatmap data should be captured.
53
- * Only paths registered here will be tracked. If empty or undefined, the SDK
54
- * will send data for all pages (the backend enforces limits at ingest time).
52
+ * List of page paths for which heatmap data should be captured client-side.
53
+ * Paths should match the dashboard "Heatmap pages" list (decoded Unicode is
54
+ * fine the SDK normalizes percent-encoding vs `window.location` mismatches).
55
55
  *
56
- * Obtain the list of registered paths from the alphana dashboard under
57
- * "Heatmap Pages" for your app, then pass them here.
56
+ * If empty or undefined, the SDK may still collect moves locally, but the
57
+ * backend only persists points when the app has at least one registered
58
+ * heatmap page and the path matches.
58
59
  *
59
60
  * Example: `heatmapPages: ["/", "/pricing", "/dashboard"]`
60
61
  */
61
62
  heatmapPages?: string[];
63
+ /**
64
+ * When true, records DOM mutations with rrweb and sends `session_replay` events
65
+ * for pixel-accurate session replay in the dashboard (requires plan + platform).
66
+ * @default false
67
+ */
68
+ sessionReplay?: boolean;
69
+ /** rrweb full snapshot interval in ms. @default 600000 (10 min) */
70
+ sessionReplayCheckoutEveryNms?: number;
71
+ /** Max rrweb events per batch before an immediate flush. @default 48 */
72
+ sessionReplayMaxEventsPerBatch?: number;
73
+ /** Periodic flush of buffered rrweb events (ms). @default 4000 */
74
+ sessionReplayFlushIntervalMs?: number;
62
75
  /** Called synchronously for every emitted event. */
63
76
  onEvent?: (event: TrackerEvent) => void;
64
77
  }
78
+ /** Assigned variant key per running A/B experiment (`null` = not in experiment). */
79
+ type AbVariantsMap = Record<string, string | null>;
65
80
  interface GeoLocation {
66
81
  /** ISO 3166-1 alpha-2 country code, e.g. "US" */
67
82
  country: string;
@@ -72,12 +87,32 @@ interface GeoLocation {
72
87
  latitude?: number;
73
88
  longitude?: number;
74
89
  }
90
+ interface UtmParams {
91
+ source?: string;
92
+ medium?: string;
93
+ campaign?: string;
94
+ term?: string;
95
+ content?: string;
96
+ }
97
+ interface AttributionContext {
98
+ landingPage: string;
99
+ referrer?: string;
100
+ referrerHost?: string;
101
+ utm?: UtmParams;
102
+ clickIds?: Record<string, string>;
103
+ capturedAt: number;
104
+ }
75
105
  interface PageView {
76
106
  path: string;
77
107
  title: string;
78
108
  timestamp: number;
79
109
  sessionId: string;
80
110
  referrer?: string;
111
+ utm?: UtmParams;
112
+ attribution?: {
113
+ firstTouch?: AttributionContext;
114
+ lastTouch?: AttributionContext;
115
+ };
81
116
  }
82
117
  interface TimeSpent {
83
118
  path: string;
@@ -124,6 +159,97 @@ interface UTurn {
124
159
  timestamp: number;
125
160
  sessionId: string;
126
161
  }
162
+ type UserProperties = Record<string, string>;
163
+ interface IdentifyEvent {
164
+ properties: UserProperties;
165
+ visitorId: string;
166
+ timestamp: number;
167
+ }
168
+ type RevenueEventStatus = "pending" | "paid" | "refunded" | "cancelled" | "failed";
169
+ interface RevenueLineItem {
170
+ id?: string;
171
+ name?: string;
172
+ category?: string;
173
+ quantity?: number;
174
+ price?: number;
175
+ }
176
+ interface RevenueEventPayload {
177
+ eventName?: "purchase" | "subscription" | "renewal" | "upgrade" | "refund" | string;
178
+ amount: number;
179
+ currency: string;
180
+ transactionId?: string;
181
+ orderId?: string;
182
+ productId?: string;
183
+ planId?: string;
184
+ coupon?: string;
185
+ status?: RevenueEventStatus;
186
+ items?: RevenueLineItem[];
187
+ metadata?: Record<string, string | number | boolean | null>;
188
+ }
189
+ interface RevenueEvent extends RevenueEventPayload {
190
+ sessionId: string;
191
+ visitorId: string;
192
+ timestamp: number;
193
+ attribution?: {
194
+ firstTouch?: AttributionContext;
195
+ lastTouch?: AttributionContext;
196
+ };
197
+ }
198
+ interface GoalEventPayload {
199
+ key: string;
200
+ name?: string;
201
+ value?: number;
202
+ currency?: string;
203
+ metadata?: Record<string, string | number | boolean | null>;
204
+ }
205
+ interface GoalEvent extends GoalEventPayload {
206
+ sessionId: string;
207
+ visitorId: string;
208
+ path: string;
209
+ timestamp: number;
210
+ }
211
+ interface JourneyStepEventPayload {
212
+ key: string;
213
+ label?: string;
214
+ path?: string;
215
+ metadata?: Record<string, string | number | boolean | null>;
216
+ }
217
+ interface JourneyStepEvent extends JourneyStepEventPayload {
218
+ sessionId: string;
219
+ visitorId: string;
220
+ path: string;
221
+ timestamp: number;
222
+ }
223
+ /**
224
+ * One-time (or rare) snapshot of the client environment for a session.
225
+ * Lets the backend align device / OS / browser with what the browser reports
226
+ * (useful vs. reduced User-Agent strings) and store locale / viewport context
227
+ * for session replay catalog rows.
228
+ */
229
+ interface ClientContext {
230
+ sessionId: string;
231
+ timestamp: number;
232
+ device: "desktop" | "mobile" | "tablet";
233
+ os: string;
234
+ browser: string;
235
+ language: string;
236
+ languages: string[];
237
+ /** `prefers-color-scheme` when available */
238
+ colorScheme: "" | "light" | "dark";
239
+ screenWidth: number;
240
+ screenHeight: number;
241
+ viewportWidth: number;
242
+ viewportHeight: number;
243
+ devicePixelRatio: number;
244
+ /** IANA time zone from `Intl`, e.g. `Asia/Tehran` */
245
+ timeZone: string;
246
+ sdkVersion: string;
247
+ }
248
+ /** One batch of rrweb `eventWithTime` payloads for the backend. */
249
+ interface SessionReplayBatch {
250
+ seq: number;
251
+ events: unknown[];
252
+ }
127
253
  type TrackerEvent = {
128
254
  type: "pageview";
129
255
  data: PageView;
@@ -139,6 +265,24 @@ type TrackerEvent = {
139
265
  } | {
140
266
  type: "uturn";
141
267
  data: UTurn;
268
+ } | {
269
+ type: "identify";
270
+ data: IdentifyEvent;
271
+ } | {
272
+ type: "revenue";
273
+ data: RevenueEvent;
274
+ } | {
275
+ type: "goal";
276
+ data: GoalEvent;
277
+ } | {
278
+ type: "journey_step";
279
+ data: JourneyStepEvent;
280
+ } | {
281
+ type: "client_context";
282
+ data: ClientContext;
283
+ } | {
284
+ type: "session_replay";
285
+ data: SessionReplayBatch;
142
286
  };
143
287
  interface SessionData {
144
288
  id: string;
@@ -150,6 +294,13 @@ interface SessionData {
150
294
  timeSpent: Record<string, number>;
151
295
  /** Collected points per path */
152
296
  heatmap: Record<string, HeatmapPoint[]>;
297
+ /** Latest properties supplied through identify(). */
298
+ userProperties: UserProperties;
299
+ /** First and latest marketing touchpoints captured for this visitor. */
300
+ attribution?: {
301
+ firstTouch?: AttributionContext;
302
+ lastTouch?: AttributionContext;
303
+ };
153
304
  /** Approximate visitor location resolved from IP (filled asynchronously) */
154
305
  location?: GeoLocation;
155
306
  }
@@ -221,12 +372,14 @@ declare class LogCapture {
221
372
 
222
373
  type SubscriberFn = (event: TrackerEvent) => void;
223
374
  type FlagSubscriberFn = (flags: Record<string, boolean>) => void;
375
+ type AbTestSubscriberFn = (variants: AbVariantsMap) => void;
224
376
  declare class UserTracker {
225
377
  private readonly cfg;
226
378
  private session;
227
379
  private navigation?;
228
380
  private time?;
229
381
  private heatmap?;
382
+ private sessionReplay?;
230
383
  /** Public so consumers can call logCapture.capture() for manual log entries. */
231
384
  logCapture?: LogCapture;
232
385
  private initialized;
@@ -238,7 +391,11 @@ declare class UserTracker {
238
391
  private userProperties;
239
392
  private flags;
240
393
  private readonly flagSubscribers;
394
+ private abVariants;
395
+ private readonly abTestSubscribers;
241
396
  constructor(config?: TrackerConfig);
397
+ private updateAttributionForPageView;
398
+ private currentAttribution;
242
399
  /**
243
400
  * Attach event listeners and start tracking.
244
401
  * Safe to call during SSR — returns `this` immediately if `window` is
@@ -283,6 +440,16 @@ declare class UserTracker {
283
440
  * ```
284
441
  */
285
442
  trackPageView(path?: string): void;
443
+ /**
444
+ * Track a monetary conversion such as a purchase, subscription, renewal,
445
+ * upgrade, or refund. Revenue events include the current attribution context
446
+ * so the backend can credit campaigns without recomputing browser state.
447
+ */
448
+ trackRevenue(payload: RevenueEventPayload): void;
449
+ /** Track a business goal such as signup, trial_start, lead, or checkout_start. */
450
+ trackGoal(payload: GoalEventPayload): void;
451
+ /** Track a named product journey milestone beyond automatic pageviews. */
452
+ trackJourneyStep(payload: JourneyStepEventPayload): void;
286
453
  /**
287
454
  * Identify the current user with a set of properties.
288
455
  * Properties are merged with any previously set ones and used for feature
@@ -315,6 +482,34 @@ declare class UserTracker {
315
482
  onFlagsChange(fn: FlagSubscriberFn): () => void;
316
483
  /** Fetch (or re-fetch) flags from the backend evaluate endpoint. */
317
484
  fetchFlags(): Promise<void>;
485
+ /**
486
+ * Returns variant keys assigned to this visitor for each running experiment.
487
+ * Fetched on `init()` and after `fetchAbTests()`.
488
+ *
489
+ * ```ts
490
+ * const variants = tracker.getAbVariants();
491
+ * // { 'checkout-cta-test': 'variant-b' }
492
+ * ```
493
+ */
494
+ getAbVariants(): AbVariantsMap;
495
+ /**
496
+ * Returns the assigned variant key for one experiment, or `null` if the
497
+ * experiment is not running or not found.
498
+ */
499
+ getAbVariant(experimentKey: string): string | null;
500
+ /**
501
+ * Returns `true` when the visitor is assigned to the given variant key.
502
+ */
503
+ isAbVariant(experimentKey: string, variantKey: string): boolean;
504
+ /**
505
+ * Subscribe to A/B assignment updates. Returns an unsubscribe function.
506
+ */
507
+ onAbTestsChange(fn: AbTestSubscriberFn): () => void;
508
+ /**
509
+ * Fetch (or re-fetch) variant assignments from `/ab-tests/evaluate`.
510
+ * @param keys When set, only these experiment keys are evaluated and merged.
511
+ */
512
+ fetchAbTests(keys?: string[]): Promise<void>;
318
513
  /** A read-only snapshot of the current session. */
319
514
  getSession(): Readonly<SessionData>;
320
515
  /** All page views recorded so far. */
@@ -380,6 +575,9 @@ declare function useHeatmapData(path?: string, refreshMs?: number): HeatmapPoint
380
575
  * Returns a live array of all page views recorded in the current session.
381
576
  */
382
577
  declare function usePageViews(): PageView[];
578
+ declare function useTrackRevenue(): (payload: RevenueEventPayload) => void;
579
+ declare function useTrackGoal(): (payload: GoalEventPayload) => void;
580
+ declare function useTrackJourneyStep(): (payload: JourneyStepEventPayload) => void;
383
581
  /**
384
582
  * Returns a live record of cumulative milliseconds spent per path.
385
583
  */
@@ -398,5 +596,29 @@ declare function useFeatureFlags(): Record<string, boolean>;
398
596
  * ```
399
597
  */
400
598
  declare function useFeatureFlagEnabled(flagKey: string): boolean;
599
+ /**
600
+ * Returns all assigned A/B variants as `{ [experimentKey]: variantKey | null }`.
601
+ * Re-renders when assignments are fetched (on `init()` or `fetchAbTests()`).
602
+ */
603
+ declare function useAbTests(): Record<string, string | null>;
604
+ /**
605
+ * Returns the assigned variant key for one running experiment, or `null`
606
+ * while loading / when the experiment is inactive.
607
+ *
608
+ * ```tsx
609
+ * const variant = useAbVariant('checkout-cta-test');
610
+ * if (variant === 'variant-b') return <BlueCta />;
611
+ * return <GreenCta />;
612
+ * ```
613
+ */
614
+ declare function useAbVariant(experimentKey: string): string | null;
615
+ /**
616
+ * Returns `true` when the visitor is assigned to the given variant key.
617
+ *
618
+ * ```tsx
619
+ * const isVariantB = useIsAbVariant('checkout-cta-test', 'variant-b');
620
+ * ```
621
+ */
622
+ declare function useIsAbVariant(experimentKey: string, variantKey: string): boolean;
401
623
 
402
- export { UserTrackerProvider, type UserTrackerProviderProps, useFeatureFlagEnabled, useFeatureFlags, useHeatmapData, usePageView, usePageViews, useTimeSpent, useTracker };
624
+ export { UserTrackerProvider, type UserTrackerProviderProps, useAbTests, useAbVariant, useFeatureFlagEnabled, useFeatureFlags, useHeatmapData, useIsAbVariant, usePageView, usePageViews, useTimeSpent, useTrackGoal, useTrackJourneyStep, useTrackRevenue, useTracker };