{"version":3,"file":"store.mjs","names":[],"sources":["../../../../@mongez/react-atom/src/store.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n  AtomStore,\n  type Atom,\n  createAtomStore,\n} from \"@mongez/atom\";\nimport React, { createContext, useContext, useEffect, useState } from \"react\";\n\n/**\n * React context that holds the active atom store. Components that read or\n * write atoms via the React hooks resolve the store-scoped clone from this\n * context. When the context is null (no provider mounted), hooks fall back\n * to the module-level singleton atom, which is the right behavior for a\n * client-only SPA.\n */\nexport const AtomStoreContext = createContext<AtomStore | null>(null);\n\nexport type AtomStoreProviderProps = {\n  /**\n   * An existing store to use. If omitted, the provider creates its own\n   * fresh store on first render. Pass an externally created store when you\n   * need to mutate it outside React (e.g. during Next.js data loading).\n   */\n  store?: AtomStore;\n\n  /**\n   * Atom templates to pre-register in the store. Pre-registration is\n   * required when you want the initial values from `initialValues` to apply\n   * to atoms that have not yet been used in React.\n   */\n  initialAtoms?: Atom<any>[];\n\n  /**\n   * Initial values keyed by atom key. Applied silently (no update event)\n   * so the first render of subscribers sees the hydrated value.\n   *\n   * If an atom in this map has not been pre-registered via `initialAtoms`\n   * or used yet, its value is queued and applied the first time that atom\n   * enters the store via a React hook.\n   */\n  initialValues?: Record<string, unknown>;\n\n  children: React.ReactNode;\n};\n\n/**\n * Provider that scopes atom reads and writes to a request-local `AtomStore`.\n *\n * Wrap the root of your component tree (or any subtree) with this provider\n * to give that subtree its own isolated copy of every atom's state. This is\n * the supported pattern for SSR in Next.js, Remix, and TanStack Start —\n * each request creates its own store, so concurrent requests cannot see\n * each other's state.\n *\n * Without a provider, atoms fall back to the module-level singleton (the\n * historical client-only behavior).\n */\nexport function AtomStoreProvider({\n  store,\n  initialAtoms,\n  initialValues,\n  children,\n}: AtomStoreProviderProps) {\n  const [activeStore] = useState<AtomStore>(() => {\n    const next = store ?? createAtomStore();\n\n    if (initialAtoms) {\n      for (const atomTemplate of initialAtoms) {\n        next.use(atomTemplate);\n      }\n    }\n\n    if (initialValues) {\n      next.hydrate(initialValues);\n    }\n\n    return next;\n  });\n\n  useEffect(() => {\n    return () => {\n      // Only auto-destroy stores that the provider itself created. Stores\n      // passed in via props are owned by the caller.\n      if (!store) {\n        activeStore.destroy();\n      }\n    };\n  }, [activeStore, store]);\n\n  return (\n    <AtomStoreContext.Provider value={activeStore}>\n      {children}\n    </AtomStoreContext.Provider>\n  );\n}\n\n/**\n * Read the active atom store. Returns null when no `<AtomStoreProvider>` is\n * mounted in the tree above this component.\n */\nexport function useAtomStore(): AtomStore | null {\n  return useContext(AtomStoreContext);\n}\n\n/**\n * Resolve an atom for the current render context.\n *\n * Two call shapes:\n *\n * - `useAtom(template)` — pass an atom you imported. Returns the\n *   store-scoped clone if a `<AtomStoreProvider>` is mounted above; falls\n *   back to the template itself otherwise. Use this when you need to call\n *   action methods (`startLoading()`, `open()`, etc.) from event handlers\n *   in an SSR-safe way.\n *\n * - `useAtom(key)` — pass a string key. Returns the scoped atom registered\n *   under that key in the active store, or `undefined` when no provider is\n *   mounted or the key has not entered the store. This is a legacy escape\n *   hatch; prefer the template form.\n */\nexport function useAtom<V, A extends Record<string, any> = {}>(\n  template: Atom<V, A>\n): Atom<V, A>;\nexport function useAtom<V = any>(key: string): Atom<V> | undefined;\nexport function useAtom(arg: Atom<any> | string): Atom<any> | undefined {\n  const store = useContext(AtomStoreContext);\n  if (typeof arg === \"string\") {\n    return store?.get(arg);\n  }\n  return store ? store.use(arg) : arg;\n}\n"],"mappings":";;;;;;;;;;;;;;AAgBA,MAAa,mBAAmB,cAAgC,IAAI;;;;;;;;;;;;;AA0CpE,SAAgB,kBAAkB,EAChC,OACA,cACA,eACA,YACyB;CACzB,MAAM,CAAC,eAAe,eAA0B;EAC9C,MAAM,OAAO,SAAS,gBAAgB;EAEtC,IAAI,cACF,KAAK,MAAM,gBAAgB,cACzB,KAAK,IAAI,YAAY;EAIzB,IAAI,eACF,KAAK,QAAQ,aAAa;EAG5B,OAAO;CACT,CAAC;CAED,gBAAgB;EACd,aAAa;GAGX,IAAI,CAAC,OACH,YAAY,QAAQ;EAExB;CACF,GAAG,CAAC,aAAa,KAAK,CAAC;CAEvB,OACE,oBAAC,iBAAiB,UAAlB;EAA2B,OAAO;EAC/B;CACwB;AAE/B;;;;;AAMA,SAAgB,eAAiC;CAC/C,OAAO,WAAW,gBAAgB;AACpC;AAsBA,SAAgB,QAAQ,KAAgD;CACtE,MAAM,QAAQ,WAAW,gBAAgB;CACzC,IAAI,OAAO,QAAQ,UACjB,OAAO,OAAO,IAAI,GAAG;CAEvB,OAAO,QAAQ,MAAM,IAAI,GAAG,IAAI;AAClC"}