diff options
| author | Dax Raad <[email protected]> | 2025-05-18 14:13:04 -0400 |
|---|---|---|
| committer | Dax Raad <[email protected]> | 2025-05-26 12:40:17 -0400 |
| commit | 0e303e6508edb4374213d1f98ec383b266339774 (patch) | |
| tree | f7dc146eb58126f55f470ef135b66c678bf16898 /js/src/server | |
| parent | bcd2fd68b7fa00af055f558049994c2975d9515d (diff) | |
| download | opencode-0e303e6508edb4374213d1f98ec383b266339774.tar.gz opencode-0e303e6508edb4374213d1f98ec383b266339774.zip | |
sync
Diffstat (limited to 'js/src/server')
| -rw-r--r-- | js/src/server/server.ts | 86 |
1 files changed, 58 insertions, 28 deletions
diff --git a/js/src/server/server.ts b/js/src/server/server.ts index 6266e9421..dd066c400 100644 --- a/js/src/server/server.ts +++ b/js/src/server/server.ts @@ -1,34 +1,64 @@ import { Log } from "../util/log"; +import { Bus } from "../bus"; -export namespace RPC { - const log = Log.create({ service: "rpc" }); +import { Hono } from "hono"; +import { streamSSE } from "hono/streaming"; +import { Session } from "../session/session"; +import { zValidator } from "@hono/zod-validator"; +import { z } from "zod"; + +export namespace Server { + const log = Log.create({ service: "server" }); const PORT = 16713; - export function listen(input?: { port?: number }) { - const port = input?.port ?? PORT; - log.info("trying", { port }); - try { - const server = Bun.serve({ - port, - websocket: { - open() {}, - message() {}, - }, - routes: { - "/ws": (req, server) => { - if (server.upgrade(req)) return; - return new Response("Not a websocket request", { status: 400 }); - }, + + export type App = ReturnType<typeof listen>; + + export function listen() { + const app = new Hono() + .get("/event", async (c) => { + log.info("event connected"); + return streamSSE(c, async (stream) => { + const unsub = Bus.subscribeAll(async (event) => { + await stream.writeSSE({ + data: JSON.stringify(event), + }); + }); + await new Promise<void>((resolve) => { + stream.onAbort(() => { + unsub(); + resolve(); + log.info("event disconnected"); + }); + }); + }); + }) + .post("/session_create", async (c) => { + const session = await Session.create(); + return c.json(session); + }) + .post( + "/session_chat", + zValidator( + "json", + z.object({ + sessionID: z.string(), + parts: z.custom<Session.Message["parts"]>(), + }), + ), + async (c) => { + const body = c.req.valid("json"); + const msg = await Session.chat(body.sessionID, ...body.parts); + return c.json(msg); }, - }); - log.info("listening", { port }); - return { - server, - }; - } catch (e: any) { - if (e?.code === "EADDRINUSE") { - return listen({ port: port + 1 }); - } - throw e; - } + ); + + Bun.serve({ + port: PORT, + hostname: "0.0.0.0", + idleTimeout: 0, + fetch: app.fetch, + }); + + return app; } } |
