Files
remanso-jetstream/server.ts
Julien Calixte c84b4c5f97 robustness: split jetstream into own container, add cursor persistence
Jetstream was running backgrounded in the same container as the API server,
so crashes went undetected and Docker never restarted it. Now each process
runs as a separate docker-compose service with independent restart policies.

Also adds cursor persistence to SQLite (saved every 5s) so restarts resume
from where they left off, moves event destructuring inside try/catch blocks,
and adds global unhandled error/rejection handlers for crash visibility.
2026-02-17 01:17:42 +01:00

71 lines
1.9 KiB
TypeScript

import { Application, Router } from "@oak/oak";
import { getNotes, getNotesByDid } from "./src/data/db.ts";
import { log } from "./src/log.ts";
const router = new Router();
const PAGINATION = 20;
router.get("/", (ctx) => {
ctx.response.body = "Hello world";
});
router.get("/notes", (ctx) => {
const cursor = ctx.request.url.searchParams.get("cursor") ?? undefined;
const limit = Number(ctx.request.url.searchParams.get("limit")) || PAGINATION;
ctx.response.body = getNotes(cursor, limit);
});
router.get("/:did/notes", (ctx) => {
const { did } = ctx.params;
const cursor = ctx.request.url.searchParams.get("cursor") ?? undefined;
const limit = Number(ctx.request.url.searchParams.get("limit")) || PAGINATION;
ctx.response.body = getNotesByDid(did, cursor, limit);
});
// router.delete("/:did/:rkey", async (ctx) => {
// const { did, rkey } = ctx.params;
// let verifiedDid: string;
// try {
// verifiedDid = await authenticateRequest(
// ctx.request.headers.get("Authorization"),
// );
// } catch {
// ctx.response.status = 401;
// ctx.response.body = { error: "Unauthorized" };
// return;
// }
// if (verifiedDid !== did) {
// ctx.response.status = 403;
// ctx.response.body = { error: "You can only delete your own notes" };
// return;
// }
// deleteNote({ did, rkey });
// ctx.response.status = 204;
// })
const app = new Application();
app.use(async (ctx, next) => {
ctx.response.headers.set("Access-Control-Allow-Origin", "*");
ctx.response.headers.set(
"Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS",
);
ctx.response.headers.set(
"Access-Control-Allow-Headers",
"Content-Type, Authorization",
);
if (ctx.request.method === "OPTIONS") {
ctx.response.status = 204;
return;
}
await next();
});
app.use(router.routes());
app.use(router.allowedMethods());
log("[server] listening on port 8080");
app.listen({ port: 8080 });