fix: keep a parked draft from outranking a discard asked after it

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015vn1jCHUcAdaG9C4NsUehF
This commit is contained in:
Ruben Fiszel
2026-09-14 20:13:20 +02:00
co-authored by Claude Opus 5
parent 4ea45a83aa
commit 8d0966d902
2 changed files with 20 additions and 2 deletions
+4
View File
@@ -803,7 +803,11 @@ export function createItemStore(ports: ItemRowPort) {
const arrived = arrivals.get(to)
if (arrived !== undefined) {
arrivals.delete(to)
// Parked before anything this entry has been asked since, so applying it now does not
// make it the latest ask: a discard asked meanwhile still outranks it.
const asked = entry.lastOutsideAsk
entry.applyExternal(arrived)
entry.lastOutsideAsk = asked
}
},
/**
+16 -2
View File
@@ -620,7 +620,11 @@ describe('item store: one entry per key', () => {
const b = { ...deployedRes, path: 'u/me/b' }
const moveOnto = async (
openBefore: boolean,
outside: (store: ReturnType<typeof createItemStore>, open: () => void) => void,
outside: (
store: ReturnType<typeof createItemStore>,
open: () => void,
moving: ItemHandle<Res>
) => void,
refuse?: string
) => {
const rows = fakeRows()
@@ -648,7 +652,7 @@ describe('item store: one entry per key', () => {
).handle
}
if (openBefore) open()
outside(store, open)
outside(store, open, moving)
gate.resolve()
expect(await moved).toMatchObject(refuse ? { ok: false } : { ok: true, moved: true })
await settle()
@@ -687,6 +691,16 @@ describe('item store: one entry per key', () => {
expect(failed.shown.value).toEqual(again)
expect(failed.rows.writes.at(-1)).toEqual({ path: 'u/me/b', value: again })
// A draft parked for the move, then Discard clicked on the editor doing the moving: the
// discard came last, so the parked draft does not come back with the item.
const discardedAfterParking = await moveOnto(false, (store, open, moving) => {
store.bridge.seed('w', 'resource', 'u/me/b', { ...b, description: 'parked draft' })
open()
void moving.discard()
})
expect(discardedAfterParking.moving.dirty).toBe(false)
expect(discardedAfterParking.rows.writes.at(-1)).toEqual({ path: 'u/me/b', value: null })
// Deleted last: the delete is what holds, however many drafts preceded it.
const deleted = await moveOnto(true, (store) => {
store.bridge.seed('w', 'resource', 'u/me/b', { ...b, description: 'first draft' })