From 980da657d99dd8d01fed82b5c80be7e3b01d0429 Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Mon, 25 Dec 2023 21:20:07 +0100 Subject: [PATCH] [Codegen] Check cache before executing query for a single item (#513) E.g. in case a manga was already loaded through the category mangas query, the query for that specific manga should not run against the server if it hasn't been executed before --- src/lib/graphql/generated/apollo-helpers.ts | 21 ++++++----- src/lib/requests/client/GraphQLClient.ts | 39 ++++++++++++++++++++- tools/scripts/codegenFormatter.ts | 21 ++++++----- 3 files changed, 64 insertions(+), 17 deletions(-) diff --git a/src/lib/graphql/generated/apollo-helpers.ts b/src/lib/graphql/generated/apollo-helpers.ts index 370765ac..9a084967 100644 --- a/src/lib/graphql/generated/apollo-helpers.ts +++ b/src/lib/graphql/generated/apollo-helpers.ts @@ -1,5 +1,10 @@ -import { FieldPolicy, FieldReadFunction, TypePolicies, TypePolicy } from '@apollo/client/cache'; -import { GetChaptersQuery } from "@/lib/graphql/generated/graphql.ts"; +import {FieldPolicy, FieldReadFunction, Reference, TypePolicies, TypePolicy} from '@apollo/client/cache'; +import { + GetCategoryQueryVariables, GetChapterQueryVariables, + GetChaptersQuery, GetExtensionQueryVariables, GetGlobalMetadataQueryVariables, + GetMangaQueryVariables, GetSourceQueryVariables, +} from "@/lib/graphql/generated/graphql.ts"; +import {FieldFunctionOptions} from "@apollo/client/cache/inmemory/policies"; export type AboutServerPayloadKeySpecifier = ('buildTime' | 'buildType' | 'discord' | 'github' | 'name' | 'revision' | 'version' | AboutServerPayloadKeySpecifier)[]; export type AboutServerPayloadFieldPolicy = { buildTime?: FieldPolicy | FieldReadFunction, @@ -508,23 +513,23 @@ export type QueryKeySpecifier = ('aboutServer' | 'aboutWebUI' | 'categories' | ' export type QueryFieldPolicy = { about?: FieldPolicy | FieldReadFunction, categories?: FieldPolicy | FieldReadFunction, - category?: FieldPolicy | FieldReadFunction, - chapter?: FieldPolicy | FieldReadFunction, + category?: FieldPolicy> | FieldReadFunction>, + chapter?: FieldPolicy> | FieldReadFunction>, chapters?: FieldPolicy | FieldReadFunction, checkForServerUpdates?: FieldPolicy | FieldReadFunction, checkForWebUIUpdate?: FieldPolicy | FieldReadFunction, downloadStatus?: FieldPolicy | FieldReadFunction, - extension?: FieldPolicy | FieldReadFunction, + extension?: FieldPolicy> | FieldReadFunction>, extensions?: FieldPolicy | FieldReadFunction, getWebUIUpdateStatus?: FieldPolicy | FieldReadFunction, lastUpdateTimestamp?: FieldPolicy | FieldReadFunction, - manga?: FieldPolicy | FieldReadFunction, + manga?: FieldPolicy> | FieldReadFunction>, mangas?: FieldPolicy | FieldReadFunction, - meta?: FieldPolicy | FieldReadFunction, + meta?: FieldPolicy> | FieldReadFunction>, metas?: FieldPolicy | FieldReadFunction, restoreStatus?: FieldPolicy | FieldReadFunction, settings?: FieldPolicy | FieldReadFunction, - source?: FieldPolicy | FieldReadFunction, + source?: FieldPolicy> | FieldReadFunction>, sources?: FieldPolicy | FieldReadFunction, updateStatus?: FieldPolicy | FieldReadFunction, validateBackup?: FieldPolicy | FieldReadFunction diff --git a/src/lib/requests/client/GraphQLClient.ts b/src/lib/requests/client/GraphQLClient.ts index 1ff9b045..4ef7f1ca 100644 --- a/src/lib/requests/client/GraphQLClient.ts +++ b/src/lib/requests/client/GraphQLClient.ts @@ -11,6 +11,7 @@ import { createUploadLink } from 'apollo-upload-client'; import { GraphQLWsLink } from '@apollo/client/link/subscriptions'; import { Client, createClient } from 'graphql-ws'; import { getMainDefinition } from '@apollo/client/utilities'; +import { TypePolicies } from '@apollo/client/cache'; import { BaseClient } from '@/lib/requests/client/BaseClient.ts'; import { StrictTypedTypePolicies } from '@/lib/graphql/generated/apollo-helpers.ts'; @@ -27,9 +28,40 @@ const typePolicies: StrictTypedTypePolicies = { DownloadType: { keyFields: ['chapter'] }, Query: { fields: { + manga(_, { args, toReference }) { + return toReference({ + __typename: 'MangaType', + id: args?.id, + }); + }, + category(_, { args, toReference }) { + return toReference({ + __typename: 'CategoryType', + id: args?.id, + }); + }, + source(_, { args, toReference }) { + return toReference({ + __typename: 'SourceType', + id: args?.id, + }); + }, + extension(_, { args, toReference }) { + return toReference({ + __typename: 'ExtensionType', + apkName: args?.pkgName, + }); + }, + meta(_, { args, toReference }) { + return toReference({ + __typename: 'GlobalMetaType', + key: args?.key, + }); + }, chapters: { keyArgs: ['condition', 'filter', 'orderBy', 'orderByType'], merge(existing, incoming) { + console.log('merge chapters', { ...existing }, { ...incoming }); if (existing == null) { return incoming; } @@ -116,7 +148,12 @@ export class GraphQLClient extends BaseClient< this.client = new ApolloClient({ cache: new InMemoryCache({ - typePolicies, + // for whatever reason there is some weird TypeError complaining that + // "FieldReadFunction>" + // is not compatible with "FieldReadFunction>" + // Since "typePolicies" is correctly typed as StrictTypedTypePolicies, and it is working as expected, + // the TypeError can just be ignored + typePolicies: typePolicies as TypePolicies, }), connectToDevTools: true, link: this.createLink(), diff --git a/tools/scripts/codegenFormatter.ts b/tools/scripts/codegenFormatter.ts index 607c7d32..e56e2752 100644 --- a/tools/scripts/codegenFormatter.ts +++ b/tools/scripts/codegenFormatter.ts @@ -51,8 +51,13 @@ generatedGraphQLFile = fs.readFileSync(generatedGraphQLFilePath, 'utf8'); const addImports = format( generatedGraphQLFile, `import { FieldPolicy, FieldReadFunction, TypePolicies, TypePolicy } from '@apollo/client/cache';`, - `import { FieldPolicy, FieldReadFunction, TypePolicies, TypePolicy } from '@apollo/client/cache'; -import { GetChaptersQuery } from "@/lib/graphql/generated/graphql.ts";`, + `import {FieldPolicy, FieldReadFunction, Reference, TypePolicies, TypePolicy} from '@apollo/client/cache'; +import { +\tGetCategoryQueryVariables, GetChapterQueryVariables, +\tGetChaptersQuery, GetExtensionQueryVariables, GetGlobalMetadataQueryVariables, +\tGetMangaQueryVariables, GetSourceQueryVariables, +} from "@/lib/graphql/generated/graphql.ts"; +import {FieldFunctionOptions} from "@apollo/client/cache/inmemory/policies";`, ); const fixTypingOfQueryTypePolicies = format( @@ -85,23 +90,23 @@ const fixTypingOfQueryTypePolicies = format( `export type QueryFieldPolicy = { \tabout?: FieldPolicy | FieldReadFunction, \tcategories?: FieldPolicy | FieldReadFunction, -\tcategory?: FieldPolicy | FieldReadFunction, -\tchapter?: FieldPolicy | FieldReadFunction, +\tcategory?: FieldPolicy> | FieldReadFunction>, +\tchapter?: FieldPolicy> | FieldReadFunction>, \tchapters?: FieldPolicy | FieldReadFunction, \tcheckForServerUpdates?: FieldPolicy | FieldReadFunction, \tcheckForWebUIUpdate?: FieldPolicy | FieldReadFunction, \tdownloadStatus?: FieldPolicy | FieldReadFunction, -\textension?: FieldPolicy | FieldReadFunction, +\textension?: FieldPolicy> | FieldReadFunction>, \textensions?: FieldPolicy | FieldReadFunction, \tgetWebUIUpdateStatus?: FieldPolicy | FieldReadFunction, \tlastUpdateTimestamp?: FieldPolicy | FieldReadFunction, -\tmanga?: FieldPolicy | FieldReadFunction, +\tmanga?: FieldPolicy> | FieldReadFunction>, \tmangas?: FieldPolicy | FieldReadFunction, -\tmeta?: FieldPolicy | FieldReadFunction, +\tmeta?: FieldPolicy> | FieldReadFunction>, \tmetas?: FieldPolicy | FieldReadFunction, \trestoreStatus?: FieldPolicy | FieldReadFunction, \tsettings?: FieldPolicy | FieldReadFunction, -\tsource?: FieldPolicy | FieldReadFunction, +\tsource?: FieldPolicy> | FieldReadFunction>, \tsources?: FieldPolicy | FieldReadFunction, \tupdateStatus?: FieldPolicy | FieldReadFunction, \tvalidateBackup?: FieldPolicy | FieldReadFunction