{"version":3,"sources":["/Users/gwakko/Projects/shared-websocket/dist/sync-react.cjs","../src/adapters/react/sync.ts"],"names":[],"mappings":"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","file":"/Users/gwakko/Projects/shared-websocket/dist/sync-react.cjs","sourcesContent":[null,"import {\n  createContext,\n  useContext,\n  useEffect,\n  useState,\n  useEffectEvent,\n  type ReactNode,\n  createElement,\n} from 'react';\nimport { TabSync } from '../../TabSync';\n\n// ─── Context ─────────────────────────────────────────────\n\nconst TabSyncContext = createContext<TabSync | null>(null);\n\n/**\n * Provider for TabSync — creates instance, auto-disposes on unmount.\n *\n * @example\n * function App() {\n *   return (\n *     <TabSyncProvider channel=\"my-app\">\n *       <Dashboard />\n *     </TabSyncProvider>\n *   );\n * }\n */\nexport interface TabSyncProviderProps {\n  /** BroadcastChannel name (default: \"tab-sync\"). */\n  channel?: string;\n  /** Enable debug logging. */\n  debug?: boolean;\n  children: ReactNode;\n}\n\nexport function TabSyncProvider({ channel, debug, children }: TabSyncProviderProps) {\n  const [sync] = useState(() => new TabSync(channel, { debug }));\n\n  useEffect(() => {\n    return () => sync[Symbol.dispose]();\n  }, [sync]);\n\n  return createElement(TabSyncContext.Provider, { value: sync }, children);\n}\n\n/**\n * Access the TabSync instance from context.\n *\n * @example\n * const sync = useTabSyncContext();\n * sync.set('theme', 'dark');\n */\nexport function useTabSyncContext(): TabSync {\n  const ctx = useContext(TabSyncContext);\n  if (!ctx) {\n    throw new Error('useTabSync must be used within <TabSyncProvider>');\n  }\n  return ctx;\n}\n\n// ─── Hooks ───────────────────────────────────────────────\n\n/**\n * Two-way state sync across browser tabs — like useState but shared.\n * - Without callback: returns [value, setter] synced across tabs.\n * - With callback: also calls your handler on every change (side effects).\n *\n * @example\n * // Shared state — updates propagate to all tabs\n * const [theme, setTheme] = useTabSync('theme', 'light');\n * <button onClick={() => setTheme('dark')}>Dark mode</button>\n *\n * @example\n * // With side effect callback\n * const [cart, setCart] = useTabSync('cart', { items: [] }, (cart) => {\n *   document.title = `Cart (${cart.items.length})`;\n * });\n *\n * @example\n * // Form state synced across tabs\n * const [draft, setDraft] = useTabSync('email-draft', '');\n * <textarea value={draft} onChange={(e) => setDraft(e.target.value)} />\n */\nexport function useTabSync<T>(\n  key: string,\n  initialValue: T,\n  callback?: (value: T) => void,\n): [T, (value: T) => void] {\n  const sync = useTabSyncContext();\n  const [value, setValue] = useState<T>(() => sync.get<T>(key) ?? initialValue);\n\n  const onSync = useEffectEvent((synced: T) => {\n    setValue(synced);\n    callback?.(synced);\n  });\n\n  useEffect(() => {\n    return sync.on<T>(key, onSync);\n  }, [sync, key]);\n\n  const setAndSync = useEffectEvent((newValue: T) => {\n    setValue(newValue);\n    sync.set(key, newValue);\n  });\n\n  return [value, setAndSync];\n}\n\n/**\n * Read-only subscription to a synced key. Returns undefined until first set.\n *\n * @example\n * const theme = useTabSyncValue<string>('theme');\n * <div className={theme === 'dark' ? 'dark' : 'light'} />\n */\nexport function useTabSyncValue<T>(key: string): T | undefined {\n  const sync = useTabSyncContext();\n  const [value, setValue] = useState<T | undefined>(() => sync.get<T>(key));\n\n  const onSync = useEffectEvent((synced: T) => {\n    setValue(synced);\n  });\n\n  useEffect(() => {\n    return sync.on<T>(key, onSync);\n  }, [sync, key]);\n\n  return value;\n}\n\n/**\n * Fire-and-forget listener for a synced key. No state, no return value.\n *\n * @example\n * useTabSyncCallback<string>('theme', (theme) => {\n *   document.documentElement.setAttribute('data-theme', theme);\n * });\n *\n * @example\n * useTabSyncCallback<Cart>('cart', (cart) => {\n *   analytics.track('cart_updated', { count: cart.items.length });\n * });\n */\nexport function useTabSyncCallback<T>(key: string, callback: (value: T) => void): void {\n  const sync = useTabSyncContext();\n\n  const handler = useEffectEvent((value: T) => {\n    callback(value);\n  });\n\n  useEffect(() => {\n    return sync.on<T>(key, handler);\n  }, [sync, key]);\n}\n"]}