feat(serviceworker): Add service worker status updates, EventBus and UI status pill for realtime observability
This commit is contained in:
@@ -2,6 +2,7 @@ import * as plugins from './plugins.js';
|
||||
import * as interfaces from '../dist_ts_interfaces/index.js';
|
||||
import { logger } from './logging.js';
|
||||
import { getMetricsCollector } from './classes.metrics.js';
|
||||
import { getEventBus, ServiceWorkerEvent } from './classes.eventbus.js';
|
||||
|
||||
// Add type definitions for ServiceWorker APIs
|
||||
declare global {
|
||||
@@ -75,8 +76,128 @@ export class ServiceworkerBackend {
|
||||
return await optionsArg.purgeCache?.(reqArg);
|
||||
});
|
||||
|
||||
// Handler for getting current SW status
|
||||
this.deesComms.createTypedHandler<interfaces.serviceworker.IRequest_Serviceworker_GetStatus>('serviceworker_getStatus', async () => {
|
||||
const metrics = getMetricsCollector();
|
||||
const metricsData = metrics.getMetrics();
|
||||
return {
|
||||
isActive: true,
|
||||
isOnline: metricsData.speedtest.isOnline,
|
||||
cacheHitRate: metrics.getCacheHitRate(),
|
||||
resourceCount: metrics.getResourceCount(),
|
||||
connectedClients: metricsData.connection.connectedClients,
|
||||
lastUpdateCheck: metricsData.update.lastCheckTimestamp,
|
||||
};
|
||||
});
|
||||
|
||||
// Periodically update connected clients count
|
||||
this.startClientCountUpdates();
|
||||
|
||||
// Subscribe to EventBus and broadcast status updates
|
||||
this.setupEventBusSubscriptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up subscriptions to EventBus events and broadcasts them to clients
|
||||
*/
|
||||
private setupEventBusSubscriptions(): void {
|
||||
const eventBus = getEventBus();
|
||||
|
||||
// Network status changes
|
||||
eventBus.on(ServiceWorkerEvent.NETWORK_ONLINE, () => {
|
||||
this.broadcastStatusUpdate({
|
||||
source: 'network',
|
||||
type: 'online',
|
||||
message: 'Connection restored',
|
||||
persist: false,
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
});
|
||||
|
||||
eventBus.on(ServiceWorkerEvent.NETWORK_OFFLINE, () => {
|
||||
this.broadcastStatusUpdate({
|
||||
source: 'network',
|
||||
type: 'offline',
|
||||
message: 'Connection lost - offline mode',
|
||||
persist: true,
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
});
|
||||
|
||||
// Update events
|
||||
eventBus.on(ServiceWorkerEvent.UPDATE_AVAILABLE, (_event, payload: any) => {
|
||||
this.broadcastStatusUpdate({
|
||||
source: 'serviceworker',
|
||||
type: 'update',
|
||||
message: 'Update available',
|
||||
details: {
|
||||
version: payload.newVersion,
|
||||
},
|
||||
persist: false,
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
});
|
||||
|
||||
eventBus.on(ServiceWorkerEvent.UPDATE_APPLIED, (_event, payload: any) => {
|
||||
this.broadcastStatusUpdate({
|
||||
source: 'serviceworker',
|
||||
type: 'update',
|
||||
message: 'Update applied',
|
||||
details: {
|
||||
version: payload.newVersion,
|
||||
},
|
||||
persist: false,
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
});
|
||||
|
||||
eventBus.on(ServiceWorkerEvent.UPDATE_ERROR, (_event, payload: any) => {
|
||||
this.broadcastStatusUpdate({
|
||||
source: 'serviceworker',
|
||||
type: 'error',
|
||||
message: `Update error: ${payload.error || 'Unknown error'}`,
|
||||
persist: true,
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
});
|
||||
|
||||
// Cache invalidation
|
||||
eventBus.on(ServiceWorkerEvent.CACHE_INVALIDATE_ALL, () => {
|
||||
this.broadcastStatusUpdate({
|
||||
source: 'serviceworker',
|
||||
type: 'cache',
|
||||
message: 'Clearing cache...',
|
||||
persist: false,
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
});
|
||||
|
||||
// Lifecycle events
|
||||
eventBus.on(ServiceWorkerEvent.ACTIVATE, () => {
|
||||
this.broadcastStatusUpdate({
|
||||
source: 'serviceworker',
|
||||
type: 'connected',
|
||||
message: 'Service worker activated',
|
||||
persist: false,
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts a status update to all connected clients
|
||||
*/
|
||||
public async broadcastStatusUpdate(status: interfaces.serviceworker.IStatusUpdate): Promise<void> {
|
||||
try {
|
||||
await this.deesComms.postMessage({
|
||||
method: 'serviceworker_statusUpdate',
|
||||
request: status,
|
||||
messageId: `sw_status_${Date.now()}`
|
||||
});
|
||||
logger.log('info', `Status update broadcast: ${status.source}:${status.type} - ${status.message}`);
|
||||
} catch (error) {
|
||||
logger.log('warn', `Failed to broadcast status update: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user