@@ -158,9 +158,14 @@ class Graph extends EventTarget {
158158 return Object . freeze ( affectedIds ) ;
159159 }
160160
161- // eslint-disable-next-line complexity
161+ /**
162+ * Upserts a list of nodes in a transaction. Will trigger observers once upsert has completed.
163+ *
164+ * @param nodes Nodes to upsert.
165+ */
162166 upsert ( ...nodes : readonly SlantNode [ ] ) {
163167 const affectedIdSet : Set < Identifier > = new Set ( ) ;
168+ const markIdAsAffected = affectedIdSet . add . bind ( affectedIdSet ) ;
164169
165170 for ( const node of nodes ) {
166171 const id = node [ '@id' ] ;
@@ -174,20 +179,22 @@ class Graph extends EventTarget {
174179 const existingNode = this . #graph. get ( id ) ;
175180
176181 if ( existingNode ) {
177- for ( const existingChildId of nodeReferenceListToIdentifierSet ( existingNode . hasPart || [ ] ) . difference (
182+ const removedHasPartIdSet = nodeReferenceListToIdentifierSet ( existingNode . hasPart || [ ] ) . difference (
178183 nodeReferenceListToIdentifierSet ( node . hasPart || [ ] )
179- ) ) {
180- for ( const id of this . #setEdge ( existingNode [ '@id' ] , 'hasPart' , existingChildId , 'delete' ) ) {
181- affectedIdSet . add ( id ) ;
182- }
184+ ) ;
185+
186+ for ( const removedHasPartId of removedHasPartIdSet ) {
187+ this . #setEdge ( existingNode [ '@id' ] , 'hasPart' , removedHasPartId , 'delete' ) . values ( ) . forEach ( markIdAsAffected ) ;
183188 }
184189
185- for ( const existingParentId of nodeReferenceListToIdentifierSet ( existingNode . isPartOf || [ ] ) . difference (
190+ const removedIsPartOfIdSet = nodeReferenceListToIdentifierSet ( existingNode . isPartOf || [ ] ) . difference (
186191 nodeReferenceListToIdentifierSet ( node . isPartOf || [ ] )
187- ) ) {
188- for ( const id of this . #setEdge( existingNode [ '@id' ] , 'isPartOf' , existingParentId , 'delete' ) ) {
189- affectedIdSet . add ( id ) ;
190- }
192+ ) ;
193+
194+ for ( const removedIsPartOfId of removedIsPartOfIdSet ) {
195+ this . #setEdge( existingNode [ '@id' ] , 'isPartOf' , removedIsPartOfId , 'delete' )
196+ . values ( )
197+ . forEach ( markIdAsAffected ) ;
191198 }
192199 }
193200
@@ -198,15 +205,11 @@ class Graph extends EventTarget {
198205 const nodeId = node [ '@id' ] ;
199206
200207 for ( const { '@id' : childId } of node . hasPart || [ ] ) {
201- for ( const id of this . #setEdge( nodeId , 'hasPart' , childId , 'add' ) ) {
202- affectedIdSet . add ( id ) ;
203- }
208+ this . #setEdge( nodeId , 'hasPart' , childId , 'add' ) . values ( ) . forEach ( markIdAsAffected ) ;
204209 }
205210
206211 for ( const { '@id' : parentId } of node . isPartOf || [ ] ) {
207- for ( const id of this . #setEdge( nodeId , 'isPartOf' , parentId , 'add' ) ) {
208- affectedIdSet . add ( id ) ;
209- }
212+ this . #setEdge( nodeId , 'isPartOf' , parentId , 'add' ) . values ( ) . forEach ( markIdAsAffected ) ;
210213 }
211214 }
212215
0 commit comments