@thisbefine/analytics 0.1.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.
Files changed (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +403 -0
  3. package/dist/core/analytics.d.ts +123 -0
  4. package/dist/core/analytics.d.ts.map +1 -0
  5. package/dist/core/analytics.js +334 -0
  6. package/dist/core/analytics.js.map +1 -0
  7. package/dist/core/errors.d.ts +94 -0
  8. package/dist/core/errors.d.ts.map +1 -0
  9. package/dist/core/errors.js +420 -0
  10. package/dist/core/errors.js.map +1 -0
  11. package/dist/core/logger.d.ts +28 -0
  12. package/dist/core/logger.d.ts.map +1 -0
  13. package/dist/core/logger.js +36 -0
  14. package/dist/core/logger.js.map +1 -0
  15. package/dist/core/logging.d.ts +12 -0
  16. package/dist/core/logging.d.ts.map +1 -0
  17. package/dist/core/logging.js +33 -0
  18. package/dist/core/logging.js.map +1 -0
  19. package/dist/core/privacy.d.ts +53 -0
  20. package/dist/core/privacy.d.ts.map +1 -0
  21. package/dist/core/privacy.js +94 -0
  22. package/dist/core/privacy.js.map +1 -0
  23. package/dist/core/queue.d.ts +59 -0
  24. package/dist/core/queue.d.ts.map +1 -0
  25. package/dist/core/queue.js +263 -0
  26. package/dist/core/queue.js.map +1 -0
  27. package/dist/core/session.d.ts +90 -0
  28. package/dist/core/session.d.ts.map +1 -0
  29. package/dist/core/session.js +246 -0
  30. package/dist/core/session.js.map +1 -0
  31. package/dist/core/storage.d.ts +64 -0
  32. package/dist/core/storage.d.ts.map +1 -0
  33. package/dist/core/storage.js +242 -0
  34. package/dist/core/storage.js.map +1 -0
  35. package/dist/core/types.d.ts +298 -0
  36. package/dist/core/types.d.ts.map +1 -0
  37. package/dist/core/types.js +34 -0
  38. package/dist/core/types.js.map +1 -0
  39. package/dist/core/validation.d.ts +11 -0
  40. package/dist/core/validation.d.ts.map +1 -0
  41. package/dist/core/validation.js +82 -0
  42. package/dist/core/validation.js.map +1 -0
  43. package/dist/core/version.d.ts +2 -0
  44. package/dist/core/version.d.ts.map +1 -0
  45. package/dist/core/version.js +4 -0
  46. package/dist/core/version.js.map +1 -0
  47. package/dist/index.d.ts +45 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +41 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/next/analytics.d.ts +59 -0
  52. package/dist/next/analytics.d.ts.map +1 -0
  53. package/dist/next/analytics.js +87 -0
  54. package/dist/next/analytics.js.map +1 -0
  55. package/dist/next.d.ts +46 -0
  56. package/dist/next.d.ts.map +1 -0
  57. package/dist/next.js +44 -0
  58. package/dist/next.js.map +1 -0
  59. package/dist/react/analytics.d.ts +51 -0
  60. package/dist/react/analytics.d.ts.map +1 -0
  61. package/dist/react/analytics.js +63 -0
  62. package/dist/react/analytics.js.map +1 -0
  63. package/dist/react/bug-report-widget.d.ts +21 -0
  64. package/dist/react/bug-report-widget.d.ts.map +1 -0
  65. package/dist/react/bug-report-widget.js +34 -0
  66. package/dist/react/bug-report-widget.js.map +1 -0
  67. package/dist/react/hooks.d.ts +141 -0
  68. package/dist/react/hooks.d.ts.map +1 -0
  69. package/dist/react/hooks.js +186 -0
  70. package/dist/react/hooks.js.map +1 -0
  71. package/dist/react.d.ts +42 -0
  72. package/dist/react.d.ts.map +1 -0
  73. package/dist/react.js +39 -0
  74. package/dist/react.js.map +1 -0
  75. package/dist/widget/bug-report.d.ts +16 -0
  76. package/dist/widget/bug-report.d.ts.map +1 -0
  77. package/dist/widget/bug-report.js +416 -0
  78. package/dist/widget/bug-report.js.map +1 -0
  79. package/package.json +107 -0
@@ -0,0 +1,87 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { usePathname, useSearchParams } from "next/navigation";
4
+ import { Suspense, useEffect, useRef } from "react";
5
+ import { getAnalytics, initAnalytics } from "../core/analytics";
6
+ /**
7
+ * Internal component that tracks page views using Next.js navigation hooks
8
+ */
9
+ const PageTracker = () => {
10
+ const pathname = usePathname();
11
+ const searchParams = useSearchParams();
12
+ const previousPath = useRef(null);
13
+ const hasTrackedInitial = useRef(false);
14
+ useEffect(() => {
15
+ const analytics = getAnalytics();
16
+ if (!analytics)
17
+ return;
18
+ const search = searchParams?.toString();
19
+ const fullPath = search ? `${pathname}?${search}` : pathname;
20
+ if (previousPath.current === fullPath && hasTrackedInitial.current) {
21
+ return;
22
+ }
23
+ analytics.page(pathname ?? undefined, {
24
+ path: pathname,
25
+ search: search || undefined,
26
+ url: typeof window !== "undefined" ? window.location.href : undefined,
27
+ });
28
+ previousPath.current = fullPath;
29
+ hasTrackedInitial.current = true;
30
+ }, [pathname, searchParams]);
31
+ return null;
32
+ };
33
+ /**
34
+ * Next.js Analytics component - initializes Thisbefine analytics
35
+ *
36
+ * Optimized for the Next.js App Router with automatic pageview tracking
37
+ * on client-side navigations using usePathname/useSearchParams.
38
+ *
39
+ * Add this component once at the root of your app (e.g., in layout.tsx).
40
+ *
41
+ * @example
42
+ * ```tsx
43
+ * // app/layout.tsx
44
+ * // Zero config - reads from NEXT_PUBLIC_TBF_API_KEY
45
+ * import { Analytics } from '@thisbefine/analytics/next';
46
+ *
47
+ * export default function RootLayout({ children }) {
48
+ * return (
49
+ * <html>
50
+ * <body>
51
+ * {children}
52
+ * <Analytics />
53
+ * </body>
54
+ * </html>
55
+ * );
56
+ * }
57
+ *
58
+ * // With explicit config
59
+ * <Analytics apiKey="tbf_xxx" host="http://localhost:3000" debug />
60
+ * ```
61
+ */
62
+ export const Analytics = ({ apiKey, host, debug = false, trackPageviews = true, config, }) => {
63
+ const initialized = useRef(false);
64
+ useEffect(() => {
65
+ if (initialized.current)
66
+ return;
67
+ if (typeof window === "undefined")
68
+ return;
69
+ const resolvedApiKey = apiKey ?? process.env.NEXT_PUBLIC_TBF_API_KEY ?? "";
70
+ if (!resolvedApiKey) {
71
+ console.warn("[Thisbefine] No API key provided. Set NEXT_PUBLIC_TBF_API_KEY or pass apiKey prop.");
72
+ return;
73
+ }
74
+ initAnalytics({
75
+ apiKey: resolvedApiKey,
76
+ host,
77
+ debug,
78
+ ...config,
79
+ });
80
+ initialized.current = true;
81
+ }, [apiKey, host, debug, config]);
82
+ if (!trackPageviews) {
83
+ return null;
84
+ }
85
+ return (_jsx(Suspense, { fallback: null, children: _jsx(PageTracker, {}) }));
86
+ };
87
+ //# sourceMappingURL=analytics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../src/next/analytics.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAmChE;;GAEG;AACH,MAAM,WAAW,GAAG,GAAG,EAAE;IACxB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IACvC,MAAM,YAAY,GAAG,MAAM,CAAgB,IAAI,CAAC,CAAC;IACjD,MAAM,iBAAiB,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAExC,SAAS,CAAC,GAAG,EAAE;QACd,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;QACjC,IAAI,CAAC,SAAS;YAAE,OAAO;QAEvB,MAAM,MAAM,GAAG,YAAY,EAAE,QAAQ,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;QAE7D,IAAI,YAAY,CAAC,OAAO,KAAK,QAAQ,IAAI,iBAAiB,CAAC,OAAO,EAAE,CAAC;YACpE,OAAO;QACR,CAAC;QAED,SAAS,CAAC,IAAI,CAAC,QAAQ,IAAI,SAAS,EAAE;YACrC,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,MAAM,IAAI,SAAS;YAC3B,GAAG,EAAE,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;SACrE,CAAC,CAAC;QAEH,YAAY,CAAC,OAAO,GAAG,QAAQ,CAAC;QAChC,iBAAiB,CAAC,OAAO,GAAG,IAAI,CAAC;IAClC,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC;IAE7B,OAAO,IAAI,CAAC;AACb,CAAC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,EACzB,MAAM,EACN,IAAI,EACJ,KAAK,GAAG,KAAK,EACb,cAAc,GAAG,IAAI,EACrB,MAAM,GACc,EAAE,EAAE;IACxB,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAElC,SAAS,CAAC,GAAG,EAAE;QACd,IAAI,WAAW,CAAC,OAAO;YAAE,OAAO;QAChC,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,OAAO;QAE1C,MAAM,cAAc,GAAG,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,EAAE,CAAC;QAE3E,IAAI,CAAC,cAAc,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,CACX,oFAAoF,CACpF,CAAC;YACF,OAAO;QACR,CAAC;QAED,aAAa,CAAC;YACb,MAAM,EAAE,cAAc;YACtB,IAAI;YACJ,KAAK;YACL,GAAG,MAAM;SACT,CAAC,CAAC;QAEH,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC;IAC5B,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAElC,IAAI,CAAC,cAAc,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,OAAO,CACN,KAAC,QAAQ,IAAC,QAAQ,EAAE,IAAI,YACvB,KAAC,WAAW,KAAG,GACL,CACX,CAAC;AACH,CAAC,CAAC"}
package/dist/next.d.ts ADDED
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @thisbefine/analytics/next
3
+ *
4
+ * Next.js integration for Thisbefine Analytics.
5
+ *
6
+ * Optimized for the App Router with automatic pageview tracking
7
+ * on client-side navigations using usePathname/useSearchParams.
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * // app/layout.tsx
12
+ * import { Analytics } from '@thisbefine/analytics/next';
13
+ *
14
+ * export default function RootLayout({ children }) {
15
+ * return (
16
+ * <html lang="en">
17
+ * <body>
18
+ * {children}
19
+ * <Analytics />
20
+ * </body>
21
+ * </html>
22
+ * );
23
+ * }
24
+ *
25
+ * // components/signup-button.tsx
26
+ * 'use client';
27
+ * import { useTrack } from '@thisbefine/analytics/next';
28
+ *
29
+ * export function SignupButton() {
30
+ * const trackSignup = useTrack('signup_clicked');
31
+ *
32
+ * return (
33
+ * <button onClick={() => trackSignup({ location: 'header' })}>
34
+ * Sign Up
35
+ * </button>
36
+ * );
37
+ * }
38
+ * ```
39
+ *
40
+ * @packageDocumentation
41
+ */
42
+ export type { AccountTraits, Analytics as AnalyticsInstance, AnalyticsConfig, UserState, UserTraits, } from "./core/types";
43
+ export type { NextAnalyticsProps } from "./next/analytics";
44
+ export { Analytics } from "./next/analytics";
45
+ export { useAnalytics, useCaptureException, useGetUser, useGroup, useIdentify, useLog, usePage, useReset, useTrack, } from "./react/hooks";
46
+ //# sourceMappingURL=next.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next.d.ts","sourceRoot":"","sources":["../src/next.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,YAAY,EACX,aAAa,EACb,SAAS,IAAI,iBAAiB,EAC9B,eAAe,EACf,SAAS,EACT,UAAU,GACV,MAAM,cAAc,CAAC;AAEtB,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EACN,YAAY,EACZ,mBAAmB,EACnB,UAAU,EACV,QAAQ,EACR,WAAW,EACX,MAAM,EACN,OAAO,EACP,QAAQ,EACR,QAAQ,GACR,MAAM,eAAe,CAAC"}
package/dist/next.js ADDED
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @thisbefine/analytics/next
3
+ *
4
+ * Next.js integration for Thisbefine Analytics.
5
+ *
6
+ * Optimized for the App Router with automatic pageview tracking
7
+ * on client-side navigations using usePathname/useSearchParams.
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * // app/layout.tsx
12
+ * import { Analytics } from '@thisbefine/analytics/next';
13
+ *
14
+ * export default function RootLayout({ children }) {
15
+ * return (
16
+ * <html lang="en">
17
+ * <body>
18
+ * {children}
19
+ * <Analytics />
20
+ * </body>
21
+ * </html>
22
+ * );
23
+ * }
24
+ *
25
+ * // components/signup-button.tsx
26
+ * 'use client';
27
+ * import { useTrack } from '@thisbefine/analytics/next';
28
+ *
29
+ * export function SignupButton() {
30
+ * const trackSignup = useTrack('signup_clicked');
31
+ *
32
+ * return (
33
+ * <button onClick={() => trackSignup({ location: 'header' })}>
34
+ * Sign Up
35
+ * </button>
36
+ * );
37
+ * }
38
+ * ```
39
+ *
40
+ * @packageDocumentation
41
+ */
42
+ export { Analytics } from "./next/analytics";
43
+ export { useAnalytics, useCaptureException, useGetUser, useGroup, useIdentify, useLog, usePage, useReset, useTrack, } from "./react/hooks";
44
+ //# sourceMappingURL=next.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next.js","sourceRoot":"","sources":["../src/next.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAWH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EACN,YAAY,EACZ,mBAAmB,EACnB,UAAU,EACV,QAAQ,EACR,WAAW,EACX,MAAM,EACN,OAAO,EACP,QAAQ,EACR,QAAQ,GACR,MAAM,eAAe,CAAC"}
@@ -0,0 +1,51 @@
1
+ import type { AnalyticsConfig } from "../core/types";
2
+ export interface AnalyticsProps {
3
+ /**
4
+ * Your Thisbefine API key.
5
+ * If not provided, reads from NEXT_PUBLIC_TBF_API_KEY environment variable.
6
+ */
7
+ apiKey?: string;
8
+ /**
9
+ * API host URL.
10
+ * Defaults to https://thisbefine.com
11
+ * For local development, use http://localhost:3000
12
+ */
13
+ host?: string;
14
+ /**
15
+ * Enable debug logging to console.
16
+ * @default false
17
+ */
18
+ debug?: boolean;
19
+ /**
20
+ * Automatically track page views.
21
+ * @default true
22
+ */
23
+ trackPageviews?: boolean;
24
+ /**
25
+ * Additional configuration options
26
+ */
27
+ config?: Omit<AnalyticsConfig, "apiKey" | "host" | "debug">;
28
+ }
29
+ /**
30
+ * Analytics component - initializes Thisbefine analytics
31
+ *
32
+ * Add this component once at the root of your app (e.g., in layout.tsx).
33
+ * It will automatically initialize analytics and track page views.
34
+ *
35
+ * @example
36
+ * ```tsx
37
+ * // Zero config - reads from NEXT_PUBLIC_TBF_API_KEY
38
+ * <Analytics />
39
+ *
40
+ * // With explicit API key
41
+ * <Analytics apiKey="tbf_xxx" />
42
+ *
43
+ * // For local development
44
+ * <Analytics apiKey="tbf_xxx" host="http://localhost:3000" />
45
+ *
46
+ * // With debug mode
47
+ * <Analytics debug />
48
+ * ```
49
+ */
50
+ export declare const Analytics: ({ apiKey, host, debug, trackPageviews, config, }: AnalyticsProps) => null;
51
+ //# sourceMappingURL=analytics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../src/react/analytics.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,MAAM,WAAW,cAAc;IAC9B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;OAEG;IACH,MAAM,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CAC5D;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,SAAS,GAAI,kDAMvB,cAAc,SA6ChB,CAAC"}
@@ -0,0 +1,63 @@
1
+ "use client";
2
+ import { useEffect, useRef } from "react";
3
+ import { initAnalytics } from "../core/analytics";
4
+ /**
5
+ * Analytics component - initializes Thisbefine analytics
6
+ *
7
+ * Add this component once at the root of your app (e.g., in layout.tsx).
8
+ * It will automatically initialize analytics and track page views.
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * // Zero config - reads from NEXT_PUBLIC_TBF_API_KEY
13
+ * <Analytics />
14
+ *
15
+ * // With explicit API key
16
+ * <Analytics apiKey="tbf_xxx" />
17
+ *
18
+ * // For local development
19
+ * <Analytics apiKey="tbf_xxx" host="http://localhost:3000" />
20
+ *
21
+ * // With debug mode
22
+ * <Analytics debug />
23
+ * ```
24
+ */
25
+ export const Analytics = ({ apiKey, host, debug = false, trackPageviews = true, config, }) => {
26
+ const initialized = useRef(false);
27
+ useEffect(() => {
28
+ if (initialized.current)
29
+ return;
30
+ if (typeof window === "undefined")
31
+ return;
32
+ const resolvedApiKey = apiKey ?? process.env.NEXT_PUBLIC_TBF_API_KEY ?? "";
33
+ if (!resolvedApiKey) {
34
+ console.warn("[Thisbefine] No API key provided. Set NEXT_PUBLIC_TBF_API_KEY or pass apiKey prop.");
35
+ return;
36
+ }
37
+ const analytics = initAnalytics({
38
+ apiKey: resolvedApiKey,
39
+ host,
40
+ debug,
41
+ ...config,
42
+ });
43
+ initialized.current = true;
44
+ if (trackPageviews) {
45
+ analytics.page();
46
+ }
47
+ }, [apiKey, host, debug, trackPageviews, config]);
48
+ useEffect(() => {
49
+ if (!trackPageviews)
50
+ return;
51
+ if (typeof window === "undefined")
52
+ return;
53
+ const handlePopState = () => {
54
+ import("../core/analytics").then(({ getAnalytics }) => {
55
+ getAnalytics()?.page();
56
+ });
57
+ };
58
+ window.addEventListener("popstate", handlePopState);
59
+ return () => window.removeEventListener("popstate", handlePopState);
60
+ }, [trackPageviews]);
61
+ return null;
62
+ };
63
+ //# sourceMappingURL=analytics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../src/react/analytics.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAmClD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,EACzB,MAAM,EACN,IAAI,EACJ,KAAK,GAAG,KAAK,EACb,cAAc,GAAG,IAAI,EACrB,MAAM,GACU,EAAE,EAAE;IACpB,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAElC,SAAS,CAAC,GAAG,EAAE;QACd,IAAI,WAAW,CAAC,OAAO;YAAE,OAAO;QAChC,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,OAAO;QAE1C,MAAM,cAAc,GAAG,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,EAAE,CAAC;QAE3E,IAAI,CAAC,cAAc,EAAE,CAAC;YACrB,OAAO,CAAC,IAAI,CACX,oFAAoF,CACpF,CAAC;YACF,OAAO;QACR,CAAC;QAED,MAAM,SAAS,GAAG,aAAa,CAAC;YAC/B,MAAM,EAAE,cAAc;YACtB,IAAI;YACJ,KAAK;YACL,GAAG,MAAM;SACT,CAAC,CAAC;QAEH,WAAW,CAAC,OAAO,GAAG,IAAI,CAAC;QAE3B,IAAI,cAAc,EAAE,CAAC;YACpB,SAAS,CAAC,IAAI,EAAE,CAAC;QAClB,CAAC;IACF,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;IAElD,SAAS,CAAC,GAAG,EAAE;QACd,IAAI,CAAC,cAAc;YAAE,OAAO;QAC5B,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,OAAO;QAE1C,MAAM,cAAc,GAAG,GAAG,EAAE;YAC3B,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE;gBACrD,YAAY,EAAE,EAAE,IAAI,EAAE,CAAC;YACxB,CAAC,CAAC,CAAC;QACJ,CAAC,CAAC;QAEF,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QACpD,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IACrE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;IAErB,OAAO,IAAI,CAAC;AACb,CAAC,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { BugReportWidgetOptions } from "../widget/bug-report";
2
+ export interface BugReportFABProps extends BugReportWidgetOptions {
3
+ }
4
+ /**
5
+ * React component that mounts the bug report FAB widget.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import { BugReportFAB } from '@thisbefine/analytics/react';
10
+ *
11
+ * const App = () => (
12
+ * <>
13
+ * <Analytics apiKey="tbf_xxx" />
14
+ * <MyApp />
15
+ * <BugReportFAB position="bottom-right" />
16
+ * </>
17
+ * );
18
+ * ```
19
+ */
20
+ export declare const BugReportFAB: (props: BugReportFABProps) => null;
21
+ //# sourceMappingURL=bug-report-widget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bug-report-widget.d.ts","sourceRoot":"","sources":["../../src/react/bug-report-widget.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAInE,MAAM,WAAW,iBAAkB,SAAQ,sBAAsB;CAAG;AAEpE;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,iBAAiB,SAepD,CAAC"}
@@ -0,0 +1,34 @@
1
+ "use client";
2
+ import { useEffect, useRef } from "react";
3
+ import { createBugReportWidget } from "../widget/bug-report";
4
+ import { useAnalytics } from "./hooks";
5
+ /**
6
+ * React component that mounts the bug report FAB widget.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * import { BugReportFAB } from '@thisbefine/analytics/react';
11
+ *
12
+ * const App = () => (
13
+ * <>
14
+ * <Analytics apiKey="tbf_xxx" />
15
+ * <MyApp />
16
+ * <BugReportFAB position="bottom-right" />
17
+ * </>
18
+ * );
19
+ * ```
20
+ */
21
+ export const BugReportFAB = (props) => {
22
+ const analytics = useAnalytics();
23
+ const destroyRef = useRef(null);
24
+ useEffect(() => {
25
+ const widget = createBugReportWidget(analytics, props);
26
+ destroyRef.current = widget.destroy;
27
+ return () => {
28
+ widget.destroy();
29
+ destroyRef.current = null;
30
+ };
31
+ }, [analytics, props.position, props.buttonColor, props.buttonText, props]);
32
+ return null;
33
+ };
34
+ //# sourceMappingURL=bug-report-widget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bug-report-widget.js","sourceRoot":"","sources":["../../src/react/bug-report-widget.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAIvC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAwB,EAAE,EAAE;IACxD,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;IACjC,MAAM,UAAU,GAAG,MAAM,CAAsB,IAAI,CAAC,CAAC;IAErD,SAAS,CAAC,GAAG,EAAE;QACd,MAAM,MAAM,GAAG,qBAAqB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QACvD,UAAU,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAEpC,OAAO,GAAG,EAAE;YACX,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC;QAC3B,CAAC,CAAC;IACH,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;IAE5E,OAAO,IAAI,CAAC;AACb,CAAC,CAAC"}
@@ -0,0 +1,141 @@
1
+ import type { LogLevel } from "../core/logging";
2
+ import type { AccountTraits, Analytics, UserTraits } from "../core/types";
3
+ /**
4
+ * Hook to access the Analytics instance
5
+ *
6
+ * @throws Error if Analytics component has not been mounted
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * const analytics = useAnalytics();
11
+ *
12
+ * const handleClick = () => {
13
+ * analytics.track('button_clicked', { buttonId: 'signup' });
14
+ * };
15
+ * ```
16
+ */
17
+ export declare const useAnalytics: () => Analytics;
18
+ /**
19
+ * Hook to get a memoized track function for a specific event
20
+ *
21
+ * This is useful for event handlers where you want to avoid
22
+ * creating new function references on each render.
23
+ *
24
+ * @param eventName - The name of the event to track
25
+ *
26
+ * @example
27
+ * ```tsx
28
+ * const trackSignup = useTrack('signup_clicked');
29
+ *
30
+ * return (
31
+ * <button onClick={() => trackSignup({ location: 'header' })}>
32
+ * Sign Up
33
+ * </button>
34
+ * );
35
+ * ```
36
+ */
37
+ export declare const useTrack: (eventName: string) => (properties?: Record<string, unknown>) => void;
38
+ /**
39
+ * Hook to identify the current user
40
+ *
41
+ * Returns a memoized identify function.
42
+ *
43
+ * @example
44
+ * ```tsx
45
+ * const identify = useIdentify();
46
+ *
47
+ * // After login
48
+ * identify(user.id, {
49
+ * email: user.email,
50
+ * name: user.name,
51
+ * plan: user.plan,
52
+ * });
53
+ * ```
54
+ */
55
+ export declare const useIdentify: () => (userId: string, traits?: UserTraits) => void;
56
+ /**
57
+ * Hook to associate the current user with an account/company
58
+ *
59
+ * Returns a memoized group function.
60
+ *
61
+ * @example
62
+ * ```tsx
63
+ * const group = useGroup();
64
+ *
65
+ * // After user selects workspace/company
66
+ * group(workspace.id, {
67
+ * name: workspace.name,
68
+ * plan: workspace.plan,
69
+ * mrr: workspace.mrr,
70
+ * });
71
+ * ```
72
+ */
73
+ export declare const useGroup: () => (accountId: string, traits?: AccountTraits) => void;
74
+ /**
75
+ * Hook to track page views
76
+ *
77
+ * Returns a memoized page function.
78
+ *
79
+ * @example
80
+ * ```tsx
81
+ * const trackPage = usePage();
82
+ *
83
+ * useEffect(() => {
84
+ * trackPage('/dashboard', { section: 'overview' });
85
+ * }, [trackPage]);
86
+ * ```
87
+ */
88
+ export declare const usePage: () => (name?: string, properties?: Record<string, unknown>) => void;
89
+ /**
90
+ * Hook to reset the analytics session (call on logout)
91
+ *
92
+ * @example
93
+ * ```tsx
94
+ * const resetAnalytics = useReset();
95
+ *
96
+ * const handleLogout = () => {
97
+ * resetAnalytics();
98
+ * // ... other logout logic
99
+ * };
100
+ * ```
101
+ */
102
+ export declare const useReset: () => () => void;
103
+ /**
104
+ * Hook to get the current user state
105
+ *
106
+ * @example
107
+ * ```tsx
108
+ * const getUser = useGetUser();
109
+ *
110
+ * const handleDebug = () => {
111
+ * console.log(getUser());
112
+ * // { anonymousId: '...', userId: '...', traits: { ... } }
113
+ * };
114
+ * ```
115
+ */
116
+ export declare const useGetUser: () => () => import("..").UserState | undefined;
117
+ /**
118
+ * Hook to capture exceptions
119
+ *
120
+ * @example
121
+ * ```tsx
122
+ * const captureException = useCaptureException();
123
+ *
124
+ * try { ... } catch (error) {
125
+ * captureException(error as Error, { component: 'Checkout' });
126
+ * }
127
+ * ```
128
+ */
129
+ export declare const useCaptureException: () => (error: Error, context?: Record<string, unknown>) => void;
130
+ /**
131
+ * Hook to send structured log events
132
+ *
133
+ * @example
134
+ * ```tsx
135
+ * const log = useLog();
136
+ *
137
+ * log('User completed onboarding', 'info', { step: 3 });
138
+ * ```
139
+ */
140
+ export declare const useLog: () => (message: string, level: LogLevel, metadata?: Record<string, unknown>) => void;
141
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/react/hooks.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAiB1E;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,YAAY,QAAO,SAE/B,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,QAAQ,GAAI,WAAW,MAAM,mBAE1B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,SAKtC,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,WAAW,iBACK,MAAM,WAAW,UAAU,SAGvD,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,QAAQ,oBACW,MAAM,WAAW,aAAa,SAG7D,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,OAAO,gBACQ,MAAM,eAAe,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,SAGvE,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,QAAQ,kBAIpB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,UAAU,gDAItB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,gBACJ,KAAK,YAAY,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,SAGnE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,MAAM,kBAEP,MAAM,SAAS,QAAQ,aAAa,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,SAKtE,CAAC"}