the asset system is reworked to support "dynamic" entries, where each entry is a separate file on disk containing the latest generation's headers+raw+gzip+zstd. when calling view.regenerate, it will look for pages that had "export const regenerate" during generation, and render those pages using the view system, but then store the results as assets instead of sending as a response. pages configured as regenerable are also bundled as views, using the non-aliasing key "page:${page.id}". this cannot alias because file paths may not contain a colon.
72 lines
1.6 KiB
TypeScript
72 lines
1.6 KiB
TypeScript
export type ScriptId = string;
|
|
|
|
export interface PageExports extends ViewExports {
|
|
regenerate?: PageRegenerateOptions;
|
|
}
|
|
export interface ViewExports {
|
|
default: render.Component;
|
|
meta: meta.Meta | ((props: { ssr: true }) => Promise<meta.Meta> | meta.Meta);
|
|
theme?: css.Theme;
|
|
layout?: Layout;
|
|
}
|
|
export interface Layout {
|
|
default: render.Component;
|
|
theme?: css.Theme;
|
|
// TODO: nested layout
|
|
}
|
|
export interface PageRegenerateOptions {
|
|
tags?: string[];
|
|
seconds?: number;
|
|
debounce?: number;
|
|
}
|
|
|
|
/**
|
|
* A filesystem object associated with some ID,
|
|
* such as a page's route to it's source file.
|
|
*/
|
|
export interface FileItem {
|
|
id: string;
|
|
file: string;
|
|
}
|
|
export interface Section {
|
|
root: string;
|
|
}
|
|
|
|
export const userData = render.userData<SitegenRender>(() => {
|
|
throw new Error("This function can only be used in a page (static or view)");
|
|
});
|
|
|
|
export interface SitegenRender {
|
|
scripts: Set<string>;
|
|
}
|
|
|
|
export function initRender(): SitegenRender {
|
|
return { scripts: new Set() };
|
|
}
|
|
|
|
/** Add a client-side script to the page. */
|
|
export function addScript(id: ScriptId | { value: ScriptId }) {
|
|
userData.get().scripts.add(typeof id === "string" ? id : id.value);
|
|
}
|
|
|
|
export function wrapDocument({
|
|
body,
|
|
head,
|
|
inlineCss,
|
|
scripts,
|
|
}: {
|
|
head: string;
|
|
body: string;
|
|
inlineCss: string;
|
|
scripts: string;
|
|
}) {
|
|
return `<!doctype html><html lang=en><head>${head}${
|
|
inlineCss ? `<style>${inlineCss}</style>` : ""
|
|
}</head><body>${body}${
|
|
scripts ? `<script>${scripts}</script>` : ""
|
|
}</body></html>`;
|
|
}
|
|
|
|
import * as render from "#engine/render";
|
|
import type * as meta from "./meta.ts";
|
|
import type * as css from "../css.ts";
|