Fixup subscriptions for promise (w/ callback) (#2379)

* Fixup subscriptions for promise (w/ callback)

* Update packages/api/src/base/Decorate.ts
This commit is contained in:
Jaco Greeff
2020-06-23 11:05:51 +02:00
committed by GitHub
parent e55c5f77f7
commit 6dfebbb9fe
7 changed files with 22 additions and 14 deletions
+4
View File
@@ -1,5 +1,9 @@
# CHANGELOG
## 1.21.0-beta.x
- Promise API will default to using `getStorage` on non-subscription calls, reducing RPC overhead
## 1.20.1 Jun 22, 2020
- **Important** RPC for `account_nextIndex` has been moved to `system_accountNextIndex` (Aligning with Substrate as a primary alias)
+8 -5
View File
@@ -21,7 +21,7 @@ import { Metadata, Null, Option, Raw, Text, TypeRegistry, u64 } from '@polkadot/
import Linkage, { LinkageResult } from '@polkadot/types/codec/Linkage';
import { DEFAULT_VERSION as EXTRINSIC_DEFAULT_VERSION } from '@polkadot/types/extrinsic/constants';
import StorageKey, { StorageEntry, unwrapStorageType } from '@polkadot/types/primitive/StorageKey';
import { assert, compactStripLength, isFunction, logger, u8aToHex } from '@polkadot/util';
import { assert, compactStripLength, logger, u8aToHex } from '@polkadot/util';
import { createSubmittable } from '../submittable';
import augmentObject from '../util/augmentObject';
@@ -387,12 +387,15 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
private _decorateStorageCall<ApiType extends ApiTypes> (creator: StorageEntry, decorateMethod: DecorateMethod<ApiType>): ReturnType<DecorateMethod<ApiType>> {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return decorateMethod((...args: unknown[]): Observable<Codec> => {
return this.hasSubscriptions && (this._type === 'rxjs' || (!!args.length && isFunction(args[args.length - 1])))
return this.hasSubscriptions
? this._rpcCore.state.subscribeStorage<[Codec]>([extractStorageArgs(creator, args)]).pipe(
map(([data]) => data) // extract first/only result from list
)
: this._rpcCore.state.getStorage(extractStorageArgs(creator, args));
}, { methodName: creator.method });
}, {
methodName: creator.method,
overrideNoSub: (...args: unknown[]) => this._rpcCore.state.getStorage(extractStorageArgs(creator, args))
});
}
private _decorateStorageRange<ApiType extends ApiTypes> (decorated: QueryableStorageEntry<ApiType>, args: [Arg?, Arg?], range: [Hash, Hash?]): Observable<[Hash, Codec][]> {
@@ -480,10 +483,10 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
? this._rpcCore.state
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
.subscribeStorage<[[Codec, Linkage<Codec>]]>([[creator, ...args]])
.pipe(map(([data]): [Codec, Linkage<Codec>] => data))
.pipe(map(([data]) => data))
: this._rpcCore.state
.subscribeStorage<[LinkageResult]>([iterKey()])
.pipe(switchMap(([key]): Observable<LinkageResult> => getNext(head = key)))
.pipe(switchMap(([key]) => getNext(head = key)))
);
}
+1 -1
View File
@@ -69,7 +69,7 @@ export function decorateMethod<Method extends DecorateFn<ObsInnerType<ReturnType
const [actualArgs, resultCb] = extractArgs(args, !!needsCallback);
if (!resultCb) {
return method(...actualArgs).pipe(first()).toPromise();
return (options?.overrideNoSub || method)(...actualArgs).pipe(first()).toPromise() as Promise<ObsInnerType<ReturnType<Method>>>;
}
return new Promise<VoidFn>((resolve, reject): void => {
+1
View File
@@ -68,6 +68,7 @@ export type MethodResult<ApiType extends ApiTypes, F extends AnyFunction> = ApiT
// information. This describes it.
export interface DecorateMethodOptions {
methodName?: string;
overrideNoSub?: (...args: unknown[]) => Observable<Codec>;
}
export type DecorateFn <T extends Codec> = (...args: any[]) => Observable<T>;
+4 -4
View File
@@ -32,7 +32,7 @@ function extractKeys (src: Record<string, Record<string, any>>, dst: Record<stri
}
function findSectionExcludes (a: string[], b: string[]): string[] {
return a.filter((section): boolean => !b.includes(section));
return a.filter((section) => !b.includes(section));
}
function extractSections (src: Record<string, Record<string, any>>, dst: Record<string, Record<string, any>>): StringsStrings {
@@ -49,15 +49,15 @@ function findMethodExcludes (src: Record<string, Record<string, any>>, dst: Reco
const dstSections = Object.keys(dst);
return dstSections
.filter((section): boolean => srcSections.includes(section))
.filter((section) => srcSections.includes(section))
.reduce((rmMethods: string[], section): string[] => {
const srcMethods = Object.keys(src[section]);
return rmMethods.concat(
...Object
.keys(dst[section])
.filter((method): boolean => !srcMethods.includes(method))
.map((method): string => `${section}.${method}`)
.filter((method) => !srcMethods.includes(method))
.map((method) => `${section}.${method}`)
);
}, []);
}
+1 -1
View File
@@ -24,7 +24,7 @@ export default function filterEvents (extHash: H256, { block: { extrinsics, head
return;
}
return allEvents.filter(({ phase }): boolean =>
return allEvents.filter(({ phase }) =>
// only ApplyExtrinsic has the extrinsic index
phase.isApplyExtrinsic && phase.asApplyExtrinsic.eqn(index)
);
+3 -3
View File
@@ -11,7 +11,7 @@ function sig ({ method, section }: StorageEntry, ...args: Type[]): string {
return `${section}.${method}(${args.join(', ')})`;
}
function doDoubleMap (creator: StorageEntry, args: any[]): [StorageEntry, [any, any]] {
function doDoubleMap (creator: StorageEntry, args: unknown[]): [StorageEntry, [any, any]] {
const { key1, key2 } = creator.meta.type.asDoubleMap;
assert(args.length === 2, `${sig(creator, key1, key2)} is a doublemap, requiring 2 arguments, ${args.length} found`);
@@ -20,7 +20,7 @@ function doDoubleMap (creator: StorageEntry, args: any[]): [StorageEntry, [any,
return [creator, args as [any, any]];
}
function doMap (creator: StorageEntry, args: any[]): [StorageEntry] | [StorageEntry, any] {
function doMap (creator: StorageEntry, args: unknown[]): [StorageEntry] | [StorageEntry, any] {
const { key, linked } = creator.meta.type.asMap;
linked.isTrue
@@ -35,7 +35,7 @@ function doMap (creator: StorageEntry, args: any[]): [StorageEntry] | [StorageEn
// sets up the arguments in the form of [creator, args] ready to be used in a storage
// call. Additionally, it verifies that the correct number of arguments have been passed
export function extractStorageArgs (creator: StorageEntry, _args: any[]): [StorageEntry, [any, any]] | [StorageEntry] | [StorageEntry, any] {
export function extractStorageArgs (creator: StorageEntry, _args: unknown[]): [StorageEntry, [any, any]] | [StorageEntry] | [StorageEntry, any] {
const args = _args.filter((arg) => !isUndefined(arg));
if (creator.meta.type.isDoubleMap) {