fix(app): reactive loops

This commit is contained in:
adamelmore
2026-01-24 00:35:02 -06:00
committed by Adam
parent da8f3e92a7
commit 962ab3bc8c
2 changed files with 53 additions and 13 deletions

View File

@@ -267,17 +267,36 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
return map return map
}) })
createEffect(() => { const rootFor = (directory: string) => {
const map = roots() const map = roots()
if (map.size === 0) return if (map.size === 0) return directory
const visited = new Set<string>()
const chain = [directory]
while (chain.length) {
const current = chain[chain.length - 1]
if (!current) return directory
const next = map.get(current)
if (!next) return current
if (visited.has(next)) return directory
visited.add(next)
chain.push(next)
}
return directory
}
createEffect(() => {
const projects = server.projects.list() const projects = server.projects.list()
const seen = new Set(projects.map((project) => project.worktree)) const seen = new Set(projects.map((project) => project.worktree))
batch(() => { batch(() => {
for (const project of projects) { for (const project of projects) {
const root = map.get(project.worktree) const root = rootFor(project.worktree)
if (!root) continue if (root === project.worktree) continue
server.projects.close(project.worktree) server.projects.close(project.worktree)
@@ -350,7 +369,7 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
projects: { projects: {
list, list,
open(directory: string) { open(directory: string) {
const root = roots().get(directory) ?? directory const root = rootFor(directory)
if (server.projects.list().find((x) => x.worktree === root)) return if (server.projects.list().find((x) => x.worktree === root)) return
globalSync.project.loadSessions(root) globalSync.project.loadSessions(root)
server.projects.open(root) server.projects.open(root)
@@ -384,7 +403,7 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
setStore("sidebar", "width", width) setStore("sidebar", "width", width)
}, },
workspaces(directory: string) { workspaces(directory: string) {
return createMemo(() => store.sidebar.workspaces[directory] ?? store.sidebar.workspacesDefault ?? false) return () => store.sidebar.workspaces[directory] ?? store.sidebar.workspacesDefault ?? false
}, },
setWorkspaces(directory: string, value: boolean) { setWorkspaces(directory: string, value: boolean) {
setStore("sidebar", "workspaces", directory, value) setStore("sidebar", "workspaces", directory, value)

View File

@@ -724,7 +724,8 @@ export default function Layout(props: ParentProps) {
if (!directory) return if (!directory) return
const [store] = globalSync.child(directory) const [store] = globalSync.child(directory)
if (store.message[session.id] !== undefined) return const cached = untrack(() => store.message[session.id] !== undefined)
if (cached) return
const q = queueFor(directory) const q = queueFor(directory)
if (q.inflight.has(session.id)) return if (q.inflight.has(session.id)) return
@@ -855,14 +856,34 @@ export default function Layout(props: ParentProps) {
setStore( setStore(
produce((draft) => { produce((draft) => {
const removed = new Set<string>([session.id]) const removed = new Set<string>([session.id])
const collect = (parentID: string) => {
for (const item of draft.session) { const byParent = new Map<string, string[]>()
if (item.parentID !== parentID) continue for (const item of draft.session) {
removed.add(item.id) const parentID = item.parentID
collect(item.id) if (!parentID) continue
const existing = byParent.get(parentID)
if (existing) {
existing.push(item.id)
continue
}
byParent.set(parentID, [item.id])
}
const stack = [session.id]
while (stack.length) {
const parentID = stack.pop()
if (!parentID) continue
const children = byParent.get(parentID)
if (!children) continue
for (const child of children) {
if (removed.has(child)) continue
removed.add(child)
stack.push(child)
} }
} }
collect(session.id)
draft.session = draft.session.filter((s) => !removed.has(s.id)) draft.session = draft.session.filter((s) => !removed.has(s.id))
}), }),
) )