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:
- Take five deep breaths
- Drink some water
- Step outside if you can
- Text or call someone you trust
"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' })
});
});
})
);
});