// embed Http Service // Purpose: Defines the embed Http Service module and the helpers/state used by this service unit. // Scope: Keeps runtime behavior unchanged while isolating responsibilities into a clear module boundary. const { app } = require('../../globals/http'); const { renderIndexHtml, renderOgImage, renderWebManifest } = require('../embedService'); /* Every client-side BrowserRouter entry point must also be an explicit HTTP entry point. Keeping this list aligned with webui/src/main.jsx lets direct loads and browser refreshes receive the same rendered index document as in-app navigation. The retired desktop composition is intentionally exposed at /old; the removed /newdrive route is intentionally absent. */ /* Every top-level React application needs the same generated index document on a direct browser load. Keeping the setup and admin routes in this explicit allowlist prevents them from working only after client-side navigation. */ app.get(['/', '/old', '/spectate', '/mini', '/display', '/scanner', '/database', '/ptz', '/reports', '/setup', '/admin'], async (req, res) => { try { const html = await renderIndexHtml(req); res.type('html').send(html); } catch (err) { res.status(500).send('Failed to render page'); } }); app.get('/og/preview.png', async (req, res) => { try { const buffer = await renderOgImage(); res.set('Cache-Control', 'public, max-age=60'); res.type('png').send(buffer); } catch (err) { res.status(500).send('Failed to render embed image'); } }); app.get('/manifest.webmanifest', (req, res) => { /* The manifest varies with server configuration, so it is served by the application rather than copied into Vite's static output. Revalidation lets browsers pick up branding changes after the server is restarted. */ res.set('Cache-Control', 'no-cache'); res.type('application/manifest+json').send(renderWebManifest()); });