@polkadot/api/rx (#233)
* api-rx (new) * Update SubmittableExtrinsic.ts * Update types.d.ts * Update index.ts * Retrieve genesisHash * extrinsics -> tx, state -> st * Update index.ts * Type cleanup * Update index.ts * Update index.ts * Update index.ts * Sign returns SubmittableExtrinsic * Example cleanup * Move to api-rx package * Add connected/disconnected events * Expand storage creation * isReady/isConnected * Add static create * Cleanup docs * Cleanups * ReplaySubjects * Basic tests * Add runtimeVersion * Test for version, meta & hash * Package location * Expand README * 2 ways of init * whenReady -> isReady * api-rx -> api/rx * Namings
This commit is contained in:
@@ -6,7 +6,8 @@ import { RpcInterface, RpcInterface$Section } from '@polkadot/rpc-core/types';
|
||||
import { ProviderInterface } from '@polkadot/rpc-provider/types';
|
||||
import { RxRpcInterface, RxRpcInterface$Section } from './types';
|
||||
|
||||
import { BehaviorSubject, Observable, Subscriber, from } from 'rxjs';
|
||||
import E3 from 'eventemitter3';
|
||||
import { BehaviorSubject, ReplaySubject, Observable, Subscriber, from } from 'rxjs';
|
||||
import Rpc from '@polkadot/rpc-core/index';
|
||||
import Ws from '@polkadot/rpc-provider/ws';
|
||||
import isFunction from '@polkadot/util/is/function';
|
||||
@@ -16,7 +17,7 @@ import defaults from './defaults';
|
||||
|
||||
type CachedMap = {
|
||||
[index: string]: {
|
||||
[index: string]: BehaviorSubject<any>
|
||||
[index: string]: ReplaySubject<any>
|
||||
}
|
||||
};
|
||||
|
||||
@@ -36,7 +37,7 @@ type CachedMap = {
|
||||
* const api = new RpcRx(provider);
|
||||
* ```
|
||||
*/
|
||||
export default class RpcRx implements RxRpcInterface {
|
||||
export default class RpcRx extends E3.EventEmitter implements RxRpcInterface {
|
||||
private _api: RpcInterface;
|
||||
private _cacheMap: CachedMap;
|
||||
private _isConnected: BehaviorSubject<boolean>;
|
||||
@@ -49,12 +50,13 @@ export default class RpcRx implements RxRpcInterface {
|
||||
* @param {ProviderInterface} provider An API provider using HTTP or WebSocket
|
||||
*/
|
||||
constructor (provider: ProviderInterface = new Ws(defaults.WS_URL)) {
|
||||
super();
|
||||
|
||||
this._api = new Rpc(provider);
|
||||
this._cacheMap = {};
|
||||
this._isConnected = new BehaviorSubject(provider.isConnected());
|
||||
|
||||
provider.on('connected', () => this._isConnected.next(true));
|
||||
provider.on('disconnected', () => this._isConnected.next(false));
|
||||
this.initEmitters(provider);
|
||||
|
||||
this.author = this.createInterface('author', this._api.author);
|
||||
this.chain = this.createInterface('chain', this._api.chain);
|
||||
@@ -66,6 +68,20 @@ export default class RpcRx implements RxRpcInterface {
|
||||
return this._isConnected;
|
||||
}
|
||||
|
||||
private initEmitters (provider: ProviderInterface): void {
|
||||
provider.on('connected', () => {
|
||||
this._isConnected.next(true);
|
||||
|
||||
this.emit('connected');
|
||||
});
|
||||
|
||||
provider.on('disconnected', () => {
|
||||
this._isConnected.next(false);
|
||||
|
||||
this.emit('disconnected');
|
||||
});
|
||||
}
|
||||
|
||||
private createInterface (sectionName: string, section: RpcInterface$Section): RxRpcInterface$Section {
|
||||
return Object
|
||||
.keys(section)
|
||||
@@ -77,7 +93,7 @@ export default class RpcRx implements RxRpcInterface {
|
||||
}, ({} as RxRpcInterface$Section));
|
||||
}
|
||||
|
||||
private createObservable (subName: string, name: string, section: RpcInterface$Section): (...params: Array<any>) => Observable<any> | BehaviorSubject<any> {
|
||||
private createObservable (subName: string, name: string, section: RpcInterface$Section): (...params: Array<any>) => Observable<any> | ReplaySubject<any> {
|
||||
if (isFunction(section[name].unsubscribe)) {
|
||||
return this.createCachedObservable(subName, name, section);
|
||||
}
|
||||
@@ -92,12 +108,12 @@ export default class RpcRx implements RxRpcInterface {
|
||||
);
|
||||
}
|
||||
|
||||
private createCachedObservable (subName: string, name: string, section: RpcInterface$Section): (...params: Array<any>) => BehaviorSubject<any> {
|
||||
private createCachedObservable (subName: string, name: string, section: RpcInterface$Section): (...params: Array<any>) => ReplaySubject<any> {
|
||||
if (!this._cacheMap[subName]) {
|
||||
this._cacheMap[subName] = {};
|
||||
}
|
||||
|
||||
return (...params: Array<any>): BehaviorSubject<any> => {
|
||||
return (...params: Array<any>): ReplaySubject<any> => {
|
||||
const paramStr = JSON.stringify(params);
|
||||
|
||||
if (!this._cacheMap[subName][paramStr]) {
|
||||
@@ -108,8 +124,8 @@ export default class RpcRx implements RxRpcInterface {
|
||||
};
|
||||
}
|
||||
|
||||
private createSubject (name: string, params: Array<any>, section: RpcInterface$Section, unsubCallback?: () => void): BehaviorSubject<any> {
|
||||
const subject = new BehaviorSubject(undefined);
|
||||
private createSubject (name: string, params: Array<any>, section: RpcInterface$Section, unsubCallback?: () => void): ReplaySubject<any> {
|
||||
const subject = new ReplaySubject(1);
|
||||
|
||||
Observable
|
||||
.create((observer: Subscriber<any>): Function => {
|
||||
|
||||
Vendored
+6
-4
@@ -2,21 +2,23 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the ISC license. See the LICENSE file for details.
|
||||
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
|
||||
import { ReplaySubject, Observable } from 'rxjs';
|
||||
import interfaces from '@polkadot/jsonrpc/types';
|
||||
|
||||
export type RxRpcInterface$Method = (...params: Array<any>) => Observable<any> | BehaviorSubject<any>;
|
||||
export type RxRpcInterface$Method = (...params: Array<any>) => Observable<any> | ReplaySubject<any>;
|
||||
|
||||
export type RxRpcInterface$Section = {
|
||||
[index: string]: RxRpcInterface$Method
|
||||
};
|
||||
|
||||
export type RxRpcInterface$Events = 'connected' | 'disconnected';
|
||||
|
||||
export type RxRpcInterface = {
|
||||
readonly author: RxRpcInterface$Section;
|
||||
readonly chain: RxRpcInterface$Section;
|
||||
readonly state: RxRpcInterface$Section;
|
||||
readonly system: RxRpcInterface$Section;
|
||||
|
||||
isConnected: () => BehaviorSubject<boolean>
|
||||
isConnected: () => Observable<boolean>
|
||||
on: (type: RxRpcInterface$Events, handler: (...args: Array<any>) => any) => void;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user