/** * The chat history route. * * @module */ import { Router } from "@oak/oak"; import type { APIResponse } from "../../shared/api.ts"; import type { ChatMessage } from "../../shared/chat.ts"; import { authMiddleware } from "../middleware/auth.ts"; import { getChatMessagesAfter, getRecentChatMessages, } from "../services/chat-service.ts"; /** * The chat history route; messages are posted and edited over the socket (see * routes/ws.ts): * * - `GET /api/chat?limit=&before=&beforeId=&after=&afterId=` — signed in. * Answers messages in ascending order: the most recent by default; with * `before`, the page of older messages preceding that cursor ("load older"); * with `after`, the messages following it (resync after a reconnect). A * cursor is an ISO `created_at` plus the message id to break ties; without * `afterId` the `after` timestamp itself is included. */ const router: Router = new Router({ prefix: "/api/chat" }); router.get("/", authMiddleware, (ctx) => { const params = ctx.request.url.searchParams; const limitParam = params.get("limit"); const limit = limitParam ? Number(limitParam) : NaN; const cappedLimit = Number.isFinite(limit) ? limit : undefined; const before = params.get("before"); const after = params.get("after"); const messages = after ? getChatMessagesAfter( { createdAt: after, id: params.get("afterId") ?? undefined }, cappedLimit, ) : getRecentChatMessages( cappedLimit, before ? { createdAt: before, id: params.get("beforeId") ?? undefined } : undefined, ); const responseBody: APIResponse = { success: true, data: messages, }; ctx.response.body = responseBody; }); export default router;