Automatic seq graph rendering, with debounce
This commit is contained in:
parent
41506fdcd5
commit
a481710cde
|
@ -47,7 +47,7 @@ export class Box {
|
||||||
}
|
}
|
||||||
|
|
||||||
setId(id) {
|
setId(id) {
|
||||||
this.el.id = id || this.name;
|
this.el.id = (id || this.name).replace(/ /g, "");
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,10 @@ class Reputation {
|
||||||
const tokensLocked = Array.from(this.locks.values())
|
const tokensLocked = Array.from(this.locks.values())
|
||||||
.filter(({dateCreated, duration}) => now - dateCreated < duration)
|
.filter(({dateCreated, duration}) => now - dateCreated < duration)
|
||||||
.reduce((acc, cur) => acc += cur.tokens, 0);
|
.reduce((acc, cur) => acc += cur.tokens, 0);
|
||||||
return Math.max(this.tokens - tokensLocked, 0);
|
if (tokensLocked > this.tokens) {
|
||||||
|
throw new Error("Assertion failure. tokensLocked > tokens");
|
||||||
|
}
|
||||||
|
return this.tokens - tokensLocked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { Actor } from './actor.js';
|
import { Actor } from './actor.js';
|
||||||
import { Action } from './action.js';
|
import { Action } from './action.js';
|
||||||
// import mermaid from 'https://unpkg.com/mermaid@9.2.2/dist/mermaid.esm.mjs';
|
import { debounce } from '../util.js';
|
||||||
|
import mermaid from 'https://unpkg.com/mermaid@9.2.2/dist/mermaid.esm.mjs';
|
||||||
|
|
||||||
export class Scene {
|
export class Scene {
|
||||||
constructor(name, rootBox) {
|
constructor(name, rootBox) {
|
||||||
|
@ -10,11 +11,14 @@ export class Scene {
|
||||||
this.box.addBox('Spacer').setInnerHTML(' ');
|
this.box.addBox('Spacer').setInnerHTML(' ');
|
||||||
this.displayValuesBox = this.box.addBox(`${this.name}-values`);
|
this.displayValuesBox = this.box.addBox(`${this.name}-values`);
|
||||||
this.box.addBox('Spacer').setInnerHTML(' ');
|
this.box.addBox('Spacer').setInnerHTML(' ');
|
||||||
this.logBox = this.box.addBox(`${this.name}-log`);
|
|
||||||
this.actors = new Set();
|
this.actors = new Set();
|
||||||
// this.seqDiagramContainer = this.box.addBox(`${this.name}-seq-diagram-container`);
|
this.seqDiagramContainer = this.box.addBox(`${this.name}-seq-diagram-container`);
|
||||||
// this.seqDiagramBox = this.box.addBox(`${this.name}-seq-diagram`);
|
this.seqDiagramElement = this.box.addBox(`${this.name}-seq-diagram-element`).setId();
|
||||||
// mermaid.mermaidAPI.initialize({ startOnLoad: false });
|
this.seqDiagramBox = this.box.addBox(`${this.name}-seq-diagram`);
|
||||||
|
this.box.addBox('Spacer').setInnerHTML(' ');
|
||||||
|
this.logBox = this.box.addBox(`${this.name}-log`);
|
||||||
|
mermaid.mermaidAPI.initialize({ startOnLoad: false });
|
||||||
|
this.dateLastRender = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
addActor(name) {
|
addActor(name) {
|
||||||
|
@ -38,6 +42,7 @@ export class Scene {
|
||||||
|
|
||||||
log(msg) {
|
log(msg) {
|
||||||
this.logBox.addBox().setInnerHTML(msg).monospace();
|
this.logBox.addBox().setInnerHTML(msg).monospace();
|
||||||
|
this.renderSequenceDiagram();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,16 +55,24 @@ export class Scene {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// async renderSequenceDiagram() {
|
async renderSequenceDiagram() {
|
||||||
// await mermaid.mermaidAPI.render(
|
const render = async () => {
|
||||||
// `${this.name}-seq-diagram-element`,
|
const dateStart = new Date();
|
||||||
// this.logBox.getInnerText(),
|
const graph = await mermaid.mermaidAPI.render(
|
||||||
// this.insertSvg,
|
this.seqDiagramElement.getId(),
|
||||||
// this.seqDiagramContainer.el
|
this.logBox.getInnerText(),
|
||||||
// );
|
);
|
||||||
// }
|
this.seqDiagramBox.setInnerHTML(graph);
|
||||||
|
if (!this.dateLastRender) {
|
||||||
|
this.dateLastRender = new Date();
|
||||||
|
}
|
||||||
|
console.log(`renderSequenceDiagram time: ${new Date() - dateStart} ms, time since last render: ${dateStart - this.dateLastRender}`);
|
||||||
|
this.dateLastRender = dateStart;
|
||||||
|
};
|
||||||
|
debounce(render, 100);
|
||||||
|
}
|
||||||
|
|
||||||
// insertSvg (svgCode) {
|
insertSvg (svgCode) {
|
||||||
// this.seqDiagramBox.setInnerHTML(svgCode);
|
this.seqDiagramElement.setInnerHTML(svgCode);
|
||||||
// };
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ export class ValidationPool extends Actor {
|
||||||
against: fee * params.mintingRatio * (1 - params.stakeForWin),
|
against: fee * params.mintingRatio * (1 - params.stakeForWin),
|
||||||
author: fee * params.mintingRatio * params.stakeForAuthor,
|
author: fee * params.mintingRatio * params.stakeForAuthor,
|
||||||
}
|
}
|
||||||
|
// TODO: Consider availability stakes
|
||||||
}
|
}
|
||||||
|
|
||||||
castVote(signingPublicKey, position, stake, lockingTime) {
|
castVote(signingPublicKey, position, stake, lockingTime) {
|
||||||
|
@ -126,7 +127,7 @@ export class ValidationPool extends Actor {
|
||||||
|
|
||||||
distributeTokens(result) {
|
distributeTokens(result) {
|
||||||
// Reward the author
|
// Reward the author
|
||||||
// TODO: Penalty to the author if the vote does not pass?
|
// TODO: If the vote fails, distribute tokens.author among winning voters
|
||||||
this.bench.reputations.addTokens(this.authorId, this.tokens.author);
|
this.bench.reputations.addTokens(this.authorId, this.tokens.author);
|
||||||
// Reward the vote winners, in proportion to their stakes
|
// Reward the vote winners, in proportion to their stakes
|
||||||
const tokensForWinners = result ? this.tokens.for : this.tokens.against;
|
const tokensForWinners = result ? this.tokens.for : this.tokens.against;
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<head>
|
||||||
|
<title>Forum Graph</title>
|
||||||
|
<script type="module" src="./debounce-test.js" defer></script>
|
||||||
|
<link type="text/css" rel="stylesheet" href="./index.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="debounce-test"></div>
|
||||||
|
</body>
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { Box } from './classes/box.js';
|
||||||
|
import { Scene } from './classes/scene.js';
|
||||||
|
import { debounce, delay } from "./util.js";
|
||||||
|
|
||||||
|
const rootElement = document.getElementById('debounce-test');
|
||||||
|
const rootBox = new Box('rootBox', rootElement).flex();
|
||||||
|
|
||||||
|
const scene = window.scene = new Scene('Debounce test', rootBox);
|
||||||
|
|
||||||
|
const log = () => scene.log("event");
|
||||||
|
debounce(log, 500);
|
||||||
|
debounce(log, 500);
|
||||||
|
await delay(500);
|
||||||
|
debounce(log, 500);
|
||||||
|
debounce(log, 500);
|
|
@ -4,10 +4,7 @@ import { Post } from './classes/post.js';
|
||||||
import { Member } from './classes/member.js';
|
import { Member } from './classes/member.js';
|
||||||
import { ForumNode } from './classes/forum-node.js';
|
import { ForumNode } from './classes/forum-node.js';
|
||||||
import { ForumNetwork } from './classes/forum-network.js';
|
import { ForumNetwork } from './classes/forum-network.js';
|
||||||
|
import { delay } from './util.js';
|
||||||
const delay = async (ms) => {
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
||||||
};
|
|
||||||
|
|
||||||
const rootElement = document.getElementById('forum-network');
|
const rootElement = document.getElementById('forum-network');
|
||||||
const rootBox = new Box('rootBox', rootElement).flex();
|
const rootBox = new Box('rootBox', rootElement).flex();
|
||||||
|
@ -23,10 +20,12 @@ window.forumNode1 = await new ForumNode('node1', window.scene).initialize(window
|
||||||
window.forumNode2 = await new ForumNode('node2', window.scene).initialize(window.forumNetwork);
|
window.forumNode2 = await new ForumNode('node2', window.scene).initialize(window.forumNetwork);
|
||||||
window.forumNode3 = await new ForumNode('node3', window.scene).initialize(window.forumNetwork);
|
window.forumNode3 = await new ForumNode('node3', window.scene).initialize(window.forumNetwork);
|
||||||
|
|
||||||
setInterval(async () => {
|
const processInterval = setInterval(async () => {
|
||||||
await window.forumNode1.processNextMessage();
|
await window.forumNode1.processNextMessage();
|
||||||
await window.forumNode2.processNextMessage();
|
await window.forumNode2.processNextMessage();
|
||||||
await window.forumNode3.processNextMessage();
|
await window.forumNode3.processNextMessage();
|
||||||
|
|
||||||
|
await window.scene.renderSequenceDiagram();
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|
||||||
// const blockchain = new Blockchain();
|
// const blockchain = new Blockchain();
|
||||||
|
@ -38,3 +37,6 @@ await delay(1000);
|
||||||
await window.author1.submitPost(window.forumNode1, window.post1, 50);
|
await window.author1.submitPost(window.forumNode1, window.post1, 50);
|
||||||
await delay(1000);
|
await delay(1000);
|
||||||
await window.author2.submitPost(window.forumNode2, window.post2, 100);
|
await window.author2.submitPost(window.forumNode2, window.post2, 100);
|
||||||
|
|
||||||
|
await delay(1000);
|
||||||
|
clearInterval(processInterval);
|
||||||
|
|
|
@ -22,3 +22,6 @@
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
font-size: 11pt;
|
font-size: 11pt;
|
||||||
}
|
}
|
||||||
|
svg {
|
||||||
|
width: 800px;
|
||||||
|
}
|
||||||
|
|
|
@ -10,5 +10,6 @@
|
||||||
<li><a href="./graph-test.html">Graph test</a></li>
|
<li><a href="./graph-test.html">Graph test</a></li>
|
||||||
<li><a href="./validation-pool-test.html">Validation Pool test</a></li>
|
<li><a href="./validation-pool-test.html">Validation Pool test</a></li>
|
||||||
<li><a href="./mermaid-test.html">Mermaid test</a></li>
|
<li><a href="./mermaid-test.html">Mermaid test</a></li>
|
||||||
|
<li><a href="./debounce-test.html">Debounce test</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -2,7 +2,25 @@
|
||||||
<head>
|
<head>
|
||||||
<title>Forum Network</title>
|
<title>Forum Network</title>
|
||||||
<link type="text/css" rel="stylesheet" href="./index.css" />
|
<link type="text/css" rel="stylesheet" href="./index.css" />
|
||||||
|
|
||||||
|
<script type="module" defer>
|
||||||
|
// import mermaid from './mermaid.mjs';
|
||||||
|
import mermaid from 'https://unpkg.com/mermaid@9.2.2/dist/mermaid.esm.mjs';
|
||||||
|
mermaid.mermaidAPI.initialize({ startOnLoad: false });
|
||||||
|
// Example of using the API var
|
||||||
|
const element = document.querySelector('#graphDiv');
|
||||||
|
const insertSvg = function (svgCode, bindFunctions) {
|
||||||
|
element.innerHTML = svgCode;
|
||||||
|
};
|
||||||
|
const graphDefinition = 'graph TB\na-->b';
|
||||||
|
const graph = await mermaid.mermaidAPI.render('graphDiv', graphDefinition, insertSvg);
|
||||||
|
console.log("executed...");
|
||||||
|
console.log(graph);
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.innerHTML = graph;
|
||||||
|
document.body.append(div);
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<div id="graphDiv"></div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
const timeouts = new Map();
|
||||||
|
|
||||||
|
export const debounce = (fn, delay) => {
|
||||||
|
const key = fn.toString();
|
||||||
|
if (!timeouts.get(key)) {
|
||||||
|
timeouts.set(key, setTimeout(async () => {
|
||||||
|
timeouts.delete(key);
|
||||||
|
await fn();
|
||||||
|
}, delay));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const delay = async (ms) => {
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
|
};
|
|
@ -2,28 +2,24 @@ import { Box } from './classes/box.js';
|
||||||
import { Scene } from './classes/scene.js';
|
import { Scene } from './classes/scene.js';
|
||||||
import { Member } from './classes/member.js';
|
import { Member } from './classes/member.js';
|
||||||
import { Bench } from './classes/bench.js';
|
import { Bench } from './classes/bench.js';
|
||||||
|
import { delay } from './util.js';
|
||||||
const delay = async (ms) => {
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
||||||
};
|
|
||||||
|
|
||||||
const rootElement = document.getElementById('validation-pool');
|
const rootElement = document.getElementById('validation-pool');
|
||||||
const rootBox = new Box('rootBox', rootElement).flex();
|
const rootBox = new Box('rootBox', rootElement).flex();
|
||||||
|
|
||||||
const scene = window.scene = new Scene('Validation Pool test', rootBox).log('sequenceDiagram');
|
const scene = window.scene = new Scene('Validation Pool test', rootBox).log('sequenceDiagram');
|
||||||
|
|
||||||
const bench = window.bench = new Bench("Bench", scene);
|
|
||||||
|
|
||||||
const member1 = window.member1 = await new Member("Member1", scene).initialize();
|
const member1 = window.member1 = await new Member("Member1", scene).initialize();
|
||||||
const member2 = window.member2 = await new Member("Member2", scene).initialize();
|
const member2 = window.member2 = await new Member("Member2", scene).initialize();
|
||||||
|
const bench = window.bench = new Bench("Bench", scene);
|
||||||
|
|
||||||
const updateDisplayValues = () => {
|
const updateDisplayValues = async () => {
|
||||||
member1.setValue('rep', bench.reputations.getTokens(member1.reputationPublicKey));
|
member1.setValue('rep', bench.reputations.getTokens(member1.reputationPublicKey));
|
||||||
member2.setValue('rep', bench.reputations.getTokens(member2.reputationPublicKey));
|
member2.setValue('rep', bench.reputations.getTokens(member2.reputationPublicKey));
|
||||||
bench.setValue('total rep', bench.getTotalReputation());
|
bench.setValue('total rep', bench.getTotalReputation());
|
||||||
bench.setValue('available rep', bench.getTotalAvailableReputation());
|
bench.setValue('available rep', bench.getTotalAvailableReputation());
|
||||||
bench.setValue('active rep', bench.getTotalActiveReputation());
|
bench.setValue('active rep', bench.getTotalActiveReputation());
|
||||||
bench.setValue('active available rep', bench.getTotalActiveAvailableReputation());
|
bench.setValue('active available rep', bench.getTotalActiveAvailableReputation());
|
||||||
|
await scene.renderSequenceDiagram();
|
||||||
};
|
};
|
||||||
|
|
||||||
updateDisplayValues();
|
updateDisplayValues();
|
||||||
|
@ -34,7 +30,7 @@ await delay(1000);
|
||||||
const pool = member1.initiateValidationPool(bench, {fee: 1, duration: 1000, tokenLossRatio: 1});
|
const pool = member1.initiateValidationPool(bench, {fee: 1, duration: 1000, tokenLossRatio: 1});
|
||||||
await member1.castVote(pool, true, 0, 0);
|
await member1.castVote(pool, true, 0, 0);
|
||||||
await member1.revealIdentity(pool); // Vote passes
|
await member1.revealIdentity(pool); // Vote passes
|
||||||
updateDisplayValues();
|
await updateDisplayValues();
|
||||||
await delay(1000);
|
await delay(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +39,7 @@ try {
|
||||||
const pool = member2.initiateValidationPool(bench, {fee: 1, duration: 1000, tokenLossRatio: 1});
|
const pool = member2.initiateValidationPool(bench, {fee: 1, duration: 1000, tokenLossRatio: 1});
|
||||||
await member2.castVote(pool, true, 0, 0);
|
await member2.castVote(pool, true, 0, 0);
|
||||||
await member2.revealIdentity(pool); // Quorum not met!
|
await member2.revealIdentity(pool); // Quorum not met!
|
||||||
updateDisplayValues();
|
await updateDisplayValues();
|
||||||
await delay(1000);
|
await delay(1000);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
if (e.message.match(/Quorum is not met/)) {
|
if (e.message.match(/Quorum is not met/)) {
|
||||||
|
@ -59,10 +55,12 @@ try {
|
||||||
const pool = member2.initiateValidationPool(bench, {fee: 1, duration: 1000, tokenLossRatio: 1});
|
const pool = member2.initiateValidationPool(bench, {fee: 1, duration: 1000, tokenLossRatio: 1});
|
||||||
await member1.castVote(pool, true, 0.5, 1);
|
await member1.castVote(pool, true, 0.5, 1);
|
||||||
await member1.revealIdentity(pool); // Vote passes
|
await member1.revealIdentity(pool); // Vote passes
|
||||||
updateDisplayValues();
|
await updateDisplayValues();
|
||||||
await delay(1000);
|
await delay(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDisplayValues();
|
await updateDisplayValues();
|
||||||
|
|
||||||
scene.deactivateAll();
|
scene.deactivateAll();
|
||||||
|
|
||||||
|
await updateDisplayValues();
|
||||||
|
|
Loading…
Reference in New Issue