mirror of
https://github.com/A6-9V/MQL5-Google-Onedrive.git
synced 2026-04-10 20:40:56 +00:00
194 lines
5.3 KiB
JavaScript
194 lines
5.3 KiB
JavaScript
|
|
// MQL5 Trading Automation Service Worker
|
||
|
|
// Version: 1.0.0
|
||
|
|
|
||
|
|
const CACHE_NAME = 'mql5-automation-v1';
|
||
|
|
const RUNTIME_CACHE = 'mql5-runtime-v1';
|
||
|
|
|
||
|
|
// Assets to cache on install
|
||
|
|
const PRECACHE_ASSETS = [
|
||
|
|
'/',
|
||
|
|
'/index.html',
|
||
|
|
'/dashboard/index.html',
|
||
|
|
'/manifest.json',
|
||
|
|
'/sw-inspector.html',
|
||
|
|
'/offline.html'
|
||
|
|
];
|
||
|
|
|
||
|
|
// Install event - cache essential assets
|
||
|
|
self.addEventListener('install', (event) => {
|
||
|
|
console.log('[Service Worker] Installing...');
|
||
|
|
|
||
|
|
event.waitUntil(
|
||
|
|
caches.open(CACHE_NAME)
|
||
|
|
.then((cache) => {
|
||
|
|
console.log('[Service Worker] Precaching assets');
|
||
|
|
return cache.addAll(PRECACHE_ASSETS);
|
||
|
|
})
|
||
|
|
.then(() => {
|
||
|
|
console.log('[Service Worker] Installation complete');
|
||
|
|
return self.skipWaiting();
|
||
|
|
})
|
||
|
|
.catch((error) => {
|
||
|
|
console.error('[Service Worker] Installation failed:', error);
|
||
|
|
})
|
||
|
|
);
|
||
|
|
});
|
||
|
|
|
||
|
|
// Activate event - clean up old caches
|
||
|
|
self.addEventListener('activate', (event) => {
|
||
|
|
console.log('[Service Worker] Activating...');
|
||
|
|
|
||
|
|
event.waitUntil(
|
||
|
|
caches.keys()
|
||
|
|
.then((cacheNames) => {
|
||
|
|
return Promise.all(
|
||
|
|
cacheNames
|
||
|
|
.filter((cacheName) => {
|
||
|
|
return cacheName !== CACHE_NAME && cacheName !== RUNTIME_CACHE;
|
||
|
|
})
|
||
|
|
.map((cacheName) => {
|
||
|
|
console.log('[Service Worker] Deleting old cache:', cacheName);
|
||
|
|
return caches.delete(cacheName);
|
||
|
|
})
|
||
|
|
);
|
||
|
|
})
|
||
|
|
.then(() => {
|
||
|
|
console.log('[Service Worker] Activation complete');
|
||
|
|
return self.clients.claim();
|
||
|
|
})
|
||
|
|
);
|
||
|
|
});
|
||
|
|
|
||
|
|
// Fetch event - serve from cache, fallback to network
|
||
|
|
self.addEventListener('fetch', (event) => {
|
||
|
|
// Skip cross-origin requests
|
||
|
|
if (!event.request.url.startsWith(self.location.origin)) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Network-first strategy for API requests
|
||
|
|
if (event.request.url.includes('/api/')) {
|
||
|
|
event.respondWith(
|
||
|
|
fetch(event.request)
|
||
|
|
.then((response) => {
|
||
|
|
// Clone the response before caching
|
||
|
|
const responseClone = response.clone();
|
||
|
|
caches.open(RUNTIME_CACHE).then((cache) => {
|
||
|
|
cache.put(event.request, responseClone);
|
||
|
|
});
|
||
|
|
return response;
|
||
|
|
})
|
||
|
|
.catch(() => {
|
||
|
|
return caches.match(event.request);
|
||
|
|
})
|
||
|
|
);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Cache-first strategy for static assets
|
||
|
|
event.respondWith(
|
||
|
|
caches.match(event.request)
|
||
|
|
.then((cachedResponse) => {
|
||
|
|
if (cachedResponse) {
|
||
|
|
// Return cached version and update cache in background
|
||
|
|
fetch(event.request)
|
||
|
|
.then((response) => {
|
||
|
|
caches.open(RUNTIME_CACHE).then((cache) => {
|
||
|
|
cache.put(event.request, response);
|
||
|
|
});
|
||
|
|
})
|
||
|
|
.catch(() => {
|
||
|
|
// Network request failed, but we have cache
|
||
|
|
});
|
||
|
|
return cachedResponse;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Not in cache, fetch from network
|
||
|
|
return fetch(event.request)
|
||
|
|
.then((response) => {
|
||
|
|
// Cache successful responses
|
||
|
|
if (response.status === 200) {
|
||
|
|
const responseClone = response.clone();
|
||
|
|
caches.open(RUNTIME_CACHE).then((cache) => {
|
||
|
|
cache.put(event.request, responseClone);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
return response;
|
||
|
|
})
|
||
|
|
.catch((error) => {
|
||
|
|
console.error('[Service Worker] Fetch failed:', error);
|
||
|
|
// Return offline page if available
|
||
|
|
return caches.match('/offline.html') || new Response('Offline');
|
||
|
|
});
|
||
|
|
})
|
||
|
|
);
|
||
|
|
});
|
||
|
|
|
||
|
|
// Message event - handle commands from clients
|
||
|
|
self.addEventListener('message', (event) => {
|
||
|
|
console.log('[Service Worker] Message received:', event.data);
|
||
|
|
|
||
|
|
if (event.data.type === 'SKIP_WAITING') {
|
||
|
|
self.skipWaiting();
|
||
|
|
}
|
||
|
|
|
||
|
|
if (event.data.type === 'CACHE_STATS') {
|
||
|
|
caches.keys().then((cacheNames) => {
|
||
|
|
Promise.all(
|
||
|
|
cacheNames.map((cacheName) => {
|
||
|
|
return caches.open(cacheName).then((cache) => {
|
||
|
|
return cache.keys().then((keys) => {
|
||
|
|
return { name: cacheName, size: keys.length };
|
||
|
|
});
|
||
|
|
});
|
||
|
|
})
|
||
|
|
).then((stats) => {
|
||
|
|
event.ports[0].postMessage({
|
||
|
|
type: 'CACHE_STATS_RESPONSE',
|
||
|
|
data: stats
|
||
|
|
});
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
if (event.data.type === 'CLEAR_CACHE') {
|
||
|
|
caches.keys().then((cacheNames) => {
|
||
|
|
Promise.all(
|
||
|
|
cacheNames.map((cacheName) => caches.delete(cacheName))
|
||
|
|
).then(() => {
|
||
|
|
event.ports[0].postMessage({
|
||
|
|
type: 'CACHE_CLEARED',
|
||
|
|
success: true
|
||
|
|
});
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
// Push notification event
|
||
|
|
self.addEventListener('push', (event) => {
|
||
|
|
console.log('[Service Worker] Push received');
|
||
|
|
|
||
|
|
const options = {
|
||
|
|
body: event.data ? event.data.text() : 'New trading notification',
|
||
|
|
icon: '/icons/icon-192x192.png',
|
||
|
|
badge: '/icons/icon-72x72.png',
|
||
|
|
vibrate: [200, 100, 200],
|
||
|
|
tag: 'trading-notification',
|
||
|
|
requireInteraction: false
|
||
|
|
};
|
||
|
|
|
||
|
|
event.waitUntil(
|
||
|
|
self.registration.showNotification('MQL5 Trading Automation', options)
|
||
|
|
);
|
||
|
|
});
|
||
|
|
|
||
|
|
// Notification click event
|
||
|
|
self.addEventListener('notificationclick', (event) => {
|
||
|
|
console.log('[Service Worker] Notification clicked');
|
||
|
|
event.notification.close();
|
||
|
|
|
||
|
|
event.waitUntil(
|
||
|
|
clients.openWindow('/')
|
||
|
|
);
|
||
|
|
});
|