mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-25 01:37:05 +00:00
feat(notifications): replace polling with WebSocket push
Eliminates the 5-second setInterval polling loop for notifications in EditorLayout. A persistent /ws/notifications WebSocket connection is opened on mount; the backend pushes each alert the instant dispatchAlert fires, with 5s auto-reconnect on close. Key changes: - NotificationService: injectable broadcaster callback (setBroadcaster) - DatabaseService.addNotificationHistory: returns full NotificationHistory record (with id/is_read) instead of void - index.ts: notificationSubscribers Set + /ws/notifications upgrade handler (JWT-verified, placed before remote proxy path) - EditorLayout: polling removed, WS connect/reconnect replaces it
This commit is contained in:
@@ -310,9 +310,9 @@ export class DatabaseService {
|
||||
}));
|
||||
}
|
||||
|
||||
public addNotificationHistory(notification: Omit<NotificationHistory, 'id' | 'is_read'>): void {
|
||||
public addNotificationHistory(notification: Omit<NotificationHistory, 'id' | 'is_read'>): NotificationHistory {
|
||||
const stmt = this.db.prepare('INSERT INTO notification_history (level, message, timestamp, is_read) VALUES (?, ?, ?, 0)');
|
||||
stmt.run(notification.level, notification.message, notification.timestamp);
|
||||
const result = stmt.run(notification.level, notification.message, notification.timestamp);
|
||||
|
||||
this.db.exec(`
|
||||
DELETE FROM notification_history
|
||||
@@ -320,6 +320,14 @@ export class DatabaseService {
|
||||
SELECT id FROM notification_history ORDER BY timestamp DESC LIMIT 100
|
||||
)
|
||||
`);
|
||||
|
||||
return {
|
||||
id: result.lastInsertRowid as number,
|
||||
level: notification.level,
|
||||
message: notification.message,
|
||||
timestamp: notification.timestamp,
|
||||
is_read: false,
|
||||
};
|
||||
}
|
||||
|
||||
public markAllNotificationsRead(): void {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { DatabaseService } from './DatabaseService';
|
||||
import { DatabaseService, NotificationHistory } from './DatabaseService';
|
||||
|
||||
export class NotificationService {
|
||||
private static instance: NotificationService;
|
||||
private dbService: DatabaseService;
|
||||
private broadcaster: ((notification: NotificationHistory) => void) | null = null;
|
||||
|
||||
private constructor() {
|
||||
this.dbService = DatabaseService.getInstance();
|
||||
@@ -15,14 +16,24 @@ export class NotificationService {
|
||||
return NotificationService.instance;
|
||||
}
|
||||
|
||||
/** Wire up the WebSocket push function after the WS server is initialised. */
|
||||
public setBroadcaster(fn: (notification: NotificationHistory) => void): void {
|
||||
this.broadcaster = fn;
|
||||
}
|
||||
|
||||
public async dispatchAlert(level: 'info' | 'warning' | 'error', message: string) {
|
||||
// 1. Log to history
|
||||
this.dbService.addNotificationHistory({
|
||||
// 1. Log to history and get the full inserted record (with id)
|
||||
const notification = this.dbService.addNotificationHistory({
|
||||
level,
|
||||
message,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
|
||||
// 2. Push to connected browser clients via WebSocket
|
||||
if (this.broadcaster) {
|
||||
this.broadcaster(notification);
|
||||
}
|
||||
|
||||
// 2. Fetch enabled agents
|
||||
const agents = this.dbService.getEnabledAgents();
|
||||
if (agents.length === 0) {
|
||||
|
||||
Reference in New Issue
Block a user