fix(frontend): подготовка к прому

This commit is contained in:
2025-12-29 01:25:25 +03:00
parent 799a11b86d
commit 5e0f22e39e
6 changed files with 39 additions and 9 deletions

View File

@@ -78,6 +78,26 @@ services:
retries: 5 retries: 5
restart: unless-stopped restart: unless-stopped
frontend:
build:
context: ./services/frontend
dockerfile: Dockerfile
container_name: audio_frontend_dev
ports:
- "3000:5173"
environment:
VITE_API_URL: http://localhost:8000
VITE_WS_URL: ws://localhost:8001/ws/live
# VITE_API_URL: http://api:8000
# VITE_WS_URL: ws://api:8001
volumes:
- ./services/frontend:/app
- /app/node_modules
networks:
- audio_network
stdin_open: true
tty: true
restart: unless-stopped
volumes: volumes:
timescale_data: timescale_data:

View File

@@ -0,0 +1,13 @@
# Node 20 + Vite dev server
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
EXPOSE 5173
CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0", "--port", "5173"]

View File

@@ -34,7 +34,7 @@ const WINDOW_OPTIONS_MS = [15_000, 30_000, 60_000, 120_000, 300_000] as const;
const DEFAULT_WINDOW_MS = 60_000; const DEFAULT_WINDOW_MS = 60_000;
const MIN_HZ = 0.1; const MIN_HZ = 0.1;
const MAX_HZ = 60; // const MAX_HZ = 60;
const DEFAULT_REQUESTED_HZ = 10; const DEFAULT_REQUESTED_HZ = 10;
// If there are more than 600 points in selected window -> downsample // If there are more than 600 points in selected window -> downsample
@@ -56,7 +56,7 @@ let flushTimer: number | null = null;
let lastSeenSample: AudioSample | null = null; let lastSeenSample: AudioSample | null = null;
function clampInt(v: number, min: number, max: number): number { function clampInt(v: number, min: number): number {
if (!Number.isFinite(v)) return min; if (!Number.isFinite(v)) return min;
return Math.max(min, v); return Math.max(min, v);
} }
@@ -68,7 +68,7 @@ function isAllowedWindowMs(
} }
function buildWsUrl(base: string, hz: number): string { function buildWsUrl(base: string, hz: number): string {
const safeHz = clampInt(hz, MIN_HZ, MAX_HZ); const safeHz = clampInt(hz, MIN_HZ);
// Prefer URL() for correctness (keeps existing params) // Prefer URL() for correctness (keeps existing params)
try { try {
@@ -188,7 +188,7 @@ export const useLiveStreamStore = create<LiveStreamState>()((set, get) => {
requestedHz: DEFAULT_REQUESTED_HZ, requestedHz: DEFAULT_REQUESTED_HZ,
setRequestedHz: (hz) => { setRequestedHz: (hz) => {
const next = clampInt(hz, MIN_HZ, MAX_HZ); const next = clampInt(hz, MIN_HZ);
const prev = get().requestedHz; const prev = get().requestedHz;
if (next === prev) return; if (next === prev) return;
@@ -223,7 +223,7 @@ export const useLiveStreamStore = create<LiveStreamState>()((set, get) => {
}, },
loadLatest: async (limit = 300) => { loadLatest: async (limit = 300) => {
const safeLimit = clampInt(limit, 1, 5000); const safeLimit = clampInt(limit, 1);
const base = env.apiUrl.replace(/\/$/, ""); const base = env.apiUrl.replace(/\/$/, "");
const url = `${base}/api/v1/audio/latest?limit=${safeLimit}`; const url = `${base}/api/v1/audio/latest?limit=${safeLimit}`;

View File

@@ -135,7 +135,6 @@ export function AudioLiveWidget() {
<FrequencyCurrentDisplay <FrequencyCurrentDisplay
latest={latest} latest={latest}
history={chartHistory} history={chartHistory}
windowMs={windowMs}
/> />
</div> </div>
<div className="lg:col-span-3 grid gap-4"> <div className="lg:col-span-3 grid gap-4">

View File

@@ -18,7 +18,6 @@ import {
type Props = { type Props = {
latest: AudioSample | null; latest: AudioSample | null;
history: AudioSample[]; // последние ~15 секунд history: AudioSample[]; // последние ~15 секунд
windowMs: number;
}; };
const HISTORY_WINDOW_MS = 15_000; // 15 секунд истории const HISTORY_WINDOW_MS = 15_000; // 15 секунд истории
@@ -68,7 +67,6 @@ function getActivityColor(freq: number, rms: number): string {
export const FrequencyCurrentDisplay = memo(function FrequencyCurrentDisplay({ export const FrequencyCurrentDisplay = memo(function FrequencyCurrentDisplay({
latest, latest,
history, history,
windowMs,
}: Props) { }: Props) {
const recentHistory = useMemo(() => { const recentHistory = useMemo(() => {
if (!latest) return []; if (!latest) return [];

View File

@@ -30,7 +30,7 @@
"strict": true, "strict": true,
"noUnusedLocals": true, "noUnusedLocals": true,
"noUnusedParameters": true, "noUnusedParameters": true,
"erasableSyntaxOnly": true, "erasableSyntaxOnly": false,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true "noUncheckedSideEffectImports": true
}, },