11import { useAtomValue } from "@effect/atom-react" ;
2- import { EnvironmentId , type OrchestrationShellSnapshot } from "@t3tools/contracts" ;
3- import { AsyncResult , Atom } from "effect/unstable/reactivity" ;
2+ import {
3+ type ArchivedSnapshotEntry ,
4+ createArchivedThreadsManager ,
5+ makeArchivedThreadsEnvironmentKey ,
6+ readArchivedThreadsSnapshotState ,
7+ } from "@t3tools/client-runtime" ;
8+ import type { EnvironmentId } from "@t3tools/contracts" ;
49import { useCallback , useMemo } from "react" ;
5- import * as Cause from "effect/Cause" ;
6- import * as Effect from "effect/Effect" ;
7- import * as Option from "effect/Option" ;
10+
811import { readEnvironmentApi } from "../environmentApi" ;
912import { appAtomRegistry } from "../rpc/atomRegistry" ;
1013
11- const ARCHIVED_THREADS_STALE_TIME_MS = 5_000 ;
12- const ARCHIVED_THREADS_IDLE_TTL_MS = 5 * 60_000 ;
13- const ARCHIVED_THREADS_ENVIRONMENT_KEY_SEPARATOR = "\u001f" ;
14-
15- export type ArchivedSnapshotEntry = {
16- readonly environmentId : EnvironmentId ;
17- readonly snapshot : OrchestrationShellSnapshot ;
18- } ;
19-
20- const knownArchivedThreadEnvironmentKeys = new Set < string > ( ) ;
21-
22- function makeArchivedThreadsEnvironmentKey ( environmentIds : ReadonlyArray < EnvironmentId > ) : string {
23- return environmentIds . toSorted ( ) . join ( ARCHIVED_THREADS_ENVIRONMENT_KEY_SEPARATOR ) ;
24- }
25-
26- function parseArchivedThreadsEnvironmentKey ( key : string ) : ReadonlyArray < EnvironmentId > {
27- if ( key . length === 0 ) {
28- return [ ] ;
29- }
30- return key
31- . split ( ARCHIVED_THREADS_ENVIRONMENT_KEY_SEPARATOR )
32- . map ( ( environmentId ) => EnvironmentId . make ( environmentId ) ) ;
33- }
34-
35- const archivedThreadSnapshotsAtom = Atom . family ( ( environmentKey : string ) => {
36- knownArchivedThreadEnvironmentKeys . add ( environmentKey ) ;
37- return Atom . make (
38- Effect . promise ( async ( ) : Promise < ReadonlyArray < ArchivedSnapshotEntry > > => {
39- const environmentIds = parseArchivedThreadsEnvironmentKey ( environmentKey ) ;
40- const snapshots = await Promise . all (
41- environmentIds . map ( async ( environmentId ) => {
42- const api = readEnvironmentApi ( environmentId ) ;
43- if ( ! api ) {
44- return null ;
45- }
46- return {
47- environmentId,
48- snapshot : await api . orchestration . getArchivedShellSnapshot ( ) ,
49- } ;
50- } ) ,
51- ) ;
52- return snapshots . filter ( ( snapshot ) => snapshot !== null ) ;
53- } ) ,
54- ) . pipe (
55- Atom . swr ( {
56- staleTime : ARCHIVED_THREADS_STALE_TIME_MS ,
57- revalidateOnMount : true ,
58- } ) ,
59- Atom . setIdleTTL ( ARCHIVED_THREADS_IDLE_TTL_MS ) ,
60- Atom . withLabel ( `archived-thread-snapshots:${ environmentKey } ` ) ,
61- ) ;
14+ const archivedThreadsManager = createArchivedThreadsManager ( {
15+ getRegistry : ( ) => appAtomRegistry ,
16+ getClient : ( environmentId ) => readEnvironmentApi ( environmentId ) ?. orchestration ?? null ,
6217} ) ;
6318
64- function readArchivedThreadsError (
65- result : AsyncResult . AsyncResult < ReadonlyArray < ArchivedSnapshotEntry > , unknown > ,
66- ) : string | null {
67- if ( result . _tag !== "Failure" ) {
68- return null ;
69- }
70-
71- const error = Cause . squash ( result . cause ) ;
72- return error instanceof Error ? error . message : "Failed to load archived threads." ;
73- }
74-
7519export function refreshArchivedThreadsForEnvironment ( environmentId : EnvironmentId ) : void {
76- for ( const key of knownArchivedThreadEnvironmentKeys ) {
77- if ( parseArchivedThreadsEnvironmentKey ( key ) . includes ( environmentId ) ) {
78- appAtomRegistry . refresh ( archivedThreadSnapshotsAtom ( key ) ) ;
79- }
80- }
20+ archivedThreadsManager . refreshForEnvironment ( environmentId ) ;
8121}
8222
8323export function useArchivedThreadSnapshots ( environmentIds : ReadonlyArray < EnvironmentId > ) : {
@@ -90,17 +30,14 @@ export function useArchivedThreadSnapshots(environmentIds: ReadonlyArray<Environ
9030 ( ) => makeArchivedThreadsEnvironmentKey ( environmentIds ) ,
9131 [ environmentIds ] ,
9232 ) ;
93- const atom = archivedThreadSnapshotsAtom ( environmentKey ) ;
33+ const atom = archivedThreadsManager . getAtom ( environmentKey ) ;
9434 const result = useAtomValue ( atom ) ;
95- const snapshots = Option . getOrElse ( AsyncResult . value ( result ) , ( ) => [ ] ) ;
9635 const refresh = useCallback ( ( ) => {
97- appAtomRegistry . refresh ( atom ) ;
98- } , [ atom ] ) ;
36+ archivedThreadsManager . refresh ( environmentIds ) ;
37+ } , [ environmentIds ] ) ;
9938
10039 return {
101- snapshots,
102- error : readArchivedThreadsError ( result ) ,
103- isLoading : result . waiting ,
40+ ...readArchivedThreadsSnapshotState ( result ) ,
10441 refresh,
10542 } ;
10643}
0 commit comments