From 644fd3efef9d30e2616969f8dbf00d9d2fecf91e Mon Sep 17 00:00:00 2001 From: Kushal Pandya Date: Tue, 11 Jun 2019 16:28:01 +0530 Subject: Add `fragmentMatcher` support in cacheConfig --- app/assets/javascripts/lib/graphql.js | 40 ++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/lib/graphql.js b/app/assets/javascripts/lib/graphql.js index 5857f9e22ae..ab8bae60ac2 100644 --- a/app/assets/javascripts/lib/graphql.js +++ b/app/assets/javascripts/lib/graphql.js @@ -1,5 +1,5 @@ import { ApolloClient } from 'apollo-client'; -import { InMemoryCache } from 'apollo-cache-inmemory'; +import { InMemoryCache, IntrospectionFragmentMatcher } from 'apollo-cache-inmemory'; import { createUploadLink } from 'apollo-upload-client'; import { ApolloLink } from 'apollo-link'; import { BatchHttpLink } from 'apollo-link-batch-http'; @@ -7,12 +7,50 @@ import csrf from '~/lib/utils/csrf'; export default (resolvers = {}, config = {}) => { let uri = `${gon.relative_url_root}/api/graphql`; + const { introspectionQueryResultData, cacheConfig } = config; if (config.baseUrl) { // Prepend baseUrl and ensure that `///` are replaced with `/` uri = `${config.baseUrl}${uri}`.replace(/\/{3,}/g, '/'); } + if (introspectionQueryResultData) { + // eslint-disable-next-line no-param-reassign + config.cacheConfig = cacheConfig || {}; + + // Extract typenames from provided introspection Query data. + // eslint-disable-next-line no-underscore-dangle + const typeNames = introspectionQueryResultData.__schema.types + .map(type => type.possibleTypes) + .reduce((acc, item) => acc.concat(item), []) + .map(item => item.name); + + Object.assign(config.cacheConfig, { + fragmentMatcher: new IntrospectionFragmentMatcher({ + introspectionQueryResultData, + }), + dataIdFromObject: obj => { + // We need to create a dynamic ID for each entry and + // each entry can have the same ID as the ID in a commit ID, + // So we create a unique cache ID with the path and the ID. + // eslint-disable-next-line no-underscore-dangle + if (typeNames.indexOf(obj.__typename) > -1) { + return `${obj.flatPath}-${obj.id}`; + } + + // If the type doesn't match any of the above we + // fallback to using the default Apollo ID. + // eslint-disable-next-line no-underscore-dangle + return obj.id || obj._id; + }, + + // Override addTypename to force it to be + // `true` to ensure that fragmentMatcher + // always has `__typename` available. + addTypename: true, + }); + } + const httpOptions = { uri, headers: { -- cgit v1.2.1