import {APIParams, APIPath, APIResponse} from 'common/api/schema' import {APIError} from 'common/api/utils' import {useEffect} from 'react' import {api} from 'web/lib/api' import {useEvent} from './use-event' import {usePersistentInMemoryState} from './use-persistent-in-memory-state' const promiseCache: Record | undefined> = {} export const useAPIGetter =

( path: P, props: APIParams

| undefined, ingoreDependencies?: string[], ) => { const propsString = JSON.stringify(props) const propsStringToTriggerRefresh = JSON.stringify( deepCopyWithoutKeys(props, ingoreDependencies || []), ) const [data, setData] = usePersistentInMemoryState | undefined>( undefined, `${path}-${propsString}`, ) const key = `${path}-${propsString}-error` const [error, setError] = usePersistentInMemoryState(undefined, key) const refresh = useEvent(async () => { if (!props) return const cachedPromise = promiseCache[key] if (cachedPromise) { await cachedPromise.then(setData).catch(setError) } else { const promise = api(path, props) promiseCache[key] = promise await promise.then(setData).catch(setError) promiseCache[key] = undefined } }) useEffect(() => { refresh() }, [propsStringToTriggerRefresh]) return {data, error, refresh} } function deepCopyWithoutKeys(obj: any, keysToRemove: string[]): any { if (Array.isArray(obj)) { return obj.map((item) => deepCopyWithoutKeys(item, keysToRemove)) } if (typeof obj === 'object' && obj !== null) { const newObj: any = {} for (const key in obj) { if (!keysToRemove.includes(key)) { newObj[key] = deepCopyWithoutKeys(obj[key], keysToRemove) } } return newObj } return obj }