@stacksee/analytics 0.11.0 → 0.11.1

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.
@@ -394,6 +394,42 @@ export declare class BrowserAnalytics<TEventMap extends DefaultEventMap = Defaul
394
394
  * ```
395
395
  */
396
396
  reset(): void;
397
+ /**
398
+ * Manually flush all queued events to providers.
399
+ *
400
+ * This method is useful when you need to ensure events are sent immediately,
401
+ * such as before navigation or critical user actions. Providers that support
402
+ * batching (like ProxyProvider) will flush their queues when this is called.
403
+ *
404
+ * If `useBeacon` is true, providers that support it will use the Beacon API
405
+ * for more reliable delivery during page unload.
406
+ *
407
+ * @param useBeacon Whether to use the Beacon API for flushing (default: false)
408
+ * @returns Promise that resolves when all providers have flushed
409
+ *
410
+ * @example
411
+ * ```typescript
412
+ * // Flush before navigation
413
+ * analytics.track('button_clicked', { buttonId: 'checkout' });
414
+ * await analytics.flush();
415
+ * window.location.href = '/checkout';
416
+ * ```
417
+ *
418
+ * @example
419
+ * ```typescript
420
+ * // Flush with beacon API before page unload
421
+ * await analytics.flush(true);
422
+ * ```
423
+ *
424
+ * @example
425
+ * ```typescript
426
+ * // Ensure critical events are sent immediately
427
+ * await analytics.track('purchase_completed', { orderId: '123' });
428
+ * await analytics.flush(); // Wait for confirmation
429
+ * showThankYouPage();
430
+ * ```
431
+ */
432
+ flush(useBeacon?: boolean): Promise<void>;
397
433
  /**
398
434
  * Updates the analytics context with new information.
399
435
  *
package/dist/client.d.ts CHANGED
@@ -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,6 +1,6 @@
1
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);
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
4
  import { i as f } from "./client-DTHZYkxx.js";
5
5
  import { P } from "./client-DTHZYkxx.js";
6
6
  import { B as k } from "./base.provider-AfFL5W_P.js";
@@ -36,13 +36,13 @@ class p {
36
36
  * ```
37
37
  */
38
38
  constructor(e) {
39
- s(this, "providerConfigs", []);
40
- s(this, "context", {});
41
- s(this, "userId");
42
- s(this, "sessionId");
43
- s(this, "userTraits");
44
- s(this, "initialized", !1);
45
- s(this, "initializePromise");
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");
46
46
  this.providerConfigs = this.normalizeProviders(e.providers), e.defaultContext && (this.context = { ...e.defaultContext }), this.sessionId = this.generateSessionId();
47
47
  }
48
48
  /**
@@ -57,26 +57,26 @@ class p {
57
57
  "pageLeave",
58
58
  "reset"
59
59
  ];
60
- return e.map((r) => {
61
- if ("initialize" in r && "track" in r)
60
+ return e.map((t) => {
61
+ if ("initialize" in t && "track" in t)
62
62
  return {
63
- provider: r,
63
+ provider: t,
64
64
  enabledMethods: new Set(i)
65
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'.`
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'.`
69
69
  );
70
70
  let o;
71
- return n.methods ? o = new Set(n.methods) : n.exclude ? o = new Set(
71
+ return s.methods ? o = new Set(s.methods) : s.exclude ? o = new Set(
72
72
  i.filter(
73
73
  (d) => {
74
74
  var h;
75
- return !((h = n.exclude) != null && h.includes(d));
75
+ return !((h = s.exclude) != null && h.includes(d));
76
76
  }
77
77
  )
78
78
  ) : o = new Set(i), {
79
- provider: n.provider,
79
+ provider: s.provider,
80
80
  enabledMethods: o
81
81
  };
82
82
  });
@@ -209,11 +209,11 @@ class p {
209
209
  * ```
210
210
  */
