mirror of
https://github.com/Egonex-AI/Understand-Anything.git
synced 2026-06-22 10:58:03 +08:00
01d7ece81d
Generates fake knowledge-graph.json with configurable node count for testing Web Worker layout performance. Forward-only edges to avoid dagre stack overflow on cyclic graphs. Usage: node scripts/generate-large-graph.mjs [nodeCount] Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
148 lines
4.5 KiB
JavaScript
148 lines
4.5 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Generate a large fake knowledge graph for testing PR #18
|
|
* (Web Worker layout for large graphs).
|
|
*
|
|
* Usage:
|
|
* node scripts/generate-large-graph.mjs [nodeCount]
|
|
*
|
|
* Default: 3000 nodes. Writes to .understand-anything/knowledge-graph.json
|
|
*/
|
|
|
|
import { writeFileSync, mkdirSync } from "node:fs";
|
|
import { resolve } from "node:path";
|
|
|
|
const NODE_COUNT = parseInt(process.argv[2] || "3000", 10);
|
|
const EDGE_RATIO = 1.7; // edges per node (realistic for codebases)
|
|
|
|
const nodeTypes = ["file", "function", "class", "module", "concept"];
|
|
const edgeTypes = [
|
|
"imports", "exports", "contains", "inherits", "implements",
|
|
"calls", "subscribes", "publishes", "middleware",
|
|
"reads_from", "writes_to", "transforms", "validates",
|
|
"depends_on", "tested_by", "configures",
|
|
"related", "similar_to",
|
|
];
|
|
const complexities = ["simple", "moderate", "complex"];
|
|
const languages = ["TypeScript", "JavaScript", "Python", "Go", "Rust"];
|
|
const frameworks = ["React", "Express", "FastAPI", "Gin", "Actix"];
|
|
|
|
function pick(arr) {
|
|
return arr[Math.floor(Math.random() * arr.length)];
|
|
}
|
|
|
|
function generateNodes(count) {
|
|
const nodes = [];
|
|
for (let i = 0; i < count; i++) {
|
|
const type = pick(nodeTypes);
|
|
const name = `${type}_${i}`;
|
|
nodes.push({
|
|
id: `node-${i}`,
|
|
type,
|
|
name,
|
|
filePath: type === "file" ? `src/${name}.ts` : undefined,
|
|
summary: `Auto-generated ${type} node #${i} for performance testing.`,
|
|
tags: [type, `group-${i % 20}`],
|
|
complexity: pick(complexities),
|
|
});
|
|
}
|
|
return nodes;
|
|
}
|
|
|
|
function generateEdges(nodes, edgeCount) {
|
|
const edges = [];
|
|
const seen = new Set();
|
|
const n = nodes.length;
|
|
|
|
for (let i = 0; i < edgeCount; i++) {
|
|
let src, tgt;
|
|
// Forward-only edges to avoid cycles (dagre blows the stack on large cyclic graphs)
|
|
do {
|
|
src = Math.floor(Math.random() * (n - 1));
|
|
const offset = Math.floor(Math.random() * Math.min(50, n - src - 1)) + 1;
|
|
tgt = src + offset;
|
|
} while (tgt >= n || src === tgt || seen.has(`${src}-${tgt}`));
|
|
|
|
seen.add(`${src}-${tgt}`);
|
|
edges.push({
|
|
source: nodes[src].id,
|
|
target: nodes[tgt].id,
|
|
type: pick(edgeTypes),
|
|
direction: "forward",
|
|
weight: Math.round(Math.random() * 100) / 100,
|
|
});
|
|
}
|
|
return edges;
|
|
}
|
|
|
|
function generateLayers(nodes) {
|
|
const layers = [];
|
|
const layerNames = [
|
|
"Presentation", "Application", "Domain", "Infrastructure",
|
|
"API Gateway", "Data Access", "Utilities", "Testing",
|
|
];
|
|
|
|
for (let i = 0; i < layerNames.length; i++) {
|
|
const start = Math.floor((i / layerNames.length) * nodes.length);
|
|
const end = Math.floor(((i + 1) / layerNames.length) * nodes.length);
|
|
layers.push({
|
|
id: `layer-${i}`,
|
|
name: layerNames[i],
|
|
description: `${layerNames[i]} layer (auto-generated)`,
|
|
nodeIds: nodes.slice(start, end).map((n) => n.id),
|
|
});
|
|
}
|
|
return layers;
|
|
}
|
|
|
|
function generateTour(nodes) {
|
|
const steps = [];
|
|
const stepCount = Math.min(8, Math.floor(nodes.length / 100));
|
|
for (let i = 0; i < stepCount; i++) {
|
|
const idx = Math.floor((i / stepCount) * nodes.length);
|
|
steps.push({
|
|
order: i + 1,
|
|
title: `Step ${i + 1}: Explore ${nodes[idx].name}`,
|
|
description: `This tour step highlights node **${nodes[idx].name}** and its surrounding context.`,
|
|
nodeIds: [nodes[idx].id, nodes[Math.min(idx + 1, nodes.length - 1)].id],
|
|
});
|
|
}
|
|
return steps;
|
|
}
|
|
|
|
// ── Generate ──
|
|
|
|
const nodes = generateNodes(NODE_COUNT);
|
|
const edgeCount = Math.floor(NODE_COUNT * EDGE_RATIO);
|
|
const edges = generateEdges(nodes, edgeCount);
|
|
const layers = generateLayers(nodes);
|
|
const tour = generateTour(nodes);
|
|
|
|
const graph = {
|
|
version: "1.0",
|
|
project: {
|
|
name: "large-test-project",
|
|
languages: languages.slice(0, 3),
|
|
frameworks: frameworks.slice(0, 2),
|
|
description: `Auto-generated project with ${NODE_COUNT} nodes for performance testing.`,
|
|
analyzedAt: new Date().toISOString(),
|
|
gitCommitHash: "0000000000000000000000000000000000000000",
|
|
},
|
|
nodes,
|
|
edges,
|
|
layers,
|
|
tour,
|
|
};
|
|
|
|
const outDir = resolve(process.cwd(), ".understand-anything");
|
|
mkdirSync(outDir, { recursive: true });
|
|
const outPath = resolve(outDir, "knowledge-graph.json");
|
|
writeFileSync(outPath, JSON.stringify(graph, null, 2));
|
|
|
|
console.log(`Generated knowledge graph:`);
|
|
console.log(` Nodes: ${nodes.length}`);
|
|
console.log(` Edges: ${edges.length}`);
|
|
console.log(` Layers: ${layers.length}`);
|
|
console.log(` Tour steps: ${tour.length}`);
|
|
console.log(` Written to: ${outPath}`);
|