recover marko-runtime.ts and parts of ssr.ts

This commit is contained in:
chloe caruso 2025-06-07 03:46:14 -07:00
parent cc4db4a4e0
commit 8f6b474120
3 changed files with 129 additions and 0 deletions

View file

@ -0,0 +1,22 @@
export const Fragment = ({ children }: { children }) => children;
// jsx
export function jsx(type, props, key) {
if (typeof type !== "function" && typeof type !== "string") {
throw new Error("Invalid JSX component type: " + ssr.inspect(type));
}
return [import_ssr.kElement, type, props];
}
// jsxDEV
function jsxDEV(type, props, _key, _isStaticChildren, source) {
if (typeof type !== "function" && typeof type !== "string") {
throw new Error("Invalid JSX component type: " + ssr.inspect(type));
}
return [ssr.kElement, type, props, source];
}
// jsxs
export { jsx as jsxs };
import * as ssr from "./ssr.ts";

View file

@ -0,0 +1,107 @@
import * as ssr from "./ssr.ts";
// @ts-ignore no types :(
import * as marko from "marko/debug/html";
// @ts-ignore no types :(
export * from "marko/debug/html";
export const createTemplate = (templateId: string, renderer) => {
const { render } = marko.createTemplate(templateId, renderer);
function wrap(props: Record<string, unknown>, n: number) {
// Marko components
const cloverAsyncMarker = { isAsync: false };
let r: ssr.Render | undefined = undefined;
try {
r = ssr.getCurrentRender();
} catch {}
// Support using Marko outside of Clover SSR
if (r) {
const markoResult = render.call(renderer, {
...props,
$global: { clover: r, cloverAsyncMarker },
});
if (cloverAsyncMarker.isAsync) {
return markoResult.then(ssr.html);
}
const rr = markoResult.toString();
return ssr.html(rr);
} else {
return renderer(props, n);
}
}
wrap.render = render;
wrap.unwrapped = renderer;
return wrap;
};
export const dynamicTag = (
scopeId,
accessor,
tag,
inputOrArgs,
content,
inputIsArgs,
serializeReason,
) => {
if (typeof tag === "function") {
clover: {
const unwrapped = tag.unwrapped;
if (unwrapped) {
tag = unwrapped;
break clover;
}
let r: ssr.Render;
try {
r = ssr.getCurrentRender();
if (!r) throw 0;
} catch {
r = marko.$global().clover as ssr.Render;
}
if (!r) throw new Error("No Clover Render Active");
const subRender = ssr.initRender(r.async !== -1, r.user);
const resolved = ssr.resolveNode(subRender, [
ssr.kElement,
tag,
inputOrArgs,
]);
if (subRender.async > 0) {
const marker = marko.$global().cloverAsyncMarker;
marker.isAsync = true;
// Wait for async work to finish
const { resolve, reject, promise } = Promise.withResolvers<string>();
subRender.asyncDone = () => {
const rejections = subRender.rejections;
if (!rejections) return resolve(ssr.renderNodeOrUndefined(resolved));
(r.rejections ??= []).push(...rejections);
return reject(new Error("Render had errors"));
};
marko.fork(
scopeId,
accessor,
promise,
(string: string) => marko.write(string),
0,
);
} else {
marko.write(ssr.renderNodeOrUndefined(resolved));
}
return;
}
}
return marko.dynamicTag(
scopeId,
accessor,
tag,
inputOrArgs,
content,
inputIsArgs,
serializeReason,
);
};
export function fork(scopeId, accessor, promise, callback, serializeMarker) {
const marker = marko.$global().cloverAsyncMarker;
marker.isAsync = true;
marko.fork(scopeId, accessor, promise, callback, serializeMarker);
}

0
framework/engine/ssr.ts Normal file
View file