NoteJS/public/sw.js
Fovway 02be77d790 Обновлены файлы PWA и улучшена функциональность
- Добавлены новые мета-теги и улучшены существующие для поддержки PWA.
- Обновлен manifest.json с новыми полями для совместимости с Brave.
- Улучшен Service Worker для кэширования манифеста и обработки ошибок.
- Обновлены инструкции по тестированию PWA, включая новую тестовую страницу для Brave.
- Оптимизирован код для обработки установки PWA на мобильных устройствах и в Brave.
2025-10-20 12:35:29 +07:00

237 lines
7.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Service Worker для NoteJS
const APP_VERSION = "1.0.6";
const CACHE_NAME = `notejs-v${APP_VERSION}`;
const STATIC_CACHE_NAME = `notejs-static-v${APP_VERSION}`;
// Файлы для кэширования при установке (включая манифест для Brave)
const STATIC_FILES = [
"/manifest.json",
"/icons/icon-72x72.png",
"/icons/icon-96x96.png",
"/icons/icon-128x128.png",
"/icons/icon-144x144.png",
"/icons/icon-152x152.png",
"/icons/icon-192x192.png",
"/icons/icon-384x384.png",
"/icons/icon-512x512.png",
"/icons/icon-32x32.png",
"/icons/icon-16x16.png",
"/icons/icon-48x48.png",
"/icon.svg",
"/logo.svg",
];
// Установка Service Worker
self.addEventListener("install", (event) => {
console.log("[SW] Установка Service Worker");
event.waitUntil(
caches
.open(STATIC_CACHE_NAME)
.then((cache) => {
console.log("[SW] Кэширование статических файлов");
return cache.addAll(STATIC_FILES);
})
.then(() => {
console.log("[SW] Статические файлы закэшированы");
return self.skipWaiting();
})
.catch((error) => {
console.error("[SW] Ошибка при кэшировании статических файлов:", error);
// Продолжаем работу даже если кэширование не удалось
return self.skipWaiting();
})
);
});
// Активация Service Worker
self.addEventListener("activate", (event) => {
console.log("[SW] Активация Service Worker");
event.waitUntil(
caches
.keys()
.then((cacheNames) => {
return Promise.all(
cacheNames.map((cacheName) => {
// Удаляем старые кэши
if (cacheName !== STATIC_CACHE_NAME) {
console.log("[SW] Удаление старого кэша:", cacheName);
return caches.delete(cacheName);
}
})
);
})
.then(() => {
console.log("[SW] Service Worker активирован");
return self.clients.claim();
})
);
});
// Перехват запросов
self.addEventListener("fetch", (event) => {
const { request } = event;
const url = new URL(request.url);
// Пропускаем запросы к API и загрузкам
if (
url.pathname.startsWith("/api/") ||
url.pathname.startsWith("/uploads/") ||
url.pathname.startsWith("/database/")
) {
return;
}
// Пропускаем запросы к внешним ресурсам
if (url.origin !== location.origin) {
return;
}
// Пропускаем HTML файлы и CSS - не кэшируем их
if (
url.pathname.endsWith(".html") ||
url.pathname.endsWith(".css") ||
url.pathname === "/" ||
url.pathname === "/index.html" ||
url.pathname === "/login.html" ||
url.pathname === "/register.html" ||
url.pathname === "/notes.html" ||
url.pathname === "/profile.html"
) {
return;
}
// Обрабатываем только GET запросы для изображений, иконок и манифеста
if (request.method === "GET") {
event.respondWith(handleRequest(request));
}
});
async function handleRequest(request) {
try {
// Сначала пытаемся получить из кэша
const cachedResponse = await caches.match(request);
if (cachedResponse) {
console.log("[SW] Запрос из кэша:", request.url);
return cachedResponse;
}
// Если нет в кэше, загружаем из сети
console.log("[SW] Запрос к сети:", request.url);
const networkResponse = await fetch(request);
// Кэшируем только изображения и иконки (без манифеста)
if (networkResponse.ok && shouldCache(request)) {
const cache = await caches.open(STATIC_CACHE_NAME);
cache.put(request, networkResponse.clone());
}
return networkResponse;
} catch (error) {
console.error("[SW] Ошибка при обработке запроса:", error);
// НЕ предоставляем fallback - приложение работает только онлайн
throw error;
}
}
// Функция для определения, нужно ли кэшировать файл
function shouldCache(request) {
const url = new URL(request.url);
// Кэшируем изображения, иконки, логотипы и манифест (для Brave совместимости)
return (
url.pathname.includes("/icons/") ||
url.pathname.endsWith(".png") ||
url.pathname.endsWith(".jpg") ||
url.pathname.endsWith(".jpeg") ||
url.pathname.endsWith(".gif") ||
url.pathname.endsWith(".webp") ||
url.pathname.endsWith(".svg") ||
url.pathname.endsWith("manifest.json")
);
}
// Обработка сообщений от основного потока
self.addEventListener("message", (event) => {
console.log("[SW] Получено сообщение:", event.data);
if (event.data && event.data.type === "SKIP_WAITING") {
self.skipWaiting();
}
if (event.data && event.data.type === "GET_VERSION") {
event.ports[0].postMessage({ version: CACHE_NAME });
}
if (event.data && event.data.type === "FORCE_UPDATE_CACHE") {
forceUpdateCache();
}
if (event.data && event.data.type === "CLEAR_ALL_CACHE") {
clearAllCache();
}
});
// Функция принудительного обновления кэша
async function forceUpdateCache() {
console.log("[SW] Принудительное обновление кэша...");
try {
// Удаляем все старые кэши
const cacheNames = await caches.keys();
await Promise.all(
cacheNames.map((cacheName) => {
console.log("[SW] Удаление кэша:", cacheName);
return caches.delete(cacheName);
})
);
// Создаем новый кэш с актуальной версией
const newCache = await caches.open(STATIC_CACHE_NAME);
await newCache.addAll(STATIC_FILES);
console.log("[SW] Кэш успешно обновлен до версии:", APP_VERSION);
// Уведомляем клиентов об обновлении
const clients = await self.clients.matchAll();
clients.forEach((client) => {
client.postMessage({
type: "CACHE_UPDATED",
version: APP_VERSION,
});
});
} catch (error) {
console.error("[SW] Ошибка при обновлении кэша:", error);
}
}
// Функция полной очистки кэша
async function clearAllCache() {
console.log("[SW] Полная очистка кэша...");
try {
const cacheNames = await caches.keys();
await Promise.all(
cacheNames.map((cacheName) => {
console.log("[SW] Удаление кэша:", cacheName);
return caches.delete(cacheName);
})
);
console.log("[SW] Весь кэш очищен");
// Уведомляем клиентов об очистке
const clients = await self.clients.matchAll();
clients.forEach((client) => {
client.postMessage({
type: "CACHE_CLEARED",
});
});
} catch (error) {
console.error("[SW] Ошибка при очистке кэша:", error);
}
}