Files
bodyshop/client/src/utils/GraphQLClient.js
2024-02-26 09:48:09 -08:00

189 lines
5.1 KiB
JavaScript

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 {getMainDefinition, offsetLimitPagination,} from "@apollo/client/utilities";
//import { split } from "apollo-link";
import apolloLogger from "apollo-link-logger";
//import axios from "axios";
import {auth} from "../firebase/firebase.utils";
import errorLink from "../graphql/apollo-error-handling";
import {SentryLink} from "apollo-link-sentry";
//import { store } from "../redux/store";
const httpLink = new HttpLink({
uri: import.meta.env.VITE_APP_GRAPHQL_ENDPOINT,
});
const wsLink = new WebSocketLink({
uri: import.meta.env.VITE_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 roundTripLink = new ApolloLink((operation, forward) => {
// Called before operation is sent to server
operation.setContext({start: new Date()});
return forward(operation).map((data) => {
// Called after server responds
const time = new Date() - operation.getContext().start;
// console.log(
// `Operation ${operation.operationName} took ${time} to complete`
// );
TrackExecutionTime(operation.operationName, time);
return data;
});
});
const TrackExecutionTime = async (operationName, time) => {
// if (process.env.NODE_ENV === "development") return;
// const rdxStore = store.getState();
// try {
// axios.post("/ioevent", {
// operationName,
// time,
// dbevent: true,
// user:
// rdxStore.user &&
// rdxStore.user.currentUser &&
// rdxStore.user.currentUser.email,
// imexshopid:
// rdxStore.user &&
// rdxStore.user.bodyshop &&
// rdxStore.user.bodyshop.imexshopid,
// });
// } catch (error) {
// console.log("IOEvent Error", error);
// }
};
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 {
console.error(
"Authentication error. Unable to add authorization token because it was empty."
);
return {headers};
}
})
.catch((error) => {
console.error(
"Authentication error. Unable to add authorization token.",
error.message
);
return {headers};
})
);
});
const retryLink = new RetryLink({
delay: {
initial: 500,
max: 5,
jitter: true,
},
attempts: {
max: 5,
retryIf: (error, _operation) => !!error,
},
});
const middlewares = [];
if (import.meta.env.DEV) {
middlewares.push(apolloLogger);
}
middlewares.push(
new SentryLink().concat(
roundTripLink.concat(
retryLink.concat(errorLink.concat(authLink.concat(link)))
)
)
);
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
conversations: offsetLimitPagination(),
},
},
},
});
const client = new ApolloClient({
link: ApolloLink.from(middlewares),
cache,
connectToDevTools: import.meta.env.DEV,
defaultOptions: {
watchQuery: {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
errorPolicy: "ignore",
},
query: {
fetchPolicy: "network-only",
errorPolicy: "all",
},
mutate: {
errorPolicy: "all",
},
},
});
export default client;