diff --git a/cli/dev/DevServer.ts b/cli/dev/DevServer.ts index f8cc950..1aa5929 100644 --- a/cli/dev/DevServer.ts +++ b/cli/dev/DevServer.ts @@ -121,26 +121,55 @@ circuit.add() async handleFileChangedOnFilesystem(absoluteFilePath: string) { const relativeFilePath = path.relative(this.projectDir, absoluteFilePath) - // We've temporarily disabled upserting manual edits from filesystem changes - // because it can be edited by the browser - if (relativeFilePath.includes("manual-edits.json")) return + console.log(`\nFile change detected: ${relativeFilePath}`) + + if (relativeFilePath.includes("manual-edits.json")) { + console.log("Skipping manual-edits.json update") + return + } await this.typesHandler?.handleFileTypeDependencies(absoluteFilePath) - console.log(`${relativeFilePath} saved. Applying changes...`) - await this.fsKy - .post("api/files/upsert", { - json: { - file_path: relativeFilePath, - text_content: fs.readFileSync(absoluteFilePath, "utf-8"), - initiator: "filesystem_change", - }, - }) - .json() + console.log("Sending file update event to clients...") + try { + if (this.httpServer) { + const sseClients = (this.httpServer as any).sseClients + if (sseClients?.size > 0) { + console.log(`Broadcasting to ${sseClients.size} clients`) + const event = { + type: "FILE_UPDATED", + file: relativeFilePath, + timestamp: Date.now(), + } + + for (const client of sseClients) { + client.write(`data: ${JSON.stringify(event)}\n\n`) + } + console.log("Event broadcast complete") + } else { + console.log("No SSE clients connected") + } + } else { + console.log("HTTP server not initialized") + } + + console.log("Updating file on server...") + await this.fsKy + .post("api/files/upsert", { + json: { + file_path: relativeFilePath, + text_content: fs.readFileSync(absoluteFilePath, "utf-8"), + initiator: "filesystem_change", + }, + }) + .json() + console.log("File update complete") + } catch (error) { + console.error("Error in handleFileChangedOnFilesystem:", error) + } } async upsertInitialFiles() { - // Scan project directory for all files and upsert them const fileNames = fs.readdirSync(this.projectDir) for (const fileName of fileNames) { if (fs.statSync(path.join(this.projectDir, fileName)).isDirectory()) diff --git a/cli/dev/register.ts b/cli/dev/register.ts index 723dbb2..0511278 100644 --- a/cli/dev/register.ts +++ b/cli/dev/register.ts @@ -16,6 +16,8 @@ export const registerDev = (program: Command) => { .argument("[file]", "Path to the snippet file") .option("-p, --port ", "Port to run server on", "3020") .action(async (file: string, options: { port: string }) => { + console.log("Starting the development server, please wait...") + let port = parseInt(options.port) const isPortAvailable = (port: number): Promise => { @@ -72,5 +74,6 @@ export const registerDev = (program: Command) => { await server.start() await server.addEntrypoint() + console.log("Development server started successfully.") }) } diff --git a/lib/server/createHttpServer.ts b/lib/server/createHttpServer.ts index 029607f..6f6e118 100644 --- a/lib/server/createHttpServer.ts +++ b/lib/server/createHttpServer.ts @@ -10,10 +10,33 @@ import { getIndex } from "../site/getIndex" export const createHttpServer = async (port = 3020) => { const fileServerHandler = getNodeHandler(winterspecBundle as any, {}) + let sseClients = new Set() const server = http.createServer(async (req, res) => { const url = new URL(req.url!, `http://${req.headers.host}`) + if (url.pathname === "/api/events/stream") { + console.log("Client connecting to SSE stream") + res.writeHead(200, { + "Content-Type": "text/event-stream", + "Cache-Control": "no-cache", + Connection: "keep-alive", + }) + + sseClients.add(res) + console.log(`SSE client connected. Total clients: ${sseClients.size}`) + + res.write('data: {"type":"connected"}\n\n') + + req.on("close", () => { + console.log("SSE client disconnected") + sseClients.delete(res) + console.log(`Remaining clients: ${sseClients.size}`) + }) + + return + } + if (url.pathname === "/standalone.min.js") { const standaloneFilePath = process.env.RUNFRAME_STANDALONE_FILE_PATH || @@ -59,6 +82,7 @@ export const createHttpServer = async (port = 3020) => { }) return new Promise<{ server: http.Server }>((resolve) => { + ;(server as any).sseClients = sseClients // Make clients accessible server.listen(port, () => { console.log(`Server running at http://localhost:${port}`) resolve({ server }) diff --git a/lib/site/getIndex.ts b/lib/site/getIndex.ts index aaed163..96e5c57 100644 --- a/lib/site/getIndex.ts +++ b/lib/site/getIndex.ts @@ -3,12 +3,97 @@ import pkg from "../../package.json" export const getIndex = async () => { return ` + +
loading...
+
+
+
+

Circuit is rendering...

+
+