Files
arbpulse/web/src/api.ts
T
Mauricio Barragan 2e8744ccf0 Initial commit: Arb Pulse monolith with CI and optional Fly deploy.
Real-time BTC cross-exchange arbitrage detection (Kraken, Bybit, OKX, Binance)
with React dashboard, GitHub Actions CI, and documented Fly.io deploy workflow.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-08 21:04:53 -06:00

44 lines
1.3 KiB
TypeScript

import type { StateSnapshot } from "./types";
/**
* Subscribe to the live state stream over SSE. Uses a relative URL so it works
* behind the Vite dev proxy and same-origin in production. EventSource
* auto-reconnects on drop.
*/
export function subscribeState(
onSnapshot: (s: StateSnapshot) => void,
onStatus: (connected: boolean) => void,
): () => void {
const source = new EventSource("/api/stream");
source.onopen = () => onStatus(true);
source.onerror = () => onStatus(false);
source.onmessage = (event) => {
try {
onSnapshot(JSON.parse(event.data) as StateSnapshot);
} catch {
/* ignore malformed frame */
}
};
return () => source.close();
}
async function post(path: string, body?: unknown): Promise<void> {
await fetch(`/api${path}`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: body ? JSON.stringify(body) : undefined,
});
}
export const control = {
pause: () => post("/control/pause"),
resume: () => post("/control/resume"),
reset: () => post("/control/reset"),
setDemo: (enabled: boolean) => post("/control/demo", { enabled }),
setRecord: (enabled: boolean) => post("/control/record", { enabled }),
setThreshold: (pct: number) => post("/control/threshold", { pct }),
setMaxTrade: (btc: number) => post("/control/max-trade", { btc }),
};