Skip to content

Commit 014770f

Browse files
committed
Use weakMap for private parts
1 parent 475ff2f commit 014770f

File tree

10 files changed

+349
-209
lines changed

10 files changed

+349
-209
lines changed

src/__tests__/client.ts

+5-3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import {
4545
} from "../testing";
4646
import { spyOnConsole } from "../testing/internal";
4747
import { waitFor } from "@testing-library/react";
48+
import { $ } from "../cache/inmemory/privates";
4849

4950
describe("client", () => {
5051
it("can be loaded via require", () => {
@@ -3525,7 +3526,8 @@ describe("@connection", () => {
35253526
const aResults = watch(aQuery);
35263527
const bResults = watch(bQuery);
35273528

3528-
expect(cache["watches"].size).toBe(2);
3529+
const watches = $(cache)["watches"];
3530+
expect(watches.size).toBe(2);
35293531

35303532
expect(aResults).toEqual([]);
35313533
expect(bResults).toEqual([]);
@@ -3543,10 +3545,10 @@ describe("@connection", () => {
35433545
expect(aResults).toEqual([]);
35443546
expect(bResults).toEqual([]);
35453547

3546-
expect(cache["watches"].size).toBe(0);
3548+
expect(watches.size).toBe(0);
35473549
const abResults = watch(abQuery);
35483550
expect(abResults).toEqual([]);
3549-
expect(cache["watches"].size).toBe(1);
3551+
expect(watches.size).toBe(1);
35503552

35513553
await wait();
35523554

src/__tests__/resultCacheCleaning.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { makeExecutableSchema } from "@graphql-tools/schema";
33
import { ApolloClient, Resolvers, gql } from "../core";
44
import { InMemoryCache, NormalizedCacheObject } from "../cache";
55
import { SchemaLink } from "../link/schema";
6+
import { $ } from "../cache/inmemory/privates";
67

78
describe("resultCache cleaning", () => {
89
const fragments = gql`
@@ -150,7 +151,7 @@ describe("resultCache cleaning", () => {
150151
});
151152

152153
afterEach(() => {
153-
const storeReader = (client.cache as InMemoryCache)["storeReader"];
154+
const { storeReader } = $(client.cache);
154155
expect(storeReader["executeSubSelectedArray"].size).toBeGreaterThan(0);
155156
expect(storeReader["executeSelectionSet"].size).toBeGreaterThan(0);
156157
client.cache.evict({

src/cache/core/cache.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ export abstract class ApolloCache<TSerialized> implements DataProxy {
273273

274274
// Make sure we compute the same (===) fragment query document every
275275
// time we receive the same fragment in readFragment.
276-
private getFragmentDoc = wrap(getFragmentQueryDocument, {
276+
getFragmentDoc = wrap(getFragmentQueryDocument, {
277277
max:
278278
cacheSizes["cache.fragmentQueryDocuments"] ||
279279
defaultCacheSizes["cache.fragmentQueryDocuments"],

src/cache/inmemory/__tests__/cache.ts

+36-28
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { ObjectCanon } from "../object-canon";
2020
import { TypePolicies } from "../policies";
2121
import { spyOnConsole } from "../../../testing/internal";
2222
import { defaultCacheSizes } from "../../../utilities";
23+
import { $ } from "../privates";
2324

2425
disableFragmentWarnings();
2526

@@ -1498,13 +1499,15 @@ describe("Cache", () => {
14981499
}
14991500
`;
15001501

1501-
const originalReader = cache["storeReader"];
1502+
const privates = $(cache);
1503+
1504+
const originalReader = privates.storeReader;
15021505
expect(originalReader).toBeInstanceOf(StoreReader);
15031506

1504-
const originalWriter = cache["storeWriter"];
1507+
const originalWriter = privates.storeWriter;
15051508
expect(originalWriter).toBeInstanceOf(StoreWriter);
15061509

1507-
const originalMBW = cache["maybeBroadcastWatch"];
1510+
const originalMBW = privates.maybeBroadcastWatch;
15081511
expect(typeof originalMBW).toBe("function");
15091512

15101513
const originalCanon = originalReader.canon;
@@ -1534,12 +1537,12 @@ describe("Cache", () => {
15341537
c: "see",
15351538
});
15361539

1537-
expect(originalReader).not.toBe(cache["storeReader"]);
1538-
expect(originalWriter).not.toBe(cache["storeWriter"]);
1539-
expect(originalMBW).not.toBe(cache["maybeBroadcastWatch"]);
1540+
expect(originalReader).not.toBe(privates.storeReader);
1541+
expect(originalWriter).not.toBe(privates.storeWriter);
1542+
expect(originalMBW).not.toBe(privates.maybeBroadcastWatch);
15401543
// The cache.storeReader.canon is preserved by default, but can be dropped
15411544
// by passing resetResultIdentities:true to cache.gc.
1542-
expect(originalCanon).toBe(cache["storeReader"].canon);
1545+
expect(originalCanon).toBe(privates.storeReader.canon);
15431546
});
15441547
});
15451548

@@ -2122,10 +2125,11 @@ describe("Cache", () => {
21222125
describe("resultCacheMaxSize", () => {
21232126
it("uses default max size on caches if resultCacheMaxSize is not configured", () => {
21242127
const cache = new InMemoryCache();
2125-
expect(cache["maybeBroadcastWatch"].options.max).toBe(
2128+
const privates = $(cache);
2129+
expect(privates.maybeBroadcastWatch.options.max).toBe(
21262130
defaultCacheSizes["inMemoryCache.maybeBroadcastWatch"]
21272131
);
2128-
expect(cache["storeReader"]["executeSelectionSet"].options.max).toBe(
2132+
expect(privates.storeReader["executeSelectionSet"].options.max).toBe(
21292133
defaultCacheSizes["inMemoryCache.executeSelectionSet"]
21302134
);
21312135
expect(cache["getFragmentDoc"].options.max).toBe(
@@ -2136,8 +2140,9 @@ describe("resultCacheMaxSize", () => {
21362140
it("configures max size on caches when resultCacheMaxSize is set", () => {
21372141
const resultCacheMaxSize = 12345;
21382142
const cache = new InMemoryCache({ resultCacheMaxSize });
2139-
expect(cache["maybeBroadcastWatch"].options.max).toBe(resultCacheMaxSize);
2140-
expect(cache["storeReader"]["executeSelectionSet"].options.max).toBe(
2143+
const privates = $(cache);
2144+
expect(privates.maybeBroadcastWatch.options.max).toBe(resultCacheMaxSize);
2145+
expect(privates.storeReader["executeSelectionSet"].options.max).toBe(
21412146
resultCacheMaxSize
21422147
);
21432148
expect(cache["getFragmentDoc"].options.max).toBe(
@@ -2400,7 +2405,7 @@ describe("InMemoryCache#broadcastWatches", function () {
24002405
[canonicalCache, nonCanonicalCache].forEach((cache) => {
24012406
// Hack: delete every watch.lastDiff, so subsequent results will be
24022407
// broadcast, even though they are deeply equal to the previous results.
2403-
cache["watches"].forEach((watch) => {
2408+
$(cache)["watches"].forEach((watch) => {
24042409
delete watch.lastDiff;
24052410
});
24062411
});
@@ -3813,19 +3818,20 @@ describe("ReactiveVar and makeVar", () => {
38133818

38143819
expect(diffs.length).toBe(5);
38153820

3816-
expect(cache["watches"].size).toBe(5);
3821+
const watches = $(cache)["watches"];
3822+
expect(watches.size).toBe(5);
38173823
expect(spy).not.toBeCalled();
38183824

38193825
unwatchers.pop()!();
3820-
expect(cache["watches"].size).toBe(4);
3826+
expect(watches.size).toBe(4);
38213827
expect(spy).not.toBeCalled();
38223828

38233829
unwatchers.shift()!();
3824-
expect(cache["watches"].size).toBe(3);
3830+
expect(watches.size).toBe(3);
38253831
expect(spy).not.toBeCalled();
38263832

38273833
unwatchers.pop()!();
3828-
expect(cache["watches"].size).toBe(2);
3834+
expect(watches.size).toBe(2);
38293835
expect(spy).not.toBeCalled();
38303836

38313837
expect(diffs.length).toBe(5);
@@ -3835,7 +3841,7 @@ describe("ReactiveVar and makeVar", () => {
38353841
expect(unwatchers.length).toBe(3);
38363842
unwatchers.forEach((unwatch) => unwatch());
38373843

3838-
expect(cache["watches"].size).toBe(0);
3844+
expect(watches.size).toBe(0);
38393845
expect(spy).toBeCalledTimes(1);
38403846
expect(spy).toBeCalledWith(cache);
38413847
});
@@ -3865,7 +3871,8 @@ describe("ReactiveVar and makeVar", () => {
38653871
watch("a");
38663872
watch("d");
38673873

3868-
expect(cache["watches"].size).toBe(5);
3874+
const watches = $(cache)["watches"];
3875+
expect(watches.size).toBe(5);
38693876
expect(diffCounts).toEqual({
38703877
a: 2,
38713878
b: 1,
@@ -3875,7 +3882,7 @@ describe("ReactiveVar and makeVar", () => {
38753882

38763883
unwatchers.a.forEach((unwatch) => unwatch());
38773884
unwatchers.a.length = 0;
3878-
expect(cache["watches"].size).toBe(3);
3885+
expect(watches.size).toBe(3);
38793886

38803887
nameVar("Hugh");
38813888
expect(diffCounts).toEqual({
@@ -3886,7 +3893,7 @@ describe("ReactiveVar and makeVar", () => {
38863893
});
38873894

38883895
cache.reset({ discardWatches: true });
3889-
expect(cache["watches"].size).toBe(0);
3896+
expect(watches.size).toBe(0);
38903897

38913898
expect(diffCounts).toEqual({
38923899
a: 2,
@@ -3926,7 +3933,7 @@ describe("ReactiveVar and makeVar", () => {
39263933
});
39273934

39283935
nameVar("Trevor");
3929-
expect(cache["watches"].size).toBe(2);
3936+
expect(watches.size).toBe(2);
39303937
expect(diffCounts).toEqual({
39313938
a: 2,
39323939
b: 2,
@@ -3937,7 +3944,7 @@ describe("ReactiveVar and makeVar", () => {
39373944
});
39383945

39393946
cache.reset({ discardWatches: true });
3940-
expect(cache["watches"].size).toBe(0);
3947+
expect(watches.size).toBe(0);
39413948

39423949
nameVar("Danielle");
39433950
expect(diffCounts).toEqual({
@@ -3949,7 +3956,7 @@ describe("ReactiveVar and makeVar", () => {
39493956
f: 2,
39503957
});
39513958

3952-
expect(cache["watches"].size).toBe(0);
3959+
expect(watches.size).toBe(0);
39533960
});
39543961

39553962
it("should recall forgotten vars once cache has watches again", () => {
@@ -3974,22 +3981,23 @@ describe("ReactiveVar and makeVar", () => {
39743981
expect(diffs.length).toBe(3);
39753982
expect(names()).toEqual(["Ben", "Ben", "Ben"]);
39763983

3977-
expect(cache["watches"].size).toBe(3);
3984+
const watches = $(cache)["watches"];
3985+
expect(watches.size).toBe(3);
39783986
expect(spy).not.toBeCalled();
39793987

39803988
unwatchers.pop()!();
3981-
expect(cache["watches"].size).toBe(2);
3989+
expect(watches.size).toBe(2);
39823990
expect(spy).not.toBeCalled();
39833991

39843992
unwatchers.shift()!();
3985-
expect(cache["watches"].size).toBe(1);
3993+
expect(watches.size).toBe(1);
39863994
expect(spy).not.toBeCalled();
39873995

39883996
nameVar("Hugh");
39893997
expect(names()).toEqual(["Ben", "Ben", "Ben", "Hugh"]);
39903998

39913999
unwatchers.pop()!();
3992-
expect(cache["watches"].size).toBe(0);
4000+
expect(watches.size).toBe(0);
39934001
expect(spy).toBeCalledTimes(1);
39944002
expect(spy).toBeCalledWith(cache);
39954003

@@ -3999,7 +4007,7 @@ describe("ReactiveVar and makeVar", () => {
39994007

40004008
// Call watch(false) to avoid immediate delivery of the "ignored" name.
40014009
unwatchers.push(watch(false));
4002-
expect(cache["watches"].size).toBe(1);
4010+
expect(watches.size).toBe(1);
40034011
expect(names()).toEqual(["Ben", "Ben", "Ben", "Hugh"]);
40044012

40054013
// This is the test that would fail if cache.watch did not call

src/cache/inmemory/__tests__/entityStore.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { TypedDocumentNode } from "@graphql-typed-document-node/core";
1616
import { stringifyForDisplay } from "../../../utilities";
1717
import { InvariantError } from "../../../utilities/globals";
1818
import { spyOnConsole } from "../../../testing/internal";
19+
import { $ } from "../privates";
1920

2021
describe("EntityStore", () => {
2122
it("should support result caching if so configured", () => {
@@ -220,13 +221,14 @@ describe("EntityStore", () => {
220221

221222
// Nothing left to collect, but let's also reset the result cache to
222223
// demonstrate that the recomputed cache results are unchanged.
223-
const originalReader = cache["storeReader"];
224+
const { storeReader } = $(cache);
225+
const originalReader = storeReader;
224226
expect(
225227
cache.gc({
226228
resetResultCache: true,
227229
})
228230
).toEqual([]);
229-
expect(cache["storeReader"]).not.toBe(originalReader);
231+
expect(storeReader).not.toBe(originalReader);
230232
const resultAfterResetResultCache = read();
231233
expect(resultAfterResetResultCache).toBe(resultBeforeGC);
232234
expect(resultAfterResetResultCache).toBe(resultAfterGC);
@@ -1000,7 +1002,7 @@ describe("EntityStore", () => {
10001002
expect(cache.gc()).toEqual([]);
10011003

10021004
const willId = cache.identify(data.parent)!;
1003-
const store = cache["data"];
1005+
const { data: store } = $(cache);
10041006
const storeRootData = store["data"];
10051007
// Hacky way of injecting a stray __ref field into the Will Smith Person
10061008
// object, clearing store.refs (which was populated by the previous GC).
@@ -2675,7 +2677,7 @@ describe("EntityStore", () => {
26752677
},
26762678
});
26772679

2678-
const store = cache["data"];
2680+
const { data: store } = $(cache);
26792681

26802682
const query = gql`
26812683
query Book($isbn: string) {

src/cache/inmemory/__tests__/readFromStore.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
TypedDocumentNode,
1919
} from "../../../core";
2020
import { defaultCacheSizes } from "../../../utilities";
21+
import { $ } from "../privates";
2122

2223
describe("resultCacheMaxSize", () => {
2324
const cache = new InMemoryCache();
@@ -2207,7 +2208,8 @@ describe("reading from the store", () => {
22072208
},
22082209
});
22092210

2210-
const canon = cache["storeReader"].canon;
2211+
const { storeReader } = $(cache);
2212+
const canon = storeReader.canon;
22112213

22122214
const query = gql`
22132215
query {
@@ -2263,7 +2265,8 @@ describe("reading from the store", () => {
22632265
},
22642266
});
22652267

2266-
const canon = cache["storeReader"].canon;
2268+
const { storeReader } = $(cache);
2269+
const canon = storeReader.canon;
22672270

22682271
const fragment = gql`
22692272
fragment CountFragment on Query {

0 commit comments

Comments
 (0)