import { Atom, Result, useAtomValue, } from "@effect-atom/atom-react"; import * as Cause from "effect/Cause"; import * as Effect from "effect/Effect"; import * as React from "react"; import type { Loadable } from "./types"; const causeMessage = (cause: Cause.Cause): Error => new Error(Cause.pretty(cause)); export const toLoadable = (result: Result.Result): Loadable => { if (Result.isSuccess(result)) { return { status: "ready", data: result.value, }; } if (Result.isFailure(result)) { return { status: "error", error: causeMessage(result.cause), }; } return { status: "loading", }; }; export const pendingResultAtom = Atom.make( Effect.never as Effect.Effect, ).pipe(Atom.keepAlive); export const pendingLoadable = ( workspace: Loadable, ): Loadable => { if (workspace.status === "loading") { return { status: "loading" }; } if (workspace.status === "error") { return { status: "error", error: workspace.error }; } throw new Error("Expected workspace loadable to be pending or errored"); }; export const useLoadableAtom = ( atom: Atom.Atom>, ): Loadable => { const result = useAtomValue(atom); return React.useMemo(() => toLoadable(result), [result]); }; export const disabledAtom = () => pendingResultAtom as unknown as Atom.Atom>;