267 lines
7.9 KiB
JavaScript
267 lines
7.9 KiB
JavaScript
const CACHE_NAME = 'basspago-v1.0.0';
|
|
const urlsToCache = [
|
|
// Páginas principais
|
|
'/',
|
|
'/pix',
|
|
'/pdv',
|
|
'/conta-digital',
|
|
'/desenvolvedores',
|
|
'/precos',
|
|
|
|
// Favicons
|
|
'/favicon-16x16.png',
|
|
'/apple-touch-icon.png',
|
|
|
|
// Imagens críticas do hero/homepage
|
|
'/src/lib/assets/backgroundSection2.png',
|
|
'/src/lib/assets/phone-card.png',
|
|
'/src/lib/assets/backgroundPDV.png',
|
|
'/src/lib/assets/phone-qrcode.png',
|
|
|
|
// Logos de parceiros (críticos para hero)
|
|
'/src/lib/assets/marca-cambionet.png',
|
|
'/src/lib/assets/marca-cazco.png',
|
|
'/src/lib/assets/marca-cdl.png',
|
|
'/src/lib/assets/marca-fecomercio-rs.png',
|
|
'/src/lib/assets/marca-gramado-sumit.png',
|
|
'/src/lib/assets/marca-hubsafe.png',
|
|
'/src/lib/assets/marca-ic-globall.png',
|
|
'/src/lib/assets/marca-ic-sindi.png',
|
|
'/src/lib/assets/marca-jusfy.png',
|
|
'/src/lib/assets/marca-sesc.png',
|
|
|
|
// Outras imagens importantes
|
|
'/src/lib/assets/cubes-plus.svg',
|
|
'/src/lib/assets/iphone-pix-mockup.png',
|
|
'/src/lib/assets/iphone-pix-mockup2.png',
|
|
'/src/lib/assets/banking-interface-mockup2.png',
|
|
'/src/lib/assets/qrcode-azul.png',
|
|
'/src/lib/assets/copy-link-pagamento.png',
|
|
|
|
// Ícones e SVGs críticos
|
|
'/src/lib/assets/pix-e-ted-azul.svg',
|
|
'/src/lib/assets/pagamentos-azul.svg',
|
|
'/src/lib/assets/cobranca.svg',
|
|
'/src/lib/assets/saldos-e-extratos.svg',
|
|
'/src/lib/assets/fluxo-de-aprovacao.svg',
|
|
'/src/lib/assets/conta-escrow-azul.svg',
|
|
'/src/lib/assets/cobranca-em-lote.svg',
|
|
'/src/lib/assets/gestao-de-usuarios.svg',
|
|
'/src/lib/assets/check.svg',
|
|
'/src/lib/assets/lock-icon.svg',
|
|
|
|
// App store badges
|
|
'/src/lib/assets/apple-store.svg',
|
|
'/src/lib/assets/google-play.svg',
|
|
|
|
// Logos da empresa
|
|
'/src/lib/assets/logo-basspago-preta.svg',
|
|
'/src/lib/assets/icon-slim-basspago.svg'
|
|
];
|
|
|
|
// Recursos para cache dinâmico (não críticos)
|
|
const dynamicCacheResources = [
|
|
'/src/lib/assets/case-1.webp',
|
|
'/src/lib/assets/case-2.webp',
|
|
'/src/lib/assets/case-3.webp',
|
|
'/src/lib/assets/case-4.webp',
|
|
'/src/lib/assets/case-5.webp',
|
|
'/src/lib/assets/case-6.webp',
|
|
'/src/lib/assets/payment-schedule-mockup.svg'
|
|
];
|
|
|
|
// Install event - Cache recursos críticos
|
|
self.addEventListener('install', (event) => {
|
|
console.log('[SW] Installing...');
|
|
|
|
event.waitUntil(
|
|
caches.open(CACHE_NAME)
|
|
.then((cache) => {
|
|
console.log('[SW] Cache opened, adding critical resources...');
|
|
|
|
// Cache recursos críticos em lotes para evitar timeout
|
|
const batchSize = 10;
|
|
const batches = [];
|
|
|
|
for (let i = 0; i < urlsToCache.length; i += batchSize) {
|
|
batches.push(urlsToCache.slice(i, i + batchSize));
|
|
}
|
|
|
|
return batches.reduce((promise, batch) => {
|
|
return promise.then(() => {
|
|
console.log('[SW] Caching batch:', batch);
|
|
return cache.addAll(batch).catch((error) => {
|
|
console.warn('[SW] Failed to cache batch:', batch, error);
|
|
// Tenta cachear individualmente em caso de erro
|
|
return Promise.allSettled(
|
|
batch.map(url => cache.add(url).catch(e => console.warn('[SW] Failed to cache:', url, e)))
|
|
);
|
|
});
|
|
});
|
|
}, Promise.resolve());
|
|
})
|
|
.then(() => {
|
|
console.log('[SW] Critical resources cached successfully');
|
|
})
|
|
.catch((error) => {
|
|
console.error('[SW] Failed to cache critical resources:', error);
|
|
})
|
|
);
|
|
|
|
// Força a ativação imediata
|
|
self.skipWaiting();
|
|
});
|
|
|
|
// Activate event - Limpa caches antigos
|
|
self.addEventListener('activate', (event) => {
|
|
console.log('[SW] Activating...');
|
|
|
|
event.waitUntil(
|
|
caches.keys().then((cacheNames) => {
|
|
return Promise.all(
|
|
cacheNames.map((cacheName) => {
|
|
if (cacheName !== CACHE_NAME) {
|
|
console.log('[SW] Deleting old cache:', cacheName);
|
|
return caches.delete(cacheName);
|
|
}
|
|
})
|
|
);
|
|
}).then(() => {
|
|
console.log('[SW] Old caches cleaned');
|
|
// Toma controle de todas as abas abertas
|
|
return self.clients.claim();
|
|
})
|
|
);
|
|
});
|
|
|
|
// Fetch event - Estratégia de cache
|
|
self.addEventListener('fetch', (event) => {
|
|
const { request } = event;
|
|
const url = new URL(request.url);
|
|
|
|
// Ignora requests que não são GET
|
|
if (request.method !== 'GET') {
|
|
return;
|
|
}
|
|
|
|
// Ignora requests para outros domínios (exceto fonts)
|
|
if (url.origin !== location.origin && !url.hostname.includes('fonts')) {
|
|
return;
|
|
}
|
|
|
|
event.respondWith(
|
|
caches.match(request)
|
|
.then((cachedResponse) => {
|
|
// Se está no cache, retorna imediatamente
|
|
if (cachedResponse) {
|
|
console.log('[SW] Serving from cache:', request.url);
|
|
|
|
// Para recursos críticos, também faz fetch em background para atualizar
|
|
if (urlsToCache.includes(url.pathname)) {
|
|
fetch(request).then((response) => {
|
|
if (response.ok) {
|
|
caches.open(CACHE_NAME).then((cache) => {
|
|
cache.put(request, response.clone());
|
|
});
|
|
}
|
|
}).catch(() => {
|
|
// Ignora erros de network em background updates
|
|
});
|
|
}
|
|
|
|
return cachedResponse;
|
|
}
|
|
|
|
// Se não está no cache, faz fetch
|
|
console.log('[SW] Fetching from network:', request.url);
|
|
return fetch(request)
|
|
.then((response) => {
|
|
// Só cacheia responses válidos
|
|
if (!response || response.status !== 200 || response.type !== 'basic') {
|
|
return response;
|
|
}
|
|
|
|
// Cacheia recursos dinâmicos se estão na lista
|
|
if (dynamicCacheResources.includes(url.pathname) ||
|
|
url.pathname.includes('/src/lib/assets/')) {
|
|
|
|
const responseToCache = response.clone();
|
|
caches.open(CACHE_NAME)
|
|
.then((cache) => {
|
|
console.log('[SW] Caching dynamic resource:', request.url);
|
|
cache.put(request, responseToCache);
|
|
});
|
|
}
|
|
|
|
return response;
|
|
})
|
|
.catch((error) => {
|
|
console.error('[SW] Fetch failed:', request.url, error);
|
|
|
|
// Fallback para páginas HTML
|
|
if (request.headers.get('accept').includes('text/html')) {
|
|
return caches.match('/');
|
|
}
|
|
|
|
throw error;
|
|
});
|
|
})
|
|
);
|
|
});
|
|
|
|
// Background Sync para cache de recursos não críticos
|
|
self.addEventListener('sync', (event) => {
|
|
if (event.tag === 'background-cache') {
|
|
event.waitUntil(
|
|
caches.open(CACHE_NAME)
|
|
.then((cache) => {
|
|
console.log('[SW] Background caching dynamic resources...');
|
|
return Promise.allSettled(
|
|
dynamicCacheResources.map(url =>
|
|
cache.add(url).catch(e => console.warn('[SW] Background cache failed:', url, e))
|
|
)
|
|
);
|
|
})
|
|
);
|
|
}
|
|
});
|
|
|
|
// Message event para comunicação com a app
|
|
self.addEventListener('message', (event) => {
|
|
if (event.data && event.data.type === 'SKIP_WAITING') {
|
|
self.skipWaiting();
|
|
}
|
|
|
|
if (event.data && event.data.type === 'GET_CACHE_STATUS') {
|
|
caches.open(CACHE_NAME).then((cache) => {
|
|
return cache.keys();
|
|
}).then((keys) => {
|
|
event.ports[0].postMessage({
|
|
type: 'CACHE_STATUS',
|
|
cached: keys.length,
|
|
total: urlsToCache.length
|
|
});
|
|
});
|
|
}
|
|
});
|
|
|
|
// Periodic background sync (se suportado)
|
|
self.addEventListener('periodicsync', (event) => {
|
|
if (event.tag === 'cache-update') {
|
|
event.waitUntil(
|
|
caches.open(CACHE_NAME)
|
|
.then((cache) => {
|
|
console.log('[SW] Periodic cache update...');
|
|
return Promise.allSettled(
|
|
urlsToCache.map(url =>
|
|
fetch(url).then(response => {
|
|
if (response.ok) {
|
|
return cache.put(url, response);
|
|
}
|
|
}).catch(e => console.warn('[SW] Periodic update failed:', url, e))
|
|
)
|
|
);
|
|
})
|
|
);
|
|
}
|
|
}); |