(function (root, factory) { const filterCommands = factory(); if (typeof module === 'object' && module.exports) module.exports = filterCommands; if (root) root.filterCommands = filterCommands; })(typeof globalThis !== 'undefined' ? globalThis : this, function () { function filterCommands(commands, filter) { const term = String(filter || '').toLowerCase(); return commands.filter(command => command.name.toLowerCase().includes(term)); } filterCommands.nextSelection = function nextSelection(current, key, count) { if (count < 1) return -1; if (key === 'ArrowDown') return (current + 1 + count) % count; if (key === 'ArrowUp') return (current - 1 + count) % count; return current; }; filterCommands.createGlobalSearchController = function createGlobalSearchController(options) { const search = options.search; const onState = options.onState; const delay = options.delay === undefined ? 250 : options.delay; let timer = null; let generation = 0; let activeController = null; let scope = { kind:'all', state:'all' }; let state = { status: 'idle', query: '', items: [], more: false, next: 1, scope }; function publish(next) { state = next; onState(next); } async function requestPage(query, page, current, append) { const requestController = new AbortController(); activeController = requestController; try { const requestScope = { ...scope }; const result = await search(query, requestController.signal, page, requestScope); const partial = result.partial === true; const incoming = result.items || result; const combined = append ? state.items.concat(incoming) : incoming; const items = [...new Map((combined || []).map(item => [`${item.kind}:${item.repository}:${item.number}`, item] )).values()]; if (current === generation) publish({ status: 'ready', query, items, partial, more: !!result.has_more, next: result.next_page, scope:requestScope, }); } catch (error) { if (error && error.name === 'AbortError') return; if (current === generation) publish(append ? { ...state, status: 'ready' } : { status: 'error', query, items: [], error, scope:{ ...scope } }); } finally { if (activeController === requestController) activeController = null; } } return { setQuery(value) { const query = String(value || '').trim(); generation += 1; const current = generation; if (timer !== null) clearTimeout(timer); if (activeController !== null) activeController.abort(); activeController = null; if (query.length < 2) { publish({ status: 'idle', query, items: [], more: false, next: 1, scope:{ ...scope } }); return; } publish({ status: 'loading', query, items: [], more: false, next: 1, scope:{ ...scope } }); timer = setTimeout(() => requestPage(query, 1, current, false), delay); }, setScope(value) { const repository = typeof value?.repository === 'string' && /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(value.repository.trim()) ? value.repository.trim() : ''; const next = { kind:['all', 'issue', 'pull'].includes(value?.kind) ? value.kind : 'all', state:['all', 'open', 'closed'].includes(value?.state) ? value.state : 'all', ...(repository ? { repository } : {}), }; if (next.kind === scope.kind && next.state === scope.state && (next.repository || '') === (scope.repository || '')) return; const query = state.query; scope = next; this.setQuery(query); }, loadMore() { if (state.status !== 'ready' || !state.more || activeController) return; const current = generation; const page = state.next; requestPage(state.query, page, current, true); }, }; }; return filterCommands; });