/** * Canvas module — the collaborative infinite canvas. * * This is the original rSpace canvas restructured as an rSpace module. * Routes are relative to the mount point (/:space/canvas in unified mode, * / in standalone mode). */ import { Hono } from "hono"; import { resolve } from "node:path"; import { renderShell } from "../../server/shell"; import { getModuleInfoList } from "../../shared/module"; import type { RSpaceModule } from "../../shared/module"; import { loadCommunity, getDocumentData } from "../../server/community-store"; const DIST_DIR = resolve(import.meta.dir, "../../dist"); const routes = new Hono(); // GET /api/meta — space metadata (owner, members) for space-settings fallback routes.get("/api/meta", async (c) => { const space = c.req.param("space") || "demo"; try { await loadCommunity(space); const doc = getDocumentData(space); if (!doc) return c.json({ meta: {} }); return c.json({ meta: { ownerDID: doc.meta?.ownerDID, members: doc.members } }); } catch { return c.json({ meta: {} }); } }); /** * Extract body content and scripts from the full canvas.html page. * Strips the shell chrome (header, tab-bar, welcome overlay) that renderShell provides, * and returns just the canvas-specific DOM + inline styles + module scripts. */ function extractCanvasContent(html: string): { body: string; styles: string; scripts: string } { // Extract inline