From b102390b238e5ce083062541d98a00fc3a10e1e1 Mon Sep 17 00:00:00 2001 From: Lenz Weber-Tronic Date: Wed, 14 Jun 2023 19:21:57 +0200 Subject: [PATCH] Use printed query for deduplication, cache print calls (#10968) Co-authored-by: Jerel Miller --- .changeset/rude-frogs-destroy.md | 5 +++++ .prettierignore | 1 + .size-limit.cjs | 4 ++-- src/__tests__/__snapshots__/exports.ts.snap | 1 + src/core/QueryManager.ts | 10 ++++++---- src/link/http/selectHttpOptionsAndBody.ts | 2 +- src/link/persisted-queries/index.ts | 2 +- src/link/subscriptions/index.ts | 2 +- src/testing/core/mocking/mockLink.ts | 2 +- src/testing/matchers/toMatchDocument.ts | 3 +-- src/utilities/graphql/print.ts | 14 ++++++++++++++ src/utilities/index.ts | 4 ++++ 12 files changed, 38 insertions(+), 12 deletions(-) create mode 100644 .changeset/rude-frogs-destroy.md create mode 100644 src/utilities/graphql/print.ts diff --git a/.changeset/rude-frogs-destroy.md b/.changeset/rude-frogs-destroy.md new file mode 100644 index 00000000000..ec5b7dca2a4 --- /dev/null +++ b/.changeset/rude-frogs-destroy.md @@ -0,0 +1,5 @@ +--- +'@apollo/client': patch +--- + +Use printed query for query deduplication. Cache `print` calls for GraphQL documents to speed up repeated operations. diff --git a/.prettierignore b/.prettierignore index de40cbb4bf5..db9d7195c36 100644 --- a/.prettierignore +++ b/.prettierignore @@ -74,6 +74,7 @@ src/utilities/globals/* !src/utilities/graphql src/utilities/graphql/* !src/utilities/graphql/operations.ts +!src/utilities/graphql/print.ts !src/utilities/graphql/DocumentTransform.ts !src/utilities/graphql/__tests__/ src/utilities/graphql/__tests__/* diff --git a/.size-limit.cjs b/.size-limit.cjs index 1c95b3f7bdc..db2b344d37f 100644 --- a/.size-limit.cjs +++ b/.size-limit.cjs @@ -1,7 +1,7 @@ const checks = [ { path: "dist/apollo-client.min.cjs", - limit: "37460" + limit: "37479" }, { path: "dist/main.cjs", @@ -10,7 +10,7 @@ const checks = [ { path: "dist/index.js", import: "{ ApolloClient, InMemoryCache, HttpLink }", - limit: "33243" + limit: "33269" }, ...[ "ApolloProvider", diff --git a/src/__tests__/__snapshots__/exports.ts.snap b/src/__tests__/__snapshots__/exports.ts.snap index e5d92cead04..83308365fd3 100644 --- a/src/__tests__/__snapshots__/exports.ts.snap +++ b/src/__tests__/__snapshots__/exports.ts.snap @@ -455,6 +455,7 @@ Array [ "mergeOptions", "offsetLimitPagination", "omitDeep", + "print", "relayStylePagination", "removeArgumentsFromDocument", "removeClientSetsFromDocument", diff --git a/src/core/QueryManager.ts b/src/core/QueryManager.ts index a8d9dd742d6..a7b24000f36 100644 --- a/src/core/QueryManager.ts +++ b/src/core/QueryManager.ts @@ -69,6 +69,7 @@ import { } from './QueryInfo'; import type { ApolloErrorOptions } from '../errors'; import { PROTOCOL_ERRORS_SYMBOL } from '../errors'; +import { print } from '../utilities'; const { hasOwnProperty } = Object.prototype; @@ -1027,7 +1028,7 @@ export class QueryManager { } private inFlightLinkObservables = new Map< - DocumentNode, + string, Map> >(); @@ -1059,8 +1060,9 @@ export class QueryManager { context = operation.context; if (deduplication) { - const byVariables = inFlightLinkObservables.get(serverQuery) || new Map(); - inFlightLinkObservables.set(serverQuery, byVariables); + const printedServerQuery = print(serverQuery); + const byVariables = inFlightLinkObservables.get(printedServerQuery) || new Map(); + inFlightLinkObservables.set(printedServerQuery, byVariables); const varJson = canonicalStringify(variables); observable = byVariables.get(varJson); @@ -1075,7 +1077,7 @@ export class QueryManager { concast.beforeNext(() => { if (byVariables.delete(varJson) && byVariables.size < 1) { - inFlightLinkObservables.delete(serverQuery); + inFlightLinkObservables.delete(printedServerQuery); } }); } diff --git a/src/link/http/selectHttpOptionsAndBody.ts b/src/link/http/selectHttpOptionsAndBody.ts index ded1664d37f..ef98d38fc45 100644 --- a/src/link/http/selectHttpOptionsAndBody.ts +++ b/src/link/http/selectHttpOptionsAndBody.ts @@ -1,5 +1,5 @@ import type { ASTNode} from 'graphql'; -import { print } from 'graphql'; +import { print } from '../../utilities'; import type { Operation } from '../core'; diff --git a/src/link/persisted-queries/index.ts b/src/link/persisted-queries/index.ts index 7543ed2c97d..25037bf449f 100644 --- a/src/link/persisted-queries/index.ts +++ b/src/link/persisted-queries/index.ts @@ -1,6 +1,6 @@ import { invariant } from '../../utilities/globals'; -import { print } from 'graphql'; +import { print } from '../../utilities'; import type { DocumentNode, ExecutionResult, diff --git a/src/link/subscriptions/index.ts b/src/link/subscriptions/index.ts index aaea5ca87e8..64d65478be0 100644 --- a/src/link/subscriptions/index.ts +++ b/src/link/subscriptions/index.ts @@ -28,7 +28,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -import { print } from "graphql"; +import { print } from '../../utilities'; import type { Client } from "graphql-ws"; import type { Operation, FetchResult } from "../core"; diff --git a/src/testing/core/mocking/mockLink.ts b/src/testing/core/mocking/mockLink.ts index 0fa2fc276b6..9b72d580204 100644 --- a/src/testing/core/mocking/mockLink.ts +++ b/src/testing/core/mocking/mockLink.ts @@ -1,6 +1,5 @@ import { invariant } from '../../../utilities/globals'; -import { print } from 'graphql'; import { equal } from '@wry/equality'; import type { @@ -18,6 +17,7 @@ import { removeConnectionDirectiveFromDocument, cloneDeep, stringifyForDisplay, + print } from '../../../utilities'; export type ResultFunction = () => T; diff --git a/src/testing/matchers/toMatchDocument.ts b/src/testing/matchers/toMatchDocument.ts index 216c83da42e..23cafefc07d 100644 --- a/src/testing/matchers/toMatchDocument.ts +++ b/src/testing/matchers/toMatchDocument.ts @@ -1,5 +1,4 @@ -import { checkDocument } from '../../utilities'; -import { print } from 'graphql'; +import { checkDocument, print } from '../../utilities'; import type { DocumentNode } from '../../core'; import type { MatcherFunction } from 'expect'; diff --git a/src/utilities/graphql/print.ts b/src/utilities/graphql/print.ts new file mode 100644 index 00000000000..be3eca857a6 --- /dev/null +++ b/src/utilities/graphql/print.ts @@ -0,0 +1,14 @@ +import { print as origPrint } from 'graphql'; +import { canUseWeakMap } from '../common/canUse'; + +const printCache = canUseWeakMap ? new WeakMap() : undefined; +export const print: typeof origPrint = (ast) => { + let result; + result = printCache?.get(ast); + + if (!result) { + result = origPrint(ast); + printCache?.set(ast, result); + } + return result; +}; diff --git a/src/utilities/index.ts b/src/utilities/index.ts index 048f1dcbeb1..24773f897ee 100644 --- a/src/utilities/index.ts +++ b/src/utilities/index.ts @@ -36,6 +36,10 @@ export { getDefaultValues, } from './graphql/getFromAST'; +export { + print +} from './graphql/print'; + export { StoreObject, Reference,