Files
Compass/web/hooks/use-api-getter.ts
MartinBraquet 25a319710e Fix import
2025-10-15 23:50:27 +02:00

69 lines
1.8 KiB
TypeScript

import {useEffect} from 'react'
import {APIParams, APIPath, APIResponse} from 'common/api/schema'
import {usePersistentInMemoryState} from './use-persistent-in-memory-state'
import {api} from 'web/lib/api'
import {useEvent} from './use-event'
import {APIError} from "common/api/utils";
const promiseCache: Record<string, Promise<any> | undefined> = {}
export const useAPIGetter = <P extends APIPath>(
path: P,
props: APIParams<P> | undefined,
ingoreDependencies?: string[]
) => {
const propsString = JSON.stringify(props)
const propsStringToTriggerRefresh = JSON.stringify(
deepCopyWithoutKeys(props, ingoreDependencies || [])
)
const [data, setData] = usePersistentInMemoryState<
APIResponse<P> | undefined
>(undefined, `${path}-${propsString}`)
const key = `${path}-${propsString}-error`
const [error, setError] = usePersistentInMemoryState<APIError | undefined>(
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
}