@likec4/core 1.18.0 → 1.19.1
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.
- package/LICENSE +1 -1
- package/dist/builder/index.d.mts +502 -0
- package/dist/builder/index.d.ts +502 -0
- package/dist/builder/index.js +871 -0
- package/dist/compute-view/index.d.mts +9 -78
- package/dist/compute-view/index.d.ts +9 -78
- package/dist/compute-view/index.js +78 -0
- package/dist/index.d.mts +9 -730
- package/dist/index.d.ts +9 -730
- package/dist/{index.mjs → index.js} +7 -784
- package/dist/model/index.d.mts +218 -606
- package/dist/model/index.d.ts +218 -606
- package/dist/model/index.js +1 -0
- package/dist/shared/chunk-RAAYCPUM.M-JWF7SS.js +21 -0
- package/dist/shared/core.BIfgabEw.d.ts +719 -0
- package/dist/shared/core.BZ9Msq7w.d.mts +719 -0
- package/dist/shared/{core.DMYY7C8s.d.mts → core.C05RDLhi.d.ts} +179 -230
- package/dist/shared/{core.DMYY7C8s.d.ts → core.CmYMqgha.d.mts} +179 -230
- package/dist/shared/core.D6-fWbM3.d.ts +127 -0
- package/dist/shared/core.D74xkKkG.d.mts +148 -0
- package/dist/shared/core.D74xkKkG.d.ts +148 -0
- package/dist/shared/core.sLaWHBjR.d.mts +127 -0
- package/dist/shared/index.DafVOuVd.js +7443 -0
- package/dist/shared/object_hash.CE_oF3I3.js +1222 -0
- package/dist/shared/view.CyZrG8BJ.js +354 -0
- package/dist/types/index.d.mts +4 -2
- package/dist/types/index.d.ts +4 -2
- package/dist/types/index.js +20 -0
- package/dist/utils/index.d.mts +419 -0
- package/dist/utils/index.d.ts +419 -0
- package/dist/utils/index.js +347 -0
- package/package.json +47 -33
- package/src/builder/Builder-style1.test-d.ts +190 -0
- package/src/builder/Builder-style2.test-d.ts +175 -0
- package/src/builder/Builder.deployment.ts +25 -20
- package/src/builder/Builder.deploymentModel.ts +80 -55
- package/src/builder/Builder.element.ts +2 -0
- package/src/builder/Builder.model.ts +57 -43
- package/src/builder/Builder.ts +412 -431
- package/src/builder/Builder.view-common.ts +234 -0
- package/src/builder/Builder.view-deployment.ts +135 -0
- package/src/builder/Builder.view-element.ts +189 -0
- package/src/builder/Builder.views.ts +109 -33
- package/src/builder/Builder.with.ts +475 -0
- package/src/builder/__snapshots__/Builder-style1.spec.ts.snap +374 -0
- package/src/builder/__snapshots__/Builder-style2.spec.ts.snap +183 -0
- package/src/builder/__snapshots__/Builder.spec.ts.snap +374 -0
- package/src/builder/_types.ts +28 -5
- package/src/builder/index.ts +10 -4
- package/src/colors/index.ts +2 -2
- package/src/compute-view/compute-view.ts +45 -54
- package/src/compute-view/deployment-view/__test__/TestHelper.ts +236 -0
- package/src/compute-view/deployment-view/__test__/fixture.ts +50 -62
- package/src/compute-view/deployment-view/_types.ts +26 -18
- package/src/compute-view/deployment-view/clean-connections.ts +173 -164
- package/src/compute-view/deployment-view/compute.ts +51 -37
- package/src/compute-view/deployment-view/memory/index.ts +9 -0
- package/src/compute-view/deployment-view/memory/memory.ts +97 -0
- package/src/compute-view/deployment-view/predicates/elements.ts +144 -0
- package/src/compute-view/deployment-view/predicates/relation-direct.ts +183 -76
- package/src/compute-view/deployment-view/predicates/relation-in-out.ts +38 -20
- package/src/compute-view/deployment-view/predicates/relation-incoming.ts +72 -23
- package/src/compute-view/deployment-view/predicates/relation-outgoing.ts +61 -22
- package/src/compute-view/deployment-view/predicates/wildcard.ts +15 -15
- package/src/compute-view/deployment-view/stages/stage-exclude.ts +5 -0
- package/src/compute-view/deployment-view/stages/stage-final.ts +245 -0
- package/src/compute-view/deployment-view/stages/stage-include.ts +95 -0
- package/src/compute-view/deployment-view/utils.ts +95 -31
- package/src/compute-view/dynamic-view/__test__/fixture.ts +4 -4
- package/src/compute-view/dynamic-view/compute.ts +59 -45
- package/src/compute-view/element-view/__test__/TestHelper.ts +258 -0
- package/src/compute-view/element-view/__test__/__snapshots__/legacy.spec.ts.snap +64 -62
- package/src/compute-view/element-view/__test__/fixture.ts +147 -117
- package/src/compute-view/element-view/_types.ts +48 -0
- package/src/compute-view/element-view/clean-connections.ts +113 -0
- package/src/compute-view/element-view/compute.ts +264 -683
- package/src/compute-view/element-view/memory/NodeGroup.ts +31 -0
- package/src/compute-view/element-view/memory/index.ts +10 -0
- package/src/compute-view/element-view/memory/memory.ts +177 -0
- package/src/compute-view/element-view/memory/stage-exclude.ts +59 -0
- package/src/compute-view/element-view/memory/stage-final.ts +129 -0
- package/src/compute-view/element-view/memory/stage-include.ts +128 -0
- package/src/compute-view/element-view/predicates/_utils.ts +86 -0
- package/src/compute-view/element-view/predicates/element-expand.ts +33 -0
- package/src/compute-view/element-view/predicates/element-kind-tag.ts +26 -0
- package/src/compute-view/element-view/predicates/element-ref.ts +37 -0
- package/src/compute-view/element-view/predicates/relation-direct.ts +309 -0
- package/src/compute-view/element-view/predicates/relation-in-out.ts +66 -0
- package/src/compute-view/element-view/predicates/relation-in.ts +118 -0
- package/src/compute-view/element-view/predicates/relation-out.ts +116 -0
- package/src/compute-view/element-view/predicates/wildcard.ts +88 -0
- package/src/compute-view/element-view/utils.ts +59 -0
- package/src/compute-view/index.ts +3 -4
- package/src/compute-view/memory/AbstractMemory.ts +45 -0
- package/src/compute-view/memory/AbstractStageExclude.ts +216 -0
- package/src/compute-view/memory/AbstractStageInclude.ts +200 -0
- package/src/compute-view/memory/_types.ts +147 -0
- package/src/compute-view/memory/index.ts +5 -0
- package/src/compute-view/memory/ops.ts +43 -0
- package/src/compute-view/utils/buildComputedNodes.ts +4 -4
- package/src/compute-view/utils/elementExpressionToPredicate.ts +1 -3
- package/src/compute-view/utils/link-nodes-with-edges.ts +3 -7
- package/src/compute-view/utils/{derive-edge-props-from-relationships.ts → merge-props-from-relationships.ts} +54 -23
- package/src/compute-view/utils/relationExpressionToPredicates.ts +2 -2
- package/src/compute-view/utils/resolve-extended-views.ts +44 -40
- package/src/compute-view/utils/resolve-global-rules.ts +6 -6
- package/src/compute-view/utils/topological-sort.ts +167 -71
- package/src/compute-view/utils/with-readable-edges.ts +14 -9
- package/src/index.ts +22 -16
- package/src/model/DeploymentElementModel.ts +150 -85
- package/src/model/DeploymentModel.ts +27 -21
- package/src/model/ElementModel.ts +51 -25
- package/src/model/LikeC4Model.test-d.ts +4 -3
- package/src/model/LikeC4Model.ts +98 -42
- package/src/model/RelationModel.ts +5 -4
- package/src/model/__test__/fixture.ts +5 -9
- package/src/model/connection/Connection.ts +72 -0
- package/src/model/connection/deployment/DeploymentConnectionModel.ts +178 -0
- package/src/model/connection/{deployment.ts → deployment/find.ts} +14 -18
- package/src/model/connection/deployment/index.ts +8 -0
- package/src/model/connection/index.ts +22 -0
- package/src/model/connection/model/ConnectionModel.ts +157 -0
- package/src/model/connection/{model.ts → model/find.ts} +43 -49
- package/src/model/connection/model/index.ts +8 -0
- package/src/model/connection/ops.ts +274 -0
- package/src/model/guards.ts +9 -0
- package/src/model/index.ts +45 -3
- package/src/model/types.ts +35 -18
- package/src/model/view/EdgeModel.ts +6 -6
- package/src/model/view/LikeC4ViewModel.ts +14 -8
- package/src/model/view/NodeModel.ts +6 -5
- package/src/types/_common.ts +53 -1
- package/src/types/deployments.ts +88 -156
- package/src/types/element.ts +2 -2
- package/src/types/expression-v2.ts +172 -0
- package/src/types/expression.ts +9 -5
- package/src/types/global.ts +3 -3
- package/src/types/index.ts +220 -13
- package/src/types/model.ts +28 -24
- package/src/types/operators.ts +1 -1
- package/src/types/relation.ts +14 -10
- package/src/types/theme.ts +0 -1
- package/src/types/view.ts +20 -18
- package/src/utils/const.ts +1 -0
- package/src/utils/fqn.ts +140 -49
- package/src/utils/getOrCreate.ts +1 -1
- package/src/utils/index.ts +75 -9
- package/src/utils/iterable/_types.ts +5 -0
- package/src/utils/iterable/filter.ts +55 -0
- package/src/utils/iterable/find.ts +36 -0
- package/src/utils/iterable/flat.ts +17 -0
- package/src/utils/iterable/index.ts +13 -0
- package/src/utils/iterable/map.ts +40 -0
- package/src/utils/iterable/reduce.ts +24 -0
- package/src/utils/iterable/some.ts +36 -0
- package/src/utils/iterable/to.ts +19 -0
- package/src/utils/iterable/unique.ts +29 -0
- package/src/utils/relations.ts +3 -64
- package/src/utils/set.ts +11 -9
- package/src/utils/string-hash.ts +1 -1
- package/dist/compute-view/index.mjs +0 -79
- package/dist/model/index.mjs +0 -2
- package/dist/shared/core.BBgiAAv1.mjs +0 -144
- package/dist/shared/core.BPyJvuMU.mjs +0 -2420
- package/dist/shared/core.BQ4AbfvB.mjs +0 -9228
- package/dist/shared/core.k12s_keD.mjs +0 -203
- package/dist/types/index.mjs +0 -21
- package/src/builder/Builder.test-d.ts +0 -124
- package/src/builder/Builder.view.ts +0 -543
- package/src/compute-view/LikeC4ModelGraph.ts +0 -330
- package/src/compute-view/deployment-view/Memory.ts +0 -108
- package/src/compute-view/deployment-view/Stage.ts +0 -145
- package/src/compute-view/deployment-view/predicates/deployment-ref.ts +0 -146
- package/src/compute-view/element-view/predicates.ts +0 -517
- package/src/compute-view/utils/sortNodes.ts +0 -101
- package/src/model/connection/ConnectionModel.ts +0 -94
- package/src/model/connection/DeploymentConnectionModel.ts +0 -99
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import { hasAtLeast, isEmpty } from 'remeda'
|
|
1
|
+
import { hasAtLeast, isEmpty, isNumber, isString } from 'remeda'
|
|
2
2
|
import { invariant, nonexhaustive } from '../../errors'
|
|
3
3
|
import type { LikeC4DeploymentModel } from '../../model'
|
|
4
4
|
import type { DeploymentConnectionModel } from '../../model/connection/deployment'
|
|
5
|
+
import type { ElementModel } from '../../model/ElementModel'
|
|
5
6
|
import type { AnyAux } from '../../model/types'
|
|
6
7
|
import {
|
|
7
8
|
type ComputedEdge,
|
|
8
9
|
type ComputedNode,
|
|
9
10
|
DefaultArrowType,
|
|
10
|
-
DeploymentElementExpression,
|
|
11
11
|
type DeploymentNodeKind,
|
|
12
12
|
type DeploymentViewRule,
|
|
13
13
|
type Fqn,
|
|
14
|
+
FqnExpr,
|
|
14
15
|
isViewRuleStyle,
|
|
15
16
|
type NonEmptyArray,
|
|
16
|
-
type Tag
|
|
17
|
+
type Tag,
|
|
17
18
|
} from '../../types'
|
|
18
19
|
import { nameFromFqn, parentFqn } from '../../utils'
|
|
19
20
|
import { applyViewRuleStyle } from '../utils/applyViewRuleStyles'
|
|
20
21
|
import { buildComputedNodes, type ComputedNodeSource } from '../utils/buildComputedNodes'
|
|
21
|
-
import {
|
|
22
|
+
import { mergePropsFromRelationships } from '../utils/merge-props-from-relationships'
|
|
22
23
|
import { uniqueTags } from '../utils/uniqueTags'
|
|
23
|
-
import type { Elem } from './_types'
|
|
24
|
-
import { type Memory, MutableMemory } from './Memory'
|
|
24
|
+
import type { Elem, Memory } from './_types'
|
|
25
25
|
|
|
26
26
|
type Predicate<T> = (x: T) => boolean
|
|
27
27
|
|
|
28
28
|
export function resolveElements(
|
|
29
29
|
model: LikeC4DeploymentModel,
|
|
30
|
-
expr:
|
|
31
|
-
) {
|
|
32
|
-
const ref = model.element(expr.ref)
|
|
30
|
+
expr: FqnExpr.DeploymentRef,
|
|
31
|
+
): Elem[] {
|
|
32
|
+
const ref = model.element(expr.ref.deployment)
|
|
33
33
|
if (ref.isDeploymentNode()) {
|
|
34
34
|
if (expr.selector === 'children') {
|
|
35
35
|
return [...ref.children()]
|
|
@@ -44,14 +44,31 @@ export function resolveElements(
|
|
|
44
44
|
return [ref]
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
export function
|
|
48
|
-
|
|
47
|
+
export function resolveModelElements(
|
|
48
|
+
model: LikeC4DeploymentModel,
|
|
49
|
+
expr: FqnExpr.ModelRef,
|
|
50
|
+
): ElementModel[] {
|
|
51
|
+
const ref = model.$model.element(expr.ref.model)
|
|
52
|
+
if (expr.selector === 'children') {
|
|
53
|
+
return [...ref.children()]
|
|
54
|
+
}
|
|
55
|
+
if (expr.selector === 'expanded') {
|
|
56
|
+
return [ref, ...ref.children()]
|
|
57
|
+
}
|
|
58
|
+
if (expr.selector === 'descendants') {
|
|
59
|
+
return [...ref.descendants()]
|
|
60
|
+
}
|
|
61
|
+
return [ref]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function deploymentExpressionToPredicate<T extends { id: string; modelRef?: number | string }>(
|
|
65
|
+
target: FqnExpr,
|
|
49
66
|
): Predicate<T> {
|
|
50
|
-
if (
|
|
67
|
+
if (FqnExpr.isWildcard(target)) {
|
|
51
68
|
return () => true
|
|
52
69
|
}
|
|
53
|
-
if (
|
|
54
|
-
const fqn = target.ref.
|
|
70
|
+
if (FqnExpr.isDeploymentRef(target)) {
|
|
71
|
+
const fqn = target.ref.deployment
|
|
55
72
|
if (target.selector === 'expanded') {
|
|
56
73
|
const fqnWithDot = fqn + '.'
|
|
57
74
|
return n => n.id === fqn || n.id.startsWith(fqnWithDot)
|
|
@@ -65,6 +82,55 @@ export function deploymentExpressionToPredicate<T extends { id: string }>(
|
|
|
65
82
|
}
|
|
66
83
|
return n => n.id === fqn
|
|
67
84
|
}
|
|
85
|
+
if (FqnExpr.isModelRef(target)) {
|
|
86
|
+
const modelFqn = (node: T) => {
|
|
87
|
+
if (isString(node.modelRef)) {
|
|
88
|
+
return node.modelRef
|
|
89
|
+
}
|
|
90
|
+
if (isNumber(node.modelRef)) {
|
|
91
|
+
return node.id
|
|
92
|
+
}
|
|
93
|
+
return null
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const fqn = target.ref.model
|
|
97
|
+
if (target.selector === 'expanded') {
|
|
98
|
+
const fqnWithDot = fqn + '.'
|
|
99
|
+
return (n) => {
|
|
100
|
+
const m = modelFqn(n)
|
|
101
|
+
if (!m) {
|
|
102
|
+
return true
|
|
103
|
+
}
|
|
104
|
+
return m === fqn || m.startsWith(fqnWithDot)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (target.selector === 'descendants') {
|
|
108
|
+
const fqnWithDot = fqn + '.'
|
|
109
|
+
return (n) => {
|
|
110
|
+
const m = modelFqn(n)
|
|
111
|
+
if (!m) {
|
|
112
|
+
return true
|
|
113
|
+
}
|
|
114
|
+
return m.startsWith(fqnWithDot)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (target.selector === 'children') {
|
|
118
|
+
return (n) => {
|
|
119
|
+
const m = modelFqn(n)
|
|
120
|
+
if (!m) {
|
|
121
|
+
return true
|
|
122
|
+
}
|
|
123
|
+
return parentFqn(m) === fqn
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return (n) => {
|
|
127
|
+
const m = modelFqn(n)
|
|
128
|
+
if (!m) {
|
|
129
|
+
return true
|
|
130
|
+
}
|
|
131
|
+
return m === fqn
|
|
132
|
+
}
|
|
133
|
+
}
|
|
68
134
|
nonexhaustive(target)
|
|
69
135
|
}
|
|
70
136
|
|
|
@@ -82,7 +148,7 @@ export function toNodeSource(el: Elem): ComputedNodeSource {
|
|
|
82
148
|
return {
|
|
83
149
|
...(onlyOneInstance && {
|
|
84
150
|
...toNodeSource(onlyOneInstance),
|
|
85
|
-
modelRef: onlyOneInstance
|
|
151
|
+
modelRef: onlyOneInstance.element.id,
|
|
86
152
|
}),
|
|
87
153
|
title,
|
|
88
154
|
...$node,
|
|
@@ -90,16 +156,16 @@ export function toNodeSource(el: Elem): ComputedNodeSource {
|
|
|
90
156
|
...(color && { color }),
|
|
91
157
|
...(shape && { shape }),
|
|
92
158
|
style: {
|
|
93
|
-
...style
|
|
159
|
+
...style,
|
|
94
160
|
},
|
|
95
161
|
deploymentRef: 1,
|
|
96
162
|
kind,
|
|
97
|
-
id
|
|
163
|
+
id,
|
|
98
164
|
}
|
|
99
165
|
}
|
|
100
166
|
invariant(el.isInstance(), 'Expected Instance')
|
|
101
167
|
const instance = el.$instance
|
|
102
|
-
const element = el
|
|
168
|
+
const element = el.element.$element
|
|
103
169
|
|
|
104
170
|
const icon = instance.style?.icon ?? element.icon
|
|
105
171
|
const color = instance.style?.color ?? element.color
|
|
@@ -107,12 +173,12 @@ export function toNodeSource(el: Elem): ComputedNodeSource {
|
|
|
107
173
|
|
|
108
174
|
const links = [
|
|
109
175
|
...(element.links ?? []),
|
|
110
|
-
...(instance.links ?? [])
|
|
176
|
+
...(instance.links ?? []),
|
|
111
177
|
]
|
|
112
178
|
|
|
113
179
|
const metadata = {
|
|
114
180
|
...element.metadata,
|
|
115
|
-
...instance.metadata
|
|
181
|
+
...instance.metadata,
|
|
116
182
|
}
|
|
117
183
|
|
|
118
184
|
const notation = instance.notation ?? element.notation
|
|
@@ -130,24 +196,24 @@ export function toNodeSource(el: Elem): ComputedNodeSource {
|
|
|
130
196
|
...shape && { shape },
|
|
131
197
|
style: {
|
|
132
198
|
...element.style,
|
|
133
|
-
...instance.style
|
|
199
|
+
...instance.style,
|
|
134
200
|
},
|
|
135
201
|
deploymentRef: el.id === instance.id ? 1 : instance.id,
|
|
136
202
|
modelRef: el.id === element.id ? 1 : element.id,
|
|
137
203
|
...notation && { notation },
|
|
138
|
-
...!isEmpty(metadata) && ({ metadata })
|
|
204
|
+
...!isEmpty(metadata) && ({ metadata }),
|
|
139
205
|
}
|
|
140
206
|
}
|
|
141
207
|
|
|
142
208
|
export function toComputedEdges<M extends AnyAux>(
|
|
143
|
-
connections: ReadonlyArray<DeploymentConnectionModel<M
|
|
209
|
+
connections: ReadonlyArray<DeploymentConnectionModel<M>>,
|
|
144
210
|
): ComputedEdge[] {
|
|
145
211
|
return connections.reduce((acc, e) => {
|
|
146
212
|
// const modelRelations = []
|
|
147
213
|
// const deploymentRelations = []
|
|
148
214
|
const relations = [
|
|
149
215
|
...e.relations.model,
|
|
150
|
-
...e.relations.deployment
|
|
216
|
+
...e.relations.deployment,
|
|
151
217
|
]
|
|
152
218
|
invariant(hasAtLeast(relations, 1), 'Edge must have at least one relation')
|
|
153
219
|
|
|
@@ -157,7 +223,7 @@ export function toComputedEdges<M extends AnyAux>(
|
|
|
157
223
|
const {
|
|
158
224
|
title,
|
|
159
225
|
...props
|
|
160
|
-
} =
|
|
226
|
+
} = mergePropsFromRelationships(relations.map(r => r.$relationship)) // || relations.find(r => r.source === source && r.target === target)
|
|
161
227
|
|
|
162
228
|
const edge: ComputedEdge = {
|
|
163
229
|
id: e.id,
|
|
@@ -166,7 +232,7 @@ export function toComputedEdges<M extends AnyAux>(
|
|
|
166
232
|
target,
|
|
167
233
|
label: title ?? null,
|
|
168
234
|
relations: relations.map((r) => r.id as M['RelationId']),
|
|
169
|
-
...props
|
|
235
|
+
...props,
|
|
170
236
|
}
|
|
171
237
|
|
|
172
238
|
// If exists same edge but in opposite direction
|
|
@@ -192,15 +258,13 @@ export function toComputedEdges<M extends AnyAux>(
|
|
|
192
258
|
}
|
|
193
259
|
|
|
194
260
|
export function buildNodes(memory: Memory): ReadonlyMap<Fqn, ComputedNode> {
|
|
195
|
-
|
|
196
|
-
invariant(memory instanceof MutableMemory, 'Expected MutableMemory')
|
|
197
|
-
return buildComputedNodes([...memory.finalElements].map(toNodeSource))
|
|
261
|
+
return buildComputedNodes([...memory.final].map(toNodeSource))
|
|
198
262
|
}
|
|
199
263
|
|
|
200
264
|
export function applyDeploymentViewRuleStyles(
|
|
201
265
|
rules: DeploymentViewRule[],
|
|
202
|
-
nodes: ComputedNode[]
|
|
203
|
-
) {
|
|
266
|
+
nodes: ComputedNode[],
|
|
267
|
+
): ComputedNode[] {
|
|
204
268
|
for (const rule of rules) {
|
|
205
269
|
if (!isViewRuleStyle(rule) || rule.targets.length === 0) {
|
|
206
270
|
continue
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { partition } from 'remeda'
|
|
2
2
|
import type { DynamicViewRule, DynamicViewStep, Fqn, ViewId, ViewRulePredicate } from '../../../types'
|
|
3
3
|
import { type FakeElementIds, fakeModel } from '../../element-view/__test__/fixture'
|
|
4
|
-
import {
|
|
4
|
+
import { computeDynamicView } from '../compute'
|
|
5
5
|
|
|
6
6
|
const emptyView = {
|
|
7
7
|
__: 'dynamic' as const,
|
|
@@ -43,13 +43,13 @@ export function $step(expr: StepExpr, props?: string | Partial<StepProps>): Dyna
|
|
|
43
43
|
|
|
44
44
|
export function compute(stepsAndRules: (DynamicViewStep | ViewRulePredicate)[]) {
|
|
45
45
|
const [steps, rules] = partition(stepsAndRules, (s): s is DynamicViewStep => 'source' in s)
|
|
46
|
-
|
|
46
|
+
let view = computeDynamicView(
|
|
47
|
+
fakeModel,
|
|
47
48
|
{
|
|
48
49
|
...emptyView,
|
|
49
50
|
steps,
|
|
50
51
|
rules: rules as DynamicViewRule[]
|
|
51
|
-
}
|
|
52
|
-
fakeModel
|
|
52
|
+
}
|
|
53
53
|
)
|
|
54
54
|
return Object.assign(view, {
|
|
55
55
|
nodeIds: view.nodes.map((node) => node.id) as string[],
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import { filter, findLast, flatMap, hasAtLeast, isTruthy, map, only, pipe, unique } from 'remeda'
|
|
1
|
+
import { filter, findLast, flatMap, hasAtLeast, isTruthy, map, only, pipe, reduce, unique } from 'remeda'
|
|
2
2
|
import { nonNullable } from '../../errors'
|
|
3
|
+
import type { LikeC4Model } from '../../model'
|
|
4
|
+
import { findConnection } from '../../model/connection/model'
|
|
5
|
+
import type { ElementModel } from '../../model/ElementModel'
|
|
6
|
+
import type { AnyAux } from '../../model/types'
|
|
3
7
|
import {
|
|
4
8
|
type Color,
|
|
5
9
|
type ComputedDynamicView,
|
|
@@ -9,7 +13,6 @@ import {
|
|
|
9
13
|
DefaultRelationshipColor,
|
|
10
14
|
type DynamicView,
|
|
11
15
|
type DynamicViewStep,
|
|
12
|
-
type Element,
|
|
13
16
|
isDynamicViewParallelSteps,
|
|
14
17
|
isViewRuleAutoLayout,
|
|
15
18
|
isViewRulePredicate,
|
|
@@ -23,7 +26,6 @@ import {
|
|
|
23
26
|
type ViewId
|
|
24
27
|
} from '../../types'
|
|
25
28
|
import { ancestorsFqn, commonAncestor, parentFqn } from '../../utils/fqn'
|
|
26
|
-
import type { LikeC4ModelGraph } from '../LikeC4ModelGraph'
|
|
27
29
|
import { applyCustomElementProperties } from '../utils/applyCustomElementProperties'
|
|
28
30
|
import { applyViewRuleStyles } from '../utils/applyViewRuleStyles'
|
|
29
31
|
import { buildComputedNodesFromElements } from '../utils/buildComputedNodes'
|
|
@@ -32,7 +34,9 @@ import { elementExprToPredicate } from '../utils/elementExpressionToPredicate'
|
|
|
32
34
|
import { resolveGlobalRulesInDynamicView } from '../utils/resolve-global-rules'
|
|
33
35
|
import { calcViewLayoutHash } from '../utils/view-hash'
|
|
34
36
|
|
|
35
|
-
|
|
37
|
+
type Element = ElementModel
|
|
38
|
+
|
|
39
|
+
namespace DynamicViewCompute {
|
|
36
40
|
export interface Step {
|
|
37
41
|
id: StepEdgeId
|
|
38
42
|
source: Element
|
|
@@ -51,18 +55,14 @@ export namespace DynamicViewComputeCtx {
|
|
|
51
55
|
}
|
|
52
56
|
}
|
|
53
57
|
|
|
54
|
-
|
|
58
|
+
class DynamicViewCompute {
|
|
55
59
|
// Intermediate state
|
|
56
60
|
private explicits = new Set<Element>()
|
|
57
|
-
private steps = [] as
|
|
58
|
-
|
|
59
|
-
public static compute(view: DynamicView, graph: LikeC4ModelGraph): ComputedDynamicView {
|
|
60
|
-
return new DynamicViewComputeCtx(view, graph).compute()
|
|
61
|
-
}
|
|
61
|
+
private steps = [] as DynamicViewCompute.Step[]
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
protected
|
|
65
|
-
protected
|
|
63
|
+
constructor(
|
|
64
|
+
protected model: LikeC4Model,
|
|
65
|
+
protected view: DynamicView
|
|
66
66
|
) {}
|
|
67
67
|
|
|
68
68
|
private addStep(
|
|
@@ -78,8 +78,8 @@ export class DynamicViewComputeCtx {
|
|
|
78
78
|
parent?: number
|
|
79
79
|
) {
|
|
80
80
|
const id = parent ? stepEdgeId(parent, index) : stepEdgeId(index)
|
|
81
|
-
const source = this.
|
|
82
|
-
const target = this.
|
|
81
|
+
const source = this.model.element(stepSource)
|
|
82
|
+
const target = this.model.element(stepTarget)
|
|
83
83
|
|
|
84
84
|
this.explicits.add(source)
|
|
85
85
|
this.explicits.add(target)
|
|
@@ -116,7 +116,7 @@ export class DynamicViewComputeCtx {
|
|
|
116
116
|
})
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
compute(): ComputedDynamicView {
|
|
120
120
|
const {
|
|
121
121
|
docUri: _docUri, // exclude docUri
|
|
122
122
|
rules: _rules, // exclude rules
|
|
@@ -141,18 +141,22 @@ export class DynamicViewComputeCtx {
|
|
|
141
141
|
stepNum++
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
const rules = resolveGlobalRulesInDynamicView(
|
|
144
|
+
const rules = resolveGlobalRulesInDynamicView(_rules, this.model.globals())
|
|
145
145
|
|
|
146
146
|
for (const rule of rules) {
|
|
147
147
|
if (isViewRulePredicate(rule)) {
|
|
148
148
|
for (const expr of rule.include) {
|
|
149
|
-
const
|
|
150
|
-
|
|
149
|
+
const satisfies = elementExprToPredicate(expr)
|
|
150
|
+
for (const e of this.model.elements()) {
|
|
151
|
+
if (satisfies(e)) {
|
|
152
|
+
this.explicits.add(e)
|
|
153
|
+
}
|
|
154
|
+
}
|
|
151
155
|
}
|
|
152
156
|
}
|
|
153
157
|
}
|
|
154
158
|
|
|
155
|
-
const elements = [...this.explicits]
|
|
159
|
+
const elements = [...this.explicits].map(e => e.$element)
|
|
156
160
|
const nodesMap = buildComputedNodesFromElements(elements)
|
|
157
161
|
|
|
158
162
|
const edges = this.steps.map(({ source, target, relations, title, isBackward, ...step }) => {
|
|
@@ -243,7 +247,7 @@ export class DynamicViewComputeCtx {
|
|
|
243
247
|
line: RelationshipLineType | null
|
|
244
248
|
notation: string | null
|
|
245
249
|
} {
|
|
246
|
-
const relationships =
|
|
250
|
+
const relationships = findConnection(source, target, 'directed').flatMap(r => [...r.relations])
|
|
247
251
|
if (relationships.length === 0) {
|
|
248
252
|
return {
|
|
249
253
|
title: null,
|
|
@@ -267,44 +271,54 @@ export class DynamicViewComputeCtx {
|
|
|
267
271
|
const relations = hasAtLeast(relationships, 1) ? map(relationships, r => r.id) : null
|
|
268
272
|
|
|
269
273
|
// Most closest relation
|
|
270
|
-
const relation = only(relationships) || relationships.find(r => r.source === source
|
|
274
|
+
const relation = only(relationships) || relationships.find(r => r.source === source && r.target === target)
|
|
275
|
+
const relationNavigateTo = relation?.$relationship.navigateTo ?? null
|
|
271
276
|
|
|
272
|
-
const navigateTo =
|
|
277
|
+
const navigateTo = relationNavigateTo && relationNavigateTo !== this.view.id ? relationNavigateTo : pipe(
|
|
273
278
|
relationships,
|
|
274
|
-
map(r => r.navigateTo),
|
|
279
|
+
map(r => r.$relationship.navigateTo),
|
|
275
280
|
filter(isTruthy),
|
|
276
281
|
filter(v => v !== this.view.id),
|
|
277
282
|
unique(),
|
|
278
283
|
only()
|
|
279
284
|
)
|
|
280
285
|
|
|
281
|
-
const commonProperties =
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
286
|
+
const commonProperties = pipe(
|
|
287
|
+
relationships,
|
|
288
|
+
reduce((acc, { title, $relationship: r }) => {
|
|
289
|
+
isTruthy(title) && acc.title.add(title)
|
|
290
|
+
isTruthy(r.tail) && acc.tail.add(r.tail)
|
|
291
|
+
isTruthy(r.head) && acc.head.add(r.head)
|
|
292
|
+
isTruthy(r.color) && acc.color.add(r.color)
|
|
293
|
+
isTruthy(r.line) && acc.line.add(r.line)
|
|
287
294
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
295
|
+
return acc
|
|
296
|
+
}, {
|
|
297
|
+
tail: new Set<RelationshipArrowType>(),
|
|
298
|
+
head: new Set<RelationshipArrowType>(),
|
|
299
|
+
color: new Set<Color>(),
|
|
300
|
+
line: new Set<RelationshipLineType>(),
|
|
301
|
+
notation: new Set<string>(),
|
|
302
|
+
title: new Set<string>()
|
|
303
|
+
})
|
|
304
|
+
)
|
|
297
305
|
|
|
298
306
|
return {
|
|
299
307
|
tags,
|
|
300
308
|
relations,
|
|
301
309
|
navigateTo: navigateTo ?? null,
|
|
302
|
-
title:
|
|
303
|
-
tail:
|
|
304
|
-
head:
|
|
305
|
-
color:
|
|
306
|
-
line:
|
|
307
|
-
notation:
|
|
310
|
+
title: only([...commonProperties.title]) ?? null,
|
|
311
|
+
tail: only([...commonProperties.tail]) ?? null,
|
|
312
|
+
head: only([...commonProperties.head]) ?? null,
|
|
313
|
+
color: only([...commonProperties.color]) ?? null,
|
|
314
|
+
line: only([...commonProperties.line]) ?? null,
|
|
315
|
+
notation: only([...commonProperties.notation]) ?? null
|
|
308
316
|
}
|
|
309
317
|
}
|
|
310
318
|
}
|
|
319
|
+
export function computeDynamicView<M extends AnyAux>(
|
|
320
|
+
model: LikeC4Model<M>,
|
|
321
|
+
view: DynamicView
|
|
322
|
+
): ComputedDynamicView {
|
|
323
|
+
return new DynamicViewCompute(model, view).compute()
|
|
324
|
+
}
|