diff options
| author | Fuwn <[email protected]> | 2026-03-28 05:49:07 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-03-28 05:49:07 +0000 |
| commit | 669115227593f51a49415da7587481ccc63c48b0 (patch) | |
| tree | 5fa7b93d7b7fabe9a3adc9c3bad8603e6bdb9070 /src/lib/Data/AniList/media.ts | |
| parent | feat(manga): allow forcing automatic refresh (diff) | |
| download | due.moe-669115227593f51a49415da7587481ccc63c48b0.tar.xz due.moe-669115227593f51a49415da7587481ccc63c48b0.zip | |
fix(cache): respect AniList media list recache windows
Diffstat (limited to 'src/lib/Data/AniList/media.ts')
| -rw-r--r-- | src/lib/Data/AniList/media.ts | 114 |
1 files changed, 64 insertions, 50 deletions
diff --git a/src/lib/Data/AniList/media.ts b/src/lib/Data/AniList/media.ts index f2a4aad6..d8315b19 100644 --- a/src/lib/Data/AniList/media.ts +++ b/src/lib/Data/AniList/media.ts @@ -233,6 +233,21 @@ const assignDefaultOptions = (options: CollectionOptions) => { return nonNullOptions; }; +const inFlightCollections = new Map<string, Promise<Media[]>>(); + +const collectionKey = ( + type: Type, + userId: number, + options: CollectionOptions, +) => + JSON.stringify({ + type, + userId, + includeCompleted: options.includeCompleted, + all: options.all, + includeRelations: options.includeRelations, + }); + export const mediaListCollection = async ( anilistAuthorisation: AniListAuthorisation, userIdentity: UserIdentity, @@ -274,61 +289,60 @@ export const mediaListCollection = async ( if (mediaCache !== undefined && mediaCache !== "") return parseJsonStringOrDefault<Media[]>(mediaCache, []); - const userIdResponse = await ( - await fetch("https://graphql.anilist.co", { - method: "POST", - headers: { - Authorization: `${anilistAuthorisation.tokenType} ${anilistAuthorisation.accessToken}`, - "Content-Type": "application/json", - Accept: "application/json", - }, - body: JSON.stringify({ - query: collectionQueryTemplate(type, userIdentity.id, options), - }), - }) - ).json(); + const key = collectionKey(type, userIdentity.id, options); + const existing = inFlightCollections.get(key); - if ( - !userIdResponse["data"] || - !userIdResponse["data"]["MediaListCollection"] || - !userIdResponse["data"]["MediaListCollection"]["lists"] - ) - return []; + if (existing) return existing; - if (mediaCache === "") - if (type === Type.Anime) - anime.set( - JSON.stringify( - flattenLists( - userIdResponse["data"]["MediaListCollection"]["lists"], - options.all, - ), - ), - ); - else - manga.set( - JSON.stringify( - flattenLists( - userIdResponse["data"]["MediaListCollection"]["lists"], - options.all, - ), - ), - ); + const request = (async () => { + const userIdResponse = await ( + await fetch("https://graphql.anilist.co", { + method: "POST", + headers: { + Authorization: `${anilistAuthorisation.tokenType} ${anilistAuthorisation.accessToken}`, + "Content-Type": "application/json", + Accept: "application/json", + }, + body: JSON.stringify({ + query: collectionQueryTemplate(type, userIdentity.id, options), + }), + }) + ).json(); - if (options.addNotification) - options.addNotification( - getOptions({ - heading: options.notificationType - ? options.notificationType - : Type[type], - description: "Re-cached media lists from AniList", - }), + if ( + !userIdResponse["data"] || + !userIdResponse["data"]["MediaListCollection"] || + !userIdResponse["data"]["MediaListCollection"]["lists"] + ) + return []; + + const flattened = flattenLists( + userIdResponse["data"]["MediaListCollection"]["lists"], + options.all, ); - return flattenLists( - userIdResponse["data"]["MediaListCollection"]["lists"], - options.all, - ); + if (mediaCache === "") + if (type === Type.Anime) anime.set(JSON.stringify(flattened)); + else manga.set(JSON.stringify(flattened)); + + if (options.addNotification) + options.addNotification( + getOptions({ + heading: options.notificationType + ? options.notificationType + : Type[type], + description: "Re-cached media lists from AniList", + }), + ); + + return flattened; + })().finally(() => { + inFlightCollections.delete(key); + }); + + inFlightCollections.set(key, request); + + return request; }; export const publicMediaListCollection = async ( |