import Fastify from "fastify"; import { restartable } from "@fastify/restartable"; import FastifyStatic from "@fastify/static"; import path from "path"; import fs from "fs"; import chokidar from "chokidar"; import nunjucks from "nunjucks"; export const description = "Runs your app."; export const options = []; export const required = []; let CONFIGURED = false; // nunjucks does it's own reload so let it do that nunjucks.configure("templates", { watch: true }); const configure = async (fastify, opts) => { const app = 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 control_mod = await import(`../controllers/todo.js?update=${new Date()}`); // 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 for(let [url, controller] of Object.entries(control_mod.default)) { const handler = new controller(); app.get(`/${url}`, 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" }); // 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 { 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); } }