(currentVersion: string | undefined)
| 48 | // ── useLatestVersion ──────────────────────────────────────────────────── |
| 49 | |
| 50 | function useLatestVersion(currentVersion: string | undefined) { |
| 51 | const channel: UpdateChannel = currentVersion ? resolveUpdateChannel(currentVersion) : "latest"; |
| 52 | const [latestVersion, setLatestVersion] = useState<string | null>(null); |
| 53 | |
| 54 | useEffect(() => { |
| 55 | if (!currentVersion) return; |
| 56 | let cancelled = false; |
| 57 | void Effect.runPromiseExit( |
| 58 | Effect.tryPromise({ |
| 59 | try: async () => { |
| 60 | const res = await fetch(EXECUTOR_DIST_TAGS_PATH); |
| 61 | if (!res.ok) return null; |
| 62 | return (await res.json()) as Partial<Record<UpdateChannel, string>>; |
| 63 | }, |
| 64 | catch: (cause) => cause, |
| 65 | }), |
| 66 | ).then((exit) => { |
| 67 | if (!cancelled && Exit.isSuccess(exit)) { |
| 68 | setLatestVersion(exit.value?.[channel] ?? null); |
| 69 | } |
| 70 | }); |
| 71 | return () => { |
| 72 | cancelled = true; |
| 73 | }; |
| 74 | }, [channel, currentVersion]); |
| 75 | |
| 76 | const updateAvailable = |
| 77 | currentVersion !== undefined && |
| 78 | latestVersion !== null && |
| 79 | compareVersions(currentVersion, latestVersion) === -1; |
| 80 | |
| 81 | return { latestVersion, updateAvailable, channel }; |
| 82 | } |
| 83 | |
| 84 | // ── Card chrome ────────────────────────────────────────────────────────── |
| 85 |
no test coverage detected