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 bd40e8e4f16b6ae69249d41c539eb16bfa72794c Mon Sep 17 00:00:00 2001 From: Lenz Weber-Tronic Date: Fri, 17 Nov 2023 15:48:22 +0100 Subject: [PATCH 3/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 4/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 fed211af413211cf78e7c0dd0618f46cfeff0e97 Mon Sep 17 00:00:00 2001 From: Lenz Weber-Tronic Date: Mon, 27 Nov 2023 17:57:50 +0100 Subject: [PATCH 5/9] `DocumentTransform`: use a `WeakCache` --- .api-reports/api-report-core.md | 2 +- .api-reports/api-report-react.md | 5 +-- .api-reports/api-report-react_components.md | 5 +-- .api-reports/api-report-react_context.md | 5 +-- .api-reports/api-report-react_hoc.md | 5 +-- .api-reports/api-report-react_hooks.md | 5 +-- .api-reports/api-report-react_ssr.md | 5 +-- .api-reports/api-report-testing.md | 5 +-- .api-reports/api-report-testing_core.md | 5 +-- .api-reports/api-report-utilities.md | 2 +- .api-reports/api-report.md | 2 +- .changeset/dirty-kids-crash.md | 5 +++ .size-limits.json | 4 +-- src/utilities/graphql/DocumentTransform.ts | 35 +++++++++++++++------ 14 files changed, 60 insertions(+), 30 deletions(-) create mode 100644 .changeset/dirty-kids-crash.md diff --git a/.api-reports/api-report-core.md b/.api-reports/api-report-core.md index f8c570ceebc..9bd593e97a9 100644 --- a/.api-reports/api-report-core.md +++ b/.api-reports/api-report-core.md @@ -595,7 +595,7 @@ export class DocumentTransform { concat(otherTransform: DocumentTransform): DocumentTransform; // (undocumented) getStableCacheEntry(document: DocumentNode): { - key: DocumentTransformCacheKey; + key?: undefined; value?: DocumentNode | undefined; } | undefined; // (undocumented) diff --git a/.api-reports/api-report-react.md b/.api-reports/api-report-react.md index 5d4ebef40d6..607a85fd909 100644 --- a/.api-reports/api-report-react.md +++ b/.api-reports/api-report-react.md @@ -722,7 +722,7 @@ class DocumentTransform { concat(otherTransform: DocumentTransform): DocumentTransform; // (undocumented) getStableCacheEntry(document: DocumentNode): { - key: DocumentTransformCacheKey; + key?: undefined; value?: DocumentNode | undefined; } | undefined; // (undocumented) @@ -742,6 +742,8 @@ type DocumentTransformCacheKey = ReadonlyArray; interface DocumentTransformOptions { // (undocumented) cache?: boolean; + // Warning: (ae-forgotten-export) The symbol "DocumentTransformCacheKey" needs to be exported by the entry point index.d.ts + // // (undocumented) getCacheKey?: (document: DocumentNode) => DocumentTransformCacheKey | undefined; } @@ -2221,7 +2223,6 @@ interface WatchQueryOptions; interface DocumentTransformOptions { // (undocumented) cache?: boolean; + // Warning: (ae-forgotten-export) The symbol "DocumentTransformCacheKey" needs to be exported by the entry point index.d.ts + // // (undocumented) getCacheKey?: (document: DocumentNode) => DocumentTransformCacheKey | undefined; } @@ -1753,7 +1755,6 @@ interface WatchQueryOptions; interface DocumentTransformOptions { // (undocumented) cache?: boolean; + // Warning: (ae-forgotten-export) The symbol "DocumentTransformCacheKey" needs to be exported by the entry point index.d.ts + // // (undocumented) getCacheKey?: (document: DocumentNode) => DocumentTransformCacheKey | undefined; } @@ -1649,7 +1651,6 @@ interface WatchQueryOptions; interface DocumentTransformOptions { // (undocumented) cache?: boolean; + // Warning: (ae-forgotten-export) The symbol "DocumentTransformCacheKey" needs to be exported by the entry point index.d.ts + // // (undocumented) getCacheKey?: (document: DocumentNode) => DocumentTransformCacheKey | undefined; } @@ -1694,7 +1696,6 @@ export function withSubscription; interface DocumentTransformOptions { // (undocumented) cache?: boolean; + // Warning: (ae-forgotten-export) The symbol "DocumentTransformCacheKey" needs to be exported by the entry point index.d.ts + // // (undocumented) getCacheKey?: (document: DocumentNode) => DocumentTransformCacheKey | undefined; } @@ -2115,7 +2117,6 @@ interface WatchQueryOptions; interface DocumentTransformOptions { // (undocumented) cache?: boolean; + // Warning: (ae-forgotten-export) The symbol "DocumentTransformCacheKey" needs to be exported by the entry point index.d.ts + // // (undocumented) getCacheKey?: (document: DocumentNode) => DocumentTransformCacheKey | undefined; } @@ -1635,7 +1637,6 @@ interface WatchQueryOptions; interface DocumentTransformOptions { // (undocumented) cache?: boolean; + // Warning: (ae-forgotten-export) The symbol "DocumentTransformCacheKey" needs to be exported by the entry point index.d.ts + // // (undocumented) getCacheKey?: (document: DocumentNode) => DocumentTransformCacheKey | undefined; } @@ -1698,7 +1700,6 @@ export function withWarningSpy(it: (...args: TArgs // src/core/types.ts:178:3 - (ae-forgotten-export) The symbol "MutationQueryReducer" needs to be exported by the entry point index.d.ts // src/core/types.ts:205:5 - (ae-forgotten-export) The symbol "Resolver" needs to be exported by the entry point index.d.ts // src/core/watchQueryOptions.ts:191:3 - (ae-forgotten-export) The symbol "UpdateQueryFn" needs to be exported by the entry point index.d.ts -// src/utilities/graphql/DocumentTransform.ts:130:7 - (ae-forgotten-export) The symbol "DocumentTransformCacheKey" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/.api-reports/api-report-testing_core.md b/.api-reports/api-report-testing_core.md index 5aaef2383c6..747aacb3ee9 100644 --- a/.api-reports/api-report-testing_core.md +++ b/.api-reports/api-report-testing_core.md @@ -575,7 +575,7 @@ class DocumentTransform { concat(otherTransform: DocumentTransform): DocumentTransform; // (undocumented) getStableCacheEntry(document: DocumentNode): { - key: DocumentTransformCacheKey; + key?: undefined; value?: DocumentNode | undefined; } | undefined; // (undocumented) @@ -595,6 +595,8 @@ type DocumentTransformCacheKey = ReadonlyArray; interface DocumentTransformOptions { // (undocumented) cache?: boolean; + // Warning: (ae-forgotten-export) The symbol "DocumentTransformCacheKey" needs to be exported by the entry point index.d.ts + // // (undocumented) getCacheKey?: (document: DocumentNode) => DocumentTransformCacheKey | undefined; } @@ -1654,7 +1656,6 @@ export function withWarningSpy(it: (...args: TArgs // src/core/types.ts:178:3 - (ae-forgotten-export) The symbol "MutationQueryReducer" needs to be exported by the entry point index.d.ts // src/core/types.ts:205:5 - (ae-forgotten-export) The symbol "Resolver" needs to be exported by the entry point index.d.ts // src/core/watchQueryOptions.ts:191:3 - (ae-forgotten-export) The symbol "UpdateQueryFn" needs to be exported by the entry point index.d.ts -// src/utilities/graphql/DocumentTransform.ts:130:7 - (ae-forgotten-export) The symbol "DocumentTransformCacheKey" needs to be exported by the entry point index.d.ts // (No @packageDocumentation comment for this package) diff --git a/.api-reports/api-report-utilities.md b/.api-reports/api-report-utilities.md index 93fab5008fc..9650213fd7f 100644 --- a/.api-reports/api-report-utilities.md +++ b/.api-reports/api-report-utilities.md @@ -753,7 +753,7 @@ export class DocumentTransform { concat(otherTransform: DocumentTransform): DocumentTransform; // (undocumented) getStableCacheEntry(document: DocumentNode): { - key: DocumentTransformCacheKey; + key?: undefined; value?: DocumentNode | undefined; } | undefined; // (undocumented) diff --git a/.api-reports/api-report.md b/.api-reports/api-report.md index 71c954da766..9b26996712a 100644 --- a/.api-reports/api-report.md +++ b/.api-reports/api-report.md @@ -745,7 +745,7 @@ export class DocumentTransform { concat(otherTransform: DocumentTransform): DocumentTransform; // (undocumented) getStableCacheEntry(document: DocumentNode): { - key: DocumentTransformCacheKey; + key?: undefined; value?: DocumentNode | undefined; } | undefined; // (undocumented) diff --git a/.changeset/dirty-kids-crash.md b/.changeset/dirty-kids-crash.md new file mode 100644 index 00000000000..4de92a20bd0 --- /dev/null +++ b/.changeset/dirty-kids-crash.md @@ -0,0 +1,5 @@ +--- +"@apollo/client": patch +--- + +`documentTransform`: use `WeakCache` instead of directly storing data on the `Trie` diff --git a/.size-limits.json b/.size-limits.json index 8a945778178..d8f4d397294 100644 --- a/.size-limits.json +++ b/.size-limits.json @@ -1,4 +1,4 @@ { - "dist/apollo-client.min.cjs": 38178, - "import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32206 + "dist/apollo-client.min.cjs": 38189, + "import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32209 } diff --git a/src/utilities/graphql/DocumentTransform.ts b/src/utilities/graphql/DocumentTransform.ts index d88bcf7615b..475e805c47d 100644 --- a/src/utilities/graphql/DocumentTransform.ts +++ b/src/utilities/graphql/DocumentTransform.ts @@ -3,6 +3,7 @@ import { canUseWeakMap, canUseWeakSet } from "../common/canUse.js"; import { checkDocument } from "./getFromAST.js"; import { invariant } from "../globals/index.js"; import type { DocumentNode } from "graphql"; +import { WeakCache } from "@wry/caches"; export type DocumentTransformCacheKey = ReadonlyArray; @@ -26,8 +27,16 @@ export class DocumentTransform { ? new WeakSet() : new Set(); - private stableCacheKeys: - | Trie<{ key: DocumentTransformCacheKey; value?: DocumentNode }> + private stableCacheKeys: Trie | undefined; + private transformCache: + | WeakCache< + WeakKey, + { + /** @deprecated this property had to be removed to prevent a potential memory leak */ + key?: never; + value?: DocumentNode; + } + > | undefined; // This default implementation of getCacheKey can be overridden by providing @@ -75,17 +84,18 @@ export class DocumentTransform { this.getCacheKey = options.getCacheKey; } - if (options.cache !== false) { - this.stableCacheKeys = new Trie(canUseWeakMap, (key) => ({ key })); - } + this.resetCache(options.cache !== false); } /** * Resets the internal cache of this transform, if it has one. */ - resetCache() { - this.stableCacheKeys = - this.stableCacheKeys && new Trie(canUseWeakMap, (key) => ({ key })); + resetCache(enableCaching?: boolean) { + if (this.stableCacheKeys || enableCaching) { + this.stableCacheKeys = new Trie(canUseWeakMap); + this.transformCache = + new WeakCache(/** TODO: decide on a maximum size (will do all max sizes in a combined separate PR) */); + } } transformDocument(document: DocumentNode) { @@ -134,7 +144,14 @@ export class DocumentTransform { Array.isArray(cacheKeys), "`getCacheKey` must return an array or undefined" ); - return this.stableCacheKeys.lookupArray(cacheKeys); + const key = this.stableCacheKeys.lookupArray(cacheKeys); + let value; + // if `stableCacheKeys` is set, `transformCache` must be set as well + this.transformCache!.set( + key, + (value = this.transformCache!.get(key) || {}) + ); + return value; } } } From 685cf3e00374dc9574c0cb09112b7b7f7850b3ab Mon Sep 17 00:00:00 2001 From: Lenz Weber-Tronic Date: Mon, 27 Nov 2023 18:27:10 +0100 Subject: [PATCH 6/9] `documentTransform`: use `optimism` and `WeakCache` --- .api-reports/api-report-core.md | 5 -- .api-reports/api-report-react.md | 5 -- .api-reports/api-report-react_components.md | 5 -- .api-reports/api-report-react_context.md | 5 -- .api-reports/api-report-react_hoc.md | 5 -- .api-reports/api-report-react_hooks.md | 5 -- .api-reports/api-report-react_ssr.md | 5 -- .api-reports/api-report-testing.md | 5 -- .api-reports/api-report-testing_core.md | 5 -- .api-reports/api-report-utilities.md | 5 -- .api-reports/api-report.md | 5 -- .changeset/dirty-kids-crash.md | 2 +- .size-limits.json | 4 +- src/utilities/graphql/DocumentTransform.ts | 82 ++++++++------------- 14 files changed, 34 insertions(+), 109 deletions(-) diff --git a/.api-reports/api-report-core.md b/.api-reports/api-report-core.md index 9bd593e97a9..dd62596b90e 100644 --- a/.api-reports/api-report-core.md +++ b/.api-reports/api-report-core.md @@ -594,11 +594,6 @@ export class DocumentTransform { // (undocumented) concat(otherTransform: DocumentTransform): DocumentTransform; // (undocumented) - getStableCacheEntry(document: DocumentNode): { - key?: undefined; - value?: DocumentNode | undefined; - } | undefined; - // (undocumented) static identity(): DocumentTransform; // (undocumented) resetCache(): void; diff --git a/.api-reports/api-report-react.md b/.api-reports/api-report-react.md index 607a85fd909..f9311d4ca71 100644 --- a/.api-reports/api-report-react.md +++ b/.api-reports/api-report-react.md @@ -721,11 +721,6 @@ class DocumentTransform { // (undocumented) concat(otherTransform: DocumentTransform): DocumentTransform; // (undocumented) - getStableCacheEntry(document: DocumentNode): { - key?: undefined; - value?: DocumentNode | undefined; - } | undefined; - // (undocumented) static identity(): DocumentTransform; // (undocumented) resetCache(): void; diff --git a/.api-reports/api-report-react_components.md b/.api-reports/api-report-react_components.md index f7c441cf9d7..966e299e1bc 100644 --- a/.api-reports/api-report-react_components.md +++ b/.api-reports/api-report-react_components.md @@ -628,11 +628,6 @@ class DocumentTransform { // (undocumented) concat(otherTransform: DocumentTransform): DocumentTransform; // (undocumented) - getStableCacheEntry(document: DocumentNode): { - key?: undefined; - value?: DocumentNode | undefined; - } | undefined; - // (undocumented) static identity(): DocumentTransform; // (undocumented) resetCache(): void; diff --git a/.api-reports/api-report-react_context.md b/.api-reports/api-report-react_context.md index f1598e4d632..f58e725d6bb 100644 --- a/.api-reports/api-report-react_context.md +++ b/.api-reports/api-report-react_context.md @@ -611,11 +611,6 @@ class DocumentTransform { // (undocumented) concat(otherTransform: DocumentTransform): DocumentTransform; // (undocumented) - getStableCacheEntry(document: DocumentNode): { - key?: undefined; - value?: DocumentNode | undefined; - } | undefined; - // (undocumented) static identity(): DocumentTransform; // (undocumented) resetCache(): void; diff --git a/.api-reports/api-report-react_hoc.md b/.api-reports/api-report-react_hoc.md index 8cb0d7bbb58..9aac717e529 100644 --- a/.api-reports/api-report-react_hoc.md +++ b/.api-reports/api-report-react_hoc.md @@ -613,11 +613,6 @@ class DocumentTransform { // (undocumented) concat(otherTransform: DocumentTransform): DocumentTransform; // (undocumented) - getStableCacheEntry(document: DocumentNode): { - key?: undefined; - value?: DocumentNode | undefined; - } | undefined; - // (undocumented) static identity(): DocumentTransform; // (undocumented) resetCache(): void; diff --git a/.api-reports/api-report-react_hooks.md b/.api-reports/api-report-react_hooks.md index a1c5b4b1f4e..9999c044fed 100644 --- a/.api-reports/api-report-react_hooks.md +++ b/.api-reports/api-report-react_hooks.md @@ -692,11 +692,6 @@ class DocumentTransform { // (undocumented) concat(otherTransform: DocumentTransform): DocumentTransform; // (undocumented) - getStableCacheEntry(document: DocumentNode): { - key?: undefined; - value?: DocumentNode | undefined; - } | undefined; - // (undocumented) static identity(): DocumentTransform; // (undocumented) resetCache(): void; diff --git a/.api-reports/api-report-react_ssr.md b/.api-reports/api-report-react_ssr.md index fa7c151aeec..ef6402a4172 100644 --- a/.api-reports/api-report-react_ssr.md +++ b/.api-reports/api-report-react_ssr.md @@ -581,11 +581,6 @@ class DocumentTransform { // (undocumented) concat(otherTransform: DocumentTransform): DocumentTransform; // (undocumented) - getStableCacheEntry(document: DocumentNode): { - key?: undefined; - value?: DocumentNode | undefined; - } | undefined; - // (undocumented) static identity(): DocumentTransform; // (undocumented) resetCache(): void; diff --git a/.api-reports/api-report-testing.md b/.api-reports/api-report-testing.md index e98e6b39978..570638d35c7 100644 --- a/.api-reports/api-report-testing.md +++ b/.api-reports/api-report-testing.md @@ -575,11 +575,6 @@ class DocumentTransform { // (undocumented) concat(otherTransform: DocumentTransform): DocumentTransform; // (undocumented) - getStableCacheEntry(document: DocumentNode): { - key?: undefined; - value?: DocumentNode | undefined; - } | undefined; - // (undocumented) static identity(): DocumentTransform; // (undocumented) resetCache(): void; diff --git a/.api-reports/api-report-testing_core.md b/.api-reports/api-report-testing_core.md index 747aacb3ee9..12f5245bf9a 100644 --- a/.api-reports/api-report-testing_core.md +++ b/.api-reports/api-report-testing_core.md @@ -574,11 +574,6 @@ class DocumentTransform { // (undocumented) concat(otherTransform: DocumentTransform): DocumentTransform; // (undocumented) - getStableCacheEntry(document: DocumentNode): { - key?: undefined; - value?: DocumentNode | undefined; - } | undefined; - // (undocumented) static identity(): DocumentTransform; // (undocumented) resetCache(): void; diff --git a/.api-reports/api-report-utilities.md b/.api-reports/api-report-utilities.md index 9650213fd7f..915d211c30e 100644 --- a/.api-reports/api-report-utilities.md +++ b/.api-reports/api-report-utilities.md @@ -752,11 +752,6 @@ export class DocumentTransform { // (undocumented) concat(otherTransform: DocumentTransform): DocumentTransform; // (undocumented) - getStableCacheEntry(document: DocumentNode): { - key?: undefined; - value?: DocumentNode | undefined; - } | undefined; - // (undocumented) static identity(): DocumentTransform; // (undocumented) resetCache(): void; diff --git a/.api-reports/api-report.md b/.api-reports/api-report.md index 9b26996712a..d47ab93fd8b 100644 --- a/.api-reports/api-report.md +++ b/.api-reports/api-report.md @@ -744,11 +744,6 @@ export class DocumentTransform { // (undocumented) concat(otherTransform: DocumentTransform): DocumentTransform; // (undocumented) - getStableCacheEntry(document: DocumentNode): { - key?: undefined; - value?: DocumentNode | undefined; - } | undefined; - // (undocumented) static identity(): DocumentTransform; // (undocumented) resetCache(): void; diff --git a/.changeset/dirty-kids-crash.md b/.changeset/dirty-kids-crash.md index 4de92a20bd0..504c049268d 100644 --- a/.changeset/dirty-kids-crash.md +++ b/.changeset/dirty-kids-crash.md @@ -2,4 +2,4 @@ "@apollo/client": patch --- -`documentTransform`: use `WeakCache` instead of directly storing data on the `Trie` +`documentTransform`: use `optimism` and `WeakCache` instead of directly storing data on the `Trie` diff --git a/.size-limits.json b/.size-limits.json index d8f4d397294..04040b15ac7 100644 --- a/.size-limits.json +++ b/.size-limits.json @@ -1,4 +1,4 @@ { - "dist/apollo-client.min.cjs": 38189, - "import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32209 + "dist/apollo-client.min.cjs": 38162, + "import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32186 } diff --git a/src/utilities/graphql/DocumentTransform.ts b/src/utilities/graphql/DocumentTransform.ts index 475e805c47d..b12a06650e1 100644 --- a/src/utilities/graphql/DocumentTransform.ts +++ b/src/utilities/graphql/DocumentTransform.ts @@ -3,7 +3,8 @@ import { canUseWeakMap, canUseWeakSet } from "../common/canUse.js"; import { checkDocument } from "./getFromAST.js"; import { invariant } from "../globals/index.js"; import type { DocumentNode } from "graphql"; -import { WeakCache } from "@wry/caches"; +// import { WeakCache } from "@wry/caches"; +import { wrap } from "optimism"; export type DocumentTransformCacheKey = ReadonlyArray; @@ -22,23 +23,12 @@ function identity(document: DocumentNode) { export class DocumentTransform { private readonly transform: TransformFn; + private cached: boolean; private readonly resultCache = canUseWeakSet ? new WeakSet() : new Set(); - private stableCacheKeys: Trie | undefined; - private transformCache: - | WeakCache< - WeakKey, - { - /** @deprecated this property had to be removed to prevent a potential memory leak */ - key?: never; - value?: DocumentNode; - } - > - | undefined; - // This default implementation of getCacheKey can be overridden by providing // options.getCacheKey to the DocumentTransform constructor. In general, a // getCacheKey function may either return an array of keys (often including @@ -83,21 +73,42 @@ export class DocumentTransform { // Override default `getCacheKey` function, which returns [document]. this.getCacheKey = options.getCacheKey; } + this.cached = options.cache !== false; - this.resetCache(options.cache !== false); + this.resetCache(); } /** * Resets the internal cache of this transform, if it has one. */ - resetCache(enableCaching?: boolean) { - if (this.stableCacheKeys || enableCaching) { - this.stableCacheKeys = new Trie(canUseWeakMap); - this.transformCache = - new WeakCache(/** TODO: decide on a maximum size (will do all max sizes in a combined separate PR) */); + resetCache() { + if (this.cached) { + const stableCacheKeys = new Trie(canUseWeakMap); + this.performWork = wrap( + DocumentTransform.prototype.performWork.bind(this), + { + makeCacheKey: (document) => { + const cacheKeys = this.getCacheKey(document); + if (cacheKeys) { + invariant( + Array.isArray(cacheKeys), + "`getCacheKey` must return an array or undefined" + ); + return stableCacheKeys.lookupArray(cacheKeys); + } + }, + // max: /** TODO: decide on a maximum size (will do all max sizes in a combined separate PR) */, + // Cache: WeakCache // TODO: waiting for an optimism release that allows this + } + ); } } + private performWork(document: DocumentNode) { + checkDocument(document); + return this.transform(document); + } + transformDocument(document: DocumentNode) { // If a user passes an already transformed result back to this function, // immediately return it. @@ -105,22 +116,10 @@ export class DocumentTransform { return document; } - const cacheEntry = this.getStableCacheEntry(document); - - if (cacheEntry && cacheEntry.value) { - return cacheEntry.value; - } - - checkDocument(document); - - const transformedDocument = this.transform(document); + const transformedDocument = this.performWork(document); this.resultCache.add(transformedDocument); - if (cacheEntry) { - cacheEntry.value = transformedDocument; - } - return transformedDocument; } @@ -135,23 +134,4 @@ export class DocumentTransform { { cache: false } ); } - - getStableCacheEntry(document: DocumentNode) { - if (!this.stableCacheKeys) return; - const cacheKeys = this.getCacheKey(document); - if (cacheKeys) { - invariant( - Array.isArray(cacheKeys), - "`getCacheKey` must return an array or undefined" - ); - const key = this.stableCacheKeys.lookupArray(cacheKeys); - let value; - // if `stableCacheKeys` is set, `transformCache` must be set as well - this.transformCache!.set( - key, - (value = this.transformCache!.get(key) || {}) - ); - return value; - } - } } From 28dd6ee5e74132919ba12bbfe6da1e0bd108e83a Mon Sep 17 00:00:00 2001 From: Lenz Weber-Tronic Date: Tue, 28 Nov 2023 11:21:46 +0100 Subject: [PATCH 7/9] update optimism to prerelease, use new `cache` option --- package-lock.json | 9 +++++---- package.json | 2 +- src/utilities/graphql/DocumentTransform.ts | 8 ++++---- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2217dbde199..453b666bb07 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@wry/trie": "^0.4.3", "graphql-tag": "^2.12.6", "hoist-non-react-statics": "^3.3.2", - "optimism": "^0.17.5", + "optimism": "^0.18.0-pre.0", "prop-types": "^15.7.2", "rehackt": "0.0.3", "response-iterator": "^0.2.6", @@ -8944,10 +8944,11 @@ } }, "node_modules/optimism": { - "version": "0.17.5", - "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.17.5.tgz", - "integrity": "sha512-TEcp8ZwK1RczmvMnvktxHSF2tKgMWjJ71xEFGX5ApLh67VsMSTy1ZUlipJw8W+KaqgOmQ+4pqwkeivY89j+4Vw==", + "version": "0.18.0-pre.0", + "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.18.0-pre.0.tgz", + "integrity": "sha512-/p+E9Wv0958NfBUQKqbdVpyah8PgPTAP5LwMgbCkRTZgPyT8l479pxwQQiqEcjQ5uorMg6vM5j4jE6EyhS+7Mg==", "dependencies": { + "@wry/caches": "^1.0.0", "@wry/context": "^0.7.0", "@wry/trie": "^0.4.3", "tslib": "^2.3.0" diff --git a/package.json b/package.json index 0cfdabf4dbd..13d023dea28 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "@wry/trie": "^0.4.3", "graphql-tag": "^2.12.6", "hoist-non-react-statics": "^3.3.2", - "optimism": "^0.17.5", + "optimism": "^0.18.0-pre.0", "prop-types": "^15.7.2", "rehackt": "0.0.3", "response-iterator": "^0.2.6", diff --git a/src/utilities/graphql/DocumentTransform.ts b/src/utilities/graphql/DocumentTransform.ts index b12a06650e1..fc2e48aa47f 100644 --- a/src/utilities/graphql/DocumentTransform.ts +++ b/src/utilities/graphql/DocumentTransform.ts @@ -3,7 +3,7 @@ import { canUseWeakMap, canUseWeakSet } from "../common/canUse.js"; import { checkDocument } from "./getFromAST.js"; import { invariant } from "../globals/index.js"; import type { DocumentNode } from "graphql"; -// import { WeakCache } from "@wry/caches"; +import { WeakCache } from "@wry/caches"; import { wrap } from "optimism"; export type DocumentTransformCacheKey = ReadonlyArray; @@ -83,7 +83,7 @@ export class DocumentTransform { */ resetCache() { if (this.cached) { - const stableCacheKeys = new Trie(canUseWeakMap); + const stableCacheKeys = new Trie(canUseWeakMap); this.performWork = wrap( DocumentTransform.prototype.performWork.bind(this), { @@ -97,8 +97,8 @@ export class DocumentTransform { return stableCacheKeys.lookupArray(cacheKeys); } }, - // max: /** TODO: decide on a maximum size (will do all max sizes in a combined separate PR) */, - // Cache: WeakCache // TODO: waiting for an optimism release that allows this + /** TODO: decide on a maximum size (will do all max sizes in a combined separate PR) */ + cache: new WeakCache(1000, (entry) => entry.dispose()), } ); } From 2c1c8bd183fb1004a314996c3ab782ab63b36ee7 Mon Sep 17 00:00:00 2001 From: Lenz Weber-Tronic Date: Tue, 28 Nov 2023 19:23:06 +0100 Subject: [PATCH 8/9] update optimism --- .size-limits.json | 4 ++-- package-lock.json | 8 ++++---- package.json | 2 +- src/utilities/graphql/DocumentTransform.ts | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.size-limits.json b/.size-limits.json index 04040b15ac7..92bd72df623 100644 --- a/.size-limits.json +++ b/.size-limits.json @@ -1,4 +1,4 @@ { - "dist/apollo-client.min.cjs": 38162, - "import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32186 + "dist/apollo-client.min.cjs": 38179, + "import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32209 } diff --git a/package-lock.json b/package-lock.json index 453b666bb07..add8a971f11 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@wry/trie": "^0.4.3", "graphql-tag": "^2.12.6", "hoist-non-react-statics": "^3.3.2", - "optimism": "^0.18.0-pre.0", + "optimism": "^0.18.0-pre.1", "prop-types": "^15.7.2", "rehackt": "0.0.3", "response-iterator": "^0.2.6", @@ -8944,9 +8944,9 @@ } }, "node_modules/optimism": { - "version": "0.18.0-pre.0", - "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.18.0-pre.0.tgz", - "integrity": "sha512-/p+E9Wv0958NfBUQKqbdVpyah8PgPTAP5LwMgbCkRTZgPyT8l479pxwQQiqEcjQ5uorMg6vM5j4jE6EyhS+7Mg==", + "version": "0.18.0-pre.1", + "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.18.0-pre.1.tgz", + "integrity": "sha512-NRJCCIliZRc9ScJa9kGWGLWjvAe2dTpSxdMLfEuofwQB8+lU/srzUpCwZJOWSlc52Q8XC652BUNmO+oY16gBwA==", "dependencies": { "@wry/caches": "^1.0.0", "@wry/context": "^0.7.0", diff --git a/package.json b/package.json index 13d023dea28..319095b931b 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "@wry/trie": "^0.4.3", "graphql-tag": "^2.12.6", "hoist-non-react-statics": "^3.3.2", - "optimism": "^0.18.0-pre.0", + "optimism": "^0.18.0-pre.1", "prop-types": "^15.7.2", "rehackt": "0.0.3", "response-iterator": "^0.2.6", diff --git a/src/utilities/graphql/DocumentTransform.ts b/src/utilities/graphql/DocumentTransform.ts index fc2e48aa47f..f963a42ed76 100644 --- a/src/utilities/graphql/DocumentTransform.ts +++ b/src/utilities/graphql/DocumentTransform.ts @@ -97,8 +97,8 @@ export class DocumentTransform { return stableCacheKeys.lookupArray(cacheKeys); } }, - /** TODO: decide on a maximum size (will do all max sizes in a combined separate PR) */ - cache: new WeakCache(1000, (entry) => entry.dispose()), + max: 1000 /** TODO: decide on a maximum size (will do all max sizes in a combined separate PR) */, + cache: WeakCache, } ); } From 8698dcd2ed2e07c59cfeed4262fdbfd5abd980fb Mon Sep 17 00:00:00 2001 From: Lenz Weber-Tronic Date: Fri, 1 Dec 2023 14:36:22 +0100 Subject: [PATCH 9/9] bump `optimism` --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index a750fdaa0ae..cfa6fda5720 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@wry/trie": "^0.5.0", "graphql-tag": "^2.12.6", "hoist-non-react-statics": "^3.3.2", - "optimism": "^0.18.0-pre.1", + "optimism": "^0.18.0", "prop-types": "^15.7.2", "rehackt": "0.0.3", "response-iterator": "^0.2.6", @@ -8944,9 +8944,9 @@ } }, "node_modules/optimism": { - "version": "0.18.0-pre.1", - "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.18.0-pre.1.tgz", - "integrity": "sha512-NRJCCIliZRc9ScJa9kGWGLWjvAe2dTpSxdMLfEuofwQB8+lU/srzUpCwZJOWSlc52Q8XC652BUNmO+oY16gBwA==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.18.0.tgz", + "integrity": "sha512-tGn8+REwLRNFnb9WmcY5IfpOqeX2kpaYJ1s6Ae3mn12AeydLkR3j+jSCmVQFoXqU8D41PAJ1RG1rCRNWmNZVmQ==", "dependencies": { "@wry/caches": "^1.0.0", "@wry/context": "^0.7.0", diff --git a/package.json b/package.json index 593f5817239..98dcb9ea4b0 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "@wry/trie": "^0.5.0", "graphql-tag": "^2.12.6", "hoist-non-react-statics": "^3.3.2", - "optimism": "^0.18.0-pre.1", + "optimism": "^0.18.0", "prop-types": "^15.7.2", "rehackt": "0.0.3", "response-iterator": "^0.2.6",