Split config rehydration off into a different file for store
This commit is contained in:
parent
74e3cce1d8
commit
b39b36d0dc
|
@ -0,0 +1,156 @@
|
|||
import { State as ConfigState, config } from 'reducers/config';
|
||||
import { dedupeCustomTokens } from 'utils/tokens';
|
||||
import {
|
||||
State as CustomTokenState,
|
||||
INITIAL_STATE as customTokensInitialState
|
||||
} from 'reducers/customTokens';
|
||||
import { loadStatePropertyOrEmptyObject } from 'utils/localStorage';
|
||||
import {
|
||||
isStaticNodeId,
|
||||
isStaticNetworkId,
|
||||
getLanguageSelection,
|
||||
getCustomNodeConfigs,
|
||||
getSelectedNode,
|
||||
getCustomNetworkConfigs,
|
||||
getSelectedNetwork
|
||||
} from 'selectors/config';
|
||||
import RootReducer, { AppState } from 'reducers';
|
||||
import CustomNode from 'libs/nodes/custom';
|
||||
import { CustomNodeConfig } from 'types/node';
|
||||
const appInitialState = RootReducer(undefined as any, { type: 'inital_state' });
|
||||
|
||||
type DeepPartial<T> = { [P in keyof T]?: DeepPartial<T[P]> };
|
||||
export function getConfigAndCustomTokensStateToSubscribe(
|
||||
state: AppState
|
||||
): Pick<DeepPartial<AppState>, 'config' | 'customTokens'> {
|
||||
const subscribedConfig: DeepPartial<ConfigState> = {
|
||||
meta: { languageSelection: getLanguageSelection(state) },
|
||||
nodes: { customNodes: getCustomNodeConfigs(state), selectedNode: getSelectedNode(state) },
|
||||
networks: {
|
||||
customNetworks: getCustomNetworkConfigs(state),
|
||||
selectedNetwork: getSelectedNetwork(state)
|
||||
}
|
||||
};
|
||||
|
||||
const subscribedTokens = state.customTokens;
|
||||
|
||||
return { config: subscribedConfig, customTokens: subscribedTokens };
|
||||
}
|
||||
|
||||
export function rehydrateConfigAndCustomTokenState() {
|
||||
const configInitialState = config(undefined as any, { type: 'inital_state' });
|
||||
const savedConfigState = loadStatePropertyOrEmptyObject<ConfigState>('config');
|
||||
const nextConfigState = { ...configInitialState };
|
||||
|
||||
// If they have a saved node, make sure we assign that too. The node selected
|
||||
// isn't serializable, so we have to assign it here.
|
||||
if (savedConfigState) {
|
||||
// we assign networks first so that when we re-hydrate custom nodes, we can check that the network exists
|
||||
nextConfigState.networks = rehydrateNetworks(
|
||||
configInitialState.networks,
|
||||
savedConfigState.networks
|
||||
);
|
||||
nextConfigState.nodes = rehydrateNodes(
|
||||
configInitialState.nodes,
|
||||
savedConfigState.nodes,
|
||||
nextConfigState.networks
|
||||
);
|
||||
nextConfigState.meta = { ...nextConfigState.meta, ...savedConfigState.meta };
|
||||
}
|
||||
|
||||
const nextCustomTokenState = rehydrateCustomTokens(nextConfigState.networks);
|
||||
|
||||
return { config: nextConfigState, customTokens: nextCustomTokenState };
|
||||
}
|
||||
|
||||
function rehydrateCustomTokens(networkState: ConfigState['networks']) {
|
||||
// Dedupe custom tokens initially
|
||||
const savedCustomTokensState =
|
||||
loadStatePropertyOrEmptyObject<CustomTokenState>('customTokens') || customTokensInitialState;
|
||||
|
||||
const { customNetworks, selectedNetwork, staticNetworks } = networkState;
|
||||
const network = isStaticNetworkId(appInitialState, selectedNetwork)
|
||||
? staticNetworks[selectedNetwork]
|
||||
: customNetworks[selectedNetwork];
|
||||
return network.isCustom
|
||||
? savedCustomTokensState
|
||||
: dedupeCustomTokens(network.tokens, savedCustomTokensState);
|
||||
}
|
||||
|
||||
function rehydrateNetworks(
|
||||
initialState: ConfigState['networks'],
|
||||
savedState: ConfigState['networks']
|
||||
): ConfigState['networks'] {
|
||||
const nextNetworkState = { ...initialState };
|
||||
nextNetworkState.customNetworks = savedState.customNetworks;
|
||||
const { customNetworks, selectedNetwork, staticNetworks } = nextNetworkState;
|
||||
const nextSelectedNetwork = isStaticNetworkId(appInitialState, savedState.selectedNetwork)
|
||||
? staticNetworks[selectedNetwork]
|
||||
: customNetworks[selectedNetwork];
|
||||
nextNetworkState.selectedNetwork = nextSelectedNetwork
|
||||
? savedState.selectedNetwork
|
||||
: initialState.selectedNetwork;
|
||||
return nextNetworkState;
|
||||
}
|
||||
|
||||
function rehydrateNodes(
|
||||
initalState: ConfigState['nodes'],
|
||||
savedState: ConfigState['nodes'],
|
||||
networkState: ConfigState['networks']
|
||||
): ConfigState['nodes'] {
|
||||
const nextNodeState = { ...initalState };
|
||||
|
||||
// re-assign the hydrated nodes
|
||||
nextNodeState.customNodes = rehydrateCustomNodes(savedState.customNodes, networkState);
|
||||
const { customNodes, staticNodes } = nextNodeState;
|
||||
nextNodeState.selectedNode = getSavedSelectedNode(
|
||||
nextNodeState.selectedNode,
|
||||
savedState.selectedNode,
|
||||
customNodes,
|
||||
staticNodes
|
||||
);
|
||||
return nextNodeState;
|
||||
}
|
||||
|
||||
function getSavedSelectedNode(
|
||||
initialState: ConfigState['nodes']['selectedNode'],
|
||||
savedState: ConfigState['nodes']['selectedNode'],
|
||||
customNodes: ConfigState['nodes']['customNodes'],
|
||||
staticNodes: ConfigState['nodes']['staticNodes']
|
||||
): ConfigState['nodes']['selectedNode'] {
|
||||
const { nodeId: savedNodeId } = savedState;
|
||||
|
||||
// if 'web3' has persisted as node selection, reset to app default
|
||||
// necessary because web3 is only initialized as a node upon MetaMask / Mist unlock
|
||||
|
||||
if (savedNodeId === 'web3') {
|
||||
return { nodeId: initialState.nodeId, pending: false };
|
||||
}
|
||||
|
||||
const nodeConfigExists = isStaticNodeId(appInitialState, savedNodeId)
|
||||
? staticNodes[savedNodeId]
|
||||
: customNodes[savedNodeId];
|
||||
|
||||
return { nodeId: nodeConfigExists ? savedNodeId : initialState.nodeId, pending: false };
|
||||
}
|
||||
|
||||
function rehydrateCustomNodes(
|
||||
state: ConfigState['nodes']['customNodes'],
|
||||
networkState: ConfigState['networks']
|
||||
) {
|
||||
const networkExists = (networkId: string) => Object.keys(networkState).includes(networkId);
|
||||
|
||||
const rehydratedCustomNodes = Object.entries(state).reduce(
|
||||
(hydratedNodes, [customNodeId, configToHydrate]) => {
|
||||
if (!networkExists(configToHydrate.network)) {
|
||||
return hydratedNodes;
|
||||
}
|
||||
|
||||
const lib = new CustomNode(configToHydrate);
|
||||
const hydratedNode: CustomNodeConfig = { ...configToHydrate, lib };
|
||||
return { ...hydratedNodes, [customNodeId]: hydratedNode };
|
||||
},
|
||||
{} as ConfigState['nodes']['customNodes']
|
||||
);
|
||||
return rehydratedCustomNodes;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export * from './store';
|
|
@ -1,13 +1,5 @@
|
|||
import throttle from 'lodash/throttle';
|
||||
import { routerMiddleware } from 'react-router-redux';
|
||||
|
||||
/*
|
||||
import { State as ConfigState, INITIAL_STATE as configInitialState } from 'reducers/config';
|
||||
*/
|
||||
import {
|
||||
State as CustomTokenState,
|
||||
INITIAL_STATE as customTokensInitialState
|
||||
} from 'reducers/customTokens';
|
||||
import {
|
||||
INITIAL_STATE as transactionInitialState,
|
||||
State as TransactionState
|
||||
|
@ -18,11 +10,14 @@ import { composeWithDevTools } from 'redux-devtools-extension';
|
|||
import { createLogger } from 'redux-logger';
|
||||
import createSagaMiddleware from 'redux-saga';
|
||||
import { loadStatePropertyOrEmptyObject, saveState } from 'utils/localStorage';
|
||||
import RootReducer from './reducers';
|
||||
import RootReducer from 'reducers';
|
||||
import promiseMiddleware from 'redux-promise-middleware';
|
||||
import { dedupeCustomTokens } from 'utils/tokens';
|
||||
import sagas from './sagas';
|
||||
import sagas from 'sagas';
|
||||
import { gasPricetoBase } from 'libs/units';
|
||||
import {
|
||||
rehydrateConfigAndCustomTokenState,
|
||||
getConfigAndCustomTokensStateToSubscribe
|
||||
} from './configAndTokens';
|
||||
|
||||
const configureStore = () => {
|
||||
const logger = createLogger({
|
||||
|
@ -62,40 +57,8 @@ const configureStore = () => {
|
|||
: { ...swapInitialState };
|
||||
|
||||
const savedTransactionState = loadStatePropertyOrEmptyObject<TransactionState>('transaction');
|
||||
const savedConfigState = loadStatePropertyOrEmptyObject<ConfigState>('config');
|
||||
/*
|
||||
// If they have a saved node, make sure we assign that too. The node selected
|
||||
// isn't serializable, so we have to assign it here.
|
||||
if (savedConfigState && savedConfigState.nodes.selectedNode.nodeName) {
|
||||
const savedNode = getNodeConfigFromId(
|
||||
savedConfigState.nodeSelection,
|
||||
savedConfigState.customNodes
|
||||
);
|
||||
// If we couldn't find it, revert to defaults
|
||||
if (savedNode) {
|
||||
savedConfigState.node = savedNode;
|
||||
const network = getNetworkConfigFromId(savedNode.network, savedConfigState.customNetworks);
|
||||
if (network) {
|
||||
savedConfigState.network = network;
|
||||
}
|
||||
} else {
|
||||
savedConfigState.nodeSelection = configInitialState.nodeSelection;
|
||||
}
|
||||
}
|
||||
|
||||
// Dedupe custom tokens initially
|
||||
const savedCustomTokensState =
|
||||
loadStatePropertyOrEmptyObject<CustomTokenState>('customTokens') || customTokensInitialState;
|
||||
const initialNetwork =
|
||||
(savedConfigState && savedConfigState.network) || configInitialState.network;
|
||||
const customTokens = dedupeCustomTokens(initialNetwork.tokens, savedCustomTokensState);
|
||||
*/
|
||||
const persistedInitialState = {
|
||||
/*
|
||||
config: {
|
||||
...configInitialState,
|
||||
...savedConfigState
|
||||
},*/
|
||||
transaction: {
|
||||
...transactionInitialState,
|
||||
fields: {
|
||||
|
@ -109,18 +72,12 @@ const configureStore = () => {
|
|||
: transactionInitialState.fields.gasPrice
|
||||
}
|
||||
},
|
||||
// customTokens,
|
||||
|
||||
// ONLY LOAD SWAP STATE FROM LOCAL STORAGE IF STEP WAS 3
|
||||
swap: swapState
|
||||
swap: swapState,
|
||||
...rehydrateConfigAndCustomTokenState()
|
||||
};
|
||||
|
||||
// if 'web3' has persisted as node selection, reset to app default
|
||||
// necessary because web3 is only initialized as a node upon MetaMask / Mist unlock
|
||||
/*
|
||||
if (persistedInitialState.config.nodeSelection === 'web3') {
|
||||
persistedInitialState.config.nodeSelection = configInitialState.nodeSelection;
|
||||
}
|
||||
*/
|
||||
store = createStore(RootReducer, persistedInitialState, middleware);
|
||||
|
||||
// Add all of the sagas to the middleware
|
||||
|
@ -132,14 +89,6 @@ const configureStore = () => {
|
|||
throttle(() => {
|
||||
const state = store.getState();
|
||||
saveState({
|
||||
/*
|
||||
config: {
|
||||
nodeSelection: state.config.nodeSelection,
|
||||
languageSelection: state.config.languageSelection,
|
||||
customNodes: state.config.customNodes,
|
||||
customNetworks: state.config.customNetworks,
|
||||
setGasLimit: state.config.setGasLimit
|
||||
},*/
|
||||
transaction: {
|
||||
fields: {
|
||||
gasPrice: state.transaction.fields.gasPrice
|
||||
|
@ -160,7 +109,7 @@ const configureStore = () => {
|
|||
allIds: []
|
||||
}
|
||||
},
|
||||
customTokens: state.customTokens
|
||||
...getConfigAndCustomTokensStateToSubscribe(state)
|
||||
});
|
||||
}, 50)
|
||||
);
|
Loading…
Reference in New Issue