@likec4/core 0.6.3 → 0.18.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.
Files changed (42) hide show
  1. package/dist/colors.d.ts +79 -0
  2. package/dist/colors.js +94 -0
  3. package/dist/compute-view/EdgeBuilder.d.ts +1 -0
  4. package/dist/compute-view/EdgeBuilder.js +1 -1
  5. package/dist/compute-view/compute-ctx.d.ts +18 -0
  6. package/dist/compute-view/compute-ctx.js +25 -0
  7. package/dist/compute-view/{compute.element-view.d.ts → compute-element-view.d.ts} +2 -2
  8. package/dist/compute-view/compute-element-view.js +416 -0
  9. package/dist/compute-view/{compute-view.d.ts → compute.d.ts} +2 -2
  10. package/dist/compute-view/{compute-view.js → compute.js} +1 -1
  11. package/dist/compute-view/index.d.ts +2 -1
  12. package/dist/compute-view/index.js +1 -1
  13. package/dist/compute-view/utils/anyPossibleRelations.d.ts +1 -0
  14. package/dist/compute-view/utils/sortNodes.d.ts +1 -0
  15. package/dist/index.d.ts +4 -2
  16. package/dist/index.js +2 -1
  17. package/dist/model-index/{model-index.d.ts → ModelIndex.d.ts} +1 -0
  18. package/dist/model-index/{model-index.js → ModelIndex.js} +3 -3
  19. package/dist/model-index/index.d.ts +2 -1
  20. package/dist/model-index/index.js +1 -1
  21. package/dist/types/computed-view.d.ts +1 -0
  22. package/dist/types/diagram.d.ts +7 -0
  23. package/dist/types/element.d.ts +3 -2
  24. package/dist/types/expression.d.ts +1 -0
  25. package/dist/types/index.d.ts +1 -0
  26. package/dist/types/model.d.ts +1 -0
  27. package/dist/types/opaque.d.ts +1 -0
  28. package/dist/types/relation.d.ts +1 -0
  29. package/dist/types/view.d.ts +1 -0
  30. package/dist/utils/compute-node-levels.d.ts +8 -0
  31. package/dist/utils/compute-node-levels.js +31 -0
  32. package/dist/utils/fqn.d.ts +3 -0
  33. package/dist/utils/fqn.js +22 -1
  34. package/dist/utils/guards.d.ts +1 -0
  35. package/dist/utils/index.d.ts +2 -0
  36. package/dist/utils/index.js +1 -0
  37. package/dist/utils/relations.d.ts +3 -1
  38. package/dist/utils/relations.js +10 -4
  39. package/package.json +31 -21
  40. package/dist/compute-view/compute.element-view.js +0 -168
  41. package/dist/compute-view/utils/evaluate-expression.d.ts +0 -10
  42. package/dist/compute-view/utils/evaluate-expression.js +0 -186
@@ -1,2 +1,3 @@
1
1
  import type { ComputedEdge, ComputedNode, Fqn } from '../../types';
2
2
  export declare function sortNodes(_nodes: Map<Fqn, ComputedNode>, edges: ComputedEdge[]): ComputedNode[];
3
+ //# sourceMappingURL=sortNodes.d.ts.map
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
- export type * as likec4 from './types';
2
- export { computeView } from './compute-view';
1
+ export type * from './types';
2
+ export * from './compute-view';
3
3
  export * from './utils';
4
4
  export * from './model-index';
5
+ export * from './colors';
6
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
- export { computeView } from './compute-view';
1
+ export * from './compute-view';
2
2
  export * from './utils';
3
3
  export * from './model-index';
4
+ export * from './colors';
@@ -28,3 +28,4 @@ export declare class ModelIndex {
28
28
  defaultViewOf: (id: Fqn) => ViewID[];
29
29
  }
30
30
  export {};
31
+ //# sourceMappingURL=ModelIndex.d.ts.map
@@ -38,9 +38,9 @@ export class ModelIndex {
38
38
  }
