fix(app): make terminal sessions scoped to workspace
This commit is contained in:
@@ -25,11 +25,11 @@ type TerminalCacheEntry = {
|
|||||||
dispose: VoidFunction
|
dispose: VoidFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTerminalSession(sdk: ReturnType<typeof useSDK>, dir: string, id: string | undefined) {
|
function createTerminalSession(sdk: ReturnType<typeof useSDK>, dir: string, session?: string) {
|
||||||
const legacy = `${dir}/terminal${id ? "/" + id : ""}.v1`
|
const legacy = session ? [`${dir}/terminal/${session}.v1`, `${dir}/terminal.v1`] : [`${dir}/terminal.v1`]
|
||||||
|
|
||||||
const [store, setStore, _, ready] = persisted(
|
const [store, setStore, _, ready] = persisted(
|
||||||
Persist.scoped(dir, id, "terminal", [legacy]),
|
Persist.workspace(dir, "terminal", legacy),
|
||||||
createStore<{
|
createStore<{
|
||||||
active?: string
|
active?: string
|
||||||
all: LocalPTY[]
|
all: LocalPTY[]
|
||||||
@@ -43,17 +43,28 @@ function createTerminalSession(sdk: ReturnType<typeof useSDK>, dir: string, id:
|
|||||||
all: createMemo(() => Object.values(store.all)),
|
all: createMemo(() => Object.values(store.all)),
|
||||||
active: createMemo(() => store.active),
|
active: createMemo(() => store.active),
|
||||||
new() {
|
new() {
|
||||||
|
const parse = (title: string) => {
|
||||||
|
const match = title.match(/^Terminal (\d+)$/)
|
||||||
|
if (!match) return
|
||||||
|
const value = Number(match[1])
|
||||||
|
if (!Number.isFinite(value) || value <= 0) return
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
const existingTitleNumbers = new Set(
|
const existingTitleNumbers = new Set(
|
||||||
store.all.map((pty) => {
|
store.all.flatMap((pty) => {
|
||||||
const match = pty.titleNumber
|
const direct = Number.isFinite(pty.titleNumber) && pty.titleNumber > 0 ? pty.titleNumber : undefined
|
||||||
return match
|
if (direct !== undefined) return [direct]
|
||||||
|
const parsed = parse(pty.title)
|
||||||
|
if (parsed === undefined) return []
|
||||||
|
return [parsed]
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
let nextNumber = 1
|
const nextNumber =
|
||||||
while (existingTitleNumbers.has(nextNumber)) {
|
Array.from({ length: existingTitleNumbers.size + 1 }, (_, index) => index + 1).find(
|
||||||
nextNumber++
|
(number) => !existingTitleNumbers.has(number),
|
||||||
}
|
) ?? 1
|
||||||
|
|
||||||
sdk.client.pty
|
sdk.client.pty
|
||||||
.create({ title: `Terminal ${nextNumber}` })
|
.create({ title: `Terminal ${nextNumber}` })
|
||||||
@@ -166,8 +177,8 @@ export const { use: useTerminal, provider: TerminalProvider } = createSimpleCont
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const load = (dir: string, id: string | undefined) => {
|
const load = (dir: string, session?: string) => {
|
||||||
const key = `${dir}:${id ?? WORKSPACE_KEY}`
|
const key = `${dir}:${WORKSPACE_KEY}`
|
||||||
const existing = cache.get(key)
|
const existing = cache.get(key)
|
||||||
if (existing) {
|
if (existing) {
|
||||||
cache.delete(key)
|
cache.delete(key)
|
||||||
@@ -176,7 +187,7 @@ export const { use: useTerminal, provider: TerminalProvider } = createSimpleCont
|
|||||||
}
|
}
|
||||||
|
|
||||||
const entry = createRoot((dispose) => ({
|
const entry = createRoot((dispose) => ({
|
||||||
value: createTerminalSession(sdk, dir, id),
|
value: createTerminalSession(sdk, dir, session),
|
||||||
dispose,
|
dispose,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@@ -185,18 +196,18 @@ export const { use: useTerminal, provider: TerminalProvider } = createSimpleCont
|
|||||||
return entry.value
|
return entry.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const session = createMemo(() => load(params.dir!, params.id))
|
const workspace = createMemo(() => load(params.dir!, params.id))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
ready: () => session().ready(),
|
ready: () => workspace().ready(),
|
||||||
all: () => session().all(),
|
all: () => workspace().all(),
|
||||||
active: () => session().active(),
|
active: () => workspace().active(),
|
||||||
new: () => session().new(),
|
new: () => workspace().new(),
|
||||||
update: (pty: Partial<LocalPTY> & { id: string }) => session().update(pty),
|
update: (pty: Partial<LocalPTY> & { id: string }) => workspace().update(pty),
|
||||||
clone: (id: string) => session().clone(id),
|
clone: (id: string) => workspace().clone(id),
|
||||||
open: (id: string) => session().open(id),
|
open: (id: string) => workspace().open(id),
|
||||||
close: (id: string) => session().close(id),
|
close: (id: string) => workspace().close(id),
|
||||||
move: (id: string, to: number) => session().move(id, to),
|
move: (id: string, to: number) => workspace().move(id, to),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user