fix(app): reactive loops
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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))
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user