diff options
| author | Fuwn <[email protected]> | 2026-04-18 09:01:39 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-04-18 09:01:39 +0000 |
| commit | 0b0f846f68e7735e426523d5b8d1fc06e2392560 (patch) | |
| tree | d16e5e0760e37f9a64cbcb031132d631cad83017 | |
| parent | fix(cdn): preserve upstream headers alongside CORS and cache overrides (diff) | |
| download | due.moe-0b0f846f68e7735e426523d5b8d1fc06e2392560.tar.xz due.moe-0b0f846f68e7735e426523d5b8d1fc06e2392560.zip | |
fix(schedule): stop duplicating first page in season pagination
The seasonal schedule collector pushed page 1 outside the while-loop,
then re-pushed the current page on every loop iteration. That meant
every multi-page season duplicated its first page's media, and the
same bug ran a second time when includeLastSeason was set.
Restructure into a shared collectAllSchedulePages helper with a single
push-then-check-hasNextPage loop, so each page is pushed exactly once.
Verified against AniList for SPRING 2026 with includeLastSeason=true:
210 media, 0 duplicates.
| -rw-r--r-- | src/lib/Data/AniList/schedule.ts | 55 |
1 files changed, 18 insertions, 37 deletions
diff --git a/src/lib/Data/AniList/schedule.ts b/src/lib/Data/AniList/schedule.ts index eb70a03b..474f0e92 100644 --- a/src/lib/Data/AniList/schedule.ts +++ b/src/lib/Data/AniList/schedule.ts @@ -57,28 +57,32 @@ const schedulePage = async ( type Season = "WINTER" | "SPRING" | "SUMMER" | "FALL"; -export const scheduleMediaListCollection = async ( +const collectAllSchedulePages = async ( year: number, season: Season, - includeLastSeason = false, + into: SchedulePage["data"]["Page"]["media"], ) => { - const scheduledMedia = []; let page = 1; - let currentPage = await schedulePage(page, year, season); - for (const candidate of currentPage.data.Page.media) - scheduledMedia.push(candidate); + while (true) { + const currentPage = await schedulePage(page, year, season); - while (currentPage["data"]["Page"]["pageInfo"]["hasNextPage"]) { - for (const candidate of currentPage.data.Page.media) - scheduledMedia.push(candidate); + for (const candidate of currentPage.data.Page.media) into.push(candidate); + + if (!currentPage.data.Page.pageInfo.hasNextPage) break; page += 1; - currentPage = await schedulePage(page, year, season); } +}; + +export const scheduleMediaListCollection = async ( + year: number, + season: Season, + includeLastSeason = false, +) => { + const scheduledMedia: SchedulePage["data"]["Page"]["media"] = []; - for (const candidate of currentPage.data.Page.media) - scheduledMedia.push(candidate); + await collectAllSchedulePages(year, season, scheduledMedia); if (includeLastSeason) { const lastSeason = { @@ -86,34 +90,11 @@ export const scheduleMediaListCollection = async ( SPRING: "WINTER", SUMMER: "SPRING", FALL: "SUMMER", - }[season]; + }[season] as Season; const lastSeasonYear = season === "WINTER" ? year - 1 : year; - let page = 1; - let currentPage = await schedulePage( - page, - lastSeasonYear, - lastSeason as Season, - ); - - for (const candidate of currentPage.data.Page.media) - scheduledMedia.push(candidate); - - while (currentPage["data"]["Page"]["pageInfo"]["hasNextPage"]) { - for (const candidate of currentPage.data.Page.media) - scheduledMedia.push(candidate); - - page += 1; - currentPage = await schedulePage( - page, - lastSeasonYear, - lastSeason as Season, - ); - } - - for (const candidate of currentPage.data.Page.media) - scheduledMedia.push(candidate); + await collectAllSchedulePages(lastSeasonYear, lastSeason, scheduledMedia); } return scheduledMedia as Partial<Media[]>; |