{"version":3,"file":"use-push-subscription.cjs","names":[],"sources":["../../src/push/use-push-subscription.ts"],"sourcesContent":["/* eslint-disable react-hooks/refs -- the ref is read inside deferred callbacks, not during render */\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useLatestRef } from \"@/hooks/use-latest-ref\";\nimport { WebPushClient, type WebPushClientConfig } from \"./web-push-client\";\nimport { isPushSupported } from \"./utils\";\n\nexport interface UsePushSubscriptionResult {\n    /** True when the browser exposes the Push + Notification APIs. */\n    supported: boolean;\n    /** Current `Notification.permission` value, or `\"unsupported\"`. */\n    permission: NotificationPermission | \"unsupported\";\n    /** True when a subscription is active on this device. */\n    subscribed: boolean;\n    /** True while a subscribe/unsubscribe call is in-flight. */\n    loading: boolean;\n    /** Last error thrown by subscribe/unsubscribe, if any. */\n    error: Error | null;\n    subscribe: () => Promise<void>;\n    unsubscribe: () => Promise<void>;\n    /** Re-read the current subscription/permission state from the browser. */\n    refresh: () => Promise<void>;\n}\n\n/**\n * React hook around {@link WebPushClient}. Tracks subscription, permission and\n * loading state; exposes imperative `subscribe`/`unsubscribe` actions.\n *\n * The hook does NOT register the service worker — the host app must do that\n * (e.g. via `vite-plugin-pwa` or a manual `navigator.serviceWorker.register`).\n *\n * @example\n * const push = usePushSubscription({\n *     vapidPublicKey: import.meta.env.VITE_VAPID_PUBLIC_KEY,\n *     onSubscribe: (sub) => api.post(\"/webpush/subscribe\", { body: sub }),\n *     onUnsubscribe: () => api.delete(\"/webpush/my\"),\n * });\n */\nexport function usePushSubscription(config: WebPushClientConfig): UsePushSubscriptionResult {\n    const configRef = useLatestRef(config);\n\n    const client = useMemo(\n        () =>\n            new WebPushClient({\n                vapidPublicKey: config.vapidPublicKey,\n                onSubscribe: (sub) => configRef.current.onSubscribe(sub),\n                onUnsubscribe: (sub) => configRef.current.onUnsubscribe?.(sub),\n                getRegistration: config.getRegistration,\n            }),\n        [config.vapidPublicKey, config.getRegistration, configRef],\n    );\n\n    const [supported] = useState<boolean>(() => isPushSupported());\n    const [permission, setPermission] = useState<NotificationPermission | \"unsupported\">(() =>\n        client.permission(),\n    );\n    const [subscribed, setSubscribed] = useState<boolean>(false);\n    const [loading, setLoading] = useState<boolean>(false);\n    const [error, setError] = useState<Error | null>(null);\n\n    const refresh = useCallback(async () => {\n        if (!supported) return;\n        setPermission(client.permission());\n        try {\n            const active = await client.isSubscribed();\n            setSubscribed(active);\n        } catch (err) {\n            setError(err instanceof Error ? err : new Error(String(err)));\n        }\n    }, [client, supported]);\n\n    useEffect(() => {\n        void refresh();\n    }, [refresh]);\n\n    const subscribe = useCallback(async () => {\n        if (!supported) return;\n        setLoading(true);\n        setError(null);\n        try {\n            await client.subscribe();\n            setSubscribed(true);\n            setPermission(client.permission());\n        } catch (err) {\n            setError(err instanceof Error ? err : new Error(String(err)));\n            throw err;\n        } finally {\n            setLoading(false);\n        }\n    }, [client, supported]);\n\n    const unsubscribe = useCallback(async () => {\n        if (!supported) return;\n        setLoading(true);\n        setError(null);\n        try {\n            await client.unsubscribe();\n            setSubscribed(false);\n        } catch (err) {\n            setError(err instanceof Error ? err : new Error(String(err)));\n            throw err;\n        } finally {\n            setLoading(false);\n        }\n    }, [client, supported]);\n\n    return {\n        supported,\n        permission,\n        subscribed,\n        loading,\n        error,\n        subscribe,\n        unsubscribe,\n        refresh,\n    };\n}\n"],"mappings":"kIAqCA,SAAgB,EAAoB,EAAwD,CACxF,IAAM,EAAY,EAAA,aAAa,CAAM,EAE/B,GAAA,EAAS,EAAA,QAAA,KAEP,IAAI,EAAA,cAAc,CACd,eAAgB,EAAO,eACvB,YAAc,GAAQ,EAAU,QAAQ,YAAY,CAAG,EACvD,cAAgB,GAAQ,EAAU,QAAQ,gBAAgB,CAAG,EAC7D,gBAAiB,EAAO,eAC5B,CAAC,EACL,CAAC,EAAO,eAAgB,EAAO,gBAAiB,CAAS,CAC7D,EAEM,CAAC,IAAA,EAAa,EAAA,SAAA,KAAwB,EAAA,gBAAgB,CAAC,EACvD,CAAC,EAAY,IAAA,EAAiB,EAAA,SAAA,KAChC,EAAO,WAAW,CACtB,EACM,CAAC,EAAY,IAAA,EAAiB,EAAA,SAAA,CAAkB,EAAK,EACrD,CAAC,EAAS,IAAA,EAAc,EAAA,SAAA,CAAkB,EAAK,EAC/C,CAAC,EAAO,IAAA,EAAY,EAAA,SAAA,CAAuB,IAAI,EAE/C,GAAA,EAAU,EAAA,YAAA,CAAY,SAAY,CAC/B,KACL,GAAc,EAAO,WAAW,CAAC,EACjC,GAAI,CACA,IAAM,EAAS,MAAM,EAAO,aAAa,EACzC,EAAc,CAAM,CACxB,OAAS,EAAK,CACV,EAAS,aAAe,MAAQ,EAAU,MAAM,OAAO,CAAG,CAAC,CAAC,CAChE,CANiC,CAOrC,EAAG,CAAC,EAAQ,CAAS,CAAC,EAqCtB,OAnCA,EAAA,EAAA,UAAA,KAAgB,CACZ,EAAa,CACjB,EAAG,CAAC,CAAO,CAAC,EAiCL,CACH,YACA,aACA,aACA,UACA,QACA,WAAA,EArCc,EAAA,YAAA,CAAY,SAAY,CACjC,KAEL,CADA,EAAW,EAAI,EACf,EAAS,IAAI,EACb,GAAI,CACA,MAAM,EAAO,UAAU,EACvB,EAAc,EAAI,EAClB,EAAc,EAAO,WAAW,CAAC,CACrC,OAAS,EAAK,CAEV,MADA,EAAS,aAAe,MAAQ,EAAU,MAAM,OAAO,CAAG,CAAC,CAAC,EACtD,CACV,QAAU,CACN,EAAW,EAAK,CACpB,CAVa,CAWjB,EAAG,CAAC,EAAQ,CAAS,CAuBjB,EACA,aAAA,EAtBgB,EAAA,YAAA,CAAY,SAAY,CACnC,KAEL,CADA,EAAW,EAAI,EACf,EAAS,IAAI,EACb,GAAI,CACA,MAAM,EAAO,YAAY,EACzB,EAAc,EAAK,CACvB,OAAS,EAAK,CAEV,MADA,EAAS,aAAe,MAAQ,EAAU,MAAM,OAAO,CAAG,CAAC,CAAC,EACtD,CACV,QAAU,CACN,EAAW,EAAK,CACpB,CATa,CAUjB,EAAG,CAAC,EAAQ,CAAS,CASjB,EACA,SACJ,CACJ"}