/** * earth-now.co * Author: Simon-Pierre Boucher * Contact: contact@spboucher.ai * File: apps/api/src/pollers/poller.ts * Purpose: Shared RT-poller plumbing — env gate, timeout-bounded JSON fetch, handle type */ export interface PollerHandle { stop(): void; } export const NOOP_POLLER: PollerHandle = { stop: () => undefined }; /** RT pollers run unless explicitly disabled (tests, offline dev). */ export function pollersEnabled(): boolean { return process.env.ENABLE_RT_POLLERS !== "0"; } /** GET a JSON document with a hard timeout; throws on HTTP/network/abort errors. */ export async function fetchJson(url: string, timeoutMs = 10_000): Promise { const res = await fetch(url, { signal: AbortSignal.timeout(timeoutMs), headers: { accept: "application/json", "user-agent": "earth-now.co/0.1 (contact@spboucher.ai)", }, }); if (!res.ok) throw new Error(`HTTP ${res.status} from ${url}`); return (await res.json()) as unknown; }