95 lines · 3.3 KB · TypeScript
RawDownload
import type { EnvironmentId, ServerConfig } 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 } from "../connection/registry.ts";import type { PreparedConnection } from "../connection/model.ts";import { EnvironmentSupervisor } from "../connection/supervisor.ts";import { safeErrorLogAttributes } from "../errors/safeLog.ts";import { followStreamInEnvironment } from "./runtime.ts"; export function initialConfigOption<E>(  initialConfig: Effect.Effect<ServerConfig, E>,): Effect.Effect<Option.Option<ServerConfig>> {  return initialConfig.pipe(    Effect.map(Option.some),    Effect.catch((error) =>      Effect.logWarning("Could not load the initial environment configuration.").pipe(        Effect.annotateLogs({ ...safeErrorLogAttributes(error) }),        Effect.as(Option.none<ServerConfig>()),      ),    ),  );} export function createEnvironmentSessionAtoms<R, E>(  runtime: Atom.AtomRuntime<EnvironmentRegistry | R, E>,) {  const initialConfigAtom = Atom.family((environmentId: EnvironmentId) =>    runtime.atom(      followStreamInEnvironment(        environmentId,        Stream.unwrap(          EnvironmentSupervisor.pipe(            Effect.map((supervisor) =>              SubscriptionRef.changes(supervisor.session).pipe(                Stream.mapEffect(                  Option.match({                    onNone: () => Effect.succeed(Option.none<ServerConfig>()),                    onSome: (session) => initialConfigOption(session.initialConfig),                  }),                ),              ),            ),          ),        ),      ),      { initialValue: Option.none() },    ),  );   // This is only the bootstrap config captured when a transport session is  // established. Consumers that need current provider/settings state must use  // createServerEnvironmentAtoms(...).configValueAtom instead.  const initialConfigValueAtom = Atom.family((environmentId: EnvironmentId) =>    Atom.make((get): ServerConfig | null =>      Option.getOrNull(        Option.getOrElse(AsyncResult.value(get(initialConfigAtom(environmentId))), () =>          Option.none(),        ),      ),    ).pipe(Atom.withLabel(`environment-config-value:${environmentId}`)),  );   const preparedConnectionAtom = Atom.family((environmentId: EnvironmentId) =>    runtime.atom(      followStreamInEnvironment(        environmentId,        Stream.unwrap(          EnvironmentSupervisor.pipe(            Effect.map((supervisor) => SubscriptionRef.changes(supervisor.prepared)),          ),        ),      ),      { initialValue: Option.none<PreparedConnection>() },    ),  );   const preparedConnectionValueAtom = Atom.family((environmentId: EnvironmentId) =>    Atom.make((get) =>      Option.getOrElse(AsyncResult.value(get(preparedConnectionAtom(environmentId))), () =>        Option.none<PreparedConnection>(),      ),    ).pipe(Atom.withLabel(`environment-prepared-connection:${environmentId}`)),  );   return {    initialConfigAtom,    initialConfigValueAtom,    preparedConnectionAtom,    preparedConnectionValueAtom,  };}