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.
- package/README.md +65 -33
- package/dist/alphana-sdk.global.js +23 -1
- package/dist/index.d.mts +212 -6
- package/dist/index.d.ts +212 -6
- package/dist/index.js +22 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +22 -2
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +228 -6
- package/dist/react/index.d.ts +228 -6
- package/dist/react/index.js +23 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +23 -1
- package/dist/react/index.mjs.map +1 -1
- package/package.json +3 -2
package/dist/react/index.d.mts
CHANGED
|
@@ -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
|
-
*
|
|
54
|
-
*
|
|
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
|
-
*
|
|
57
|
-
*
|
|
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 };
|
package/dist/react/index.d.ts
CHANGED
|
@@ -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
|
-
*
|
|
54
|
-
*
|
|
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
|
-
*
|
|
57
|
-
*
|
|
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 };
|