@agoric/casting 0.4.3-upgrade-14-dev-c8f9e7b.0 → 0.4.3-upgrade-16-dev-8879538.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +0 -34
- package/README.md +3 -3
- package/package.json +25 -22
- package/src/casting-spec.d.ts +8 -8
- package/src/casting-spec.d.ts.map +1 -1
- package/src/casting-spec.js +7 -9
- package/src/change-follower.d.ts +1 -1
- package/src/change-follower.d.ts.map +1 -1
- package/src/change-follower.js +2 -2
- package/src/defaults.d.ts +2 -2
- package/src/defaults.d.ts.map +1 -1
- package/src/defaults.js +1 -1
- package/src/follower-cosmjs.d.ts +1 -1
- package/src/follower-cosmjs.d.ts.map +1 -1
- package/src/follower-cosmjs.js +27 -10
- package/src/follower.d.ts +1 -1
- package/src/follower.d.ts.map +1 -1
- package/src/follower.js +6 -6
- package/src/iterable.d.ts +12 -12
- package/src/iterable.d.ts.map +1 -1
- package/src/iterable.js +2 -1
- package/src/leader-netconfig.d.ts +2 -2
- package/src/leader-netconfig.d.ts.map +1 -1
- package/src/leader.d.ts +1 -1
- package/src/main.js +2 -0
- package/src/makeHttpClient.d.ts +2 -0
- package/src/makeHttpClient.d.ts.map +1 -0
- package/src/makeHttpClient.js +56 -0
- package/src/netconfig.d.ts.map +1 -1
- package/src/shuffle.d.ts +1 -1
- package/src/shuffle.d.ts.map +1 -1
- package/src/types.d.ts +6 -5
- package/src/types.d.ts.map +1 -1
- package/src/types.js +4 -4
- package/test/interpose-net-access.test.js +118 -0
- package/test/{test-mvp.js → mvp.test.js} +2 -2
- package/test/net-access-fixture.js +196 -0
- package/tsconfig.build.json +6 -0
- package/{jsconfig.json → tsconfig.json} +1 -0
- package/jsconfig.build.json +0 -12
- /package/test/{test-netconfig.js → netconfig.test.js} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,40 +3,6 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
-
### [0.4.3-u13.0](https://github.com/Agoric/agoric-sdk/compare/@agoric/casting@0.4.3-u12.0...@agoric/casting@0.4.3-u13.0) (2023-12-07)
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
### Bug Fixes
|
|
10
|
-
|
|
11
|
-
* **casting:** dont crash on bad capdata ([3f01369](https://github.com/Agoric/agoric-sdk/commit/3f0136994c0b4033c872f9593cabb19bab05f01c))
|
|
12
|
-
* **casting:** properly follow an unpopulated state entry ([48296f7](https://github.com/Agoric/agoric-sdk/commit/48296f78f783e8e5ae1e5fbe92ae10e5e7880837))
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
### [0.4.3-u12.0](https://github.com/Agoric/agoric-sdk/compare/@agoric/casting@0.4.3-u11wf.0...@agoric/casting@0.4.3-u12.0) (2023-11-10)
|
|
17
|
-
|
|
18
|
-
**Note:** Version bump only for package @agoric/casting
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
### [0.4.3-u11wf.0](https://github.com/Agoric/agoric-sdk/compare/@agoric/casting@0.4.3-u11.0...@agoric/casting@0.4.3-u11wf.0) (2023-09-23)
|
|
25
|
-
|
|
26
|
-
**Note:** Version bump only for package @agoric/casting
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
### [0.4.3-u11.0](https://github.com/Agoric/agoric-sdk/compare/@agoric/casting@0.4.2...@agoric/casting@0.4.3-u11.0) (2023-08-24)
|
|
33
|
-
|
|
34
|
-
**Note:** Version bump only for package @agoric/casting
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
6
|
### [0.4.2](https://github.com/Agoric/agoric-sdk/compare/@agoric/casting@0.4.1...@agoric/casting@0.4.2) (2023-06-02)
|
|
41
7
|
|
|
42
8
|
**Note:** Version bump only for package @agoric/casting
|
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@ The `followerOpts` argument in `makeFollower(leader, key, followerOpts)` provide
|
|
|
42
42
|
- the `decode` option is a function to translate `buf: Uint8Array` into `data: string`
|
|
43
43
|
- (default) - interpret buf as a utf-8 string, then `JSON.parse` it
|
|
44
44
|
- the `unserializer` option can be
|
|
45
|
-
- (default) - release unserialized objects using
|
|
45
|
+
- (default) - release unserialized objects using [@endo/marshal](https://www.npmjs.com/package/@endo/marshal)'s `makeMarshal()`
|
|
46
46
|
- `null` - don't additionally unserialize data before releasing it
|
|
47
47
|
- any unserializer object supporting `E(unserializer).fromCapData(data)`
|
|
48
48
|
- the `crasher` option can be
|
|
@@ -65,8 +65,8 @@ The `followerOpts` argument in `makeFollower(leader, key, followerOpts)` provide
|
|
|
65
65
|
|
|
66
66
|
This package currently depends on:
|
|
67
67
|
- Hardened Javascript
|
|
68
|
-
-
|
|
69
|
-
-
|
|
68
|
+
- [@agoric/notifier](../notifier) async iterable adapters to implement `iterateLatest`
|
|
69
|
+
- [@endo/marshal](https://www.npmjs.com/package/@endo/marshal) for default object unserialization
|
|
70
70
|
- [CosmJS](https://github.com/cosmos/cosmjs) for proof verification, although [it does not yet support light client tracking of the validator set](https://github.com/cosmos/cosmjs/issues/492)
|
|
71
71
|
- a bespoke follower of [WebSocket Tendermint events](https://docs.tendermint.com/master/tendermint-core/subscription.html#legacy-streaming-api)
|
|
72
72
|
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/casting",
|
|
3
|
-
"version": "0.4.3-upgrade-
|
|
3
|
+
"version": "0.4.3-upgrade-16-dev-8879538.0+8879538",
|
|
4
4
|
"description": "Agoric's OCap broadcasting system",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/main.js",
|
|
7
7
|
"repository": "https://github.com/Agoric/agoric-sdk",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"build": "exit 0",
|
|
10
|
-
"prepack": "tsc --build
|
|
10
|
+
"prepack": "tsc --build tsconfig.build.json",
|
|
11
11
|
"postpack": "git clean -f '*.d.ts*'",
|
|
12
12
|
"demo": "node -e 'import(\"./test/fake-rpc-server.js\").then(ns => ns.develop())'",
|
|
13
13
|
"test": "ava",
|
|
@@ -15,33 +15,33 @@
|
|
|
15
15
|
"test:xs": "exit 0",
|
|
16
16
|
"lint-fix": "yarn lint:eslint --fix",
|
|
17
17
|
"lint": "run-s --continue-on-error lint:*",
|
|
18
|
-
"lint:types": "tsc
|
|
18
|
+
"lint:types": "tsc",
|
|
19
19
|
"lint:eslint": "eslint --ext .js,.ts ."
|
|
20
20
|
},
|
|
21
21
|
"keywords": [],
|
|
22
22
|
"author": "Agoric",
|
|
23
23
|
"license": "Apache-2.0",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@agoric/internal": "0.
|
|
26
|
-
"@agoric/notifier": "0.6.3-upgrade-
|
|
27
|
-
"@agoric/
|
|
28
|
-
"@
|
|
29
|
-
"@cosmjs/
|
|
30
|
-
"@cosmjs/
|
|
31
|
-
"@cosmjs/
|
|
32
|
-
"@
|
|
33
|
-
"@endo/
|
|
34
|
-
"@endo/
|
|
35
|
-
"@endo/
|
|
36
|
-
"@endo/
|
|
37
|
-
"@endo/promise-kit": "0.2.56",
|
|
25
|
+
"@agoric/internal": "0.3.3-upgrade-16-dev-8879538.0+8879538",
|
|
26
|
+
"@agoric/notifier": "0.6.3-upgrade-16-dev-8879538.0+8879538",
|
|
27
|
+
"@agoric/store": "0.9.3-upgrade-16-dev-8879538.0+8879538",
|
|
28
|
+
"@cosmjs/encoding": "^0.32.3",
|
|
29
|
+
"@cosmjs/proto-signing": "^0.32.3",
|
|
30
|
+
"@cosmjs/stargate": "^0.32.3",
|
|
31
|
+
"@cosmjs/tendermint-rpc": "^0.32.3",
|
|
32
|
+
"@endo/far": "^1.1.2",
|
|
33
|
+
"@endo/init": "^1.1.2",
|
|
34
|
+
"@endo/lockdown": "^1.0.7",
|
|
35
|
+
"@endo/marshal": "^1.5.0",
|
|
36
|
+
"@endo/promise-kit": "^1.1.2",
|
|
38
37
|
"node-fetch": "^2.6.0"
|
|
39
38
|
},
|
|
40
39
|
"devDependencies": {
|
|
41
|
-
"@
|
|
40
|
+
"@agoric/cosmic-proto": "0.4.1-upgrade-16-dev-8879538.0+8879538",
|
|
41
|
+
"@endo/ses-ava": "^1.2.2",
|
|
42
42
|
"@types/node-fetch": "^2.6.2",
|
|
43
|
-
"ava": "^5.
|
|
44
|
-
"c8": "^
|
|
43
|
+
"ava": "^5.3.0",
|
|
44
|
+
"c8": "^9.1.0",
|
|
45
45
|
"express": "^4.17.1",
|
|
46
46
|
"ws": "^7.2.0"
|
|
47
47
|
},
|
|
@@ -49,14 +49,17 @@
|
|
|
49
49
|
"access": "public"
|
|
50
50
|
},
|
|
51
51
|
"engines": {
|
|
52
|
-
"node": "
|
|
52
|
+
"node": "^18.12 || ^20.9"
|
|
53
53
|
},
|
|
54
54
|
"ava": {
|
|
55
55
|
"files": [
|
|
56
|
-
"test
|
|
56
|
+
"test/**/*.test.*"
|
|
57
57
|
],
|
|
58
58
|
"timeout": "20m",
|
|
59
59
|
"workerThreads": false
|
|
60
60
|
},
|
|
61
|
-
"
|
|
61
|
+
"typeCoverage": {
|
|
62
|
+
"atLeast": 88.94
|
|
63
|
+
},
|
|
64
|
+
"gitHead": "8879538cd1d125a08346f02dd5701d0d70c90bb8"
|
|
62
65
|
}
|
package/src/casting-spec.d.ts
CHANGED
|
@@ -2,15 +2,15 @@ export function vstorageKeySpecToPath({ storeName, storeSubkey }: VStorageKey):
|
|
|
2
2
|
/**
|
|
3
3
|
* @param {string} storagePath
|
|
4
4
|
* @param {string} [storeName]
|
|
5
|
-
* @returns {import('./types').CastingSpec}
|
|
5
|
+
* @returns {import('./types.js').CastingSpec}
|
|
6
6
|
*/
|
|
7
|
-
export function DEFAULT_PATH_CONVERTER(storagePath: string, storeName?: string | undefined): import(
|
|
7
|
+
export function DEFAULT_PATH_CONVERTER(storagePath: string, storeName?: string | undefined): import("./types.js").CastingSpec;
|
|
8
8
|
/**
|
|
9
|
-
* @type {Record<string, (path: string) => import('./types').CastingSpec>}
|
|
9
|
+
* @type {Record<string, (path: string) => import('./types.js').CastingSpec>}
|
|
10
10
|
*/
|
|
11
|
-
export const pathPrefixToConverters: Record<string, (path: string) => import(
|
|
12
|
-
export function makeCastingSpecFromString(specString: string): import(
|
|
13
|
-
export function makeCastingSpecFromObject(specObj: any): import(
|
|
14
|
-
export function makeCastingSpecFromRef(specCap: ERef<any>): Promise<import(
|
|
15
|
-
export function makeCastingSpec(sourceP: ERef<unknown>): Promise<import(
|
|
11
|
+
export const pathPrefixToConverters: Record<string, (path: string) => import("./types.js").CastingSpec>;
|
|
12
|
+
export function makeCastingSpecFromString(specString: string): import("./types.js").CastingSpec;
|
|
13
|
+
export function makeCastingSpecFromObject(specObj: any): import("./types.js").CastingSpec;
|
|
14
|
+
export function makeCastingSpecFromRef(specCap: ERef<any>): Promise<import("./types.js").CastingSpec>;
|
|
15
|
+
export function makeCastingSpec(sourceP: ERef<unknown>): Promise<import("./types.js").CastingSpec>;
|
|
16
16
|
//# sourceMappingURL=casting-spec.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"casting-spec.d.ts","sourceRoot":"","sources":["casting-spec.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"casting-spec.d.ts","sourceRoot":"","sources":["casting-spec.js"],"names":[],"mappings":"AA6CO,kEAHI,WAAW,GACT,MAAM,CAYlB;AAlCD;;;;GAIG;AACH,oDAJW,MAAM,mCAEJ,OAAO,YAAY,EAAE,WAAW,CAa5C;AAsBD;;GAEG;AACH,qCAFU,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,YAAY,EAAE,WAAW,CAAC,CAMzE;AAMI,sDAHI,MAAM,GACJ,OAAO,YAAY,EAAE,WAAW,CAc5C;AAQM,mDAHI,GAAG,GACD,OAAO,YAAY,EAAE,WAAW,CAmC5C;AAMM,gDAHI,IAAI,CAAC,GAAG,CAAC,GACP,OAAO,CAAC,OAAO,YAAY,EAAE,WAAW,CAAC,CAKrD;AAQM,yCAHI,IAAI,CAAC,OAAO,CAAC,GACX,OAAO,CAAC,OAAO,YAAY,EAAE,WAAW,CAAC,CAgBrD"}
|
package/src/casting-spec.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import * as encodingStar from '@cosmjs/encoding';
|
|
2
2
|
import { E, getInterfaceOf } from '@endo/far';
|
|
3
3
|
|
|
4
|
-
import './types.js';
|
|
5
|
-
|
|
6
4
|
const { toAscii } = encodingStar;
|
|
7
5
|
|
|
8
6
|
/**
|
|
9
7
|
* @param {string} storagePath
|
|
10
|
-
* @returns {import('./types').CastingSpec}
|
|
8
|
+
* @returns {import('./types.js').CastingSpec}
|
|
11
9
|
*/
|
|
12
10
|
const swingsetPathToCastingSpec = storagePath =>
|
|
13
11
|
harden({
|
|
@@ -24,7 +22,7 @@ const NO_DATA_VALUE = new Uint8Array([255]);
|
|
|
24
22
|
/**
|
|
25
23
|
* @param {string} storagePath
|
|
26
24
|
* @param {string} [storeName]
|
|
27
|
-
* @returns {import('./types').CastingSpec}
|
|
25
|
+
* @returns {import('./types.js').CastingSpec}
|
|
28
26
|
*/
|
|
29
27
|
const vstoragePathToCastingSpec = (storagePath, storeName = 'vstorage') => {
|
|
30
28
|
const elems = storagePath ? storagePath.split('.') : [];
|
|
@@ -60,7 +58,7 @@ export const vstorageKeySpecToPath = ({ storeName, storeSubkey }) => {
|
|
|
60
58
|
export const DEFAULT_PATH_CONVERTER = vstoragePathToCastingSpec;
|
|
61
59
|
|
|
62
60
|
/**
|
|
63
|
-
* @type {Record<string, (path: string) => import('./types').CastingSpec>}
|
|
61
|
+
* @type {Record<string, (path: string) => import('./types.js').CastingSpec>}
|
|
64
62
|
*/
|
|
65
63
|
export const pathPrefixToConverters = harden({
|
|
66
64
|
'swingset:': swingsetPathToCastingSpec,
|
|
@@ -70,7 +68,7 @@ export const pathPrefixToConverters = harden({
|
|
|
70
68
|
|
|
71
69
|
/**
|
|
72
70
|
* @param {string} specString
|
|
73
|
-
* @returns {import('./types').CastingSpec}
|
|
71
|
+
* @returns {import('./types.js').CastingSpec}
|
|
74
72
|
*/
|
|
75
73
|
export const makeCastingSpecFromString = specString => {
|
|
76
74
|
assert.typeof(specString, 'string');
|
|
@@ -90,7 +88,7 @@ const te = new TextEncoder();
|
|
|
90
88
|
|
|
91
89
|
/**
|
|
92
90
|
* @param {any} specObj
|
|
93
|
-
* @returns {import('./types').CastingSpec}
|
|
91
|
+
* @returns {import('./types.js').CastingSpec}
|
|
94
92
|
*/
|
|
95
93
|
export const makeCastingSpecFromObject = specObj => {
|
|
96
94
|
const {
|
|
@@ -129,7 +127,7 @@ export const makeCastingSpecFromObject = specObj => {
|
|
|
129
127
|
|
|
130
128
|
/**
|
|
131
129
|
* @param {ERef<any>} specCap
|
|
132
|
-
* @returns {Promise<import('./types').CastingSpec>}
|
|
130
|
+
* @returns {Promise<import('./types.js').CastingSpec>}
|
|
133
131
|
*/
|
|
134
132
|
export const makeCastingSpecFromRef = async specCap => {
|
|
135
133
|
const specObj = await E(specCap).getStoreKey();
|
|
@@ -140,7 +138,7 @@ export const makeCastingSpecFromRef = async specCap => {
|
|
|
140
138
|
* Create an abstract type from a given source representation
|
|
141
139
|
*
|
|
142
140
|
* @param {ERef<unknown>} sourceP
|
|
143
|
-
* @returns {Promise<import('./types').CastingSpec>}
|
|
141
|
+
* @returns {Promise<import('./types.js').CastingSpec>}
|
|
144
142
|
*/
|
|
145
143
|
export const makeCastingSpec = async sourceP => {
|
|
146
144
|
const spec = await sourceP;
|
package/src/change-follower.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export function makePollingChangeFollower(leader: import(
|
|
1
|
+
export function makePollingChangeFollower(leader: import("./types.js").Leader): Promise<import("./types.js").Follower<import("./types.js").CastingChange>>;
|
|
2
2
|
//# sourceMappingURL=change-follower.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"change-follower.d.ts","sourceRoot":"","sources":["change-follower.js"],"names":[],"mappings":"AASO,kDAHI,OAAO,
|
|
1
|
+
{"version":3,"file":"change-follower.d.ts","sourceRoot":"","sources":["change-follower.js"],"names":[],"mappings":"AASO,kDAHI,OAAO,YAAY,EAAE,MAAM,GACzB,OAAO,CAAC,OAAO,YAAY,EAAE,QAAQ,CAAC,OAAO,YAAY,EAAE,aAAa,CAAC,CAAC,CA6CtF"}
|
package/src/change-follower.js
CHANGED
|
@@ -4,8 +4,8 @@ import { DEFAULT_KEEP_POLLING } from './defaults.js';
|
|
|
4
4
|
/**
|
|
5
5
|
* Just return an unspecified allegedValue every poll period.
|
|
6
6
|
*
|
|
7
|
-
* @param {import('./types').Leader} leader
|
|
8
|
-
* @returns {Promise<import('./types.js').Follower<import('./types').CastingChange>>}
|
|
7
|
+
* @param {import('./types.js').Leader} leader
|
|
8
|
+
* @returns {Promise<import('./types.js').Follower<import('./types.js').CastingChange>>}
|
|
9
9
|
*/
|
|
10
10
|
export const makePollingChangeFollower = async leader => {
|
|
11
11
|
const { keepPolling = DEFAULT_KEEP_POLLING } = await E(leader).getOptions();
|
package/src/defaults.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export function MAKE_DEFAULT_DECODER(): (str: any) => any;
|
|
|
15
15
|
/**
|
|
16
16
|
* Unserialize the JSONable data.
|
|
17
17
|
*
|
|
18
|
-
* @type {() => import('./types').Unserializer}
|
|
18
|
+
* @type {() => import('./types.js').Unserializer}
|
|
19
19
|
*/
|
|
20
|
-
export const MAKE_DEFAULT_UNSERIALIZER: () => import(
|
|
20
|
+
export const MAKE_DEFAULT_UNSERIALIZER: () => import("./types.js").Unserializer;
|
|
21
21
|
//# sourceMappingURL=defaults.d.ts.map
|
package/src/defaults.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["defaults.js"],"names":[],"mappings":"AAIA;;GAEG;AACH,yDAA0D;AAE1D,uCAAwC;AAExC,mDAAoD;AAEpD,6CAA8C;AAUvC,0BAHI,MAAM,GACJ,
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["defaults.js"],"names":[],"mappings":"AAIA;;GAEG;AACH,yDAA0D;AAE1D,uCAAwC;AAExC,mDAAoD;AAEpD,6CAA8C;AAUvC,0BAHI,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAEgD;AAMnE,qCAHI,MAAM,oCAKhB;AAOM,8HAEN;AAQM,sCAHI,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAMzB;AAUM,8CALI,MAAM,OACN,GAAG,iCAED,OAAO,CAAC,IAAI,CAAC,CASzB;AAOM,wCAFM,OAAO,CAAC,OAAO,CAAC,CAGgD;AAEtE,0DAaN;AAED;;;;GAIG;AACH,wCAFU,MAAM,OAAO,YAAY,EAAE,YAAY,CA2B/C"}
|
package/src/defaults.js
CHANGED
|
@@ -95,7 +95,7 @@ export const MAKE_DEFAULT_DECODER = () => {
|
|
|
95
95
|
/**
|
|
96
96
|
* Unserialize the JSONable data.
|
|
97
97
|
*
|
|
98
|
-
* @type {() => import('./types').Unserializer}
|
|
98
|
+
* @type {() => import('./types.js').Unserializer}
|
|
99
99
|
*/
|
|
100
100
|
export const MAKE_DEFAULT_UNSERIALIZER = () => {
|
|
101
101
|
const ifaceAllegedPrefix = 'Alleged: ';
|
package/src/follower-cosmjs.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export function makeCosmjsFollower<T>(sourceP: any, leaderOrMaker?: import("./types.js").LeaderOrMaker | undefined, options?: import("./types.js").FollowerOptions | undefined): ValueFollower<T>;
|
|
2
|
-
export type ValueFollower<T> = import(
|
|
2
|
+
export type ValueFollower<T> = import("./types.js").Follower<import("./types.js").ValueFollowerElement<T>>;
|
|
3
3
|
/**
|
|
4
4
|
* The response of an ABCI query to Tendermint.
|
|
5
5
|
* This is a subset of `tendermint34.AbciQueryResponse` in order
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"follower-cosmjs.d.ts","sourceRoot":"","sources":["follower-cosmjs.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"follower-cosmjs.d.ts","sourceRoot":"","sources":["follower-cosmjs.js"],"names":[],"mappings":"AAyGO,mCAFoB,CAAC,WAHjB,GAAG,+HAGD,aAAa,CAAC,CAAC,CAAC,CAsf5B;0BAnkBiG,CAAC,IAAzE,OAAO,YAAY,EAAE,QAAQ,CAAC,OAAO,YAAY,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC;;;;;;iCAIxF;IACZ,QAAY,CAAC,KAAK,EAAE,UAAU,CAAC;IAC/B,QAAY,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB"}
|
package/src/follower-cosmjs.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
/// <reference types="ses"/>
|
|
2
|
-
/* eslint-disable no-await-in-loop, @jessie.js/no-nested-await */
|
|
1
|
+
/// <reference types="ses" />
|
|
3
2
|
|
|
4
3
|
import { E, Far } from '@endo/far';
|
|
5
4
|
import * as tendermint34 from '@cosmjs/tendermint-rpc';
|
|
@@ -11,6 +10,15 @@ import { MAKE_DEFAULT_DECODER, MAKE_DEFAULT_UNSERIALIZER } from './defaults.js';
|
|
|
11
10
|
import { makeCastingSpec } from './casting-spec.js';
|
|
12
11
|
import { makeLeader as defaultMakeLeader } from './leader-netconfig.js';
|
|
13
12
|
|
|
13
|
+
// A lot of cosmjs classes end up hardened through instances shared by this
|
|
14
|
+
// package so preemptively harden them all.
|
|
15
|
+
// However we cannot directly harden a module namespace object (exotic behavior
|
|
16
|
+
// for bindings) so spread the namespace instead
|
|
17
|
+
harden({
|
|
18
|
+
tendermint34: { ...tendermint34 },
|
|
19
|
+
stargateStar: { ...stargateStar },
|
|
20
|
+
});
|
|
21
|
+
|
|
14
22
|
const { QueryClient } = stargateStar;
|
|
15
23
|
const { Tendermint34Client } = tendermint34;
|
|
16
24
|
const { details: X, quote: q, Fail } = assert;
|
|
@@ -91,8 +99,8 @@ const proofs = ['strict', 'none', 'optimistic'];
|
|
|
91
99
|
/**
|
|
92
100
|
* @template T
|
|
93
101
|
* @param {any} sourceP
|
|
94
|
-
* @param {import('./types').LeaderOrMaker} [leaderOrMaker]
|
|
95
|
-
* @param {import('./types').FollowerOptions} [options]
|
|
102
|
+
* @param {import('./types.js').LeaderOrMaker} [leaderOrMaker]
|
|
103
|
+
* @param {import('./types.js').FollowerOptions} [options]
|
|
96
104
|
* @returns {ValueFollower<T>}
|
|
97
105
|
*/
|
|
98
106
|
export const makeCosmjsFollower = (
|
|
@@ -240,6 +248,7 @@ export const makeCosmjsFollower = (
|
|
|
240
248
|
* @returns {Promise<QueryStoreResponse>}
|
|
241
249
|
*/
|
|
242
250
|
const tryGetDataAtHeight = async blockHeight => {
|
|
251
|
+
await null;
|
|
243
252
|
if (proof === 'strict') {
|
|
244
253
|
// Crash hard if we can't prove.
|
|
245
254
|
return getProvenDataAtHeight(blockHeight).catch(crash);
|
|
@@ -274,6 +283,7 @@ export const makeCosmjsFollower = (
|
|
|
274
283
|
* @param {number} [blockHeight] desired height, or the latest height if not set
|
|
275
284
|
*/
|
|
276
285
|
const getDataAtHeight = async blockHeight => {
|
|
286
|
+
await null;
|
|
277
287
|
for (let attempt = 0; ; attempt += 1) {
|
|
278
288
|
try {
|
|
279
289
|
// AWAIT
|
|
@@ -356,6 +366,7 @@ export const makeCosmjsFollower = (
|
|
|
356
366
|
);
|
|
357
367
|
}
|
|
358
368
|
}
|
|
369
|
+
harden(allValuesFromCell);
|
|
359
370
|
|
|
360
371
|
/**
|
|
361
372
|
* @param {import('./types.js').StreamCell<T>} streamCell
|
|
@@ -371,6 +382,7 @@ export const makeCosmjsFollower = (
|
|
|
371
382
|
);
|
|
372
383
|
}
|
|
373
384
|
}
|
|
385
|
+
harden(reverseValuesFromCell);
|
|
374
386
|
|
|
375
387
|
/**
|
|
376
388
|
* @param {import('./types.js').StreamCell<T>} streamCell
|
|
@@ -388,6 +400,7 @@ export const makeCosmjsFollower = (
|
|
|
388
400
|
);
|
|
389
401
|
}
|
|
390
402
|
}
|
|
403
|
+
harden(lastValueFromCell);
|
|
391
404
|
|
|
392
405
|
/**
|
|
393
406
|
* @yields {ValueFollowerElement<T>}
|
|
@@ -396,6 +409,7 @@ export const makeCosmjsFollower = (
|
|
|
396
409
|
/** @type {number | undefined} the last known latest height */
|
|
397
410
|
let lastHeight;
|
|
398
411
|
let lastValue;
|
|
412
|
+
await null;
|
|
399
413
|
for (;;) {
|
|
400
414
|
const latest = await getDataAtHeight();
|
|
401
415
|
if (lastHeight && latest.height <= lastHeight) {
|
|
@@ -432,6 +446,7 @@ export const makeCosmjsFollower = (
|
|
|
432
446
|
lastValue = latest.value;
|
|
433
447
|
}
|
|
434
448
|
}
|
|
449
|
+
harden(getLatestIterable);
|
|
435
450
|
|
|
436
451
|
/**
|
|
437
452
|
* @param {number} [cursorBlockHeight]
|
|
@@ -446,11 +461,11 @@ export const makeCosmjsFollower = (
|
|
|
446
461
|
// block.
|
|
447
462
|
// If the block has no corresponding data, wait for the first block to
|
|
448
463
|
// contain data.
|
|
464
|
+
await null;
|
|
449
465
|
for (;;) {
|
|
450
466
|
let thisHeight;
|
|
451
|
-
({ value: cursorData, height: thisHeight } =
|
|
452
|
-
cursorBlockHeight
|
|
453
|
-
));
|
|
467
|
+
({ value: cursorData, height: thisHeight } =
|
|
468
|
+
await getDataAtHeight(cursorBlockHeight));
|
|
454
469
|
if (cursorData.length !== 0) {
|
|
455
470
|
cursorBlockHeight = thisHeight;
|
|
456
471
|
const cursorStreamCell = streamCellForData(
|
|
@@ -550,6 +565,7 @@ export const makeCosmjsFollower = (
|
|
|
550
565
|
cursorData = currentData;
|
|
551
566
|
}
|
|
552
567
|
}
|
|
568
|
+
harden(getEachIterableAtHeight);
|
|
553
569
|
|
|
554
570
|
/**
|
|
555
571
|
* @param {number} [cursorBlockHeight]
|
|
@@ -560,10 +576,10 @@ export const makeCosmjsFollower = (
|
|
|
560
576
|
// cursorBlockHeight) so we know not to emit duplicates
|
|
561
577
|
// of that cell.
|
|
562
578
|
let cursorData;
|
|
579
|
+
await null;
|
|
563
580
|
while (cursorBlockHeight === undefined || cursorBlockHeight > 0) {
|
|
564
|
-
({ value: cursorData, height: cursorBlockHeight } =
|
|
565
|
-
cursorBlockHeight
|
|
566
|
-
));
|
|
581
|
+
({ value: cursorData, height: cursorBlockHeight } =
|
|
582
|
+
await getDataAtHeight(cursorBlockHeight));
|
|
567
583
|
if (cursorData.length === 0) {
|
|
568
584
|
// No data at the cursor height, so signal beginning of stream.
|
|
569
585
|
return;
|
|
@@ -573,6 +589,7 @@ export const makeCosmjsFollower = (
|
|
|
573
589
|
cursorBlockHeight = cursorStreamCell.blockHeight - 1;
|
|
574
590
|
}
|
|
575
591
|
}
|
|
592
|
+
harden(getReverseIterableAtHeight);
|
|
576
593
|
|
|
577
594
|
/** @type {ValueFollower<T>} */
|
|
578
595
|
return Far('chain follower', {
|
package/src/follower.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export function makeFollower<T>(specP: ERef<import(
|
|
1
|
+
export function makeFollower<T>(specP: ERef<import("./types.js").CastingSpec> | string, leaderOrMaker?: import("./types.js").LeaderOrMaker | undefined, options?: import("./types.js").FollowerOptions | undefined): Promise<import("./follower-cosmjs.js").ValueFollower<T>>;
|
|
2
2
|
//# sourceMappingURL=follower.d.ts.map
|
package/src/follower.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"follower.d.ts","sourceRoot":"","sources":["follower.js"],"names":[],"mappings":"AA4DO,
|
|
1
|
+
{"version":3,"file":"follower.d.ts","sourceRoot":"","sources":["follower.js"],"names":[],"mappings":"AA4DO,6BAF2D,CAAC,SAHxD,IAAI,CAAC,OAAO,YAAY,EAAE,WAAW,CAAC,GAAG,MAAM,+HAG7C,OAAO,CAAC,OAAO,sBAAsB,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,CASpE"}
|
package/src/follower.js
CHANGED
|
@@ -11,12 +11,12 @@ import { makeCastingSpec } from './casting-spec.js';
|
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* @template T
|
|
14
|
-
* @param {ERef<import('./types').CastingSpec>} spec
|
|
14
|
+
* @param {ERef<import('./types.js').CastingSpec>} spec
|
|
15
15
|
*/
|
|
16
16
|
const makeSubscriptionFollower = spec => {
|
|
17
17
|
const transform = value =>
|
|
18
18
|
harden({ value, blockHeight: NaN, currentBlockHeight: NaN });
|
|
19
|
-
/** @type {import('./types').Follower<import('./types.js').ValueFollowerElement<T>>} */
|
|
19
|
+
/** @type {import('./types.js').Follower<import('./types.js').ValueFollowerElement<T>>} */
|
|
20
20
|
const follower = Far('subscription/notifier follower', {
|
|
21
21
|
getLatestIterable: async () => {
|
|
22
22
|
const { notifier, subscription } = await spec;
|
|
@@ -53,10 +53,10 @@ const makeSubscriptionFollower = spec => {
|
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
55
|
* @template T
|
|
56
|
-
* @param {ERef<import('./types').CastingSpec> | string} specP
|
|
57
|
-
* @param {import('./types').LeaderOrMaker} [leaderOrMaker]
|
|
58
|
-
* @param {import('./types').FollowerOptions} [options]
|
|
59
|
-
* @returns {Promise<import('./follower-cosmjs').ValueFollower<T>>}
|
|
56
|
+
* @param {ERef<import('./types.js').CastingSpec> | string} specP
|
|
57
|
+
* @param {import('./types.js').LeaderOrMaker} [leaderOrMaker]
|
|
58
|
+
* @param {import('./types.js').FollowerOptions} [options]
|
|
59
|
+
* @returns {Promise<import('./follower-cosmjs.js').ValueFollower<T>>}
|
|
60
60
|
*/
|
|
61
61
|
export const makeFollower = async (specP, leaderOrMaker, options) => {
|
|
62
62
|
const spec = await makeCastingSpec(specP);
|
package/src/iterable.d.ts
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
export function mapAsyncIterable<TIn, TOut>(iterable: AsyncIterable<TIn>, transform: (value: TIn) => TOut): AsyncIterable<TOut>;
|
|
2
|
-
export function iterateLatest<T>(follower: ERef<import("./types").Follower<T>>): {
|
|
2
|
+
export function iterateLatest<T>(follower: ERef<import("./types.js").Follower<T>>): {
|
|
3
3
|
/** @returns {AsyncIterator<T>} */
|
|
4
|
-
[Symbol.asyncIterator]: () => AsyncIterator<T
|
|
5
|
-
} & import("@endo/eventual-send").RemotableBrand<{}, {
|
|
4
|
+
[Symbol.asyncIterator]: () => AsyncIterator<T>;
|
|
5
|
+
} & import("@endo/pass-style").RemotableObject<`Alleged: ${string}`> & import("@endo/eventual-send").RemotableBrand<{}, {
|
|
6
6
|
/** @returns {AsyncIterator<T>} */
|
|
7
|
-
[Symbol.asyncIterator]: () => AsyncIterator<T
|
|
7
|
+
[Symbol.asyncIterator]: () => AsyncIterator<T>;
|
|
8
8
|
}>;
|
|
9
|
-
export function iterateEach<T>(follower: ERef<import("./types").Follower<T>>, options?: import("./types").IterateEachOptions | undefined): {
|
|
9
|
+
export function iterateEach<T>(follower: ERef<import("./types.js").Follower<T>>, options?: import("./types.js").IterateEachOptions | undefined): {
|
|
10
10
|
/** @returns {AsyncIterator<T>} */
|
|
11
|
-
[Symbol.asyncIterator]: () => AsyncIterator<T
|
|
12
|
-
} & import("@endo/eventual-send").RemotableBrand<{}, {
|
|
11
|
+
[Symbol.asyncIterator]: () => AsyncIterator<T>;
|
|
12
|
+
} & import("@endo/pass-style").RemotableObject<`Alleged: ${string}`> & import("@endo/eventual-send").RemotableBrand<{}, {
|
|
13
13
|
/** @returns {AsyncIterator<T>} */
|
|
14
|
-
[Symbol.asyncIterator]: () => AsyncIterator<T
|
|
14
|
+
[Symbol.asyncIterator]: () => AsyncIterator<T>;
|
|
15
15
|
}>;
|
|
16
|
-
export function iterateReverse<T>(follower: ERef<import("./types").Follower<T>>, options?: import("./types").IterateEachOptions | undefined): {
|
|
16
|
+
export function iterateReverse<T>(follower: ERef<import("./types.js").Follower<T>>, options?: import("./types.js").IterateEachOptions | undefined): {
|
|
17
17
|
/** @returns {AsyncIterator<T>} */
|
|
18
|
-
[Symbol.asyncIterator]: () => AsyncIterator<T
|
|
19
|
-
} & import("@endo/eventual-send").RemotableBrand<{}, {
|
|
18
|
+
[Symbol.asyncIterator]: () => AsyncIterator<T>;
|
|
19
|
+
} & import("@endo/pass-style").RemotableObject<`Alleged: ${string}`> & import("@endo/eventual-send").RemotableBrand<{}, {
|
|
20
20
|
/** @returns {AsyncIterator<T>} */
|
|
21
|
-
[Symbol.asyncIterator]: () => AsyncIterator<T
|
|
21
|
+
[Symbol.asyncIterator]: () => AsyncIterator<T>;
|
|
22
22
|
}>;
|
|
23
23
|
export { subscribeEach, subscribeLatest } from "@agoric/notifier/subscribe.js";
|
|
24
24
|
//# sourceMappingURL=iterable.d.ts.map
|
package/src/iterable.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iterable.d.ts","sourceRoot":"","sources":["iterable.js"],"names":[],"mappings":"AAWO,
|
|
1
|
+
{"version":3,"file":"iterable.d.ts","sourceRoot":"","sources":["iterable.js"],"names":[],"mappings":"AAWO,iCAHY,GAAG,EACK,IAAI,YAFpB,aAAa,CACL,GAAG,AADM,CAAC,aAClB,CAAC,KAAK,EAAE,GAAG,KACK,IAAI,AADA,GAClB,aAAa,CAAC,IAAI,CAAC,CAU/B;AAQM,8BAGyB,CAAC,YALtB,IAAI,CAAC,OAAO,YAAY,EAAE,QAAQ,CAKb,CAAC,AALc,CAAC,CAAC;IAK7C,kCAAkC;kCAApB,aAAa,CAAC,CAAC,CAAC;;IAA9B,kCAAkC;kCAApB,aAAa,CAAC,CAAC,CAAC;GAQ9B;AASG,4BAGyB,CAAC,YANtB,IAAI,CAAC,OAAO,YAAY,EAAE,QAAQ,CAMb,CAAC,AANc,CAAC,CAAC;IAM7C,kCAAkC;kCAApB,aAAa,CAAC,CAAC,CAAC;;IAA9B,kCAAkC;kCAApB,aAAa,CAAC,CAAC,CAAC;GAQ9B;AAOG,+BAGyB,CAAC,YANtB,IAAI,CAAC,OAAO,YAAY,EAAE,QAAQ,CAMb,CAAC,AANc,CAAC,CAAC;IAM7C,kCAAkC;kCAApB,aAAa,CAAC,CAAC,CAAC;;IAA9B,kCAAkC;kCAApB,aAAa,CAAC,CAAC,CAAC;GAQ9B"}
|
package/src/iterable.js
CHANGED
|
@@ -15,6 +15,7 @@ export const mapAsyncIterable = (iterable, transform) => {
|
|
|
15
15
|
yield transform(value);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
+
harden(transformGenerator);
|
|
18
19
|
return transformGenerator();
|
|
19
20
|
};
|
|
20
21
|
|
|
@@ -22,7 +23,7 @@ export const mapAsyncIterable = (iterable, transform) => {
|
|
|
22
23
|
* TODO: Remove this function when we have an @endo/publish-kit that suppports pull topics
|
|
23
24
|
*
|
|
24
25
|
* @template T
|
|
25
|
-
* @param {ERef<import('./types').Follower<T>>} follower
|
|
26
|
+
* @param {ERef<import('./types.js').Follower<T>>} follower
|
|
26
27
|
*/
|
|
27
28
|
export const iterateLatest = follower =>
|
|
28
29
|
// For now, just pass through the iterable.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export function makeLeaderFromRpcAddresses(rpcAddrs: string[], leaderOptions?: import("./types.js").LeaderOptions | undefined): import(
|
|
1
|
+
export function makeLeaderFromRpcAddresses(rpcAddrs: string[], leaderOptions?: import("./types.js").LeaderOptions | undefined): import("./types.js").Leader;
|
|
2
2
|
export function makeLeaderFromNetworkConfig(netconfigURL: string, options?: import("./types.js").LeaderOptions | undefined): Promise<any>;
|
|
3
|
-
export function makeLeader(bootstrap?: string | undefined, options?: import("./types.js").LeaderOptions | undefined): ERef<import(
|
|
3
|
+
export function makeLeader(bootstrap?: string | undefined, options?: import("./types.js").LeaderOptions | undefined): ERef<import("./types.js").Leader>;
|
|
4
4
|
//# sourceMappingURL=leader-netconfig.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"leader-netconfig.d.ts","sourceRoot":"","sources":["leader-netconfig.js"],"names":[],"mappings":"AAgBO,qDAJI,MAAM,EAAE,mEAEN,OAAO,YAAY,EAAE,MAAM,CAevC;AAMM,0DAHI,MAAM,0EAoChB;AAOM,sHAFM,
|
|
1
|
+
{"version":3,"file":"leader-netconfig.d.ts","sourceRoot":"","sources":["leader-netconfig.js"],"names":[],"mappings":"AAgBO,qDAJI,MAAM,EAAE,mEAEN,OAAO,YAAY,EAAE,MAAM,CAevC;AAMM,0DAHI,MAAM,0EAoChB;AAOM,sHAFM,IAAI,CAAC,OAAO,YAAY,EAAE,MAAM,CAAC,CAO7C"}
|
package/src/leader.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export function makeRoundRobinLeader(endpoints: string[], leaderOptions?: import(
|
|
1
|
+
export function makeRoundRobinLeader(endpoints: string[], leaderOptions?: import("./types.js").LeaderOptions): import("./types.js").Leader;
|
|
2
2
|
//# sourceMappingURL=leader.d.ts.map
|
package/src/main.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"makeHttpClient.d.ts","sourceRoot":"","sources":["makeHttpClient.js"],"names":[],"mappings":"AA2BO,oCAJI,MAAM,SACN,OAAO,MAAM,CAAC,KAAK,GACjB,OAAO,wBAAwB,EAAE,SAAS,CA8BtD"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
const { freeze } = Object;
|
|
4
|
+
|
|
5
|
+
const filterBadStatus = res => {
|
|
6
|
+
if (res.status >= 400) {
|
|
7
|
+
throw new Error(`Bad status on response: ${res.status}`);
|
|
8
|
+
}
|
|
9
|
+
return res;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Make an RpcClient using explicit access to the network.
|
|
14
|
+
*
|
|
15
|
+
* The RpcClient implementations included in cosmjs
|
|
16
|
+
* such as {@link https://cosmos.github.io/cosmjs/latest/tendermint-rpc/classes/HttpClient.html HttpClient}
|
|
17
|
+
* use ambient authority (fetch or axios) for network access.
|
|
18
|
+
*
|
|
19
|
+
* To facilitate cooperation without vulnerability,
|
|
20
|
+
* as well as unit testing, etc. this RpcClient maker takes
|
|
21
|
+
* network access as a parameter, following
|
|
22
|
+
* {@link https://github.com/Agoric/agoric-sdk/wiki/OCap-Discipline|OCap Discipline}.
|
|
23
|
+
*
|
|
24
|
+
* @param {string} url
|
|
25
|
+
* @param {typeof window.fetch} fetch
|
|
26
|
+
* @returns {import('@cosmjs/tendermint-rpc').RpcClient}
|
|
27
|
+
*/
|
|
28
|
+
export const makeHttpClient = (url, fetch) => {
|
|
29
|
+
const headers = {}; // XXX needed?
|
|
30
|
+
|
|
31
|
+
// based on cosmjs 0.30.1:
|
|
32
|
+
// https://github.com/cosmos/cosmjs/blob/33271bc51cdc865cadb647a1b7ab55d873637f39/packages/tendermint-rpc/src/rpcclients/http.ts#L37
|
|
33
|
+
// https://github.com/cosmos/cosmjs/blob/33271bc51cdc865cadb647a1b7ab55d873637f39/packages/tendermint-rpc/src/rpcclients/httpclient.ts#L25
|
|
34
|
+
return freeze({
|
|
35
|
+
disconnect: () => {
|
|
36
|
+
// nothing to be done
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @param {import('@cosmjs/json-rpc').JsonRpcRequest} request
|
|
41
|
+
*/
|
|
42
|
+
execute: async request => {
|
|
43
|
+
const settings = {
|
|
44
|
+
method: 'POST',
|
|
45
|
+
body: request ? JSON.stringify(request) : undefined,
|
|
46
|
+
headers: {
|
|
47
|
+
'Content-Type': 'application/json',
|
|
48
|
+
...headers,
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
return fetch(url, settings)
|
|
52
|
+
.then(filterBadStatus)
|
|
53
|
+
.then(res => res.json());
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
};
|
package/src/netconfig.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"netconfig.d.ts","sourceRoot":"","sources":["netconfig.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;GAYG;AACH,kEAWE;AAQK,8CAJI,OAAO,
|
|
1
|
+
{"version":3,"file":"netconfig.d.ts","sourceRoot":"","sources":["netconfig.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;GAYG;AACH,kEAWE;AAQK,8CAJI,OAAO,GACL,OAAO,CAAC,QAAQ,IAAI,aAAa,CAIL;;;;;;;;;;cA3B3B,MAAM,EAAE;;;;eACR,MAAM"}
|
package/src/shuffle.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export function shuffle<T>(a: T
|
|
1
|
+
export function shuffle<T>(a: Array<T>): void;
|
|
2
2
|
//# sourceMappingURL=shuffle.d.ts.map
|
package/src/shuffle.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shuffle.d.ts","sourceRoot":"","sources":["shuffle.js"],"names":[],"mappings":"AAMO,
|
|
1
|
+
{"version":3,"file":"shuffle.d.ts","sourceRoot":"","sources":["shuffle.js"],"names":[],"mappings":"AAMO,wBAFU,CAAC,KAAP,KAAK,CAAC,CAAC,CAAC,QASlB"}
|
package/src/types.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export type ERef<T> = import('@endo/far').ERef<T>;
|
|
2
1
|
export type LeaderOptions = {
|
|
3
2
|
retryCallback?: ((where: string, err: any, attempt?: number) => Promise<void>) | null | undefined;
|
|
4
3
|
jitter?: ((where: string) => Promise<void>) | undefined;
|
|
@@ -31,14 +30,14 @@ export type ValueFollowerElement<T> = ValueFollowerBase & ({
|
|
|
31
30
|
value: undefined;
|
|
32
31
|
error: any;
|
|
33
32
|
});
|
|
34
|
-
export type Unserializer = Pick<import(
|
|
33
|
+
export type Unserializer = Pick<import("@endo/marshal").Marshal<unknown>, "fromCapData" | "unserialize">;
|
|
35
34
|
export type Crasher = {
|
|
36
35
|
crash: (...args: unknown[]) => void;
|
|
37
36
|
};
|
|
38
37
|
export type FollowerOptions = {
|
|
39
38
|
unserializer?: import("@endo/far").FarRef<Unserializer, import("@endo/eventual-send").DataOnly<Unserializer>> | null | undefined;
|
|
40
39
|
decode?: ((text: string) => any) | undefined;
|
|
41
|
-
proof?: "
|
|
40
|
+
proof?: "none" | "strict" | "optimistic" | undefined;
|
|
42
41
|
crasher?: import("@endo/far").FarRef<Crasher, import("@endo/eventual-send").DataOnly<Crasher>> | undefined;
|
|
43
42
|
};
|
|
44
43
|
export type CastingSpec = {
|
|
@@ -46,8 +45,8 @@ export type CastingSpec = {
|
|
|
46
45
|
storeSubkey?: Uint8Array | undefined;
|
|
47
46
|
dataPrefixBytes?: Uint8Array | undefined;
|
|
48
47
|
noDataValue?: Uint8Array | undefined;
|
|
49
|
-
subscription?: ERef<Subscription<any>> | undefined;
|
|
50
|
-
notifier?: ERef<Notifier<any>> | undefined;
|
|
48
|
+
subscription?: globalThis.ERef<Subscription<any>> | undefined;
|
|
49
|
+
notifier?: globalThis.ERef<Notifier<any>> | undefined;
|
|
51
50
|
};
|
|
52
51
|
export type IterateEachOptions = {
|
|
53
52
|
height?: number | undefined;
|
|
@@ -56,4 +55,6 @@ export type StreamCell<T> = {
|
|
|
56
55
|
blockHeight: number;
|
|
57
56
|
values: Array<T>;
|
|
58
57
|
};
|
|
58
|
+
import type { Subscription } from '@agoric/notifier';
|
|
59
|
+
import type { Notifier } from '@agoric/notifier';
|
|
59
60
|
//# sourceMappingURL=types.d.ts.map
|
package/src/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.js"],"names":[],"mappings":";6BAW8B,MAAM,OAAO,GAAG,YAAY,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;sBAC5D,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;2BACxB,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC;;;;YAMnC,UAAU,EAAE;;;WAKZ,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;YAC9D,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC;gBAChC,MAAM,aAAa;kBACnB,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC;kBAC9E,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;;4BAG7D,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC;qBAOqB,CAAC;uBAFzD,MAAM,OAAO,CAAC,aAAa,CAE6B,CAAC,AAF5B,CAAC,CAAC;qBAC/B,CAAC,OAAO,CAAC,EAAE,kBAAkB,KAAK,OAAO,CAAC,aAAa,CACC,CAAC,AADA,CAAC,CAAC;wBAC3D,CAAC,OAAO,CAAC,EAAE,kBAAkB,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;;;iBAK3D,MAAM;wBACN,MAAM;;iCAMuB,CAAC,IAA/B,iBAAiB,GAAG,CAAC;IAAE,KAAK,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,GAAG,CAAA;CAAE,CAAC;2BAIrE,IAAI,CAAC,OAAO,eAAe,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,aAAa,CAAC;;WAK5E,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI;;;;qBAMrB,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;uBAwBf,CAAC;iBADP,MAAM;YACN,KAAK,CAAC,CAAC,CAAC;;kCAnFmB,kBAAkB;8BAAlB,kBAAkB"}
|
package/src/types.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// @jessie-check
|
|
2
2
|
|
|
3
|
-
//
|
|
4
|
-
import '@agoric/notifier';
|
|
5
|
-
|
|
3
|
+
// Ensure this is a module.
|
|
6
4
|
export {};
|
|
7
5
|
|
|
8
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* @import {Notifier, Subscription} from '@agoric/notifier';
|
|
8
|
+
*/
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* @typedef {object} LeaderOptions
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
/* global globalThis */
|
|
3
|
+
import anyTest from 'ava';
|
|
4
|
+
import {
|
|
5
|
+
createProtobufRpcClient,
|
|
6
|
+
QueryClient,
|
|
7
|
+
setupBankExtension,
|
|
8
|
+
} from '@cosmjs/stargate';
|
|
9
|
+
import { Tendermint34Client } from '@cosmjs/tendermint-rpc';
|
|
10
|
+
import {
|
|
11
|
+
QueryChildrenRequest,
|
|
12
|
+
QueryChildrenResponse,
|
|
13
|
+
} from '@agoric/cosmic-proto/vstorage/query.js';
|
|
14
|
+
|
|
15
|
+
import { makeHttpClient } from '../src/makeHttpClient.js';
|
|
16
|
+
import { captureIO, replayIO, web1, web2 } from './net-access-fixture.js';
|
|
17
|
+
|
|
18
|
+
/** @type {import('ava').TestFn<Awaited<ReturnType<typeof makeTestContext>>>} */
|
|
19
|
+
const test = /** @type {any} */ (anyTest);
|
|
20
|
+
|
|
21
|
+
const RECORDING = false;
|
|
22
|
+
|
|
23
|
+
const makeTestContext = async () => {
|
|
24
|
+
return { fetch: globalThis.fetch };
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
test.before(async t => {
|
|
28
|
+
t.context = await makeTestContext();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const scenario1 = {
|
|
32
|
+
endpoint: 'https://emerynet.rpc.agoric.net/',
|
|
33
|
+
request: {
|
|
34
|
+
id: 1,
|
|
35
|
+
method: 'no-such-method',
|
|
36
|
+
params: [],
|
|
37
|
+
},
|
|
38
|
+
gov2: {
|
|
39
|
+
addr: 'agoric140dmkrz2e42ergjj7gyvejhzmjzurvqeq82ang',
|
|
40
|
+
balance: { amount: '25050000', denom: 'uist' },
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
test('interpose net access', async t => {
|
|
45
|
+
const fetchMock = replayIO(web1);
|
|
46
|
+
const rpcClient = makeHttpClient(scenario1.endpoint, fetchMock);
|
|
47
|
+
|
|
48
|
+
t.log('raw JSON RPC');
|
|
49
|
+
const res = await rpcClient.execute({
|
|
50
|
+
...scenario1.request,
|
|
51
|
+
jsonrpc: '2.0',
|
|
52
|
+
});
|
|
53
|
+
t.like(res, { error: { message: 'Method not found' } });
|
|
54
|
+
|
|
55
|
+
t.log('Cosmos SDK RPC: balance query');
|
|
56
|
+
const tmClient = await Tendermint34Client.create(rpcClient);
|
|
57
|
+
const qClient = new QueryClient(tmClient);
|
|
58
|
+
const ext = setupBankExtension(qClient);
|
|
59
|
+
const actual = await ext.bank.balance(
|
|
60
|
+
scenario1.gov2.addr,
|
|
61
|
+
scenario1.gov2.balance.denom,
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
t.deepEqual(actual, scenario1.gov2.balance);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const scenario2 = {
|
|
68
|
+
endpoint: 'https://emerynet.rpc.agoric.net/',
|
|
69
|
+
children: [
|
|
70
|
+
'activityhash',
|
|
71
|
+
'beansOwing',
|
|
72
|
+
'egress',
|
|
73
|
+
'highPrioritySenders',
|
|
74
|
+
'published',
|
|
75
|
+
'swingStore',
|
|
76
|
+
],
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// XXX open code until https://github.com/Agoric/agoric-sdk/issues/9200
|
|
80
|
+
class QueryClientImpl {
|
|
81
|
+
rpc;
|
|
82
|
+
|
|
83
|
+
service;
|
|
84
|
+
|
|
85
|
+
constructor(rpc, opts) {
|
|
86
|
+
this.service = opts?.service || 'agoric.vstorage.Query';
|
|
87
|
+
this.rpc = rpc;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
Children(request) {
|
|
91
|
+
const reqData = QueryChildrenRequest.encode(request).finish();
|
|
92
|
+
const promise = this.rpc.request(this.service, 'Children', reqData);
|
|
93
|
+
return promise.then(respData => QueryChildrenResponse.decode(respData));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
test(`vstorage query: Children (RECORDING: ${RECORDING})`, async t => {
|
|
98
|
+
const { context: io } = t;
|
|
99
|
+
|
|
100
|
+
const { fetch: fetchMock, web } = io.recording
|
|
101
|
+
? captureIO(io.fetch)
|
|
102
|
+
: { fetch: replayIO(web2), web: new Map() };
|
|
103
|
+
const rpcClient = makeHttpClient(scenario2.endpoint, fetchMock);
|
|
104
|
+
|
|
105
|
+
const tmClient = await Tendermint34Client.create(rpcClient);
|
|
106
|
+
const qClient = new QueryClient(tmClient);
|
|
107
|
+
const rpc = createProtobufRpcClient(qClient);
|
|
108
|
+
const queryService = new QueryClientImpl(rpc);
|
|
109
|
+
|
|
110
|
+
const children = await queryService.Children({ path: '' });
|
|
111
|
+
if (io.recording) {
|
|
112
|
+
t.snapshot(web);
|
|
113
|
+
}
|
|
114
|
+
t.deepEqual(children, {
|
|
115
|
+
children: scenario2.children,
|
|
116
|
+
pagination: undefined,
|
|
117
|
+
});
|
|
118
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
import './lockdown.js';
|
|
4
4
|
|
|
5
5
|
import { makeMarshal } from '@endo/marshal';
|
|
@@ -201,7 +201,7 @@ test('yields error on bad capdata without terminating', async t => {
|
|
|
201
201
|
const castingSpec = makeCastingSpec(':mailbox.agoric1foobarbaz');
|
|
202
202
|
const follower = await makeFollower(castingSpec, leader, so);
|
|
203
203
|
let i = 0;
|
|
204
|
-
|
|
204
|
+
|
|
205
205
|
for await (const { value, error } of iterateEach(follower)) {
|
|
206
206
|
if (i === 0) {
|
|
207
207
|
t.log(`value from follower, should be undefined:`, value);
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
const { stringify: jq } = JSON;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file to regenerate
|
|
5
|
+
* 1. set RECORDING=true in interpose-net-access.test.js
|
|
6
|
+
* 2. run: yarn test test/interpose-net-access.test.js --update-snapshots
|
|
7
|
+
* 3. for each map in interpose-net-access.test.js.md, copy it and
|
|
8
|
+
* 4. replace all occurences of => with : and paste as args to Object.fromEntries()
|
|
9
|
+
* 5. change RECORDING back to false
|
|
10
|
+
*/
|
|
11
|
+
export const web1 = new Map([
|
|
12
|
+
[
|
|
13
|
+
jq([
|
|
14
|
+
'https://emerynet.rpc.agoric.net/',
|
|
15
|
+
{
|
|
16
|
+
method: 'POST',
|
|
17
|
+
body: jq({
|
|
18
|
+
id: 1208387614,
|
|
19
|
+
method: 'no-such-method',
|
|
20
|
+
params: [],
|
|
21
|
+
jsonrpc: '2.0',
|
|
22
|
+
}),
|
|
23
|
+
headers: { 'Content-Type': 'application/json' },
|
|
24
|
+
},
|
|
25
|
+
]),
|
|
26
|
+
{
|
|
27
|
+
error: {
|
|
28
|
+
code: -32601,
|
|
29
|
+
message: 'Method not found',
|
|
30
|
+
},
|
|
31
|
+
id: 1208387614,
|
|
32
|
+
jsonrpc: '2.0',
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
[
|
|
36
|
+
jq([
|
|
37
|
+
'https://emerynet.rpc.agoric.net/',
|
|
38
|
+
{
|
|
39
|
+
method: 'POST',
|
|
40
|
+
body: jq({
|
|
41
|
+
jsonrpc: '2.0',
|
|
42
|
+
id: 797030719,
|
|
43
|
+
method: 'abci_query',
|
|
44
|
+
params: {
|
|
45
|
+
path: '/cosmos.bank.v1beta1.Query/Balance',
|
|
46
|
+
data: '0a2d61676f726963313430646d6b727a326534326572676a6a37677976656a687a6d6a7a7572767165713832616e67120475697374',
|
|
47
|
+
prove: false,
|
|
48
|
+
},
|
|
49
|
+
}),
|
|
50
|
+
headers: { 'Content-Type': 'application/json' },
|
|
51
|
+
},
|
|
52
|
+
]),
|
|
53
|
+
{
|
|
54
|
+
id: 797030719,
|
|
55
|
+
jsonrpc: '2.0',
|
|
56
|
+
result: {
|
|
57
|
+
response: {
|
|
58
|
+
code: 0,
|
|
59
|
+
codespace: '',
|
|
60
|
+
height: '123985',
|
|
61
|
+
index: '0',
|
|
62
|
+
info: '',
|
|
63
|
+
key: null,
|
|
64
|
+
log: '',
|
|
65
|
+
proofOps: null,
|
|
66
|
+
value: 'ChAKBHVpc3QSCDI1MDUwMDAw',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
],
|
|
71
|
+
]);
|
|
72
|
+
|
|
73
|
+
export const web2 = new Map([
|
|
74
|
+
[
|
|
75
|
+
jq([
|
|
76
|
+
'https://emerynet.rpc.agoric.net/',
|
|
77
|
+
{
|
|
78
|
+
method: 'POST',
|
|
79
|
+
body: jq({
|
|
80
|
+
jsonrpc: '2.0',
|
|
81
|
+
id: 1757612624,
|
|
82
|
+
method: 'abci_query',
|
|
83
|
+
params: {
|
|
84
|
+
path: '/agoric.vstorage.Query/Children',
|
|
85
|
+
data: '',
|
|
86
|
+
prove: false,
|
|
87
|
+
},
|
|
88
|
+
}),
|
|
89
|
+
headers: { 'Content-Type': 'application/json' },
|
|
90
|
+
},
|
|
91
|
+
]),
|
|
92
|
+
{
|
|
93
|
+
id: 1757612624,
|
|
94
|
+
jsonrpc: '2.0',
|
|
95
|
+
result: {
|
|
96
|
+
response: {
|
|
97
|
+
code: 0,
|
|
98
|
+
codespace: '',
|
|
99
|
+
height: '123985',
|
|
100
|
+
index: '0',
|
|
101
|
+
info: '',
|
|
102
|
+
key: null,
|
|
103
|
+
log: '',
|
|
104
|
+
proofOps: null,
|
|
105
|
+
value:
|
|
106
|
+
'CgxhY3Rpdml0eWhhc2gKCmJlYW5zT3dpbmcKBmVncmVzcwoTaGlnaFByaW9yaXR5U2VuZGVycwoJcHVibGlzaGVkCgpzd2luZ1N0b3Jl',
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
]);
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @param {string} str
|
|
115
|
+
* ack: https://stackoverflow.com/a/7616484
|
|
116
|
+
*/
|
|
117
|
+
const hashCode = str => {
|
|
118
|
+
let hash = 0;
|
|
119
|
+
let i;
|
|
120
|
+
let chr;
|
|
121
|
+
if (str.length === 0) return hash;
|
|
122
|
+
for (i = 0; i < str.length; i += 1) {
|
|
123
|
+
chr = str.charCodeAt(i);
|
|
124
|
+
// eslint-disable-next-line no-bitwise
|
|
125
|
+
hash = (hash << 5) - hash + chr;
|
|
126
|
+
// eslint-disable-next-line no-bitwise
|
|
127
|
+
hash |= 0; // Convert to 32bit integer
|
|
128
|
+
}
|
|
129
|
+
return hash;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Normalize JSON RPC request ID
|
|
134
|
+
*
|
|
135
|
+
* tendermint-rpc generates ids using ambient access to Math.random()
|
|
136
|
+
* So we normalize them to a hash of the rest of the JSON.
|
|
137
|
+
*
|
|
138
|
+
* Earlier, we tried a sequence number, but it was non-deterministic
|
|
139
|
+
* with multiple interleaved requests.
|
|
140
|
+
*
|
|
141
|
+
* @param {string} argsKey
|
|
142
|
+
*/
|
|
143
|
+
const normalizeID = argsKey => {
|
|
144
|
+
// arbitrary string unlikely to occur in a request. from `pwgen 16 -1`
|
|
145
|
+
const placeholder = 'Ajaz1chei7ohnguv';
|
|
146
|
+
|
|
147
|
+
const noid = argsKey.replace(/\\"id\\":\d+/, `\\"id\\":${placeholder}`);
|
|
148
|
+
const id = Math.abs(hashCode(noid));
|
|
149
|
+
return noid.replace(placeholder, `${id}`);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Wrap `fetch` to capture JSON RPC IO traffic.
|
|
154
|
+
*
|
|
155
|
+
* @param {typeof window.fetch} fetch
|
|
156
|
+
* returns wraped fetch along with a .web map for use with {@link replayIO}
|
|
157
|
+
*/
|
|
158
|
+
export const captureIO = fetch => {
|
|
159
|
+
const web = new Map();
|
|
160
|
+
/** @type {typeof window.fetch} */
|
|
161
|
+
// @ts-expect-error mock
|
|
162
|
+
const f = async (...args) => {
|
|
163
|
+
const key = normalizeID(JSON.stringify(args));
|
|
164
|
+
const resp = await fetch(...args);
|
|
165
|
+
return {
|
|
166
|
+
json: async () => {
|
|
167
|
+
const data = await resp.json();
|
|
168
|
+
web.set(key, data);
|
|
169
|
+
return data;
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
};
|
|
173
|
+
return { fetch: f, web };
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Replay captured JSON RPC IO.
|
|
178
|
+
*
|
|
179
|
+
* @param {Map<string, any>} web map from
|
|
180
|
+
* JSON-stringified fetch args to fetched JSON data.
|
|
181
|
+
*/
|
|
182
|
+
export const replayIO = web => {
|
|
183
|
+
/** @type {typeof window.fetch} */
|
|
184
|
+
// @ts-expect-error mock
|
|
185
|
+
const f = async (...args) => {
|
|
186
|
+
const key = normalizeID(JSON.stringify(args));
|
|
187
|
+
const data = web.get(key);
|
|
188
|
+
if (!data) {
|
|
189
|
+
throw Error(`no data for ${key}`);
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
json: async () => data,
|
|
193
|
+
};
|
|
194
|
+
};
|
|
195
|
+
return f;
|
|
196
|
+
};
|
package/jsconfig.build.json
DELETED
|
File without changes
|