import { DocumentNode } from "graphql" ; import { ApolloQueryResult } from "@apollo/client" ; import { DollarApollo } from "@vue/apollo-option/types/vue-apollo" ; import { ArmServer } from "@/lib/arm-server" ; import { ANILIST_IDS_FROM_MAL_IDS , LIST_VIEW_QUERY } from "@/graphql/documents/queries" ; import { AnilistIdsFromMalIdsQuery , AnilistIdsFromMalIdsQueryVariables , ListViewListEntries , ListViewQuery , ListViewQueryVariables , } from "@/graphql/generated/types" ; import { Instance } from "@/types" ; import { isNil } from "@/utils" ; type BaseResult = { Page : null | { pageInfo : null | { lastPage : number | null ; } ; } ; } ; type FetchAllPagesOptions < R extends BaseResult , V extends { page : number ; } > = { apollo : DollarApollo < any > ; query : DocumentNode ; variables : Omit < V , "page" > ; result ? : ( data : R ) => void ; } ; export const fetchAllPages = async < R extends BaseResult , V extends { page : number ; } > ( { apollo , query , variables , result , } ) => { const firstResponse = await apollo . query < R > ( { query , variables : { ... variables , page : 1 , } , } ) ; if ( ! isNil ( result ) ) result ( firstResponse . data ) ; const pagesLeft = firstResponse . data . Page ?. pageInfo ?. lastPage ?? 1 - 1 ; const promises = [ ] ; for ( let i = 0 ; i < pagesLeft ; i ++ ) { promises . push ( new Promise ( async ( resolve ) => { let response ; try { response = await apollo . query < R > ( { query , variables : { ... variables , page : i + 2 , } , } ) ; } catch { response = null ; } if ( isNil ( response ) ) return resolve ( null ) ; if ( ! isNil ( result ) ) result ( response . data ) ; resolve ( response ) ; } ) ) ; } const restOfResponses = await Promise . all ( promises ) ; return [ firstResponse , ... restOfResponses ] ; } ; type MapResult = { [ malId ] : number ; } ; export const getAnilistIdsFromMalIds = async ( apollo , malIds ) : Promise < MapResult > => { const armResponse = await ArmServer . batchGetIds ( malIds . map ( ( id ) => ( { myanimelist : id } ) ) ) ; const armResults = armResponse . filter ( ( item ) => ! isNil ( item ) && ! isNil ( item . anilist ) && ! isNil ( item . myanimelist ) ) . reduce ( ( obj , item ) => ( { ... obj , [ item ! . myanimelist ! ] : item ! . anilist ! , } ) , { } as MapResult ) ; const idsLeft = malIds . filter ( ( id ) => ! Object . keys ( armResults ) . map ( Number ) . includes ( id ) ) ; const responses = await fetchAllPages < AnilistIdsFromMalIdsQuery , AnilistIdsFromMalIdsQueryVariables > ( { apollo , query : ANILIST_IDS_FROM_MAL_IDS , variables : { malIds : idsLeft , } , } ) ; const anilistResults = responses . map ( ( data ) => data ?. data . Page ?. media ?? [ ] ) . flat ( ) . reduce ( ( obj , item ) => ( { ... obj , [ item ! . idMal ! ] : item ! . id ! , } ) , { } as MapResult ) ; return { ... armResults , ... anilistResults , } ; } ; export const getALofOfEntries = async ( { $apollo } , amount ) => { const entries = [ ] ; const fiveHundreds = Math . floor ( amount / 500 ) ; for ( let i = 0 ; i < fiveHundreds ; i ++ ) { const { data , errors } = await $apollo . query < ListViewQuery , ListViewQueryVariables > ( { query : LIST_VIEW_QUERY , errorPolicy : "all" , } ) ; if ( errors || data . ListEntries . length < 1 ) break ; entries . push ( ... data . ListEntries ) ; } return entries ; } ;