feat(web): share realtime hub across domain events

This commit is contained in:
jjbrunton committed 2026-08-08 15:46:25 +01:00
1 parent 66a1146562
commit a51e0b6b31
2 files changed
+26 -1

No files matched your search

+7 -1
View File
@@ -1,6 +1,10 @@
import type { Request, RequestHandler, Response } from 'express'; import type { Request, RequestHandler, Response } from 'express';
import type { LogEntry } from './types.js'; import type { LogEntry } from './types.js';
import { RealtimeEventHub } from './events/index.js'; import {
createDashboardEventAdapters,
createDashboardEventPublisher,
RealtimeEventHub,
} from './events/index.js';
import { createExpressSseHandler } from './events/express-sse-adapter.js'; import { createExpressSseHandler } from './events/express-sse-adapter.js';
const MAX_LOGS = 500; const MAX_LOGS = 500;
@@ -15,10 +19,12 @@ export class LogBroadcaster {
private clients = new Set<Response>(); private clients = new Set<Response>();
private readonly eventHub: RealtimeEventHub; private readonly eventHub: RealtimeEventHub;
readonly events: RequestHandler; readonly events: RequestHandler;
readonly dashboardEvents: ReturnType<typeof createDashboardEventAdapters>;
constructor(eventHub?: RealtimeEventHub) { constructor(eventHub?: RealtimeEventHub) {
this.eventHub = eventHub ?? new RealtimeEventHub({ capacity: MAX_LOGS }); this.eventHub = eventHub ?? new RealtimeEventHub({ capacity: MAX_LOGS });
this.events = createExpressSseHandler({ hub: this.eventHub }); this.events = createExpressSseHandler({ hub: this.eventHub });
this.dashboardEvents = createDashboardEventAdapters(createDashboardEventPublisher(this.eventHub));
} }
push(level: LogEntry['level'], message: string, data?: unknown): void { push(level: LogEntry['level'], message: string, data?: unknown): void {
+19
View File
@@ -0,0 +1,19 @@
import { describe, expect, it } from 'vitest';
import { LogBroadcaster } from '../../src/web/log-broadcaster.js';
import { RealtimeEventHub } from '../../src/web/events/index.js';
describe('dashboard event wiring', () => {
it('publishes domain and log events through the same ordered hub', () => {
const hub = new RealtimeEventHub({ capacity: 20 });
const broadcaster = new LogBroadcaster(hub);
const received: string[] = [];
const subscription = hub.subscribe((event) => received.push(event.type));
broadcaster.dashboardEvents.bot({ running: true, dryRun: false });
broadcaster.push('info', 'Bot started');
expect(received).toEqual(['bot.status.changed', 'log.created']);
subscription.unsubscribe();
broadcaster.closeAll();
});
});