65 lines
2.3 KiB
JavaScript
65 lines
2.3 KiB
JavaScript
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;
|