| 28 | let inflight: Promise<number | null> | null = null; |
| 29 | |
| 30 | async function fetchStars(): Promise<number | null> { |
| 31 | const controller = new AbortController(); |
| 32 | const timer = setTimeout(() => controller.abort(), TIMEOUT_MS); |
| 33 | try { |
| 34 | const init: RequestInit & { cf?: { cacheTtl: number; cacheEverything: boolean } } = { |
| 35 | headers: { "User-Agent": "executor.sh", Accept: "application/vnd.github+json" }, |
| 36 | signal: controller.signal, |
| 37 | cf: { cacheTtl: 1800, cacheEverything: true }, |
| 38 | }; |
| 39 | const res = await fetch(`https://api.github.com/repos/${REPO}`, init); |
| 40 | if (!res.ok) return null; |
| 41 | const data = (await res.json()) as { stargazers_count?: number }; |
| 42 | return typeof data.stargazers_count === "number" ? data.stargazers_count : null; |
| 43 | } catch { |
| 44 | return null; |
| 45 | } finally { |
| 46 | clearTimeout(timer); |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | /** Live star count, memoized per isolate with a TTL. null when unavailable. */ |
| 51 | export function getStars(): Promise<number | null> { |