@pi-top/apollo-cache-updaters v1.5.0
The problem
Apollo cache updates are verbose and require an understanding of how the cache uses references and normalises data internally.
This solution
A set of declarative updaters that perform common actions automatically.
Restructuring updaters to be declarative makes cache updates more concise. This makes it possible to write complex updates inline.
Common patterns in update methods are done automatically, for instance
writeFragment automatically generates it's fragment from data. All automatic
behaviours are easy to disable.
Table of Contents
Installation
This module is distributed via npm which is bundled with node and
should be installed as one of your project's dependencies:
npm install --save @pi-top/apollo-cache-updatersThe @apollo/client package is a peerDepencency.
Usage
This package exports updaters for the cache actions: evict, modify,
writeFragment and writeQuery. It also exports a helper called combine
(see below).
Updaters
Each updater accepts a createOptions callback that is called with the
ExecutionResult and the ApolloCache as the first and second arguments
respectively. The createOptions callback is used to create options for a cache
method, for example writeQuery's createOptions callback should return the
same options that would be passed cache.writeQuery:
import { writeQuery } from '@pi-top/apollo-cache-updaters';
const update = writeQuery((result) => ({
data: result.data,
query: gql`
query GetStuff {
stuff {
id
__typename
}
}
`,
})),createOptions can also return an array of options, for when multiple similar
operations need to performed from a single ExecutionResult:
import { writeQuery } from '@pi-top/apollo-cache-updaters';
const update = writeQuery((result) => result.data.stuffs.map(stuff => ({
data: { stuff },
variables: { id: stuff.id }
query: gql`
query GetStuff($id: string) {
stuff(id: $id) {
id
__typename
}
}
`,
}))writeFragment
writeFragment automatically generates it's fragment from the data property
when fragment is undefined. Note that when using this behaviour the
__typename property is required to exist in data:
import { writeFragment } from '@pi-top/apollo-cache-updaters';
const update = writeFragment((result) => ({
data: {
...thing,
__typename: 'Thing',
stuff: result.data.stuff
}
}))evict
evict automatically calls cache.gc if there was a successful eviction. To
stop the behaviour there is an option gc that can be set to false
import { evict } from '@pi-top/apollo-cache-updaters';
const update = evict((result, cache) => ({
id: cache.identify(result.data),
gc: false,
}))combine
When multiple types of operation need to performed for one ExecutionResult the
combine method can be used:
import { combine } from '@pi-top/apollo-cache-updaters';
const update = combine(
writeFragment((result) => ({
data: {
...thing,
stuff: result.data.stuff
}
})),
writeQuery((result) => ({
data: result.data,
query: GET_STUFF,
})),
)skipping updates
Sometimes we want to conditionally update the cache, to do this we can set the
skip value in the updater options:
import { evict } from '@pi-top/apollo-cache-updaters'
const update = evict((result, cache) => ({
id: cache.identify(objectToDelete),
skip: !(result.data && result.data.deleted),
}));Typescript
The project comes fully typed.
LICENSE
MIT