Last active
May 20, 2019 19:14
-
-
Save qswitcher/cce9053d50a17f6e6ec74a211da36192 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { | |
InMemoryCache | |
} = require('apollo-cache-inmemory'); | |
const getQueryName = (query) => { | |
const defs = query.definitions; | |
if (defs && defs.length) { | |
const operationDefinition = defs.filter( | |
({kind}) => kind === 'OperationDefinition' | |
); | |
return ( | |
operationDefinition.length && | |
operationDefinition[0].name && | |
operationDefinition[0].name.value | |
); | |
} | |
return null; | |
}; | |
/** | |
* Optimized version of InMemoryCache which caches the first execution | |
* of `initialQueryName` named query for the initial pageload. | |
*/ | |
class OptimizedInMemoryCache extends InMemoryCache { | |
constructor({initialQueryName, ...rest}) { | |
super(rest); | |
this.initialQueryName = initialQueryName; | |
} | |
extract(optimistic) { | |
const normalizedCache = super.extract(optimistic); | |
return {_INITIAL_QUERY: this._INITIAL_QUERY, ...normalizedCache}; | |
} | |
restore(data) { | |
this._INITIAL_QUERY = data._INITIAL_QUERY; | |
return super.restore(data); | |
} | |
reset() { | |
this._INITIAL_QUERY = null; | |
return super.reset(); | |
} | |
write(write) { | |
if ( | |
this.initialQueryName && | |
this.initialQueryName === getQueryName(write.query) && | |
!this._INITIAL_QUERY | |
) { | |
// Save the first query, don't normalize this to the cache | |
this._INITIAL_QUERY = { | |
result: write.result, | |
variables: write.variables | |
}; | |
super.broadcastWatches(); | |
return; | |
} | |
super.write(write); | |
} | |
read(query) { | |
if (this.useInitialQuery(query)) { | |
return this._INITIAL_QUERY.result; | |
} | |
return super.read(query); | |
} | |
diff(query) { | |
if (this.useInitialQuery(query)) { | |
return {result: this._INITIAL_QUERY.result, complete: true}; | |
} | |
return super.diff(query); | |
} | |
useInitialQuery(query) { | |
return ( | |
this.initialQueryName && | |
this.initialQueryName === getQueryName(query.query) && | |
this._INITIAL_QUERY && | |
isEqual(this._INITIAL_QUERY.variables, query.variables) | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi Jeff! Sorry for reaching out on a few platforms, just trying to get your attention. I a relatively novice programming trying to implement a similar custom cache for Apollo Client at a bootcamp right now. There isn't much documentation on how I might go about doing so, besides the article that you've written. Think you'd have some time to answer a few questions via either email or phone? It'd really help my group out.