import { attachEnvironmentDescriptor, createKnownEnvironment, type KnownEnvironment, } from "@t3tools/client-runtime/environment"; import type { ExecutionEnvironmentDescriptor } from "@t3tools/contracts"; import * as Effect from "effect/Effect"; import { PrimaryEnvironmentRequestError, retryTransientBootstrap } from "./auth"; import { PrimaryEnvironmentHttpClient } from "./httpClient"; import { runPrimaryHttp } from "../../lib/runtime"; import { readPrimaryEnvironmentTarget } from "./target"; let primaryEnvironmentDescriptor: ExecutionEnvironmentDescriptor | null = null; let primaryEnvironmentDescriptorPromise: Promise | null = null; function createPrimaryKnownEnvironment(input: { readonly source: KnownEnvironment["source"]; readonly target: KnownEnvironment["target"]; }): KnownEnvironment | null { const descriptor = readPrimaryEnvironmentDescriptor(); if (!descriptor) { return null; } return attachEnvironmentDescriptor( createKnownEnvironment({ id: descriptor.environmentId, label: descriptor.label, source: input.source, target: input.target, }), descriptor, ); } async function fetchPrimaryEnvironmentDescriptor(): Promise { return retryTransientBootstrap(async () => { let descriptor: ExecutionEnvironmentDescriptor; try { descriptor = await runPrimaryHttp( PrimaryEnvironmentHttpClient.pipe(Effect.flatMap((client) => client.metadata.descriptor())), ); } catch (error) { throw PrimaryEnvironmentRequestError.fromCause({ operation: "fetch-environment-descriptor", cause: error, }); } writePrimaryEnvironmentDescriptor(descriptor); return descriptor; }); } export function readPrimaryEnvironmentDescriptor(): ExecutionEnvironmentDescriptor | null { return primaryEnvironmentDescriptor; } export function writePrimaryEnvironmentDescriptor( descriptor: ExecutionEnvironmentDescriptor | null, ): void { primaryEnvironmentDescriptor = descriptor; } export function getPrimaryKnownEnvironment(): KnownEnvironment | null { const primaryTarget = readPrimaryEnvironmentTarget(); if (!primaryTarget) { return null; } return createPrimaryKnownEnvironment({ source: primaryTarget.source, target: primaryTarget.target, }); } export function resolveInitialPrimaryEnvironmentDescriptor(): Promise { const descriptor = readPrimaryEnvironmentDescriptor(); if (descriptor) { return Promise.resolve(descriptor); } if (primaryEnvironmentDescriptorPromise) { return primaryEnvironmentDescriptorPromise; } const nextPromise = fetchPrimaryEnvironmentDescriptor(); primaryEnvironmentDescriptorPromise = nextPromise; return nextPromise.finally(() => { if (primaryEnvironmentDescriptorPromise === nextPromise) { primaryEnvironmentDescriptorPromise = null; } }); } export function __resetPrimaryEnvironmentBootstrapForTests(): void { primaryEnvironmentDescriptorPromise = null; primaryEnvironmentDescriptor = null; } export const resetPrimaryEnvironmentDescriptorForTests = __resetPrimaryEnvironmentBootstrapForTests; export const __resetPrimaryEnvironmentDescriptorBootstrapForTests = __resetPrimaryEnvironmentBootstrapForTests;