aboutsummaryrefslogtreecommitdiff
path: root/src/lib/Data/AniList/media.ts
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-03-28 05:49:07 +0000
committerFuwn <[email protected]>2026-03-28 05:49:07 +0000
commit669115227593f51a49415da7587481ccc63c48b0 (patch)
tree5fa7b93d7b7fabe9a3adc9c3bad8603e6bdb9070 /src/lib/Data/AniList/media.ts
parentfeat(manga): allow forcing automatic refresh (diff)
downloaddue.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.ts114
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 (