43 lines
1.3 KiB
TypeScript
43 lines
1.3 KiB
TypeScript
import { cluster, namespaces } from '@/lib/clusterMock'
|
|||
|
|
|
||
|
|
/**
|
||
|
|
* Mock stand-in for the real atlas `GET /api/stream`. Emits synthetic `topology` deltas on an
|
||
|
|
* interval and a keepalive comment frame, matching the SSE shape the frontend expects — no real
|
||
|
|
* informer, no real cluster.
|
||
|
|
*/
|
||
|
|
export async function GET(req: Request) {
|
||
|
|
const encoder = new TextEncoder()
|
||
|
|
let seq = cluster.generation
|
||
|
|
|
||
|
|
const stream = new ReadableStream({
|
||
|
|
start(controller) {
|
||
|
|
const send = (event: string, data: unknown) => {
|
||
|
|
controller.enqueue(encoder.encode(`event: ${event}\nid: ${seq++}\ndata: ${JSON.stringify(data)}\n\n`))
|
||
|
|
}
|
||
|
|
|
||
|
|
const keepalive = setInterval(() => {
|
||
|
|
controller.enqueue(encoder.encode(': keepalive\n\n'))
|
||
|
|
}, 30_000)
|
||
|
|
|
||
|
|
const delta = setInterval(() => {
|
||
|
|
const ns = namespaces[Math.floor(Math.random() * namespaces.length)]
|
||
|
|
send('topology', { namespace: ns.name, running: ns.running, total: ns.total })
|
||
|
|
}, 5_000)
|
||
|
|
|
||
|
|
req.signal.addEventListener('abort', () => {
|
||
|
|
clearInterval(keepalive)
|
||
|
|
clearInterval(delta)
|
||
|
|
controller.close()
|
||
|
|
})
|
||
|
|
},
|
||
|
|
})
|
||
|
|
|
||
|
|
return new Response(stream, {
|
||
|
|
headers: {
|
||
|
|
'Content-Type': 'text/event-stream',
|
||
|
|
'Cache-Control': 'no-cache',
|
||
|
|
Connection: 'keep-alive',
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|