Skip to content

Commit f699163

Browse files
authored
fix(client): register running sessions missed while disconnected (#53012)
1 parent 8b813d3 commit f699163

2 files changed

Lines changed: 23 additions & 1 deletion

File tree

‎packages/client/src/solid/data.ts‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,11 @@ export function createData(config: CreateDataInput) {
652652
})
653653
activeUpdates = undefined
654654
setStore("session", "active", reconcile(Object.fromEntries(snapshot)))
655+
// Sessions created before this connection (while disconnected, or before the client started)
656+
// never delivered `session.created`; without their info a running child never joins its root's family.
657+
snapshot.forEach((status, id) => {
658+
if (status === "running" && !store.session.info[id]) refresh(() => result.session.sync(id))
659+
})
655660
})
656661
.catch(() => {
657662
if (activeUpdates === updates) activeUpdates = undefined

‎packages/client/test/solid-data.test.ts‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1186,6 +1186,21 @@ test.each([
11861186
}
11871187
})
11881188

1189+
test("adds running sessions created while disconnected to their family", async () => {
1190+
const root = { ...session(0), id: "ses_root" }
1191+
const child = { ...session(0), id: "ses_child", parentID: "ses_root" }
1192+
const setup = activityFixture(() => Response.json({ data: { ses_child: { type: "running" } } }), [child])
1193+
1194+
try {
1195+
setup.data.session.remember(root)
1196+
setup.emit({ type: "server.connected", data: {} })
1197+
await wait(() => setup.data.session.family("ses_root").includes("ses_child"))
1198+
expect(setup.data.session.status("ses_child")).toBe("running")
1199+
} finally {
1200+
setup.dispose()
1201+
}
1202+
})
1203+
11891204
test("ignores activity snapshots from an older connection", async () => {
11901205
const reads: ReturnType<typeof Promise.withResolvers<Response>>[] = []
11911206
const setup = activityFixture(() => {
@@ -1257,14 +1272,16 @@ function modelInfo(name: string): ModelInfo {
12571272
}
12581273
}
12591274

1260-
function activityFixture(read: () => Response | Promise<Response>) {
1275+
function activityFixture(read: () => Response | Promise<Response>, sessions: SessionInfo[] = []) {
12611276
const listeners = new Set<Parameters<CreateDataInput["event"]["listen"]>[0]>()
12621277
const api = OpenCode.make({
12631278
baseUrl: "http://opencode.local",
12641279
fetch: async (input, init) => {
12651280
const request = input instanceof Request ? input : new Request(input, init)
12661281
const path = new URL(request.url).pathname
12671282
if (path === "/api/session/active") return read()
1283+
const known = sessions.find((item) => path === `/api/session/${item.id}`)
1284+
if (known) return Response.json({ data: known })
12681285
if (path === "/api/project") return Response.json([])
12691286
if (path === "/api/location") return Response.json({ directory: "/project" })
12701287
return Response.json({ location: { directory: "/project" }, data: { branch: "main" } })

0 commit comments

Comments
 (0)