77 lines · 3.3 KB · TypeScript
RawDownload
import type { OrchestrationV2ThreadProjection, ScopedThreadRef } from "@t3tools/contracts";import * as Option from "effect/Option";import { AsyncResult, Atom } from "effect/unstable/reactivity"; import type { EnvironmentThread } from "./models.ts";import { EMPTY_ENVIRONMENT_THREAD_STATE, type EnvironmentThreadState } from "./threadState.ts";import { parseThreadKey, threadKey } from "./entities.ts"; const EMPTY_VISIBLE_TURN_ITEMS: OrchestrationV2ThreadProjection["visibleTurnItems"] = Object.freeze(  [],); export function createEnvironmentThreadDetailAtoms<E>(  threadStateAtom: (    environmentId: ScopedThreadRef["environmentId"],    threadId: ScopedThreadRef["threadId"],  ) => Atom.Atom<AsyncResult.AsyncResult<EnvironmentThreadState, E>>,) {  const threadStateValueAtomFamily = Atom.family((key: string) => {    const ref = parseThreadKey(key);    return Atom.make((get) =>      Option.getOrElse(        AsyncResult.value(get(threadStateAtom(ref.environmentId, ref.threadId))),        () => EMPTY_ENVIRONMENT_THREAD_STATE,      ),    ).pipe(Atom.setIdleTTL(0), Atom.withLabel(`environment-thread-state-value:${key}`));  });   const threadAtomFamily = Atom.family((key: string) => {    const ref = parseThreadKey(key);    let previousProjection: OrchestrationV2ThreadProjection | null = null;    let previousValue: EnvironmentThread | null = null;    return Atom.make((get) => {      const projection = Option.getOrNull(get(threadStateValueAtomFamily(key)).data);      if (projection === previousProjection) return previousValue;      previousProjection = projection;      previousValue = projection === null ? null : { environmentId: ref.environmentId, projection };      return previousValue;    }).pipe(Atom.setIdleTTL(0), Atom.withLabel(`environment-thread:${key}`));  });   const visibleTurnItemsAtomFamily = Atom.family((key: string) =>    Atom.make(      (get): OrchestrationV2ThreadProjection["visibleTurnItems"] =>        Option.getOrNull(get(threadStateValueAtomFamily(key)).data)?.visibleTurnItems ??        EMPTY_VISIBLE_TURN_ITEMS,    ).pipe(Atom.setIdleTTL(0), Atom.withLabel(`environment-thread-visible-turn-items:${key}`)),  );   const statusAtomFamily = Atom.family((key: string) =>    Atom.make((get) => get(threadStateValueAtomFamily(key)).status).pipe(      Atom.setIdleTTL(0),      Atom.withLabel(`environment-thread-status:${key}`),    ),  );  const errorAtomFamily = Atom.family((key: string) =>    Atom.make((get) => Option.getOrNull(get(threadStateValueAtomFamily(key)).error)).pipe(      Atom.setIdleTTL(0),      Atom.withLabel(`environment-thread-error:${key}`),    ),  );  const historyAtomFamily = Atom.family((key: string) =>    Atom.make((get) => get(threadStateValueAtomFamily(key)).history).pipe(      Atom.setIdleTTL(0),      Atom.withLabel(`environment-thread-history:${key}`),    ),  );   return {    stateAtom: (ref: ScopedThreadRef) => threadStateValueAtomFamily(threadKey(ref)),    threadAtom: (ref: ScopedThreadRef) => threadAtomFamily(threadKey(ref)),    visibleTurnItemsAtom: (ref: ScopedThreadRef) => visibleTurnItemsAtomFamily(threadKey(ref)),    statusAtom: (ref: ScopedThreadRef) => statusAtomFamily(threadKey(ref)),    errorAtom: (ref: ScopedThreadRef) => errorAtomFamily(threadKey(ref)),    historyAtom: (ref: ScopedThreadRef) => historyAtomFamily(threadKey(ref)),  };}