Files
wow-pi/packages/wow-contexts/src/builder.ts
2026-06-09 00:39:43 +08:00

62 lines
1.6 KiB
TypeScript

import {
type ContextFileEntry,
resolveContextPath,
scanDir,
tryRead,
} from "./files";
import { resolvePaths } from "./resolver";
export interface BuildResult {
content: string | null;
loadedPaths: Map<string, string>;
}
export async function build(cwd: string): Promise<BuildResult> {
const paths = resolvePaths(cwd);
const files: ContextFileEntry[] = [];
const loadedPaths = new Map<string, string>();
for (const entry of paths) {
if (entry.endsWith("/*.md")) {
const dir = resolveContextPath(entry.slice(0, -4), cwd);
const before = files.length;
await scanDir(dir, files);
for (let index = before; index < files.length; index++) {
const file = files[index];
if (file) loadedPaths.set(file.rel, fileHash(file.content));
}
continue;
}
const abs = resolveContextPath(entry, cwd);
const before = files.length;
await tryRead(abs, entry, files);
if (files.length > before) {
const file = files[files.length - 1];
if (file) loadedPaths.set(abs, fileHash(file.content));
}
}
const nonEmpty = files.filter((file) => file.content.length > 0);
return {
content:
nonEmpty.length > 0
? nonEmpty
.map(
(file) => `<file path="${file.rel}">\n${file.content}\n</file>`,
)
.join("\n\n")
: null,
loadedPaths,
};
}
export function fileHash(content: string): string {
let hash = 0;
for (let index = 0; index < content.length; index++) {
hash = ((hash << 5) - hash + content.charCodeAt(index)) | 0;
}
return hash.toString(16);
}