@productbet/tracker-react 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.
@@ -0,0 +1,5 @@
1
+ import type { ProductBetTracker } from "@productbet/tracker-core";
2
+ export declare function useTracker(): ProductBetTracker | null;
3
+ export declare function useIdentify(userId: string | null | undefined, attributes?: Record<string, unknown>): void;
4
+ export declare function useTrackEvent(): (eventName: string, properties?: Record<string, unknown>) => void;
5
+ export declare function usePageView(pathname?: string): void;
@@ -0,0 +1,4 @@
1
+ export { ProductBetProvider, ProductBetContext } from "./provider";
2
+ export type { ProductBetProviderProps } from "./provider";
3
+ export { useTracker, useIdentify, useTrackEvent, usePageView } from "./hooks";
4
+ export type { TrackerOptions, AutoTrackingOptions, RedactionOptions, } from "@productbet/tracker-core";
package/dist/index.js ADDED
@@ -0,0 +1,69 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var react = require('react');
5
+ var trackerCore = require('@productbet/tracker-core');
6
+
7
+ const ProductBetContext = react.createContext(null);
8
+ function ProductBetProvider({ apiKey, children, ...options }) {
9
+ const trackerRef = react.useRef(null);
10
+ if (!trackerRef.current && typeof window !== "undefined") {
11
+ trackerRef.current = trackerCore.ProductBetTracker.init(apiKey, options);
12
+ }
13
+ react.useEffect(() => {
14
+ const tracker = trackerRef.current;
15
+ if (!tracker)
16
+ return;
17
+ tracker.start();
18
+ return () => {
19
+ tracker.stop();
20
+ };
21
+ }, []);
22
+ return (jsxRuntime.jsx(ProductBetContext.Provider, { value: trackerRef.current, children: children }));
23
+ }
24
+
25
+ function useTracker() {
26
+ return react.useContext(ProductBetContext);
27
+ }
28
+ function useIdentify(userId, attributes) {
29
+ const tracker = useTracker();
30
+ const prevUserIdRef = react.useRef(null);
31
+ react.useEffect(() => {
32
+ if (!tracker || !userId)
33
+ return;
34
+ if (userId === prevUserIdRef.current)
35
+ return;
36
+ prevUserIdRef.current = userId;
37
+ tracker.identify(userId, attributes);
38
+ }, [tracker, userId, attributes]);
39
+ }
40
+ function useTrackEvent() {
41
+ const tracker = useTracker();
42
+ return (eventName, properties) => {
43
+ tracker?.track(eventName, properties);
44
+ };
45
+ }
46
+ function usePageView(pathname) {
47
+ const tracker = useTracker();
48
+ const prevPathRef = react.useRef(undefined);
49
+ react.useEffect(() => {
50
+ if (!tracker || !pathname)
51
+ return;
52
+ if (pathname === prevPathRef.current)
53
+ return;
54
+ prevPathRef.current = pathname;
55
+ tracker.track("$page_view", {
56
+ path: pathname,
57
+ url: typeof window !== "undefined" ? window.location.href : undefined,
58
+ title: typeof document !== "undefined" ? document.title : undefined,
59
+ });
60
+ }, [tracker, pathname]);
61
+ }
62
+
63
+ exports.ProductBetContext = ProductBetContext;
64
+ exports.ProductBetProvider = ProductBetProvider;
65
+ exports.useIdentify = useIdentify;
66
+ exports.usePageView = usePageView;
67
+ exports.useTrackEvent = useTrackEvent;
68
+ exports.useTracker = useTracker;
69
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/provider.tsx","../src/hooks.ts"],"sourcesContent":["import {\n createContext,\n useEffect,\n useRef,\n type ReactNode,\n} from \"react\"\nimport {\n ProductBetTracker,\n type TrackerOptions,\n} from \"@productbet/tracker-core\"\n\nexport const ProductBetContext = createContext<ProductBetTracker | null>(null)\n\nexport interface ProductBetProviderProps extends TrackerOptions {\n apiKey: string\n children: ReactNode\n}\n\nexport function ProductBetProvider({\n apiKey,\n children,\n ...options\n}: ProductBetProviderProps) {\n const trackerRef = useRef<ProductBetTracker | null>(null)\n\n if (!trackerRef.current && typeof window !== \"undefined\") {\n trackerRef.current = ProductBetTracker.init(apiKey, options)\n }\n\n useEffect(() => {\n const tracker = trackerRef.current\n if (!tracker) return\n\n tracker.start()\n\n return () => {\n tracker.stop()\n }\n }, [])\n\n return (\n <ProductBetContext.Provider value={trackerRef.current}>\n {children}\n </ProductBetContext.Provider>\n )\n}\n","import { useContext, useEffect, useRef } from \"react\"\nimport { ProductBetContext } from \"./provider\"\nimport type { ProductBetTracker } from \"@productbet/tracker-core\"\n\nexport function useTracker(): ProductBetTracker | null {\n return useContext(ProductBetContext)\n}\n\nexport function useIdentify(\n userId: string | null | undefined,\n attributes?: Record<string, unknown>,\n): void {\n const tracker = useTracker()\n const prevUserIdRef = useRef<string | null | undefined>(null)\n\n useEffect(() => {\n if (!tracker || !userId) return\n if (userId === prevUserIdRef.current) return\n\n prevUserIdRef.current = userId\n tracker.identify(userId, attributes)\n }, [tracker, userId, attributes])\n}\n\nexport function useTrackEvent(): (\n eventName: string,\n properties?: Record<string, unknown>,\n) => void {\n const tracker = useTracker()\n\n return (eventName: string, properties?: Record<string, unknown>) => {\n tracker?.track(eventName, properties)\n }\n}\n\nexport function usePageView(pathname?: string): void {\n const tracker = useTracker()\n const prevPathRef = useRef<string | undefined>(undefined)\n\n useEffect(() => {\n if (!tracker || !pathname) return\n if (pathname === prevPathRef.current) return\n\n prevPathRef.current = pathname\n tracker.track(\"$page_view\", {\n path: pathname,\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n title: typeof document !== \"undefined\" ? document.title : undefined,\n })\n }, [tracker, pathname])\n}\n"],"names":["createContext","useRef","ProductBetTracker","useEffect","_jsx","useContext"],"mappings":";;;;;;MAWa,iBAAiB,GAAGA,mBAAa,CAA2B,IAAI;AAOvE,SAAU,kBAAkB,CAAC,EAC/B,MAAM,EACN,QAAQ,EACR,GAAG,OAAO,EACY,EAAA;AACtB,IAAA,MAAM,UAAU,GAAGC,YAAM,CAA2B,IAAI,CAAC;IAEzD,IAAI,CAAC,UAAU,CAAC,OAAO,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACtD,UAAU,CAAC,OAAO,GAAGC,6BAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC;IAChE;IAEAC,eAAS,CAAC,MAAK;AACX,QAAA,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO;AAClC,QAAA,IAAI,CAAC,OAAO;YAAE;QAEd,OAAO,CAAC,KAAK,EAAE;AAEf,QAAA,OAAO,MAAK;YACR,OAAO,CAAC,IAAI,EAAE;AAClB,QAAA,CAAC;IACL,CAAC,EAAE,EAAE,CAAC;AAEN,IAAA,QACIC,cAAA,CAAC,iBAAiB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,UAAU,CAAC,OAAO,EAAA,QAAA,EAChD,QAAQ,EAAA,CACgB;AAErC;;SCzCgB,UAAU,GAAA;AACtB,IAAA,OAAOC,gBAAU,CAAC,iBAAiB,CAAC;AACxC;AAEM,SAAU,WAAW,CACvB,MAAiC,EACjC,UAAoC,EAAA;AAEpC,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE;AAC5B,IAAA,MAAM,aAAa,GAAGJ,YAAM,CAA4B,IAAI,CAAC;IAE7DE,eAAS,CAAC,MAAK;AACX,QAAA,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM;YAAE;AACzB,QAAA,IAAI,MAAM,KAAK,aAAa,CAAC,OAAO;YAAE;AAEtC,QAAA,aAAa,CAAC,OAAO,GAAG,MAAM;AAC9B,QAAA,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IACxC,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;AACrC;SAEgB,aAAa,GAAA;AAIzB,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE;AAE5B,IAAA,OAAO,CAAC,SAAiB,EAAE,UAAoC,KAAI;AAC/D,QAAA,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,UAAU,CAAC;AACzC,IAAA,CAAC;AACL;AAEM,SAAU,WAAW,CAAC,QAAiB,EAAA;AACzC,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE;AAC5B,IAAA,MAAM,WAAW,GAAGF,YAAM,CAAqB,SAAS,CAAC;IAEzDE,eAAS,CAAC,MAAK;AACX,QAAA,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ;YAAE;AAC3B,QAAA,IAAI,QAAQ,KAAK,WAAW,CAAC,OAAO;YAAE;AAEtC,QAAA,WAAW,CAAC,OAAO,GAAG,QAAQ;AAC9B,QAAA,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE;AACxB,YAAA,IAAI,EAAE,QAAQ;AACd,YAAA,GAAG,EAAE,OAAO,MAAM,KAAK,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,SAAS;AACrE,YAAA,KAAK,EAAE,OAAO,QAAQ,KAAK,WAAW,GAAG,QAAQ,CAAC,KAAK,GAAG,SAAS;AACtE,SAAA,CAAC;AACN,IAAA,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AAC3B;;;;;;;;;"}
package/dist/index.mjs ADDED
@@ -0,0 +1,62 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { createContext, useRef, useEffect, useContext } from 'react';
3
+ import { ProductBetTracker } from '@productbet/tracker-core';
4
+
5
+ const ProductBetContext = createContext(null);
6
+ function ProductBetProvider({ apiKey, children, ...options }) {
7
+ const trackerRef = useRef(null);
8
+ if (!trackerRef.current && typeof window !== "undefined") {
9
+ trackerRef.current = ProductBetTracker.init(apiKey, options);
10
+ }
11
+ useEffect(() => {
12
+ const tracker = trackerRef.current;
13
+ if (!tracker)
14
+ return;
15
+ tracker.start();
16
+ return () => {
17
+ tracker.stop();
18
+ };
19
+ }, []);
20
+ return (jsx(ProductBetContext.Provider, { value: trackerRef.current, children: children }));
21
+ }
22
+
23
+ function useTracker() {
24
+ return useContext(ProductBetContext);
25
+ }
26
+ function useIdentify(userId, attributes) {
27
+ const tracker = useTracker();
28
+ const prevUserIdRef = useRef(null);
29
+ useEffect(() => {
30
+ if (!tracker || !userId)
31
+ return;
32
+ if (userId === prevUserIdRef.current)
33
+ return;
34
+ prevUserIdRef.current = userId;
35
+ tracker.identify(userId, attributes);
36
+ }, [tracker, userId, attributes]);
37
+ }
38
+ function useTrackEvent() {
39
+ const tracker = useTracker();
40
+ return (eventName, properties) => {
41
+ tracker?.track(eventName, properties);
42
+ };
43
+ }
44
+ function usePageView(pathname) {
45
+ const tracker = useTracker();
46
+ const prevPathRef = useRef(undefined);
47
+ useEffect(() => {
48
+ if (!tracker || !pathname)
49
+ return;
50
+ if (pathname === prevPathRef.current)
51
+ return;
52
+ prevPathRef.current = pathname;
53
+ tracker.track("$page_view", {
54
+ path: pathname,
55
+ url: typeof window !== "undefined" ? window.location.href : undefined,
56
+ title: typeof document !== "undefined" ? document.title : undefined,
57
+ });
58
+ }, [tracker, pathname]);
59
+ }
60
+
61
+ export { ProductBetContext, ProductBetProvider, useIdentify, usePageView, useTrackEvent, useTracker };
62
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sources":["../src/provider.tsx","../src/hooks.ts"],"sourcesContent":["import {\n createContext,\n useEffect,\n useRef,\n type ReactNode,\n} from \"react\"\nimport {\n ProductBetTracker,\n type TrackerOptions,\n} from \"@productbet/tracker-core\"\n\nexport const ProductBetContext = createContext<ProductBetTracker | null>(null)\n\nexport interface ProductBetProviderProps extends TrackerOptions {\n apiKey: string\n children: ReactNode\n}\n\nexport function ProductBetProvider({\n apiKey,\n children,\n ...options\n}: ProductBetProviderProps) {\n const trackerRef = useRef<ProductBetTracker | null>(null)\n\n if (!trackerRef.current && typeof window !== \"undefined\") {\n trackerRef.current = ProductBetTracker.init(apiKey, options)\n }\n\n useEffect(() => {\n const tracker = trackerRef.current\n if (!tracker) return\n\n tracker.start()\n\n return () => {\n tracker.stop()\n }\n }, [])\n\n return (\n <ProductBetContext.Provider value={trackerRef.current}>\n {children}\n </ProductBetContext.Provider>\n )\n}\n","import { useContext, useEffect, useRef } from \"react\"\nimport { ProductBetContext } from \"./provider\"\nimport type { ProductBetTracker } from \"@productbet/tracker-core\"\n\nexport function useTracker(): ProductBetTracker | null {\n return useContext(ProductBetContext)\n}\n\nexport function useIdentify(\n userId: string | null | undefined,\n attributes?: Record<string, unknown>,\n): void {\n const tracker = useTracker()\n const prevUserIdRef = useRef<string | null | undefined>(null)\n\n useEffect(() => {\n if (!tracker || !userId) return\n if (userId === prevUserIdRef.current) return\n\n prevUserIdRef.current = userId\n tracker.identify(userId, attributes)\n }, [tracker, userId, attributes])\n}\n\nexport function useTrackEvent(): (\n eventName: string,\n properties?: Record<string, unknown>,\n) => void {\n const tracker = useTracker()\n\n return (eventName: string, properties?: Record<string, unknown>) => {\n tracker?.track(eventName, properties)\n }\n}\n\nexport function usePageView(pathname?: string): void {\n const tracker = useTracker()\n const prevPathRef = useRef<string | undefined>(undefined)\n\n useEffect(() => {\n if (!tracker || !pathname) return\n if (pathname === prevPathRef.current) return\n\n prevPathRef.current = pathname\n tracker.track(\"$page_view\", {\n path: pathname,\n url: typeof window !== \"undefined\" ? window.location.href : undefined,\n title: typeof document !== \"undefined\" ? document.title : undefined,\n })\n }, [tracker, pathname])\n}\n"],"names":["_jsx"],"mappings":";;;;MAWa,iBAAiB,GAAG,aAAa,CAA2B,IAAI;AAOvE,SAAU,kBAAkB,CAAC,EAC/B,MAAM,EACN,QAAQ,EACR,GAAG,OAAO,EACY,EAAA;AACtB,IAAA,MAAM,UAAU,GAAG,MAAM,CAA2B,IAAI,CAAC;IAEzD,IAAI,CAAC,UAAU,CAAC,OAAO,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACtD,UAAU,CAAC,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC;IAChE;IAEA,SAAS,CAAC,MAAK;AACX,QAAA,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO;AAClC,QAAA,IAAI,CAAC,OAAO;YAAE;QAEd,OAAO,CAAC,KAAK,EAAE;AAEf,QAAA,OAAO,MAAK;YACR,OAAO,CAAC,IAAI,EAAE;AAClB,QAAA,CAAC;IACL,CAAC,EAAE,EAAE,CAAC;AAEN,IAAA,QACIA,GAAA,CAAC,iBAAiB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,UAAU,CAAC,OAAO,EAAA,QAAA,EAChD,QAAQ,EAAA,CACgB;AAErC;;SCzCgB,UAAU,GAAA;AACtB,IAAA,OAAO,UAAU,CAAC,iBAAiB,CAAC;AACxC;AAEM,SAAU,WAAW,CACvB,MAAiC,EACjC,UAAoC,EAAA;AAEpC,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE;AAC5B,IAAA,MAAM,aAAa,GAAG,MAAM,CAA4B,IAAI,CAAC;IAE7D,SAAS,CAAC,MAAK;AACX,QAAA,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM;YAAE;AACzB,QAAA,IAAI,MAAM,KAAK,aAAa,CAAC,OAAO;YAAE;AAEtC,QAAA,aAAa,CAAC,OAAO,GAAG,MAAM;AAC9B,QAAA,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IACxC,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;AACrC;SAEgB,aAAa,GAAA;AAIzB,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE;AAE5B,IAAA,OAAO,CAAC,SAAiB,EAAE,UAAoC,KAAI;AAC/D,QAAA,OAAO,EAAE,KAAK,CAAC,SAAS,EAAE,UAAU,CAAC;AACzC,IAAA,CAAC;AACL;AAEM,SAAU,WAAW,CAAC,QAAiB,EAAA;AACzC,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE;AAC5B,IAAA,MAAM,WAAW,GAAG,MAAM,CAAqB,SAAS,CAAC;IAEzD,SAAS,CAAC,MAAK;AACX,QAAA,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ;YAAE;AAC3B,QAAA,IAAI,QAAQ,KAAK,WAAW,CAAC,OAAO;YAAE;AAEtC,QAAA,WAAW,CAAC,OAAO,GAAG,QAAQ;AAC9B,QAAA,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE;AACxB,YAAA,IAAI,EAAE,QAAQ;AACd,YAAA,GAAG,EAAE,OAAO,MAAM,KAAK,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,SAAS;AACrE,YAAA,KAAK,EAAE,OAAO,QAAQ,KAAK,WAAW,GAAG,QAAQ,CAAC,KAAK,GAAG,SAAS;AACtE,SAAA,CAAC;AACN,IAAA,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AAC3B;;;;"}
@@ -0,0 +1,8 @@
1
+ import { type ReactNode } from "react";
2
+ import { ProductBetTracker, type TrackerOptions } from "@productbet/tracker-core";
3
+ export declare const ProductBetContext: import("react").Context<ProductBetTracker | null>;
4
+ export interface ProductBetProviderProps extends TrackerOptions {
5
+ apiKey: string;
6
+ children: ReactNode;
7
+ }
8
+ export declare function ProductBetProvider({ apiKey, children, ...options }: ProductBetProviderProps): import("react/jsx-runtime").JSX.Element;
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@productbet/tracker-react",
3
+ "version": "0.1.0",
4
+ "description": "React integration for ProductBet behavioral analytics SDK",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.mjs",
11
+ "require": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "dependencies": {
19
+ "@productbet/tracker-core": "0.1.0"
20
+ },
21
+ "peerDependencies": {
22
+ "react": ">=18.0.0",
23
+ "react-dom": ">=18.0.0"
24
+ },
25
+ "devDependencies": {
26
+ "@rollup/plugin-commonjs": "^28.0.0",
27
+ "@rollup/plugin-node-resolve": "^16.0.0",
28
+ "@rollup/plugin-typescript": "^12.0.0",
29
+ "@types/react": "^19.0.0",
30
+ "rimraf": "^6.0.0",
31
+ "rollup": "^4.0.0",
32
+ "tslib": "^2.8.0",
33
+ "typescript": "^5.8.0"
34
+ },
35
+ "sideEffects": false,
36
+ "license": "MIT",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "https://github.com/productbet/productbet",
40
+ "directory": "packages/tracker-react"
41
+ },
42
+ "keywords": [
43
+ "analytics",
44
+ "react",
45
+ "session-recording",
46
+ "productbet"
47
+ ],
48
+ "scripts": {
49
+ "build": "rollup -c rollup.config.mjs",
50
+ "dev": "rollup -c rollup.config.mjs --watch",
51
+ "clean": "rimraf dist"
52
+ }
53
+ }