| 1 | import { useEffect, type Dispatch, type MutableRefObject, type SetStateAction } from "react"; |
| 2 | import type { TabMeta } from "../lib/types"; |
| 3 | import { hydrateComposerProfileFromMeta, hydrateComposerProfilesFromTabs, pruneUserPlanModeIntents, type ComposerProfile, type UserPlanModeIntents } from "../lib/composerProfile"; |
| 4 | |
| 5 | export function useTabProjectionLifecycle(input: { |
| 6 | tabs: readonly TabMeta[]; |
| 7 | activeTabId?: string | null; |
| 8 | activeMeta: TabMeta | null | undefined; |
| 9 | meta: Parameters<typeof hydrateComposerProfileFromMeta>[2] | null | undefined; |
| 10 | planIntentsRef: MutableRefObject<UserPlanModeIntents>; |
| 11 | setOrder: Dispatch<SetStateAction<string[]>>; |
| 12 | setProfiles: Dispatch<SetStateAction<Record<string, ComposerProfile>>>; |
| 13 | }) { |
| 14 | const { tabs, activeTabId, meta, planIntentsRef, setOrder, setProfiles } = input; |
| 15 | useEffect(() => { |
| 16 | const ids = tabs.map((tab) => tab.id); |
| 17 | setOrder((current) => { |
| 18 | const next = current.filter((id) => ids.includes(id)); |
| 19 | for (const id of ids) if (!next.includes(id)) next.push(id); |
| 20 | return next.join("\u0000") === current.join("\u0000") ? current : next; |
| 21 | }); |
| 22 | const present = new Set(ids); |
| 23 | planIntentsRef.current = pruneUserPlanModeIntents(planIntentsRef.current, present); |
| 24 | setProfiles((current) => hydrateComposerProfilesFromTabs(current, [...tabs])); |
| 25 | }, [planIntentsRef, setOrder, setProfiles, tabs]); |
| 26 | |
| 27 | useEffect(() => { |
| 28 | if (!activeTabId || !meta) return; |
| 29 | setProfiles((current) => hydrateComposerProfileFromMeta(current, activeTabId, meta)); |
| 30 | }, [activeTabId, meta, setProfiles]); |
| 31 | } |
| 32 |