codigo0/public/sw.js
planetazuzu a42c467cd8 feat: Implementación completa de herramientas y actualización de protocolos
-  Herramientas nuevas:
  * Temporizador de RCP con alertas cada 2 minutos
  * Calculadora de Duración de Botella de Oxígeno
  * Calculadora de Goteo (gotas/min y ml/h)
  * Tabla de perfusión Adrenalina agregada

-  Actualización Protocolo RCP:
  * Orden actualizado: Comprobar consciencia → Llamar 112 → Iniciar RCP
  * Aplicado a RCP Adulto SVB y Pediátrico

-  Cambios UI:
  * Botones de emergencias críticas con fondo negro y texto blanco
  * Enlaces de códigos corregidos

-  Medicación TES:
  * Nueva sección separada para medicación autorizada bajo prescripción
  * Aviso legal prominente
  * Sin dosis ni decisiones clínicas

-  Correcciones:
  * Errores de sintaxis JSX corregidos (símbolos < y >)
  * Favicon SVG actualizado
  * GitHub Pages configurado correctamente
2025-12-17 15:19:57 +01:00

148 lines
3.7 KiB
JavaScript

// Service Worker para PWA
// Cache First Strategy para funcionamiento offline
const CACHE_NAME = 'emerges-tes-v1';
const RUNTIME_CACHE = 'emerges-tes-runtime-v1';
// Archivos estáticos a cachear en la instalación
const STATIC_ASSETS = [
'/',
'/index.html',
'/manifest.json',
'/favicon.ico',
];
// Instalación del Service Worker
self.addEventListener('install', (event) => {
console.log('[SW] Installing service worker...');
event.waitUntil(
caches.open(CACHE_NAME)
.then((cache) => {
console.log('[SW] Caching static assets');
return cache.addAll(STATIC_ASSETS);
})
.then(() => self.skipWaiting()) // Activar inmediatamente
);
});
// Activación del Service Worker
self.addEventListener('activate', (event) => {
console.log('[SW] Activating service worker...');
event.waitUntil(
caches.keys().then((cacheNames) => {
return Promise.all(
cacheNames
.filter((cacheName) => {
// Eliminar caches antiguos
return cacheName !== CACHE_NAME && cacheName !== RUNTIME_CACHE;
})
.map((cacheName) => {
console.log('[SW] Deleting old cache:', cacheName);
return caches.delete(cacheName);
})
);
})
.then(() => self.clients.claim()) // Tomar control de todas las páginas
);
});
// Interceptar peticiones
self.addEventListener('fetch', (event) => {
const { request } = event;
const url = new URL(request.url);
// Ignorar peticiones no GET
if (request.method !== 'GET') {
return;
}
// Ignorar peticiones a APIs externas (si las hay)
if (url.origin !== location.origin) {
return;
}
// Estrategia: Cache First para assets estáticos
if (
request.destination === 'script' ||
request.destination === 'style' ||
request.destination === 'image' ||
request.destination === 'font' ||
url.pathname.endsWith('.md')
) {
event.respondWith(cacheFirst(request));
} else {
// Network First para HTML y otros
event.respondWith(networkFirst(request));
}
});
// Cache First Strategy
async function cacheFirst(request) {
const cache = await caches.open(CACHE_NAME);
const cached = await cache.match(request);
if (cached) {
return cached;
}
try {
const response = await fetch(request);
if (response.ok) {
cache.put(request, response.clone());
}
return response;
} catch (error) {
console.error('[SW] Fetch failed:', error);
// Si es una imagen, retornar una imagen placeholder
if (request.destination === 'image') {
return new Response('', { status: 404 });
}
throw error;
}
}
// Network First Strategy
async function networkFirst(request) {
const cache = await caches.open(RUNTIME_CACHE);
try {
const response = await fetch(request);
if (response.ok) {
cache.put(request, response.clone());
}
return response;
} catch (error) {
console.log('[SW] Network failed, trying cache:', error);
const cached = await cache.match(request);
if (cached) {
return cached;
}
// Si no hay cache y estamos offline, retornar index.html para SPA
if (request.mode === 'navigate') {
const indexCache = await caches.open(CACHE_NAME);
const indexHtml = await indexCache.match('/index.html');
if (indexHtml) {
return indexHtml;
}
}
throw error;
}
}
// Manejar mensajes del cliente
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting();
}
if (event.data && event.data.type === 'CACHE_URLS') {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
return cache.addAll(event.data.urls);
})
);
}
});