/** * rNotes demo — client-side WebSocket controller. * * Connects to rSpace via DemoSync, populates note cards, * packing list checkboxes, sidebar, and notebook header. */ import { DemoSync, type DemoShape } from "../../../lib/demo-sync-vanilla"; // ── Helpers ── function shapesByType(shapes: Record, type: string): DemoShape[] { return Object.values(shapes).filter((s) => s.type === type); } function shapeByType(shapes: Record, type: string): DemoShape | undefined { return Object.values(shapes).find((s) => s.type === type); } function $(id: string): HTMLElement | null { return document.getElementById(id); } // ── Simple markdown renderer ── function renderMarkdown(text: string): string { if (!text) return ""; const lines = text.split("\n"); const out: string[] = []; let inCodeBlock = false; let codeLang = ""; let codeLines: string[] = []; let inList: "ul" | "ol" | null = null; function flushList() { if (inList) { out.push(inList === "ul" ? "" : ""); inList = null; } } function flushCode() { if (inCodeBlock) { const escaped = codeLines.join("\n").replace(//g, ">"); out.push(`
${codeLang ? `
${codeLang}
` : ""}
${escaped}
`); inCodeBlock = false; codeLines = []; codeLang = ""; } } for (const raw of lines) { const line = raw; // Code fence if (line.startsWith("```")) { if (inCodeBlock) { flushCode(); } else { flushList(); inCodeBlock = true; codeLang = line.slice(3).trim(); } continue; } if (inCodeBlock) { codeLines.push(line); continue; } // Blank line if (!line.trim()) { flushList(); continue; } // Headings if (line.startsWith("### ")) { flushList(); out.push(`

${inlineFormat(line.slice(4))}

`); continue; } if (line.startsWith("## ")) { flushList(); out.push(`

${inlineFormat(line.slice(3))}

`); continue; } if (line.startsWith("# ")) { flushList(); out.push(`

${inlineFormat(line.slice(2))}

`); continue; } if (line.startsWith("#### ")) { flushList(); out.push(`

${inlineFormat(line.slice(5))}

`); continue; } if (line.startsWith("##### ")) { flushList(); out.push(`
${inlineFormat(line.slice(6))}
`); continue; } // Blockquote if (line.startsWith("> ")) { flushList(); out.push(`

${inlineFormat(line.slice(2))}

`); continue; } // Unordered list const ulMatch = line.match(/^[-*]\s+(.+)/); if (ulMatch) { if (inList !== "ul") { flushList(); out.push("