Spaces:
Sleeping
Sleeping
Download server.mjs from mfuntowicz/hfinfer: direct link, hf CLI and curl.
- Browser
- Download file 4.68 kB
-
https://huggingface.co/spaces/mfuntowicz/hfinfer/resolve/main/server.mjs
- Command line
-
hf download hf://spaces/mfuntowicz/hfinfer/server.mjs
-
curl -L -o server.mjs https://huggingface.co/spaces/mfuntowicz/hfinfer/resolve/main/server.mjs
4.68 kB
| // Production server for the Docker Space. No dependencies. | |
| // | |
| // / -> static dashboard from dist/ | |
| // /data/* -> benchmark files from DATA_DIR (bucket volume, default ./data) | |
| // | |
| // /data/index.json is generated ON THE FLY by scanning DATA_DIR, so new | |
| // .jsonl files dropped into the bucket are discovered immediately — no | |
| // manifest regeneration, no rebuild. | |
| import { createServer } from 'node:http' | |
| import { createReadStream, existsSync, readdirSync, statSync } from 'node:fs' | |
| import { extname, join, normalize, resolve, sep } from 'node:path' | |
| import { fileURLToPath } from 'node:url' | |
| const root = resolve(fileURLToPath(new URL('.', import.meta.url))) | |
| const distDir = join(root, 'dist') | |
| const dataDir = resolve(process.env.DATA_DIR ?? join(root, 'data')) | |
| const port = Number(process.env.PORT ?? 7860) | |
| const MIME = { | |
| '.html': 'text/html; charset=utf-8', | |
| '.js': 'text/javascript', | |
| '.css': 'text/css', | |
| '.json': 'application/json', | |
| '.jsonl': 'application/x-ndjson', | |
| '.svg': 'image/svg+xml', | |
| '.png': 'image/png', | |
| '.ico': 'image/x-icon', | |
| '.woff2': 'font/woff2', | |
| '.map': 'application/json', | |
| } | |
| function sendFile(res, file, cacheControl) { | |
| const stream = createReadStream(file) | |
| stream.on('data', (chunk) => { | |
| res.bytesSent = (res.bytesSent ?? 0) + chunk.length | |
| }) | |
| stream.on('error', (err) => { | |
| // Never let a stream error crash the server (it would take down the Space). | |
| console.error(`[server] failed to read ${file}:`, err.message) | |
| if (!res.headersSent) res.writeHead(500) | |
| res.end() | |
| }) | |
| res.writeHead(200, { | |
| 'Content-Type': MIME[extname(file)] ?? 'application/octet-stream', | |
| 'Cache-Control': cacheControl, | |
| }) | |
| stream.pipe(res) | |
| } | |
| /** Join rel onto base, refusing path traversal outside base. */ | |
| function safeJoin(base, rel) { | |
| const file = normalize(join(base, rel)) | |
| return file === base || file.startsWith(base + sep) ? file : null | |
| } | |
| /** Recursively collect .jsonl paths under dir, prefixed with prefix. */ | |
| function collectJsonl(dir, prefix, out) { | |
| for (const entry of readdirSync(dir).sort()) { | |
| const full = join(dir, entry) | |
| if (statSync(full).isDirectory()) collectJsonl(full, `${prefix}${entry}/`, out) | |
| else if (entry.endsWith('.jsonl')) out.push(`${prefix}${entry}`) | |
| } | |
| return out | |
| } | |
| /** | |
| * Scan DATA_DIR and build the categories manifest. Category directories are | |
| * walked recursively to support the partitioned layout | |
| * (<category>/<host>/<date>/<name>.jsonl) alongside legacy flat files. | |
| */ | |
| function buildManifest() { | |
| const categories = {} | |
| if (existsSync(dataDir)) { | |
| for (const entry of readdirSync(dataDir).sort()) { | |
| const full = join(dataDir, entry) | |
| if (statSync(full).isDirectory()) { | |
| const files = collectJsonl(full, `${entry}/`, []) | |
| if (files.length > 0) categories[entry] = files | |
| } else if (entry.endsWith('.jsonl')) { | |
| ;(categories.models ??= []).push(entry) | |
| } | |
| } | |
| } | |
| return { categories } | |
| } | |
| createServer((req, res) => { | |
| const start = Date.now() | |
| res.on('finish', () => { | |
| console.log( | |
| `[http] ${req.method} ${req.url} -> ${res.statusCode} ${res.bytesSent ?? 0}B (${Date.now() - start}ms)` | |
| ) | |
| }) | |
| try { | |
| handle(req, res) | |
| } catch (err) { | |
| // Never crash the process on a single bad request. | |
| console.error('[server] handler error:', err) | |
| if (!res.headersSent) res.writeHead(500) | |
| res.end('internal error') | |
| } | |
| }).listen(port, '0.0.0.0', () => { | |
| console.log(`dashboard: http://0.0.0.0:${port} (dist=${distDir}, data=${dataDir})`) | |
| }) | |
| function handle(req, res) { | |
| const url = new URL(req.url ?? '/', `http://${req.headers.host ?? 'localhost'}`) | |
| const path = decodeURIComponent(url.pathname) | |
| // Dynamic manifest — always reflects the current bucket contents. | |
| if (path === '/data/index.json') { | |
| res.writeHead(200, { 'Content-Type': 'application/json', 'Cache-Control': 'no-store' }) | |
| res.end(JSON.stringify(buildManifest())) | |
| return | |
| } | |
| // Benchmark data files (never cached: results are appended over time). | |
| if (path.startsWith('/data/')) { | |
| const file = safeJoin(dataDir, path.slice('/data/'.length)) | |
| if (file && existsSync(file) && statSync(file).isFile()) { | |
| sendFile(res, file, 'no-store') | |
| } else { | |
| res.writeHead(404) | |
| res.end('not found') | |
| } | |
| return | |
| } | |
| // Static dashboard, SPA fallback to index.html. | |
| let file = safeJoin(distDir, path === '/' ? 'index.html' : path.slice(1)) | |
| if (!file || !existsSync(file) || !statSync(file).isFile()) { | |
| file = join(distDir, 'index.html') | |
| } | |
| sendFile(res, file, file.includes(`${sep}assets${sep}`) ? 'public, max-age=31536000, immutable' : 'no-cache') | |
| } | |