More cleanups to collective derives (#4320)

This commit is contained in:
Jaco
2021-12-11 10:50:33 +02:00
committed by GitHub
parent c7cb1d84ab
commit 6276e45155
3 changed files with 32 additions and 48 deletions
@@ -22,18 +22,17 @@ export function getInstance (api: ApiInterfaceRx, section: string): string {
: section;
}
export function withSection <T> (_section: Collective, fn: (section: string, instanceId: string, api: ApiInterfaceRx) => T): (instanceId: string, api: ApiInterfaceRx) => T {
export function withSection <T, F extends (...args: any[]) => Observable<T>> (_section: Collective, fn: (section: string, api: ApiInterfaceRx, instanceId: string) => F): (instanceId: string, api: ApiInterfaceRx) => F {
return (instanceId: string, api: ApiInterfaceRx) =>
fn(getInstance(api, _section), instanceId, api);
memo(instanceId, fn(getInstance(api, _section), api, instanceId)) as unknown as F;
}
export function callMethod <T> (method: 'members' | 'proposals' | 'proposalCount', empty: T): (_section: Collective) => (instanceId: string, api: ApiInterfaceRx) => () => Observable<T> {
return (_section: Collective) =>
withSection(_section, (section, instanceId, api) =>
memo(instanceId, (): Observable<T> =>
withSection(_section, (section, api) =>
(): Observable<T> =>
isFunction(api.query[section]?.[method])
? api.query[section as 'council'][method]() as unknown as Observable<T>
: of(empty)
)
);
}
+2 -4
View File
@@ -11,7 +11,6 @@ import { map, of } from 'rxjs';
import { isFunction } from '@polkadot/util';
import { memo } from '../util';
import { withSection } from './helpers';
// We are re-exporting these from here to ensure that *.d.ts generation is correct
@@ -19,8 +18,8 @@ export type { ApiInterfaceRx } from '@polkadot/api/types';
export type { AccountId } from '@polkadot/types/interfaces';
export function prime (_section: Collective): (instanceId: string, api: ApiInterfaceRx) => () => Observable<AccountId | null> {
return withSection(_section, (section, instanceId, api) =>
memo(instanceId, (): Observable<AccountId | null> =>
return withSection(_section, (section, api) =>
(): Observable<AccountId | null> =>
isFunction(api.query[section as 'council']?.prime)
? api.query[section as 'council'].prime<Option<AccountId>>().pipe(
map((optPrime): AccountId | null =>
@@ -28,6 +27,5 @@ export function prime (_section: Collective): (instanceId: string, api: ApiInter
)
)
: of(null)
)
);
}
+26 -39
View File
@@ -12,7 +12,7 @@ import { catchError, combineLatest, map, of, switchMap } from 'rxjs';
import { isFunction } from '@polkadot/util';
import { memo } from '../util';
import { firstObservable } from '../util';
import { callMethod, withSection } from './helpers';
// We are re-exporting these from here to ensure that *.d.ts generation is correct
@@ -36,61 +36,48 @@ function parse (api: ApiInterfaceRx, [hashes, proposals, votes]: Result): Derive
.filter((proposal): proposal is DeriveCollectiveProposal => !!proposal);
}
function _proposalsFrom (section: string, instanceId: string, api: ApiInterfaceRx): (hashes: (Hash | Uint8Array | string)[]) => Observable<DeriveCollectiveProposal[]> {
return memo(instanceId, (hashes: (Hash | Uint8Array | string)[]): Observable<DeriveCollectiveProposal[]> =>
(isFunction(api.query[section]?.proposals) && hashes.length
? combineLatest([
of(hashes),
// this should simply be api.query[section].proposalOf.multi<Option<Proposal>>(hashes),
// however we have had cases on Edgeware where the indices have moved around after an
// upgrade, which results in invalid on-chain data
combineLatest(hashes.map((h) =>
api.query[section].proposalOf<Option<Proposal>>(h).pipe(
catchError(() => of(null))
)
)),
api.query[section].voting.multi<Option<Votes>>(hashes)
])
: of<Result>([[], [], []])
).pipe(
map((r) => parse(api, r))
)
);
}
function withProposals <T> (_section: Collective, fn: (section: string, instanceId: string, api: ApiInterfaceRx, proposalsFrom: (hashes: (string | Hash | Uint8Array)[]) => Observable<DeriveCollectiveProposal[]>) => T): (instanceId: string, api: ApiInterfaceRx) => T {
return withSection(_section, (section, instanceId, api) =>
fn(section, instanceId, api, _proposalsFrom(section, instanceId, api))
function _proposalsFrom (section: string, api: ApiInterfaceRx, hashes: (Hash | Uint8Array | string)[]): Observable<DeriveCollectiveProposal[]> {
return (isFunction(api.query[section]?.proposals) && hashes.length
? combineLatest([
of(hashes),
// this should simply be api.query[section].proposalOf.multi<Option<Proposal>>(hashes),
// however we have had cases on Edgeware where the indices have moved around after an
// upgrade, which results in invalid on-chain data
combineLatest(hashes.map((h) =>
api.query[section].proposalOf<Option<Proposal>>(h).pipe(
catchError(() => of(null))
)
)),
api.query[section].voting.multi<Option<Votes>>(hashes)
])
: of<Result>([[], [], []])
).pipe(
map((r) => parse(api, r))
);
}
export function hasProposals (_section: Collective): (instanceId: string, api: ApiInterfaceRx) => () => Observable<boolean> {
return withSection(_section, (section, instanceId, api) =>
memo(instanceId, (): Observable<boolean> =>
return withSection(_section, (section, api) =>
(): Observable<boolean> =>
of(isFunction(api.query[section]?.proposals))
)
);
}
export function proposals (_section: Collective): (instanceId: string, api: ApiInterfaceRx) => () => Observable<DeriveCollectiveProposal[]> {
return withProposals(_section, (section, instanceId, api, proposalsFrom) =>
memo(instanceId, (): Observable<DeriveCollectiveProposal[]> =>
return withSection(_section, (section, api) =>
(): Observable<DeriveCollectiveProposal[]> =>
api.derive[section as 'council'].proposalHashes().pipe(
switchMap(proposalsFrom)
switchMap((all) => _proposalsFrom(section, api, all))
)
)
);
}
export function proposal (_section: Collective): (instanceId: string, api: ApiInterfaceRx) => (hash: Hash | Uint8Array | string) => Observable<DeriveCollectiveProposal | null> {
return withProposals(_section, (section, instanceId, api, proposalsFrom) =>
memo(instanceId, (hash: Hash | Uint8Array | string): Observable<DeriveCollectiveProposal | null> =>
return withSection(_section, (section, api) =>
(hash: Hash | Uint8Array | string): Observable<DeriveCollectiveProposal | null> =>
isFunction(api.query[section]?.proposals)
? proposalsFrom([hash]).pipe(
map(([proposal]) => proposal)
)
? firstObservable(_proposalsFrom(section, api, [hash]))
: of(null)
)
);
}