Basic same-type multi queries (#866)

* Basic same-type multi queries

* Remove extra map, straight to switchMap
This commit is contained in:
Jaco Greeff
2019-05-27 15:46:30 +12:00
committed by ian.he
parent 89ebae9d78
commit d9e581fbdc
8 changed files with 38 additions and 14 deletions
@@ -20,7 +20,9 @@ export function indexToId (api: ApiInterface$Rx) {
return (querySection.enumSet(accountIndex.div(ENUMSET_SIZE)) as Observable<Vector<AccountId>>)
.pipe(
startWith([]),
map((accounts) => (accounts || [])[accountIndex.mod(ENUMSET_SIZE).toNumber()]),
map((accounts) =>
(accounts || [])[accountIndex.mod(ENUMSET_SIZE).toNumber()]
),
drr()
);
};
+6 -9
View File
@@ -2,7 +2,7 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { combineLatest, Observable } from 'rxjs';
import { Observable } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { ApiInterface$Rx } from '@plugnet/api/types';
import { ENUMSET_SIZE } from '@plugnet/types/type/AccountIndex';
@@ -24,15 +24,12 @@ export function indexes (api: ApiInterface$Rx) {
return (api.query.indices.nextEnumSet() as Observable<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, ...]
map((next: AccountIndex) =>
[...Array(next.toNumber() + 1).keys()]
// 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) =>
api.query.indices.enumSet.multi([...Array(next.toNumber() + 1).keys()]) as Observable<any>
),
switchMap((enumRange) => combineLatest(
// retrieve the full enum set for the specific index - each query can return
// up to ENUMSET_SIZE (64) records, each containing an AccountId
enumRange.map((index) => (api.query.indices.enumSet(index) as Observable<any>))
)),
map((all: Array<Array<AccountId> | undefined>) =>
(all || []).reduce((result, list, outerIndex) => {
(list || []).forEach((accountId, innerIndex) => {
+1
View File
@@ -12,6 +12,7 @@ import { drr } from '../util/drr';
export function fees (api: ApiInterface$Rx) {
return (): Observable<DerivedFees> => {
// FIXME Remove fees checks, only use balances (fees is a removed module now)
return (combineLatest([
api.query.balances.creationFee(),
api.query.balances.existentialDeposit(),
@@ -14,6 +14,7 @@ export function votes (api: ApiInterface$Rx) {
return !accountIds || !accountIds.length
? of([]).pipe(drr())
: combineLatest(
// FIXME Convert to multi
accountIds.map(
(accountId) => api.query.democracy.voteOf([referendumId, accountId]) as Observable<Vote>
)
@@ -11,6 +11,7 @@ import { drr } from '../util/drr';
function allBonds (api: ApiInterface$Rx, stashIds: Array<AccountId>) {
return combineLatest(
// FIXME Convert to multi
stashIds.map((id) =>
(api.query.staking.bonded(id) as Observable<Option<AccountId>>)
)
+10 -4
View File
@@ -548,16 +548,22 @@ export default abstract class ApiBase<CodecResult, SubscriptionResult> implement
[arg]
) as unknown as HashResult<C, S>;
// FIXME as above...
decorated.key = (arg?: CodecArg): string =>
u8aToHex(compactStripLength(method(arg))[1]);
decorated.multi = (args: Array<CodecArg>, callback?: CodecCallback): S =>
onCall(
() => this._rpcRx.state.subscribeStorage(args.map((arg) => [method, arg])),
[],
callback
) as unknown as S;
decorated.size = (arg?: CodecArg): U64Result<C, S> =>
onCall(
(arg: CodecArg) => this._rpcRx.state.getStorageSize([method, arg]),
[arg]
) as unknown as U64Result<C, S>;
decorated.key = (arg?: CodecArg): string =>
u8aToHex(compactStripLength(method(arg))[1]);
return this.decorateFunctionMeta(method, decorated) as QueryableStorageFunction<C, S>;
}
+1
View File
@@ -52,6 +52,7 @@ export interface QueryableStorageFunctionBase<CodecResult, SubscriptionResult> e
at: (hash: Hash | Uint8Array | string, arg?: CodecArg) => CodecResult;
hash: (arg?: CodecArg) => HashResult<CodecResult, SubscriptionResult>;
key: (arg?: CodecArg) => string;
multi: (args: Array<CodecArg>, callback?: CodecCallback) => SubscriptionResult;
size: (arg?: CodecArg) => U64Result<CodecResult, SubscriptionResult>;
}
@@ -78,6 +78,21 @@ describe.skip('e2e queries', () => {
});
});
it('subscribes to multiple results (freeBalance.multi)', (done) => {
api.query.balances.freeBalance.multi([
keyring.alice.address(),
keyring.bob.address(),
keyring.ferdie.address(),
'5DTestUPts3kjeXSTMyerHihn1uwMfLj8vU8sqF7qYrFabHE'
], (balances) => {
expect(balances).toHaveLength(4);
console.error(balances);
done();
});
});
it('makes a query at a specific block', async () => {
const header = await api.rpc.chain.getHeader();
const events = await api.query.system.events.at(header.hash);