@hydration-audit/dashboard 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +3 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.html +1607 -0
- package/dist/index.mjs +3 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import http from "http";
|
|
3
3
|
import fs from "fs";
|
|
4
4
|
import path from "path";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
5
6
|
import { WebSocketServer } from "ws";
|
|
6
7
|
var MIME_TYPES = {
|
|
7
8
|
".html": "text/html",
|
|
@@ -19,10 +20,8 @@ async function startDashboard(reportPath, port = 4173) {
|
|
|
19
20
|
} catch {
|
|
20
21
|
console.warn(`Could not read report at ${absoluteReportPath}`);
|
|
21
22
|
}
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
"app"
|
|
25
|
-
);
|
|
23
|
+
const currentDir = path.dirname(fileURLToPath(import.meta.url));
|
|
24
|
+
const staticDir = fs.existsSync(path.join(currentDir, "app")) ? path.join(currentDir, "app") : currentDir;
|
|
26
25
|
const server = http.createServer((req, res) => {
|
|
27
26
|
const url = req.url ?? "/";
|
|
28
27
|
if (url === "/api/report") {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["import http from 'node:http';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { WebSocketServer } from 'ws';\nimport type { AnalysisReport } from '@hydration-audit/core';\n\nconst MIME_TYPES: Record<string, string> = {\n '.html': 'text/html',\n '.js': 'application/javascript',\n '.css': 'text/css',\n '.json': 'application/json',\n '.svg': 'image/svg+xml',\n};\n\n/**\n * Start the dashboard server.\n * Serves a static SPA and provides a WebSocket for live report updates.\n */\nexport async function startDashboard(\n reportPath: string,\n port = 4173,\n): Promise<{ url: string; close: () => void }> {\n const absoluteReportPath = path.resolve(reportPath);\n\n // Read the initial report\n let currentReport: AnalysisReport | null = null;\n try {\n const content = fs.readFileSync(absoluteReportPath, 'utf-8');\n currentReport = JSON.parse(content);\n } catch {\n console.warn(`Could not read report at ${absoluteReportPath}`);\n }\n\n const
|
|
1
|
+
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["import http from 'node:http';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { WebSocketServer } from 'ws';\nimport type { AnalysisReport } from '@hydration-audit/core';\n\nconst MIME_TYPES: Record<string, string> = {\n '.html': 'text/html',\n '.js': 'application/javascript',\n '.css': 'text/css',\n '.json': 'application/json',\n '.svg': 'image/svg+xml',\n};\n\n/**\n * Start the dashboard server.\n * Serves a static SPA and provides a WebSocket for live report updates.\n */\nexport async function startDashboard(\n reportPath: string,\n port = 4173,\n): Promise<{ url: string; close: () => void }> {\n const absoluteReportPath = path.resolve(reportPath);\n\n // Read the initial report\n let currentReport: AnalysisReport | null = null;\n try {\n const content = fs.readFileSync(absoluteReportPath, 'utf-8');\n currentReport = JSON.parse(content);\n } catch {\n console.warn(`Could not read report at ${absoluteReportPath}`);\n }\n\n const currentDir = path.dirname(fileURLToPath(import.meta.url));\n const staticDir = fs.existsSync(path.join(currentDir, 'app'))\n ? path.join(currentDir, 'app')\n : currentDir;\n\n const server = http.createServer((req, res) => {\n const url = req.url ?? '/';\n\n // API endpoint for report data\n if (url === '/api/report') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(currentReport ?? { error: 'No report loaded' }));\n return;\n }\n\n // Serve static files\n let filePath = path.join(staticDir, url === '/' ? 'index.html' : url);\n const ext = path.extname(filePath);\n\n // SPA fallback — serve index.html for non-file routes\n if (!ext) {\n filePath = path.join(staticDir, 'index.html');\n }\n\n try {\n const content = fs.readFileSync(filePath);\n const mime = MIME_TYPES[path.extname(filePath)] ?? 'text/plain';\n res.writeHead(200, { 'Content-Type': mime });\n res.end(content);\n } catch {\n res.writeHead(404);\n res.end('Not found');\n }\n });\n\n // WebSocket for live reload\n const wss = new WebSocketServer({ server });\n\n // Watch report file for changes\n let watcher: fs.FSWatcher | null = null;\n try {\n watcher = fs.watch(absoluteReportPath, () => {\n try {\n const content = fs.readFileSync(absoluteReportPath, 'utf-8');\n currentReport = JSON.parse(content);\n // Notify all connected clients\n for (const client of wss.clients) {\n if (client.readyState === 1) {\n client.send(JSON.stringify({ type: 'update', report: currentReport }));\n }\n }\n } catch {\n // Ignore parse errors during write\n }\n });\n } catch {\n console.warn('Could not watch report file for changes');\n }\n\n return new Promise((resolve) => {\n server.listen(port, () => {\n const url = `http://localhost:${port}`;\n console.log(`\\n Dashboard running at ${url}\\n`);\n resolve({\n url,\n close: () => {\n watcher?.close();\n wss.close();\n server.close();\n },\n });\n });\n });\n}\n"],"mappings":";AAAA,OAAO,UAAU;AACjB,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;AAGhC,IAAM,aAAqC;AAAA,EACzC,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AACV;AAMA,eAAsB,eACpB,YACA,OAAO,MACsC;AAC7C,QAAM,qBAAqB,KAAK,QAAQ,UAAU;AAGlD,MAAI,gBAAuC;AAC3C,MAAI;AACF,UAAM,UAAU,GAAG,aAAa,oBAAoB,OAAO;AAC3D,oBAAgB,KAAK,MAAM,OAAO;AAAA,EACpC,QAAQ;AACN,YAAQ,KAAK,4BAA4B,kBAAkB,EAAE;AAAA,EAC/D;AAEA,QAAM,aAAa,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAC9D,QAAM,YAAY,GAAG,WAAW,KAAK,KAAK,YAAY,KAAK,CAAC,IACxD,KAAK,KAAK,YAAY,KAAK,IAC3B;AAEJ,QAAM,SAAS,KAAK,aAAa,CAAC,KAAK,QAAQ;AAC7C,UAAM,MAAM,IAAI,OAAO;AAGvB,QAAI,QAAQ,eAAe;AACzB,UAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,UAAI,IAAI,KAAK,UAAU,iBAAiB,EAAE,OAAO,mBAAmB,CAAC,CAAC;AACtE;AAAA,IACF;AAGA,QAAI,WAAW,KAAK,KAAK,WAAW,QAAQ,MAAM,eAAe,GAAG;AACpE,UAAM,MAAM,KAAK,QAAQ,QAAQ;AAGjC,QAAI,CAAC,KAAK;AACR,iBAAW,KAAK,KAAK,WAAW,YAAY;AAAA,IAC9C;AAEA,QAAI;AACF,YAAM,UAAU,GAAG,aAAa,QAAQ;AACxC,YAAM,OAAO,WAAW,KAAK,QAAQ,QAAQ,CAAC,KAAK;AACnD,UAAI,UAAU,KAAK,EAAE,gBAAgB,KAAK,CAAC;AAC3C,UAAI,IAAI,OAAO;AAAA,IACjB,QAAQ;AACN,UAAI,UAAU,GAAG;AACjB,UAAI,IAAI,WAAW;AAAA,IACrB;AAAA,EACF,CAAC;AAGD,QAAM,MAAM,IAAI,gBAAgB,EAAE,OAAO,CAAC;AAG1C,MAAI,UAA+B;AACnC,MAAI;AACF,cAAU,GAAG,MAAM,oBAAoB,MAAM;AAC3C,UAAI;AACF,cAAM,UAAU,GAAG,aAAa,oBAAoB,OAAO;AAC3D,wBAAgB,KAAK,MAAM,OAAO;AAElC,mBAAW,UAAU,IAAI,SAAS;AAChC,cAAI,OAAO,eAAe,GAAG;AAC3B,mBAAO,KAAK,KAAK,UAAU,EAAE,MAAM,UAAU,QAAQ,cAAc,CAAC,CAAC;AAAA,UACvE;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF,CAAC;AAAA,EACH,QAAQ;AACN,YAAQ,KAAK,yCAAyC;AAAA,EACxD;AAEA,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,WAAO,OAAO,MAAM,MAAM;AACxB,YAAM,MAAM,oBAAoB,IAAI;AACpC,cAAQ,IAAI;AAAA,yBAA4B,GAAG;AAAA,CAAI;AAC/C,cAAQ;AAAA,QACN;AAAA,QACA,OAAO,MAAM;AACX,mBAAS,MAAM;AACf,cAAI,MAAM;AACV,iBAAO,MAAM;AAAA,QACf;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hydration-audit/dashboard",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Web dashboard for visualizing JavaScript hydration costs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"preact": "^10.24.0",
|
|
22
22
|
"d3-hierarchy": "^3.1.2",
|
|
23
23
|
"ws": "^8.18.0",
|
|
24
|
-
"@hydration-audit/core": "0.2.
|
|
24
|
+
"@hydration-audit/core": "0.2.3"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@preact/preset-vite": "^2.9.0",
|