astro
Version:
Astro is a modern site builder with web best practices, performance, and DX front-of-mind.
65 lines (64 loc) • 1.81 kB
JavaScript
import { markHTMLString } from "../../escape.js";
import { isPromise } from "../../util.js";
import { renderChild } from "../any.js";
import { createBufferedRenderer } from "../util.js";
const renderTemplateResultSym = Symbol.for("astro.renderTemplateResult");
class RenderTemplateResult {
[renderTemplateResultSym] = true;
htmlParts;
expressions;
error;
constructor(htmlParts, expressions) {
this.htmlParts = htmlParts;
this.error = void 0;
this.expressions = expressions.map((expression) => {
if (isPromise(expression)) {
return Promise.resolve(expression).catch((err) => {
if (!this.error) {
this.error = err;
throw err;
}
});
}
return expression;
});
}
render(destination) {
const flushers = this.expressions.map((exp) => {
return createBufferedRenderer(destination, (bufferDestination) => {
if (exp || exp === 0) {
return renderChild(bufferDestination, exp);
}
});
});
let i = 0;
const iterate = () => {
while (i < this.htmlParts.length) {
const html = this.htmlParts[i];
const flusher = flushers[i];
i++;
if (html) {
destination.write(markHTMLString(html));
}
if (flusher) {
const result = flusher.flush();
if (isPromise(result)) {
return result.then(iterate);
}
}
}
};
return iterate();
}
}
function isRenderTemplateResult(obj) {
return typeof obj === "object" && obj !== null && !!obj[renderTemplateResultSym];
}
function renderTemplate(htmlParts, ...expressions) {
return new RenderTemplateResult(htmlParts, expressions);
}
export {
RenderTemplateResult,
isRenderTemplateResult,
renderTemplate
};