{"version":3,"sources":["../src/index.ts","../package.json","../src/createDatanova.ts","../src/providers/DatanovaProvider.tsx","../src/hooks/useDatanova.ts","../src/hooks/useVariant.ts","../src/components/TrackPageView.tsx","../src/components/TrackClick.tsx","../src/components/TrackImpression.tsx","../src/components/TrackSubmit.tsx","../src/components/TrackChange.tsx","../src/components/Experiment.tsx"],"names":["name","version","createDatanova","keyOrServices","datanova","Datanova","DatanovaEventsService","DatanovaExperimentsService","__name","DatanovaContext","createContext","DatanovaProvider","children","jsx","useDatanova","context","useContext","useVariant","experimentId","client","state","setState","useState","useEffect","cancelled","fetchVariant","__async","variant","err","TrackPageView","eventName","properties","trackPageView","TrackClick","trackClick","isValidElement","originalOnClick","cloneElement","event","TrackImpression","threshold","triggerOnce","trackImpression","InView","inView","TrackSubmit","trackSubmit","originalOnSubmit","TrackChange","trackChange","originalOnChange","value","__spreadProps","__spreadValues","Experiment","control","variantContent","loadingContent","errorContent","data","isLoading","error","Fragment"],"mappings":"kcAOA,IAAA,CAAA,CAAA,MAAA,CAAA,cAAA,CAAA,CAAA,CAAA,MAAA,CAAA,gBAAA,CAAA,IAAA,CAAA,CAAA,MAAA,CAAA,yBAAA,CAAA,IAAA,CAAA,CAAA,MAAA,CAAA,qBAAA,CAAA,IAAA,CAAA,CAAA,MAAA,CAAA,SAAA,CAAA,cAAA,CAAA,CAAA,CAAA,MAAA,CAAA,SAAA,CAAA,oBAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,UAAA,CAAA,IAAA,CAAA,YAAA,CAAA,IAAA,CAAA,QAAA,CAAA,IAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,IAAA,IAAA,CAAA,IAAA,CAAA,GAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,CAAA,IAAA,IAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,MAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,YAAA,CAAA,IAAA,CAAA,CAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,IAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,IAAA,CAAA,CAAA,CAAA,EAAA,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,IAAA,CAAA,CAAA,CAAA,EAAA,CAAA,MAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,EAAA,CAAA,MAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,OAAA,CAAA,OAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,IAAA,EAAA,EAAA,CAAA,CAAA,CCNE,IAAAA,EAAQ,iBAAA,CACRC,CAAAA,CAAW,QCgCN,SAASC,CAAAA,CACdC,CAAAA,CAMU,CACV,IAAMC,CAAAA,CAAW,IAAIC,SAErB,OAAI,OAAOF,GAAkB,QAAA,CAC3BC,CAAAA,CAAS,IAAA,CAAK,CACZ,cAAe,IAAIE,qBAAAA,CAAsBH,CAAa,CAAA,CACtD,kBAAA,CAAoB,IAAII,0BAAAA,CAA2BJ,CAAa,CAAA,CAChE,OAAA,CAAS,CACP,OAAA,CAAS,CACP,KAAAH,CAAAA,CACA,OAAA,CAAAC,CACF,CACF,CACF,CAAC,CAAA,CAEDG,EAAS,IAAA,CAAK,CACZ,cAAeD,CAAAA,CAAc,aAAA,CAC7B,mBAAoBA,CAAAA,CAAc,kBAAA,CAClC,OAAA,CAAS,CACP,QAAS,CACP,IAAA,CAAAH,EACA,OAAA,CAAAC,CACF,CACF,CACF,CAAC,CAAA,CAGIG,CACT,CAnCgBI,CAAAA,CAAAN,CAAAA,CAAA,kBCnBT,IAAMO,CAAAA,CAAkBC,cAA2C,IAAI,CAAA,CAyEvE,SAASC,CAAAA,CAAiB,CAAE,QAAA,CAAAP,CAAAA,CAAU,SAAAQ,CAAS,CAAA,CAA0B,CAC9E,OAAOC,GAAAA,CAACJ,CAAAA,CAAgB,QAAA,CAAhB,CAAyB,KAAA,CAAOL,CAAAA,CAAW,SAAAQ,CAAAA,CAAS,CAC9D,CAFgBJ,CAAAA,CAAAG,CAAAA,CAAA,kBAAA,CAAA,CChDT,SAASG,GAAc,CAC5B,IAAMC,EAAUC,UAAAA,CAAWP,CAAe,EAE1C,GAAI,CAACM,CAAAA,CACH,MAAM,IAAI,KAAA,CAAM,oDAAoD,EAGtE,OAAO,CACL,WAAYA,CAAAA,CAAQ,UAAA,CACpB,aAAA,CAAeA,CAAAA,CAAQ,cACvB,eAAA,CAAiBA,CAAAA,CAAQ,gBACzB,WAAA,CAAaA,CAAAA,CAAQ,YACrB,WAAA,CAAaA,CAAAA,CAAQ,WAAA,CACrB,QAAA,CAAUA,EAAQ,QAAA,CAClB,KAAA,CAAOA,EAAQ,KACjB,CACF,CAhBgBP,CAAAA,CAAAM,CAAAA,CAAA,aAAA,CAAA,CCGT,SAASG,CAAAA,CAAW,CAAE,YAAA,CAAAC,CAAa,CAAA,CAA8C,CACtF,IAAMC,CAAAA,CAASH,UAAAA,CAAWP,CAAe,CAAA,CACnC,CAACW,CAAAA,CAAOC,CAAQ,EAAIC,QAAAA,CAA0B,CAClD,UAAW,IAAA,CACX,IAAA,CAAM,OACN,KAAA,CAAO,IACT,CAAC,CAAA,CAED,OAAAC,SAAAA,CAAU,IAAM,CACd,GAAI,CAACJ,EAAQ,CACXE,CAAAA,CAAS,CACP,SAAA,CAAW,MACX,IAAA,CAAM,SAAA,CACN,MAAO,IAAI,KAAA,CAAM,mDAAmD,CACtE,CAAC,CAAA,CACD,MACF,CAEA,IAAIG,CAAAA,CAAY,MAEhB,SAAeC,CAAAA,EAAe,QAAAC,CAAAA,CAAA,IAAA,CAAA,IAAA,CAAA,WAAA,CAC5B,GAAI,CACFL,EAAS,CAAE,SAAA,CAAW,GAAM,IAAA,CAAM,KAAA,CAAA,CAAW,MAAO,IAAK,CAAC,CAAA,CAC1D,IAAMM,EAAU,MAAMR,CAAAA,CAAQ,WAAWD,CAAY,CAAA,CAEhDM,GACHH,CAAAA,CAAS,CACP,SAAA,CAAW,CAAA,CAAA,CACX,KAAMM,CAAAA,CACN,KAAA,CAAO,IACT,CAAC,EAEL,OAASC,CAAAA,CAAK,CACPJ,CAAAA,EACHH,CAAAA,CAAS,CACP,SAAA,CAAW,KAAA,CACX,KAAM,SAAA,CACN,KAAA,CAAOO,aAAe,KAAA,CAAQA,CAAAA,CAAM,IAAI,KAAA,CAAM,2BAA2B,CAC3E,CAAC,EAEL,CACF,CAAA,CAAA,CArBe,OAAApB,CAAAA,CAAAiB,CAAAA,CAAA,cAAA,CAAA,CAuBX,OAAO,QAAW,WAAA,CACpBA,CAAAA,GAEAJ,CAAAA,CAAS,CAAE,UAAW,KAAA,CAAO,IAAA,CAAM,SAAA,CAAW,KAAA,CAAO,IAAK,CAAC,CAAA,CAGtD,IAAM,CACXG,CAAAA,CAAY,KACd,CACF,CAAA,CAAG,CAACN,CAAAA,CAAcC,CAAM,CAAC,CAAA,CAElBC,CACT,CAvDgBZ,CAAAA,CAAAS,EAAA,YAAA,CAAA,CCMT,SAASY,CAAAA,CAAc,CAAE,SAAA,CAAAC,CAAAA,CAAW,WAAAC,CAAW,CAAA,CAAuB,CAC3E,GAAM,CAAE,aAAA,CAAAC,CAAc,EAAIlB,CAAAA,EAAY,CAEtC,OAAAS,SAAAA,CAAU,IAAM,CACdS,CAAAA,CAAcF,EAAWC,CAAU,EACrC,CAAA,CAAG,CAACD,EAAWC,CAAAA,CAAYC,CAAa,CAAC,CAAA,CAElC,IACT,CARgBxB,CAAAA,CAAAqB,EAAA,eAAA,CAAA,CCZT,SAASI,CAAAA,CAAW,CAAE,SAAArB,CAAAA,CAAU,SAAA,CAAAkB,EAAW,UAAA,CAAAC,CAAW,CAAA,CAAoB,CAC/E,GAAM,CAAE,UAAA,CAAAG,CAAW,CAAA,CAAIpB,CAAAA,GAEvB,GAAI,CAACqB,cAAAA,CAAevB,CAAQ,EAC1B,MAAM,IAAI,MAAM,oDAAoD,CAAA,CAGtE,IAAMwB,CAAAA,CAAkBxB,CAAAA,CAAS,KAAA,CAAM,OAAA,CASvC,OAAOyB,YAAAA,CAAazB,CAAAA,CAAU,CAAE,OAAA,CAPZJ,CAAAA,CAAC8B,GAAsB,CACzCJ,CAAAA,CAAWJ,CAAAA,CAAWC,CAAU,EAC5BK,CAAAA,EACFA,CAAAA,CAAgBE,CAAK,EAEzB,CAAA,CALoB,cAOiC,CAAC,CACxD,CAjBgB9B,CAAAA,CAAAyB,EAAA,YAAA,CAAA,CC4BT,SAASM,CAAAA,CAAgB,CAC9B,QAAA,CAAA3B,CAAAA,CACA,UAAAkB,CAAAA,CACA,UAAA,CAAAC,EACA,SAAA,CAAAS,CAAAA,CAAY,EAAA,CACZ,WAAA,CAAAC,EAAc,IAChB,CAAA,CAAyB,CACvB,GAAM,CAAE,gBAAAC,CAAgB,CAAA,CAAI5B,CAAAA,EAAY,CAExC,OACED,GAAAA,CAAC8B,MAAAA,CAAA,CACC,QAAA,CAAWC,CAAAA,EAAW,CAChBA,CAAAA,EACFF,CAAAA,CAAgBZ,CAAAA,CAAWC,CAAU,EAEzC,CAAA,CACA,SAAA,CAAWS,EACX,WAAA,CAAaC,CAAAA,CAEZ,SAAA7B,CAAAA,CACH,CAEJ,CAtBgBJ,CAAAA,CAAA+B,EAAA,iBAAA,CAAA,CC3BT,SAASM,CAAAA,CAAY,CAAE,SAAAjC,CAAAA,CAAU,SAAA,CAAAkB,EAAW,UAAA,CAAAC,CAAW,EAAqB,CACjF,GAAM,CAAE,WAAA,CAAAe,CAAY,CAAA,CAAIhC,CAAAA,GAExB,GAAI,CAACqB,eAAevB,CAAQ,CAAA,CAC1B,MAAM,IAAI,MAAM,qDAAqD,CAAA,CAGvE,IAAMmC,CAAAA,CAAmBnC,CAAAA,CAAS,MAAM,QAAA,CAOxC,OAAOyB,YAAAA,CAAazB,CAAAA,CAAU,CAAE,QAAA,CALXJ,CAAAA,CAAC8B,GAAqB,CACzCQ,CAAAA,CAAYhB,EAAWC,CAAU,CAAA,CACjCgB,CAAAA,EAAA,IAAA,EAAAA,EAAmBT,CAAAA,EACrB,CAAA,CAHqB,eAKkC,CAAC,CAC1D,CAfgB9B,CAAAA,CAAAqC,CAAAA,CAAA,aAAA,CAAA,CCCT,SAASG,EAAY,CAAE,QAAA,CAAApC,CAAAA,CAAU,SAAA,CAAAkB,EAAW,UAAA,CAAAC,CAAW,EAAqB,CACjF,GAAM,CAAE,WAAA,CAAAkB,CAAY,CAAA,CAAInC,CAAAA,GAExB,GAAI,CAACqB,eAAevB,CAAQ,CAAA,CAC1B,MAAM,IAAI,KAAA,CAAM,qDAAqD,CAAA,CAGvE,IAAMsC,CAAAA,CAAmBtC,CAAAA,CAAS,MAAM,QAAA,CAoBxC,OAAOyB,aAAazB,CAAAA,CAAU,CAAE,QAAA,CAlBXJ,CAAAA,CACnB8B,GACG,CACH,IAAIa,EAEAb,CAAAA,EAAS,OAAOA,GAAU,QAAA,EAAY,QAAA,GAAYA,CAAAA,CACpDa,CAAAA,CAASb,EAA8C,MAAA,CAAO,KAAA,CAE9Da,EAAQb,CAAAA,CAGVW,CAAAA,CAAYnB,EAAWsB,CAAAA,CAAAC,CAAAA,CAAA,EAAA,CAClBtB,CAAAA,CAAAA,CADkB,CAErB,KAAA,CAAAoB,CACF,EAAC,CAAA,CACDD,CAAAA,EAAA,MAAAA,CAAAA,CAAmBZ,CAAAA,EACrB,CAAA,CAhBqB,cAAA,CAkBkC,CAAC,CAC1D,CA5BgB9B,EAAAwC,CAAAA,CAAA,aAAA,CAAA,CCST,SAASM,CAAAA,CAAW,CACzB,aAAApC,CAAAA,CACA,OAAA,CAAAqC,EACA,OAAA,CAASC,CAAAA,CACT,OAAA,CAASC,CAAAA,CACT,MAAOC,CACT,CAAA,CAAoB,CAClB,GAAM,CAAE,KAAAC,CAAAA,CAAM,SAAA,CAAAC,CAAAA,CAAW,KAAA,CAAAC,CAAM,CAAA,CAAI5C,CAAAA,CAAW,CAAE,YAAA,CAAAC,CAAa,CAAC,CAAA,CAE9D,OAAI0C,CAAAA,CACK/C,GAAAA,CAAAiD,SAAA,CAAG,QAAA,CAAAL,GAAA,IAAA,CAAAA,CAAAA,CAAkB,KAAK,CAAA,CAG/BI,CAAAA,CACKhD,GAAAA,CAAAiD,QAAAA,CAAA,CAAG,QAAA,CAAAJ,CAAAA,EAAA,KAAAA,CAAAA,CAAgBH,CAAAA,CAAQ,EAK7B1C,GAAAA,CAAAiD,QAAAA,CAAA,CAAG,QAAA,CAFMH,IAAS,SAAA,CAAYH,CAAAA,CAAiBD,EAEpC,CACpB,CApBgB/C,EAAA8C,CAAAA,CAAA,YAAA,CAAA","file":"index.mjs","sourcesContent":["export type {\n  Event,\n  EventsService,\n  ExperimentsService,\n  SDKConfig,\n  Variant,\n} from '@datanova/browser';\nexport {\n  EventType,\n  ConsoleEventsService,\n  DatanovaEventsService,\n  DatanovaExperimentsService,\n  NoopEventsService,\n  RandomExperimentsService,\n  generateAnonymousId,\n} from '@datanova/browser';\n\nexport { createDatanova } from './createDatanova';\nexport { useDatanova } from './hooks/useDatanova';\nexport { useVariant } from './hooks/useVariant';\nexport { DatanovaProvider } from './providers/DatanovaProvider';\nexport {\n  TrackPageView,\n  TrackClick,\n  TrackImpression,\n  TrackSubmit,\n  TrackChange,\n  Experiment,\n  type TrackPageViewProps,\n  type TrackClickProps,\n  type TrackImpressionProps,\n  type TrackSubmitProps,\n  type TrackChangeProps,\n} from './components';\n","{\n  \"name\": \"@datanova/react\",\n  \"version\": \"2.0.0\",\n  \"description\": \"React SDK for event tracking and A/B testing with Datanova\",\n  \"main\": \"dist/index.js\",\n  \"module\": \"dist/index.mjs\",\n  \"types\": \"dist/index.d.ts\",\n  \"exports\": {\n    \".\": {\n      \"types\": \"./dist/index.d.ts\",\n      \"import\": \"./dist/index.mjs\",\n      \"require\": \"./dist/index.js\"\n    }\n  },\n  \"sideEffects\": false,\n  \"files\": [\n    \"dist/\",\n    \"README.md\",\n    \"LICENSE\"\n  ],\n  \"scripts\": {\n    \"build\": \"NODE_ENV=production tsup\",\n    \"dev\": \"NODE_ENV=development tsup --watch\",\n    \"lint\": \"eslint src\",\n    \"tc\": \"tsc --noEmit\",\n    \"format\": \"prettier --write src\",\n    \"test\": \"vitest\",\n    \"test:ui\": \"vitest --ui\",\n    \"test:coverage\": \"vitest --coverage\"\n  },\n  \"publishConfig\": {\n    \"access\": \"public\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/d0-datanova/react-sdk.git\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/d0-datanova/react-sdk/issues\"\n  },\n  \"homepage\": \"https://github.com/d0-datanova/react-sdk#readme\",\n  \"keywords\": [\n    \"analytics\",\n    \"ai\",\n    \"data-analyst\",\n    \"react\",\n    \"react-hooks\",\n    \"event-tracking\",\n    \"ab-testing\"\n  ],\n  \"author\": \"\",\n  \"license\": \"MIT\",\n  \"peerDependencies\": {\n    \"react\": \">=16.8.0\"\n  },\n  \"dependencies\": {\n    \"@datanova/browser\": \"2.0.0\",\n    \"react-intersection-observer\": \"^9.16.0\"\n  },\n  \"devDependencies\": {\n    \"@eslint/js\": \"^9.30.1\",\n    \"@semantic-release/changelog\": \"^6.0.3\",\n    \"@semantic-release/commit-analyzer\": \"^13.0.1\",\n    \"@semantic-release/git\": \"^10.0.1\",\n    \"@semantic-release/release-notes-generator\": \"^14.0.3\",\n    \"@testing-library/jest-dom\": \"^6.6.3\",\n    \"@testing-library/react\": \"^16.3.0\",\n    \"@testing-library/user-event\": \"^14.6.1\",\n    \"@types/node\": \"^24.0.12\",\n    \"@types/react\": \"^19.1.8\",\n    \"@vitest/ui\": \"^3.2.4\",\n    \"conventional-changelog-conventionalcommits\": \"^9.0.0\",\n    \"eslint\": \"^9.30.1\",\n    \"happy-dom\": \"^18.0.1\",\n    \"prettier\": \"^3.6.2\",\n    \"react\": \"^19.1.0\",\n    \"semantic-release\": \"^24.2.6\",\n    \"tsup\": \"^8.5.0\",\n    \"typescript\": \"^5.8.3\",\n    \"typescript-eslint\": \"^8.36.0\",\n    \"vitest\": \"^3.2.4\"\n  }\n}\n","import {\n  Datanova,\n  DatanovaEventsService,\n  DatanovaExperimentsService,\n  EventsService,\n  ExperimentsService,\n} from '@datanova/browser';\nimport { name, version } from '../package.json';\n\n// Overload signatures\nexport function createDatanova(apiKey: string): Datanova;\nexport function createDatanova(config: {\n  eventsService?: EventsService;\n  experimentsService?: ExperimentsService;\n}): Datanova;\n\n/**\n * Create and initialize a Datanova client for React applications\n * @param keyOrServices - Either an SDK key string or configuration object\n * @returns Initialized Datanova instance\n * @example\n * ```javascript\n * import { createReactDatanova } from '@datanova/react';\n *\n * // Simple usage with API key\n * const client = createReactDatanova(\"YOUR_SDK_KEY\");\n *\n * // Advanced usage with custom services\n * const client = createReactDatanova({\n *   eventsService: new DatanovaEventsService(\"YOUR_SDK_KEY\"),\n *   experimentsService: new DatanovaExperimentsService(\"YOUR_SDK_KEY\")\n * });\n * ```\n */\nexport function createDatanova(\n  keyOrServices:\n    | string\n    | {\n        eventsService?: EventsService;\n        experimentsService?: ExperimentsService;\n      }\n): Datanova {\n  const datanova = new Datanova();\n\n  if (typeof keyOrServices === 'string') {\n    datanova.init({\n      eventsService: new DatanovaEventsService(keyOrServices),\n      experimentsService: new DatanovaExperimentsService(keyOrServices),\n      context: {\n        library: {\n          name,\n          version,\n        },\n      },\n    });\n  } else {\n    datanova.init({\n      eventsService: keyOrServices.eventsService,\n      experimentsService: keyOrServices.experimentsService,\n      context: {\n        library: {\n          name,\n          version,\n        },\n      },\n    });\n  }\n\n  return datanova;\n}\n","'use client';\n\nimport { ReactNode, createContext } from 'react';\nimport { Datanova } from '@datanova/browser';\n\n/**\n * Props for the DatanovaProvider component\n */\ninterface DatanovaProviderProps {\n  datanova: Datanova;\n  children: ReactNode;\n}\n\nexport type DatanovaContextValue = Datanova;\n\nexport const DatanovaContext = createContext<DatanovaContextValue | null>(null);\n\n/**\n * Provider component that provides Datanova tracking methods to child components.\n * Must be placed at the root of your component tree.\n *\n * @remarks\n * The DatanovaProvider uses React Context to make the Datanova instance available\n * throughout your application. Initialize the Datanova instance outside of your\n * component tree to prevent re-initialization on re-renders.\n *\n * @example\n * Basic usage with SDK key:\n * ```jsx\n * import { createReactDatanova, DatanovaProvider } from '@datanova/react';\n *\n * // Simple initialization with SDK key\n * const datanova = createReactDatanova(\"your-sdk-key\");\n *\n * function App() {\n *   return (\n *     <DatanovaProvider datanova={datanova}>\n *       <YourApp />\n *     </DatanovaProvider>\n *   );\n * }\n * ```\n *\n * @example\n * Advanced usage with custom services:\n * ```jsx\n * import { createReactDatanova, DatanovaProvider } from '@datanova/react';\n * import { DatanovaEventsService, DatanovaExperimentsService } from '@datanova/browser';\n *\n * // Custom configuration with specific services\n * const datanova = createReactDatanova({\n *   eventsService: new YourEventsService(),\n *   experimentsService: new YourExperimentsService()\n * });\n *\n * function App() {\n *   return (\n *     <DatanovaProvider datanova={datanova}>\n *       <YourApp />\n *     </DatanovaProvider>\n *   );\n * }\n * ```\n *\n * @example\n * Development usage with ConsoleEventsService:\n * ```jsx\n * import { createReactDatanova, DatanovaProvider } from '@datanova/react';\n * import { ConsoleEventsService } from '@datanova/browser';\n *\n * // Use ConsoleEventsService for development/debugging\n * const datanova = createReactDatanova({\n *   eventsService: new ConsoleEventsService()\n * });\n *\n * function App() {\n *   return (\n *     <DatanovaProvider datanova={datanova}>\n *       <YourApp />\n *     </DatanovaProvider>\n *   );\n * }\n * ```\n *\n * @param props - The provider props\n * @param props.datanova - The Datanova instance to provide to child components\n * @param props.children - The child components that will have access to the Datanova instance\n */\nexport function DatanovaProvider({ datanova, children }: DatanovaProviderProps) {\n  return <DatanovaContext.Provider value={datanova}>{children}</DatanovaContext.Provider>;\n}\n","'use client';\n\nimport { useContext } from 'react';\nimport { DatanovaContext } from '../providers/DatanovaProvider';\n\n/**\n * Hook to access Datanova analytics tracking methods.\n * Must be used within a DatanovaProvider component.\n *\n * @returns Object containing track, trackClick, trackPageView, trackImpression, trackSubmit, trackChange, identify, and reset methods\n *\n * @example\n * ```jsx\n * import { useDatanova } from '@datanova/react';\n *\n * function MyComponent() {\n *   const { trackClick, identify, reset } = useDatanova();\n *\n *   const handleClick = () => {\n *     trackClick('Button Clicked', { buttonId: 'submit' });\n *   };\n *\n *   const handleLogin = (userId, plan) => {\n *     // Simple identify with just userId\n *     identify(userId);\n *\n *     // Or with user properties (v1.7.0+)\n *     identify(userId, { plan });\n *   };\n *\n *   const handleLogout = () => {\n *     reset();\n *   };\n *\n *   return <button onClick={handleClick}>Track Event</button>;\n * }\n * ```\n *\n * @throws {Error} If used outside of a DatanovaProvider\n */\nexport function useDatanova() {\n  const context = useContext(DatanovaContext);\n\n  if (!context) {\n    throw new Error('useDatanova must be used within a DatanovaProvider');\n  }\n\n  return {\n    trackClick: context.trackClick,\n    trackPageView: context.trackPageView,\n    trackImpression: context.trackImpression,\n    trackSubmit: context.trackSubmit,\n    trackChange: context.trackChange,\n    identify: context.identify,\n    reset: context.reset,\n  };\n}\n","'use client';\n\nimport { useContext, useEffect, useState } from 'react';\nimport { Variant } from '@datanova/browser';\nimport { DatanovaContext } from '../providers/DatanovaProvider';\n\ntype ExperimentState =\n  | { isLoading: true; data: undefined; error: null }\n  | { isLoading: false; data: Variant; error: null }\n  | { isLoading: false; data: 'control'; error: Error };\n\n/**\n * Hook to get and track A/B test experiment variants.\n * Automatically tracks experiment exposure and manages loading/error states.\n *\n * SSR-safe: During server-side rendering, this hook returns null\n * to avoid hydration mismatches. The actual variant is fetched client-side.\n *\n * @param experimentId - The numeric ID of the experiment\n * @returns Object containing variant, loading state, and error\n *\n * @example\n * ```jsx\n * import { useVariant } from '@datanova/react';\n *\n * function MyComponent() {\n *   const { loading, data, error } = useVariant({ experimentId: 20 });\n *\n *   if (loading) return <div>Loading...</div>;\n *   if (error) return <div>Error: {error.message}</div>;\n *\n *   return (\n *     <div>\n *       {data === 'variant' ? (\n *         <NewFeature />\n *       ) : (\n *         <OldFeature />\n *       )}\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useVariant({ experimentId }: { experimentId: number }): ExperimentState {\n  const client = useContext(DatanovaContext);\n  const [state, setState] = useState<ExperimentState>({\n    isLoading: true,\n    data: undefined,\n    error: null,\n  });\n\n  useEffect(() => {\n    if (!client) {\n      setState({\n        isLoading: false,\n        data: 'control',\n        error: new Error('useVariant must be used within a DatanovaProvider'),\n      });\n      return;\n    }\n\n    let cancelled = false;\n\n    async function fetchVariant() {\n      try {\n        setState({ isLoading: true, data: undefined, error: null });\n        const variant = await client!.getVariant(experimentId);\n\n        if (!cancelled) {\n          setState({\n            isLoading: false,\n            data: variant,\n            error: null,\n          });\n        }\n      } catch (err) {\n        if (!cancelled) {\n          setState({\n            isLoading: false,\n            data: 'control',\n            error: err instanceof Error ? err : new Error('Failed to load experiment'),\n          });\n        }\n      }\n    }\n\n    if (typeof window !== 'undefined') {\n      fetchVariant();\n    } else {\n      setState({ isLoading: false, data: 'control', error: null });\n    }\n\n    return () => {\n      cancelled = true;\n    };\n  }, [experimentId, client]);\n\n  return state;\n}\n","'use client';\n\nimport { useEffect } from 'react';\nimport { useDatanova } from '../hooks/useDatanova';\n\n/**\n * Props for the TrackPageView component\n */\nexport interface TrackPageViewProps {\n  /** Event name to track when the component mounts */\n  eventName: string;\n  /** Optional properties to include with the event */\n  properties?: Record<string, unknown>;\n}\n\n/**\n * Component that tracks a page view event when it mounts.\n * The browser SDK automatically captures page metadata like URL, title, and referrer.\n *\n * @example\n * ```jsx\n * import { TrackPageView } from '@datanova/react';\n *\n * function HomePage() {\n *   return (\n *     <>\n *       <TrackPageView eventName=\"Home Page Viewed\" />\n *       <h1>Welcome to our site</h1>\n *     </>\n *   );\n * }\n * ```\n *\n * @example\n * ```jsx\n * // With additional properties\n * function ProductPage({ productId }) {\n *   return (\n *     <>\n *       <TrackPageView\n *         eventName=\"Product Page Viewed\"\n *         properties={{ productId, category: 'electronics' }}\n *       />\n *       <ProductDetails />\n *     </>\n *   );\n * }\n * ```\n */\nexport function TrackPageView({ eventName, properties }: TrackPageViewProps) {\n  const { trackPageView } = useDatanova();\n\n  useEffect(() => {\n    trackPageView(eventName, properties);\n  }, [eventName, properties, trackPageView]);\n\n  return null;\n}\n","'use client';\n\nimport { MouseEvent, ReactElement, cloneElement, isValidElement } from 'react';\nimport { useDatanova } from '../hooks/useDatanova';\n\n/**\n * Props for the TrackClick component\n */\nexport interface TrackClickProps {\n  children: ReactElement<{ onClick?: (event: MouseEvent) => void }>;\n  /** Event name to track when the element is clicked */\n  eventName: string;\n  /** Optional properties to include with the event */\n  properties?: Record<string, unknown>;\n}\n\n/**\n * Component that tracks click events on its child element.\n * Wraps a single React element and tracks when it's clicked, preserving any existing onClick handler.\n *\n * @example\n * ```jsx\n * import { TrackClick } from '@datanova/react';\n *\n * function CTAButton() {\n *   return (\n *     <TrackClick eventName=\"CTA Clicked\" properties={{ location: 'header' }}>\n *       <button onClick={() => console.log('Original handler')}>\n *         Get Started\n *       </button>\n *     </TrackClick>\n *   );\n * }\n * ```\n *\n * @throws {Error} If children is not a valid React element\n */\nexport function TrackClick({ children, eventName, properties }: TrackClickProps) {\n  const { trackClick } = useDatanova();\n\n  if (!isValidElement(children)) {\n    throw new Error('TrackClick must be used with a valid React element');\n  }\n\n  const originalOnClick = children.props.onClick;\n\n  const handleClick = (event: MouseEvent) => {\n    trackClick(eventName, properties);\n    if (originalOnClick) {\n      originalOnClick(event);\n    }\n  };\n\n  return cloneElement(children, { onClick: handleClick });\n}\n","'use client';\n\nimport { ReactNode } from 'react';\nimport { InView } from 'react-intersection-observer';\nimport { useDatanova } from '../hooks/useDatanova';\n\n/**\n * Props for the TrackImpression component\n */\nexport interface TrackImpressionProps {\n  children: ReactNode;\n  /** Event name to track when the element comes into view */\n  eventName: string;\n  /** Optional properties to include with the event */\n  properties?: Record<string, unknown>;\n  /** Percentage of element that must be visible to trigger (0-1). Default: 0.5 (50%) */\n  threshold?: number;\n  /** Whether to track only the first impression. Default: true */\n  triggerOnce?: boolean;\n}\n\n/**\n * Component that tracks when its children come into the viewport using Intersection Observer.\n * Useful for tracking impressions of content blocks, images, or any visual elements.\n *\n * @example\n * ```jsx\n * import { TrackImpression } from '@datanova/react';\n *\n * function HeroSection() {\n *   return (\n *     <TrackImpression eventName=\"Hero Section Viewed\">\n *       <section className=\"hero\">\n *         <h1>Welcome to Our Product</h1>\n *         <p>Start your journey today</p>\n *       </section>\n *     </TrackImpression>\n *   );\n * }\n * ```\n *\n * @example\n * ```jsx\n * // Track when 80% of element is visible, multiple times\n * <TrackImpression\n *   eventName=\"Product Card Viewed\"\n *   properties={{ productId: '123' }}\n *   threshold={0.8}\n *   triggerOnce={false}\n * >\n *   <ProductCard />\n * </TrackImpression>\n * ```\n *\n * @example\n * ```jsx\n * // Track lazy-loaded content\n * <TrackImpression\n *   eventName=\"Comments Section Viewed\"\n *   threshold={0.1} // Track when just 10% is visible\n * >\n *   <LazyComments />\n * </TrackImpression>\n * ```\n */\nexport function TrackImpression({\n  children,\n  eventName,\n  properties,\n  threshold = 0.5,\n  triggerOnce = true,\n}: TrackImpressionProps) {\n  const { trackImpression } = useDatanova();\n\n  return (\n    <InView\n      onChange={(inView) => {\n        if (inView) {\n          trackImpression(eventName, properties);\n        }\n      }}\n      threshold={threshold}\n      triggerOnce={triggerOnce}\n    >\n      {children}\n    </InView>\n  );\n}\n","'use client';\n\nimport { FormEvent, ReactElement, cloneElement, isValidElement } from 'react';\nimport { useDatanova } from '../hooks/useDatanova';\n\n/**\n * Props for the TrackSubmit component\n */\nexport interface TrackSubmitProps {\n  children: ReactElement<{ onSubmit?: (event: FormEvent) => void }>;\n  /** Event name to track when the form is submitted */\n  eventName: string;\n  /** Optional properties to include with the event */\n  properties?: Record<string, unknown>;\n}\n\n/**\n * Component that tracks submit events on form elements.\n * Wraps a form element and tracks when it's submitted, preserving any existing onSubmit handler.\n *\n * @example\n * ```jsx\n * import { TrackSubmit } from '@datanova/react';\n *\n * function ContactForm() {\n *   return (\n *     <TrackSubmit eventName=\"Contact Form Submitted\" properties={{ type: 'inquiry' }}>\n *       <form onSubmit={(e) => { e.preventDefault(); console.log('Form submitted'); }}>\n *         <input type=\"email\" name=\"email\" required />\n *         <button type=\"submit\">Submit</button>\n *       </form>\n *     </TrackSubmit>\n *   );\n * }\n * ```\n *\n * @throws {Error} If children is not a valid React element\n */\nexport function TrackSubmit({ children, eventName, properties }: TrackSubmitProps) {\n  const { trackSubmit } = useDatanova();\n\n  if (!isValidElement(children)) {\n    throw new Error('TrackSubmit must be used with a valid React element');\n  }\n\n  const originalOnSubmit = children.props.onSubmit;\n\n  const handleSubmit = (event: FormEvent) => {\n    trackSubmit(eventName, properties);\n    originalOnSubmit?.(event);\n  };\n\n  return cloneElement(children, { onSubmit: handleSubmit });\n}\n","'use client';\n\nimport { ReactElement, cloneElement, isValidElement } from 'react';\nimport { useDatanova } from '../hooks/useDatanova';\n\n/**\n * Props for the TrackChange component\n */\nexport interface TrackChangeProps {\n  children: ReactElement<{ onChange?: (value: unknown) => void }>;\n  /** Event name to track when the element value changes */\n  eventName: string;\n  /** Optional properties to include with the event */\n  properties?: Record<string, unknown>;\n}\n\n/**\n * Component that tracks change events on form elements.\n * Wraps a form element (select, input, etc.) and tracks when its value changes,\n * preserving any existing onChange handler.\n *\n * @example\n * ```jsx\n * import { TrackChange } from '@datanova/react';\n *\n * function FilterForm() {\n *   return (\n *     <TrackChange eventName=\"Date Filter Changed\" properties={{ filter: 'date' }}>\n *       <select onChange={(e) => console.log('Selected:', e.target.value)}>\n *         <option value=\"7d\">Last 7 days</option>\n *         <option value=\"30d\">Last 30 days</option>\n *       </select>\n *     </TrackChange>\n *   );\n * }\n * ```\n *\n * @throws {Error} If children is not a valid React element\n */\nexport function TrackChange({ children, eventName, properties }: TrackChangeProps) {\n  const { trackChange } = useDatanova();\n\n  if (!isValidElement(children)) {\n    throw new Error('TrackChange must be used with a valid React element');\n  }\n\n  const originalOnChange = children.props.onChange;\n\n  const handleChange = (\n    event: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement> | unknown\n  ) => {\n    let value: unknown;\n\n    if (event && typeof event === 'object' && 'target' in event) {\n      value = (event as React.ChangeEvent<HTMLInputElement>).target.value;\n    } else {\n      value = event;\n    }\n\n    trackChange(eventName, {\n      ...properties,\n      value,\n    });\n    originalOnChange?.(event);\n  };\n\n  return cloneElement(children, { onChange: handleChange });\n}\n","'use client';\n\nimport { ReactNode } from 'react';\nimport { useVariant } from '../hooks/useVariant';\n\ninterface ExperimentProps {\n  /** The numeric ID of the experiment */\n  experimentId: number;\n  /** Content to show for the control variant */\n  control: ReactNode;\n  /** Content to show for the variant */\n  variant: ReactNode;\n  /** Optional content to show while loading */\n  loading?: ReactNode;\n  /** Optional content to show on error */\n  error?: ReactNode;\n}\n\n/**\n * Component for declarative A/B testing.\n * Automatically handles experiment assignment and tracks exposure.\n *\n * @example\n * ```jsx\n * import { Experiment } from '@datanova/react';\n *\n * function HomePage() {\n *   return (\n *     <Experiment\n *       experimentId={20}\n *       control={<OldHero />}\n *       variant={<NewHero />}\n *     />\n *   );\n * }\n * ```\n *\n * @example With loading and error states\n * ```jsx\n * <Experiment\n *   experimentId={20}\n *   control={<OldCheckout />}\n *   variant={<NewCheckout />}\n *   loading={<CheckoutSkeleton />}\n *   error={<OldCheckout />} // Fallback to control on error\n * />\n * ```\n */\nexport function Experiment({\n  experimentId,\n  control,\n  variant: variantContent,\n  loading: loadingContent,\n  error: errorContent,\n}: ExperimentProps) {\n  const { data, isLoading, error } = useVariant({ experimentId });\n\n  if (isLoading) {\n    return <>{loadingContent ?? null}</>;\n  }\n\n  if (error) {\n    return <>{errorContent ?? control}</>;\n  }\n\n  const content = data === 'variant' ? variantContent : control;\n\n  return <>{content}</>;\n}\n"]}