agentcrumbs
Version:
Debug mode for any agent.
116 lines • 3.8 kB
JavaScript
import http from "node:http";
import fs from "node:fs";
import { EventEmitter } from "node:events";
import { CrumbStore } from "./store.js";
const SESSION_FILE = "/tmp/agentcrumbs.session";
export class CollectorServer extends EventEmitter {
server;
stores = new Map();
baseDir;
port;
constructor(port, storeDir) {
super();
this.port = port;
this.baseDir = storeDir;
}
getStoreForApp(app) {
let store = this.stores.get(app);
if (!store) {
store = CrumbStore.forApp(app, this.baseDir);
this.stores.set(app, store);
}
return store;
}
start() {
return new Promise((resolve, reject) => {
this.server = http.createServer((req, res) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
if (req.method === "OPTIONS") {
res.writeHead(204);
res.end();
return;
}
if (req.url === "/health" && req.method === "GET") {
const apps = CrumbStore.listApps(this.baseDir);
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify({
status: "ok",
port: this.port,
apps,
session: this.getActiveSession() ?? null,
}));
return;
}
if (req.url === "/crumb" && req.method === "POST") {
let body = "";
req.on("data", (chunk) => {
body += chunk.toString();
});
req.on("end", () => {
try {
const crumb = JSON.parse(body);
const app = crumb.app || "unknown";
const store = this.getStoreForApp(app);
store.appendRaw(body);
this.emit("crumb", crumb);
res.writeHead(200);
res.end("ok");
}
catch {
res.writeHead(400);
res.end("bad json");
}
});
return;
}
res.writeHead(404);
res.end();
});
this.server.on("error", (err) => {
this.emit("error", err);
reject(err);
});
this.server.listen(this.port, () => {
resolve();
});
});
}
stop() {
if (this.server) {
this.server.close();
this.server = undefined;
}
for (const store of this.stores.values()) {
store.close();
}
this.stores.clear();
}
getPort() {
return this.port;
}
startSession(id) {
fs.writeFileSync(SESSION_FILE, id);
}
stopSession() {
try {
const id = fs.readFileSync(SESSION_FILE, "utf-8").trim();
fs.unlinkSync(SESSION_FILE);
return id || undefined;
}
catch {
return undefined;
}
}
getActiveSession() {
try {
const id = fs.readFileSync(SESSION_FILE, "utf-8").trim();
return id || undefined;
}
catch {
return undefined;
}
}
}
//# sourceMappingURL=server.js.map