/** * `useManifest` — the structure feed. Fetches `.nwire/manifest.json` (the deep * manifest) via TanStack Query and exposes a tolerant native view. Re-keys per * project so a switch refetches. */ import { computed, toValue, type MaybeRefOrGetter } from "vue"; import { useQuery } from "@tanstack/vue-query"; import { manifestView, type Manifest, type ManifestView } from "../lib/manifest"; const MANIFEST_URL = "/__nwire/manifest.json"; export function useManifest(project?: MaybeRefOrGetter) { const key = computed(() => ["manifest", toValue(project) ?? "active"] as const); const query = useQuery({ queryKey: key, queryFn: async (): Promise => { // The global fetch shim appends `?project=`. const res = await fetch(MANIFEST_URL); if (!res.ok) { throw new Error(`Manifest fetch failed (${res.status}). Run \`nwire cache\` to build it.`); } return (await res.json()) as Manifest; }, staleTime: 5_000, // keepPreviousData: smooth refresh, no flash while a refetch is in flight. placeholderData: (prev) => prev, }); const view = computed(() => query.data.value ? manifestView(query.data.value) : null, ); return { manifest: query.data, view, isLoading: query.isLoading, isFetching: query.isFetching, isError: query.isError, error: computed(() => (query.error.value as Error | null)?.message ?? null), refetch: query.refetch, }; }