Automatic seq graph rendering, with debounce
This commit is contained in:
parent
41506fdcd5
commit
a481710cde
|
@ -47,7 +47,7 @@ export class Box {
|
|||
}
|
||||
|
||||
setId(id) {
|
||||
this.el.id = id || this.name;
|
||||
this.el.id = (id || this.name).replace(/ /g, "");
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,10 @@ class Reputation {
|
|||
const tokensLocked = Array.from(this.locks.values())
|
||||
.filter(({dateCreated, duration}) => now - dateCreated < duration)
|
||||
.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 { 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 {
|
||||
constructor(name, rootBox) {
|
||||
|
@ -10,11 +11,14 @@ export class Scene {
|
|||
this.box.addBox('Spacer').setInnerHTML(' ');
|
||||
this.displayValuesBox = this.box.addBox(`${this.name}-values`);
|
||||
this.box.addBox('Spacer').setInnerHTML(' ');
|
||||
this.logBox = this.box.addBox(`${this.name}-log`);
|
||||
this.actors = new Set();
|
||||
// this.seqDiagramContainer = this.box.addBox(`${this.name}-seq-diagram-container`);
|
||||
// this.seqDiagramBox = this.box.addBox(`${this.name}-seq-diagram`);
|
||||
// mermaid.mermaidAPI.initialize({ startOnLoad: false });
|
||||
this.seqDiagramContainer = this.box.addBox(`${this.name}-seq-diagram-container`);
|
||||
this.seqDiagramElement = this.box.addBox(`${this.name}-seq-diagram-element`).setId();
|
||||
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) {
|
||||
|
@ -38,6 +42,7 @@ export class Scene {
|
|||
|
||||
log(msg) {
|
||||
this.logBox.addBox().setInnerHTML(msg).monospace();
|
||||
this.renderSequenceDiagram();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -50,16 +55,24 @@ export class Scene {
|
|||
}
|
||||
}
|
||||
|
||||
// async renderSequenceDiagram() {
|
||||
// await mermaid.mermaidAPI.render(
|
||||
// `${this.name}-seq-diagram-element`,
|
||||
// this.logBox.getInnerText(),
|
||||
// this.insertSvg,
|
||||
// this.seqDiagramContainer.el
|
||||
// );
|
||||
// }
|
||||
|
||||
// insertSvg (svgCode) {
|
||||
// this.seqDiagramBox.setInnerHTML(svgCode);
|
||||
// };
|
||||
async renderSequenceDiagram() {
|
||||
const render = async () => {
|
||||
const dateStart = new Date();
|
||||
const graph = await mermaid.mermaidAPI.render(
|
||||
this.seqDiagramElement.getId(),
|
||||
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) {
|
||||
this.seqDiagramElement.setInnerHTML(svgCode);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ export class ValidationPool extends Actor {
|
|||
against: fee * params.mintingRatio * (1 - params.stakeForWin),
|
||||
author: fee * params.mintingRatio * params.stakeForAuthor,
|
||||
}
|
||||
// TODO: Consider availability stakes
|
||||
}
|
||||
|
||||
castVote(signingPublicKey, position, stake, lockingTime) {
|
||||
|
@ -126,7 +127,7 @@ export class ValidationPool extends Actor {
|
|||
|
||||
distributeTokens(result) {
|
||||
// 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);
|
||||
// Reward the vote winners, in proportion to their stakes
|
||||
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 { ForumNode } from './classes/forum-node.js';
|
||||
import { ForumNetwork } from './classes/forum-network.js';
|
||||
|
||||
const delay = async (ms) => {
|
||||
await new Promise((resolve) => setTimeout(resolve, ms));
|
||||
};
|
||||
import { delay } from './util.js';
|
||||
|
||||
const rootElement = document.getElementById('forum-network');
|
||||
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.forumNode3 = await new ForumNode('node3', window.scene).initialize(window.forumNetwork);
|
||||
|
||||
setInterval(async () => {
|
||||
const processInterval = setInterval(async () => {
|
||||
await window.forumNode1.processNextMessage();
|
||||
await window.forumNode2.processNextMessage();
|
||||
await window.forumNode3.processNextMessage();
|
||||
|
||||
await window.scene.renderSequenceDiagram();
|
||||
}, 100);
|
||||
|
||||
// const blockchain = new Blockchain();
|
||||
|
@ -38,3 +37,6 @@ await delay(1000);
|
|||
await window.author1.submitPost(window.forumNode1, window.post1, 50);
|
||||
await delay(1000);
|
||||
await window.author2.submitPost(window.forumNode2, window.post2, 100);
|
||||
|
||||
await delay(1000);
|
||||
clearInterval(processInterval);
|
||||
|
|
|
@ -22,3 +22,6 @@
|
|||
font-family: monospace;
|
||||
font-size: 11pt;
|
||||
}
|
||||
svg {
|
||||
width: 800px;
|
||||
}
|
||||
|
|
|
@ -10,5 +10,6 @@
|
|||
<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="./mermaid-test.html">Mermaid test</a></li>
|
||||
<li><a href="./debounce-test.html">Debounce test</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
|
|
|
@ -2,7 +2,25 @@
|
|||
<head>
|
||||
<title>Forum Network</title>
|
||||
<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>
|
||||
<body>
|
||||
<div id="graphDiv"></div>
|
||||
</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 { Member } from './classes/member.js';
|
||||
import { Bench } from './classes/bench.js';
|
||||
|
||||
const delay = async (ms) => {
|
||||
await new Promise((resolve) => setTimeout(resolve, ms));
|
||||
};
|
||||
import { delay } from './util.js';
|
||||
|
||||
const rootElement = document.getElementById('validation-pool');
|
||||
const rootBox = new Box('rootBox', rootElement).flex();
|
||||
|
||||
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 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));
|
||||
member2.setValue('rep', bench.reputations.getTokens(member2.reputationPublicKey));
|
||||
bench.setValue('total rep', bench.getTotalReputation());
|
||||
bench.setValue('available rep', bench.getTotalAvailableReputation());
|
||||
bench.setValue('active rep', bench.getTotalActiveReputation());
|
||||
bench.setValue('active available rep', bench.getTotalActiveAvailableReputation());
|
||||
await scene.renderSequenceDiagram();
|
||||
};
|
||||
|
||||
updateDisplayValues();
|
||||
|
@ -34,7 +30,7 @@ await delay(1000);
|
|||
const pool = member1.initiateValidationPool(bench, {fee: 1, duration: 1000, tokenLossRatio: 1});
|
||||
await member1.castVote(pool, true, 0, 0);
|
||||
await member1.revealIdentity(pool); // Vote passes
|
||||
updateDisplayValues();
|
||||
await updateDisplayValues();
|
||||
await delay(1000);
|
||||
}
|
||||
|
||||
|
@ -43,7 +39,7 @@ try {
|
|||
const pool = member2.initiateValidationPool(bench, {fee: 1, duration: 1000, tokenLossRatio: 1});
|
||||
await member2.castVote(pool, true, 0, 0);
|
||||
await member2.revealIdentity(pool); // Quorum not met!
|
||||
updateDisplayValues();
|
||||
await updateDisplayValues();
|
||||
await delay(1000);
|
||||
} catch(e) {
|
||||
if (e.message.match(/Quorum is not met/)) {
|
||||
|
@ -59,10 +55,12 @@ try {
|
|||
const pool = member2.initiateValidationPool(bench, {fee: 1, duration: 1000, tokenLossRatio: 1});
|
||||
await member1.castVote(pool, true, 0.5, 1);
|
||||
await member1.revealIdentity(pool); // Vote passes
|
||||
updateDisplayValues();
|
||||
await updateDisplayValues();
|
||||
await delay(1000);
|
||||
}
|
||||
|
||||
updateDisplayValues();
|
||||
await updateDisplayValues();
|
||||
|
||||
scene.deactivateAll();
|
||||
|
||||
await updateDisplayValues();
|
||||
|
|
Loading…
Reference in New Issue