diff --git a/frontend/conversation-photo-drafts.js b/frontend/conversation-photo-drafts.js index d1a41aa..ad052d1 100644 --- a/frontend/conversation-photo-drafts.js +++ b/frontend/conversation-photo-drafts.js @@ -35,12 +35,11 @@ await current.pending; const attachments = await store.load(target); if (generation !== current.generation) return false; - current.controller.clear(); - if (attachments?.length) { - current.restoring = true; - try { current.controller.restore(attachments); } - finally { current.restoring = false; } - } + current.restoring = true; + try { + current.controller.clear(); + if (attachments?.length) current.controller.restore(attachments); + } finally { current.restoring = false; } return Boolean(attachments?.length); } @@ -51,9 +50,13 @@ try { await checkpoint(kind); } catch (_error) { return false; } if (generation === current.generation) { - current.controller.clear(); - current.target = null; - current.generation += 1; + current.restoring = true; + try { current.controller.clear(); } + finally { + current.restoring = false; + current.target = null; + current.generation += 1; + } } return true; } @@ -64,9 +67,13 @@ const target = { ...current.target }; await current.pending; await store.remove(target); - current.controller.clear(); - current.target = null; - current.generation += 1; + current.restoring = true; + try { current.controller.clear(); } + finally { + current.restoring = false; + current.target = null; + current.generation += 1; + } return true; } diff --git a/tests/test_conversation_photo_drafts.py b/tests/test_conversation_photo_drafts.py index 46f63b2..fc02fbd 100644 --- a/tests/test_conversation_photo_drafts.py +++ b/tests/test_conversation_photo_drafts.py @@ -168,6 +168,35 @@ const drafts = createCoordinator({{store, lanes:{{issue:{{controller}}}}}}); assert json.loads(run_node(script)) == ["save:1:first.webp", "restore:second.webp"] +def test_coordinator_clear_does_not_delete_the_durable_draft_during_reopen(): + script = f""" +const createCoordinator = require({json.dumps(str(COORDINATOR))}); +const records=new Map(); let current=[]; let drafts; const restored=[]; +const key=target=>target.kind+':'+target.number; +const store={{ + save:async(target,attachments)=>attachments?.length?records.set(key(target),attachments):records.delete(key(target)), + load:async target=>records.get(key(target))||null, + remove:async target=>records.delete(key(target)), +}}; +const controller={{ + serialize:async()=>current, + restore:value=>{{current=value;restored.push(value[0].filename);}}, + clear:()=>{{current=[];drafts.checkpoint('today').catch(()=>{{}});}}, +}}; +drafts=createCoordinator({{store,lanes:{{today:{{controller}}}}}}); +const target={{kind:'issue',repository:'stackchain/dashboard',number:1054}}; +(async()=>{{ + await drafts.open('today',target); + current=[{{filename:'proof.webp',contentType:'image/webp',blob:new Blob(['proof'])}}]; + await drafts.checkpoint('today'); + await drafts.switchTo('today',target); + await Promise.resolve(); + process.stdout.write(JSON.stringify({{restored,saved:(await store.load(target))?.[0]?.filename||null}})); +}})().catch(error=>{{console.error(error);process.exit(1);}}); +""" + assert json.loads(run_node(script)) == {"restored": ["proof.webp"], "saved": "proof.webp"} + + def test_my_work_wires_durable_photo_drafts_into_all_conversation_boundaries(): dashboard = DASHBOARD.read_text() html = INDEX.read_text()