11import { Injectable } from '@angular/core' ;
22import * as go from 'gojs' ;
3- import produce from "immer" ;
3+ import produce , { current } from "immer" ;
44
55@Injectable ( )
66export class DataSyncService {
@@ -18,6 +18,12 @@ export class DataSyncService {
1818
1919 // maintain a map of modified nodes for fast lookup during insertion
2020 const modifiedNodesMap = new go . Map < go . Key , go . ObjectData > ( ) ;
21+ // generate a map of keys -> indices for faster operations
22+ const keyIdxMap = new Map < go . Key , number > ( ) ;
23+ nodeData . forEach ( ( nd , idx ) => {
24+ const key = model ? model . getKeyForNodeData ( nd ) : nd [ 'key' ] ;
25+ keyIdxMap . set ( key , idx ) ;
26+ } ) ;
2127
2228 // nodeData is immutable, modify it using the immer package's "produce" function (creates new array)
2329 var newNodeDataArray = produce ( nodeData , ( draft ) => {
@@ -27,12 +33,9 @@ export class DataSyncService {
2733 // Get the value of the node key property checking wether is a function or a string
2834 const key = model ? model . getKeyForNodeData ( nd ) : nd [ 'key' ] ;
2935 modifiedNodesMap . set ( key , nd ) ;
30- for ( let i = 0 ; i < nodeData . length ; i ++ ) {
31- const ndEntry = nodeData [ i ] ;
32- const keyNdEntry = model ? model . getKeyForNodeData ( ndEntry ) : ndEntry [ 'key' ] ;
33- if ( keyNdEntry === key ) {
34- draft [ i ] = nd ;
35- }
36+ const idx = keyIdxMap . get ( key ) ;
37+ if ( idx !== undefined && idx >= 0 ) {
38+ draft [ idx ] = nd ;
3639 }
3740 } ) ;
3841 }
@@ -41,18 +44,18 @@ export class DataSyncService {
4144 if ( changes . insertedNodeKeys ) {
4245 changes . insertedNodeKeys . forEach ( ( key : go . Key ) => {
4346 const nd = modifiedNodesMap . get ( key ) ;
44- if ( nd ) {
47+ if ( nd && ! keyIdxMap . has ( key ) ) {
4548 draft . push ( nd ) ;
4649 }
4750 } ) ;
4851 }
4952
5053 // account for removed node data
5154 if ( changes . removedNodeKeys ) {
52- changes . removedNodeKeys . forEach ( rnk => {
53- const idx = draft . findIndex ( nd => { return model . getKeyForNodeData ( nd ) == rnk } ) ;
54- if ( idx >= 0 ) draft . splice ( idx , 1 ) ;
55- } ) ;
55+ const removals = changes . removedNodeKeys . map ( key => keyIdxMap . get ( key ) ) . sort ( ) ;
56+ for ( let i = removals . length - 1 ; i >= 0 ; i -- ) {
57+ draft . splice ( removals [ i ] , 1 ) ;
58+ }
5659 }
5760 } ) ;
5861
@@ -72,6 +75,12 @@ export class DataSyncService {
7275
7376 // maintain a map of modified nodes for fast lookup during insertion
7477 const modifiedLinksMap = new go . Map < go . Key , go . ObjectData > ( ) ;
78+ // generate a map of keys -> indices for faster operations
79+ const keyIdxMap = new Map < go . Key , number > ( ) ;
80+ linkData . forEach ( ( ld , idx ) => {
81+ const key = model ? model . getKeyForLinkData ( ld ) : ld [ 'key' ] ;
82+ keyIdxMap . set ( key , idx ) ;
83+ } ) ;
7584
7685 // linkData is immutable, modify it using the immer package's "produce" function (creates new array)
7786 linkData = produce ( linkData , draft => {
@@ -81,13 +90,9 @@ export class DataSyncService {
8190 // Get the value of the link key
8291 const key = model ? model . getKeyForLinkData ( ld ) : ld [ 'key' ] ;
8392 modifiedLinksMap . set ( key , ld ) ;
84-
85- for ( let i = 0 ; i < linkData . length ; i ++ ) {
86- const ldEntry = linkData [ i ] ;
87- const keyLdEntry = model ? model . getKeyForLinkData ( ldEntry ) : ldEntry [ 'key' ] ;
88- if ( keyLdEntry === key ) {
89- draft [ i ] = ld ;
90- }
93+ const idx = keyIdxMap . get ( key ) ;
94+ if ( idx !== undefined && idx >= 0 ) {
95+ draft [ idx ] = ld ;
9196 }
9297 } ) ;
9398 }
@@ -96,18 +101,18 @@ export class DataSyncService {
96101 if ( changes . insertedLinkKeys ) {
97102 changes . insertedLinkKeys . forEach ( ( key : go . Key ) => {
98103 const nd = modifiedLinksMap . get ( key ) ;
99- if ( nd ) {
104+ if ( nd && ! keyIdxMap . has ( key ) ) {
100105 draft . push ( nd ) ;
101106 }
102107 } ) ;
103108 }
104109
105110 // account for removed link data
106111 if ( changes . removedLinkKeys ) {
107- changes . removedLinkKeys . forEach ( rlk => {
108- const idx = draft . findIndex ( ld => { return model . getKeyForLinkData ( ld ) == rlk } ) ;
109- if ( idx >= 0 ) draft . splice ( idx , 1 ) ;
110- } ) ;
112+ const removals = changes . removedLinkKeys . map ( key => keyIdxMap . get ( key ) ) . sort ( ) ;
113+ for ( let i = removals . length - 1 ; i >= 0 ; i -- ) {
114+ draft . splice ( removals [ i ] , 1 ) ;
115+ }
111116 }
112117 } ) ;
113118
0 commit comments