easy-jsx-html-engine
Version:
Dead simple HTML engine using JSX syntax.
76 lines (74 loc) • 2.19 kB
JavaScript
import { ErrorBoundary } from "./error-boundary";
import { isPromise } from "./util";
import { createElement, dangerouslyPreventEscaping, Fragment, } from "./create-element";
if (!globalThis.SUSPENSE_ROOT) {
globalThis.SUSPENSE_ROOT = {
requests: new Map(),
counter: 1,
};
}
export const loaderScript = `
<script data-suspense>
${`(function(
d=document,
q=d.querySelector.bind(d),
m="[data-suspense]",
a=m+"#s\\\\:",
){
window.suspense = {
tp(n) {
var x = q("div"+a+"p"+n),
y = q("template"+a+"r"+n),
z = d.importNode(y.content, true),
b = Array.from(z.childNodes);
x.replaceWith(z);
y.remove();
q("script"+a+"s"+n).remove();
return b;
},
cleanup() {
d.querySelectorAll(m).forEach(e => e.remove());
delete window.suspense;
}
};
})()`
// poor-man's minify
.replace(/(?<!var|return|delete)\s+|[,;]\s*(?=\)|\})/g, "")}
</script>
`;
export function Suspense(props) {
const elem = ErrorBoundary({
catch: props.catch,
children: [props.children],
});
if (!isPromise(elem) ||
!props.rid ||
!SUSPENSE_ROOT.requests.has(props.rid)) {
// just pretend this suspense is an error boundary
return elem;
}
const data = SUSPENSE_ROOT.requests.get(props.rid);
const id = data.children.length;
data.children.push(Promise.resolve(elem));
return createElement("div", {
"data-suspense": true,
id: `s:p${id}`,
}, props.fallback);
}
export function CreateResolvedTemplate({ resolvedScriptMiddleware, } = {}) {
return function ResolvedTemplate({ id, children }) {
let script = `suspense.tp(${id})`;
if (resolvedScriptMiddleware) {
script = resolvedScriptMiddleware(script);
}
return createElement(Fragment, {}, createElement("template", {
"data-suspense": true,
id: `s:r${id}`,
}, children), createElement("script", {
"data-suspense": true,
id: `s:s${id}`,
}, dangerouslyPreventEscaping(script)));
};
}
export const ResolvedTemplate = CreateResolvedTemplate();
//# sourceMappingURL=suspense.js.map