Добавлены функции управления кэшем и обновления PWA

- Реализованы функции для принудительного обновления кэша и полной очистки кэша в классе PWAManager.
- Добавлены обработчики сообщений от сервисного работника для обновления кэша и очистки кэша.
- Обновлен сервисный работник для поддержки новых функций управления кэшем и уведомлений о статусе кэша.
- Добавлены глобальные функции для управления кэшем через интерфейс браузера.
This commit is contained in:
Fovway 2025-10-20 09:27:55 +07:00
parent 4949b78dee
commit fbc2b5259c
2 changed files with 277 additions and 4 deletions

View File

@ -11,6 +11,7 @@ class PWAManager {
this.setupInstallPrompt();
this.setupAppInstalled();
this.checkPWARequirements();
this.setupServiceWorkerMessages();
}
// Проверка требований PWA
@ -179,6 +180,171 @@ class PWAManager {
hasDeferredPrompt: this.deferredPrompt !== null
};
}
// Принудительное обновление кэша
async forceUpdateCache() {
console.log('Принудительное обновление кэша...');
if ('serviceWorker' in navigator && navigator.serviceWorker.controller) {
try {
// Отправляем сообщение Service Worker для обновления кэша
navigator.serviceWorker.controller.postMessage({
type: 'FORCE_UPDATE_CACHE'
});
console.log('Запрос на обновление кэша отправлен');
return true;
} catch (error) {
console.error('Ошибка при обновлении кэша:', error);
return false;
}
} else {
console.log('Service Worker не доступен');
return false;
}
}
// Полная очистка кэша
async clearAllCache() {
console.log('Полная очистка кэша...');
if ('serviceWorker' in navigator && navigator.serviceWorker.controller) {
try {
// Отправляем сообщение Service Worker для очистки кэша
navigator.serviceWorker.controller.postMessage({
type: 'CLEAR_ALL_CACHE'
});
console.log('Запрос на очистку кэша отправлен');
return true;
} catch (error) {
console.error('Ошибка при очистке кэша:', error);
return false;
}
} else {
console.log('Service Worker не доступен');
return false;
}
}
// Получение версии кэша
async getCacheVersion() {
return new Promise((resolve) => {
if ('serviceWorker' in navigator && navigator.serviceWorker.controller) {
const messageChannel = new MessageChannel();
messageChannel.port1.onmessage = (event) => {
resolve(event.data.version || 'Неизвестно');
};
navigator.serviceWorker.controller.postMessage(
{ type: 'GET_VERSION' },
[messageChannel.port2]
);
} else {
resolve('Service Worker не доступен');
}
});
}
// Проверка обновлений и принудительное обновление
async checkForUpdates() {
console.log('Проверка обновлений...');
if ('serviceWorker' in navigator) {
try {
const registration = await navigator.serviceWorker.getRegistration();
if (registration) {
await registration.update();
console.log('Проверка обновлений завершена');
return true;
}
} catch (error) {
console.error('Ошибка при проверке обновлений:', error);
return false;
}
}
return false;
}
// Настройка обработки сообщений от Service Worker
setupServiceWorkerMessages() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.addEventListener('message', (event) => {
console.log('Получено сообщение от SW:', event.data);
switch (event.data.type) {
case 'CACHE_UPDATED':
console.log('Кэш обновлен до версии:', event.data.version);
this.showNotification('Кэш успешно обновлен!', 'success');
break;
case 'CACHE_CLEARED':
console.log('Кэш полностью очищен');
this.showNotification('Кэш полностью очищен!', 'info');
break;
}
});
}
}
// Показ уведомления
showNotification(message, type = 'info') {
// Создаем уведомление
const notification = document.createElement('div');
notification.className = `pwa-notification pwa-notification-${type}`;
notification.textContent = message;
// Стили для уведомления
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
padding: 12px 20px;
border-radius: 8px;
color: white;
font-weight: bold;
z-index: 10000;
max-width: 300px;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
transform: translateX(100%);
transition: transform 0.3s ease;
`;
// Цвета для разных типов уведомлений
switch (type) {
case 'success':
notification.style.backgroundColor = '#28a745';
break;
case 'error':
notification.style.backgroundColor = '#dc3545';
break;
case 'warning':
notification.style.backgroundColor = '#ffc107';
notification.style.color = '#000';
break;
default:
notification.style.backgroundColor = '#007bff';
}
// Добавляем на страницу
document.body.appendChild(notification);
// Анимация появления
setTimeout(() => {
notification.style.transform = 'translateX(0)';
}, 100);
// Автоматическое удаление через 3 секунды
setTimeout(() => {
notification.style.transform = 'translateX(100%)';
setTimeout(() => {
if (notification.parentNode) {
notification.parentNode.removeChild(notification);
}
}, 300);
}, 3000);
}
}
// Инициализация PWA Manager
@ -187,7 +353,43 @@ const pwaManager = new PWAManager();
// Экспорт для использования в других скриптах
window.PWAManager = pwaManager;
// Добавляем глобальную функцию для отладки
// Добавляем глобальные функции для управления кэшем
window.debugPWA = () => {
console.log('PWA Debug Info:', pwaManager.getPWAInfo());
};
// Принудительное обновление кэша
window.updateCache = () => {
return pwaManager.forceUpdateCache();
};
// Полная очистка кэша
window.clearCache = () => {
return pwaManager.clearAllCache();
};
// Получение версии кэша
window.getCacheVersion = () => {
return pwaManager.getCacheVersion();
};
// Проверка обновлений
window.checkUpdates = () => {
return pwaManager.checkForUpdates();
};
// Комбинированная функция: проверка обновлений + принудительное обновление кэша
window.forceUpdate = async () => {
console.log('Принудительное обновление приложения...');
// Сначала проверяем обновления
await pwaManager.checkForUpdates();
// Затем принудительно обновляем кэш
await pwaManager.forceUpdateCache();
// Перезагружаем страницу
setTimeout(() => {
window.location.reload();
}, 1000);
};

View File

@ -1,6 +1,7 @@
// Service Worker для NoteJS
const CACHE_NAME = 'notejs-v1.0.1';
const STATIC_CACHE_NAME = 'notejs-static-v1.0.1';
const APP_VERSION = '1.0.2';
const CACHE_NAME = `notejs-v${APP_VERSION}`;
const STATIC_CACHE_NAME = `notejs-static-v${APP_VERSION}`;
// Файлы для кэширования при установке
const STATIC_FILES = [
@ -126,4 +127,74 @@ self.addEventListener('message', (event) => {
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);
}
}