feat(web): wire domain events into realtime stream

This commit is contained in:
jjbrunton committed 2026-08-08 16:00:17 +01:00
1 parent 8c8ff11fd7
commit d5f0175dc2
6 files changed
+155 -1

No files matched your search

+37 -1
View File
@@ -33,6 +33,7 @@ import { MediaSyncService } from './services/media-sync.js';
import { RateLimiter } from './utils/rate-limiter.js';
import { fetchWithTimeout } from './utils/fetch-with-timeout.js';
import { WebServer } from './web/server.js';
import { reportReply } from './web/event-reporting.js';
export interface AppContainer {
config: Config;
@@ -126,6 +127,10 @@ export async function bootstrap(config: Config, logger: Logger): Promise<AppCont
if (loggedIn) {
logger.info('Reddit login verified');
}
broadcaster.dashboardEvents.redditSession({
state: loggedIn ? 'authenticated' : 'login-required',
username: loggedIn ? config.reddit.username : undefined,
});
// Reddit API client (shares browser context for auth)
const redditApi = new RedditApiClient(config, logger);
@@ -273,16 +278,47 @@ export async function bootstrap(config: Config, logger: Logger): Promise<AppCont
webServer.setChatService(chatService);
// Stream sync-progress frames over the dashboard's SSE channel so the
// full-sync UI can show live phase + per-room progress.
let lastSyncProgress: { kind: 'full' | 'delta'; current: number; startedAt: number } | null = null;
chatService.setProgressListener((progress) => {
webServer!.broadcastSyncProgress(progress as Record<string, unknown> | null);
if (progress) {
const syncId = `chat-${progress.startedAt}`;
if (progress.phase === 'starting') {
broadcaster.dashboardEvents.sync({ phase: 'started', id: syncId, kind: progress.kind });
} else {
broadcaster.dashboardEvents.sync({
phase: 'progress',
id: syncId,
kind: progress.kind,
current: progress.current,
total: progress.total,
label: progress.label ?? progress.phase,
});
}
lastSyncProgress = progress;
} else if (lastSyncProgress) {
broadcaster.dashboardEvents.sync({
phase: 'completed',
id: `chat-${lastSyncProgress.startedAt}`,
kind: lastSyncProgress.kind,
processed: lastSyncProgress.current,
});
lastSyncProgress = null;
}
});
chatService.setNewReplyListener(({ username, replySnippet }) => {
chatService.setNewReplyListener(({ conversationId, replyId, username, replySnippet }) => {
webServer!.logActivity(
'response',
`Reply from u/${username}: ${replySnippet}`,
username,
);
webServer!.pushLog('info', `💬 Reply from u/${username}`);
reportReply(broadcaster.dashboardEvents, {
conversationId,
replyId,
username,
body: replySnippet,
});
});
webServer.setMediaService(mediaService);
webServer.setMediaSyncService(mediaSyncService);