frontend-plugin-api: enable recursive cloning of extensions

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2025-01-24 16:28:08 +01:00
parent f1efb47bb4
commit 93a0f15c6e
2 changed files with 17 additions and 35 deletions
@@ -143,44 +143,16 @@ describe('buildAppTree', () => {
expect(Array.from(tree.nodes.keys())).toEqual(['a', 'b', 'c', 'd']);
expect(JSON.parse(JSON.stringify(tree.root))).toMatchInlineSnapshot(`
{
"attachments": {
"x": [
{
"attachments": {
"x": [
{
"id": "c",
},
{
"id": "d",
},
],
},
"id": "b",
},
{
"attachments": {
"x": [
{
"id": "d",
},
],
},
"id": "c",
},
],
},
"id": "a",
}
`);
expect(String(tree.root)).toMatchInlineSnapshot(`
"<a>
x [
<b>
x [
<c />
<c>
x [
<d />
]
</c>
<d />
]
</b>
@@ -145,6 +145,7 @@ export function resolveAppTree(
}
const orphans = new Array<SerializableAppNode>();
const clones = new Map<string, Array<SerializableAppNode>>();
// A node with the provided rootNodeId must be found in the tree, and it must not be attached to anything
let rootNode: AppNode | undefined = undefined;
@@ -167,13 +168,22 @@ export function resolveAppTree(
const parent = nodes.get(attachTo.id);
if (parent) {
const cloneParents = clones.get(attachTo.id) ?? [];
if (!foundFirstParent) {
foundFirstParent = true;
node.setParent(parent, attachTo.input);
} else {
// TODO(Rugvip): Perhaps makes sense to keep track of these with a `clones` map, similar to `orphans`?
cloneParents.unshift(parent);
}
for (const extraParent of cloneParents) {
const clonedNode = new SerializableAppNode(spec);
clonedNode.setParent(parent, attachTo.input);
clonedNode.setParent(extraParent, attachTo.input);
clones.set(
spec.id,
clones.get(spec.id)?.concat(clonedNode) ?? [clonedNode],
);
}
}
}