From a2af72998c0cf49f43a7c577c804bfd339641db6 Mon Sep 17 00:00:00 2001 From: Brian Kim Date: Fri, 27 Aug 2021 14:21:27 -0400 Subject: [PATCH] make disableNetworkFetches reactive --- package.json | 2 +- src/core/ApolloClient.ts | 49 ++++++++++++++++++++++++++++++++++------ src/core/QueryManager.ts | 2 +- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index e3db772c799..5cd27f896a5 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ { "name": "apollo-client", "path": "./dist/apollo-core.cjs.min.js", - "maxSize": "24.7 kB" + "maxSize": "24.9 kB" } ], "engines": { diff --git a/src/core/ApolloClient.ts b/src/core/ApolloClient.ts index cf61b920c43..0c3e2712ee6 100644 --- a/src/core/ApolloClient.ts +++ b/src/core/ApolloClient.ts @@ -89,7 +89,6 @@ export function mergeOptions< export class ApolloClient implements DataProxy { public link: ApolloLink; public cache: ApolloCache; - public disableNetworkFetches: boolean; public version: string; public queryDeduplication: boolean; public defaultOptions: DefaultOptions = {}; @@ -101,6 +100,14 @@ export class ApolloClient implements DataProxy { private clearStoreCallbacks: Array<() => Promise> = []; private localState: LocalState; + // This boolean is set by ssr-related options/properties like + // options.ssrMode, options.ssrForceFetchDelay, and + // options.disableNetworkFetches, and causes network-first fetch policies to + // be overridden. + private forceCache: boolean = false; + private ssrFetchPolicyOverrides = + new Map(); + /** * Constructs an instance of {@link ApolloClient}. * @@ -180,14 +187,14 @@ export class ApolloClient implements DataProxy { this.link = link; this.cache = cache; - this.disableNetworkFetches = ssrMode || ssrForceFetchDelay > 0; + this.forceCache = !!(ssrMode || ssrForceFetchDelay > 0); this.queryDeduplication = queryDeduplication; this.defaultOptions = defaultOptions || {}; this.typeDefs = typeDefs; if (ssrForceFetchDelay) { setTimeout( - () => (this.disableNetworkFetches = false), + () => (this.forceCache = false), ssrForceFetchDelay, ); } @@ -268,6 +275,24 @@ export class ApolloClient implements DataProxy { }); } + // TODO: deprecate and remove this property? + public get disableNetworkFetches(): boolean { + return this.forceCache; + } + + public set disableNetworkFetches(value: boolean) { + this.forceCache = value; + this.queryManager.ssrMode = value; + if (value) { + const overrides = Array.from(this.ssrFetchPolicyOverrides); + this.ssrFetchPolicyOverrides.clear(); + overrides.forEach( + ([query, fetchPolicy]) => query.setOptions({ fetchPolicy }), + ); + this.getObservableQueries('all').forEach((oq) => oq['updatePolling']()); + } + } + /** * Call this method to terminate any active client processes, making it safe * to dispose of this `ApolloClient` instance. @@ -302,16 +327,26 @@ export class ApolloClient implements DataProxy { options = mergeOptions(this.defaultOptions.watchQuery, options); } + const { fetchPolicy } = options; // XXX Overwriting options is probably not the best way to do this long term... if ( - this.disableNetworkFetches && - (options.fetchPolicy === 'network-only' || - options.fetchPolicy === 'cache-and-network') + this.forceCache && ( + fetchPolicy === 'network-only' || + fetchPolicy === 'cache-and-network' + ) ) { options = { ...options, fetchPolicy: 'cache-first' }; } - return this.queryManager.watchQuery(options); + const query = this.queryManager.watchQuery(options); + if (fetchPolicy !== options.fetchPolicy) { + this.ssrFetchPolicyOverrides.set(query, fetchPolicy!); + query.subscribe({ + complete: () => this.ssrFetchPolicyOverrides.delete(query), + }); + } + + return query; } /** diff --git a/src/core/QueryManager.ts b/src/core/QueryManager.ts index 09e6c5f819c..eade750c25f 100644 --- a/src/core/QueryManager.ts +++ b/src/core/QueryManager.ts @@ -79,7 +79,7 @@ export class QueryManager { public cache: ApolloCache; public link: ApolloLink; public readonly assumeImmutableResults: boolean; - public readonly ssrMode: boolean; + public ssrMode: boolean; private queryDeduplication: boolean; private clientAwareness: Record = {};