authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2025-06-07 03:46:14-07:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2025-10-14 02:40:44-07:00
loga9419bd19945024b0e70a4c3fc56342cf5247d69
treed0c95f26a7403a25d286654bdb531a45ec11bb16
parent0a8336e50495e659d9cfd113e258cca17e8148ac
signature Commit is signed but in an unrecognized format.

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


3 files changed, 129 insertions(+), 0 deletions(-)

framework/engine/jsx-runtime.ts created+22
......@@ -0,0 +1,22 @@
1export const Fragment = ({ children }: { children }) => children;
2
3// jsx
4export function jsx(type, props, key) {
5 if (typeof type !== "function" && typeof type !== "string") {
6 throw new Error("Invalid JSX component type: " + ssr.inspect(type));
7 }
8 return [import_ssr.kElement, type, props];
9}
10
11// jsxDEV
12function jsxDEV(type, props, _key, _isStaticChildren, source) {
13 if (typeof type !== "function" && typeof type !== "string") {
14 throw new Error("Invalid JSX component type: " + ssr.inspect(type));
15 }
16 return [ssr.kElement, type, props, source];
17}
18
19// jsxs
20export { jsx as jsxs };
21
22import * as ssr from "./ssr.ts";
framework/engine/marko-runtime.ts created+107
......@@ -0,0 +1,107 @@
1import * as ssr from "./ssr.ts";
2// @ts-ignore no types :(
3import * as marko from "marko/debug/html";
4// @ts-ignore no types :(
5export * from "marko/debug/html";
6
7export const createTemplate = (templateId: string, renderer) => {
8 const { render } = marko.createTemplate(templateId, renderer);
9 function wrap(props: Record<string, unknown>, n: number) {
10 // Marko components
11 const cloverAsyncMarker = { isAsync: false };
12 let r: ssr.Render | undefined = undefined;
13 try {
14 r = ssr.getCurrentRender();
15 } catch {}
16 // Support using Marko outside of Clover SSR
17 if (r) {
18 const markoResult = render.call(renderer, {
19 ...props,
20 $global: { clover: r, cloverAsyncMarker },
21 });
22 if (cloverAsyncMarker.isAsync) {
23 return markoResult.then(ssr.html);
24 }
25 const rr = markoResult.toString();
26 return ssr.html(rr);
27 } else {
28 return renderer(props, n);
29 }
30 }
31 wrap.render = render;
32 wrap.unwrapped = renderer;
33 return wrap;
34};
35
36export const dynamicTag = (
37 scopeId,
38 accessor,
39 tag,
40 inputOrArgs,
41 content,
42 inputIsArgs,
43 serializeReason,
44) => {
45 if (typeof tag === "function") {
46 clover: {
47 const unwrapped = tag.unwrapped;
48 if (unwrapped) {
49 tag = unwrapped;
50 break clover;
51 }
52 let r: ssr.Render;
53 try {
54 r = ssr.getCurrentRender();
55 if (!r) throw 0;
56 } catch {
57 r = marko.$global().clover as ssr.Render;
58 }
59 if (!r) throw new Error("No Clover Render Active");
60 const subRender = ssr.initRender(r.async !== -1, r.user);
61 const resolved = ssr.resolveNode(subRender, [
62 ssr.kElement,
63 tag,
64 inputOrArgs,
65 ]);
66
67 if (subRender.async > 0) {
68 const marker = marko.$global().cloverAsyncMarker;
69 marker.isAsync = true;
70
71 // Wait for async work to finish
72 const { resolve, reject, promise } = Promise.withResolvers<string>();
73 subRender.asyncDone = () => {
74 const rejections = subRender.rejections;
75 if (!rejections) return resolve(ssr.renderNodeOrUndefined(resolved));
76 (r.rejections ??= []).push(...rejections);
77 return reject(new Error("Render had errors"));
78 };
79 marko.fork(
80 scopeId,
81 accessor,
82 promise,
83 (string: string) => marko.write(string),
84 0,
85 );
86 } else {
87 marko.write(ssr.renderNodeOrUndefined(resolved));
88 }
89 return;
90 }
91 }
92 return marko.dynamicTag(
93 scopeId,
94 accessor,
95 tag,
96 inputOrArgs,
97 content,
98 inputIsArgs,
99 serializeReason,
100 );
101};
102
103export function fork(scopeId, accessor, promise, callback, serializeMarker) {
104 const marker = marko.$global().cloverAsyncMarker;
105 marker.isAsync = true;
106 marko.fork(scopeId, accessor, promise, callback, serializeMarker);
107}
framework/engine/ssr.ts created