summaryrefslogtreecommitdiffhomepage
path: root/js/src/server
diff options
context:
space:
mode:
authorDax Raad <[email protected]>2025-05-18 14:13:04 -0400
committerDax Raad <[email protected]>2025-05-26 12:40:17 -0400
commit0e303e6508edb4374213d1f98ec383b266339774 (patch)
treef7dc146eb58126f55f470ef135b66c678bf16898 /js/src/server
parentbcd2fd68b7fa00af055f558049994c2975d9515d (diff)
downloadopencode-0e303e6508edb4374213d1f98ec383b266339774.tar.gz
opencode-0e303e6508edb4374213d1f98ec383b266339774.zip
sync
Diffstat (limited to 'js/src/server')
-rw-r--r--js/src/server/server.ts86
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;
}
}