@stacksee/analytics 0.11.0 → 0.12.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 +40 -0
- package/dist/adapters/server/server-analytics.d.ts +4 -0
- package/dist/client.d.ts +6 -2
- package/dist/client.js +157 -86
- package/dist/core/events/types.d.ts +74 -2
- package/dist/server.d.ts +2 -2
- package/dist/server.js +96 -74
- package/package.json +1 -1
|
@@ -47,6 +47,10 @@ export declare class BrowserAnalytics<TEventMap extends DefaultEventMap = Defaul
|
|
|
47
47
|
* Checks if a method should be called on a provider based on routing configuration
|
|
48
48
|
*/
|
|
49
49
|
private shouldCallMethod;
|
|
50
|
+
/**
|
|
51
|
+
* Checks if an event should be tracked on a provider based on event filtering configuration
|
|
52
|
+
*/
|
|
53
|
+
private shouldTrackEvent;
|
|
50
54
|
/**
|
|
51
55
|
* Initializes all analytics providers and sets up browser context.
|
|
52
56
|
*
|
|
@@ -394,6 +398,42 @@ export declare class BrowserAnalytics<TEventMap extends DefaultEventMap = Defaul
|
|
|
394
398
|
* ```
|
|
395
399
|
*/
|
|
396
400
|
reset(): void;
|
|
401
|
+
/**
|
|
402
|
+
* Manually flush all queued events to providers.
|
|
403
|
+
*
|
|
404
|
+
* This method is useful when you need to ensure events are sent immediately,
|
|
405
|
+
* such as before navigation or critical user actions. Providers that support
|
|
406
|
+
* batching (like ProxyProvider) will flush their queues when this is called.
|
|
407
|
+
*
|
|
408
|
+
* If `useBeacon` is true, providers that support it will use the Beacon API
|
|
409
|
+
* for more reliable delivery during page unload.
|
|
410
|
+
*
|
|
411
|
+
* @param useBeacon Whether to use the Beacon API for flushing (default: false)
|
|
412
|
+
* @returns Promise that resolves when all providers have flushed
|
|
413
|
+
*
|
|
414
|
+
* @example
|
|
415
|
+
* ```typescript
|
|
416
|
+
* // Flush before navigation
|
|
417
|
+
* analytics.track('button_clicked', { buttonId: 'checkout' });
|
|
418
|
+
* await analytics.flush();
|
|
419
|
+
* window.location.href = '/checkout';
|
|
420
|
+
* ```
|
|
421
|
+
*
|
|
422
|
+
* @example
|
|
423
|
+
* ```typescript
|
|
424
|
+
* // Flush with beacon API before page unload
|
|
425
|
+
* await analytics.flush(true);
|
|
426
|
+
* ```
|
|
427
|
+
*
|
|
428
|
+
* @example
|
|
429
|
+
* ```typescript
|
|
430
|
+
* // Ensure critical events are sent immediately
|
|
431
|
+
* await analytics.track('purchase_completed', { orderId: '123' });
|
|
432
|
+
* await analytics.flush(); // Wait for confirmation
|
|
433
|
+
* showThankYouPage();
|
|
434
|
+
* ```
|
|
435
|
+
*/
|
|
436
|
+
flush(useBeacon?: boolean): Promise<void>;
|
|
397
437
|
/**
|
|
398
438
|
* Updates the analytics context with new information.
|
|
399
439
|
*
|
|
@@ -43,6 +43,10 @@ export declare class ServerAnalytics<TEventMap extends Record<string, Record<str
|
|
|
43
43
|
* Checks if a method should be called on a provider based on routing configuration
|
|
44
44
|
*/
|
|
45
45
|
private shouldCallMethod;
|
|
46
|
+
/**
|
|
47
|
+
* Checks if an event should be tracked on a provider based on event filtering configuration
|
|
48
|
+
*/
|
|
49
|
+
private shouldTrackEvent;
|
|
46
50
|
/**
|
|
47
51
|
* Initializes all analytics providers.
|
|
48
52
|
*
|
package/dist/client.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { BrowserAnalytics } from './adapters/client/browser-analytics.js';
|
|
2
|
-
import {
|
|
2
|
+
import { ProviderConfigOrProvider } from './core/events/types.js';
|
|
3
3
|
import { EventMapFromCollection } from './core/events/index.js';
|
|
4
4
|
export interface ClientAnalyticsConfig {
|
|
5
|
-
providers?:
|
|
5
|
+
providers?: ProviderConfigOrProvider[];
|
|
6
6
|
debug?: boolean;
|
|
7
7
|
enabled?: boolean;
|
|
8
8
|
}
|
|
@@ -60,6 +60,10 @@ export declare function pageLeave(properties?: Record<string, unknown>): void;
|
|
|
60
60
|
* Convenience function to reset user session
|
|
61
61
|
*/
|
|
62
62
|
export declare function reset(): void;
|
|
63
|
+
/**
|
|
64
|
+
* Convenience function to flush queued events
|
|
65
|
+
*/
|
|
66
|
+
export declare function flush(useBeacon?: boolean): Promise<void>;
|
|
63
67
|
/**
|
|
64
68
|
* Reset the analytics instance (for testing purposes)
|
|
65
69
|
* @internal
|
package/dist/client.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { i as
|
|
5
|
-
import { P } from "./client-DTHZYkxx.js";
|
|
6
|
-
import { B as
|
|
7
|
-
class
|
|
1
|
+
var f = Object.defineProperty;
|
|
2
|
+
var p = (n, e, t) => e in n ? f(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t;
|
|
3
|
+
var a = (n, e, t) => p(n, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
import { i as g } from "./client-DTHZYkxx.js";
|
|
5
|
+
import { P as k } from "./client-DTHZYkxx.js";
|
|
6
|
+
import { B as O } from "./base.provider-AfFL5W_P.js";
|
|
7
|
+
class m {
|
|
8
8
|
/**
|
|
9
9
|
* Creates a new BrowserAnalytics instance for client-side event tracking.
|
|
10
10
|
*
|
|
@@ -36,20 +36,20 @@ class p {
|
|
|
36
36
|
* ```
|
|
37
37
|
*/
|
|
38
38
|
constructor(e) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
a(this, "providerConfigs", []);
|
|
40
|
+
a(this, "context", {});
|
|
41
|
+
a(this, "userId");
|
|
42
|
+
a(this, "sessionId");
|
|
43
|
+
a(this, "userTraits");
|
|
44
|
+
a(this, "initialized", !1);
|
|
45
|
+
a(this, "initializePromise");
|
|
46
46
|
this.providerConfigs = this.normalizeProviders(e.providers), e.defaultContext && (this.context = { ...e.defaultContext }), this.sessionId = this.generateSessionId();
|
|
47
47
|
}
|
|
48
48
|
/**
|
|
49
49
|
* Normalizes provider configurations into a consistent internal format
|
|
50
50
|
*/
|
|
51
51
|
normalizeProviders(e) {
|
|
52
|
-
const
|
|
52
|
+
const t = [
|
|
53
53
|
"initialize",
|
|
54
54
|
"identify",
|
|
55
55
|
"track",
|
|
@@ -61,31 +61,51 @@ class p {
|
|
|
61
61
|
if ("initialize" in r && "track" in r)
|
|
62
62
|
return {
|
|
63
63
|
provider: r,
|
|
64
|
-
enabledMethods: new Set(
|
|
64
|
+
enabledMethods: new Set(t)
|
|
65
65
|
};
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
`[Analytics] Provider ${
|
|
66
|
+
const i = r;
|
|
67
|
+
i.methods && i.exclude && console.warn(
|
|
68
|
+
`[Analytics] Provider ${i.provider.name} has both 'methods' and 'exclude' specified. Using 'methods' and ignoring 'exclude'.`
|
|
69
|
+
), i.events && i.excludeEvents && console.warn(
|
|
70
|
+
`[Analytics] Provider ${i.provider.name} has both 'events' and 'excludeEvents' specified. Using 'events' and ignoring 'excludeEvents'.`
|
|
71
|
+
), i.events && i.eventPatterns && console.warn(
|
|
72
|
+
`[Analytics] Provider ${i.provider.name} has both 'events' and 'eventPatterns' specified. Using 'events' and ignoring 'eventPatterns'.`
|
|
73
|
+
), i.excludeEvents && i.eventPatterns && console.warn(
|
|
74
|
+
`[Analytics] Provider ${i.provider.name} has both 'excludeEvents' and 'eventPatterns' specified. Using 'eventPatterns' and ignoring 'excludeEvents'.`
|
|
69
75
|
);
|
|
70
|
-
let
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
(
|
|
74
|
-
var
|
|
75
|
-
return !((
|
|
76
|
+
let d;
|
|
77
|
+
i.methods ? d = new Set(i.methods) : i.exclude ? d = new Set(
|
|
78
|
+
t.filter(
|
|
79
|
+
(u) => {
|
|
80
|
+
var c;
|
|
81
|
+
return !((c = i.exclude) != null && c.includes(u));
|
|
76
82
|
}
|
|
77
83
|
)
|
|
78
|
-
) :
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
) : d = new Set(t);
|
|
85
|
+
let s, h, v;
|
|
86
|
+
return i.events && i.events.length > 0 ? s = new Set(i.events) : i.eventPatterns && i.eventPatterns.length > 0 ? v = i.eventPatterns.map((u) => {
|
|
87
|
+
const c = u.replace(/\*/g, ".*");
|
|
88
|
+
return new RegExp(`^${c}$`);
|
|
89
|
+
}) : i.excludeEvents && i.excludeEvents.length > 0 && (h = new Set(i.excludeEvents)), {
|
|
90
|
+
provider: i.provider,
|
|
91
|
+
enabledMethods: d,
|
|
92
|
+
enabledEvents: s,
|
|
93
|
+
excludedEvents: h,
|
|
94
|
+
eventPatterns: v
|
|
81
95
|
};
|
|
82
96
|
});
|
|
83
97
|
}
|
|
84
98
|
/**
|
|
85
99
|
* Checks if a method should be called on a provider based on routing configuration
|
|
86
100
|
*/
|
|
87
|
-
shouldCallMethod(e,
|
|
88
|
-
return e.enabledMethods.has(
|
|
101
|
+
shouldCallMethod(e, t) {
|
|
102
|
+
return e.enabledMethods.has(t);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Checks if an event should be tracked on a provider based on event filtering configuration
|
|
106
|
+
*/
|
|
107
|
+
shouldTrackEvent(e, t) {
|
|
108
|
+
return !e.enabledEvents && !e.excludedEvents && !e.eventPatterns ? !0 : e.enabledEvents ? e.enabledEvents.has(t) : e.eventPatterns ? e.eventPatterns.some((r) => r.test(t)) : e.excludedEvents ? !e.excludedEvents.has(t) : !0;
|
|
89
109
|
}
|
|
90
110
|
/**
|
|
91
111
|
* Initializes all analytics providers and sets up browser context.
|
|
@@ -118,12 +138,12 @@ class p {
|
|
|
118
138
|
* ```
|
|
119
139
|
*/
|
|
120
140
|
async initialize() {
|
|
121
|
-
if (
|
|
141
|
+
if (g() && !this.initialized)
|
|
122
142
|
return this.initializePromise ? this.initializePromise : (this.initializePromise = this._doInitialize(), this.initializePromise);
|
|
123
143
|
}
|
|
124
144
|
async _doInitialize() {
|
|
125
145
|
const e = this.providerConfigs.map(
|
|
126
|
-
(
|
|
146
|
+
(t) => t.provider.initialize()
|
|
127
147
|
);
|
|
128
148
|
await Promise.all(e), this.initialized = !0, this.updateContext({
|
|
129
149
|
page: {
|
|
@@ -208,12 +228,12 @@ class p {
|
|
|
208
228
|
* }
|
|
209
229
|
* ```
|
|
210
230
|
*/
|
|
211
|
-
identify(e,
|
|
212
|
-
this.userId = e, this.userTraits =
|
|
231
|
+
identify(e, t) {
|
|
232
|
+
this.userId = e, this.userTraits = t, this.ensureInitialized().catch((r) => {
|
|
213
233
|
console.error("[Analytics] Failed to initialize during identify:", r);
|
|
214
234
|
});
|
|
215
235
|
for (const r of this.providerConfigs)
|
|
216
|
-
this.shouldCallMethod(r, "identify") && r.provider.identify(e,
|
|
236
|
+
this.shouldCallMethod(r, "identify") && r.provider.identify(e, t);
|
|
217
237
|
}
|
|
218
238
|
/**
|
|
219
239
|
* Tracks a custom event with properties.
|
|
@@ -290,33 +310,35 @@ class p {
|
|
|
290
310
|
* }
|
|
291
311
|
* ```
|
|
292
312
|
*/
|
|
293
|
-
async track(e,
|
|
313
|
+
async track(e, t) {
|
|
294
314
|
await this.ensureInitialized();
|
|
295
315
|
const r = {
|
|
296
316
|
action: e,
|
|
297
317
|
category: this.getCategoryFromEventName(e),
|
|
298
|
-
properties:
|
|
318
|
+
properties: t,
|
|
299
319
|
timestamp: Date.now(),
|
|
300
320
|
userId: this.userId,
|
|
301
321
|
sessionId: this.sessionId
|
|
302
|
-
},
|
|
322
|
+
}, i = {
|
|
303
323
|
...this.context,
|
|
304
324
|
user: this.userId || this.userTraits ? {
|
|
305
325
|
userId: this.userId,
|
|
306
326
|
email: this.userTraits && "email" in this.userTraits ? this.userTraits.email : void 0,
|
|
307
327
|
traits: this.userTraits
|
|
308
328
|
} : void 0
|
|
309
|
-
},
|
|
329
|
+
}, d = this.providerConfigs.filter(
|
|
330
|
+
(s) => this.shouldCallMethod(s, "track") && this.shouldTrackEvent(s, e)
|
|
331
|
+
).map(async (s) => {
|
|
310
332
|
try {
|
|
311
|
-
await
|
|
333
|
+
await s.provider.track(r, i);
|
|
312
334
|
} catch (h) {
|
|
313
335
|
console.error(
|
|
314
|
-
`[Analytics] Provider ${
|
|
336
|
+
`[Analytics] Provider ${s.provider.name} failed to track event:`,
|
|
315
337
|
h
|
|
316
338
|
);
|
|
317
339
|
}
|
|
318
340
|
});
|
|
319
|
-
await Promise.all(
|
|
341
|
+
await Promise.all(d);
|
|
320
342
|
}
|
|
321
343
|
/**
|
|
322
344
|
* Tracks a page view event.
|
|
@@ -379,8 +401,8 @@ class p {
|
|
|
379
401
|
* ```
|
|
380
402
|
*/
|
|
381
403
|
pageView(e) {
|
|
382
|
-
this.ensureInitialized().catch((
|
|
383
|
-
console.error("[Analytics] Failed to initialize during pageView:",
|
|
404
|
+
this.ensureInitialized().catch((t) => {
|
|
405
|
+
console.error("[Analytics] Failed to initialize during pageView:", t);
|
|
384
406
|
}), this.updateContext({
|
|
385
407
|
page: {
|
|
386
408
|
path: window.location.pathname,
|
|
@@ -388,8 +410,8 @@ class p {
|
|
|
388
410
|
referrer: document.referrer
|
|
389
411
|
}
|
|
390
412
|
});
|
|
391
|
-
for (const
|
|
392
|
-
this.shouldCallMethod(
|
|
413
|
+
for (const t of this.providerConfigs)
|
|
414
|
+
this.shouldCallMethod(t, "pageView") && t.provider.pageView(e, this.context);
|
|
393
415
|
}
|
|
394
416
|
/**
|
|
395
417
|
* Tracks when a user leaves a page.
|
|
@@ -447,14 +469,14 @@ class p {
|
|
|
447
469
|
* ```
|
|
448
470
|
*/
|
|
449
471
|
pageLeave(e) {
|
|
450
|
-
this.ensureInitialized().catch((
|
|
472
|
+
this.ensureInitialized().catch((t) => {
|
|
451
473
|
console.error(
|
|
452
474
|
"[Analytics] Failed to initialize during pageLeave:",
|
|
453
|
-
|
|
475
|
+
t
|
|
454
476
|
);
|
|
455
477
|
});
|
|
456
|
-
for (const
|
|
457
|
-
this.shouldCallMethod(
|
|
478
|
+
for (const t of this.providerConfigs)
|
|
479
|
+
this.shouldCallMethod(t, "pageLeave") && t.provider.pageLeave && t.provider.pageLeave(e, this.context);
|
|
458
480
|
}
|
|
459
481
|
/**
|
|
460
482
|
* Resets the analytics state, clearing user ID and generating a new session.
|
|
@@ -513,6 +535,55 @@ class p {
|
|
|
513
535
|
for (const e of this.providerConfigs)
|
|
514
536
|
this.shouldCallMethod(e, "reset") && e.provider.reset();
|
|
515
537
|
}
|
|
538
|
+
/**
|
|
539
|
+
* Manually flush all queued events to providers.
|
|
540
|
+
*
|
|
541
|
+
* This method is useful when you need to ensure events are sent immediately,
|
|
542
|
+
* such as before navigation or critical user actions. Providers that support
|
|
543
|
+
* batching (like ProxyProvider) will flush their queues when this is called.
|
|
544
|
+
*
|
|
545
|
+
* If `useBeacon` is true, providers that support it will use the Beacon API
|
|
546
|
+
* for more reliable delivery during page unload.
|
|
547
|
+
*
|
|
548
|
+
* @param useBeacon Whether to use the Beacon API for flushing (default: false)
|
|
549
|
+
* @returns Promise that resolves when all providers have flushed
|
|
550
|
+
*
|
|
551
|
+
* @example
|
|
552
|
+
* ```typescript
|
|
553
|
+
* // Flush before navigation
|
|
554
|
+
* analytics.track('button_clicked', { buttonId: 'checkout' });
|
|
555
|
+
* await analytics.flush();
|
|
556
|
+
* window.location.href = '/checkout';
|
|
557
|
+
* ```
|
|
558
|
+
*
|
|
559
|
+
* @example
|
|
560
|
+
* ```typescript
|
|
561
|
+
* // Flush with beacon API before page unload
|
|
562
|
+
* await analytics.flush(true);
|
|
563
|
+
* ```
|
|
564
|
+
*
|
|
565
|
+
* @example
|
|
566
|
+
* ```typescript
|
|
567
|
+
* // Ensure critical events are sent immediately
|
|
568
|
+
* await analytics.track('purchase_completed', { orderId: '123' });
|
|
569
|
+
* await analytics.flush(); // Wait for confirmation
|
|
570
|
+
* showThankYouPage();
|
|
571
|
+
* ```
|
|
572
|
+
*/
|
|
573
|
+
async flush(e = !1) {
|
|
574
|
+
const t = this.providerConfigs.map(async (r) => {
|
|
575
|
+
if (r.provider.flush && typeof r.provider.flush == "function")
|
|
576
|
+
try {
|
|
577
|
+
await r.provider.flush(e);
|
|
578
|
+
} catch (i) {
|
|
579
|
+
console.error(
|
|
580
|
+
`[Analytics] Provider ${r.provider.name} failed to flush:`,
|
|
581
|
+
i
|
|
582
|
+
);
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
await Promise.all(t);
|
|
586
|
+
}
|
|
516
587
|
/**
|
|
517
588
|
* Updates the analytics context with new information.
|
|
518
589
|
*
|
|
@@ -574,14 +645,14 @@ class p {
|
|
|
574
645
|
* ```
|
|
575
646
|
*/
|
|
576
647
|
updateContext(e) {
|
|
577
|
-
var
|
|
648
|
+
var t, r, i;
|
|
578
649
|
this.context = {
|
|
579
650
|
...this.context,
|
|
580
651
|
...e,
|
|
581
652
|
page: e.page ? {
|
|
582
|
-
path: e.page.path || ((
|
|
653
|
+
path: e.page.path || ((t = this.context.page) == null ? void 0 : t.path) || window.location.pathname,
|
|
583
654
|
title: e.page.title || ((r = this.context.page) == null ? void 0 : r.title),
|
|
584
|
-
referrer: e.page.referrer || ((
|
|
655
|
+
referrer: e.page.referrer || ((i = this.context.page) == null ? void 0 : i.referrer)
|
|
585
656
|
} : this.context.page,
|
|
586
657
|
device: {
|
|
587
658
|
...this.context.device,
|
|
@@ -594,8 +665,8 @@ class p {
|
|
|
594
665
|
};
|
|
595
666
|
}
|
|
596
667
|
getCategoryFromEventName(e) {
|
|
597
|
-
const
|
|
598
|
-
return
|
|
668
|
+
const t = e.split("_");
|
|
669
|
+
return t.length > 1 && t[0] ? t[0] : "engagement";
|
|
599
670
|
}
|
|
600
671
|
generateSessionId() {
|
|
601
672
|
return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
|
|
@@ -615,51 +686,51 @@ class p {
|
|
|
615
686
|
return e.indexOf("Chrome") !== -1 ? "Chrome" : e.indexOf("Safari") !== -1 ? "Safari" : e.indexOf("Firefox") !== -1 ? "Firefox" : e.indexOf("Edge") !== -1 ? "Edge" : "Unknown";
|
|
616
687
|
}
|
|
617
688
|
}
|
|
618
|
-
let
|
|
619
|
-
function
|
|
620
|
-
if (
|
|
621
|
-
return console.warn("[Analytics] Already initialized"),
|
|
689
|
+
let o = null;
|
|
690
|
+
function y(n) {
|
|
691
|
+
if (o)
|
|
692
|
+
return console.warn("[Analytics] Already initialized"), o;
|
|
622
693
|
const e = {
|
|
623
|
-
providers:
|
|
624
|
-
debug:
|
|
625
|
-
enabled:
|
|
694
|
+
providers: n.providers || [],
|
|
695
|
+
debug: n.debug,
|
|
696
|
+
enabled: n.enabled
|
|
626
697
|
};
|
|
627
|
-
return
|
|
628
|
-
console.error("[Analytics] Failed to initialize:",
|
|
629
|
-
}),
|
|
698
|
+
return o = new m(e), o.initialize().catch((t) => {
|
|
699
|
+
console.error("[Analytics] Failed to initialize:", t);
|
|
700
|
+
}), o;
|
|
630
701
|
}
|
|
631
702
|
function l() {
|
|
632
|
-
if (!
|
|
703
|
+
if (!o)
|
|
633
704
|
throw new Error(
|
|
634
705
|
"[Analytics] Not initialized. Call createAnalytics() first."
|
|
635
706
|
);
|
|
636
|
-
return
|
|
707
|
+
return o;
|
|
637
708
|
}
|
|
638
|
-
function
|
|
639
|
-
return l().track(
|
|
709
|
+
function P(n, e) {
|
|
710
|
+
return l().track(n, e);
|
|
640
711
|
}
|
|
641
|
-
function
|
|
642
|
-
l().identify(
|
|
712
|
+
function z(n, e) {
|
|
713
|
+
l().identify(n, e);
|
|
643
714
|
}
|
|
644
|
-
function
|
|
645
|
-
l().pageView(
|
|
715
|
+
function C(n) {
|
|
716
|
+
l().pageView(n);
|
|
646
717
|
}
|
|
647
|
-
function
|
|
648
|
-
l().pageLeave(
|
|
718
|
+
function A(n) {
|
|
719
|
+
l().pageLeave(n);
|
|
649
720
|
}
|
|
650
|
-
function
|
|
721
|
+
function b() {
|
|
651
722
|
l().reset();
|
|
652
723
|
}
|
|
653
724
|
export {
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
725
|
+
O as BaseAnalyticsProvider,
|
|
726
|
+
m as BrowserAnalytics,
|
|
727
|
+
k as PostHogClientProvider,
|
|
728
|
+
y as createAnalytics,
|
|
729
|
+
y as createClientAnalytics,
|
|
659
730
|
l as getAnalytics,
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
731
|
+
z as identify,
|
|
732
|
+
A as pageLeave,
|
|
733
|
+
C as pageView,
|
|
734
|
+
b as reset,
|
|
735
|
+
P as track
|
|
665
736
|
};
|
|
@@ -67,14 +67,16 @@ export interface AnalyticsProvider {
|
|
|
67
67
|
pageView(properties?: Record<string, unknown>, context?: EventContext): Promise<void> | void;
|
|
68
68
|
pageLeave?(properties?: Record<string, unknown>, context?: EventContext): Promise<void> | void;
|
|
69
69
|
reset(): Promise<void> | void;
|
|
70
|
+
flush?(useBeacon?: boolean): Promise<void> | void;
|
|
70
71
|
}
|
|
71
72
|
/**
|
|
72
73
|
* Provider methods that can be selectively enabled/disabled through routing
|
|
73
74
|
*/
|
|
74
75
|
export type ProviderMethod = "initialize" | "identify" | "track" | "pageView" | "pageLeave" | "reset";
|
|
75
76
|
/**
|
|
76
|
-
* Configuration for selective provider method routing.
|
|
77
|
-
* Allows you to control which methods are called on a specific provider
|
|
77
|
+
* Configuration for selective provider method routing and event filtering.
|
|
78
|
+
* Allows you to control which methods are called on a specific provider
|
|
79
|
+
* and which events are tracked.
|
|
78
80
|
*
|
|
79
81
|
* @example
|
|
80
82
|
* ```typescript
|
|
@@ -93,6 +95,33 @@ export type ProviderMethod = "initialize" | "identify" | "track" | "pageView" |
|
|
|
93
95
|
* exclude: ['pageView']
|
|
94
96
|
* }
|
|
95
97
|
* ```
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* // Only track specific events (solves 1-to-50 problem)
|
|
102
|
+
* {
|
|
103
|
+
* provider: new EmitKitServerProvider({...}),
|
|
104
|
+
* events: ['newsletter_signup', 'user_registered']
|
|
105
|
+
* }
|
|
106
|
+
* ```
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* // Track all events except specific ones
|
|
111
|
+
* {
|
|
112
|
+
* provider: new PostHogServerProvider({...}),
|
|
113
|
+
* excludeEvents: ['newsletter_signup']
|
|
114
|
+
* }
|
|
115
|
+
* ```
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* // Use glob patterns to match multiple events
|
|
120
|
+
* {
|
|
121
|
+
* provider: new EmitKitServerProvider({...}),
|
|
122
|
+
* eventPatterns: ['newsletter_*', 'user_*']
|
|
123
|
+
* }
|
|
124
|
+
* ```
|
|
96
125
|
*/
|
|
97
126
|
export interface ProviderConfig {
|
|
98
127
|
/**
|
|
@@ -111,6 +140,49 @@ export interface ProviderConfig {
|
|
|
111
140
|
* Mutually exclusive with `methods`.
|
|
112
141
|
*/
|
|
113
142
|
exclude?: ProviderMethod[];
|
|
143
|
+
/**
|
|
144
|
+
* Only track these specific event names on this provider.
|
|
145
|
+
* If specified, all other events will be skipped.
|
|
146
|
+
* Mutually exclusive with `excludeEvents`.
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* {
|
|
151
|
+
* provider: new EmitKitServerProvider({...}),
|
|
152
|
+
* events: ['newsletter_signup'] // Only this event goes to EmitKit
|
|
153
|
+
* }
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
events?: string[];
|
|
157
|
+
/**
|
|
158
|
+
* Skip these specific event names on this provider.
|
|
159
|
+
* All other events will be tracked normally.
|
|
160
|
+
* Mutually exclusive with `events` and `eventPatterns`.
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```typescript
|
|
164
|
+
* {
|
|
165
|
+
* provider: new BentoClientProvider({...}),
|
|
166
|
+
* excludeEvents: ['page_view'] // Everything except page views
|
|
167
|
+
* }
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
excludeEvents?: string[];
|
|
171
|
+
/**
|
|
172
|
+
* Glob-style patterns to match event names.
|
|
173
|
+
* Supports wildcards (*) for flexible event routing.
|
|
174
|
+
* Mutually exclusive with `excludeEvents`.
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* ```typescript
|
|
178
|
+
* {
|
|
179
|
+
* provider: new EmitKitServerProvider({...}),
|
|
180
|
+
* eventPatterns: ['newsletter_*', 'user_registered']
|
|
181
|
+
* // Matches: newsletter_signup, newsletter_unsubscribe, user_registered
|
|
182
|
+
* }
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
eventPatterns?: string[];
|
|
114
186
|
}
|
|
115
187
|
/**
|
|
116
188
|
* Provider configuration - supports both simple provider instances
|
package/dist/server.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ServerAnalytics } from './adapters/server/server-analytics.js';
|
|
2
|
-
import {
|
|
2
|
+
import { ProviderConfigOrProvider } from './core/events/types.js';
|
|
3
3
|
import { EventMapFromCollection } from './core/events/index.js';
|
|
4
4
|
export interface ServerAnalyticsConfig {
|
|
5
|
-
providers?:
|
|
5
|
+
providers?: ProviderConfigOrProvider[];
|
|
6
6
|
debug?: boolean;
|
|
7
7
|
enabled?: boolean;
|
|
8
8
|
}
|
package/dist/server.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
1
|
+
var u = Object.defineProperty;
|
|
2
|
+
var h = (i, e, t) => e in i ? u(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t;
|
|
3
|
+
var c = (i, e, t) => h(i, typeof e != "symbol" ? e + "" : e, t);
|
|
4
4
|
import { P as w } from "./server-DjEk1fUD.js";
|
|
5
|
-
import { B as
|
|
6
|
-
class
|
|
5
|
+
import { B as y } from "./base.provider-AfFL5W_P.js";
|
|
6
|
+
class f {
|
|
7
7
|
/**
|
|
8
8
|
* Creates a new ServerAnalytics instance for server-side event tracking.
|
|
9
9
|
*
|
|
@@ -34,17 +34,17 @@ class v {
|
|
|
34
34
|
* analytics.initialize();
|
|
35
35
|
* ```
|
|
36
36
|
*/
|
|
37
|
-
constructor(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
this.config =
|
|
37
|
+
constructor(e) {
|
|
38
|
+
c(this, "providerConfigs", []);
|
|
39
|
+
c(this, "config");
|
|
40
|
+
c(this, "initialized", !1);
|
|
41
|
+
this.config = e, this.providerConfigs = this.normalizeProviders(e.providers);
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
44
|
* Normalizes provider configurations into a consistent internal format
|
|
45
45
|
*/
|
|
46
|
-
normalizeProviders(
|
|
47
|
-
const
|
|
46
|
+
normalizeProviders(e) {
|
|
47
|
+
const t = [
|
|
48
48
|
"initialize",
|
|
49
49
|
"identify",
|
|
50
50
|
"track",
|
|
@@ -52,35 +52,55 @@ class v {
|
|
|
52
52
|
"pageLeave",
|
|
53
53
|
"reset"
|
|
54
54
|
];
|
|
55
|
-
return
|
|
56
|
-
if ("initialize" in
|
|
55
|
+
return e.map((n) => {
|
|
56
|
+
if ("initialize" in n && "track" in n)
|
|
57
57
|
return {
|
|
58
|
-
provider:
|
|
59
|
-
enabledMethods: new Set(
|
|
58
|
+
provider: n,
|
|
59
|
+
enabledMethods: new Set(t)
|
|
60
60
|
};
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
`[Analytics] Provider ${
|
|
61
|
+
const r = n;
|
|
62
|
+
r.methods && r.exclude && console.warn(
|
|
63
|
+
`[Analytics] Provider ${r.provider.name} has both 'methods' and 'exclude' specified. Using 'methods' and ignoring 'exclude'.`
|
|
64
|
+
), r.events && r.excludeEvents && console.warn(
|
|
65
|
+
`[Analytics] Provider ${r.provider.name} has both 'events' and 'excludeEvents' specified. Using 'events' and ignoring 'excludeEvents'.`
|
|
66
|
+
), r.events && r.eventPatterns && console.warn(
|
|
67
|
+
`[Analytics] Provider ${r.provider.name} has both 'events' and 'eventPatterns' specified. Using 'events' and ignoring 'eventPatterns'.`
|
|
68
|
+
), r.excludeEvents && r.eventPatterns && console.warn(
|
|
69
|
+
`[Analytics] Provider ${r.provider.name} has both 'excludeEvents' and 'eventPatterns' specified. Using 'eventPatterns' and ignoring 'excludeEvents'.`
|
|
64
70
|
);
|
|
65
|
-
let
|
|
66
|
-
|
|
67
|
-
|
|
71
|
+
let a;
|
|
72
|
+
r.methods ? a = new Set(r.methods) : r.exclude ? a = new Set(
|
|
73
|
+
t.filter(
|
|
68
74
|
(l) => {
|
|
69
|
-
var
|
|
70
|
-
return !((
|
|
75
|
+
var v;
|
|
76
|
+
return !((v = r.exclude) != null && v.includes(l));
|
|
71
77
|
}
|
|
72
78
|
)
|
|
73
|
-
) :
|
|
74
|
-
|
|
75
|
-
|
|
79
|
+
) : a = new Set(t);
|
|
80
|
+
let o, d, s;
|
|
81
|
+
return r.events && r.events.length > 0 ? o = new Set(r.events) : r.eventPatterns && r.eventPatterns.length > 0 ? s = r.eventPatterns.map((l) => {
|
|
82
|
+
const v = l.replace(/\*/g, ".*");
|
|
83
|
+
return new RegExp(`^${v}$`);
|
|
84
|
+
}) : r.excludeEvents && r.excludeEvents.length > 0 && (d = new Set(r.excludeEvents)), {
|
|
85
|
+
provider: r.provider,
|
|
86
|
+
enabledMethods: a,
|
|
87
|
+
enabledEvents: o,
|
|
88
|
+
excludedEvents: d,
|
|
89
|
+
eventPatterns: s
|
|
76
90
|
};
|
|
77
91
|
});
|
|
78
92
|
}
|
|
79
93
|
/**
|
|
80
94
|
* Checks if a method should be called on a provider based on routing configuration
|
|
81
95
|
*/
|
|
82
|
-
shouldCallMethod(
|
|
83
|
-
return
|
|
96
|
+
shouldCallMethod(e, t) {
|
|
97
|
+
return e.enabledMethods.has(t);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Checks if an event should be tracked on a provider based on event filtering configuration
|
|
101
|
+
*/
|
|
102
|
+
shouldTrackEvent(e, t) {
|
|
103
|
+
return !e.enabledEvents && !e.excludedEvents && !e.eventPatterns ? !0 : e.enabledEvents ? e.enabledEvents.has(t) : e.eventPatterns ? e.eventPatterns.some((n) => n.test(t)) : e.excludedEvents ? !e.excludedEvents.has(t) : !0;
|
|
84
104
|
}
|
|
85
105
|
/**
|
|
86
106
|
* Initializes all analytics providers.
|
|
@@ -120,8 +140,8 @@ class v {
|
|
|
120
140
|
*/
|
|
121
141
|
initialize() {
|
|
122
142
|
if (!this.initialized) {
|
|
123
|
-
for (const
|
|
124
|
-
|
|
143
|
+
for (const e of this.providerConfigs)
|
|
144
|
+
e.provider.initialize();
|
|
125
145
|
this.initialized = !0;
|
|
126
146
|
}
|
|
127
147
|
}
|
|
@@ -171,9 +191,9 @@ class v {
|
|
|
171
191
|
* }
|
|
172
192
|
* ```
|
|
173
193
|
*/
|
|
174
|
-
identify(
|
|
175
|
-
for (const
|
|
176
|
-
this.shouldCallMethod(
|
|
194
|
+
identify(e, t) {
|
|
195
|
+
for (const n of this.providerConfigs)
|
|
196
|
+
this.shouldCallMethod(n, "identify") && n.provider.identify(e, t);
|
|
177
197
|
}
|
|
178
198
|
/**
|
|
179
199
|
* Tracks a custom event with properties and optional context.
|
|
@@ -296,34 +316,36 @@ class v {
|
|
|
296
316
|
* }
|
|
297
317
|
* ```
|
|
298
318
|
*/
|
|
299
|
-
async track(
|
|
319
|
+
async track(e, t, n) {
|
|
300
320
|
var d;
|
|
301
321
|
if (!this.initialized) {
|
|
302
322
|
console.warn("[Analytics] Not initialized. Call initialize() first.");
|
|
303
323
|
return;
|
|
304
324
|
}
|
|
305
|
-
const
|
|
306
|
-
action:
|
|
307
|
-
category: this.getCategoryFromEventName(
|
|
308
|
-
properties:
|
|
325
|
+
const r = {
|
|
326
|
+
action: e,
|
|
327
|
+
category: this.getCategoryFromEventName(e),
|
|
328
|
+
properties: t,
|
|
309
329
|
timestamp: Date.now(),
|
|
310
|
-
userId:
|
|
311
|
-
sessionId:
|
|
312
|
-
},
|
|
330
|
+
userId: n == null ? void 0 : n.userId,
|
|
331
|
+
sessionId: n == null ? void 0 : n.sessionId
|
|
332
|
+
}, a = {
|
|
313
333
|
...this.config.defaultContext,
|
|
314
|
-
...
|
|
315
|
-
user: (
|
|
316
|
-
},
|
|
334
|
+
...n == null ? void 0 : n.context,
|
|
335
|
+
user: (n == null ? void 0 : n.user) || ((d = n == null ? void 0 : n.context) == null ? void 0 : d.user)
|
|
336
|
+
}, o = this.providerConfigs.filter(
|
|
337
|
+
(s) => this.shouldCallMethod(s, "track") && this.shouldTrackEvent(s, e)
|
|
338
|
+
).map(async (s) => {
|
|
317
339
|
try {
|
|
318
|
-
await s.provider.track(
|
|
319
|
-
} catch (
|
|
340
|
+
await s.provider.track(r, a);
|
|
341
|
+
} catch (l) {
|
|
320
342
|
console.error(
|
|
321
343
|
`[Analytics] Provider ${s.provider.name} failed to track event:`,
|
|
322
|
-
|
|
344
|
+
l
|
|
323
345
|
);
|
|
324
346
|
}
|
|
325
347
|
});
|
|
326
|
-
await Promise.all(
|
|
348
|
+
await Promise.all(o);
|
|
327
349
|
}
|
|
328
350
|
/**
|
|
329
351
|
* Tracks a page view event from the server side.
|
|
@@ -385,14 +407,14 @@ class v {
|
|
|
385
407
|
* }
|
|
386
408
|
* ```
|
|
387
409
|
*/
|
|
388
|
-
pageView(
|
|
410
|
+
pageView(e, t) {
|
|
389
411
|
if (!this.initialized) return;
|
|
390
|
-
const
|
|
412
|
+
const n = {
|
|
391
413
|
...this.config.defaultContext,
|
|
392
|
-
...
|
|
414
|
+
...t == null ? void 0 : t.context
|
|
393
415
|
};
|
|
394
|
-
for (const
|
|
395
|
-
this.shouldCallMethod(
|
|
416
|
+
for (const r of this.providerConfigs)
|
|
417
|
+
this.shouldCallMethod(r, "pageView") && r.provider.pageView(e, n);
|
|
396
418
|
}
|
|
397
419
|
/**
|
|
398
420
|
* Tracks when a user leaves a page from the server side.
|
|
@@ -453,14 +475,14 @@ class v {
|
|
|
453
475
|
* }
|
|
454
476
|
* ```
|
|
455
477
|
*/
|
|
456
|
-
pageLeave(
|
|
478
|
+
pageLeave(e, t) {
|
|
457
479
|
if (!this.initialized) return;
|
|
458
|
-
const
|
|
480
|
+
const n = {
|
|
459
481
|
...this.config.defaultContext,
|
|
460
|
-
...
|
|
482
|
+
...t == null ? void 0 : t.context
|
|
461
483
|
};
|
|
462
|
-
for (const
|
|
463
|
-
this.shouldCallMethod(
|
|
484
|
+
for (const r of this.providerConfigs)
|
|
485
|
+
this.shouldCallMethod(r, "pageLeave") && r.provider.pageLeave && r.provider.pageLeave(e, n);
|
|
464
486
|
}
|
|
465
487
|
/**
|
|
466
488
|
* Shuts down all analytics providers and flushes pending events.
|
|
@@ -547,25 +569,25 @@ class v {
|
|
|
547
569
|
* ```
|
|
548
570
|
*/
|
|
549
571
|
async shutdown() {
|
|
550
|
-
const
|
|
551
|
-
await Promise.all(
|
|
572
|
+
const e = this.providerConfigs.map((t) => "shutdown" in t.provider && typeof t.provider.shutdown == "function" ? t.provider.shutdown() : Promise.resolve());
|
|
573
|
+
await Promise.all(e);
|
|
552
574
|
}
|
|
553
|
-
getCategoryFromEventName(
|
|
554
|
-
const
|
|
555
|
-
return
|
|
575
|
+
getCategoryFromEventName(e) {
|
|
576
|
+
const t = e.split("_");
|
|
577
|
+
return t.length > 1 && t[0] ? t[0] : "engagement";
|
|
556
578
|
}
|
|
557
579
|
}
|
|
558
|
-
function
|
|
559
|
-
const
|
|
560
|
-
providers:
|
|
561
|
-
debug:
|
|
562
|
-
enabled:
|
|
563
|
-
},
|
|
564
|
-
return
|
|
580
|
+
function x(i) {
|
|
581
|
+
const e = {
|
|
582
|
+
providers: i.providers || [],
|
|
583
|
+
debug: i.debug,
|
|
584
|
+
enabled: i.enabled
|
|
585
|
+
}, t = new f(e);
|
|
586
|
+
return t.initialize(), t;
|
|
565
587
|
}
|
|
566
588
|
export {
|
|
567
|
-
|
|
589
|
+
y as BaseAnalyticsProvider,
|
|
568
590
|
w as PostHogServerProvider,
|
|
569
|
-
|
|
570
|
-
|
|
591
|
+
f as ServerAnalytics,
|
|
592
|
+
x as createServerAnalytics
|
|
571
593
|
};
|