diff --git a/commands/app.js b/commands/app.js index c531244..7c919f2 100644 --- a/commands/app.js +++ b/commands/app.js @@ -1,8 +1,9 @@ import Fastify from "fastify"; +import { restartable } from "@fastify/restartable"; import FastifyStatic from "@fastify/static"; import path from "path"; -import { ToDo } from "../lib/models.js"; import fs from "fs"; +import chokidar from "chokidar"; import nunjucks from "nunjucks"; export const description = "Runs your app."; @@ -11,39 +12,72 @@ export const options = []; export const required = []; -const fastify = Fastify({ - logger: true -}); +let CONFIGURED = false; +// nunjucks does it's own reload so let it do that +nunjucks.configure("templates", { watch: true }); -fastify.get("/todo", async (req, rep) => { - try { - const todo_list = await ToDo.all({}); - - // this is for exporing the problem of getting good error messages from templates - const result = nunjucks.render("templates/todo.html", - {todo_list, your_todos: "Your Todos"}); - - rep.code(200) - .type("text/html") - .send(result); - } catch(error) { - console.error(error); - console.error(error.stack); - console.error(error.source); - } -}); +const configure = async (fastify, opts) => { + + // MAGIC: this is how you trick the importer to reload modules + // that have changed. Since it uses a URL you can add a query + // to it, but that isn't parsed as the file. Using a date then + // tags the module as being "new" when it's still the same file + // TODO: maybe use fs timestamps instead? + // BUG: sometimes reload is too fast for vim and crashes + const controller = await import(`../controllers/todo.js?update=${new Date()}`); + + const handler = new controller.Todo(); + const app = fastify(opts); + + // this is a sample that uses the handler we dynamic load + // to handle the /todo but not sure how to work the actual + // URL mappings for it. Also not sure about using classes + app.get("/todo", async (req, rep) => { + try { + await handler.get(req, rep); + } catch(error) { + console.error(error); + console.error(error.stack); + console.error(error.source); + } + }); + + app.register(FastifyStatic, { + root: path.join(path.resolve("."), 'static'), + prefix: '/', // optional: default '/' + constraints: {}, // optional: default {} + index: "index.html" + }); -fastify.register(FastifyStatic, { - root: path.join(path.resolve("."), 'static'), - prefix: '/', // optional: default '/' - constraints: {}, // optional: default {} - index: "index.html" -}) + // this is from fastify/restartable + app.addHook('onClose', async () => { + if(!app.closingRestartable) { + console.log('closing the app because of restart') + } else{ + console.log('closing the app because server is stopping') + } + }) + + return app; +} + +const app = await await restartable(configure, { logger: true}); +const host = await app.listen({port: 3000}); + +const reload = () => { + if(CONFIGURED) { + app.restart(); + } +} export const main = async (arg, opts) => { try { - await fastify.listen({port: 3000}); + chokidar.watch(["lib","commands","controllers","static","migrations","tests"]) + .on("add", path => reload()) + .on("change", path => reload()) + .on("unlink", path => reload()) + .on("ready", () => CONFIGURED = true); } catch(err) { fastify.log.error(err); process.exit(1); diff --git a/package-lock.json b/package-lock.json index 9cda522..efe0aaf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,10 @@ }, "bin": { "bando": "bando.js" + }, + "devDependencies": { + "@fastify/restartable": "github:fastify/restartable", + "chokidar": "^3.6.0" } }, "node_modules/@fastify/accept-negotiator": { @@ -77,6 +81,15 @@ "helmet": "^7.0.0" } }, + "node_modules/@fastify/restartable": { + "version": "2.2.0", + "resolved": "git+ssh://git@github.com/fastify/restartable.git#cd9c628df92283b8da2e5cff102d645c4c154a1b", + "dev": true, + "license": "MIT", + "dependencies": { + "fastify": "^4.16.3" + } + }, "node_modules/@fastify/send": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@fastify/send/-/send-2.1.0.tgz", @@ -346,6 +359,19 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "devOptional": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", @@ -431,6 +457,15 @@ } ] }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, "node_modules/bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", @@ -610,6 +645,30 @@ "node": ">=8" } }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "devOptional": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", @@ -1052,6 +1111,20 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "optional": true }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -1353,6 +1426,18 @@ "node": ">= 0.10" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "devOptional": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-core-module": { "version": "2.13.1", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", @@ -1945,6 +2030,15 @@ "node": ">=6" } }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "devOptional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/npmlog": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", @@ -2277,6 +2371,18 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "devOptional": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/real-require": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", diff --git a/package.json b/package.json index f6dced1..d2046a7 100644 --- a/package.json +++ b/package.json @@ -18,5 +18,9 @@ "knex-paginate": "^3.1.1", "nunjucks": "^3.2.4", "sqlite3": "^5.1.7" + }, + "devDependencies": { + "@fastify/restartable": "github:fastify/restartable", + "chokidar": "^3.6.0" } } diff --git a/templates/header.html b/templates/header.html index f4dd15f..ea85462 100644 --- a/templates/header.html +++ b/templates/header.html @@ -3,7 +3,6 @@
-Welcome {{ name }}, here's your TODOs
+ +