import { useEffect, useState } from "react"; import type { Channel, PackagesManifest, PackageVersion } from "../types/packages.ts"; const STABLE_URL = "/fedora/43/x86_64/packages.json"; const UNSTABLE_URL = "/fedora/43/x86_64/unstable/packages.json"; function tagPackages( manifest: PackagesManifest, channel: Channel, ): PackageVersion[] { return manifest.packages.map((p) => ({ ...p, channel, baseUrl: manifest.baseUrl, })); } export function usePackages() { const [packages, setPackages] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { let cancelled = false; const fetchManifest = async ( url: string, channel: Channel, ): Promise => { const res = await fetch(url); if (!res.ok) { if (res.status === 404) return []; throw new Error(`HTTP ${res.status} fetching ${channel} manifest`); } const data = (await res.json()) as PackagesManifest; return tagPackages(data, channel); }; Promise.all([ fetchManifest(STABLE_URL, "stable"), fetchManifest(UNSTABLE_URL, "unstable"), ]) .then(([stable, unstable]) => { if (!cancelled) setPackages([...stable, ...unstable]); }) .catch((err: unknown) => { if (!cancelled) setError(err instanceof Error ? err.message : String(err)); }) .finally(() => { if (!cancelled) setLoading(false); }); return () => { cancelled = true; }; }, []); return { packages, loading, error }; }