{"version":3,"file":"useFetch-7b31c560.js","sources":["../../../../src/scripts/hooks/useFetch.tsx"],"sourcesContent":["import { useEffect, useReducer, useRef } from 'react';\n\ninterface State {\n data?: T;\n error?: Error;\n}\n\ntype Cache = { [url: string]: T };\n\n// discriminated union type\ntype Action =\n | { type: 'loading' }\n | { type: 'fetched'; payload: T }\n | { type: 'error'; payload: Error };\n\nexport function useFetch(\n url?: string,\n options?: RequestInit\n): State {\n const cache = useRef>({});\n\n // Used to prevent state update if the component is unmounted\n const cancelRequest = useRef(false);\n\n const initialState: State = {\n error: undefined,\n data: undefined\n };\n\n // Keep state logic separated\n const fetchReducer = (state: State, action: Action): State => {\n switch (action.type) {\n case 'loading':\n return { ...initialState };\n case 'fetched':\n return { ...initialState, data: action.payload };\n case 'error':\n return { ...initialState, error: action.payload };\n default:\n return state;\n }\n };\n\n const [state, dispatch] = useReducer(fetchReducer, initialState);\n\n useEffect(() => {\n // Do nothing if the url is not given\n if (!url) return;\n\n cancelRequest.current = false;\n\n const fetchData = async () => {\n dispatch({ type: 'loading' });\n\n // If a cache exists for this url, return it\n if (cache.current[url]) {\n dispatch({ type: 'fetched', payload: cache.current[url] });\n return;\n }\n\n try {\n const response = await fetch(url, options);\n if (!response.ok) {\n throw new Error(response.statusText);\n }\n\n const data = (await response.json()) as T;\n cache.current[url] = data;\n if (cancelRequest.current) return;\n\n dispatch({ type: 'fetched', payload: data });\n } catch (error) {\n if (cancelRequest.current) return;\n\n dispatch({ type: 'error', payload: error as Error });\n }\n };\n\n void fetchData();\n\n // Use the cleanup function for avoiding a possibly...\n // ...state update after the component was unmounted\n return () => {\n cancelRequest.current = true;\n };\n }, [url]);\n\n return state;\n}\n"],"names":["useFetch","url","options","cache","useRef","cancelRequest","initialState","fetchReducer","state","action","dispatch","useReducer","useEffect","response","data","error"],"mappings":"yCAegB,SAAAA,EACdC,EACAC,EACU,CACJ,MAAAC,EAAQC,SAAiB,CAAA,CAAE,EAG3BC,EAAgBD,SAAgB,EAAK,EAErCE,EAAyB,CAC7B,MAAO,OACP,KAAM,MAAA,EAIFC,EAAe,CAACC,EAAiBC,IAAgC,CACrE,OAAQA,EAAO,KAAM,CACnB,IAAK,UACI,MAAA,CAAE,GAAGH,GACd,IAAK,UACH,MAAO,CAAE,GAAGA,EAAc,KAAMG,EAAO,OAAQ,EACjD,IAAK,QACH,MAAO,CAAE,GAAGH,EAAc,MAAOG,EAAO,OAAQ,EAClD,QACSD,OAAAA,CACX,CAAA,EAGI,CAACA,EAAOE,CAAQ,EAAIC,EAAAA,WAAWJ,EAAcD,CAAY,EAE/DM,OAAAA,EAAAA,UAAU,IAEHX,GAELI,EAAc,QAAU,IAEN,SAAY,CAIxB,GAHKK,EAAA,CAAE,KAAM,SAAA,CAAW,EAGxBP,EAAM,QAAQF,CAAG,EAAG,CACbS,EAAA,CAAE,KAAM,UAAW,QAASP,EAAM,QAAQF,CAAG,EAAG,EACzD,OAGE,GAAA,CACF,MAAMY,EAAW,MAAM,MAAMZ,EAAKC,CAAO,EACrC,GAAA,CAACW,EAAS,GACN,MAAA,IAAI,MAAMA,EAAS,UAAU,EAG/B,MAAAC,EAAQ,MAAMD,EAAS,OAE7B,GADMV,EAAA,QAAQF,CAAG,EAAIa,EACjBT,EAAc,QAAS,OAE3BK,EAAS,CAAE,KAAM,UAAW,QAASI,CAAM,CAAA,QACpCC,GACP,GAAIV,EAAc,QAAS,OAE3BK,EAAS,CAAE,KAAM,QAAS,QAASK,CAAgB,CAAA,CACrD,CAAA,GAGa,EAIR,IAAM,CACXV,EAAc,QAAU,EAAA,GApChB,OAsCT,CAACJ,CAAG,CAAC,EAEDO,CACT"}