Add support for flowchart diagrams alongside sequence
This commit is contained in:
parent
b644d6c119
commit
1066372371
|
@ -4,9 +4,9 @@ export class Action {
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
log(src, dest, msg, obj, symbol = '->>') {
|
async log(src, dest, msg, obj, symbol = '->>') {
|
||||||
const logObj = false;
|
const logObj = false;
|
||||||
this.scene.log(
|
await this.scene.sequence.log(
|
||||||
`${src.name} ${symbol} ${dest.name} : ${this.name} ${msg ?? ''} ${
|
`${src.name} ${symbol} ${dest.name} : ${this.name} ${msg ?? ''} ${
|
||||||
logObj && obj ? JSON.stringify(obj) : ''
|
logObj && obj ? JSON.stringify(obj) : ''
|
||||||
}`,
|
}`,
|
||||||
|
|
|
@ -5,7 +5,6 @@ export class Actor {
|
||||||
this.callbacks = new Map();
|
this.callbacks = new Map();
|
||||||
this.status = this.scene.addDisplayValue(`${this.name} status`);
|
this.status = this.scene.addDisplayValue(`${this.name} status`);
|
||||||
this.status.set('New');
|
this.status.set('New');
|
||||||
this.scene.log(`participant ${this.name}`);
|
|
||||||
this.values = new Map();
|
this.values = new Map();
|
||||||
this.active = 0;
|
this.active = 0;
|
||||||
this.scene.registerActor(this);
|
this.scene.registerActor(this);
|
||||||
|
@ -13,31 +12,31 @@ export class Actor {
|
||||||
|
|
||||||
activate() {
|
activate() {
|
||||||
this.active += 1;
|
this.active += 1;
|
||||||
this.scene.log(`activate ${this.name}`);
|
this.scene.sequence.log(`activate ${this.name}`, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
deactivate() {
|
async deactivate() {
|
||||||
if (!this.active) {
|
if (!this.active) {
|
||||||
throw new Error(`${this.name} is not active, can not deactivate`);
|
throw new Error(`${this.name} is not active, can not deactivate`);
|
||||||
}
|
}
|
||||||
this.active -= 1;
|
this.active -= 1;
|
||||||
this.scene.log(`deactivate ${this.name}`);
|
await this.scene.sequence.log(`deactivate ${this.name}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
send(dest, action, detail) {
|
async send(dest, action, detail) {
|
||||||
action.log(this, dest, detail ? JSON.stringify(detail) : '');
|
await action.log(this, dest, detail ? JSON.stringify(detail) : '');
|
||||||
dest.recv(this, action, detail);
|
await dest.recv(this, action, detail);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
recv(src, action, detail) {
|
async recv(src, action, detail) {
|
||||||
const cb = this.callbacks.get(action.name);
|
const cb = this.callbacks.get(action.name);
|
||||||
if (!cb) {
|
if (!cb) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`[${this.scene.name} actor ${this.name} does not have a callback registered for ${action.name}`,
|
`[${this.scene.name} actor ${this.name} does not have a callback registered for ${action.name}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
cb(src, detail);
|
await cb(src, detail);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +55,7 @@ export class Actor {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
setValue(label, value) {
|
async setValue(label, value) {
|
||||||
if (typeof value === 'number') {
|
if (typeof value === 'number') {
|
||||||
value = value.toFixed(2);
|
value = value.toFixed(2);
|
||||||
}
|
}
|
||||||
|
@ -66,7 +65,7 @@ export class Actor {
|
||||||
this.values.set(label, displayValue);
|
this.values.set(label, displayValue);
|
||||||
}
|
}
|
||||||
if (value !== displayValue.get()) {
|
if (value !== displayValue.get()) {
|
||||||
this.scene.log(`note over ${this.name} : ${label} = ${value}`);
|
await this.scene.sequence.log(`note over ${this.name} : ${label} = ${value}`);
|
||||||
}
|
}
|
||||||
displayValue.set(value);
|
displayValue.set(value);
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -18,8 +18,6 @@ export class Bench extends Actor {
|
||||||
this.actions = {
|
this.actions = {
|
||||||
createValidationPool: new Action('create validation pool', scene),
|
createValidationPool: new Action('create validation pool', scene),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.activate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
listValidationPools() {
|
listValidationPools() {
|
||||||
|
@ -56,7 +54,7 @@ export class Bench extends Actor {
|
||||||
.reduce((acc, cur) => (acc += cur), 0);
|
.reduce((acc, cur) => (acc += cur), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
initiateValidationPool({
|
async initiateValidationPool({
|
||||||
postId,
|
postId,
|
||||||
fee,
|
fee,
|
||||||
duration,
|
duration,
|
||||||
|
@ -84,7 +82,7 @@ export class Bench extends Actor {
|
||||||
this.scene,
|
this.scene,
|
||||||
);
|
);
|
||||||
this.validationPools.set(validationPool.id, validationPool);
|
this.validationPools.set(validationPool.id, validationPool);
|
||||||
this.actions.createValidationPool.log(this, validationPool);
|
await this.actions.createValidationPool.log(this, validationPool);
|
||||||
validationPool.activate();
|
validationPool.activate();
|
||||||
return validationPool;
|
return validationPool;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
import { DisplayValue } from './display-value.js';
|
import { DisplayValue } from './display-value.js';
|
||||||
|
import { CryptoUtil } from './crypto.js';
|
||||||
|
|
||||||
export class Box {
|
export class Box {
|
||||||
constructor(name, parentEl, elementType = 'div') {
|
constructor(name, parentEl, elementType = 'div') {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.el = document.createElement(elementType);
|
this.el = document.createElement(elementType);
|
||||||
|
this.el.id = `box_${CryptoUtil.randomUUID().replaceAll('-', '').slice(0, 8)}`;
|
||||||
this.el.classList.add('box');
|
this.el.classList.add('box');
|
||||||
|
if (name) {
|
||||||
this.el.setAttribute('box-name', name);
|
this.el.setAttribute('box-name', name);
|
||||||
|
}
|
||||||
if (parentEl) {
|
if (parentEl) {
|
||||||
parentEl.appendChild(this.el);
|
parentEl.appendChild(this.el);
|
||||||
}
|
}
|
||||||
|
@ -27,8 +31,7 @@ export class Box {
|
||||||
}
|
}
|
||||||
|
|
||||||
addBox(name, elementType) {
|
addBox(name, elementType) {
|
||||||
const box = new Box(name, null, elementType);
|
const box = new Box(name, this.el, elementType);
|
||||||
this.el.appendChild(box.el);
|
|
||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,11 +49,6 @@ export class Box {
|
||||||
return this.el.innerText;
|
return this.el.innerText;
|
||||||
}
|
}
|
||||||
|
|
||||||
setId(id) {
|
|
||||||
this.el.id = (id || this.name).replace(/ /g, '');
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
getId() {
|
getId() {
|
||||||
return this.el.id;
|
return this.el.id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ export class Business extends Actor {
|
||||||
async submitRequest(fee, content) {
|
async submitRequest(fee, content) {
|
||||||
const request = new Request(fee, content);
|
const request = new Request(fee, content);
|
||||||
this.requests.set(request.id, request);
|
this.requests.set(request.id, request);
|
||||||
this.actions.assignWork.log(this, this.availability);
|
await this.actions.assignWork.log(this, this.availability);
|
||||||
this.worker = await this.availability.assignWork(request.id);
|
this.worker = await this.availability.assignWork(request.id);
|
||||||
return request.id;
|
return request.id;
|
||||||
}
|
}
|
||||||
|
@ -54,13 +54,13 @@ export class Business extends Actor {
|
||||||
requestId,
|
requestId,
|
||||||
workEvidence,
|
workEvidence,
|
||||||
});
|
});
|
||||||
this.actions.submitPost.log(this, this.forum);
|
await this.actions.submitPost.log(this, this.forum);
|
||||||
const postId = await this.forum.addPost(reputationPublicKey, post);
|
const postId = await this.forum.addPost(reputationPublicKey, post);
|
||||||
|
|
||||||
// Initiate a validation pool for this work evidence.
|
// Initiate a validation pool for this work evidence.
|
||||||
// Validation pool supports secret ballots but we aren't using that here, since we want
|
// Validation pool supports secret ballots but we aren't using that here, since we want
|
||||||
// the post to be attributable to the reputation holder.
|
// the post to be attributable to the reputation holder.
|
||||||
this.actions.initiateValidationPool.log(this, this.bench);
|
await this.actions.initiateValidationPool.log(this, this.bench);
|
||||||
const pool = await this.bench.initiateValidationPool({
|
const pool = await this.bench.initiateValidationPool({
|
||||||
postId,
|
postId,
|
||||||
fee: request.fee,
|
fee: request.fee,
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { Actor } from './actor.js';
|
import { Actor } from './actor.js';
|
||||||
|
|
||||||
import { Action } from './action.js';
|
import { Action } from './action.js';
|
||||||
import { PostMessage } from './message.js';
|
import { PostMessage } from './message.js';
|
||||||
import { CryptoUtil } from './crypto.js';
|
import { CryptoUtil } from './crypto.js';
|
||||||
|
@ -25,7 +24,6 @@ export class Expert extends Actor {
|
||||||
// this.reputationPublicKey = await CryptoUtil.exportKey(this.reputationKey.publicKey);
|
// this.reputationPublicKey = await CryptoUtil.exportKey(this.reputationKey.publicKey);
|
||||||
this.reputationPublicKey = this.name;
|
this.reputationPublicKey = this.name;
|
||||||
this.status.set('Initialized');
|
this.status.set('Initialized');
|
||||||
this.activate();
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,19 +31,19 @@ export class Expert extends Actor {
|
||||||
// TODO: Include fee
|
// TODO: Include fee
|
||||||
const postMessage = new PostMessage({ post, stake });
|
const postMessage = new PostMessage({ post, stake });
|
||||||
await postMessage.sign(this.reputationKey);
|
await postMessage.sign(this.reputationKey);
|
||||||
this.actions.submitPostViaNetwork.log(this, forumNode, null, { id: post.id });
|
await this.actions.submitPostViaNetwork.log(this, forumNode, null, { id: post.id });
|
||||||
// For now, directly call forumNode.receiveMessage();
|
// For now, directly call forumNode.receiveMessage();
|
||||||
await forumNode.receiveMessage(JSON.stringify(postMessage.toJSON()));
|
await forumNode.receiveMessage(JSON.stringify(postMessage.toJSON()));
|
||||||
}
|
}
|
||||||
|
|
||||||
async submitPost(forum, postContent) {
|
async submitPost(forum, postContent) {
|
||||||
// TODO: Include fee
|
// TODO: Include fee
|
||||||
this.actions.submitPost.log(this, forum);
|
await this.actions.submitPost.log(this, forum);
|
||||||
return forum.addPost(this.reputationPublicKey, postContent);
|
return forum.addPost(this.reputationPublicKey, postContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
async submitPostWithFee(bench, forum, postContent, poolOptions) {
|
async submitPostWithFee(bench, forum, postContent, poolOptions) {
|
||||||
this.actions.submitPost.log(this, forum);
|
await this.actions.submitPost.log(this, forum);
|
||||||
const postId = await forum.addPost(this.reputationPublicKey, postContent);
|
const postId = await forum.addPost(this.reputationPublicKey, postContent);
|
||||||
const pool = await this.initiateValidationPool(bench, { ...poolOptions, postId, anonymous: false });
|
const pool = await this.initiateValidationPool(bench, { ...poolOptions, postId, anonymous: false });
|
||||||
return { postId, pool };
|
return { postId, pool };
|
||||||
|
@ -59,12 +57,12 @@ export class Expert extends Actor {
|
||||||
} else {
|
} else {
|
||||||
poolOptions.signingPublicKey = this.reputationPublicKey;
|
poolOptions.signingPublicKey = this.reputationPublicKey;
|
||||||
}
|
}
|
||||||
this.actions.initiateValidationPool.log(
|
await this.actions.initiateValidationPool.log(
|
||||||
this,
|
this,
|
||||||
bench,
|
bench,
|
||||||
`(fee: ${poolOptions.fee})`,
|
`(fee: ${poolOptions.fee})`,
|
||||||
);
|
);
|
||||||
const pool = bench.initiateValidationPool(poolOptions);
|
const pool = await bench.initiateValidationPool(poolOptions);
|
||||||
this.validationPools.set(pool.id, poolOptions);
|
this.validationPools.set(pool.id, poolOptions);
|
||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +80,7 @@ export class Expert extends Actor {
|
||||||
}
|
}
|
||||||
// TODO: encrypt vote
|
// TODO: encrypt vote
|
||||||
// TODO: sign message
|
// TODO: sign message
|
||||||
this.actions.castVote.log(
|
await this.actions.castVote.log(
|
||||||
this,
|
this,
|
||||||
validationPool,
|
validationPool,
|
||||||
`(${position ? 'for' : 'against'}, stake: ${stake}, anonymous: ${anonymous})`,
|
`(${position ? 'for' : 'against'}, stake: ${stake}, anonymous: ${anonymous})`,
|
||||||
|
@ -95,12 +93,12 @@ export class Expert extends Actor {
|
||||||
async revealIdentity(validationPool) {
|
async revealIdentity(validationPool) {
|
||||||
const { signingPublicKey } = this.validationPools.get(validationPool.id);
|
const { signingPublicKey } = this.validationPools.get(validationPool.id);
|
||||||
// TODO: sign message
|
// TODO: sign message
|
||||||
this.actions.revealIdentity.log(this, validationPool);
|
await this.actions.revealIdentity.log(this, validationPool);
|
||||||
validationPool.revealIdentity(signingPublicKey, this.reputationPublicKey);
|
validationPool.revealIdentity(signingPublicKey, this.reputationPublicKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
async registerAvailability(availability, stake) {
|
async registerAvailability(availability, stake) {
|
||||||
this.actions.registerAvailability.log(this, availability, `(stake: ${stake})`);
|
await this.actions.registerAvailability.log(this, availability, `(stake: ${stake})`);
|
||||||
await availability.register(this.reputationPublicKey, stake);
|
await availability.register(this.reputationPublicKey, stake);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +109,7 @@ export class Expert extends Actor {
|
||||||
}
|
}
|
||||||
|
|
||||||
async submitWork(business, requestId, evidence, { tokenLossRatio, duration }) {
|
async submitWork(business, requestId, evidence, { tokenLossRatio, duration }) {
|
||||||
this.actions.submitWork.log(this, business);
|
await this.actions.submitWork.log(this, business);
|
||||||
return business.submitWork(this.reputationPublicKey, requestId, evidence, { tokenLossRatio, duration });
|
return business.submitWork(this.reputationPublicKey, requestId, evidence, { tokenLossRatio, duration });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ export class ForumNode extends Actor {
|
||||||
.filter((forumNode) => forumNode.keyPair.publicKey !== this.keyPair.publicKey);
|
.filter((forumNode) => forumNode.keyPair.publicKey !== this.keyPair.publicKey);
|
||||||
for (const forumNode of otherForumNodes) {
|
for (const forumNode of otherForumNodes) {
|
||||||
// For now just call receiveMessage on the target node
|
// For now just call receiveMessage on the target node
|
||||||
this.actions.peerMessage.log(this, forumNode, null, message.content);
|
await this.actions.peerMessage.log(this, forumNode, null, message.content);
|
||||||
await forumNode.receiveMessage(JSON.stringify(message.toJSON()));
|
await forumNode.receiveMessage(JSON.stringify(message.toJSON()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ export class ForumNode extends Actor {
|
||||||
try {
|
try {
|
||||||
await Message.verify(messageJson);
|
await Message.verify(messageJson);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.actions.processMessage.log(this, this, 'invalid signature', messageJson, '-x');
|
await this.actions.processMessage.log(this, this, 'invalid signature', messageJson, '-x');
|
||||||
console.log(`${this.name}: received message with invalid signature`);
|
console.log(`${this.name}: received message with invalid signature`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ export class ForumNode extends Actor {
|
||||||
if (!post.id) {
|
if (!post.id) {
|
||||||
post.id = CryptoUtil.randomUUID();
|
post.id = CryptoUtil.randomUUID();
|
||||||
}
|
}
|
||||||
this.actions.storePost.log(this, this, null, { authorId, post, stake });
|
await this.actions.storePost.log(this, this, null, { authorId, post, stake });
|
||||||
this.forumView.addPost(authorId, post.id, post, stake);
|
this.forumView.addPost(authorId, post.id, post, stake);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ class Post extends Actor {
|
||||||
this.authorPublicKey = authorPublicKey;
|
this.authorPublicKey = authorPublicKey;
|
||||||
this.value = 0;
|
this.value = 0;
|
||||||
this.citations = postContent.citations;
|
this.citations = postContent.citations;
|
||||||
|
this.title = postContent.title;
|
||||||
this.totalCitationWeight = this.citations.reduce((total, { weight }) => total += weight, 0);
|
this.totalCitationWeight = this.citations.reduce((total, { weight }) => total += weight, 0);
|
||||||
if (this.totalCitationWeight > params.revaluationLimit) {
|
if (this.totalCitationWeight > params.revaluationLimit) {
|
||||||
throw new Error('Post total citation weight exceeds revaluation limit '
|
throw new Error('Post total citation weight exceeds revaluation limit '
|
||||||
|
@ -23,8 +24,8 @@ class Post extends Actor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setPostValue(value) {
|
async setPostValue(value) {
|
||||||
this.setValue('value', value);
|
await this.setValue('value', value);
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ class Post extends Actor {
|
||||||
export class Forum extends Actor {
|
export class Forum extends Actor {
|
||||||
constructor(name, scene) {
|
constructor(name, scene) {
|
||||||
super(name, scene);
|
super(name, scene);
|
||||||
this.posts = new Graph();
|
this.posts = new Graph(scene);
|
||||||
this.actions = {
|
this.actions = {
|
||||||
addPost: new Action('add post', scene),
|
addPost: new Action('add post', scene),
|
||||||
};
|
};
|
||||||
|
@ -47,9 +48,9 @@ export class Forum extends Actor {
|
||||||
|
|
||||||
async addPost(authorId, postContent) {
|
async addPost(authorId, postContent) {
|
||||||
const post = new Post(this, authorId, postContent);
|
const post = new Post(this, authorId, postContent);
|
||||||
this.actions.addPost.log(this, post);
|
await this.actions.addPost.log(this, post);
|
||||||
this.posts.addVertex(post.id, post);
|
this.posts.addVertex(post.id, post, post.title);
|
||||||
for (const { postId: citedPostId, weight } of postContent.citations) {
|
for (const { postId: citedPostId, weight } of post.citations) {
|
||||||
this.posts.addEdge('citation', post.id, citedPostId, { weight });
|
this.posts.addEdge('citation', post.id, citedPostId, { weight });
|
||||||
}
|
}
|
||||||
return post.id;
|
return post.id;
|
||||||
|
@ -63,7 +64,7 @@ export class Forum extends Actor {
|
||||||
return this.posts.getVertices();
|
return this.posts.getVertices();
|
||||||
}
|
}
|
||||||
|
|
||||||
propagateValue(postId, increment, depth = 0) {
|
async propagateValue(postId, increment, depth = 0) {
|
||||||
if (depth > params.maxPropagationDepth) {
|
if (depth > params.maxPropagationDepth) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
@ -78,7 +79,7 @@ export class Forum extends Actor {
|
||||||
|
|
||||||
// Increment the value of the given post
|
// Increment the value of the given post
|
||||||
const postValue = post.getPostValue();
|
const postValue = post.getPostValue();
|
||||||
post.setPostValue(postValue + increment);
|
await post.setPostValue(postValue + increment);
|
||||||
|
|
||||||
// Award reputation to post author
|
// Award reputation to post author
|
||||||
console.log('reward for post author', post.authorPublicKey, increment);
|
console.log('reward for post author', post.authorPublicKey, increment);
|
||||||
|
@ -86,7 +87,7 @@ export class Forum extends Actor {
|
||||||
|
|
||||||
// Recursively distribute reputation to citations, according to weights
|
// Recursively distribute reputation to citations, according to weights
|
||||||
for (const { postId: citedPostId, weight } of post.citations) {
|
for (const { postId: citedPostId, weight } of post.citations) {
|
||||||
addRewards(this.propagateValue(citedPostId, weight * increment, depth + 1));
|
addRewards(await this.propagateValue(citedPostId, weight * increment, depth + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
return rewards;
|
return rewards;
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
import mermaid from 'https://unpkg.com/mermaid@9.2.2/dist/mermaid.esm.min.mjs';
|
|
||||||
import { debounce } from '../util.js';
|
|
||||||
|
|
||||||
export class Vertex {
|
export class Vertex {
|
||||||
constructor(data) {
|
constructor(data) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
@ -29,13 +26,14 @@ export class Edge {
|
||||||
export class CategorizedEdges {}
|
export class CategorizedEdges {}
|
||||||
|
|
||||||
export class Graph {
|
export class Graph {
|
||||||
constructor() {
|
constructor(scene) {
|
||||||
|
this.scene = scene;
|
||||||
this.vertices = new Map();
|
this.vertices = new Map();
|
||||||
this.edgeLabels = new Map();
|
this.edgeLabels = new Map();
|
||||||
this.nextVertexId = 0;
|
this.nextVertexId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
addVertex(id, data) {
|
addVertex(id, data, label) {
|
||||||
// Support simple case of auto-incremented numeric ids
|
// Support simple case of auto-incremented numeric ids
|
||||||
if (typeof id === 'object') {
|
if (typeof id === 'object') {
|
||||||
data = id;
|
data = id;
|
||||||
|
@ -46,6 +44,9 @@ export class Graph {
|
||||||
}
|
}
|
||||||
const vertex = new Vertex(data);
|
const vertex = new Vertex(data);
|
||||||
this.vertices.set(id, vertex);
|
this.vertices.set(id, vertex);
|
||||||
|
if (this.scene.flowchart) {
|
||||||
|
this.scene.flowchart.log(`${id}[${label ?? id}]`);
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,6 +84,9 @@ export class Graph {
|
||||||
this.setEdge(label, from, to, edge);
|
this.setEdge(label, from, to, edge);
|
||||||
this.getVertex(from).edges.from.push(edge);
|
this.getVertex(from).edges.from.push(edge);
|
||||||
this.getVertex(to).edges.to.push(edge);
|
this.getVertex(to).edges.to.push(edge);
|
||||||
|
if (this.scene.flowchart) {
|
||||||
|
this.scene.flowchart.log(`${from} --> ${to}`);
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,20 +105,4 @@ export class Graph {
|
||||||
countVertices() {
|
countVertices() {
|
||||||
return this.vertices.size;
|
return this.vertices.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
async renderGraph() {
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
this.dateLastRender = dateStart;
|
|
||||||
};
|
|
||||||
debounce(render, 100);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,18 +28,27 @@ export class PostContent {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setTitle(title) {
|
||||||
|
this.title = title;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
toJSON() {
|
toJSON() {
|
||||||
return {
|
return {
|
||||||
content: this.content,
|
content: this.content,
|
||||||
citations: this.citations.map((citation) => citation.toJSON()),
|
citations: this.citations.map((citation) => citation.toJSON()),
|
||||||
...(this.id ? { id: this.id } : {}),
|
...(this.id ? { id: this.id } : {}),
|
||||||
|
title: this.title,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromJSON({ id, content, citations }) {
|
static fromJSON({
|
||||||
|
id, content, citations, title,
|
||||||
|
}) {
|
||||||
const post = new PostContent(content);
|
const post = new PostContent(content);
|
||||||
post.citations = citations.map((citation) => Citation.fromJSON(citation));
|
post.citations = citations.map((citation) => Citation.fromJSON(citation));
|
||||||
post.id = id;
|
post.id = id;
|
||||||
|
post.title = title;
|
||||||
return post;
|
return post;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,24 +3,47 @@ import { Actor } from './actor.js';
|
||||||
import { Action } from './action.js';
|
import { Action } from './action.js';
|
||||||
import { debounce } from '../util.js';
|
import { debounce } from '../util.js';
|
||||||
|
|
||||||
|
class MermaidDiagram {
|
||||||
|
constructor(box) {
|
||||||
|
this.box = box;
|
||||||
|
this.container = this.box.addBox('Container');
|
||||||
|
this.element = this.box.addBox('Element');
|
||||||
|
this.renderBox = this.box.addBox('Render');
|
||||||
|
this.box.addBox('Spacer').setInnerHTML(' ');
|
||||||
|
this.logBox = this.box.addBox('Log');
|
||||||
|
}
|
||||||
|
|
||||||
|
async log(msg, render = true) {
|
||||||
|
this.logBox.addBox().setInnerHTML(msg).monospace();
|
||||||
|
if (render) {
|
||||||
|
await this.render();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
async render() {
|
||||||
|
const render = async () => {
|
||||||
|
const innerText = this.logBox.getInnerText();
|
||||||
|
const graph = await mermaid.mermaidAPI.render(
|
||||||
|
this.element.getId(),
|
||||||
|
innerText,
|
||||||
|
);
|
||||||
|
this.renderBox.setInnerHTML(graph);
|
||||||
|
};
|
||||||
|
await debounce(render, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class Scene {
|
export class Scene {
|
||||||
constructor(name, rootBox) {
|
constructor(name, rootBox) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.box = rootBox.addBox(name);
|
this.box = rootBox.addBox(name);
|
||||||
this.titleBox = this.box.addBox().setInnerHTML(name);
|
this.titleBox = this.box.addBox('Title').setInnerHTML(name);
|
||||||
this.box.addBox('Spacer').setInnerHTML(' ');
|
this.box.addBox('Spacer').setInnerHTML(' ');
|
||||||
this.displayValuesBox = this.box.addBox(`${this.name}-values`);
|
this.displayValuesBox = this.box.addBox('Values');
|
||||||
this.box.addBox('Spacer').setInnerHTML(' ');
|
this.box.addBox('Spacer').setInnerHTML(' ');
|
||||||
this.actors = new Set();
|
this.actors = new Set();
|
||||||
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({
|
mermaid.mermaidAPI.initialize({
|
||||||
startOnLoad: false,
|
startOnLoad: false,
|
||||||
theme: 'base',
|
theme: 'base',
|
||||||
|
@ -28,18 +51,37 @@ export class Scene {
|
||||||
darkMode: true,
|
darkMode: true,
|
||||||
primaryColor: '#2a5b6c',
|
primaryColor: '#2a5b6c',
|
||||||
primaryTextColor: '#b6b6b6',
|
primaryTextColor: '#b6b6b6',
|
||||||
|
// lineColor: '#349cbd',
|
||||||
|
lineColor: '#57747d',
|
||||||
|
signalColor: '#57747d',
|
||||||
|
// signalColor: '#349cbd',
|
||||||
noteBkgColor: '#516f77',
|
noteBkgColor: '#516f77',
|
||||||
noteTextColor: '#cecece',
|
noteTextColor: '#cecece',
|
||||||
activationBkgColor: '#1d3f49',
|
activationBkgColor: '#1d3f49',
|
||||||
activationBorderColor: '#569595',
|
activationBorderColor: '#569595',
|
||||||
signalColor: '#57747d',
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
this.dateLastRender = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addActor(name) {
|
withSequenceDiagram() {
|
||||||
|
const box = this.box.addBox('Sequence diagram');
|
||||||
|
this.sequence = new MermaidDiagram(box);
|
||||||
|
this.sequence.log('sequenceDiagram', false);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
withFlowchart(direction = 'BT') {
|
||||||
|
const box = this.box.addBox('Flowchart');
|
||||||
|
this.flowchart = new MermaidDiagram(box);
|
||||||
|
this.flowchart.log(`graph ${direction}`, false);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
async addActor(name) {
|
||||||
const actor = new Actor(name, this);
|
const actor = new Actor(name, this);
|
||||||
|
if (this.sequence) {
|
||||||
|
await this.scene.sequence.log(`participant ${name}`);
|
||||||
|
}
|
||||||
return actor;
|
return actor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,12 +99,6 @@ export class Scene {
|
||||||
return dv;
|
return dv;
|
||||||
}
|
}
|
||||||
|
|
||||||
log(msg) {
|
|
||||||
this.logBox.addBox().setInnerHTML(msg).monospace();
|
|
||||||
this.renderSequenceDiagram();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
deactivateAll() {
|
deactivateAll() {
|
||||||
for (const actor of this.actors.values()) {
|
for (const actor of this.actors.values()) {
|
||||||
while (actor.active) {
|
while (actor.active) {
|
||||||
|
@ -70,20 +106,4 @@ export class Scene {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
this.dateLastRender = dateStart;
|
|
||||||
};
|
|
||||||
debounce(render, 100);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,12 +193,12 @@ export class ValidationPool extends Actor {
|
||||||
|
|
||||||
if (quorumMet) {
|
if (quorumMet) {
|
||||||
this.setStatus(`Resolved - ${result ? 'Won' : 'Lost'}`);
|
this.setStatus(`Resolved - ${result ? 'Won' : 'Lost'}`);
|
||||||
this.scene.log(`note over ${this.name} : ${result ? 'Win' : 'Lose'}`);
|
this.scene.sequence.log(`note over ${this.name} : ${result ? 'Win' : 'Lose'}`);
|
||||||
this.applyTokenLocking();
|
this.applyTokenLocking();
|
||||||
this.distributeTokens(result);
|
await this.distributeTokens(result);
|
||||||
} else {
|
} else {
|
||||||
this.setStatus('Resolved - Quorum not met');
|
this.setStatus('Resolved - Quorum not met');
|
||||||
this.scene.log(`note over ${this.name} : Quorum not met`);
|
this.scene.sequence.log(`note over ${this.name} : Quorum not met`);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.deactivate();
|
this.deactivate();
|
||||||
|
@ -206,7 +206,7 @@ export class ValidationPool extends Actor {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
distributeTokens({ votePasses }) {
|
async distributeTokens({ votePasses }) {
|
||||||
const rewards = new Map();
|
const rewards = new Map();
|
||||||
const addReward = (id, value) => rewards.set(id, (rewards.get(id) ?? 0) + value);
|
const addReward = (id, value) => rewards.set(id, (rewards.get(id) ?? 0) + value);
|
||||||
|
|
||||||
|
@ -231,7 +231,7 @@ export class ValidationPool extends Actor {
|
||||||
|
|
||||||
if (votePasses && !!this.forum) {
|
if (votePasses && !!this.forum) {
|
||||||
// Recurse through forum to determine reputation effects
|
// Recurse through forum to determine reputation effects
|
||||||
const forumReputationEffects = this.forum.propagateValue(this.postId, this.tokensMinted);
|
const forumReputationEffects = await this.forum.propagateValue(this.postId, this.tokensMinted);
|
||||||
for (const [id, value] of forumReputationEffects) {
|
for (const [id, value] of forumReputationEffects) {
|
||||||
addReward(id, value);
|
addReward(id, value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,5 +14,6 @@
|
||||||
<li><a href="/tests/debounce.html">Debounce</a></li>
|
<li><a href="/tests/debounce.html">Debounce</a></li>
|
||||||
<li><a href="/tests/availability.html">Availability</a></li>
|
<li><a href="/tests/availability.html">Availability</a></li>
|
||||||
<li><a href="/tests/forum.html">Forum</a></li>
|
<li><a href="/tests/forum.html">Forum</a></li>
|
||||||
|
<li><a href="/tests/flowchart.html">Flowchart</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -56,13 +56,13 @@
|
||||||
|
|
||||||
const updateDisplayValues = async () => {
|
const updateDisplayValues = async () => {
|
||||||
for (const expert of experts) {
|
for (const expert of experts) {
|
||||||
expert.setValue(
|
await expert.setValue(
|
||||||
"rep",
|
"rep",
|
||||||
bench.reputations.getTokens(expert.reputationPublicKey)
|
bench.reputations.getTokens(expert.reputationPublicKey)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
bench.setValue("total rep", bench.getTotalReputation());
|
await bench.setValue("total rep", bench.getTotalReputation());
|
||||||
await scene.renderSequenceDiagram();
|
await scene.sequence.render();
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateDisplayValuesAndDelay = async () => {
|
const updateDisplayValuesAndDelay = async () => {
|
||||||
|
@ -77,7 +77,7 @@
|
||||||
request = await expert.getAssignedWork(availability, business);
|
request = await expert.getAssignedWork(availability, business);
|
||||||
if (request) {
|
if (request) {
|
||||||
worker = expert;
|
worker = expert;
|
||||||
worker.actions.getAssignedWork.log(worker, availability);
|
await worker.actions.getAssignedWork.log(worker, availability);
|
||||||
worker.activate();
|
worker.activate();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<head>
|
||||||
|
<title>Debounce test</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="/index.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="debounce-test"></div>
|
||||||
|
</body>
|
||||||
|
<script type="module">
|
||||||
|
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));
|
||||||
|
|
||||||
|
let eventCount = 0;
|
||||||
|
const event = () => {
|
||||||
|
eventCount++;
|
||||||
|
console.log(`event ${eventCount}`);
|
||||||
|
};
|
||||||
|
await debounce(event, 500);
|
||||||
|
await debounce(event, 500);
|
||||||
|
await delay(500);
|
||||||
|
await debounce(event, 500);
|
||||||
|
await debounce(event, 500);
|
||||||
|
if (eventCount !== 2) {
|
||||||
|
throw new Error(`Expected 2 events, got ${eventCount}`);
|
||||||
|
}
|
||||||
|
console.log(`eventCount: ${eventCount}`);
|
||||||
|
</script>
|
|
@ -0,0 +1,39 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<head>
|
||||||
|
<title>Flowchart test</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="/index.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="flowchart-test"></div>
|
||||||
|
</body>
|
||||||
|
<script type="module">
|
||||||
|
import { Box } from "/classes/box.js";
|
||||||
|
import { Scene } from "/classes/scene.js";
|
||||||
|
import { Actor } from "/classes/actor.js";
|
||||||
|
import { Action } from "/classes/action.js";
|
||||||
|
import { Expert } from "/classes/expert.js";
|
||||||
|
import { delay } from "/util.js";
|
||||||
|
|
||||||
|
const DEFAULT_DELAY_INTERVAL = 500;
|
||||||
|
|
||||||
|
const rootElement = document.getElementById("flowchart-test");
|
||||||
|
const rootBox = new Box("rootBox", rootElement).flex();
|
||||||
|
|
||||||
|
const scene = (window.scene = new Scene("Flowchart test", rootBox));
|
||||||
|
scene.withSequenceDiagram();
|
||||||
|
|
||||||
|
const actor1 = new Actor("A", scene);
|
||||||
|
const actor2 = new Actor("B", scene);
|
||||||
|
const action1 = new Action("Action 1", scene);
|
||||||
|
await action1.log(actor1, actor2);
|
||||||
|
await actor1.setValue("value", 1);
|
||||||
|
|
||||||
|
await scene.withFlowchart();
|
||||||
|
await scene.flowchart.log("A --> B");
|
||||||
|
|
||||||
|
await delay(DEFAULT_DELAY_INTERVAL);
|
||||||
|
action1.log(actor1, actor2);
|
||||||
|
|
||||||
|
await delay(DEFAULT_DELAY_INTERVAL);
|
||||||
|
await scene.flowchart.log("A --> C");
|
||||||
|
</script>
|
|
@ -43,7 +43,7 @@
|
||||||
await window.forumNode2.processNextMessage();
|
await window.forumNode2.processNextMessage();
|
||||||
await window.forumNode3.processNextMessage();
|
await window.forumNode3.processNextMessage();
|
||||||
|
|
||||||
await window.scene.renderSequenceDiagram();
|
await window.scene.sequence.render();
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|
||||||
// const blockchain = new Blockchain();
|
// const blockchain = new Blockchain();
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
const rootElement = document.getElementById("forum-test");
|
const rootElement = document.getElementById("forum-test");
|
||||||
const rootBox = new Box("rootBox", rootElement).flex();
|
const rootBox = new Box("rootBox", rootElement).flex();
|
||||||
|
|
||||||
const scene = (window.scene = new Scene("Forum test", rootBox).log(
|
const scene = (window.scene = new Scene("Forum test", rootBox));
|
||||||
"sequenceDiagram"
|
scene.withSequenceDiagram();
|
||||||
));
|
scene.withFlowchart();
|
||||||
|
|
||||||
const experts = (window.experts = []);
|
const experts = (window.experts = []);
|
||||||
const newExpert = async () => {
|
const newExpert = async () => {
|
||||||
|
@ -44,13 +44,12 @@
|
||||||
|
|
||||||
const updateDisplayValues = async () => {
|
const updateDisplayValues = async () => {
|
||||||
for (const expert of experts) {
|
for (const expert of experts) {
|
||||||
expert.setValue(
|
await expert.setValue(
|
||||||
"rep",
|
"rep",
|
||||||
bench.reputations.getTokens(expert.reputationPublicKey)
|
bench.reputations.getTokens(expert.reputationPublicKey)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
bench.setValue("total rep", bench.getTotalReputation());
|
await bench.setValue("total rep", bench.getTotalReputation());
|
||||||
await scene.renderSequenceDiagram();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateDisplayValuesAndDelay = async (delayMs) => {
|
const updateDisplayValuesAndDelay = async (delayMs) => {
|
||||||
|
@ -63,7 +62,7 @@
|
||||||
const { postId: postId1, pool: pool1 } = await expert1.submitPostWithFee(
|
const { postId: postId1, pool: pool1 } = await expert1.submitPostWithFee(
|
||||||
bench,
|
bench,
|
||||||
forum,
|
forum,
|
||||||
new PostContent({ hello: "there" }),
|
new PostContent({ hello: "there" }).setTitle("Post 1"),
|
||||||
{
|
{
|
||||||
fee: 10,
|
fee: 10,
|
||||||
duration: 1000,
|
duration: 1000,
|
||||||
|
@ -81,7 +80,9 @@
|
||||||
const { postId: postId2, pool: pool2 } = await expert2.submitPostWithFee(
|
const { postId: postId2, pool: pool2 } = await expert2.submitPostWithFee(
|
||||||
bench,
|
bench,
|
||||||
forum,
|
forum,
|
||||||
new PostContent({ hello: "to you as well" }).addCitation(postId1, 0.5),
|
new PostContent({ hello: "to you as well" })
|
||||||
|
.setTitle("Post 2")
|
||||||
|
.addCitation(postId1, 0.5),
|
||||||
{
|
{
|
||||||
fee: 10,
|
fee: 10,
|
||||||
duration: 1000,
|
duration: 1000,
|
||||||
|
@ -99,7 +100,9 @@
|
||||||
const { pool: pool3 } = await expert3.submitPostWithFee(
|
const { pool: pool3 } = await expert3.submitPostWithFee(
|
||||||
bench,
|
bench,
|
||||||
forum,
|
forum,
|
||||||
new PostContent({ hello: "y'all" }).addCitation(postId2, 0.5),
|
new PostContent({ hello: "y'all" })
|
||||||
|
.setTitle("Post 3")
|
||||||
|
.addCitation(postId2, 0.5),
|
||||||
{
|
{
|
||||||
fee: 10,
|
fee: 10,
|
||||||
duration: 1000,
|
duration: 1000,
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<head>
|
||||||
|
<title>Forum Graph</title>
|
||||||
|
<link type="text/css" rel="stylesheet" href="/index.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="graph-test"></div>
|
||||||
|
</body>
|
||||||
|
<script type="module">
|
||||||
|
import { Box } from "/classes/box.js";
|
||||||
|
import { Scene } from "/classes/scene.js";
|
||||||
|
import { Graph } from "/classes/graph.js";
|
||||||
|
|
||||||
|
const rootElement = document.getElementById("graph-test");
|
||||||
|
const rootBox = new Box("rootBox", rootElement).flex();
|
||||||
|
|
||||||
|
window.scene = new Scene("Graph test", rootBox);
|
||||||
|
|
||||||
|
window.graph = new Graph();
|
||||||
|
|
||||||
|
window.v = [];
|
||||||
|
function addVertex() {
|
||||||
|
const vertex = window.graph.addVertex({ seq: window.v.length });
|
||||||
|
window.v.push(vertex);
|
||||||
|
}
|
||||||
|
addVertex();
|
||||||
|
addVertex();
|
||||||
|
addVertex();
|
||||||
|
addVertex();
|
||||||
|
addVertex();
|
||||||
|
|
||||||
|
window.graph.addEdge("e1", 0, 1);
|
||||||
|
</script>
|
|
@ -17,9 +17,8 @@
|
||||||
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(
|
const scene = (window.scene = new Scene("Validation Pool test", rootBox));
|
||||||
"sequenceDiagram"
|
await scene.withSequenceDiagram();
|
||||||
));
|
|
||||||
const expert1 = (window.expert1 = await new Expert(
|
const expert1 = (window.expert1 = await new Expert(
|
||||||
"Expert1",
|
"Expert1",
|
||||||
scene
|
scene
|
||||||
|
@ -31,21 +30,21 @@
|
||||||
const bench = (window.bench = new Bench(undefined, "Bench", scene));
|
const bench = (window.bench = new Bench(undefined, "Bench", scene));
|
||||||
|
|
||||||
const updateDisplayValues = async () => {
|
const updateDisplayValues = async () => {
|
||||||
expert1.setValue(
|
await expert1.setValue(
|
||||||
"rep",
|
"rep",
|
||||||
bench.reputations.getTokens(expert1.reputationPublicKey)
|
bench.reputations.getTokens(expert1.reputationPublicKey)
|
||||||
);
|
);
|
||||||
expert2.setValue(
|
await expert2.setValue(
|
||||||
"rep",
|
"rep",
|
||||||
bench.reputations.getTokens(expert2.reputationPublicKey)
|
bench.reputations.getTokens(expert2.reputationPublicKey)
|
||||||
);
|
);
|
||||||
bench.setValue("total rep", bench.getTotalReputation());
|
await bench.setValue("total rep", bench.getTotalReputation());
|
||||||
// With params.lockingTimeExponent = 0 and params.activeVoterThreshold = null,
|
// With params.lockingTimeExponent = 0 and params.activeVoterThreshold = null,
|
||||||
// these next 3 propetries are all equal to total rep
|
// these next 3 propetries are all equal to total rep
|
||||||
// bench.setValue('available rep', bench.getTotalAvailableReputation());
|
// await bench.setValue('available rep', bench.getTotalAvailableReputation());
|
||||||
// bench.setValue('active rep', bench.getTotalActiveReputation());
|
// await bench.setValue('active rep', bench.getTotalActiveReputation());
|
||||||
// bench.setValue('active available rep', bench.getTotalActiveAvailableReputation());
|
// await bench.setValue('active available rep', bench.getTotalActiveAvailableReputation());
|
||||||
await scene.renderSequenceDiagram();
|
await scene.sequence.render();
|
||||||
};
|
};
|
||||||
|
|
||||||
updateDisplayValues();
|
updateDisplayValues();
|
||||||
|
|
|
@ -1,17 +1,20 @@
|
||||||
const timeouts = new Map();
|
const timers = new Map();
|
||||||
|
|
||||||
export const debounce = (fn, delay) => {
|
export const debounce = async (fn, delayMs) => {
|
||||||
const key = fn.toString();
|
const timer = timers.get(fn);
|
||||||
if (!timeouts.get(key)) {
|
if (timer) {
|
||||||
timeouts.set(key, setTimeout(async () => {
|
return timer.result;
|
||||||
timeouts.delete(key);
|
|
||||||
await fn();
|
|
||||||
}, delay));
|
|
||||||
}
|
}
|
||||||
|
const result = await fn();
|
||||||
|
timers.set(fn, { result });
|
||||||
|
setTimeout(() => {
|
||||||
|
timers.delete(fn);
|
||||||
|
}, delayMs);
|
||||||
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const delay = async (ms) => {
|
export const delay = async (delayMs) => {
|
||||||
await new Promise((resolve) => {
|
await new Promise((resolve) => {
|
||||||
setTimeout(resolve, ms);
|
setTimeout(resolve, delayMs);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue