@yamada-ui/react
Version:
React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion
1 lines • 4.18 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","names":["useMounted"],"sources":["../../../../src/hooks/use-async/index.ts"],"sourcesContent":["\"use client\"\n\nimport type { DependencyList } from \"react\"\nimport { useCallback, useEffect, useRef, useState } from \"react\"\nimport { useMounted } from \"../use-mounted\"\n\nexport type FunctionReturningPromise = (...args: any[]) => Promise<any>\n\n/**\n * `useAsync` is a custom hook that executes an asynchronous function and tracks its state.\n *\n * @see https://yamada-ui.com/docs/hooks/use-async\n */\nexport function useAsync<Y extends FunctionReturningPromise>(\n func: Y,\n deps: DependencyList = [],\n) {\n const [state, callback] = useAsyncFunc(func, deps, { loading: true })\n\n useEffect(() => {\n callback()\n }, [callback])\n\n return state\n}\n\nexport type AsyncState<Y> =\n | {\n error: Error\n loading: false\n value?: undefined\n }\n | {\n loading: boolean\n error?: undefined\n value?: undefined\n }\n | {\n loading: false\n value: Y\n error?: undefined\n }\n | {\n loading: true\n error?: Error | undefined\n value?: Y\n }\n\nexport type PromiseType<P extends Promise<any>> =\n P extends Promise<infer Y> ? Y : never\n\ntype StateFromFunctionReturningPromise<Y extends FunctionReturningPromise> =\n AsyncState<PromiseType<ReturnType<Y>>>\n\nexport type AsyncFnReturn<\n Y extends FunctionReturningPromise = FunctionReturningPromise,\n> = [StateFromFunctionReturningPromise<Y>, Y]\n\nexport function useAsyncFunc<Y extends FunctionReturningPromise>(\n func: Y,\n deps: DependencyList = [],\n initialState: StateFromFunctionReturningPromise<Y> = { loading: false },\n): AsyncFnReturn<Y> {\n const lastCallId = useRef(0)\n const mounted = useMounted()\n const [state, setState] =\n useState<StateFromFunctionReturningPromise<Y>>(initialState)\n\n const callback = useCallback(\n (...args: Parameters<Y>): ReturnType<Y> => {\n const callId = ++lastCallId.current\n\n if (!state.loading)\n setState((prevState) => ({ ...prevState, loading: true }))\n\n return func(...args).then(\n (value) => {\n if (mounted() && callId === lastCallId.current)\n setState({ loading: false, value })\n\n return value\n },\n (error) => {\n if (mounted() && callId === lastCallId.current)\n setState({ error, loading: false })\n\n return error\n },\n ) as ReturnType<Y>\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n deps,\n )\n\n return [state, callback as unknown as Y]\n}\n\nexport type AsyncStateRetry<Y> = AsyncState<Y> & {\n retry(): void\n}\n\nexport function useAsyncRetry<Y>(\n func: () => Promise<Y>,\n deps: DependencyList = [],\n) {\n const [attempt, setAttempt] = useState<number>(0)\n const state = useAsync(func, [...deps, attempt])\n\n const stateLoading = state.loading\n\n const retry = useCallback(() => {\n if (stateLoading) return\n\n setAttempt((currentAttempt) => currentAttempt + 1)\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [...deps, stateLoading])\n\n return { ...state, retry }\n}\n"],"mappings":";;;;;;;;;;;;;;AAaA,SAAgB,SACd,MACA,OAAuB,EAAE,EACzB;CACA,MAAM,CAAC,OAAO,YAAY,aAAa,MAAM,MAAM,EAAE,SAAS,MAAM,CAAC;AAErE,4BAAgB;AACd,YAAU;IACT,CAAC,SAAS,CAAC;AAEd,QAAO;;AAmCT,SAAgB,aACd,MACA,OAAuB,EAAE,EACzB,eAAqD,EAAE,SAAS,OAAO,EACrD;CAClB,MAAM,+BAAoB,EAAE;CAC5B,MAAM,UAAUA,4CAAY;CAC5B,MAAM,CAAC,OAAO,gCACmC,aAAa;AA4B9D,QAAO,CAAC,+BAzBL,GAAG,SAAuC;EACzC,MAAM,SAAS,EAAE,WAAW;AAE5B,MAAI,CAAC,MAAM,QACT,WAAU,eAAe;GAAE,GAAG;GAAW,SAAS;GAAM,EAAE;AAE5D,SAAO,KAAK,GAAG,KAAK,CAAC,MAClB,UAAU;AACT,OAAI,SAAS,IAAI,WAAW,WAAW,QACrC,UAAS;IAAE,SAAS;IAAO;IAAO,CAAC;AAErC,UAAO;MAER,UAAU;AACT,OAAI,SAAS,IAAI,WAAW,WAAW,QACrC,UAAS;IAAE;IAAO,SAAS;IAAO,CAAC;AAErC,UAAO;IAEV;IAGH,KACD,CAEuC;;AAO1C,SAAgB,cACd,MACA,OAAuB,EAAE,EACzB;CACA,MAAM,CAAC,SAAS,kCAA+B,EAAE;CACjD,MAAM,QAAQ,SAAS,MAAM,CAAC,GAAG,MAAM,QAAQ,CAAC;CAEhD,MAAM,eAAe,MAAM;CAE3B,MAAM,qCAA0B;AAC9B,MAAI,aAAc;AAElB,cAAY,mBAAmB,iBAAiB,EAAE;IAEjD,CAAC,GAAG,MAAM,aAAa,CAAC;AAE3B,QAAO;EAAE,GAAG;EAAO;EAAO"}