39
39
  for (const { id, viewOf } of Object.values(views)) {
40
40
  if (viewOf) {
41
- const views = index._defaultElementView.get(viewOf) ?? [];
42
- views.push(id);
43
- index._defaultElementView.set(viewOf, views);
41
+ const viewsOf = index._defaultElementView.get(viewOf) ?? [];
42
+ viewsOf.push(id);
43
+ index._defaultElementView.set(viewOf, viewsOf);
44
44
  }
45
45
  }
46
46
  return index;
@@ -1 +1,2 @@
1
- export * from './model-index';
1
+ export * from './ModelIndex';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- export * from './model-index';
1
+ export * from './ModelIndex';
@@ -28,3 +28,4 @@ export interface ComputedView<Node extends ComputedNode = ComputedNode, Edge ext
28
28
  nodes: Node[];
29
29
  edges: Edge[];
30
30
  }
31
+ //# sourceMappingURL=computed-view.d.ts.map
@@ -24,4 +24,11 @@ export interface DiagramEdge extends ComputedEdge {
24
24
  export interface DiagramView extends ComputedView<DiagramNode, DiagramEdge> {
25
25
  width: number;
26
26
  height: number;
27
+ boundingBox: {
28
+ x: number;
29
+ y: number;
30
+ width: number;
31
+ height: number;
32
+ };
27
33
  }
34
+ //# sourceMappingURL=diagram.d.ts.map
@@ -2,8 +2,8 @@ import type { Opaque } from './opaque';
2
2
  export type Fqn = Opaque<string, 'Fqn'>;
3
3
  export declare function Fqn(name: string, parent?: Fqn | null): Fqn;
4
4
  export type ElementKind = Opaque<string, 'ElementKind'>;
5
- export type ThemeColor = 'primary' | 'secondary' | 'muted';
6
- export type ElementShape = 'rectangle' | 'person' | 'browser' | 'cylinder' | 'storage' | 'queue';
5
+ export type ThemeColor = 'amber' | 'blue' | 'gray' | 'slate' | 'green' | 'indigo' | 'muted' | 'primary' | 'red' | 'secondary' | 'sky';
6
+ export type ElementShape = 'rectangle' | 'person' | 'browser' | 'mobile' | 'cylinder' | 'storage' | 'queue';
7
7
  export declare const DefaultThemeColor: ThemeColor;
8
8
  export declare const DefaultElementShape: ElementShape;
9
9
  export interface ElementStyle {
@@ -24,3 +24,4 @@ export interface Element {
24
24
  readonly shape?: ElementShape;
25
25
  readonly color?: ThemeColor;
26
26
  }
27
+ //# sourceMappingURL=element.d.ts.map
@@ -41,3 +41,4 @@ export type AnyRelationExpression = RelationExpr | InOutExpr | IncomingExpr | Ou
41
41
  export declare function isAnyRelation(expr: Expression): expr is AnyRelationExpression;
42
42
  export type Expression = ElementExpression | AnyRelationExpression;
43
43
  export {};
44
+ //# sourceMappingURL=expression.d.ts.map
@@ -8,3 +8,4 @@ export type * from './view';
8
8
  export type * from './expression';
9
9
  export type * from './computed-view';
10
10
  export type * from './diagram';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -7,3 +7,4 @@ export interface LikeC4Model {
7
7
  relations: Record<RelationID, Relation>;
8
8
  views: Record<ViewID, ComputedView>;
9
9
  }
10
+ //# sourceMappingURL=model.d.ts.map
@@ -100,3 +100,4 @@ type WontWork = UnwrapOpaque<string>;
100
100
  */
101
101
  export type UnwrapOpaque<OpaqueType extends Tagged<unknown>> = OpaqueType extends Opaque<infer Type, OpaqueType[typeof tag]> ? Type : OpaqueType;
102
102
  export {};
103
+ //# sourceMappingURL=opaque.d.ts.map
@@ -8,3 +8,4 @@ export interface Relation {
8
8
  readonly title: string;
9
9
  readonly tags?: Tag[];
10
10
  }
11
+ //# sourceMappingURL=relation.d.ts.map
@@ -27,3 +27,4 @@ export interface ElementView {
27
27
  readonly description?: string;
28
28
  readonly rules: ViewRule[];
29
29
  }
30
+ //# sourceMappingURL=view.d.ts.map
@@ -0,0 +1,8 @@
1
+ import type { ComputedView } from '../types/computed-view';
2
+ type NodeLevelDepth = {
3
+ level: number;
4
+ depth: number;
5
+ };
6
+ export declare const computeNodeLevels: ({ nodes }: ComputedView) => Record<import("..").Fqn, NodeLevelDepth>;
7
+ export {};
8
+ //# sourceMappingURL=compute-node-levels.d.ts.map
@@ -0,0 +1,31 @@
1
+ import invariant from 'tiny-invariant';
2
+ export const computeNodeLevels = ({ nodes }) => {
3
+ const nodeLevels = {};
4
+ const compute = (node, level) => {
5
+ let levels = nodeLevels[node.id];
6
+ if (levels) {
7
+ return levels;
8
+ }
9
+ if (node.children.length === 0) {
10
+ levels = { level, depth: 0 };
11
+ nodeLevels[node.id] = levels;
12
+ return levels;
13
+ }
14
+ let depth = 1;
15
+ for (const childId of node.children) {
16
+ const child = nodes.find(n => n.id === childId);
17
+ invariant(child, `Child ${childId} not found`);
18
+ const { depth: childDepth } = compute(child, level + 1);
19
+ depth = Math.max(childDepth + 1, depth);
20
+ }
21
+ levels = { level, depth };
22
+ nodeLevels[node.id] = levels;
23
+ return levels;
24
+ };
25
+ for (const node of nodes) {
26
+ if (!node.parent) {
27
+ compute(node, 0);
28
+ }
29
+ }
30
+ return nodeLevels;
31
+ };
@@ -2,9 +2,12 @@ import type { Element, Fqn } from '../types';
2
2
  export declare function nameFromFqn(fqn: Fqn): string;
3
3
  export declare function isAncestor(...args: [ancestor: Fqn, another: Fqn] | [ancestor: Element, another: Element]): boolean;
4
4
  export declare function isSameHierarchy(...args: [one: Fqn, another: Fqn] | [one: Element, another: Element]): boolean;
5
+ export declare function isDescendantOf(ancestors: Element[]): (e: Element) => boolean;
6
+ export declare function notDescendantOf(ancestors: Element[]): (e: Element) => boolean;
5
7
  export declare function commonAncestor(first: Fqn, second: Fqn): Fqn | null;
6
8
  export declare function parentFqn(fqn: Fqn): Fqn | null;
7
9
  export declare const compareFqnHierarchically: (a: string, b: string) => number;
8
10
  export declare const compareByFqnHierarchically: <T extends {
9
11
  id: Fqn;
10
12
  }>(a: T, b: T) => number;
13
+ //# sourceMappingURL=fqn.d.ts.map
package/dist/utils/fqn.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { anyPass } from 'rambdax';
1
2
  import { isString } from './guards';
2
3
  export function nameFromFqn(fqn) {
3
4
  const lastDot = fqn.lastIndexOf('.');
@@ -18,7 +19,26 @@ export function isSameHierarchy(...args) {
18
19
  const another = isString(args[1]) ? args[1] : args[1].id;
19
20
  return one === another || another.startsWith(one + '.') || one.startsWith(another + '.');
20
21
  }
22
+ export function isDescendantOf(ancestors) {
23
+ const predicates = ancestors.flatMap(a => [
24
+ (e) => e.id === a.id,
25
+ (e) => isAncestor(a, e)
26
+ ]);
27
+ return anyPass(predicates);
28
+ }
29
+ export function notDescendantOf(ancestors) {
30
+ const isDescendant = isDescendantOf(ancestors);
31
+ return (e) => !isDescendant(e);
32
+ }
21
33
  export function commonAncestor(first, second) {
34
+ const parentA = parentFqn(first);
35
+ const parentB = parentFqn(second);
36
+ if (parentA === parentB) {
37
+ return parentA;
38
+ }
39
+ if (!parentA || !parentB) {
40
+ return null;
41
+ }
22
42
  const a = first.split('.');
23
43
  const b = second.split('.');
24
44
  let ancestor = null;
@@ -40,7 +60,8 @@ export const compareFqnHierarchically = (a, b) => {
40
60
  const depthA = a.split('.').length;
41
61
  const depthB = b.split('.').length;
42
62
  if (depthA === depthB) {
43
- return a.localeCompare(b);
63
+ // return a.localeCompare(b)
64
+ return 0;
44
65
  }
45
66
  else {
46
67
  return depthA - depthB;
@@ -1,3 +1,4 @@
1
1
  export declare function isString(value: unknown): value is string;
2
2
  export declare function failExpectedNever(arg: never): never;
3
3
  export declare function ignoreNeverInRuntime(arg: never): void;
4
+ //# sourceMappingURL=guards.d.ts.map
@@ -1,3 +1,5 @@
1
1
  export * from './fqn';
2
2
  export * from './guards';
3
+ export * from './compute-node-levels';
3
4
  export * as Relations from './relations';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -1,3 +1,4 @@
1
1
  export * from './fqn';
2
2
  export * from './guards';
3
+ export * from './compute-node-levels';
3
4
  export * as Relations from './relations';
@@ -1,4 +1,4 @@
1
- import type { Fqn } from '../types';
1
+ import type { Fqn, Element } from '../types';
2
2
  type Relation = {
3
3
  source: Fqn;
4
4
  target: Fqn;
@@ -13,4 +13,6 @@ export declare const isAnyBetween: (source: Fqn, target: Fqn) => import("rambdax
13
13
  export declare const isIncoming: (target: Fqn) => (rel: Relation) => boolean;
14
14
  export declare const isOutgoing: (source: Fqn) => (rel: Relation) => boolean;
15
15
  export declare const isAnyInOut: (source: Fqn) => import("rambdax").Predicate<Relation>;
16
+ export declare const hasRelation: (rel: Relation) => (element: Element) => boolean;
16
17
  export {};
18
+ //# sourceMappingURL=relations.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { either } from 'rambdax';
2
- import { compareFqnHierarchically } from './fqn';
2
+ import { compareFqnHierarchically, isAncestor } from './fqn';
3
3
  export const compareRelations = (a, b) => {
4
4
  return (compareFqnHierarchically(a.source, b.source) || compareFqnHierarchically(a.target, b.target));
5
5
  };
@@ -13,7 +13,8 @@ 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 === source || (rel.source + '.').startsWith(sourcePrefix)) &&
17
+ (rel.target === target || (rel.target + '.').startsWith(targetPrefix)));
17
18
  };
18
19
  };
19
20
  export const isAnyBetween = (source, target) => {
@@ -22,15 +23,20 @@ export const isAnyBetween = (source, target) => {
22
23
  export const isIncoming = (target) => {
23
24
  const targetPrefix = target + '.';
24
25
  return (rel) => {
25
- return (!(rel.source + '.').startsWith(targetPrefix) && (rel.target + '.').startsWith(targetPrefix));
26
+ return (!(rel.source + '.').startsWith(targetPrefix) && (rel.target === target || (rel.target + '.').startsWith(targetPrefix)));
26
27
  };
27
28
  };
28
29
  export const isOutgoing = (source) => {
29
30
  const sourcePrefix = source + '.';
30
31
  return (rel) => {
31
- return ((rel.source + '.').startsWith(sourcePrefix) && !(rel.target + '.').startsWith(sourcePrefix));
32
+ return ((rel.source === source || (rel.source + '.').startsWith(sourcePrefix)) && !(rel.target + '.').startsWith(sourcePrefix));
32
33
  };
33
34
  };
34
35
  export const isAnyInOut = (source) => {
35
36
  return either(isIncoming(source), isOutgoing(source));
36
37
  };
38
+ export const hasRelation = (rel) => {
39
+ return (element) => {
40
+ return isAncestor(rel.source, element.id) || isAncestor(rel.target, element.id);
41
+ };
42
+ };
package/package.json CHANGED
@@ -1,12 +1,15 @@
1
1
  {
2
2
  "name": "@likec4/core",
3
- "version": "0.6.3",
3
+ "version": "0.18.0",
4
4
  "license": "MIT",
5
5
  "bugs": "https://github.com/likec4/likec4/issues",
6
- "homepage": "https://like-c4.dev",
6
+ "homepage": "https://likec4.dev",
7
7
  "author": "Denis Davydkov <denis@davydkov.com>",
8
8
  "files": [
9
- "dist"
9
+ "dist",
10
+ "!dist/__test__",
11
+ "!**/*.spec.*",
12
+ "!**/*.map"
10
13
  ],
11
14
  "repository": {
12
15
  "type": "git",
@@ -14,77 +17,84 @@
14
17
  "directory": "packages/core"
15
18
  },
16
19
  "scripts": {
17
- "compile": "tsc --emitDeclarationOnly",
18
- "build:release": "tsc -p tsconfig.esm.json",
20
+ "compile": "tsc --noEmit",
19
21
  "build": "tsc",
20
22
  "dev": "tsc --watch",
21
23
  "lint": "run -T eslint src/ --fix",
22
- "test": "vitest run",
23
- "test:watch": "vitest",
24
+ "test": "run -T vitest run",
25
+ "test:watch": "run -T vitest",
24
26
  "clean": "run -T rimraf dist"
25
27
  },
26
- "main": "./dist/index.js",
28
+ "module": "./dist/index.js",
27
29
  "types": "./dist/index.d.ts",
28
30
  "type": "module",
29
31
  "exports": {
30
32
  ".": {
31
33
  "types": "./dist/index.d.ts",
32
34
  "import": "./dist/index.js",
33
- "require": "./dist/index.cjs"
35
+ "default": "./dist/index.js"
34
36
  },
35
37
  "./types": {
36
38
  "types": "./dist/types/index.d.ts",
37
39
  "import": "./dist/types/index.js",
38
- "require": "./dist/types/index.cjs"
40
+ "default": "./dist/types/index.js"
41
+ },
42
+ "./colors": {
43
+ "types": "./dist/colors.d.ts",
44
+ "import": "./dist/colors.js",
45
+ "default": "./dist/colors.js"
39
46
  },
40
47
  "./utils": {
41
48
  "types": "./dist/utils/index.d.ts",
42
49
  "import": "./dist/utils/index.js",
43
- "require": "./dist/utils/index.cjs"
50
+ "default": "./dist/utils/index.js"
44
51
  },
45
52
  "./compute-view": {
46
53
  "types": "./dist/compute-view/index.d.ts",
47
54
  "import": "./dist/compute-view/index.js",
48
- "require": "./dist/compute-view/index.cjs"
55
+ "default": "./dist/compute-view/index.js"
49
56
  }
50
57
  },
51
58
  "sideEffects": false,
52
59
  "publishConfig": {
53
60
  "registry": "https://registry.npmjs.org",
54
61
  "access": "public",
55
- "main": "./dist/index.js",
62
+ "module": "./dist/index.js",
56
63
  "types": "./dist/index.d.ts",
57
64
  "exports": {
58
65
  ".": {
59
66
  "types": "./dist/index.d.ts",
60
67
  "import": "./dist/index.js",
61
- "require": "./dist/index.cjs"
68
+ "default": "./dist/index.js"
62
69
  },
63
70
  "./types": {
64
71
  "types": "./dist/types/index.d.ts",
65
72
  "import": "./dist/types/index.js",
66
- "require": "./dist/types/index.cjs"
73
+ "default": "./dist/types/index.js"
74
+ },
75
+ "./colors": {
76
+ "types": "./dist/colors.d.ts",
77
+ "import": "./dist/colors.js",
78
+ "default": "./dist/colors.js"
67
79
  },
68
80
  "./utils": {
69
81
  "types": "./dist/utils/index.d.ts",
70
82
  "import": "./dist/utils/index.js",
71
- "require": "./dist/utils/index.cjs"
83
+ "default": "./dist/utils/index.js"
72
84
  },
73
85
  "./compute-view": {
74
86
  "types": "./dist/compute-view/index.d.ts",
75
87
  "import": "./dist/compute-view/index.js",
76
- "require": "./dist/compute-view/index.cjs"
88
+ "default": "./dist/compute-view/index.js"
77
89
  }
78
90
  }
79
91
  },
80
92
  "dependencies": {
81
93
  "@dagrejs/graphlib": "^2.1.12",
82
- "rambdax": "^9.1.0",
94
+ "rambdax": "^9.1.1",
83
95
  "tiny-invariant": "^1.3.1"
84
96
  },
85
97
  "devDependencies": {
86
- "typescript": "^5.0.4",
87
- "vite": "^4.2.2",
88
- "vitest": "^0.30.1"
98
+ "typescript": "^5.1.3"
89
99
  }
90
100
  }
@@ -1,168 +0,0 @@
1
- import { anyPass, filter, head } from 'rambdax';
2
- import { DefaultElementShape, DefaultThemeColor } from '../types';
3
- import * as Expression from '../types/expression';
4
- import { isViewRuleAutoLayout, isViewRuleExpression, isViewRuleStyle } from '../types/view';
5
- import { Relations, compareByFqnHierarchically, failExpectedNever, isSameHierarchy, parentFqn } from '../utils';
6
- import { EdgeBuilder } from './EdgeBuilder';
7
- import { anyPossibleRelations } from './utils/anyPossibleRelations';
8
- import { evaluateExpression } from './utils/evaluate-expression';
9
- import { sortNodes } from './utils/sortNodes';
10
- function updateSetWith(set, elements, addToSet = true) {
11
- for (const e of elements) {
12
- addToSet ? set.add(e) : set.delete(e);
13
- }
14
- }
15
- function transformToNodes(elementsIterator, index, currentViewid) {
16
- return [...elementsIterator]
17
- .sort(compareByFqnHierarchically)
18
- .reduce((map, { id, title, color, shape, description }) => {
19
- let parent = parentFqn(id);
20
- while (parent) {
21
- if (map.has(parent)) {
22
- break;
23
- }
24
- parent = parentFqn(parent);
25
- }
26
- const navigateTo = head(index.defaultViewOf(id).filter(v => v !== currentViewid));
27
- map.set(id, Object.assign({
28
- id,
29
- parent,
30
- title,
31
- color: color ?? DefaultThemeColor,
32
- shape: shape ?? DefaultElementShape,
33
- children: []
34
- }, description ? { description } : {}, navigateTo ? { navigateTo } : {}));
35
- if (parent) {
36
- map.get(parent)?.children.push(id);
37
- }
38
- return map;
39
- }, new Map());
40
- }
41
- function applyViewRuleStyles(rules, nodes) {
42
- for (const rule of rules) {
43
- const predicates = [];
44
- if (!rule.style.color && !rule.style.shape) {
45
- // skip empty
46
- continue;
47
- }
48
- for (const target of rule.targets) {
49
- if (Expression.isWildcard(target)) {
50
- predicates.push(() => true);
51
- break;
52
- }
53
- if (Expression.isElementRef(target)) {
54
- const { element, isDescedants } = target;
55
- predicates.push(isDescedants ? n => n.id.startsWith(element + '.') : n => n.id === element);
56
- continue;
57
- }
58
- failExpectedNever(target);
59
- }
60
- filter(anyPass(predicates), nodes).forEach(n => {
61
- n.shape = rule.style.shape ?? n.shape;
62
- n.color = rule.style.color ?? n.color;
63
- });
64
- }
65
- return nodes;
66
- }
67
- export function computeElementView(view, index) {
68
- const relations = new Set();
69
- const elements = new Set();
70
- const neighbours = new Set();
71
- const rootElement = view.viewOf ?? null;
72
- const rulesInclude = view.rules.filter(isViewRuleExpression);
73
- if (rootElement && rulesInclude.length == 0) {
74
- elements.add(index.find(rootElement));
75
- }
76
- for (const { isInclude, exprs } of rulesInclude) {
77
- for (const expr of exprs) {
78
- let { elements: newElements, neighbours: newNeighbours, relations: newRelations } = evaluateExpression(index, expr, rootElement);
79
- if (isInclude) {
80
- const filters = [];
81
- // When include element(s) without newNeighbours, include in-out relations
82
- if (elements.size > 0 &&
83
- newElements.length > 0 &&
84
- newNeighbours.length === 0 &&
85
- Expression.isElement(expr)) {
86
- for (const e of elements) {
87
- for (const newE of newElements) {
88
- if (!isSameHierarchy(e, newE)) {
89
- filters.push(Relations.isAnyBetween(e.id, newE.id));
90
- }
91
- }
92
- }
93
- }
94
- // // When include elements by tag or kind, include in-out relations
95
- // if (elements.size > 0 && newElements.length > 0 && (Expression.isElementKind(expr) || Expression.isElementTag(expr))) {
96
- // for (const e of elements) {
97
- // for (const newE of newElements) {
98
- // if (e.id !== newE.id && !isAncestor(e, newE) && !isAncestor(newE, e)) {
99
- // filters.push(isAnyRelationBetween(e.id, newE.id))
100
- // }
101
- // }
102
- // }
103
- // }
104
- if (filters.length > 0) {
105
- newRelations = newRelations.concat(index.filterRelations(anyPass(filters)));
106
- }
107
- }
108
- else {
109
- if (Expression.isAnyRelation(expr)) {
110
- // Exclude only relations, but not elements and neighbours
111
- newNeighbours = [];
112
- newElements = [];
113
- }
114
- else {
115
- newNeighbours = newNeighbours.concat(newElements);
116
- // Also exclude nested elements from current neighbours
117
- // for (const n of neighbours) {
118
- // if (newNeighbours.some(e => n.id.startsWith(e.id + '.'))) {
119
- // newNeighbours.push(n)
120
- // }
121
- // }
122
- // Do not exclude relations
123
- newRelations = [];
124
- }
125
- }
126
- updateSetWith(elements, newElements, isInclude);
127
- updateSetWith(relations, newRelations, isInclude);
128
- updateSetWith(neighbours, newNeighbours, isInclude);
129
- }
130
- }
131
- const elementsIds = new Set([...elements].map(e => e.id));
132
- const edgeBuilder = new EdgeBuilder();
133
- const resolvedRelations = [...relations];
134
- for (const [source, target] of anyPossibleRelations([...elements, ...neighbours])) {
135
- if (!elementsIds.has(source.id) && !elementsIds.has(target.id)) {
136
- continue;
137
- }
138
- const findPredicate = Relations.isBetween(source.id, target.id);
139
- let idx = resolvedRelations.findIndex(findPredicate);
140
- while (idx >= 0) {
141
- const [rel] = resolvedRelations.splice(idx, 1);
142
- if (rel) {
143
- elements.add(source);
144
- elements.add(target);
145
- edgeBuilder.add(source.id, target.id, rel);
146
- }
147
- idx = resolvedRelations.findIndex(findPredicate);
148
- }
149
- }
150
- const nodesreg = transformToNodes(elements, index, view.id);
151
- const edges = edgeBuilder.build().map(edge => {
152
- while (edge.parent) {
153
- if (nodesreg.has(edge.parent)) {
154
- break;
155
- }
156
- edge.parent = parentFqn(edge.parent);
157
- }
158
- return edge;
159
- });
160
- const nodes = applyViewRuleStyles(view.rules.filter(isViewRuleStyle), sortNodes(nodesreg, edges));
161
- const autoLayoutRule = view.rules.find(isViewRuleAutoLayout);
162
- return {
163
- ...view,
164
- autoLayout: autoLayoutRule?.autoLayout ?? 'TB',
165
- nodes,
166
- edges
167
- };
168
- }
@@ -1,10 +0,0 @@
1
- import type { ModelIndex } from '../../model-index';
2
- import type { Element, Fqn, Relation, Expression } from '../../types';
3
- export declare const keepLeafs: (elements: Element[]) => Element[];
4
- interface EvaluateViewExpressionResult {
5
- elements: Element[];
6
- neighbours: Element[];
7
- relations: Relation[];
8
- }
9
- export declare function evaluateExpression(index: ModelIndex, expr: Expression, rootElement: Fqn | null): EvaluateViewExpressionResult;
10
- export {};