1import { useAtomValue } from "@effect/atom-react";
2import { scopeThreadRef } from "@t3tools/client-runtime/environment";
3import {
4 EMPTY_V2_ITEM_SUPPORT,
5 resolveV2ItemSupport,
6 v2ItemSupportEqual,
7 type V2ItemSupport,
8} from "@t3tools/client-runtime/state/item-support";
9import type { EnvironmentId, ThreadId, TurnItemId } from "@t3tools/contracts";
10import { Atom } from "effect/reactivity";
11
12import { environmentThreadDetails } from "./threads";
13
14interface ItemSupportTarget {
15 readonly environmentId: EnvironmentId;
16 readonly threadId: ThreadId;
17 readonly itemId: TurnItemId;
18}
19
20function supportKey(target: ItemSupportTarget): string {
21 return JSON.stringify(target);
22}
23
24function parseSupportKey(key: string): ItemSupportTarget {
25 return JSON.parse(key) as ItemSupportTarget;
26}
27
28const itemSupportAtomFamily = Atom.family((key: string) => {
29 const target = parseSupportKey(key);
30 const ref = scopeThreadRef(target.environmentId, target.threadId);
31 let previous = EMPTY_V2_ITEM_SUPPORT;
32 return Atom.make((get): V2ItemSupport => {
33 const scoped = get(environmentThreadDetails.threadAtom(ref));
34 if (scoped === null) return EMPTY_V2_ITEM_SUPPORT;
35 const next = resolveV2ItemSupport(scoped.projection, target.itemId);
36 if (v2ItemSupportEqual(previous, next)) return previous;
37 previous = next;
38 return next;
39 }).pipe(Atom.withLabel(`mobile-v2-item-support:${key}`));
40});
41
42export function useV2ItemSupport(target: {
43 readonly environmentId: EnvironmentId;
44 readonly sourceThreadId: ThreadId;
45 readonly sourceItemId: TurnItemId;
46}): V2ItemSupport {
47 return useAtomValue(
48 itemSupportAtomFamily(
49 supportKey({
50 environmentId: target.environmentId,
51 threadId: target.sourceThreadId,
52 itemId: target.sourceItemId,
53 }),
54 ),
55 );
56}