Files
mcpedia/apps/web/app/lib/fetcher.ts
T
mytheclipsebotreviewandinternal-model 4330f47c65
CI / typecheck + tests (push) Canceled after 0s
CI / build + deploy (Nix) — api (push) Canceled after 0s
CI / build + deploy (Nix) — mcp (push) Canceled after 0s
CI / build + deploy (Nix) — worker (push) Canceled after 0s
CI / build + deploy (web) (push) Canceled after 0s
feat(web): FE overhaul — SWR centralized data layer + dashboard + islands
- Add SWR foundation (lib/fetcher, lib/swr, lib/api) with typed
  hooks: useSections/useDocuments/useSearch/useRelated/useRevisions/useQueueStatus
- Replace ad-hoc useEffect+fetch in Header/Sidebar/CommandMenu/search
  with SWR (dedup 4s, focus throttle 10s, debounced search 180ms)
- Doc page: RelatedGrid + RevisionList as SWR client islands (RSC hero stays)
- DocForm: SWR mutate on create/update for live sidebar invalidation
- New APIs: /api/related, /api/revisions, /api/tags, /api/queue/status,
  /api/docs filtering (?section=&status=)
- New UI: DocumentCard, SectionCard, SearchBar, TagCloud, QueueBadge,
  EmptyState, dashboard (/dashboard with QueueStrip live + section stats)
- Layout wraps SWRProvider; no TanStack code (SWR-only per spec)
- Verified: next build passes (16.3.4 Turbopack), no manual fetch sprawl remains

Co-Authored-By: internal-model
2026-09-08 19:37:27 +07:00

33 lines
791 B
TypeScript

export class FetchError extends Error {
status: number;
info: unknown;
constructor(message: string, status: number, info: unknown) {
super(message);
this.name = "FetchError";
this.status = status;
this.info = info;
}
}
export async function fetcher<T>(url: string): Promise<T> {
const res = await fetch(url);
if (!res.ok) {
let info: unknown = null;
try {
info = await res.json();
} catch {
try {
info = await res.text();
} catch {
info = null;
}
}
const msg =
(info as { error?: string })?.error ||
(typeof info === "string" ? info : null) ||
`Request failed: ${res.status} ${res.statusText}`;
throw new FetchError(msg, res.status, info);
}
return (await res.json()) as T;
}