chore: initial trade-visualizer import

This commit is contained in:
u1
2026-01-31 01:14:32 +01:00
commit 37210d9681
48 changed files with 9303 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { DriftTick, fetchLatestTicks } from '../../lib/hasura';
import { useInterval } from '../../app/hooks/useInterval';
type Params = {
symbol: string;
source?: string;
limit: number;
pollMs: number;
};
type Result = {
ticks: DriftTick[];
latest: DriftTick | null;
loading: boolean;
error: string | null;
refresh: () => Promise<void>;
};
export function useTicks({ symbol, source, limit, pollMs }: Params): Result {
const [ticks, setTicks] = useState<DriftTick[]>([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const inFlight = useRef(false);
const fetchOnce = useCallback(async () => {
if (inFlight.current) return;
inFlight.current = true;
setLoading(true);
try {
const next = await fetchLatestTicks(symbol, limit, source?.trim() ? source : undefined);
setTicks(next);
setError(null);
} catch (e: any) {
setError(String(e?.message || e));
} finally {
setLoading(false);
inFlight.current = false;
}
}, [symbol, limit, source]);
useEffect(() => {
void fetchOnce();
}, [fetchOnce]);
useInterval(() => void fetchOnce(), pollMs);
const latest = useMemo(() => (ticks.length ? ticks[ticks.length - 1] : null), [ticks]);
return { ticks, latest, loading, error, refresh: fetchOnce };
}