@stacksee/analytics 0.3.4 → 0.4.3

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.
@@ -7,14 +7,408 @@ export declare class BrowserAnalytics<TEventMap extends DefaultEventMap = Defaul
7
7
  private sessionId?;
8
8
  private initialized;
9
9
  private initializePromise?;
10
+ /**
11
+ * Creates a new BrowserAnalytics instance for client-side event tracking.
12
+ *
13
+ * Automatically generates a session ID and sets up the analytics context.
14
+ * The instance will be ready to track events once initialized.
15
+ *
16
+ * @param config Analytics configuration including providers and default context
17
+ * @param config.providers Array of analytics provider instances (e.g., PostHogClientProvider)
18
+ * @param config.defaultContext Optional default context to include with all events
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * import { BrowserAnalytics } from '@stacksee/analytics/client';
23
+ * import { PostHogClientProvider } from '@stacksee/analytics/providers/posthog';
24
+ *
25
+ * const analytics = new BrowserAnalytics({
26
+ * providers: [
27
+ * new PostHogClientProvider({
28
+ * apiKey: 'your-posthog-api-key',
29
+ * host: 'https://app.posthog.com'
30
+ * })
31
+ * ],
32
+ * defaultContext: {
33
+ * app: { version: '1.0.0' }
34
+ * }
35
+ * });
36
+ *
37
+ * await analytics.initialize();
38
+ * ```
39
+ */
10
40
  constructor(config: AnalyticsConfig);
41
+ /**
42
+ * Initializes all analytics providers and sets up browser context.
43
+ *
44
+ * This method must be called before tracking events. It initializes all configured
45
+ * providers and automatically captures browser context including page information,
46
+ * device type, OS, and browser details.
47
+ *
48
+ * The method is safe to call multiple times and will not re-initialize if already done.
49
+ * If called while initialization is in progress, it returns the existing promise.
50
+ *
51
+ * @returns Promise that resolves when initialization is complete
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * const analytics = new BrowserAnalytics({ providers: [] });
56
+ *
57
+ * // Initialize before tracking events
58
+ * await analytics.initialize();
59
+ *
60
+ * // Now ready to track events
61
+ * analytics.track('page_viewed', { page: '/dashboard' });
62
+ * ```
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * // Safe to call multiple times
67
+ * await analytics.initialize(); // First call does the work
68
+ * await analytics.initialize(); // Subsequent calls return immediately
69
+ * ```
70
+ */
11
71
  initialize(): Promise<void>;
12
72
  private _doInitialize;
13
73
  private ensureInitialized;
74
+ /**
75
+ * Identifies a user with optional traits.
76
+ *
77
+ * Associates subsequent events with the specified user ID and optionally
78
+ * sets user properties. This method should be called when a user logs in
79
+ * or when you want to associate events with a known user.
80
+ *
81
+ * The method automatically ensures initialization but doesn't block execution
82
+ * if initialization is still in progress.
83
+ *
84
+ * @param userId Unique identifier for the user (e.g., database ID, email)
85
+ * @param traits Optional user properties and characteristics
86
+ *
87
+ * @example
88
+ * ```typescript
89
+ * // Basic user identification
90
+ * analytics.identify('user-123');
91
+ * ```
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * // Identify with user traits
96
+ * analytics.identify('user-123', {
97
+ * email: 'john@example.com',
98
+ * name: 'John Doe',
99
+ * plan: 'pro',
100
+ * signupDate: '2024-01-15',
101
+ * preferences: {
102
+ * newsletter: true,
103
+ * notifications: false
104
+ * }
105
+ * });
106
+ * ```
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * // In a login handler
111
+ * async function handleLogin(email: string, password: string) {
112
+ * const user = await login(email, password);
113
+ *
114
+ * analytics.identify(user.id, {
115
+ * email: user.email,
116
+ * name: user.name,
117
+ * lastLogin: new Date().toISOString()
118
+ * });
119
+ * }
120
+ * ```
121
+ */
14
122
  identify(userId: string, traits?: Record<string, unknown>): void;
