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 MaricicandWill authored and GitHub committed 2020-04-06 15:38:45 +02:00
1 parent 20a0283380
commit bb8e804567
322 files changed
+10896 -10602

No files matched your search

+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.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -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});
File renamed without changes.
@@ -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;
File renamed without changes.
@@ -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);
File renamed without changes.
@@ -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;
}
File renamed without changes.
+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 './';
File renamed without changes.
File renamed without changes.
@@ -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;
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loaded 100 of 322 files, more files were not shown because too many files have changed in this diff. Show more