function createFeatureLoader({ document, urls, timeoutMs = 10000 }) { const pending = new Map(); const loaded = new Set(); function load(name) { if (loaded.has(name)) return Promise.resolve(); if (pending.has(name)) return pending.get(name); const url = urls[name]; if (!url) return Promise.reject(new Error('Unknown feature: ' + name)); const request = new Promise((resolve, reject) => { const script = document.createElement('script'); let timeout; const fail = () => { clearTimeout(timeout); script.remove(); pending.delete(name); reject(new Error('Could not load ' + name.replace(/-/g, ' ') + '.')); }; script.src = url; script.async = true; script.onload = () => { clearTimeout(timeout); pending.delete(name); loaded.add(name); resolve(); }; script.onerror = fail; timeout = setTimeout(fail, timeoutMs); document.head.appendChild(script); }); pending.set(name, request); return request; } async function run(name, elements, callback) { const trigger = elements?.trigger; const status = elements?.status; const retryLabel = elements?.retryLabel || 'Tap New issue to retry.'; if (trigger) trigger.disabled = true; if (status) status.textContent = 'Loading ' + name.replace(/-/g, ' ') + '…'; try { await load(name); callback(); if (status) status.textContent = ''; return true; } catch (_error) { if (status) { const label = name === 'issue-capture' ? 'Issue capture' : name === 'pull-workflow' ? 'Pull workspace' : name === 'security-center' ? 'Security center' : name.replace(/-/g, ' '); status.textContent = label + ' could not load. ' + retryLabel; } return false; } finally { if (trigger) trigger.disabled = false; } } return { load, run, ready: name => loaded.has(name) }; } if (typeof module !== 'undefined' && module.exports) module.exports = createFeatureLoader;