UNPKG

fluxel

Version:

An ultra-lightweight, high-performance library for efficient DOM building and dynamic web UIs

96 lines (95 loc) 3.24 kB
import { JSDOM } from "jsdom"; import ensureNode from "../jsxEnsureNode.js"; import Fluxel from "../index.js"; export default function renderToString(renderer, options = {}) { const metadata = options === null || options === void 0 ? void 0 : options.metadata; const reactive = !!(options === null || options === void 0 ? void 0 : options.reactive); const query = (options === null || options === void 0 ? void 0 : options.search) || ""; const hash = (options === null || options === void 0 ? void 0 : options.hash) || ""; const url = `http://localhost.dummy${(options === null || options === void 0 ? void 0 : options.pathname) || "/"}${query ? `?${query}` : ""}${hash ? `#${hash}` : ""}`; const jsdom = new JSDOM("", { url }); const renderingContext = { createElementCount: 0 }; const document = new Proxy(jsdom.window.document, { get (target, p) { if (p === "createElement") { return (tagName, props)=>{ const element = target.createElement(tagName, props); if (reactive) { element.dataset["fluxelEid"] = (renderingContext.createElementCount++).toString(); } return element; }; } return target[p]; } }); Object.defineProperties(global, { Node: { get: ()=>jsdom.window.Node, configurable: true, enumerable: false }, HTMLElement: { get: ()=>jsdom.window.HTMLElement, configurable: true, enumerable: false }, document: { get: ()=>document, configurable: true, enumerable: false }, location: { get: ()=>jsdom.window.location, configurable: true, enumerable: false } }); const fsc = Fluxel.forwardStyleCache; Fluxel.forwardStyleCache = []; function nodeToString(node) { if ("dataset" in node && node.dataset instanceof jsdom.window.DOMStringMap) { node.dataset.fluxelSsr = "true"; node.dataset.fluxelMetadata = metadata || ""; if (reactive) { node.dataset.fluxelECount = renderingContext.createElementCount.toString(); } } const container = jsdom.window.document.createElement("div"); container.appendChild(node); return container.innerHTML; } const node = ensureNode(renderer()); const style = Fluxel.forwardStyleCache.join("\n"); Object.defineProperties(global, { Node: { value: null, configurable: true, enumerable: false }, HTMLElement: { value: null, configurable: true, enumerable: false }, document: { value: null, configurable: true, enumerable: false }, location: { value: null, configurable: true, enumerable: false } }); Fluxel.forwardStyleCache = fsc; return { dom: nodeToString(node), style }; }