From 61cbf92f7b497bc677822ab6c5fe9404d1fa6cbb Mon Sep 17 00:00:00 2001 From: Sam Stenvall Date: Fri, 6 Oct 2023 22:28:48 +0300 Subject: [PATCH 1/3] Show all circuits under "All circuits"... --- webif/src/routes/+page.svelte | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/webif/src/routes/+page.svelte b/webif/src/routes/+page.svelte index 4a656a5..2770f44 100644 --- a/webif/src/routes/+page.svelte +++ b/webif/src/routes/+page.svelte @@ -56,9 +56,7 @@ return d.circuit.type === 'main' && d.circuit.sensor.type !== 'unmetered' }) - circuitSensorData = message.data.filter((d) => { - return d.circuit.type === 'circuit' - }) + circuitSensorData = message.data break case 'configuration': configuration = message.data From 93e6d4d409c158917d415cf7a5c3e08976890943 Mon Sep 17 00:00:00 2001 From: Sam Stenvall Date: Fri, 6 Oct 2023 22:29:05 +0300 Subject: [PATCH 2/3] Add static build for the web interface --- webif/package-lock.json | 25 ++++++------------------- webif/package.json | 2 +- webif/svelte.config.js | 9 ++++----- 3 files changed, 11 insertions(+), 25 deletions(-) diff --git a/webif/package-lock.json b/webif/package-lock.json index 48d3856..aa4e815 100644 --- a/webif/package-lock.json +++ b/webif/package-lock.json @@ -8,7 +8,7 @@ "name": "web-ng", "version": "0.0.1", "devDependencies": { - "@sveltejs/adapter-auto": "^2.0.0", + "@sveltejs/adapter-static": "^2.0.3", "@sveltejs/kit": "^1.20.4", "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", @@ -584,16 +584,13 @@ "integrity": "sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==", "dev": true }, - "node_modules/@sveltejs/adapter-auto": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-2.1.0.tgz", - "integrity": "sha512-o2pZCfATFtA/Gw/BB0Xm7k4EYaekXxaPGER3xGSY3FvzFJGTlJlZjBseaXwYSM94lZ0HniOjTokN3cWaLX6fow==", + "node_modules/@sveltejs/adapter-static": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-2.0.3.tgz", + "integrity": "sha512-VUqTfXsxYGugCpMqQv1U0LIdbR3S5nBkMMDmpjGVJyM6Q2jHVMFtdWJCkeHMySc6mZxJ+0eZK3T7IgmUCDrcUQ==", "dev": true, - "dependencies": { - "import-meta-resolve": "^3.0.0" - }, "peerDependencies": { - "@sveltejs/kit": "^1.0.0" + "@sveltejs/kit": "^1.5.0" } }, "node_modules/@sveltejs/kit": { @@ -1785,16 +1782,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/import-meta-resolve": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-3.0.0.tgz", - "integrity": "sha512-4IwhLhNNA8yy445rPjD/lWh++7hMDOml2eHtd58eG7h+qK3EryMuuRbsHGPikCoAgIkkDnckKfWSk2iDla/ejg==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", diff --git a/webif/package.json b/webif/package.json index d805f74..cec9fa9 100644 --- a/webif/package.json +++ b/webif/package.json @@ -13,7 +13,7 @@ "prettier-check": "prettier --check src/" }, "devDependencies": { - "@sveltejs/adapter-auto": "^2.0.0", + "@sveltejs/adapter-static": "^2.0.3", "@sveltejs/kit": "^1.20.4", "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", diff --git a/webif/svelte.config.js b/webif/svelte.config.js index 18b4716..909b13e 100644 --- a/webif/svelte.config.js +++ b/webif/svelte.config.js @@ -1,4 +1,4 @@ -import adapter from '@sveltejs/adapter-auto' +import adapter from '@sveltejs/adapter-static' import { vitePreprocess } from '@sveltejs/kit/vite' /** @type {import('@sveltejs/kit').Config} */ @@ -8,10 +8,9 @@ const config = { preprocess: vitePreprocess(), kit: { - // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list. - // If your environment is not supported or you settled on a specific environment, switch out the adapter. - // See https://kit.svelte.dev/docs/adapters for more information about adapters. - adapter: adapter(), + adapter: adapter({ + fallback: 'index.html' + }), }, } From 2eb6daf1237a78d778c51183c0113ccb5aa18957 Mon Sep 17 00:00:00 2001 From: Sam Stenvall Date: Fri, 6 Oct 2023 22:29:18 +0300 Subject: [PATCH 3/3] Improve the built-in HTTP server so it can serve the Svelte app --- src/http/server.ts | 73 +++++++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/src/http/server.ts b/src/http/server.ts index 01d34ed..97b8d12 100644 --- a/src/http/server.ts +++ b/src/http/server.ts @@ -1,42 +1,63 @@ +import fs from 'fs' +import path from 'path' import { IncomingMessage, RequestListener, ServerResponse } from 'http' import { promises as fsPromisified } from 'fs' +const basePath = __dirname + '/../../webif/build' + +const mimeTypes = new Map([ + ['.html', 'text/html'], + ['.js', 'text/javascript'], + ['.css', 'text/css'], + ['.json', 'application/json'], + ['.png', 'image/png'], +]) + export const httpRequestHandler: RequestListener = async (req: IncomingMessage, res: ServerResponse) => { - // Main routing logic - let reqUrl = req.url + const filePath = resolveFilePath(req.url) + + // Serve 404 if file doesn't exist + if (!fs.existsSync(filePath)) { + res.writeHead(404) + res.end('Not found') + return + } + + // File exists, try to determine MIME type + const extension = path.extname(filePath).toLowerCase() + const mimeType = mimeTypes.get(extension) + + await serveStaticFile(filePath, mimeType, res) +} + +const resolveFilePath = (reqUrl: string | undefined): string => { + // Strip query parameters if (reqUrl?.indexOf('?') !== -1) { reqUrl = reqUrl?.substring(0, reqUrl?.indexOf('?')) } - switch (reqUrl) { - case '/': - case '/index.html': - await serveStaticFile('index.html', 'text/html', res) - break - case '/eachwatt.css': - await serveStaticFile('eachwatt.css', 'text/css', res) - break - case '/eachwatt.js': - await serveStaticFile('eachwatt.js', 'text/javascript', res) - break - case '/eachwatt_logo.png': - await serveStaticFile('eachwatt_logo.png', 'image/png', res) - break - default: - res.writeHead(404) - res.end('Not found') - break + // "Convert" to file path + let filePath + if (!reqUrl || reqUrl === '/') { + filePath = '/index.html' + } else { + filePath = reqUrl } -} -const resolveFilePath = (file: string): string => { - return __dirname + '/../../webif/' + file + return basePath + filePath } -const serveStaticFile = async (file: string, contentType: string, res: ServerResponse): Promise => { - const fileContents = await fsPromisified.readFile(resolveFilePath(file)) +const serveStaticFile = async ( + filePath: string, + contentType: string | undefined, + res: ServerResponse, +): Promise => { + const fileContents = await fsPromisified.readFile(filePath) + + if (contentType !== undefined) { + res.setHeader('Content-Type', contentType) + } - res.setHeader('Content-Type', contentType) res.writeHead(200) res.end(fileContents) }