likec4 1.27.2 → 1.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import{relative as Z}from"node:path";import{f as ee,g as x,T as te,N as U,i as ne,n as _,j as S,u as m,l as ie,C as re,a as oe,b as D,c as ae,t as se,d as P,m as de,p as ce,e as O,L as le}from"./likec4.D_S6au6n.mjs";function pe(t){var e,i;if(t){if("astNode"in t)return ge(t);if(Array.isArray(t))return t.reduce(A,void 0);{const n=t,r=ue(n)?fe((i=(e=n?.root)===null||e===void 0?void 0:e.astNode)!==null&&i!==void 0?i:n?.astNode):void 0;return v(n,r)}}else return}function ue(t){return typeof t<"u"&&"e\
1
+ import{relative as Z}from"node:path";import{f as ee,g as x,T as te,N as U,i as ne,n as _,j as S,u as m,l as ie,C as re,a as oe,b as D,c as ae,t as se,d as P,m as de,p as ce,e as O,L as le}from"./likec4.10Nsb-Q7.mjs";function pe(t){var e,i;if(t){if("astNode"in t)return ge(t);if(Array.isArray(t))return t.reduce(A,void 0);{const n=t,r=ue(n)?fe((i=(e=n?.root)===null||e===void 0?void 0:e.astNode)!==null&&i!==void 0?i:n?.astNode):void 0;return v(n,r)}}else return}function ue(t){return typeof t<"u"&&"e\
2
2
  lement"in t&&"text"in t}function fe(t){try{return x(t).uri.toString()}catch{return}}function ge(t){var e,i;const{astNode:n,property:r,index:a}=t??{},o=(e=n?.$cstNode)!==null&&e!==void 0?e:n?.$textRegion;if(!(n===void 0||o===void 0)){if(r===void 0)return v(o,T(n));{const s=d=>a!==void 0&&a>-1&&Array.isArray(n[r])?a<d.length?d[a]:void 0:d.reduce(A,void 0);if(!((i=o.assignments)===null||i===void 0)&&i[r]){const d=s(o.assignments[r]);return d&&v(d,T(n))}else if(n.$cstNode){const d=s(ee(n.$cstNode,r));
3
3
  return d&&v(d,T(n))}else return}}}function T(t){var e,i,n,r;return t.$cstNode?(i=(e=x(t))===null||e===void 0?void 0:e.uri)===null||i===void 0?void 0:i.toString():t.$textRegion?t.$textRegion.documentURI||((r=(n=new te(t,a=>a.$container?[a.$container]:[]).find(a=>{var o;return(o=a.$textRegion)===null||o===void 0?void 0:o.documentURI}))===null||n===void 0?void 0:n.$textRegion)===null||r===void 0?void 0:r.documentURI):void 0}function v(t,e){var i,n;const r={offset:t.offset,end:(i=t.end)!==null&&i!==
4
4
  void 0?i:t.offset+t.length,length:(n=t.length)!==null&&n!==void 0?n:t.end-t.offset};return t.range&&(r.range=t.range),e??(e=t.fileURI),e&&(r.fileURI=e),r}function A(t,e){var i,n;if(t){if(!e)return t&&v(t)}else return e&&v(e);const r=(i=t.end)!==null&&i!==void 0?i:t.offset+t.length,a=(n=e.end)!==null&&n!==void 0?n:e.offset+e.length,o=Math.min(t.offset,e.offset),s=Math.max(r,a),d=s-o,c={offset:o,end:s,length:d};if(t.range&&e.range&&(c.range={start:e.range.start.line<t.range.start.line||e.range.start.
@@ -8640,24 +8640,24 @@ declare class Graph<
8640
8640
  GraphAttributes extends Attributes = Attributes
8641
8641
  > extends AbstractGraph<NodeAttributes, EdgeAttributes, GraphAttributes> {}
8642
8642
 
8643
- const DefaultEdgeStyle="dashed";const E$1=defaultTheme.font,D=createLogger("dot");class DotPrinter{constructor(e){this.view=e;this.compoundIds=new Set(e.nodes.filter(isCompound).map(
8644
- t=>t.id)),this.edgesWithCompounds=new Set(this.compoundIds.size>0?e.edges.filter(t=>this.compoundIds.has(t.source)||this.compoundIds.has(t.target)).map(t=>t.id):[]);for(const t of e.nodes)this.graphology.addNode(t.id,{origin:t,level:t.level,depth:t.depth??0,modelRef:ComputedNode.modelRef(t),deploymentRef:ComputedNode.deploymentRef(t),maxConnectedHierarchyDistance:0});for(const t of e.edges){let r=this.graphology.getNodeAttribute(t.source,"deploymentRef"),s=this.graphology.getNodeAttribute(t.target,"deploymentRef");(r===
8645
- null||s===null)&&(r=this.graphology.getNodeAttribute(t.source,"modelRef"),s=this.graphology.getNodeAttribute(t.target,"modelRef"));let d=-1;r!==null&&s!==null?d=hierarchyDistance(r,s):D.warn(`Edge ${t.id} of view ${e.id} is invalid, sourceFqn: ${r}, targetFqn: ${s}`),this.graphology.addEdgeWithKey(t.id,t.source,t.target,{origin:t,hierarchyDistance:d,weight:1}),d>this.graphology.getNodeAttribute(t.source,"maxConnectedHierarchyDistance")&&this.graphology.mergeNodeAttributes(t.source,{maxConnectedHierarchyDistance:d}),
8646
- d>this.graphology.getNodeAttribute(t.target,"maxConnectedHierarchyDistance")&&this.graphology.mergeNodeAttributes(t.target,{maxConnectedHierarchyDistance:d});}this.graphology.forEachEdge((t,{hierarchyDistance:r},s,d,n,a)=>{const p=Math.max(n.maxConnectedHierarchyDistance,a.maxConnectedHierarchyDistance);if(p>r)this.graphology.mergeEdgeAttributes(t,{weight:p-r+1});else {const g=this.graphology.directedDegree(s),$=this.graphology.directedDegree(d);g===1&&$===1&&r>1&&this.graphology.mergeEdgeAttributes(
8647
- t,{weight:r});}});const i=this.graphvizModel=this.createGraph();this.applyNodeAttributes(i.attributes.node),this.applyEdgeAttributes(i.attributes.edge);}ids=new Set;subgraphs=new Map;nodes=new Map;edges=new Map;compoundIds;edgesWithCompounds;graphology=new Graph({allowSelfLoops:true,multi:true,type:"directed"});graphvizModel;get hasEdgesWithCompounds(){return this.edgesWithCompounds.size>0}postBuild(e){}build(e){const i=(r,s)=>{const d=this.generateGraphvizId(r),n=this.elementToSubgraph(r,s.subgraph(d));this.
8648
- subgraphs.set(r.id,n);for(const a of r.children){const p=this.computedNode(a);if(isCompound(p))i(p,n);else {const g=nonNullable(this.getGraphNode(p.id),`Graphviz Node not found for ${p.id}`);n.node(g.id);}}},t=[];for(const r of this.view.nodes)if(isCompound(r))isNullish(r.parent)&&t.push(r);else {const s=this.generateGraphvizId(r),d=this.elementToNode(r,e.node(s));this.nodes.set(r.id,d);}for(const r of t)i(r,e);for(const r of this.view.edges){const s=this.addEdge(r,e);s&&this.edges.set(r.id,s);}}print(){const e=this.graphvizModel;return this.
8649
- build(e),this.postBuild(e),toDot(this.graphvizModel,{print:{indentStyle:"space",indentSize:2}})}createGraph(){const e=this.view.autoLayout,i=digraph({[attribute.bgcolor]:"transparent",[attribute.layout]:"dot",[attribute.compound]:true,[attribute.rankdir]:e.direction,[attribute.TBbalance]:"min",[attribute.splines]:"spline",[attribute.outputorder]:"nodesfirst",[attribute.nodesep]:pxToInch(e.nodeSep??110),[attribute.ranksep]:pxToInch(e.rankSep??120),[attribute.pad]:pxToInch(15),[attribute.fontname]:E$1});return i.attributes.graph.apply({[attribute.fontsize]:pxToPoints(15),[attribute.labeljust]:e.direction==="RL"?"r":"l",[attribute.labelloc]:e.direction===
8650
- "BT"?"b":"t",[attribute.margin]:50.1}),i}applyNodeAttributes(e){e.apply({[attribute.fontname]:E$1,[attribute.shape]:"rect",[attribute.fillcolor]:defaultTheme.elements[DefaultThemeColor].fill,[attribute.fontcolor]:defaultTheme.elements[DefaultThemeColor].hiContrast,[attribute.color]:defaultTheme.elements[DefaultThemeColor].stroke,[attribute.style]:"filled",[attribute.penwidth]:0});}applyEdgeAttributes(e){e.apply({[attribute.arrowsize]:.75,[attribute.fontname]:E$1,[attribute.fontsize]:pxToPoints(14),[attribute.penwidth]:pxToPoints(2),[attribute.color]:defaultTheme.relationships[DefaultRelationshipColor].lineColor,[attribute.fontcolor]:defaultTheme.relationships[DefaultRelationshipColor].labelColor});}checkNodeId(e,i=false){return i?e="cluster_"+e:e.toLowerCase().startsWith("clust\
8651
- er")&&(e="nd_"+e),this.ids.has(e)?null:(this.ids.add(e),e)}generateGraphvizId(e){const i=isCompound(e);let t=nameFromFqn(e.id).toLowerCase(),r=this.checkNodeId(t,i);if(r!==null)return r;t=nameFromFqn(e.id).toLowerCase();let s=1;do r=this.checkNodeId(t+"_"+s++,i);while(r===null);return r}elementToSubgraph(e,i){invariant(isCompound(e),"node should be compound"),invariant(isNumber(e.depth),"node.depth should be defined");const t=this.getElementColorValues(e.color),r=compoundLabelColor(t.loContrast);return i.apply({[attribute.likec4_id]:e.id,[attribute.likec4_level]:e.level,[attribute.likec4_depth]:e.
8652
- depth,[attribute.fillcolor]:compoundColor(t.fill,e.depth),[attribute.color]:compoundColor(t.stroke,e.depth),[attribute.style]:"filled",[attribute.margin]:pxToPoints(e.children.length>1?40:32)}),isEmpty(e.title.trim())||i.set(attribute.label,compoundLabel(e,r)),i}elementToNode(e,i){invariant(!isCompound(e),"node should not be compound");const t=isTruthy(e.icon),r=this.getElementColorValues(e.color);let s=e.style.size,d=e.style.textSize,n=e.style.padding;!s&&d&&(s=d),!d&&s&&(d=s),!n&&s&&(n=s),s??=DefaultShapeSize,d??=DefaultTextSize,n??=DefaultPaddingSize;const a=defaultTheme.spacing[n];switch(i.attributes.apply({[attribute.likec4_id]:e.id,[attribute.likec4_level]:e.level,[attribute.label]:nodeLabel(
8653
- e,r,{shape:s,text:d}),[attribute.margin]:`${pxToInch(t?8:a)},${pxToInch(a)}`}),i.attributes.set(attribute.width,pxToInch(defaultTheme.sizes[s].width)),i.attributes.set(attribute.height,pxToInch(defaultTheme.sizes[s].height)),e.color!==DefaultThemeColor&&i.attributes.apply({[attribute.fillcolor]:r.fill,[attribute.fontcolor]:r.hiContrast,[attribute.color]:r.stroke}),e.shape){case "cylinder":case "storage":{i.attributes.apply({[attribute.margin]:`${pxToInch(t?8:a)},${pxToInch(0)}`,[attribute.penwidth]:pxToPoints(2),[attribute.shape]:"cylinder"});break}case "browser":{i.attributes.apply({[attribute.margin]:`${pxToInch(t?8:a+4)},${pxToInch(a+6)}`});break}case "mobile":{i.attributes.
8654
- apply({[attribute.margin]:`${pxToInch(t?8:a+4)},${pxToInch(a)}`});break}case "queue":{i.attributes.apply({[attribute.width]:pxToInch(defaultTheme.sizes[s].width),[attribute.height]:pxToInch(defaultTheme.sizes[s].height-8),[attribute.margin]:`${pxToInch(t?8:a+4)},${pxToInch(a)}`});break}}return i}leafElements(e){return e===null?this.view.nodes.filter(i=>!isCompound(i)):this.computedNode(e).children.flatMap(i=>{const t=this.computedNode(i);return isCompound(t)?this.leafElements(t.id):t})}descendants(e){return e===null?this.view.nodes.slice():this.computedNode(e).children.flatMap(i=>{const t=this.computedNode(
8655
- i);return [t,...this.descendants(t.id)]})}computedNode(e){return nonNullable(this.view.nodes.find(i=>i.id===e),`Node ${e} not found`)}getGraphNode(e){return this.nodes.get(e)??null}getSubgraph(e){return this.subgraphs.get(e)??null}edgeEndpoint(e,i){let t=this.computedNode(e),r=this.getGraphNode(e),s;return r||(invariant(isCompound(t),"endpoint node should be compound"),s=this.getSubgraph(e)?.id,invariant(s,`subgraph ${e} not found`),t=nonNullable(i(this.leafElements(e)),`leaf element in ${e} not found`),r=nonNullable(this.getGraphNode(t.id),`source g\
8656
- raphviz node ${t.id} not found`)),[t,r,s]}findInternalEdges(e){if(e===null)return this.view.edges.slice();const i=this.computedNode(e);return pipe(this.descendants(e),flatMap(t=>concat(t.inEdges,t.outEdges)),unique(),difference(concat(i.inEdges,i.outEdges)),map(t=>this.view.edges.find(r=>r.id===t)),filter(isTruthy))}withoutCompoundEdges(e){return this.edgesWithCompounds.size===0?e:{...e,inEdges:e.inEdges.filter(i=>!this.edgesWithCompounds.has(i)),outEdges:e.outEdges.filter(i=>!this.edgesWithCompounds.has(i))}}assignGroups(){const e=pipe(this.view.
8657
- nodes,filter(isCompound),map(t=>t.id),sort(compareFqnHierarchically),reverse(),map(t=>{const r=this.findInternalEdges(t).filter(s=>s.source!==s.target&&!this.compoundIds.has(s.source)&&!this.compoundIds.has(s.target));return {id:t,edges:r}}),filter(({edges:t})=>t.length>1&&t.length<8),take(4)),i=new Set;for(const t of e){const r=t.edges.filter(s=>!i.has(s.source)&&!i.has(s.target));for(const s of r)try{const d=nonNullable(this.getGraphNode(s.source),`Graphviz Node not found for ${s.source}`),n=nonNullable(this.getGraphNode(s.target),`Graphviz Node not found for ${s.target}`);
8658
- i.add(s.source),i.add(s.target),d.attributes.set(attribute.group,t.id),n.attributes.set(attribute.group,t.id);}catch(d){D.error(`Failed to assign group to edge ${s.id}`,{error:d});}}}applyManualLayout({height:e,...i}){const t=i.x<0?-i.x:0,r=i.y<0?-i.y:0,s=t>0||r>0;for(const{id:d,...n}of i.nodes){const a=this.getGraphNode(d);if(!a)continue;const p=pxToInch(n.center.x)+t,g=pxToInch(e-n.center.y);n.fixedsize?a.attributes.apply({[attribute.pos]:`${p},${g}!`,[attribute.pin]:true,[attribute.width]:pxToInch(n.fixedsize.width),[attribute.height]:pxToInch(n.fixedsize.height),[attribute.fixedsize]:true}):
8659
- a.attributes.set(attribute.pos,`${p},${g}`);}for(const[d,n]of this.edges.entries()){n.attributes.delete(attribute.weight),n.attributes.delete(attribute.minlen),n.attributes.delete(attribute.constraint);const a=i.edges.find(p=>p.id===d)?.dotpos;a&&!s&&n.attributes.set(attribute.pos,a);}return this.graphvizModel.apply({[attribute.layout]:"fdp",[attribute.overlap]:"vpsc",[attribute.sep]:"+50,50",[attribute.esep]:"+10,10",[attribute.start]:"random2",[attribute.splines]:"compound"}),this.graphvizModel.delete(attribute.compound),this.graphvizModel.delete(attribute.rankdir),this.graphvizModel.delete(attribute.nodesep),
8660
- this.graphvizModel.delete(attribute.ranksep),this.graphvizModel.delete(attribute.pack),this.graphvizModel.delete(attribute.pad),this.graphvizModel.delete(attribute.packmode),this.graphvizModel.attributes.graph.delete(attribute.margin),this}getRelationshipColorValues(e){return isThemeColor(e)?defaultTheme.relationships[e]:this.view.customColorDefinitions[e]?.relationships??defaultTheme.relationships[DefaultThemeColor]}getElementColorValues(e){return isThemeColor(e)?defaultTheme.elements[e]:this.view.customColorDefinitions[e]?.elements??defaultTheme.elements[DefaultThemeColor]}}
8643
+ const DefaultEdgeStyle="dashed";const v=defaultTheme.font,D=createLogger("dot");class DotPrinter{constructor(e){this.view=e;this.compoundIds=new Set(e.nodes.filter(isCompound).map(
8644
+ t=>t.id)),this.edgesWithCompounds=new Set(this.compoundIds.size>0?e.edges.filter(t=>this.compoundIds.has(t.source)||this.compoundIds.has(t.target)).map(t=>t.id):[]);for(const t of e.nodes)this.graphology.addNode(t.id,{origin:t,level:t.level,depth:t.depth??0,modelRef:ComputedNode.modelRef(t),deploymentRef:ComputedNode.deploymentRef(t),maxConnectedHierarchyDistance:0});for(const t of e.edges){let s=this.graphology.getNodeAttribute(t.source,"deploymentRef"),r=this.graphology.getNodeAttribute(t.target,"deploymentRef");(s===
8645
+ null||r===null)&&(s=this.graphology.getNodeAttribute(t.source,"modelRef"),r=this.graphology.getNodeAttribute(t.target,"modelRef"));let d=-1;s!==null&&r!==null?d=hierarchyDistance(s,r):D.warn(`Edge ${t.id} of view ${e.id} is invalid, sourceFqn: ${s}, targetFqn: ${r}`),this.graphology.addEdgeWithKey(t.id,t.source,t.target,{origin:t,hierarchyDistance:d,weight:1}),d>this.graphology.getNodeAttribute(t.source,"maxConnectedHierarchyDistance")&&this.graphology.mergeNodeAttributes(t.source,{maxConnectedHierarchyDistance:d}),
8646
+ d>this.graphology.getNodeAttribute(t.target,"maxConnectedHierarchyDistance")&&this.graphology.mergeNodeAttributes(t.target,{maxConnectedHierarchyDistance:d});}this.graphology.forEachEdge((t,{hierarchyDistance:s},r,d,n,a)=>{const p=Math.max(n.maxConnectedHierarchyDistance,a.maxConnectedHierarchyDistance);if(p>s)this.graphology.mergeEdgeAttributes(t,{weight:p-s+1});else {const g=this.graphology.directedDegree(r),$=this.graphology.directedDegree(d);g===1&&$===1&&s>1&&this.graphology.mergeEdgeAttributes(
8647
+ t,{weight:s});}});const i=this.graphvizModel=this.createGraph();this.applyNodeAttributes(i.attributes.node),this.applyEdgeAttributes(i.attributes.edge);}ids=new Set;subgraphs=new Map;nodes=new Map;edges=new Map;compoundIds;edgesWithCompounds;graphology=new Graph({allowSelfLoops:true,multi:true,type:"directed"});graphvizModel;get hasEdgesWithCompounds(){return this.edgesWithCompounds.size>0}postBuild(e){}build(e){const i=(s,r)=>{const d=this.generateGraphvizId(s),n=this.elementToSubgraph(s,r.subgraph(d));this.
8648
+ subgraphs.set(s.id,n);for(const a of s.children){const p=this.computedNode(a);if(isCompound(p))i(p,n);else {const g=nonNullable(this.getGraphNode(p.id),`Graphviz Node not found for ${p.id}`);n.node(g.id);}}},t=[];for(const s of this.view.nodes)if(isCompound(s))isNullish(s.parent)&&t.push(s);else {const r=this.generateGraphvizId(s),d=this.elementToNode(s,e.node(r));this.nodes.set(s.id,d);}for(const s of t)i(s,e);for(const s of this.view.edges){const r=this.addEdge(s,e);r&&this.edges.set(s.id,r);}}print(){const e=this.graphvizModel;return this.
8649
+ build(e),this.postBuild(e),toDot(this.graphvizModel,{print:{indentStyle:"space",indentSize:2}})}createGraph(){const e=this.view.autoLayout,i=digraph({[attribute.likec4_viewId]:this.view.id,[attribute.bgcolor]:"transparent",[attribute.layout]:"dot",[attribute.compound]:true,[attribute.rankdir]:e.direction,[attribute.TBbalance]:"min",[attribute.splines]:"spline",[attribute.outputorder]:"nodesfirst",[attribute.nodesep]:pxToInch(e.nodeSep??110),[attribute.ranksep]:pxToInch(e.rankSep??120),[attribute.pad]:pxToInch(15),[attribute.fontname]:v});return i.attributes.graph.apply({[attribute.fontsize]:pxToPoints(15),[attribute.labeljust]:e.direction==="RL"?
8650
+ "r":"l",[attribute.labelloc]:e.direction==="BT"?"b":"t",[attribute.margin]:50.1}),i}applyNodeAttributes(e){e.apply({[attribute.fontname]:v,[attribute.shape]:"rect",[attribute.fillcolor]:defaultTheme.elements[DefaultThemeColor].fill,[attribute.fontcolor]:defaultTheme.elements[DefaultThemeColor].hiContrast,[attribute.color]:defaultTheme.elements[DefaultThemeColor].stroke,[attribute.style]:"filled",[attribute.penwidth]:0});}applyEdgeAttributes(e){e.apply({[attribute.arrowsize]:.75,[attribute.fontname]:v,[attribute.fontsize]:pxToPoints(14),[attribute.penwidth]:pxToPoints(2),[attribute.color]:defaultTheme.relationships[DefaultRelationshipColor].lineColor,[attribute.fontcolor]:defaultTheme.relationships[DefaultRelationshipColor].labelColor});}checkNodeId(e,i=false){return i?e="cluster_"+
8651
+ e:e.toLowerCase().startsWith("cluster")&&(e="nd_"+e),this.ids.has(e)?null:(this.ids.add(e),e)}generateGraphvizId(e){const i=isCompound(e);let t=nameFromFqn(e.id).toLowerCase(),s=this.checkNodeId(t,i);if(s!==null)return s;t=nameFromFqn(e.id).toLowerCase();let r=1;do s=this.checkNodeId(t+"_"+r++,i);while(s===null);return s}elementToSubgraph(e,i){invariant(isCompound(e),"node should be compound"),invariant(isNumber(e.depth),"node.depth should be defined");const t=this.getElementColorValues(e.color),s=compoundLabelColor(t.loContrast);return i.apply({[attribute.likec4_id]:e.id,[attribute.likec4_level]:e.
8652
+ level,[attribute.likec4_depth]:e.depth,[attribute.fillcolor]:compoundColor(t.fill,e.depth),[attribute.color]:compoundColor(t.stroke,e.depth),[attribute.style]:"filled",[attribute.margin]:pxToPoints(e.children.length>1?40:32)}),isEmpty(e.title.trim())||i.set(attribute.label,compoundLabel(e,s)),i}elementToNode(e,i){invariant(!isCompound(e),"node should not be compound");const t=isTruthy(e.icon),s=this.getElementColorValues(e.color);let r=e.style.size,d=e.style.textSize,n=e.style.padding;!r&&d&&(r=d),!d&&r&&(d=r),!n&&r&&(n=r),r??=DefaultShapeSize,d??=DefaultTextSize,n??=DefaultPaddingSize;const a=defaultTheme.spacing[n];switch(i.attributes.apply({[attribute.likec4_id]:e.id,[attribute.likec4_level]:e.
8653
+ level,[attribute.label]:nodeLabel(e,s,{shape:r,text:d}),[attribute.margin]:`${pxToInch(t?8:a)},${pxToInch(a)}`}),i.attributes.set(attribute.width,pxToInch(defaultTheme.sizes[r].width)),i.attributes.set(attribute.height,pxToInch(defaultTheme.sizes[r].height)),e.color!==DefaultThemeColor&&i.attributes.apply({[attribute.fillcolor]:s.fill,[attribute.fontcolor]:s.hiContrast,[attribute.color]:s.stroke}),e.shape){case "cylinder":case "storage":{i.attributes.apply({[attribute.margin]:`${pxToInch(t?8:a)},${pxToInch(0)}`,[attribute.penwidth]:pxToPoints(2),[attribute.shape]:"cylinder"});break}case "browser":{i.attributes.apply({[attribute.margin]:`${pxToInch(t?8:a+4)},${pxToInch(a+6)}`});break}case "\
8654
+ mobile":{i.attributes.apply({[attribute.margin]:`${pxToInch(t?8:a+4)},${pxToInch(a)}`});break}case "queue":{i.attributes.apply({[attribute.width]:pxToInch(defaultTheme.sizes[r].width),[attribute.height]:pxToInch(defaultTheme.sizes[r].height-8),[attribute.margin]:`${pxToInch(t?8:a+4)},${pxToInch(a)}`});break}}return i}leafElements(e){return e===null?this.view.nodes.filter(i=>!isCompound(i)):this.computedNode(e).children.flatMap(i=>{const t=this.computedNode(i);return isCompound(t)?this.leafElements(t.id):t})}descendants(e){return e===null?this.view.nodes.slice():this.computedNode(e).children.flatMap(
8655
+ i=>{const t=this.computedNode(i);return [t,...this.descendants(t.id)]})}computedNode(e){return nonNullable(this.view.nodes.find(i=>i.id===e),`Node ${e} not found`)}getGraphNode(e){return this.nodes.get(e)??null}getSubgraph(e){return this.subgraphs.get(e)??null}edgeEndpoint(e,i){let t=this.computedNode(e),s=this.getGraphNode(e),r;return s||(invariant(isCompound(t),"endpoint node should be compound"),r=this.getSubgraph(e)?.id,invariant(r,`subgraph ${e} not found`),t=nonNullable(i(this.leafElements(e)),`leaf element in ${e} not found`),s=nonNullable(this.
8656
+ getGraphNode(t.id),`source graphviz node ${t.id} not found`)),[t,s,r]}findInternalEdges(e){if(e===null)return this.view.edges.slice();const i=this.computedNode(e);return pipe(this.descendants(e),flatMap(t=>concat(t.inEdges,t.outEdges)),unique(),difference(concat(i.inEdges,i.outEdges)),map(t=>this.view.edges.find(s=>s.id===t)),filter(isTruthy))}withoutCompoundEdges(e){return this.edgesWithCompounds.size===0?e:{...e,inEdges:e.inEdges.filter(i=>!this.edgesWithCompounds.has(i)),outEdges:e.outEdges.filter(i=>!this.edgesWithCompounds.has(i))}}assignGroups(){
8657
+ const e=pipe(this.view.nodes,filter(isCompound),map(t=>t.id),sort(compareFqnHierarchically),reverse(),map(t=>{const s=this.findInternalEdges(t).filter(r=>r.source!==r.target&&!this.compoundIds.has(r.source)&&!this.compoundIds.has(r.target));return {id:t,edges:s}}),filter(({edges:t})=>t.length>1&&t.length<8),take(4)),i=new Set;for(const t of e){const s=t.edges.filter(r=>!i.has(r.source)&&!i.has(r.target));for(const r of s)try{const d=nonNullable(this.getGraphNode(r.source),`Graphviz Node not found for ${r.source}`),n=nonNullable(this.getGraphNode(r.target),`Graphviz Node not f\
8658
+ ound for ${r.target}`);i.add(r.source),i.add(r.target),d.attributes.set(attribute.group,t.id),n.attributes.set(attribute.group,t.id);}catch(d){D.error(`Failed to assign group to edge ${r.id}`,{error:d});}}}applyManualLayout({height:e,...i}){const t=i.x<0?-i.x:0,s=i.y<0?-i.y:0,r=t>0||s>0;for(const{id:d,...n}of i.nodes){const a=this.getGraphNode(d);if(!a)continue;const p=pxToInch(n.center.x)+t,g=pxToInch(e-n.center.y);n.fixedsize?a.attributes.apply({[attribute.pos]:`${p},${g}!`,[attribute.pin]:true,[attribute.width]:pxToInch(n.fixedsize.width),[attribute.height]:pxToInch(n.fixedsize.
8659
+ height),[attribute.fixedsize]:true}):a.attributes.set(attribute.pos,`${p},${g}`);}for(const[d,n]of this.edges.entries()){n.attributes.delete(attribute.weight),n.attributes.delete(attribute.minlen),n.attributes.delete(attribute.constraint);const a=i.edges.find(p=>p.id===d)?.dotpos;a&&!r&&n.attributes.set(attribute.pos,a);}return this.graphvizModel.apply({[attribute.layout]:"fdp",[attribute.overlap]:"vpsc",[attribute.sep]:"+50,50",[attribute.esep]:"+10,10",[attribute.start]:"random2",[attribute.splines]:"compound"}),this.graphvizModel.delete(attribute.compound),this.graphvizModel.delete(attribute.rankdir),this.
8660
+ graphvizModel.delete(attribute.nodesep),this.graphvizModel.delete(attribute.ranksep),this.graphvizModel.delete(attribute.pack),this.graphvizModel.delete(attribute.pad),this.graphvizModel.delete(attribute.packmode),this.graphvizModel.attributes.graph.delete(attribute.margin),this}getRelationshipColorValues(e){return isThemeColor(e)?defaultTheme.relationships[e]:this.view.customColorDefinitions[e]?.relationships??defaultTheme.relationships[DefaultThemeColor]}getElementColorValues(e){return isThemeColor(e)?defaultTheme.elements[e]:this.view.customColorDefinitions[e]?.elements??defaultTheme.elements[DefaultThemeColor]}}
8661
8661
 
8662
8662
  class DeploymentViewPrinter extends DotPrinter{createGraph(){
8663
8663
  const e=super.createGraph(),o=this.view.autoLayout;return e.delete(attribute.TBbalance),e.apply({[attribute.nodesep]:pxToInch(o.nodeSep??130),[attribute.ranksep]:pxToInch(o.rankSep??130)}),e}postBuild(e){pipe(this.view.nodes,map(o=>({node:o,graphvizNode:this.getGraphNode(o.id)})),groupBy(({node:o,graphvizNode:a})=>{if(a!=null)return ComputedNode$1.modelRef(o)??void 0}),values(),filter(hasAtLeast(2)),forEach(o=>{e.subgraph({[attribute.rank]:"same"},a=>{for(const{graphvizNode:s}of o)a.node(nonNullable(s).id);});}),tap(()=>{e.set(attribute.newrank,true),e.set(attribute.clusterrank,"global"),e.delete(attribute.pack),e.delete(attribute.packmode);}));}elementToSubgraph(e,o){
@@ -10147,13 +10147,12 @@ interface ReadonlyAction<TInput> extends BaseTransformation<TInput, ReadonlyOutp
10147
10147
  declare function readonly<TInput>(): ReadonlyAction<TInput>;
10148
10148
 
10149
10149
  declare const ProjectConfig: ObjectSchema<{
10150
- readonly name: SchemaWithPipe<readonly [StringSchema<undefined>, NonEmptyAction<string, undefined>, DescriptionAction<string, "Project name, must be unique in the workspace">]>;
10151
- readonly contactPerson: OptionalSchema<SchemaWithPipe<readonly [StringSchema<undefined>, NonEmptyAction<string, undefined>, DescriptionAction<string, "A person who has been involved in creating or maintaining this project">]>, undefined>;
10152
- readonly exclude: OptionalSchema<SchemaWithPipe<readonly [ArraySchema<StringSchema<undefined>, undefined>, DescriptionAction<string[], "List of file patterns to exclude from the project, default is [\"node_modules\"]">]>, undefined>;
10150
+ readonly name: SchemaWithPipe<readonly [SchemaWithPipe<readonly [StringSchema<undefined>, NonEmptyAction<string, undefined>]>, DescriptionAction<string, "Project name, must be unique in the workspace">]>;
10151
+ readonly contactPerson: OptionalSchema<SchemaWithPipe<readonly [SchemaWithPipe<readonly [StringSchema<undefined>, NonEmptyAction<string, undefined>]>, DescriptionAction<string, "A person who has been involved in creating or maintaining this project">]>, undefined>;
10152
+ readonly exclude: OptionalSchema<SchemaWithPipe<readonly [ArraySchema<StringSchema<undefined>, undefined>, DescriptionAction<string[], "List of file patterns to exclude from the project, default is [\"**/node_modules/**/*\"]">]>, undefined>;
10153
10153
  }, undefined>;
10154
10154
  type ProjectConfig = InferOutput<typeof ProjectConfig>;
10155
10155
 
10156
- declare const idattr: unique symbol;
10157
10156
  declare module 'langium' {
10158
10157
  interface LangiumDocument {
10159
10158
  likec4ProjectId?: c4.ProjectId;
@@ -10162,6 +10161,7 @@ declare module 'langium' {
10162
10161
  likec4ProjectId?: c4.ProjectId;
10163
10162
  }
10164
10163
  }
10164
+ declare const idattr: unique symbol;
10165
10165
  declare module './generated/ast' {
10166
10166
  interface Element {
10167
10167
  [idattr]?: c4.Fqn | undefined;
@@ -1,4 +1,4 @@
1
- import { L as LikeC4LanguageServices } from '../shared/likec4.QmEWuoHf.mjs';
1
+ import { L as LikeC4LanguageServices } from '../shared/likec4.DwrogUe0.mjs';
2
2
  import '@likec4/core';
3
3
  import 'type-fest';
4
4
  import '@likec4/core/types';
@@ -1,2 +1,2 @@
1
- export{L as LikeC4VitePlugin}from"../shared/likec4.CfxVv3pJ.mjs";import"node:path";import"../shared/likec4.D_S6au6n.mjs";import"node:fs";import"node:url";import"tty";import"node:util";import"util";import"path";import"os";import"crypto";import"net";import"url";import"fs";import"child_process";import"@likec4/core";import"@likec4/core/types";import"events";import"buffer";import"@hpcc-js/wasm-graphviz";import"@likec4/core/compute-view";import"@likec4/core/utils";import"node:process";import"boxen";import"node:child_process";
1
+ export{L as LikeC4VitePlugin}from"../shared/likec4.7Lz9HWDi.mjs";import"node:path";import"../shared/likec4.10Nsb-Q7.mjs";import"node:fs";import"node:url";import"tty";import"node:util";import"util";import"path";import"os";import"crypto";import"net";import"url";import"fs";import"child_process";import"@likec4/core";import"@likec4/core/types";import"events";import"buffer";import"@hpcc-js/wasm-graphviz";import"@likec4/core/compute-view";import"@likec4/core/utils";import"node:process";import"boxen";import"node:child_process";
2
2
  import"node:events";import"node:fs/promises";import"node:stream/promises";import"node:os";import"fs/promises";import"@likec4/core/model";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "likec4",
3
- "version": "1.27.2",
3
+ "version": "1.28.0",
4
4
  "license": "MIT",
5
5
  "homepage": "https://likec4.dev",
6
6
  "author": "Denis Davydkov <denis@davydkov.com>",
@@ -77,10 +77,10 @@
77
77
  "playwright": "^1.51.1",
78
78
  "react": "^19.0.0",
79
79
  "react-dom": "^19.0.0",
80
- "rollup": "^4.38.0",
81
- "type-fest": "^4.38.0",
82
- "vite": "^6.2.4",
83
- "@likec4/core": "1.27.2"
80
+ "rollup": "^4.39.0",
81
+ "type-fest": "^4.39.1",
82
+ "vite": "^6.2.5",
83
+ "@likec4/core": "1.28.0"
84
84
  },
85
85
  "devDependencies": {
86
86
  "@pandacss/dev": "^0.53.3",
@@ -100,7 +100,7 @@
100
100
  "@types/react-dom": "^19.0.4",
101
101
  "@types/semver": "^7.7.0",
102
102
  "@types/yargs": "^17.0.33",
103
- "@xyflow/react": "^12.5.2",
103
+ "@xyflow/react": "^12.5.3",
104
104
  "@xyflow/system": "^0.0.53",
105
105
  "dts-bundle-generator": "^9.5.1",
106
106
  "autoprefixer": "^10.4.21",
@@ -109,17 +109,17 @@
109
109
  "conf": "^13.1.0",
110
110
  "consola": "^3.4.2",
111
111
  "defu": "^6.1.4",
112
- "esbuild": "^0.25.1",
112
+ "esbuild": "^0.25.2",
113
113
  "esbuild-node-externals": "^1.18.0",
114
114
  "esm-env": "^1.2.2",
115
115
  "fast-equals": "^5.2.2",
116
116
  "fdir": "^6.4.3",
117
- "framer-motion": "^12.6.2",
117
+ "framer-motion": "^12.6.3",
118
118
  "get-port": "^7.1.0",
119
119
  "glob": "^11.0.1",
120
120
  "html-to-image": "^1.11.13",
121
121
  "json5": "^2.2.3",
122
- "ky": "^1.7.5",
122
+ "ky": "^1.8.0",
123
123
  "langium": "3.4.0",
124
124
  "merge-error-cause": "^5.0.2",
125
125
  "mkdirp": "^3.0.1",
@@ -141,14 +141,14 @@
141
141
  "terser": "^5.39.0",
142
142
  "tinyrainbow": "^2.0.0",
143
143
  "tsx": "~4.19.3",
144
- "turbo": "^2.4.4",
145
- "typescript": "^5.8.2",
144
+ "turbo": "^2.5.0",
145
+ "typescript": "^5.8.3",
146
146
  "ufo": "^1.5.4",
147
147
  "unbuild": "^3.5.0",
148
148
  "vite-plugin-dts": "^4.5.3",
149
149
  "vite-plugin-inspect": "^11.0.0",
150
150
  "vite-plugin-singlefile": "^2.2.0",
151
- "vitest": "^3.0.9",
151
+ "vitest": "^3.1.1",
152
152
  "vscode-jsonrpc": "8.2.0",
153
153
  "vscode-languageserver": "9.0.1",
154
154
  "vscode-languageserver-types": "3.17.5",
@@ -156,15 +156,15 @@
156
156
  "wireit": "^0.14.11",
157
157
  "which": "^5.0.0",
158
158
  "yargs": "17.7.2",
159
- "@likec4/style-preset": "1.27.2",
160
- "@likec4/styles": "1.27.2",
161
- "@likec4/diagram": "1.27.2",
162
- "@likec4/icons": "1.27.2",
163
- "@likec4/language-server": "1.27.2",
164
- "@likec4/layouts": "1.27.2",
165
- "@likec4/generators": "1.27.2",
166
- "@likec4/log": "1.27.2",
167
- "@likec4/tsconfig": "1.27.2"
159
+ "@likec4/style-preset": "1.28.0",
160
+ "@likec4/diagram": "1.28.0",
161
+ "@likec4/styles": "1.28.0",
162
+ "@likec4/generators": "1.28.0",
163
+ "@likec4/icons": "1.28.0",
164
+ "@likec4/language-server": "1.28.0",
165
+ "@likec4/layouts": "1.28.0",
166
+ "@likec4/log": "1.28.0",
167
+ "@likec4/tsconfig": "1.28.0"
168
168
  },
169
169
  "scripts": {
170
170
  "typecheck": "tsc --build --verbose",