Wrap all derives in memo (like rpc-core) (#1564)

This commit is contained in:
Jaco Greeff
2019-11-11 14:25:07 +01:00
committed by GitHub
parent e73c147275
commit 2875fdf2cf
40 changed files with 190 additions and 216 deletions
@@ -11,7 +11,7 @@ import { isU8a } from '@polkadot/util';
import { decodeAddress } from '@polkadot/util-crypto';
import { createType } from '@polkadot/types';
import { drr } from '../util';
import { memo } from '../util';
export type AccountIdAndIndex = [AccountId?, AccountIndex?];
@@ -54,6 +54,6 @@ function retrieve (api: ApiInterfaceRx, address: Address | AccountId | AccountIn
* ```
*/
export function idAndIndex (api: ApiInterfaceRx): (address?: Address | AccountId | AccountIndex | string | null) => Observable<AccountIdAndIndex> {
return (address?: Address | AccountId | AccountIndex | string | null): Observable<AccountIdAndIndex> =>
retrieve(api, address).pipe(drr());
return memo((address?: Address | AccountId | AccountIndex | string | null): Observable<AccountIdAndIndex> =>
retrieve(api, address));
}
@@ -9,7 +9,7 @@ import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { drr } from '../util';
import { memo } from '../util';
/**
* @name idToIndex
@@ -26,12 +26,11 @@ import { drr } from '../util';
* ```
*/
export function idToIndex (api: ApiInterfaceRx): (accountId: AccountId | string) => Observable<AccountIndex | undefined> {
return (accountId: AccountId | string): Observable<AccountIndex | undefined> =>
return memo((accountId: AccountId | string): Observable<AccountIndex | undefined> =>
api.derive.accounts.indexes().pipe(
startWith({}),
map((indexes: AccountIndexes): AccountIndex | undefined =>
(indexes || {})[accountId.toString()]
),
drr()
);
)
));
}
@@ -10,7 +10,7 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
import { ENUMSET_SIZE } from '@polkadot/types/primitive/Generic/AccountIndex';
import { createType, ClassOf, Vec } from '@polkadot/types';
import { drr } from '../util';
import { memo } from '../util';
/**
* @name indexToId
@@ -28,7 +28,7 @@ import { drr } from '../util';
export function indexToId (api: ApiInterfaceRx): (accountIndex: AccountIndex | string) => Observable<AccountId | undefined> {
const querySection = api.query.indices || api.query.balances;
return (_accountIndex: AccountIndex | string): Observable<AccountId | undefined> => {
return memo((_accountIndex: AccountIndex | string): Observable<AccountId | undefined> => {
const accountIndex = _accountIndex instanceof ClassOf('AccountIndex')
? _accountIndex
: createType('AccountIndex', _accountIndex);
@@ -37,8 +37,7 @@ export function indexToId (api: ApiInterfaceRx): (accountIndex: AccountIndex | s
startWith([]),
map((accounts): AccountId | undefined =>
(accounts || [])[accountIndex.mod(ENUMSET_SIZE).toNumber()]
),
drr()
)
);
};
});
}
+9 -10
View File
@@ -9,9 +9,9 @@ import { AccountIndexes } from '../types';
import { Observable } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { ENUMSET_SIZE } from '@polkadot/types/primitive/Generic/AccountIndex';
import { createType } from '@polkadot/types';
import { createType, Vec } from '@polkadot/types';
import { drr } from '../util';
import { memo } from '../util';
const enumsetSize = ENUMSET_SIZE.toNumber();
@@ -31,17 +31,17 @@ const enumsetSize = ENUMSET_SIZE.toNumber();
* ```
*/
export function indexes (api: ApiInterfaceRx): () => Observable<AccountIndexes> {
return (): Observable<AccountIndexes> =>
return memo((): Observable<AccountIndexes> =>
api.query.indices.nextEnumSet<AccountIndex>().pipe(
// use the nextEnumSet (which is a counter of the number of sets) to construct
// a range of values to query [0, 1, 2, ...]. Retrieve the full enum set for the
// specific index - each query can return up to ENUMSET_SIZE (64) records, each
// containing an AccountId
switchMap((next: AccountIndex): Observable<any> =>
api.query.indices.enumSet.multi([...Array(next.toNumber() + 1).keys()]) as Observable<any>
switchMap((next: AccountIndex): Observable<Vec<AccountId>[]> =>
api.query.indices.enumSet.multi<Vec<AccountId>>([...Array(next.toNumber() + 1).keys()])
),
map((all: (AccountId[] | undefined)[]): AccountIndexes =>
(all || []).reduce((result: AccountIndexes, list, outerIndex): AccountIndexes => {
map((all: AccountId[][]): AccountIndexes =>
all.reduce((result: AccountIndexes, list, outerIndex): AccountIndexes => {
(list || []).forEach((accountId, innerIndex): void => {
// re-create the index based on position 0 is [0][0] and likewise
// 64 (0..63 in first) is [1][0] (the first index value in set 2)
@@ -51,7 +51,6 @@ export function indexes (api: ApiInterfaceRx): () => Observable<AccountIndexes>
});
return result;
}, {})),
drr()
);
}, {}))
));
}
+4 -5
View File
@@ -12,7 +12,7 @@ import { map, switchMap } from 'rxjs/operators';
import { Bytes, Option, u32 } from '@polkadot/types';
import { u8aToString } from '@polkadot/util';
import { drr } from '../util';
import { memo } from '../util';
function retrieveNick (api: ApiInterfaceRx, accountId?: AccountId): Observable<string | undefined> {
return ((
@@ -33,7 +33,7 @@ function retrieveNick (api: ApiInterfaceRx, accountId?: AccountId): Observable<s
* @description Returns aux. info with regards to an account, current that includes the accountId, accountIndex and nickname
*/
export function info (api: ApiInterfaceRx): (address?: AccountIndex | AccountId | Address | string | null) => Observable<DeriveAccountInfo> {
return (address?: AccountIndex | AccountId | Address | string | null): Observable<DeriveAccountInfo> =>
return memo((address?: AccountIndex | AccountId | Address | string | null): Observable<DeriveAccountInfo> =>
api.derive.accounts.idAndIndex(address).pipe(
switchMap(([accountId, accountIndex]): Observable<[DeriveAccountInfo, string?]> =>
combineLatest([
@@ -43,7 +43,6 @@ export function info (api: ApiInterfaceRx): (address?: AccountIndex | AccountId
),
map(([{ accountId, accountIndex }, nickname]): DeriveAccountInfo => ({
accountId, accountIndex, nickname
})),
drr()
);
}))
));
}
+4 -5
View File
@@ -12,7 +12,7 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
import { Option, Vec, createType } from '@polkadot/types';
import { bnMax } from '@polkadot/util';
import { drr } from '../util';
import { memo } from '../util';
type ResultBalance = [Balance, Balance, BalanceLock[], Option<VestingSchedule>];
type Result = [AccountId, BlockNumber, ResultBalance, Index];
@@ -76,7 +76,7 @@ function queryBalances (api: ApiInterfaceRx, accountId: AccountId): Observable<R
* ```
*/
export function all (api: ApiInterfaceRx): (address: AccountIndex | AccountId | Address | string) => Observable<DerivedBalances> {
return (address: AccountIndex | AccountId | Address | string): Observable<DerivedBalances> =>
return memo((address: AccountIndex | AccountId | Address | string): Observable<DerivedBalances> =>
api.derive.accounts.info(address).pipe(
switchMap(({ accountId }): Observable<Result> =>
(accountId
@@ -94,7 +94,6 @@ export function all (api: ApiInterfaceRx): (address: AccountIndex | AccountId |
: of([createType('AccountId'), createType('BlockNumber'), [createType('Balance'), createType('Balance'), createType('Vec<BalanceLock>'), createType('Option<VestingSchedule>', null)], createType('Index')])
)
),
map(calcBalances),
drr()
);
map(calcBalances)
));
}
+4 -5
View File
@@ -9,7 +9,7 @@ import { DerivedFees } from '../types';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { drr } from '../util';
import { memo } from '../util';
type Result = [Balance, Balance, Balance, Balance, Balance];
@@ -56,7 +56,7 @@ export function fees (api: ApiInterfaceRx): () => Observable<DerivedFees> {
? queryV2
: queryV1;
return (): Observable<DerivedFees> =>
return memo((): Observable<DerivedFees> =>
query(api).pipe(
map(([creationFee, existentialDeposit, transferFee, transactionBaseFee, transactionByteFee]): DerivedFees => ({
creationFee,
@@ -64,7 +64,6 @@ export function fees (api: ApiInterfaceRx): () => Observable<DerivedFees> {
transactionBaseFee,
transactionByteFee,
transferFee
})),
drr()
);
}))
));
}
@@ -3,23 +3,20 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, AccountIndex, Address } from '@polkadot/types/interfaces';
import { DerivedBalances } from '../types';
import { combineLatest, Observable, of } from 'rxjs';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { DerivedBalances } from '../types';
import { drr } from '../util';
import { memo } from '../util';
export function votingBalances (api: ApiInterfaceRx): (addresses?: (AccountId | AccountIndex | Address | string)[]) => Observable<DerivedBalances[]> {
return (addresses?: (AccountId | AccountIndex | Address | string)[]): Observable<DerivedBalances[]> =>
(
!addresses || !addresses.length
? of([] as DerivedBalances[])
: combineLatest(
addresses.map((accountId): Observable<DerivedBalances> =>
api.derive.balances.all(accountId))
)
).pipe(
drr()
);
return memo((addresses?: (AccountId | AccountIndex | Address | string)[]): Observable<DerivedBalances[]> =>
!addresses || !addresses.length
? of([] as DerivedBalances[])
: combineLatest(
addresses.map((accountId): Observable<DerivedBalances> =>
api.derive.balances.all(accountId))
)
);
}
@@ -10,10 +10,10 @@ import { switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Vec } from '@polkadot/types';
import { drr } from '../util';
import { memo } from '../util';
export function votingBalancesNominatorsFor (api: ApiInterfaceRx): (address: AccountId | AccountIndex | Address | string) => Observable<DerivedBalances[]> {
return (address: AccountId | AccountIndex | Address | string): Observable<DerivedBalances[]> =>
return memo((address: AccountId | AccountIndex | Address | string): Observable<DerivedBalances[]> =>
api.derive.accounts.info(address).pipe(
switchMap(({ accountId }): Observable<AccountId[]> =>
accountId
@@ -22,7 +22,6 @@ export function votingBalancesNominatorsFor (api: ApiInterfaceRx): (address: Acc
),
switchMap((accounts): Observable<DerivedBalances[]> =>
api.derive.balances.votingBalances(accounts)
),
drr()
);
)
));
}
+4 -5
View File
@@ -8,7 +8,7 @@ import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { drr } from '../util';
import { memo } from '../util';
/**
* @name bestNumber
@@ -23,9 +23,8 @@ import { drr } from '../util';
* ```
*/
export function bestNumber (api: ApiInterfaceRx): () => Observable<BlockNumber> {
return (): Observable<BlockNumber> =>
return memo((): Observable<BlockNumber> =>
api.derive.chain.subscribeNewHeads().pipe(
map((header: Header): BlockNumber => header.number.unwrap()),
drr()
);
map((header: Header): BlockNumber => header.number.unwrap())
));
}
@@ -8,7 +8,7 @@ import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { drr } from '../util';
import { memo } from '../util';
/**
* @name bestNumberFinalized
@@ -24,9 +24,8 @@ import { drr } from '../util';
* ```
*/
export function bestNumberFinalized (api: ApiInterfaceRx): () => Observable<BlockNumber> {
return (): Observable<BlockNumber> =>
return memo((): Observable<BlockNumber> =>
api.rpc.chain.subscribeFinalizedHeads().pipe(
map((header): BlockNumber => header.number.unwrap()),
drr()
);
map((header): BlockNumber => header.number.unwrap())
));
}
@@ -9,7 +9,7 @@ import { map } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { createType } from '@polkadot/types';
import { drr } from '../util';
import { memo } from '../util';
/**
* @name bestNumberLag
@@ -25,14 +25,13 @@ import { drr } from '../util';
* ```
*/
export function bestNumberLag (api: ApiInterfaceRx): () => Observable<BlockNumber> {
return (): Observable<BlockNumber> =>
return memo((): Observable<BlockNumber> =>
combineLatest([
api.derive.chain.bestNumber(),
api.derive.chain.bestNumberFinalized()
]).pipe(
map(([bestNumber, bestNumberFinalized]): BlockNumber =>
createType('BlockNumber', bestNumber.sub(bestNumberFinalized))
),
drr()
);
)
));
}
+4 -5
View File
@@ -11,7 +11,7 @@ import { catchError, map } from 'rxjs/operators';
import { Vec } from '@polkadot/types';
import { HeaderExtended } from '../type';
import { drr } from '../util';
import { memo } from '../util';
/**
* @name bestNumberFinalized
@@ -28,7 +28,7 @@ import { drr } from '../util';
* ```
*/
export function getHeader (api: ApiInterfaceRx): (hash: Uint8Array | string) => Observable<HeaderExtended | undefined> {
return (hash: Uint8Array | string): Observable<HeaderExtended | undefined> =>
return memo((hash: Uint8Array | string): Observable<HeaderExtended | undefined> =>
combineLatest([
api.rpc.chain.getHeader(hash),
api.query.session
@@ -43,7 +43,6 @@ export function getHeader (api: ApiInterfaceRx): (hash: Uint8Array | string) =>
// we supplied an invalid hash. (Due to defaults, storeage will have an
// empty value, so only the RPC is affected). So return undefined
of()
),
drr()
);
)
));
}
@@ -8,7 +8,7 @@ import { Observable, combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';
import { HeaderExtended } from '../type';
import { drr } from '../util';
import { memo } from '../util';
/**
* @name subscribeNewHeads
@@ -24,14 +24,13 @@ import { drr } from '../util';
* ```
*/
export function subscribeNewHeads (api: ApiInterfaceRx): () => Observable<HeaderExtended> {
return (): Observable<HeaderExtended> =>
return memo((): Observable<HeaderExtended> =>
combineLatest([
api.rpc.chain.subscribeNewHeads(),
api.derive.staking.validators()
]).pipe(
map(([header, { validators }]): HeaderExtended =>
new HeaderExtended(header, validators)
),
drr()
);
)
));
}
+5 -7
View File
@@ -9,7 +9,7 @@ import BN from 'bn.js';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { drr } from '../util';
import { memo } from '../util';
type ResultV2 = [BN, BN, BN, BN, BN, BN, BN, BN, BN, BN];
@@ -51,8 +51,7 @@ function queryV1 (api: ApiInterfaceRx): Observable<DerivedContractFees> {
parseResult([
callBaseFee, contractFee, createBaseFee, creationFee, ZERO, ZERO, ZERO, transactionBaseFee, transactionByteFee, transferFee
])
),
drr()
)
);
}
@@ -104,7 +103,7 @@ function queryConstants (api: ApiInterfaceRx): Observable<ResultV2> {
* ```
*/
export function fees (api: ApiInterfaceRx): () => Observable<DerivedContractFees> {
return (): Observable<DerivedContractFees> => {
return memo((): Observable<DerivedContractFees> => {
if (api.query.contract && !api.query.contract.rentByteFee) {
return queryV1(api);
}
@@ -119,8 +118,7 @@ export function fees (api: ApiInterfaceRx): () => Observable<DerivedContractFees
parseResult([
callBaseFee, contractFee, createBaseFee, creationFee, rentByteFee, rentDepositOffset, tombstoneDeposit, transactionBaseFee, transactionByteFee, transferFee
])
),
drr()
)
);
};
});
}
@@ -12,7 +12,7 @@ import { Option } from '@polkadot/types';
import { isNull } from '@polkadot/util';
import { ReferendumInfoExtended } from '../type';
import { drr } from '../util';
import { memo } from '../util';
export function constructInfo (index: BN | number, optionInfo?: Option<ReferendumInfo>): Option<ReferendumInfoExtended> {
const info = optionInfo
@@ -28,11 +28,10 @@ export function constructInfo (index: BN | number, optionInfo?: Option<Referendu
}
export function referendumInfo (api: ApiInterfaceRx): (index: BN | number) => Observable<Option<ReferendumInfoExtended>> {
return (index: BN | number): Observable<Option<ReferendumInfoExtended>> =>
return memo((index: BN | number): Observable<Option<ReferendumInfoExtended>> =>
api.query.democracy.referendumInfoOf<Option<ReferendumInfo>>(index).pipe(
map((optionInfo): Option<ReferendumInfoExtended> =>
constructInfo(index, optionInfo)
),
drr()
);
)
));
}
@@ -11,11 +11,11 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
import { Option, Vec } from '@polkadot/types';
import { ReferendumInfoExtended } from '../type';
import { drr } from '../util';
import { memo } from '../util';
import { constructInfo } from './referendumInfo';
export function referendumInfos (api: ApiInterfaceRx): (ids?: (BN | number)[]) => Observable<Option<ReferendumInfoExtended>[]> {
return (ids: (BN | number)[] = []): Observable<Option<ReferendumInfoExtended>[]> =>
return memo((ids: (BN | number)[] = []): Observable<Option<ReferendumInfoExtended>[]> =>
(
!ids || !ids.length
? of([] as Option<ReferendumInfo>[])
@@ -25,7 +25,6 @@ export function referendumInfos (api: ApiInterfaceRx): (ids?: (BN | number)[]) =
ids.map((id, index): Option<ReferendumInfoExtended> =>
constructInfo(id, infos[index])
)
),
drr()
);
)
));
}
@@ -11,10 +11,10 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
import { Vec, createType } from '@polkadot/types';
import { DerivedBalances, DerivedReferendumVote } from '../types';
import { drr } from '../util';
import { memo } from '../util';
export function referendumVotesFor (api: ApiInterfaceRx): (referendumId: BN | number) => Observable<DerivedReferendumVote[]> {
return (referendumId: BN | number): Observable<DerivedReferendumVote[]> =>
return memo((referendumId: BN | number): Observable<DerivedReferendumVote[]> =>
api.query.democracy.votersFor<Vec<AccountId>>(referendumId).pipe(
switchMap((votersFor): Observable<[Vec<AccountId>, Vote[], DerivedBalances[]]> =>
combineLatest([
@@ -29,7 +29,6 @@ export function referendumVotesFor (api: ApiInterfaceRx): (referendumId: BN | nu
balance: balances[index].votingBalance || createType('Balance'),
vote: votes[index] || createType('Vote')
} as unknown as DerivedReferendumVote))
),
drr()
);
)
));
}
@@ -11,10 +11,10 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
import { Option } from '@polkadot/types';
import { ReferendumInfoExtended } from '../type';
import { drr } from '../util';
import { memo } from '../util';
export function referendums (api: ApiInterfaceRx): () => Observable<Option<ReferendumInfoExtended>[]> {
return (): Observable<Option<ReferendumInfoExtended>[]> =>
return memo((): Observable<Option<ReferendumInfoExtended>[]> =>
api.queryMulti<[ReferendumIndex, ReferendumIndex]>([
api.query.democracy.nextTally,
api.query.democracy.referendumCount
@@ -27,7 +27,6 @@ export function referendums (api: ApiInterfaceRx): () => Observable<Option<Refer
)
)
: of([])
),
drr()
);
)
));
}
+9 -10
View File
@@ -8,17 +8,16 @@ import BN from 'bn.js';
import { Observable, of } from 'rxjs';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { drr } from '../util';
import { memo } from '../util';
export function votes (api: ApiInterfaceRx): (referendumId: BN, accountIds?: AccountId[]) => Observable<Vote[]> {
return (referendumId: BN, accountIds: AccountId[] = []): Observable<Vote[]> =>
(
!accountIds || !accountIds.length
? of([] as Vote[])
: api.query.democracy.voteOf.multi<Vote>(
accountIds.map((accountId): [BN, AccountId] =>
[referendumId, accountId]
)
return memo((referendumId: BN, accountIds: AccountId[] = []): Observable<Vote[]> =>
!accountIds || !accountIds.length
? of([] as Vote[])
: api.query.democracy.voteOf.multi<Vote>(
accountIds.map((accountId): [BN, AccountId] =>
[referendumId, accountId]
)
).pipe(drr());
)
);
}
@@ -9,7 +9,7 @@ import { Observable } from 'rxjs';
import { Vec } from '@polkadot/types';
import { switchMap, map } from 'rxjs/operators';
import { approvalFlagsToBools } from '../util/approvalFlagsToBools';
import { drr } from '../util';
import { memo } from '../util';
/**
* @name approvalsOf
@@ -24,7 +24,7 @@ import { drr } from '../util';
* ```
*/
export function approvalsOf (api: ApiInterfaceRx): (who: AccountId) => Observable<boolean[][]> {
return (who: AccountId | string): Observable<boolean[][]> =>
return memo((who: AccountId | string): Observable<boolean[][]> =>
api.query.elections.nextVoterSet<SetIndex>().pipe(
switchMap((nextVoterSet: SetIndex): Observable<Vec<ApprovalFlag>[]> =>
api.query.elections.approvalsOf.multi(
@@ -37,7 +37,6 @@ export function approvalsOf (api: ApiInterfaceRx): (who: AccountId) => Observabl
votes.map((flags: Vec<ApprovalFlag>): boolean[] =>
approvalFlagsToBools(flags)
)
),
drr()
);
)
));
}
@@ -11,7 +11,7 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
import { Vec } from '@polkadot/types';
import { approvalFlagsToBools } from '../util/approvalFlagsToBools';
import { drr } from '../util';
import { memo } from '../util';
/**
* @name approvalsOfAt
@@ -26,9 +26,8 @@ import { drr } from '../util';
* ```
*/
export function approvalsOfAt (api: ApiInterfaceRx): (who: AccountId, at: SetIndex) => Observable<boolean[]> {
return (who: AccountId | string, at: SetIndex | BN | number): Observable<boolean[]> =>
return memo((who: AccountId | string, at: SetIndex | BN | number): Observable<boolean[]> =>
api.query.elections.approvalsOf<Vec<ApprovalFlag>>([who.toString(), at]).pipe(
map((flags: Vec<ApprovalFlag>): boolean[] => approvalFlagsToBools(flags)),
drr()
);
map((flags: Vec<ApprovalFlag>): boolean[] => approvalFlagsToBools(flags))
));
}
+3 -3
View File
@@ -11,7 +11,7 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
import { createType, Vec, u32 } from '@polkadot/types';
import { DerivedElectionsInfo } from '../types';
import { drr } from '../util';
import { memo } from '../util';
type ResultElectionsInner = [u32, u32, Vec<[AccountId, BlockNumber] & Codec>, SetIndex, BlockNumber, VoteIndex, SetIndex];
type ResultElections = [Vec<AccountId>, ResultElectionsInner];
@@ -97,6 +97,6 @@ export function info (api: ApiInterfaceRx): () => Observable<DerivedElectionsInf
? queryPhragmen
: queryElections;
return (): Observable<DerivedElectionsInfo> =>
query(api).pipe(drr());
return memo((): Observable<DerivedElectionsInfo> =>
query(api));
}
@@ -11,7 +11,7 @@ import BN from 'bn.js';
import { of, combineLatest, Observable } from 'rxjs';
import { switchMap, map } from 'rxjs/operators';
import { drr } from '../util';
import { memo } from '../util';
/**
* @name voterPositions
@@ -27,7 +27,7 @@ import { drr } from '../util';
* ```
*/
export function voterPositions (api: ApiInterfaceRx): () => Observable<DerivedVoterPositions> {
return (): Observable<DerivedVoterPositions> =>
return memo((): Observable<DerivedVoterPositions> =>
api.query.elections.nextVoterSet<SetIndex>().pipe(
switchMap((nextVoterSet: SetIndex): Observable<[BN, Vec<Option<AccountId>>[]]> => combineLatest(
of(api.consts.elections.voterSetSize) as any as Observable<BN>,
@@ -53,7 +53,6 @@ export function voterPositions (api: ApiInterfaceRx): () => Observable<DerivedVo
return result;
}, {});
}),
drr()
);
})
));
}
+4 -5
View File
@@ -10,7 +10,7 @@ import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { createType, Vec } from '@polkadot/types';
import { drr } from '../util';
import { memo } from '../util';
/**
* @name voters
@@ -25,7 +25,7 @@ import { drr } from '../util';
* ```
*/
export function voters (api: ApiInterfaceRx): () => Observable<Vec<AccountId>> {
return (): Observable<Vec<AccountId>> =>
return memo((): Observable<Vec<AccountId>> =>
api.derive.elections.voterPositions().pipe(
map((voterPositions: DerivedVoterPositions): Vec<AccountId> =>
createType(
@@ -34,7 +34,6 @@ export function voters (api: ApiInterfaceRx): () => Observable<Vec<AccountId>> {
.sort((a, b): number => a[1].globalIndex.cmp(b[1].globalIndex))
.map(([accountId]): AccountId => createType('AccountId', accountId))
)
),
drr()
);
)
));
}
@@ -10,13 +10,13 @@ import { map, switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Bytes, Option, u32 } from '@polkadot/types';
import { drr } from '../util';
import { memo } from '../util';
/**
* @description Return a boolean array indicating whether the passed accounts had received heartbeats in the current session
*/
export function receivedHeartbeats (api: ApiInterfaceRx): () => Observable<DerivedHeartbeats> {
return (): Observable<DerivedHeartbeats> =>
return memo((): Observable<DerivedHeartbeats> =>
api.query.imOnline?.receivedHeartbeats && api.query.imOnline.authoredBlocks
? api.derive.staking.overview().pipe(
switchMap(({ currentIndex, validators }): Observable<[AccountId[], Option<Bytes>[], u32[]]> =>
@@ -35,8 +35,7 @@ export function receivedHeartbeats (api: ApiInterfaceRx): () => Observable<Deriv
isOnline: !heartbeats[index].isEmpty || numBlocks[index].gtn(0)
}
}), {})
),
drr()
)
)
: of({});
: of({}));
}
+4 -5
View File
@@ -9,12 +9,11 @@ import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { drr } from '../util';
import { memo } from '../util';
export function eraLength (api: ApiInterfaceRx): () => Observable<BlockNumber> {
return (): Observable<BlockNumber> =>
return memo((): Observable<BlockNumber> =>
api.derive.session.info().pipe(
map(({ eraLength }: DerivedSessionInfo): BlockNumber => eraLength),
drr()
);
map(({ eraLength }: DerivedSessionInfo): BlockNumber => eraLength)
));
}
@@ -9,12 +9,11 @@ import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { drr } from '../util';
import { memo } from '../util';
export function eraProgress (api: ApiInterfaceRx): () => Observable<BlockNumber> {
return (): Observable<BlockNumber> =>
return memo((): Observable<BlockNumber> =>
api.derive.session.info().pipe(
map(({ eraProgress }: DerivedSessionInfo): BlockNumber => eraProgress),
drr()
);
map(({ eraProgress }: DerivedSessionInfo): BlockNumber => eraProgress)
));
}
+4 -5
View File
@@ -10,10 +10,10 @@ import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { createType, u32 as U32 } from '@polkadot/types';
import { drr } from '../util';
import { memo } from '../util';
export function indexes (api: ApiInterfaceRx): () => Observable<DeriveSessionIndexes> {
return (): Observable<DeriveSessionIndexes> =>
return memo((): Observable<DeriveSessionIndexes> =>
(
// Some chains (eg. very limited node-template), does not have session
api.query.session && api.query.staking
@@ -26,7 +26,6 @@ export function indexes (api: ApiInterfaceRx): () => Observable<DeriveSessionInd
).pipe(
map(([currentIndex, currentEra, validatorCount]): DeriveSessionIndexes => ({
currentIndex, currentEra, validatorCount
})),
drr()
);
}))
));
}
+3 -3
View File
@@ -10,7 +10,7 @@ import { map } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Option, u64, createType } from '@polkadot/types';
import { drr } from '../util';
import { memo } from '../util';
type ResultV1Session = [Option<BlockNumber>, BlockNumber, BlockNumber, SessionIndex];
type ResultV1 = [BlockNumber, DeriveSessionIndexes, ResultV1Session];
@@ -127,6 +127,6 @@ export function info (api: ApiInterfaceRx): () => Observable<DerivedSessionInfo>
: infoLatestAura // 2.x with Aura (not all info there)
: infoV1;
return (): Observable<DerivedSessionInfo> =>
query(api).pipe(drr());
return memo((): Observable<DerivedSessionInfo> =>
query(api));
}
@@ -9,12 +9,11 @@ import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { drr } from '../util';
import { memo } from '../util';
export function sessionProgress (api: ApiInterfaceRx): () => Observable<BlockNumber> {
return (): Observable<BlockNumber> =>
return memo((): Observable<BlockNumber> =>
api.derive.session.info().pipe(
map(({ sessionProgress }: DerivedSessionInfo): BlockNumber => sessionProgress),
drr()
);
map(({ sessionProgress }: DerivedSessionInfo): BlockNumber => sessionProgress)
));
}
@@ -10,13 +10,13 @@ import { Observable, combineLatest, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { Option } from '@polkadot/types';
import { drr } from '../util';
import { memo } from '../util';
/**
* @description From the list of stash accounts, retrieve the list of controllers
*/
export function controllers (api: ApiInterfaceRx): () => Observable<[AccountId[], Option<AccountId>[]]> {
return (): Observable<[AccountId[], Option<AccountId>[]]> =>
return memo((): Observable<[AccountId[], Option<AccountId>[]]> =>
api.query.staking.validators<[AccountId[]] & Codec>().pipe(
switchMap(([stashIds]): Observable<[AccountId[], Option<AccountId>[]]> =>
combineLatest([
@@ -26,7 +26,6 @@ export function controllers (api: ApiInterfaceRx): () => Observable<[AccountId[]
? of([])
: api.query.staking.bonded.multi<Option<AccountId>>(stashIds)
])
),
drr()
);
)
));
}
+6 -6
View File
@@ -3,7 +3,7 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { AccountId, Balance, BlockNumber, Exposure, Keys, RewardDestination, StakingLedger, UnlockChunk, ValidatorPrefs } from '@polkadot/types/interfaces';
import { Codec } from '@polkadot/types/types';
import { ITuple } from '@polkadot/types/types';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { DerivedRecentlyOffline, DerivedStaking, DerivedUnlocking } from '../types';
@@ -15,7 +15,7 @@ import { createType, Option, Vec } from '@polkadot/types';
import { isUndefined } from '@polkadot/util';
import { drr } from '../util';
import { memo } from '../util';
interface ParseInput {
accountId: AccountId;
@@ -136,7 +136,7 @@ function parseResult ({ accountId, controllerId, stashId, eraLength, bestNumber,
};
}
type MultiResultV1 = [Option<AccountId>, Option<StakingLedger>, [Vec<AccountId>], RewardDestination, Exposure, [ValidatorPrefs] & Codec];
type MultiResultV1 = [Option<AccountId>, Option<StakingLedger>, [Vec<AccountId>], RewardDestination, Exposure, ITuple<[ValidatorPrefs]>];
function retrieveInfoV1 (api: ApiInterfaceRx, accountId: AccountId, stashId: AccountId, controllerId: AccountId): Observable<DerivedStaking> {
return combineLatest([
@@ -167,7 +167,7 @@ function retrieveInfoV2 (api: ApiInterfaceRx, accountId: AccountId, stashId: Acc
return combineLatest([
api.derive.chain.bestNumber(),
api.derive.session.eraLength(),
api.query.session.queuedKeys<Vec<[AccountId, Keys] & Codec>>(),
api.query.session.queuedKeys<Vec<ITuple<[AccountId, Keys]>>>(),
api.queryMulti([
[api.query.staking.ledger, controllerId],
[api.query.staking.nominators, stashId],
@@ -218,6 +218,6 @@ export function info (api: ApiInterfaceRx): (_accountId: Uint8Array | string) =>
? retrieveV2
: retrieveV1;
return (accountId: Uint8Array | string): Observable<DerivedStaking> =>
query(api, createType('AccountId', accountId)).pipe(drr());
return memo((accountId: Uint8Array | string): Observable<DerivedStaking> =>
query(api, createType('AccountId', accountId)));
}
+4 -5
View File
@@ -11,7 +11,7 @@ import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { Option, Vec } from '@polkadot/types';
import { drr } from '../util';
import { memo } from '../util';
// NOTE Unused ATM, preparing for V2-only
@@ -57,9 +57,8 @@ export function infoStash (api: ApiInterfaceRx): (stashId: AccountId) => Observa
? retrieveV2
: retrieveV1;
return (stashId: AccountId): Observable<DerivedStakingStash> =>
return memo((stashId: AccountId): Observable<DerivedStakingStash> =>
query(api, stashId).pipe(
map((result): DerivedStakingStash => parse(stashId, result)),
drr()
);
map((result): DerivedStakingStash => parse(stashId, result))
));
}
+4 -5
View File
@@ -10,13 +10,13 @@ import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { createType } from '@polkadot/types';
import { drr } from '../util';
import { memo } from '../util';
/**
* @description Retrieve the staking overview, including elected and points earned
*/
export function overview (api: ApiInterfaceRx): () => Observable<DerivedStakingOverview> {
return (): Observable<DerivedStakingOverview> =>
return memo((): Observable<DerivedStakingOverview> =>
combineLatest([
api.derive.session.indexes(),
api.derive.staking.validators()
@@ -32,7 +32,6 @@ export function overview (api: ApiInterfaceRx): () => Observable<DerivedStakingO
),
map(([{ currentElected, currentEra, currentIndex, validators, validatorCount }, eraPoints]): DerivedStakingOverview => ({
currentElected, currentEra, currentIndex, eraPoints, validators, validatorCount
})),
drr()
);
}))
));
}
@@ -11,7 +11,7 @@ import { map } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { DerivedRecentlyOffline } from '../types';
import { drr } from '../util';
import { memo } from '../util';
type OfflineResult = [AccountId, BlockNumber, BN][] & Codec;
@@ -36,7 +36,7 @@ function expandDerived (recentlyOffline: OfflineResult): DerivedRecentlyOffline
* @description Retrieve a keyed record of accounts recently reported to be offline
*/
export function recentlyOffline (api: ApiInterfaceRx): () => Observable<DerivedRecentlyOffline> {
return (): Observable<DerivedRecentlyOffline> =>
return memo((): Observable<DerivedRecentlyOffline> =>
(
// TODO recentlyOffline has been dropped for 2.x and replaced, figure out the
// replacement as actually use and implement it
@@ -44,7 +44,6 @@ export function recentlyOffline (api: ApiInterfaceRx): () => Observable<DerivedR
? api.query.staking.recentlyOffline<OfflineResult>()
: of([] as unknown as OfflineResult)
).pipe(
map(expandDerived),
drr()
);
map(expandDerived)
));
}
@@ -10,13 +10,13 @@ import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { Vec } from '@polkadot/types';
import { drr } from '../util';
import { memo } from '../util';
/**
* @description Retrieve latest list of validators
*/
export function validators (api: ApiInterfaceRx): () => Observable<DeriveStakingValidators> {
return (): Observable<DeriveStakingValidators> =>
return memo((): Observable<DeriveStakingValidators> =>
(
// Sadly the node-template is (for some obscure reason) not comprehensive, so while the derive works
// in all actual real-world deployed chains, it does create some confusion for limited template chains
@@ -29,7 +29,6 @@ export function validators (api: ApiInterfaceRx): () => Observable<DeriveStaking
).pipe(
map(([validators, currentElected]): DeriveStakingValidators => ({
currentElected, validators
})),
drr()
);
}))
));
}
-8
View File
@@ -1,8 +0,0 @@
// Copyright 2017-2019 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { drr as drrBase, DrrResult } from '@polkadot/rpc-core/rxjs';
export const drr = (): DrrResult =>
drrBase({ skipTimeout: true });
-1
View File
@@ -3,5 +3,4 @@
// of the Apache-2.0 license. See the LICENSE file for details.
export * from './approvalFlagsToBools';
export * from './drr';
export * from './memo';
+26 -7
View File
@@ -3,12 +3,31 @@
// of the Apache-2.0 license. See the LICENSE file for details.v
import createMemo from 'memoizee';
import { Observable, Observer } from 'rxjs';
import { drr } from '@polkadot/rpc-core/rxjs';
export function memo <T extends Function> (fn: T, withoutJSON?: boolean): T {
return withoutJSON
? createMemo(fn)
: createMemo(fn, {
// eslint-disable-next-line @typescript-eslint/unbound-method
normalizer: JSON.stringify
});
type ObsFn <T> = (...params: any[]) => Observable<T>;
// Normalize via JSON.stringify, allow e.g. AccountId -> ss58
// eslint-disable-next-line @typescript-eslint/unbound-method
const normalizer = JSON.stringify;
// Wraps a derive, doing 2 things to optimize calls -
// 1. creates a memo of the inner fn -> Observable, removing when unsubscribed
// 2. wraps the observable in a drr() (which includes an unsub delay)
export function memo <T> (inner: ObsFn<T>): ObsFn<T> {
const cached = createMemo(
(...params: any[]): Observable<T> =>
Observable.create((observer: Observer<T>): VoidCallback => {
const sub = inner(...params).subscribe(observer);
return (): void => {
cached.delete(...params);
sub.unsubscribe();
};
}).pipe(drr()),
{ normalizer }
);
return cached;
}