Skip to content

Commit

Permalink
Merge pull request #2234 from Emurgo/yushi/ergo-connector-action-map-…
Browse files Browse the repository at this point in the history
…typing

Get rid of some type coersions in Ergo connector store initialization code
  • Loading branch information
vsubhuman committed Jul 20, 2021
2 parents 538c5f6 + 1c44694 commit 021a23f
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 17 deletions.
13 changes: 8 additions & 5 deletions packages/yoroi-extension/app/ergo-connector/stores/index.js
Expand Up @@ -31,23 +31,26 @@ const storeClasses = Object.freeze({
});

export type StoresMap = {|
stateFetchStore: StateFetchStore,
stateFetchStore: StateFetchStore<StoresMap, ActionsMap>,
profile: ProfileStore,
uiDialogs: UiDialogsStore<{||}, ActionsMap>,
uiNotifications: UiNotificationsStore<{||}, ActionsMap>,
explorers: ExplorerStore,
coinPriceStore: ConnectorCoinPriceStore,
loading: ConnectorLoadingStore,
connector: ConnectorStore,
tokenInfoStore: TokenInfoStore,
tokenInfoStore: TokenInfoStore<StoresMap, ActionsMap>,
substores: {|
ada: AdaStoresMap,
ergo: ErgoStoresMap,
|},
|};

/** Constant that represents the stores across the lifetime of the application */
const stores: WithNullableFields<StoresMap> = observable({
// Note: initially we assign a map of all-null values which violates the type (thus
// the cast to `any`), but as soon as the below set-up code is executed, the object
// becomes conformant to the type.
const stores: StoresMap = (observable({
stateFetchStore: null, // best to initialize first to avoid issues
profile: null,
explorers: null,
Expand All @@ -58,7 +61,7 @@ const stores: WithNullableFields<StoresMap> = observable({
connector: null,
tokenInfoStore: null,
substores: null,
});
}): any);

function initializeSubstore<T: {...}>(
substore: T,
Expand All @@ -79,7 +82,7 @@ export default (action(
if (stores[name]) stores[name].teardown();
});
storeNames.forEach(name => {
stores[name] = (new storeClasses[name]((stores: any), api, (actions: any)): any);
stores[name] = (new storeClasses[name](stores, api, actions): any);
});
storeNames.forEach(name => {
if (stores[name]) stores[name].initialize();
Expand Down
13 changes: 8 additions & 5 deletions packages/yoroi-extension/app/stores/index.js
Expand Up @@ -63,9 +63,9 @@ const storeClasses = Object.freeze({
});

export type StoresMap = {|
stateFetchStore: StateFetchStore,
stateFetchStore: StateFetchStore<StoresMap, ActionsMap>,
coinPriceStore: CoinPriceStore,
tokenInfoStore: TokenInfoStore,
tokenInfoStore: TokenInfoStore<StoresMap, ActionsMap>,
profile: ProfileStore,
serverConnectionStore: ServerConnectionStore,
app: AppStore,
Expand Down Expand Up @@ -96,7 +96,10 @@ export type StoresMap = {|
|};

/** Constant that represents the stores across the lifetime of the application */
const stores: WithNullableFields<StoresMap> = observable({
// Note: initially we assign a map of all-null values which violates the type (thus
// the cast to `any`), but as soon as the below set-up code is executed, the object
// becomes conformant to the type.
const stores: StoresMap = (observable({
stateFetchStore: null, // best to initialize first to avoid issues
coinPriceStore: null,
tokenInfoStore: null,
Expand All @@ -123,7 +126,7 @@ const stores: WithNullableFields<StoresMap> = observable({
explorers: null,
substores: null,
router: null,
});
}): any);

function initializeSubstore<T: {...}>(
substore: T,
Expand Down Expand Up @@ -160,7 +163,7 @@ export default (action(
storeNames.forEach(name => {
// Careful: we pass incomplete `store` down to child components
// Any toplevel store that accesses `store` in its constructor may crash
stores[name] = ((new storeClasses[name]((stores: any), api, actions)): any);
stores[name] = ((new storeClasses[name](stores, api, actions)): any);
});
storeNames.forEach(name => { if (stores[name]) stores[name].initialize(); });

Expand Down
13 changes: 10 additions & 3 deletions packages/yoroi-extension/app/stores/toplevel/StateFetchStore.js
Expand Up @@ -6,10 +6,17 @@ import type { IFetcher } from '../../api/common/lib/state-fetch/IFetcher';
import { RemoteFetcher } from '../../api/common/lib/state-fetch/remoteFetcher';
import { BatchedFetcher } from '../../api/common/lib/state-fetch/batchedFetcher';
import environment from '../../environment';
import type { ActionsMap } from '../../actions/index';
import type { StoresMap } from '../index';

export default class StateFetchStore extends Store<StoresMap, ActionsMap> {
export default class StateFetchStore<
StoresMapType: {
+profile: {
+currentLocale: string,
...
},
...
},
ActionsMapType
> extends Store<StoresMapType, ActionsMapType> {

@observable fetcher: IFetcher;

Expand Down
34 changes: 30 additions & 4 deletions packages/yoroi-extension/app/stores/toplevel/TokenInfoStore.js
Expand Up @@ -15,8 +15,6 @@ import {
import type {
DefaultTokenEntry,
} from '../../api/common/lib/MultiToken';
import type { ActionsMap } from '../../actions/index';
import type { StoresMap } from '../index';
import {
getAllSchemaTables,
raii,
Expand All @@ -25,6 +23,9 @@ import { GetToken } from '../../api/ada/lib/storage/database/primitives/api/read
import { ModifyToken } from '../../api/ada/lib/storage/database/primitives/api/write';
import { genCardanoAssetMap } from '../../api/ada/lib/storage/bridge/updateTransactions';
import { PublicDeriver } from '../../api/ada/lib/storage/models/PublicDeriver/index'
import type WalletsActions from '../../actions/wallet-actions';
import type TransactionsStore from './TransactionsStore';
import type { IFetcher } from '../../api/ada/lib/state-fetch/IFetcher';

export type TokenInfoMap = Map<
string, // network ID. String because mobx requires string for observable maps
Expand All @@ -34,7 +35,27 @@ export type TokenInfoMap = Map<
>
>;

export default class TokenInfoStore extends Store<StoresMap, ActionsMap> {
export default class TokenInfoStore<
StoresMapType: {
+transactions?: TransactionsStore,
+loading: {
+getDatabase: () => any,
...
},
+substores: {
+ada: {
+stateFetchStore: {
+fetcher: IFetcher,
...
},
...
},
...
},
...
},
ActionsMapType: { +wallets?: WalletsActions, ... },
> extends Store<StoresMapType, ActionsMapType> {
@observable tokenInfo: TokenInfoMap;

setup(): void {
Expand All @@ -50,7 +71,12 @@ export default class TokenInfoStore extends Store<StoresMap, ActionsMap> {

@action _fetchMissingTokenInfo
: ({| wallet: PublicDeriver<> |}) => Promise<void>
= async ({ wallet }) => {
= async ({ wallet }) => {

// the Ergo connector doesn't have this store, but it this function won't be invoked
if (!this.stores.transactions) {
throw new Error(`${nameof(TokenInfoStore)}::${nameof(this._fetchMissingTokenInfo)} missing transactions store`);
}

const { requests } = this.stores.transactions.getTxRequests(wallet);

Expand Down

0 comments on commit 021a23f

Please sign in to comment.