'use client'; /** Browser-side fetches: same origin `/api/v1/*` (Next rewrite → FastAPI). Never import server `api.ts` in client components. */ import type { Envelope, LivePosition, Paginated, PositionsSnapshot, SatelliteRow, SearchPayload, SearchResult, Track } from './types'; async function get(path: string, signal?: AbortSignal): Promise { const res = await fetch(`/api/v1${path}`, { headers: { accept: 'application/json' }, signal }); if (!res.ok) throw new Error(`API ${res.status} on ${path}`); return (await res.json()) as T; } export const clientApi = { positions: (signal?: AbortSignal) => get>('/orbit/positions', signal), live: (ident: string, signal?: AbortSignal) => get>(`/satellites/${encodeURIComponent(ident)}/live`, signal), position: (ident: string, signal?: AbortSignal) => get>(`/satellites/${encodeURIComponent(ident)}/position`, signal), track: (ident: string, signal?: AbortSignal) => get>(`/satellites/${encodeURIComponent(ident)}/track`, signal), satellite: (ident: string, signal?: AbortSignal) => get>(`/satellites/${encodeURIComponent(ident)}`, signal), satellites: (qs: string, signal?: AbortSignal) => get>(`/satellites?${qs}`, signal), search: (q: string, limit = 12, signal?: AbortSignal) => get>(`/search?q=${encodeURIComponent(q)}&limit=${limit}`, signal), suggest: (q: string, signal?: AbortSignal) => get>(`/search/suggest?q=${encodeURIComponent(q)}`, signal), view: (entity_type: string, entity_id: string) => fetch('/api/v1/views', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ entity_type, entity_id }), keepalive: true }).catch(() => undefined), };