Skip to content

Instantly share code, notes, and snippets.

@jakubriedl
Created March 25, 2018 23:38
Show Gist options
  • Save jakubriedl/7085a43ff6793348fafb0e15ee803658 to your computer and use it in GitHub Desktop.
Save jakubriedl/7085a43ff6793348fafb0e15ee803658 to your computer and use it in GitHub Desktop.
Apollo cache nesting patch
import {patchApolloHints} from './patchApollo'
const apolloConfig = {
formatResponse: (response, options) => {
patchApolloHints(response)
// and some more stuff
},
cacheControl: true
}
import _ from 'lodash'
function isSetHint (hint) {
return hint && (hint.maxAge !== 0 || !!hint.scope)
}
function inheritCache (hint) {
if (isSetHint(hint)) return hint
let path = hint.path.slice(0, -1)
// eslint-disable-next-line no-invalid-this
while (path.length > 1 && !isSetHint(this[path.join('.')])) {
path = path.slice(0, -1)
}
// eslint-disable-next-line no-invalid-this
const parent = this[path.join('.')]
if (isSetHint(parent)) {
hint.maxAge = parent.maxAge
hint.scope = parent.scope
}
return hint
}
function blockErrorCache (hint) {
let hasError = false
let path = [...hint.path]
do {
// eslint-disable-next-line no-invalid-this
hasError = hasError || this[path.join('.')]
path = path.slice(0, -1)
} while (!hasError && path.length)
if (hasError) {
hint.maxAge = 0
delete hint.scope
}
return hint
}
function hasErrors (response) {
return response.errors && response.errors.length > 0
}
export function patchApolloHints (response) {
let hints = _.get(response, 'extensions.cacheControl.hints')
if (Array.isArray(hints)) {
hints = hints.map(inheritCache, _.keyBy(hints, hint => hint.path.join('.')))
if (hasErrors(response)) {
hints = hints.map(blockErrorCache, _.keyBy(response.errors, err => (err.path || ['untracked']).join('.')))
}
response.extensions.cacheControl.hints = hints
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment