@nitra/vite-boot
Version:
111 lines (95 loc) • 3.07 kB
JavaScript
import { ApolloClient, InMemoryCache, from } from '@apollo/client/core'
import { onError } from '@apollo/client/link/error'
import { createClient } from 'graphql-ws'
import { GraphQLWsLink } from '@apollo/client/link/subscriptions'
import { checkToken, refreshToken, getToken } from './token.js'
import { user } from './user.js'
/**
*
* @param options
*/
function createRestartableClient(options) {
let restartRequested = false
let restart = () => {
restartRequested = true
}
const client = createClient({
...options,
on: {
...options.on,
opened: socket => {
options.on?.opened?.(socket)
restart = () => {
if (socket.readyState === WebSocket.OPEN) {
// if the socket is still open for the restart, do the restart
socket.close(4205, 'Client Restart')
} else {
// otherwise the socket might've closed, indicate that you want
// a restart on the next opened event
restartRequested = true
}
}
// just in case you were eager to restart
if (restartRequested) {
restartRequested = false
restart()
}
}
}
})
return {
...client,
restart: () => restart()
}
}
export let connectionParam = {}
export const wsClient = createRestartableClient({
url: `${import.meta.env.VITE_HASURA_PROTOCOL}://${import.meta.env.VITE_HASURA_HOST}/v1/graphql`,
connectionParams: () => {
const token = getToken()
if (token) {
const check = checkToken(token)
if (check.result === 'ok' && user.role) {
const headers = {}
// Якщо є токен - додаємо його в заголовки
headers.Authorization = `Bearer ${token}`
headers['x-hasura-role'] = user.role
connectionParam = { headers }
return connectionParam
}
}
connectionParam = {}
return connectionParam
}
})
const wsLink = new GraphQLWsLink(wsClient)
const errorLink = onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors) {
for (const err of graphQLErrors) {
console.error('graphQLErrors:', err)
}
}
if (networkError) {
if (networkError?.message?.match('JWTExpired')) {
// Запускаємо рефреш токену асинхронно
// Чистимо токен
refreshToken()
// Пока спробуємо без логауту
// бо робить його не тільки в випадкі коли роль не підходить
// } else if (networkError?.message === `Invalid message 'type' property "connection_error"`) {
// // Роль не підходить хашурі
// router.push('/logout')
} else {
console.log(`[Network error]:`, networkError?.message, networkError)
}
}
})
export const apolloClient = new ApolloClient({
link: from([errorLink, wsLink]),
cache: new InMemoryCache(),
defaultOptions: {
watchQuery: {
fetchPolicy: 'cache-and-network'
}
}
})