Canvas: fix A2UI v0.8 rendering

This commit is contained in:
Peter Steinberger
2025-12-17 13:20:27 +01:00
parent 81a9439eb2
commit 9eaa45a291
14 changed files with 301 additions and 134 deletions

View File

@@ -507,7 +507,8 @@ export class A2uiMessageProcessor implements MessageProcessor {
surface,
visited,
dataContextPath,
idSuffix
idSuffix,
key
);
}
}
@@ -725,10 +726,19 @@ export class A2uiMessageProcessor implements MessageProcessor {
surface: Surface,
visited: Set<string>,
dataContextPath: string,
idSuffix = ""
idSuffix = "",
propertyKey: string | null = null
): ResolvedValue {
const isComponentIdReferenceKey = (key: string) =>
key === "child" || key.endsWith("Child");
// 1. If it's a string that matches a component ID, build that node.
if (typeof value === "string" && surface.components.has(value)) {
if (
typeof value === "string" &&
propertyKey &&
isComponentIdReferenceKey(propertyKey) &&
surface.components.has(value)
) {
return this.#buildNodeRecursive(
value,
surface,
@@ -814,7 +824,8 @@ export class A2uiMessageProcessor implements MessageProcessor {
surface,
visited,
dataContextPath,
idSuffix
idSuffix,
propertyKey
)
);
}
@@ -843,7 +854,8 @@ export class A2uiMessageProcessor implements MessageProcessor {
surface,
visited,
dataContextPath,
idSuffix
idSuffix,
key
);
}
return newObj;

View File

@@ -375,6 +375,45 @@ describe("A2uiMessageProcessor", () => {
assert.strictEqual(plainTree.properties.children[0].type, "Text");
});
it("should not treat enum-like strings as child component IDs", () => {
processor.processMessages([
{
surfaceUpdate: {
surfaceId: "@default",
components: [
{
id: "root",
component: {
Column: { children: { explicitList: ["body"] } },
},
},
{
id: "body",
component: {
Text: {
text: { literalString: "Hello" },
usageHint: "body",
},
},
},
],
},
},
{
beginRendering: {
root: "root",
surfaceId: "@default",
},
},
]);
const tree = processor.getSurfaces().get("@default")?.componentTree;
const plainTree = toPlainObject(tree);
assert.strictEqual(plainTree.id, "root");
assert.strictEqual(plainTree.properties.children[0].id, "body");
assert.strictEqual(plainTree.properties.children[0].type, "Text");
});
it("should throw an error on circular dependencies", () => {
// First, load the components
processor.processMessages([