File size: 1,301 Bytes
0134cb4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | import { useEffect, useState } from "react";
import { api } from "../api";
import type { EngineResponse } from "../types";
// One shared fetch for every component that shows engine tickets (PARLAY tab, ENGINE tab, featured banner).
let shared: { at: number; promise: Promise<EngineResponse> } | null = null;
const TTL_MS = 60_000;
function load(): Promise<EngineResponse> {
if (!shared || Date.now() - shared.at > TTL_MS) {
const promise = api.parlaysEngine();
shared = { at: Date.now(), promise };
promise.catch(() => { if (shared?.promise === promise) shared = null; });
}
return shared.promise;
}
/** Engine board with automatic retries while the server is cold or briefly unavailable. */
export function useEngine(): { data: EngineResponse | null; error: boolean } {
const [data, setData] = useState<EngineResponse | null>(null);
const [error, setError] = useState(false);
useEffect(() => {
let alive = true;
let tries = 0;
const go = () => {
load()
.then((r) => { if (alive) { setData(r); setError(false); } })
.catch(() => {
if (!alive) return;
setError(true);
if (++tries < 6) setTimeout(go, 8000);
});
};
go();
return () => { alive = false; };
}, []);
return { data, error };
}
|