import { attachEnvironmentDescriptor, createKnownEnvironment, type KnownEnvironment, } from "@t3tools/client-runtime"; import type { EnvironmentId, ExecutionEnvironmentDescriptor } from "@t3tools/contracts"; import * as Effect from "effect/Effect"; import { HttpClientError } from "effect/unstable/http"; import { create } from "zustand"; import { BootstrapHttpError, retryTransientBootstrap } from "./auth"; import { PrimaryEnvironmentHttpClient } from "./httpClient"; import { runPrimaryHttp } from "../../lib/runtime"; import { readPrimaryEnvironmentTarget } from "./target"; interface PrimaryEnvironmentBootstrapState { readonly descriptor: ExecutionEnvironmentDescriptor | null; readonly setDescriptor: (descriptor: ExecutionEnvironmentDescriptor | null) => void; readonly reset: () => void; } const usePrimaryEnvironmentBootstrapStore = create()((set) => ({ descriptor: null, setDescriptor: (descriptor) => set({ descriptor }), reset: () => set({ descriptor: 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) { const status = HttpClientError.isHttpClientError(error) && error.response !== undefined ? error.response.status : 500; throw new BootstrapHttpError({ message: `Failed to load server environment descriptor (${status}).`, status, }); } writePrimaryEnvironmentDescriptor(descriptor); return descriptor; }); } export function readPrimaryEnvironmentDescriptor(): ExecutionEnvironmentDescriptor | null { return usePrimaryEnvironmentBootstrapStore.getState().descriptor; } export function usePrimaryEnvironmentId(): EnvironmentId | null { return usePrimaryEnvironmentBootstrapStore((state) => state.descriptor?.environmentId ?? null); } export function writePrimaryEnvironmentDescriptor( descriptor: ExecutionEnvironmentDescriptor | null, ): void { usePrimaryEnvironmentBootstrapStore.getState().setDescriptor(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; usePrimaryEnvironmentBootstrapStore.getState().reset(); } export const resetPrimaryEnvironmentDescriptorForTests = __resetPrimaryEnvironmentBootstrapForTests; export const __resetPrimaryEnvironmentDescriptorBootstrapForTests = __resetPrimaryEnvironmentBootstrapForTests;