feat(deploy): add portable external-service stack
This commit is contained in:
@@ -77,6 +77,9 @@ export function sessionRoutes(
|
||||
"Access-Control-Allow-Origin": origin,
|
||||
"Access-Control-Allow-Credentials": "true",
|
||||
});
|
||||
// Send the handshake immediately. Without this, Node waits for the first event body and
|
||||
// proxies/clients cannot establish an idle SSE subscription or inspect its headers.
|
||||
reply.raw.flushHeaders();
|
||||
const send = (event: string, data: object) => reply.raw.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);
|
||||
const off = d.hub.subscribe(id, send, rt?.bridge.pendingWidget() ?? null);
|
||||
req.raw.on("close", off);
|
||||
|
||||
@@ -2,9 +2,33 @@ import { test, expect } from "vitest";
|
||||
import { buildApp } from "../src/app.js";
|
||||
import { loadConfig } from "../src/config.js";
|
||||
|
||||
test("GET /health ritorna ok", async () => {
|
||||
test("GET /health reports process readiness without external services", async () => {
|
||||
const app = buildApp(loadConfig({ THT_HARNESS_DIR: "/tmp/h" }));
|
||||
const res = await app.inject({ method: "GET", url: "/health" });
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(res.headers["content-type"]).toContain("application/json");
|
||||
expect(res.json()).toEqual({ status: "ok" });
|
||||
});
|
||||
|
||||
test("SSE response headers are flushed before the first event", async () => {
|
||||
const app = buildApp(loadConfig({ THT_HARNESS_DIR: "/tmp/h" }));
|
||||
await app.listen({ port: 0, host: "127.0.0.1" });
|
||||
const port = (app.server.address() as { port: number }).port;
|
||||
const controller = new AbortController();
|
||||
|
||||
try {
|
||||
const response = await Promise.race([
|
||||
fetch(`http://127.0.0.1:${port}/sessions/header-probe/events`, {
|
||||
signal: controller.signal,
|
||||
}),
|
||||
new Promise<never>((_, reject) =>
|
||||
setTimeout(() => reject(new Error("SSE headers were not flushed")), 250),
|
||||
),
|
||||
]);
|
||||
expect(response.headers.get("content-type")).toContain("text/event-stream");
|
||||
expect(response.headers.get("cache-control")).toBe("no-cache");
|
||||
} finally {
|
||||
controller.abort();
|
||||
await app.close();
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user