@likec4/core 0.6.2 → 0.7.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 (51) hide show
  1. package/dist/__test__/data.d.ts +174 -0
  2. package/dist/__test__/data.js +188 -0
  3. package/dist/__test__/index.d.ts +2 -0
  4. package/dist/__test__/index.js +1 -0
  5. package/dist/compute-view/EdgeBuilder.d.ts +8 -0
  6. package/dist/compute-view/EdgeBuilder.js +34 -0
  7. package/dist/compute-view/compute.d.ts +12 -0
  8. package/dist/compute-view/compute.element-view.d.ts +5 -0
  9. package/dist/compute-view/compute.element-view.js +168 -0
  10. package/dist/compute-view/compute.js +14 -0
  11. package/dist/compute-view/index.d.ts +3 -0
  12. package/dist/compute-view/index.js +1 -0
  13. package/dist/compute-view/utils/anyPossibleRelations.d.ts +3 -0
  14. package/dist/compute-view/utils/anyPossibleRelations.js +12 -0
  15. package/dist/compute-view/utils/evaluate-expression.d.ts +11 -0
  16. package/dist/compute-view/utils/evaluate-expression.js +186 -0
  17. package/dist/compute-view/utils/sortNodes.d.ts +3 -0
  18. package/dist/compute-view/utils/sortNodes.js +42 -0
  19. package/dist/index.d.ts +5 -0
  20. package/dist/index.js +3 -0
  21. package/dist/model-index/ModelIndex.d.ts +31 -0
  22. package/dist/model-index/ModelIndex.js +143 -0
  23. package/dist/model-index/index.d.ts +2 -0
  24. package/dist/model-index/index.js +1 -0
  25. package/dist/types/computed-view.d.ts +31 -0
  26. package/dist/types/computed-view.js +1 -0
  27. package/dist/types/diagram.d.ts +28 -0
  28. package/dist/types/diagram.js +1 -0
  29. package/dist/types/element.d.ts +27 -0
  30. package/dist/types/element.js +5 -0
  31. package/dist/types/expression.d.ts +44 -0
  32. package/dist/types/expression.js +24 -0
  33. package/dist/types/index.d.ts +11 -0
  34. package/dist/types/index.js +2 -0
  35. package/dist/types/model.d.ts +10 -0
  36. package/dist/types/model.js +1 -0
  37. package/dist/types/opaque.d.ts +103 -0
  38. package/dist/types/opaque.js +1 -0
  39. package/dist/types/relation.d.ts +11 -0
  40. package/dist/types/relation.js +1 -0
  41. package/dist/types/view.d.ts +30 -0
  42. package/dist/types/view.js +9 -0
  43. package/dist/utils/fqn.d.ts +11 -0
  44. package/dist/utils/fqn.js +51 -0
  45. package/dist/utils/guards.d.ts +4 -0
  46. package/dist/utils/guards.js +10 -0
  47. package/dist/utils/index.d.ts +4 -0
  48. package/dist/utils/index.js +3 -0
  49. package/dist/utils/relations.d.ts +17 -0
  50. package/dist/utils/relations.js +36 -0
  51. package/package.json +18 -16
