Просмотр исходного кода

Allow multiple concurrent reference searches (#33739)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
GitOrigin-RevId: 403d4f5900a8c4ccdc64032d365adb285a191b71
Alf Eaton 2 месяцев назад
Родитель
Сommit
d8c33cc34c

+ 1 - 1
services/web/frontend/js/features/ide-react/context/references-context.tsx

@@ -194,7 +194,7 @@ export const ReferencesProvider: FC<React.PropsWithChildren> = ({
         return { hits: [] }
       }
       const indexer = await indexerRef.current
-      return await indexer.search(query)
+      return await indexer.search(query, 'searchLocalReferences')
     },
     []
   )

+ 17 - 9
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<string, string> = new Map()
   private worker: Worker
   private updateResolve: ((result: Set<string>) => 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<AdvancedReferenceSearchResult> {
-    this.worker.postMessage({ type: 'search', query })
+  async search(
+    query: string,
+    id: string = uuid()
+  ): Promise<AdvancedReferenceSearchResult> {
+    this.worker.postMessage({ id, type: 'search', query })
     const { promise, resolve } =
       Promise.withResolvers<AdvancedReferenceSearchResult>()
-    this.searchResolve = resolve
+    this.searchResolvers.set(id, resolve)
     return promise
   }
 }

+ 3 - 3
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<string> }
-  | { 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
     }