dao-governance-framework/forum-network/public/classes/graph.js

86 lines
2.1 KiB
JavaScript
Raw Normal View History

export class Vertex {
constructor(data) {
this.data = data;
this.edges = {
from: [],
to: [],
};
}
}
export class Edge {
constructor(label, from, to, data) {
this.from = from;
this.to = to;
this.label = label;
this.data = data;
}
}
export class Graph {
constructor() {
this.vertices = new Map();
this.edgeLabels = new Map();
this.nextVertexId = 0;
}
addVertex(id, data) {
// Support simple case of auto-incremented numeric ids
if (typeof id === 'object') {
data = id;
id = this.nextVertexId++;
}
const vertex = new Vertex(data);
this.vertices.set(id, vertex);
return this;
}
getVertex(id) {
return this.vertices.get(id);
}
getVertexData(id) {
return this.getVertex(id)?.data;
}
getVertices() {
return Array.from(this.vertices.values()).map(({ data }) => data);
}
getEdge(label, from, to) {
const edges = this.edgeLabels.get(label);
return edges?.get(JSON.stringify({ from, to }));
}
setEdge(label, from, to, edge) {
let edges = this.edgeLabels.get(label);
if (!edges) {
edges = new Map();
this.edgeLabels.set(label, edges);
}
edges.set(JSON.stringify({ from, to }), edge);
}
addEdge(label, from, to, data) {
if (this.getEdge(label, from, to)) {
throw new Error(`Edge ${label} from ${from} to ${to} already exists`);
}
const edge = new Edge(label, from, to, data);
this.setEdge(label, from, to, edge);
this.getVertex(from).edges.from.push(edge);
this.getVertex(to).edges.to.push(edge);
return this;
}
getEdges(label, from, to) {
const edgeLabels = label ? [label] : Array.from(this.edgeLabels.keys());
return edgeLabels.flatMap((edgeLabel) => {
const edges = this.edgeLabels.get(edgeLabel);
return Array.from(edges?.values() || []).filter((edge) => {
const matchFrom = from === null || from === undefined || from === edge.from;
const matchTo = to === null || to === undefined || to === edge.to;
return matchFrom && matchTo;
});
});
}
}