refactor(client): archivedSessionIds public face becomes a plain array

Public snapshot state stays in the store engine's plain-data vocabulary
(immer drafts reject Sets without the MapSet plugin, which stays off):
manager/service/contract carry readonly SessionId[] in Host order, and
the tree derivations build their own transient Set — the
expandedProjects pattern. Membership-unchanged installs still keep the
array reference for Object.is short-circuits.
This commit is contained in:
imccyu
2026-07-31 10:40:09 +08:00
committed by imccyu
parent 5fc2645afc
commit 9ed87a6dba
26 changed files with 62 additions and 53 deletions
@@ -554,7 +554,7 @@ describe('workspaces action face', () => {
// Default archive mirrors the production effect: the id joins the list
// state's archive set (features render against the same snapshot).
await ws.archiveSession('s1' as SessionId)
expect([...ws.list.getSnapshot().archivedSessionIds]).toEqual(['s1'])
expect(ws.list.getSnapshot().archivedSessionIds).toEqual(['s1'])
expect(ws.calls.map(c => c.method)).toEqual(
['create', 'create', 'pickDirectory', 'rename', 'delete', 'openPath', 'insertSessionBefore', 'archiveSession'])
@@ -573,7 +573,7 @@ describe('workspaces action face', () => {
expect((await ws.insertSessionBefore('w1' as WorkspaceId, 's1' as SessionId)).sessionIds).toEqual([])
// The stub replaces the default set mutation: the set stays as-is.
await ws.archiveSession('s2' as SessionId)
expect([...ws.list.getSnapshot().archivedSessionIds]).toEqual(['s1'])
expect(ws.list.getSnapshot().archivedSessionIds).toEqual(['s1'])
await runtime.dispose()
})
})