mirror of
https://github.com/hansjone/mind-map.git
synced 2026-10-09 00:43:20 +08:00
Initial commit: DSH mind-map canvas monorepo
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
commit
2ecd300ada
92 changed files with 20486 additions and 0 deletions
40
scripts/extract-skins.mjs
Normal file
40
scripts/extract-skins.mjs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
const srcPath =
|
||||
"C:/Users/zhout/.dsh/profiles/web/node_modules/dsh-dream-skin/lib/client.js";
|
||||
const src = fs.readFileSync(srcPath, "utf8");
|
||||
const start = src.indexOf("const SKINS = [");
|
||||
const end = src.indexOf("];", start);
|
||||
if (start < 0 || end < 0) throw new Error("SKINS not found");
|
||||
const block = src.slice(start, end + 2);
|
||||
const skins = new Function(`${block}; return SKINS;`)();
|
||||
|
||||
const names = {
|
||||
abyss: ["Abyss", "深渊"],
|
||||
aurora: ["Aurora", "极光"],
|
||||
nebula: ["Nebula", "星云"],
|
||||
ember: ["Ember", "余烬"],
|
||||
midnight: ["Midnight", "午夜"],
|
||||
ivory: ["Ivory", "象牙"],
|
||||
mist: ["Mist", "晨雾"],
|
||||
rose: ["Rose", "玫瑰"],
|
||||
};
|
||||
|
||||
const out = skins.map((s) => ({
|
||||
id: s.id,
|
||||
colorScheme: s.colorScheme,
|
||||
name: names[s.id]?.[0] ?? s.id,
|
||||
nameZh: names[s.id]?.[1] ?? s.id,
|
||||
tokens: s.tokens,
|
||||
}));
|
||||
|
||||
const dir = path.resolve("packages/dream-skin/src");
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
fs.writeFileSync(path.join(dir, "skins.json"), JSON.stringify(out, null, 2));
|
||||
console.log(
|
||||
"wrote",
|
||||
out.length,
|
||||
"skins:",
|
||||
out.map((s) => s.id).join(","),
|
||||
);
|
||||
84
scripts/stress-10k.mts
Normal file
84
scripts/stress-10k.mts
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/**
|
||||
* Stress: create a canvas and grow to N nodes via API.
|
||||
* Usage: node --import tsx scripts/stress-10k.mts [count=10000]
|
||||
*/
|
||||
const BASE = process.env.MINDMAP_URL ?? "http://127.0.0.1:17890";
|
||||
const COUNT = Number(process.argv[2] ?? 10_000);
|
||||
|
||||
async function json<T>(url: string, init?: RequestInit): Promise<T> {
|
||||
const res = await fetch(url, {
|
||||
...init,
|
||||
headers: { "Content-Type": "application/json", ...(init?.headers ?? {}) },
|
||||
});
|
||||
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
|
||||
return res.json() as Promise<T>;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const t0 = performance.now();
|
||||
const created = await json<{
|
||||
canvas: { id: string; focusNodeId: string };
|
||||
}>(`${BASE}/api/canvases`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ title: `stress-${COUNT}` }),
|
||||
});
|
||||
const canvasId = created.canvas.id;
|
||||
let parent = created.canvas.focusNodeId;
|
||||
const batch = 50;
|
||||
let made = 1;
|
||||
console.log(`canvas ${canvasId}, target ${COUNT}`);
|
||||
|
||||
while (made < COUNT) {
|
||||
const n = Math.min(batch, COUNT - made);
|
||||
const ops = Array.from({ length: n }, (_, i) => ({
|
||||
type: "create_node" as const,
|
||||
text: `n${made + i}`,
|
||||
parentId: parent,
|
||||
sidePref: (made + i) % 2 === 0 ? (-1 as const) : (1 as const),
|
||||
}));
|
||||
const tBatch = performance.now();
|
||||
const result = await json<{
|
||||
snapshot: { nodes: { id: string }[]; canvas: { focusNodeId: string } };
|
||||
positions: Record<string, unknown>;
|
||||
}>(`${BASE}/api/canvases/${canvasId}/ops`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ ops, origin: "user", summary: `batch ${made}` }),
|
||||
});
|
||||
made += n;
|
||||
// widen tree: periodically use a recent child as parent
|
||||
const nodes = result.snapshot.nodes;
|
||||
parent = nodes[Math.floor(nodes.length * 0.5)]?.id ?? parent;
|
||||
const dt = performance.now() - tBatch;
|
||||
if (made % 500 === 0 || made >= COUNT) {
|
||||
console.log(
|
||||
`nodes=${made} batch=${dt.toFixed(0)}ms layoutKeys=${Object.keys(result.positions).length}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const tLoad0 = performance.now();
|
||||
const loaded = await json<{ nodes: unknown[]; positions: Record<string, unknown> }>(
|
||||
`${BASE}/api/canvases/${canvasId}`,
|
||||
);
|
||||
const tLoad = performance.now() - tLoad0;
|
||||
const total = performance.now() - t0;
|
||||
console.log(
|
||||
JSON.stringify(
|
||||
{
|
||||
ok: true,
|
||||
canvasId,
|
||||
nodes: loaded.nodes.length,
|
||||
positions: Object.keys(loaded.positions).length,
|
||||
loadMs: Math.round(tLoad),
|
||||
totalMs: Math.round(total),
|
||||
},
|
||||
null,
|
||||
2,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
main().catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue