From 5020d2c288d72e88a8ef563095c494c7ea8709bc Mon Sep 17 00:00:00 2001 From: Igor Barcik Date: Wed, 13 May 2026 13:46:47 +0200 Subject: [PATCH] style: format code for better readability - Format arrays and objects on multiple lines for clarity - Add trailing commas to arrays and objects - Format function parameters across multiple lines when needed - Format string concatenation and template literals consistently - Format try-catch blocks with proper spacing --- src/server.ts | 198 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 151 insertions(+), 47 deletions(-) diff --git a/src/server.ts b/src/server.ts index 3a8854e..583941d 100644 --- a/src/server.ts +++ b/src/server.ts @@ -164,8 +164,8 @@ if (viewCount === 0) { "Demo View", JSON.stringify([ { url: "https://www.google.com", durationSec: 30, forceDarkMode: false, bakeStyles: false }, - { url: "https://duck.ai", durationSec: 30, forceDarkMode: false, bakeStyles: false }, - { url: "https://www.msn.com", durationSec: 30, forceDarkMode: false, bakeStyles: false }, + { url: "https://duck.ai", durationSec: 30, forceDarkMode: false, bakeStyles: false }, + { url: "https://www.msn.com", durationSec: 30, forceDarkMode: false, bakeStyles: false }, ]), "ssr", 0, @@ -229,7 +229,7 @@ function dbDelete(id: string): boolean { function dbBanIP(ip: string, reason?: string): void { db.run( "INSERT OR REPLACE INTO banned_ips (ip, banned_at, reason, banned_by) VALUES (?, ?, ?, ?)", - [ip, Math.floor(Date.now() / 1000), reason ?? "Manual ban", "admin"] + [ip, Math.floor(Date.now() / 1000), reason ?? "Manual ban", "admin"], ); } @@ -241,7 +241,12 @@ function dbIsBanned(ip: string): boolean { return db.query("SELECT ip FROM banned_ips WHERE ip = ?").get(ip) != null; } -function dbGetBannedIPs(): Array<{ ip: string; banned_at: number; reason: string; banned_by: string }> { +function dbGetBannedIPs(): Array<{ + ip: string; + banned_at: number; + reason: string; + banned_by: string; +}> { return db.query("SELECT * FROM banned_ips ORDER BY banned_at DESC").all() as Array<{ ip: string; banned_at: number; @@ -292,11 +297,11 @@ function deviceTrack(ip: string, viewId: string, viewName: string, userAgent: st existing.requestCount++; } else { devices.set(ip, { ip, viewId, viewName, userAgent, lastSeen: Date.now(), requestCount: 1 }); - + // First user connecting to this view - trigger warmup if (!warmedUpViews.has(viewId)) { warmedUpViews.add(viewId); - warmupView(viewId).catch(err => { + warmupView(viewId).catch((err) => { console.error(`[warmup] Failed to warm up view ${viewId}:`, err); }); } @@ -321,7 +326,7 @@ function devicesSnapshot(): DeviceEntry[] { // ═══════════════════════════════════════════════════════════════ function getDebugData() { - const viewsDebug = viewCacheAll().map(v => { + const viewsDebug = viewCacheAll().map((v) => { const idx = getCurrentURLIndex(v); return { id: v.id, @@ -336,7 +341,7 @@ function getDebugData() { currentUrl: v.urls[idx]?.url ?? "", remainingSec: getRemainingSec(v), totalCycleSec: v.urls.reduce((s, u) => s + u.durationSec, 0), - cacheEntries: cacheStats().filter(c => c.viewId === v.id), + cacheEntries: cacheStats().filter((c) => c.viewId === v.id), }; }); @@ -438,7 +443,9 @@ class PagePool { return true; } catch (err) { console.warn(`[page-pool] resetPage failed, discarding page: ${err}`); - try { await page.close(); } catch {} + try { + await page.close(); + } catch {} return false; } } @@ -513,10 +520,7 @@ let pagePool: PagePool; // WEBSOCKET DEBUG CLIENTS // ═══════════════════════════════════════════════════════════════ -const debugClients = new Map< - any, - { interval: number; timer: ReturnType } ->(); +const debugClients = new Map }>(); const DEBUG_DEFAULT_INTERVAL_MS = 1000; const DEBUG_MIN_INTERVAL_MS = 100; @@ -668,12 +672,19 @@ async function renderViewToCache(view: View, urlIndex: number, key: string): Pro let body: string; if (view.method === "mjpeg") { const jpeg = await renderScreenshotFrame( - urlItem.url, view.viewportWidth, view.viewportHeight, forceDarkMode, + urlItem.url, + view.viewportWidth, + view.viewportHeight, + forceDarkMode, ); body = jpeg.toString("base64"); } else { body = await renderSSR( - urlItem.url, view.viewportWidth, view.viewportHeight, forceDarkMode, bakeStyles, + urlItem.url, + view.viewportWidth, + view.viewportHeight, + forceDarkMode, + bakeStyles, ); } @@ -823,7 +834,8 @@ function stripScriptTags(html: string): string { // ── Recursive @import resolver (max 3 levels deep) ── async function resolveCSSImports(cssText: string, baseUrl: string, depth = 0): Promise { if (depth > 3) return cssText; - const importRe = /@import\s+(?:url\s*\(\s*["']?([^)"']+)["']?\s*\)|["']([^"']+)["'])\s*([^;]*);/gi; + const importRe = + /@import\s+(?:url\s*\(\s*["']?([^)"']+)["']?\s*\)|["']([^"']+)["'])\s*([^;]*);/gi; const replacements: Array<{ match: string; resolved: string }> = []; let m: RegExpExecArray | null; @@ -839,7 +851,10 @@ async function resolveCSSImports(cssText: string, baseUrl: string, depth = 0): P if (!res.ok) throw new Error("failed"); let imported = await res.text(); imported = await resolveCSSImports(imported, importUrl, depth + 1); - replacements.push({ match: m[0], resolved: "/* begin " + importUrl + " */\n" + imported + "\n/* end " + importUrl + " */" }); + replacements.push({ + match: m[0], + resolved: "/* begin " + importUrl + " */\n" + imported + "\n/* end " + importUrl + " */", + }); } catch { replacements.push({ match: m[0], resolved: "/* unresolved import: " + importUrl + " */" }); } @@ -865,40 +880,117 @@ async function bakeComputedStyles(page: Page): Promise { await page.evaluate((): void => { const computedProperties = [ // Layout - "display", "position", "top", "right", "bottom", "left", - "width", "height", "min-width", "min-height", "max-width", "max-height", - "margin", "margin-top", "margin-right", "margin-bottom", "margin-left", - "padding", "padding-top", "padding-right", "padding-bottom", "padding-left", + "display", + "position", + "top", + "right", + "bottom", + "left", + "width", + "height", + "min-width", + "min-height", + "max-width", + "max-height", + "margin", + "margin-top", + "margin-right", + "margin-bottom", + "margin-left", + "padding", + "padding-top", + "padding-right", + "padding-bottom", + "padding-left", // Flex/Grid - "flex", "flex-direction", "flex-wrap", "flex-flow", "flex-grow", "flex-shrink", "flex-basis", - "justify-content", "align-items", "align-content", "align-self", "gap", "row-gap", "column-gap", - "grid", "grid-template", "grid-template-columns", "grid-template-rows", "grid-area", + "flex", + "flex-direction", + "flex-wrap", + "flex-flow", + "flex-grow", + "flex-shrink", + "flex-basis", + "justify-content", + "align-items", + "align-content", + "align-self", + "gap", + "row-gap", + "column-gap", + "grid", + "grid-template", + "grid-template-columns", + "grid-template-rows", + "grid-area", // Box model - "box-sizing", "border-top-width", "border-right-width", "border-bottom-width", "border-left-width", - "border-top-style", "border-right-style", "border-bottom-style", "border-left-style", - "border-top-color", "border-right-color", "border-bottom-color", "border-left-color", - "border-top-left-radius", "border-top-right-radius", "border-bottom-right-radius", "border-bottom-left-radius", + "box-sizing", + "border-top-width", + "border-right-width", + "border-bottom-width", + "border-left-width", + "border-top-style", + "border-right-style", + "border-bottom-style", + "border-left-style", + "border-top-color", + "border-right-color", + "border-bottom-color", + "border-left-color", + "border-top-left-radius", + "border-top-right-radius", + "border-bottom-right-radius", + "border-bottom-left-radius", // Colors & Background - "color", "background-color", "background-image", "background-size", "background-position", - "background-repeat", "background-attachment", "background-clip", "background-origin", + "color", + "background-color", + "background-image", + "background-size", + "background-position", + "background-repeat", + "background-attachment", + "background-clip", + "background-origin", // Typography - "font-family", "font-size", "font-weight", "font-style", "font-variant", - "line-height", "text-align", "text-decoration-line", "text-decoration-color", - "text-transform", "letter-spacing", "word-spacing", - "white-space", "overflow-wrap", "word-break", + "font-family", + "font-size", + "font-weight", + "font-style", + "font-variant", + "line-height", + "text-align", + "text-decoration-line", + "text-decoration-color", + "text-transform", + "letter-spacing", + "word-spacing", + "white-space", + "overflow-wrap", + "word-break", // Visual - "opacity", "visibility", "z-index", "overflow-x", "overflow-y", - "box-shadow", "text-shadow", "transform", "transform-origin", + "opacity", + "visibility", + "z-index", + "overflow-x", + "overflow-y", + "box-shadow", + "text-shadow", + "transform", + "transform-origin", // List/Table - "list-style-type", "list-style-position", "border-collapse", "border-spacing", + "list-style-type", + "list-style-position", + "border-collapse", + "border-spacing", // Cursor/pointer - "cursor", "pointer-events", + "cursor", + "pointer-events", ]; // Cache of default computed values keyed by tagName const defaultCache = new Map>(); const hiddenContainer = document.createElement("div"); - hiddenContainer.style.cssText = "position:absolute;visibility:hidden;pointer-events:none;top:-9999px;"; + hiddenContainer.style.cssText = + "position:absolute;visibility:hidden;pointer-events:none;top:-9999px;"; document.body.appendChild(hiddenContainer); function getTagDefaults(tag: string): Map { @@ -913,7 +1005,9 @@ async function bakeComputedStyles(page: Page): Promise { cache.set(prop, cs.getPropertyValue(prop)); } el.remove(); - } catch { /* unknown tag, cache will be empty */ } + } catch { + /* unknown tag, cache will be empty */ + } defaultCache.set(tag, cache); return cache; } @@ -921,7 +1015,8 @@ async function bakeComputedStyles(page: Page): Promise { function shouldBake(value: string, defaultValue: string): boolean { if (!value) return false; // Skip browser keywords that cannot be serialized as inline style values - if (value === "initial" || value === "inherit" || value === "unset" || value === "revert") return false; + if (value === "initial" || value === "inherit" || value === "unset" || value === "revert") + return false; return value !== defaultValue; } @@ -931,7 +1026,8 @@ async function bakeComputedStyles(page: Page): Promise { if (el === hiddenContainer) continue; // Skip non-visual tags const tag = el.tagName.toLowerCase(); - if (["script", "style", "meta", "link", "noscript", "template", "head", "html"].includes(tag)) continue; + if (["script", "style", "meta", "link", "noscript", "template", "head", "html"].includes(tag)) + continue; const computed = window.getComputedStyle(el); const defaults = getTagDefaults(tag); @@ -1081,7 +1177,7 @@ async function inlineAllResources(page: Page, html: string): Promise { html = html.replace( linkRegex, - `/* inlined: ${css.url} */\n${resolvedCSS}\n` + `/* inlined: ${css.url} */\n${resolvedCSS}\n`, ); } for (const img of payload.images) { @@ -1498,7 +1594,9 @@ const server = Bun.serve<{ interval: number }>({ }, interval); debugClients.set(ws, { interval, timer }); // Send initial payload immediately - try { ws.send(JSON.stringify(getDebugData())); } catch {} + try { + ws.send(JSON.stringify(getDebugData())); + } catch {} }, message(ws, msg) { try { @@ -1510,15 +1608,21 @@ const server = Bun.serve<{ interval: number }>({ clearInterval(client.timer); client.interval = interval; client.timer = setInterval(() => { - try { ws.send(JSON.stringify(getDebugData())); } catch { + try { + ws.send(JSON.stringify(getDebugData())); + } catch { clearInterval(client.timer); debugClients.delete(ws); } }, interval); // Push immediately after rate change - try { ws.send(JSON.stringify(getDebugData())); } catch {} + try { + ws.send(JSON.stringify(getDebugData())); + } catch {} } - } catch { /* ignore malformed messages */ } + } catch { + /* ignore malformed messages */ + } }, close(ws) { const client = debugClients.get(ws);