const CACHE_NAME = 'the-door-v2'; const ASSETS = [ '/', '/index.html', '/about', '/manifest.json' ]; // Crisis resources to show when everything fails const CRISIS_OFFLINE_RESPONSE = ` You're Not Alone | The Door

You are not alone.

Your connection is down, but help is still available.

Call or text 988
Suicide & Crisis Lifeline
Free, 24/7, Confidential

Call 988 Now

Or text HOME to 741741
Crisis Text Line

When you're ready:

"The Lord is close to the brokenhearted and saves those who are crushed in spirit." — Psalm 34:18

This page was created by The Door — a crisis intervention project.
Connection will restore automatically. You don't have to go through this alone.

`; // Install event - cache core assets self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE_NAME).then((cache) => { return cache.addAll(ASSETS); }) ); self.skipWaiting(); }); // Activate event - cleanup old caches self.addEventListener('activate', (event) => { event.waitUntil( caches.keys().then((keys) => { return Promise.all( keys.filter((key) => key !== CACHE_NAME).map((key) => caches.delete(key)) ); }) ); self.clients.claim(); }); // Fetch event - network first, fallback to cache for static, // but for the crisis front door, we want to ensure the shell is ALWAYS available. self.addEventListener('fetch', (event) => { const url = new URL(event.request.url); // Skip API calls - they should always go to network if (url.pathname.startsWith('/api/')) { return; } // Skip non-GET requests if (event.request.method !== 'GET') { return; } event.respondWith( fetch(event.request) .then((response) => { // If we got a valid response, cache it for next time if (response.ok && ASSETS.includes(url.pathname)) { const copy = response.clone(); caches.open(CACHE_NAME).then((cache) => cache.put(event.request, copy)); } return response; }) .catch(() => { // If network fails, try cache return caches.match(event.request).then((cached) => { if (cached) return cached; // If it's a navigation request and we're offline, show offline crisis page if (event.request.mode === 'navigate') { return new Response(CRISIS_OFFLINE_RESPONSE, { status: 200, headers: new Headers({ 'Content-Type': 'text/html' }) }); } // For other requests, return a simple offline message return new Response('Offline. Call 988 for immediate help.', { status: 503, statusText: 'Service Unavailable', headers: new Headers({ 'Content-Type': 'text/plain' }) }); }); }) ); });