@@ -10,6 +10,7 @@ import * as Y from 'yjs'
10
10
11
11
import { ACTOR_CONFIG } from '@/renderer/core/layout/constants'
12
12
import type {
13
+ BatchUpdateBoundsOperation ,
13
14
CreateLinkOperation ,
14
15
CreateNodeOperation ,
15
16
CreateRerouteOperation ,
@@ -864,6 +865,12 @@ class LayoutStoreImpl implements LayoutStore {
864
865
case 'deleteNode' :
865
866
this . handleDeleteNode ( operation as DeleteNodeOperation , change )
866
867
break
868
+ case 'batchUpdateBounds' :
869
+ this . handleBatchUpdateBounds (
870
+ operation as BatchUpdateBoundsOperation ,
871
+ change
872
+ )
873
+ break
867
874
case 'createLink' :
868
875
this . handleCreateLink ( operation as CreateLinkOperation , change )
869
876
break
@@ -1092,6 +1099,38 @@ class LayoutStoreImpl implements LayoutStore {
1092
1099
change . nodeIds . push ( operation . nodeId )
1093
1100
}
1094
1101
1102
+ private handleBatchUpdateBounds (
1103
+ operation : BatchUpdateBoundsOperation ,
1104
+ change : LayoutChange
1105
+ ) : void {
1106
+ const spatialUpdates : Array < { nodeId : NodeId ; bounds : Bounds } > = [ ]
1107
+
1108
+ for ( const nodeId of operation . nodeIds ) {
1109
+ const data = operation . bounds [ nodeId ]
1110
+ const ynode = this . ynodes . get ( nodeId )
1111
+ if ( ! ynode || ! data ) continue
1112
+
1113
+ ynode . set ( 'position' , { x : data . bounds . x , y : data . bounds . y } )
1114
+ ynode . set ( 'size' , {
1115
+ width : data . bounds . width ,
1116
+ height : data . bounds . height
1117
+ } )
1118
+ ynode . set ( 'bounds' , data . bounds )
1119
+
1120
+ spatialUpdates . push ( { nodeId, bounds : data . bounds } )
1121
+ change . nodeIds . push ( nodeId )
1122
+ }
1123
+
1124
+ // Batch update spatial index for better performance
1125
+ if ( spatialUpdates . length > 0 ) {
1126
+ this . spatialIndex . batchUpdate ( spatialUpdates )
1127
+ }
1128
+
1129
+ if ( change . nodeIds . length ) {
1130
+ change . type = 'update'
1131
+ }
1132
+ }
1133
+
1095
1134
private handleCreateLink (
1096
1135
operation : CreateLinkOperation ,
1097
1136
change : LayoutChange
@@ -1372,19 +1411,38 @@ class LayoutStoreImpl implements LayoutStore {
1372
1411
const originalSource = this . currentSource
1373
1412
this . currentSource = LayoutSource . Vue
1374
1413
1375
- this . ydoc . transact ( ( ) => {
1376
- for ( const { nodeId, bounds } of updates ) {
1377
- const ynode = this . ynodes . get ( nodeId )
1378
- if ( ! ynode ) continue
1414
+ const nodeIds : NodeId [ ] = [ ]
1415
+ const boundsRecord : BatchUpdateBoundsOperation [ 'bounds' ] = { }
1379
1416
1380
- this . spatialIndex . update ( nodeId , bounds )
1381
- ynode . set ( 'bounds' , bounds )
1382
- ynode . set ( 'position' , { x : bounds . x , y : bounds . y } )
1383
- ynode . set ( 'size' , { width : bounds . width , height : bounds . height } )
1417
+ for ( const { nodeId, bounds } of updates ) {
1418
+ const ynode = this . ynodes . get ( nodeId )
1419
+ if ( ! ynode ) continue
1420
+ const currentLayout = yNodeToLayout ( ynode )
1421
+
1422
+ boundsRecord [ nodeId ] = {
1423
+ bounds,
1424
+ previousBounds : currentLayout . bounds
1384
1425
}
1385
- } , this . currentActor )
1426
+ nodeIds . push ( nodeId )
1427
+ }
1428
+
1429
+ if ( ! nodeIds . length ) {
1430
+ this . currentSource = originalSource
1431
+ return
1432
+ }
1433
+
1434
+ const operation : BatchUpdateBoundsOperation = {
1435
+ type : 'batchUpdateBounds' ,
1436
+ entity : 'node' ,
1437
+ nodeIds,
1438
+ bounds : boundsRecord ,
1439
+ timestamp : Date . now ( ) ,
1440
+ source : this . currentSource ,
1441
+ actor : this . currentActor
1442
+ }
1443
+
1444
+ this . applyOperation ( operation )
1386
1445
1387
- // Restore original source
1388
1446
this . currentSource = originalSource
1389
1447
}
1390
1448
}
0 commit comments