Enable easy show/hide experts when coding forum tests
This commit is contained in:
parent
e6969fde81
commit
3141d07a41
|
@ -1,7 +1,9 @@
|
||||||
import { Action } from '../display/action.js';
|
import { Action } from '../display/action.js';
|
||||||
import { PostMessage } from '../forum-network/message.js';
|
import { PostMessage } from '../forum-network/message.js';
|
||||||
import { CryptoUtil } from '../util/crypto.js';
|
import { CryptoUtil } from '../supporting/crypto.js';
|
||||||
import { ReputationHolder } from '../reputation/reputation-holder.js';
|
import { ReputationHolder } from '../reputation/reputation-holder.js';
|
||||||
|
import { EdgeTypes } from '../../util/constants.js';
|
||||||
|
import { displayNumber } from '../../util/helpers.js';
|
||||||
|
|
||||||
export class Expert extends ReputationHolder {
|
export class Expert extends ReputationHolder {
|
||||||
constructor(dao, name, scene, options) {
|
constructor(dao, name, scene, options) {
|
||||||
|
@ -20,6 +22,25 @@ export class Expert extends ReputationHolder {
|
||||||
this.tokens = [];
|
this.tokens = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getReputation() {
|
||||||
|
const authorVertex = this.dao.forum.graph.getVertex(this.reputationPublicKey);
|
||||||
|
if (!authorVertex) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const authorEdges = authorVertex.getEdges(EdgeTypes.AUTHOR, false);
|
||||||
|
const tokenValues = authorEdges.map(({ data: { tokenId } }) => this.dao.reputation.valueOf(tokenId));
|
||||||
|
return tokenValues.reduce((value, total) => total += value, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
getLabel() {
|
||||||
|
return `${this.name}
|
||||||
|
<table><tr>
|
||||||
|
<td>reputation</td>
|
||||||
|
<td>${displayNumber(this.getReputation())}</td>
|
||||||
|
</tr></table>`
|
||||||
|
.replaceAll(/\n\s*/g, '');
|
||||||
|
}
|
||||||
|
|
||||||
async initialize() {
|
async initialize() {
|
||||||
this.reputationKey = await CryptoUtil.generateAsymmetricKey();
|
this.reputationKey = await CryptoUtil.generateAsymmetricKey();
|
||||||
// this.reputationPublicKey = await CryptoUtil.exportKey(this.reputationKey.publicKey);
|
// this.reputationPublicKey = await CryptoUtil.exportKey(this.reputationKey.publicKey);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Action } from '../display/action.js';
|
import { Action } from '../display/action.js';
|
||||||
import { Actor } from '../display/actor.js';
|
import { Actor } from '../display/actor.js';
|
||||||
import { CryptoUtil } from '../util/crypto.js';
|
import { CryptoUtil } from '../supporting/crypto.js';
|
||||||
|
|
||||||
class Worker {
|
class Worker {
|
||||||
constructor(reputationPublicKey, tokenId, stakeAmount, duration) {
|
constructor(reputationPublicKey, tokenId, stakeAmount, duration) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { randomID } from '../../util.js';
|
import { randomID } from '../../util/helpers.js';
|
||||||
import { Action } from '../display/action.js';
|
import { Action } from '../display/action.js';
|
||||||
import { Actor } from '../display/actor.js';
|
import { Actor } from '../display/actor.js';
|
||||||
import { PostContent } from '../util/post-content.js';
|
import { PostContent } from '../supporting/post-content.js';
|
||||||
|
|
||||||
class Request {
|
class Request {
|
||||||
static nextSeq = 0;
|
static nextSeq = 0;
|
||||||
|
|
|
@ -3,18 +3,10 @@ import { Action } from '../display/action.js';
|
||||||
import { Actor } from '../display/actor.js';
|
import { Actor } from '../display/actor.js';
|
||||||
import params from '../../params.js';
|
import params from '../../params.js';
|
||||||
import { ReputationHolder } from '../reputation/reputation-holder.js';
|
import { ReputationHolder } from '../reputation/reputation-holder.js';
|
||||||
import { displayNumber, EPSILON, INCINERATOR_ADDRESS } from '../../util.js';
|
import { displayNumber } from '../../util/helpers.js';
|
||||||
|
import {
|
||||||
const EdgeTypes = {
|
EPSILON, INCINERATOR_ADDRESS, EdgeTypes, VertexTypes,
|
||||||
CITATION: 'citation',
|
} from '../../util/constants.js';
|
||||||
BALANCE: 'balance',
|
|
||||||
AUTHOR: 'author',
|
|
||||||
};
|
|
||||||
|
|
||||||
const VertexTypes = {
|
|
||||||
POST: 'post',
|
|
||||||
AUTHOR: 'author',
|
|
||||||
};
|
|
||||||
|
|
||||||
class Post extends Actor {
|
class Post extends Actor {
|
||||||
constructor(forum, senderId, postContent) {
|
constructor(forum, senderId, postContent) {
|
||||||
|
@ -65,36 +57,7 @@ class Post extends Actor {
|
||||||
async setValue(value) {
|
async setValue(value) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
await this.setDisplayValue('value', value);
|
await this.setDisplayValue('value', value);
|
||||||
this.forum.graph.setVertexDisplayLabel(this.id, this.getLabel());
|
this.forum.graph.getVertex(this.id).setDisplayLabel(this.getLabel());
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Author extends Actor {
|
|
||||||
constructor(forum, publicKey) {
|
|
||||||
super(publicKey, forum.scene);
|
|
||||||
this.forum = forum;
|
|
||||||
this.publicKey = publicKey;
|
|
||||||
this.name = publicKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
getReputation() {
|
|
||||||
const authorVertex = this.forum.graph.getVertex(this.publicKey);
|
|
||||||
if (!authorVertex) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
const authorEdges = authorVertex.getEdges(EdgeTypes.AUTHOR, false);
|
|
||||||
const tokenValues = authorEdges.map(({ data: { tokenId } }) => this.forum.dao.reputation.valueOf(tokenId));
|
|
||||||
console.log('getReputation', { authorEdges, tokenValues });
|
|
||||||
return tokenValues.reduce((value, total) => total += value, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
getLabel() {
|
|
||||||
return `${this.name}
|
|
||||||
<table><tr>
|
|
||||||
<td>reputation</td>
|
|
||||||
<td>${displayNumber(this.getReputation())}</td>
|
|
||||||
</tr></table>`
|
|
||||||
.replaceAll(/\n\s*/g, '');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,21 +118,29 @@ export class Forum extends ReputationHolder {
|
||||||
const post = postVertex.data;
|
const post = postVertex.data;
|
||||||
post.setStatus('Validated');
|
post.setStatus('Validated');
|
||||||
post.initialValue = initialValue;
|
post.initialValue = initialValue;
|
||||||
this.graph.setVertexDisplayLabel(post.id, post.getLabel());
|
postVertex.setDisplayLabel(post.getLabel());
|
||||||
|
|
||||||
const addAuthorToGraph = (publicKey, weight, authorTokenId) => {
|
const addAuthorToGraph = (publicKey, weight, authorTokenId) => {
|
||||||
const author = new Author(this, publicKey);
|
// For graph display purposes, we want to use the existing Expert actors from the current scene.
|
||||||
|
const author = this.scene.findActor(({ reputationPublicKey }) => reputationPublicKey === publicKey);
|
||||||
|
if (author.options.hide) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
author.setDisplayValue('reputation', () => author.getReputation());
|
author.setDisplayValue('reputation', () => author.getReputation());
|
||||||
const authorVertex = this.graph.getVertex(publicKey)
|
const authorVertex = this.graph.getVertex(publicKey)
|
||||||
?? this.graph.addVertex(VertexTypes.AUTHOR, publicKey, author, author.getLabel());
|
?? this.graph.addVertex(VertexTypes.AUTHOR, publicKey, author, author.getLabel(), {
|
||||||
const authorEdge = this.graph.addEdge(
|
hide: author.options.hide,
|
||||||
|
});
|
||||||
|
this.graph.addEdge(
|
||||||
EdgeTypes.AUTHOR,
|
EdgeTypes.AUTHOR,
|
||||||
postVertex,
|
postVertex,
|
||||||
authorVertex,
|
authorVertex,
|
||||||
weight,
|
weight,
|
||||||
{ tokenId: authorTokenId },
|
{ tokenId: authorTokenId },
|
||||||
|
{
|
||||||
|
hide: author.options.hide,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
console.log('addAuthorToGraph', { authorVertex, authorEdge });
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// In the case of multiple authors, mint additional (empty) tokens.
|
// In the case of multiple authors, mint additional (empty) tokens.
|
||||||
|
@ -198,8 +169,9 @@ export class Forum extends ReputationHolder {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Apply computed rewards to update values of tokens
|
// Apply computed rewards to update values of tokens
|
||||||
for (const [authorTokenId, amount] of rewardsAccumulator) {
|
for (const [authorEdge, amount] of rewardsAccumulator) {
|
||||||
console.log('reward', { authorTokenId, amount });
|
const { to: authorVertex, data: { tokenId: authorTokenId } } = authorEdge;
|
||||||
|
const { data: author } = authorVertex;
|
||||||
// The primary author gets the validation pool minted token.
|
// The primary author gets the validation pool minted token.
|
||||||
// So we don't need to transfer any reputation to the primary author.
|
// So we don't need to transfer any reputation to the primary author.
|
||||||
// Their reward will be the remaining balance after all other transfers.
|
// Their reward will be the remaining balance after all other transfers.
|
||||||
|
@ -210,6 +182,8 @@ export class Forum extends ReputationHolder {
|
||||||
this.dao.reputation.transferValueFrom(tokenId, authorTokenId, amount);
|
this.dao.reputation.transferValueFrom(tokenId, authorTokenId, amount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
await author.computeDisplayValues();
|
||||||
|
authorVertex.setDisplayLabel(author.getLabel());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transfer ownership of the minted tokens to the authors
|
// Transfer ownership of the minted tokens to the authors
|
||||||
|
@ -218,8 +192,6 @@ export class Forum extends ReputationHolder {
|
||||||
const author = authorVertex.data;
|
const author = authorVertex.data;
|
||||||
const { tokenId: authorTokenId } = authorEdge.data;
|
const { tokenId: authorTokenId } = authorEdge.data;
|
||||||
this.dao.reputation.transfer(this.id, author.publicKey, authorTokenId);
|
this.dao.reputation.transfer(this.id, author.publicKey, authorTokenId);
|
||||||
authorVertex.setDisplayLabel(author.getLabel());
|
|
||||||
await author.computeDisplayValues();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,9 +315,9 @@ export class Forum extends ReputationHolder {
|
||||||
|
|
||||||
// Apply reputation effects to post authors, not to the post directly
|
// Apply reputation effects to post authors, not to the post directly
|
||||||
for (const authorEdge of postVertex.getEdges(EdgeTypes.AUTHOR, true)) {
|
for (const authorEdge of postVertex.getEdges(EdgeTypes.AUTHOR, true)) {
|
||||||
const { weight, data: { tokenId }, to: { data: author } } = authorEdge;
|
const { weight, to: { data: author } } = authorEdge;
|
||||||
const authorIncrement = weight * appliedIncrement;
|
const authorIncrement = weight * appliedIncrement;
|
||||||
rewardsAccumulator.set(tokenId, authorIncrement);
|
rewardsAccumulator.set(authorEdge, authorIncrement);
|
||||||
this.actions.propagate.log(post, author, `(${authorIncrement})`);
|
this.actions.propagate.log(post, author, `(${authorIncrement})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { Stake } from '../supporting/stake.js';
|
||||||
import { Voter } from '../supporting/voter.js';
|
import { Voter } from '../supporting/voter.js';
|
||||||
import params from '../../params.js';
|
import params from '../../params.js';
|
||||||
import { Action } from '../display/action.js';
|
import { Action } from '../display/action.js';
|
||||||
import { displayNumber } from '../../util.js';
|
import { displayNumber } from '../../util/helpers.js';
|
||||||
|
|
||||||
const ValidationPoolStates = Object.freeze({
|
const ValidationPoolStates = Object.freeze({
|
||||||
OPEN: 'OPEN',
|
OPEN: 'OPEN',
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
import { displayNumber } from '../../util.js';
|
import { displayNumber } from '../../util/helpers.js';
|
||||||
|
|
||||||
export class Actor {
|
export class Actor {
|
||||||
constructor(name, scene, { announce = false } = {}) {
|
/**
|
||||||
|
* @param {string} name
|
||||||
|
* @param {Scene} scene
|
||||||
|
* @param {boolean} options.announce
|
||||||
|
* @param {boolean} options.hide
|
||||||
|
*/
|
||||||
|
constructor(name, scene, options = {}) {
|
||||||
if (!scene) throw new Error('An actor without a scene!');
|
if (!scene) throw new Error('An actor without a scene!');
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
|
@ -11,7 +17,8 @@ export class Actor {
|
||||||
this.values = new Map();
|
this.values = new Map();
|
||||||
this.valueFunctions = new Map();
|
this.valueFunctions = new Map();
|
||||||
this.active = 0;
|
this.active = 0;
|
||||||
scene?.registerActor(this, announce);
|
this.options = options;
|
||||||
|
scene?.registerActor(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
activate() {
|
activate() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { DisplayValue } from './display-value.js';
|
import { DisplayValue } from './display-value.js';
|
||||||
import { randomID } from '../../util.js';
|
import { randomID } from '../../util/helpers.js';
|
||||||
|
|
||||||
export class Box {
|
export class Box {
|
||||||
constructor(name, parentEl, options = {}) {
|
constructor(name, parentEl, options = {}) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { displayNumber } from '../../util.js';
|
import { displayNumber } from '../../util/helpers.js';
|
||||||
|
|
||||||
export class DisplayValue {
|
export class DisplayValue {
|
||||||
constructor(name, box) {
|
constructor(name, box) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import mermaid from 'https://unpkg.com/mermaid@9.2.2/dist/mermaid.esm.min.mjs';
|
import mermaid from 'https://unpkg.com/mermaid@9.2.2/dist/mermaid.esm.min.mjs';
|
||||||
import { debounce } from '../../util.js';
|
import { debounce } from '../../util/helpers.js';
|
||||||
|
|
||||||
export class MermaidDiagram {
|
export class MermaidDiagram {
|
||||||
constructor(box, logBox) {
|
constructor(box, logBox) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { Action } from './action.js';
|
import { Action } from './action.js';
|
||||||
import { CryptoUtil } from '../util/crypto.js';
|
import { CryptoUtil } from '../supporting/crypto.js';
|
||||||
import { MermaidDiagram } from './mermaid.js';
|
import { MermaidDiagram } from './mermaid.js';
|
||||||
import { SequenceDiagram } from './sequence.js';
|
import { SequenceDiagram } from './sequence.js';
|
||||||
import { Table } from './table.js';
|
import { Table } from './table.js';
|
||||||
|
@ -86,9 +86,9 @@ export class Scene {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
registerActor(actor, announce) {
|
registerActor(actor) {
|
||||||
this.actors.add(actor);
|
this.actors.add(actor);
|
||||||
if (announce) {
|
if (actor.options.announce) {
|
||||||
this.sequence?.log(`participant ${actor.name}`);
|
this.sequence?.log(`participant ${actor.name}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,10 +116,12 @@ export class Scene {
|
||||||
row.set('elapsedMs', new Date() - this.dateStart);
|
row.set('elapsedMs', new Date() - this.dateStart);
|
||||||
row.set('label', label);
|
row.set('label', label);
|
||||||
for (const actor of this.actors) {
|
for (const actor of this.actors) {
|
||||||
for (const [aKey, { name, value }] of actor.getValuesMap()) {
|
if (!actor.options.hide) {
|
||||||
const key = `${actor.name}:${aKey}`;
|
for (const [aKey, { name, value }] of actor.getValuesMap()) {
|
||||||
columns.push({ key, title: name });
|
const key = `${actor.name}:${aKey}`;
|
||||||
row.set(key, value);
|
columns.push({ key, title: name });
|
||||||
|
row.set(key, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
columns.push({ key: 'label', title: '' });
|
columns.push({ key: 'label', title: '' });
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { hexToRGB } from '../../util.js';
|
import { hexToRGB } from '../../util/helpers.js';
|
||||||
import { MermaidDiagram } from './mermaid.js';
|
import { MermaidDiagram } from './mermaid.js';
|
||||||
|
|
||||||
export class SequenceDiagram extends MermaidDiagram {
|
export class SequenceDiagram extends MermaidDiagram {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { displayNumber } from '../../util.js';
|
import { displayNumber } from '../../util/helpers.js';
|
||||||
|
|
||||||
export class Table {
|
export class Table {
|
||||||
constructor(box) {
|
constructor(box) {
|
||||||
|
|
|
@ -3,7 +3,7 @@ import {
|
||||||
Message, PostMessage, PeerMessage, messageFromJSON,
|
Message, PostMessage, PeerMessage, messageFromJSON,
|
||||||
} from './message.js';
|
} from './message.js';
|
||||||
import { NetworkNode } from './network-node.js';
|
import { NetworkNode } from './network-node.js';
|
||||||
import { randomID } from '../../util.js';
|
import { randomID } from '../../util/helpers.js';
|
||||||
|
|
||||||
export class ForumNode extends NetworkNode {
|
export class ForumNode extends NetworkNode {
|
||||||
constructor(name, scene) {
|
constructor(name, scene) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { CryptoUtil } from '../util/crypto.js';
|
import { CryptoUtil } from '../supporting/crypto.js';
|
||||||
import { PostContent } from '../util/post-content.js';
|
import { PostContent } from '../supporting/post-content.js';
|
||||||
|
|
||||||
export class Message {
|
export class Message {
|
||||||
constructor(content) {
|
constructor(content) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { randomID } from '../util/util.js';
|
import { randomID } from '../util/util/helpers.js';
|
||||||
|
|
||||||
class Pledge {
|
class Pledge {
|
||||||
constructor({ stake, duration }) {
|
constructor({ stake, duration }) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { randomID } from '../../util.js';
|
import { randomID } from '../../util/helpers.js';
|
||||||
import { Actor } from '../display/actor.js';
|
import { Actor } from '../display/actor.js';
|
||||||
|
|
||||||
export class ReputationHolder extends Actor {
|
export class ReputationHolder extends Actor {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { ERC721 } from '../supporting/erc721.js';
|
import { ERC721 } from '../supporting/erc721.js';
|
||||||
|
import { randomID } from '../../util/helpers.js';
|
||||||
import { EPSILON, randomID } from '../../util.js';
|
import { EPSILON } from '../../util/constants.js';
|
||||||
|
|
||||||
class Lock {
|
class Lock {
|
||||||
constructor(tokenId, amount, duration) {
|
constructor(tokenId, amount, duration) {
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
|
const getEdgeKey = ({ from, to }) => btoa([from.id, to.id]).replaceAll(/[^A-Za-z0-9]+/g, '');
|
||||||
|
|
||||||
export class Vertex {
|
export class Vertex {
|
||||||
constructor(graph, type, id, data) {
|
constructor(graph, type, id, data, options = {}) {
|
||||||
this.graph = graph;
|
this.graph = graph;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
this.options = options;
|
||||||
this.edges = {
|
this.edges = {
|
||||||
from: [],
|
from: [],
|
||||||
to: [],
|
to: [],
|
||||||
|
@ -17,17 +20,50 @@ export class Vertex {
|
||||||
}
|
}
|
||||||
|
|
||||||
setDisplayLabel(label) {
|
setDisplayLabel(label) {
|
||||||
this.graph.setVertexDisplayLabel(this.id, label);
|
if (this.options.hide) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.graph.flowchart?.log(`${this.id}[${label}]`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Edge {
|
export class Edge {
|
||||||
constructor(type, from, to, weight, data) {
|
constructor(graph, type, from, to, weight, data, options = {}) {
|
||||||
|
this.graph = graph;
|
||||||
this.from = from;
|
this.from = from;
|
||||||
this.to = to;
|
this.to = to;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.weight = weight;
|
this.weight = weight;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
this.options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
getHtml() {
|
||||||
|
let html = '<table>';
|
||||||
|
for (const { type, weight } of this.graph.getEdges(null, this.from, this.to)) {
|
||||||
|
html += `<tr><td>${type}</td><td>${weight}</td></tr>`;
|
||||||
|
}
|
||||||
|
html += '</table>';
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
getFlowchartNode() {
|
||||||
|
return `${getEdgeKey(this)}(${this.getHtml()})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
displayEdgeNode() {
|
||||||
|
if (this.options.hide) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.graph.flowchart?.log(this.getFlowchartNode());
|
||||||
|
}
|
||||||
|
|
||||||
|
displayEdge() {
|
||||||
|
if (this.options.hide) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.graph.flowchart?.log(`${this.from.id} --- ${this.getFlowchartNode()} --> ${this.to.id}`);
|
||||||
|
this.graph.flowchart?.log(`class ${getEdgeKey(this)} edge`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,11 +82,7 @@ export class WDAG {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
setVertexDisplayLabel(id, label) {
|
addVertex(type, id, data, label, options) {
|
||||||
this.flowchart?.log(`${id}[${label}]`);
|
|
||||||
}
|
|
||||||
|
|
||||||
addVertex(type, 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;
|
||||||
|
@ -59,9 +91,9 @@ export class WDAG {
|
||||||
if (this.vertices.has(id)) {
|
if (this.vertices.has(id)) {
|
||||||
throw new Error(`Vertex already exists with id: ${id}`);
|
throw new Error(`Vertex already exists with id: ${id}`);
|
||||||
}
|
}
|
||||||
const vertex = new Vertex(this, type, id, data);
|
const vertex = new Vertex(this, type, id, data, options);
|
||||||
this.vertices.set(id, vertex);
|
this.vertices.set(id, vertex);
|
||||||
this.setVertexDisplayLabel(id, label ?? id);
|
vertex.setDisplayLabel(id, label ?? id);
|
||||||
return vertex;
|
return vertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,10 +109,6 @@ export class WDAG {
|
||||||
return Array.from(this.vertices.values()).map(({ data }) => data);
|
return Array.from(this.vertices.values()).map(({ data }) => data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static getEdgeKey({ from, to }) {
|
|
||||||
return btoa([from.id, to.id]).replaceAll(/[^A-Za-z0-9]+/g, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
getEdge(type, from, to) {
|
getEdge(type, from, to) {
|
||||||
from = from instanceof Vertex ? from : this.getVertex(from);
|
from = from instanceof Vertex ? from : this.getVertex(from);
|
||||||
to = to instanceof Vertex ? to : this.getVertex(to);
|
to = to instanceof Vertex ? to : this.getVertex(to);
|
||||||
|
@ -88,7 +116,7 @@ export class WDAG {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
const edges = this.edgeTypes.get(type);
|
const edges = this.edgeTypes.get(type);
|
||||||
const edgeKey = WDAG.getEdgeKey({ from, to });
|
const edgeKey = getEdgeKey({ from, to });
|
||||||
return edges?.get(edgeKey);
|
return edges?.get(edgeKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,46 +124,31 @@ export class WDAG {
|
||||||
return this.getEdge(type, from, to)?.weight;
|
return this.getEdge(type, from, to)?.weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
getEdgeHtml({ from, to }) {
|
setEdgeWeight(type, from, to, weight, data, options) {
|
||||||
let html = '<table>';
|
|
||||||
for (const { type, weight } of this.getEdges(null, from, to)) {
|
|
||||||
html += `<tr><td>${type}</td><td>${weight}</td></tr>`;
|
|
||||||
}
|
|
||||||
html += '</table>';
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
||||||
getEdgeFlowchartNode(edge) {
|
|
||||||
const edgeKey = WDAG.getEdgeKey(edge);
|
|
||||||
return `${edgeKey}(${this.getEdgeHtml(edge)})`;
|
|
||||||
}
|
|
||||||
|
|
||||||
setEdgeWeight(type, from, to, weight, data) {
|
|
||||||
from = from instanceof Vertex ? from : this.getVertex(from);
|
from = from instanceof Vertex ? from : this.getVertex(from);
|
||||||
to = to instanceof Vertex ? to : this.getVertex(to);
|
to = to instanceof Vertex ? to : this.getVertex(to);
|
||||||
const edge = new Edge(type, from, to, weight, data);
|
const edge = new Edge(this, type, from, to, weight, data, options);
|
||||||
let edges = this.edgeTypes.get(type);
|
let edges = this.edgeTypes.get(type);
|
||||||
if (!edges) {
|
if (!edges) {
|
||||||
edges = new Map();
|
edges = new Map();
|
||||||
this.edgeTypes.set(type, edges);
|
this.edgeTypes.set(type, edges);
|
||||||
}
|
}
|
||||||
const edgeKey = WDAG.getEdgeKey(edge);
|
const edgeKey = getEdgeKey(edge);
|
||||||
edges.set(edgeKey, edge);
|
edges.set(edgeKey, edge);
|
||||||
this.flowchart?.log(this.getEdgeFlowchartNode(edge));
|
edge.displayEdgeNode();
|
||||||
return edge;
|
return edge;
|
||||||
}
|
}
|
||||||
|
|
||||||
addEdge(type, from, to, weight, data) {
|
addEdge(type, from, to, weight, data, options) {
|
||||||
from = from instanceof Vertex ? from : this.getVertex(from);
|
from = from instanceof Vertex ? from : this.getVertex(from);
|
||||||
to = to instanceof Vertex ? to : this.getVertex(to);
|
to = to instanceof Vertex ? to : this.getVertex(to);
|
||||||
if (this.getEdge(type, from, to)) {
|
if (this.getEdge(type, from, to)) {
|
||||||
throw new Error(`Edge ${type} from ${from.id} to ${to.id} already exists`);
|
throw new Error(`Edge ${type} from ${from.id} to ${to.id} already exists`);
|
||||||
}
|
}
|
||||||
const edge = this.setEdgeWeight(type, from, to, weight, data);
|
const edge = this.setEdgeWeight(type, from, to, weight, data, options);
|
||||||
from.edges.from.push(edge);
|
from.edges.from.push(edge);
|
||||||
to.edges.to.push(edge);
|
to.edges.to.push(edge);
|
||||||
this.flowchart?.log(`${from.id} --- ${this.getEdgeFlowchartNode(edge)} --> ${to.id}`);
|
edge.displayEdge();
|
||||||
this.flowchart?.log(`class ${WDAG.getEdgeKey(edge)} edge`);
|
|
||||||
return edge;
|
return edge;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
export class PrioritizedQueue {
|
|
||||||
constructor() {
|
|
||||||
this.buffer = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add an item to the buffer, ahead of the next lowest priority item
|
|
||||||
add(message, priority) {
|
|
||||||
const idx = this.buffer.findIndex((item) => item.priority < priority);
|
|
||||||
if (idx < 0) {
|
|
||||||
this.buffer.push({ message, priority });
|
|
||||||
} else {
|
|
||||||
this.buffer.splice(idx, 0, { message, priority });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the highest priority item in the buffer
|
|
||||||
pop() {
|
|
||||||
if (!this.buffer.length) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
const item = this.buffer.shift();
|
|
||||||
return item.message;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -14,7 +14,7 @@
|
||||||
import { Scene } from '../classes/display/scene.js';
|
import { Scene } from '../classes/display/scene.js';
|
||||||
import { Actor } from '../classes/display/actor.js';
|
import { Actor } from '../classes/display/actor.js';
|
||||||
import { Action } from '../classes/display/action.js';
|
import { Action } from '../classes/display/action.js';
|
||||||
import { delay } from '../util.js';
|
import { delay } from '../util/helpers.js';
|
||||||
|
|
||||||
const DEFAULT_DELAY_INTERVAL = 500;
|
const DEFAULT_DELAY_INTERVAL = 500;
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
// import { ValidationPool } from '../classes/validation-pool.js';
|
// import { ValidationPool } from '../classes/validation-pool.js';
|
||||||
// import { TokenHolder } from '../classes/token-holder.js';
|
// import { TokenHolder } from '../classes/token-holder.js';
|
||||||
// import { ReputationToken } from '../classes/reputation-token.js';
|
// import { ReputationToken } from '../classes/reputation-token.js';
|
||||||
import { delay } from '../util.js';
|
import { delay } from '../util/helpers.js';
|
||||||
|
|
||||||
const DEFAULT_DELAY_INTERVAL = 500;
|
const DEFAULT_DELAY_INTERVAL = 500;
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,9 @@ import { Scene } from '../../classes/display/scene.js';
|
||||||
import { Expert } from '../../classes/actors/expert.js';
|
import { Expert } from '../../classes/actors/expert.js';
|
||||||
import { DAO } from '../../classes/dao/dao.js';
|
import { DAO } from '../../classes/dao/dao.js';
|
||||||
import { Public } from '../../classes/actors/public.js';
|
import { Public } from '../../classes/actors/public.js';
|
||||||
import { PostContent } from '../../classes/util/post-content.js';
|
import { PostContent } from '../../classes/supporting/post-content.js';
|
||||||
import { delayOrWait } from '../../classes/display/controls.js';
|
import { delayOrWait } from '../../classes/display/controls.js';
|
||||||
import { mochaRun } from '../../util.js';
|
import { mochaRun } from '../../util/helpers.js';
|
||||||
|
|
||||||
const DELAY_INTERVAL = 100;
|
const DELAY_INTERVAL = 100;
|
||||||
const POOL_DURATION = 200;
|
const POOL_DURATION = 200;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Business } from '../../classes/dao/business.js';
|
import { Business } from '../../classes/dao/business.js';
|
||||||
import { Scene } from '../../classes/display/scene.js';
|
import { Scene } from '../../classes/display/scene.js';
|
||||||
import { Box } from '../../classes/display/box.js';
|
import { Box } from '../../classes/display/box.js';
|
||||||
import { mochaRun } from '../../util.js';
|
import { mochaRun } from '../../util/helpers.js';
|
||||||
|
|
||||||
describe('Business', function tests() {
|
describe('Business', function tests() {
|
||||||
this.timeout(0);
|
this.timeout(0);
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Box } from '../../classes/display/box.js';
|
||||||
import { Scene } from '../../classes/display/scene.js';
|
import { Scene } from '../../classes/display/scene.js';
|
||||||
import { Action } from '../../classes/display/action.js';
|
import { Action } from '../../classes/display/action.js';
|
||||||
import { Actor } from '../../classes/display/actor.js';
|
import { Actor } from '../../classes/display/actor.js';
|
||||||
import { debounce, delay, mochaRun } from '../../util.js';
|
import { debounce, delay, mochaRun } from '../../util/helpers.js';
|
||||||
|
|
||||||
describe('Debounce', () => {
|
describe('Debounce', () => {
|
||||||
let scene;
|
let scene;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { Box } from '../../classes/display/box.js';
|
import { Box } from '../../classes/display/box.js';
|
||||||
import { Scene } from '../../classes/display/scene.js';
|
import { Scene } from '../../classes/display/scene.js';
|
||||||
import { PostContent } from '../../classes/util/post-content.js';
|
import { PostContent } from '../../classes/supporting/post-content.js';
|
||||||
import { Expert } from '../../classes/actors/expert.js';
|
import { Expert } from '../../classes/actors/expert.js';
|
||||||
import { ForumNode } from '../../classes/forum-network/forum-node.js';
|
import { ForumNode } from '../../classes/forum-network/forum-node.js';
|
||||||
import { Network } from '../../classes/forum-network/network.js';
|
import { Network } from '../../classes/forum-network/network.js';
|
||||||
import { mochaRun, randomID } from '../../util.js';
|
import { mochaRun, randomID } from '../../util/helpers.js';
|
||||||
import { delayOrWait } from '../../classes/display/controls.js';
|
import { delayOrWait } from '../../classes/display/controls.js';
|
||||||
|
|
||||||
describe('Forum Network', function tests() {
|
describe('Forum Network', function tests() {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Box } from '../../../classes/display/box.js';
|
import { Box } from '../../../classes/display/box.js';
|
||||||
import { Scene } from '../../../classes/display/scene.js';
|
import { Scene } from '../../../classes/display/scene.js';
|
||||||
import { Expert } from '../../../classes/actors/expert.js';
|
import { Expert } from '../../../classes/actors/expert.js';
|
||||||
import { PostContent } from '../../../classes/util/post-content.js';
|
import { PostContent } from '../../../classes/supporting/post-content.js';
|
||||||
import params from '../../../params.js';
|
import params from '../../../params.js';
|
||||||
import { DAO } from '../../../classes/dao/dao.js';
|
import { DAO } from '../../../classes/dao/dao.js';
|
||||||
import { delayOrWait } from '../../../classes/display/controls.js';
|
import { delayOrWait } from '../../../classes/display/controls.js';
|
||||||
|
@ -55,12 +55,16 @@ export class ForumTest {
|
||||||
return postId;
|
return postId;
|
||||||
}
|
}
|
||||||
|
|
||||||
async newExpert(options) {
|
async newExpert() {
|
||||||
|
// Hide by default, for simplicity of rendering first 9 forum tests
|
||||||
|
const options = {
|
||||||
|
hide: !this.options.displayAuthors,
|
||||||
|
announce: this.options.displayAuthors,
|
||||||
|
};
|
||||||
const index = this.experts.length;
|
const index = this.experts.length;
|
||||||
const name = `Expert${index + 1}`;
|
const name = `Expert${index + 1}`;
|
||||||
const expert = await new Expert(this.dao, name, this.scene, options).initialize();
|
const expert = await new Expert(this.dao, name, this.scene, options).initialize();
|
||||||
this.experts.push(expert);
|
this.experts.push(expert);
|
||||||
// await expert.addComputedValue('rep', () => this.dao.reputation.valueOwnedBy(expert.reputationPublicKey));
|
|
||||||
return expert;
|
return expert;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,12 +85,13 @@ export class ForumTest {
|
||||||
scene.addDisplayValue('q4. leachingValue').set(params.leachingValue);
|
scene.addDisplayValue('q4. leachingValue').set(params.leachingValue);
|
||||||
scene.addDisplayValue(' ');
|
scene.addDisplayValue(' ');
|
||||||
|
|
||||||
this.dao = new DAO('DAO', scene, { announce: true });
|
// If we're going to announce experts, announce the DAO so it appears first.
|
||||||
|
this.dao = new DAO('DAO', scene, { announce: this.options.displayAuthors });
|
||||||
this.forum = this.dao.forum;
|
this.forum = this.dao.forum;
|
||||||
this.experts = [];
|
this.experts = [];
|
||||||
this.posts = [];
|
this.posts = [];
|
||||||
|
|
||||||
await this.newExpert({ announce: true });
|
await this.newExpert();
|
||||||
|
|
||||||
await this.dao.addComputedValue('total value', () => this.dao.reputation.getTotal());
|
await this.dao.addComputedValue('total value', () => this.dao.reputation.getTotal());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
import { mochaRun } from '../../../util.js';
|
import { mochaRun } from '../../../util/helpers.js';
|
||||||
import { ForumTest } from './forum.test-util.js';
|
import { ForumTest } from './forum.test-util.js';
|
||||||
|
|
||||||
describe('Forum', function tests() {
|
describe('Forum', function tests() {
|
||||||
this.timeout(0);
|
this.timeout(0);
|
||||||
|
|
||||||
const forumTest = new ForumTest();
|
const forumTest = new ForumTest({ displayAuthors: false });
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
await forumTest.setup();
|
await forumTest.setup();
|
||||||
|
await forumTest.newExpert();
|
||||||
|
await forumTest.newExpert();
|
||||||
});
|
});
|
||||||
|
|
||||||
context('Negative citation of a negative citation', async () => {
|
context('Negative citation of a negative citation', async () => {
|
||||||
|
@ -19,14 +21,14 @@ describe('Forum', function tests() {
|
||||||
|
|
||||||
it('Post2 negatively cites Post1', async () => {
|
it('Post2 negatively cites Post1', async () => {
|
||||||
const { forum, experts, posts } = forumTest;
|
const { forum, experts, posts } = forumTest;
|
||||||
await forumTest.addPost(experts[0], 10, [{ postId: posts[0], weight: -1 }]);
|
await forumTest.addPost(experts[1], 10, [{ postId: posts[0], weight: -1 }]);
|
||||||
forum.getPost(posts[0]).value.should.equal(0);
|
forum.getPost(posts[0]).value.should.equal(0);
|
||||||
forum.getPost(posts[1]).value.should.equal(20);
|
forum.getPost(posts[1]).value.should.equal(20);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Post3 negatively cites Post2, restoring Post1 post to its initial value', async () => {
|
it('Post3 negatively cites Post2, restoring Post1 post to its initial value', async () => {
|
||||||
const { forum, experts, posts } = forumTest;
|
const { forum, experts, posts } = forumTest;
|
||||||
await forumTest.addPost(experts[0], 10, [{ postId: posts[1], weight: -1 }]);
|
await forumTest.addPost(experts[2], 10, [{ postId: posts[1], weight: -1 }]);
|
||||||
forum.getPost(posts[0]).value.should.equal(10);
|
forum.getPost(posts[0]).value.should.equal(10);
|
||||||
forum.getPost(posts[1]).value.should.equal(0);
|
forum.getPost(posts[1]).value.should.equal(0);
|
||||||
forum.getPost(posts[2]).value.should.equal(20);
|
forum.getPost(posts[2]).value.should.equal(20);
|
||||||
|
@ -34,11 +36,4 @@ describe('Forum', function tests() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// await addPost(experts[0], 10);
|
|
||||||
// await addPost(experts[0], 10, [{ postId: posts[3], weight: -1 }]);
|
|
||||||
// await addPost(experts[0], 10, [{ postId: posts[4], weight: -1 }]);
|
|
||||||
|
|
||||||
// await addPost(expert3, 'Post 4', 100, [{ postId: postId2, weight: -1 }]);
|
|
||||||
// await addPost(expert1, 'Post 5', 100, [{ postId: postId3, weight: -1 }]);
|
|
||||||
|
|
||||||
mochaRun();
|
mochaRun();
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
import { mochaRun } from '../../../util.js';
|
import { mochaRun } from '../../../util/helpers.js';
|
||||||
import { ForumTest } from './forum.test-util.js';
|
import { ForumTest } from './forum.test-util.js';
|
||||||
|
|
||||||
describe('Forum', function tests() {
|
describe('Forum', function tests() {
|
||||||
this.timeout(0);
|
this.timeout(0);
|
||||||
|
|
||||||
const forumTest = new ForumTest();
|
const forumTest = new ForumTest({ displayAuthors: true });
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
await forumTest.setup();
|
await forumTest.setup();
|
||||||
|
await forumTest.newExpert();
|
||||||
|
await forumTest.newExpert();
|
||||||
});
|
});
|
||||||
|
|
||||||
context('Post with multiple authors', async () => {
|
context('Post with multiple authors', async () => {
|
||||||
|
@ -19,9 +21,6 @@ describe('Forum', function tests() {
|
||||||
forum = forumTest.forum;
|
forum = forumTest.forum;
|
||||||
experts = forumTest.experts;
|
experts = forumTest.experts;
|
||||||
posts = forumTest.posts;
|
posts = forumTest.posts;
|
||||||
|
|
||||||
await forumTest.newExpert({ announce: true });
|
|
||||||
await forumTest.newExpert({ announce: true });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Post1', async () => {
|
it('Post1', async () => {
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
import { mochaRun } from '../../../util.js';
|
import { mochaRun } from '../../../util/helpers.js';
|
||||||
import { ForumTest } from './forum.test-util.js';
|
import { ForumTest } from './forum.test-util.js';
|
||||||
|
|
||||||
describe('Forum', function tests() {
|
describe('Forum', function tests() {
|
||||||
this.timeout(0);
|
this.timeout(0);
|
||||||
|
|
||||||
const forumTest = new ForumTest();
|
const forumTest = new ForumTest({ displayAuthors: true });
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
await forumTest.setup();
|
await forumTest.setup();
|
||||||
|
await forumTest.newExpert();
|
||||||
|
await forumTest.newExpert();
|
||||||
});
|
});
|
||||||
|
|
||||||
context('Multiple posts with overlapping authors', async () => {
|
context('Multiple posts with overlapping authors', async () => {
|
||||||
|
@ -19,9 +21,6 @@ describe('Forum', function tests() {
|
||||||
forum = forumTest.forum;
|
forum = forumTest.forum;
|
||||||
experts = forumTest.experts;
|
experts = forumTest.experts;
|
||||||
posts = forumTest.posts;
|
posts = forumTest.posts;
|
||||||
|
|
||||||
await forumTest.newExpert({ announce: true });
|
|
||||||
await forumTest.newExpert({ announce: true });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Post1 with two authors', async () => {
|
it('Post1 with two authors', async () => {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { mochaRun } from '../../../util.js';
|
import { mochaRun } from '../../../util/helpers.js';
|
||||||
import { ForumTest } from './forum.test-util.js';
|
import { ForumTest } from './forum.test-util.js';
|
||||||
|
|
||||||
describe('Forum', function tests() {
|
describe('Forum', function tests() {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { mochaRun } from '../../../util.js';
|
import { mochaRun } from '../../../util/helpers.js';
|
||||||
import { ForumTest } from './forum.test-util.js';
|
import { ForumTest } from './forum.test-util.js';
|
||||||
|
|
||||||
describe('Forum', function tests() {
|
describe('Forum', function tests() {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { mochaRun } from '../../../util.js';
|
import { mochaRun } from '../../../util/helpers.js';
|
||||||
import { ForumTest } from './forum.test-util.js';
|
import { ForumTest } from './forum.test-util.js';
|
||||||
|
|
||||||
describe('Forum', function tests() {
|
describe('Forum', function tests() {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { mochaRun } from '../../../util.js';
|
import { mochaRun } from '../../../util/helpers.js';
|
||||||
import { ForumTest } from './forum.test-util.js';
|
import { ForumTest } from './forum.test-util.js';
|
||||||
|
|
||||||
describe('Forum', function tests() {
|
describe('Forum', function tests() {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { EPSILON, mochaRun } from '../../../util.js';
|
import { mochaRun } from '../../../util/helpers.js';
|
||||||
|
import { EPSILON } from '../../../util/constants.js';
|
||||||
import { ForumTest } from './forum.test-util.js';
|
import { ForumTest } from './forum.test-util.js';
|
||||||
|
|
||||||
describe('Forum', function tests() {
|
describe('Forum', function tests() {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { mochaRun } from '../../../util.js';
|
import { mochaRun } from '../../../util/helpers.js';
|
||||||
import { ForumTest } from './forum.test-util.js';
|
import { ForumTest } from './forum.test-util.js';
|
||||||
|
|
||||||
describe('Forum', function tests() {
|
describe('Forum', function tests() {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { INCINERATOR_ADDRESS, mochaRun } from '../../../util.js';
|
import { INCINERATOR_ADDRESS, mochaRun } from '../../../util/helpers.js';
|
||||||
import { ForumTest } from './forum.test-util.js';
|
import { ForumTest } from './forum.test-util.js';
|
||||||
|
|
||||||
describe('Forum', function tests() {
|
describe('Forum', function tests() {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { INCINERATOR_ADDRESS, mochaRun } from '../../../util.js';
|
import { INCINERATOR_ADDRESS, mochaRun } from '../../../util/helpers.js';
|
||||||
import { ForumTest } from './forum.test-util.js';
|
import { ForumTest } from './forum.test-util.js';
|
||||||
|
|
||||||
describe('Forum', function tests() {
|
describe('Forum', function tests() {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { Box } from '../../classes/display/box.js';
|
import { Box } from '../../classes/display/box.js';
|
||||||
import { Scene } from '../../classes/display/scene.js';
|
import { Scene } from '../../classes/display/scene.js';
|
||||||
import { Expert } from '../../classes/actors/expert.js';
|
import { Expert } from '../../classes/actors/expert.js';
|
||||||
import { PostContent } from '../../classes/util/post-content.js';
|
import { PostContent } from '../../classes/supporting/post-content.js';
|
||||||
import { DAO } from '../../classes/dao/dao.js';
|
import { DAO } from '../../classes/dao/dao.js';
|
||||||
import { delayOrWait } from '../../classes/display/controls.js';
|
import { delayOrWait } from '../../classes/display/controls.js';
|
||||||
import { mochaRun } from '../../util.js';
|
import { mochaRun } from '../../util/helpers.js';
|
||||||
|
|
||||||
const POOL_DURATION_MS = 100;
|
const POOL_DURATION_MS = 100;
|
||||||
const DEFAULT_DELAY_MS = 100;
|
const DEFAULT_DELAY_MS = 100;
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Actor } from '../../classes/display/actor.js';
|
||||||
import { Box } from '../../classes/display/box.js';
|
import { Box } from '../../classes/display/box.js';
|
||||||
import { Scene } from '../../classes/display/scene.js';
|
import { Scene } from '../../classes/display/scene.js';
|
||||||
import { VM } from '../../classes/supporting/vm.js';
|
import { VM } from '../../classes/supporting/vm.js';
|
||||||
import { mochaRun } from '../../util.js';
|
import { mochaRun } from '../../util/helpers.js';
|
||||||
|
|
||||||
const contractIds = ['contract-id-1', 'contract-id-2'];
|
const contractIds = ['contract-id-1', 'contract-id-2'];
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Box } from '../../classes/display/box.js';
|
import { Box } from '../../classes/display/box.js';
|
||||||
import { Scene } from '../../classes/display/scene.js';
|
import { Scene } from '../../classes/display/scene.js';
|
||||||
import { WDAG } from '../../classes/supporting/wdag.js';
|
import { WDAG } from '../../classes/supporting/wdag.js';
|
||||||
import { mochaRun } from '../../util.js';
|
import { mochaRun } from '../../util/helpers.js';
|
||||||
|
|
||||||
const rootElement = document.getElementById('scene');
|
const rootElement = document.getElementById('scene');
|
||||||
const rootBox = new Box('rootBox', rootElement).flex();
|
const rootBox = new Box('rootBox', rootElement).flex();
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
export const EPSILON = 2.23e-16;
|
||||||
|
|
||||||
|
export const INCINERATOR_ADDRESS = 0;
|
||||||
|
|
||||||
|
export const EdgeTypes = {
|
||||||
|
CITATION: 'citation',
|
||||||
|
BALANCE: 'balance',
|
||||||
|
AUTHOR: 'author',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const VertexTypes = {
|
||||||
|
POST: 'post',
|
||||||
|
AUTHOR: 'author',
|
||||||
|
};
|
|
@ -1,11 +1,5 @@
|
||||||
import { CryptoUtil } from './classes/util/crypto.js';
|
|
||||||
|
|
||||||
const timers = new Map();
|
const timers = new Map();
|
||||||
|
|
||||||
export const EPSILON = 2.23e-16;
|
|
||||||
|
|
||||||
export const INCINERATOR_ADDRESS = 0;
|
|
||||||
|
|
||||||
export const debounce = async (fn, delayMs) => {
|
export const debounce = async (fn, delayMs) => {
|
||||||
const timer = timers.get(fn);
|
const timer = timers.get(fn);
|
||||||
if (timer) {
|
if (timer) {
|
||||||
|
@ -39,7 +33,7 @@ export const displayNumber = (value, decimals = 2) => (value.toString().length >
|
||||||
? value.toFixed(decimals)
|
? value.toFixed(decimals)
|
||||||
: value);
|
: value);
|
||||||
|
|
||||||
export const randomID = () => CryptoUtil.randomUUID().replaceAll('-', '').slice(0, 8);
|
export const randomID = () => window.crypto.randomUUID().replaceAll('-', '').slice(0, 8);
|
||||||
|
|
||||||
export const mochaRun = () => {
|
export const mochaRun = () => {
|
||||||
if (mocha._state !== 'running') {
|
if (mocha._state !== 'running') {
|
Loading…
Reference in New Issue