Skip to content
Source
Sign inSign up

desktopCliCommand.ts

52 lines1.8 KB

1import type { DesktopBridge, DesktopCliCommandState } from "@t3tools/contracts";
2import * as Effect from "effect/Effect";
3import * as Schema from "effect/Schema";
4import { Atom } from "effect/reactivity";
5​
6import { appAtomRegistry } from "~/rpc/atomRegistry";
7​
8type DesktopCliCommandBridge = DesktopBridge["cliCommand"];
9​
10class DesktopCliCommandUnavailableError extends Schema.TaggedError<DesktopCliCommandUnavailableError>()(
11 "DesktopCliCommandUnavailableError",
12 {},
13) {
14 override get message(): string {
15 return "The t3 command is unavailable.";
16 }
18​
19class DesktopCliCommandLoadError extends Schema.TaggedError<DesktopCliCommandLoadError>()(
20 "DesktopCliCommandLoadError",
21 { cause: Schema.Defect() },
22) {
23 override get message(): string {
24 return "Failed to load the t3 command state.";
25 }
27​
28export function getDesktopCliCommandBridge(): DesktopCliCommandBridge | undefined {
29 return typeof window === "undefined" ? undefined : window.desktopBridge?.cliCommand;
31​
32const loadDesktopCliCommandState = Effect.fn("loadDesktopCliCommandState")(function* () {
33 const bridge = getDesktopCliCommandBridge();
34 if (!bridge) {
35 return yield* new DesktopCliCommandUnavailableError();
36 }
37 return yield* Effect.tryPromise({
38 try: (): Promise<DesktopCliCommandState> => bridge.getState(),
39 catch: (cause) => new DesktopCliCommandLoadError({ cause }),
40 });
41});
42​
43export const desktopCliCommandStateAtom = Atom.make(loadDesktopCliCommandState()).pipe(
44 // Keep the loaded state, but let the SWR wrapper revalidate when Settings remounts.
45 Atom.keepAlive,
46 Atom.swr({ staleTime: 30_000, revalidateOnMount: true }),
47 Atom.withLabel("desktop:cli-command:load"),
48);
49​
50export function refreshDesktopCliCommandState(): void {
51 appAtomRegistry.refresh(desktopCliCommandStateAtom);