@stacksee/analytics 0.11.1 → 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.
@@ -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
  *
@@ -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 { AnalyticsProvider } from './core/events/types.js';
2
+ import { ProviderConfigOrProvider } from './core/events/types.js';
3
3
  import { EventMapFromCollection } from './core/events/index.js';
4
4
  export interface ClientAnalyticsConfig {
5
- providers?: AnalyticsProvider[];
5
+ providers?: ProviderConfigOrProvider[];
6
6
  debug?: boolean;
7
7
  enabled?: boolean;
8
8
  }
package/dist/client.js CHANGED
@@ -1,10 +1,10 @@
1
- var c = Object.defineProperty;
2
- var u = (r, e, i) => e in r ? c(r, e, { enumerable: !0, configurable: !0, writable: !0, value: i }) : r[e] = i;
3
- var n = (r, e, i) => u(r, 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 {
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
- n(this, "providerConfigs", []);
40
- n(this, "context", {});
41
- n(this, "userId");
42
- n(this, "sessionId");
43
- n(this, "userTraits");
44
- n(this, "initialized", !1);
45
- n(this, "initializePromise");
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 i = [
52
+ const t = [
53
53
  "initialize",
54
54
  "identify",
55
55
  "track",
@@ -57,35 +57,55 @@ class p {
57
57
  "pageLeave",
58
58
  "reset"
59
59
  ];
60
- return e.map((t) => {
61
- if ("initialize" in t && "track" in t)
60
+ return e.map((r) => {
61
+ if ("initialize" in r && "track" in r)
62
62
  return {
63
- provider: t,
64
- enabledMethods: new Set(i)
63
+ provider: r,
64
+ enabledMethods: new Set(t)
65
65
  };
66
- const s = t;
67
- s.methods && s.exclude && console.warn(
68
- `[Analytics] Provider ${s.provider.name} has both 'methods' and 'exclude' specified. Using 'methods' and ignoring 'exclude'.`
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 o;
71
- return s.methods ? o = new Set(s.methods) : s.exclude ? o = new Set(
72
- i.filter(
73
- (d) => {
74
- var h;
75
- return !((h = s.exclude) != null && h.includes(d));
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
- ) : o = new Set(i), {
79
- provider: s.provider,
80
- enabledMethods: o
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, i) {
88
- return e.enabledMethods.has(i);
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 (f() && !this.initialized)
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
- (i) => i.provider.initialize()
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, i) {
212
- this.userId = e, this.userTraits = i, this.ensureInitialized().catch((t) => {
213
- console.error("[Analytics] Failed to initialize during identify:", t);
231
+ identify(e, t) {
232
+ this.userId = e, this.userTraits = t, this.ensureInitialized().catch((r) => {
233
+ console.error("[Analytics] Failed to initialize during identify:", r);
214
234
  });
215
- for (const t of this.providerConfigs)
216
- this.shouldCallMethod(t, "identify") && t.provider.identify(e, i);
235
+ for (const r of this.providerConfigs)
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, i) {
313
+ async track(e, t) {
294
314
  await this.ensureInitialized();
295
- const t = {
315
+ const r = {
296
316
  action: e,
297
317
  category: this.getCategoryFromEventName(e),
298
- properties: i,
318
+ properties: t,
299
319
  timestamp: Date.now(),
300
320
  userId: this.userId,
301
321
  sessionId: this.sessionId
302
- }, s = {
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
- }, o = this.providerConfigs.filter((d) => this.shouldCallMethod(d, "track")).map(async (d) => {
329
+ }, d = this.providerConfigs.filter(
330
+ (s) => this.shouldCallMethod(s, "track") && this.shouldTrackEvent(s, e)
331
+ ).map(async (s) => {
310
332
  try {
311
- await d.provider.track(t, s);
333
+ await s.provider.track(r, i);
312
334
  } catch (h) {
313
335
  console.error(
314
- `[Analytics] Provider ${d.provider.name} failed to track event:`,
336
+ `[Analytics] Provider ${s.provider.name} failed to track event:`,
315
337
  h
316
338
  );
317
339
  }
318
340
  });
319
- await Promise.all(o);
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((i) => {
383
- console.error("[Analytics] Failed to initialize during pageView:", i);
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 i of this.providerConfigs)
392
- this.shouldCallMethod(i, "pageView") && i.provider.pageView(e, this.context);
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((i) => {
472
+ this.ensureInitialized().catch((t) => {
451
473
  console.error(
452
474
  "[Analytics] Failed to initialize during pageLeave:",
453
- i
475
+ t
454
476
  );
455
477
  });
456
- for (const i of this.providerConfigs)
457
- this.shouldCallMethod(i, "pageLeave") && i.provider.pageLeave && i.provider.pageLeave(e, this.context);
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.
@@ -549,18 +571,18 @@ class p {
549
571
  * ```
550
572
  */
551
573
  async flush(e = !1) {
552
- const i = this.providerConfigs.map(async (t) => {
553
- if (t.provider.flush && typeof t.provider.flush == "function")
574
+ const t = this.providerConfigs.map(async (r) => {
575
+ if (r.provider.flush && typeof r.provider.flush == "function")
554
576
  try {
555
- await t.provider.flush(e);
556
- } catch (s) {
577
+ await r.provider.flush(e);
578
+ } catch (i) {
557
579
  console.error(
558
- `[Analytics] Provider ${t.provider.name} failed to flush:`,
559
- s
580
+ `[Analytics] Provider ${r.provider.name} failed to flush:`,
581
+ i
560
582
  );
561
583
  }
562
584
  });
563
- await Promise.all(i);
585
+ await Promise.all(t);
564
586
  }
565
587
  /**
566
588
  * Updates the analytics context with new information.
@@ -623,14 +645,14 @@ class p {
623
645
  * ```
624
646
  */
625
647
  updateContext(e) {
626
- var i, t, s;
648
+ var t, r, i;
627
649
  this.context = {
628
650
  ...this.context,
629
651
  ...e,
630
652
  page: e.page ? {
631
- path: e.page.path || ((i = this.context.page) == null ? void 0 : i.path) || window.location.pathname,
632
- title: e.page.title || ((t = this.context.page) == null ? void 0 : t.title),
633
- referrer: e.page.referrer || ((s = this.context.page) == null ? void 0 : s.referrer)
653
+ path: e.page.path || ((t = this.context.page) == null ? void 0 : t.path) || window.location.pathname,
654
+ title: e.page.title || ((r = this.context.page) == null ? void 0 : r.title),
655
+ referrer: e.page.referrer || ((i = this.context.page) == null ? void 0 : i.referrer)
634
656
  } : this.context.page,
635
657
  device: {
636
658
  ...this.context.device,
@@ -643,8 +665,8 @@ class p {
643
665
  };
644
666
  }
645
667
  getCategoryFromEventName(e) {
646
- const i = e.split("_");
647
- return i.length > 1 && i[0] ? i[0] : "engagement";
668
+ const t = e.split("_");
669
+ return t.length > 1 && t[0] ? t[0] : "engagement";
648
670
  }
649
671
  generateSessionId() {
650
672
  return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
@@ -664,51 +686,51 @@ class p {
664
686
  return e.indexOf("Chrome") !== -1 ? "Chrome" : e.indexOf("Safari") !== -1 ? "Safari" : e.indexOf("Firefox") !== -1 ? "Firefox" : e.indexOf("Edge") !== -1 ? "Edge" : "Unknown";
665
687
  }
666
688
  }
667
- let a = null;
668
- function v(r) {
669
- if (a)
670
- return console.warn("[Analytics] Already initialized"), a;
689
+ let o = null;
690
+ function y(n) {
691
+ if (o)
692
+ return console.warn("[Analytics] Already initialized"), o;
671
693
  const e = {
672
- providers: r.providers || [],
673
- debug: r.debug,
674
- enabled: r.enabled
694
+ providers: n.providers || [],
695
+ debug: n.debug,
696
+ enabled: n.enabled
675
697
  };
676
- return a = new p(e), a.initialize().catch((i) => {
677
- console.error("[Analytics] Failed to initialize:", i);
678
- }), a;
698
+ return o = new m(e), o.initialize().catch((t) => {
699
+ console.error("[Analytics] Failed to initialize:", t);
700
+ }), o;
679
701
  }
680
702
  function l() {
681
- if (!a)
703
+ if (!o)
682
704
  throw new Error(
683
705
  "[Analytics] Not initialized. Call createAnalytics() first."
684
706
  );
685
- return a;
707
+ return o;
686
708
  }
687
- function y(r, e) {
688
- return l().track(r, e);
709
+ function P(n, e) {
710
+ return l().track(n, e);
689
711
  }
690
- function w(r, e) {
691
- l().identify(r, e);
712
+ function z(n, e) {
713
+ l().identify(n, e);
692
714
  }
693
- function x(r) {
694
- l().pageView(r);
715
+ function C(n) {
716
+ l().pageView(n);
695
717
  }
696
- function z(r) {
697
- l().pageLeave(r);
718
+ function A(n) {
719
+ l().pageLeave(n);
698
720
  }
699
- function C() {
721
+ function b() {
700
722
  l().reset();
701
723
  }
702
724
  export {
703
- k as BaseAnalyticsProvider,
704
- p as BrowserAnalytics,
705
- P as PostHogClientProvider,
706
- v as createAnalytics,
707
- v as createClientAnalytics,
725
+ O as BaseAnalyticsProvider,
726
+ m as BrowserAnalytics,
727
+ k as PostHogClientProvider,
728
+ y as createAnalytics,
729
+ y as createClientAnalytics,
708
730
  l as getAnalytics,
709
- w as identify,
710
- z as pageLeave,
711
- x as pageView,
712
- C as reset,
713
- y as track
731
+ z as identify,
732
+ A as pageLeave,
733
+ C as pageView,
734
+ b as reset,
735
+ P as track
714
736
  };
@@ -74,8 +74,9 @@ export interface AnalyticsProvider {
74
74
  */
75
75
  export type ProviderMethod = "initialize" | "identify" | "track" | "pageView" | "pageLeave" | "reset";
76
76
  /**
77
- * Configuration for selective provider method routing.
78
- * 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.
79
80
  *
80
81
  * @example
81
82
  * ```typescript
@@ -94,6 +95,33 @@ export type ProviderMethod = "initialize" | "identify" | "track" | "pageView" |
94
95
  * exclude: ['pageView']
95
96
  * }
96
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
+ * ```
97
125
  */
98
126
  export interface ProviderConfig {
99
127
  /**
@@ -112,6 +140,49 @@ export interface ProviderConfig {
112
140
  * Mutually exclusive with `methods`.
113
141
  */
114
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[];
115
186
  }
116
187
  /**
117
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 { AnalyticsProvider } from './core/events/types.js';
2
+ import { ProviderConfigOrProvider } from './core/events/types.js';
3
3
  import { EventMapFromCollection } from './core/events/index.js';
4
4
  export interface ServerAnalyticsConfig {
5
- providers?: AnalyticsProvider[];
5
+ providers?: ProviderConfigOrProvider[];
6
6
  debug?: boolean;
7
7
  enabled?: boolean;
8
8
  }
package/dist/server.js CHANGED
@@ -1,9 +1,9 @@
1
- var h = Object.defineProperty;
2
- var f = (a, r, e) => r in a ? h(a, r, { enumerable: !0, configurable: !0, writable: !0, value: e }) : a[r] = e;
3
- var o = (a, r, e) => f(a, typeof r != "symbol" ? r + "" : r, e);
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 x } from "./base.provider-AfFL5W_P.js";
6
- class v {
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(r) {
38
- o(this, "providerConfigs", []);
39
- o(this, "config");
40
- o(this, "initialized", !1);
41
- this.config = r, this.providerConfigs = this.normalizeProviders(r.providers);
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(r) {
47
- const e = [
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 r.map((i) => {
56
- if ("initialize" in i && "track" in i)
55
+ return e.map((n) => {
56
+ if ("initialize" in n && "track" in n)
57
57
  return {
58
- provider: i,
59
- enabledMethods: new Set(e)
58
+ provider: n,
59
+ enabledMethods: new Set(t)
60
60
  };
61
- const t = i;
62
- t.methods && t.exclude && console.warn(
63
- `[Analytics] Provider ${t.provider.name} has both 'methods' and 'exclude' specified. Using 'methods' and ignoring 'exclude'.`
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 n;
66
- return t.methods ? n = new Set(t.methods) : t.exclude ? n = new Set(
67
- e.filter(
71
+ let a;
72
+ r.methods ? a = new Set(r.methods) : r.exclude ? a = new Set(
73
+ t.filter(
68
74
  (l) => {
69
- var d;
70
- return !((d = t.exclude) != null && d.includes(l));
75
+ var v;
76
+ return !((v = r.exclude) != null && v.includes(l));
71
77
  }
72
78
  )
73
- ) : n = new Set(e), {
74
- provider: t.provider,
75
- enabledMethods: n
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(r, e) {
83
- return r.enabledMethods.has(e);
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 r of this.providerConfigs)
124
- r.provider.initialize();
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(r, e) {
175
- for (const i of this.providerConfigs)
176
- this.shouldCallMethod(i, "identify") && i.provider.identify(r, e);
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(r, e, i) {
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 t = {
306
- action: r,
307
- category: this.getCategoryFromEventName(r),
308
- properties: e,
325
+ const r = {
326
+ action: e,
327
+ category: this.getCategoryFromEventName(e),
328
+ properties: t,
309
329
  timestamp: Date.now(),
310
- userId: i == null ? void 0 : i.userId,
311
- sessionId: i == null ? void 0 : i.sessionId
312
- }, n = {
330
+ userId: n == null ? void 0 : n.userId,
331
+ sessionId: n == null ? void 0 : n.sessionId
332
+ }, a = {
313
333
  ...this.config.defaultContext,
314
- ...i == null ? void 0 : i.context,
315
- user: (i == null ? void 0 : i.user) || ((d = i == null ? void 0 : i.context) == null ? void 0 : d.user)
316
- }, l = this.providerConfigs.filter((s) => this.shouldCallMethod(s, "track")).map(async (s) => {
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(t, n);
319
- } catch (c) {
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
- c
344
+ l
323
345
  );
324
346
  }
325
347
  });
326
- await Promise.all(l);
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(r, e) {
410
+ pageView(e, t) {
389
411
  if (!this.initialized) return;
390
- const i = {
412
+ const n = {
391
413
  ...this.config.defaultContext,
392
- ...e == null ? void 0 : e.context
414
+ ...t == null ? void 0 : t.context
393
415
  };
394
- for (const t of this.providerConfigs)
395
- this.shouldCallMethod(t, "pageView") && t.provider.pageView(r, i);
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(r, e) {
478
+ pageLeave(e, t) {
457
479
  if (!this.initialized) return;
458
- const i = {
480
+ const n = {
459
481
  ...this.config.defaultContext,
460
- ...e == null ? void 0 : e.context
482
+ ...t == null ? void 0 : t.context
461
483
  };
462
- for (const t of this.providerConfigs)
463
- this.shouldCallMethod(t, "pageLeave") && t.provider.pageLeave && t.provider.pageLeave(r, i);
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 r = this.providerConfigs.map((e) => "shutdown" in e.provider && typeof e.provider.shutdown == "function" ? e.provider.shutdown() : Promise.resolve());
551
- await Promise.all(r);
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(r) {
554
- const e = r.split("_");
555
- return e.length > 1 && e[0] ? e[0] : "engagement";
575
+ getCategoryFromEventName(e) {
576
+ const t = e.split("_");
577
+ return t.length > 1 && t[0] ? t[0] : "engagement";
556
578
  }
557
579
  }
558
- function g(a) {
559
- const r = {
560
- providers: a.providers || [],
561
- debug: a.debug,
562
- enabled: a.enabled
563
- }, e = new v(r);
564
- return e.initialize(), e;
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
- x as BaseAnalyticsProvider,
589
+ y as BaseAnalyticsProvider,
568
590
  w as PostHogServerProvider,
569
- v as ServerAnalytics,
570
- g as createServerAnalytics
591
+ f as ServerAnalytics,
592
+ x as createServerAnalytics
571
593
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stacksee/analytics",
3
- "version": "0.11.1",
3
+ "version": "0.12.0",
4
4
  "description": "A highly typed, provider-agnostic analytics library for TypeScript applications",
5
5
  "type": "module",
6
6
  "exports": {