import { useContext, useEffect, useState } from 'react'; const loadingDefault = () => ( Loading… ); const errorDefault = err => ( Error:
{`${err}`}
); export function Fetch({ using, args, ok, loading, error }) { const [asyncData, setAsyncData] = useState({ state: null }); useEffect(() => { let ignore = false; setAsyncData({ state: 'loading' }); (async () => { try { const data = await using(...args); !ignore && setAsyncData({ state: 'done', data }); } catch (err) { !ignore && setAsyncData({ state: 'error', err }); } })(); return () => { ignore = true; } }, args); if (asyncData.state === 'loading') { return (loading || loadingDefault)(...args); } else if (asyncData.state === 'error') { return (error || errorDefault)(asyncData.err); } else if (asyncData.state === null) { return wat, request has not started (bug?); } else { if (asyncData.state !== 'done') { console.warn(`unexpected async data state: ${asyncData.state}`); } return ok(asyncData.data); } } ///// async function getJson(url, credentials) { const opts = {}; if (credentials) opts.credentials = 'include'; const res = await fetch(url, opts); if (!res.ok) { const m = await res.text(); throw new Error(`Failed to fetch: ${m}`); } return await res.json(); } export function GetJson({ endpoint, params, credentials, ...forFetch }) { const host = import.meta.env.VITE_NOTIFICATIONS_HOST; const url = new URL(endpoint, host); for (let [key, val] of Object.entries(params ?? {})) { url.searchParams.append(key, val); } return ( ); } export async function postJson(url, body, credentials) { const opts = { method: 'POST', headers: {'Content-Type': 'applicaiton/json'}, body, }; if (credentials) opts.credentials = 'include'; const res = await fetch(url, opts); if (!res.ok) { const m = await res.text(); let reason try { reason = JSON.parse(m)?.reason; } catch (err) {}; if (reason) throw reason; throw new Error(`Failed to fetch: ${m}`); } try { return await res.json(); } catch (e) { if ([201, 204].includes(res.status)) return null; throw e; } } export function PostJson({ endpoint, data, credentials, ...forFetch }) { const host = import.meta.env.VITE_NOTIFICATIONS_HOST; const url = new URL(endpoint, host); return ( ); }