From cfc8fdfad06c05676b38bc89f0b0ef2f2c518d0d Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Wed, 19 Dec 2018 12:35:52 -0500 Subject: [PATCH] Allow disabling InMemoryCache result caching. Although this is a rather drastic option, creating an InMemoryCache that does not attempt to cache previous results may help reduce memory usage, at the expense of cache performance on repeated reads: new InMemoryCache({ resultCaching: false, // defaults to true }) See this comment by @barbalex for one such situation: https://github.com/apollographql/apollo-client/issues/4210#issuecomment-446366207 At the very least, this option should help diagnose problems with result caching, even if it's not the right long-term solution. --- .../src/__tests__/__snapshots__/cache.ts.snap | 146 ++++++- .../__tests__/__snapshots__/mapCache.ts.snap | 150 ++++++- .../src/__tests__/cache.ts | 405 ++++++++---------- .../src/inMemoryCache.ts | 18 +- packages/apollo-cache-inmemory/src/index.ts | 7 +- 5 files changed, 463 insertions(+), 263 deletions(-) diff --git a/packages/apollo-cache-inmemory/src/__tests__/__snapshots__/cache.ts.snap b/packages/apollo-cache-inmemory/src/__tests__/__snapshots__/cache.ts.snap index 08cc1a7e210..0cd8b06df71 100644 --- a/packages/apollo-cache-inmemory/src/__tests__/__snapshots__/cache.ts.snap +++ b/packages/apollo-cache-inmemory/src/__tests__/__snapshots__/cache.ts.snap @@ -1,8 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[ - `Cache writeFragment will write some deeply nested data into the store at any id 1` -] = ` +exports[`Cache writeFragment will write some deeply nested data into the store at any id (1/2) 1`] = ` Object { "bar": Object { "i": 7, @@ -19,9 +17,7 @@ Object { } `; -exports[ - `Cache writeFragment will write some deeply nested data into the store at any id 2` -] = ` +exports[`Cache writeFragment will write some deeply nested data into the store at any id (1/2) 2`] = ` Object { "bar": Object { "i": 7, @@ -42,9 +38,7 @@ Object { } `; -exports[ - `Cache writeFragment will write some deeply nested data into the store at any id 3` -] = ` +exports[`Cache writeFragment will write some deeply nested data into the store at any id (1/2) 3`] = ` Object { "bar": Object { "i": 10, @@ -65,9 +59,7 @@ Object { } `; -exports[ - `Cache writeFragment will write some deeply nested data into the store at any id 4` -] = ` +exports[`Cache writeFragment will write some deeply nested data into the store at any id (1/2) 4`] = ` Object { "bar": Object { "i": 10, @@ -88,9 +80,7 @@ Object { } `; -exports[ - `Cache writeFragment will write some deeply nested data into the store at any id 5` -] = ` +exports[`Cache writeFragment will write some deeply nested data into the store at any id (1/2) 5`] = ` Object { "bar": Object { "i": 7, @@ -111,9 +101,129 @@ Object { } `; -exports[ - `Cache writeFragment will write some deeply nested data into the store at any id 6` -] = ` +exports[`Cache writeFragment will write some deeply nested data into the store at any id (1/2) 6`] = ` +Object { + "bar": Object { + "i": 10, + "j": 11, + "k": 12, + }, + "foo": Object { + "e": 4, + "f": 5, + "g": 6, + "h": Object { + "generated": false, + "id": "bar", + "type": "id", + "typename": "Bar", + }, + }, +} +`; + +exports[`Cache writeFragment will write some deeply nested data into the store at any id (2/2) 1`] = ` +Object { + "bar": Object { + "i": 7, + }, + "foo": Object { + "e": 4, + "h": Object { + "generated": false, + "id": "bar", + "type": "id", + "typename": undefined, + }, + }, +} +`; + +exports[`Cache writeFragment will write some deeply nested data into the store at any id (2/2) 2`] = ` +Object { + "bar": Object { + "i": 7, + "j": 8, + "k": 9, + }, + "foo": Object { + "e": 4, + "f": 5, + "g": 6, + "h": Object { + "generated": false, + "id": "bar", + "type": "id", + "typename": undefined, + }, + }, +} +`; + +exports[`Cache writeFragment will write some deeply nested data into the store at any id (2/2) 3`] = ` +Object { + "bar": Object { + "i": 10, + "j": 8, + "k": 9, + }, + "foo": Object { + "e": 4, + "f": 5, + "g": 6, + "h": Object { + "generated": false, + "id": "bar", + "type": "id", + "typename": undefined, + }, + }, +} +`; + +exports[`Cache writeFragment will write some deeply nested data into the store at any id (2/2) 4`] = ` +Object { + "bar": Object { + "i": 10, + "j": 11, + "k": 12, + }, + "foo": Object { + "e": 4, + "f": 5, + "g": 6, + "h": Object { + "generated": false, + "id": "bar", + "type": "id", + "typename": undefined, + }, + }, +} +`; + +exports[`Cache writeFragment will write some deeply nested data into the store at any id (2/2) 5`] = ` +Object { + "bar": Object { + "i": 7, + "j": 8, + "k": 9, + }, + "foo": Object { + "e": 4, + "f": 5, + "g": 6, + "h": Object { + "generated": false, + "id": "bar", + "type": "id", + "typename": "Bar", + }, + }, +} +`; + +exports[`Cache writeFragment will write some deeply nested data into the store at any id (2/2) 6`] = ` Object { "bar": Object { "i": 10, diff --git a/packages/apollo-cache-inmemory/src/__tests__/__snapshots__/mapCache.ts.snap b/packages/apollo-cache-inmemory/src/__tests__/__snapshots__/mapCache.ts.snap index d644838f32c..0ff0bd5d836 100644 --- a/packages/apollo-cache-inmemory/src/__tests__/__snapshots__/mapCache.ts.snap +++ b/packages/apollo-cache-inmemory/src/__tests__/__snapshots__/mapCache.ts.snap @@ -1,8 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[ - `MapCache Cache writeFragment will write some deeply nested data into the store at any id 1` -] = ` +exports[`MapCache Cache writeFragment will write some deeply nested data into the store at any id (1/2) 1`] = ` Object { "bar": Object { "i": 7, @@ -19,9 +17,7 @@ Object { } `; -exports[ - `MapCache Cache writeFragment will write some deeply nested data into the store at any id 2` -] = ` +exports[`MapCache Cache writeFragment will write some deeply nested data into the store at any id (1/2) 2`] = ` Object { "bar": Object { "i": 7, @@ -42,9 +38,7 @@ Object { } `; -exports[ - `MapCache Cache writeFragment will write some deeply nested data into the store at any id 3` -] = ` +exports[`MapCache Cache writeFragment will write some deeply nested data into the store at any id (1/2) 3`] = ` Object { "bar": Object { "i": 10, @@ -65,9 +59,7 @@ Object { } `; -exports[ - `MapCache Cache writeFragment will write some deeply nested data into the store at any id 4` -] = ` +exports[`MapCache Cache writeFragment will write some deeply nested data into the store at any id (1/2) 4`] = ` Object { "bar": Object { "i": 10, @@ -88,9 +80,7 @@ Object { } `; -exports[ - `MapCache Cache writeFragment will write some deeply nested data into the store at any id 5` -] = ` +exports[`MapCache Cache writeFragment will write some deeply nested data into the store at any id (1/2) 5`] = ` Object { "bar": Object { "i": 7, @@ -111,9 +101,7 @@ Object { } `; -exports[ - `MapCache Cache writeFragment will write some deeply nested data into the store at any id 6` -] = ` +exports[`MapCache Cache writeFragment will write some deeply nested data into the store at any id (1/2) 6`] = ` Object { "bar": Object { "i": 10, @@ -134,9 +122,129 @@ Object { } `; -exports[ - `MapCache writing to the store throws when trying to write an object without id that was previously queried with id 1` -] = ` +exports[`MapCache Cache writeFragment will write some deeply nested data into the store at any id (2/2) 1`] = ` +Object { + "bar": Object { + "i": 7, + }, + "foo": Object { + "e": 4, + "h": Object { + "generated": false, + "id": "bar", + "type": "id", + "typename": undefined, + }, + }, +} +`; + +exports[`MapCache Cache writeFragment will write some deeply nested data into the store at any id (2/2) 2`] = ` +Object { + "bar": Object { + "i": 7, + "j": 8, + "k": 9, + }, + "foo": Object { + "e": 4, + "f": 5, + "g": 6, + "h": Object { + "generated": false, + "id": "bar", + "type": "id", + "typename": undefined, + }, + }, +} +`; + +exports[`MapCache Cache writeFragment will write some deeply nested data into the store at any id (2/2) 3`] = ` +Object { + "bar": Object { + "i": 10, + "j": 8, + "k": 9, + }, + "foo": Object { + "e": 4, + "f": 5, + "g": 6, + "h": Object { + "generated": false, + "id": "bar", + "type": "id", + "typename": undefined, + }, + }, +} +`; + +exports[`MapCache Cache writeFragment will write some deeply nested data into the store at any id (2/2) 4`] = ` +Object { + "bar": Object { + "i": 10, + "j": 11, + "k": 12, + }, + "foo": Object { + "e": 4, + "f": 5, + "g": 6, + "h": Object { + "generated": false, + "id": "bar", + "type": "id", + "typename": undefined, + }, + }, +} +`; + +exports[`MapCache Cache writeFragment will write some deeply nested data into the store at any id (2/2) 5`] = ` +Object { + "bar": Object { + "i": 7, + "j": 8, + "k": 9, + }, + "foo": Object { + "e": 4, + "f": 5, + "g": 6, + "h": Object { + "generated": false, + "id": "bar", + "type": "id", + "typename": "Bar", + }, + }, +} +`; + +exports[`MapCache Cache writeFragment will write some deeply nested data into the store at any id (2/2) 6`] = ` +Object { + "bar": Object { + "i": 10, + "j": 11, + "k": 12, + }, + "foo": Object { + "e": 4, + "f": 5, + "g": 6, + "h": Object { + "generated": false, + "id": "bar", + "type": "id", + "typename": "Bar", + }, + }, +} +`; + +exports[`MapCache writing to the store throws when trying to write an object without id that was previously queried with id 1`] = ` "Error writing result to store for query: query Failure { item { diff --git a/packages/apollo-cache-inmemory/src/__tests__/cache.ts b/packages/apollo-cache-inmemory/src/__tests__/cache.ts index 0cd4f2cc631..f0cb6e27ed1 100644 --- a/packages/apollo-cache-inmemory/src/__tests__/cache.ts +++ b/packages/apollo-cache-inmemory/src/__tests__/cache.ts @@ -3,39 +3,66 @@ import gql, { disableFragmentWarnings } from 'graphql-tag'; import { stripSymbols } from 'apollo-utilities'; import { cloneDeep } from 'lodash'; -import { InMemoryCache, ApolloReducerConfig, NormalizedCache } from '..'; +import { InMemoryCache, InMemoryCacheConfig, NormalizedCache } from '..'; disableFragmentWarnings(); describe('Cache', () => { - function createCache({ - initialState, - config, - }: { - initialState?: any; - config?: ApolloReducerConfig; - } = {}): ApolloCache { - return new InMemoryCache( - config || { addTypename: false }, - // XXX this is the old format. The tests need to be updated but since it is mapped down - ).restore(initialState ? initialState.apollo.data : {}); + function itWithInitialData( + message: string, + initialDataForCaches: ({ [key: string]: any })[], + callback: (...caches: InMemoryCache[]) => any, + ) { + const cachesList: InMemoryCache[][] = [ + initialDataForCaches.map( + data => new InMemoryCache({ + addTypename: false, + }).restore(cloneDeep(data)) + ), + initialDataForCaches.map( + data => new InMemoryCache({ + addTypename: false, + resultCaching: false, + }).restore(cloneDeep(data)) + ), + ]; + + cachesList.forEach((caches, i) => { + it(message + ` (${i+1}/${cachesList.length})`, () => callback(...caches)); + }); + } + + function itWithCacheConfig( + message: string, + config: InMemoryCacheConfig, + callback: (cache: InMemoryCache) => any, + ) { + const caches = [ + new InMemoryCache({ + addTypename: false, + ...config, + resultCaching: true, + }), + new InMemoryCache({ + addTypename: false, + ...config, + resultCaching: false, + }), + ]; + + caches.forEach((cache, i) => { + it(message + ` (${i+1}/${caches.length})`, () => callback(cache)); + }); } describe('readQuery', () => { - it('will read some data from the store', () => { - const proxy = createCache({ - initialState: { - apollo: { - data: { - ROOT_QUERY: { - a: 1, - b: 2, - c: 3, - }, - }, - }, - }, - }); + itWithInitialData('will read some data from the store', [{ + ROOT_QUERY: { + a: 1, + b: 2, + c: 3, + }, + }], proxy => { expect( stripSymbols( proxy.readQuery({ @@ -74,41 +101,33 @@ describe('Cache', () => { ).toEqual({ a: 1, b: 2, c: 3 }); }); - it('will read some deeply nested data from the store', () => { - const proxy = createCache({ - initialState: { - apollo: { - data: { - ROOT_QUERY: { - a: 1, - b: 2, - c: 3, - d: { - type: 'id', - id: 'foo', - generated: false, - }, - }, - foo: { - e: 4, - f: 5, - g: 6, - h: { - type: 'id', - id: 'bar', - generated: false, - }, - }, - bar: { - i: 7, - j: 8, - k: 9, - }, - }, - }, + itWithInitialData('will read some deeply nested data from the store', [{ + ROOT_QUERY: { + a: 1, + b: 2, + c: 3, + d: { + type: 'id', + id: 'foo', + generated: false, }, - }); - + }, + foo: { + e: 4, + f: 5, + g: 6, + h: { + type: 'id', + id: 'bar', + generated: false, + }, + }, + bar: { + i: 7, + j: 8, + k: 9, + }, + }], proxy => { expect( stripSymbols( proxy.readQuery({ @@ -170,20 +189,12 @@ describe('Cache', () => { }); }); - it('will read some data from the store with variables', () => { - const proxy = createCache({ - initialState: { - apollo: { - data: { - ROOT_QUERY: { - 'field({"literal":true,"value":42})': 1, - 'field({"literal":false,"value":42})': 2, - }, - }, - }, - }, - }); - + itWithInitialData('will read some data from the store with variables', [{ + ROOT_QUERY: { + 'field({"literal":true,"value":42})': 1, + 'field({"literal":false,"value":42})': 2, + }, + }], proxy => { expect( stripSymbols( proxy.readQuery({ @@ -202,19 +213,11 @@ describe('Cache', () => { ).toEqual({ a: 1, b: 2 }); }); - it('will read some data from the store with null variables', () => { - const proxy = createCache({ - initialState: { - apollo: { - data: { - ROOT_QUERY: { - 'field({"literal":false,"value":null})': 1, - }, - }, - }, - }, - }); - + itWithInitialData('will read some data from the store with null variables', [{ + ROOT_QUERY: { + 'field({"literal":false,"value":null})': 1, + }, + }], proxy => { expect( stripSymbols( proxy.readQuery({ @@ -232,20 +235,12 @@ describe('Cache', () => { ).toEqual({ a: 1 }); }); - it('should not mutate arguments passed in', () => { - const proxy = createCache({ - initialState: { - apollo: { - data: { - ROOT_QUERY: { - 'field({"literal":true,"value":42})': 1, - 'field({"literal":false,"value":42})': 2, - }, - }, - }, - }, - }); - + itWithInitialData('should not mutate arguments passed in', [{ + ROOT_QUERY: { + 'field({"literal":true,"value":42})': 1, + 'field({"literal":false,"value":42})': 2, + }, + }], proxy => { const options = { query: gql` query($literal: Boolean, $value: Int) { @@ -266,9 +261,10 @@ describe('Cache', () => { }); describe('readFragment', () => { - it('will throw an error when there is no fragment', () => { - const proxy = createCache(); - + itWithInitialData('will throw an error when there is no fragment', [ + // Empty data, but still want to test with/without result caching. + {}, + ], proxy => { expect(() => { proxy.readFragment({ id: 'x', @@ -297,9 +293,9 @@ describe('Cache', () => { ); }); - it('will throw an error when there is more than one fragment but no fragment name', () => { - const proxy = createCache(); - + itWithInitialData('will throw an error when there is more than one fragment but no fragment name', [ + {}, + ], proxy => { expect(() => { proxy.readFragment({ id: 'x', @@ -338,44 +334,36 @@ describe('Cache', () => { ); }); - it('will read some deeply nested data from the store at any id', () => { - const proxy = createCache({ - initialState: { - apollo: { - data: { - ROOT_QUERY: { - __typename: 'Type1', - a: 1, - b: 2, - c: 3, - d: { - type: 'id', - id: 'foo', - generated: false, - }, - }, - foo: { - __typename: 'Foo', - e: 4, - f: 5, - g: 6, - h: { - type: 'id', - id: 'bar', - generated: false, - }, - }, - bar: { - __typename: 'Bar', - i: 7, - j: 8, - k: 9, - }, - }, - }, + itWithInitialData('will read some deeply nested data from the store at any id', [{ + ROOT_QUERY: { + __typename: 'Type1', + a: 1, + b: 2, + c: 3, + d: { + type: 'id', + id: 'foo', + generated: false, }, - }); - + }, + foo: { + __typename: 'Foo', + e: 4, + f: 5, + g: 6, + h: { + type: 'id', + id: 'bar', + generated: false, + }, + }, + bar: { + __typename: 'Bar', + i: 7, + j: 8, + k: 9, + }, + }], proxy => { expect( stripSymbols( proxy.readFragment({ @@ -490,21 +478,13 @@ describe('Cache', () => { ).toEqual({ i: 7, j: 8, k: 9 }); }); - it('will read some data from the store with variables', () => { - const proxy = createCache({ - initialState: { - apollo: { - data: { - foo: { - __typename: 'Foo', - 'field({"literal":true,"value":42})': 1, - 'field({"literal":false,"value":42})': 2, - }, - }, - }, - }, - }); - + itWithInitialData('will read some data from the store with variables', [{ + foo: { + __typename: 'Foo', + 'field({"literal":true,"value":42})': 1, + 'field({"literal":false,"value":42})': 2, + }, + }], proxy => { expect( stripSymbols( proxy.readFragment({ @@ -524,27 +504,18 @@ describe('Cache', () => { ).toEqual({ a: 1, b: 2 }); }); - it('will return null when an id that can’t be found is provided', () => { - const client1 = createCache(); - const client2 = createCache({ - initialState: { - apollo: { - data: { - bar: { __typename: 'Bar', a: 1, b: 2, c: 3 }, - }, - }, - }, - }); - const client3 = createCache({ - initialState: { - apollo: { - data: { - foo: { __typename: 'Foo', a: 1, b: 2, c: 3 }, - }, - }, - }, - }); - + itWithInitialData('will return null when an id that can’t be found is provided', [ + // client1 + {}, + // client2 + { + bar: { __typename: 'Bar', a: 1, b: 2, c: 3 }, + }, + // client3 + { + foo: { __typename: 'Foo', a: 1, b: 2, c: 3 }, + }, + ], (client1, client2, client3) => { expect( stripSymbols( client1.readFragment({ @@ -591,9 +562,9 @@ describe('Cache', () => { }); describe('writeQuery', () => { - it('will write some data to the store', () => { - const proxy = createCache(); - + itWithInitialData('will write some data to the store', [ + {} + ], proxy => { proxy.writeQuery({ data: { a: 1 }, query: gql` @@ -647,9 +618,9 @@ describe('Cache', () => { }); }); - it('will write some deeply nested data to the store', () => { - const proxy = createCache(); - + itWithInitialData('will write some deeply nested data to the store', [ + {} + ], proxy => { proxy.writeQuery({ data: { a: 1, d: { e: 4 } }, query: gql` @@ -767,9 +738,9 @@ describe('Cache', () => { }); }); - it('will write some data to the store with variables', () => { - const proxy = createCache(); - + itWithInitialData('will write some data to the store with variables', [ + {}, + ], proxy => { proxy.writeQuery({ data: { a: 1, @@ -794,9 +765,10 @@ describe('Cache', () => { }, }); }); - it('will write some data to the store with variables where some are null', () => { - const proxy = createCache(); + itWithInitialData('will write some data to the store with variables where some are null', [ + {} + ], proxy => { proxy.writeQuery({ data: { a: 1, @@ -824,9 +796,9 @@ describe('Cache', () => { }); describe('writeFragment', () => { - it('will throw an error when there is no fragment', () => { - const proxy = createCache(); - + itWithInitialData('will throw an error when there is no fragment', [ + {}, + ], proxy => { expect(() => { proxy.writeFragment({ data: {}, @@ -857,9 +829,9 @@ describe('Cache', () => { ); }); - it('will throw an error when there is more than one fragment but no fragment name', () => { - const proxy = createCache(); - + itWithInitialData('will throw an error when there is more than one fragment but no fragment name', [ + {} + ], proxy => { expect(() => { proxy.writeFragment({ data: {}, @@ -900,11 +872,10 @@ describe('Cache', () => { ); }); - it('will write some deeply nested data into the store at any id', () => { - const proxy = createCache({ - config: { dataIdFromObject: (o: any) => o.id, addTypename: false }, - }); - + itWithCacheConfig('will write some deeply nested data into the store at any id', { + dataIdFromObject: (o: any) => o.id, + addTypename: false, + }, proxy => { proxy.writeFragment({ data: { __typename: 'Foo', e: 4, h: { id: 'bar', i: 7 } }, id: 'foo', @@ -1019,10 +990,10 @@ describe('Cache', () => { expect((proxy as InMemoryCache).extract()).toMatchSnapshot(); }); - it('writes data that can be read back', () => { - const proxy = createCache({ - config: { addTypename: true }, - }); + + itWithCacheConfig('writes data that can be read back', { + addTypename: true, + }, proxy => { const readWriteFragment = gql` fragment aFragment on query { getSomething { @@ -1047,11 +1018,9 @@ describe('Cache', () => { expect(stripSymbols(result)).toEqual(data); }); - it('will write some data to the store with variables', () => { - const proxy = createCache({ - config: { addTypename: true }, - }); - + itWithCacheConfig('will write some data to the store with variables', { + addTypename: true, + }, proxy => { proxy.writeFragment({ data: { a: 1, @@ -1082,9 +1051,9 @@ describe('Cache', () => { }); describe('performTransaction', () => { - it('will not broadcast mid-transaction', () => { - const cache = createCache(); - + itWithInitialData('will not broadcast mid-transaction', [ + {}, + ], cache => { let numBroadcasts = 0; const query = gql` @@ -1130,9 +1099,9 @@ describe('Cache', () => { }); describe('performOptimisticTransaction', () => { - it('will only broadcast once', () => { - const cache = createCache(); - + itWithInitialData('will only broadcast once', [ + {}, + ], cache => { let numBroadcasts = 0; const query = gql` @@ -1171,7 +1140,7 @@ describe('Cache', () => { }); expect(numBroadcasts).toEqual(0); - }, 1); + }, 1 as any); expect(numBroadcasts).toEqual(1); }); diff --git a/packages/apollo-cache-inmemory/src/inMemoryCache.ts b/packages/apollo-cache-inmemory/src/inMemoryCache.ts index 9515a0b9e06..41dd5ade92d 100644 --- a/packages/apollo-cache-inmemory/src/inMemoryCache.ts +++ b/packages/apollo-cache-inmemory/src/inMemoryCache.ts @@ -21,15 +21,21 @@ import { import { StoreReader } from './readFromStore'; import { StoreWriter } from './writeToStore'; -import { defaultNormalizedCacheFactory, DepTrackingCache } from './depTrackingCache'; +import { DepTrackingCache } from './depTrackingCache'; import { wrap, CacheKeyNode, OptimisticWrapperFunction } from './optimism'; import { ObjectCache } from './objectCache'; import { record } from './recordingCache'; -const defaultConfig: ApolloReducerConfig = { + +export interface InMemoryCacheConfig extends ApolloReducerConfig { + resultCaching?: boolean; +} + +const defaultConfig: InMemoryCacheConfig = { fragmentMatcher: new HeuristicFragmentMatcher(), dataIdFromObject: defaultDataIdFromObject, addTypename: true, + resultCaching: true, }; export function defaultDataIdFromObject(result: any): string | null { @@ -46,7 +52,7 @@ export function defaultDataIdFromObject(result: any): string | null { export class InMemoryCache extends ApolloCache { protected data: NormalizedCache; - protected config: ApolloReducerConfig; + protected config: InMemoryCacheConfig; protected optimistic: OptimisticStoreItem[] = []; private watches = new Set(); private addTypename: boolean; @@ -59,7 +65,7 @@ export class InMemoryCache extends ApolloCache { // don't forget to turn it back on! private silenceBroadcast: boolean = false; - constructor(config: ApolloReducerConfig = {}) { + constructor(config: InMemoryCacheConfig = {}) { super(); this.config = { ...defaultConfig, ...config }; @@ -79,7 +85,9 @@ export class InMemoryCache extends ApolloCache { } this.addTypename = this.config.addTypename; - this.data = defaultNormalizedCacheFactory(); + this.data = this.config.resultCaching + ? new DepTrackingCache() + : new ObjectCache(); this.storeReader = new StoreReader(this.cacheKeyRoot); this.storeWriter = new StoreWriter(); diff --git a/packages/apollo-cache-inmemory/src/index.ts b/packages/apollo-cache-inmemory/src/index.ts index 5ef7f2df296..d3e1779cb8b 100644 --- a/packages/apollo-cache-inmemory/src/index.ts +++ b/packages/apollo-cache-inmemory/src/index.ts @@ -1,4 +1,9 @@ -export { InMemoryCache, defaultDataIdFromObject } from './inMemoryCache'; +export { + InMemoryCache, + InMemoryCacheConfig, + defaultDataIdFromObject, +} from './inMemoryCache'; + export * from './readFromStore'; export * from './writeToStore'; export * from './fragmentMatcher';