From d5d8cb10c468a1f256286b354a428afd69765c15 Mon Sep 17 00:00:00 2001 From: Lenz Weber-Tronic Date: Thu, 16 Nov 2023 18:09:58 +0100 Subject: [PATCH 1/9] `print`: use `WeakCache` instead of `WeakMap` --- .changeset/polite-avocados-warn.md | 5 +++++ .size-limit.cjs | 5 +++-- package-lock.json | 12 ++++++++++++ package.json | 1 + src/utilities/graphql/print.ts | 13 +++++-------- 5 files changed, 26 insertions(+), 10 deletions(-) create mode 100644 .changeset/polite-avocados-warn.md diff --git a/.changeset/polite-avocados-warn.md b/.changeset/polite-avocados-warn.md new file mode 100644 index 00000000000..dd04015cf3d --- /dev/null +++ b/.changeset/polite-avocados-warn.md @@ -0,0 +1,5 @@ +--- +"@apollo/client": patch +--- + +`print`: use `WeakCache` instead of `WeakMap` diff --git a/.size-limit.cjs b/.size-limit.cjs index 63819405fd1..e2233d201f3 100644 --- a/.size-limit.cjs +++ b/.size-limit.cjs @@ -1,7 +1,7 @@ const checks = [ { path: "dist/apollo-client.min.cjs", - limit: "38164", + limit: "38178", }, { path: "dist/main.cjs", @@ -10,7 +10,7 @@ const checks = [ { path: "dist/index.js", import: "{ ApolloClient, InMemoryCache, HttpLink }", - limit: "32188", + limit: "32206", }, ...[ "ApolloProvider", @@ -35,6 +35,7 @@ const checks = [ "react", "react-dom", "@graphql-typed-document-node/core", + "@wry/caches", "@wry/context", "@wry/equality", "@wry/trie", diff --git a/package-lock.json b/package-lock.json index 9cf8221c770..2217dbde199 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "license": "MIT", "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", + "@wry/caches": "^1.0.0", "@wry/context": "^0.7.3", "@wry/equality": "^0.5.6", "@wry/trie": "^0.4.3", @@ -3294,6 +3295,17 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@wry/caches": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@wry/caches/-/caches-1.0.0.tgz", + "integrity": "sha512-FHRUDe2tqrXAj6A/1D39No68lFWbbnh+NCpG9J/6idhL/2Mb/AaxBTYg/sbUVImEo8a4mWeOewUlB1W7uLjByA==", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@wry/context": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.7.3.tgz", diff --git a/package.json b/package.json index 3a7d6f0196f..da96797c4ea 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,7 @@ }, "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", + "@wry/caches": "^1.0.0", "@wry/context": "^0.7.3", "@wry/equality": "^0.5.6", "@wry/trie": "^0.4.3", diff --git a/src/utilities/graphql/print.ts b/src/utilities/graphql/print.ts index d90a15611d0..572584e4ca3 100644 --- a/src/utilities/graphql/print.ts +++ b/src/utilities/graphql/print.ts @@ -1,23 +1,20 @@ import type { ASTNode } from "graphql"; import { print as origPrint } from "graphql"; -import { canUseWeakMap } from "../common/canUse.js"; +import { WeakCache } from "@wry/caches" -let printCache: undefined | WeakMap; -// further TODO: replace with `optimism` with a `WeakCache` once those are available +let printCache!: WeakCache; export const print = Object.assign( (ast: ASTNode) => { - let result; - result = printCache?.get(ast); + let result = printCache.get(ast); if (!result) { - result = origPrint(ast); - printCache?.set(ast, result); + printCache.set(ast, result = origPrint(ast)); } return result; }, { reset() { - printCache = canUseWeakMap ? new WeakMap() : undefined; + printCache = new WeakCache(/** TODO: decide on a maximum size (will do all max sizes in a combined separate PR) */); }, } ); From 29bf59da53b2846f9f713e93000c9d1d16d6b0a1 Mon Sep 17 00:00:00 2001 From: Lenz Weber-Tronic Date: Thu, 16 Nov 2023 18:11:41 +0100 Subject: [PATCH 2/9] format --- src/utilities/graphql/print.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/utilities/graphql/print.ts b/src/utilities/graphql/print.ts index 572584e4ca3..d536ff8bb77 100644 --- a/src/utilities/graphql/print.ts +++ b/src/utilities/graphql/print.ts @@ -1,6 +1,6 @@ import type { ASTNode } from "graphql"; import { print as origPrint } from "graphql"; -import { WeakCache } from "@wry/caches" +import { WeakCache } from "@wry/caches"; let printCache!: WeakCache; export const print = Object.assign( @@ -8,13 +8,16 @@ export const print = Object.assign( let result = printCache.get(ast); if (!result) { - printCache.set(ast, result = origPrint(ast)); + printCache.set(ast, (result = origPrint(ast))); } return result; }, { reset() { - printCache = new WeakCache(/** TODO: decide on a maximum size (will do all max sizes in a combined separate PR) */); + printCache = new WeakCache< + ASTNode, + string + >(/** TODO: decide on a maximum size (will do all max sizes in a combined separate PR) */); }, } ); From 1902da108fb78b0fc4f3b8f3d28c2e5a48800da9 Mon Sep 17 00:00:00 2001 From: Lenz Weber-Tronic Date: Fri, 17 Nov 2023 15:14:35 +0100 Subject: [PATCH 3/9] `parse` function: improve memory management * use LRU `WeakCache` instead of `Map` to keep a limited number of hash results * hash cache is initiated lazily, only when needed * expose `parse.resetCache()` method --- .api-reports/api-report-react.md | 6 ++++++ .api-reports/api-report-react_parser.md | 6 ++++++ .api-reports/api-report.md | 6 ++++++ .changeset/cold-llamas-turn.md | 8 ++++++++ src/react/parser/index.ts | 20 +++++++++++++++++++- 5 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 .changeset/cold-llamas-turn.md diff --git a/.api-reports/api-report-react.md b/.api-reports/api-report-react.md index 5d4ebef40d6..968c7ec60c4 100644 --- a/.api-reports/api-report-react.md +++ b/.api-reports/api-report-react.md @@ -1397,6 +1397,12 @@ type OperationVariables = Record; // @public (undocumented) export function parser(document: DocumentNode): IDocumentDefinition; +// @public (undocumented) +export namespace parser { + var // (undocumented) + resetCache: () => void; +} + // @public (undocumented) type Path = ReadonlyArray; diff --git a/.api-reports/api-report-react_parser.md b/.api-reports/api-report-react_parser.md index 96d961506af..9dd7eab4a8b 100644 --- a/.api-reports/api-report-react_parser.md +++ b/.api-reports/api-report-react_parser.md @@ -34,6 +34,12 @@ export function operationName(type: DocumentType_2): string; // @public (undocumented) export function parser(document: DocumentNode): IDocumentDefinition; +// @public (undocumented) +export namespace parser { + var // (undocumented) + resetCache: () => void; +} + // @public (undocumented) export function verifyDocumentType(document: DocumentNode, type: DocumentType_2): void; diff --git a/.api-reports/api-report.md b/.api-reports/api-report.md index 71c954da766..e3107b741e2 100644 --- a/.api-reports/api-report.md +++ b/.api-reports/api-report.md @@ -1892,6 +1892,12 @@ export function parseAndCheckHttpResponse(operations: Operation | Operation[]): // @public (undocumented) export function parser(document: DocumentNode): IDocumentDefinition; +// @public (undocumented) +export namespace parser { + var // (undocumented) + resetCache: () => void; +} + // @public (undocumented) export type Path = ReadonlyArray; diff --git a/.changeset/cold-llamas-turn.md b/.changeset/cold-llamas-turn.md new file mode 100644 index 00000000000..e0c2e1b9a79 --- /dev/null +++ b/.changeset/cold-llamas-turn.md @@ -0,0 +1,8 @@ +--- +"@apollo/client": patch +--- + +`parse` function: improve memory management +* use LRU `WeakCache` instead of `Map` to keep a limited number of hash results +* hash cache is initiated lazily, only when needed +* expose `parse.resetCache()` method diff --git a/src/react/parser/index.ts b/src/react/parser/index.ts index 984b491142f..cbaa8f69612 100644 --- a/src/react/parser/index.ts +++ b/src/react/parser/index.ts @@ -1,3 +1,4 @@ +import { WeakCache } from "@wry/caches"; import { invariant } from "../../utilities/globals/index.js"; import type { @@ -19,7 +20,16 @@ export interface IDocumentDefinition { variables: ReadonlyArray; } -const cache = new Map(); +let cache: + | undefined + | WeakCache< + DocumentNode, + { + name: string; + type: DocumentType; + variables: readonly VariableDefinitionNode[]; + } + >; export function operationName(type: DocumentType) { let name; @@ -39,6 +49,10 @@ export function operationName(type: DocumentType) { // This parser is mostly used to safety check incoming documents. export function parser(document: DocumentNode): IDocumentDefinition { + if (!cache) { + cache = + new WeakCache(/** TODO: decide on a maximum size (will do all max sizes in a combined separate PR) */); + } const cached = cache.get(document); if (cached) return cached; @@ -131,6 +145,10 @@ export function parser(document: DocumentNode): IDocumentDefinition { return payload; } +parser.resetCache = () => { + cache = undefined; +}; + export function verifyDocumentType(document: DocumentNode, type: DocumentType) { const operation = parser(document); const requiredOperationName = operationName(type); From 74ffef1536e44207d4019d45ac2587958d806b4f Mon Sep 17 00:00:00 2001 From: Lenz Weber-Tronic Date: Fri, 17 Nov 2023 15:36:24 +0100 Subject: [PATCH 4/9] Update cold-llamas-turn.md --- .changeset/cold-llamas-turn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/cold-llamas-turn.md b/.changeset/cold-llamas-turn.md index e0c2e1b9a79..45267c54740 100644 --- a/.changeset/cold-llamas-turn.md +++ b/.changeset/cold-llamas-turn.md @@ -4,5 +4,5 @@ `parse` function: improve memory management * use LRU `WeakCache` instead of `Map` to keep a limited number of hash results -* hash cache is initiated lazily, only when needed +* cache is initiated lazily, only when needed * expose `parse.resetCache()` method From ae711fb0e2d4570a96743bef2893306ab8642b64 Mon Sep 17 00:00:00 2001 From: Lenz Weber-Tronic Date: Fri, 17 Nov 2023 15:42:14 +0100 Subject: [PATCH 5/9] Update cold-llamas-turn.md --- .changeset/cold-llamas-turn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/cold-llamas-turn.md b/.changeset/cold-llamas-turn.md index 45267c54740..a3f1e0099df 100644 --- a/.changeset/cold-llamas-turn.md +++ b/.changeset/cold-llamas-turn.md @@ -3,6 +3,6 @@ --- `parse` function: improve memory management -* use LRU `WeakCache` instead of `Map` to keep a limited number of hash results +* use LRU `WeakCache` instead of `Map` to keep a limited number of parsed results * cache is initiated lazily, only when needed * expose `parse.resetCache()` method From bd40e8e4f16b6ae69249d41c539eb16bfa72794c Mon Sep 17 00:00:00 2001 From: Lenz Weber-Tronic Date: Fri, 17 Nov 2023 15:48:22 +0100 Subject: [PATCH 6/9] update size limit --- .size-limits.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.size-limits.json b/.size-limits.json index f71b98fe37c..8a945778178 100644 --- a/.size-limits.json +++ b/.size-limits.json @@ -1,4 +1,4 @@ { - "dist/apollo-client.min.cjs": 37975, - "import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32019 + "dist/apollo-client.min.cjs": 38178, + "import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32206 } From f84da806411314c19a9fda8d76bf1e9bd46833c1 Mon Sep 17 00:00:00 2001 From: Lenz Weber-Tronic Date: Fri, 17 Nov 2023 15:56:17 +0100 Subject: [PATCH 7/9] size-limit --- .size-limits.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.size-limits.json b/.size-limits.json index 52108cf4fb9..8a945778178 100644 --- a/.size-limits.json +++ b/.size-limits.json @@ -1,4 +1,4 @@ { - "dist/apollo-client.min.cjs": 38164, - "import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32188 + "dist/apollo-client.min.cjs": 38178, + "import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32206 } From 2b70f47b04fa741c6216a686d4d65bc1396efb5c Mon Sep 17 00:00:00 2001 From: Lenz Weber-Tronic Date: Fri, 17 Nov 2023 15:58:10 +0100 Subject: [PATCH 8/9] size-limit --- .size-limits.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.size-limits.json b/.size-limits.json index 8a945778178..633c6a52fd8 100644 --- a/.size-limits.json +++ b/.size-limits.json @@ -1,4 +1,4 @@ { - "dist/apollo-client.min.cjs": 38178, + "dist/apollo-client.min.cjs": 38201, "import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32206 } From ed09a9c0f1810ba67cd0cf9205dda3f4727ab292 Mon Sep 17 00:00:00 2001 From: phryneas Date: Wed, 29 Nov 2023 10:51:54 +0000 Subject: [PATCH 9/9] Clean up Prettier, Size-limit, and Api-Extractor --- .size-limits.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.size-limits.json b/.size-limits.json index d5dd8296590..ee06be421b2 100644 --- a/.size-limits.json +++ b/.size-limits.json @@ -1,4 +1,4 @@ { - "dist/apollo-client.min.cjs": 38603, + "dist/apollo-client.min.cjs": 38625, "import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32203 }