Skip to content

Commit

Permalink
documentTransform: use optimism and WeakCache (#11389)
Browse files Browse the repository at this point in the history
  • Loading branch information
phryneas committed Dec 1, 2023
1 parent b1ff9c2 commit 139acd1
Show file tree
Hide file tree
Showing 14 changed files with 54 additions and 99 deletions.
5 changes: 0 additions & 5 deletions .api-reports/api-report-core.md
Expand Up @@ -558,11 +558,6 @@ export class DocumentTransform {
// (undocumented)
concat(otherTransform: DocumentTransform): DocumentTransform;
// (undocumented)
getStableCacheEntry(document: DocumentNode): {
key: DocumentTransformCacheKey;
value?: DocumentNode | undefined;
} | undefined;
// (undocumented)
static identity(): DocumentTransform;
resetCache(): void;
// (undocumented)
Expand Down
8 changes: 2 additions & 6 deletions .api-reports/api-report-react.md
Expand Up @@ -677,11 +677,6 @@ class DocumentTransform {
// (undocumented)
concat(otherTransform: DocumentTransform): DocumentTransform;
// (undocumented)
getStableCacheEntry(document: DocumentNode): {
key: DocumentTransformCacheKey;
value?: DocumentNode | undefined;
} | undefined;
// (undocumented)
static identity(): DocumentTransform;
resetCache(): void;
// (undocumented)
Expand All @@ -697,6 +692,8 @@ type DocumentTransformCacheKey = ReadonlyArray<unknown>;
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;
}
Expand Down Expand Up @@ -2224,7 +2221,6 @@ interface WatchQueryOptions<TVariables extends OperationVariables = OperationVar
// src/react/hooks/useBackgroundQuery.ts:26:3 - (ae-forgotten-export) The symbol "FetchMoreFunction" needs to be exported by the entry point index.d.ts
// src/react/hooks/useBackgroundQuery.ts:27:3 - (ae-forgotten-export) The symbol "RefetchFunction" needs to be exported by the entry point index.d.ts
// src/react/hooks/useLoadableQuery.ts:49:5 - (ae-forgotten-export) The symbol "ResetFunction" needs to be exported by the entry point index.d.ts
// src/utilities/graphql/DocumentTransform.ts:129:7 - (ae-forgotten-export) The symbol "DocumentTransformCacheKey" needs to be exported by the entry point index.d.ts

// (No @packageDocumentation comment for this package)

Expand Down
8 changes: 2 additions & 6 deletions .api-reports/api-report-react_components.md
Expand Up @@ -591,11 +591,6 @@ class DocumentTransform {
// (undocumented)
concat(otherTransform: DocumentTransform): DocumentTransform;
// (undocumented)
getStableCacheEntry(document: DocumentNode): {
key: DocumentTransformCacheKey;
value?: DocumentNode | undefined;
} | undefined;
// (undocumented)
static identity(): DocumentTransform;
resetCache(): void;
// (undocumented)
Expand All @@ -611,6 +606,8 @@ type DocumentTransformCacheKey = ReadonlyArray<unknown>;
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;
}
Expand Down Expand Up @@ -1689,7 +1686,6 @@ interface WatchQueryOptions<TVariables extends OperationVariables = OperationVar
// src/core/types.ts:174:3 - (ae-forgotten-export) The symbol "MutationQueryReducer" needs to be exported by the entry point index.d.ts
// src/core/types.ts:201:5 - (ae-forgotten-export) The symbol "Resolver" needs to be exported by the entry point index.d.ts
// src/core/watchQueryOptions.ts:253:2 - (ae-forgotten-export) The symbol "UpdateQueryFn" needs to be exported by the entry point index.d.ts
// src/utilities/graphql/DocumentTransform.ts:129:7 - (ae-forgotten-export) The symbol "DocumentTransformCacheKey" needs to be exported by the entry point index.d.ts

// (No @packageDocumentation comment for this package)

Expand Down
8 changes: 2 additions & 6 deletions .api-reports/api-report-react_context.md
Expand Up @@ -574,11 +574,6 @@ class DocumentTransform {
// (undocumented)
concat(otherTransform: DocumentTransform): DocumentTransform;
// (undocumented)
getStableCacheEntry(document: DocumentNode): {
key: DocumentTransformCacheKey;
value?: DocumentNode | undefined;
} | undefined;
// (undocumented)
static identity(): DocumentTransform;
resetCache(): void;
// (undocumented)
Expand All @@ -594,6 +589,8 @@ type DocumentTransformCacheKey = ReadonlyArray<unknown>;
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;
}
Expand Down Expand Up @@ -1585,7 +1582,6 @@ interface WatchQueryOptions<TVariables extends OperationVariables = OperationVar
// src/core/types.ts:174:3 - (ae-forgotten-export) The symbol "MutationQueryReducer" needs to be exported by the entry point index.d.ts
// src/core/types.ts:201:5 - (ae-forgotten-export) The symbol "Resolver" needs to be exported by the entry point index.d.ts
// src/core/watchQueryOptions.ts:253:2 - (ae-forgotten-export) The symbol "UpdateQueryFn" needs to be exported by the entry point index.d.ts
// src/utilities/graphql/DocumentTransform.ts:129:7 - (ae-forgotten-export) The symbol "DocumentTransformCacheKey" needs to be exported by the entry point index.d.ts

// (No @packageDocumentation comment for this package)

Expand Down
8 changes: 2 additions & 6 deletions .api-reports/api-report-react_hoc.md
Expand Up @@ -576,11 +576,6 @@ class DocumentTransform {
// (undocumented)
concat(otherTransform: DocumentTransform): DocumentTransform;
// (undocumented)
getStableCacheEntry(document: DocumentNode): {
key: DocumentTransformCacheKey;
value?: DocumentNode | undefined;
} | undefined;
// (undocumented)
static identity(): DocumentTransform;
resetCache(): void;
// (undocumented)
Expand All @@ -596,6 +591,8 @@ type DocumentTransformCacheKey = ReadonlyArray<unknown>;
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;
}
Expand Down Expand Up @@ -1630,7 +1627,6 @@ export function withSubscription<TProps extends TGraphQLVariables | {} = {}, TDa
// src/core/types.ts:174:3 - (ae-forgotten-export) The symbol "MutationQueryReducer" needs to be exported by the entry point index.d.ts
// src/core/types.ts:201:5 - (ae-forgotten-export) The symbol "Resolver" needs to be exported by the entry point index.d.ts
// src/core/watchQueryOptions.ts:253:2 - (ae-forgotten-export) The symbol "UpdateQueryFn" needs to be exported by the entry point index.d.ts
// src/utilities/graphql/DocumentTransform.ts:129:7 - (ae-forgotten-export) The symbol "DocumentTransformCacheKey" needs to be exported by the entry point index.d.ts

// (No @packageDocumentation comment for this package)

Expand Down
8 changes: 2 additions & 6 deletions .api-reports/api-report-react_hooks.md
Expand Up @@ -648,11 +648,6 @@ class DocumentTransform {
// (undocumented)
concat(otherTransform: DocumentTransform): DocumentTransform;
// (undocumented)
getStableCacheEntry(document: DocumentNode): {
key: DocumentTransformCacheKey;
value?: DocumentNode | undefined;
} | undefined;
// (undocumented)
static identity(): DocumentTransform;
resetCache(): void;
// (undocumented)
Expand All @@ -668,6 +663,8 @@ type DocumentTransformCacheKey = ReadonlyArray<unknown>;
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;
}
Expand Down Expand Up @@ -2115,7 +2112,6 @@ interface WatchQueryOptions<TVariables extends OperationVariables = OperationVar
// src/react/hooks/useBackgroundQuery.ts:26:3 - (ae-forgotten-export) The symbol "FetchMoreFunction" needs to be exported by the entry point index.d.ts
// src/react/hooks/useBackgroundQuery.ts:27:3 - (ae-forgotten-export) The symbol "RefetchFunction" needs to be exported by the entry point index.d.ts
// src/react/hooks/useLoadableQuery.ts:49:5 - (ae-forgotten-export) The symbol "ResetFunction" needs to be exported by the entry point index.d.ts
// src/utilities/graphql/DocumentTransform.ts:129:7 - (ae-forgotten-export) The symbol "DocumentTransformCacheKey" needs to be exported by the entry point index.d.ts

// (No @packageDocumentation comment for this package)

Expand Down
8 changes: 2 additions & 6 deletions .api-reports/api-report-react_ssr.md
Expand Up @@ -544,11 +544,6 @@ class DocumentTransform {
// (undocumented)
concat(otherTransform: DocumentTransform): DocumentTransform;
// (undocumented)
getStableCacheEntry(document: DocumentNode): {
key: DocumentTransformCacheKey;
value?: DocumentNode | undefined;
} | undefined;
// (undocumented)
static identity(): DocumentTransform;
resetCache(): void;
// (undocumented)
Expand All @@ -564,6 +559,8 @@ type DocumentTransformCacheKey = ReadonlyArray<unknown>;
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;
}
Expand Down Expand Up @@ -1571,7 +1568,6 @@ interface WatchQueryOptions<TVariables extends OperationVariables = OperationVar
// src/core/types.ts:174:3 - (ae-forgotten-export) The symbol "MutationQueryReducer" needs to be exported by the entry point index.d.ts
// src/core/types.ts:201:5 - (ae-forgotten-export) The symbol "Resolver" needs to be exported by the entry point index.d.ts
// src/core/watchQueryOptions.ts:253:2 - (ae-forgotten-export) The symbol "UpdateQueryFn" needs to be exported by the entry point index.d.ts
// src/utilities/graphql/DocumentTransform.ts:129:7 - (ae-forgotten-export) The symbol "DocumentTransformCacheKey" needs to be exported by the entry point index.d.ts

// (No @packageDocumentation comment for this package)

Expand Down
8 changes: 2 additions & 6 deletions .api-reports/api-report-testing.md
Expand Up @@ -538,11 +538,6 @@ class DocumentTransform {
// (undocumented)
concat(otherTransform: DocumentTransform): DocumentTransform;
// (undocumented)
getStableCacheEntry(document: DocumentNode): {
key: DocumentTransformCacheKey;
value?: DocumentNode | undefined;
} | undefined;
// (undocumented)
static identity(): DocumentTransform;
resetCache(): void;
// (undocumented)
Expand All @@ -558,6 +553,8 @@ type DocumentTransformCacheKey = ReadonlyArray<unknown>;
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;
}
Expand Down Expand Up @@ -1633,7 +1630,6 @@ export function withWarningSpy<TArgs extends any[], TResult>(it: (...args: TArgs
// src/core/types.ts:174:3 - (ae-forgotten-export) The symbol "MutationQueryReducer" needs to be exported by the entry point index.d.ts
// src/core/types.ts:201:5 - (ae-forgotten-export) The symbol "Resolver" needs to be exported by the entry point index.d.ts
// src/core/watchQueryOptions.ts:253:2 - (ae-forgotten-export) The symbol "UpdateQueryFn" needs to be exported by the entry point index.d.ts
// src/utilities/graphql/DocumentTransform.ts:129:7 - (ae-forgotten-export) The symbol "DocumentTransformCacheKey" needs to be exported by the entry point index.d.ts

// (No @packageDocumentation comment for this package)

Expand Down
8 changes: 2 additions & 6 deletions .api-reports/api-report-testing_core.md
Expand Up @@ -537,11 +537,6 @@ class DocumentTransform {
// (undocumented)
concat(otherTransform: DocumentTransform): DocumentTransform;
// (undocumented)
getStableCacheEntry(document: DocumentNode): {
key: DocumentTransformCacheKey;
value?: DocumentNode | undefined;
} | undefined;
// (undocumented)
static identity(): DocumentTransform;
resetCache(): void;
// (undocumented)
Expand All @@ -557,6 +552,8 @@ type DocumentTransformCacheKey = ReadonlyArray<unknown>;
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;
}
Expand Down Expand Up @@ -1590,7 +1587,6 @@ export function withWarningSpy<TArgs extends any[], TResult>(it: (...args: TArgs
// src/core/types.ts:174:3 - (ae-forgotten-export) The symbol "MutationQueryReducer" needs to be exported by the entry point index.d.ts
// src/core/types.ts:201:5 - (ae-forgotten-export) The symbol "Resolver" needs to be exported by the entry point index.d.ts
// src/core/watchQueryOptions.ts:253:2 - (ae-forgotten-export) The symbol "UpdateQueryFn" needs to be exported by the entry point index.d.ts
// src/utilities/graphql/DocumentTransform.ts:129:7 - (ae-forgotten-export) The symbol "DocumentTransformCacheKey" needs to be exported by the entry point index.d.ts

// (No @packageDocumentation comment for this package)

Expand Down
5 changes: 0 additions & 5 deletions .api-reports/api-report-utilities.md
Expand Up @@ -715,11 +715,6 @@ export class DocumentTransform {
// (undocumented)
concat(otherTransform: DocumentTransform): DocumentTransform;
// (undocumented)
getStableCacheEntry(document: DocumentNode): {
key: DocumentTransformCacheKey;
value?: DocumentNode | undefined;
} | undefined;
// (undocumented)
static identity(): DocumentTransform;
resetCache(): void;
// (undocumented)
Expand Down
5 changes: 0 additions & 5 deletions .api-reports/api-report.md
Expand Up @@ -701,11 +701,6 @@ export class DocumentTransform {
// (undocumented)
concat(otherTransform: DocumentTransform): DocumentTransform;
// (undocumented)
getStableCacheEntry(document: DocumentNode): {
key: DocumentTransformCacheKey;
value?: DocumentNode | undefined;
} | undefined;
// (undocumented)
static identity(): DocumentTransform;
resetCache(): void;
// (undocumented)
Expand Down
5 changes: 5 additions & 0 deletions .changeset/dirty-kids-crash.md
@@ -0,0 +1,5 @@
---
"@apollo/client": patch
---

`documentTransform`: use `optimism` and `WeakCache` instead of directly storing data on the `Trie`
4 changes: 2 additions & 2 deletions .size-limits.json
@@ -1,4 +1,4 @@
{
"dist/apollo-client.min.cjs": 38646,
"import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32304
"dist/apollo-client.min.cjs": 38632,
"import { ApolloClient, InMemoryCache, HttpLink } from \"dist/index.js\" (production)": 32319
}
65 changes: 31 additions & 34 deletions src/utilities/graphql/DocumentTransform.ts
Expand Up @@ -3,6 +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 { wrap } from "optimism";

export type DocumentTransformCacheKey = ReadonlyArray<unknown>;

Expand All @@ -21,14 +23,11 @@ function identity(document: DocumentNode) {

export class DocumentTransform {
private readonly transform: TransformFn;
private cached: boolean;

private readonly resultCache =
canUseWeakSet ? new WeakSet<DocumentNode>() : new Set<DocumentNode>();

private stableCacheKeys:
| Trie<{ key: DocumentTransformCacheKey; 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
Expand Down Expand Up @@ -73,18 +72,40 @@ export class DocumentTransform {
// Override default `getCacheKey` function, which returns [document].
this.getCacheKey = options.getCacheKey;
}
this.cached = options.cache !== false;

if (options.cache !== false) {
this.stableCacheKeys = new Trie(canUseWeakMap, (key) => ({ key }));
}
this.resetCache();
}

/**
* Resets the internal cache of this transform, if it has one.
*/
resetCache() {
this.stableCacheKeys =
this.stableCacheKeys && new Trie(canUseWeakMap, (key) => ({ key }));
if (this.cached) {
const stableCacheKeys = new Trie<WeakKey>(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: 1000 /** TODO: decide on a maximum size (will do all max sizes in a combined separate PR) */,
cache: WeakCache<any, any>,
}
);
}
}

private performWork(document: DocumentNode) {
checkDocument(document);
return this.transform(document);
}

transformDocument(document: DocumentNode) {
Expand All @@ -94,22 +115,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;
}

Expand All @@ -124,16 +133,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"
);
return this.stableCacheKeys.lookupArray(cacheKeys);
}
}
}

0 comments on commit 139acd1

Please sign in to comment.