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, };}
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,
};
}