@likec4/core 0.4.0 → 0.6.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.
@@ -12,7 +12,8 @@ export class EdgeBuilder {
12
12
  return this;
13
13
  }
14
14
  build() {
15
- return keys(this._relationsObj).flatMap(source => {
15
+ return keys(this._relationsObj)
16
+ .flatMap(source => {
16
17
  const targets = this._relationsObj[source] ?? {};
17
18
  return keys(targets).map(target => {
18
19
  const relations = (targets[target] ?? []).sort(compareRelations);
@@ -26,6 +27,8 @@ export class EdgeBuilder {
26
27
  relations: pluck('id', relations)
27
28
  };
28
29
  });
29
- }).sort(compareRelations).reverse();
30
+ })
31
+ .sort(compareRelations)
32
+ .reverse();
30
33
  }
31
34
  }
@@ -1,4 +1,4 @@
1
- import { anyPass, filter } from 'rambdax';
1
+ import { anyPass, filter, head } from 'rambdax';
2
2
  import { DefaultElementShape, DefaultThemeColor } from '../types';
3
3
  import * as Expression from '../types/expression';
4
4
  import { isViewRuleAutoLayout, isViewRuleExpression, isViewRuleStyle } from '../types/view';
@@ -12,8 +12,10 @@ function updateSetWith(set, elements, addToSet = true) {
12
12
  addToSet ? set.add(e) : set.delete(e);
13
13
  }
14
14
  }
