UNPKG

next-safe-action

Version:

Type safe and validated Server Actions in your Next.js project.

118 lines (115 loc) 3.38 kB
import { t as FrameworkErrorHandler } from "./errors-BsNXg-5Q.mjs"; import * as React from "react"; //#region src/hooks-utils.ts const getActionStatus = ({ isIdle, isExecuting, isTransitioning, result, hasNavigated, hasThrownError }) => { if (isIdle) return "idle"; else if (isExecuting) return "executing"; else if (isTransitioning) return "transitioning"; else if ( hasThrownError || typeof result.validationErrors !== "undefined" || typeof result.serverError !== "undefined" ) return "hasErrored"; else if (hasNavigated) return "hasNavigated"; else return "hasSucceeded"; }; const getActionShorthandStatusObject = (status) => { return { isIdle: status === "idle", isExecuting: status === "executing", isTransitioning: status === "transitioning", isPending: status === "executing" || status === "transitioning", hasSucceeded: status === "hasSucceeded", hasErrored: status === "hasErrored", hasNavigated: status === "hasNavigated", }; }; /** * Converts a callback to a ref to avoid triggering re-renders when passed as a * prop or avoid re-executing effects when passed as a dependency */ function useCallbackRef(callback) { const callbackRef = React.useRef(callback); React.useEffect(() => { callbackRef.current = callback; }); return React.useMemo(() => (arg) => callbackRef.current?.(arg), []); } const useActionCallbacks = ({ result, input, status, cb, navigationError, thrownError }) => { const onExecute = useCallbackRef(cb?.onExecute); const onSuccess = useCallbackRef(cb?.onSuccess); const onError = useCallbackRef(cb?.onError); const onSettled = useCallbackRef(cb?.onSettled); const onNavigation = useCallbackRef(cb?.onNavigation); React.useEffect(() => { const executeCallbacks = async () => { switch (status) { case "executing": await Promise.resolve(onExecute?.({ input })).then(() => {}); break; case "transitioning": break; case "hasSucceeded": if (navigationError || thrownError) break; await Promise.all([ Promise.resolve( onSuccess?.({ data: result.data, input, }) ), Promise.resolve( onSettled?.({ result, input, }) ), ]); break; case "hasErrored": await Promise.all([ Promise.resolve( onError?.({ error: { ...result, ...(thrownError ? { thrownError } : {}), }, input, }) ), Promise.resolve( onSettled?.({ result, input, }) ), ]); break; } if (!navigationError) return; if (FrameworkErrorHandler.getNavigationKind(navigationError) === "redirect" || status === "hasNavigated") { const navigationKind = FrameworkErrorHandler.getNavigationKind(navigationError); await Promise.all([ Promise.resolve( onNavigation?.({ input, navigationKind, }) ), Promise.resolve( onSettled?.({ result, input, navigationKind, }) ), ]); } }; executeCallbacks().catch(console.error); }, [input, status, result, navigationError, thrownError, onExecute, onSuccess, onSettled, onError, onNavigation]); }; //#endregion export { getActionStatus as n, useActionCallbacks as r, getActionShorthandStatusObject as t }; //# sourceMappingURL=hooks-utils-DA2xDVWH.mjs.map