Skip to content
Source
Sign inSign up

useConnectionController.ts

119 lines4.4 KB

1import { useAtomValue } from "@effect/atom-react";
2import {
3 RelayConnectionRegistration,
4 RelayConnectionTarget,
5} from "@t3tools/client-runtime/connection";
6import type { EnvironmentId } from "@t3tools/contracts";
7import type {
8 RelayClientEnvironmentRecord,
9 RelayEnvironmentStatusResponse,
10} from "@t3tools/contracts/relay";
11import * as Option from "effect/Option";
12import { useMemo } from "react";
13​
14import { environmentCatalog } from "../../connection/catalog";
15import {
16 connectPairingUrl as connectPairingUrlAtom,
17 updateBearerConnection,
18} from "../../connection/onboarding";
19import { useWorkspaceEnvironments } from "../../state/workspace";
20import { relayEnvironmentDiscovery } from "../../state/relay";
21import { useAtomCommand } from "../../state/use-atom-command";
22import { relayManagedEnvironmentIds } from "./environmentSections";
23​
24export interface RelayEnvironmentView {
25 readonly environment: RelayClientEnvironmentRecord;
26 readonly availability: "checking" | "online" | "offline" | "error";
27 readonly status: RelayEnvironmentStatusResponse | null;
28 readonly error: string | null;
29 readonly traceId: string | null;
31​
32export function useConnectionController() {
33 const connectedEnvironments = useWorkspaceEnvironments();
34 const discovery = useAtomValue(relayEnvironmentDiscovery.stateValueAtom);
35 const connectPairingUrlMutation = useAtomCommand(connectPairingUrlAtom, {
36 reportFailure: false,
37 });
38 const updateBearer = useAtomCommand(updateBearerConnection, { reportFailure: false });
39 const registerEnvironment = useAtomCommand(environmentCatalog.register, "environment register");
40 const removeEnvironmentMutation = useAtomCommand(environmentCatalog.remove, "environment remove");
41 const retryEnvironmentMutation = useAtomCommand(environmentCatalog.retryNow, "environment retry");
42 const setEnvironmentEnabledMutation = useAtomCommand(
43 environmentCatalog.setEnabled,
44 "environment toggle",
45 );
46 const refreshRelayEnvironments = useAtomCommand(
47 relayEnvironmentDiscovery.refresh,
48 "relay environment refresh",
49 );
50​
51 const registeredIds = useMemo(
52 () => relayManagedEnvironmentIds(connectedEnvironments),
53 [connectedEnvironments],
54 );
55 const relayEnvironments = useMemo<ReadonlyArray<RelayEnvironmentView>>(
56 () =>
57 [...discovery.environments.values()].map((entry) => ({
58 environment: entry.environment,
59 availability: entry.availability,
60 status: Option.getOrNull(entry.status),
61 error: Option.getOrNull(entry.error)?.message ?? null,
62 traceId: Option.getOrNull(entry.error)?.traceId ?? null,
63 })),
64 [discovery.environments],
65 );
66 const availableRelayEnvironments = useMemo(
67 () => relayEnvironments.filter((entry) => !registeredIds.has(entry.environment.environmentId)),
68 [registeredIds, relayEnvironments],
69 );
70​
71 const connectPairingUrl = (pairingUrl: string, expectedEnvironmentId?: EnvironmentId) =>
72 connectPairingUrlMutation({
73 pairingUrl,
74 ...(expectedEnvironmentId === undefined ? {} : { expectedEnvironmentId }),
75 });
76 const connectRelayEnvironment = (environment: RelayClientEnvironmentRecord) =>
77 registerEnvironment(
78 new RelayConnectionRegistration({
79 target: new RelayConnectionTarget({
80 environmentId: environment.environmentId,
81 label: environment.label,
82 }),
83 }),
84 );
85 const removeEnvironment = (environmentId: EnvironmentId) =>
86 removeEnvironmentMutation(environmentId);
87 const retryEnvironment = (environmentId: EnvironmentId) =>
88 retryEnvironmentMutation(environmentId);
89 const setEnvironmentEnabled = (environmentId: EnvironmentId, enabled: boolean) =>
90 setEnvironmentEnabledMutation({ environmentId, enabled });
91 const updateEnvironment = (
92 environmentId: EnvironmentId,
93 updates: { readonly label: string; readonly displayUrl: string },
94 ) =>
95 updateBearer({
96 environmentId,
97 label: updates.label,
98 httpBaseUrl: updates.displayUrl,
99 });
100​
101 return {
102 connectedEnvironments,
103 relayEnvironments,
104 availableRelayEnvironments,
105 relayDiscovery: {
106 isRefreshing: discovery.refreshing,
107 isOffline: discovery.offline,
108 error: Option.getOrNull(discovery.error)?.message ?? null,
109 errorTraceId: Option.getOrNull(discovery.error)?.traceId ?? null,
110 },
111 connectPairingUrl,
112 connectRelayEnvironment,
113 removeEnvironment,
114 retryEnvironment,
115 setEnvironmentEnabled,
116 updateEnvironment,
117 refreshRelayEnvironments,
118 };