From 6276e4515555aa6fbb046e095b018cc5e97d8d66 Mon Sep 17 00:00:00 2001 From: Jaco Date: Sat, 11 Dec 2021 09:50:33 +0100 Subject: [PATCH] More cleanups to collective derives (#4320) --- packages/api-derive/src/collective/helpers.ts | 9 ++- packages/api-derive/src/collective/prime.ts | 6 +- .../api-derive/src/collective/proposals.ts | 65 ++++++++----------- 3 files changed, 32 insertions(+), 48 deletions(-) diff --git a/packages/api-derive/src/collective/helpers.ts b/packages/api-derive/src/collective/helpers.ts index 74b1bf0730..0f89f3e585 100644 --- a/packages/api-derive/src/collective/helpers.ts +++ b/packages/api-derive/src/collective/helpers.ts @@ -22,18 +22,17 @@ export function getInstance (api: ApiInterfaceRx, section: string): string { : section; } -export function withSection (_section: Collective, fn: (section: string, instanceId: string, api: ApiInterfaceRx) => T): (instanceId: string, api: ApiInterfaceRx) => T { +export function withSection Observable> (_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 (method: 'members' | 'proposals' | 'proposalCount', empty: T): (_section: Collective) => (instanceId: string, api: ApiInterfaceRx) => () => Observable { return (_section: Collective) => - withSection(_section, (section, instanceId, api) => - memo(instanceId, (): Observable => + withSection(_section, (section, api) => + (): Observable => isFunction(api.query[section]?.[method]) ? api.query[section as 'council'][method]() as unknown as Observable : of(empty) - ) ); } diff --git a/packages/api-derive/src/collective/prime.ts b/packages/api-derive/src/collective/prime.ts index c9305b9a88..4c84214753 100644 --- a/packages/api-derive/src/collective/prime.ts +++ b/packages/api-derive/src/collective/prime.ts @@ -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 { - return withSection(_section, (section, instanceId, api) => - memo(instanceId, (): Observable => + return withSection(_section, (section, api) => + (): Observable => isFunction(api.query[section as 'council']?.prime) ? api.query[section as 'council'].prime>().pipe( map((optPrime): AccountId | null => @@ -28,6 +27,5 @@ export function prime (_section: Collective): (instanceId: string, api: ApiInter ) ) : of(null) - ) ); } diff --git a/packages/api-derive/src/collective/proposals.ts b/packages/api-derive/src/collective/proposals.ts index 80ec083355..3ff58305b7 100644 --- a/packages/api-derive/src/collective/proposals.ts +++ b/packages/api-derive/src/collective/proposals.ts @@ -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 { - return memo(instanceId, (hashes: (Hash | Uint8Array | string)[]): Observable => - (isFunction(api.query[section]?.proposals) && hashes.length - ? combineLatest([ - of(hashes), - // this should simply be api.query[section].proposalOf.multi>(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>(h).pipe( - catchError(() => of(null)) - ) - )), - api.query[section].voting.multi>(hashes) - ]) - : of([[], [], []]) - ).pipe( - map((r) => parse(api, r)) - ) - ); -} - -function withProposals (_section: Collective, fn: (section: string, instanceId: string, api: ApiInterfaceRx, proposalsFrom: (hashes: (string | Hash | Uint8Array)[]) => Observable) => 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 { + return (isFunction(api.query[section]?.proposals) && hashes.length + ? combineLatest([ + of(hashes), + // this should simply be api.query[section].proposalOf.multi>(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>(h).pipe( + catchError(() => of(null)) + ) + )), + api.query[section].voting.multi>(hashes) + ]) + : of([[], [], []]) + ).pipe( + map((r) => parse(api, r)) ); } export function hasProposals (_section: Collective): (instanceId: string, api: ApiInterfaceRx) => () => Observable { - return withSection(_section, (section, instanceId, api) => - memo(instanceId, (): Observable => + return withSection(_section, (section, api) => + (): Observable => of(isFunction(api.query[section]?.proposals)) - ) ); } export function proposals (_section: Collective): (instanceId: string, api: ApiInterfaceRx) => () => Observable { - return withProposals(_section, (section, instanceId, api, proposalsFrom) => - memo(instanceId, (): Observable => + return withSection(_section, (section, api) => + (): Observable => 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 { - return withProposals(_section, (section, instanceId, api, proposalsFrom) => - memo(instanceId, (hash: Hash | Uint8Array | string): Observable => + return withSection(_section, (section, api) => + (hash: Hash | Uint8Array | string): Observable => isFunction(api.query[section]?.proposals) - ? proposalsFrom([hash]).pipe( - map(([proposal]) => proposal) - ) + ? firstObservable(_proposalsFrom(section, api, [hash])) : of(null) - ) ); }