Skip to content
This repository was archived by the owner on May 24, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
8a59985
FrequencyObservable as a function returning a observable
amaury1093 Sep 7, 2018
f113991
Fix tests
amaury1093 Sep 7, 2018
5e613d4
Test a new api
amaury1093 Sep 12, 2018
9ecae21
Make frequency observables work
amaury1093 Sep 13, 2018
660c5ef
Fix tests
amaury1093 Sep 13, 2018
6e99b67
Remove overview
amaury1093 Sep 13, 2018
e4298fa
Don't cover index.ts
amaury1093 Sep 13, 2018
bb5509c
Fix a lot of stuff
amaury1093 Sep 13, 2018
1008d5a
Remove useless import
amaury1093 Sep 13, 2018
3aa360b
Change testRegex for jest
amaury1093 Sep 13, 2018
ea75324
Add ambient for packages with no typigns
amaury1093 Sep 13, 2018
7c03c5c
Generate docs
amaury1093 Sep 13, 2018
80b283f
Remove NullProvider
amaury1093 Sep 13, 2018
a46b19a
Remove NullProvider
amaury1093 Sep 13, 2018
3447e95
Regenerate docs
amaury1093 Sep 13, 2018
1f0c25a
Silent jest on CI
amaury1093 Sep 13, 2018
b4404e2
Fix makeContract and post
amaury1093 Sep 13, 2018
165df16
Regen docs
amaury1093 Sep 13, 2018
9b8edd8
Update summary
amaury1093 Sep 13, 2018
fb89a94
Update ambient
amaury1093 Sep 13, 2018
439d3bd
Export post$ too
amaury1093 Sep 13, 2018
18e640f
Fix makeContract
amaury1093 Sep 13, 2018
431fe51
Fix memoization for frequency observables
amaury1093 Sep 17, 2018
44dde4a
Don't lint lib
amaury1093 Sep 17, 2018
15caa62
Fix bugs with rpc$
amaury1093 Sep 17, 2018
0cbe22a
Remove useless packages
amaury1093 Sep 17, 2018
85f8fb9
Generate docs
amaury1093 Sep 17, 2018
c5e0c56
Update withoutLoading syntax
amaury1093 Sep 17, 2018
82fca45
Use json.stringify for normalizer
amaury1093 Sep 17, 2018
4893e97
Fix bug normalizer
amaury1093 Sep 17, 2018
e449a57
Remove withApi in docs
amaury1093 Sep 17, 2018
3a885fe
Fix bug memoization
amaury1093 Sep 17, 2018
c6ee32e
Remove onEvery2Blocks
amaury1093 Sep 17, 2018
041441b
Options then args
amaury1093 Sep 17, 2018
8a066db
CreateRpc in makeContract fix
amaury1093 Sep 17, 2018
d2bb3c7
Fix getContract memoization
amaury1093 Sep 17, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Test a new api
  • Loading branch information
amaury1093 committed Sep 13, 2018
commit 5e613d4671d8033910151e7d0124bea8b3b4856f
26 changes: 22 additions & 4 deletions packages/light.js/example/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,33 @@
//
// SPDX-License-Identifier: MIT

import Api from '@parity/api';
import React from 'react';
import ReactDOM from 'react-dom';
import 'symbol-observable'; // TODO Remove this once https://github.com/acdlite/recompose/pull/660 is merged

import App from './App';
// import App from './App';
import light, { balanceOf$, frequency } from './light.js';
import provider from './provider';
import provider, { localProvider } from './provider';

const api = new Api(localProvider);

light.setProvider(provider);
balanceOf$.setFrequency([frequency.onEvery2Seconds$]);
const a = balanceOf$('0x73e41c8efb30c2d18a21df05dacb8ed91d3e0bbe');
const b = balanceOf$('0x73e41c8efb30c2d18a21df05dacb8ed91d3e0bbe');
const c = balanceOf$(
'0x73e41c8efb30c2d18a21df05dacb8ed91d3e0bbe',
localProvider
);
const d = balanceOf$(
'0x73e41c8efb30c2d18a21df05dacb8ed91d3e0bbe',
localProvider
);

// a.subscribe(console.log);
c.subscribe(console.log);
d.subscribe(console.log);

console.log('a === b', a === b, 'a === c', a === c, 'c === d', c === d);

ReactDOM.render(<App />, document.getElementById('root'));
// ReactDOM.render(<App />, document.getElementById('root'));
9 changes: 4 additions & 5 deletions packages/light.js/example/src/provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@

import Api from '@parity/api';

const provider =
// new Api.Provider.Ws('ws://127.0.0.1:8546', 'VrS2FTt3oWz5CJbe') // Force to use local secure Api
window.web3
? window.web3.currentProvider
: new Api.Provider.Ws('ws://127.0.0.1:8546'); // Can add PARITY_TOKEN as 2nd argument to access secure API, e.g. switch default account
export const currentProvider = window.web3 && window.web3.currentProvider;
export const localProvider = new Api.Provider.Ws('ws://127.0.0.1:8546');

