fix: synchronize mounted component props
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/compiler",
|
||||
"version": "0.8.19",
|
||||
"version": "0.8.20",
|
||||
"type": "module",
|
||||
"main": "src/index.ts",
|
||||
"exports": {
|
||||
|
||||
@@ -834,7 +834,7 @@ function renderPageComponentInvocation(
|
||||
|
||||
const attrs = expandBindings(node.attrs)
|
||||
.filter((attr) => attr.name !== "data-component")
|
||||
.map((attr) => renderPageComponentAttr(attr, loops))
|
||||
.map((attr) => renderPageComponentAttr(attr, loops, reactive))
|
||||
.join("");
|
||||
|
||||
const inner = node.children
|
||||
@@ -3170,7 +3170,11 @@ function __wrnProp(v: unknown): string {
|
||||
|
||||
return __wrnAttr(value);
|
||||
}
|
||||
function renderPageComponentAttr(attr: Attr, dynamicExpressions: string[]): string {
|
||||
function renderPageComponentAttr(
|
||||
attr: Attr,
|
||||
dynamicExpressions: string[],
|
||||
reactive: PageReactive | null,
|
||||
): string {
|
||||
if (attr.event) {
|
||||
return ` ${componentEventAttribute(attr.name)}="${attrEscape(attr.value)}"`;
|
||||
}
|
||||
@@ -3188,6 +3192,12 @@ function renderPageComponentAttr(attr: Attr, dynamicExpressions: string[]): stri
|
||||
dynamicExpressions.push(`\${__wrnexusPropAttr(${expression})}`);
|
||||
|
||||
const marker = `\x00WRNEACH${dynamicExpressions.length - 1}\x00`;
|
||||
// The mount disappears during SSR. Preserve every dynamic component prop
|
||||
// as a parent-owned binding; server-only expressions simply fail closed in
|
||||
// the browser, while page state can continue driving the mounted child.
|
||||
const binding = ` data-wrn-prop-bind-${dynamicExpressions.length - 1}="${attrEscape(
|
||||
JSON.stringify([attr.name, attr.value]),
|
||||
)}"`;
|
||||
|
||||
return ` ${attr.name}="${marker}"`;
|
||||
return ` ${attr.name}="${marker}"${binding}`;
|
||||
}
|
||||
|
||||
@@ -1151,6 +1151,16 @@ page Home {
|
||||
|
||||
expect(output).toContain("__wrnexusPropAttr([");
|
||||
});
|
||||
test("page state passed to a component retains a parent-owned prop binding", () => {
|
||||
const output = generate(
|
||||
parse(`page Home {
|
||||
state count = 1
|
||||
view { <Child value={count} /> }
|
||||
}`),
|
||||
);
|
||||
expect(output).toContain("data-wrn-prop-bind-");
|
||||
expect(output).toContain("{count}");
|
||||
});
|
||||
test("nested component props retain parent-owned reactive bindings", () => {
|
||||
const output = generate(
|
||||
parse(`component Parent {
|
||||
|
||||
Reference in New Issue
Block a user