Search query string
Search configuration
Optional authentication token
Optional abort signal to cancel search
OptionalspecificPage: numberOptional specific page number (disables pagination)
Promise with collected results and final page info
export async function executeSearchLoop(
searchQuery: string,
searchConfig: SearchServiceConfig,
token: string | undefined,
abortSignal: AbortSignal | undefined,
specificPage?: number,
): Promise<SearchLoopResult> {
let results: AniListManga[] = [];
let currentPage = specificPage || 1;
let hasNextPage = true;
let lastPageInfo: PageInfo | undefined = undefined;
const isSinglePageMode = specificPage !== undefined;
console.info(
`[MangaSearchService] 🌐 Making network request to AniList API for "${searchQuery}" - bypassCache=${searchConfig.bypassCache}`,
);
while (hasNextPage && results.length < searchConfig.maxSearchResults) {
try {
if (abortSignal?.aborted) {
throw new Error("Search aborted by abort signal");
}
// Execute the search request
const searchResult = await executeSingleSearch(
searchQuery,
currentPage,
searchConfig,
token,
);
console.debug(
`[MangaSearchService] 🔍 Search response for "${searchQuery}" page ${currentPage}: ${searchResult?.Page?.media?.length || 0} results`,
);
// Log detailed results if cache is bypassed
if (searchConfig.bypassCache && searchResult?.Page?.media?.length > 0) {
console.debug(
`[MangaSearchService] 🔍 Titles received from API:`,
searchResult.Page.media.map((m) => ({
id: m.id,
romaji: m.title?.romaji,
english: m.title?.english,
native: m.title?.native,
synonyms: m.synonyms?.length,
})),
);
}
// Validate search result structure
if (!validateSearchResult(searchResult, searchQuery)) {
break;
}
// Add results to collection
results = [...results, ...searchResult.Page.media];
lastPageInfo = searchResult.Page.pageInfo;
// Check if pagination should continue
hasNextPage = shouldContinuePagination(
searchResult.Page.pageInfo,
currentPage,
results.length,
searchConfig.maxSearchResults,
isSinglePageMode,
);
currentPage++;
if (hasNextPage) {
await acquireRateLimit();
}
} catch (error: unknown) {
handleSearchError(error, searchQuery);
throw error;
}
}
return { results, lastPageInfo };
}
Execute paginated search loop collecting results until completion.
Continues pagination while results available, max not reached, and not aborted. Respects rate limiting between requests.