/** * Stage-7 closure smoke server — boots a real Bun.serve over a * `createTestHost`-backed Host and mounts FOUR concrete engines: * * 1. `api-graphql-yoga` at `POST /graphql/yoga` — accepts a federated * schema contributed by TWO plugins (`plugin-a` and `plugin-b`). * 2. `api-graphql-apollo` at `POST /graphql/apollo` — same federated * schema, different engine, identical observable surface. * 3. `api-ws-bun` at `WS /ws` — real WebSocket upgrade via Bun's * `server.upgrade(...)` flow; engine.attach wires the heartbeat / * backpressure / handshake pipeline; `POST /ws/publish` broadcasts * a tenant-scoped event via `engine.broadcast(...)`. * 4. `api-sse-bun` at `GET /sse` — handshake → ReadableStream body; * `POST /sse/publish` calls `engine.publish(...)` to fan-out. * * No mocks. No hand-wired shims. If a downstream surface is missing, * STOP and open a coherence-fix change. */ import { createTestHost, type TestHost } from "@suaveplan/api-host/testing"; import { createGraphqlRegistry, type GraphqlRegistry, } from "@suaveplan/api-graphql"; import { createApolloGraphqlEngine } from "@suaveplan/api-graphql-apollo"; import { createYogaGraphqlEngine, type PluginRegistryEntry, } from "@suaveplan/api-graphql-yoga"; import { createBunWsEngine, type BunWsEngine, type ManagedConnection, type BunWsSocketSink, } from "@suaveplan/api-ws-bun"; import { createBunSseEngine, type BunSseEngine, } from "@suaveplan/api-sse-bun"; import type { Principal } from "@suaveplan/api-types/principal"; import type { TenantId } from "@suaveplan/api-types/tenant"; import type { RequestContext } from "@suaveplan/api-types/plugin-context"; // ── Bun WebSocket socket shape ───────────────────────────────────────── interface WsLikeSocket { readonly data: { readonly connectionId: string; readonly tenant: TenantId; readonly subscribeTopic: string | null; }; send(data: string): void; close(code: number, reason?: string): void; ping(): void; } // ── Seed identities ──────────────────────────────────────────────────── const SEED_PRINCIPAL: Principal = { id: "engines-smoke-principal" as Principal["id"], scopes: ["engines:run"] as unknown as Principal["scopes"], claims: { source: "foundation-stack-engines" }, }; const TENANT_A = "tenant-a" as TenantId; const TENANT_B = "tenant-b" as TenantId; // ── Plugin A: contributes `pluginA` + `bothA` on Query ───────────────── function buildPluginARegistry(): GraphqlRegistry { const reg = createGraphqlRegistry({ plugin: "plugin-a" }); reg.addTypes(` type Query { pluginA: String! bothA: String! } `); reg.addResolvers({ Query: { pluginA: () => "from plugin-a", bothA: () => "A-half-of-both", }, }); return reg; } // ── Plugin B: contributes `pluginB` + `bothB` on Query ───────────────── function buildPluginBRegistry(): GraphqlRegistry { const reg = createGraphqlRegistry({ plugin: "plugin-b" }); reg.addTypes(` extend type Query { pluginB: String! bothB: String! } `); reg.addResolvers({ Query: { pluginB: () => "from plugin-b", bothB: () => "B-half-of-both", }, }); return reg; } /** * Yoga consumes the two registries as separate federation entries; the * engine merges them via `federatePlugins(entries)` at `buildSchema`. */ function buildYogaEngine() { const entries: ReadonlyArray = [ { plugin: "plugin-a", registry: buildPluginARegistry() as PluginRegistryEntry["registry"], }, { plugin: "plugin-b", registry: buildPluginBRegistry() as PluginRegistryEntry["registry"], }, ]; const engine = createYogaGraphqlEngine({ entries }); // The engine appends one __inline__ entry from the registry passed // to `buildSchema`; an empty registry is sufficient — the merge // happens off the `entries` list. const empty = createGraphqlRegistry({ plugin: "__inline__" }); engine.buildSchema(empty); return engine; } /** * Apollo accepts a single registry — we manually combine plugin-a + * plugin-b SDL + resolver maps into one registry before handing it to * the engine. `mergeSdl` runs internally on the engine side over a * single contribution; collisions across plugins would surface here at * registry-merge time (the two contributions are disjoint by design). */ function buildApolloEngine() { // Federate the two plugins by chaining both contributions into a // single registry handed to the Apollo engine. The engine's // `buildSchema` runs `mergeSdl` over the registry's typeDefs, which // is the same merger used by Yoga's federation path — so the // observable behaviour matches the Yoga sibling. const combined = createGraphqlRegistry({ plugin: "federated" }); combined.addTypes(` type Query { pluginA: String! bothA: String! } `); combined.addTypes(` extend type Query { pluginB: String! bothB: String! } `); combined.addResolvers({ Query: { pluginA: () => "from plugin-a", bothA: () => "A-half-of-both", }, }); combined.addResolvers({ Query: { pluginB: () => "from plugin-b", bothB: () => "B-half-of-both", }, }); const engine = createApolloGraphqlEngine(); engine.buildSchema(combined); return engine; } function buildStubGraphqlContext(): RequestContext { return {} as RequestContext; } // ── WS engine ────────────────────────────────────────────────────────── interface SmokeBag { readonly host: TestHost; readonly yoga: ReturnType; readonly apollo: ReturnType; readonly ws: BunWsEngine>; readonly sse: BunSseEngine; readonly wsConnections: Map< string, { connection: ManagedConnection; tenant: TenantId } >; } function makeReconnectSecret(): Uint8Array { const buffer = new ArrayBuffer(32); const bytes = new Uint8Array(buffer); for (let i = 0; i < 32; i++) bytes[i] = i + 1; return bytes; } async function bootstrap(): Promise { const host = await createTestHost({ seed: { principal: SEED_PRINCIPAL, tenants: [ { id: TENANT_A, slug: "tenant-a", status: "active" as const, createdAt: new Date( "2026-01-01T00:00:00.000Z" ).toISOString(), }, { id: TENANT_B, slug: "tenant-b", status: "active" as const, createdAt: new Date( "2026-01-01T00:00:00.000Z" ).toISOString(), }, ], defaultTenant: null, }, }); const yoga = buildYogaEngine(); const apollo = buildApolloEngine(); const ws = createBunWsEngine>({ reconnectTokenSecret: makeReconnectSecret() as Uint8Array, pluginId: "engines-smoke-ws", }); const sse = createBunSseEngine({ plugin: "engines-smoke-sse", authenticate: (req: { url: string }) => { const url = new URL(req.url); const tenant = url.searchParams.get("tenant") ?? "tenant-a"; return { tenantId: tenant as TenantId, principal: SEED_PRINCIPAL, }; }, }); return { host, yoga, apollo, ws, sse, wsConnections: new Map(), }; } // ── HTTP routing ─────────────────────────────────────────────────────── function json(body: unknown, init?: ResponseInit): Response { return new Response(JSON.stringify(body), { ...init, headers: { "content-type": "application/json", ...(init?.headers ?? {}), }, }); } async function handleGraphqlYoga(req: Request, bag: SmokeBag): Promise { const body = (await req.json().catch(() => ({}))) as { query?: string; variables?: Record; operationName?: string; }; if (typeof body.query !== "string") { return json({ errors: [{ message: "missing query" }] }, { status: 400 }); } try { const result = await bag.yoga.executeQuery( { query: body.query, ...(body.variables !== undefined ? { variables: body.variables } : {}), ...(body.operationName !== undefined ? { operationName: body.operationName } : {}), }, buildStubGraphqlContext() ); return json(result); } catch (err) { return json( { errors: [ { message: err instanceof Error ? err.message : String(err), }, ], }, { status: 500 } ); } } async function handleGraphqlApollo( req: Request, bag: SmokeBag ): Promise { const body = (await req.json().catch(() => ({}))) as { query?: string; variables?: Record; operationName?: string; }; if (typeof body.query !== "string") { return json({ errors: [{ message: "missing query" }] }, { status: 400 }); } try { const result = await bag.apollo.executeQuery( { query: body.query, ...(body.variables !== undefined ? { variables: body.variables } : {}), ...(body.operationName !== undefined ? { operationName: body.operationName } : {}), }, buildStubGraphqlContext() ); return json(result); } catch (err) { return json( { errors: [ { message: err instanceof Error ? err.message : String(err), }, ], }, { status: 500 } ); } } async function handleWsPublish( req: Request, bag: SmokeBag ): Promise { const body = (await req.json().catch(() => ({}))) as { topic?: string; tenant?: string; payload?: Record; }; const topic = body.topic ?? "default"; const tenant = (body.tenant ?? "tenant-a") as TenantId; const payload = body.payload ?? {}; const delivered = bag.ws.broadcast( { tenant, capabilities: new Set(), }, topic, { tenant, payload } ); return json({ delivered, topic, tenant }); } async function handleSseAccept( req: Request, url: URL, bag: SmokeBag ): Promise { const topic = url.searchParams.get("topic") ?? "default"; return bag.sse.acceptRequest({ request: { headers: req.headers, url: req.url, method: req.method, }, path: "/sse", topic, }); } async function handleSsePublish( req: Request, bag: SmokeBag ): Promise { const body = (await req.json().catch(() => ({}))) as { topic?: string; tenant?: string; data?: string; id?: string; }; const topic = body.topic ?? "default"; const tenant = (body.tenant ?? "tenant-a") as TenantId; const delivered = await bag.sse.publish({ topic, tenantId: tenant, event: { id: body.id ?? `e-${Date.now()}`, data: body.data ?? "tick", }, }); return json({ delivered, topic, tenant }); } function handleEnginesList(bag: SmokeBag): Response { return json({ engines: [ { name: "yoga", path: "/graphql/yoga", method: "POST" }, { name: "apollo", path: "/graphql/apollo", method: "POST" }, { name: "ws-bun", path: "/ws", method: "GET (upgrade)" }, { name: "sse-bun", path: "/sse", method: "GET" }, ], host: { adminPrefix: "/admin", wsConnections: bag.ws.connectionsSnapshot(), sseConnections: bag.sse.snapshotConnections(), }, }); } // ── Bootstrap + Bun.serve ────────────────────────────────────────────── if (import.meta.main) { const port = Number.parseInt(process.env["PORT"] ?? "3711", 10); const bag = await bootstrap(); interface WsAttachData { readonly connectionId: string; readonly tenant: TenantId; readonly subscribeTopic: string | null; } const server = Bun.serve({ port, idleTimeout: 0, async fetch(request: Request, server: { upgrade: (req: Request, opts: { data: WsAttachData }) => boolean }): Promise { const url = new URL(request.url); if (url.pathname === "/internal/livez") { return new Response("ok", { status: 200 }); } if (url.pathname === "/internal/engines") { return handleEnginesList(bag); } if (request.method === "POST" && url.pathname === "/graphql/yoga") { return handleGraphqlYoga(request, bag); } if ( request.method === "POST" && url.pathname === "/graphql/apollo" ) { return handleGraphqlApollo(request, bag); } if (request.method === "POST" && url.pathname === "/ws/publish") { return handleWsPublish(request, bag); } if (request.method === "GET" && url.pathname === "/sse") { return handleSseAccept(request, url, bag); } if (request.method === "POST" && url.pathname === "/sse/publish") { return handleSsePublish(request, bag); } // WS upgrade endpoint if (url.pathname === "/ws") { const tenant = (url.searchParams.get("tenant") ?? "tenant-a") as TenantId; const connectionId = `c-${Date.now()}-${Math.random() .toString(36) .slice(2, 8)}`; const subscribeTopic = url.searchParams.get("topic"); const upgraded = server.upgrade(request, { data: { connectionId, tenant, subscribeTopic }, }); if (upgraded) { // Return undefined => the upgrade response is sent by Bun. return new Response(null, { status: 101 }); } return new Response("upgrade failed", { status: 400 }); } return bag.host.fetch(request); }, websocket: { open(socket: WsLikeSocket) { const data = socket.data; const sink: BunWsSocketSink = { send: (s: string) => socket.send(s), close: (code: number, reason?: string) => socket.close(code, reason), ping: () => socket.ping(), }; const conn = bag.ws.attach({ id: data.connectionId, principal: SEED_PRINCIPAL, tenantId: data.tenant, capabilities: new Set(), tokenExpiresAt: Date.now() + 60 * 60 * 1000, sink, }); bag.wsConnections.set(data.connectionId, { connection: conn, tenant: data.tenant, }); if (data.subscribeTopic !== null) { conn.subscribe(data.subscribeTopic, { tenant: data.tenant, }); } }, message(socket: WsLikeSocket, message: string | Buffer) { const data = socket.data; const entry = bag.wsConnections.get(data.connectionId); if (entry === undefined) return; // Parse incoming control frames — `{ "op": "subscribe", // "topic": "..." }` and `{ "op": "ack", "id": "..." }`. try { const text = typeof message === "string" ? message : new TextDecoder().decode(message); const parsed = JSON.parse(text) as { op?: string; topic?: string; id?: string; }; if (parsed.op === "subscribe" && parsed.topic) { entry.connection.subscribe(parsed.topic, { tenant: entry.tenant, }); } else if (parsed.op === "ack" && parsed.id) { entry.connection.ack(parsed.id); } } catch { /* ignore malformed inbound frames */ } bag.ws.recordInbound(entry.connection); }, close(socket: WsLikeSocket) { const data = socket.data; const entry = bag.wsConnections.get(data.connectionId); if (entry !== undefined) { try { entry.connection.close(1000, "client closed"); } catch { /* idempotent */ } bag.wsConnections.delete(data.connectionId); } }, }, }); // eslint-disable-next-line no-console console.log( `[e2e-foundation-stack-engines] listening on :${server.port} (engines: yoga, apollo, ws-bun, sse-bun)` ); const shutdown = async (): Promise => { try { await bag.yoga.dispose(); } catch { /* idempotent */ } try { await bag.apollo.dispose(); } catch { /* idempotent */ } try { await bag.ws.dispose(); } catch { /* idempotent */ } try { bag.sse.dispose(); } catch { /* idempotent */ } try { await bag.host.dispose(); } catch { /* idempotent */ } server.stop(true); process.exit(0); }; process.on("SIGINT", shutdown); process.on("SIGTERM", shutdown); }