@@ -50,7 +50,10 @@ function addDummy(sources, targets, obj, options, directionS, directionT){
5050
5151}
5252
53+ let id2log = id => id . replace ( / \- c o m p o n e n t s / g, '' ) . replace ( / _ _ o r i g i n / g, '' ) . replace ( / _ _ t e r m i n u s / g, '' )
54+
5355function drawNodeNew ( id , label , type , properties , options ) {
56+ //console.log(id)
5457 let o = {
5558 id : id ,
5659 label : label ,
@@ -73,12 +76,26 @@ function drawNodeNew(id, label, type, properties, options){
7376 }
7477 o . visited = visited [ id ] ;
7578 }
76- else if ( visited [ id ] ) {
77- if ( type === 'action' ) {
78- visited [ id ] . forEach ( ( v , i ) => { visited [ id ] [ i ] ++ } ) ; // for actions, increase all index by one to point to the next activation in the array.
79+ else {
80+ let iid = id2log ( id )
81+ if ( visited [ iid ] ) {
82+ if ( type === 'action' ) {
83+ visited [ iid ] . forEach ( ( v , i ) => { visited [ iid ] [ i ] ++ } ) ; // for actions, increase all index by one to point to the next activation in the array.
84+ }
85+
86+ if ( type === 'retain' ) {
87+ if ( ( visited [ iid ] . length >= 1 && id . endsWith ( '__origin' ) ) || ( visited [ iid ] . length === 2 && id . endsWith ( '__terminus' ) ) ) {
88+ o . visited = visited [ iid ] ;
89+ }
90+ }
91+ else {
92+ o . visited = visited [ iid ] ;
93+ }
94+
7995 }
80- o . visited = visited [ id ] ;
96+ //console.log("iid:", id, iid, visited[iid], o.visited)
8197 }
98+
8299 }
83100
84101 if ( visited && ( visited [ id ] || id === 'Entry' ) )
@@ -175,16 +192,19 @@ function drawNodeNew(id, label, type, properties, options){
175192 ports : [ ] ,
176193 properties : { } ,
177194 children : [ ] ,
178- edges : [ ]
195+ edges : [ ] ,
196+ visited : visited ? visited [ id2log ( `${ id } -body` ) ] : undefined
179197 } , {
180198 id : `${ id } -handler` ,
181199 label : 'error handler' ,
182200 type : 'handler' ,
183201 ports : [ ] ,
184202 properties : { } ,
185203 children : [ ] ,
186- edges : [ ]
204+ edges : [ ] ,
205+ visited : visited ? visited [ id2log ( `${ id } -handler` ) ] : undefined
187206 } ] ;
207+
188208 o . edges = [ drawEdgeNew ( `${ id } -body` , `${ id } -handler` , o , undefined , 'RIGHT' ) ] ;
189209 }
190210 else if ( o . type === 'Entry' || o . type === 'Exit' ) {
@@ -200,7 +220,8 @@ function drawNodeNew(id, label, type, properties, options){
200220 o . height = 4 ;
201221 // Dummy node's `properties` is `sources`, used to determine if the dummy is visited
202222 if ( visited && Array . isArray ( properties ) ) {
203- properties . forEach ( s => { // a source id
223+ properties . forEach ( s => { // a source id
224+ s = id2log ( s ) ;
204225 if ( visited [ s ] ) { // if the source is visited
205226 visited [ s ] . forEach ( a => { // find out if any of its activation was success
206227 if ( activations [ a ] . response . success ) { // if so, dummy is visited
@@ -291,16 +312,21 @@ function drawEdgeNew(sourceId, targetId, layer, type, direction, sourcePort, tar
291312 sourcePort : sourcePort ,
292313 target : targetId ,
293314 targetPort : targetPort ,
294- visited : ( visited && visited [ sourceId ] && visited [ targetId ] )
315+ // visited: (visited && visited[sourceId] && visited[targetId])
295316 } ;
296317}
297318
298319function ir2graph ( ir , gm , id , prevId , options = { } ) { // ir and graph model
299- if ( Array . isArray ( ir ) ) {
320+ if ( ir . type === 'sequence' || Array . isArray ( ir ) ) {
300321 // for an array of things, prevId is the previous element
301322 // console.log(ir, gm, id, prevId);
302- let count = 0 , prev ;
303- ir . forEach ( obj => {
323+ let count = 0 , prev , array ;
324+ if ( ir . type === 'sequence' )
325+ array = ir . components
326+ else
327+ array = ir
328+
329+ array . forEach ( obj => {
304330 if ( obj . options && obj . options . helper ) {
305331 // do nothing
306332 }
@@ -314,6 +340,7 @@ function ir2graph(ir, gm, id, prevId, options={}){ // ir and graph model
314340 return prev ;
315341 }
316342 else {
343+ //id = `${id}-${ir.type}`
317344 if ( ir . type === 'action' ) {
318345 let name = ir . name ;
319346 if ( ir . displayLabel )
@@ -324,7 +351,7 @@ function ir2graph(ir, gm, id, prevId, options={}){ // ir and graph model
324351 return [ id ] ;
325352 }
326353 else if ( ir . type === 'function' ) {
327- gm . children . push ( drawNodeNew ( id , ir . exec . code , ir . type , undefined , options ) )
354+ gm . children . push ( drawNodeNew ( id , ir . function . exec . code , ir . type , undefined , options ) )
328355
329356 if ( prevId )
330357 prevId . forEach ( pid => gm . edges . push ( drawEdgeNew ( pid , id , gm ) ) ) ;
@@ -372,15 +399,15 @@ function ir2graph(ir, gm, id, prevId, options={}){ // ir and graph model
372399 tryPart = tryCatchPart . children [ 0 ] ,
373400 catchPart = tryCatchPart . children [ 1 ]
374401
375- ir2graph ( ir . body , tryPart , tryPart . id , undefined , options ) ;
376- ir2graph ( ir . handler , catchPart , catchPart . id , undefined , options ) ;
402+ ir2graph ( ir . body , tryPart , tryPart . id + '-components' , undefined , options ) ;
403+ ir2graph ( ir . handler , catchPart , catchPart . id + '-components' , undefined , options ) ;
377404
378405 return [ gm . children [ gm . children . length - 1 ] . id ] ;
379406 }
380- else if ( ir . type === 'while' || ir . type === 'dowhile' ) {
407+ else if ( ir . type === 'while' || ir . type === 'dowhile' || ir . type === 'while_nosave' || ir . type === 'dowhile_nosave' ) {
381408 let firstTestId , firstBodyId , lastTestId , lastBodyId ;
382409
383- if ( ir . type === 'while' ) {
410+ if ( ir . type === 'while' || ir . type === 'while_nosave' ) {
384411 firstTestId = gm . children . length ;
385412 lastTestId = ir2graph ( ir . test , gm , `${ id } -test` , undefined , options ) ;
386413 if ( prevId ) // connect prevId to the first node in test
@@ -427,7 +454,7 @@ function ir2graph(ir, gm, id, prevId, options={}){ // ir and graph model
427454 if ( prevId ) {
428455 prevId . forEach ( pid => gm . edges . push ( drawEdgeNew ( pid , `${ id } __origin` , gm ) ) ) ;
429456 }
430- let lastNodes = ir2graph ( ir . body , gm , ` ${ id } -body` , [ `${ id } __origin` ] , options ) ;
457+ let lastNodes = ir2graph ( ir . components , gm , id , [ `${ id } __origin` ] , options ) ;
431458 gm . children . push ( drawNodeNew ( `${ id } __terminus` , '' , ir . type , undefined , options ) ) ;
432459 if ( lastNodes ) {
433460 lastNodes . forEach ( pid => gm . edges . push ( drawEdgeNew ( pid , `${ id } __terminus` , gm ) ) ) ;
@@ -440,41 +467,26 @@ function ir2graph(ir, gm, id, prevId, options={}){ // ir and graph model
440467
441468 return [ `${ id } __terminus` ] ;
442469 }
443- else if ( ir . type === 'let' ) {
444- if ( ir . body && ir . body . length > 0 && ir . body [ 0 ] . options && ir . body [ 0 ] . options . helper === 'retry_1' ) {
445- // retry, insert a compound node
446- gm . children . push ( drawNodeNew ( id , ir . declarations . count , 'retry' , undefined , options ) ) ;
447- if ( prevId ) {
448- prevId . forEach ( pid => gm . edges . push ( drawEdgeNew ( pid , id , gm ) ) ) ;
449- }
450- // body is in ir.body[1].body[0].finalizer[0].body[0].body
451- ir2graph ( ir . body [ 1 ] . body [ 0 ] . finalizer [ 0 ] . body [ 0 ] . body , gm . children [ gm . children . length - 1 ] , `${ id } -body-1-body-0-finalizer-0-body-0-body` , undefined , options ) ;
452-
453- return [ gm . children [ gm . children . length - 1 ] . id ] ;
454-
455- }
456- else if ( ir . body && ir . body . length > 0 && ir . body [ 0 ] . test && ir . body [ 0 ] . test . length > 0 && ir . body [ 0 ] . test [ 0 ] . options && ir . body [ 0 ] . test [ 0 ] . options . helper === 'repeat_1' ) {
457- // repeat, insert a compound node
458- gm . children . push ( drawNodeNew ( id , ir . declarations . count , 'repeat' , undefined , options ) ) ;
459- if ( prevId ) {
460- prevId . forEach ( pid => gm . edges . push ( drawEdgeNew ( pid , id , gm ) ) ) ;
461- }
462- // body is in ir.body[0].body
463- ir2graph ( ir . body [ 0 ] . body , gm . children [ gm . children . length - 1 ] , `${ id } -body-0-body` , undefined , options ) ;
464-
465- return [ gm . children [ gm . children . length - 1 ] . id ] ;
470+ else if ( ir . type === 'retry' || ir . type === 'repeat' ) {
471+ gm . children . push ( drawNodeNew ( id , ir . count , ir . type , undefined , options ) ) ;
472+ if ( prevId ) {
473+ prevId . forEach ( pid => gm . edges . push ( drawEdgeNew ( pid , id , gm ) ) ) ;
466474 }
467- else {
468- // regular let
469- let s = JSON . stringify ( ir . declarations , undefined , 4 ) ;
470- gm . children . push ( drawNodeNew ( id , s , ir . type , undefined , options ) )
471- if ( prevId )
472- prevId . forEach ( pid => gm . edges . push ( drawEdgeNew ( pid , id , gm ) ) ) ;
475+ // body is in ir.components
476+ ir2graph ( ir . components , gm . children [ gm . children . length - 1 ] , `${ id } -components` , undefined , options ) ;
477+
478+ return [ gm . children [ gm . children . length - 1 ] . id ] ;
479+ }
480+ else if ( ir . type === 'let' ) {
481+ // regular let
482+ let s = JSON . stringify ( ir . declarations , undefined , 4 ) ;
483+ gm . children . push ( drawNodeNew ( id , s , ir . type , undefined , options ) )
484+ if ( prevId )
485+ prevId . forEach ( pid => gm . edges . push ( drawEdgeNew ( pid , id , gm ) ) ) ;
473486
474- return ir2graph ( ir . body , gm , `${ id } -body` , [ id ] , options ) ;
475- }
487+ return ir2graph ( ir . components , gm , `${ id } -components` , [ id ] , options ) ;
476488 }
477- else if ( ir . type === 'literal' ) {
489+ else if ( ir . type === 'literal' || ir . type === 'value' ) {
478490 const s = JSON . stringify ( ir . value , undefined , 4 ) ;
479491 gm . children . push ( drawNodeNew ( id , s , ir . type , undefined , options ) )
480492 if ( prevId )
@@ -486,7 +498,7 @@ function ir2graph(ir, gm, id, prevId, options={}){ // ir and graph model
486498 let lastBodyNode = ir2graph ( ir . body , gm , `${ id } -body` , prevId , undefined , options ) ;
487499 return ir2graph ( ir . finalizer , gm , `${ id } -finalizer` , lastBodyNode , undefined , options ) ;
488500 }
489- else if ( typeof ir . body === 'object' ) {
501+ else if ( typeof ir . components === 'object' ) {
490502 // generic handler for any subgraph-via-body node
491503 const label = capitalize ( ir . type ) ,
492504 type = ir . type ,
@@ -499,13 +511,13 @@ function ir2graph(ir, gm, id, prevId, options={}){ // ir and graph model
499511 if ( prevId )
500512 prevId . forEach ( pid => gm . edges . push ( drawEdgeNew ( pid , id , gm ) ) ) ;
501513
502- ir2graph ( ir . body , body , `${ id } -body ` , undefined , options )
514+ ir2graph ( ir . components , body , `${ id } -components ` , undefined , options )
503515
504516 return [ id ]
505517
506518 } else {
507519 console . error ( 'wskflow warning! unsupported node type' , ir )
508- }
520+ }
509521 }
510522}
511523
@@ -533,7 +545,7 @@ function fsm2graph(ir, containerElement, acts, options){
533545 activations . forEach ( ( a , index ) => {
534546 if ( a . logs ) { // states recorded in logs
535547 a . logs . forEach ( log => {
536- if ( log . indexOf ( 'stdout: Entering state ' ) !== - 1 ) {
548+ if ( log . indexOf ( 'stdout: Entering composition ' ) !== - 1 ) {
537549 // a conductor path log
538550 let path = log . substring ( log . lastIndexOf ( ' ' ) + 1 ) ;
539551 // replace all [,],.in path to - to use as a id, as css selector cannot have those characters
@@ -564,7 +576,7 @@ function fsm2graph(ir, containerElement, acts, options){
564576 viewOptions = Object . assign ( { renderFunctionsInView } , options )
565577
566578 graphData . children . push ( drawNodeNew ( 'Entry' , 'start' , 'Entry' ) ) ; // insert Entry node
567- let lastNodes = ir2graph ( ir . composition , graphData , 'fsm ' , [ 'Entry' ] , // build the graph model, link the start of the graph to Entry
579+ let lastNodes = ir2graph ( ir , graphData , 'composition ' , [ 'Entry' ] , // build the graph model, link the start of the graph to Entry
568580 viewOptions ) ; // <-- options to the rendering
569581 if ( lastNodes == undefined )
570582 lastNodes = [ 'Entry' ] ;
@@ -665,8 +677,8 @@ function fsm2graph(ir, containerElement, acts, options){
665677 *
666678 */
667679const isSimpleComposition = ir => {
668- const isShort = ir . composition . length <= 2 ,
669- numNonFuncs = numNonFunctions ( ir . composition ) ,
680+ const isShort = ir . components ? ir . components . length <= 2 : true ,
681+ numNonFuncs = numNonFunctions ( ir ) ,
670682 atMostOneNonFunction = numNonFuncs <= 3
671683
672684 debug ( 'isSimpleComposition' , isShort , numNonFuncs )
@@ -678,6 +690,7 @@ const isSimpleComposition = ir => {
678690 *
679691 */
680692const numNonFunctions = composition => {
693+ if ( composition === undefined ) return 0
681694 if ( composition . type === 'function' ) {
682695 return 0
683696 } else if ( composition . type ) {
0 commit comments