next-pwa-pack
Version:
PWA cache provider for Next.js/React apps (service worker, manifest, offline page, SPA cache, offline)
1 lines • 1.73 kB
JavaScript
const connections=new Set;function broadcastEvent(e){const n=`data: ${JSON.stringify(e)}\n\n`;console.log("[PWA-SSE] Broadcasting:",e),console.log("[PWA-SSE] Active connections:",connections.size),connections.forEach((e=>{try{e.enqueue(n)}catch(n){connections.delete(e)}}))}export function withPWA(e,n={webhookPath:"/api/pwa/revalidate",sseEndpoint:"/api/pwa/cache-events",revalidationSecret:process.env.REVALIDATION_SECRET}){return function(t){const o=t.nextUrl;return o.pathname===n?.webhookPath&&"POST"===t.method?handleRevalidation(t,n):o.pathname===n?.sseEndpoint&&"GET"===t.method?handleSSE(t):e(t)}}async function handleRevalidation(e,n){try{const{tags:t,secret:o,urls:a}=await e.json();return o!==n.revalidationSecret?new Response(JSON.stringify({error:"Unauthorized"}),{status:401,headers:{"Content-Type":"application/json"}}):(console.log("[PWA] Revalidation request:",{tags:t,urls:a}),broadcastEvent({type:"revalidate",tags:t,urls:a,timestamp:(new Date).toISOString()}),new Response(JSON.stringify({success:!0,message:"Revalidation completed",timestamp:(new Date).toISOString()}),{status:200,headers:{"Content-Type":"application/json"}}))}catch(e){return console.error("[PWA] Revalidation error:",e),new Response(JSON.stringify({error:"Internal server error"}),{status:500,headers:{"Content-Type":"application/json"}})}}function handleSSE(e){const n=new ReadableStream({start(n){connections.add(n);const t={type:"connected",timestamp:(new Date).toISOString()};n.enqueue(`data: ${JSON.stringify(t)}\n\n`),e.signal.addEventListener("abort",(()=>{connections.delete(n);try{n.close()}catch{}}))}});return new Response(n,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}})}