Files
electric-cherry/src/hooks.server.ts
T
2026-10-18 16:55:49 -04:00

63 lines
2.3 KiB
TypeScript

import type { Handle } from '@sveltejs/kit';
import { migrate } from '$lib/server/db/migrate.js';
import { startWorker } from '$lib/server/pipeline/worker.js';
import { interruptDeployments } from '$lib/server/provisioning/history.js';
import { authenticationHandle } from '$lib/server/auth/guard.js';
import { invalidateFleet } from '$lib/server/pipeline/bus.js';
import { startPerformanceMonitor } from '$lib/server/performance.js';
import { withOperationSource } from '$lib/server/hosts/operation-context.js';
import { withHostRequestContext } from '$lib/server/hosts/request-context.js';
import { startDiscordWorker } from '$lib/server/discord/worker.js';
let booted = false;
let rejectionLoggerRegistered = false;
function boot(): void {
if (booted) return;
if (!rejectionLoggerRegistered) {
process.on('unhandledRejection', (reason) => {
console.error('[process] unhandled rejection:', reason);
});
rejectionLoggerRegistered = true;
}
migrate();
interruptDeployments();
startWorker();
startDiscordWorker();
startPerformanceMonitor();
booted = true;
}
// Boot synchronously before serving requests. Failed startup stays unbooted so
// the next request retries migrations and worker startup before reaching the UI.
export const handle: Handle = async (input) => {
boot();
const started = performance.now();
const response = await withHostRequestContext(() =>
withOperationSource(
`${input.event.request.method} ${input.event.route.id ?? 'Web request'}`,
() => authenticationHandle(input)
)
);
const elapsed = performance.now() - started;
response.headers.append('Server-Timing', `app;dur=${elapsed.toFixed(1)}`);
if (
process.env.EC_PERF_LOG === 'true' &&
elapsed > 250 &&
!input.event.route.id?.startsWith('/api/agent/')
) {
console.info('[request]', {
route: input.event.route.id,
method: input.event.request.method,
status: response.status,
elapsedMs: Math.round(elapsed)
});
}
if (
input.event.locals.user &&
!['GET', 'HEAD', 'OPTIONS'].includes(input.event.request.method) &&
response.status < 400
)
invalidateFleet();
return response;
};