configureStore.ts
1 import { applyMiddleware, createStore, Store } from 'redux'; 2 import createSagaMiddleware from 'redux-saga'; 3 import { routerMiddleware } from 'react-router-redux'; 4 import { composeWithDevTools } from 'redux-devtools-extension'; 5 import { createLogger } from 'redux-logger'; 6 import throttle from 'lodash/throttle'; 7 8 import { loadStatePropertyOrEmptyObject, saveState } from 'utils/localStorage'; 9 import { gasPriceToBase } from 'libs/units'; 10 import RootReducer, { AppState } from './reducers'; 11 import sagas from './sagas'; 12 import { TransactionState } from './transaction/types'; 13 import { INITIAL_STATE as transactionInitialState } from './transaction/reducer'; 14 import { SwapState } from './swap/types'; 15 import { INITIAL_STATE as initialSwapState } from './swap/reducer'; 16 import { AddressBookState } from './addressBook/types'; 17 import { TransactionsState } from './transactions/types'; 18 import { INITIAL_STATE as initialTransactionsState } from './transactions/reducer'; 19 import { WalletState } from './wallet/types'; 20 import { INITIAL_STATE as initialWalletState } from './wallet/reducer'; 21 import { 22 rehydrateConfigAndCustomTokenState, 23 getConfigAndCustomTokensStateToSubscribe 24 } from './configAndTokens'; 25 import rehydrateAddressBook from './rehydrateAddressBook'; 26 27 export default function configureStore() { 28 const logger = createLogger({ 29 collapsed: true 30 }); 31 const sagaMiddleware = createSagaMiddleware(); 32 let middleware; 33 let store: Store<AppState>; 34 35 if (process.env.NODE_ENV !== 'production') { 36 middleware = composeWithDevTools( 37 applyMiddleware(sagaMiddleware, logger, routerMiddleware(history as any)) 38 ); 39 } else { 40 middleware = applyMiddleware(sagaMiddleware, routerMiddleware(history as any)); 41 } 42 43 // ONLY LOAD SWAP STATE FROM LOCAL STORAGE IF STEP WAS 3 44 const localSwapState = loadStatePropertyOrEmptyObject<SwapState>('swap'); 45 const swapState = 46 localSwapState && localSwapState.step === 3 47 ? { 48 ...initialSwapState, 49 ...localSwapState 50 } 51 : { ...initialSwapState }; 52 53 const savedTransactionState = loadStatePropertyOrEmptyObject<TransactionState>('transaction'); 54 const savedTransactionsState = loadStatePropertyOrEmptyObject<TransactionsState>('transactions'); 55 const savedAddressBook = loadStatePropertyOrEmptyObject<AddressBookState>('addressBook'); 56 const savedWalletState = loadStatePropertyOrEmptyObject<WalletState>('wallet'); 57 58 const persistedInitialState: Partial<AppState> = { 59 transaction: { 60 ...transactionInitialState, 61 fields: { 62 ...transactionInitialState.fields, 63 gasPrice: 64 savedTransactionState && savedTransactionState.fields.gasPrice 65 ? { 66 raw: savedTransactionState.fields.gasPrice.raw, 67 value: gasPriceToBase(+savedTransactionState.fields.gasPrice.raw) 68 } 69 : transactionInitialState.fields.gasPrice 70 } 71 }, 72 swap: swapState, 73 transactions: { 74 ...initialTransactionsState, 75 ...savedTransactionsState 76 }, 77 addressBook: rehydrateAddressBook(savedAddressBook), 78 wallet: { 79 ...initialWalletState, 80 ...savedWalletState 81 }, 82 ...rehydrateConfigAndCustomTokenState() 83 }; 84 85 store = createStore<AppState>(RootReducer, persistedInitialState as any, middleware); 86 87 // Add all of the sagas to the middleware 88 Object.keys(sagas).forEach((saga: keyof typeof sagas) => { 89 sagaMiddleware.run(sagas[saga]); 90 }); 91 92 store.subscribe( 93 throttle(() => { 94 const state: AppState = store.getState(); 95 96 saveState({ 97 transaction: { 98 fields: { 99 gasPrice: state.transaction.fields.gasPrice 100 } 101 }, 102 swap: { 103 ...state.swap, 104 options: { 105 byId: {}, 106 allIds: [] 107 }, 108 bityRates: { 109 byId: {}, 110 allIds: [] 111 }, 112 shapeshiftRates: { 113 byId: {}, 114 allIds: [] 115 } 116 }, 117 transactions: { 118 recent: state.transactions.recent 119 }, 120 addressBook: state.addressBook, 121 wallet: { 122 recentAddresses: state.wallet.recentAddresses 123 }, 124 ...getConfigAndCustomTokensStateToSubscribe(state) 125 }); 126 }, 50) 127 ); 128 129 return store; 130 }