1import { useAtomValue } from "@effect/atom-react";
2import {
3 createManagedRelayQueryManager,
4 deregisterManagedRelayEnvironment,
5 managedRelaySessionAtom,
6 readManagedRelaySnapshotState,
7} from "@t3tools/client-runtime/relay";
8import {
9 createAtomCommandScheduler,
10 createRuntimeCommand,
11} from "@t3tools/client-runtime/state/runtime";
12import type { EnvironmentId } from "@t3tools/contracts";
13import type { RelayClientEnvironmentRecord } from "@t3tools/contracts/relay";
14import { AsyncResult, Atom } from "effect/reactivity";
15import { useCallback, useEffect } from "react";
16
17import * as Runtime from "../../lib/runtime";
18import { appAtomRegistry } from "../../state/atom-registry";
19import { cloudDebugLog } from "./cloudDebugLog";
20
21const managedRelayAtomRuntime = Atom.runtime(Runtime.layer);
22
23export const managedRelayQueryManager = createManagedRelayQueryManager(managedRelayAtomRuntime, {
24 onQueryEvent: (event) =>
25 cloudDebugLog(`query:${event.operation}:${event.stage}:${event.phase}`, { ...event }),
26});
27
28const managedRelayMutationScheduler = createAtomCommandScheduler();
29
30export const deregisterManagedRelayEnvironmentCommand = createRuntimeCommand(
31 managedRelayAtomRuntime,
32 {
33 label: "mobile:managed-relay:deregister-environment",
34 scheduler: managedRelayMutationScheduler,
35 concurrency: {
36 mode: "serial",
37 key: (input: { readonly accountId: string; readonly environmentId: EnvironmentId }) =>
38 input.accountId,
39 },
40 execute: (input, registry) => deregisterManagedRelayEnvironment(registry, input),
41 },
42);
43
44const EMPTY_ENVIRONMENTS_ATOM = Atom.make(
45 AsyncResult.success<ReadonlyArray<RelayClientEnvironmentRecord>>([]),
46).pipe(Atom.keepAlive, Atom.withLabel("managed-relay:mobile:environments:null"));
47
48export function useManagedRelayEnvironments() {
49 const session = useAtomValue(managedRelaySessionAtom);
50 const accountId = session?.accountId ?? null;
51 const atom = accountId
52 ? managedRelayQueryManager.environmentsAtom(accountId)
53 : EMPTY_ENVIRONMENTS_ATOM;
54 const result = useAtomValue(atom);
55 const snapshot = readManagedRelaySnapshotState(result);
56 useEffect(() => {
57 if (snapshot.error) {
58 console.error("[t3-cloud] Relay environment listing failed", {
59 message: snapshot.error,
60 traceId: snapshot.errorTraceId,
61 });
62 }
63 }, [snapshot.error, snapshot.errorTraceId]);
64 const refresh = useCallback(() => {
65 if (accountId) {
66 managedRelayQueryManager.refreshEnvironments(appAtomRegistry, accountId);
67 }
68 }, [accountId]);
69
70 return {
71 ...snapshot,
72 accountId,
73 refresh,
74 };
75}
76
77export function refreshManagedRelayEnvironments(): void {
78 const session = appAtomRegistry.get(managedRelaySessionAtom);
79 if (session) {
80 managedRelayQueryManager.refreshEnvironments(appAtomRegistry, session.accountId);
81 }
82}