@@ -0,0 +1,186 @@
1
+ import { anyPass, map, pluck, uniq } from 'rambdax';
2
+ import * as Expr from '../../types/expression';
3
+ import { failExpectedNever, isAncestor } from '../../utils';
4
+ import { isBetween, isIncoming, isInside, isOutgoing } from '../../utils/relations';
5
+ import { anyPossibleRelations } from './anyPossibleRelations';
6
+ const dropNested = (elements) => {
7
+ return elements.reduce((acc, current) => {
8
+ if (acc.length === 0)
9
+ return [current];
10
+ // current is a child of some in acc
11
+ if (acc.some(p => p.id === current.id || isAncestor(p, current))) {
12
+ return acc;
13
+ }
14
+ return [
15
+ // drop children of current
16
+ ...acc.filter(e => !isAncestor(current, e)),
17
+ current
18
+ ];
19
+ }, []);
20
+ };
21
+ export const keepLeafs = (elements) => {
22
+ return elements.reduce((acc, current) => {
23
+ if (acc.length === 0)
24
+ return [current];
25
+ // current is an ancestor of some in acc
26
+ if (acc.some(p => p.id === current.id || isAncestor(current, p))) {
27
+ return acc;
28
+ }
29
+ return [
30
+ // drop ancestors of current
31
+ ...acc.filter(e => !isAncestor(e, current)),
32
+ current
33
+ ];
34
+ }, []);
35
+ };
36
+ const evaluateElementExpression = (index, expr, rootElement = null) => {
37
+ let elements = [];
38
+ let neighbours = [];
39
+ let relations = [];
40
+ // const inOutRelations = (elements: Element[]) => {
41
+ // if (elements.length == 0) return []
42
+ // const filters = dropNested(elements).map(e => isAnyInOut(e.id))
43
+ // return index.filterRelations(anyPass(filters))
44
+ // }
45
+ const allRelationsBetween = (elements) => {
46
+ if (elements.length <= 1)
47
+ return [];
48
+ const filters = [];
49
+ for (const [source, target] of anyPossibleRelations(elements)) {
50
+ filters.push(isBetween(source.id, target.id));
51
+ }
52
+ return filters.length ? index.filterRelations(anyPass(filters)) : [];
53
+ };
54
+ // WildcardExpression
55
+ if (Expr.isWildcard(expr)) {
56
+ if (rootElement) {
57
+ elements = [index.find(rootElement), ...index.children(rootElement)];
58
+ neighbours = [
59
+ ...index.siblings(rootElement),
60
+ ...index.ancestors(rootElement).flatMap(a => [...index.siblings(a.id)])
61
+ ];
62
+ relations = index.filterRelations(anyPass([isInside(rootElement), isIncoming(rootElement), isOutgoing(rootElement)]));
63
+ }
64
+ else {
65
+ elements = index.rootElements();
66
+ neighbours = elements;
67
+ relations = allRelationsBetween(elements);
68
+ }
69
+ return {
70
+ elements,
71
+ neighbours,
72
+ relations
73
+ };
74
+ }
75
+ // Identifier
76
+ if (Expr.isElementRef(expr)) {
77
+ elements = expr.isDescedants ? index.children(expr.element) : [index.find(expr.element)];
78
+ if (expr.isDescedants) {
79
+ relations = index.filterRelations(isInside(expr.element));
80
+ // relations = index.filterRelations(anyPass([
81
+ // isBetween(expr.element),
82
+ // isIncoming(expr.element),
83
+ // isOutgoing(expr.element),
84
+ // ]))
85
+ // } else {
86
+ // relations = index.filterRelations(anyPass([
87
+ // isIncoming(expr.element),
88
+ // isOutgoing(expr.element)
89
+ // ]))
90
+ }
91
+ return {
92
+ elements,
93
+ neighbours,
94
+ relations
95
+ };
96
+ }
97
+ failExpectedNever(expr);
98
+ };
99
+ export function evaluateExpression(index, expr, rootElement) {
100
+ const elements = [];
101
+ let neighbours = [];
102
+ let relations = [];
103
+ if (Expr.isInOut(expr)) {
104
+ const targets = evaluateElementExpression(index, expr.inout).elements;
105
+ for (const target of targets) {
106
+ const incoming = index.filterRelations(isIncoming(target.id));
107
+ const outgoing = index.filterRelations(isOutgoing(target.id));
108
+ if (incoming.length + outgoing.length > 0) {
109
+ elements.push(target);
110
+ neighbours = neighbours.concat(map(index.find, [...pluck('source', incoming), ...pluck('target', outgoing)]));
111
+ relations = relations.concat([...incoming, ...outgoing]);
112
+ }
113
+ }
114
+ return {
115
+ elements: uniq(elements),
116
+ neighbours: dropNested(neighbours),
117
+ relations: uniq(relations)
118
+ };
119
+ }
120
+ if (Expr.isIncoming(expr)) {
121
+ const targets = evaluateElementExpression(index, expr.incoming).elements;
122
+ for (const target of targets) {
123
+ const incoming = index.filterRelations(isIncoming(target.id));
124
+ if (incoming.length > 0) {
125
+ elements.push(target);
126
+ neighbours = neighbours.concat(map(index.find, pluck('source', incoming)));
127
+ relations = relations.concat(incoming);
128
+ }
129
+ }
130
+ return {
131
+ elements: uniq(elements),
132
+ neighbours: dropNested(neighbours),
133
+ relations: uniq(relations)
134
+ };
135
+ }
136
+ if (Expr.isOutgoing(expr)) {
137
+ const sources = evaluateElementExpression(index, expr.outgoing).elements;
138
+ for (const source of sources) {
139
+ const outgoing = index.filterRelations(isOutgoing(source.id));
140
+ if (outgoing.length > 0) {
141
+ elements.push(source);
142
+ neighbours = neighbours.concat(map(index.find, pluck('target', outgoing)));
143
+ relations = relations.concat(outgoing);
144
+ }
145
+ }
146
+ return {
147
+ elements: uniq(elements),
148
+ neighbours: dropNested(neighbours),
149
+ relations: uniq(relations)
150
+ };
151
+ }
152
+ if (Expr.isRelation(expr)) {
153
+ const isSourceWildcard = Expr.isWildcard(expr.source);
154
+ const isTargetWildcard = Expr.isWildcard(expr.target);
155
+ if (isSourceWildcard && !isTargetWildcard) {
156
+ return evaluateExpression(index, {
157
+ incoming: expr.target
158
+ }, rootElement);
159
+ }
160
+ if (!isSourceWildcard && isTargetWildcard) {
161
+ return evaluateExpression(index, {
162
+ outgoing: expr.source
163
+ }, rootElement);
164
+ }
165
+ const sources = evaluateElementExpression(index, expr.source).elements;
166
+ const targets = evaluateElementExpression(index, expr.target).elements;
167
+ for (const source of sources) {
168
+ for (const target of targets) {
169
+ if (isAncestor(source.id, target.id) || isAncestor(target.id, source.id)) {
170
+ continue;
171
+ }
172
+ const foundRelations = index.filterRelations(isBetween(source.id, target.id));
173
+ if (foundRelations.length > 0) {
174
+ relations = relations.concat(foundRelations);
175
+ neighbours.push(source, target);
176
+ }
177
+ }
178
+ }
179
+ return {
180
+ elements,
181
+ neighbours: uniq(neighbours),
182
+ relations: uniq(relations)
183
+ };
184
+ }
185
+ return evaluateElementExpression(index, expr, rootElement);
186
+ }
@@ -0,0 +1,3 @@
1
+ import type { ComputedEdge, ComputedNode, Fqn } from '../../types';
2
+ export declare function sortNodes(_nodes: Map<Fqn, ComputedNode>, edges: ComputedEdge[]): ComputedNode[];
3
+ //# sourceMappingURL=sortNodes.d.ts.map
@@ -0,0 +1,42 @@
1
+ import { Graph, alg } from '@dagrejs/graphlib';
2
+ export function sortNodes(_nodes, edges) {
3
+ const g = new Graph({
4
+ compound: true,
5
+ directed: true,
6
+ multigraph: false
7
+ });
8
+ for (const nd of _nodes.values()) {
9
+ g.setNode(nd.id);
10
+ // console.log(`add ${nd.id}`)
11
+ if (nd.parent) {
12
+ g.setEdge(nd.parent, nd.id);
13
+ // console.log(`${nd.parent} -> ${nd.id}`)
14
+ }
15
+ }
16
+ for (const edge of edges) {
17
+ const source = _nodes.get(edge.source);
18
+ let target = _nodes.get(edge.target);
19
+ while (source && target) {
20
+ if (!g.hasEdge(source.id, target.id)) {
21
+ g.setEdge(source.id, target.id);
22
+ // console.log(`${source.id} -> ${target.id}`)
23
+ if (!alg.isAcyclic(g)) {
24
+ g.removeEdge(source.id, target.id);
25
+ // console.log(`remove ${source.id} -> ${target.id}`)
26
+ }
27
+ }
28
+ if (target.parent && target.parent !== edge.parent) {
29
+ target = _nodes.get(target.parent);
30
+ }
31
+ else {
32
+ target = undefined;
33
+ }
34
+ }
35
+ }
36
+ const sorted = alg.topsort(g);
37
+ const nodes = sorted.map(id => _nodes.get(id));
38
+ for (const node of nodes) {
39
+ node.children = nodes.flatMap(n => (n.parent === node.id ? n.id : []));
40
+ }
41
+ return nodes;
42
+ }
@@ -0,0 +1,5 @@
1
+ export type * from './types';
2
+ export * from './compute-view';
3
+ export * from './utils';
4
+ export * from './model-index';
5
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export * from './compute-view';
2
+ export * from './utils';
3
+ export * from './model-index';
@@ -0,0 +1,31 @@
1
+ import type { Predicate } from 'rambdax';
2
+ import type { Element, ElementView, Fqn, Relation, RelationID, ViewID } from '../types';
3
+ type ModelInput = {
4
+ elements: Record<Fqn, Element>;
5
+ relations: Record<RelationID, Relation>;
6
+ views: Record<ViewID, ElementView>;
7
+ };
8
+ export declare class ModelIndex {
9
+ private root;
10
+ private _elements;
11
+ private _relations;
12
+ private _defaultElementView;
13
+ get relations(): Relation[];
14
+ filterRelations: (predicate: Predicate<Relation>) => Relation[];
15
+ static from({ elements, relations, views }: ModelInput): ModelIndex;
16
+ addElement(el: Element): void;
17
+ private locateTrie;
18
+ find: (id: Fqn) => Element;
19
+ children: (id: Fqn) => Element[];
20
+ siblings: (id: Fqn) => Element[];
21
+ /**
22
+ * Ancestors from closest parent to root
23
+ */
24
+ ancestors: (id: Fqn) => Element[];
25
+ rootElements(): Element[];
26
+ get elements(): Element[];
27
+ addRelation(rel: Relation): void;
28
+ defaultViewOf: (id: Fqn) => ViewID[];
29
+ }
30
+ export {};
31
+ //# sourceMappingURL=ModelIndex.d.ts.map
@@ -0,0 +1,143 @@
1
+ import { values } from 'rambdax';
2
+ import invariant from 'tiny-invariant';
3
+ import { parentFqn } from '../utils/fqn';
4
+ function childrenOf(trie) {
5
+ const children = [];
6
+ for (const { el } of values(trie.children)) {
7
+ if (el) {
8
+ children.push(el);
9
+ }
10
+ }
11
+ return children;
12
+ }
13
+ function asPath(id) {
14
+ return id.split('.');
15
+ }
16
+ export class ModelIndex {
17
+ root = {
18
+ children: {}
19
+ };
20
+ _elements = new Set();
21
+ _relations = new Map();
22
+ _defaultElementView = new Map();
23
+ // private _taggedElements = new Map<Tag, Set<Element>>()
24
+ // private _taggedRelations = new Map<Tag, Set<Relation>>()
25
+ get relations() {
26
+ return [...this._relations.values()];
27
+ }
28
+ filterRelations = (predicate) => {
29
+ return [...this._relations.values()].filter(predicate);
30
+ };
31
+ static from({ elements, relations, views }) {
32
+ const index = new ModelIndex();
33
+ for (const el of Object.values(elements)) {
34
+ index.addElement(el);
35
+ }
36
+ for (const rel of Object.values(relations)) {
37
+ index.addRelation(rel);
38
+ }
39
+ for (const { id, viewOf } of Object.values(views)) {
40
+ if (viewOf) {
41
+ const views = index._defaultElementView.get(viewOf) ?? [];
42
+ views.push(id);
43
+ index._defaultElementView.set(viewOf, views);
44
+ }
45
+ }
46
+ return index;
47
+ }
48
+ addElement(el) {
49
+ const path = asPath(el.id);
50
+ let scope = this.root;
51
+ for (const name of path) {
52
+ const next = scope.children[name] ?? {
53
+ children: {}
54
+ };
55
+ scope.children[name] = next;
56
+ scope = next;
57
+ }
58
+ scope.el = el;
59
+ this._elements.add(el);
60
+ }
61
+ locateTrie = (id) => {
62
+ let scope = this.root;
63
+ for (const name of asPath(id)) {
64
+ const next = scope.children[name];
65
+ invariant(next, `Invalid index, Element not found at path ${name} of ${id}`);
66
+ scope = next;
67
+ }
68
+ return scope;
69
+ };
70
+ find = (id) => {
71
+ const trie = this.locateTrie(id);
72
+ if (!trie.el) {
73
+ throw new Error(`Invalid index, element not found at path ${id}`);
74
+ }
75
+ return trie.el;
76
+ };
77
+ children = (id) => {
78
+ return childrenOf(this.locateTrie(id));
79
+ };
80
+ siblings = (id) => {
81
+ const parent = parentFqn(id);
82
+ const trie = parent ? this.locateTrie(parent) : this.root;
83
+ return childrenOf(trie).filter(e => e.id !== id);
84
+ };
85
+ /**
86
+ * Ancestors from closest parent to root
87
+ */
88
+ ancestors = (id) => {
89
+ const path = asPath(id);
90
+ const ancestors = [];
91
+ // The root
92
+ if (path.length === 1) {
93
+ return ancestors;
94
+ }
95
+ // Remove the element itself
96
+ path.pop();
97
+ let name = path.shift();
98
+ let trie = this.root;
99
+ while (name) {
100
+ const next = trie.children[name];
101
+ invariant(next, `Invalid index, Element not found at path ${name} of ${id}`);
102
+ trie = next;
103
+ if (!trie.el) {
104
+ throw new Error(`invalid index, no element ${name} found in ${id}`);
105
+ }
106
+ ancestors.unshift(trie.el);
107
+ name = path.shift();
108
+ }
109
+ return ancestors;
110
+ };
111
+ // tagged = (tag?: Tag): TaggedResult => {
112
+ // return tag ? {
113
+ // elements: [...this._taggedElements.get(tag)?.values() ?? []],
114
+ // relations: [...this._taggedRelations.get(tag)?.values() ?? []],
115
+ // } : {
116
+ // elements: uniq([...this._taggedElements.values()].flatMap(s => [...s.values()])),
117
+ // relations: uniq([...this._taggedRelations.values()].flatMap(s => [...s.values()]))
118
+ // }
119
+ // }
120
+ rootElements() {
121
+ return childrenOf(this.root);
122
+ }
123
+ get elements() {
124
+ return [...this._elements];
125
+ }
126
+ // hasElement(fqn: Fqn): boolean {
127
+ // return fqn in this._elements
128
+ // }
129
+ addRelation(rel) {
130
+ // Validate source and target
131
+ this.locateTrie(rel.source);
132
+ this.locateTrie(rel.target);
133
+ this._relations.set(rel.id, rel);
134
+ // for (const tag of rel.tags) {
135
+ // const tagged = this._taggedRelations.get(tag) ?? new Set()
136
+ // tagged.add(rel)
137
+ // this._taggedRelations.set(tag, tagged)
138
+ // }
139
+ }
140
+ defaultViewOf = (id) => {
141
+ return this._defaultElementView.get(id) ?? [];
142
+ };
143
+ }
@@ -0,0 +1,2 @@
1
+ export * from './ModelIndex';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ export * from './ModelIndex';
@@ -0,0 +1,31 @@
1
+ import type { Opaque } from './opaque';
2
+ import type { ElementShape, Fqn, ThemeColor } from './element';
3
+ import type { RelationID } from './relation';
4
+ import type { ElementView, ViewID, ViewRuleAutoLayout } from './view';
5
+ export type NodeId = Fqn;
6
+ export type EdgeId = Opaque<string, 'EdgeId'>;
7
+ export interface ComputedNode {
8
+ id: NodeId;
9
+ parent: NodeId | null;
10
+ title: string;
11
+ description?: string;
12
+ technology?: string;
13
+ children: NodeId[];
14
+ shape: ElementShape;
15
+ color: ThemeColor;
16
+ navigateTo?: ViewID;
17
+ }
18
+ export interface ComputedEdge {
19
+ id: EdgeId;
20
+ parent: NodeId | null;
21
+ source: NodeId;
22
+ target: NodeId;
23
+ label: string | null;
24
+ relations: RelationID[];
25
+ }
26
+ export interface ComputedView<Node extends ComputedNode = ComputedNode, Edge extends ComputedEdge = ComputedEdge> extends ElementView {
27
+ autoLayout: ViewRuleAutoLayout['autoLayout'];
28
+ nodes: Node[];
29
+ edges: Edge[];
30
+ }
31
+ //# sourceMappingURL=computed-view.d.ts.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,28 @@
1
+ import type { ComputedEdge, ComputedNode, ComputedView } from './computed-view';
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
+ }
11
+ export interface DiagramNode extends ComputedNode {
12
+ size: {
13
+ width: number;
14
+ height: number;
15
+ };
16
+ labels: DiagramLabel[];
17
+ position: Point;
18
+ }
19
+ export interface DiagramEdge extends ComputedEdge {
20
+ points: Point[];
21
+ headArrow?: Point[];
22
+ labels: DiagramLabel[];
23
+ }
24
+ export interface DiagramView extends ComputedView<DiagramNode, DiagramEdge> {
25
+ width: number;
26
+ height: number;
27
+ }
28
+ //# sourceMappingURL=diagram.d.ts.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ import type { Opaque } from './opaque';
2
+ export type Fqn = Opaque<string, 'Fqn'>;
3
+ export declare function Fqn(name: string, parent?: Fqn | null): Fqn;
4
+ export type ElementKind = Opaque<string, 'ElementKind'>;
5
+ export type ThemeColor = 'primary' | 'secondary' | 'muted';
6
+ export type ElementShape = 'rectangle' | 'person' | 'browser' | 'cylinder' | 'storage' | 'queue';
7
+ export declare const DefaultThemeColor: ThemeColor;
8
+ export declare const DefaultElementShape: ElementShape;
9
+ export interface ElementStyle {
10
+ shape?: ElementShape;
11
+ }
12
+ export type Tag = Opaque<string, 'Tag'>;
13
+ export interface TagSpec {
14
+ readonly id: Tag;
15
+ readonly style: ElementStyle;
16
+ }
17
+ export interface Element {
18
+ readonly id: Fqn;
19
+ readonly kind: ElementKind;
20
+ readonly title: string;
21
+ readonly description?: string;
22
+ readonly technology?: string;
23
+ readonly tags?: Tag[];
24
+ readonly shape?: ElementShape;
25
+ readonly color?: ThemeColor;
26
+ }
27
+ //# sourceMappingURL=element.d.ts.map
@@ -0,0 +1,5 @@
1
+ export function Fqn(name, parent) {
2
+ return (parent ? parent + '.' + name : name);
3
+ }
4
+ export const DefaultThemeColor = 'primary';
5
+ export const DefaultElementShape = 'rectangle';
@@ -0,0 +1,44 @@
1
+ import type { Fqn } from './element';
2
+ interface BaseExr {
3
+ element?: never;
4
+ isDescedants?: never;
5
+ wildcard?: never;
6
+ source?: never;
7
+ target?: never;
8
+ inout?: never;
9
+ incoming?: never;
10
+ outgoing?: never;
11
+ }
12
+ export interface ElementRefExpr extends Omit<BaseExr, 'element' | 'isDescedants'> {
13
+ element: Fqn;
14
+ isDescedants: boolean;
15
+ }
16
+ export declare function isElementRef(expr: Expression): expr is ElementRefExpr;
17
+ export interface WildcardExpr extends Omit<BaseExr, 'wildcard'> {
18
+ wildcard: true;
19
+ }
20
+ export declare function isWildcard(expr: Expression): expr is WildcardExpr;
21
+ export type ElementExpression = ElementRefExpr | WildcardExpr;
22
+ export declare function isElement(expr: Expression): expr is ElementExpression;
23
+ export interface RelationExpr extends Omit<BaseExr, 'source' | 'target'> {
24
+ source: ElementExpression;
25
+ target: ElementExpression;
26
+ }
27
+ export declare function isRelation(expr: Expression): expr is RelationExpr;
28
+ export interface InOutExpr extends Omit<BaseExr, 'inout'> {
29
+ inout: ElementExpression;
30
+ }
31
+ export declare function isInOut(expr: Expression): expr is InOutExpr;
32
+ export interface IncomingExpr extends Omit<BaseExr, 'incoming'> {
33
+ incoming: ElementExpression;
34
+ }
35
+ export declare function isIncoming(expr: Expression): expr is IncomingExpr;
36
+ export interface OutgoingExpr extends Omit<BaseExr, 'outgoing'> {
37
+ outgoing: ElementExpression;
38
+ }
39
+ export declare function isOutgoing(expr: Expression): expr is OutgoingExpr;
40
+ export type AnyRelationExpression = RelationExpr | InOutExpr | IncomingExpr | OutgoingExpr;
41
+ export declare function isAnyRelation(expr: Expression): expr is AnyRelationExpression;
42
+ export type Expression = ElementExpression | AnyRelationExpression;
43
+ export {};
44
+ //# sourceMappingURL=expression.d.ts.map
@@ -0,0 +1,24 @@
1
+ export function isElementRef(expr) {
2
+ return 'element' in expr && 'isDescedants' in expr;
3
+ }
4
+ export function isWildcard(expr) {
5
+ return 'wildcard' in expr;
6
+ }
7
+ export function isElement(expr) {
8
+ return isElementRef(expr) || isWildcard(expr);
9
+ }
10
+ export function isRelation(expr) {
11
+ return 'source' in expr && 'target' in expr;
12
+ }
13
+ export function isInOut(expr) {
14
+ return 'inout' in expr;
15
+ }
16
+ export function isIncoming(expr) {
17
+ return 'incoming' in expr;
18
+ }
19
+ export function isOutgoing(expr) {
20
+ return 'outgoing' in expr;
21
+ }
22
+ export function isAnyRelation(expr) {
23
+ return isRelation(expr) || isInOut(expr) || isIncoming(expr) || isOutgoing(expr);
24
+ }
@@ -0,0 +1,11 @@
1
+ export { Fqn, DefaultThemeColor, DefaultElementShape } from './element';
2
+ export { isViewRuleExpression, isViewRuleStyle } from './view';
3
+ export type * from './opaque';
4
+ export type * from './element';
5
+ export type * from './relation';
6
+ export type * from './model';
7
+ export type * from './view';
8
+ export type * from './expression';
9
+ export type * from './computed-view';
10
+ export type * from './diagram';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ export { Fqn, DefaultThemeColor, DefaultElementShape } from './element';
2
+ export { isViewRuleExpression, isViewRuleStyle } from './view';
@@ -0,0 +1,10 @@
1
+ import type { Fqn, Element } from './element';
2
+ import type { RelationID, Relation } from './relation';
3
+ import type { ViewID } from './view';
4
+ import type { ComputedView } from '../compute-view';
5
+ export interface LikeC4Model {
6
+ elements: Record<Fqn, Element>;
7
+ relations: Record<RelationID, Relation>;
8
+ views: Record<ViewID, ComputedView>;
9
+ }
10
+ //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1 @@
1
+ export {};