@@ -160,6 +160,8 @@ qx.Class.define("osparc.desktop.StudyEditor", {
160160 __studyEditorIdlingTracker : null ,
161161 __lastSyncedProjectDocument : null ,
162162 __lastSyncedProjectVersion : null ,
163+ __pendingProjectData : null ,
164+ __applyProjectDocumentTimer : null ,
163165 __updatingStudy : null ,
164166 __updateThrottled : null ,
165167 __nodesSlidesTree : null ,
@@ -334,57 +336,91 @@ qx.Class.define("osparc.desktop.StudyEditor", {
334336 if ( data [ "projectId" ] === this . getStudy ( ) . getUuid ( ) ) {
335337 if ( data [ "clientSessionId" ] && data [ "clientSessionId" ] === osparc . utils . Utils . getClientSessionID ( ) ) {
336338 // ignore my own updates
337- console . debug ( "Ignoring my own projectDocument:updated event " , data ) ;
339+ console . debug ( "ProjectDocument Discarded: My own " , data ) ;
338340 return ;
339341 }
340-
341- const documentVersion = data [ "version" ] ;
342- if ( this . __lastSyncedProjectVersion && documentVersion <= this . __lastSyncedProjectVersion ) {
343- // ignore old updates
344- console . debug ( "Ignoring old projectDocument:updated event" , data ) ;
345- return ;
346- }
347- this . __lastSyncedProjectVersion = documentVersion ;
348-
349- const updatedStudy = data [ "document" ] ;
350- // curate projectDocument:updated document
351- this . self ( ) . curateBackendProjectDocument ( updatedStudy ) ;
352-
353- const myStudy = this . getStudy ( ) . serialize ( ) ;
354- // curate myStudy
355- this . self ( ) . curateFrontendProjectDocument ( myStudy ) ;
356-
357- this . __blockUpdates = true ;
358- const delta = osparc . wrapper . JsonDiffPatch . getInstance ( ) . diff ( myStudy , updatedStudy ) ;
359- const jsonPatches = osparc . wrapper . JsonDiffPatch . getInstance ( ) . deltaToJsonPatches ( delta ) ;
360- const uiPatches = [ ] ;
361- const workbenchPatches = [ ] ;
362- const studyPatches = [ ] ;
363- for ( const jsonPatch of jsonPatches ) {
364- if ( jsonPatch . path . startsWith ( '/ui/' ) ) {
365- uiPatches . push ( jsonPatch ) ;
366- } else if ( jsonPatch . path . startsWith ( '/workbench/' ) ) {
367- workbenchPatches . push ( jsonPatch ) ;
368- } else {
369- studyPatches . push ( jsonPatch ) ;
370- }
371- }
372- if ( workbenchPatches . length > 0 ) {
373- this . getStudy ( ) . getWorkbench ( ) . updateWorkbenchFromPatches ( workbenchPatches ) ;
374- }
375- if ( uiPatches . length > 0 ) {
376- this . getStudy ( ) . getUi ( ) . updateUiFromPatches ( uiPatches ) ;
377- }
378- if ( studyPatches . length > 0 ) {
379- this . getStudy ( ) . updateStudyFromPatches ( studyPatches ) ;
380- }
381-
382- this . __blockUpdates = false ;
342+ this . __projectDocumentReceived ( data ) ;
383343 }
384344 } , this ) ;
385345 }
386346 } ,
387347
348+ __projectDocumentReceived : function ( data ) {
349+ const documentVersion = data [ "version" ] ;
350+
351+ // Ignore outdated updates
352+ if ( this . __lastSyncedProjectVersion && documentVersion <= this . __lastSyncedProjectVersion ) {
353+ // ignore old updates
354+ console . debug ( "ProjectDocument Discarded: Ignoring old" , data ) ;
355+ return ;
356+ }
357+
358+ // Always keep the latest version in pending buffer
359+ if ( ! this . __pendingProjectData || documentVersion > ( this . __pendingProjectData . version || 0 ) ) {
360+ this . __pendingProjectData = data ;
361+ }
362+
363+ // Reset the timer if it's already running
364+ if ( this . __applyProjectDocumentTimer ) {
365+ console . log ( "ProjectDocument Discarded: Resetting applyProjectDocument timer" ) ;
366+ clearTimeout ( this . __applyProjectDocumentTimer ) ;
367+ }
368+
369+ // Throttle applying updates
370+ this . __applyProjectDocumentTimer = setTimeout ( ( ) => {
371+ if ( ! this . __pendingProjectData ) {
372+ return ;
373+ }
374+ this . __applyProjectDocumentTimer = null ;
375+
376+ // Apply the latest buffered project document
377+ const latestData = this . __pendingProjectData ;
378+ this . __pendingProjectData = null ;
379+
380+ this . __applyProjectDocument ( latestData ) ;
381+ } , 10 * this . self ( ) . THROTTLE_PATCH_TIME ) ;
382+ } ,
383+
384+ __applyProjectDocument : function ( data ) {
385+ console . log ( "ProjectDocument applying:" , data ) ;
386+ this . __lastSyncedProjectVersion = data [ "version" ] ;
387+ const updatedProjectDocument = data [ "document" ] ;
388+
389+ // curate projectDocument:updated document
390+ this . self ( ) . curateBackendProjectDocument ( updatedProjectDocument ) ;
391+
392+ const myStudy = this . getStudy ( ) . serialize ( ) ;
393+ // curate myStudy
394+ this . self ( ) . curateFrontendProjectDocument ( myStudy ) ;
395+
396+ this . __blockUpdates = true ;
397+ const delta = osparc . wrapper . JsonDiffPatch . getInstance ( ) . diff ( myStudy , updatedProjectDocument ) ;
398+ const jsonPatches = osparc . wrapper . JsonDiffPatch . getInstance ( ) . deltaToJsonPatches ( delta ) ;
399+ const uiPatches = [ ] ;
400+ const workbenchPatches = [ ] ;
401+ const studyPatches = [ ] ;
402+ for ( const jsonPatch of jsonPatches ) {
403+ if ( jsonPatch . path . startsWith ( '/ui/' ) ) {
404+ uiPatches . push ( jsonPatch ) ;
405+ } else if ( jsonPatch . path . startsWith ( '/workbench/' ) ) {
406+ workbenchPatches . push ( jsonPatch ) ;
407+ } else {
408+ studyPatches . push ( jsonPatch ) ;
409+ }
410+ }
411+ if ( workbenchPatches . length > 0 ) {
412+ this . getStudy ( ) . getWorkbench ( ) . updateWorkbenchFromPatches ( workbenchPatches ) ;
413+ }
414+ if ( uiPatches . length > 0 ) {
415+ this . getStudy ( ) . getUi ( ) . updateUiFromPatches ( uiPatches ) ;
416+ }
417+ if ( studyPatches . length > 0 ) {
418+ this . getStudy ( ) . updateStudyFromPatches ( studyPatches ) ;
419+ }
420+
421+ this . __blockUpdates = false ;
422+ } ,
423+
388424 __listenToLogger : function ( ) {
389425 const socket = osparc . wrapper . WebSocket . getInstance ( ) ;
390426
0 commit comments