diff --git a/ui/shared/search/controller.js b/ui/shared/search/controller.js index 6fd81b4..378bc8a 100644 --- a/ui/shared/search/controller.js +++ b/ui/shared/search/controller.js @@ -46,6 +46,7 @@ export class SearchController { // Current results this.results = []; this.groups = []; + this.queryGeneration = 0; // Create debounced query function this.debouncedQuery = debounce( @@ -66,21 +67,27 @@ export class SearchController { * Query immediately without debouncing * @param {string} query - The search query */ - async queryImmediate(query) { - await this.executeQuery(query.trim()); + queryImmediate(query) { + this.executeQuery(query.trim()); } /** * Execute the query and update results * @private */ - async executeQuery(query) { - this.results = await this.aggregator.query(query); - this.groups = groupResults(this.results); + executeQuery(query) { + const generation = ++this.queryGeneration; - if (this.onResultsChanged) { - this.onResultsChanged(this.results, this.groups); - } + this.aggregator.query(query, (results) => { + if (generation !== this.queryGeneration) { + return; + } + this.results = results; + this.groups = groupResults(results); + if (this.onResultsChanged) { + this.onResultsChanged(this.results, this.groups); + } + }); } /** diff --git a/ui/system/results_aggregator.js b/ui/system/results_aggregator.js index 5e62e94..aa54964 100644 --- a/ui/system/results_aggregator.js +++ b/ui/system/results_aggregator.js @@ -15,29 +15,25 @@ export class ResultsAggregator { this.providers = this.providers.filter((p) => p.name !== name); } - // Query all providers in parallel and return sorted results - async query(text) { - const promises = this.providers.map(async (provider) => { + // Query all providers in parallel, calling onUpdate as each resolves + query(text, onUpdate) { + const results = []; + + this.providers.map(async (provider) => { try { - const results = await provider.query(text); - // Tag results with provider name and icon - return results.map((r) => ({ + const providerResults = await provider.query(text); + const tagged = providerResults.map((r) => ({ ...r, provider: provider.name, providerIcon: provider.icon, })); + results.push(...tagged); + results.sort((a, b) => (b.score || 0) - (a.score || 0)); + console.log(`Updating results from ${provider.name}`); + onUpdate(results); } catch (e) { console.error(`Provider ${provider.name} error:`, e); - return []; } }); - - const resultsArrays = await Promise.all(promises); - const allResults = resultsArrays.flat(); - - // Sort by score (descending), defaulting to 0 if not set - allResults.sort((a, b) => (b.score || 0) - (a.score || 0)); - - return allResults; } }