const provider = currentProvider || localProvider;

export default provider;
4 changes: 3 additions & 1 deletion packages/light.js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@

import { setApi, setProvider } from './api';
import * as frequency from './frequency';
import { memoizeAll } from './rpc/utils/addMemoize';
import * as rpc from './rpc';
import './overview';

export * from './rpc';
export * from './utils/isLoading';
export * from './types';
export { withoutLoading } from './utils/operators/withoutLoading';

export { frequency };
export const { balanceOf$ } = memoizeAll(rpc);
export default { setApi, setProvider };
140 changes: 75 additions & 65 deletions packages/light.js/src/rpc/eth/eth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,79 +19,89 @@ import {
} from '../../frequency';
import { switchMapPromise } from '../../utils/operators';

/**
* Observable which contains the array of all addresses managed by the light
* client.
*
* Calls eth_accounts.
*
* @return - An Observable containing the list of public addresses.
*/
export const accounts$ = createRpc$<Address[], Address[]>({
frequency: [onAccountsChanged$],
name: 'accounts$'
});
// /**
// * Observable which contains the array of all addresses managed by the light
// * client.
// *
// * Calls eth_accounts.
// *
// * @return - An Observable containing the list of public addresses.
// */
// export const accounts$ = (api?: any) =>
// createRpc$<Address[], Address[]>(
// {
// frequency: [onAccountsChanged$],
// name: 'accounts$'
// },
// api
// );

/**
* Get the balance of a given account. Calls `eth_getBalance`.
*
* @param address - The account address to query the balance.
* @return - An Observable containing the balance.
*/
export const balanceOf$ = createRpc$<any, BigNumber>({
calls: ['eth_getBalance'],
frequency: [onEveryBlock$, onStartup$],
name: 'balanceOf$',
pipes: (address: Address) => [
switchMapPromise(() => api().eth.getBalance(address))
]
});
export const balanceOf$ = (address: Address, provider?: any) =>
createRpc$<any, BigNumber>(
{
calls: ['eth_getBalance'],
frequency: [onEveryBlock$, onStartup$],
name: 'balanceOf$',
pipes: api => [switchMapPromise(() => api.eth.getBalance(address))]
},
provider
)(address);

/**
* Get the default account managed by the light client.
*
* @return - An Observable containing the public address
* of the default account.
*/
export const defaultAccount$ = createRpc$<Address[], Address>({
dependsOn: accounts$,
name: 'defaultAccount$',
pipes: () => [map(accounts => accounts[0])]
});
// /**
// * Get the default account managed by the light client.
// *
// * @return - An Observable containing the public address
// * of the default account.
// */
// export const defaultAccount$ = (api?: any) =>
// createRpc$<Address[], Address>(
// {
// dependsOn: accounts$,
// name: 'defaultAccount$',
// pipes: [map(accounts => accounts[0])]
// },
// any
// );

/**
* Get the current block number.
*
* @return {Observable<Number>} - An Observable containing the block height.
*/
export const blockNumber$ = createRpc$<BigNumber, BigNumber>({
frequency: [onEveryBlock$],
name: 'blockNumber$'
});
// /**
// * Get the current block number.
// *
// * @return {Observable<Number>} - An Observable containing the block height.
// */
// export const blockNumber$ = createRpc$<BigNumber, BigNumber>({
// frequency: [onEveryBlock$],
// name: 'blockNumber$'
// });

/**
* Shorthand for fetching the current account's balance.
*/
export const myBalance$ = createRpc$<Address, BigNumber>({
calls: [`eth_getBalance`],
dependsOn: defaultAccount$,
name: 'myBalance$',
pipes: () => [
switchMap(
defaultAccount =>
isNullOrLoading(defaultAccount)
? of(RPC_LOADING)
: balanceOf$(defaultAccount)
)
]
});
// /**
// * Shorthand for fetching the current account's balance.
// */
// export const myBalance$ = createRpc$<Address, BigNumber>({
// calls: [`eth_getBalance`],
// dependsOn: defaultAccount$,
// name: 'myBalance$',
// pipes: () => [
// switchMap(
// defaultAccount =>
// isNullOrLoading(defaultAccount)
// ? of(RPC_LOADING)
// : balanceOf$(defaultAccount)
// )
// ]
// });

/**
* Get the syncStatus state.
*
* @return - An Observable containing the syncing state object, or false.
*/
export const syncStatus$ = createRpc$<object | boolean, object | boolean>({
frequency: [onSyncingChanged$],
name: 'syncStatus$'
});
// /**
// * Get the syncStatus state.
// *
// * @return - An Observable containing the syncing state object, or false.
// */
// export const syncStatus$ = createRpc$<object | boolean, object | boolean>({
// frequency: [onSyncingChanged$],
// name: 'syncStatus$'
// });
6 changes: 3 additions & 3 deletions packages/light.js/src/rpc/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
// SPDX-License-Identifier: MIT

