import { useContext, useCallback, useState } from 'react'; import { TippleContext } from './context'; import { executeRequest, mergeFetchOptions } from './util'; import { ExecuteRequestOptions } from './types'; export type TypedUsePush = ( url: string, opts: UsePushOptions ) => UsePushResponse; export interface PushState { fetching: boolean; data?: T; error?: Error; } interface UsePushOptions { domains: D[]; baseUrl?: string; fetchOptions?: RequestInit; } type UsePushResponse = [PushState, () => Promise, () => void]; /** Hook for executing push requests (POST, PUT, DELETE, etc.). */ export const usePush = ( url: string, opts: UsePushOptions ): UsePushResponse => { const { config, clearDomains } = useContext(TippleContext); const [state, setState] = useState>({ fetching: false }); /** Executes fetching of data. */ const doFetch = useCallback( async (overrides: ExecuteRequestOptions = {}) => { setState({ ...state, fetching: true }); try { const response = await executeRequest( `${overrides.baseUrl || opts.baseUrl || config.baseUrl || ''}${url}`, { method: 'POST', ...mergeFetchOptions( config.fetchOptions, opts.fetchOptions, overrides.fetchOptions ), } ); clearDomains(opts.domains); setState({ fetching: false, data: response }); return response; } catch (error) { setState({ ...state, error }); throw error; } }, [url, state, opts, config, clearDomains] ); const reset = useCallback(() => setState({ fetching: false }), []); return [{ ...state }, doFetch, reset]; };