@@ -87,11 +87,35 @@ async function searchUniProt(
8787 return data . results . map ( mapApiResultToEntry )
8888}
8989
90+ async function searchByXref ( id : string ) {
91+ const query = buildXrefQuery ( id )
92+ if ( query ) {
93+ try {
94+ return await searchUniProt ( query )
95+ } catch ( e ) {
96+ console . error ( `xref search failed for ${ id } :` , e )
97+ }
98+ }
99+ return [ ]
100+ }
101+
102+ function deduplicateEntries ( entries : UniProtEntry [ ] ) {
103+ const seen = new Set < string > ( )
104+ const result : UniProtEntry [ ] = [ ]
105+ for ( const entry of entries ) {
106+ if ( ! seen . has ( entry . accession ) ) {
107+ seen . add ( entry . accession )
108+ result . push ( entry )
109+ }
110+ }
111+ return result
112+ }
113+
90114/**
91115 * Search UniProt for entries matching a gene, returning multiple results.
92116 * Tries multiple strategies in order of specificity:
93117 * 1. Recognized database IDs (Ensembl, RefSeq, CCDS, HGNC) via xref search
94- * 2. Gene name search
118+ * 2. Gene name search (fallback if no reviewed entries found)
95119 */
96120export async function searchUniProtEntries ( {
97121 recognizedIds = [ ] ,
@@ -103,72 +127,29 @@ export async function searchUniProtEntries({
103127 geneId ?: string
104128 geneName ?: string
105129 organismId ?: number
106- } ) : Promise < UniProtEntry [ ] > {
107- const entries : UniProtEntry [ ] = [ ]
108- const seenAccessions = new Set < string > ( )
109-
110- const addEntries = ( newEntries : UniProtEntry [ ] ) => {
111- for ( const entry of newEntries ) {
112- if ( ! seenAccessions . has ( entry . accession ) ) {
113- seenAccessions . add ( entry . accession )
114- entries . push ( entry )
115- }
116- }
117- }
118-
119- // Strategy 1: Search by recognized database IDs (most specific)
120- for ( const id of recognizedIds ) {
121- const query = buildXrefQuery ( id )
122- if ( query ) {
123- try {
124- const results = await searchUniProt ( query )
125- addEntries ( results )
126- if ( results . some ( e => e . isReviewed ) ) {
127- break
128- }
129- } catch {
130- // xref search failed, continue to next ID
131- }
132- }
133- }
134-
135- // Strategy 2: Try legacy gene_id if it looks like a recognized database ID
130+ } ) {
131+ // Collect all IDs to search, including legacy geneId if applicable
132+ const idsToSearch = new Set ( recognizedIds )
136133 const strippedGeneId = geneId ? stripTrailingVersion ( geneId ) : undefined
137- if (
138- strippedGeneId &&
139- isRecognizedDatabaseId ( strippedGeneId ) &&
140- ! recognizedIds . includes ( strippedGeneId )
141- ) {
142- const query = buildXrefQuery ( strippedGeneId )
143- if ( query ) {
144- try {
145- addEntries ( await searchUniProt ( query ) )
146- } catch {
147- // xref search failed
148- }
149- }
134+ if ( strippedGeneId && isRecognizedDatabaseId ( strippedGeneId ) ) {
135+ idsToSearch . add ( strippedGeneId )
150136 }
151137
152- // Strategy 3: If no reviewed entries found, try gene name search
138+ // Search all xrefs in parallel
139+ const xrefResults = await Promise . all ( [ ...idsToSearch ] . map ( searchByXref ) )
140+ let entries = deduplicateEntries ( xrefResults . flat ( ) )
141+
142+ // Fallback: if no reviewed entries found, try gene name search
153143 if ( ! entries . some ( e => e . isReviewed ) && geneName ) {
154144 try {
155145 const query = `gene:${ geneName } +AND+organism_id:${ organismId } +AND+reviewed:true`
156- addEntries ( await searchUniProt ( query , 5 ) )
157- } catch {
158- // gene name search failed
146+ const geneNameResults = await searchUniProt ( query , 5 )
147+ entries = deduplicateEntries ( [ ...entries , ...geneNameResults ] )
148+ } catch ( e ) {
149+ console . error ( `gene name search failed for ${ geneName } :` , e )
159150 }
160151 }
161152
162153 // Sort reviewed entries first
163- entries . sort ( ( a , b ) => {
164- if ( a . isReviewed && ! b . isReviewed ) {
165- return - 1
166- }
167- if ( ! a . isReviewed && b . isReviewed ) {
168- return 1
169- }
170- return 0
171- } )
172-
173- return entries
154+ return entries . toSorted ( ( a , b ) => Number ( b . isReviewed ) - Number ( a . isReviewed ) )
174155}
0 commit comments