@acala-network/chopsticks 0.3.11 → 0.4.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/chopsticks.js +1 -1
- package/{dist → lib}/blockchain/block-builder.d.ts +3 -1
- package/{dist → lib}/blockchain/block-builder.js +29 -10
- package/{dist → lib}/blockchain/index.d.ts +3 -2
- package/{dist → lib}/blockchain/index.js +8 -3
- package/{dist → lib}/blockchain/inherent/parachain/babe-randomness.d.ts +1 -1
- package/{dist → lib}/blockchain/inherent/parachain/nimbus-author-inherent.d.ts +1 -1
- package/{dist → lib}/blockchain/inherent/parachain/validation-data.d.ts +1 -1
- package/{dist → lib}/blockchain/inherent/parachain/validation-data.js +63 -38
- package/{dist → lib}/blockchain/txpool.d.ts +4 -0
- package/{dist → lib}/blockchain/txpool.js +7 -2
- package/{dist → lib}/cli.js +12 -2
- package/lib/dry-run-preimage.d.ts +2 -0
- package/lib/dry-run-preimage.js +99 -0
- package/{dist → lib}/executor.js +2 -6
- package/{dist → lib}/logger.js +7 -3
- package/{dist → lib}/rpc/substrate/author.js +22 -6
- package/{dist → lib}/rpc/substrate/chain.d.ts +1 -0
- package/{dist → lib}/rpc/substrate/chain.js +10 -4
- package/lib/rpc/substrate/system.d.ts +3 -0
- package/{dist → lib}/server.js +6 -1
- package/{dist → lib}/setup.js +3 -1
- package/{dist → lib}/utils/decoder.js +5 -1
- package/{dist → lib}/utils/set-storage.js +4 -2
- package/package.json +40 -63
- package/template/diff.html +139 -78
- package/LICENSE +0 -201
- package/README.md +0 -71
- package/dist/executor.test.d.ts +0 -1
- package/dist/executor.test.js +0 -138
- package/dist/rpc/substrate/author.d.ts +0 -3
- /package/{dist → lib}/api.d.ts +0 -0
- /package/{dist → lib}/api.js +0 -0
- /package/{dist → lib}/blockchain/block.d.ts +0 -0
- /package/{dist → lib}/blockchain/block.js +0 -0
- /package/{dist → lib}/blockchain/head-state.d.ts +0 -0
- /package/{dist → lib}/blockchain/head-state.js +0 -0
- /package/{dist → lib}/blockchain/inherent/index.d.ts +0 -0
- /package/{dist → lib}/blockchain/inherent/index.js +0 -0
- /package/{dist → lib}/blockchain/inherent/para-enter.d.ts +0 -0
- /package/{dist → lib}/blockchain/inherent/para-enter.js +0 -0
- /package/{dist → lib}/blockchain/inherent/parachain/babe-randomness.js +0 -0
- /package/{dist → lib}/blockchain/inherent/parachain/nimbus-author-inherent.js +0 -0
- /package/{dist → lib}/blockchain/storage-layer.d.ts +0 -0
- /package/{dist → lib}/blockchain/storage-layer.js +0 -0
- /package/{dist → lib}/cli.d.ts +0 -0
- /package/{dist → lib}/db/entities.d.ts +0 -0
- /package/{dist → lib}/db/entities.js +0 -0
- /package/{dist → lib}/db/index.d.ts +0 -0
- /package/{dist → lib}/db/index.js +0 -0
- /package/{dist → lib}/dry-run.d.ts +0 -0
- /package/{dist → lib}/dry-run.js +0 -0
- /package/{dist → lib}/executor.d.ts +0 -0
- /package/{dist → lib}/genesis-provider.d.ts +0 -0
- /package/{dist → lib}/genesis-provider.js +0 -0
- /package/{dist → lib}/index.d.ts +0 -0
- /package/{dist → lib}/index.js +0 -0
- /package/{dist → lib}/logger.d.ts +0 -0
- /package/{dist → lib}/rpc/dev.d.ts +0 -0
- /package/{dist → lib}/rpc/dev.js +0 -0
- /package/{dist → lib}/rpc/index.d.ts +0 -0
- /package/{dist → lib}/rpc/index.js +0 -0
- /package/{dist → lib}/rpc/shared.d.ts +0 -0
- /package/{dist → lib}/rpc/shared.js +0 -0
- /package/{dist/rpc/substrate/index.d.ts → lib/rpc/substrate/author.d.ts} +0 -0
- /package/{dist/rpc/substrate/payment.d.ts → lib/rpc/substrate/index.d.ts} +0 -0
- /package/{dist → lib}/rpc/substrate/index.js +0 -0
- /package/{dist/rpc/substrate/state.d.ts → lib/rpc/substrate/payment.d.ts} +0 -0
- /package/{dist → lib}/rpc/substrate/payment.js +0 -0
- /package/{dist/rpc/substrate/system.d.ts → lib/rpc/substrate/state.d.ts} +0 -0
- /package/{dist → lib}/rpc/substrate/state.js +0 -0
- /package/{dist → lib}/rpc/substrate/system.js +0 -0
- /package/{dist → lib}/run-block.d.ts +0 -0
- /package/{dist → lib}/run-block.js +0 -0
- /package/{dist → lib}/schema/index.d.ts +0 -0
- /package/{dist → lib}/schema/index.js +0 -0
- /package/{dist → lib}/server.d.ts +0 -0
- /package/{dist → lib}/setup-with-server.d.ts +0 -0
- /package/{dist → lib}/setup-with-server.js +0 -0
- /package/{dist → lib}/setup.d.ts +0 -0
- /package/{dist → lib}/utils/decoder.d.ts +0 -0
- /package/{dist → lib}/utils/generate-html-diff.d.ts +0 -0
- /package/{dist → lib}/utils/generate-html-diff.js +0 -0
- /package/{dist → lib}/utils/import-storage.d.ts +0 -0
- /package/{dist → lib}/utils/import-storage.js +0 -0
- /package/{dist → lib}/utils/index.d.ts +0 -0
- /package/{dist → lib}/utils/index.js +0 -0
- /package/{dist → lib}/utils/open-html.d.ts +0 -0
- /package/{dist → lib}/utils/open-html.js +0 -0
- /package/{dist → lib}/utils/proof.d.ts +0 -0
- /package/{dist → lib}/utils/proof.js +0 -0
- /package/{dist → lib}/utils/set-storage.d.ts +0 -0
- /package/{dist → lib}/utils/time-travel.d.ts +0 -0
- /package/{dist → lib}/utils/time-travel.js +0 -0
- /package/{dist → lib}/xcm/downward.d.ts +0 -0
- /package/{dist → lib}/xcm/downward.js +0 -0
- /package/{dist → lib}/xcm/horizontal.d.ts +0 -0
- /package/{dist → lib}/xcm/horizontal.js +0 -0
- /package/{dist → lib}/xcm/index.d.ts +0 -0
- /package/{dist → lib}/xcm/index.js +0 -0
- /package/{dist → lib}/xcm/upward.d.ts +0 -0
- /package/{dist → lib}/xcm/upward.js +0 -0
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const shared_1 = require("../shared");
|
|
4
|
+
const processHeader = (header) => {
|
|
5
|
+
const res = header.toJSON();
|
|
6
|
+
res.number = '0x' + res.number.toString(16); // number is hex format
|
|
7
|
+
return res;
|
|
8
|
+
};
|
|
4
9
|
const handlers = {
|
|
5
10
|
chain_getBlockHash: async (context, [blockNumber]) => {
|
|
6
11
|
const block = await context.chain.getBlockAt(blockNumber);
|
|
@@ -14,7 +19,7 @@ const handlers = {
|
|
|
14
19
|
if (!block) {
|
|
15
20
|
throw new shared_1.ResponseError(1, `Block ${hash} not found`);
|
|
16
21
|
}
|
|
17
|
-
return await block.header;
|
|
22
|
+
return processHeader(await block.header);
|
|
18
23
|
},
|
|
19
24
|
chain_getBlock: async (context, [hash]) => {
|
|
20
25
|
const block = await context.chain.getBlock(hash);
|
|
@@ -37,7 +42,7 @@ const handlers = {
|
|
|
37
42
|
const id = context.chain.headState.subscribeHead(() => update());
|
|
38
43
|
const callback = subscribe('chain_newHead', id, () => context.chain.headState.unsubscribeHead(id));
|
|
39
44
|
update = async () => {
|
|
40
|
-
callback(await context.chain.head.header);
|
|
45
|
+
callback(processHeader(await context.chain.head.header));
|
|
41
46
|
};
|
|
42
47
|
update();
|
|
43
48
|
return id;
|
|
@@ -45,9 +50,9 @@ const handlers = {
|
|
|
45
50
|
chain_subscribeFinalizedHeads: async (context, _params, { subscribe }) => {
|
|
46
51
|
let update = () => { };
|
|
47
52
|
const id = context.chain.headState.subscribeHead(() => update());
|
|
48
|
-
const callback = subscribe('
|
|
53
|
+
const callback = subscribe('chain_finalizedHead', id, () => context.chain.headState.unsubscribeHead(id));
|
|
49
54
|
update = async () => {
|
|
50
|
-
callback(await context.chain.head.header);
|
|
55
|
+
callback(processHeader(await context.chain.head.header));
|
|
51
56
|
};
|
|
52
57
|
update();
|
|
53
58
|
return id;
|
|
@@ -59,6 +64,7 @@ const handlers = {
|
|
|
59
64
|
const alias = {
|
|
60
65
|
chain_subscribeNewHeads: handlers.chain_subscribeNewHead,
|
|
61
66
|
chain_unsubscribeNewHeads: handlers.chain_unsubscribeNewHead,
|
|
67
|
+
chain_unsubscribeFinalizedHeads: handlers.chain_unsubscribeNewHead,
|
|
62
68
|
};
|
|
63
69
|
exports.default = {
|
|
64
70
|
...handlers,
|
package/{dist → lib}/server.js
RENAMED
|
@@ -76,6 +76,7 @@ const createServer = async (handler, port) => {
|
|
|
76
76
|
subscriptions[subid] = onCancel;
|
|
77
77
|
return (data) => {
|
|
78
78
|
if (subscriptions[subid]) {
|
|
79
|
+
logger.trace({ method, subid, data: (0, logger_1.truncate)(data) }, 'Subscription notification');
|
|
79
80
|
send({
|
|
80
81
|
jsonrpc: '2.0',
|
|
81
82
|
method,
|
|
@@ -128,7 +129,11 @@ const createServer = async (handler, port) => {
|
|
|
128
129
|
}, 'Received message');
|
|
129
130
|
try {
|
|
130
131
|
const resp = await handler(req, subscriptionManager);
|
|
131
|
-
logger.trace(
|
|
132
|
+
logger.trace({
|
|
133
|
+
id: req.id,
|
|
134
|
+
method: req.method,
|
|
135
|
+
result: (0, logger_1.truncate)(resp),
|
|
136
|
+
}, 'Sending response for request');
|
|
132
137
|
send({
|
|
133
138
|
id: req.id,
|
|
134
139
|
jsonrpc: '2.0',
|
package/{dist → lib}/setup.js
RENAMED
|
@@ -63,8 +63,10 @@ const setup = async (argv) => {
|
|
|
63
63
|
});
|
|
64
64
|
if (argv.timestamp)
|
|
65
65
|
await (0, time_travel_1.timeTravel)(chain, argv.timestamp);
|
|
66
|
-
|
|
66
|
+
// override wasm before importing storage, in case new pallets have been
|
|
67
|
+
// added that have storage imports
|
|
67
68
|
await (0, import_storage_1.overrideWasm)(chain, argv['wasm-override']);
|
|
69
|
+
await (0, import_storage_1.importStorage)(chain, argv['import-storage']);
|
|
68
70
|
return { chain, api, ws: provider };
|
|
69
71
|
};
|
|
70
72
|
exports.setup = setup;
|
|
@@ -100,6 +100,10 @@ const decodeStorageDiff = async (block, diff) => {
|
|
|
100
100
|
lodash_1.default.merge(oldState, await (0, exports.decodeKeyValue)(block, key, (await block.get(key))));
|
|
101
101
|
lodash_1.default.merge(newState, await (0, exports.decodeKeyValue)(block, key, value));
|
|
102
102
|
}
|
|
103
|
-
|
|
103
|
+
const oldStateWithoutEvents = lodash_1.default.cloneDeep(oldState);
|
|
104
|
+
if (oldStateWithoutEvents['system']?.['events']) {
|
|
105
|
+
oldStateWithoutEvents['system']['events'] = [];
|
|
106
|
+
}
|
|
107
|
+
return [oldState, newState, diffPatcher.diff(oldStateWithoutEvents, newState)];
|
|
104
108
|
};
|
|
105
109
|
exports.decodeStorageDiff = decodeStorageDiff;
|
|
@@ -28,12 +28,14 @@ function objectToStorageItems(meta, storage) {
|
|
|
28
28
|
throw Error(`Cannot find storage ${storageName} in pallet ${sectionName}`);
|
|
29
29
|
if (storageEntry.meta.type.isPlain) {
|
|
30
30
|
const key = new types_1.StorageKey(meta.registry, [storageEntry]);
|
|
31
|
-
|
|
31
|
+
const type = storageEntry.meta.modifier.isOptional ? `Option<${key.outputType}>` : key.outputType;
|
|
32
|
+
storageItems.push([key.toHex(), storage ? meta.registry.createType(type, storage).toHex() : null]);
|
|
32
33
|
}
|
|
33
34
|
else {
|
|
34
35
|
for (const [keys, value] of storage) {
|
|
35
36
|
const key = new types_1.StorageKey(meta.registry, [storageEntry, keys]);
|
|
36
|
-
|
|
37
|
+
const type = storageEntry.meta.modifier.isOptional ? `Option<${key.outputType}>` : key.outputType;
|
|
38
|
+
storageItems.push([key.toHex(), value ? meta.registry.createType(type, value).toHex() : null]);
|
|
37
39
|
}
|
|
38
40
|
}
|
|
39
41
|
}
|
package/package.json
CHANGED
|
@@ -1,91 +1,68 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acala-network/chopsticks",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"main": "./
|
|
5
|
-
"types": "./
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"main": "./lib/index.js",
|
|
5
|
+
"types": "./lib/index.d.ts",
|
|
6
6
|
"author": "Bryan Chen <xlchen1291@gmail.com>",
|
|
7
7
|
"license": "Apache-2.0",
|
|
8
|
-
"packageManager": "yarn@3.2.4",
|
|
9
|
-
"workspaces": [
|
|
10
|
-
".",
|
|
11
|
-
"executor/pkg"
|
|
12
|
-
],
|
|
13
8
|
"bin": "./chopsticks.js",
|
|
14
9
|
"scripts": {
|
|
15
10
|
"lint": "tsc --noEmit --project tsconfig.json && eslint . --ext .js,.ts && prettier --check .",
|
|
16
11
|
"fix": "eslint . --ext .js,.ts --fix && prettier -w .",
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"dev": "
|
|
26
|
-
"dev:karura": "ts-node-dev --transpile-only --inspect --notify=false src/cli.ts -- dev --config=configs/karura.yml",
|
|
27
|
-
"dev:acala": "ts-node-dev --transpile-only --inspect --notify=false src/cli.ts -- dev --config=configs/acala.yml",
|
|
28
|
-
"dev:moonriver": "ts-node-dev --transpile-only --inspect --notify=false src/cli.ts -- dev --config=configs/moonriver.yml",
|
|
29
|
-
"dev:moonbeam": "ts-node-dev --transpile-only --inspect --notify=false src/cli.ts -- dev --config=configs/moonbeam.yml"
|
|
12
|
+
"build": "rm -rf lib && tsc -p ./tsconfig.json",
|
|
13
|
+
"test": "vitest run",
|
|
14
|
+
"test:watch": "vitest",
|
|
15
|
+
"script:start": "cd ../..; ts-node packages/chopsticks/src/cli.ts",
|
|
16
|
+
"script:run": "LOG_LEVEL=trace ts-node-dev --transpile-only --inspect --notify=false src/cli.ts -- dev --config=../../configs/dev.yml",
|
|
17
|
+
"dev:karura": "ts-node-dev --transpile-only --inspect --notify=false src/cli.ts -- dev --config=../../configs/karura.yml",
|
|
18
|
+
"dev:acala": "ts-node-dev --transpile-only --inspect --notify=false src/cli.ts -- dev --config=../../configs/acala.yml",
|
|
19
|
+
"dev:moonriver": "ts-node-dev --transpile-only --inspect --notify=false src/cli.ts -- dev --config=../../configs/moonriver.yml",
|
|
20
|
+
"dev:moonbeam": "ts-node-dev --transpile-only --inspect --notify=false src/cli.ts -- dev --config=../../configs/moonbeam.yml"
|
|
30
21
|
},
|
|
31
22
|
"dependencies": {
|
|
32
|
-
"@acala-network/chopsticks-executor": "0.
|
|
33
|
-
"@polkadot/api": "^9.
|
|
34
|
-
"@polkadot/rpc-provider": "^9.
|
|
35
|
-
"@polkadot/types": "^9.
|
|
36
|
-
"@polkadot/types-codec": "^9.
|
|
37
|
-
"@polkadot/types-known": "^9.
|
|
38
|
-
"@polkadot/util": "^10.2
|
|
39
|
-
"@polkadot/util-crypto": "^10.2
|
|
40
|
-
"axios": "^1.
|
|
23
|
+
"@acala-network/chopsticks-executor": "0.4.0",
|
|
24
|
+
"@polkadot/api": "^9.14.2",
|
|
25
|
+
"@polkadot/rpc-provider": "^9.14.2",
|
|
26
|
+
"@polkadot/types": "^9.14.2",
|
|
27
|
+
"@polkadot/types-codec": "^9.14.2",
|
|
28
|
+
"@polkadot/types-known": "^9.14.2",
|
|
29
|
+
"@polkadot/util": "^10.4.2",
|
|
30
|
+
"@polkadot/util-crypto": "^10.4.2",
|
|
31
|
+
"axios": "^1.3.3",
|
|
41
32
|
"js-yaml": "^4.1.0",
|
|
42
33
|
"jsondiffpatch": "^0.4.1",
|
|
43
34
|
"lodash": "^4.17.21",
|
|
44
|
-
"pino": "^8.
|
|
45
|
-
"pino-pretty": "^9.
|
|
35
|
+
"pino": "^8.10.0",
|
|
36
|
+
"pino-pretty": "^9.3.0",
|
|
46
37
|
"reflect-metadata": "^0.1.13",
|
|
47
38
|
"sqlite3": "^5.1.4",
|
|
48
|
-
"typeorm": "^0.3.
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"zod": "^3.20.2"
|
|
39
|
+
"typeorm": "^0.3.12",
|
|
40
|
+
"ws": "^8.12.1",
|
|
41
|
+
"yargs": "^17.7.1",
|
|
42
|
+
"zod": "^3.20.6"
|
|
53
43
|
},
|
|
54
44
|
"devDependencies": {
|
|
55
45
|
"@types/js-yaml": "^4.0.5",
|
|
56
46
|
"@types/lodash": "^4.14.191",
|
|
57
|
-
"@types/node": "^18.
|
|
47
|
+
"@types/node": "^18.14.0",
|
|
48
|
+
"@types/prettier": "^2.7.2",
|
|
58
49
|
"@types/ws": "^8.5.4",
|
|
59
|
-
"@types/yargs": "^17.0.
|
|
60
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
61
|
-
"@typescript-eslint/parser": "^5.
|
|
62
|
-
"eslint": "^8.
|
|
50
|
+
"@types/yargs": "^17.0.22",
|
|
51
|
+
"@typescript-eslint/eslint-plugin": "^5.53.0",
|
|
52
|
+
"@typescript-eslint/parser": "^5.53.0",
|
|
53
|
+
"eslint": "^8.34.0",
|
|
63
54
|
"eslint-config-prettier": "^8.6.0",
|
|
64
55
|
"eslint-plugin-import": "^2.27.5",
|
|
65
56
|
"eslint-plugin-sort-imports-es6-autofix": "^0.6.0",
|
|
66
|
-
"
|
|
67
|
-
"lint-staged": "^13.1.0",
|
|
68
|
-
"prettier": "^2.8.3",
|
|
57
|
+
"prettier": "^2.8.4",
|
|
69
58
|
"ts-node": "^10.9.1",
|
|
70
59
|
"ts-node-dev": "^2.0.0",
|
|
71
|
-
"
|
|
72
|
-
"
|
|
60
|
+
"typescript": "^4.9.5",
|
|
61
|
+
"vitest": "^0.28.5"
|
|
73
62
|
},
|
|
74
63
|
"files": [
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"
|
|
78
|
-
]
|
|
79
|
-
"engines": {
|
|
80
|
-
"node": ">=v14"
|
|
81
|
-
},
|
|
82
|
-
"prettier": {
|
|
83
|
-
"tabWidth": 2,
|
|
84
|
-
"semi": false,
|
|
85
|
-
"singleQuote": true
|
|
86
|
-
},
|
|
87
|
-
"lint-staged": {
|
|
88
|
-
"*.{js,ts}": "eslint --cache --fix",
|
|
89
|
-
"*.{js,ts,css,md}": "prettier --write"
|
|
90
|
-
}
|
|
64
|
+
"lib",
|
|
65
|
+
"template",
|
|
66
|
+
"chopsticks.js"
|
|
67
|
+
]
|
|
91
68
|
}
|
package/template/diff.html
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
div#app {
|
|
15
15
|
margin: 0 !important;
|
|
16
|
-
padding:
|
|
16
|
+
padding: 0 !important;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
.diff {
|
|
@@ -24,6 +24,36 @@
|
|
|
24
24
|
line-height: 150%;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
.diff > button {
|
|
28
|
+
position: absolute;
|
|
29
|
+
display: none;
|
|
30
|
+
left: 50%;
|
|
31
|
+
top: 50%;
|
|
32
|
+
translate: -50% -50%;
|
|
33
|
+
background: #fff;
|
|
34
|
+
border: none;
|
|
35
|
+
border-radius: 50%;
|
|
36
|
+
padding: 10px;
|
|
37
|
+
cursor: pointer;
|
|
38
|
+
cursor: pointer;
|
|
39
|
+
opacity: 80%;
|
|
40
|
+
width: 40px;
|
|
41
|
+
height: 40px;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.diff > button > img {
|
|
45
|
+
width: 100%;
|
|
46
|
+
height: 100%;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.diff > button:hover {
|
|
50
|
+
opacity: 100%;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.diff:hover > button {
|
|
54
|
+
display: block;
|
|
55
|
+
}
|
|
56
|
+
|
|
27
57
|
.diffWrap {
|
|
28
58
|
position: relative;
|
|
29
59
|
z-index: 1;
|
|
@@ -37,30 +67,36 @@
|
|
|
37
67
|
|
|
38
68
|
.diffAdd {
|
|
39
69
|
color: darkseagreen;
|
|
70
|
+
display: inline-flex;
|
|
40
71
|
}
|
|
41
72
|
|
|
42
73
|
.diffRemove {
|
|
43
74
|
text-decoration: line-through;
|
|
44
75
|
text-decoration-thickness: 1px;
|
|
45
76
|
color: red;
|
|
77
|
+
display: inline-flex;
|
|
46
78
|
}
|
|
47
79
|
|
|
48
80
|
.diffUpdateFrom {
|
|
49
81
|
text-decoration: line-through;
|
|
50
82
|
text-decoration-thickness: 1px;
|
|
51
83
|
color: red;
|
|
84
|
+
display: inline-flex;
|
|
52
85
|
}
|
|
53
86
|
|
|
54
87
|
.diffUpdateTo {
|
|
55
88
|
color: darkseagreen;
|
|
89
|
+
display: inline-flex;
|
|
56
90
|
}
|
|
57
91
|
|
|
58
92
|
.diffUpdateArrow {
|
|
59
93
|
color: #ccc;
|
|
60
94
|
}
|
|
95
|
+
|
|
61
96
|
.unchanged {
|
|
62
97
|
color: #666;
|
|
63
98
|
}
|
|
99
|
+
|
|
64
100
|
.delta {
|
|
65
101
|
color: #ccc;
|
|
66
102
|
font-size: 12px;
|
|
@@ -94,76 +130,82 @@
|
|
|
94
130
|
return { className: className.join(' ') }
|
|
95
131
|
}
|
|
96
132
|
|
|
97
|
-
function valueRenderer(
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
133
|
+
function valueRenderer(viewPartial) {
|
|
134
|
+
return function (raw, value, ...keys) {
|
|
135
|
+
const modifyPath = keys.reverse().join('.')
|
|
136
|
+
const removePath = keys.map(x => Number.isInteger(parseInt(x)) ? '_' + x : x).join('.')
|
|
137
|
+
const isDelta = _.has(delta, modifyPath) || _.has(delta, removePath)
|
|
101
138
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
139
|
+
function renderSpan(name, body, raw) {
|
|
140
|
+
return (
|
|
141
|
+
<span key={name} {...styling(['diff', name])}>
|
|
142
|
+
{body}
|
|
143
|
+
{_.isObjectLike(raw) ? <button onClick={() => viewPartial({ [modifyPath]: raw })}><img src='data:image/svg+xml;base64,PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KDTwhLS0gVXBsb2FkZWQgdG86IFNWRyBSZXBvLCB3d3cuc3ZncmVwby5jb20sIFRyYW5zZm9ybWVkIGJ5OiBTVkcgUmVwbyBNaXhlciBUb29scyAtLT4KPHN2ZyBmaWxsPSIjMDAwMDAwIiBoZWlnaHQ9IjY0cHgiIHdpZHRoPSI2NHB4IiB2ZXJzaW9uPSIxLjEiIGlkPSJMYXllcl8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMjQyLjEzMyAyNDIuMTMzIiB4bWw6c3BhY2U9InByZXNlcnZlIiBzdHJva2U9IiMwMDAwMDAiPgoNPGcgaWQ9IlNWR1JlcG9fYmdDYXJyaWVyIiBzdHJva2Utd2lkdGg9IjAiLz4KDTxnIGlkPSJTVkdSZXBvX3RyYWNlckNhcnJpZXIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgoNPGcgaWQ9IlNWR1JlcG9faWNvbkNhcnJpZXIiPiA8ZyBpZD0iWE1MSURfMjVfIj4gPHBhdGggaWQ9IlhNTElEXzI2XyIgZD0iTTg5LjI0NywxMzEuNjczbC00Ny43MzIsNDcuNzNsLTE1LjkwOS0xNS45MWMtNC4yOS00LjI5MS0xMC43NDItNS41NzItMTYuMzQ3LTMuMjUyIEMzLjY1NCwxNjIuNTYzLDAsMTY4LjAzMywwLDE3NC4xdjUzLjAzMmMwLDguMjg0LDYuNzE2LDE1LDE1LDE1bDUzLjAzMywwLjAwMWMwLjAwNy0wLjAwMSwwLjAxMi0wLjAwMSwwLjAxOSwwIGM4LjI4NSwwLDE1LTYuNzE2LDE1LTE1YzAtNC4zNzctMS44NzUtOC4zMTYtNC44NjUtMTEuMDU5bC0xNS40NTgtMTUuNDU4bDQ3LjczLTQ3LjcyOWM1Ljg1OC01Ljg1OCw1Ljg1OC0xNS4zNTUsMC0yMS4yMTMgQzEwNC42MDMsMTI1LjgxNSw5NS4xMDQsMTI1LjgxNiw4OS4yNDcsMTMxLjY3M3oiLz4gPHBhdGggaWQ9IlhNTElEXzI4XyIgZD0iTTIyNy4xMzMsMEgxNzQuMWMtNi4wNjcsMC0xMS41MzYsMy42NTUtMTMuODU4LDkuMjZjLTIuMzIxLDUuNjA1LTEuMDM4LDEyLjA1NywzLjI1MiwxNi4zNDdsMTUuOTExLDE1LjkxMSBsLTQ3LjcyOSw0Ny43M2MtNS44NTgsNS44NTgtNS44NTgsMTUuMzU1LDAsMjEuMjEzYzIuOTI5LDIuOTI5LDYuNzY4LDQuMzkzLDEwLjYwNiw0LjM5M2MzLjgzOSwwLDcuNjc4LTEuNDY0LDEwLjYwNi00LjM5NCBsNDcuNzMtNDcuNzNsMTUuOTA5LDE1LjkxYzIuODY5LDIuODcsNi43MDYsNC4zOTQsMTAuNjA5LDQuMzk0YzEuOTMzLDAsMy44ODItMC4zNzMsNS43MzctMS4xNDIgYzUuNjA1LTIuMzIyLDkuMjYtNy43OTIsOS4yNi0xMy44NThWMTVDMjQyLjEzMyw2LjcxNiwyMzUuNDE3LDAsMjI3LjEzMywweiIvPiA8L2c+IDwvZz4KDTwvc3ZnPg==' /></button> : null}
|
|
144
|
+
</span>
|
|
145
|
+
);
|
|
146
|
+
}
|
|
109
147
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
148
|
+
function renderDelta(value) {
|
|
149
|
+
if (/^\d+(,\d+)*$/.test(value[0]) && /^\d+(,\d+)*$/.test(value[1])) {
|
|
150
|
+
const oldValue = parseInt(value[0].replace(/,/g, ''))
|
|
151
|
+
const newValue = parseInt(value[1].replace(/,/g, ''))
|
|
152
|
+
if (oldValue > 0 && newValue > 0) {
|
|
153
|
+
const delta = Number(newValue - oldValue)
|
|
154
|
+
return (<span className="delta" >{delta > 0 ? '+' : ''}{delta.toLocaleString()}</span>)
|
|
155
|
+
}
|
|
117
156
|
}
|
|
118
157
|
}
|
|
119
|
-
}
|
|
120
158
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
+
if (isDelta && Array.isArray(value)) {
|
|
160
|
+
switch (value.length) {
|
|
161
|
+
case 0:
|
|
162
|
+
return (
|
|
163
|
+
<span {...styling('diffWrap')}>
|
|
164
|
+
{renderSpan('diff', '[]')}
|
|
165
|
+
</span>
|
|
166
|
+
)
|
|
167
|
+
case 1:
|
|
168
|
+
return (
|
|
169
|
+
<span {...styling('diffWrap')}>
|
|
170
|
+
{renderSpan(
|
|
171
|
+
'diffAdd',
|
|
172
|
+
stringifyAndShrink(value[0]),
|
|
173
|
+
value[0]
|
|
174
|
+
)}
|
|
175
|
+
</span>
|
|
176
|
+
);
|
|
177
|
+
case 2:
|
|
178
|
+
return (
|
|
179
|
+
<span {...styling('diffWrap')}>
|
|
180
|
+
{renderSpan(
|
|
181
|
+
'diffUpdateFrom',
|
|
182
|
+
stringifyAndShrink(value[0]),
|
|
183
|
+
value[0]
|
|
184
|
+
)}
|
|
185
|
+
{renderSpan('diffUpdateArrow', ' => ')}
|
|
186
|
+
{renderSpan(
|
|
187
|
+
'diffUpdateTo',
|
|
188
|
+
stringifyAndShrink(value[1]),
|
|
189
|
+
value[1]
|
|
190
|
+
)}
|
|
191
|
+
{renderDelta(value)}
|
|
192
|
+
</span>
|
|
193
|
+
);
|
|
194
|
+
case 3:
|
|
195
|
+
return (
|
|
196
|
+
<span {...styling('diffWrap')}>
|
|
197
|
+
{renderSpan('diffRemove', stringifyAndShrink(value[0]), value[0])}
|
|
198
|
+
</span>
|
|
199
|
+
);
|
|
200
|
+
}
|
|
159
201
|
}
|
|
160
|
-
}
|
|
161
202
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
203
|
+
return (
|
|
204
|
+
<span {...styling('diffWrap')}>
|
|
205
|
+
{renderSpan('unchanged', stringifyAndShrink(value), value)}
|
|
206
|
+
</span>
|
|
207
|
+
);
|
|
208
|
+
}
|
|
167
209
|
};
|
|
168
210
|
|
|
169
211
|
function prepareDelta(value) {
|
|
@@ -208,30 +250,49 @@
|
|
|
208
250
|
class App extends React.Component {
|
|
209
251
|
constructor(props) {
|
|
210
252
|
super(props);
|
|
211
|
-
this.state = { showUnchanged: false };
|
|
253
|
+
this.state = { showUnchanged: false, partial: null };
|
|
212
254
|
}
|
|
213
255
|
|
|
214
256
|
toggle = (e) => {
|
|
215
257
|
this.setState(state => {
|
|
216
|
-
return { showUnchanged: !state.showUnchanged }
|
|
258
|
+
return { ...state, showUnchanged: !state.showUnchanged }
|
|
259
|
+
})
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
viewPartial = (value) => {
|
|
263
|
+
this.setState(state => {
|
|
264
|
+
return { ...state, partial: _.isEqual(state.partial, value) ? null : value }
|
|
217
265
|
})
|
|
218
266
|
}
|
|
219
267
|
|
|
220
268
|
render() {
|
|
221
269
|
return (
|
|
222
270
|
<div>
|
|
223
|
-
<
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
271
|
+
<div style={{ display: 'flex', flexDirection: 'row' }}>
|
|
272
|
+
<div style={{ flex: 1, padding: '0 10px', overflow: 'hidden', overflowY: 'scroll', height: '100vh' }}>
|
|
273
|
+
<input type="checkbox" onChange={this.toggle} id="show_unchanged" />
|
|
274
|
+
<label for="show_unchanged" style={{ fontSize: '12px', color: 'white' }}>Show Unchanged</label>
|
|
275
|
+
<ReactJsonTree.JSONTree
|
|
276
|
+
theme={theme}
|
|
277
|
+
invertTheme={false}
|
|
278
|
+
data={this.state.showUnchanged ? _.merge(_.cloneDeep(left), delta) : delta}
|
|
279
|
+
valueRenderer={valueRenderer(this.viewPartial)}
|
|
280
|
+
postprocessValue={prepareDelta}
|
|
281
|
+
isCustomNode={Array.isArray}
|
|
282
|
+
shouldExpandNodeInitially={expandFirstLevel}
|
|
283
|
+
hideRoot
|
|
284
|
+
/>
|
|
285
|
+
</div>
|
|
286
|
+
{this.state.partial ? <div style={{ flex: 1, padding: '0 10px', overflow: 'hidden', overflowY: 'scroll', height: '100vh' }}>
|
|
287
|
+
<ReactJsonTree.JSONTree
|
|
288
|
+
theme={theme}
|
|
289
|
+
invertTheme={false}
|
|
290
|
+
data={this.state.partial}
|
|
291
|
+
shouldExpandNodeInitially={() => true}
|
|
292
|
+
hideRoot
|
|
293
|
+
/>
|
|
294
|
+
</div> : null}
|
|
295
|
+
</div>
|
|
235
296
|
</div>
|
|
236
297
|
);
|
|
237
298
|
}
|