From d8c33cc34cc11ffb90cad596d0bd3afdd7b1154f Mon Sep 17 00:00:00 2001 From: Alf Eaton Date: Tue, 19 May 2026 12:25:40 +0100 Subject: [PATCH] Allow multiple concurrent reference searches (#33739) Co-authored-by: Claude Opus 4.7 (1M context) GitOrigin-RevId: 403d4f5900a8c4ccdc64032d365adb285a191b71 --- .../ide-react/context/references-context.tsx | 2 +- .../ide-react/references/reference-indexer.ts | 26 ++++++++++++------- .../ide-react/references/references.worker.ts | 6 ++--- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/services/web/frontend/js/features/ide-react/context/references-context.tsx b/services/web/frontend/js/features/ide-react/context/references-context.tsx index f143888011..38385dcd65 100644 --- a/services/web/frontend/js/features/ide-react/context/references-context.tsx +++ b/services/web/frontend/js/features/ide-react/context/references-context.tsx @@ -194,7 +194,7 @@ export const ReferencesProvider: FC = ({ return { hits: [] } } const indexer = await indexerRef.current - return await indexer.search(query) + return await indexer.search(query, 'searchLocalReferences') }, [] ) diff --git a/services/web/frontend/js/features/ide-react/references/reference-indexer.ts b/services/web/frontend/js/features/ide-react/references/reference-indexer.ts index 1d36726f3d..3c554e43da 100644 --- a/services/web/frontend/js/features/ide-react/references/reference-indexer.ts +++ b/services/web/frontend/js/features/ide-react/references/reference-indexer.ts @@ -3,6 +3,7 @@ import { generateSHA1Hash } from '@/shared/utils/sha1' import { AdvancedReferenceSearchResult, Changes } from './types' import { debugConsole } from '@/utils/debugging' import type { ReferenceWorkerResponse } from './references.worker' +import { v4 as uuid } from 'uuid' const ONE_MB = 1024 * 1024 const MAX_BIB_DATA_SIZE = 6 * ONE_MB @@ -11,9 +12,10 @@ export class ReferenceIndexer { private fileIndexHash: Map = new Map() private worker: Worker private updateResolve: ((result: Set) => void) | null = null - private searchResolve: - | ((result: AdvancedReferenceSearchResult) => void) - | null = null + private searchResolvers = new Map< + string, + (result: AdvancedReferenceSearchResult) => void + >() constructor() { this.worker = new Worker( @@ -26,9 +28,12 @@ export class ReferenceIndexer { private handleMessage(event: MessageEvent) { const data = event.data as ReferenceWorkerResponse - if (data.type === 'searchResult' && this.searchResolve) { - this.searchResolve(data.result) - this.searchResolve = null + if (data.type === 'searchResult') { + const searchResolver = this.searchResolvers.get(data.id) + if (searchResolver) { + searchResolver(data.result) + this.searchResolvers.delete(data.id) + } } else if (data.type === 'updateKeys' && this.updateResolve) { this.updateResolve(data.keys) this.updateResolve = null @@ -127,11 +132,14 @@ export class ReferenceIndexer { }) } - async search(query: string): Promise { - this.worker.postMessage({ type: 'search', query }) + async search( + query: string, + id: string = uuid() + ): Promise { + this.worker.postMessage({ id, type: 'search', query }) const { promise, resolve } = Promise.withResolvers() - this.searchResolve = resolve + this.searchResolvers.set(id, resolve) return promise } } diff --git a/services/web/frontend/js/features/ide-react/references/references.worker.ts b/services/web/frontend/js/features/ide-react/references/references.worker.ts index fd7cdfc537..3a2c440203 100644 --- a/services/web/frontend/js/features/ide-react/references/references.worker.ts +++ b/services/web/frontend/js/features/ide-react/references/references.worker.ts @@ -14,11 +14,11 @@ const indices = importOverleafModules('referenceIndices') as { export type ReferenceWorkerRequest = | { type: 'update'; changes: Changes } - | { type: 'search'; query: string } + | { id: string; type: 'search'; query: string } export type ReferenceWorkerResponse = | { type: 'updateKeys'; keys: Set } - | { type: 'searchResult'; result: AdvancedReferenceSearchResult } + | { id: string; type: 'searchResult'; result: AdvancedReferenceSearchResult } function createIndex(): ReferenceIndex { const Klass = indices[0]?.import.default ?? BasicReferenceIndex @@ -37,7 +37,7 @@ self.addEventListener('message', async (event: MessageEvent) => { case 'search': { const result = await indexer.search(message.query) - self.postMessage({ type: 'searchResult', result }) + self.postMessage({ id: message.id, type: 'searchResult', result }) break }