15
- function transformToNodes(elementsIterator, index) {
16
- return [...elementsIterator].sort(compareByFqnHierarchically).reduce((map, { id, title, color, shape, description }) => {
15
+ function transformToNodes(elementsIterator, index, currentViewid) {
16
+ return [...elementsIterator]
17
+ .sort(compareByFqnHierarchically)
18
+ .reduce((map, { id, title, color, shape, description }) => {
17
19
  let parent = parentFqn(id);
18
20
  while (parent) {
19
21
  if (map.has(parent)) {
@@ -21,14 +23,14 @@ function transformToNodes(elementsIterator, index) {
21
23
  }
22
24
  parent = parentFqn(parent);
23
25
  }
24
- const navigateTo = index.defaultViewOf(id);
26
+ const navigateTo = head(index.defaultViewOf(id).filter(v => v !== currentViewid));
25
27
  map.set(id, Object.assign({
26
28
  id,
27
29
  parent,
28
30
  title,
29
31
  color: color ?? DefaultThemeColor,
30
32
  shape: shape ?? DefaultElementShape,
31
- children: [],
33
+ children: []
32
34
  }, description ? { description } : {}, navigateTo ? { navigateTo } : {}));
33
35
  if (parent) {
34
36
  map.get(parent)?.children.push(id);
@@ -50,9 +52,7 @@ function applyViewRuleStyles(rules, nodes) {
50
52
  }
51
53
  if (Expression.isElementRef(target)) {
52
54
  const { element, isDescedants } = target;
53
- predicates.push(isDescedants
54
- ? (n) => n.id.startsWith(element + '.')
55
- : (n) => n.id === element);
55
+ predicates.push(isDescedants ? n => n.id.startsWith(element + '.') : n => n.id === element);
56
56
  continue;
57
57
  }
58
58
  failExpectedNever(target);
@@ -79,7 +79,10 @@ export function computeElementView(view, index) {
79
79
  if (isInclude) {
80
80
  const filters = [];
81
81
  // When include element(s) without newNeighbours, include in-out relations
82
- if (elements.size > 0 && newElements.length > 0 && newNeighbours.length === 0 && Expression.isElement(expr)) {
82
+ if (elements.size > 0 &&
83
+ newElements.length > 0 &&
84
+ newNeighbours.length === 0 &&
85
+ Expression.isElement(expr)) {
83
86
  for (const e of elements) {
84
87
  for (const newE of newElements) {
85
88
  if (!isSameHierarchy(e, newE)) {
@@ -144,7 +147,7 @@ export function computeElementView(view, index) {
144
147
  idx = resolvedRelations.findIndex(findPredicate);
145
148
  }
146
149
  }
147
- const nodesreg = transformToNodes(elements, index);
150
+ const nodesreg = transformToNodes(elements, index, view.id);
148
151
  const edges = edgeBuilder.build().map(edge => {
149
152
  while (edge.parent) {
150
153
  if (nodesreg.has(edge.parent)) {
@@ -54,21 +54,12 @@ const evaluateElementExpression = (index, expr, rootElement = null) => {
54
54
  // WildcardExpression
55
55
  if (Expr.isWildcard(expr)) {
56
56
  if (rootElement) {
57
- elements = [
58
- index.find(rootElement),
59
- ...index.children(rootElement)
60
- ];
57
+ elements = [index.find(rootElement), ...index.children(rootElement)];
61
58
  neighbours = [
62
59
  ...index.siblings(rootElement),
63
- ...index.ancestors(rootElement).flatMap(a => [
64
- ...index.siblings(a.id)
65
- ])
60
+ ...index.ancestors(rootElement).flatMap(a => [...index.siblings(a.id)])
66
61
  ];
67
- relations = index.filterRelations(anyPass([
68
- isInside(rootElement),
69
- isIncoming(rootElement),
70
- isOutgoing(rootElement),
71
- ]));
62
+ relations = index.filterRelations(anyPass([isInside(rootElement), isIncoming(rootElement), isOutgoing(rootElement)]));
72
63
  }
73
64
  else {
74
65
  elements = index.rootElements();
@@ -116,14 +107,8 @@ export function evaluateExpression(index, expr, rootElement) {
116
107
  const outgoing = index.filterRelations(isOutgoing(target.id));
117
108
  if (incoming.length + outgoing.length > 0) {
118
109
  elements.push(target);
119
- neighbours = neighbours.concat(map(index.find, [
120
- ...pluck('source', incoming),
121
- ...pluck('target', outgoing),
122
- ]));
123
- relations = relations.concat([
124
- ...incoming,
125
- ...outgoing
126
- ]);
110
+ neighbours = neighbours.concat(map(index.find, [...pluck('source', incoming), ...pluck('target', outgoing)]));
111
+ relations = relations.concat([...incoming, ...outgoing]);
127
112
  }
128
113
  }
129
114
  return {
@@ -36,7 +36,7 @@ export function sortNodes(_nodes, edges) {
36
36
  const sorted = alg.topsort(g);
37
37
  const nodes = sorted.map(id => _nodes.get(id));
38
38
  for (const node of nodes) {
39
- node.children = nodes.flatMap(n => n.parent === node.id ? n.id : []);
39
+ node.children = nodes.flatMap(n => (n.parent === node.id ? n.id : []));
40
40
  }
41
41
  return nodes;
42
42
  }
@@ -25,6 +25,6 @@ export declare class ModelIndex {
25
25
  rootElements(): Element[];
26
26
  get elements(): Element[];
27
27
  addRelation(rel: Relation): void;
28
- defaultViewOf: (id: Fqn) => ViewID | undefined;
28
+ defaultViewOf: (id: Fqn) => ViewID[];
29
29
  }
30
30
  export {};
@@ -38,7 +38,9 @@ export class ModelIndex {
38
38
  }
39
39
  for (const { id, viewOf } of Object.values(views)) {
40
40
  if (viewOf) {
41
- index._defaultElementView.set(viewOf, id);
41
+ const views = index._defaultElementView.get(viewOf) ?? [];
42
+ views.push(id);
43
+ index._defaultElementView.set(viewOf, views);
42
44
  }
43
45
  }
44
46
  return index;
@@ -136,6 +138,6 @@ export class ModelIndex {
136
138
  // }
137
139
  }
138
140
  defaultViewOf = (id) => {
139
- return this._defaultElementView.get(id);
141
+ return this._defaultElementView.get(id) ?? [];
140
142
  };
141
143
  }
@@ -1,23 +1,25 @@
1
1
  import type { ComputedEdge, ComputedNode, ComputedView } from './computed-view';
2
2
  export type Point = [x: number, y: number];
3
+ export interface DiagramLabel {
4
+ align: 'left' | 'right' | 'center';
5
+ fontStyle?: 'bold' | 'normal';
6
+ fontSize: number;
7
+ pt: Point;
8
+ width: number;
9
+ text: string;
10
+ }
3
11
  export interface DiagramNode extends ComputedNode {
4
12
  size: {
5
13
  width: number;
6
14
  height: number;
7
15
  };
16
+ labels: DiagramLabel[];
8
17
  position: Point;
9
- relative: Point;
10
18
  }
11
19
  export interface DiagramEdge extends ComputedEdge {
12
20
  points: Point[];
13
21
  headArrow?: Point[];
14
- labelBox: {
15
- x: number;
16
- y: number;
17
- width: number;
18
- height?: number;
19
- align?: 'left' | 'right' | 'center';
20
- } | null;
22
+ labels: DiagramLabel[];
21
23
  }
22
24
  export interface DiagramView extends ComputedView<DiagramNode, DiagramEdge> {
23
25
  width: number;
@@ -1,7 +1,7 @@
1
1
  import { either } from 'rambdax';
2
2
  import { compareFqnHierarchically } from './fqn';
3
3
  export const compareRelations = (a, b) => {
4
- return compareFqnHierarchically(a.source, b.source) || compareFqnHierarchically(a.target, b.target);
4
+ return (compareFqnHierarchically(a.source, b.source) || compareFqnHierarchically(a.target, b.target));
5
5
  };
6
6
  export const isInside = (parent) => {
7
7
  const prefix = parent + '.';
@@ -13,7 +13,7 @@ export const isBetween = (source, target) => {
13
13
  const sourcePrefix = source + '.';
14
14
  const targetPrefix = target + '.';
15
15
  return (rel) => {
16
- return (rel.source + '.').startsWith(sourcePrefix) && (rel.target + '.').startsWith(targetPrefix);
16
+ return ((rel.source + '.').startsWith(sourcePrefix) && (rel.target + '.').startsWith(targetPrefix));
17
17
  };
18
18
  };
19
19
  export const isAnyBetween = (source, target) => {
@@ -22,13 +22,13 @@ export const isAnyBetween = (source, target) => {
22
22
  export const isIncoming = (target) => {
23
23
  const targetPrefix = target + '.';
24
24
  return (rel) => {
25
- return !(rel.source + '.').startsWith(targetPrefix) && (rel.target + '.').startsWith(targetPrefix);
25
+ return (!(rel.source + '.').startsWith(targetPrefix) && (rel.target + '.').startsWith(targetPrefix));
26
26
  };
27
27
  };
28
28
  export const isOutgoing = (source) => {
29
29
  const sourcePrefix = source + '.';
30
30
  return (rel) => {
31
- return (rel.source + '.').startsWith(sourcePrefix) && !(rel.target + '.').startsWith(sourcePrefix);
31
+ return ((rel.source + '.').startsWith(sourcePrefix) && !(rel.target + '.').startsWith(sourcePrefix));
32
32
  };
33
33
  };
34
34
  export const isAnyInOut = (source) => {
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@likec4/core",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
+ "license": "MIT",
4
5
  "bugs": "https://github.com/likec4/likec4/issues",
5
6
  "homepage": "https://like-c4.dev",
6
7
  "author": "Denis Davydkov <denis@davydkov.com>",
@@ -9,7 +10,8 @@
9
10
  ],
10
11
  "repository": {
11
12
  "type": "git",
12
- "url": "https://github.com/likec4/likec4.git"
13
+ "url": "https://github.com/likec4/likec4.git",
14
+ "directory": "packages/core"
13
15
  },
14
16
  "scripts": {
15
17
  "compile": "",
@@ -19,7 +21,7 @@
19
21
  "lint": "run -T eslint src/ --fix",
20
22
  "test": "vitest run",
21
23
  "test:watch": "vitest",
22
- "clean": "rimraf dist"
24
+ "clean": "run -T rimraf dist"
23
25
  },
24
26
  "main": "./dist/index.js",
25
27
  "types": "./dist/index.d.ts",
@@ -81,8 +83,8 @@
81
83
  "tiny-invariant": "^1.3.1"
82
84
  },
83
85
  "devDependencies": {
84
- "typescript": "^5.0.3",
85
- "vite": "^4.2.1",
86
+ "typescript": "^5.0.4",
87
+ "vite": "^4.2.2",
86
88
  "vitest": "^0.30.1"
87
89
  }
88
90
  }