Skip to content

Commit

Permalink
Avoid removing used generated data from cache
Browse files Browse the repository at this point in the history
  • Loading branch information
dferber90 committed May 7, 2018
1 parent 02304f4 commit 1b8d95b
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 102 deletions.
224 changes: 123 additions & 101 deletions packages/apollo-cache-inmemory/src/__tests__/writeToStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1882,174 +1882,196 @@ describe('writing to the store', () => {
});
});

it('should updated nested inlined array fields', () => {
it('should keep reference when type of mixed inlined field with changes', () => {
const store = defaultNormalizedCacheFactory();

const query = gql`
query {
shelter {
id
animals {
animals {
species {
name
species {
name
}
}
}
}
`;

const dataIdFromObject = (object: any) => {
if (object.__typename && object.id) {
return object.__typename + '__' + object.id;
}
return undefined;
};

writeQueryToStore({
query,
dataIdFromObject,
result: {
shelter: {
__typename: 'Shelter',
animals: [
{
__typename: 'Animal',
name: 'Carol',
species: {
__typename: 'Cat',
name: 'cat',
},
},
{
__typename: 'Animal',
name: 'Dieter',
species: {
__typename: 'Dog',
name: 'dog',
},
animals: [
{
__typename: 'Animal',
species: {
__typename: 'Cat',
name: 'cat',
},
],
id: 'some-id',
},
},
],
},
store,
});

expect(store.toObject()).toEqual({
'$Shelter__some-id.animals.0.species': {
name: 'cat',
},
'$Shelter__some-id.animals.1.species': {
name: 'dog',
},
'Shelter__some-id': {
'$ROOT_QUERY.animals.0.species': { name: 'cat' },
ROOT_QUERY: {
animals: [
{
generated: true,
id: 'Shelter__some-id.animals.0',
type: 'id',
typename: 'Animal',
},
{
generated: true,
id: 'Shelter__some-id.animals.1',
id: 'ROOT_QUERY.animals.0',
type: 'id',
typename: 'Animal',
},
],
id: 'some-id',
},
'Shelter__some-id.animals.0': {
name: 'Carol',
'ROOT_QUERY.animals.0': {
species: {
generated: true,
id: '$Shelter__some-id.animals.0.species',
id: '$ROOT_QUERY.animals.0.species',
type: 'id',
typename: 'Cat',
},
},
'Shelter__some-id.animals.1': {
name: 'Dieter',
});

writeQueryToStore({
query,
result: {
animals: [
{
__typename: 'Animal',
species: {
__typename: 'Dog',
name: 'dog',
},
},
],
},
store,
});

expect(store.toObject()).toEqual({
'$ROOT_QUERY.animals.0.species': { name: 'dog' },
ROOT_QUERY: {
animals: [
{
generated: true,
id: 'ROOT_QUERY.animals.0',
type: 'id',
typename: 'Animal',
},
],
},
'ROOT_QUERY.animals.0': {
species: {
generated: true,
id: '$Shelter__some-id.animals.1.species',
id: '$ROOT_QUERY.animals.0.species',
type: 'id',
typename: 'Dog',
},
},
ROOT_QUERY: {
shelter: {
generated: false,
id: 'Shelter__some-id',
type: 'id',
typename: 'Shelter',
},
},
});
});

it('should not keep reference when type of mixed inlined field with changes to non-inlined field', () => {
const store = defaultNormalizedCacheFactory();

const dataIdFromObject = (object: any) => {
if (object.__typename && object.id) {
return object.__typename + '__' + object.id;
}
return undefined;
};

const query = gql`
query {
animals {
species {
id
name
}
}
}
`;

writeQueryToStore({
query,
dataIdFromObject,
result: {
shelter: {
__typename: 'Shelter',
animals: [
// First element deleted -> nested "type" field has GraphQL Type change
{
__typename: 'Animal',
name: 'Dieter',
species: {
__typename: 'Dog',
name: 'dog',
},
animals: [
{
__typename: 'Animal',
species: {
__typename: 'Cat',
name: 'cat',
},
],
id: 'some-id',
},
},
],
},
dataIdFromObject,
store,
});

expect(store.toObject()).toEqual({
'$Shelter__some-id.animals.0.species': {
name: 'dog',
},
'Shelter__some-id': {
'$ROOT_QUERY.animals.0.species': { name: 'cat' },
ROOT_QUERY: {
animals: [
{
generated: true,
id: 'Shelter__some-id.animals.0',
id: 'ROOT_QUERY.animals.0',
type: 'id',
typename: 'Animal',
},
],
id: 'some-id',
},
'Shelter__some-id.animals.0': {
name: 'Dieter',
'ROOT_QUERY.animals.0': {
species: {
generated: true,
id: '$Shelter__some-id.animals.0.species',
id: '$ROOT_QUERY.animals.0.species',
type: 'id',
typename: 'Dog',
typename: 'Cat',
},
},
'Shelter__some-id.animals.1': {
name: 'Dieter',
species: {
generated: true,
id: '$Shelter__some-id.animals.1.species',
type: 'id',
typename: 'Dog',
},
});

writeQueryToStore({
query,
result: {
animals: [
{
__typename: 'Animal',
species: {
id: 'dog-species',
__typename: 'Dog',
name: 'dog',
},
},
],
},
dataIdFromObject,
store,
});

expect(store.toObject()).toEqual({
'$ROOT_QUERY.animals.0.species': undefined,
'Dog__dog-species': {
id: 'dog-species',
name: 'dog',
},
ROOT_QUERY: {
shelter: {
animals: [
{
generated: true,
id: 'ROOT_QUERY.animals.0',
type: 'id',
typename: 'Animal',
},
],
},
'ROOT_QUERY.animals.0': {
species: {
generated: false,
id: 'Shelter__some-id',
id: 'Dog__dog-species',
type: 'id',
typename: 'Shelter',
typename: 'Dog',
},
},
});
Expand Down
7 changes: 6 additions & 1 deletion packages/apollo-cache-inmemory/src/writeToStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,12 @@ function writeFieldToStore({
// we should only merge if it's an object of the same type
// otherwise, we should delete the generated object
if (typenameChanged) {
store.delete(generatedKey);
// remove the old generated value in case the old value was
// inlined and the new value is not, which is indicated by
// the old id being generated and the new id being real
if (!generated) {
store.delete(generatedKey);
}
} else {
shouldMerge = true;
}
Expand Down

0 comments on commit 1b8d95b

Please sign in to comment.