import { Redis } from 'ioredis'; import { createDb, buildLogs } from '@bmm/db'; import type { BuildEvent, BuildStatus } from '@bmm/types'; import { config } from '../config.js'; const pub = new Redis(config.REDIS_URL, { maxRetriesPerRequest: null }); const db = createDb(); function channel(buildId: string): string { return `build:${buildId}`; } export async function emitLog( buildId: string, level: 'info' | 'warn' | 'error', message: string, ): Promise { const at = new Date().toISOString(); const evt: BuildEvent = { type: 'log', level, message, at }; await pub.publish(channel(buildId), JSON.stringify(evt)); await db.insert(buildLogs).values({ buildId, level, message }); } export async function emitStatus(buildId: string, status: BuildStatus): Promise { const at = new Date().toISOString(); const evt: BuildEvent = { type: 'status', status, at }; await pub.publish(channel(buildId), JSON.stringify(evt)); } export async function emitDone( buildId: string, status: BuildStatus, serverId: string, publicUrl: string | null, ): Promise { const at = new Date().toISOString(); const evt: BuildEvent = { type: 'done', status, serverId, publicUrl, at }; await pub.publish(channel(buildId), JSON.stringify(evt)); } export async function emitError(buildId: string, message: string): Promise { const at = new Date().toISOString(); const evt: BuildEvent = { type: 'error', message, at }; await pub.publish(channel(buildId), JSON.stringify(evt)); await db.insert(buildLogs).values({ buildId, level: 'error', message }); }