Restructure the js app (#243)

* prettier

* linter

* add prettier, and format the code

* remove common, merge it with frontend

* refactor the app

* better lint and code fix

* travis for the frontend app

* travis build script

Signed-off-by: Daniel Maricic <daniel@woss.io>

* lint and build

* update the README.md

Signed-off-by: Daniel Maricic <daniel@woss.io>

* change the commands to reflect refactor

Signed-off-by: Daniel Maricic <daniel@woss.io>

* prettier and tslint are friends

Signed-off-by: Daniel Maricic <daniel@woss.io>

* code that wasn't linted properly before

Signed-off-by: Daniel Maricic <daniel@woss.io>

* prettier rc got deleted

* workgin on making the travis pass

Signed-off-by: Daniel Maricic <daniel@woss.io>

* travis build please?

Signed-off-by: Daniel Maricic <daniel@woss.io>

* update readme.md

Signed-off-by: Daniel Maricic <daniel@woss.io>

* dockerfile deleted from fronted - out of scope

Signed-off-by: Daniel Maricic <daniel@woss.io>

* remove

Signed-off-by: Daniel Maricic <daniel@woss.io>

* tsconfig

Signed-off-by: Daniel Maricic <daniel@woss.io>

* found the reason why EOL wasn't happening

Signed-off-by: Daniel Maricic <daniel@woss.io>

* type for the event in the ConnectionInput

as suggested

* strictnullCheck to true

* noImplicitAny

* noUnusedParams

* AfgHandling

* update

* fix Location.tsx

* Few minor fixes

* remove connection input and revert to original

* esnext fixes the imports for icons and non default `* as `

* update to the tsconfig.test.json don't use commonjs please

* fixed wrong comment for TIMEOUT_BASE

* return totem.svg and type decraration of maybe

Signed-off-by: Daniel Maricic <daniel@woss.io>

Co-authored-by: Will <w.kopp@kigroup.de>
This commit is contained in:
Daniel Maricic
2020-04-06 15:38:45 +02:00
committed by GitHub
parent 20a0283380
commit bb8e804567
322 changed files with 10896 additions and 10602 deletions
+5 -1
View File
@@ -1,4 +1,8 @@
[*.{js,ts,tsx,json,css}]
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true
+2 -2
View File
@@ -7,10 +7,10 @@ backend/target
node_modules
# testing
packages/*/coverage
coverage
# production
packages/*/build
build
# misc
.DS_Store
+4 -3
View File
@@ -30,6 +30,7 @@ before_script:
script:
- yarn
- yarn check:all
- yarn build:all
- cd backend && cargo test
- cd frontend && yarn
- yarn test
- yarn check
- yarn build
+21 -9
View File
@@ -1,16 +1,18 @@
# Polkadot Telemetry
## Getting Started
To run the backend, you will need `cargo` to build the binary. We recommend using [`rustup`](https://rustup.rs/).
To run the frontend make sure to grab the latest stable version of node and install dependencies before doing anything:
```
```sh
nvm install stable
yarn
```
### Terminal 1 - Backend
```
cd backend
cargo build --release
@@ -20,35 +22,45 @@ cargo build --release
By default, telemetry will listen on the local interface only (127.0.0.1) on port 8000. You may change both those values:
Use another port:
```
PORT=8123 telemetry
```
You may also change the the listening interface. This is especially required if you are using docker:
```
BIND=0.0.0.0 telemetry
```
### Terminal 2 - Frontend
```
yarn start:frontend
```sh
cd frontend
yarn
yarn start
```
### Terminal 3 - Node
Follow up installation instructions from the [Polkadot repo](https://github.com/paritytech/polkadot)
```
```sh
./target/release/polkadot --dev --telemetry-url ws://localhost:8000/submit
```
### Run via Docker
To run via docker make sure that you have Docker Desktop
- If you dont you can download for you OS here [Docker Desktop](https://www.docker.com/products/docker-desktop)
```
- If you dont you can download for you OS here [Docker Desktop](https://www.docker.com/products/docker-desktop)
```sh
docker-compose up --build -d
```
- -d stands for detach, if you would like to see logs i recommend using [Kitmatic](https://kitematic.com/) or dont use the -d
- --build will build the images and rebuild, but this is not required everytime
- If you want to makes UI changes, there is no need to rebuild the image as the files are being copied in via volumes.
- -d stands for detach, if you would like to see logs i recommend using [Kitmatic](https://kitematic.com/) or don't use the -d
- --build will build the images and rebuild, but this is not required every time
- If you want to makes UI changes, there is no need to rebuild the image as the files are being copied in via volumes.
Now navigate to localhost:3000 in your browser to view the app.
@@ -25,8 +25,8 @@
"blakejs": "^1.1.0",
"husky": "^4.2.3",
"lint-staged": "^10.1.0",
"react": "16.4.0",
"react-dom": "16.4.2",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-measure": "^2.3.0",
"react-scripts-ts": "2.17.0",
"react-svg": "^4.1.1",
@@ -56,10 +56,10 @@
"jest": "^23.6.0",
"jest-localstorage-mock": "^2.2.0",
"mock-socket": "^8.0.2",
"prettier": "^2.0.2",
"react-test-renderer": "^16.5.2",
"ts-jest": "^23.10.2",
"tslint-config-prettier": "^1.18.0",
"prettier": "^2.0.2",
"tslint-plugin-prettier": "^2.3.0",
"typescript": "^2.9.2"
},
@@ -68,4 +68,4 @@
"pretty:fix"
]
}
}
}
@@ -1,19 +1,19 @@
// Jdenticon 2.1.1 | jdenticon.com | MIT licensed | (c) 2014-2018 Daniel Mester Pirttijärvi
(function(q,y,z){var t=z(q,q.jQuery);"undefined"!==typeof module&&"exports"in module?module.exports=t:"function"===typeof define&&define.amd?define([],function(){return t}):q[y]=t})(this,"jdenticon",function(q,y){function z(a,b,c){for(var d=document.createElementNS("http://www.w3.org/2000/svg",b),f=2;f+1<arguments.length;f+=2)d.setAttribute(arguments[f],arguments[f+1]);a.appendChild(d)}function t(a){this.b=Math.min(Number(a.getAttribute("width"))||100,Number(a.getAttribute("height"))||100);for(this.a=
a;a.firstChild;)a.removeChild(a.firstChild);a.setAttribute("viewBox","0 0 "+this.b+" "+this.b);a.setAttribute("preserveAspectRatio","xMidYMid meet")}function K(a){this.b=a;this.a='\x3csvg xmlns\x3d"http://www.w3.org/2000/svg" width\x3d"'+a+'" height\x3d"'+a+'" viewBox\x3d"0 0 '+a+" "+a+'" preserveAspectRatio\x3d"xMidYMid meet"\x3e'}function N(a){return function(a){for(var b=[],d=0;d<a.length;d++)for(var f=a[d],e=28;0<=e;e-=4)b.push((f>>>e&15).toString(16));return b.join("")}(function(a){for(var b=
1732584193,d=4023233417,f=2562383102,e=271733878,h=3285377520,k=[b,d,f,e,h],g=0;g<a.length;g++){for(var u=a[g],l=16;80>l;l++){var A=u[l-3]^u[l-8]^u[l-14]^u[l-16];u[l]=A<<1|A>>>31}for(l=0;80>l;l++)A=(b<<5|b>>>27)+(20>l?(d&f^~d&e)+1518500249:40>l?(d^f^e)+1859775393:60>l?(d&f^d&e^f&e)+2400959708:(d^f^e)+3395469782)+h+u[l],h=e,e=f,f=d<<30|d>>>2,d=b,b=A|0;k[0]=b=k[0]+b|0;k[1]=d=k[1]+d|0;k[2]=f=k[2]+f|0;k[3]=e=k[3]+e|0;k[4]=h=k[4]+h|0}return k}(function(a){function b(a,b){for(var c=[],d=-1,e=0;e<b;e++)d=
e/4|0,c[d]=(c[d]||0)+(f[a+e]<<8*(3-(e&3)));for(;16>++d;)c[d]=0;return c}var d=encodeURI(a),f=[];a=0;var e,h=[];for(e=0;e<d.length;e++){if("%"==d[e]){var k=r(d,e+1,2);e+=2}else k=d.charCodeAt(e);f[a++]=k}f[a++]=128;for(e=0;e+64<=a;e+=64)h.push(b(e,64));d=a-e;e=b(e,d);64<d+8&&(h.push(e),e=b(0,0));e[15]=8*a-8;h.push(e);return h}(a)))}function E(a,b){var c=a.canvas.width,d=a.canvas.height;a.save();this.b=a;b?this.a=b:(this.a=Math.min(c,d),a.translate((c-this.a)/2|0,(d-this.a)/2|0));a.clearRect(0,0,this.a,
this.a)}function v(a){a|=0;return 0>a?"00":16>a?"0"+a.toString(16):256>a?a.toString(16):"ff"}function F(a,b,c){c=0>c?c+6:6<c?c-6:c;return v(255*(1>c?a+(b-a)*c:3>c?b:4>c?a+(b-a)*(4-c):a))}function O(a){"undefined"!=typeof MutationObserver&&(new MutationObserver(function(b){for(var c=0;c<b.length;c++){for(var d=b[c],f=d.addedNodes,e=0;f&&e<f.length;e++){var h=f[e];if(1==h.nodeType)if(g.w(h))a(h);else{h=h.querySelectorAll(g.A);for(var k=0;k<h.length;k++)a(h[k])}}"attributes"==d.type&&g.w(d.target)&&
a(d.target)}})).observe(document.body,{childList:!0,attributes:!0,attributeFilter:[g.o,g.s,"width","height"],subtree:!0})}function r(a,b,c){return parseInt(a.substr(b,c),16)}function p(a){return(10*a+.5|0)/10}function L(){this.j=""}function G(a){this.b={};this.h=a;this.a=a.b}function M(a){this.h=a;this.c=w.a}function P(a,b){a=b.O(a);return[m.i(a,b.H,b.G(0)),m.i(a,b.v,b.u(.5)),m.i(a,b.H,b.G(1)),m.i(a,b.v,b.u(1)),m.i(a,b.v,b.u(0))]}function B(a,b){this.x=a;this.y=b}function w(a,b,c,d){this.b=a;this.c=
b;this.h=c;this.a=d}function H(a,b,c,d,f,e,h){function k(e,f,k,h,g){h=h?r(b,h,1):0;f=f[r(b,k,1)%f.length];a.D(p[n[e]]);for(e=0;e<g.length;e++)m.c=new w(c+g[e][0]*l,d+g[e][1]*l,l,h++%4),f(m,l,e);a.F()}function g(a){if(0<=a.indexOf(q))for(var b=0;b<a.length;b++)if(0<=n.indexOf(a[b]))return!0}h.C&&a.m(h.C);e=.5+f*(void 0===e?.08:e)|0;f-=2*e;var m=new M(a),l=0|f/4;c+=0|e+f/2-2*l;d+=0|e+f/2-2*l;var p=P(r(b,-7)/268435455,h),n=[];for(f=0;3>f;f++){var q=r(b,8+f,1)%p.length;if(g([0,4])||g([2,3]))q=1;n.push(q)}k(0,
I.I,2,3,[[1,0],[2,0],[2,3],[1,3],[0,1],[3,1],[3,2],[0,2]]);k(1,I.I,4,5,[[0,0],[3,0],[3,3],[0,3]]);k(2,I.M,1,null,[[1,1],[2,1],[2,2],[1,2]]);a.finish()}function J(){function a(a,b){var d=c[a];d&&1<d.length||(d=b);return function(a){a=d[0]+a*(d[1]-d[0]);return 0>a?0:1<a?1:a}}var b=n.config||q.jdenticon_config||{},c=b.lightness||{},d=b.saturation||{},f="color"in d?d.color:d;d=d.grayscale;return{O:function(a){var c=b.hues,d;c&&0<c.length&&(d=c[0|.999*a*c.length]);return"number"==typeof d?(d/360%1+1)%
1:a},v:"number"==typeof f?f:.5,H:"number"==typeof d?d:0,u:a("color",[.4,.8]),G:a("grayscale",[.3,.9]),C:m.parse(b.backColor)}}function C(a){return/^[0-9a-f]{11,}$/i.test(a)&&a}function D(a){return N(null==a?"":""+a)}function x(a,b,c){if("string"===typeof a){if(g.J){a=document.querySelectorAll(a);for(var d=0;d<a.length;d++)x(a[d],b,c)}}else if(d=g.w(a))if(b=C(b)||null!=b&&D(b)||C(a.getAttribute(g.s))||a.hasAttribute(g.o)&&D(a.getAttribute(g.o)))a=d==g.B?new G(new t(a)):new E(a.getContext("2d")),H(a,
b,0,0,a.a,c,J())}function n(){g.J&&x(g.A)}function Q(){var a=(n.config||q.jdenticon_config||{}).replaceMode;"never"!=a&&(n(),"observe"==a&&O(x))}t.prototype={m:function(a,b){b&&z(this.a,"rect","width","100%","height","100%","fill",a,"opacity",b)},c:function(a,b){z(this.a,"path","fill",a,"d",b)}};K.prototype={m:function(a,b){b&&(this.a+='\x3crect width\x3d"100%" height\x3d"100%" fill\x3d"'+a+'" opacity\x3d"'+b.toFixed(2)+'"/\x3e')},c:function(a,b){this.a+='\x3cpath fill\x3d"'+a+'" d\x3d"'+b+'"/\x3e'},
toString:function(){return this.a+"\x3c/svg\x3e"}};var g={B:1,L:2,s:"data-jdenticon-hash",o:"data-jdenticon-value",J:"undefined"!==typeof document&&"querySelectorAll"in document,w:function(a){if(a){var b=a.tagName;if(/svg/i.test(b))return g.B;if(/canvas/i.test(b)&&"getContext"in a)return g.L}}};g.A="["+g.s+"],["+g.o+"]";E.prototype={m:function(a){var b=this.b,c=this.a;b.fillStyle=m.K(a);b.fillRect(0,0,c,c)},D:function(a){this.b.fillStyle=m.K(a);this.b.beginPath()},F:function(){this.b.fill()},f:function(a){var b=
this.b,c;b.moveTo(a[0].x,a[0].y);for(c=1;c<a.length;c++)b.lineTo(a[c].x,a[c].y);b.closePath()},g:function(a,b,c){var d=this.b;b/=2;d.moveTo(a.x+b,a.y+b);d.arc(a.x+b,a.y+b,b,0,2*Math.PI,c);d.closePath()},finish:function(){this.b.restore()}};var m={P:function(a,b,c){return"#"+v(a)+v(b)+v(c)},parse:function(a){if(/^#[0-9a-f]{3,8}$/i.test(a)){if(6>a.length){var b=a[1],c=a[2],d=a[3];a=a[4]||"";return"#"+b+b+c+c+d+d+a+a}if(7==a.length||8<a.length)return a}},K:function(a){var b=r(a,7,2);return isNaN(b)?
a:"rgba("+r(a,1,2)+","+r(a,3,2)+","+r(a,5,2)+","+(b/255).toFixed(2)+")"},N:function(a,b,c){if(0==b)return a=v(255*c),"#"+a+a+a;b=.5>=c?c*(b+1):c+b-c*b;c=2*c-b;return"#"+F(c,b,6*a+2)+F(c,b,6*a)+F(c,b,6*a-2)},i:function(a,b,c){var d=[.55,.5,.5,.46,.6,.55,.55][6*a+.5|0];return m.N(a,b,.5>c?c*d*2:d+(c-.5)*(1-d)*2)}},I={M:[function(a,b){var c=.42*b;a.f([0,0,b,0,b,b-2*c,b-c,b,0,b])},function(a,b){var c=0|.5*b;a.b(b-c,0,c,0|.8*b,2)},function(a,b){var c=0|b/3;a.a(c,c,b-c,b-c)},function(a,b){var c=.1*b,d=
6>b?1:8>b?2:0|.25*b;c=1<c?0|c:.5<c?1:c;a.a(d,d,b-c-d,b-c-d)},function(a,b){var c=0|.15*b,d=0|.5*b;a.g(b-d-c,b-d-c,d)},function(a,b){var c=.1*b,d=4*c;3<d&&(d|=0);a.a(0,0,b,b);a.f([d,d,b-c,d,d+(b-d-c)/2,b-c],!0)},function(a,b){a.f([0,0,b,0,b,.7*b,.4*b,.4*b,.7*b,b,0,b])},function(a,b){a.b(b/2,b/2,b/2,b/2,3)},function(a,b){a.a(0,0,b,b/2);a.a(0,b/2,b/2,b/2);a.b(b/2,b/2,b/2,b/2,1)},function(a,b){var c=.14*b,d=4>b?1:6>b?2:0|.35*b;c=8>b?c:0|c;a.a(0,0,b,b);a.a(d,d,b-d-c,b-d-c,!0)},function(a,b){var c=.12*
b,d=3*c;a.a(0,0,b,b);a.g(d,d,b-c-d,!0)},function(a,b){a.b(b/2,b/2,b/2,b/2,3)},function(a,b){var c=.25*b;a.a(0,0,b,b);a.l(c,c,b-c,b-c,!0)},function(a,b,c){var d=.4*b;c||a.g(d,d,1.2*b)}],I:[function(a,b){a.b(0,0,b,b,0)},function(a,b){a.b(0,b/2,b,b/2,0)},function(a,b){a.l(0,0,b,b)},function(a,b){var c=b/6;a.g(c,c,b-2*c)}]};L.prototype={f:function(a){for(var b="M"+p(a[0].x)+" "+p(a[0].y),c=1;c<a.length;c++)b+="L"+p(a[c].x)+" "+p(a[c].y);this.j+=b+"Z"},g:function(a,b,c){c=c?0:1;var d=p(b/2),f=p(b);this.j+=
"M"+p(a.x)+" "+p(a.y+b/2)+"a"+d+","+d+" 0 1,"+c+" "+f+",0a"+d+","+d+" 0 1,"+c+" "+-f+",0"}};G.prototype={m:function(a){a=/^(#......)(..)?/.exec(a);this.h.m(a[1],a[2]?r(a[2],0)/255:1)},D:function(a){this.c=this.b[a]||(this.b[a]=new L)},F:function(){},f:function(a){this.c.f(a)},g:function(a,b,c){this.c.g(a,b,c)},finish:function(){for(var a in this.b)this.h.c(a,this.b[a].j)}};M.prototype={f:function(a,b){var c=b?-2:2,d=this.c,f=[];for(b=b?a.length-2:0;b<a.length&&0<=b;b+=c)f.push(d.l(a[b],a[b+1]));this.h.f(f)},
g:function(a,b,c,d){this.h.g(this.c.l(a,b,c,c),c,d)},a:function(a,b,c,d,f){this.f([a,b,a+c,b,a+c,b+d,a,b+d],f)},b:function(a,b,c,d,f,e){a=[a+c,b,a+c,b+d,a,b+d,a,b];a.splice((f||0)%4*2,2);this.f(a,e)},l:function(a,b,c,d,f){this.f([a+c/2,b,a+c,b+d/2,a+c/2,b+d,a,b+d/2],f)}};w.prototype={l:function(a,b,c,d){var f=this.b+this.h,e=this.c+this.h;return 1===this.a?new B(f-b-(d||0),this.c+a):2===this.a?new B(f-a-(c||0),e-b-(d||0)):3===this.a?new B(this.b+b,e-a-(c||0)):new B(this.b+a,this.c+b)}};w.a=new w(0,
0,0,0);n.drawIcon=function(a,b,c,d){if(!a)throw Error("No canvas specified.");a=new E(a,c);H(a,C(b)||D(b),0,0,c,d||0,J())};n.toSvg=function(a,b,c){var d=new K(b);H(new G(d),C(a)||D(a),0,0,b,c,J());return d.toString()};n.update=x;n.version="2.1.1";y&&(y.fn.jdenticon=function(a,b){this.each(function(c,d){x(d,a,b)});return this});"function"===typeof setTimeout&&setTimeout(Q,0);return n});
// Jdenticon 2.1.1 | jdenticon.com | MIT licensed | (c) 2014-2018 Daniel Mester Pirttijärvi
(function(q,y,z){var t=z(q,q.jQuery);"undefined"!==typeof module&&"exports"in module?module.exports=t:"function"===typeof define&&define.amd?define([],function(){return t}):q[y]=t})(this,"jdenticon",function(q,y){function z(a,b,c){for(var d=document.createElementNS("http://www.w3.org/2000/svg",b),f=2;f+1<arguments.length;f+=2)d.setAttribute(arguments[f],arguments[f+1]);a.appendChild(d)}function t(a){this.b=Math.min(Number(a.getAttribute("width"))||100,Number(a.getAttribute("height"))||100);for(this.a=
a;a.firstChild;)a.removeChild(a.firstChild);a.setAttribute("viewBox","0 0 "+this.b+" "+this.b);a.setAttribute("preserveAspectRatio","xMidYMid meet")}function K(a){this.b=a;this.a='\x3csvg xmlns\x3d"http://www.w3.org/2000/svg" width\x3d"'+a+'" height\x3d"'+a+'" viewBox\x3d"0 0 '+a+" "+a+'" preserveAspectRatio\x3d"xMidYMid meet"\x3e'}function N(a){return function(a){for(var b=[],d=0;d<a.length;d++)for(var f=a[d],e=28;0<=e;e-=4)b.push((f>>>e&15).toString(16));return b.join("")}(function(a){for(var b=
1732584193,d=4023233417,f=2562383102,e=271733878,h=3285377520,k=[b,d,f,e,h],g=0;g<a.length;g++){for(var u=a[g],l=16;80>l;l++){var A=u[l-3]^u[l-8]^u[l-14]^u[l-16];u[l]=A<<1|A>>>31}for(l=0;80>l;l++)A=(b<<5|b>>>27)+(20>l?(d&f^~d&e)+1518500249:40>l?(d^f^e)+1859775393:60>l?(d&f^d&e^f&e)+2400959708:(d^f^e)+3395469782)+h+u[l],h=e,e=f,f=d<<30|d>>>2,d=b,b=A|0;k[0]=b=k[0]+b|0;k[1]=d=k[1]+d|0;k[2]=f=k[2]+f|0;k[3]=e=k[3]+e|0;k[4]=h=k[4]+h|0}return k}(function(a){function b(a,b){for(var c=[],d=-1,e=0;e<b;e++)d=
e/4|0,c[d]=(c[d]||0)+(f[a+e]<<8*(3-(e&3)));for(;16>++d;)c[d]=0;return c}var d=encodeURI(a),f=[];a=0;var e,h=[];for(e=0;e<d.length;e++){if("%"==d[e]){var k=r(d,e+1,2);e+=2}else k=d.charCodeAt(e);f[a++]=k}f[a++]=128;for(e=0;e+64<=a;e+=64)h.push(b(e,64));d=a-e;e=b(e,d);64<d+8&&(h.push(e),e=b(0,0));e[15]=8*a-8;h.push(e);return h}(a)))}function E(a,b){var c=a.canvas.width,d=a.canvas.height;a.save();this.b=a;b?this.a=b:(this.a=Math.min(c,d),a.translate((c-this.a)/2|0,(d-this.a)/2|0));a.clearRect(0,0,this.a,
this.a)}function v(a){a|=0;return 0>a?"00":16>a?"0"+a.toString(16):256>a?a.toString(16):"ff"}function F(a,b,c){c=0>c?c+6:6<c?c-6:c;return v(255*(1>c?a+(b-a)*c:3>c?b:4>c?a+(b-a)*(4-c):a))}function O(a){"undefined"!=typeof MutationObserver&&(new MutationObserver(function(b){for(var c=0;c<b.length;c++){for(var d=b[c],f=d.addedNodes,e=0;f&&e<f.length;e++){var h=f[e];if(1==h.nodeType)if(g.w(h))a(h);else{h=h.querySelectorAll(g.A);for(var k=0;k<h.length;k++)a(h[k])}}"attributes"==d.type&&g.w(d.target)&&
a(d.target)}})).observe(document.body,{childList:!0,attributes:!0,attributeFilter:[g.o,g.s,"width","height"],subtree:!0})}function r(a,b,c){return parseInt(a.substr(b,c),16)}function p(a){return(10*a+.5|0)/10}function L(){this.j=""}function G(a){this.b={};this.h=a;this.a=a.b}function M(a){this.h=a;this.c=w.a}function P(a,b){a=b.O(a);return[m.i(a,b.H,b.G(0)),m.i(a,b.v,b.u(.5)),m.i(a,b.H,b.G(1)),m.i(a,b.v,b.u(1)),m.i(a,b.v,b.u(0))]}function B(a,b){this.x=a;this.y=b}function w(a,b,c,d){this.b=a;this.c=
b;this.h=c;this.a=d}function H(a,b,c,d,f,e,h){function k(e,f,k,h,g){h=h?r(b,h,1):0;f=f[r(b,k,1)%f.length];a.D(p[n[e]]);for(e=0;e<g.length;e++)m.c=new w(c+g[e][0]*l,d+g[e][1]*l,l,h++%4),f(m,l,e);a.F()}function g(a){if(0<=a.indexOf(q))for(var b=0;b<a.length;b++)if(0<=n.indexOf(a[b]))return!0}h.C&&a.m(h.C);e=.5+f*(void 0===e?.08:e)|0;f-=2*e;var m=new M(a),l=0|f/4;c+=0|e+f/2-2*l;d+=0|e+f/2-2*l;var p=P(r(b,-7)/268435455,h),n=[];for(f=0;3>f;f++){var q=r(b,8+f,1)%p.length;if(g([0,4])||g([2,3]))q=1;n.push(q)}k(0,
I.I,2,3,[[1,0],[2,0],[2,3],[1,3],[0,1],[3,1],[3,2],[0,2]]);k(1,I.I,4,5,[[0,0],[3,0],[3,3],[0,3]]);k(2,I.M,1,null,[[1,1],[2,1],[2,2],[1,2]]);a.finish()}function J(){function a(a,b){var d=c[a];d&&1<d.length||(d=b);return function(a){a=d[0]+a*(d[1]-d[0]);return 0>a?0:1<a?1:a}}var b=n.config||q.jdenticon_config||{},c=b.lightness||{},d=b.saturation||{},f="color"in d?d.color:d;d=d.grayscale;return{O:function(a){var c=b.hues,d;c&&0<c.length&&(d=c[0|.999*a*c.length]);return"number"==typeof d?(d/360%1+1)%
1:a},v:"number"==typeof f?f:.5,H:"number"==typeof d?d:0,u:a("color",[.4,.8]),G:a("grayscale",[.3,.9]),C:m.parse(b.backColor)}}function C(a){return/^[0-9a-f]{11,}$/i.test(a)&&a}function D(a){return N(null==a?"":""+a)}function x(a,b,c){if("string"===typeof a){if(g.J){a=document.querySelectorAll(a);for(var d=0;d<a.length;d++)x(a[d],b,c)}}else if(d=g.w(a))if(b=C(b)||null!=b&&D(b)||C(a.getAttribute(g.s))||a.hasAttribute(g.o)&&D(a.getAttribute(g.o)))a=d==g.B?new G(new t(a)):new E(a.getContext("2d")),H(a,
b,0,0,a.a,c,J())}function n(){g.J&&x(g.A)}function Q(){var a=(n.config||q.jdenticon_config||{}).replaceMode;"never"!=a&&(n(),"observe"==a&&O(x))}t.prototype={m:function(a,b){b&&z(this.a,"rect","width","100%","height","100%","fill",a,"opacity",b)},c:function(a,b){z(this.a,"path","fill",a,"d",b)}};K.prototype={m:function(a,b){b&&(this.a+='\x3crect width\x3d"100%" height\x3d"100%" fill\x3d"'+a+'" opacity\x3d"'+b.toFixed(2)+'"/\x3e')},c:function(a,b){this.a+='\x3cpath fill\x3d"'+a+'" d\x3d"'+b+'"/\x3e'},
toString:function(){return this.a+"\x3c/svg\x3e"}};var g={B:1,L:2,s:"data-jdenticon-hash",o:"data-jdenticon-value",J:"undefined"!==typeof document&&"querySelectorAll"in document,w:function(a){if(a){var b=a.tagName;if(/svg/i.test(b))return g.B;if(/canvas/i.test(b)&&"getContext"in a)return g.L}}};g.A="["+g.s+"],["+g.o+"]";E.prototype={m:function(a){var b=this.b,c=this.a;b.fillStyle=m.K(a);b.fillRect(0,0,c,c)},D:function(a){this.b.fillStyle=m.K(a);this.b.beginPath()},F:function(){this.b.fill()},f:function(a){var b=
this.b,c;b.moveTo(a[0].x,a[0].y);for(c=1;c<a.length;c++)b.lineTo(a[c].x,a[c].y);b.closePath()},g:function(a,b,c){var d=this.b;b/=2;d.moveTo(a.x+b,a.y+b);d.arc(a.x+b,a.y+b,b,0,2*Math.PI,c);d.closePath()},finish:function(){this.b.restore()}};var m={P:function(a,b,c){return"#"+v(a)+v(b)+v(c)},parse:function(a){if(/^#[0-9a-f]{3,8}$/i.test(a)){if(6>a.length){var b=a[1],c=a[2],d=a[3];a=a[4]||"";return"#"+b+b+c+c+d+d+a+a}if(7==a.length||8<a.length)return a}},K:function(a){var b=r(a,7,2);return isNaN(b)?
a:"rgba("+r(a,1,2)+","+r(a,3,2)+","+r(a,5,2)+","+(b/255).toFixed(2)+")"},N:function(a,b,c){if(0==b)return a=v(255*c),"#"+a+a+a;b=.5>=c?c*(b+1):c+b-c*b;c=2*c-b;return"#"+F(c,b,6*a+2)+F(c,b,6*a)+F(c,b,6*a-2)},i:function(a,b,c){var d=[.55,.5,.5,.46,.6,.55,.55][6*a+.5|0];return m.N(a,b,.5>c?c*d*2:d+(c-.5)*(1-d)*2)}},I={M:[function(a,b){var c=.42*b;a.f([0,0,b,0,b,b-2*c,b-c,b,0,b])},function(a,b){var c=0|.5*b;a.b(b-c,0,c,0|.8*b,2)},function(a,b){var c=0|b/3;a.a(c,c,b-c,b-c)},function(a,b){var c=.1*b,d=
6>b?1:8>b?2:0|.25*b;c=1<c?0|c:.5<c?1:c;a.a(d,d,b-c-d,b-c-d)},function(a,b){var c=0|.15*b,d=0|.5*b;a.g(b-d-c,b-d-c,d)},function(a,b){var c=.1*b,d=4*c;3<d&&(d|=0);a.a(0,0,b,b);a.f([d,d,b-c,d,d+(b-d-c)/2,b-c],!0)},function(a,b){a.f([0,0,b,0,b,.7*b,.4*b,.4*b,.7*b,b,0,b])},function(a,b){a.b(b/2,b/2,b/2,b/2,3)},function(a,b){a.a(0,0,b,b/2);a.a(0,b/2,b/2,b/2);a.b(b/2,b/2,b/2,b/2,1)},function(a,b){var c=.14*b,d=4>b?1:6>b?2:0|.35*b;c=8>b?c:0|c;a.a(0,0,b,b);a.a(d,d,b-d-c,b-d-c,!0)},function(a,b){var c=.12*
b,d=3*c;a.a(0,0,b,b);a.g(d,d,b-c-d,!0)},function(a,b){a.b(b/2,b/2,b/2,b/2,3)},function(a,b){var c=.25*b;a.a(0,0,b,b);a.l(c,c,b-c,b-c,!0)},function(a,b,c){var d=.4*b;c||a.g(d,d,1.2*b)}],I:[function(a,b){a.b(0,0,b,b,0)},function(a,b){a.b(0,b/2,b,b/2,0)},function(a,b){a.l(0,0,b,b)},function(a,b){var c=b/6;a.g(c,c,b-2*c)}]};L.prototype={f:function(a){for(var b="M"+p(a[0].x)+" "+p(a[0].y),c=1;c<a.length;c++)b+="L"+p(a[c].x)+" "+p(a[c].y);this.j+=b+"Z"},g:function(a,b,c){c=c?0:1;var d=p(b/2),f=p(b);this.j+=
"M"+p(a.x)+" "+p(a.y+b/2)+"a"+d+","+d+" 0 1,"+c+" "+f+",0a"+d+","+d+" 0 1,"+c+" "+-f+",0"}};G.prototype={m:function(a){a=/^(#......)(..)?/.exec(a);this.h.m(a[1],a[2]?r(a[2],0)/255:1)},D:function(a){this.c=this.b[a]||(this.b[a]=new L)},F:function(){},f:function(a){this.c.f(a)},g:function(a,b,c){this.c.g(a,b,c)},finish:function(){for(var a in this.b)this.h.c(a,this.b[a].j)}};M.prototype={f:function(a,b){var c=b?-2:2,d=this.c,f=[];for(b=b?a.length-2:0;b<a.length&&0<=b;b+=c)f.push(d.l(a[b],a[b+1]));this.h.f(f)},
g:function(a,b,c,d){this.h.g(this.c.l(a,b,c,c),c,d)},a:function(a,b,c,d,f){this.f([a,b,a+c,b,a+c,b+d,a,b+d],f)},b:function(a,b,c,d,f,e){a=[a+c,b,a+c,b+d,a,b+d,a,b];a.splice((f||0)%4*2,2);this.f(a,e)},l:function(a,b,c,d,f){this.f([a+c/2,b,a+c,b+d/2,a+c/2,b+d,a,b+d/2],f)}};w.prototype={l:function(a,b,c,d){var f=this.b+this.h,e=this.c+this.h;return 1===this.a?new B(f-b-(d||0),this.c+a):2===this.a?new B(f-a-(c||0),e-b-(d||0)):3===this.a?new B(this.b+b,e-a-(c||0)):new B(this.b+a,this.c+b)}};w.a=new w(0,
0,0,0);n.drawIcon=function(a,b,c,d){if(!a)throw Error("No canvas specified.");a=new E(a,c);H(a,C(b)||D(b),0,0,c,d||0,J())};n.toSvg=function(a,b,c){var d=new K(b);H(new G(d),C(a)||D(a),0,0,b,c,J());return d.toString()};n.update=x;n.version="2.1.1";y&&(y.fn.jdenticon=function(a,b){this.each(function(c,d){x(d,a,b)});return this});"function"===typeof setTimeout&&setTimeout(Q,0);return n});
@@ -1,4 +1,4 @@
import { Types } from '@dotstats/common';
import { Types } from './common';
import { State, UpdateBound } from './state';
// Number of blocks which are kept in memory
@@ -21,7 +21,7 @@ export class AfgHandling {
this.getState().authoritySetId != null &&
authoritySetId !== this.getState().authoritySetId
) {
// the visualization is restarted when we receive a new auhority set
// the visualization is restarted when we receive a new authority set
this.updateState({
authoritySetId,
authorities,
@@ -113,7 +113,6 @@ export class AfgHandling {
public receivedPre(
addr: Types.Address,
height: Types.BlockNumber,
hash: Types.BlockHash,
voter: Types.Address,
what: string
) {
@@ -136,7 +135,7 @@ export class AfgHandling {
// a vote on all preceding blocks. This function marks
// the preceding blocks as implicitly voted on and stores
// a pointer to the block which contains the explicit vote.
const op = (i: Types.BlockNumber, index: number): boolean => {
const op = (index: number): boolean => {
const consensusDetail = state.consensusInfo[index][1][addr][voter];
if (
what === 'prevote' &&
@@ -192,7 +191,7 @@ export class AfgHandling {
const item: Types.ConsensusItem = [height, consensusView];
const insertPos = consensusInfo.findIndex(
([elHeight, elView]) => elHeight < height
([elHeight]) => elHeight < height
);
if (insertPos >= 0) {
consensusInfo.splice(insertPos, 0, item);
@@ -6,8 +6,8 @@
.App-no-telemetry {
width: 100vw;
height: 100vh;
line-height: 80vh;
/* height: 100vh; */
/* line-height: 80vh; */
font-size: 56px;
font-weight: 100;
text-align: center;
@@ -1,5 +1,5 @@
import * as React from 'react';
import { Types, SortedCollection, Maybe, Compare } from '@dotstats/common';
import { Types, SortedCollection, Maybe, Compare } from './common';
import { AllChains, Chains, Chain, Ago, OfflineIndicator } from './components';
import { Row, Column } from './components/List';
import { Connection } from './Connection';
@@ -189,7 +189,7 @@ export default class App extends React.Component<{}, State> {
});
};
private onHashChange = (event: Event) => {
private onHashChange = () => {
const { tab = '' } = getHashData();
this.setState({ tab });
@@ -1,11 +1,4 @@
import {
VERSION,
timestamp,
FeedMessage,
Types,
Maybe,
sleep,
} from '@dotstats/common';
import { VERSION, timestamp, FeedMessage, Types, Maybe, sleep } from './common';
import {
State,
Update,
@@ -17,10 +10,9 @@ import {
import { PersistentSet } from './persist';
import { getHashData, setHashData } from './utils';
import { AfgHandling } from './AfgHandling';
import { VIS_AUTHORITIES_LIMIT } from '../../frontend/src/components/Consensus';
import { VIS_AUTHORITIES_LIMIT } from './components/Consensus';
import { Column } from './components/List';
const { Actions } = FeedMessage;
import { ACTIONS } from './common/feed';
const TIMEOUT_BASE = (1000 * 5) as Types.Milliseconds; // 5 seconds
const TIMEOUT_MAX = (1000 * 60 * 5) as Types.Milliseconds; // 5 minutes
@@ -40,8 +32,6 @@ export class Connection {
? `wss://${window.location.hostname}/feed/`
: `ws://127.0.0.1:8000/feed`;
// private static readonly address = 'wss://telemetry.polkadot.io/feed/';
private static async socket(): Promise<WebSocket> {
let socket = await Connection.trySocket();
let timeout = TIMEOUT_BASE;
@@ -158,7 +148,7 @@ export class Connection {
for (const message of messages) {
switch (message.action) {
case Actions.FeedVersion: {
case ACTIONS.FeedVersion: {
if (message.payload !== VERSION) {
this.state = this.update({ status: 'upgrade-requested' });
this.clean();
@@ -172,7 +162,7 @@ export class Connection {
break;
}
case Actions.BestBlock: {
case ACTIONS.BestBlock: {
const [best, blockTimestamp, blockAverage] = message.payload;
nodes.mutEach((node) => node.newBestBlock());
@@ -182,7 +172,7 @@ export class Connection {
break;
}
case Actions.BestFinalized: {
case ACTIONS.BestFinalized: {
const [finalized /*, hash */] = message.payload;
this.state = this.update({ finalized });
@@ -190,7 +180,7 @@ export class Connection {
break;
}
case Actions.AddedNode: {
case ACTIONS.AddedNode: {
const [
id,
nodeDetails,
@@ -219,7 +209,7 @@ export class Connection {
break;
}
case Actions.RemovedNode: {
case ACTIONS.RemovedNode: {
const id = message.payload;
nodes.remove(id);
@@ -227,7 +217,7 @@ export class Connection {
break;
}
case Actions.StaleNode: {
case ACTIONS.StaleNode: {
const id = message.payload;
nodes.mutAndSort(id, (node) => node.setStale(true));
@@ -235,7 +225,7 @@ export class Connection {
break;
}
case Actions.LocatedNode: {
case ACTIONS.LocatedNode: {
const [id, lat, lon, city] = message.payload;
nodes.mutAndMaybeSort(
@@ -247,7 +237,7 @@ export class Connection {
break;
}
case Actions.ImportedBlock: {
case ACTIONS.ImportedBlock: {
const [id, blockDetails] = message.payload;
nodes.mutAndSort(id, (node) => node.updateBlock(blockDetails));
@@ -255,7 +245,7 @@ export class Connection {
break;
}
case Actions.FinalizedBlock: {
case ACTIONS.FinalizedBlock: {
const [id, height, hash] = message.payload;
nodes.mutAndMaybeSort(
@@ -268,7 +258,7 @@ export class Connection {
break;
}
case Actions.NodeStats: {
case ACTIONS.NodeStats: {
const [id, nodeStats] = message.payload;
nodes.mutAndMaybeSort(
@@ -280,7 +270,7 @@ export class Connection {
break;
}
case Actions.NodeHardware: {
case ACTIONS.NodeHardware: {
const [id, nodeHardware] = message.payload;
nodes.mutAndMaybeSort(
@@ -295,7 +285,7 @@ export class Connection {
break;
}
case Actions.NodeIO: {
case ACTIONS.NodeIO: {
const [id, nodeIO] = message.payload;
nodes.mutAndMaybeSort(
@@ -310,7 +300,7 @@ export class Connection {
break;
}
case Actions.TimeSync: {
case ACTIONS.TimeSync: {
this.state = this.update({
timeDiff: (timestamp() - message.payload) as Types.Milliseconds,
});
@@ -318,7 +308,7 @@ export class Connection {
break;
}
case Actions.AddedChain: {
case ACTIONS.AddedChain: {
const [label, nodeCount] = message.payload;
const chain = chains.get(label);
@@ -333,7 +323,7 @@ export class Connection {
break;
}
case Actions.RemovedChain: {
case ACTIONS.RemovedChain: {
chains.delete(message.payload);
if (this.state.subscribed === message.payload) {
@@ -345,7 +335,7 @@ export class Connection {
break;
}
case Actions.SubscribedTo: {
case ACTIONS.SubscribedTo: {
nodes.clear();
this.state = this.update({ subscribed: message.payload, nodes });
@@ -353,7 +343,7 @@ export class Connection {
break;
}
case Actions.UnsubscribedFrom: {
case ACTIONS.UnsubscribedFrom: {
if (this.state.subscribed === message.payload) {
nodes.clear();
@@ -363,13 +353,13 @@ export class Connection {
break;
}
case Actions.Pong: {
case ACTIONS.Pong: {
this.pong(Number(message.payload));
break;
}
case Actions.AfgFinalized: {
case ACTIONS.AfgFinalized: {
const [nodeAddress, finalizedNumber, finalizedHash] = message.payload;
const no = parseInt(String(finalizedNumber), 10) as Types.BlockNumber;
afg.receivedFinalized(nodeAddress, no, finalizedHash);
@@ -377,23 +367,23 @@ export class Connection {
break;
}
case Actions.AfgReceivedPrevote: {
case ACTIONS.AfgReceivedPrevote: {
const [nodeAddress, blockNumber, blockHash, voter] = message.payload;
const no = parseInt(String(blockNumber), 10) as Types.BlockNumber;
afg.receivedPre(nodeAddress, no, blockHash, voter, 'prevote');
afg.receivedPre(nodeAddress, no, voter, 'prevote');
break;
}
case Actions.AfgReceivedPrecommit: {
case ACTIONS.AfgReceivedPrecommit: {
const [nodeAddress, blockNumber, blockHash, voter] = message.payload;
const no = parseInt(String(blockNumber), 10) as Types.BlockNumber;
afg.receivedPre(nodeAddress, no, blockHash, voter, 'precommit');
afg.receivedPre(nodeAddress, no, voter, 'precommit');
break;
}
case Actions.AfgAuthoritySet: {
case ACTIONS.AfgAuthoritySet: {
const [authoritySetId, authorities] = message.payload;
afg.receivedAuthoritySet(authoritySetId, authorities);

Before

Width:  |  Height:  |  Size: 324 KiB

After

Width:  |  Height:  |  Size: 324 KiB

@@ -12,7 +12,11 @@ export type Compare<T> = (a: T, b: T) => number;
*
* @return {number} insertion index
*/
export function sortedInsert<T>(item: T, into: Array<T>, compare: Compare<T>): number {
export function sortedInsert<T>(
item: T,
into: Array<T>,
compare: Compare<T>
): number {
if (into.length === 0) {
into.push(item);
@@ -23,7 +27,7 @@ export function sortedInsert<T>(item: T, into: Array<T>, compare: Compare<T>): n
let max = into.length - 1;
while (min !== max) {
const guess = (min + max) / 2 | 0;
const guess = ((min + max) / 2) | 0;
if (compare(item, into[guess]) < 0) {
max = Math.max(min, guess - 1);
@@ -50,7 +54,11 @@ export function sortedInsert<T>(item: T, into: Array<T>, compare: Compare<T>): n
*
* @return {number} index of the element, `-1` if not found
*/
export function sortedIndexOf<T>(item: T, within: Array<T>, compare: Compare<T>): number {
export function sortedIndexOf<T>(
item: T,
within: Array<T>,
compare: Compare<T>
): number {
if (within.length === 0) {
return -1;
}
@@ -59,7 +67,7 @@ export function sortedIndexOf<T>(item: T, within: Array<T>, compare: Compare<T>)
let max = within.length - 1;
while (min !== max) {
let guess = (min + max) / 2 | 0;
const guess = ((min + max) / 2) | 0;
const other = within[guess];
if (item === other) {
@@ -113,7 +121,9 @@ export class SortedCollection<Item extends { id: number }> {
public add(item: Item) {
if (this.map.length <= item.id) {
// Grow map if item.id would be out of scope
this.map = this.map.concat(Array<Maybe<Item>>(Math.max(10, 1 + item.id - this.map.length)));
this.map = this.map.concat(
Array<Maybe<Item>>(Math.max(10, 1 + item.id - this.map.length))
);
}
// Remove old item if overriding
@@ -178,7 +188,11 @@ export class SortedCollection<Item extends { id: number }> {
}
}
public mutAndMaybeSort(id: number, mutator: (item: Item) => void, sort: boolean) {
public mutAndMaybeSort(
id: number,
mutator: (item: Item) => void,
sort: boolean
) {
if (sort) {
this.mutAndSort(id, mutator);
} else {
@@ -1,4 +1,4 @@
import { Opaque, Maybe } from './helpers';
import { Maybe } from './helpers';
import { stringify, parse, Stringified } from './stringify';
import {
FeedVersion,
@@ -22,32 +22,32 @@ import {
AuthoritySetInfo,
} from './types';
export const Actions = {
FeedVersion : 0x00 as 0x00,
BestBlock : 0x01 as 0x01,
BestFinalized : 0x02 as 0x02,
AddedNode : 0x03 as 0x03,
RemovedNode : 0x04 as 0x04,
LocatedNode : 0x05 as 0x05,
ImportedBlock : 0x06 as 0x06,
FinalizedBlock : 0x07 as 0x07,
NodeStats : 0x08 as 0x08,
NodeHardware : 0x09 as 0x09,
TimeSync : 0x0A as 0x0A,
AddedChain : 0x0B as 0x0B,
RemovedChain : 0x0C as 0x0C,
SubscribedTo : 0x0D as 0x0D,
UnsubscribedFrom : 0x0E as 0x0E,
Pong : 0x0F as 0x0F,
AfgFinalized : 0x10 as 0x10,
AfgReceivedPrevote : 0x11 as 0x11,
AfgReceivedPrecommit : 0x12 as 0x12,
AfgAuthoritySet : 0x13 as 0x13,
StaleNode : 0x14 as 0x14,
NodeIO : 0x15 as 0x15,
export const ACTIONS = {
FeedVersion: 0x00 as 0x00,
BestBlock: 0x01 as 0x01,
BestFinalized: 0x02 as 0x02,
AddedNode: 0x03 as 0x03,
RemovedNode: 0x04 as 0x04,
LocatedNode: 0x05 as 0x05,
ImportedBlock: 0x06 as 0x06,
FinalizedBlock: 0x07 as 0x07,
NodeStats: 0x08 as 0x08,
NodeHardware: 0x09 as 0x09,
TimeSync: 0x0a as 0x0a,
AddedChain: 0x0b as 0x0b,
RemovedChain: 0x0c as 0x0c,
SubscribedTo: 0x0d as 0x0d,
UnsubscribedFrom: 0x0e as 0x0e,
Pong: 0x0f as 0x0f,
AfgFinalized: 0x10 as 0x10,
AfgReceivedPrevote: 0x11 as 0x11,
AfgReceivedPrecommit: 0x12 as 0x12,
AfgAuthoritySet: 0x13 as 0x13,
StaleNode: 0x14 as 0x14,
NodeIO: 0x15 as 0x15,
};
export type Action = typeof Actions[keyof typeof Actions];
export type Action = typeof ACTIONS[keyof typeof ACTIONS];
export type Payload = Message['payload'];
export namespace Variants {
@@ -56,112 +56,121 @@ export namespace Variants {
}
export interface FeedVersionMessage extends MessageBase {
action: typeof Actions.FeedVersion;
action: typeof ACTIONS.FeedVersion;
payload: FeedVersion;
}
export interface BestBlockMessage extends MessageBase {
action: typeof Actions.BestBlock;
action: typeof ACTIONS.BestBlock;
payload: [BlockNumber, Timestamp, Maybe<Milliseconds>];
}
export interface BestFinalizedBlockMessage extends MessageBase {
action: typeof Actions.BestFinalized;
action: typeof ACTIONS.BestFinalized;
payload: [BlockNumber, BlockHash];
}
export interface AddedNodeMessage extends MessageBase {
action: typeof Actions.AddedNode;
payload: [NodeId, NodeDetails, NodeStats, NodeIO, NodeHardware, BlockDetails, Maybe<NodeLocation>, Timestamp];
action: typeof ACTIONS.AddedNode;
payload: [
NodeId,
NodeDetails,
NodeStats,
NodeIO,
NodeHardware,
BlockDetails,
Maybe<NodeLocation>,
Timestamp
];
}
export interface RemovedNodeMessage extends MessageBase {
action: typeof Actions.RemovedNode;
action: typeof ACTIONS.RemovedNode;
payload: NodeId;
}
export interface LocatedNodeMessage extends MessageBase {
action: typeof Actions.LocatedNode;
action: typeof ACTIONS.LocatedNode;
payload: [NodeId, Latitude, Longitude, City];
}
export interface ImportedBlockMessage extends MessageBase {
action: typeof Actions.ImportedBlock;
action: typeof ACTIONS.ImportedBlock;
payload: [NodeId, BlockDetails];
}
export interface FinalizedBlockMessage extends MessageBase {
action: typeof Actions.FinalizedBlock;
action: typeof ACTIONS.FinalizedBlock;
payload: [NodeId, BlockNumber, BlockHash];
}
export interface NodeStatsMessage extends MessageBase {
action: typeof Actions.NodeStats;
action: typeof ACTIONS.NodeStats;
payload: [NodeId, NodeStats];
}
export interface NodeHardwareMessage extends MessageBase {
action: typeof Actions.NodeHardware;
action: typeof ACTIONS.NodeHardware;
payload: [NodeId, NodeHardware];
}
export interface NodeIOMessage extends MessageBase {
action: typeof Actions.NodeIO;
action: typeof ACTIONS.NodeIO;
payload: [NodeId, NodeIO];
}
export interface TimeSyncMessage extends MessageBase {
action: typeof Actions.TimeSync;
action: typeof ACTIONS.TimeSync;
payload: Timestamp;
}
export interface AddedChainMessage extends MessageBase {
action: typeof Actions.AddedChain;
action: typeof ACTIONS.AddedChain;
payload: [ChainLabel, NodeCount];
}
export interface RemovedChainMessage extends MessageBase {
action: typeof Actions.RemovedChain;
action: typeof ACTIONS.RemovedChain;
payload: ChainLabel;
}
export interface SubscribedToMessage extends MessageBase {
action: typeof Actions.SubscribedTo;
action: typeof ACTIONS.SubscribedTo;
payload: ChainLabel;
}
export interface UnsubscribedFromMessage extends MessageBase {
action: typeof Actions.UnsubscribedFrom;
action: typeof ACTIONS.UnsubscribedFrom;
payload: ChainLabel;
}
export interface PongMessage extends MessageBase {
action: typeof Actions.Pong;
action: typeof ACTIONS.Pong;
payload: string; // just echo whatever `ping` sent
}
export interface AfgFinalizedMessage extends MessageBase {
action: typeof Actions.AfgFinalized;
action: typeof ACTIONS.AfgFinalized;
payload: [Address, BlockNumber, BlockHash];
}
export interface AfgAuthoritySet extends MessageBase {
action: typeof Actions.AfgAuthoritySet;
action: typeof ACTIONS.AfgAuthoritySet;
payload: AuthoritySetInfo;
}
export interface AfgReceivedPrecommit extends MessageBase {
action: typeof Actions.AfgReceivedPrecommit;
action: typeof ACTIONS.AfgReceivedPrecommit;
payload: [Address, BlockNumber, BlockHash, Address];
}
export interface AfgReceivedPrevote extends MessageBase {
action: typeof Actions.AfgReceivedPrevote;
action: typeof ACTIONS.AfgReceivedPrevote;
payload: [Address, BlockNumber, BlockHash, Address];
}
export interface StaleNodeMessage extends MessageBase {
action: typeof Actions.StaleNode;
action: typeof ACTIONS.StaleNode;
payload: NodeId;
}
}
@@ -194,7 +203,7 @@ export type Message =
* Data type to be sent to the feed. Passing through strings means we can only serialize once,
* no matter how many feed clients are listening in.
*/
export interface SquashedMessages extends Array<Action | Payload> {};
export interface SquashedMessages extends Array<Action | Payload> {}
export type Data = Stringified<SquashedMessages>;
/**
@@ -213,7 +222,7 @@ export function serialize(messages: Array<Message>): Data {
squashed[index++] = action;
squashed[index++] = payload;
})
});
return stringify(squashed);
}
@@ -231,7 +240,7 @@ export function deserialize(data: Data): Array<Message> {
const messages = new Array<Message>(json.length / 2);
for (const index of messages.keys()) {
const [ action, payload ] = json.slice(index * 2);
const [action, payload] = json.slice(index * 2);
messages[index] = { action, payload } as Message;
}
@@ -4,7 +4,9 @@ import { Milliseconds, Timestamp } from './types';
* PhantomData akin to Rust, because sometimes you need to be smarter than
* the compiler.
*/
export abstract class PhantomData<P> { public __PHANTOM__: P }
export abstract class PhantomData<P> {
public __PHANTOM__: P;
}
/**
* Opaque type, similar to `opaque type` in Flow, or new types in Rust/C.
@@ -109,6 +111,8 @@ export class NumStats<T extends number> {
}
private nonEmpty(): Readonly<Array<number>> {
return this.index < this.history ? this.stack.slice(0, this.index) : this.stack;
return this.index < this.history
? this.stack.slice(0, this.index)
: this.stack;
}
}
@@ -9,7 +9,7 @@ export type Id<T> = Opaque<number, T>;
* Higher order function producing new auto-incremented `Id`s.
*/
export function idGenerator<I extends Id<any>>(): () => I {
let current = 0;
let current = 0;
return () => current++ as I;
return () => current++ as I;
}
+84
View File
@@ -0,0 +1,84 @@
export function* map<T, U>(
iter: IterableIterator<T>,
fn: (item: T) => U
): IterableIterator<U> {
for (const item of iter) {
yield fn(item);
}
}
export function* chain<T>(
a: IterableIterator<T>,
b: IterableIterator<T>
): IterableIterator<T> {
yield* a;
yield* b;
}
export function* zip<T, U>(
a: IterableIterator<T>,
b: IterableIterator<U>
): IterableIterator<[T, U]> {
let itemA = a.next();
let itemB = b.next();
while (!itemA.done && !itemB.done) {
yield [itemA.value, itemB.value];
itemA = a.next();
itemB = b.next();
}
}
export function* take<T>(
iter: IterableIterator<T>,
n: number
): IterableIterator<T> {
for (const item of iter) {
if (n-- === 0) {
return;
}
yield item;
}
}
export function skip<T>(
iter: IterableIterator<T>,
n: number
): IterableIterator<T> {
while (n-- !== 0 && !iter.next().done) {}
return iter;
}
export function reduce<T, R>(
iter: IterableIterator<T>,
fn: (accu: R, item: T) => R,
accumulator: R
): R {
for (const item of iter) {
accumulator = fn(accumulator, item);
}
return accumulator;
}
export function join(
iter: IterableIterator<{ toString: () => string }>,
glue: string
): string {
const first = iter.next();
if (first.done) {
return '';
}
let result = first.value.toString();
for (const item of iter) {
result += glue + item;
}
return result;
}
+8
View File
@@ -0,0 +1,8 @@
export abstract class Stringified<T> {
public __PHANTOM__: T;
}
export const parse = (JSON.parse as any) as <T>(val: Stringified<T>) => T;
export const stringify = (JSON.stringify as any) as <T>(
val: T
) => Stringified<T>;
@@ -27,26 +27,55 @@ export type BytesPerSecond = Opaque<number, 'BytesPerSecond'>;
export type NetworkId = Opaque<string, 'NetworkId'>;
export type NetworkState = Opaque<string | object, 'NetworkState'>;
export type BlockDetails = [BlockNumber, BlockHash, Milliseconds, Timestamp, Maybe<PropagationTime>];
export type NodeDetails = [NodeName, NodeImplementation, NodeVersion, Maybe<Address>, Maybe<NetworkId>];
export type BlockDetails = [
BlockNumber,
BlockHash,
Milliseconds,
Timestamp,
Maybe<PropagationTime>
];
export type NodeDetails = [
NodeName,
NodeImplementation,
NodeVersion,
Maybe<Address>,
Maybe<NetworkId>
];
export type NodeStats = [PeerCount, TransactionCount];
export type NodeIO = [Array<Bytes>, Array<Bytes>, Array<BytesPerSecond>, Array<BytesPerSecond>];
export type NodeHardware = [Array<MemoryUse>, Array<CPUUse>, Array<BytesPerSecond>, Array<BytesPerSecond>, Array<Timestamp>];
export type NodeIO = [
Array<Bytes>,
Array<Bytes>,
Array<BytesPerSecond>,
Array<BytesPerSecond>
];
export type NodeHardware = [
Array<MemoryUse>,
Array<CPUUse>,
Array<BytesPerSecond>,
Array<BytesPerSecond>,
Array<Timestamp>
];
export type NodeLocation = [Latitude, Longitude, City];
export declare type Authority = {
Address: Address,
NodeId: Maybe<NodeId>,
Name: Maybe<NodeName>,
};
export interface Authority {
Address: Address;
NodeId: Maybe<NodeId>;
Name: Maybe<NodeName>;
}
export declare type Authorities = Array<Address>;
export declare type AuthoritySetId = Opaque<number, 'AuthoritySetId'>;
export declare type AuthoritySetInfo = [AuthoritySetId, Authorities, Address, BlockNumber, BlockHash];
export declare type AuthoritySetInfo = [
AuthoritySetId,
Authorities,
Address,
BlockNumber,
BlockHash
];
export declare type ConsensusItem = [BlockNumber, ConsensusView];
export declare type ConsensusInfo = Array<ConsensusItem>;
export declare type ConsensusView = Map<Address, ConsensusState>;
export declare type ConsensusState = Map<Address, ConsensusDetail>;
export declare type ConsensusDetail = {
export interface ConsensusDetail {
Precommit: Precommit;
ImplicitPrecommit: ImplicitPrecommit;
Prevote: Prevote;
@@ -56,7 +85,7 @@ export declare type ConsensusDetail = {
ImplicitFinalized: Finalized;
FinalizedHash: BlockHash;
FinalizedHeight: BlockNumber;
};
}
export declare type Precommit = Opaque<boolean, 'Precommit'>;
export declare type Prevote = Opaque<boolean, 'Prevote'>;
export declare type Finalized = Opaque<boolean, 'Finalized'>;
@@ -1,6 +1,6 @@
import * as React from 'react';
import './Tile.css';
import { timestamp, Types } from '@dotstats/common';
import { timestamp, Types } from '../common';
export namespace Ago {
export interface Props {
@@ -1,6 +1,6 @@
import * as React from 'react';
import { Connection } from '../Connection';
import { Types, Maybe } from '@dotstats/common';
import { Types, Maybe } from '../common';
import { ChainData } from '../state';
import './AllChains.css';
@@ -1,6 +1,6 @@
import * as React from 'react';
import { Connection } from '../../Connection';
import { Types, Maybe } from '@dotstats/common';
import { Types, Maybe } from '../../common';
import { State as AppState } from '../../state';
import { formatNumber, secondsWithPrecision, getHashData } from '../../utils';
import { Tab } from './';
@@ -1,7 +1,7 @@
import * as React from 'react';
import { Connection } from '../Connection';
import { Icon } from './Icon';
import { Types, Maybe } from '@dotstats/common';
import { Types, Maybe } from '../common';
import { ChainData } from '../state';
import githubIcon from '../icons/mark-github.svg';
@@ -1,5 +1,5 @@
import * as React from 'react';
import { Types, Maybe } from '@dotstats/common';
import { Types, Maybe } from '../../common';
import { Connection } from '../../Connection';
import Measure, { BoundingRect, ContentRect } from 'react-measure';
@@ -357,7 +357,7 @@ export class Consensus extends React.Component<Consensus.Props, {}> {
private getSmallRow(blocks: Types.ConsensusInfo) {
const smallBlockSizeChanged = (
isFirstBlock: boolean,
_isFirstBlock: boolean,
rect: BoundingRect
) => {
if (this.smallBlocksSizeDetected(this.state)) {
@@ -1,7 +1,7 @@
import * as React from 'react';
import Measure, { BoundingRect, ContentRect } from 'react-measure';
import { Types, Maybe } from '@dotstats/common';
import { Types, Maybe } from '../../common';
import { Icon, Tooltip, PolkadotIcon } from '../';
import Jdenticon from './Jdenticon';
@@ -1,5 +1,5 @@
import * as React from 'react';
import { Maybe } from '@dotstats/common';
import { Maybe } from '../common';
import { Node } from '../state';
import { Icon } from './';
@@ -1,5 +1,5 @@
import * as React from 'react';
import { Types, Maybe, timestamp } from '@dotstats/common';
import { Types, Maybe, timestamp } from '../../common';
import { State, Node } from '../../state';
import { Truncate } from './';
import { Ago, Icon, Tooltip, Sparkline, PolkadotIcon } from '../';
@@ -59,6 +59,7 @@ import dothereumIcon from '../../icons/dothereum.svg';
import katalchainIcon from '../../icons/katalchain.svg';
import bifrostIcon from '../../icons/bifrost.svg';
import totemIcon from '../../icons/totem.svg';
import unknownImplementationIcon from '../../icons/question-solid.svg';
const ICONS = {
@@ -1,5 +1,5 @@
import * as React from 'react';
import { Maybe } from '@dotstats/common';
import { Maybe } from '../../common';
import { Column } from './';
import { Icon, Tooltip } from '../';
import { Persistent } from '../../persist';
@@ -1,5 +1,5 @@
import * as React from 'react';
import { Types, Maybe } from '@dotstats/common';
import { Types, Maybe } from '../../common';
import { Filter } from '../';
import { State as AppState, Node } from '../../state';
import { Row } from './';
@@ -86,7 +86,7 @@ export class List extends React.Component<List.Props, {}> {
<React.Fragment>
<div className="List" style={{ height }}>
<table>
<Row.Header columns={selectedColumns} sortBy={sortBy} />
<Row.HEADER columns={selectedColumns} sortBy={sortBy} />
<tbody style={{ transform }}>
{nodes.map((node) => (
<Row
@@ -1,5 +1,5 @@
import * as React from 'react';
import { Types, Maybe } from '@dotstats/common';
import { Types, Maybe } from '../../common';
import { Node } from '../../state';
import { Persistent, PersistentSet } from '../../persist';
import { HeaderCell, Column } from './';
@@ -51,7 +51,7 @@ export class Row extends React.Component<Row.Props, Row.State> {
Column.NETWORK_STATE,
];
public static Header = (props: HeaderProps) => {
public static HEADER = (props: HeaderProps) => {
const { columns, sortBy } = props;
const last = columns.length - 1;
@@ -91,7 +91,7 @@ export class Location extends React.Component<Location.Props, Location.State> {
city,
} = this.props.node;
let validatorRow = null;
let validatorRow = <div />;
if (validator) {
validatorRow = (
@@ -1,5 +1,5 @@
import * as React from 'react';
import { Types, Maybe } from '@dotstats/common';
import { Types, Maybe } from '../../common';
import { Filter } from '../';
import { State as AppState, Node } from '../../state';
import { Location } from './';
@@ -1,5 +1,5 @@
import * as React from 'react';
import { Maybe } from '@dotstats/common';
import { Maybe } from '../../common';
import { State as AppState } from '../../state';
import { Setting } from './';
import { Row } from '../List';
@@ -1,5 +1,5 @@
import * as React from 'react';
import { Types, Maybe } from '@dotstats/common';
import { Types, Maybe } from '../common';
import sparkline from '@fnando/sparkline';
import { Tooltip } from './';
@@ -79,7 +79,7 @@ export class Sparkline extends React.Component<Sparkline.Props, {}> {
};
private onMouseMove = (
event: MouseEvent,
_event: MouseEvent,
data: { value: number; index: number }
) => {
const { format, stamps } = this.props;

Before

Width:  |  Height:  |  Size: 366 B

After

Width:  |  Height:  |  Size: 366 B

Before

Width:  |  Height:  |  Size: 265 B

After

Width:  |  Height:  |  Size: 265 B

Before

Width:  |  Height:  |  Size: 144 B

After

Width:  |  Height:  |  Size: 144 B

Before

Width:  |  Height:  |  Size: 145 B

After

Width:  |  Height:  |  Size: 145 B

Before

Width:  |  Height:  |  Size: 145 B

After

Width:  |  Height:  |  Size: 145 B

Before

Width:  |  Height:  |  Size: 142 B

After

Width:  |  Height:  |  Size: 142 B

Before

Width:  |  Height:  |  Size: 142 B

After

Width:  |  Height:  |  Size: 142 B

Before

Width:  |  Height:  |  Size: 142 B

After

Width:  |  Height:  |  Size: 142 B

Before

Width:  |  Height:  |  Size: 142 B

After

Width:  |  Height:  |  Size: 142 B

Before

Width:  |  Height:  |  Size: 144 B

After

Width:  |  Height:  |  Size: 144 B

Before

Width:  |  Height:  |  Size: 297 B

After

Width:  |  Height:  |  Size: 297 B

Before

Width:  |  Height:  |  Size: 395 B

After

Width:  |  Height:  |  Size: 395 B

Before

Width:  |  Height:  |  Size: 250 B

After

Width:  |  Height:  |  Size: 250 B

Before

Width:  |  Height:  |  Size: 397 B

After

Width:  |  Height:  |  Size: 397 B

Before

Width:  |  Height:  |  Size: 352 B

After

Width:  |  Height:  |  Size: 352 B

Before

Width:  |  Height:  |  Size: 366 B

After

Width:  |  Height:  |  Size: 366 B

Before

Width:  |  Height:  |  Size: 283 B

After

Width:  |  Height:  |  Size: 283 B

Before

Width:  |  Height:  |  Size: 686 B

After

Width:  |  Height:  |  Size: 686 B

Before

Width:  |  Height:  |  Size: 268 B

After

Width:  |  Height:  |  Size: 268 B

Before

Width:  |  Height:  |  Size: 438 B

After

Width:  |  Height:  |  Size: 438 B

Before

Width:  |  Height:  |  Size: 588 B

After

Width:  |  Height:  |  Size: 588 B

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Before

Width:  |  Height:  |  Size: 646 B

After

Width:  |  Height:  |  Size: 646 B

Some files were not shown because too many files have changed in this diff Show More