From 507257ef238fa59687d33893596539a1ee546426 Mon Sep 17 00:00:00 2001 From: Hayleigh Thompson Date: Wed, 6 Dec 2023 22:01:42 +0000 Subject: :sparkles: Create a simple preview server for trying out lustre. --- src/http.ffi.mjs | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/http_ffi.erl | 76 ++++++++++++++++++++++++++++++++++++++++++++ src/lustre/try.gleam | 7 ++++ 3 files changed, 173 insertions(+) create mode 100644 src/http.ffi.mjs create mode 100644 src/http_ffi.erl create mode 100644 src/lustre/try.gleam diff --git a/src/http.ffi.mjs b/src/http.ffi.mjs new file mode 100644 index 0000000..56fd950 --- /dev/null +++ b/src/http.ffi.mjs @@ -0,0 +1,90 @@ +import { readFileSync } from "node:fs"; +import * as Fs from "node:fs/promises"; +import * as Http from "node:http"; +import * as Path from "node:path"; +import * as Process from "node:process"; + +const cwd = Process.cwd(); +const root = Path.join(cwd, "build/dev/javascript"); +const toml = readFileSync(Path.join(cwd, "gleam.toml"), "utf-8"); +const name = toml.match(/name *= *"(.+)"/)[1]; + +const html = ` + + + + + Lustre preview server + + + + +
+ +`; + +const server = Http.createServer((req, res) => { + switch (true) { + case req.url === "/": { + res.setHeader("Content-Type", "text/html"); + res.statusCode = 200; + res.end(html); + + break; + } + + case req.url.endsWith(".js"): + case req.url.endsWith(".mjs"): { + Fs.readFile(Path.join(root, req.url), "utf-8") + .then((src) => { + res.setHeader("Content-Type", "application/javascript"); + res.statusCode = 200; + res.end(src); + }) + .catch((err) => { + res.statusCode = 404; + res.end(err); + }); + + break; + } + + case req.url.endsWith(".css"): { + Fs.readFile(Path.join(root, req.url), "utf-8") + .then((src) => { + res.setHeader("Content-Type", "text/css"); + res.statusCode = 200; + res.end(src); + }) + .catch((err) => { + res.statusCode = 404; + res.end(err); + }); + + break; + } + + default: { + Fs.readFile(Path.join(root, req.url), "utf-8") + .then((src) => { + res.setHeader("Content-Type", "text/plain"); + res.statusCode = 200; + res.end(src); + }) + .catch((err) => { + res.statusCode = 404; + res.end(err); + }); + } + } +}); + +export const serve = (port) => { + server.listen(port, "localhost"); +}; diff --git a/src/http_ffi.erl b/src/http_ffi.erl new file mode 100644 index 0000000..507ee06 --- /dev/null +++ b/src/http_ffi.erl @@ -0,0 +1,76 @@ +-module(http_ffi). +-export([serve/1]). + +serve(Port) -> + {ok, Pattern} = re:compile("name *= *\"(?.+)\""), + {ok, Toml} = file:read_file("gleam.toml"), + {match, [Name]} = re:run(Toml, Pattern, [{capture, all_names, binary}]), + + Html = + << + "\n" + "\n" + "\n" + " \n" + " \n" + " Lustre preview server\n" + "\n" + " \n" + "\n" + "\n" + "
\n" + "\n" + "" + >>, + + file:write_file("build/dev/javascript/index.html", Html), + + AbsPath = + string:trim( + filename:absname("build/dev/javascript"), trailing, "/." + ), + + inets:start(), + Address = {127, 0, 0, 1}, + + {ok, Pid} = + httpd:start_service([ + {bind_address, Address}, + {document_root, AbsPath}, + {server_root, AbsPath}, + {directory_index, ["index.html"]}, + {server_name, "localhost"}, + {port, Port}, + {default_type, "text/html"}, + {mime_types, mime_types()}, + {modules, [mod_alias, mod_dir, mod_get]} + ]), + + receive + {From, shutdown} -> + ok = httpd:stop_service(Pid), + From ! done + end. + +mime_types() -> + [ + {"html", "text/html"}, + {"htm", "text/html"}, + {"js", "text/javascript"}, + {"mjs", "text/javascript"}, + {"css", "text/css"}, + {"gif", "image/gif"}, + {"jpg", "image/jpeg"}, + {"jpeg", "image/jpeg"}, + {"png", "image/png"} + ]. diff --git a/src/lustre/try.gleam b/src/lustre/try.gleam new file mode 100644 index 0000000..5984f30 --- /dev/null +++ b/src/lustre/try.gleam @@ -0,0 +1,7 @@ +pub fn main() { + serve(1234) +} + +@external(erlang, "http_ffi", "serve") +@external(javascript, "../http.ffi.mjs", "serve") +fn serve(port: Int) -> Nil -- cgit v1.2.3