release: WRNexusJS 0.2.47
This commit is contained in:
@@ -996,6 +996,20 @@ function viewHasEvents(nodes: ViewNode[]): boolean {
|
||||
});
|
||||
}
|
||||
|
||||
function viewHasServerEach(nodes: ViewNode[]): boolean {
|
||||
return nodes.some((node) => {
|
||||
if (node.type === "text") return false;
|
||||
|
||||
if (node.type === "each") return true;
|
||||
|
||||
if (node.type === "if") {
|
||||
return node.branches.some((branch) => viewHasServerEach(branch.body));
|
||||
}
|
||||
|
||||
return viewHasServerEach(node.children);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a text node. Interpolations that reference state stay as client
|
||||
* mustaches (`{expr}`, hydrated by the reactive runtime); interpolations of
|
||||
@@ -1102,6 +1116,18 @@ function renderComponentEachNode(node: EachNode, ctx: CompCtx): string {
|
||||
);
|
||||
}
|
||||
|
||||
function serverLoopLocalsAttribute(ctx: CompCtx): string {
|
||||
const locals = [...(ctx.serverLocals ?? [])];
|
||||
|
||||
if (locals.length === 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const entries = locals.map((name) => `${JSON.stringify(name)}: ${name}`).join(", ");
|
||||
|
||||
return ` data-wrn-loop-locals="\${__wrnexusEncodeLoopLocals({ ${entries} })}"`;
|
||||
}
|
||||
|
||||
/** Render a component view node into template-literal-ready source. */
|
||||
function renderComponentNode(node: ViewNode, ctx: CompCtx): string {
|
||||
if (node.type === "text") return compileText(node.value, ctx);
|
||||
@@ -1167,7 +1193,14 @@ function renderComponentNode(node: ViewNode, ctx: CompCtx): string {
|
||||
? exprRefsState(a.value, elementContext.loopVars)
|
||||
: false;
|
||||
|
||||
if (!a.value.includes("{") || (!referencesState && !referencesLoopVariable)) {
|
||||
const referencesServerLocal = ctx.serverLocals
|
||||
? exprRefsState(a.value, ctx.serverLocals)
|
||||
: false;
|
||||
|
||||
if (
|
||||
!a.value.includes("{") ||
|
||||
(!referencesState && !referencesLoopVariable && !referencesServerLocal)
|
||||
) {
|
||||
return rendered;
|
||||
}
|
||||
|
||||
@@ -1195,8 +1228,17 @@ function renderComponentNode(node: ViewNode, ctx: CompCtx): string {
|
||||
|
||||
const staticClassValue = staticClasses.join(" ");
|
||||
|
||||
const classReferencesState = exprRefsState(staticClassValue, ctx.stateNames);
|
||||
const classReferencesLoopVariable = elementContext.loopVars
|
||||
? exprRefsState(staticClassValue, elementContext.loopVars)
|
||||
: false;
|
||||
const classReferencesServerLocal = ctx.serverLocals
|
||||
? exprRefsState(staticClassValue, ctx.serverLocals)
|
||||
: false;
|
||||
|
||||
const classHasReactiveExpression =
|
||||
staticClassValue.includes("{") && exprRefsState(staticClassValue, ctx.stateNames);
|
||||
staticClassValue.includes("{") &&
|
||||
(classReferencesState || classReferencesLoopVariable || classReferencesServerLocal);
|
||||
|
||||
const classAttribute =
|
||||
staticClasses.length > 0 || conditionalClasses.length > 0
|
||||
@@ -1208,9 +1250,6 @@ function renderComponentNode(node: ViewNode, ctx: CompCtx): string {
|
||||
: "";
|
||||
|
||||
const classBindings = conditionalClasses
|
||||
.filter(({ expression }) => {
|
||||
return !ctx.serverLocals || !exprRefsState(expression, ctx.serverLocals);
|
||||
})
|
||||
.map(({ className, expression }, index) => {
|
||||
const marker = attrEscape(JSON.stringify([className, expression]));
|
||||
|
||||
@@ -1218,8 +1257,14 @@ function renderComponentNode(node: ViewNode, ctx: CompCtx): string {
|
||||
})
|
||||
.join("");
|
||||
|
||||
const loopLocalsAttribute = serverLoopLocalsAttribute(ctx);
|
||||
|
||||
const allAttrs =
|
||||
`${classAttribute}` + `${classReactiveBinding}` + `${classBindings}` + `${attrs}`;
|
||||
`${loopLocalsAttribute}` +
|
||||
`${classAttribute}` +
|
||||
`${classReactiveBinding}` +
|
||||
`${classBindings}` +
|
||||
`${attrs}`;
|
||||
|
||||
if (VOID_ELEMENTS.has(node.tag.toLowerCase())) {
|
||||
return `<${node.tag}${allAttrs}>`;
|
||||
@@ -1232,6 +1277,11 @@ function renderComponentNode(node: ViewNode, ctx: CompCtx): string {
|
||||
|
||||
function generateComponent(ast: PageAst): string {
|
||||
const out: string[] = [];
|
||||
const hasServerEach = viewHasServerEach(ast.view);
|
||||
|
||||
if (hasServerEach) {
|
||||
out.push(`import { Buffer } from "node:buffer";`);
|
||||
}
|
||||
|
||||
const effectiveProps =
|
||||
ast.kind === "layout" && !ast.props.some((prop) => prop.name === "content")
|
||||
@@ -1420,6 +1470,12 @@ function __wireRaw(v: any): string {
|
||||
return String(v == null ? "" : v);
|
||||
}`);
|
||||
|
||||
if (hasServerEach) {
|
||||
out.push(`function __wrnexusEncodeLoopLocals(value: Record<string, any>): string {
|
||||
return Buffer.from(JSON.stringify(value), "utf8").toString("base64");
|
||||
}`);
|
||||
}
|
||||
|
||||
if (needsScope) {
|
||||
out.push(`function __wrnexusSerializeScopeValue(value: any): string {
|
||||
if (value === undefined) {
|
||||
|
||||
Reference in New Issue
Block a user