@@ -222,6 +222,33 @@ export function useAlgoliaSearch() {
222222 }
223223 }
224224
225+ /** Fetch metadata for a single batch of packages (max 1000) by exact name. */
226+ async function getPackagesByNameSlice ( names : string [ ] ) : Promise < NpmSearchResult [ ] > {
227+ if ( names . length === 0 ) return [ ]
228+
229+ const response = await $fetch < { results : ( AlgoliaHit | null ) [ ] } > (
230+ `https://${ algolia . appId } -dsn.algolia.net/1/indexes/*/objects` ,
231+ {
232+ method : 'POST' ,
233+ headers : {
234+ 'x-algolia-api-key' : algolia . apiKey ,
235+ 'x-algolia-application-id' : algolia . appId ,
236+ } ,
237+ body : {
238+ requests : names . map ( name => ( {
239+ indexName,
240+ objectID : name ,
241+ attributesToRetrieve : ATTRIBUTES_TO_RETRIEVE ,
242+ } ) ) ,
243+ } ,
244+ } ,
245+ )
246+
247+ return response . results
248+ . filter ( ( r ) : r is AlgoliaHit => r !== null && 'name' in r )
249+ . map ( hitToSearchResult )
250+ }
251+
225252 /** Fetch metadata for specific packages by exact name using Algolia's getObjects API. */
226253 async function getPackagesByName ( packageNames : string [ ] ) : Promise < NpmSearchResponse > {
227254 if ( packageNames . length === 0 ) {
@@ -230,36 +257,18 @@ export function useAlgoliaSearch() {
230257
231258 // Algolia getObjects has a limit of 1000 objects per request, so batch if needed
232259 const BATCH_SIZE = 1000
233- const allHits : AlgoliaHit [ ] = [ ]
234-
260+ const batches : string [ ] [ ] = [ ]
235261 for ( let i = 0 ; i < packageNames . length ; i += BATCH_SIZE ) {
236- const batch = packageNames . slice ( i , i + BATCH_SIZE )
237- const response = await $fetch < { results : ( AlgoliaHit | null ) [ ] } > (
238- `https://${ algolia . appId } -dsn.algolia.net/1/indexes/*/objects` ,
239- {
240- method : 'POST' ,
241- headers : {
242- 'x-algolia-api-key' : algolia . apiKey ,
243- 'x-algolia-application-id' : algolia . appId ,
244- } ,
245- body : {
246- requests : batch . map ( name => ( {
247- indexName,
248- objectID : name ,
249- attributesToRetrieve : ATTRIBUTES_TO_RETRIEVE ,
250- } ) ) ,
251- } ,
252- } ,
253- )
254-
255- const hits = response . results . filter ( ( r ) : r is AlgoliaHit => r !== null && 'name' in r )
256- allHits . push ( ...hits )
262+ batches . push ( packageNames . slice ( i , i + BATCH_SIZE ) )
257263 }
258264
265+ const results = await Promise . all ( batches . map ( batch => getPackagesByNameSlice ( batch ) ) )
266+ const allObjects = results . flat ( )
267+
259268 return {
260269 isStale : false ,
261- objects : allHits . map ( hitToSearchResult ) ,
262- total : allHits . length ,
270+ objects : allObjects ,
271+ total : allObjects . length ,
263272 time : new Date ( ) . toISOString ( ) ,
264273 }
265274 }
@@ -366,5 +375,6 @@ export function useAlgoliaSearch() {
366375 searchWithSuggestions,
367376 searchByOwner,
368377 getPackagesByName,
378+ getPackagesByNameSlice,
369379 }
370380}
0 commit comments