import { Elysia, t } from "elysia"; import { subMinutes } from "date-fns"; import { getDailyStats } from "../app/dailyStatsStore.ts"; import { generationStore } from "../app/generationStore.ts"; import { globalStats } from "../app/globalStats.ts"; import { getUserDailyStats } from "../app/userDailyStatsStore.ts"; import { getUserStats } from "../app/userStatsStore.ts"; import { withAdmin } from "./withUser.ts"; const STATS_INTERVAL_MIN = 3; export const statsRoute = new Elysia() .get( "", async () => { const after = subMinutes(new Date(), STATS_INTERVAL_MIN); const generations = await generationStore.getAll({ after }); const imagesPerMinute = generations.length / STATS_INTERVAL_MIN; const stepsPerMinute = generations .map((generation) => generation.value.info?.steps ?? 0) .reduce((sum, steps) => sum + steps, 0) / STATS_INTERVAL_MIN; const pixelsPerMinute = generations .map((generation) => (generation.value.info?.width ?? 0) * (generation.value.info?.height ?? 0) ) .reduce((sum, pixels) => sum + pixels, 0) / STATS_INTERVAL_MIN; const pixelStepsPerMinute = generations .map((generation) => (generation.value.info?.width ?? 0) * (generation.value.info?.height ?? 0) * (generation.value.info?.steps ?? 0) ) .reduce((sum, pixelSteps) => sum + pixelSteps, 0) / STATS_INTERVAL_MIN; return { imageCount: globalStats.imageCount, stepCount: globalStats.stepCount, pixelCount: globalStats.pixelCount, pixelStepCount: globalStats.pixelStepCount, userCount: globalStats.userIds.length, imagesPerMinute, stepsPerMinute, pixelsPerMinute, pixelStepsPerMinute, }; }, { response: t.Object({ imageCount: t.Number(), stepCount: t.Number(), pixelCount: t.Number(), pixelStepCount: t.Number(), userCount: t.Number(), imagesPerMinute: t.Number(), stepsPerMinute: t.Number(), pixelsPerMinute: t.Number(), pixelStepsPerMinute: t.Number(), }), }, ) .get( "/daily/:year/:month/:day", async ({ params }) => { const year = Number(params.year); const month = Number(params.month); const day = Number(params.day); const stats = await getDailyStats(year, month, day); return { imageCount: stats.imageCount, pixelCount: stats.pixelCount, userCount: stats.userIds.length, timestamp: stats.timestamp, }; }, { params: t.Object({ year: t.Number(), month: t.Number(), day: t.Number(), }), response: t.Object({ imageCount: t.Number(), pixelCount: t.Number(), userCount: t.Number(), timestamp: t.Number(), }), }, ) .get( "/users/:userId", async ({ params }) => { const userId = params.userId; const stats = await getUserStats(userId); return { imageCount: stats.imageCount, pixelCount: stats.pixelCount, timestamp: stats.timestamp, }; }, { params: t.Object({ userId: t.Number() }), response: t.Object({ imageCount: t.Number(), pixelCount: t.Number(), timestamp: t.Number(), }), }, ) .get( "/users/:userId/tagcount", async ({ params, query }) => { return withAdmin(query, async () => { const userId = Number(params.userId); const stats = await getUserStats(userId); return { tagCountMap: stats.tagCountMap, timestamp: stats.timestamp, }; }); }, { params: t.Object({ userId: t.Number() }), query: t.Object({ sessionId: t.String() }), response: t.Object({ tagCountMap: t.Record(t.String(), t.Number()), timestamp: t.Number(), }), }, ) .get( "/users/:userId/daily/:year/:month/:day", async ({ params }) => { const { userId, year, month, day } = params; const stats = await getUserDailyStats(userId, year, month, day); return { imageCount: stats.imageCount, pixelCount: stats.pixelCount, timestamp: stats.timestamp, }; }, { params: t.Object({ userId: t.Number(), year: t.Number(), month: t.Number(), day: t.Number(), }), response: t.Object({ imageCount: t.Number(), pixelCount: t.Number(), timestamp: t.Number(), }), }, );