Skip to content

Commit

Permalink
a more complete build manifest
Browse files Browse the repository at this point in the history
  • Loading branch information
Fil committed Oct 23, 2024
1 parent 1ffe346 commit e9e2758
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 24 deletions.
36 changes: 30 additions & 6 deletions src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {existsSync} from "node:fs";
import {copyFile, readFile, rm, stat, writeFile} from "node:fs/promises";
import {basename, dirname, extname, join} from "node:path/posix";
import type {Config} from "./config.js";
import {CliError} from "./error.js";
import {CliError, enoent} from "./error.js";
import {getClientPath, prepareOutput} from "./files.js";
import {findModule, getModuleHash, readJavaScript} from "./javascript/module.js";
import {transpileModule} from "./javascript/transpile.js";
Expand All @@ -16,6 +16,7 @@ import type {Resolvers} from "./resolvers.js";
import {getModuleResolvers, getResolvers} from "./resolvers.js";
import {resolveStylesheetPath} from "./resolvers.js";
import {bundleStyles, rollupClient} from "./rollup.js";
import type {Params} from "./route.js";
import {searchIndex} from "./search.js";
import {Telemetry} from "./telemetry.js";
import {tree} from "./tree.js";
Expand Down Expand Up @@ -74,6 +75,23 @@ export async function build(
let assetCount = 0;
let pageCount = 0;
const pagePaths = new Set<string>();

const {title} = config;
const buildManifest: BuildManifest = {...(title && {title}), pages: [], modules: [], files: []};
const addToManifest = (
type: string,
file: string,
{title, path, params}: {title?: string | null; path?: string; params?: Params}
) => {
const source = path == null || path === file.slice(1) ? null : join("/", path);
buildManifest[type].push({
path: config.normalizePath(file),
...(title != null && {title}),
...(source && {source}),
...(params && {params})
});
};

for await (const path of config.paths()) {
effects.output.write(`${faint("load")} ${path} `);
const start = performance.now();
Expand All @@ -95,6 +113,7 @@ export async function build(
}
const file = loaders.find(path);
if (file) {
addToManifest("files", path, file);
effects.output.write(`${faint("copy")} ${join(root, path)} ${faint("→")} `);
const sourcePath = join(root, await file.load({useStale: true}, effects));
await effects.copyFile(sourcePath, path);
Expand Down Expand Up @@ -192,7 +211,11 @@ export async function build(
// Copy over referenced files, accumulating hashed aliases.
for (const file of files) {
effects.output.write(`${faint("copy")} ${join(root, file)} ${faint("→")} `);
const sourcePath = join(root, await loaders.loadFile(join("/", file), {useStale: true}, effects));
const path = join("/", file);
const loader = loaders.find(path);
if (!loader) throw enoent(path);
addToManifest("files", path, loader);
const sourcePath = join(root, await loader.load({useStale: true}, effects));
const contents = await readFile(sourcePath);
const hash = createHash("sha256").update(contents).digest("hex").slice(0, 8);
const alias = applyHash(join("/_file", file), hash);
Expand Down Expand Up @@ -255,6 +278,7 @@ export async function build(
if (!module) throw new Error(`import not found: ${path}`);
const sourcePath = join(root, module.path);
const importPath = join("_import", module.path);
addToManifest("modules", path, module);
effects.output.write(`${faint("copy")} ${sourcePath} ${faint("→")} `);
const resolveImport = loaders.getModuleResolver(path);
const input = await readJavaScript(sourcePath);
Expand Down Expand Up @@ -320,15 +344,13 @@ export async function build(
}

// Render pages!
const buildManifest: BuildManifest = {pages: []};
if (config.title) buildManifest.title = config.title;
for (const [path, output] of outputs) {
effects.output.write(`${faint("render")} ${path} ${faint("→")} `);
if (output.type === "page") {
const {page, resolvers} = output;
const html = await renderPage(page, {...config, path, resolvers});
await effects.writeFile(`${path}.html`, html);
buildManifest.pages.push({path: config.normalizePath(path), title: page.title});
addToManifest("pages", path, page);
} else {
const {resolvers} = output;
const source = await renderModule(root, path, resolvers);
Expand Down Expand Up @@ -489,5 +511,7 @@ export class FileBuildEffects implements BuildEffects {

export interface BuildManifest {
title?: string;
pages: {path: string; title: string | null}[];
pages: {path: string; title?: string | null; source?: string; params?: Params}[];
modules: {path: string; source?: string; params?: Params}[];
files: {path: string; source?: string; params?: Params}[];
}
10 changes: 0 additions & 10 deletions src/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,6 @@ export class LoaderResolver {
);
}

/**
* Loads the file at the specified path, returning a promise to the path to
* the (possibly generated) file relative to the source root.
*/
async loadFile(path: string, options?: LoadOptions, effects?: LoadEffects): Promise<string> {
const loader = this.find(path);
if (!loader) throw enoent(path);
return await loader.load(options, effects);
}

/**
* Loads the page at the specified path, returning a promise to the parsed
* page object.
Expand Down
4 changes: 2 additions & 2 deletions src/markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export interface MarkdownPage {
data: FrontMatter;
style: string | null;
code: MarkdownCode[];
source?: string;
path?: string;
params?: Params;
}

Expand Down Expand Up @@ -260,7 +260,7 @@ export function parseMarkdown(input: string, options: ParseOptions): MarkdownPag
title,
style: getStyle(data, options),
code,
source,
path: source,
params
};
}
Expand Down
5 changes: 4 additions & 1 deletion src/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,10 @@ export class PreviewServer {
}
throw enoent(path);
} else if (pathname.startsWith("/_file/")) {
send(req, await loaders.loadFile(pathname.slice("/_file".length)), {root}).pipe(res);
const path = pathname.slice("/_file".length);
const loader = loaders.find(path);
if (!loader) throw enoent(path);
send(req, await loader.load(), {root}).pipe(res);
} else {
if ((pathname = normalize(pathname)).startsWith("..")) throw new Error("Invalid path: " + pathname);

Expand Down
12 changes: 7 additions & 5 deletions test/build-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,13 @@ describe("build", () => {
effects.buildManifest!.pages.sort((a, b) => ascending(a.path, b.path));
assert.deepEqual(effects.buildManifest, {
pages: [
{path: "/", title: "Hello, world!"},
{path: "/cities/", title: "Cities"},
{path: "/cities/portland", title: "Portland"},
{path: "/weather", title: "It's going to be !"}
]
{path: "/", title: "Hello, world!", source: "/index.md"},
{path: "/cities/", title: "Cities", source: "/cities/index.md"},
{path: "/cities/portland", title: "Portland", source: "/cities/portland.md"},
{path: "/weather", title: "It's going to be !", source: "/weather.md"}
],
files: [{path: "/weather.txt"}],
modules: []
});

await Promise.all([inputDir, cacheDir, outputDir].map((dir) => rm(dir, {recursive: true}))).catch(() => {});
Expand Down

0 comments on commit e9e2758

Please sign in to comment.