fix(1758): data node being down (#1871)
* fix: timeout data node requests for node switcher * chore: generate apollo client library * chore: migrate console lite to use new apollo client package * chore: migrate explorer across * chore: remove completely unused file * chore: migrate stats * chore: migrate trading * chore: migrate multisigner app * chore: migrate token over * chore: final migrations * test: adjust tests for new behaviour * fix: build script * Update libs/apollo-client/src/lib/apollo-client.ts * chore: fix conflicts * fix: cache * test: setup mocks before each test * style: lint * style: lint * chore: resolve conflicts * test: fix tests
This commit is contained in:
parent
d0d06bd4ab
commit
dccc750154
@ -1,6 +1,5 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { createClient } from './lib/apollo-client';
|
||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
||||
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
||||
import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment';
|
||||
@ -16,6 +15,7 @@ import Header from './components/header';
|
||||
import { Main } from './components/main';
|
||||
import LocalContext from './context/local-context';
|
||||
import useLocalValues from './hooks/use-local-values';
|
||||
import type { InMemoryCacheConfig } from '@apollo/client';
|
||||
|
||||
function App() {
|
||||
const [theme, toggleTheme] = useThemeSwitcher();
|
||||
@ -30,10 +30,34 @@ function App() {
|
||||
setMenuOpen(false);
|
||||
}, [location, setMenuOpen]);
|
||||
|
||||
const cacheConfig: InMemoryCacheConfig = {
|
||||
typePolicies: {
|
||||
Market: {
|
||||
merge: true,
|
||||
},
|
||||
Party: {
|
||||
merge: true,
|
||||
},
|
||||
Query: {},
|
||||
Account: {
|
||||
keyFields: false,
|
||||
fields: {
|
||||
balanceFormatted: {},
|
||||
},
|
||||
},
|
||||
Node: {
|
||||
keyFields: false,
|
||||
},
|
||||
Instrument: {
|
||||
keyFields: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<EnvironmentProvider>
|
||||
<ThemeContext.Provider value={theme}>
|
||||
<NetworkLoader createClient={createClient}>
|
||||
<NetworkLoader cache={cacheConfig}>
|
||||
<VegaWalletProvider>
|
||||
<LocalContext.Provider value={localValues}>
|
||||
<AppLoader>
|
||||
|
@ -1,88 +0,0 @@
|
||||
import {
|
||||
ApolloClient,
|
||||
from,
|
||||
HttpLink,
|
||||
InMemoryCache,
|
||||
split,
|
||||
} from '@apollo/client';
|
||||
import { onError } from '@apollo/client/link/error';
|
||||
import { RetryLink } from '@apollo/client/link/retry';
|
||||
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
|
||||
import { createClient as createWSClient } from 'graphql-ws';
|
||||
import { getMainDefinition } from '@apollo/client/utilities';
|
||||
|
||||
export function createClient(base?: string) {
|
||||
if (!base) {
|
||||
throw new Error('Base must be passed into createClient!');
|
||||
}
|
||||
const urlHTTP = new URL(base);
|
||||
const urlWS = new URL(base);
|
||||
// Replace http with ws, preserving if its a secure connection eg. https => wss
|
||||
urlWS.protocol = urlWS.protocol.replace('http', 'ws');
|
||||
|
||||
const cache = new InMemoryCache({
|
||||
typePolicies: {
|
||||
Market: {
|
||||
merge: true,
|
||||
},
|
||||
Party: {
|
||||
merge: true,
|
||||
},
|
||||
Query: {},
|
||||
Account: {
|
||||
keyFields: false,
|
||||
fields: {
|
||||
balanceFormatted: {},
|
||||
},
|
||||
},
|
||||
Node: {
|
||||
keyFields: false,
|
||||
},
|
||||
Instrument: {
|
||||
keyFields: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const retryLink = new RetryLink({
|
||||
delay: {
|
||||
initial: 300,
|
||||
max: 10000,
|
||||
jitter: true,
|
||||
},
|
||||
});
|
||||
|
||||
const httpLink = new HttpLink({
|
||||
uri: urlHTTP.href,
|
||||
credentials: 'same-origin',
|
||||
});
|
||||
|
||||
const wsLink = new GraphQLWsLink(
|
||||
createWSClient({
|
||||
url: urlWS.href,
|
||||
})
|
||||
);
|
||||
|
||||
const splitLink = split(
|
||||
({ query }) => {
|
||||
const definition = getMainDefinition(query);
|
||||
return (
|
||||
definition.kind === 'OperationDefinition' &&
|
||||
definition.operation === 'subscription'
|
||||
);
|
||||
},
|
||||
wsLink,
|
||||
httpLink
|
||||
);
|
||||
|
||||
const errorLink = onError(({ graphQLErrors, networkError }) => {
|
||||
console.log(graphQLErrors);
|
||||
console.log(networkError);
|
||||
});
|
||||
|
||||
return new ApolloClient({
|
||||
connectToDevTools: process.env['NODE_ENV'] === 'development',
|
||||
link: from([errorLink, retryLink, splitLink]),
|
||||
cache,
|
||||
});
|
||||
}
|
@ -9,12 +9,12 @@ import {
|
||||
useEnvironment,
|
||||
} from '@vegaprotocol/environment';
|
||||
import { NetworkInfo } from '@vegaprotocol/network-info';
|
||||
import { createClient } from './lib/apollo-client';
|
||||
import { Nav } from './components/nav';
|
||||
import { Header } from './components/header';
|
||||
import { Main } from './components/main';
|
||||
import { TendermintWebsocketProvider } from './contexts/websocket/tendermint-websocket-provider';
|
||||
import { ENV } from './config/env';
|
||||
import type { InMemoryCacheConfig } from '@apollo/client';
|
||||
|
||||
function App() {
|
||||
const { VEGA_ENV } = useEnvironment();
|
||||
@ -36,10 +36,18 @@ function App() {
|
||||
});
|
||||
}, [VEGA_ENV]);
|
||||
|
||||
const cacheConfig: InMemoryCacheConfig = {
|
||||
typePolicies: {
|
||||
Node: {
|
||||
keyFields: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={theme}>
|
||||
<TendermintWebsocketProvider>
|
||||
<NetworkLoader createClient={createClient}>
|
||||
<NetworkLoader cache={cacheConfig}>
|
||||
<div
|
||||
className={`${
|
||||
menuOpen && 'h-[100vh] overflow-hidden'
|
||||
|
@ -1,52 +0,0 @@
|
||||
import { ApolloClient, from, HttpLink, InMemoryCache } from '@apollo/client';
|
||||
import { onError } from '@apollo/client/link/error';
|
||||
import { RetryLink } from '@apollo/client/link/retry';
|
||||
|
||||
export function createClient(base?: string) {
|
||||
if (!base) {
|
||||
throw new Error('Base must be passed into createClient!');
|
||||
}
|
||||
const urlHTTP = new URL(base);
|
||||
const urlWS = new URL(base);
|
||||
// Replace http with ws, preserving if its a secure connection eg. https => wss
|
||||
urlWS.protocol = urlWS.protocol.replace('http', 'ws');
|
||||
|
||||
const cache = new InMemoryCache({
|
||||
typePolicies: {
|
||||
Query: {},
|
||||
Account: {
|
||||
keyFields: false,
|
||||
fields: {
|
||||
balanceFormatted: {},
|
||||
},
|
||||
},
|
||||
Node: {
|
||||
keyFields: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const retryLink = new RetryLink({
|
||||
delay: {
|
||||
initial: 300,
|
||||
max: 10000,
|
||||
jitter: true,
|
||||
},
|
||||
});
|
||||
|
||||
const httpLink = new HttpLink({
|
||||
uri: urlHTTP.href,
|
||||
credentials: 'same-origin',
|
||||
});
|
||||
|
||||
const errorLink = onError(({ graphQLErrors, networkError }) => {
|
||||
console.log(graphQLErrors);
|
||||
console.log(networkError);
|
||||
});
|
||||
|
||||
return new ApolloClient({
|
||||
connectToDevTools: process.env['NODE_ENV'] === 'development',
|
||||
link: from([errorLink, retryLink, httpLink]),
|
||||
cache,
|
||||
});
|
||||
}
|
@ -1,7 +1,4 @@
|
||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
||||
import { useRoutes } from 'react-router-dom';
|
||||
import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment';
|
||||
import { createClient } from './lib/apollo-client';
|
||||
|
||||
import '../styles.scss';
|
||||
import { Navbar } from './components/navbar';
|
||||
@ -12,16 +9,10 @@ const AppRouter = () => useRoutes(routerConfig);
|
||||
|
||||
export function App() {
|
||||
return (
|
||||
<EnvironmentProvider>
|
||||
<ThemeContext.Provider value="light">
|
||||
<NetworkLoader createClient={createClient}>
|
||||
<div className="max-h-full min-h-full bg-white">
|
||||
<Navbar />
|
||||
<AppRouter />
|
||||
</div>
|
||||
</NetworkLoader>
|
||||
</ThemeContext.Provider>
|
||||
</EnvironmentProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,88 +0,0 @@
|
||||
import {
|
||||
ApolloClient,
|
||||
from,
|
||||
HttpLink,
|
||||
InMemoryCache,
|
||||
split,
|
||||
} from '@apollo/client';
|
||||
import { onError } from '@apollo/client/link/error';
|
||||
import { RetryLink } from '@apollo/client/link/retry';
|
||||
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
|
||||
import { createClient as createWSClient } from 'graphql-ws';
|
||||
import { getMainDefinition } from '@apollo/client/utilities';
|
||||
|
||||
export function createClient(base?: string) {
|
||||
if (!base) {
|
||||
throw new Error('Base must be passed into createClient!');
|
||||
}
|
||||
const urlHTTP = new URL(base);
|
||||
const urlWS = new URL(base);
|
||||
// Replace http with ws, preserving if its a secure connection eg. https => wss
|
||||
urlWS.protocol = urlWS.protocol.replace('http', 'ws');
|
||||
|
||||
const cache = new InMemoryCache({
|
||||
typePolicies: {
|
||||
Market: {
|
||||
merge: true,
|
||||
},
|
||||
Party: {
|
||||
merge: true,
|
||||
},
|
||||
Query: {},
|
||||
Account: {
|
||||
keyFields: false,
|
||||
fields: {
|
||||
balanceFormatted: {},
|
||||
},
|
||||
},
|
||||
Node: {
|
||||
keyFields: false,
|
||||
},
|
||||
Instrument: {
|
||||
keyFields: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const retryLink = new RetryLink({
|
||||
delay: {
|
||||
initial: 300,
|
||||
max: 10000,
|
||||
jitter: true,
|
||||
},
|
||||
});
|
||||
|
||||
const httpLink = new HttpLink({
|
||||
uri: urlHTTP.href,
|
||||
credentials: 'same-origin',
|
||||
});
|
||||
|
||||
const wsLink = new GraphQLWsLink(
|
||||
createWSClient({
|
||||
url: urlWS.href,
|
||||
})
|
||||
);
|
||||
|
||||
const splitLink = split(
|
||||
({ query }) => {
|
||||
const definition = getMainDefinition(query);
|
||||
return (
|
||||
definition.kind === 'OperationDefinition' &&
|
||||
definition.operation === 'subscription'
|
||||
);
|
||||
},
|
||||
wsLink,
|
||||
httpLink
|
||||
);
|
||||
|
||||
const errorLink = onError(({ graphQLErrors, networkError }) => {
|
||||
console.log(graphQLErrors);
|
||||
console.log(networkError);
|
||||
});
|
||||
|
||||
return new ApolloClient({
|
||||
connectToDevTools: process.env['NODE_ENV'] === 'development',
|
||||
link: from([errorLink, retryLink, splitLink]),
|
||||
cache,
|
||||
});
|
||||
}
|
@ -1,16 +1,47 @@
|
||||
import { StrictMode } from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
||||
import { EnvironmentProvider, NetworkLoader } from '@vegaprotocol/environment';
|
||||
|
||||
import App from './app/app';
|
||||
import type { InMemoryCacheConfig } from '@apollo/client';
|
||||
|
||||
const rootElement = document.getElementById('root');
|
||||
const root = rootElement && createRoot(rootElement);
|
||||
|
||||
const cache: InMemoryCacheConfig = {
|
||||
typePolicies: {
|
||||
Market: {
|
||||
merge: true,
|
||||
},
|
||||
Party: {
|
||||
merge: true,
|
||||
},
|
||||
Query: {},
|
||||
Account: {
|
||||
keyFields: false,
|
||||
fields: {
|
||||
balanceFormatted: {},
|
||||
},
|
||||
},
|
||||
Node: {
|
||||
keyFields: false,
|
||||
},
|
||||
Instrument: {
|
||||
keyFields: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
root?.render(
|
||||
<StrictMode>
|
||||
<BrowserRouter>
|
||||
<EnvironmentProvider>
|
||||
<ThemeContext.Provider value="light">
|
||||
<NetworkLoader cache={cache}>
|
||||
<App />
|
||||
</NetworkLoader>
|
||||
</ThemeContext.Provider>
|
||||
</EnvironmentProvider>
|
||||
</BrowserRouter>
|
||||
</StrictMode>
|
||||
);
|
||||
|
@ -11,7 +11,6 @@ import { AsyncRenderer, Button, Lozenge } from '@vegaprotocol/ui-toolkit';
|
||||
import type { EthereumConfig } from '@vegaprotocol/web3';
|
||||
import { useEthereumConfig, Web3Provider } from '@vegaprotocol/web3';
|
||||
import { ThemeContext, useThemeSwitcher, t } from '@vegaprotocol/react-helpers';
|
||||
import { createClient } from './lib/apollo-client';
|
||||
import { ENV } from './config/env';
|
||||
import { ContractsProvider } from './config/contracts/contracts-provider';
|
||||
import {
|
||||
@ -24,6 +23,7 @@ import { createConnectors } from './lib/web3-connectors';
|
||||
import { Web3Connector } from './components/web3-connector';
|
||||
import { EthWalletContainer } from './components/eth-wallet-container';
|
||||
import { useWeb3React } from '@web3-react/core';
|
||||
import type { InMemoryCacheConfig } from '@apollo/client';
|
||||
|
||||
const pageWrapperClasses = classnames(
|
||||
'min-h-screen w-screen',
|
||||
@ -96,10 +96,26 @@ function App() {
|
||||
}
|
||||
|
||||
const Wrapper = () => {
|
||||
const cache: InMemoryCacheConfig = {
|
||||
typePolicies: {
|
||||
Query: {},
|
||||
Account: {
|
||||
keyFields: false,
|
||||
fields: {
|
||||
balanceFormatted: {},
|
||||
},
|
||||
},
|
||||
Node: {
|
||||
keyFields: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
return (
|
||||
<EnvironmentProvider>
|
||||
<NetworkLoader createClient={createClient}>
|
||||
<NetworkLoader cache={cache}>
|
||||
<ContractsProvider>
|
||||
<App />
|
||||
</ContractsProvider>
|
||||
</NetworkLoader>
|
||||
</EnvironmentProvider>
|
||||
);
|
||||
|
@ -1,54 +0,0 @@
|
||||
import * as Sentry from '@sentry/react';
|
||||
import { ApolloClient, from, HttpLink, InMemoryCache } from '@apollo/client';
|
||||
import { onError } from '@apollo/client/link/error';
|
||||
import { RetryLink } from '@apollo/client/link/retry';
|
||||
|
||||
export function createClient(base?: string) {
|
||||
if (!base) {
|
||||
throw new Error('Base must be passed into createClient!');
|
||||
}
|
||||
const urlHTTP = new URL(base);
|
||||
const urlWS = new URL(base);
|
||||
// Replace http with ws, preserving if its a secure connection eg. https => wss
|
||||
urlWS.protocol = urlWS.protocol.replace('http', 'ws');
|
||||
|
||||
const cache = new InMemoryCache({
|
||||
typePolicies: {
|
||||
Query: {},
|
||||
Account: {
|
||||
keyFields: false,
|
||||
fields: {
|
||||
balanceFormatted: {},
|
||||
},
|
||||
},
|
||||
Node: {
|
||||
keyFields: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const retryLink = new RetryLink({
|
||||
delay: {
|
||||
initial: 300,
|
||||
max: 10000,
|
||||
jitter: true,
|
||||
},
|
||||
});
|
||||
|
||||
const httpLink = new HttpLink({
|
||||
uri: urlHTTP.href,
|
||||
credentials: 'same-origin',
|
||||
});
|
||||
|
||||
const errorLink = onError(({ graphQLErrors, networkError }) => {
|
||||
console.log(graphQLErrors);
|
||||
console.log(networkError);
|
||||
Sentry.captureException(graphQLErrors);
|
||||
});
|
||||
|
||||
return new ApolloClient({
|
||||
connectToDevTools: process.env['NODE_ENV'] === 'development',
|
||||
link: from([errorLink, retryLink, httpLink]),
|
||||
cache,
|
||||
});
|
||||
}
|
@ -3,14 +3,13 @@ import { Header } from './components/header';
|
||||
import { StatsManager } from '@vegaprotocol/network-stats';
|
||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
||||
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
||||
import { createClient } from './lib/apollo-client';
|
||||
|
||||
function App() {
|
||||
const [theme, toggleTheme] = useThemeSwitcher();
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={theme}>
|
||||
<NetworkLoader createClient={createClient}>
|
||||
<NetworkLoader>
|
||||
<div className="w-screen min-h-screen grid pb-6 bg-white text-neutral-900 dark:bg-black dark:text-neutral-100">
|
||||
<div className="layout-grid w-screen justify-self-center">
|
||||
<Header theme={theme} toggleTheme={toggleTheme} />
|
||||
|
@ -1,52 +0,0 @@
|
||||
import { ApolloClient, from, HttpLink, InMemoryCache } from '@apollo/client';
|
||||
import { onError } from '@apollo/client/link/error';
|
||||
import { RetryLink } from '@apollo/client/link/retry';
|
||||
|
||||
export function createClient(base?: string) {
|
||||
if (!base) {
|
||||
throw new Error('Base must be passed into createClient!');
|
||||
}
|
||||
const urlHTTP = new URL(base);
|
||||
const urlWS = new URL(base);
|
||||
// Replace http with ws, preserving if its a secure connection eg. https => wss
|
||||
urlWS.protocol = urlWS.protocol.replace('http', 'ws');
|
||||
|
||||
const cache = new InMemoryCache({
|
||||
typePolicies: {
|
||||
Query: {},
|
||||
Account: {
|
||||
keyFields: false,
|
||||
fields: {
|
||||
balanceFormatted: {},
|
||||
},
|
||||
},
|
||||
Node: {
|
||||
keyFields: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const retryLink = new RetryLink({
|
||||
delay: {
|
||||
initial: 300,
|
||||
max: 10000,
|
||||
jitter: true,
|
||||
},
|
||||
});
|
||||
|
||||
const httpLink = new HttpLink({
|
||||
uri: urlHTTP.href,
|
||||
credentials: 'same-origin',
|
||||
});
|
||||
|
||||
const errorLink = onError(({ graphQLErrors, networkError }) => {
|
||||
console.log(graphQLErrors);
|
||||
console.log(networkError);
|
||||
});
|
||||
|
||||
return new ApolloClient({
|
||||
connectToDevTools: process.env['NODE_ENV'] === 'development',
|
||||
link: from([errorLink, retryLink, httpLink]),
|
||||
cache,
|
||||
});
|
||||
}
|
@ -26,9 +26,148 @@ import {
|
||||
EnvironmentProvider,
|
||||
NetworkLoader,
|
||||
} from '@vegaprotocol/environment';
|
||||
import { createClient } from './lib/apollo-client';
|
||||
import { createConnectors } from './lib/web3-connectors';
|
||||
import { ENV } from './config/env';
|
||||
import type {
|
||||
FieldFunctionOptions,
|
||||
InMemoryCacheConfig,
|
||||
Reference,
|
||||
} from '@apollo/client';
|
||||
import sortBy from 'lodash/sortBy';
|
||||
import uniqBy from 'lodash/uniqBy';
|
||||
|
||||
import { deterministicShuffle } from './lib/deterministic-shuffle';
|
||||
import { addDecimal } from '@vegaprotocol/react-helpers';
|
||||
|
||||
const formatUintToNumber = (amount: string, decimals = 18) =>
|
||||
addDecimal(amount, decimals).toString();
|
||||
|
||||
const createReadField = (fieldName: string) => ({
|
||||
[`${fieldName}Formatted`]: {
|
||||
read(_: string, options: FieldFunctionOptions) {
|
||||
const amount = options.readField(fieldName) as string;
|
||||
return amount ? formatUintToNumber(amount) : '0';
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Create seed in memory. Validator list order will remain the same
|
||||
// until the page is refreshed.
|
||||
const VALIDATOR_RANDOMISER_SEED = (
|
||||
Math.floor(Math.random() * 1000) + 1
|
||||
).toString();
|
||||
|
||||
const cache: InMemoryCacheConfig = {
|
||||
typePolicies: {
|
||||
Query: {
|
||||
fields: {
|
||||
nodes: {
|
||||
// Merge function to make the validator list random but remain consistent
|
||||
// as the user navigates around the site. If the user refreshes the list
|
||||
// will be randomised.
|
||||
merge: (existing = [], incoming) => {
|
||||
// uniqBy will take the first of any matches
|
||||
const uniq = uniqBy([...incoming, ...existing], 'id');
|
||||
// sort result so that the input is consistent
|
||||
const sorted = sortBy(uniq, 'id');
|
||||
// randomise based on seed string
|
||||
const random = deterministicShuffle(
|
||||
VALIDATOR_RANDOMISER_SEED,
|
||||
sorted
|
||||
);
|
||||
return random;
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Account: {
|
||||
keyFields: false,
|
||||
fields: {
|
||||
balanceFormatted: {
|
||||
read(_: string, options: FieldFunctionOptions) {
|
||||
const balance = options.readField('balance');
|
||||
const asset = options.readField('asset');
|
||||
const decimals = options.readField('decimals', asset as Reference);
|
||||
if (typeof balance !== 'string') return '0';
|
||||
if (typeof decimals !== 'number') return '0';
|
||||
return balance && decimals
|
||||
? formatUintToNumber(balance, decimals)
|
||||
: '0';
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Delegation: {
|
||||
keyFields: false,
|
||||
// Only get full updates
|
||||
merge(_, incoming) {
|
||||
return incoming;
|
||||
},
|
||||
fields: {
|
||||
...createReadField('amount'),
|
||||
},
|
||||
},
|
||||
Reward: {
|
||||
keyFields: false,
|
||||
fields: {
|
||||
...createReadField('amount'),
|
||||
},
|
||||
},
|
||||
RewardPerAssetDetail: {
|
||||
keyFields: false,
|
||||
fields: {
|
||||
...createReadField('totalAmount'),
|
||||
},
|
||||
},
|
||||
Node: {
|
||||
keyFields: false,
|
||||
fields: {
|
||||
...createReadField('pendingStake'),
|
||||
...createReadField('stakedByOperator'),
|
||||
...createReadField('stakedByDelegates'),
|
||||
...createReadField('stakedTotal'),
|
||||
},
|
||||
},
|
||||
NodeData: {
|
||||
merge: (existing = {}, incoming) => {
|
||||
return { ...existing, ...incoming };
|
||||
},
|
||||
fields: {
|
||||
...createReadField('stakedTotal'),
|
||||
},
|
||||
},
|
||||
Party: {
|
||||
fields: {
|
||||
stake: {
|
||||
merge(existing, incoming) {
|
||||
return {
|
||||
...existing,
|
||||
...incoming,
|
||||
};
|
||||
},
|
||||
read(stake) {
|
||||
if (stake) {
|
||||
return {
|
||||
...stake,
|
||||
currentStakeAvailableFormatted: formatUintToNumber(
|
||||
stake.currentStakeAvailable
|
||||
),
|
||||
};
|
||||
}
|
||||
return stake;
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Withdrawal: {
|
||||
fields: {
|
||||
pendingOnForeignChain: {
|
||||
read: (isPending = false) => isPending,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const Web3Container = ({
|
||||
chainId,
|
||||
@ -129,7 +268,7 @@ const AppContainer = () => {
|
||||
function App() {
|
||||
return (
|
||||
<EnvironmentProvider>
|
||||
<NetworkLoader createClient={createClient}>
|
||||
<NetworkLoader cache={cache}>
|
||||
<AppContainer />
|
||||
</NetworkLoader>
|
||||
</EnvironmentProvider>
|
||||
|
@ -1,150 +0,0 @@
|
||||
import type { FieldFunctionOptions, Reference } from '@apollo/client';
|
||||
import { ApolloClient, from, HttpLink, InMemoryCache } from '@apollo/client';
|
||||
import { onError } from '@apollo/client/link/error';
|
||||
import { RetryLink } from '@apollo/client/link/retry';
|
||||
import { addDecimal } from '@vegaprotocol/react-helpers';
|
||||
import sortBy from 'lodash/sortBy';
|
||||
import uniqBy from 'lodash/uniqBy';
|
||||
|
||||
import { deterministicShuffle } from './deterministic-shuffle';
|
||||
|
||||
// Create seed in memory. Validator list order will remain the same
|
||||
// until the page is refreshed.
|
||||
const VALIDATOR_RANDOMISER_SEED = (
|
||||
Math.floor(Math.random() * 1000) + 1
|
||||
).toString();
|
||||
|
||||
export function createClient(base?: string) {
|
||||
if (!base) {
|
||||
throw new Error('Base must be passed into createClient!');
|
||||
}
|
||||
const formatUintToNumber = (amount: string, decimals = 18) =>
|
||||
addDecimal(amount, decimals).toString();
|
||||
|
||||
const createReadField = (fieldName: string) => ({
|
||||
[`${fieldName}Formatted`]: {
|
||||
read(_: string, options: FieldFunctionOptions) {
|
||||
const amount = options.readField(fieldName) as string;
|
||||
return amount ? formatUintToNumber(amount) : '0';
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const cache = new InMemoryCache({
|
||||
typePolicies: {
|
||||
Query: {
|
||||
fields: {
|
||||
nodes: {
|
||||
// Merge function to make the validator list random but remain consistent
|
||||
// as the user navigates around the site. If the user refreshes the list
|
||||
// will be randomised.
|
||||
merge: (existing = [], incoming) => {
|
||||
// uniqBy will take the first of any matches
|
||||
const uniq = uniqBy([...incoming, ...existing], 'id');
|
||||
// sort result so that the input is consistent
|
||||
const sorted = sortBy(uniq, 'id');
|
||||
// randomise based on seed string
|
||||
const random = deterministicShuffle(
|
||||
VALIDATOR_RANDOMISER_SEED,
|
||||
sorted
|
||||
);
|
||||
return random;
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Account: {
|
||||
keyFields: false,
|
||||
fields: {
|
||||
balanceFormatted: {
|
||||
read(_: string, options: FieldFunctionOptions) {
|
||||
const balance = options.readField('balance');
|
||||
const asset = options.readField('asset');
|
||||
const decimals = options.readField(
|
||||
'decimals',
|
||||
asset as Reference
|
||||
);
|
||||
if (typeof balance !== 'string') return '0';
|
||||
if (typeof decimals !== 'number') return '0';
|
||||
return balance && decimals
|
||||
? formatUintToNumber(balance, decimals)
|
||||
: '0';
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Delegation: {
|
||||
keyFields: false,
|
||||
// Only get full updates
|
||||
merge(_, incoming) {
|
||||
return incoming;
|
||||
},
|
||||
fields: {
|
||||
...createReadField('amount'),
|
||||
},
|
||||
},
|
||||
Reward: {
|
||||
keyFields: false,
|
||||
fields: {
|
||||
...createReadField('amount'),
|
||||
},
|
||||
},
|
||||
RewardPerAssetDetail: {
|
||||
keyFields: false,
|
||||
fields: {
|
||||
...createReadField('totalAmount'),
|
||||
},
|
||||
},
|
||||
Node: {
|
||||
keyFields: false,
|
||||
fields: {
|
||||
...createReadField('pendingStake'),
|
||||
...createReadField('stakedByOperator'),
|
||||
...createReadField('stakedByDelegates'),
|
||||
...createReadField('stakedTotal'),
|
||||
},
|
||||
},
|
||||
NodeData: {
|
||||
merge: (existing = {}, incoming) => {
|
||||
return { ...existing, ...incoming };
|
||||
},
|
||||
fields: {
|
||||
...createReadField('stakedTotal'),
|
||||
},
|
||||
},
|
||||
Withdrawal: {
|
||||
fields: {
|
||||
pendingOnForeignChain: {
|
||||
read: (isPending = false) => isPending,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const retryLink = new RetryLink({
|
||||
delay: {
|
||||
initial: 300,
|
||||
max: 10000,
|
||||
jitter: true,
|
||||
},
|
||||
});
|
||||
|
||||
const httpLink = new HttpLink({
|
||||
uri: base,
|
||||
credentials: 'same-origin',
|
||||
});
|
||||
|
||||
const errorLink = onError(({ graphQLErrors, networkError }) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(graphQLErrors);
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(networkError);
|
||||
});
|
||||
|
||||
return new ApolloClient({
|
||||
connectToDevTools: process.env['NODE_ENV'] === 'development',
|
||||
link: from([errorLink, retryLink, httpLink]),
|
||||
cache,
|
||||
});
|
||||
}
|
@ -219,7 +219,7 @@ describe('market states', { tags: '@smoke' }, function () {
|
||||
|
||||
states.forEach((marketState) => {
|
||||
describe(marketState, function () {
|
||||
before(function () {
|
||||
beforeEach(function () {
|
||||
cy.mockTradingPage(marketState);
|
||||
cy.mockGQLSubscription();
|
||||
cy.visit('/#/markets/market-0');
|
||||
|
@ -1,8 +1,9 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import { useEagerConnect } from '@vegaprotocol/wallet';
|
||||
import { NetworkLoader } from '@vegaprotocol/environment';
|
||||
import { Connectors } from '../../lib/vega-connectors';
|
||||
import { createClient } from '../../lib/apollo-client';
|
||||
import type { InMemoryCacheConfig } from '@apollo/client';
|
||||
|
||||
interface AppLoaderProps {
|
||||
children: ReactNode;
|
||||
@ -15,6 +16,55 @@ interface AppLoaderProps {
|
||||
export function AppLoader({ children }: AppLoaderProps) {
|
||||
// Get keys from vega wallet immediately
|
||||
useEagerConnect(Connectors);
|
||||
|
||||
return <NetworkLoader createClient={createClient}>{children}</NetworkLoader>;
|
||||
const cache: InMemoryCacheConfig = useMemo(
|
||||
() => ({
|
||||
typePolicies: {
|
||||
Account: {
|
||||
keyFields: false,
|
||||
fields: {
|
||||
balanceFormatted: {},
|
||||
},
|
||||
},
|
||||
Instrument: {
|
||||
keyFields: false,
|
||||
},
|
||||
TradableInstrument: {
|
||||
keyFields: ['instrument'],
|
||||
},
|
||||
Product: {
|
||||
keyFields: ['settlementAsset', ['id']],
|
||||
},
|
||||
MarketData: {
|
||||
keyFields: ['market', ['id']],
|
||||
},
|
||||
Node: {
|
||||
keyFields: false,
|
||||
},
|
||||
Withdrawal: {
|
||||
fields: {
|
||||
pendingOnForeignChain: {
|
||||
read: (isPending = false) => isPending,
|
||||
},
|
||||
},
|
||||
},
|
||||
ERC20: {
|
||||
keyFields: ['contractAddress'],
|
||||
},
|
||||
PositionUpdate: {
|
||||
keyFields: false,
|
||||
},
|
||||
AccountUpdate: {
|
||||
keyFields: false,
|
||||
},
|
||||
Party: {
|
||||
keyFields: false,
|
||||
},
|
||||
Fees: {
|
||||
keyFields: false,
|
||||
},
|
||||
},
|
||||
}),
|
||||
[]
|
||||
);
|
||||
return <NetworkLoader cache={cache}>{children}</NetworkLoader>;
|
||||
}
|
||||
|
@ -1,117 +0,0 @@
|
||||
import {
|
||||
ApolloClient,
|
||||
ApolloLink,
|
||||
split,
|
||||
from,
|
||||
HttpLink,
|
||||
InMemoryCache,
|
||||
} from '@apollo/client';
|
||||
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
|
||||
import { getMainDefinition } from '@apollo/client/utilities';
|
||||
import { onError } from '@apollo/client/link/error';
|
||||
import { RetryLink } from '@apollo/client/link/retry';
|
||||
import { createClient as createWSClient } from 'graphql-ws';
|
||||
|
||||
export function createClient(base?: string) {
|
||||
if (!base) {
|
||||
throw new Error('Base must be passed into createClient!');
|
||||
}
|
||||
const urlHTTP = new URL(base);
|
||||
const urlWS = new URL(base);
|
||||
// Replace http with ws, preserving if its a secure connection eg. https => wss
|
||||
urlWS.protocol = urlWS.protocol.replace('http', 'ws');
|
||||
|
||||
const cache = new InMemoryCache({
|
||||
typePolicies: {
|
||||
Account: {
|
||||
keyFields: false,
|
||||
fields: {
|
||||
balanceFormatted: {},
|
||||
},
|
||||
},
|
||||
Instrument: {
|
||||
keyFields: false,
|
||||
},
|
||||
TradableInstrument: {
|
||||
keyFields: ['instrument'],
|
||||
},
|
||||
Product: {
|
||||
keyFields: ['settlementAsset', ['id']],
|
||||
},
|
||||
MarketData: {
|
||||
keyFields: ['market', ['id']],
|
||||
},
|
||||
Node: {
|
||||
keyFields: false,
|
||||
},
|
||||
Withdrawal: {
|
||||
fields: {
|
||||
pendingOnForeignChain: {
|
||||
read: (isPending = false) => isPending,
|
||||
},
|
||||
},
|
||||
},
|
||||
ERC20: {
|
||||
keyFields: ['contractAddress'],
|
||||
},
|
||||
PositionUpdate: {
|
||||
keyFields: false,
|
||||
},
|
||||
AccountUpdate: {
|
||||
keyFields: false,
|
||||
},
|
||||
Party: {
|
||||
keyFields: false,
|
||||
},
|
||||
Fees: {
|
||||
keyFields: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const retryLink = new RetryLink({
|
||||
delay: {
|
||||
initial: 300,
|
||||
max: 10000,
|
||||
jitter: true,
|
||||
},
|
||||
});
|
||||
|
||||
const httpLink = new HttpLink({
|
||||
uri: urlHTTP.href,
|
||||
credentials: 'same-origin',
|
||||
});
|
||||
|
||||
const wsLink = process.browser
|
||||
? new GraphQLWsLink(
|
||||
createWSClient({
|
||||
url: urlWS.href,
|
||||
})
|
||||
)
|
||||
: new ApolloLink((operation, forward) => forward(operation));
|
||||
|
||||
const splitLink = process.browser
|
||||
? split(
|
||||
({ query }) => {
|
||||
const definition = getMainDefinition(query);
|
||||
return (
|
||||
definition.kind === 'OperationDefinition' &&
|
||||
definition.operation === 'subscription'
|
||||
);
|
||||
},
|
||||
wsLink,
|
||||
httpLink
|
||||
)
|
||||
: httpLink;
|
||||
|
||||
const errorLink = onError(({ graphQLErrors, networkError }) => {
|
||||
console.log(graphQLErrors);
|
||||
console.log(networkError);
|
||||
});
|
||||
|
||||
return new ApolloClient({
|
||||
connectToDevTools: process.env['NODE_ENV'] === 'development',
|
||||
link: from([errorLink, retryLink, splitLink]),
|
||||
cache,
|
||||
});
|
||||
}
|
3
libs/apollo-client/.babelrc
Normal file
3
libs/apollo-client/.babelrc
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"presets": [["@nrwl/web/babel", { "useBuiltIns": "usage" }]]
|
||||
}
|
18
libs/apollo-client/.eslintrc.json
Normal file
18
libs/apollo-client/.eslintrc.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"extends": ["../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
11
libs/apollo-client/README.md
Normal file
11
libs/apollo-client/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# apollo-client
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `nx test apollo-client` to execute the unit tests via [Jest](https://jestjs.io).
|
||||
|
||||
## Running lint
|
||||
|
||||
Run `nx lint apollo-client` to execute the lint via [ESLint](https://eslint.org/).
|
15
libs/apollo-client/jest.config.ts
Normal file
15
libs/apollo-client/jest.config.ts
Normal file
@ -0,0 +1,15 @@
|
||||
/* eslint-disable */
|
||||
export default {
|
||||
displayName: 'apollo-client',
|
||||
preset: '../../jest.preset.js',
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
tsconfig: '<rootDir>/tsconfig.spec.json',
|
||||
},
|
||||
},
|
||||
transform: {
|
||||
'^.+\\.[tj]sx?$': 'ts-jest',
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
|
||||
coverageDirectory: '../../coverage/libs/apollo-client',
|
||||
};
|
4
libs/apollo-client/package.json
Normal file
4
libs/apollo-client/package.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "@vegaprotocol/apollo-client",
|
||||
"version": "0.0.1"
|
||||
}
|
43
libs/apollo-client/project.json
Normal file
43
libs/apollo-client/project.json
Normal file
@ -0,0 +1,43 @@
|
||||
{
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "libs/apollo-client/src",
|
||||
"projectType": "library",
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nrwl/web:rollup",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"options": {
|
||||
"outputPath": "dist/libs/apollo-client",
|
||||
"tsConfig": "libs/apollo-client/tsconfig.lib.json",
|
||||
"project": "libs/apollo-client/package.json",
|
||||
"entryFile": "libs/apollo-client/src/index.ts",
|
||||
"external": ["react/jsx-runtime"],
|
||||
"rollupConfig": "@nrwl/react/plugins/bundle-rollup",
|
||||
"compiler": "babel",
|
||||
"assets": [
|
||||
{
|
||||
"glob": "libs/apollo-client/README.md",
|
||||
"input": ".",
|
||||
"output": "."
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nrwl/linter:eslint",
|
||||
"outputs": ["{options.outputFile}"],
|
||||
"options": {
|
||||
"lintFilePatterns": ["libs/apollo-client/**/*.ts"]
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nrwl/jest:jest",
|
||||
"outputs": ["coverage/libs/apollo-client"],
|
||||
"options": {
|
||||
"jestConfig": "libs/apollo-client/jest.config.ts",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
}
|
1
libs/apollo-client/src/index.ts
Normal file
1
libs/apollo-client/src/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './lib/apollo-client';
|
@ -1,3 +1,4 @@
|
||||
import type { InMemoryCacheConfig } from '@apollo/client';
|
||||
import {
|
||||
ApolloClient,
|
||||
from,
|
||||
@ -11,10 +12,11 @@ import { getMainDefinition } from '@apollo/client/utilities';
|
||||
import { createClient as createWSClient } from 'graphql-ws';
|
||||
import { onError } from '@apollo/client/link/error';
|
||||
import { RetryLink } from '@apollo/client/link/retry';
|
||||
import ApolloLinkTimeout from 'apollo-link-timeout';
|
||||
|
||||
const isBrowser = typeof window !== 'undefined';
|
||||
|
||||
export default function createClient(base?: string) {
|
||||
export function createClient(base?: string, cacheConfig?: InMemoryCacheConfig) {
|
||||
if (!base) {
|
||||
throw new Error('Base must be passed into createClient!');
|
||||
}
|
||||
@ -22,7 +24,7 @@ export default function createClient(base?: string) {
|
||||
const urlWS = new URL(base);
|
||||
// Replace http with ws, preserving if its a secure connection eg. https => wss
|
||||
urlWS.protocol = urlWS.protocol.replace('http', 'ws');
|
||||
|
||||
const timeoutLink = new ApolloLinkTimeout(10000);
|
||||
const retryLink = new RetryLink({
|
||||
delay: {
|
||||
initial: 300,
|
||||
@ -64,7 +66,7 @@ export default function createClient(base?: string) {
|
||||
});
|
||||
|
||||
return new ApolloClient({
|
||||
link: from([errorLink, retryLink, splitLink]),
|
||||
cache: new InMemoryCache(),
|
||||
link: from([errorLink, timeoutLink, retryLink, splitLink]),
|
||||
cache: new InMemoryCache(cacheConfig),
|
||||
});
|
||||
}
|
19
libs/apollo-client/tsconfig.json
Normal file
19
libs/apollo-client/tsconfig.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
],
|
||||
"compilerOptions": {
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
}
|
||||
}
|
10
libs/apollo-client/tsconfig.lib.json
Normal file
10
libs/apollo-client/tsconfig.lib.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"declaration": true,
|
||||
"types": []
|
||||
},
|
||||
"include": ["**/*.ts"],
|
||||
"exclude": ["jest.config.ts", "**/*.spec.ts"]
|
||||
}
|
20
libs/apollo-client/tsconfig.spec.json
Normal file
20
libs/apollo-client/tsconfig.spec.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"include": [
|
||||
"jest.config.ts",
|
||||
"**/*.test.ts",
|
||||
"**/*.spec.ts",
|
||||
"**/*.test.tsx",
|
||||
"**/*.spec.tsx",
|
||||
"**/*.test.js",
|
||||
"**/*.spec.js",
|
||||
"**/*.test.jsx",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
@ -3,8 +3,11 @@ import { ApolloProvider } from '@apollo/client';
|
||||
import { useEnvironment } from '../../hooks';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { NetworkLoader } from './network-loader';
|
||||
import { createClient } from '@vegaprotocol/apollo-client';
|
||||
import { createMockClient } from 'mock-apollo-client';
|
||||
|
||||
jest.mock('@apollo/client');
|
||||
jest.mock('@vegaprotocol/apollo-client');
|
||||
jest.mock('../../hooks');
|
||||
|
||||
// @ts-ignore Typescript doesn't recognise mocked instances
|
||||
@ -15,15 +18,6 @@ ApolloProvider.mockImplementation(({ children }: { children: ReactNode }) => {
|
||||
const SKELETON_TEXT = 'LOADING';
|
||||
const SUCCESS_TEXT = 'LOADED';
|
||||
|
||||
const createClient = jest.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
createClient.mockReset();
|
||||
createClient.mockImplementation(() => {
|
||||
return jest.fn();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Network loader', () => {
|
||||
it('renders a skeleton when there is no vega url in the environment', () => {
|
||||
// @ts-ignore Typescript doesn't recognise mocked instances
|
||||
@ -32,9 +26,7 @@ describe('Network loader', () => {
|
||||
}));
|
||||
|
||||
render(
|
||||
<NetworkLoader skeleton={SKELETON_TEXT} createClient={createClient}>
|
||||
{SUCCESS_TEXT}
|
||||
</NetworkLoader>
|
||||
<NetworkLoader skeleton={SKELETON_TEXT}>{SUCCESS_TEXT}</NetworkLoader>
|
||||
);
|
||||
|
||||
expect(screen.getByText(SKELETON_TEXT)).toBeInTheDocument();
|
||||
@ -42,20 +34,19 @@ describe('Network loader', () => {
|
||||
expect(createClient).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('renders the child components wrapped in an apollo provider when the environment has a vega url', () => {
|
||||
it('renders the child components wrapped in an apollo provider when the environment has a vega url', async () => {
|
||||
// @ts-ignore -- ts does not seem to infer this type correctly
|
||||
createClient.mockReturnValueOnce(createMockClient());
|
||||
|
||||
// @ts-ignore Typescript doesn't recognise mocked instances
|
||||
useEnvironment.mockImplementation(() => ({
|
||||
VEGA_URL: 'http://vega.node',
|
||||
}));
|
||||
|
||||
render(
|
||||
<NetworkLoader skeleton={SKELETON_TEXT} createClient={createClient}>
|
||||
{SUCCESS_TEXT}
|
||||
</NetworkLoader>
|
||||
<NetworkLoader skeleton={SKELETON_TEXT}>{SUCCESS_TEXT}</NetworkLoader>
|
||||
);
|
||||
|
||||
expect(() => screen.getByText(SKELETON_TEXT)).toThrow();
|
||||
expect(screen.getByText(SUCCESS_TEXT)).toBeInTheDocument();
|
||||
expect(createClient).toHaveBeenCalledWith('http://vega.node');
|
||||
expect(createClient).toHaveBeenCalledWith('http://vega.node', undefined);
|
||||
expect(await screen.findByText(SUCCESS_TEXT)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
@ -1,28 +1,29 @@
|
||||
import { useMemo } from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import type { ApolloClient } from '@apollo/client';
|
||||
import type { InMemoryCacheConfig } from '@apollo/client';
|
||||
import { ApolloProvider } from '@apollo/client';
|
||||
import { useEnvironment } from '../../hooks';
|
||||
import { createClient } from '@vegaprotocol/apollo-client';
|
||||
|
||||
type NetworkLoaderProps<T> = {
|
||||
type NetworkLoaderProps = {
|
||||
children?: ReactNode;
|
||||
skeleton?: ReactNode;
|
||||
createClient: (url: string) => ApolloClient<T>;
|
||||
cache?: InMemoryCacheConfig;
|
||||
};
|
||||
|
||||
export function NetworkLoader<T>({
|
||||
export function NetworkLoader({
|
||||
skeleton,
|
||||
children,
|
||||
createClient,
|
||||
}: NetworkLoaderProps<T>) {
|
||||
cache,
|
||||
}: NetworkLoaderProps) {
|
||||
const { VEGA_URL } = useEnvironment();
|
||||
|
||||
const client = useMemo(() => {
|
||||
if (VEGA_URL) {
|
||||
return createClient(VEGA_URL);
|
||||
return createClient(VEGA_URL, cache);
|
||||
}
|
||||
return undefined;
|
||||
}, [VEGA_URL, createClient]);
|
||||
}, [VEGA_URL, cache]);
|
||||
|
||||
if (!client) {
|
||||
return (
|
||||
|
@ -2,10 +2,10 @@ import type { ReactNode } from 'react';
|
||||
import { ApolloProvider } from '@apollo/client';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
import type { NodeData } from '../../types';
|
||||
import type createClient from '../../utils/apollo-client';
|
||||
import { LayoutRow } from './layout-row';
|
||||
import { LayoutCell } from './layout-cell';
|
||||
import { NodeBlockHeight } from './node-block-height';
|
||||
import type { createClient } from '@vegaprotocol/apollo-client';
|
||||
|
||||
type NodeStatsContentProps = {
|
||||
data?: NodeData;
|
||||
|
@ -2,11 +2,11 @@
|
||||
// workaround based on: https://github.com/facebook/react/issues/11565
|
||||
import type { ComponentProps, ReactNode } from 'react';
|
||||
import { renderHook } from '@testing-library/react';
|
||||
import createClient from '../utils/apollo-client';
|
||||
import { createClient } from '@vegaprotocol/apollo-client';
|
||||
import { useEnvironment, EnvironmentProvider } from './use-environment';
|
||||
import { Networks } from '../types';
|
||||
import createMockClient from './mocks/apollo-client';
|
||||
jest.mock('../utils/apollo-client');
|
||||
jest.mock('@vegaprotocol/apollo-client');
|
||||
|
||||
jest.mock('react-dom', () => ({
|
||||
...jest.requireActual('react-dom'),
|
||||
|
@ -2,14 +2,14 @@
|
||||
// workaround based on: https://github.com/facebook/react/issues/11565
|
||||
import type { ComponentProps, ReactNode } from 'react';
|
||||
import { renderHook, waitFor, act } from '@testing-library/react';
|
||||
import createClient from '../utils/apollo-client';
|
||||
import { createClient } from '@vegaprotocol/apollo-client';
|
||||
import { useEnvironment, EnvironmentProvider } from './use-environment';
|
||||
import { Networks, ErrorType } from '../types';
|
||||
import type { MockRequestConfig } from './mocks/apollo-client';
|
||||
import createMockClient from './mocks/apollo-client';
|
||||
import { getErrorByType } from '../utils/validate-node';
|
||||
|
||||
jest.mock('../utils/apollo-client');
|
||||
jest.mock('@vegaprotocol/apollo-client');
|
||||
|
||||
jest.mock('react-dom', () => ({
|
||||
...jest.requireActual('react-dom'),
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { renderHook, act } from '@testing-library/react';
|
||||
import { ApolloClient } from '@apollo/client';
|
||||
import createClient from '../utils/apollo-client';
|
||||
import { createClient } from '@vegaprotocol/apollo-client';
|
||||
import { useNodes } from './use-nodes';
|
||||
import createMockClient, {
|
||||
getMockStatisticsResult,
|
||||
} from './mocks/apollo-client';
|
||||
import { waitFor } from '@testing-library/react';
|
||||
|
||||
jest.mock('../utils/apollo-client');
|
||||
jest.mock('@vegaprotocol/apollo-client');
|
||||
|
||||
const MOCK_DURATION = 1073;
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
import type { Dispatch } from 'react';
|
||||
import { useState, useEffect, useReducer } from 'react';
|
||||
import { produce } from 'immer';
|
||||
import type createClient from '../utils/apollo-client';
|
||||
import { initializeNode } from '../utils/initialize-node';
|
||||
import type { NodeData, Configuration } from '../types';
|
||||
import type { createClient } from '@vegaprotocol/apollo-client';
|
||||
|
||||
type StatisticsPayload = {
|
||||
block: NodeData['block']['value'];
|
||||
|
@ -1,9 +1,9 @@
|
||||
import createClient from './apollo-client';
|
||||
import { StatisticsDocument, BlockTimeDocument } from './__generated__/Node';
|
||||
import type {
|
||||
StatisticsQuery,
|
||||
BlockTimeSubscription,
|
||||
} from './__generated__/Node';
|
||||
import { createClient } from '@vegaprotocol/apollo-client';
|
||||
|
||||
type Callbacks = {
|
||||
onStatsSuccess: (data: StatisticsQuery) => void;
|
||||
|
@ -44,6 +44,7 @@
|
||||
"allotment": "^1.14.5",
|
||||
"alpha-lyrae": "vegaprotocol/alpha-lyrae",
|
||||
"apollo": "^2.33.9",
|
||||
"apollo-link-timeout": "^4.0.0",
|
||||
"bignumber.js": "^9.0.2",
|
||||
"buffer": "^6.0.3",
|
||||
"classnames": "^2.3.1",
|
||||
|
@ -17,6 +17,7 @@
|
||||
"resolveJsonModule": true,
|
||||
"paths": {
|
||||
"@vegaprotocol/accounts": ["libs/accounts/src/index.ts"],
|
||||
"@vegaprotocol/apollo-client": ["libs/apollo-client/src/index.ts"],
|
||||
"@vegaprotocol/assets": ["libs/assets/src/index.ts"],
|
||||
"@vegaprotocol/candles-chart": ["libs/candles-chart/src/index.ts"],
|
||||
"@vegaprotocol/cypress": ["libs/cypress/src/index.ts"],
|
||||
|
@ -2,6 +2,7 @@
|
||||
"version": 2,
|
||||
"projects": {
|
||||
"accounts": "libs/accounts",
|
||||
"apollo-client": "libs/apollo-client",
|
||||
"assets": "libs/assets",
|
||||
"candles-chart": "libs/candles-chart",
|
||||
"console-lite": "apps/console-lite",
|
||||
|
@ -7985,6 +7985,11 @@ apollo-link-http@^1.5.5:
|
||||
apollo-link-http-common "^0.2.16"
|
||||
tslib "^1.9.3"
|
||||
|
||||
apollo-link-timeout@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/apollo-link-timeout/-/apollo-link-timeout-4.0.0.tgz#3e255bcced6a6babdcc080b1919dd958c036e235"
|
||||
integrity sha512-2tZsNvmbsAHunWSsGi+URLMQSDoSU0NRDJeYicX/eB7J94QXydgvZOG4FCsgU5hY0dhUrPrLCotcpJjvOOfSlA==
|
||||
|
||||
apollo-link@^1.2.14, apollo-link@^1.2.3:
|
||||
version "1.2.14"
|
||||
resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.14.tgz#3feda4b47f9ebba7f4160bef8b977ba725b684d9"
|
||||
|
Loading…
Reference in New Issue
Block a user