export * from './eth';
export * from './net';
export * from './other';
export * from './parity';
// export * from './net';
// export * from './other';
// export * from './parity';
23 changes: 23 additions & 0 deletions packages/light.js/src/rpc/utils/addMemoize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2015-2018 Parity Technologies (UK) Ltd.
// This file is part of Parity.
//
// SPDX-License-Identifier: MIT

import * as memoizee from 'memoizee';

import { RpcKey, RpcMap } from '../../types';

/**
* Given an {@link RpcMap} of {@link RpcObservables}, memoize all the RpcObservables.
*
* @ignore
* @param rpcMap - The input RpcMap to memoize.
*/
export const memoizeAll = (rpcMap: RpcMap) =>
Object.keys(rpcMap).reduce(
(result, key) => {
(result as RpcMap)[key as RpcKey] = memoizee(rpcMap[key as RpcKey]);
return result;
},
{} as RpcMap
);
22 changes: 9 additions & 13 deletions packages/light.js/src/rpc/utils/createRpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//
// SPDX-License-Identifier: MIT

import * as memoizee from 'memoizee';
import * as Api from '@parity/api';
import { isFunction, isObject } from '@parity/api/lib/util/types';
import { merge, ReplaySubject, Observable, OperatorFunction } from 'rxjs';
import { multicast, refCount } from 'rxjs/operators';
Expand Down Expand Up @@ -50,7 +50,11 @@ const frequencyMixins = {
* @param metadata - The metadata to add.
* @return - The original RpcObservable with patched metadata.
*/
const createRpc = <Source, Out>(metadata: Metadata<Source, Out>) => {
const createRpc = <Source, Out>(
metadata: Metadata<Source, Out>,
provider: any
) => {
const api = provider ? new Api(provider) : getApi();
// rpc$ will hold the RpcObservable minus its metadata
const rpc$: RpcObservableWithoutMetadata<Source, Out> = (...args: any[]) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add memoization based on api and the observable args

// The source Observable can either be another RpcObservable (in the
Expand All @@ -73,7 +77,7 @@ const createRpc = <Source, Out>(metadata: Metadata<Source, Out>) => {
// The pipes to add
const pipes: OperatorFunction<any, any>[] = [];
if (metadata.pipes && isFunction(metadata.pipes)) {
pipes.push(...metadata.pipes(...args));
pipes.push(...metadata.pipes(api));
}
pipes.push(multicast(() => subject$), refCount());
if (options.withoutLoading === true) {
Expand All @@ -92,17 +96,9 @@ const createRpc = <Source, Out>(metadata: Metadata<Source, Out>) => {
return source$.pipe(...pipes);
};

// We memoize only if the api has been already set by the user. The reason
// is: at startup the NullProvider is used. If we memoized, then this
// provider will be used all the time
const memoizedRpc$ =
getApi() instanceof NullProvider
? rpc$
: memoizee(rpc$, { primitive: true, length: false });
Object.assign(rpc$, frequencyMixins, { metadata });

Object.assign(memoizedRpc$, frequencyMixins, { metadata });

return memoizedRpc$ as RpcObservable<Source, Out>;
return rpc$ as RpcObservable<Source, Out>;
};

export default createRpc;
34 changes: 31 additions & 3 deletions packages/light.js/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
import BigNumber from 'bignumber.js';
import { Observable, OperatorFunction, ReplaySubject } from 'rxjs';

import * as frequency from './frequency';
import * as rpc from './rpc';

declare global {
interface Window {
parity: any;
Expand Down Expand Up @@ -34,17 +37,42 @@ export interface Metadata<Source, Out> {
pipes?: (...args: any[]) => OperatorFunction<Source, Out>[];
}

export interface FrequencyObservable<T> {
(): Observable<T>;
metadata?: { calls?: string[]; name: string };
export type FrequencyKey = keyof typeof frequency;

export interface FrequencyObservableMetadata {
calls?: string[];
name: string;
}

export interface FrequencyObservable<T> extends Observable<T> {
metadata?: FrequencyObservableMetadata;
}

export type FrequencyMap = {
[index in FrequencyKey]: FrequencyObservable<any>
};

export interface MakeContract {
abi: any; // use types from @parity/abi
address: string;
readonly contractObject: any; // TODO from @parity/api
[index: string]: any | string | ((...args: any[]) => any); // use types from @parity/abi
}

export type RpcKey = keyof typeof rpc;

export interface RpcObservable<Source, Out> {
(...args: any[]): Observable<Out>;
metadata?: Metadata<Source, Out>;
setFrequency?(frequency: FrequencyObservable<Source>[]): void; // post$, makeContract... don't have setFrequency
}

export type RpcMap = { [index in RpcKey]: RpcObservable<any, any> };

export interface RpcObservableOptions {
withoutLoading?: boolean;
}

// TODO This should be on @parity/api
export type Tx = {
from: Address;
Expand Down