import { createGraphEngine } from '@graphora/engine' import { createForceLayout } from '@graphora/layouts' import { CanvasGraphRenderer, GRAPHORA_STYLE_ATTRIBUTE, createViewport } from '@graphora/renderer' import './style.css' const container = document.querySelector('#graph') if (container === null) { throw new Error('Missing graph container.') } void main() async function main(): Promise { const services = [ 'Gateway', 'Auth', 'Billing', 'Search', 'Orders', 'Inventory', 'Email' ] const graph = { nodes: services.map((label, index) => ({ id: label.toLowerCase(), label, attributes: { [GRAPHORA_STYLE_ATTRIBUTE]: { fill: index === 0 ? '#0f766e' : '#2563eb', radius: index === 0 ? 26 : 18 } } })), edges: [ ['gateway', 'auth'], ['gateway', 'orders'], ['gateway', 'search'], ['orders', 'billing'], ['orders', 'inventory'], ['billing', 'email'], ['inventory', 'email'], ['search', 'inventory'] ].map(([source, target], index) => ({ id: `${source}-${target}`, source, target, attributes: { [GRAPHORA_STYLE_ATTRIBUTE]: { stroke: index % 2 === 0 ? '#64748b' : '#94a3b8', strokeWidth: 1.8 } } })) } const renderer = new CanvasGraphRenderer() const engine = createGraphEngine({ graph, renderer, layout: createForceLayout({ iterations: 120, linkDistance: 96, chargeStrength: -260, collisionRadius: 30, seed: 4 }), viewport: createViewport({ width: container.clientWidth, height: container.clientHeight }), theme: { backgroundColor: '#fbfdff', label: { fontSize: 12 }, edge: { arrow: { end: true, size: 7 } } } }) engine.mount(container) await engine.runLayout({ fitToView: { padding: 64 } }) }