fix(builder): deep-clone node data on id regeneration to avoid shared props

regenerateTreeIds shallow-copied each node's data, leaving data.props (and
data.custom) as the same object reference between the original node and its
duplicate/pasted copy. Craft.js's setProp mutates data.props in place, so
editing the duplicate's props silently mutated the original too. Deep-clone
data via structuredClone before applying id remaps so no mutable sub-object
is shared between original and regenerated nodes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-12 12:25:22 -07:00
parent 97123c4c58
commit 1a88baa95d
2 changed files with 25 additions and 1 deletions
+8 -1
View File
@@ -43,11 +43,18 @@ export function regenerateTreeIds(tree: NodeTree): NodeTree {
newLinkedNodes[slot] = remapId(linkedId);
}
// Deep-clone data so mutable sub-objects (props, custom, etc.) are never
// shared by reference between the original node and its regenerated
// copy. Craft.js's setProp mutates data.props in place, so a shallow
// copy here would let edits to the duplicate silently corrupt the
// original.
const clonedData = structuredClone(oldNode.data);
const newNode: Node = {
...oldNode,
id: newId,
data: {
...oldNode.data,
...clonedData,
parent: newParent,
nodes: (oldNode.data.nodes || []).map(remapId),
linkedNodes: newLinkedNodes,