fix(trading,explorer,governance): consistent zustand usage (#3133)

This commit is contained in:
Matthew Russell 2023-03-10 06:01:51 -08:00 committed by GitHub
parent 52183555a9
commit 1098accb84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 152 additions and 148 deletions

View File

@ -21,7 +21,7 @@ type NavStore = {
hide: () => void;
};
export const useNavStore = create<NavStore>((set, get) => ({
export const useNavStore = create<NavStore>()((set, get) => ({
open: false,
toggle: () => set({ open: !get().open }),
hide: () => set({ open: false }),

View File

@ -9,26 +9,28 @@ export type PendingTxsStore = {
resetPendingTxs: () => void;
};
export const usePendingBalancesStore = create<PendingTxsStore>((set, get) => ({
pendingBalances: [],
addPendingTxs: (event: Event[]) => {
set({
pendingBalances: uniqBy(
[...get().pendingBalances, ...event],
'transactionHash'
),
});
},
removePendingTx: (event: Event) => {
set({
pendingBalances: [
...get().pendingBalances.filter(
({ transactionHash }) => transactionHash !== event.transactionHash
export const usePendingBalancesStore = create<PendingTxsStore>()(
(set, get) => ({
pendingBalances: [],
addPendingTxs: (event: Event[]) => {
set({
pendingBalances: uniqBy(
[...get().pendingBalances, ...event],
'transactionHash'
),
],
});
},
resetPendingTxs: () => {
set({ pendingBalances: [] });
},
}));
});
},
removePendingTx: (event: Event) => {
set({
pendingBalances: [
...get().pendingBalances.filter(
({ transactionHash }) => transactionHash !== event.transactionHash
),
],
});
},
resetPendingTxs: () => {
set({ pendingBalances: [] });
},
})
);

View File

@ -38,7 +38,7 @@ export interface RefreshBalances {
vestingAssociatedBalance: BigNumber;
}
export const useBalances = create<BalancesStore>((set) => ({
export const useBalances = create<BalancesStore>()((set) => ({
associationBreakdown: {
stakingAssociations: {},
vestingAssociations: {},

View File

@ -1,7 +1,7 @@
import { toBigNum } from '@vegaprotocol/utils';
import type { TrancheServiceResponse } from '@vegaprotocol/smart-contracts';
import type BigNumber from 'bignumber.js';
import create from 'zustand';
import { create } from 'zustand';
import { ENV } from '../../config';
export interface Tranche {
@ -36,7 +36,7 @@ export type TranchesStore = {
const secondsToDate = (seconds: number) => new Date(seconds * 1000);
export const useTranches = create<TranchesStore>((set) => ({
export const useTranches = create<TranchesStore>()((set) => ({
tranches: null,
loading: false,
error: null,

View File

@ -1,5 +1,4 @@
import type ethers from 'ethers';
import type { GetState, SetState } from 'zustand';
import { create } from 'zustand';
export interface TxData {
@ -16,27 +15,25 @@ interface TransactionStore {
remove: (tx: TxData) => void;
}
export const useTransactionStore = create(
(set: SetState<TransactionStore>, get: GetState<TransactionStore>) => ({
transactions: [],
add: (tx) => {
const { transactions } = get();
set({ transactions: [...transactions, tx] });
},
update: (tx) => {
const { transactions } = get();
set({
transactions: [
...transactions.filter((t) => t.tx.hash !== tx.tx.hash),
tx,
],
});
},
remove: (tx) => {
const { transactions } = get();
set({
transactions: transactions.filter((t) => t.tx.hash !== tx.tx.hash),
});
},
})
);
export const useTransactionStore = create<TransactionStore>()((set, get) => ({
transactions: [],
add: (tx) => {
const { transactions } = get();
set({ transactions: [...transactions, tx] });
},
update: (tx) => {
const { transactions } = get();
set({
transactions: [
...transactions.filter((t) => t.tx.hash !== tx.tx.hash),
tx,
],
});
},
remove: (tx) => {
const { transactions } = get();
set({
transactions: transactions.filter((t) => t.tx.hash !== tx.tx.hash),
});
},
}));

View File

@ -15,7 +15,7 @@ interface PageTitleStore {
updateTitle: (title: string) => void;
}
export const useGlobalStore = create<GlobalStore>((set) => ({
export const useGlobalStore = create<GlobalStore>()((set) => ({
nodeSwitcherDialog: false,
marketId: LocalStorage.getItem('marketId') || null,
shouldDisplayWelcomeDialog: false,

View File

@ -11,7 +11,7 @@ interface Actions {
open: (open?: boolean) => void;
}
export const useTransferDialog = create<State & Actions>((set) => ({
export const useTransferDialog = create<State & Actions>()((set) => ({
isOpen: false,
open: (open = true) => {
set(() => ({ isOpen: open }));

View File

@ -9,4 +9,4 @@ type HeaderStore = {
[url: string]: HeaderEntry | undefined;
};
export const useHeaderStore = create<HeaderStore>(() => ({}));
export const useHeaderStore = create<HeaderStore>()(() => ({}));

View File

@ -20,7 +20,7 @@ export type AssetDetailsDialogStore = {
open: (id: string, trigger?: HTMLElement | null, asJson?: boolean) => void;
};
export const useAssetDetailsDialogStore = create<AssetDetailsDialogStore>(
export const useAssetDetailsDialogStore = create<AssetDetailsDialogStore>()(
(set) => ({
isOpen: false,
id: '',

View File

@ -15,7 +15,7 @@ interface Actions {
close: () => void;
}
export const useDepositDialog = create<State & Actions>((set) => ({
export const useDepositDialog = create<State & Actions>()((set) => ({
isOpen: false,
assetId: undefined,
open: (assetId) => set(() => ({ assetId, isOpen: true })),

View File

@ -1,18 +0,0 @@
import { act } from 'react-dom/test-utils';
const zu = jest.requireActual('zustand'); // if using jest
// a variable to hold reset functions for all stores declared in the app
const storeResetFns = new Set();
// when creating a store, we get its initial state, create a reset function and add it in the set
export const create = (createState) => {
const store = zu.create(createState);
const initialState = store.getState();
storeResetFns.add(() => store.setState(initialState, true));
return store;
};
// Reset all stores after each test run
beforeEach(() => {
act(() => storeResetFns.forEach((resetFn) => resetFn()));
});

View File

@ -0,0 +1,21 @@
import type { StateCreator } from 'zustand';
import { act } from 'react-dom/test-utils';
const { create: actualCreate } = jest.requireActual('zustand'); // if using jest
// a variable to hold reset functions for all stores declared in the app
const storeResetFns = new Set<() => void>();
// when creating a store, we get its initial state, create a reset function and add it in the set
export const create =
() =>
<S>(createState: StateCreator<S>) => {
const store = actualCreate(createState);
const initialState = store.getState();
storeResetFns.add(() => store.setState(initialState, true));
return store;
};
// Reset all stores after each test run
beforeEach(() => {
act(() => storeResetFns.forEach((resetFn) => resetFn()));
});

View File

@ -34,7 +34,7 @@ export type EnvStore = Env & Actions;
export const STORAGE_KEY = 'vega_url';
const SUBSCRIPTION_TIMEOUT = 3000;
export const useEnvironment = create<EnvStore>((set, get) => ({
export const useEnvironment = create<EnvStore>()((set, get) => ({
...compileEnvVars(),
nodes: [],
status: 'default',

View File

@ -17,7 +17,8 @@
"**/*.test.js",
"**/*.spec.jsx",
"**/*.test.jsx",
"jest.config.ts"
"jest.config.ts",
"__mocks__"
],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}

View File

@ -77,7 +77,7 @@ const randomToast = (): Toast => {
};
type PriceStore = { price: number; setPrice: (p: number) => void };
const usePrice = create<PriceStore>((set) => ({
const usePrice = create<PriceStore>()((set) => ({
price: 0,
setPrice: (p) => set((state) => ({ price: p })),
}));

View File

@ -47,8 +47,8 @@ type Actions = {
type ToastsStore = State & Actions;
export const useToasts = create(
immer<ToastsStore>((set, get) => ({
export const useToasts = create<ToastsStore>()(
immer((set) => ({
toasts: {},
count: 0,
add: (toast) =>

View File

@ -1,18 +0,0 @@
import { act } from 'react-dom/test-utils';
const zu = jest.requireActual('zustand'); // if using jest
// a variable to hold reset functions for all stores declared in the app
const storeResetFns = new Set();
// when creating a store, we get its initial state, create a reset function and add it in the set
export const create = (createState) => {
const store = zu.create(createState);
const initialState = store.getState();
storeResetFns.add(() => store.setState(initialState, true));
return store;
};
// Reset all stores after each test run
beforeEach(() => {
act(() => storeResetFns.forEach((resetFn) => resetFn()));
});

View File

@ -0,0 +1,21 @@
import type { StateCreator } from 'zustand';
import { act } from 'react-dom/test-utils';
const { create: actualCreate } = jest.requireActual('zustand'); // if using jest
// a variable to hold reset functions for all stores declared in the app
const storeResetFns = new Set<() => void>();
// when creating a store, we get its initial state, create a reset function and add it in the set
export const create =
() =>
<S>(createState: StateCreator<S>) => {
const store = actualCreate(createState);
const initialState = store.getState();
storeResetFns.add(() => store.setState(initialState, true));
return store;
};
// Reset all stores after each test run
beforeEach(() => {
act(() => storeResetFns.forEach((resetFn) => resetFn()));
});

View File

@ -8,8 +8,11 @@ import {
import type { MockedResponse } from '@apollo/client/testing';
import { MockedProvider } from '@apollo/client/testing';
import { VegaWalletProvider } from '../provider';
import { VegaConnectDialog, CLOSE_DELAY } from './connect-dialog';
import type { VegaWalletDialogStore } from './connect-dialog';
import {
VegaConnectDialog,
CLOSE_DELAY,
useVegaWalletDialogStore,
} from './connect-dialog';
import type { VegaConnectDialogProps } from '..';
import {
ClientErrors,
@ -24,11 +27,6 @@ import { ChainIdDocument } from '@vegaprotocol/react-helpers';
const mockUpdateDialogOpen = jest.fn();
const mockCloseVegaDialog = jest.fn();
const mockStoreObj: Partial<VegaWalletDialogStore> = {
updateVegaWalletDialog: mockUpdateDialogOpen,
closeVegaWalletDialog: mockCloseVegaDialog,
vegaWalletDialogOpen: true,
};
jest.mock('@vegaprotocol/environment');
@ -44,11 +42,6 @@ useEnvironment.mockImplementation(() => ({
HOSTED_WALLET_URL: mockHostedWalletUrl,
}));
jest.mock('zustand', () => ({
create: () => (storeGetter: (store: VegaWalletDialogStore) => unknown) =>
storeGetter(mockStoreObj as VegaWalletDialogStore),
}));
let defaultProps: VegaConnectDialogProps;
const INITIAL_KEY = 'some-key';
@ -66,6 +59,12 @@ beforeEach(() => {
defaultProps = {
connectors,
};
useVegaWalletDialogStore.setState({
updateVegaWalletDialog: mockUpdateDialogOpen,
closeVegaWalletDialog: mockCloseVegaDialog,
vegaWalletDialogOpen: true,
});
});
const mockVegaWalletUrl = 'http://mock.wallet.com';

View File

@ -37,7 +37,7 @@ export interface VegaConnectDialogProps {
onChangeOpen?: (open: boolean) => void;
}
export const useVegaWalletDialogStore = create<VegaWalletDialogStore>(
export const useVegaWalletDialogStore = create<VegaWalletDialogStore>()(
(set) => ({
vegaWalletDialogOpen: false,
updateVegaWalletDialog: (open: boolean) =>

View File

@ -52,8 +52,8 @@ export interface VegaTransactionStore {
) => void;
}
export const useVegaTransactionStore = create(
subscribeWithSelector<VegaTransactionStore>((set, get) => ({
export const useVegaTransactionStore = create<VegaTransactionStore>()(
subscribeWithSelector((set, get) => ({
transactions: [] as VegaStoredTxState[],
create: (body: Transaction, order?: OrderTxUpdateFieldsFragment) => {
const transactions = get().transactions;

View File

@ -17,7 +17,8 @@
"**/*.test.js",
"**/*.spec.jsx",
"**/*.test.jsx",
"jest.config.ts"
"jest.config.ts",
"__mocks__"
],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}

View File

@ -1,27 +0,0 @@
import { act } from '@testing-library/react';
const zu = jest.requireActual('zustand'); // if using jest
// a variable to hold reset functions for all stores declared in the app
const storeResetFns = new Set();
// when creating a store, we get its initial state, create a reset function and add it in the set
export const create = (createState) => {
let store;
if (typeof createState === 'function') {
store = zu.create(createState);
} else {
store = (selector, equalityFn) =>
zu.useStore(createState, selector, equalityFn);
Object.assign(store, createState);
}
const initialState = store.getState();
storeResetFns.add(() => store.setState(initialState, true));
return store;
};
// Reset all stores after each test run
beforeEach(() => {
act(() => storeResetFns.forEach((resetFn) => resetFn()));
});
export default create;

View File

@ -0,0 +1,24 @@
import type { StateCreator } from 'zustand';
import { act } from 'react-dom/test-utils';
const { create: actualCreate } = jest.requireActual('zustand'); // if using jest
// a variable to hold reset functions for all stores declared in the app
const storeResetFns = new Set<() => void>();
// when creating a store, we get its initial state, create a reset function and add it in the set
export const create =
() =>
<S>(createState: StateCreator<S>) => {
const store = actualCreate(createState);
const initialState = store.getState();
storeResetFns.add(() => store.setState(initialState, true));
return store;
};
// Reset all stores after each test run
beforeEach(() => {
act(() => storeResetFns.forEach((resetFn) => resetFn()));
});
// also export default as web3-react internals import and use zustand as the default import
export default create;

View File

@ -55,8 +55,8 @@ export interface EthTransactionStore {
delete: (index: number) => void;
}
export const useEthTransactionStore = create(
subscribeWithSelector<EthTransactionStore>((set, get) => ({
export const useEthTransactionStore = create<EthTransactionStore>()(
subscribeWithSelector((set, get) => ({
transactions: [] as EthStoredTxState[],
create: (
contract: Contract | null,

View File

@ -49,8 +49,8 @@ export interface EthWithdrawApprovalStore {
delete: (index: number) => void;
}
export const useEthWithdrawApprovalsStore = create(
subscribeWithSelector<EthWithdrawApprovalStore>((set, get) => ({
export const useEthWithdrawApprovalsStore = create<EthWithdrawApprovalStore>()(
subscribeWithSelector((set, get) => ({
transactions: [] as EthWithdrawalApprovalState[],
create: (
withdrawal: EthWithdrawalApprovalState['withdrawal'],

View File

@ -13,7 +13,7 @@ interface Actions {
close: () => void;
}
export const useWeb3ConnectStore = create<State & Actions>((set) => ({
export const useWeb3ConnectStore = create<State & Actions>()((set) => ({
isOpen: false,
connectors: [],
initialize: (connectors, desiredChainId) => {

View File

@ -17,7 +17,8 @@
"**/*.test.js",
"**/*.spec.jsx",
"**/*.test.jsx",
"jest.config.ts"
"jest.config.ts",
"__mocks__"
],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}

View File

@ -11,7 +11,7 @@ export interface WithdrawStore {
update: (state: Partial<WithdrawStore>) => void;
}
export const useWithdrawStore = create<WithdrawStore>((set) => ({
export const useWithdrawStore = create<WithdrawStore>()((set) => ({
asset: undefined,
balance: new BigNumber(0),
min: new BigNumber(0),

View File

@ -17,7 +17,7 @@ interface Actions {
close: () => void;
}
export const useWithdrawalDialog = create<State & Actions>((set) => ({
export const useWithdrawalDialog = create<State & Actions>()((set) => ({
isOpen: false,
assetId: undefined,
open: (assetId) => set(() => ({ assetId, isOpen: true })),