@stacksee/analytics 0.9.7 → 0.10.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/dist/adapters/client/browser-analytics.d.ts +9 -1
- package/dist/adapters/server/server-analytics.d.ts +9 -1
- package/dist/client.js +145 -100
- package/dist/core/events/types.d.ts +63 -1
- package/dist/providers/client.js +7 -5
- package/dist/providers/server.d.ts +1 -1
- package/dist/providers/server.js +160 -119
- package/dist/server.js +143 -101
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AnalyticsConfig, EventContext } from '../../core/events/types.js';
|
|
2
2
|
type DefaultEventMap = Record<string, Record<string, unknown>>;
|
|
3
3
|
export declare class BrowserAnalytics<TEventMap extends DefaultEventMap = DefaultEventMap, TUserTraits extends Record<string, unknown> = Record<string, unknown>> {
|
|
4
|
-
private
|
|
4
|
+
private providerConfigs;
|
|
5
5
|
private context;
|
|
6
6
|
private userId?;
|
|
7
7
|
private sessionId?;
|
|
@@ -39,6 +39,14 @@ export declare class BrowserAnalytics<TEventMap extends DefaultEventMap = Defaul
|
|
|
39
39
|
* ```
|
|
40
40
|
*/
|
|
41
41
|
constructor(config: AnalyticsConfig);
|
|
42
|
+
/**
|
|
43
|
+
* Normalizes provider configurations into a consistent internal format
|
|
44
|
+
*/
|
|
45
|
+
private normalizeProviders;
|
|
46
|
+
/**
|
|
47
|
+
* Checks if a method should be called on a provider based on routing configuration
|
|
48
|
+
*/
|
|
49
|
+
private shouldCallMethod;
|
|
42
50
|
/**
|
|
43
51
|
* Initializes all analytics providers and sets up browser context.
|
|
44
52
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AnalyticsConfig, EventContext, UserContext } from '../../core/events/types.js';
|
|
2
2
|
type DefaultEventMap = Record<string, Record<string, unknown>>;
|
|
3
3
|
export declare class ServerAnalytics<TEventMap extends Record<string, Record<string, unknown>> = DefaultEventMap, TUserTraits extends Record<string, unknown> = Record<string, unknown>> {
|
|
4
|
-
private
|
|
4
|
+
private providerConfigs;
|
|
5
5
|
private config;
|
|
6
6
|
private initialized;
|
|
7
7
|
/**
|
|
@@ -35,6 +35,14 @@ export declare class ServerAnalytics<TEventMap extends Record<string, Record<str
|
|
|
35
35
|
* ```
|
|
36
36
|
*/
|
|
37
37
|
constructor(config: AnalyticsConfig);
|
|
38
|
+
/**
|
|
39
|
+
* Normalizes provider configurations into a consistent internal format
|
|
40
|
+
*/
|
|
41
|
+
private normalizeProviders;
|
|
42
|
+
/**
|
|
43
|
+
* Checks if a method should be called on a provider based on routing configuration
|
|
44
|
+
*/
|
|
45
|
+
private shouldCallMethod;
|
|
38
46
|
/**
|
|
39
47
|
* Initializes all analytics providers.
|
|
40
48
|
*
|
package/dist/client.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var s = (t, e, i) =>
|
|
4
|
-
import { i as
|
|
5
|
-
import { P
|
|
6
|
-
import { B as
|
|
7
|
-
class
|
|
1
|
+
var c = Object.defineProperty;
|
|
2
|
+
var u = (t, e, i) => e in t ? c(t, e, { enumerable: !0, configurable: !0, writable: !0, value: i }) : t[e] = i;
|
|
3
|
+
var s = (t, e, i) => u(t, typeof e != "symbol" ? e + "" : e, i);
|
|
4
|
+
import { i as f } from "./client-DTHZYkxx.js";
|
|
5
|
+
import { P } from "./client-DTHZYkxx.js";
|
|
6
|
+
import { B as k } from "./base.provider-AfFL5W_P.js";
|
|
7
|
+
class p {
|
|
8
8
|
/**
|
|
9
9
|
* Creates a new BrowserAnalytics instance for client-side event tracking.
|
|
10
|
-
*
|
|
10
|
+
*
|
|
11
11
|
* Automatically generates a session ID and sets up the analytics context.
|
|
12
12
|
* The instance will be ready to track events once initialized.
|
|
13
|
-
*
|
|
13
|
+
*
|
|
14
14
|
* @param config Analytics configuration including providers and default context
|
|
15
15
|
* @param config.providers Array of analytics provider instances (e.g., PostHogClientProvider)
|
|
16
16
|
* @param config.defaultContext Optional default context to include with all events
|
|
17
|
-
*
|
|
17
|
+
*
|
|
18
18
|
* @example
|
|
19
19
|
* ```typescript
|
|
20
20
|
* import { BrowserAnalytics } from '@stacksee/analytics/client';
|
|
21
21
|
* import { PostHogClientProvider } from '@stacksee/analytics/providers/posthog';
|
|
22
|
-
*
|
|
22
|
+
*
|
|
23
23
|
* const analytics = new BrowserAnalytics({
|
|
24
24
|
* providers: [
|
|
25
25
|
* new PostHogClientProvider({
|
|
@@ -31,43 +31,85 @@ class f {
|
|
|
31
31
|
* app: { version: '1.0.0' }
|
|
32
32
|
* }
|
|
33
33
|
* });
|
|
34
|
-
*
|
|
34
|
+
*
|
|
35
35
|
* await analytics.initialize();
|
|
36
36
|
* ```
|
|
37
37
|
*/
|
|
38
38
|
constructor(e) {
|
|
39
|
-
s(this, "
|
|
39
|
+
s(this, "providerConfigs", []);
|
|
40
40
|
s(this, "context", {});
|
|
41
41
|
s(this, "userId");
|
|
42
42
|
s(this, "sessionId");
|
|
43
43
|
s(this, "userTraits");
|
|
44
44
|
s(this, "initialized", !1);
|
|
45
45
|
s(this, "initializePromise");
|
|
46
|
-
this.
|
|
46
|
+
this.providerConfigs = this.normalizeProviders(e.providers), e.defaultContext && (this.context = { ...e.defaultContext }), this.sessionId = this.generateSessionId();
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Normalizes provider configurations into a consistent internal format
|
|
50
|
+
*/
|
|
51
|
+
normalizeProviders(e) {
|
|
52
|
+
const i = [
|
|
53
|
+
"initialize",
|
|
54
|
+
"identify",
|
|
55
|
+
"track",
|
|
56
|
+
"pageView",
|
|
57
|
+
"pageLeave",
|
|
58
|
+
"reset"
|
|
59
|
+
];
|
|
60
|
+
return e.map((r) => {
|
|
61
|
+
if ("initialize" in r && "track" in r)
|
|
62
|
+
return {
|
|
63
|
+
provider: r,
|
|
64
|
+
enabledMethods: new Set(i)
|
|
65
|
+
};
|
|
66
|
+
const n = r;
|
|
67
|
+
n.methods && n.exclude && console.warn(
|
|
68
|
+
`[Analytics] Provider ${n.provider.name} has both 'methods' and 'exclude' specified. Using 'methods' and ignoring 'exclude'.`
|
|
69
|
+
);
|
|
70
|
+
let o;
|
|
71
|
+
return n.methods ? o = new Set(n.methods) : n.exclude ? o = new Set(
|
|
72
|
+
i.filter(
|
|
73
|
+
(d) => {
|
|
74
|
+
var h;
|
|
75
|
+
return !((h = n.exclude) != null && h.includes(d));
|
|
76
|
+
}
|
|
77
|
+
)
|
|
78
|
+
) : o = new Set(i), {
|
|
79
|
+
provider: n.provider,
|
|
80
|
+
enabledMethods: o
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Checks if a method should be called on a provider based on routing configuration
|
|
86
|
+
*/
|
|
87
|
+
shouldCallMethod(e, i) {
|
|
88
|
+
return e.enabledMethods.has(i);
|
|
47
89
|
}
|
|
48
90
|
/**
|
|
49
91
|
* Initializes all analytics providers and sets up browser context.
|
|
50
|
-
*
|
|
92
|
+
*
|
|
51
93
|
* This method must be called before tracking events. It initializes all configured
|
|
52
94
|
* providers and automatically captures browser context including page information,
|
|
53
95
|
* device type, OS, and browser details.
|
|
54
|
-
*
|
|
96
|
+
*
|
|
55
97
|
* The method is safe to call multiple times and will not re-initialize if already done.
|
|
56
98
|
* If called while initialization is in progress, it returns the existing promise.
|
|
57
|
-
*
|
|
99
|
+
*
|
|
58
100
|
* @returns Promise that resolves when initialization is complete
|
|
59
|
-
*
|
|
101
|
+
*
|
|
60
102
|
* @example
|
|
61
103
|
* ```typescript
|
|
62
104
|
* const analytics = new BrowserAnalytics({ providers: [] });
|
|
63
|
-
*
|
|
105
|
+
*
|
|
64
106
|
* // Initialize before tracking events
|
|
65
107
|
* await analytics.initialize();
|
|
66
|
-
*
|
|
108
|
+
*
|
|
67
109
|
* // Now ready to track events
|
|
68
110
|
* analytics.track('page_viewed', { page: '/dashboard' });
|
|
69
111
|
* ```
|
|
70
|
-
*
|
|
112
|
+
*
|
|
71
113
|
* @example
|
|
72
114
|
* ```typescript
|
|
73
115
|
* // Safe to call multiple times
|
|
@@ -76,12 +118,12 @@ class f {
|
|
|
76
118
|
* ```
|
|
77
119
|
*/
|
|
78
120
|
async initialize() {
|
|
79
|
-
if (
|
|
121
|
+
if (f() && !this.initialized)
|
|
80
122
|
return this.initializePromise ? this.initializePromise : (this.initializePromise = this._doInitialize(), this.initializePromise);
|
|
81
123
|
}
|
|
82
124
|
async _doInitialize() {
|
|
83
|
-
const e = this.
|
|
84
|
-
(i) => i.initialize()
|
|
125
|
+
const e = this.providerConfigs.map(
|
|
126
|
+
(i) => i.provider.initialize()
|
|
85
127
|
);
|
|
86
128
|
await Promise.all(e), this.initialized = !0, this.updateContext({
|
|
87
129
|
page: {
|
|
@@ -170,8 +212,8 @@ class f {
|
|
|
170
212
|
this.userId = e, this.userTraits = i, this.ensureInitialized().catch((r) => {
|
|
171
213
|
console.error("[Analytics] Failed to initialize during identify:", r);
|
|
172
214
|
});
|
|
173
|
-
for (const r of this.
|
|
174
|
-
r.identify(e, i);
|
|
215
|
+
for (const r of this.providerConfigs)
|
|
216
|
+
this.shouldCallMethod(r, "identify") && r.provider.identify(e, i);
|
|
175
217
|
}
|
|
176
218
|
/**
|
|
177
219
|
* Tracks a custom event with properties.
|
|
@@ -191,7 +233,7 @@ class f {
|
|
|
191
233
|
* @param eventName Name of the event to track (must match your event definitions)
|
|
192
234
|
* @param properties Event-specific properties and data
|
|
193
235
|
* @returns Promise that resolves when tracking is complete for all providers
|
|
194
|
-
*
|
|
236
|
+
*
|
|
195
237
|
* @example
|
|
196
238
|
* ```typescript
|
|
197
239
|
* // Track a simple event
|
|
@@ -257,43 +299,43 @@ class f {
|
|
|
257
299
|
timestamp: Date.now(),
|
|
258
300
|
userId: this.userId,
|
|
259
301
|
sessionId: this.sessionId
|
|
260
|
-
},
|
|
302
|
+
}, n = {
|
|
261
303
|
...this.context,
|
|
262
304
|
user: this.userId || this.userTraits ? {
|
|
263
305
|
userId: this.userId,
|
|
264
306
|
email: this.userTraits && "email" in this.userTraits ? this.userTraits.email : void 0,
|
|
265
307
|
traits: this.userTraits
|
|
266
308
|
} : void 0
|
|
267
|
-
},
|
|
309
|
+
}, o = this.providerConfigs.filter((d) => this.shouldCallMethod(d, "track")).map(async (d) => {
|
|
268
310
|
try {
|
|
269
|
-
await d.track(r,
|
|
270
|
-
} catch (
|
|
311
|
+
await d.provider.track(r, n);
|
|
312
|
+
} catch (h) {
|
|
271
313
|
console.error(
|
|
272
|
-
`[Analytics] Provider ${d.name} failed to track event:`,
|
|
273
|
-
|
|
314
|
+
`[Analytics] Provider ${d.provider.name} failed to track event:`,
|
|
315
|
+
h
|
|
274
316
|
);
|
|
275
317
|
}
|
|
276
318
|
});
|
|
277
|
-
await Promise.all(
|
|
319
|
+
await Promise.all(o);
|
|
278
320
|
}
|
|
279
321
|
/**
|
|
280
322
|
* Tracks a page view event.
|
|
281
|
-
*
|
|
323
|
+
*
|
|
282
324
|
* Automatically captures current page information (path, title, referrer) and
|
|
283
325
|
* updates the analytics context. This method should be called when users
|
|
284
326
|
* navigate to a new page or view.
|
|
285
|
-
*
|
|
327
|
+
*
|
|
286
328
|
* The method automatically ensures initialization but doesn't block execution
|
|
287
329
|
* if initialization is still in progress.
|
|
288
|
-
*
|
|
330
|
+
*
|
|
289
331
|
* @param properties Optional properties to include with the page view
|
|
290
|
-
*
|
|
332
|
+
*
|
|
291
333
|
* @example
|
|
292
334
|
* ```typescript
|
|
293
335
|
* // Basic page view tracking
|
|
294
336
|
* analytics.pageView();
|
|
295
337
|
* ```
|
|
296
|
-
*
|
|
338
|
+
*
|
|
297
339
|
* @example
|
|
298
340
|
* ```typescript
|
|
299
341
|
* // Page view with additional properties
|
|
@@ -304,12 +346,12 @@ class f {
|
|
|
304
346
|
* source: 'organic_search'
|
|
305
347
|
* });
|
|
306
348
|
* ```
|
|
307
|
-
*
|
|
349
|
+
*
|
|
308
350
|
* @example
|
|
309
351
|
* ```typescript
|
|
310
352
|
* // In a SvelteKit app with automatic navigation tracking
|
|
311
353
|
* import { afterNavigate } from '$app/navigation';
|
|
312
|
-
*
|
|
354
|
+
*
|
|
313
355
|
* afterNavigate(() => {
|
|
314
356
|
* analytics.pageView({
|
|
315
357
|
* timestamp: Date.now(),
|
|
@@ -317,16 +359,16 @@ class f {
|
|
|
317
359
|
* });
|
|
318
360
|
* });
|
|
319
361
|
* ```
|
|
320
|
-
*
|
|
362
|
+
*
|
|
321
363
|
* @example
|
|
322
364
|
* ```typescript
|
|
323
365
|
* // In a React app with React Router
|
|
324
366
|
* import { useEffect } from 'react';
|
|
325
367
|
* import { useLocation } from 'react-router-dom';
|
|
326
|
-
*
|
|
368
|
+
*
|
|
327
369
|
* function usePageTracking() {
|
|
328
370
|
* const location = useLocation();
|
|
329
|
-
*
|
|
371
|
+
*
|
|
330
372
|
* useEffect(() => {
|
|
331
373
|
* analytics.pageView({
|
|
332
374
|
* path: location.pathname,
|
|
@@ -346,27 +388,27 @@ class f {
|
|
|
346
388
|
referrer: document.referrer
|
|
347
389
|
}
|
|
348
390
|
});
|
|
349
|
-
for (const i of this.
|
|
350
|
-
i.pageView(e, this.context);
|
|
391
|
+
for (const i of this.providerConfigs)
|
|
392
|
+
this.shouldCallMethod(i, "pageView") && i.provider.pageView(e, this.context);
|
|
351
393
|
}
|
|
352
394
|
/**
|
|
353
395
|
* Tracks when a user leaves a page.
|
|
354
|
-
*
|
|
396
|
+
*
|
|
355
397
|
* This method should be called before navigation to track user engagement
|
|
356
398
|
* and session duration. It's useful for understanding how long users spend
|
|
357
399
|
* on different pages and their navigation patterns.
|
|
358
|
-
*
|
|
400
|
+
*
|
|
359
401
|
* Note: Not all analytics providers support page leave events. The method
|
|
360
402
|
* will only call providers that implement the pageLeave method.
|
|
361
|
-
*
|
|
403
|
+
*
|
|
362
404
|
* @param properties Optional properties to include with the page leave event
|
|
363
|
-
*
|
|
405
|
+
*
|
|
364
406
|
* @example
|
|
365
407
|
* ```typescript
|
|
366
408
|
* // Basic page leave tracking
|
|
367
409
|
* analytics.pageLeave();
|
|
368
410
|
* ```
|
|
369
|
-
*
|
|
411
|
+
*
|
|
370
412
|
* @example
|
|
371
413
|
* ```typescript
|
|
372
414
|
* // Page leave with engagement metrics
|
|
@@ -377,14 +419,14 @@ class f {
|
|
|
377
419
|
* exitIntent: true // detected exit intent
|
|
378
420
|
* });
|
|
379
421
|
* ```
|
|
380
|
-
*
|
|
422
|
+
*
|
|
381
423
|
* @example
|
|
382
424
|
* ```typescript
|
|
383
425
|
* // In a SvelteKit app with automatic navigation tracking
|
|
384
426
|
* import { beforeNavigate } from '$app/navigation';
|
|
385
|
-
*
|
|
427
|
+
*
|
|
386
428
|
* let pageStartTime = Date.now();
|
|
387
|
-
*
|
|
429
|
+
*
|
|
388
430
|
* beforeNavigate(() => {
|
|
389
431
|
* analytics.pageLeave({
|
|
390
432
|
* duration: Date.now() - pageStartTime,
|
|
@@ -392,7 +434,7 @@ class f {
|
|
|
392
434
|
* });
|
|
393
435
|
* });
|
|
394
436
|
* ```
|
|
395
|
-
*
|
|
437
|
+
*
|
|
396
438
|
* @example
|
|
397
439
|
* ```typescript
|
|
398
440
|
* // Track page leave on browser unload
|
|
@@ -406,27 +448,30 @@ class f {
|
|
|
406
448
|
*/
|
|
407
449
|
pageLeave(e) {
|
|
408
450
|
this.ensureInitialized().catch((i) => {
|
|
409
|
-
console.error(
|
|
451
|
+
console.error(
|
|
452
|
+
"[Analytics] Failed to initialize during pageLeave:",
|
|
453
|
+
i
|
|
454
|
+
);
|
|
410
455
|
});
|
|
411
|
-
for (const i of this.
|
|
412
|
-
i.pageLeave && i.pageLeave(e, this.context);
|
|
456
|
+
for (const i of this.providerConfigs)
|
|
457
|
+
this.shouldCallMethod(i, "pageLeave") && i.provider.pageLeave && i.provider.pageLeave(e, this.context);
|
|
413
458
|
}
|
|
414
459
|
/**
|
|
415
460
|
* Resets the analytics state, clearing user ID and generating a new session.
|
|
416
|
-
*
|
|
461
|
+
*
|
|
417
462
|
* This method should be called when a user logs out or when you want to
|
|
418
463
|
* start tracking a new user session. It clears the current user ID,
|
|
419
464
|
* generates a new session ID, and calls reset on all providers.
|
|
420
|
-
*
|
|
465
|
+
*
|
|
421
466
|
* Use this method to ensure user privacy and accurate session tracking
|
|
422
467
|
* when users switch accounts or log out.
|
|
423
|
-
*
|
|
468
|
+
*
|
|
424
469
|
* @example
|
|
425
470
|
* ```typescript
|
|
426
471
|
* // Basic reset on logout
|
|
427
472
|
* analytics.reset();
|
|
428
473
|
* ```
|
|
429
|
-
*
|
|
474
|
+
*
|
|
430
475
|
* @example
|
|
431
476
|
* ```typescript
|
|
432
477
|
* // In a logout handler
|
|
@@ -435,26 +480,26 @@ class f {
|
|
|
435
480
|
* await analytics.track('user_logged_out', {
|
|
436
481
|
* sessionDuration: Date.now() - sessionStartTime
|
|
437
482
|
* });
|
|
438
|
-
*
|
|
483
|
+
*
|
|
439
484
|
* // Reset analytics state
|
|
440
485
|
* analytics.reset();
|
|
441
|
-
*
|
|
486
|
+
*
|
|
442
487
|
* // Clear user data and redirect
|
|
443
488
|
* clearUserData();
|
|
444
489
|
* window.location.href = '/login';
|
|
445
490
|
* }
|
|
446
491
|
* ```
|
|
447
|
-
*
|
|
492
|
+
*
|
|
448
493
|
* @example
|
|
449
494
|
* ```typescript
|
|
450
495
|
* // Account switching scenario
|
|
451
496
|
* async function switchAccount(newUserId: string) {
|
|
452
497
|
* // Reset to clear previous user
|
|
453
498
|
* analytics.reset();
|
|
454
|
-
*
|
|
499
|
+
*
|
|
455
500
|
* // Identify the new user
|
|
456
501
|
* analytics.identify(newUserId);
|
|
457
|
-
*
|
|
502
|
+
*
|
|
458
503
|
* // Track account switch
|
|
459
504
|
* analytics.track('account_switched', {
|
|
460
505
|
* newUserId,
|
|
@@ -465,25 +510,25 @@ class f {
|
|
|
465
510
|
*/
|
|
466
511
|
reset() {
|
|
467
512
|
this.userId = void 0, this.userTraits = void 0, this.sessionId = this.generateSessionId();
|
|
468
|
-
for (const e of this.
|
|
469
|
-
e.reset();
|
|
513
|
+
for (const e of this.providerConfigs)
|
|
514
|
+
this.shouldCallMethod(e, "reset") && e.provider.reset();
|
|
470
515
|
}
|
|
471
516
|
/**
|
|
472
517
|
* Updates the analytics context with new information.
|
|
473
|
-
*
|
|
518
|
+
*
|
|
474
519
|
* The context is included with all tracked events and provides additional
|
|
475
520
|
* metadata about the user's environment, current page, device, and other
|
|
476
521
|
* relevant information. This method merges new context with existing context.
|
|
477
|
-
*
|
|
522
|
+
*
|
|
478
523
|
* Context typically includes page information, device details, UTM parameters,
|
|
479
524
|
* and custom application context.
|
|
480
|
-
*
|
|
525
|
+
*
|
|
481
526
|
* @param context Partial context to merge with existing context
|
|
482
527
|
* @param context.page Page-related context (path, title, referrer)
|
|
483
528
|
* @param context.device Device-related context (type, OS, browser)
|
|
484
529
|
* @param context.utm UTM campaign tracking parameters
|
|
485
530
|
* @param context.app Application-specific context
|
|
486
|
-
*
|
|
531
|
+
*
|
|
487
532
|
* @example
|
|
488
533
|
* ```typescript
|
|
489
534
|
* // Update page context
|
|
@@ -495,7 +540,7 @@ class f {
|
|
|
495
540
|
* }
|
|
496
541
|
* });
|
|
497
542
|
* ```
|
|
498
|
-
*
|
|
543
|
+
*
|
|
499
544
|
* @example
|
|
500
545
|
* ```typescript
|
|
501
546
|
* // Add UTM parameters from URL
|
|
@@ -510,7 +555,7 @@ class f {
|
|
|
510
555
|
* }
|
|
511
556
|
* });
|
|
512
557
|
* ```
|
|
513
|
-
*
|
|
558
|
+
*
|
|
514
559
|
* @example
|
|
515
560
|
* ```typescript
|
|
516
561
|
* // Update application context
|
|
@@ -529,14 +574,14 @@ class f {
|
|
|
529
574
|
* ```
|
|
530
575
|
*/
|
|
531
576
|
updateContext(e) {
|
|
532
|
-
var i, r,
|
|
577
|
+
var i, r, n;
|
|
533
578
|
this.context = {
|
|
534
579
|
...this.context,
|
|
535
580
|
...e,
|
|
536
581
|
page: e.page ? {
|
|
537
582
|
path: e.page.path || ((i = this.context.page) == null ? void 0 : i.path) || window.location.pathname,
|
|
538
583
|
title: e.page.title || ((r = this.context.page) == null ? void 0 : r.title),
|
|
539
|
-
referrer: e.page.referrer || ((
|
|
584
|
+
referrer: e.page.referrer || ((n = this.context.page) == null ? void 0 : n.referrer)
|
|
540
585
|
} : this.context.page,
|
|
541
586
|
device: {
|
|
542
587
|
...this.context.device,
|
|
@@ -570,51 +615,51 @@ class f {
|
|
|
570
615
|
return e.indexOf("Chrome") !== -1 ? "Chrome" : e.indexOf("Safari") !== -1 ? "Safari" : e.indexOf("Firefox") !== -1 ? "Firefox" : e.indexOf("Edge") !== -1 ? "Edge" : "Unknown";
|
|
571
616
|
}
|
|
572
617
|
}
|
|
573
|
-
let
|
|
618
|
+
let a = null;
|
|
574
619
|
function v(t) {
|
|
575
|
-
if (
|
|
576
|
-
return console.warn("[Analytics] Already initialized"),
|
|
620
|
+
if (a)
|
|
621
|
+
return console.warn("[Analytics] Already initialized"), a;
|
|
577
622
|
const e = {
|
|
578
623
|
providers: t.providers || [],
|
|
579
624
|
debug: t.debug,
|
|
580
625
|
enabled: t.enabled
|
|
581
626
|
};
|
|
582
|
-
return
|
|
627
|
+
return a = new p(e), a.initialize().catch((i) => {
|
|
583
628
|
console.error("[Analytics] Failed to initialize:", i);
|
|
584
|
-
}),
|
|
629
|
+
}), a;
|
|
585
630
|
}
|
|
586
|
-
function
|
|
587
|
-
if (!
|
|
631
|
+
function l() {
|
|
632
|
+
if (!a)
|
|
588
633
|
throw new Error(
|
|
589
634
|
"[Analytics] Not initialized. Call createAnalytics() first."
|
|
590
635
|
);
|
|
591
|
-
return
|
|
592
|
-
}
|
|
593
|
-
function y(t, e) {
|
|
594
|
-
return a().track(t, e);
|
|
636
|
+
return a;
|
|
595
637
|
}
|
|
596
638
|
function w(t, e) {
|
|
597
|
-
|
|
639
|
+
return l().track(t, e);
|
|
640
|
+
}
|
|
641
|
+
function y(t, e) {
|
|
642
|
+
l().identify(t, e);
|
|
598
643
|
}
|
|
599
644
|
function x(t) {
|
|
600
|
-
|
|
645
|
+
l().pageView(t);
|
|
601
646
|
}
|
|
602
647
|
function z(t) {
|
|
603
|
-
|
|
648
|
+
l().pageLeave(t);
|
|
604
649
|
}
|
|
605
|
-
function
|
|
606
|
-
|
|
650
|
+
function C() {
|
|
651
|
+
l().reset();
|
|
607
652
|
}
|
|
608
653
|
export {
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
654
|
+
k as BaseAnalyticsProvider,
|
|
655
|
+
p as BrowserAnalytics,
|
|
656
|
+
P as PostHogClientProvider,
|
|
612
657
|
v as createAnalytics,
|
|
613
658
|
v as createClientAnalytics,
|
|
614
|
-
|
|
615
|
-
|
|
659
|
+
l as getAnalytics,
|
|
660
|
+
y as identify,
|
|
616
661
|
z as pageLeave,
|
|
617
662
|
x as pageView,
|
|
618
|
-
|
|
619
|
-
|
|
663
|
+
C as reset,
|
|
664
|
+
w as track
|
|
620
665
|
};
|
|
@@ -13,6 +13,17 @@ export interface UserContext<TTraits extends Record<string, unknown> = Record<st
|
|
|
13
13
|
email?: string;
|
|
14
14
|
traits?: TTraits;
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Server-side context enrichment
|
|
18
|
+
* Used by server analytics to add request-specific metadata
|
|
19
|
+
*/
|
|
20
|
+
export interface ServerContext {
|
|
21
|
+
userAgent?: string;
|
|
22
|
+
ip?: string;
|
|
23
|
+
requestId?: string;
|
|
24
|
+
timestamp?: number;
|
|
25
|
+
[key: string]: unknown;
|
|
26
|
+
}
|
|
16
27
|
export interface EventContext<TTraits extends Record<string, unknown> = Record<string, unknown>> {
|
|
17
28
|
user?: UserContext<TTraits>;
|
|
18
29
|
page?: {
|
|
@@ -31,6 +42,7 @@ export interface EventContext<TTraits extends Record<string, unknown> = Record<s
|
|
|
31
42
|
userAgent?: string;
|
|
32
43
|
language?: string;
|
|
33
44
|
timezone?: string;
|
|
45
|
+
ip?: string;
|
|
34
46
|
screen?: {
|
|
35
47
|
width?: number;
|
|
36
48
|
height?: number;
|
|
@@ -45,6 +57,7 @@ export interface EventContext<TTraits extends Record<string, unknown> = Record<s
|
|
|
45
57
|
medium?: string;
|
|
46
58
|
name?: string;
|
|
47
59
|
};
|
|
60
|
+
server?: ServerContext;
|
|
48
61
|
}
|
|
49
62
|
export interface AnalyticsProvider {
|
|
50
63
|
name: string;
|
|
@@ -55,8 +68,57 @@ export interface AnalyticsProvider {
|
|
|
55
68
|
pageLeave?(properties?: Record<string, unknown>, context?: EventContext): Promise<void> | void;
|
|
56
69
|
reset(): Promise<void> | void;
|
|
57
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Provider methods that can be selectively enabled/disabled through routing
|
|
73
|
+
*/
|
|
74
|
+
export type ProviderMethod = "initialize" | "identify" | "track" | "pageView" | "pageLeave" | "reset";
|
|
75
|
+
/**
|
|
76
|
+
* Configuration for selective provider method routing.
|
|
77
|
+
* Allows you to control which methods are called on a specific provider.
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* // Only call track and identify, skip pageView
|
|
82
|
+
* {
|
|
83
|
+
* provider: new BentoClientProvider({...}),
|
|
84
|
+
* methods: ['track', 'identify']
|
|
85
|
+
* }
|
|
86
|
+
* ```
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* // Call all methods except pageView
|
|
91
|
+
* {
|
|
92
|
+
* provider: new GoogleAnalyticsProvider({...}),
|
|
93
|
+
* exclude: ['pageView']
|
|
94
|
+
* }
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
export interface ProviderConfig {
|
|
98
|
+
/**
|
|
99
|
+
* The analytics provider instance
|
|
100
|
+
*/
|
|
101
|
+
provider: AnalyticsProvider;
|
|
102
|
+
/**
|
|
103
|
+
* Only call these methods on this provider.
|
|
104
|
+
* If specified, all other methods will be skipped.
|
|
105
|
+
* Mutually exclusive with `exclude`.
|
|
106
|
+
*/
|
|
107
|
+
methods?: ProviderMethod[];
|
|
108
|
+
/**
|
|
109
|
+
* Skip these methods on this provider.
|
|
110
|
+
* All other methods will be called normally.
|
|
111
|
+
* Mutually exclusive with `methods`.
|
|
112
|
+
*/
|
|
113
|
+
exclude?: ProviderMethod[];
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Provider configuration - supports both simple provider instances
|
|
117
|
+
* and advanced routing configurations
|
|
118
|
+
*/
|
|
119
|
+
export type ProviderConfigOrProvider = AnalyticsProvider | ProviderConfig;
|
|
58
120
|
export interface AnalyticsConfig {
|
|
59
|
-
providers:
|
|
121
|
+
providers: ProviderConfigOrProvider[];
|
|
60
122
|
debug?: boolean;
|
|
61
123
|
enabled?: boolean;
|
|
62
124
|
defaultContext?: Partial<EventContext>;
|