import { ApolloClient, InMemoryCache, HttpLink, from } from '@apollo/client'; import { Config } from '../config'; import { WebSocketLink } from "@apollo/client/link/ws"; import { RetryLink } from "@apollo/client/link/retry"; import { onError } from "@apollo/client/link/error"; import { SubscriptionClient } from "subscriptions-transport-ws"; import { User } from '../types/user'; export function createClient(setLoggedIn: (boolean) => void) { const subscriptionClient = new SubscriptionClient(Config.subscriptionEndpoint, { reconnect: true, }); const errorLink = onError(({ operation }) => { const { response } = operation.getContext(); if (response.status === 401) setLoggedIn(false); }); const retryLink = new RetryLink({attempts: {max: 2}}).split( (operation) => operation.operationName === 'subscription', new WebSocketLink(subscriptionClient), new HttpLink({ uri: Config.graphQLEndpoint, credentials: 'include', }) ); const cache = new InMemoryCache({}); return new ApolloClient({ cache: cache, link: from([ errorLink, retryLink ]), defaultOptions: { watchQuery: { fetchPolicy: 'cache-and-network', errorPolicy: 'ignore', }, query: { fetchPolicy: 'network-only', errorPolicy: 'all', }, mutate: { errorPolicy: 'all', }, } }); } export function mergeArrayByField(fieldName: string) { return (existing: T[] = [], incoming: T[], { readField, mergeObjects }) => { const merged: any[] = existing ? existing.slice(0) : []; const objectFieldToIndex: Record = Object.create(null); if (existing) { existing.forEach((obj, index) => { objectFieldToIndex[readField(fieldName, obj)] = index; }); } incoming.forEach(obj => { const field = readField(fieldName, obj); const index = objectFieldToIndex[field]; if (typeof index === "number") { merged[index] = mergeObjects(merged[index], obj); } else { objectFieldToIndex[name] = merged.length; merged.push(obj); } }); return merged; } }