UNPKG

easy-jsx-html-engine

Version:

Dead simple HTML engine using JSX syntax.

61 lines 2.44 kB
import { loaderScript, ResolvedTemplate as DefaultResolvedTemplate, } from "./suspense"; function noop() { } export function renderToStream(body, options) { const waitUntil = (typeof options === "object" ? options.waitUntil : options) ?? noop; const ResolvedTemplate = (typeof options === "object" && options.ResolvedTemplate) || DefaultResolvedTemplate; const rid = globalThis.SUSPENSE_ROOT.counter++; const requestData = { children: [] }; SUSPENSE_ROOT.requests.set(rid, requestData); if (typeof body === "function") { try { body = body(rid); } catch (error) { // Avoids memory leaks by removing the request data SUSPENSE_ROOT.requests.delete(rid); throw error; } } // No suspense was used, just return the HTML if (!requestData || !requestData.children.length) { SUSPENSE_ROOT.requests.delete(rid); return Promise.resolve(body).then((elem) => elem.toHTML()); } const { readable, writable } = new TransformStream(); waitUntil(sendToStream(writable, body, requestData, ResolvedTemplate).finally(() => { // Removes the current state SUSPENSE_ROOT.requests.delete(rid); })); return readable; } async function sendToStream(writable, layout, requestData, ResolvedTemplate) { const w = writable.getWriter(); try { const encoder = new TextEncoder(); await w.write(encoder.encode((await layout).toHTML())); if (!requestData.children.length) { return; } await w.write(encoder.encode(loaderScript)); let count = 0; const children = []; while (count < requestData.children.length || children.length) { for (; count < requestData.children.length; count++) { children.push([requestData.children[count], count]); } const [html, id] = await Promise.race(children.map(async ([e, i]) => [await e, i])); await w.write(encoder.encode((await ResolvedTemplate({ id, children: html, })).toHTML())); children.splice(children.findIndex(([, i]) => i === id), 1); } await w.write(encoder.encode("<script data-suspense>suspense.cleanup()</script>")); } finally { await w.close(); w.releaseLock(); } } //# sourceMappingURL=stream-webapi.js.map