sync children node data

This commit is contained in:
hjlarry 2025-09-26 14:07:34 +08:00
parent 113aa4ae08
commit a6d4bf3399
1 changed files with 47 additions and 1 deletions

View File

@ -540,7 +540,8 @@ export class CollaborationManager {
const oldNodesMap = new Map(oldNodes.map(node => [node.id, node]))
const newNodesMap = new Map(newNodes.map(node => [node.id, node]))
const shouldSyncDataKey = (key: string) => !key.startsWith('_') && key !== 'selected'
const syncDataAllowList = new Set(['_children'])
const shouldSyncDataKey = (key: string) => (syncDataAllowList.has(key) || !key.startsWith('_')) && key !== 'selected'
// Delete removed nodes
oldNodes.forEach((oldNode) => {
@ -549,6 +550,44 @@ export class CollaborationManager {
})
// Add or update nodes with fine-grained sync for data properties
const copyOptionalNodeProps = (source: Node, target: any) => {
const optionalProps: Array<keyof Node | keyof any> = [
'parentId',
'positionAbsolute',
'extent',
'zIndex',
'draggable',
'selectable',
'dragHandle',
'dragging',
'connectable',
'expandParent',
'focusable',
'hidden',
'style',
'className',
'ariaLabel',
'markerStart',
'markerEnd',
'resizing',
'deletable',
]
optionalProps.forEach((prop) => {
const value = (source as any)[prop]
if (value === undefined) {
if (prop in target)
delete target[prop]
return
}
if (value !== null && typeof value === 'object')
target[prop as string] = JSON.parse(JSON.stringify(value))
else
target[prop as string] = value
})
}
newNodes.forEach((newNode) => {
const oldNode = oldNodesMap.get(newNode.id)
@ -565,6 +604,8 @@ export class CollaborationManager {
data: {},
}
copyOptionalNodeProps(newNode, nodeData)
// Clone data properties, excluding private ones
Object.entries(newNode.data).forEach(([key, value]) => {
if (shouldSyncDataKey(key) && value !== undefined)
@ -592,6 +633,9 @@ export class CollaborationManager {
if (oldNode.height !== newNode.height)
updatedNode.height = newNode.height
// Ensure optional node props stay in sync
copyOptionalNodeProps(newNode, updatedNode)
// Ensure data object exists
if (!updatedNode.data)
updatedNode.data = {}
@ -632,6 +676,8 @@ export class CollaborationManager {
data: {},
}
copyOptionalNodeProps(newNode, nodeData)
Object.entries(newNode.data).forEach(([key, value]) => {
if (shouldSyncDataKey(key) && value !== undefined)
nodeData.data[key] = JSON.parse(JSON.stringify(value))