211
211
  identify(e, i) {
212
- this.userId = e, this.userTraits = i, this.ensureInitialized().catch((r) => {
213
- console.error("[Analytics] Failed to initialize during identify:", r);
212
+ this.userId = e, this.userTraits = i, this.ensureInitialized().catch((t) => {
213
+ console.error("[Analytics] Failed to initialize during identify:", t);
214
214
  });
215
- for (const r of this.providerConfigs)
216
- this.shouldCallMethod(r, "identify") && r.provider.identify(e, i);
215
+ for (const t of this.providerConfigs)
216
+ this.shouldCallMethod(t, "identify") && t.provider.identify(e, i);
217
217
  }
218
218
  /**
219
219
  * Tracks a custom event with properties.
@@ -292,14 +292,14 @@ class p {
292
292
  */
293
293
  async track(e, i) {
294
294
  await this.ensureInitialized();
295
- const r = {
295
+ const t = {
296
296
  action: e,
297
297
  category: this.getCategoryFromEventName(e),
298
298
  properties: i,
299
299
  timestamp: Date.now(),
300
300
  userId: this.userId,
301
301
  sessionId: this.sessionId
302
- }, n = {
302
+ }, s = {
303
303
  ...this.context,
304
304
  user: this.userId || this.userTraits ? {
305
305
  userId: this.userId,
@@ -308,7 +308,7 @@ class p {
308
308
  } : void 0
309
309
  }, o = this.providerConfigs.filter((d) => this.shouldCallMethod(d, "track")).map(async (d) => {
310
310
  try {
311
- await d.provider.track(r, n);
311
+ await d.provider.track(t, s);
312
312
  } catch (h) {
313
313
  console.error(
314
314
  `[Analytics] Provider ${d.provider.name} failed to track event:`,
@@ -513,6 +513,55 @@ class p {
513
513
  for (const e of this.providerConfigs)
514
514
  this.shouldCallMethod(e, "reset") && e.provider.reset();
515
515
  }
516
+ /**
517
+ * Manually flush all queued events to providers.
518
+ *
519
+ * This method is useful when you need to ensure events are sent immediately,
520
+ * such as before navigation or critical user actions. Providers that support
521
+ * batching (like ProxyProvider) will flush their queues when this is called.
522
+ *
523
+ * If `useBeacon` is true, providers that support it will use the Beacon API
524
+ * for more reliable delivery during page unload.
525
+ *
526
+ * @param useBeacon Whether to use the Beacon API for flushing (default: false)
527
+ * @returns Promise that resolves when all providers have flushed
528
+ *
529
+ * @example
530
+ * ```typescript
531
+ * // Flush before navigation
532
+ * analytics.track('button_clicked', { buttonId: 'checkout' });
533
+ * await analytics.flush();
534
+ * window.location.href = '/checkout';
535
+ * ```
536
+ *
537
+ * @example
538
+ * ```typescript
539
+ * // Flush with beacon API before page unload
540
+ * await analytics.flush(true);
541
+ * ```
542
+ *
543
+ * @example
544
+ * ```typescript
545
+ * // Ensure critical events are sent immediately
546
+ * await analytics.track('purchase_completed', { orderId: '123' });
547
+ * await analytics.flush(); // Wait for confirmation
548
+ * showThankYouPage();
549
+ * ```
550
+ */
551
+ async flush(e = !1) {
552
+ const i = this.providerConfigs.map(async (t) => {
553
+ if (t.provider.flush && typeof t.provider.flush == "function")
554
+ try {
555
+ await t.provider.flush(e);
556
+ } catch (s) {
557
+ console.error(
558
+ `[Analytics] Provider ${t.provider.name} failed to flush:`,
559
+ s
560
+ );
561
+ }
562
+ });
563
+ await Promise.all(i);
564
+ }
516
565
  /**
517
566
  * Updates the analytics context with new information.
518
567
  *
@@ -574,14 +623,14 @@ class p {
574
623
  * ```
575
624
  */
576
625
  updateContext(e) {
577
- var i, r, n;
626
+ var i, t, s;
578
627
  this.context = {
579
628
  ...this.context,
580
629
  ...e,
581
630
  page: e.page ? {
582
631
  path: e.page.path || ((i = this.context.page) == null ? void 0 : i.path) || window.location.pathname,
583
- title: e.page.title || ((r = this.context.page) == null ? void 0 : r.title),
584
- referrer: e.page.referrer || ((n = this.context.page) == null ? void 0 : n.referrer)
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)
585
634
  } : this.context.page,
586
635
  device: {
587
636
  ...this.context.device,
@@ -616,13 +665,13 @@ class p {
616
665
  }
617
666
  }
618
667
  let a = null;
619
- function v(t) {
668
+ function v(r) {
620
669
  if (a)
621
670
  return console.warn("[Analytics] Already initialized"), a;
622
671
  const e = {
623
- providers: t.providers || [],
624
- debug: t.debug,
625
- enabled: t.enabled
672
+ providers: r.providers || [],
673
+ debug: r.debug,
674
+ enabled: r.enabled
626
675
  };
627
676
  return a = new p(e), a.initialize().catch((i) => {
628
677
  console.error("[Analytics] Failed to initialize:", i);
@@ -635,17 +684,17 @@ function l() {
635
684
  );
636
685
  return a;
637
686
  }
638
- function w(t, e) {
639
- return l().track(t, e);
687
+ function y(r, e) {
688
+ return l().track(r, e);
640
689
  }
641
- function y(t, e) {
642
- l().identify(t, e);
690
+ function w(r, e) {
691
+ l().identify(r, e);
643
692
  }
644
- function x(t) {
645
- l().pageView(t);
693
+ function x(r) {
694
+ l().pageView(r);
646
695
  }
647
- function z(t) {
648
- l().pageLeave(t);
696
+ function z(r) {
697
+ l().pageLeave(r);
649
698
  }
650
699
  function C() {
651
700
  l().reset();
@@ -657,9 +706,9 @@ export {
657
706
  v as createAnalytics,
658
707
  v as createClientAnalytics,
659
708
  l as getAnalytics,
660
- y as identify,
709
+ w as identify,
661
710
  z as pageLeave,
662
711
  x as pageView,
663
712
  C as reset,
664
- w as track
713
+ y as track
665
714
  };
@@ -67,6 +67,7 @@ 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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stacksee/analytics",
3
- "version": "0.11.0",
3
+ "version": "0.11.1",
4
4
  "description": "A highly typed, provider-agnostic analytics library for TypeScript applications",
5
5
  "type": "module",
6
6
  "exports": {