import { ApolloClient, ApolloLink, InMemoryCache, split } from "@apollo/client"; import { setContext } from "@apollo/client/link/context"; import { HttpLink } from "@apollo/client/link/http"; //"apollo-link-http"; import { RetryLink } from "@apollo/client/link/retry"; import { WebSocketLink } from "@apollo/client/link/ws"; //import { split } from "apollo-link"; import apolloLogger from "apollo-link-logger"; import { getMainDefinition } from "@apollo/client/utilities"; import { auth } from "../firebase/firebase.utils"; import errorLink from "../graphql/apollo-error-handling"; const httpLink = new HttpLink({ uri: process.env.REACT_APP_GRAPHQL_ENDPOINT, }); const wsLink = new WebSocketLink({ uri: process.env.REACT_APP_GRAPHQL_ENDPOINT_WS, options: { lazy: true, reconnect: true, connectionParams: async () => { const token = auth.currentUser && (await auth.currentUser.getIdToken()); if (token) { return { headers: { authorization: token ? `Bearer ${token}` : "", }, }; } }, }, }); const subscriptionMiddleware = { applyMiddleware: async (options, next) => { options.authToken = auth.currentUser && (await auth.currentUser.getIdToken()); next(); }, }; wsLink.subscriptionClient.use([subscriptionMiddleware]); const link = split( // split based on operation type ({ query }) => { const definition = getMainDefinition(query); // console.log( // "##Intercepted GQL Transaction : " + // definition.operation + // "|" + // definition.name.value + // "##", // query // ); return ( definition.kind === "OperationDefinition" && definition.operation === "subscription" ); }, wsLink, httpLink ); const authLink = setContext((_, { headers }) => { return ( auth.currentUser && auth.currentUser.getIdToken().then((token) => { if (token) { return { headers: { ...headers, authorization: token ? `Bearer ${token}` : "", }, }; } else { return { headers }; } }) ); }); const retryLink = new RetryLink({ delay: { initial: 500, max: 5, jitter: true, }, attempts: { max: 5, retryIf: (error, _operation) => !!error, }, }); const middlewares = []; if (process.env.NODE_ENV === "development") { middlewares.push(apolloLogger); } middlewares.push(retryLink.concat(errorLink.concat(authLink.concat(link)))); const cache = new InMemoryCache({}); export default new ApolloClient({ link: ApolloLink.from(middlewares), cache, connectToDevTools: process.env.NODE_ENV !== "production", defaultOptions: { query: { fetchPolicy: "network-only", }, watchQuery: { fetchPolicy: "network-only", }, }, });