1export function virtualFiles(
2 map: Record<
3 string,
4 | string
5 | esbuild.OnLoadResult
6 | (() => Awaitable<string | esbuild.OnLoadResult>)
7 >,
8) {
9 return {
10 name: "clover vfs",
11 setup(b) {
12 b.onResolve(
13 {
14 filter: new RegExp(
15 `^(?:${
16 Object.keys(map).map((file) => string.escapeRegExp(file)).join(
17 "|",
18 )
19 })\$`,
20 ),
21 },
22 ({ path }) => ({ path, namespace: "vfs" }),
23 );
24 b.onLoad(
25 { filter: /./, namespace: "vfs" },
26 async ({ path }) => {
27 let entry = map[path];
28 if (typeof entry === "function") entry = await entry();
29 return ({
30 resolveDir: ".",
31 loader: "ts",
32 ...typeof entry === "string" ? { contents: entry } : entry,
33 });
34 },
35 );
36 },
37 } satisfies esbuild.Plugin;
38}
39
40export function banFiles(
41 files: string[],
42) {
43 return {
44 name: "clover vfs",
45 setup(b) {
46 b.onResolve(
47 {
48 filter: new RegExp(
49 `^(?:${files.map((file) => string.escapeRegExp(file)).join("|")})\$`,
50 ),
51 },
52 ({ path, importer }) => {
53 throw new Error(
54 `Loading ${path} (from ${importer}) is banned!`,
55 );
56 },
57 );
58 },
59 } satisfies esbuild.Plugin;
60}
61
62export function markoViaBuildCache(): esbuild.Plugin {
63 return {
64 name: "marko via build cache",
65 setup(b) {
66 b.onLoad(
67 { filter: /\.marko$|\.mdo$/ },
68 async ({ path: file }) => {
69 const cacheEntry = markoCache.get(file);
70 if (!cacheEntry) {
71 if (!fs.existsSync(file)) {
72 console.warn(`File does not exist: ${file}`);
73 }
74 throw new Error("Marko file not in cache: " + file);
75 }
76 return ({
77 loader: "ts",
78 contents: cacheEntry.src,
79 resolveDir: path.dirname(file),
80 });
81 },
82 );
83 },
84 };
85}
86
87export function isIgnoredSource(source: string) {
88 return source.includes("<define:")
89 || source.startsWith("vfs:")
90 || source.startsWith("dropped:")
91 || source.includes("node_modules");
92}
93
94import * as fs from "#sitegen/fs";
95import * as string from "@clo/lib/string";
96import * as esbuild from "esbuild";
97import * as path from "node:path";
98import * as hot from "./hot.ts";
99import { markoCache } from "./marko.ts";