Skip to content

Commit

Permalink
Merge pull request #3422 from dferber90/df-fix-cache-normalization-fo…
Browse files Browse the repository at this point in the history
…r-mixed-fields

Fix cache normalization for mixed fields
  • Loading branch information
hwillson authored May 24, 2018
2 parents 2a88ed6 + f649eb9 commit 4b96be9
Show file tree
Hide file tree
Showing 4 changed files with 209 additions and 3 deletions.
5 changes: 5 additions & 0 deletions packages/apollo-cache-inmemory/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Change log

### Next

- Fixed cache invalidation for inlined mixed types in union fields within arrays.
[PR #3422](https://github.com/apollographql/apollo-client/pull/3422)

### 1.2.0
- Various optimizations for cache read performance [#3300](https://github.com/apollographql/apollo-client/pull/3300)
- Fix typo in documentation
Expand Down
195 changes: 195 additions & 0 deletions packages/apollo-cache-inmemory/src/__tests__/writeToStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1881,4 +1881,199 @@ describe('writing to the store', () => {
},
});
});

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

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

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

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

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: '$ROOT_QUERY.animals.0.species',
type: 'id',
typename: 'Dog',
},
},
});
});

it('should not keep reference when type of mixed inlined field 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,
result: {
animals: [
{
__typename: 'Animal',
species: {
__typename: 'Cat',
name: 'cat',
},
},
],
},
dataIdFromObject,
store,
});

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

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: {
animals: [
{
generated: true,
id: 'ROOT_QUERY.animals.0',
type: 'id',
typename: 'Animal',
},
],
},
'ROOT_QUERY.animals.0': {
species: {
generated: false,
id: 'Dog__dog-species',
type: 'id',
typename: 'Dog',
},
},
});
});
});
11 changes: 8 additions & 3 deletions packages/apollo-cache-inmemory/src/writeToStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -450,10 +450,15 @@ function writeFieldToStore({

if (escapedId.generated) {
generatedKey = escapedId.id;
// we should only merge if it's an object of the same type
// otherwise, we should delete the generated object
// 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);
// Only delete the generated object when the old object was
// inlined, and the new object is not. This is indicated by
// the old id being generated, and the new id being real.
if (!generated) {
store.delete(generatedKey);
}
} else {
shouldMerge = true;
}
Expand Down
1 change: 1 addition & 0 deletions packages/apollo-client/AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Clément Prévost <prevostclement@gmail.com>
David Alan Hjelle <dahjelle+github.com@thehjellejar.com>
David Glasser <glasser@meteor.com>
Dominic Watson <intellix@gmail.com>
Dominik Ferber <dominik.ferber+dev@gmail.com>
Dhaivat Pandya <dhaivat@meteor.com>
Dhaivat Pandya <dhaivatpandya@gmail.com>
Evans Hauser <evanshauser@gmail.com>
Expand Down

0 comments on commit 4b96be9

Please sign in to comment.