function createAssignAndStart({ available, claim, start, recover, announce }) { let request = null; function run(item, { alreadyOwned = false } = {}) { if (request) return request; if (!available()) { announce('Today is full—remove an item before assigning this issue.'); return Promise.resolve('full'); } request = Promise.resolve() .then(() => alreadyOwned ? item : claim(item)) .then(confirmed => { const outcome = start(confirmed); if (outcome === 'started') { announce(alreadyOwned ? 'Added to Today and ready to work.' : 'Assigned, added to Today, and ready to work.'); return outcome; } announce(alreadyOwned ? 'Today could not start. The issue is open so you can recover.' : 'Assigned to you, but Today could not start. The issue is open so you can recover.'); recover(confirmed); return 'recovery'; }) .finally(() => { request = null; }); return request; } return { run }; } if (typeof module !== 'undefined' && module.exports) module.exports = createAssignAndStart;