Skip to content

Instantly share code, notes, and snippets.

@aleccool213
Last active November 21, 2019 14:34
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aleccool213/2c05dda3e017d7c2af699da435f5e895 to your computer and use it in GitHub Desktop.
Save aleccool213/2c05dda3e017d7c2af699da435f5e895 to your computer and use it in GitHub Desktop.
A helper for apollo-local-state to create mutations much easier
import { IFieldResolver } from 'graphql-tools';
import { DocumentNode } from 'graphql';
import { ResolverContext } from '.';
interface InputVariablesShape<TInput> {
input: TInput;
}
/**
* Creates a client-side mutation resolver which reads one item from the cache,
* mutates it using the given mutation, then writes it back to the cache.
* @param reducer Func which mutates data and returns it. Must be a pure function.
* @param fragment Used to read/write data to apollo-link-state.
* @param fragmentName Name of fragment inside
* @param getId A func which returns the id of the entity to be used in the `reducer` func.
*/
export const createResolver = <InputShape, EntityType>(
reducer: (entity: EntityType, input: InputShape) => EntityType,
fragment: DocumentNode,
fragmentName: string,
getId: (input: InputShape) => string,
) => {
const resolver: IFieldResolver<void, ResolverContext, any> = (
_obj,
args: InputVariablesShape<InputShape>,
{ cache, getCacheKey },
) => {
const { input } = args;
// 1. Get the id of the object in the cache using `getId`
const id = getCacheKey({ id: getId(input) });
// 2. Get the data from the cache
const entity: EntityType | null = cache.readFragment({
fragment,
fragmentName,
id,
});
if (!entity) {
return null;
}
// 3. Update the data locally
const newEntity: EntityType = reducer(entity, input);
// 4. Write the data back to the cache
cache.writeFragment({
fragment,
fragmentName,
id,
data: newEntity,
});
return null;
};
return resolver;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment