import useSWR, { type SWRConfiguration } from "swr"; import { Failure, fromPromise, Success } from "./async-op.ts"; import { swrResponseToResult } from "./result/swr.ts"; import type { FailurePayload } from "./types.ts"; export type DocContentTypeMismatch = { type: "DOC_CONTENT_TYPE_MISMATCH"; }; type FetchJsonResult = | Success | Failure; export async function fetchJson(url: string): Promise> { const result = await fromPromise(() => fetch(url)); if (result.isFailure) { return new Failure({ type: "NETWORK_ERROR" }); } const { value: response } = result; if (!response.ok) { return new Failure({ type: "API_ERROR", code: response.status }); } // This can happen due to Netlify rewrites serving index.html in case the // requested doc file is not found. if (response.headers.get("Content-Type") !== "application/json") { return new Failure({ type: "DOC_CONTENT_TYPE_MISMATCH" }); } const parsed = await fromPromise(() => response.json()); if (parsed.isFailure) { return new Failure({ type: "UNKNOWN_ERROR" }); } return parsed; } /** * Fetches a JSON document at provided URL. Note that the return type can be * explicitly provided, but it is not validated at runtime — beware! */ export function useFetchJson( url: string, config?: SWRConfiguration, ) { return useSWR>(url, fetchJson, config); } /** * Fetches a JSON document at provided URL. Response will be wrapped in a * Result. Note that the return type can be explicitly provided, but it is * not validated at runtime — beware! */ export function useFetchJsonResult( url: string, config?: SWRConfiguration, ) { return swrResponseToResult(useFetchJson(url, config)); }