Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/lib/apollo/persistence_mapper.js')
-rw-r--r--app/assets/javascripts/lib/apollo/persistence_mapper.js67
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);
+};