|
|
|
@ -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({}); |
|
|
|
|
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()}`); |
|
|
|
|
|
|
|
|
|
// 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"}); |
|
|
|
|
const handler = new controller.Todo(); |
|
|
|
|
const app = fastify(opts); |
|
|
|
|
|
|
|
|
|
rep.code(200) |
|
|
|
|
.type("text/html") |
|
|
|
|
.send(result); |
|
|
|
|
// 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); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
fastify.register(FastifyStatic, { |
|
|
|
|
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 { |
|
|
|
|
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); |
|
|
|
|