Add derive functions (#540)
* Make types work * Add test for derive * Skip e2e * Change description * Add some comments * Add caching * Integrate cache * Add tests * Add test * Fix types in tests * Add e2e tests * Add comments * Fix lint * Bump versions * Remove useless stuff * Address grumbles
This commit is contained in:
committed by
Jaco Greeff
parent
22123f9491
commit
f6c93e48b7
@@ -2,7 +2,8 @@ const config = require('@polkadot/dev/config/jest');
|
||||
|
||||
module.exports = Object.assign({}, config, {
|
||||
moduleNameMapper: {
|
||||
'@polkadot/api$': '<rootDir>/packages/api/src/$1',
|
||||
'@polkadot/api-derive(.*)$': '<rootDir>/packages/api-derive/src/$1',
|
||||
'@polkadot/api(.*)$': '<rootDir>/packages/api/src/$1',
|
||||
'@polkadot/rpc-(core|provider|rx)(.*)$': '<rootDir>/packages/rpc-$1/src/$2',
|
||||
'@polkadot/extrinsics(.*)$': '<rootDir>/packages/type-extrinsics/src/$1',
|
||||
'@polkadot/jsonrpc(.*)$': '<rootDir>/packages/type-jsonrpc/src/$1',
|
||||
@@ -11,6 +12,7 @@ module.exports = Object.assign({}, config, {
|
||||
},
|
||||
modulePathIgnorePatterns: [
|
||||
'<rootDir>/packages/api/build',
|
||||
'<rootDir>/packages/api-derive/build',
|
||||
'<rootDir>/packages/rpc-core/build',
|
||||
'<rootDir>/packages/rpc-provider/build',
|
||||
'<rootDir>/packages/rpc-rx/build',
|
||||
|
||||
201
packages/api-derive/LICENSE
Normal file
201
packages/api-derive/LICENSE
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
3
packages/api-derive/README.md
Normal file
3
packages/api-derive/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# @polkadot/api-derive
|
||||
|
||||
Common functions used across Polkadot, derived from RPC calls and storage queries.
|
||||
41
packages/api-derive/package.json
Normal file
41
packages/api-derive/package.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"name": "@polkadot/api-derive",
|
||||
"version": "0.38.1",
|
||||
"description": "Common functions used across Polkadot, derived from RPC calls and storage queries.",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
"Polkadot",
|
||||
"Promise",
|
||||
"RxJs"
|
||||
],
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"maintainers": [
|
||||
"Jaco Greeff <jacogr@gmail.com>"
|
||||
],
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=8.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/polkadot-js/api.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/polkadot-js/api/issues"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/api/tree/master/packages/api-derive#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.2.0",
|
||||
"@polkadot/api": "^0.38.1",
|
||||
"@polkadot/types": "^0.38.1",
|
||||
"@types/memoizee": "^0.4.2",
|
||||
"@types/rx": "^4.1.1",
|
||||
"memoizee": "^0.4.14",
|
||||
"rxjs": "^6.3.3"
|
||||
}
|
||||
}
|
||||
30
packages/api-derive/src/cache.spec.ts
Normal file
30
packages/api-derive/src/cache.spec.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright 2017-2019 @polkadot/ui-react-rx authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import ApiRx from '@polkadot/api/rx';
|
||||
|
||||
import { cache } from './cache';
|
||||
|
||||
describe('cache', () => {
|
||||
const f = cache((api: ApiRx) => (a: number, b: number) => [api, a, b]);
|
||||
const api = {} as ApiRx;
|
||||
|
||||
it('should hit cache when all arguments are the same', () => {
|
||||
const first = f(api)(2, 3);
|
||||
const second = f(api)(2, 3);
|
||||
|
||||
expect(first).toBe(second);
|
||||
});
|
||||
|
||||
it('should not hit cache when some arguments are not the same', () => {
|
||||
const first = f(api)(2, 3);
|
||||
const second1 = f(api)(5, 3);
|
||||
const second2 = f(api)(2, 5);
|
||||
const second3 = f({} as ApiRx)(2, 3);
|
||||
|
||||
expect(first).not.toBe(second1);
|
||||
expect(first).not.toBe(second2);
|
||||
expect(first).not.toBe(second3);
|
||||
});
|
||||
});
|
||||
30
packages/api-derive/src/cache.ts
Normal file
30
packages/api-derive/src/cache.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright 2017-2019 @polkadot/ui-react-rx authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import memoizee from 'memoizee';
|
||||
import ApiRx from '@polkadot/api/rx';
|
||||
|
||||
/**
|
||||
* Create memoization for a 2-currified function.
|
||||
*
|
||||
* @param fn - The function to memoize.
|
||||
* @param map - The Map used to cache function returns.
|
||||
* @example
|
||||
* ```javascript
|
||||
* const f = (api: ApiRx) => (b: number) => a * b;
|
||||
* const cached = cache(f);
|
||||
* f(api)(1, 2);
|
||||
* f(api)(1); // Cache not hit
|
||||
* f({})(1, 2); // Cache not hit
|
||||
* f(api)(1, 2); // Cache hit
|
||||
* ```
|
||||
*/
|
||||
export const cache = (fn: Function, map = new WeakMap()) => (api: ApiRx) => {
|
||||
if (!map.has(api)) {
|
||||
const innerFn = fn(api);
|
||||
map.set(api, memoizee(innerFn));
|
||||
}
|
||||
|
||||
return map.get(api);
|
||||
};
|
||||
20
packages/api-derive/src/chain/bestNumber.ts
Normal file
20
packages/api-derive/src/chain/bestNumber.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright 2017-2019 @polkadot/ui-react-rx authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import { filter, map } from 'rxjs/operators';
|
||||
import ApiRx from '@polkadot/api/rx';
|
||||
import { BlockNumber, Header } from '@polkadot/types/index';
|
||||
|
||||
/**
|
||||
* Get the latest block number.
|
||||
*/
|
||||
export function bestNumber (api: ApiRx) {
|
||||
return (): Observable<BlockNumber> =>
|
||||
api.rpc.chain.subscribeNewHead()
|
||||
.pipe(
|
||||
filter((header: Header) => header && !!header.blockNumber),
|
||||
map(({ blockNumber }: Header) => blockNumber)
|
||||
);
|
||||
}
|
||||
5
packages/api-derive/src/chain/index.ts
Normal file
5
packages/api-derive/src/chain/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
// Copyright 2017-2019 @polkadot/ui-react-rx authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
export * from './bestNumber';
|
||||
38
packages/api-derive/src/index.spec.ts
Normal file
38
packages/api-derive/src/index.spec.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright 2017-2019 @polkadot/ui-react-rx authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Observable } from 'rxjs';
|
||||
import ApiRx from '@polkadot/api/rx';
|
||||
import MockProvider from '@polkadot/rpc-provider/mock';
|
||||
|
||||
import { Derive } from './index';
|
||||
|
||||
const testFunction = (api: ApiRx) => {
|
||||
return <
|
||||
Section extends keyof Derive,
|
||||
Method extends keyof (typeof api.derive[Section])
|
||||
>(section: Section, method: Method, inputs: any[]) => {
|
||||
describe(`derive.${section}.${method}`, () => {
|
||||
it('should return an Observable', () => {
|
||||
expect((api.derive[section][method] as any)(...inputs) instanceof Observable);
|
||||
});
|
||||
|
||||
it('should be memoized', () => {
|
||||
const first = (api.derive[section][method] as any)(...inputs);
|
||||
const second = (api.derive[section][method] as any)(...inputs);
|
||||
|
||||
expect(first).toBe(second);
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
describe('derive', () => {
|
||||
const api = new ApiRx(new MockProvider());
|
||||
|
||||
beforeAll((done) => api.isReady.subscribe(() => done()));
|
||||
|
||||
testFunction(api)('chain', 'bestNumber', []);
|
||||
testFunction(api)('session', 'sessionProgress', []);
|
||||
});
|
||||
45
packages/api-derive/src/index.ts
Normal file
45
packages/api-derive/src/index.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2017-2019 @polkadot/ui-react-rx authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import ApiRx from '@polkadot/api/rx';
|
||||
|
||||
import { cache } from './cache';
|
||||
import * as chain from './chain';
|
||||
import * as session from './session';
|
||||
|
||||
// Put all derived functions in an object, for easier Object.keys()-ing.
|
||||
const functions = { chain, session };
|
||||
|
||||
/**
|
||||
* T represents the section here (chain, balances...), and P represents
|
||||
* the function name (bestNumber, sessionProgress...).
|
||||
*/
|
||||
type ReturnTypes<T extends Record<keyof T, (...args: any[]) => any>> = {
|
||||
[P in keyof T]: ReturnType<T[P]>
|
||||
};
|
||||
|
||||
export interface Derive {
|
||||
chain: ReturnTypes<typeof chain>;
|
||||
session: ReturnTypes<typeof session>;
|
||||
}
|
||||
|
||||
export default function decorateDerive (api: ApiRx): Derive {
|
||||
const derive = {} as Derive;
|
||||
|
||||
Object.keys(functions).forEach((sectionName: string) => {
|
||||
const section = functions[sectionName as keyof Derive];
|
||||
derive[sectionName as keyof Derive] = Object.keys(section).reduce((result, methodName) => {
|
||||
// Create cache for the section_method function
|
||||
// @ts-ignore No idea how to make this work...
|
||||
const cached = cache(section[methodName as keyof section]);
|
||||
// Add this cached function into the result
|
||||
// @ts-ignore No idea how to make this work...
|
||||
result[methodName as keyof section] = cached(api);
|
||||
|
||||
return result;
|
||||
}, {} as ReturnTypes<typeof section>);
|
||||
});
|
||||
|
||||
return derive;
|
||||
}
|
||||
5
packages/api-derive/src/session/index.ts
Normal file
5
packages/api-derive/src/session/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
// Copyright 2017-2019 @polkadot/ui-react-rx authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
export * from './sessionProgress';
|
||||
26
packages/api-derive/src/session/sessionProgress.ts
Normal file
26
packages/api-derive/src/session/sessionProgress.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright 2017-2019 @polkadot/ui-react-rx authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { combineLatest, Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import ApiRx from '@polkadot/api/rx';
|
||||
import { BlockNumber } from '@polkadot/types/index';
|
||||
|
||||
import { bestNumber } from '../chain';
|
||||
|
||||
export function sessionProgress (api: ApiRx) {
|
||||
return (): Observable<BN> =>
|
||||
combineLatest([
|
||||
bestNumber(api)(),
|
||||
api.query.session.sessionLength(),
|
||||
api.query.session.lastLengthChange()
|
||||
]).pipe(map(
|
||||
([bestNumber, sessionLength, lastLengthChange]) =>
|
||||
(bestNumber as BlockNumber || new BN(0))
|
||||
.sub(lastLengthChange as BlockNumber || new BN(0))
|
||||
.add(sessionLength as BlockNumber || new BN(1))
|
||||
.mod(sessionLength as BlockNumber || new BN(1))
|
||||
));
|
||||
}
|
||||
38
packages/api-derive/test/e2e/derive.spec.ts
Normal file
38
packages/api-derive/test/e2e/derive.spec.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright 2017-2018 @polkadot/api-derive authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import BN from 'bn.js';
|
||||
import ApiRx from '@polkadot/api/rx';
|
||||
import { BlockNumber } from '@polkadot/types/index';
|
||||
|
||||
describe.skip('derive e2e', () => {
|
||||
let api: ApiRx;
|
||||
|
||||
beforeAll(() => {
|
||||
jest.setTimeout(30000);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
api = await ApiRx.create().toPromise();
|
||||
});
|
||||
|
||||
it('derive.chain.bestNumber', async (done) => {
|
||||
api.derive.chain.bestNumber().subscribe((blockNumber: BlockNumber) => {
|
||||
expect(blockNumber instanceof BlockNumber).toBe(true);
|
||||
expect(blockNumber.gten(0)).toBe(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('derive.session.sessionProgress', async (done) => {
|
||||
api.derive.session.sessionProgress().subscribe((progress: BN) => {
|
||||
expect(progress instanceof BN).toBe(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
jest.setTimeout(5000);
|
||||
});
|
||||
});
|
||||
@@ -8,6 +8,7 @@ import { ApiRxInterface, QueryableStorageFunction, QueryableModuleStorage, Query
|
||||
|
||||
import { Observable, from, of } from 'rxjs';
|
||||
import { catchError, map } from 'rxjs/operators';
|
||||
import decorateDerive, { Derive } from '@polkadot/api-derive/index';
|
||||
import Rpc from '@polkadot/rpc-core/index';
|
||||
import RpcRx from '@polkadot/rpc-rx/index';
|
||||
import { Storage } from '@polkadot/storage/types';
|
||||
@@ -118,6 +119,7 @@ import SubmittableExtrinsic from './SubmittableExtrinsic';
|
||||
* ```
|
||||
*/
|
||||
export default class ApiRx extends ApiBase<RpcRx, QueryableStorage, SubmittableExtrinsics> implements ApiRxInterface {
|
||||
protected _derive: Derive;
|
||||
private _isReady: Observable<ApiRx>;
|
||||
|
||||
/**
|
||||
@@ -165,6 +167,7 @@ export default class ApiRx extends ApiBase<RpcRx, QueryableStorage, SubmittableE
|
||||
|
||||
assert(this.hasSubscriptions, 'ApiRx can only be used with a provider supporting subscriptions');
|
||||
|
||||
this._derive = decorateDerive(this);
|
||||
this._isReady = from(
|
||||
// convinced you can observable from an event, however my mind groks this form better
|
||||
new Promise((resolveReady) =>
|
||||
@@ -175,6 +178,10 @@ export default class ApiRx extends ApiBase<RpcRx, QueryableStorage, SubmittableE
|
||||
);
|
||||
}
|
||||
|
||||
get derive (): Derive {
|
||||
return this._derive;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Observable that carries the connected state for the provider. Results in a boolean flag that is true/false based on the connectivity.
|
||||
*/
|
||||
|
||||
@@ -11,6 +11,7 @@ import interfaces from '@polkadot/jsonrpc/index';
|
||||
import testKeyring from '@polkadot/keyring/testing';
|
||||
import storage from '@polkadot/storage/static';
|
||||
import { Codec } from '@polkadot/types/types';
|
||||
import metadata from '@polkadot/types/Metadata/static';
|
||||
import { Header } from '@polkadot/types/index';
|
||||
import { bnToU8a, logger, u8aToHex } from '@polkadot/util';
|
||||
import { randomAsU8a } from '@polkadot/util-crypto';
|
||||
@@ -41,12 +42,15 @@ export default class Mock implements ProviderInterface {
|
||||
private emitter = new EventEmitter();
|
||||
public isUpdating: boolean = true;
|
||||
private requests: { [index: string]: (...params: any[]) => string } = {
|
||||
'chain_getBlockHash': (blockNumber: number): string => '0x1234',
|
||||
'chain_getRuntimeVersion': (): string => '0x1234',
|
||||
'state_getStorage': (storage: MockState$Db, params: Array<any>): string => {
|
||||
return u8aToHex(
|
||||
storage[(params[0] as string)]
|
||||
);
|
||||
},
|
||||
'system_chain': (): string => 'mockChain',
|
||||
'state_getMetadata': (): string => metadata,
|
||||
'system_name': (): string => 'mockClient',
|
||||
'system_version': (): string => '9.8.7'
|
||||
};
|
||||
@@ -68,7 +72,7 @@ export default class Mock implements ProviderInterface {
|
||||
}
|
||||
|
||||
get hasSubscriptions (): boolean {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
isConnected (): boolean {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"paths":
|
||||
{
|
||||
"@polkadot/api/*": ["packages/api/src/*"],
|
||||
"@polkadot/api-rx/*": ["packages/api-rx/src/*"],
|
||||
"@polkadot/api-derive/*": ["packages/api-derive/src/*"],
|
||||
"@polkadot/rpc-core/*": ["packages/rpc-core/src/*"],
|
||||
"@polkadot/rpc-provider/*": ["packages/rpc-provider/src/*"],
|
||||
"@polkadot/rpc-rx/*": ["packages/rpc-rx/src/*"],
|
||||
|
||||
92
yarn.lock
92
yarn.lock
@@ -1455,6 +1455,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/marked/-/marked-0.4.2.tgz#64a89e53ea37f61cc0f3ee1732c555c2dbf6452f"
|
||||
integrity sha512-cDB930/7MbzaGF6U3IwSQp6XBru8xWajF5PV2YZZeV8DyiliTuld11afVztGI9+yJZ29il5E+NpGA6ooV/Cjkg==
|
||||
|
||||
"@types/memoizee@^0.4.2":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/memoizee/-/memoizee-0.4.2.tgz#a500158999a8144a9b46cf9a9fb49b15f1853573"
|
||||
integrity sha512-bhdZXZWKfpkQuuiQjVjnPiNeBHpIAC6rfOFqlJXKD3VC35mCcolfVfXYTnk9Ppee5Mkmmz3Llgec7xCdJAbzWw==
|
||||
|
||||
"@types/minimatch@*", "@types/minimatch@3.0.3":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||
@@ -3100,6 +3105,13 @@ d3@3.5.17:
|
||||
resolved "https://registry.yarnpkg.com/d3/-/d3-3.5.17.tgz#bc46748004378b21a360c9fc7cf5231790762fb8"
|
||||
integrity sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g=
|
||||
|
||||
d@1:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f"
|
||||
integrity sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=
|
||||
dependencies:
|
||||
es5-ext "^0.10.9"
|
||||
|
||||
dagre-d3-renderer@^0.4.25:
|
||||
version "0.4.26"
|
||||
resolved "https://registry.yarnpkg.com/dagre-d3-renderer/-/dagre-d3-renderer-0.4.26.tgz#648a491209b853ae96ddf3fea41a1f104479a5a1"
|
||||
@@ -3454,6 +3466,24 @@ es-to-primitive@^1.2.0:
|
||||
is-date-object "^1.0.1"
|
||||
is-symbol "^1.0.2"
|
||||
|
||||
es5-ext@^0.10.14, es5-ext@^0.10.35, es5-ext@^0.10.45, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
|
||||
version "0.10.46"
|
||||
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.46.tgz#efd99f67c5a7ec789baa3daa7f79870388f7f572"
|
||||
integrity sha512-24XxRvJXNFwEMpJb3nOkiRJKRoupmjYmOPVlI65Qy2SrtxwOTB+g6ODjBKOtwEHbYrhWRty9xxOWLNdClT2djw==
|
||||
dependencies:
|
||||
es6-iterator "~2.0.3"
|
||||
es6-symbol "~3.1.1"
|
||||
next-tick "1"
|
||||
|
||||
es6-iterator@^2.0.1, es6-iterator@~2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
|
||||
integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c=
|
||||
dependencies:
|
||||
d "1"
|
||||
es5-ext "^0.10.35"
|
||||
es6-symbol "^3.1.1"
|
||||
|
||||
es6-promise@^4.0.3:
|
||||
version "4.2.5"
|
||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.5.tgz#da6d0d5692efb461e082c14817fe2427d8f5d054"
|
||||
@@ -3466,6 +3496,24 @@ es6-promisify@^5.0.0:
|
||||
dependencies:
|
||||
es6-promise "^4.0.3"
|
||||
|
||||
es6-symbol@^3.1.1, es6-symbol@~3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77"
|
||||
integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=
|
||||
dependencies:
|
||||
d "1"
|
||||
es5-ext "~0.10.14"
|
||||
|
||||
es6-weak-map@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f"
|
||||
integrity sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=
|
||||
dependencies:
|
||||
d "1"
|
||||
es5-ext "^0.10.14"
|
||||
es6-iterator "^2.0.1"
|
||||
es6-symbol "^3.1.1"
|
||||
|
||||
escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
@@ -3508,6 +3556,14 @@ esutils@^2.0.2:
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
|
||||
integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=
|
||||
|
||||
event-emitter@^0.3.5:
|
||||
version "0.3.5"
|
||||
resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39"
|
||||
integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=
|
||||
dependencies:
|
||||
d "1"
|
||||
es5-ext "~0.10.14"
|
||||
|
||||
eventemitter3@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163"
|
||||
@@ -4943,7 +4999,7 @@ is-primitive@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575"
|
||||
integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU=
|
||||
|
||||
is-promise@^2.1.0:
|
||||
is-promise@^2.1, is-promise@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
|
||||
integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=
|
||||
@@ -6017,6 +6073,13 @@ lru-cache@~4.0.1:
|
||||
pseudomap "^1.0.1"
|
||||
yallist "^2.0.0"
|
||||
|
||||
lru-queue@0.1:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3"
|
||||
integrity sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=
|
||||
dependencies:
|
||||
es5-ext "~0.10.2"
|
||||
|
||||
make-dir@^1.0.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
|
||||
@@ -6140,6 +6203,20 @@ mem@^4.0.0:
|
||||
mimic-fn "^1.0.0"
|
||||
p-is-promise "^1.1.0"
|
||||
|
||||
memoizee@^0.4.14:
|
||||
version "0.4.14"
|
||||
resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.14.tgz#07a00f204699f9a95c2d9e77218271c7cd610d57"
|
||||
integrity sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg==
|
||||
dependencies:
|
||||
d "1"
|
||||
es5-ext "^0.10.45"
|
||||
es6-weak-map "^2.0.2"
|
||||
event-emitter "^0.3.5"
|
||||
is-promise "^2.1"
|
||||
lru-queue "0.1"
|
||||
next-tick "1"
|
||||
timers-ext "^0.1.5"
|
||||
|
||||
meow@^3.3.0:
|
||||
version "3.7.0"
|
||||
resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb"
|
||||
@@ -6458,6 +6535,11 @@ needle@^2.2.1:
|
||||
iconv-lite "^0.4.4"
|
||||
sax "^1.2.4"
|
||||
|
||||
next-tick@1:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
|
||||
integrity sha1-yobR/ogoFpsBICCOPchCS524NCw=
|
||||
|
||||
nice-try@^1.0.4:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||
@@ -8956,6 +9038,14 @@ timed-out@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
|
||||
integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=
|
||||
|
||||
timers-ext@^0.1.5:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6"
|
||||
integrity sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==
|
||||
dependencies:
|
||||
es5-ext "~0.10.46"
|
||||
next-tick "1"
|
||||
|
||||
tmp@0.0.31:
|
||||
version "0.0.31"
|
||||
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7"
|
||||
|
||||
Reference in New Issue
Block a user