export type TilesetBounds = { minLon: number; minLat: number; maxLon: number; maxLat: number; }; export type SourceItem = { id: string; name: string; enabled: boolean; center: number[]; status: string; downloadedAt?: string | null; builtAt?: string | null; lastError?: string | null; bounds?: TilesetBounds | null; }; export type StyleItem = { name: string; url: string; }; export type SyncStatus = { isRunning: boolean; lastStartedAt?: string | null; lastFinishedAt?: string | null; nextScheduledAt?: string | null; lastError?: string | null; }; export async function fetchJson(url: string, options?: RequestInit): Promise { const response = await fetch(url, options); if (!response.ok) { const body = await response.text(); throw new Error(body || `${response.status} ${response.statusText}`); } if (response.status === 204) { return undefined as T; } return (await response.json()) as T; }