120 lines · 4.0 KB · TypeScript
RawDownload
import type { EnvironmentId as EnvironmentIdType } from "@t3tools/contracts";import * as Effect from "effect/Effect";import * as Option from "effect/Option";import * as Stream from "effect/Stream";import * as SubscriptionRef from "effect/SubscriptionRef";import { AsyncResult, Atom } from "effect/unstable/reactivity"; import { EnvironmentRegistry, type EnvironmentRegistryService } from "../connection/registry.ts";import type { ConnectionCatalogEntry } from "../connection/catalog.ts";import { AVAILABLE_CONNECTION_STATE } from "../connection/model.ts";import { EnvironmentSupervisor } from "../connection/supervisor.ts";import {  createAtomCommandScheduler,  createRuntimeCommand,  followStreamInEnvironment,} from "./runtime.ts"; export interface EnvironmentCatalogState {  readonly isReady: boolean;  readonly entries: ReadonlyMap<EnvironmentIdType, ConnectionCatalogEntry>;} export const EMPTY_ENVIRONMENT_CATALOG_STATE: EnvironmentCatalogState = Object.freeze({  isReady: false,  entries: new Map(),}); export function createEnvironmentCatalogAtoms<R, E>(  runtime: Atom.AtomRuntime<EnvironmentRegistry | R, E>,) {  const commandScheduler = createAtomCommandScheduler();  const serial = { mode: "serial" as const, key: () => "environment-catalog" };  const catalogAtom = runtime.atom(    Stream.unwrap(      EnvironmentRegistry.pipe(        Effect.map((registry) =>          SubscriptionRef.changes(registry.entries).pipe(            Stream.map((entries) => ({              isReady: true,              entries,            })),          ),        ),      ),    ),    { initialValue: EMPTY_ENVIRONMENT_CATALOG_STATE },  );   const catalogValueAtom = Atom.make((get) =>    Option.getOrElse(AsyncResult.value(get(catalogAtom)), () => EMPTY_ENVIRONMENT_CATALOG_STATE),  ).pipe(Atom.withLabel("environment-catalog-value"));   const networkStatusAtom = runtime.atom(    Stream.unwrap(      EnvironmentRegistry.pipe(        Effect.map((registry) => SubscriptionRef.changes(registry.networkStatus)),      ),    ),    { initialValue: "unknown" as const },  );   const networkStatusValueAtom = Atom.make((get) =>    Option.getOrElse(AsyncResult.value(get(networkStatusAtom)), () => "unknown" as const),  ).pipe(Atom.withLabel("environment-network-status-value"));   const stateAtom = Atom.family((environmentId: EnvironmentIdType) =>    runtime.atom(      followStreamInEnvironment(        environmentId,        Stream.unwrap(          EnvironmentSupervisor.pipe(            Effect.map((supervisor) => SubscriptionRef.changes(supervisor.state)),          ),        ),      ),      { initialValue: AVAILABLE_CONNECTION_STATE },    ),  );   const register = createRuntimeCommand(runtime, {    label: "environment-catalog:register",    scheduler: commandScheduler,    concurrency: serial,    execute: (target: Parameters<EnvironmentRegistryService["register"]>[0]) =>      EnvironmentRegistry.pipe(Effect.flatMap((registry) => registry.register(target))),  });  const remove = createRuntimeCommand(runtime, {    label: "environment-catalog:remove",    scheduler: commandScheduler,    concurrency: serial,    execute: (environmentId: EnvironmentIdType) =>      EnvironmentRegistry.pipe(Effect.flatMap((registry) => registry.remove(environmentId))),  });  const removeRelayEnvironments = createRuntimeCommand(runtime, {    label: "environment-catalog:remove-relay-environments",    scheduler: commandScheduler,    concurrency: serial,    execute: (_input: void) =>      EnvironmentRegistry.pipe(Effect.flatMap((registry) => registry.removeRelayEnvironments())),  });  const retryNow = createRuntimeCommand(runtime, {    label: "environment-catalog:retry-now",    scheduler: commandScheduler,    concurrency: serial,    execute: (environmentId: EnvironmentIdType) =>      EnvironmentRegistry.pipe(Effect.flatMap((registry) => registry.retryNow(environmentId))),  });   return {    catalogAtom,    catalogValueAtom,    networkStatusAtom,    networkStatusValueAtom,    stateAtom,    register,    remove,    removeRelayEnvironments,    retryNow,  };}