import { EnvironmentId, type OrchestrationV2ArchivedShellSnapshot } from "@t3tools/contracts"; import * as Arr from "effect/Array"; import { pipe } from "effect/Function"; import * as Option from "effect/Option"; import * as Order from "effect/Order"; import { AsyncResult, Atom } from "effect/unstable/reactivity"; export interface ArchivedSnapshotEntry { readonly environmentId: EnvironmentId; readonly snapshot: OrchestrationV2ArchivedShellSnapshot; } export interface ArchivedThreadSnapshotsState { readonly snapshots: ReadonlyArray; readonly error: string | null; readonly isLoading: boolean; } const ARCHIVED_THREADS_ENVIRONMENT_KEY_SEPARATOR = "\u001f"; const environmentIdOrder = Order.String as Order.Order; export function makeArchivedThreadsEnvironmentKey( environmentIds: ReadonlyArray, ): string { return pipe(environmentIds, Arr.sort(environmentIdOrder), (sortedEnvironmentIds) => sortedEnvironmentIds.join(ARCHIVED_THREADS_ENVIRONMENT_KEY_SEPARATOR), ); } export function parseArchivedThreadsEnvironmentKey(key: string): ReadonlyArray { if (key.length === 0) { return []; } return pipe( key.split(ARCHIVED_THREADS_ENVIRONMENT_KEY_SEPARATOR), Arr.map((environmentId) => EnvironmentId.make(environmentId)), ); } export function createArchivedThreadSnapshotsAtomFamily(options: { readonly getSnapshotAtom: ( environmentId: EnvironmentId, ) => Atom.Atom>; readonly labelPrefix: string; }) { return Atom.family((environmentKey: string) => Atom.make((get): ArchivedThreadSnapshotsState => { const snapshots: ArchivedSnapshotEntry[] = []; let error: string | null = null; let isLoading = false; for (const environmentId of parseArchivedThreadsEnvironmentKey(environmentKey)) { const result = get(options.getSnapshotAtom(environmentId)); isLoading ||= result.waiting; const snapshot = Option.getOrNull(AsyncResult.value(result)); if (snapshot !== null) { snapshots.push({ environmentId, snapshot }); } if (error === null && result._tag === "Failure") { error = "Failed to load archived threads."; } } return { snapshots, error, isLoading }; }).pipe(Atom.withLabel(`${options.labelPrefix}:${environmentKey}`)), ); }