Allow multiple concurrent reference searches (#33739)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> GitOrigin-RevId: 403d4f5900a8c4ccdc64032d365adb285a191b71
This commit is contained in:
@@ -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')
|
||||
},
|
||||
[]
|
||||
)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user