import { makeVar, InMemoryCache } from '@apollo/client/core'; import log from 'loglevel'; const showNavigationSidebarVar = makeVar(false); const showProfileSidebarVar = makeVar(false); const scrollToElementVar = makeVar(''); const currentFilterVar = makeVar(''); const helloEmailVar = makeVar(''); const languageVar = makeVar('de'); const idToRefFactory = (__typename) => (_, { args, toReference }) => { log.debug(`Referencing ${__typename} with ${args.id}`); return toReference({ __typename, id: args.id, }); }; const typePolicies = { ProjectNode: { keyFields: ['slug'], }, InstrumentNode: { keyFields: ['slug'], }, RoomNode: { keyFields: ['slug'], }, ChapterNode: { fields: { contentBlocks: { merge(_existing, incoming) { // always replace the whole array return incoming; }, }, }, }, ModuleNode: { fields: { inEditMode: { read(previous) { return previous !== undefined ? previous : false; }, }, }, keyFields: ['slug'], }, PrivateUserNode: { fields: { language: { read() { console.log(`returning language ${languageVar()}`); return languageVar(); }, }, }, }, RoomEntryNode: { keyFields: ['slug'], }, // https://www.apollographql.com/docs/react/local-state/managing-state-with-field-policies/#example Query: { fields: { sidebar: { read() { return { profile: showProfileSidebarVar(), navigation: showNavigationSidebarVar(), }; }, }, scrollPosition: { read() { return { scrollTo: scrollToElementVar(), }; }, }, instrumentFilter: { read() { return { currentFilter: currentFilterVar(), }; }, }, helloEmail: { read() { return { email: helloEmailVar(), }; }, }, // these used to be in cacheRedirects, now here contentBlock: { read: idToRefFactory('ContentBlockNode') }, chapter: { read: idToRefFactory('ChapterNode') }, assignment: { read: idToRefFactory('AssignmentNode') }, objective: { read: idToRefFactory('ObjectiveNode') }, objectiveGroup: { read: idToRefFactory('ObjectiveGroupNode') }, projectEntry: { read: idToRefFactory('ProjectEntryNode') }, }, }, }; const possibleTypes = { ContentBlockInterface: ['ContentBlockNode', 'SnapshotContentBlockNode'], ChapterInterface: ['ChapterNode', 'SnapshotChapterNode'], }; const cache = new InMemoryCache({ // used to 'override' the behavior in resolving different types. We use it for local state management // https://www.apollographql.com/docs/react/local-state/managing-state-with-field-policies/#example typePolicies, possibleTypes, // todo: document what this does, or link the doc for it at least // dataIdFromObject: obj => { // switch (obj.__typename) { // case 'InstrumentNode': // case 'ModuleNode': // case 'RoomEntryNode': // return `${obj.__typename}:${obj.slug}`; // default: // return defaultDataIdFromObject(obj); // } // }, }); // TODO: Monkey-patching in a fix for an open issue suggesting that // `readQuery` should return null or undefined if the query is not yet in the // cache: https://github.com/apollographql/apollo-feature-requests/issues/1 // probably not needed any more, as per https://github.com/apollographql/apollo-client/pull/7098 // cache.originalReadQuery = cache.readQuery; // cache.readQuery = (...args) => { // try { // return cache.originalReadQuery(...args); // } catch (err) { // console.error(err); // return undefined; // } // }; export { showProfileSidebarVar, showNavigationSidebarVar, scrollToElementVar, currentFilterVar, helloEmailVar, languageVar, cache, }; export default cache;