mirror of
https://github.com/MetaFam/TheGame.git
synced 2026-01-14 00:48:18 -05:00
110 lines
2.8 KiB
TypeScript
110 lines
2.8 KiB
TypeScript
import { retryExchange } from '@urql/exchange-retry';
|
|
import { NextComponentType } from 'next';
|
|
import {
|
|
initUrqlClient,
|
|
NextUrqlContext,
|
|
withUrqlClient,
|
|
WithUrqlProps,
|
|
} from 'next-urql';
|
|
import React, { createElement } from 'react';
|
|
import {
|
|
cacheExchange,
|
|
Client,
|
|
CombinedError,
|
|
createClient,
|
|
fetchExchange,
|
|
ssrExchange,
|
|
} from 'urql';
|
|
|
|
import { CONFIG } from '#config';
|
|
import { getTokenFromStore } from '#lib/auth';
|
|
|
|
const errorHasResponseTimeout = (err: CombinedError) =>
|
|
err.graphQLErrors.length > 0 &&
|
|
!!err.graphQLErrors.find((e: Error) => e.message === 'ResponseTimeout');
|
|
|
|
const retryExchangeFunc = retryExchange({
|
|
maxNumberAttempts: 5,
|
|
initialDelayMs: 1000,
|
|
randomDelay: true,
|
|
retryIf: (error) =>
|
|
!!(
|
|
errorHasResponseTimeout(error) ||
|
|
error.networkError ||
|
|
error.response?.size === 0
|
|
),
|
|
});
|
|
|
|
export const client = createClient({
|
|
url: CONFIG.graphqlURL,
|
|
suspense: false,
|
|
exchanges: [cacheExchange, retryExchangeFunc, fetchExchange],
|
|
fetchOptions: () => {
|
|
const token = getTokenFromStore();
|
|
return {
|
|
headers: {
|
|
Authorization: token ? `Bearer ${token}` : '',
|
|
},
|
|
};
|
|
},
|
|
});
|
|
|
|
export const getSSRClient = (): [Client, ReturnType<typeof ssrExchange>] => {
|
|
const ssrCache = ssrExchange({ isClient: false });
|
|
|
|
const ssrClient = initUrqlClient(
|
|
{
|
|
url: CONFIG.graphqlURL,
|
|
exchanges: [
|
|
// debugExchange,
|
|
cacheExchange,
|
|
ssrCache,
|
|
retryExchangeFunc,
|
|
fetchExchange,
|
|
],
|
|
},
|
|
false,
|
|
);
|
|
if (!ssrClient) throw new Error('wtf');
|
|
|
|
return [ssrClient, ssrCache];
|
|
};
|
|
|
|
// We do this to enable ssr cache on pages that are not directly wrapped in 'withUrqlClient' (but on _app)
|
|
// https://github.com/FormidableLabs/urql/issues/1481
|
|
const customWithUrqlClient =
|
|
(
|
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
WithUrql: NextComponentType<NextUrqlContext, {}, WithUrqlProps>,
|
|
): React.FC<WithUrqlProps> =>
|
|
({ pageProps, urqlState, ...props }) =>
|
|
createElement(WithUrql, {
|
|
urqlState: pageProps.urqlState || urqlState,
|
|
pageProps,
|
|
...props,
|
|
});
|
|
|
|
export const wrapUrqlClient = (AppOrPage: React.FC<WithUrqlProps>) =>
|
|
customWithUrqlClient(
|
|
withUrqlClient(
|
|
(_ssrExchange, ctx) => ({
|
|
url: CONFIG.graphqlURL,
|
|
exchanges: [cacheExchange, retryExchangeFunc, fetchExchange],
|
|
fetchOptions: () => {
|
|
const token = ctx
|
|
? ctx?.req?.headers?.authorization?.replace(/^Bearer\s+/, '').trim()
|
|
: getTokenFromStore();
|
|
return {
|
|
headers: {
|
|
Authorization: token ? `Bearer ${token}` : '',
|
|
},
|
|
};
|
|
},
|
|
}),
|
|
{
|
|
neverSuspend: true,
|
|
ssr: false,
|
|
},
|
|
)(AppOrPage),
|
|
);
|