Skip to content
Source
Sign inSign up

use-thread-detail.ts

109 lines3.9 KB

1import { useAtomValue } from "@effect/atom-react";
2import type { PendingThreadRequests } from "@t3tools/client-runtime/state/thread-requests";
3import type { EnvironmentThreadStructure } from "@t3tools/client-runtime/state/models";
4import type { EnvironmentThread } from "@t3tools/client-runtime/state/shell";
5import type {
6 EnvironmentId,
7 OrchestrationV2ThreadProjection,
8 ScopedThreadRef,
9 ThreadId,
10} from "@t3tools/contracts";
11import { Atom } from "effect/reactivity";
12​
13import { environmentThreadDetails, useEnvironmentThread } from "./threads";
14import { useThreadSelection } from "./use-thread-selection";
15​
16const EMPTY_THREAD_PROJECTION_ATOM = Atom.make<EnvironmentThread | null>(null).pipe(
17 Atom.withLabel("mobile-thread-projection:empty"),
18);
19const EMPTY_THREAD_STRUCTURE_ATOM = Atom.make<EnvironmentThreadStructure | null>(null).pipe(
20 Atom.withLabel("mobile-thread-structure:empty"),
21);
22const EMPTY_VISIBLE_TURN_ITEMS_ATOM = Atom.make<
23 OrchestrationV2ThreadProjection["visibleTurnItems"]
24>(Object.freeze([])).pipe(Atom.withLabel("mobile-thread-visible-turn-items:empty"));
25​
26export interface ThreadDetailTarget {
27 readonly environmentId: EnvironmentId | null;
28 readonly threadId: ThreadId | null;
30​
31export function useSelectedThreadDetailState() {
32 const { selectedThreadDetailRef } = useThreadSelection();
33 return useEnvironmentThread(
34 selectedThreadDetailRef?.environmentId ?? null,
35 selectedThreadDetailRef?.threadId ?? null,
36 );
38​
39function useThreadProjection(target: ThreadDetailTarget): EnvironmentThread | null {
40 return useAtomValue(
41 target.environmentId === null || target.threadId === null
42 ? EMPTY_THREAD_PROJECTION_ATOM
43 : environmentThreadDetails.threadAtom({
44 environmentId: target.environmentId,
45 threadId: target.threadId,
46 }),
47 );
49​
50/** Keeps its value through streamed text; runs, sessions, and item status still update. */
51export function useQuietThreadStructure(
52 ref: ScopedThreadRef | null,
53): EnvironmentThreadStructure | null {
54 return useAtomValue(
55 ref === null ? EMPTY_THREAD_STRUCTURE_ATOM : environmentThreadDetails.quietThreadAtom(ref),
56 );
58​
59export function useSelectedThreadProjection(): EnvironmentThread | null {
60 const { selectedThreadDetailRef } = useThreadSelection();
61 return useThreadProjection({
62 environmentId: selectedThreadDetailRef?.environmentId ?? null,
63 threadId: selectedThreadDetailRef?.threadId ?? null,
64 });
66​
67function useThreadVisibleTurnItems(
68 target: ThreadDetailTarget,
69): OrchestrationV2ThreadProjection["visibleTurnItems"] {
70 return useAtomValue(
71 target.environmentId === null || target.threadId === null
72 ? EMPTY_VISIBLE_TURN_ITEMS_ATOM
73 : environmentThreadDetails.visibleTurnItemsAtom({
74 environmentId: target.environmentId,
75 threadId: target.threadId,
76 }),
77 );
79​
80export function useSelectedThreadVisibleTurnItems(): OrchestrationV2ThreadProjection["visibleTurnItems"] {
81 const { selectedThreadDetailRef } = useThreadSelection();
82 return useThreadVisibleTurnItems({
83 environmentId: selectedThreadDetailRef?.environmentId ?? null,
84 threadId: selectedThreadDetailRef?.threadId ?? null,
85 });
87​
88const EMPTY_WORKTREE_PATH_ATOM = Atom.make<string | null>(null);
89const EMPTY_PENDING_REQUESTS_ATOM = Atom.make<PendingThreadRequests | null>(null);
90​
91export function useThreadWorktreePath(ref: ScopedThreadRef | null) {
92 return useAtomValue(
93 ref === null ? EMPTY_WORKTREE_PATH_ATOM : environmentThreadDetails.worktreePathAtom(ref),
94 );
96​
97export function useSelectedThreadWorktreePath() {
98 const { selectedThreadDetailRef } = useThreadSelection();
99 return useThreadWorktreePath(selectedThreadDetailRef);
101​
102export function useSelectedThreadPendingRequests() {
103 const { selectedThreadDetailRef } = useThreadSelection();
104 return useAtomValue(
105 selectedThreadDetailRef === null
106 ? EMPTY_PENDING_REQUESTS_ATOM
107 : environmentThreadDetails.pendingRequestsAtom(selectedThreadDetailRef),
108 );