import { NextRequest, NextResponse } from 'next/server'; // Prevent static generation of this route export const dynamic = 'force-dynamic'; export const runtime = 'nodejs'; // Store connected clients for webhook notifications const webhookClients = new Set<{ id: string; controller: ReadableStreamDefaultController }>(); export async function GET(request: NextRequest) { const { searchParams } = new URL(request.url); const clientId = searchParams.get('clientId') || Math.random().toString(36).substr(2, 9); const stream = new ReadableStream({ start(controller) { // Add this client to the set webhookClients.add({ id: clientId, controller }); // Send initial connection message controller.enqueue(`data: ${JSON.stringify({ type: 'connected', clientId, message: 'Webhook connection established' })}\n\n`); // Clean up when client disconnects request.signal.addEventListener('abort', () => { webhookClients.delete({ id: clientId, controller }); }); } }); return new NextResponse(stream, { headers: { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': 'Cache-Control' } }); } // Webhook endpoint that can be called when files change export async function POST(request: NextRequest) { try { const body = await request.json(); const { type = 'update', slug } = body; // Notify all connected clients const message = JSON.stringify({ type, slug, timestamp: new Date().toISOString() }); webhookClients.forEach(({ controller }) => { try { controller.enqueue(`data: ${message}\n\n`); } catch (error) { // Remove disconnected clients webhookClients.delete({ id: '', controller }); } }); return NextResponse.json({ success: true, clientsNotified: webhookClients.size }); } catch (error) { console.error('Webhook error:', error); return NextResponse.json({ error: 'Invalid webhook payload' }, { status: 400 }); } }