{"version":3,"file":"react.mjs","names":[],"sources":["../src/react.tsx"],"sourcesContent":["import { createContext, useCallback, useContext, useEffect, useRef } from 'react';\nimport type { ReactNode } from 'react';\n\nimport { LayersReactNative } from './index.js';\nimport type { ConsentState, EventProperties, LayersRNConfig } from './index.js';\n\nconst LayersRNContext = createContext<LayersReactNative | null>(null);\n\nexport interface LayersRNProviderProps {\n  config: LayersRNConfig;\n  children: ReactNode;\n}\n\n/**\n * Provides a LayersReactNative instance to the React component tree.\n * Initializes the client on mount and shuts it down on unmount.\n *\n * @example\n * ```tsx\n * import { LayersRNProvider } from '@layers/react-native/react';\n *\n * function App() {\n *   return (\n *     <LayersRNProvider config={{ appId: 'app', environment: 'production' }}>\n *       <MyApp />\n *     </LayersRNProvider>\n *   );\n * }\n * ```\n */\nexport function LayersRNProvider({ config, children }: LayersRNProviderProps) {\n  const clientRef = useRef<LayersReactNative | null>(null);\n\n  if (clientRef.current === null) {\n    clientRef.current = new LayersReactNative(config);\n  }\n\n  useEffect(() => {\n    const client = clientRef.current;\n    if (!client) return;\n\n    void client.init();\n\n    return () => {\n      client.shutdown();\n      // The ref deliberately keeps the client. React 18 StrictMode runs\n      // mount → cleanup → mount WITHOUT re-rendering in between, so nulling it\n      // here made the second effect bail on `if (!client) return` while the\n      // children still held the client captured at render — a shut-down SDK\n      // that never initialized again. shutdown() releases the init latch, so\n      // re-running init() on this same instance brings it back up.\n    };\n    // Config is intentionally captured once at mount time via useRef above.\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, []);\n\n  return <LayersRNContext.Provider value={clientRef.current}>{children}</LayersRNContext.Provider>;\n}\n\n/**\n * Returns the LayersReactNative instance from the nearest LayersRNProvider.\n * Throws if used outside a LayersRNProvider.\n */\nexport function useLayers(): LayersReactNative {\n  const client = useContext(LayersRNContext);\n  if (!client) {\n    throw new Error('useLayers must be used within a <LayersRNProvider>');\n  }\n  return client;\n}\n\n/**\n * Returns a stable, memoized track function bound to the current LayersReactNative instance.\n *\n * @example\n * ```tsx\n * import { useTrack } from '@layers/react-native/react';\n *\n * function PurchaseButton() {\n *   const track = useTrack();\n *   return <Button onPress={() => track('purchase_tap', { item: 'premium' })} title=\"Buy\" />;\n * }\n * ```\n */\nexport function useTrack(): (eventName: string, properties?: EventProperties) => void {\n  const client = useLayers();\n  return useCallback(\n    (eventName: string, properties?: EventProperties) => {\n      void client.track(eventName, properties);\n    },\n    [client]\n  );\n}\n\n/**\n * Returns a stable, memoized screen function bound to the current LayersReactNative instance.\n *\n * @example\n * ```tsx\n * import { useScreen } from '@layers/react-native/react';\n * import { useEffect } from 'react';\n *\n * function HomeScreen() {\n *   const screen = useScreen();\n *   useEffect(() => { screen('home'); }, [screen]);\n *   return <View />;\n * }\n * ```\n */\nexport function useScreen(): (screenName: string, properties?: EventProperties) => void {\n  const client = useLayers();\n  return useCallback(\n    (screenName: string, properties?: EventProperties) => {\n      void client.screen(screenName, properties);\n    },\n    [client]\n  );\n}\n\n/**\n * Returns a stable, memoized identify function that sets the app user ID.\n * Pass `undefined` to clear the current user ID.\n *\n * @example\n * ```tsx\n * import { useIdentify } from '@layers/react-native/react';\n *\n * function LoginScreen() {\n *   const identify = useIdentify();\n *   const onLogin = (userId: string) => identify(userId);\n *   const onLogout = () => identify(undefined);\n * }\n * ```\n */\nexport function useIdentify(): (userId: string | undefined) => void {\n  const client = useLayers();\n  return useCallback(\n    (userId: string | undefined) => {\n      if (userId) {\n        client.setAppUserId(userId);\n      } else {\n        client.clearAppUserId();\n      }\n    },\n    [client]\n  );\n}\n\n/**\n * Returns stable, memoized consent functions bound to the current LayersReactNative instance.\n *\n * @example\n * ```tsx\n * import { useConsent } from '@layers/react-native/react';\n *\n * function ConsentScreen() {\n *   const { setConsent, getConsentState } = useConsent();\n *   return (\n *     <Button\n *       onPress={() => setConsent({ analytics: true, advertising: false })}\n *       title=\"Accept Analytics Only\"\n *     />\n *   );\n * }\n * ```\n */\nexport function useConsent(): {\n  setConsent: (consent: ConsentState) => void;\n  getConsentState: () => ConsentState;\n} {\n  const client = useLayers();\n  const setConsent = useCallback(\n    (consent: ConsentState) => {\n      void client.setConsent(consent);\n    },\n    [client]\n  );\n  const getConsentState = useCallback(() => {\n    return client.getConsentState();\n  }, [client]);\n  return { setConsent, getConsentState };\n}\n"],"mappings":";;;;;;;AAMA,MAAM,kBAAkB,cAAwC,KAAK;;;;;;;;;;;;;;;;;;AAwBrE,SAAgB,iBAAiB,EAAE,QAAQ,YAAmC;CAC5E,MAAM,YAAY,OAAiC,KAAK;AAExD,KAAI,UAAU,YAAY,KACxB,WAAU,UAAU,IAAI,kBAAkB,OAAO;AAGnD,iBAAgB;EACd,MAAM,SAAS,UAAU;AACzB,MAAI,CAAC,OAAQ;AAEb,EAAK,OAAO,MAAM;AAElB,eAAa;AACX,UAAO,UAAU;;IAUlB,EAAE,CAAC;AAEN,QAAO,oBAAC,gBAAgB;EAAS,OAAO,UAAU;EAAU;GAAoC;;;;;;AAOlG,SAAgB,YAA+B;CAC7C,MAAM,SAAS,WAAW,gBAAgB;AAC1C,KAAI,CAAC,OACH,OAAM,IAAI,MAAM,qDAAqD;AAEvE,QAAO;;;;;;;;;;;;;;;AAgBT,SAAgB,WAAsE;CACpF,MAAM,SAAS,WAAW;AAC1B,QAAO,aACJ,WAAmB,eAAiC;AACnD,EAAK,OAAO,MAAM,WAAW,WAAW;IAE1C,CAAC,OAAO,CACT;;;;;;;;;;;;;;;;;AAkBH,SAAgB,YAAwE;CACtF,MAAM,SAAS,WAAW;AAC1B,QAAO,aACJ,YAAoB,eAAiC;AACpD,EAAK,OAAO,OAAO,YAAY,WAAW;IAE5C,CAAC,OAAO,CACT;;;;;;;;;;;;;;;;;AAkBH,SAAgB,cAAoD;CAClE,MAAM,SAAS,WAAW;AAC1B,QAAO,aACJ,WAA+B;AAC9B,MAAI,OACF,QAAO,aAAa,OAAO;MAE3B,QAAO,gBAAgB;IAG3B,CAAC,OAAO,CACT;;;;;;;;;;;;;;;;;;;;AAqBH,SAAgB,aAGd;CACA,MAAM,SAAS,WAAW;AAU1B,QAAO;EAAE,YATU,aAChB,YAA0B;AACzB,GAAK,OAAO,WAAW,QAAQ;KAEjC,CAAC,OAAO,CACT;EAIoB,iBAHG,kBAAkB;AACxC,UAAO,OAAO,iBAAiB;KAC9B,CAAC,OAAO,CAAC;EAC0B"}