import { useSafely } from '@rocket.chat/fuselage-hooks'; import { useCallback, useMemo, useState } from 'react'; import { AsyncStatePhase, AsyncState, asyncState } from '../lib/asyncState'; type AsyncStateObject = AsyncState & { resolve: (value: T | ((prev: T | undefined) => T)) => void; reject: (error: Error) => void; reset: () => void; update: () => void; }; export const useAsyncState = (initialValue?: T | (() => T)): AsyncStateObject => { const [state, setState] = useSafely( useState>(() => { if (typeof initialValue === 'undefined') { return asyncState.loading(); } return asyncState.resolved(typeof initialValue === 'function' ? (initialValue as () => T)() : initialValue); }), ); const resolve = useCallback( (value: T | ((prev: T | undefined) => T)) => { setState((state) => { if (typeof value === 'function') { return asyncState.resolve(state, (value as (prev: T | undefined) => T)(state.value)); } return asyncState.resolve(state, value); }); }, [setState], ); const reject = useCallback( (error: Error) => { setState((state) => asyncState.reject(state, error)); }, [setState], ); const update = useCallback(() => { setState((state) => asyncState.update(state)); }, [setState]); const reset = useCallback(() => { setState((state) => asyncState.reload(state)); }, [setState]); return useMemo( () => ({ ...state, resolve, reject, reset, update, }), [state, resolve, reject, reset, update], ); }; export { AsyncStatePhase, AsyncState };