123
+ /**
124
+ * Tracks a custom event with properties.
125
+ *
126
+ * This is the main method for tracking user interactions and business events.
127
+ * The method ensures initialization before tracking and sends the event to all
128
+ * configured providers. Events are enriched with context information like
129
+ * timestamp, user ID, session ID, and browser context.
130
+ *
131
+ * If providers are configured, the method waits for all providers to complete
132
+ * tracking. Failed providers don't prevent others from succeeding.
133
+ *
134
+ * @param eventName Name of the event to track (must match your event definitions)
135
+ * @param properties Event-specific properties and data
136
+ * @returns Promise that resolves when tracking is complete for all providers
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * // Track a simple event
141
+ * await analytics.track('button_clicked', {
142
+ * buttonId: 'signup-cta',
143
+ * page: '/landing'
144
+ * });
145
+ * ```
146
+ *
147
+ * @example
148
+ * ```typescript
149
+ * // Track a purchase event
150
+ * await analytics.track('purchase_completed', {
151
+ * orderId: 'order-123',
152
+ * amount: 99.99,
153
+ * currency: 'USD',
154
+ * items: [
155
+ * { id: 'item-1', name: 'Product A', price: 49.99 },
156
+ * { id: 'item-2', name: 'Product B', price: 49.99 }
157
+ * ],
158
+ * paymentMethod: 'credit_card'
159
+ * });
160
+ * ```
161
+ *
162
+ * @example
163
+ * ```typescript
164
+ * // Fire-and-forget for non-critical events (client-side typical usage)
165
+ * analytics.track('feature_viewed', { feature: 'dashboard' });
166
+ * // Don't await - let it track in the background
167
+ * ```
168
+ *
169
+ * @example
170
+ * ```typescript
171
+ * // Error handling
172
+ * try {
173
+ * await analytics.track('critical_event', { data: 'important' });
174
+ * } catch (error) {
175
+ * // Individual provider failures are handled internally
176
+ * // This catch would only trigger for initialization failures
177
+ * console.error('Failed to track event:', error);
178
+ * }
179
+ * ```
180
+ */
15
181
  track<TEventName extends keyof TEventMap & string>(eventName: TEventName, properties: TEventMap[TEventName]): Promise<void>;
16
- page(properties?: Record<string, unknown>): void;
182
+ /**
183
+ * Tracks a page view event.
184
+ *
185
+ * Automatically captures current page information (path, title, referrer) and
186
+ * updates the analytics context. This method should be called when users
187
+ * navigate to a new page or view.
188
+ *
189
+ * The method automatically ensures initialization but doesn't block execution
190
+ * if initialization is still in progress.
191
+ *
192
+ * @param properties Optional properties to include with the page view
193
+ *
194
+ * @example
195
+ * ```typescript
196
+ * // Basic page view tracking
197
+ * analytics.pageView();
198
+ * ```
199
+ *
200
+ * @example
201
+ * ```typescript
202
+ * // Page view with additional properties
203
+ * analytics.pageView({
204
+ * category: 'product',
205
+ * productId: 'prod-123',
206
+ * loadTime: 1200,
207
+ * source: 'organic_search'
208
+ * });
209
+ * ```
210
+ *
211
+ * @example
212
+ * ```typescript
213
+ * // In a SvelteKit app with automatic navigation tracking
214
+ * import { afterNavigate } from '$app/navigation';
215
+ *
216
+ * afterNavigate(() => {
217
+ * analytics.pageView({
218
+ * timestamp: Date.now(),
219
+ * userAgent: navigator.userAgent
220
+ * });
221
+ * });
222
+ * ```
223
+ *
224
+ * @example
225
+ * ```typescript
226
+ * // In a React app with React Router
227
+ * import { useEffect } from 'react';
228
+ * import { useLocation } from 'react-router-dom';
229
+ *
230
+ * function usePageTracking() {
231
+ * const location = useLocation();
232
+ *
233
+ * useEffect(() => {
234
+ * analytics.pageView({
235
+ * path: location.pathname,
236
+ * search: location.search
237
+ * });
238
+ * }, [location]);
239
+ * }
240
+ * ```
241
+ */
242
+ pageView(properties?: Record<string, unknown>): void;
243
+ /**
244
+ * Tracks when a user leaves a page.
245
+ *
246
+ * This method should be called before navigation to track user engagement
247
+ * and session duration. It's useful for understanding how long users spend
248
+ * on different pages and their navigation patterns.
249
+ *
250
+ * Note: Not all analytics providers support page leave events. The method
251
+ * will only call providers that implement the pageLeave method.
252
+ *
253
+ * @param properties Optional properties to include with the page leave event
254
+ *
255
+ * @example
256
+ * ```typescript
257
+ * // Basic page leave tracking
258
+ * analytics.pageLeave();
259
+ * ```
260
+ *
261
+ * @example
262
+ * ```typescript
263
+ * // Page leave with engagement metrics
264
+ * analytics.pageLeave({
265
+ * timeOnPage: 45000, // 45 seconds
266
+ * scrollDepth: 80, // percentage
267
+ * interactions: 3, // number of clicks/interactions
268
+ * exitIntent: true // detected exit intent
269
+ * });
270
+ * ```
271
+ *
272
+ * @example
273
+ * ```typescript
274
+ * // In a SvelteKit app with automatic navigation tracking
275
+ * import { beforeNavigate } from '$app/navigation';
276
+ *
277
+ * let pageStartTime = Date.now();
278
+ *
279
+ * beforeNavigate(() => {
280
+ * analytics.pageLeave({
281
+ * duration: Date.now() - pageStartTime,
282
+ * exitType: 'navigation'
283
+ * });
284
+ * });
285
+ * ```
286
+ *
287
+ * @example
288
+ * ```typescript
289
+ * // Track page leave on browser unload
290
+ * window.addEventListener('beforeunload', () => {
291
+ * analytics.pageLeave({
292
+ * exitType: 'browser_close',
293
+ * sessionDuration: Date.now() - sessionStartTime
294
+ * });
295
+ * });
296
+ * ```
297
+ */
298
+ pageLeave(properties?: Record<string, unknown>): void;
299
+ /**
300
+ * Resets the analytics state, clearing user ID and generating a new session.
301
+ *
302
+ * This method should be called when a user logs out or when you want to
303
+ * start tracking a new user session. It clears the current user ID,
304
+ * generates a new session ID, and calls reset on all providers.
305
+ *
306
+ * Use this method to ensure user privacy and accurate session tracking
307
+ * when users switch accounts or log out.
308
+ *
309
+ * @example
310
+ * ```typescript
311
+ * // Basic reset on logout
312
+ * analytics.reset();
313
+ * ```
314
+ *
315
+ * @example
316
+ * ```typescript
317
+ * // In a logout handler
318
+ * async function handleLogout() {
319
+ * // Track logout event before resetting
320
+ * await analytics.track('user_logged_out', {
321
+ * sessionDuration: Date.now() - sessionStartTime
322
+ * });
323
+ *
324
+ * // Reset analytics state
325
+ * analytics.reset();
326
+ *
327
+ * // Clear user data and redirect
328
+ * clearUserData();
329
+ * window.location.href = '/login';
330
+ * }
331
+ * ```
332
+ *
333
+ * @example
334
+ * ```typescript
335
+ * // Account switching scenario
336
+ * async function switchAccount(newUserId: string) {
337
+ * // Reset to clear previous user
338
+ * analytics.reset();
339
+ *
340
+ * // Identify the new user
341
+ * analytics.identify(newUserId);
342
+ *
343
+ * // Track account switch
344
+ * analytics.track('account_switched', {
345
+ * newUserId,
346
+ * timestamp: Date.now()
347
+ * });
348
+ * }
349
+ * ```
350
+ */
17
351
  reset(): void;
