import{Path}from"utils/path";import{sourceDir}from"../constants";importtype{Dependency,PageSyntax}from"../types/html";// Support the Component interface.// Resolves dependencies automatically and allows partial page refresh./** * Convert a Path-specified dependency into an HTML tag. * Usually used to pull them into frontmatter. */constgetDependency=(path: Path): PageSyntax=>{constextension=path.extension;switch(extension){case"js":
return["script",{src: path.toString(),type: "module"}];case"ts":
returngetDependency(path.replaceExtension("js"));case"css":
return["link",{rel: "stylesheet",href: path.toString()}];case"scss":
returngetDependency(path.replaceExtension("css"));default:
thrownewError(`Unknown extension: ${extension}`);}};/** * Construct a dependency header with a list of source configurations. */constmakeDependencyHeader=(dependencies: Dependency[]): PageSyntax=>{if(dependencies.length===0){returnnull;}returndependencies.map(({ src })=>{returngetDependency(Path.create(src));});};constcomponentCache: {[key: string]: Function}={};/** * Require a component from disk. * @param name name of the component */constrequireComponent=(name: string)=>{constmaybeComponent=componentCache[name];if(maybeComponent){returnmaybeComponent;}constrootPath=sourceDir;constcomponentFunction=require(`${rootPath}/components/${name}/${name}.js`).default;componentCache[name]=componentFunction;returncomponentFunction;};/** * Render a JS component. * @param name the name of the component * @param args arguments to pass to that component. * @returns the component */constcomponent=(name: string,args?: Object): {dependsOn: Dependency[];body: PageSyntax}=>{constcomponentFunction=requireComponent(name);const{ dependsOn, body }=componentFunction(args);constcomponentWithDependencies=[makeDependencyHeader(dependsOn),body];return{ dependsOn,body: componentWithDependencies};};export{component};