History

Use Effect exit for local update check

Rhys Sullivan committed 6 months ago

Commit c1c64301 parent b039b6e1 file · +21 −9Browse files

Unified · Split

apps/local/src/web/shell.tsx+21−9
@@ -1,6 +1,7 @@
1import { Link, Outlet, useLocation } from "@tanstack/react-router";1import { Link, Outlet, useLocation } from "@tanstack/react-router";
2import { useCallback, useEffect, useRef, useState } from "react";2import { useCallback, useEffect, useRef, useState } from "react";
3import { useAtomRefresh } from "@effect/atom-react";3import { useAtomRefresh } from "@effect/atom-react";
4import { Data, Effect, Exit } from "effect";
4import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";5import * as AsyncResult from "effect/unstable/reactivity/AsyncResult";
5import { sourcesAtom, toolsAtom } from "@executor-js/react/api/atoms";6import { sourcesAtom, toolsAtom } from "@executor-js/react/api/atoms";
6import { useSourcesWithPending } from "@executor-js/react/api/optimistic";7import { useSourcesWithPending } from "@executor-js/react/api/optimistic";
@@ -29,6 +30,10 @@ type UpdateChannel = "latest" | "beta"; · 22 unmodified lines
29 30
30const EXECUTOR_DIST_TAGS_PATH = "/v1/app/npm/dist-tags";31const EXECUTOR_DIST_TAGS_PATH = "/v1/app/npm/dist-tags";
31 32
33class LatestVersionCheckError extends Data.TaggedError("LatestVersionCheckError")<{
34 readonly cause: unknown;
35}> {}
36
32type ParsedVersion = {37type ParsedVersion = {
33 readonly major: number;38 readonly major: number;
34 readonly minor: number;39 readonly minor: number;
@@ -95,15 +100,22 @@ function useLatestVersion(currentVersion: string) { · 60 unmodified lines
95 100
96 useEffect(() => {101 useEffect(() => {
97 let cancelled = false;102 let cancelled = false;
98 fetch(EXECUTOR_DIST_TAGS_PATH)103
99 .then(async (res) => {104 const latestVersionEffect = Effect.tryPromise({
100 if (!res.ok) throw new Error(`Failed to load dist tags: ${res.status}`);105 try: async () => {
101 return res.json() as Promise<Partial<Record<UpdateChannel, string>>>;106 const res = await fetch(EXECUTOR_DIST_TAGS_PATH);
102 })107 if (!res.ok) return {};
103 .then((data) => {108 return (await res.json()) as Partial<Record<UpdateChannel, string>>;
104 if (!cancelled) setLatestVersion(data[channel] ?? null);109 },
105 })110 catch: (cause) => new LatestVersionCheckError({ cause }),
106 .catch(() => {});111 });
112
113 void Effect.runPromiseExit(latestVersionEffect).then((exit) => {
114 if (!cancelled && Exit.isSuccess(exit)) {
115 setLatestVersion(exit.value[channel] ?? null);
116 }
117 });
118
107 return () => {119 return () => {
108 cancelled = true;120 cancelled = true;
109 };121 };