diff options
Diffstat (limited to 'app/assets/javascripts/lib/apollo/persistence_mapper.js')
-rw-r--r-- | app/assets/javascripts/lib/apollo/persistence_mapper.js | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/app/assets/javascripts/lib/apollo/persistence_mapper.js b/app/assets/javascripts/lib/apollo/persistence_mapper.js new file mode 100644 index 00000000000..8fc7c69c79d --- /dev/null +++ b/app/assets/javascripts/lib/apollo/persistence_mapper.js @@ -0,0 +1,67 @@ +// this file is based on https://github.com/apollographql/apollo-cache-persist/blob/master/examples/react-native/src/utils/persistence/persistenceMapper.ts +// with some heavy refactororing + +/* eslint-disable @gitlab/require-i18n-strings */ +/* eslint-disable no-underscore-dangle */ +/* eslint-disable no-param-reassign */ +/* eslint-disable dot-notation */ +export const persistenceMapper = async (data) => { + const parsed = JSON.parse(data); + + const mapped = {}; + const persistEntities = []; + const rootQuery = parsed['ROOT_QUERY']; + + // cache entities that have `__persist: true` + Object.keys(parsed).forEach((key) => { + if (parsed[key]['__persist']) { + persistEntities.push(key); + } + }); + + // cache root queries that have `@persist` directive + mapped['ROOT_QUERY'] = Object.keys(rootQuery).reduce( + (obj, key) => { + if (key === '__typename') return obj; + + if (/@persist$/.test(key)) { + obj[key] = rootQuery[key]; + + if (Array.isArray(rootQuery[key])) { + const entities = rootQuery[key].map((item) => item.__ref); + persistEntities.push(...entities); + } else { + const entity = rootQuery[key].__ref; + persistEntities.push(entity); + } + } + + return obj; + }, + { __typename: 'Query' }, + ); + + persistEntities.reduce((obj, key) => { + const parsedEntity = parsed[key]; + + // check for root queries and only cache root query properties that have `__persist: true` + // we need this to prevent overcaching when we fetch the same entity (e.g. project) more than once + // with different set of fields + + if (Object.values(rootQuery).some((value) => value.__ref === key)) { + const mappedEntity = {}; + Object.entries(parsedEntity).forEach(([parsedKey, parsedValue]) => { + if (!parsedValue || typeof parsedValue !== 'object' || parsedValue['__persist']) { + mappedEntity[parsedKey] = parsedValue; + } + }); + obj[key] = mappedEntity; + } else { + obj[key] = parsed[key]; + } + + return obj; + }, mapped); + + return JSON.stringify(mapped); +}; |