woby
Version:
A high-performance framework with fine-grained observable/signal-based reactivity for building rich applications.
80 lines (79 loc) • 2.89 kB
JavaScript
;
const setters = require("./setters-CyO2VUT6.cjs");
const root = require("./root-D1a_tPqg.cjs");
const merge_style = require("./merge_style-DkxC2kon.cjs");
const render = (child, parent) => {
if (!parent || !(parent instanceof HTMLElement)) throw new Error("Invalid parent node");
parent.textContent = "";
return root.root((stack, dispose) => {
setters.setChild(parent, child, setters.FragmentUtils.make(), stack);
return () => {
dispose(stack);
parent.textContent = "";
};
});
};
const Portal = ({ when = true, mount, wrapper, children }) => {
const portal = setters.get(wrapper) || setters.createHTMLNode("div");
if (!(portal instanceof HTMLElement)) throw new Error("Invalid wrapper node");
const condition = merge_style.boolean(when);
const stack = new Error();
setters.useRenderEffect(() => {
if (!setters.get(condition)) return;
const parent = setters.get(mount) || document.body;
if (!(parent instanceof Element)) throw new Error("Invalid mount node");
parent.insertBefore(portal, null);
return () => {
parent.removeChild(portal);
};
}, stack);
setters.useRenderEffect(() => {
if (!setters.get(condition)) return;
return render(children, portal);
}, stack);
return setters.assign(() => setters.get(condition) || children, { metadata: { portal } });
};
const SuspenseCollector = {
create: () => {
const parent = SuspenseCollector.get();
const suspenses = merge_style.observable([]);
const active = merge_style.memo(() => suspenses().some((suspense) => suspense.active()));
const register = (suspense) => {
parent == null ? void 0 : parent.register(suspense);
suspenses((prev) => [...prev, suspense]);
};
const unregister = (suspense) => {
parent == null ? void 0 : parent.unregister(suspense);
suspenses((prev) => prev.filter((other) => other !== suspense));
};
const data = { suspenses, active, register, unregister };
return data;
},
get: () => {
return setters.context(setters.SYMBOL_SUSPENSE_COLLECTOR);
},
wrap: (fn) => {
const data = SuspenseCollector.create();
return setters.context({ [setters.SYMBOL_SUSPENSE_COLLECTOR]: data }, () => {
return merge_style.resolve(() => fn(data));
});
}
};
const renderToString = (child) => {
return new Promise((resolve) => {
root.root((stack, dispose) => {
setters.get(SuspenseCollector.wrap((suspenses) => {
const { portal } = Portal({ children: child }).metadata;
setters.effect((stack2) => {
if (suspenses.active()) return;
resolve(portal.innerHTML);
dispose(stack2);
}, { suspense: false, stack });
}));
});
});
};
exports.Portal = Portal;
exports.render = render;
exports.renderToString = renderToString;
//# sourceMappingURL=render_to_string-QEFRB-Fu.cjs.map