UNPKG

astro

Version:

Astro is a modern site builder with web best practices, performance, and DX front-of-mind.

84 lines (83 loc) 2.68 kB
import { markHTMLString } from "../../escape.js"; import { isPromise } from "../../util.js"; import { renderChild } from "../any.js"; import { createBufferedRenderer } from "../util.js"; const renderTemplateResultSym = /* @__PURE__ */ 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 { htmlParts, expressions } = this; for (let i = 0; i < htmlParts.length; i++) { const html = htmlParts[i]; if (html) { destination.write(markHTMLString(html)); } if (i >= expressions.length) break; const exp = expressions[i]; if (!(exp || exp === 0)) continue; const result = renderChild(destination, exp); if (isPromise(result)) { const startIdx = i + 1; const remaining = expressions.length - startIdx; const flushers = new Array(remaining); for (let j = 0; j < remaining; j++) { const rExp = expressions[startIdx + j]; flushers[j] = createBufferedRenderer(destination, (bufferDestination) => { if (rExp || rExp === 0) { return renderChild(bufferDestination, rExp); } }); } return result.then(() => { let k = 0; const iterate = () => { while (k < flushers.length) { const rHtml = htmlParts[startIdx + k]; if (rHtml) { destination.write(markHTMLString(rHtml)); } const flushResult = flushers[k++].flush(); if (isPromise(flushResult)) { return flushResult.then(iterate); } } const lastHtml = htmlParts[htmlParts.length - 1]; if (lastHtml) { destination.write(markHTMLString(lastHtml)); } }; 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 };