fix: keep client session projection stores across removal and revival
The per-session ProjectionValueStore was deleted on host/session-removed even though the Session instance survives removal (open() is idempotent and drop() only removes the map entry). A re-added or re-listed session resumed on the same instance with an empty projection face, so projection-backed UI (such as the OpenRouter cost readout) reverted to blank until a fresh host baseline landed. Retain the store on removal and lift the removed tombstone from the surviving instance on revival (host/session-added and list-refresh re-listing), so chat switching keeps cost readouts populated.
This commit is contained in:
@@ -190,7 +190,7 @@ describe('list lifecycle', () => {
|
||||
expect(manager.getListSnapshot().items.map(i => i.sessionId)).toEqual([S2])
|
||||
})
|
||||
|
||||
it('retains title projections before list arrival, keeps last-wins by seq, and clears them on removal', async () => {
|
||||
it('retains title projections before list arrival, keeps last-wins by seq, and survives removal', async () => {
|
||||
const api = new FakeApiClient()
|
||||
const manager = new SessionManager(api, fakeRemote())
|
||||
const titleFrame = (rpcId: string, title: string, seq: number) => {
|
||||
@@ -212,9 +212,13 @@ describe('list lifecycle', () => {
|
||||
expect(titled.items[0]?.title).toBe('Newest')
|
||||
expect(titled.items[1]?.title).toBeUndefined()
|
||||
|
||||
// A removed-then-re-added session is the same durable lifecycle under the
|
||||
// resident-instance rule: its projection face (here the title) survives
|
||||
// the round-trip, so the row resurfacing shows the retained value rather
|
||||
// than re-seeding from an empty store.
|
||||
manager.handleHostEnvelope({ rpcId: 'removed' as never, payload: { type: 'host/session-removed', sessionId: S1 } })
|
||||
manager.handleHostEnvelope({ rpcId: 'readded' as never, payload: { type: 'host/session-added', blank: true, sessionId: S1 } })
|
||||
expect(manager.getListSnapshot().items.find(item => item.sessionId === S1)?.title).toBeUndefined()
|
||||
expect(manager.getListSnapshot().items.find(item => item.sessionId === S1)?.title).toBe('Newest')
|
||||
})
|
||||
|
||||
it('seeds cold titles from the list rows\' projections block under higher-seq-wins', async () => {
|
||||
|
||||
Reference in New Issue
Block a user