| 1 | import { useState } from "react"; |
| 2 | import { useCommittedCommand } from "../lib/useCommittedCommand"; |
| 3 | import { activeTabMirror } from "./activeTabMirror"; |
| 4 | import type { InvocationMetadataMap } from "../lib/invocationDisplay"; |
| 5 | |
| 6 | /** |
| 7 | * Owns the per-tab invocation metadata ledger: commits are bound to the |
| 8 | * layout-committed active tab through the mirror, never a stale render |
| 9 | * capture, and identical kind/color maps commit as no-ops. |
| 10 | */ |
| 11 | export function useInvocationMetadata() { |
| 12 | const [invocationMetadataByTab, setInvocationMetadataByTab] = useState<Record<string, InvocationMetadataMap>>({}); |
| 13 | const handleInvocationMetadataChange = useCommittedCommand((metadata: InvocationMetadataMap) => { |
| 14 | const sourceTabId = activeTabMirror().current; |
| 15 | if (!sourceTabId) return; |
| 16 | setInvocationMetadataByTab((current) => { |
| 17 | const previous = current[sourceTabId] ?? {}; |
| 18 | const names = Object.keys(metadata); |
| 19 | if (names.length === Object.keys(previous).length && names.every((name) => ( |
| 20 | previous[name]?.kind === metadata[name]?.kind && previous[name]?.color === metadata[name]?.color |
| 21 | ))) return current; |
| 22 | return { ...current, [sourceTabId]: metadata }; |
| 23 | }); |
| 24 | }); |
| 25 | return { invocationMetadataByTab, handleInvocationMetadataChange }; |
| 26 | } |
| 27 |