352
+ /**
353
+ * Updates the analytics context with new information.
354
+ *
355
+ * The context is included with all tracked events and provides additional
356
+ * metadata about the user's environment, current page, device, and other
357
+ * relevant information. This method merges new context with existing context.
358
+ *
359
+ * Context typically includes page information, device details, UTM parameters,
360
+ * and custom application context.
361
+ *
362
+ * @param context Partial context to merge with existing context
363
+ * @param context.page Page-related context (path, title, referrer)
364
+ * @param context.device Device-related context (type, OS, browser)
365
+ * @param context.utm UTM campaign tracking parameters
366
+ * @param context.app Application-specific context
367
+ *
368
+ * @example
369
+ * ```typescript
370
+ * // Update page context
371
+ * analytics.updateContext({
372
+ * page: {
373
+ * path: '/dashboard',
374
+ * title: 'User Dashboard',
375
+ * referrer: 'https://google.com'
376
+ * }
377
+ * });
378
+ * ```
379
+ *
380
+ * @example
381
+ * ```typescript
382
+ * // Add UTM parameters from URL
383
+ * const urlParams = new URLSearchParams(window.location.search);
384
+ * analytics.updateContext({
385
+ * utm: {
386
+ * source: urlParams.get('utm_source') || undefined,
387
+ * medium: urlParams.get('utm_medium') || undefined,
388
+ * campaign: urlParams.get('utm_campaign') || undefined,
389
+ * term: urlParams.get('utm_term') || undefined,
390
+ * content: urlParams.get('utm_content') || undefined
391
+ * }
392
+ * });
393
+ * ```
394
+ *
395
+ * @example
396
+ * ```typescript
397
+ * // Update application context
398
+ * analytics.updateContext({
399
+ * app: {
400
+ * version: '2.1.0',
401
+ * feature: 'beta-dashboard',
402
+ * theme: 'dark'
403
+ * },
404
+ * device: {
405
+ * screenWidth: window.innerWidth,
406
+ * screenHeight: window.innerHeight,
407
+ * timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
408
+ * }
409
+ * });
410
+ * ```
411
+ */
18
412
  updateContext(context: Partial<EventContext>): void;
19
413
  private getCategoryFromEventName;
20
414
  private generateSessionId;