88 RecipeMeta ,
99 Runtime ,
1010 RuntimeProgram ,
11+ UI ,
1112} from "@commontools/runner" ;
1213import { StorageManager } from "@commontools/runner/storage/cache" ;
1314import {
@@ -404,16 +405,22 @@ function createShortId(id: string): string {
404405
405406function createCharmConnection (
406407 charm : { id : string ; name ?: string } ,
407- details ?: { name ?: string ; readingFrom : Array < { id : string } > ; readBy : Array < { id : string } > } ,
408+ details ?: {
409+ name ?: string ;
410+ readingFrom : Array < { id : string } > ;
411+ readBy : Array < { id : string } > ;
412+ } ,
408413) : CharmConnection {
409414 return {
410415 name : details ?. name || charm . name || createShortId ( charm . id ) ,
411- readingFrom : details ?. readingFrom . map ( c => c . id ) || [ ] ,
412- readBy : details ?. readBy . map ( c => c . id ) || [ ] ,
416+ readingFrom : details ?. readingFrom . map ( ( c ) => c . id ) || [ ] ,
417+ readBy : details ?. readBy . map ( ( c ) => c . id ) || [ ] ,
413418 } ;
414419}
415420
416- async function buildConnectionMap ( config : SpaceConfig ) : Promise < CharmConnectionMap > {
421+ async function buildConnectionMap (
422+ config : SpaceConfig ,
423+ ) : Promise < CharmConnectionMap > {
417424 const charms = await listCharms ( config ) ;
418425 const connections : CharmConnectionMap = new Map ( ) ;
419426
@@ -424,7 +431,11 @@ async function buildConnectionMap(config: SpaceConfig): Promise<CharmConnectionM
424431 connections . set ( charm . id , createCharmConnection ( charm , details ) ) ;
425432 } catch ( error ) {
426433 // Skip charms that can't be inspected, but include them with no connections
427- console . error ( `Warning: Could not inspect charm ${ charm . id } : ${ error instanceof Error ? error . message : String ( error ) } ` ) ;
434+ console . error (
435+ `Warning: Could not inspect charm ${ charm . id } : ${
436+ error instanceof Error ? error . message : String ( error )
437+ } `,
438+ ) ;
428439 connections . set ( charm . id , createCharmConnection ( charm ) ) ;
429440 }
430441 }
@@ -441,35 +452,37 @@ function generateAsciiMap(connections: CharmConnectionMap): string {
441452
442453 // Sort charms by connection count for better visualization
443454 const sortedCharms = Array . from ( connections . entries ( ) ) . sort (
444- ( [ , a ] , [ , b ] ) =>
445- ( b . readingFrom . length + b . readBy . length ) -
446- ( a . readingFrom . length + a . readBy . length )
455+ ( [ , a ] , [ , b ] ) =>
456+ ( b . readingFrom . length + b . readBy . length ) -
457+ ( a . readingFrom . length + a . readBy . length ) ,
447458 ) ;
448459
449460 for ( const [ id , info ] of sortedCharms ) {
450461 const shortId = createShortId ( id ) ;
451462 output += `📦 ${ info . name } [${ shortId } ]\n` ;
452-
463+
453464 if ( info . readingFrom . length > 0 ) {
454465 output += " ← reads from:\n" ;
455466 for ( const sourceId of info . readingFrom ) {
456- const sourceName = connections . get ( sourceId ) ?. name || createShortId ( sourceId ) ;
467+ const sourceName = connections . get ( sourceId ) ?. name ||
468+ createShortId ( sourceId ) ;
457469 output += ` • ${ sourceName } \n` ;
458470 }
459471 }
460-
472+
461473 if ( info . readBy . length > 0 ) {
462474 output += " → read by:\n" ;
463475 for ( const targetId of info . readBy ) {
464- const targetName = connections . get ( targetId ) ?. name || createShortId ( targetId ) ;
476+ const targetName = connections . get ( targetId ) ?. name ||
477+ createShortId ( targetId ) ;
465478 output += ` • ${ targetName } \n` ;
466479 }
467480 }
468-
481+
469482 if ( info . readingFrom . length === 0 && info . readBy . length === 0 ) {
470483 output += " (no connections)\n" ;
471484 }
472-
485+
473486 output += "\n" ;
474487 }
475488
@@ -504,11 +517,16 @@ export enum MapFormat {
504517 DOT = "dot" ,
505518}
506519
507- export async function getCharmConnections ( config : SpaceConfig ) : Promise < CharmConnectionMap > {
520+ export async function getCharmConnections (
521+ config : SpaceConfig ,
522+ ) : Promise < CharmConnectionMap > {
508523 return await buildConnectionMap ( config ) ;
509524}
510525
511- export function formatSpaceMap ( connections : CharmConnectionMap , format : MapFormat ) : string {
526+ export function formatSpaceMap (
527+ connections : CharmConnectionMap ,
528+ format : MapFormat ,
529+ ) : string {
512530 switch ( format ) {
513531 case MapFormat . ASCII :
514532 return generateAsciiMap ( connections ) ;
@@ -519,7 +537,10 @@ export function formatSpaceMap(connections: CharmConnectionMap, format: MapForma
519537 }
520538}
521539
522- export async function generateSpaceMap ( config : SpaceConfig , format : MapFormat = MapFormat . ASCII ) : Promise < string > {
540+ export async function generateSpaceMap (
541+ config : SpaceConfig ,
542+ format : MapFormat = MapFormat . ASCII ,
543+ ) : Promise < string > {
523544 const connections = await getCharmConnections ( config ) ;
524545 return formatSpaceMap ( connections , format ) ;
525546}
@@ -578,3 +599,39 @@ export async function inspectCharm(
578599 readBy,
579600 } ;
580601}
602+
603+ export async function getCharmView (
604+ config : CharmConfig ,
605+ ) : Promise < unknown > {
606+ const data = await inspectCharm ( config ) ;
607+ return data . result ?. [ UI ] ;
608+ }
609+
610+ export function formatViewTree ( view : unknown ) : string {
611+ const isVNode = ( v : any ) : v is { name : string ; children : any [ ] } => {
612+ return v && typeof v === "object" && v . type === "vnode" && v . name ;
613+ } ;
614+
615+ const format = (
616+ node : unknown ,
617+ prefix : string ,
618+ last : boolean ,
619+ ) : string => {
620+ const branch = last ? "└─ " : "├─ " ;
621+ if ( ! isVNode ( node ) ) {
622+ return `${ prefix } ${ branch } ${ String ( node ) } ` ;
623+ }
624+
625+ const children = Array . isArray ( node . children ) ? node . children : [ ] ;
626+ let output = `${ prefix } ${ branch } ${ node . name } ` ;
627+ const nextPrefix = prefix + ( last ? " " : "│ " ) ;
628+ for ( let i = 0 ; i < children . length ; i ++ ) {
629+ const child = children [ i ] ;
630+ const isLast = i === children . length - 1 ;
631+ output += "\n" + format ( child , nextPrefix , isLast ) ;
632+ }
633+ return output ;
634+ } ;
635+
636+ return format ( view , "" , true ) ;
637+ }
0 commit comments