import type { RelayClientEnvironmentRecord, RelayEnvironmentStatusResponse,} from "@t3tools/contracts/relay";import type { EnvironmentId } from "@t3tools/contracts";import { RelayEnvironmentConnectScope, RelayEnvironmentStatusScope,} from "@t3tools/contracts/relay";import { decodeRelayJwt } from "@t3tools/shared/relayJwt";import * as Cause from "effect/Cause";import * as Clock from "effect/Clock";import * as Data from "effect/Data";import * as Effect from "effect/Effect";import * as Option from "effect/Option";import * as Schema from "effect/Schema";import * as Stream from "effect/Stream";import { AsyncResult, Atom, AtomRegistry } from "effect/unstable/reactivity"; import { findErrorTraceId } from "../errors/errorTrace.ts";import * as ManagedRelay from "./managedRelay.ts";import { relayProtectedErrorMessage } from "./errorPresentation.ts"; const DEFAULT_STALE_TIME_MS = 15_000;const DEFAULT_IDLE_TTL_MS = 5 * 60_000;const CLERK_TOKEN_EXPIRY_SKEW_MS = 5_000;const isManagedRelayRequestFailedError = Schema.is(ManagedRelay.ManagedRelayRequestFailedError); export interface ManagedRelaySession { readonly accountId: string; readonly readClerkToken: () => Effect.Effect<string | null, ManagedRelaySessionError>;} export interface ManagedRelaySessionInput { readonly accountId: string; readonly readClerkToken: () => Promise<string | null>;} interface ManagedRelaySessionControl { readonly updateReadClerkToken: ( readClerkToken: ManagedRelaySessionInput["readClerkToken"], ) => void;} export interface ManagedRelaySnapshotState<A> { readonly data: A | null; readonly error: string | null; readonly errorTraceId: string | null; readonly isPending: boolean;} export interface ManagedRelayQueryEvent { readonly operation: "environments" | "devices" | "environment-status"; readonly stage: "clerk-token" | "relay-request" | "validation"; readonly phase: "start" | "success" | "failure"; readonly accountId: string; readonly environmentId?: string; readonly message?: string; readonly traceId?: string | null;} export class ManagedRelaySessionError extends Data.TaggedError("ManagedRelaySessionError")<{ readonly message: string; readonly cause?: unknown;}> {} export class ManagedRelaySnapshotError extends Data.TaggedError("ManagedRelaySnapshotError")<{ readonly message: string;}> {} export const managedRelaySessionAtom = Atom.make<ManagedRelaySession | null>(null).pipe( Atom.keepAlive, Atom.withLabel("managed-relay:session"),); const managedRelaySessionControls = new WeakMap<ManagedRelaySession, ManagedRelaySessionControl>(); export function createManagedRelaySession(input: ManagedRelaySessionInput): ManagedRelaySession { let cachedToken: { readonly token: string; readonly expiresAtMillis: number } | null = null; let pendingToken: Promise<string | null> | null = null; let readClerkToken = input.readClerkToken; let tokenProviderGeneration = 0; const readCachedClerkToken = async (nowMillis: number): Promise<string | null> => { if (cachedToken && cachedToken.expiresAtMillis > nowMillis + CLERK_TOKEN_EXPIRY_SKEW_MS) { return cachedToken.token; } if (pendingToken) { return await pendingToken; } const operationGeneration = tokenProviderGeneration; const operation = readClerkToken().then((token) => { if (operationGeneration !== tokenProviderGeneration) { return token; } if (!token) { cachedToken = null; return null; } try { const expiresAtSeconds = decodeRelayJwt(token).exp; cachedToken = typeof expiresAtSeconds === "number" ? { token, expiresAtMillis: expiresAtSeconds * 1_000 } : null; } catch { cachedToken = null; } return token; }); pendingToken = operation; try { return await operation; } finally { if (pendingToken === operation) { pendingToken = null; } } }; const session: ManagedRelaySession = { accountId: input.accountId, readClerkToken: Effect.fn("clientRuntime.managedRelaySession.readClerkToken")(function* () { const nowMillis = yield* Clock.currentTimeMillis; return yield* Effect.tryPromise({ try: () => readCachedClerkToken(nowMillis), catch: (cause) => new ManagedRelaySessionError({ message: "Could not obtain the T3 Connect session token.", cause, }), }); }), }; managedRelaySessionControls.set(session, { updateReadClerkToken: (nextReadClerkToken) => { readClerkToken = nextReadClerkToken; tokenProviderGeneration += 1; pendingToken = null; }, }); return session;} export function setManagedRelaySession( registry: AtomRegistry.AtomRegistry, input: ManagedRelaySessionInput | null,): void { const current = registry.get(managedRelaySessionAtom); if (input === null) { if (current !== null) { registry.set(managedRelaySessionAtom, null); } return; } if (current?.accountId === input.accountId) { const control = managedRelaySessionControls.get(current); if (control) { // Clerk can replace its token reader during routine same-account refreshes. // Keep the session stable so those refreshes do not invalidate queries or reconnect leases. control.updateReadClerkToken(input.readClerkToken); return; } } registry.set(managedRelaySessionAtom, createManagedRelaySession(input));} export function managedRelayAccountChanges( registry: AtomRegistry.AtomRegistry,): Stream.Stream<string | null> { return AtomRegistry.toStream(registry, managedRelaySessionAtom).pipe( Stream.map((session) => session?.accountId ?? null), Stream.changes, Stream.drop(1), );} function readSessionClerkToken( session: ManagedRelaySession,): Effect.Effect<string, ManagedRelaySessionError> { return session.readClerkToken().pipe( Effect.flatMap((token) => token ? Effect.succeed(token) : Effect.fail( new ManagedRelaySessionError({ message: "The T3 Connect session token is unavailable.", }), ), ), );} /** Removes an environment from the signed-in account without contacting that environment. */export const deregisterManagedRelayEnvironment = Effect.fn( "clientRuntime.managedRelaySession.deregisterEnvironment",)(function* ( registry: AtomRegistry.AtomRegistry, input: { readonly accountId: string; readonly environmentId: EnvironmentId },) { const session = registry.get(managedRelaySessionAtom); if (!session || session.accountId !== input.accountId) { return yield* new ManagedRelaySessionError({ message: "Sign in to T3 Connect before deregistering an environment.", }); } const clerkToken = yield* readSessionClerkToken(session); const relay = yield* ManagedRelay.ManagedRelayClient; yield* relay.unlinkEnvironment({ clerkToken, environmentId: input.environmentId });}); function requireClerkToken( get: Atom.AtomContext, accountId: string,): Effect.Effect<string, ManagedRelaySessionError> { const session = get(managedRelaySessionAtom); if (!session || session.accountId !== accountId) { return Effect.fail( new ManagedRelaySessionError({ message: "Sign in to T3 Connect before loading relay data.", }), ); } return readSessionClerkToken(session);} function statusKey(input: { readonly accountId: string; readonly environment: RelayClientEnvironmentRecord;}): string { return JSON.stringify(input);} function parseStatusKey(key: string): { readonly accountId: string; readonly environment: RelayClientEnvironmentRecord;} { return JSON.parse(key) as { readonly accountId: string; readonly environment: RelayClientEnvironmentRecord; };} function endpointMatches( left: RelayClientEnvironmentRecord["endpoint"], right: RelayClientEnvironmentRecord["endpoint"],): boolean { return ( left.httpBaseUrl === right.httpBaseUrl && left.wsBaseUrl === right.wsBaseUrl && left.providerKind === right.providerKind );} function validateEnvironmentStatus( environment: RelayClientEnvironmentRecord, status: RelayEnvironmentStatusResponse,): Effect.Effect<RelayEnvironmentStatusResponse, ManagedRelaySnapshotError> { if (status.environmentId !== environment.environmentId) { return Effect.fail( new ManagedRelaySnapshotError({ message: "Relay returned status for a different environment.", }), ); } if (!endpointMatches(status.endpoint, environment.endpoint)) { return Effect.fail( new ManagedRelaySnapshotError({ message: "Relay returned status for a different endpoint.", }), ); } if (status.descriptor && status.descriptor.environmentId !== environment.environmentId) { return Effect.fail( new ManagedRelaySnapshotError({ message: "Relay returned status descriptor for a different environment.", }), ); } return Effect.succeed(status);} export function readManagedRelaySnapshotState<A>( result: AsyncResult.AsyncResult<A, unknown>,): ManagedRelaySnapshotState<A> { let error: string | null = null; let errorTraceId: string | null = null; if (result._tag === "Failure") { const cause = Cause.squash(result.cause); error = isManagedRelayRequestFailedError(cause) && cause.relayError ? relayProtectedErrorMessage(cause.relayError) : cause instanceof Error ? cause.message : "Could not load T3 Connect data."; errorTraceId = findErrorTraceId(cause); } return { data: Option.getOrNull(AsyncResult.value(result)), error, errorTraceId, isPending: result.waiting, };} export function createManagedRelayQueryManager( runtime: Atom.AtomRuntime<ManagedRelay.ManagedRelayClient>, options?: { readonly staleTimeMs?: number; readonly idleTtlMs?: number; readonly onQueryEvent?: (event: ManagedRelayQueryEvent) => void; },) { const staleTime = options?.staleTimeMs ?? DEFAULT_STALE_TIME_MS; const idleTtl = options?.idleTtlMs ?? DEFAULT_IDLE_TTL_MS; const observe = <A, E, R>( input: Omit<ManagedRelayQueryEvent, "phase" | "message" | "traceId">, effect: Effect.Effect<A, E, R>, ): Effect.Effect<A, E, R> => Effect.gen(function* () { options?.onQueryEvent?.({ ...input, phase: "start" }); return yield* effect.pipe( Effect.onExit((exit) => Effect.sync(() => { if (exit._tag === "Success") { options?.onQueryEvent?.({ ...input, phase: "success" }); return; } const error = Cause.squash(exit.cause); options?.onQueryEvent?.({ ...input, phase: "failure", message: error instanceof Error ? error.message : String(error), traceId: findErrorTraceId(error), }); }), ), ); }); const environmentsAtom = Atom.family((accountId: string) => runtime .atom((get) => Effect.gen(function* () { const base = { operation: "environments" as const, accountId }; const clerkToken = yield* observe( { ...base, stage: "clerk-token" }, requireClerkToken(get, accountId), ); const relay = yield* ManagedRelay.ManagedRelayClient; return yield* observe( { ...base, stage: "relay-request" }, relay.listEnvironments({ clerkToken }), ); }), ) .pipe( Atom.swr({ staleTime, revalidateOnMount: true }), Atom.setIdleTTL(idleTtl), Atom.withLabel(`managed-relay:environments:${accountId}`), ), ); const devicesAtom = Atom.family((accountId: string) => runtime .atom((get) => Effect.gen(function* () { const base = { operation: "devices" as const, accountId }; const clerkToken = yield* observe( { ...base, stage: "clerk-token" }, requireClerkToken(get, accountId), ); const relay = yield* ManagedRelay.ManagedRelayClient; return yield* observe( { ...base, stage: "relay-request" }, relay.listDevices({ clerkToken }), ); }), ) .pipe( Atom.swr({ staleTime, revalidateOnMount: true }), Atom.setIdleTTL(idleTtl), Atom.withLabel(`managed-relay:devices:${accountId}`), ), ); const environmentStatusAtom = Atom.family((key: string) => { const { accountId, environment } = parseStatusKey(key); return runtime .atom((get) => Effect.gen(function* () { const base = { operation: "environment-status" as const, accountId, environmentId: environment.environmentId, }; const clerkToken = yield* observe( { ...base, stage: "clerk-token" }, requireClerkToken(get, accountId), ); const relay = yield* ManagedRelay.ManagedRelayClient; const status = yield* observe( { ...base, stage: "relay-request" }, relay.getEnvironmentStatus({ clerkToken, scopes: [RelayEnvironmentStatusScope, RelayEnvironmentConnectScope], environmentId: environment.environmentId, }), ); return yield* observe( { ...base, stage: "validation" }, validateEnvironmentStatus(environment, status), ); }), ) .pipe( Atom.swr({ staleTime, revalidateOnMount: true }), Atom.setIdleTTL(idleTtl), Atom.withLabel(`managed-relay:environment-status:${key}`), ); }); return { environmentsAtom, devicesAtom, environmentStatusAtom: (input: { readonly accountId: string; readonly environment: RelayClientEnvironmentRecord; }) => environmentStatusAtom(statusKey(input)), refreshEnvironments(registry: AtomRegistry.AtomRegistry, accountId: string): void { registry.refresh(environmentsAtom(accountId)); }, refreshDevices(registry: AtomRegistry.AtomRegistry, accountId: string): void { registry.refresh(devicesAtom(accountId)); }, refreshEnvironmentStatus( registry: AtomRegistry.AtomRegistry, input: { readonly accountId: string; readonly environment: RelayClientEnvironmentRecord; }, ): void { registry.refresh(environmentStatusAtom(statusKey(input))); }, };}
import type {
RelayClientEnvironmentRecord,
RelayEnvironmentStatusResponse,
} from "@t3tools/contracts/relay";
import type { EnvironmentId } from "@t3tools/contracts";
import {
RelayEnvironmentConnectScope,
RelayEnvironmentStatusScope,
} from "@t3tools/contracts/relay";
import { decodeRelayJwt } from "@t3tools/shared/relayJwt";
import * as Cause from "effect/Cause";
import * as Clock from "effect/Clock";
import * as Data from "effect/Data";
import * as Effect from "effect/Effect";
import * as Option from "effect/Option";
import * as Schema from "effect/Schema";
import * as Stream from "effect/Stream";
import { AsyncResult, Atom, AtomRegistry } from "effect/unstable/reactivity";
import { findErrorTraceId } from "../errors/errorTrace.ts";
import * as ManagedRelay from "./managedRelay.ts";
import { relayProtectedErrorMessage } from "./errorPresentation.ts";
const DEFAULT_STALE_TIME_MS = 15_000;
const DEFAULT_IDLE_TTL_MS = 5 * 60_000;
const CLERK_TOKEN_EXPIRY_SKEW_MS = 5_000;
const isManagedRelayRequestFailedError = Schema.is(ManagedRelay.ManagedRelayRequestFailedError);
export interface ManagedRelaySession {
readonly accountId: string;
readonly readClerkToken: () => Effect.Effect<string | null, ManagedRelaySessionError>;
}
export interface ManagedRelaySessionInput {
readonly accountId: string;
readonly readClerkToken: () => Promise<string | null>;
}
interface ManagedRelaySessionControl {
readonly updateReadClerkToken: (
readClerkToken: ManagedRelaySessionInput["readClerkToken"],
) => void;
}
export interface ManagedRelaySnapshotState<A> {
readonly data: A | null;
readonly error: string | null;
readonly errorTraceId: string | null;
readonly isPending: boolean;
}
export interface ManagedRelayQueryEvent {
readonly operation: "environments" | "devices" | "environment-status";
readonly stage: "clerk-token" | "relay-request" | "validation";
readonly phase: "start" | "success" | "failure";
readonly accountId: string;
readonly environmentId?: string;
readonly message?: string;
readonly traceId?: string | null;
}
export class ManagedRelaySessionError extends Data.TaggedError("ManagedRelaySessionError")<{
readonly message: string;
readonly cause?: unknown;
}> {}
export class ManagedRelaySnapshotError extends Data.TaggedError("ManagedRelaySnapshotError")<{
readonly message: string;
}> {}
export const managedRelaySessionAtom = Atom.make<ManagedRelaySession | null>(null).pipe(
Atom.keepAlive,
Atom.withLabel("managed-relay:session"),
);
const managedRelaySessionControls = new WeakMap<ManagedRelaySession, ManagedRelaySessionControl>();
export function createManagedRelaySession(input: ManagedRelaySessionInput): ManagedRelaySession {
let cachedToken: { readonly token: string; readonly expiresAtMillis: number } | null = null;
let pendingToken: Promise<string | null> | null = null;
let readClerkToken = input.readClerkToken;
let tokenProviderGeneration = 0;
const readCachedClerkToken = async (nowMillis: number): Promise<string | null> => {
if (cachedToken && cachedToken.expiresAtMillis > nowMillis + CLERK_TOKEN_EXPIRY_SKEW_MS) {
return cachedToken.token;
}
if (pendingToken) {
return await pendingToken;
}
const operationGeneration = tokenProviderGeneration;
const operation = readClerkToken().then((token) => {
if (operationGeneration !== tokenProviderGeneration) {
return token;
}
if (!token) {
cachedToken = null;
return null;
}
try {
const expiresAtSeconds = decodeRelayJwt(token).exp;
cachedToken =
typeof expiresAtSeconds === "number"
? { token, expiresAtMillis: expiresAtSeconds * 1_000 }
: null;
} catch {
cachedToken = null;
}
return token;
});
pendingToken = operation;
try {
return await operation;
} finally {
if (pendingToken === operation) {
pendingToken = null;
}
}
};
const session: ManagedRelaySession = {
accountId: input.accountId,
readClerkToken: Effect.fn("clientRuntime.managedRelaySession.readClerkToken")(function* () {
const nowMillis = yield* Clock.currentTimeMillis;
return yield* Effect.tryPromise({
try: () => readCachedClerkToken(nowMillis),
catch: (cause) =>
new ManagedRelaySessionError({
message: "Could not obtain the T3 Connect session token.",
cause,
}),
});
}),
};
managedRelaySessionControls.set(session, {
updateReadClerkToken: (nextReadClerkToken) => {
readClerkToken = nextReadClerkToken;
tokenProviderGeneration += 1;
pendingToken = null;
},
});
return session;
}
export function setManagedRelaySession(
registry: AtomRegistry.AtomRegistry,
input: ManagedRelaySessionInput | null,
): void {
const current = registry.get(managedRelaySessionAtom);
if (input === null) {
if (current !== null) {
registry.set(managedRelaySessionAtom, null);
}
return;
}
if (current?.accountId === input.accountId) {
const control = managedRelaySessionControls.get(current);
if (control) {
// Clerk can replace its token reader during routine same-account refreshes.
// Keep the session stable so those refreshes do not invalidate queries or reconnect leases.
control.updateReadClerkToken(input.readClerkToken);
return;
}
}
registry.set(managedRelaySessionAtom, createManagedRelaySession(input));
}
export function managedRelayAccountChanges(
registry: AtomRegistry.AtomRegistry,
): Stream.Stream<string | null> {
return AtomRegistry.toStream(registry, managedRelaySessionAtom).pipe(
Stream.map((session) => session?.accountId ?? null),
Stream.changes,
Stream.drop(1),
);
}
function readSessionClerkToken(
session: ManagedRelaySession,
): Effect.Effect<string, ManagedRelaySessionError> {
return session.readClerkToken().pipe(
Effect.flatMap((token) =>
token
? Effect.succeed(token)
: Effect.fail(
new ManagedRelaySessionError({
message: "The T3 Connect session token is unavailable.",
}),
),
),
);
}
/** Removes an environment from the signed-in account without contacting that environment. */
export const deregisterManagedRelayEnvironment = Effect.fn(
"clientRuntime.managedRelaySession.deregisterEnvironment",
)(function* (
registry: AtomRegistry.AtomRegistry,
input: { readonly accountId: string; readonly environmentId: EnvironmentId },
) {
const session = registry.get(managedRelaySessionAtom);
if (!session || session.accountId !== input.accountId) {
return yield* new ManagedRelaySessionError({
message: "Sign in to T3 Connect before deregistering an environment.",
});
}
const clerkToken = yield* readSessionClerkToken(session);
const relay = yield* ManagedRelay.ManagedRelayClient;
yield* relay.unlinkEnvironment({ clerkToken, environmentId: input.environmentId });
});
function requireClerkToken(
get: Atom.AtomContext,
accountId: string,
): Effect.Effect<string, ManagedRelaySessionError> {
const session = get(managedRelaySessionAtom);
if (!session || session.accountId !== accountId) {
return Effect.fail(
new ManagedRelaySessionError({
message: "Sign in to T3 Connect before loading relay data.",
}),
);
}
return readSessionClerkToken(session);
}
function statusKey(input: {
readonly accountId: string;
readonly environment: RelayClientEnvironmentRecord;
}): string {
return JSON.stringify(input);
}
function parseStatusKey(key: string): {
readonly accountId: string;
readonly environment: RelayClientEnvironmentRecord;
} {
return JSON.parse(key) as {
readonly accountId: string;
readonly environment: RelayClientEnvironmentRecord;
};
}
function endpointMatches(
left: RelayClientEnvironmentRecord["endpoint"],
right: RelayClientEnvironmentRecord["endpoint"],
): boolean {
return (
left.httpBaseUrl === right.httpBaseUrl &&
left.wsBaseUrl === right.wsBaseUrl &&
left.providerKind === right.providerKind
);
}
function validateEnvironmentStatus(
environment: RelayClientEnvironmentRecord,
status: RelayEnvironmentStatusResponse,
): Effect.Effect<RelayEnvironmentStatusResponse, ManagedRelaySnapshotError> {
if (status.environmentId !== environment.environmentId) {
return Effect.fail(
new ManagedRelaySnapshotError({
message: "Relay returned status for a different environment.",
}),
);
}
if (!endpointMatches(status.endpoint, environment.endpoint)) {
return Effect.fail(
new ManagedRelaySnapshotError({
message: "Relay returned status for a different endpoint.",
}),
);
}
if (status.descriptor && status.descriptor.environmentId !== environment.environmentId) {
return Effect.fail(
new ManagedRelaySnapshotError({
message: "Relay returned status descriptor for a different environment.",
}),
);
}
return Effect.succeed(status);
}
export function readManagedRelaySnapshotState<A>(
result: AsyncResult.AsyncResult<A, unknown>,
): ManagedRelaySnapshotState<A> {
let error: string | null = null;
let errorTraceId: string | null = null;
if (result._tag === "Failure") {
const cause = Cause.squash(result.cause);
error =
isManagedRelayRequestFailedError(cause) && cause.relayError
? relayProtectedErrorMessage(cause.relayError)
: cause instanceof Error
? cause.message
: "Could not load T3 Connect data.";
errorTraceId = findErrorTraceId(cause);
}
return {
data: Option.getOrNull(AsyncResult.value(result)),
error,
errorTraceId,
isPending: result.waiting,
};
}
export function createManagedRelayQueryManager(
runtime: Atom.AtomRuntime<ManagedRelay.ManagedRelayClient>,
options?: {
readonly staleTimeMs?: number;
readonly idleTtlMs?: number;
readonly onQueryEvent?: (event: ManagedRelayQueryEvent) => void;
},
) {
const staleTime = options?.staleTimeMs ?? DEFAULT_STALE_TIME_MS;
const idleTtl = options?.idleTtlMs ?? DEFAULT_IDLE_TTL_MS;
const observe = <A, E, R>(
input: Omit<ManagedRelayQueryEvent, "phase" | "message" | "traceId">,
effect: Effect.Effect<A, E, R>,
): Effect.Effect<A, E, R> =>
Effect.gen(function* () {
options?.onQueryEvent?.({ ...input, phase: "start" });
return yield* effect.pipe(
Effect.onExit((exit) =>
Effect.sync(() => {
if (exit._tag === "Success") {
options?.onQueryEvent?.({ ...input, phase: "success" });
return;
}
const error = Cause.squash(exit.cause);
options?.onQueryEvent?.({
...input,
phase: "failure",
message: error instanceof Error ? error.message : String(error),
traceId: findErrorTraceId(error),
});
}),
),
);
});
const environmentsAtom = Atom.family((accountId: string) =>
runtime
.atom((get) =>
Effect.gen(function* () {
const base = { operation: "environments" as const, accountId };
const clerkToken = yield* observe(
{ ...base, stage: "clerk-token" },
requireClerkToken(get, accountId),
);
const relay = yield* ManagedRelay.ManagedRelayClient;
return yield* observe(
{ ...base, stage: "relay-request" },
relay.listEnvironments({ clerkToken }),
);
}),
)
.pipe(
Atom.swr({ staleTime, revalidateOnMount: true }),
Atom.setIdleTTL(idleTtl),
Atom.withLabel(`managed-relay:environments:${accountId}`),
),
);
const devicesAtom = Atom.family((accountId: string) =>
runtime
.atom((get) =>
Effect.gen(function* () {
const base = { operation: "devices" as const, accountId };
const clerkToken = yield* observe(
{ ...base, stage: "clerk-token" },
requireClerkToken(get, accountId),
);
const relay = yield* ManagedRelay.ManagedRelayClient;
return yield* observe(
{ ...base, stage: "relay-request" },
relay.listDevices({ clerkToken }),
);
}),
)
.pipe(
Atom.swr({ staleTime, revalidateOnMount: true }),
Atom.setIdleTTL(idleTtl),
Atom.withLabel(`managed-relay:devices:${accountId}`),
),
);
const environmentStatusAtom = Atom.family((key: string) => {
const { accountId, environment } = parseStatusKey(key);
return runtime
.atom((get) =>
Effect.gen(function* () {
const base = {
operation: "environment-status" as const,
accountId,
environmentId: environment.environmentId,
};
const clerkToken = yield* observe(
{ ...base, stage: "clerk-token" },
requireClerkToken(get, accountId),
);
const relay = yield* ManagedRelay.ManagedRelayClient;
const status = yield* observe(
{ ...base, stage: "relay-request" },
relay.getEnvironmentStatus({
clerkToken,
scopes: [RelayEnvironmentStatusScope, RelayEnvironmentConnectScope],
environmentId: environment.environmentId,
}),
);
return yield* observe(
{ ...base, stage: "validation" },
validateEnvironmentStatus(environment, status),
);
}),
)
.pipe(
Atom.swr({ staleTime, revalidateOnMount: true }),
Atom.setIdleTTL(idleTtl),
Atom.withLabel(`managed-relay:environment-status:${key}`),
);
});
return {
environmentsAtom,
devicesAtom,
environmentStatusAtom: (input: {
readonly accountId: string;
readonly environment: RelayClientEnvironmentRecord;
}) => environmentStatusAtom(statusKey(input)),
refreshEnvironments(registry: AtomRegistry.AtomRegistry, accountId: string): void {
registry.refresh(environmentsAtom(accountId));
},
refreshDevices(registry: AtomRegistry.AtomRegistry, accountId: string): void {
registry.refresh(devicesAtom(accountId));
},
refreshEnvironmentStatus(
registry: AtomRegistry.AtomRegistry,
input: {
readonly accountId: string;
readonly environment: RelayClientEnvironmentRecord;
},
): void {
registry.refresh(environmentStatusAtom(statusKey(input)));
},
};
}