/** * Canvas graph: example graph and initial graph from storage. * Used by useCanvasGraph and CanvasPage (e.g. Load example). */ import type { AppNode, AppEdge } from '@/lib/graph/nodeTypes' import { DEFAULT_NODE_STYLE } from '@/lib/graph/flowUtils' import { loadGraphFromStorage } from '@/app/pleroma/projectGraphStorage' /** Ensure each edge has data.targetType from the target node (for labels without depending on nodes in edgesForFlow). */ export function backfillEdgeTargetTypes( nodes: AppNode[], edges: AppEdge[] ): AppEdge[] { const typeById = new Map(nodes.map((n) => [n.id, n.type ?? ''])) return edges.map((e) => { const targetType = typeById.get(e.target) ?? (e.data as Record)?.targetType ?? '' const data = typeof e.data === 'object' && e.data !== null ? (e.data as Record) : {} if (data.targetType === targetType) return e return { ...e, data: { ...data, targetType } } }) } const NODE_GAP = 150 const EXAMPLE_NODES: AppNode[] = [ { id: 'var_001', position: { x: 50, y: 100 }, data: { value: 'Zoe', valueType: 'string' as const }, type: 'variable', style: DEFAULT_NODE_STYLE.variable, }, { id: 'cfg_001', position: { x: 50 + DEFAULT_NODE_STYLE.variable.width + NODE_GAP, y: 50 }, data: { plantuml: '@startuml\nactor User\nparticipant "{{ var_001 }}" as R\nUser -> R : loves\n@enduml\n', title: 'config-cfg_001', }, type: 'config', style: DEFAULT_NODE_STYLE.config, }, { id: 'rnd_001', position: { x: 50 + DEFAULT_NODE_STYLE.variable.width + NODE_GAP + DEFAULT_NODE_STYLE.config.width + NODE_GAP, y: 50, }, data: {}, type: 'render', style: DEFAULT_NODE_STYLE.render, }, ] const EXAMPLE_EDGES: AppEdge[] = [ { id: 'e-var_001-cfg_001', source: 'var_001', target: 'cfg_001', type: 'animated' }, { id: 'e-cfg_001-rnd_001', source: 'cfg_001', target: 'rnd_001', type: 'animated' }, ] export function getExampleGraph(): { nodes: AppNode[]; edges: AppEdge[] } { const nodes = EXAMPLE_NODES.map((n) => ({ ...n, data: n.data && typeof n.data === 'object' ? { ...(n.data as object) } : n.data, })) const edges = backfillEdgeTargetTypes( nodes, EXAMPLE_EDGES.map((e) => ({ ...e })) ) return { nodes, edges } } export function getInitialGraph(projectId: string | undefined): { nodes: AppNode[]; edges: AppEdge[] } { if (projectId) { const stored = loadGraphFromStorage(projectId) if (stored && (stored.nodes.length > 0 || stored.edges.length > 0)) { const nodes = stored.nodes as AppNode[] const edges = backfillEdgeTargetTypes(nodes, stored.edges as AppEdge[]) return { nodes, edges } } return { nodes: [], edges: [] } } return getExampleGraph() }