Search query.
Filter options.
Page number.
Results per page.
Optional
token: stringOptional access token.
Optional
bypassCache: booleanOptional parameter to bypass cache.
Promise resolving to search results.
export async function advancedSearchManga(
search: string,
filters: {
genres?: string[];
tags?: string[];
formats?: string[];
} = {},
page: number = 1,
perPage: number = 50,
token?: string,
bypassCache?: boolean,
): Promise<SearchResult<AniListManga>> {
// Generate cache key with additional filters
const cacheKey = generateCacheKey(search, page, perPage, filters);
// Check if we should bypass the cache
if (!bypassCache && isCacheValid(searchCache, cacheKey)) {
console.log(`📋 Using cached advanced search results for: "${search}"`);
return searchCache[cacheKey].data;
}
if (bypassCache) {
console.log(
`🚨 FORCE SEARCH: Bypassing cache for "${search}" in client.advancedSearchManga - will make API request`,
);
}
console.log(
`🔍 Advanced search for manga: "${search}" with filters:`,
filters,
);
try {
// Map filters to variables
const variables = {
search,
page,
perPage,
genre_in: filters.genres,
tag_in: filters.tags,
format_in: filters.formats,
};
console.log("Query:", ADVANCED_SEARCH_MANGA);
console.log("Variables:", variables, { bypassCache });
// Updated type parameter to correctly handle potential nested data structure
const response = await request<{
data?: { Page: SearchResult<AniListManga>["Page"] };
Page?: SearchResult<AniListManga>["Page"];
}>(ADVANCED_SEARCH_MANGA, variables, token, undefined, bypassCache);
console.log("🔍 advancedSearchManga response:", response);
// Validate the response structure before using it
if (!response || !response.data) {
console.error(
`Invalid API response for advanced search "${search}":`,
response,
);
throw new Error(`Invalid API response: missing data property`);
}
// Check if the API response has a nested data object (response.data.data structure)
const responseData = response.data.data
? response.data.data
: response.data;
if (!responseData.Page) {
console.error(
`Invalid API response for advanced search "${search}": missing Page property`,
responseData,
);
throw new Error(`Invalid API response: missing Page property`);
}
const result = { Page: responseData.Page };
// Ensure media array exists (even if empty)
if (!result.Page.media) {
result.Page.media = [];
}
// Log the number of results found
console.log(
`🔍 Found ${result.Page.media.length} manga for advanced search "${search}" (page ${page}/${result.Page.pageInfo?.lastPage || 1})`,
);
// Cache the results if not bypassing cache
if (!bypassCache) {
searchCache[cacheKey] = {
data: result,
timestamp: Date.now(),
};
// Persist the updated cache
persistSearchCache();
console.log(
`💾 Cached ${result.Page.media.length} advanced search results for "${search}"`,
);
} else {
console.log(
`🚨 FORCE SEARCH: Not caching advanced search results for "${search}" as bypassCache=true`,
);
}
return result;
} catch (error) {
console.error(`Error in advanced search for: ${search}`, error);
// Return a valid but empty result to prevent crashing
const emptyResult: SearchResult<AniListManga> = {
Page: {
pageInfo: {
total: 0,
currentPage: page,
lastPage: 1,
hasNextPage: false,
perPage,
},
media: [],
},
};
return emptyResult;
}
}
Advanced search for manga with additional filters.