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 };
}