78 lines
2.1 KiB
TypeScript
78 lines
2.1 KiB
TypeScript
// / <reference path="./types/jsx.d.ts" />
|
|
import { Pico } from "./deps.ts";
|
|
|
|
import config from "./config.ts";
|
|
|
|
const React = {
|
|
createElement: Pico.h.bind(Pico),
|
|
};
|
|
|
|
class StringReader implements Deno.Reader {
|
|
private data: Uint8Array;
|
|
private offset = 0;
|
|
constructor(text: string) {
|
|
this.data = new TextEncoder().encode(text);
|
|
}
|
|
|
|
async read(p: Uint8Array): Promise<number | null> {
|
|
if (this.offset >= this.data.byteLength) return null;
|
|
|
|
const forLength = Math.min(p.length, this.data.length - this.offset);
|
|
|
|
for (let i = 0; i < forLength; i++) {
|
|
p[i] = this.data[i + this.offset];
|
|
}
|
|
|
|
this.offset += forLength;
|
|
|
|
return forLength;
|
|
}
|
|
}
|
|
|
|
type ELM = any;
|
|
|
|
type Component = () => ELM;
|
|
|
|
const componentCache = new Map<string, Component>();
|
|
|
|
async function loadComponent(name: string) {
|
|
let mod = componentCache.get(name);
|
|
if (!mod || config.general.dev) {
|
|
mod = (await import(`./views/${name}.tsx`)).default;
|
|
if (!mod) throw new Error("Invalid component " + name);
|
|
componentCache.set(name, mod);
|
|
}
|
|
|
|
return mod;
|
|
}
|
|
|
|
Promise.resolve().then(async () => {
|
|
console.log("[PRECACHE] Start loading pages");
|
|
await loadComponent("index");
|
|
await loadComponent("package");
|
|
await loadComponent("browse_folder");
|
|
await loadComponent("browse_file");
|
|
console.log("[PRECACHE] Finished loading pages");
|
|
});
|
|
|
|
// import index from "./views/index.tsx";
|
|
// componentCache.set("index", index as Component);
|
|
// import pkg from "./views/package.tsx";
|
|
// componentCache.set("package", pkg as Component);
|
|
// import browse_folder from "./views/browse_folder.tsx";
|
|
// componentCache.set("browse_folder", browse_folder as Component);
|
|
// import browse_file from "./views/browse_file.tsx";
|
|
// componentCache.set("browse_file", browse_file as Component);
|
|
|
|
export default async function render(
|
|
name: string,
|
|
data: any
|
|
): Promise<Deno.Reader> {
|
|
const Component = await loadComponent(name);
|
|
|
|
//@ts-ignore
|
|
const res = await Pico.renderSSR(<Component {...data} />);
|
|
|
|
return new StringReader("<!DOCTYPE html>\n" + res);
|
|
}
|