github.com/pluralsh/plural-cli@v0.9.5/pkg/ui/web/src/services/apollo.tsx (about) 1 import { GraphQLErrors } from '@apollo/client/errors' 2 import { useMemo, useState } from 'react' 3 import { create } from '@absinthe/socket' 4 import { createAbsintheSocketLink } from '@absinthe/socket-apollo-link' 5 import { 6 ApolloClient, 7 ApolloLink, 8 HttpLink, 9 InMemoryCache, 10 NormalizedCacheObject, 11 } from '@apollo/client' 12 import { setContext } from '@apollo/client/link/context' 13 import { onError } from '@apollo/client/link/error' 14 import { RetryLink } from '@apollo/client/link/retry' 15 import { Socket as PhoenixSocket } from 'phoenix' 16 17 const API_HOST = 'app.plural.sh' 18 const GQL_URL = `https://${API_HOST}/gql` 19 const WS_URI = `wss://${API_HOST}/socket` 20 21 // const splitLink = split(({ query }) => { 22 // const definition = getMainDefinition(query) 23 // 24 // return ( 25 // definition.kind === 'OperationDefinition' 26 // && definition.operation === 'subscription' 27 // ) 28 // }, 29 // socketLink, 30 // retryLink.concat(resetToken).concat(httpLink),) 31 32 interface ApolloClientHook { 33 client: ApolloClient<NormalizedCacheObject> 34 error: GraphQLErrors | undefined 35 } 36 37 export function useApolloClient(token: string): ApolloClientHook { 38 const [error, setError] = useState<GraphQLErrors>() 39 40 const authLink = setContext(() => ({ headers: token ? { authorization: `Bearer ${token}` } : {} })) 41 const httpLink = useMemo(() => new HttpLink({ uri: GQL_URL }), []) 42 const absintheSocket = create(new PhoenixSocket(WS_URI, { params: () => (token ? { Authorization: `Bearer ${token}` } : {}) })) 43 const errorLink = onError(({ graphQLErrors }) => { 44 if (!error && graphQLErrors) { 45 const clearDelay = 15000 46 47 setError(graphQLErrors) 48 setTimeout(() => setError(undefined), clearDelay) 49 } 50 }) 51 const _socketLink = createAbsintheSocketLink(absintheSocket) 52 const _retryLink = new RetryLink({ 53 delay: { initial: 200 }, 54 attempts: { 55 max: Infinity, 56 retryIf: error => !!error, 57 }, 58 }) 59 60 return useMemo(() => ({ 61 client: new ApolloClient<NormalizedCacheObject>({ 62 link: ApolloLink.from([authLink, errorLink, httpLink]), 63 cache: new InMemoryCache(), 64 }), 65 error, 66 }), [authLink, error, httpLink, errorLink]) 67 }