{"version":3,"file":"use-async.cjs","names":[],"sources":["../../src/hooks/use-async.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { useLatestRef } from \"./use-latest-ref\";\n\nexport type AsyncStatus = \"idle\" | \"pending\" | \"success\" | \"error\";\n\nexport interface UseAsyncResult<T> {\n    status: AsyncStatus;\n    data: T | undefined;\n    error: unknown;\n    isPending: boolean;\n    isSuccess: boolean;\n    isError: boolean;\n    /** Trigger the async function. Resolves with the new data or rejects. */\n    run: () => Promise<T>;\n    /** Reset state back to idle. */\n    reset: () => void;\n}\n\n/**\n * Run an async function and track its `idle/pending/success/error` state.\n *\n * - Discards results from stale runs (race-condition safe).\n * - `immediate` (default `false`) triggers the function on mount and when\n *   `deps` change. With `false`, call `run()` manually.\n * - Returns a stable object so callers can destructure or pass around safely.\n *\n * For server data with caching, prefer React Query — `useAsync` is the\n * minimal one-shot primitive without dependencies.\n */\nexport function useAsync<T>(\n    asyncFn: () => Promise<T>,\n    deps: ReadonlyArray<unknown> = [],\n    options: { immediate?: boolean } = {},\n): UseAsyncResult<T> {\n    const { immediate = false } = options;\n    const [state, setState] = useState<{\n        status: AsyncStatus;\n        data: T | undefined;\n        error: unknown;\n    }>({ status: \"idle\", data: undefined, error: undefined });\n\n    const fnRef = useLatestRef(asyncFn);\n    const callIdRef = useRef<number>(0);\n    const mountedRef = useRef<boolean>(true);\n\n    useEffect(() => {\n        mountedRef.current = true;\n        return () => {\n            mountedRef.current = false;\n        };\n    }, []);\n\n    const run = useCallback(async (): Promise<T> => {\n        const callId = ++callIdRef.current;\n        setState((current) => ({ ...current, status: \"pending\", error: undefined }));\n        try {\n            const data = await fnRef.current();\n            if (mountedRef.current && callIdRef.current === callId) {\n                setState({ status: \"success\", data, error: undefined });\n            }\n            return data;\n        } catch (error) {\n            if (mountedRef.current && callIdRef.current === callId) {\n                setState({ status: \"error\", data: undefined, error });\n            }\n            throw error;\n        }\n    }, [fnRef]);\n\n    const reset = useCallback((): void => {\n        callIdRef.current++;\n        setState({ status: \"idle\", data: undefined, error: undefined });\n    }, []);\n\n    useEffect(() => {\n        if (!immediate) return;\n        run().catch(() => {\n            /* error already captured in state */\n        });\n        // eslint-disable-next-line react-hooks/exhaustive-deps\n    }, [immediate, ...deps]);\n\n    return {\n        status: state.status,\n        data: state.data,\n        error: state.error,\n        isPending: state.status === \"pending\",\n        isSuccess: state.status === \"success\",\n        isError: state.status === \"error\",\n        run,\n        reset,\n    };\n}\n"],"mappings":"+DA6BA,SAAgB,EACZ,EACA,EAA+B,CAAC,EAChC,EAAmC,CAAC,EACnB,CACjB,GAAM,CAAE,YAAY,IAAU,EACxB,CAAC,EAAO,IAAA,EAAY,EAAA,SAAA,CAIvB,CAAE,OAAQ,OAAQ,KAAM,IAAA,GAAW,MAAO,IAAA,EAAU,CAAC,EAElD,EAAQ,EAAA,aAAa,CAAO,EAC5B,GAAA,EAAY,EAAA,OAAA,CAAe,CAAC,EAC5B,GAAA,EAAa,EAAA,OAAA,CAAgB,EAAI,GAEvC,EAAA,EAAA,UAAA,MACI,EAAW,QAAU,OACR,CACT,EAAW,QAAU,EACzB,GACD,CAAC,CAAC,EAEL,IAAM,GAAA,EAAM,EAAA,YAAA,CAAY,SAAwB,CAC5C,IAAM,EAAS,EAAE,EAAU,QAC3B,EAAU,IAAa,CAAE,GAAG,EAAS,OAAQ,UAAW,MAAO,IAAA,EAAU,EAAE,EAC3E,GAAI,CACA,IAAM,EAAO,MAAM,EAAM,QAAQ,EAIjC,OAHI,EAAW,SAAW,EAAU,UAAY,GAC5C,EAAS,CAAE,OAAQ,UAAW,OAAM,MAAO,IAAA,EAAU,CAAC,EAEnD,CACX,OAAS,EAAO,CAIZ,MAHI,EAAW,SAAW,EAAU,UAAY,GAC5C,EAAS,CAAE,OAAQ,QAAS,KAAM,IAAA,GAAW,OAAM,CAAC,EAElD,CACV,CACJ,EAAG,CAAC,CAAK,CAAC,EAEJ,GAAA,EAAQ,EAAA,YAAA,KAAwB,CAClC,EAAU,UACV,EAAS,CAAE,OAAQ,OAAQ,KAAM,IAAA,GAAW,MAAO,IAAA,EAAU,CAAC,CAClE,EAAG,CAAC,CAAC,EAUL,OARA,EAAA,EAAA,UAAA,KAAgB,CACP,GACL,EAAI,CAAC,CAAC,UAAY,CAElB,CAAC,CAEL,EAAG,CAAC,EAAW,GAAG,CAAI,CAAC,EAEhB,CACH,OAAQ,EAAM,OACd,KAAM,EAAM,KACZ,MAAO,EAAM,MACb,UAAW,EAAM,SAAW,UAC5B,UAAW,EAAM,SAAW,UAC5B,QAAS,EAAM,SAAW,QAC1B,MACA,OACJ,CACJ"}