(function (root, factory) { const api = factory(); if (typeof module === 'object' && module.exports) module.exports = api; else root.createTodayReadiness = api; })(typeof globalThis !== 'undefined' ? globalThis : this, function () { 'use strict'; return function createTodayReadiness({ inspect, onOpen = () => {}, onGate = () => {}, onPreview = () => {} }) { let pending = null; let generation = 0; async function classify(item) { if (item?.kind !== 'issue') return { status:'ready', dependencies:[] }; try { const detail = await inspect(item); if (detail?.available !== true) return { status:'unknown', dependencies:[] }; const dependencies = Array.isArray(detail.dependencies) ? detail.dependencies.filter(dependency => dependency?.state === 'open') : []; return { status:dependencies.length ? 'blocked' : 'ready', dependencies }; } catch (_error) { return { status:'unknown', dependencies:[] }; } } async function run(action, items, target = null) { const request = ++generation; const ordered = Array.isArray(items) ? items.slice() : []; const preferred = target || ordered[0] || null; if (!preferred) return 'empty'; const preferredIndex = ordered.indexOf(preferred); const candidates = preferredIndex >= 0 ? ordered.slice(preferredIndex).concat(ordered.slice(0, preferredIndex)) : [preferred].concat(ordered); const targetState = { item:preferred, ...(await classify(preferred)) }; if (request !== generation) return 'superseded'; if (targetState.status === 'ready') { pending = null; onOpen(action, preferred); return 'opened'; } const fallbackStates = await Promise.all(candidates.slice(1).map(async item => ({ item, ...(await classify(item)), }))); const states = [targetState, ...fallbackStates]; if (request !== generation) return 'superseded'; const nextReadyState = states.slice(1).find(state => state.status === 'ready'); pending = { action, items:ordered, target:preferred, status:targetState.status, dependencies:targetState.dependencies, nextReady:nextReadyState?.item || null, }; onGate({ ...pending, items:pending.items.slice() }); return 'gated'; } function open(item) { if (!pending || !item) return false; const action = pending.action; pending = null; generation += 1; onOpen(action, item); return true; } function previewBlocker(blocker) { if (!pending || !blocker) return false; const current = pending.dependencies.find(dependency => dependency?.repository === blocker.repository && Number(dependency?.number) === Number(blocker.number) ); if (!current) return false; onPreview(current); return true; } return { run, retry: () => pending ? run(pending.action, pending.items, pending.target) : Promise.resolve('closed'), previewBlocker, startNextReady: () => open(pending?.nextReady), workAnyway: () => open(pending?.target), cancel() { generation += 1; pending = null; }, snapshot: () => pending ? { ...pending, items:pending.items.slice() } : { open:false }, }; }; });