function createUpdateReplyReadNext({ post, markRead, queue, canQueue, deliver, accept = () => undefined, next = () => undefined, }) { let inFlight = null; async function admit(item, body, operationId, replyConfirmed) { const admission = await queue({ kind: 'update-reply-read', notificationId: item.notification_id, body, operationId, replyConfirmed, }); if (!admission || (!admission.item && admission.durable !== true)) { throw new Error('Reply and acknowledgement were not saved for delivery.'); } accept(item); return { accepted: true, delivery: admission.background ? 'queued' : 'saved', next: await next(item), }; } function submit(item, body, operationId, attachment = null) { if (inFlight) return inFlight; inFlight = (async () => { let replyConfirmed = false; try { if (attachment) { const admission = await queue({ kind:'update-reply-read', notificationId:item.notification_id, body, operationId, replyConfirmed:false, attachment, }); if (!admission?.item) throw new Error('Reply and screenshot were not saved for delivery.'); const outcome = deliver ? await deliver(admission.item) : null; const remaining = outcome?.remaining?.find(candidate => candidate.id === admission.item.id); if (remaining?.status === 'attention') { throw new Error(remaining.error || 'Reply and screenshot need attention.'); } accept(item); return { accepted:true, delivery:outcome?.confirmed?.length ? 'posted' : 'queued', next:await next(item) }; } try { await post(item, body, operationId); replyConfirmed = true; await markRead(item.notification_id); } catch (error) { if (!canQueue(error)) throw error; return await admit(item, body, operationId, replyConfirmed); } accept(item); return { accepted: true, delivery: 'posted', next: await next(item) }; } finally { inFlight = null; } })(); return inFlight; } return { submit, busy: () => Boolean(inFlight) }; } if (typeof module !== 'undefined' && module.exports) module.exports = createUpdateReplyReadNext;