Skip to content

Commit

Permalink
frontend: add handlebars support
Browse files Browse the repository at this point in the history
  • Loading branch information
terrablue committed Sep 3, 2023
1 parent 84ccaa8 commit 9c9caf0
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 6 deletions.
5 changes: 5 additions & 0 deletions packages/frontend/src/frontends/common/exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,10 @@
export {default as register} from "./register.js";
// directly used by vue
export {default as compile} from "./compile.js";

// directly used by handlebars
export {default as load} from "./load.js";

// generally used
export {default as module} from "./module.js";
export {default as peers} from "./peers.js";
6 changes: 6 additions & 0 deletions packages/frontend/src/frontends/common/load.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import {tryreturn} from "runtime-compat/async";
import errors from "./errors.js";

export default async path =>
tryreturn(_ => import(`${path}.js`))
.orelse(_ => errors.MissingComponent.throw(path.name, path));
7 changes: 1 addition & 6 deletions packages/frontend/src/frontends/common/register.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {tryreturn} from "runtime-compat/async";
import errors from "./errors.js";

const load = async path =>
tryreturn(_ => import(`${path}.js`))
.orelse(_ => errors.MissingComponent.throw(path.name, path));
import load from "./load.js";

export default ({app, rootname, ...rest}) => {
const {config: {location}} = app;
Expand Down
1 change: 1 addition & 0 deletions packages/frontend/src/frontends/exports.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export {default as react} from "./react/module.js";
export {default as solid} from "./solid/module.js";
export {default as svelte} from "./svelte/module.js";
export {default as vue} from "./vue/module.js";
export {default as handlebars} from "./handlebars/module.js";
10 changes: 10 additions & 0 deletions packages/frontend/src/frontends/handlebars/imports.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import handlebars from "handlebars";
import runtime from "handlebars/runtime.js";

export const compile = {
server(text) {
return `export default ${handlebars.precompile(text)}`;
},
};

export const render = precompiled => runtime.template(precompiled);
61 changes: 61 additions & 0 deletions packages/frontend/src/frontends/handlebars/module.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import {Response, Status} from "runtime-compat/http";
import {filter} from "runtime-compat/object";
import {compile, peers, load} from "../common/exports.js";

const handler = ({directory, render}) =>
(name, props = {}, {status = Status.OK, page} = {}) => async app => {
const components = app.runpath(app.config.location.server, directory);
const {default : component} = await load(components.join(name));

const body = render(component)(props);

const headers = await app.headers();

return new Response(await app.render({body, page}), {status, headers});
};

const name = "handlebars";
const dependencies = ["handlebars"];
const default_extension = "hbs";
const on = filter(peers, ([key]) => dependencies.includes(key));

export default ({
directory,
extension = default_extension,
} = {}) => {
const rootname = name;
let imports = {};

return {
name: `primate:${name}`,
async init(app, next) {
await app.depend(on, `frontend:${name}`);

imports = await import("./imports.js");

return next(app);
},
register(app, next) {
const {config} = app;

app.register(extension, handler({
directory: directory ?? config.location.components,
render: imports.render,
}));

return next(app);
},
async compile(app, next) {
await compile({
app,
directory: directory ?? app.config.location.components,
extension,
rootname,
compile: imports.compile.server,
});

return next(app);
},
};
};

0 comments on commit 9c9caf0

Please sign in to comment.