@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
|
@@ -3,44 +3,50 @@ import type { SetRequired } from 'type-fest'
|
|
|
3
3
|
import { nonNullable } from '../errors'
|
|
4
4
|
import {
|
|
5
5
|
type ComputedDeploymentView,
|
|
6
|
-
DefaultElementShape,
|
|
7
|
-
DefaultThemeColor,
|
|
8
6
|
type DeployedInstance,
|
|
7
|
+
type DeploymentElementStyle,
|
|
9
8
|
type DeploymentNode,
|
|
10
9
|
type DeploymentNodeKind,
|
|
11
10
|
type DeploymentRelation,
|
|
12
11
|
type ElementShape as C4ElementShape,
|
|
12
|
+
type IteratorLike,
|
|
13
13
|
type Link,
|
|
14
|
-
type PhysicalElementStyle,
|
|
15
14
|
type Tag,
|
|
16
15
|
type Tag as C4Tag,
|
|
17
|
-
type ThemeColor
|
|
16
|
+
type ThemeColor,
|
|
17
|
+
DefaultElementShape,
|
|
18
|
+
DefaultThemeColor,
|
|
18
19
|
} from '../types'
|
|
19
|
-
import { commonAncestor,
|
|
20
|
+
import { commonAncestor, hierarchyLevel } from '../utils'
|
|
20
21
|
import { difference, intersection, union } from '../utils/set'
|
|
21
22
|
import type { LikeC4DeploymentModel } from './DeploymentModel'
|
|
22
23
|
import type { ElementModel } from './ElementModel'
|
|
23
24
|
import type { RelationshipModel, RelationshipsIterator } from './RelationModel'
|
|
24
|
-
import type { AnyAux, IncomingFilter,
|
|
25
|
+
import type { AnyAux, IncomingFilter, OutgoingFilter } from './types'
|
|
25
26
|
import type { LikeC4ViewModel } from './view/LikeC4ViewModel'
|
|
26
27
|
|
|
27
|
-
export type DeploymentElementsIterator<M extends AnyAux> = IteratorLike<
|
|
28
|
+
export type DeploymentElementsIterator<M extends AnyAux> = IteratorLike<
|
|
29
|
+
DeploymentNodeModel<M> | DeployedInstanceModel<M>
|
|
30
|
+
>
|
|
28
31
|
export type DeployedInstancesIterator<M extends AnyAux> = IteratorLike<DeployedInstanceModel<M>>
|
|
29
32
|
export type DeploymentNodesIterator<M extends AnyAux> = IteratorLike<DeploymentNodeModel<M>>
|
|
30
33
|
|
|
31
|
-
export
|
|
34
|
+
export type DeploymentElementModel<M extends AnyAux = AnyAux> = DeploymentNodeModel<M> | DeployedInstanceModel<M>
|
|
35
|
+
|
|
36
|
+
abstract class AbstractDeploymentElementModel<M extends AnyAux = AnyAux> {
|
|
37
|
+
abstract readonly id: M['DeploymentFqn']
|
|
38
|
+
abstract readonly parent: DeploymentNodeModel<M> | null
|
|
39
|
+
abstract readonly title: string
|
|
40
|
+
abstract readonly hierarchyLevel: number
|
|
41
|
+
|
|
32
42
|
abstract readonly $model: LikeC4DeploymentModel<M>
|
|
33
43
|
abstract readonly $node: DeploymentNode | DeployedInstance
|
|
34
44
|
|
|
35
|
-
get
|
|
36
|
-
return this.$node.id
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
get style(): SetRequired<PhysicalElementStyle, 'shape' | 'color'> {
|
|
45
|
+
get style(): SetRequired<DeploymentElementStyle, 'shape' | 'color'> {
|
|
40
46
|
return {
|
|
41
47
|
shape: DefaultElementShape,
|
|
42
48
|
color: DefaultThemeColor,
|
|
43
|
-
...this.$node.style
|
|
49
|
+
...this.$node.style,
|
|
44
50
|
}
|
|
45
51
|
}
|
|
46
52
|
|
|
@@ -56,10 +62,6 @@ export abstract class DeploymentElementModel<M extends AnyAux = AnyAux> {
|
|
|
56
62
|
return this.$node.tags ?? []
|
|
57
63
|
}
|
|
58
64
|
|
|
59
|
-
get title(): string {
|
|
60
|
-
return this.$node.title ?? nameFromFqn(this.id)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
65
|
get description(): string | null {
|
|
64
66
|
return this.$node.description ?? null
|
|
65
67
|
}
|
|
@@ -68,10 +70,6 @@ export abstract class DeploymentElementModel<M extends AnyAux = AnyAux> {
|
|
|
68
70
|
return this.$node.technology ?? null
|
|
69
71
|
}
|
|
70
72
|
|
|
71
|
-
get parent(): DeploymentNodeModel<M> | null {
|
|
72
|
-
return this.$model.parent(this)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
73
|
get links(): ReadonlyArray<Link> {
|
|
76
74
|
return this.$node.links ?? []
|
|
77
75
|
}
|
|
@@ -118,6 +116,18 @@ export abstract class DeploymentElementModel<M extends AnyAux = AnyAux> {
|
|
|
118
116
|
return
|
|
119
117
|
}
|
|
120
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Resolve siblings of the element and its ancestors
|
|
121
|
+
* (from root to closest)
|
|
122
|
+
*/
|
|
123
|
+
public *descendingSiblings(): DeploymentElementsIterator<M> {
|
|
124
|
+
for (const ancestor of [...this.ancestors()].reverse()) {
|
|
125
|
+
yield* ancestor.siblings()
|
|
126
|
+
}
|
|
127
|
+
yield* this.siblings()
|
|
128
|
+
return
|
|
129
|
+
}
|
|
130
|
+
|
|
121
131
|
public incoming(filter: IncomingFilter = 'all'): IteratorLike<DeploymentRelationModel<M>> {
|
|
122
132
|
return this.$model.incoming(this, filter)
|
|
123
133
|
}
|
|
@@ -153,6 +163,9 @@ export abstract class DeploymentElementModel<M extends AnyAux = AnyAux> {
|
|
|
153
163
|
*/
|
|
154
164
|
public *views(): IteratorLike<LikeC4ViewModel<M, ComputedDeploymentView>> {
|
|
155
165
|
for (const view of this.$model.views()) {
|
|
166
|
+
if (!view.isDeploymentView()) {
|
|
167
|
+
continue
|
|
168
|
+
}
|
|
156
169
|
if (view.includesDeployment(this.id)) {
|
|
157
170
|
yield view
|
|
158
171
|
}
|
|
@@ -168,35 +181,46 @@ export abstract class DeploymentElementModel<M extends AnyAux = AnyAux> {
|
|
|
168
181
|
return false
|
|
169
182
|
}
|
|
170
183
|
|
|
171
|
-
public abstract
|
|
172
|
-
public abstract
|
|
184
|
+
public abstract outgoingModelRelationships(): RelationshipsIterator<M>
|
|
185
|
+
public abstract incomingModelRelationships(): RelationshipsIterator<M>
|
|
173
186
|
|
|
174
187
|
protected cachedOutgoing: RelationshipsAccum<M> | null = null
|
|
175
188
|
protected cachedIncoming: RelationshipsAccum<M> | null = null
|
|
176
189
|
|
|
177
190
|
public get allOutgoing(): RelationshipsAccum<M> {
|
|
178
|
-
this.cachedOutgoing ??=
|
|
179
|
-
new Set(this.
|
|
180
|
-
new Set(this.outgoing())
|
|
191
|
+
this.cachedOutgoing ??= RelationshipsAccum.from(
|
|
192
|
+
new Set(this.outgoingModelRelationships()),
|
|
193
|
+
new Set(this.outgoing()),
|
|
181
194
|
)
|
|
182
195
|
return this.cachedOutgoing
|
|
183
196
|
}
|
|
184
197
|
|
|
185
198
|
public get allIncoming(): RelationshipsAccum<M> {
|
|
186
|
-
this.cachedIncoming ??=
|
|
187
|
-
new Set(this.
|
|
188
|
-
new Set(this.incoming())
|
|
199
|
+
this.cachedIncoming ??= RelationshipsAccum.from(
|
|
200
|
+
new Set(this.incomingModelRelationships()),
|
|
201
|
+
new Set(this.incoming()),
|
|
189
202
|
)
|
|
190
203
|
return this.cachedIncoming
|
|
191
204
|
}
|
|
192
205
|
}
|
|
193
206
|
|
|
194
|
-
export class DeploymentNodeModel<M extends AnyAux = AnyAux> extends
|
|
207
|
+
export class DeploymentNodeModel<M extends AnyAux = AnyAux> extends AbstractDeploymentElementModel<M> {
|
|
208
|
+
override id: M['DeploymentFqn']
|
|
209
|
+
override title: string
|
|
210
|
+
override hierarchyLevel: number
|
|
211
|
+
|
|
195
212
|
constructor(
|
|
196
213
|
public readonly $model: LikeC4DeploymentModel<M>,
|
|
197
|
-
public readonly $node: DeploymentNode
|
|
214
|
+
public readonly $node: DeploymentNode,
|
|
198
215
|
) {
|
|
199
216
|
super()
|
|
217
|
+
this.id = $node.id
|
|
218
|
+
this.title = $node.title
|
|
219
|
+
this.hierarchyLevel = hierarchyLevel($node.id)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
get parent(): DeploymentNodeModel<M> | null {
|
|
223
|
+
return this.$model.parent(this)
|
|
200
224
|
}
|
|
201
225
|
|
|
202
226
|
get kind(): DeploymentNodeKind {
|
|
@@ -207,8 +231,8 @@ export class DeploymentNodeModel<M extends AnyAux = AnyAux> extends DeploymentEl
|
|
|
207
231
|
return this.$model.children(this)
|
|
208
232
|
}
|
|
209
233
|
|
|
210
|
-
public descendants(): DeploymentElementsIterator<M> {
|
|
211
|
-
return this.$model.descendants(this)
|
|
234
|
+
public descendants(sort: 'asc' | 'desc' = 'desc'): DeploymentElementsIterator<M> {
|
|
235
|
+
return this.$model.descendants(this, sort)
|
|
212
236
|
}
|
|
213
237
|
|
|
214
238
|
public override isDeploymentNode(): this is DeploymentNodeModel<M> {
|
|
@@ -219,7 +243,7 @@ export class DeploymentNodeModel<M extends AnyAux = AnyAux> extends DeploymentEl
|
|
|
219
243
|
* Iterate over all instances nested in this deployment node.
|
|
220
244
|
*/
|
|
221
245
|
public *instances(): DeployedInstancesIterator<M> {
|
|
222
|
-
for (const nested of this.descendants()) {
|
|
246
|
+
for (const nested of this.descendants('desc')) {
|
|
223
247
|
if (nested.isInstance()) {
|
|
224
248
|
yield nested
|
|
225
249
|
}
|
|
@@ -254,16 +278,16 @@ export class DeploymentNodeModel<M extends AnyAux = AnyAux> extends DeploymentEl
|
|
|
254
278
|
}
|
|
255
279
|
const {
|
|
256
280
|
outgoing,
|
|
257
|
-
incoming
|
|
281
|
+
incoming,
|
|
258
282
|
} = (this._relationshipsFromInstances = {
|
|
259
283
|
outgoing: new Set<RelationshipModel<M>>(),
|
|
260
|
-
incoming: new Set<RelationshipModel<M>>()
|
|
284
|
+
incoming: new Set<RelationshipModel<M>>(),
|
|
261
285
|
})
|
|
262
286
|
for (const instance of this.instances()) {
|
|
263
|
-
for (const r of instance
|
|
287
|
+
for (const r of instance.element.outgoing()) {
|
|
264
288
|
outgoing.add(r)
|
|
265
289
|
}
|
|
266
|
-
for (const r of instance
|
|
290
|
+
for (const r of instance.element.incoming()) {
|
|
267
291
|
incoming.add(r)
|
|
268
292
|
}
|
|
269
293
|
}
|
|
@@ -273,98 +297,127 @@ export class DeploymentNodeModel<M extends AnyAux = AnyAux> extends DeploymentEl
|
|
|
273
297
|
/**
|
|
274
298
|
* We return only relationships that are not already present in nested instances
|
|
275
299
|
*/
|
|
276
|
-
public override
|
|
277
|
-
|
|
278
|
-
outgoing,
|
|
279
|
-
incoming
|
|
280
|
-
} = this.relationshipsFromInstances()
|
|
281
|
-
return difference(outgoing, incoming).values()
|
|
300
|
+
public override outgoingModelRelationships(): RelationshipsIterator<M> {
|
|
301
|
+
return this.relationshipsFromInstances().outgoing.values()
|
|
282
302
|
}
|
|
283
303
|
|
|
284
304
|
/**
|
|
285
305
|
* We return only relationships that are not already present in nested instances
|
|
286
306
|
*/
|
|
287
|
-
public override
|
|
307
|
+
public override incomingModelRelationships(): RelationshipsIterator<M> {
|
|
308
|
+
return this.relationshipsFromInstances().incoming.values()
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Returns an iterator of relationships between nested instances
|
|
313
|
+
*/
|
|
314
|
+
public internalModelRelationships(): ReadonlySet<RelationshipModel<M>> {
|
|
288
315
|
const {
|
|
289
316
|
outgoing,
|
|
290
|
-
incoming
|
|
317
|
+
incoming,
|
|
291
318
|
} = this.relationshipsFromInstances()
|
|
292
|
-
return
|
|
319
|
+
return intersection(incoming, outgoing)
|
|
293
320
|
}
|
|
294
321
|
}
|
|
295
322
|
|
|
296
|
-
export class DeployedInstanceModel<M extends AnyAux = AnyAux> extends
|
|
323
|
+
export class DeployedInstanceModel<M extends AnyAux = AnyAux> extends AbstractDeploymentElementModel<M> {
|
|
324
|
+
override readonly id: M['DeploymentFqn']
|
|
325
|
+
override readonly title: string
|
|
326
|
+
override readonly hierarchyLevel: number
|
|
327
|
+
|
|
297
328
|
constructor(
|
|
298
329
|
public readonly $model: LikeC4DeploymentModel<M>,
|
|
299
330
|
public readonly $instance: DeployedInstance,
|
|
300
|
-
public readonly
|
|
331
|
+
public readonly element: ElementModel<M>,
|
|
301
332
|
) {
|
|
302
333
|
super()
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
return nonNullable(this.$model.parent(this), `Parent of ${this.id} not found`)
|
|
334
|
+
this.id = $instance.id
|
|
335
|
+
this.title = $instance.title ?? element.title
|
|
336
|
+
this.hierarchyLevel = hierarchyLevel($instance.id)
|
|
307
337
|
}
|
|
308
338
|
|
|
309
339
|
get $node(): DeployedInstance {
|
|
310
340
|
return this.$instance
|
|
311
341
|
}
|
|
312
342
|
|
|
313
|
-
|
|
314
|
-
|
|
343
|
+
get parent(): DeploymentNodeModel<M> {
|
|
344
|
+
return nonNullable(this.$model.parent(this), `Parent of ${this.id} not found`)
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
override get style(): SetRequired<DeploymentElementStyle, 'shape' | 'color'> {
|
|
348
|
+
const { icon, style } = this.element.$element
|
|
315
349
|
return {
|
|
316
|
-
shape: this
|
|
317
|
-
color: this
|
|
350
|
+
shape: this.element.shape,
|
|
351
|
+
color: this.element.color,
|
|
318
352
|
...icon && { icon },
|
|
319
353
|
...style,
|
|
320
|
-
...this.$instance.style
|
|
354
|
+
...this.$instance.style,
|
|
321
355
|
}
|
|
322
356
|
}
|
|
323
357
|
|
|
324
358
|
override get shape(): C4ElementShape {
|
|
325
|
-
return this.$instance.style?.shape ?? this
|
|
359
|
+
return this.$instance.style?.shape ?? this.element.shape
|
|
326
360
|
}
|
|
327
361
|
|
|
328
362
|
override get color(): ThemeColor {
|
|
329
|
-
return this.$instance.style?.color as ThemeColor ?? this
|
|
363
|
+
return this.$instance.style?.color as ThemeColor ?? this.element.color
|
|
330
364
|
}
|
|
331
365
|
|
|
332
366
|
override get tags(): ReadonlyArray<C4Tag> {
|
|
333
367
|
return this.$instance.tags ?? []
|
|
334
368
|
}
|
|
335
369
|
|
|
336
|
-
override get title(): string {
|
|
337
|
-
return this.$instance.title ?? this.$element.title
|
|
338
|
-
}
|
|
339
|
-
|
|
340
370
|
override get description(): string | null {
|
|
341
|
-
return this.$instance.description ?? this
|
|
371
|
+
return this.$instance.description ?? this.element.description
|
|
342
372
|
}
|
|
343
373
|
|
|
344
374
|
override get technology(): string | null {
|
|
345
|
-
return this.$instance.technology ?? this
|
|
375
|
+
return this.$instance.technology ?? this.element.technology
|
|
346
376
|
}
|
|
347
377
|
|
|
348
378
|
override get links(): ReadonlyArray<Link> {
|
|
349
|
-
return this.$instance.links ?? this
|
|
379
|
+
return this.$instance.links ?? this.element.links
|
|
350
380
|
}
|
|
351
381
|
|
|
352
382
|
public override isInstance(): this is DeployedInstanceModel<M> {
|
|
353
383
|
return true
|
|
354
384
|
}
|
|
355
385
|
|
|
356
|
-
public override
|
|
357
|
-
return this
|
|
386
|
+
public override outgoingModelRelationships(): RelationshipsIterator<M> {
|
|
387
|
+
return this.element.outgoing()
|
|
358
388
|
}
|
|
359
|
-
public override
|
|
360
|
-
return this
|
|
389
|
+
public override incomingModelRelationships(): RelationshipsIterator<M> {
|
|
390
|
+
return this.element.incoming()
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Iterate over all views that include this instance.
|
|
395
|
+
* (Some views may include the parent deployment node instead of the instance.)
|
|
396
|
+
*/
|
|
397
|
+
public override *views(): IteratorLike<LikeC4ViewModel<M, ComputedDeploymentView>> {
|
|
398
|
+
for (const view of this.$model.views()) {
|
|
399
|
+
if (!view.isDeploymentView()) {
|
|
400
|
+
continue
|
|
401
|
+
}
|
|
402
|
+
if (view.includesDeployment(this.id)) {
|
|
403
|
+
yield view
|
|
404
|
+
continue
|
|
405
|
+
}
|
|
406
|
+
// check if the view includes parent referecing this element
|
|
407
|
+
if (
|
|
408
|
+
view.includesDeployment(this.parent.id)
|
|
409
|
+
&& this.parent.onlyOneInstance()
|
|
410
|
+
) {
|
|
411
|
+
yield view
|
|
412
|
+
}
|
|
413
|
+
}
|
|
361
414
|
}
|
|
362
415
|
}
|
|
363
416
|
|
|
364
417
|
export class NestedElementOfDeployedInstanceModel<M extends AnyAux> {
|
|
365
418
|
constructor(
|
|
366
419
|
public readonly instance: DeployedInstanceModel<M>,
|
|
367
|
-
public readonly element: ElementModel<M
|
|
420
|
+
public readonly element: ElementModel<M>,
|
|
368
421
|
) {
|
|
369
422
|
}
|
|
370
423
|
|
|
@@ -372,13 +425,13 @@ export class NestedElementOfDeployedInstanceModel<M extends AnyAux> {
|
|
|
372
425
|
return this.instance.id
|
|
373
426
|
}
|
|
374
427
|
|
|
375
|
-
get style(): SetRequired<
|
|
428
|
+
get style(): SetRequired<DeploymentElementStyle, 'shape' | 'color'> {
|
|
376
429
|
const { icon, style } = this.element.$element
|
|
377
430
|
return {
|
|
378
431
|
shape: this.element.shape,
|
|
379
432
|
color: this.element.color,
|
|
380
433
|
...icon && { icon },
|
|
381
|
-
...style
|
|
434
|
+
...style,
|
|
382
435
|
}
|
|
383
436
|
}
|
|
384
437
|
|
|
@@ -414,14 +467,14 @@ export type DeploymentRelationEndpoint<M extends AnyAux> =
|
|
|
414
467
|
| DeploymentElementModel<M>
|
|
415
468
|
| NestedElementOfDeployedInstanceModel<M>
|
|
416
469
|
|
|
417
|
-
export class DeploymentRelationModel<M extends AnyAux> {
|
|
470
|
+
export class DeploymentRelationModel<M extends AnyAux = AnyAux> {
|
|
418
471
|
public boundary: DeploymentNodeModel<M> | null
|
|
419
472
|
public source: DeploymentRelationEndpoint<M>
|
|
420
473
|
public target: DeploymentRelationEndpoint<M>
|
|
421
474
|
|
|
422
475
|
constructor(
|
|
423
476
|
public readonly $model: LikeC4DeploymentModel<M>,
|
|
424
|
-
public readonly $relationship: DeploymentRelation
|
|
477
|
+
public readonly $relationship: DeploymentRelation,
|
|
425
478
|
) {
|
|
426
479
|
this.source = $model.deploymentRef($relationship.source)
|
|
427
480
|
this.target = $model.deploymentRef($relationship.target)
|
|
@@ -480,13 +533,25 @@ export class DeploymentRelationModel<M extends AnyAux> {
|
|
|
480
533
|
}
|
|
481
534
|
|
|
482
535
|
export class RelationshipsAccum<M extends AnyAux> {
|
|
536
|
+
static empty<M extends AnyAux>(): RelationshipsAccum<M> {
|
|
537
|
+
return new RelationshipsAccum()
|
|
538
|
+
}
|
|
539
|
+
static from<M extends AnyAux>(
|
|
540
|
+
model: Iterable<RelationshipModel<M>> | undefined,
|
|
541
|
+
deployment?: Iterable<DeploymentRelationModel<M>>,
|
|
542
|
+
): RelationshipsAccum<M> {
|
|
543
|
+
return new RelationshipsAccum(
|
|
544
|
+
new Set(model),
|
|
545
|
+
new Set(deployment),
|
|
546
|
+
)
|
|
547
|
+
}
|
|
483
548
|
/**
|
|
484
549
|
* @param model relationships from logical model
|
|
485
550
|
* @param deployment relationships from deployment model
|
|
486
551
|
*/
|
|
487
552
|
constructor(
|
|
488
|
-
public readonly model: ReadonlySet<RelationshipModel<M
|
|
489
|
-
public readonly deployment: ReadonlySet<DeploymentRelationModel<M>>
|
|
553
|
+
public readonly model: ReadonlySet<RelationshipModel<M>> = new Set(),
|
|
554
|
+
public readonly deployment: ReadonlySet<DeploymentRelationModel<M>> = new Set(),
|
|
490
555
|
) {
|
|
491
556
|
}
|
|
492
557
|
|
|
@@ -506,9 +571,9 @@ export class RelationshipsAccum<M extends AnyAux> {
|
|
|
506
571
|
* Returns new Accum containing all the elements which are both in this and otherAccum
|
|
507
572
|
*/
|
|
508
573
|
public intersect(otherAccum: RelationshipsAccum<M>): RelationshipsAccum<M> {
|
|
509
|
-
return
|
|
574
|
+
return RelationshipsAccum.from(
|
|
510
575
|
intersection(this.model, otherAccum.model),
|
|
511
|
-
intersection(this.deployment, otherAccum.deployment)
|
|
576
|
+
intersection(this.deployment, otherAccum.deployment),
|
|
512
577
|
)
|
|
513
578
|
}
|
|
514
579
|
|
|
@@ -516,9 +581,9 @@ export class RelationshipsAccum<M extends AnyAux> {
|
|
|
516
581
|
* Returns new Accum containing all the elements which are both in this and otherAccum
|
|
517
582
|
*/
|
|
518
583
|
public difference(otherAccum: RelationshipsAccum<M>): RelationshipsAccum<M> {
|
|
519
|
-
return
|
|
584
|
+
return RelationshipsAccum.from(
|
|
520
585
|
difference(this.model, otherAccum.model),
|
|
521
|
-
difference(this.deployment, otherAccum.deployment)
|
|
586
|
+
difference(this.deployment, otherAccum.deployment),
|
|
522
587
|
)
|
|
523
588
|
}
|
|
524
589
|
|
|
@@ -526,9 +591,9 @@ export class RelationshipsAccum<M extends AnyAux> {
|
|
|
526
591
|
* Returns new Accum containing all the elements from both
|
|
527
592
|
*/
|
|
528
593
|
public union(otherAccum: RelationshipsAccum<M>): RelationshipsAccum<M> {
|
|
529
|
-
return
|
|
594
|
+
return RelationshipsAccum.from(
|
|
530
595
|
union(this.model, otherAccum.model),
|
|
531
|
-
union(this.deployment, otherAccum.deployment)
|
|
596
|
+
union(this.deployment, otherAccum.deployment),
|
|
532
597
|
)
|
|
533
598
|
}
|
|
534
599
|
}
|
|
@@ -3,28 +3,29 @@ import { values } from 'remeda'
|
|
|
3
3
|
import type { LiteralUnion } from 'type-fest'
|
|
4
4
|
import { invariant, nonNullable } from '../errors'
|
|
5
5
|
import {
|
|
6
|
-
type AnyLikeC4Model,
|
|
7
6
|
type ComputedDeploymentView,
|
|
8
|
-
DeploymentElement,
|
|
9
7
|
type DeploymentRef,
|
|
10
8
|
type DeploymentRelation,
|
|
11
|
-
type
|
|
9
|
+
type GenericLikeC4Model,
|
|
10
|
+
type IteratorLike,
|
|
11
|
+
type Tag as C4Tag,
|
|
12
|
+
DeploymentElement,
|
|
12
13
|
} from '../types'
|
|
13
|
-
import { ancestorsFqn, parentFqn } from '../utils/fqn'
|
|
14
|
+
import { ancestorsFqn, parentFqn, sortParentsFirst } from '../utils/fqn'
|
|
14
15
|
import { getOrCreate } from '../utils/getOrCreate'
|
|
15
16
|
import { isString } from '../utils/guards'
|
|
16
17
|
import {
|
|
17
|
-
DeployedInstanceModel,
|
|
18
18
|
type DeployedInstancesIterator,
|
|
19
|
-
DeploymentElementModel,
|
|
19
|
+
type DeploymentElementModel,
|
|
20
20
|
type DeploymentElementsIterator,
|
|
21
|
-
DeploymentNodeModel,
|
|
22
21
|
type DeploymentNodesIterator,
|
|
22
|
+
DeployedInstanceModel,
|
|
23
|
+
DeploymentNodeModel,
|
|
23
24
|
DeploymentRelationModel,
|
|
24
|
-
NestedElementOfDeployedInstanceModel
|
|
25
|
+
NestedElementOfDeployedInstanceModel,
|
|
25
26
|
} from './DeploymentElementModel'
|
|
26
27
|
import type { LikeC4Model } from './LikeC4Model'
|
|
27
|
-
import { type AnyAux,
|
|
28
|
+
import { type AnyAux, type IncomingFilter, type OutgoingFilter, getId } from './types'
|
|
28
29
|
import type { LikeC4ViewModel } from './view/LikeC4ViewModel'
|
|
29
30
|
|
|
30
31
|
export class LikeC4DeploymentModel<M extends AnyAux = AnyAux> {
|
|
@@ -63,15 +64,15 @@ export class LikeC4DeploymentModel<M extends AnyAux = AnyAux> {
|
|
|
63
64
|
|
|
64
65
|
constructor(
|
|
65
66
|
public readonly $model: LikeC4Model<M>,
|
|
66
|
-
public readonly $deployments:
|
|
67
|
+
public readonly $deployments: GenericLikeC4Model['deployments'],
|
|
67
68
|
) {
|
|
68
|
-
for (const element of values($deployments.elements)) {
|
|
69
|
+
for (const element of sortParentsFirst(values($deployments.elements))) {
|
|
69
70
|
const el = this.addElement(element)
|
|
70
71
|
for (const tag of el.tags) {
|
|
71
72
|
this.#allTags.get(tag).add(el)
|
|
72
73
|
}
|
|
73
74
|
if (el.isInstance()) {
|
|
74
|
-
this.#instancesOf.get(el
|
|
75
|
+
this.#instancesOf.get(el.element.id).add(el)
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
78
|
for (const relation of values($deployments.relations)) {
|
|
@@ -83,7 +84,7 @@ export class LikeC4DeploymentModel<M extends AnyAux = AnyAux> {
|
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
public element(el: M['DeploymentOrFqn']): DeploymentElementModel<M> {
|
|
86
|
-
if (el instanceof
|
|
87
|
+
if (el instanceof DeploymentNodeModel || el instanceof DeployedInstanceModel) {
|
|
87
88
|
return el
|
|
88
89
|
}
|
|
89
90
|
const id = getId(el)
|
|
@@ -256,10 +257,15 @@ export class LikeC4DeploymentModel<M extends AnyAux = AnyAux> {
|
|
|
256
257
|
/**
|
|
257
258
|
* Get all descendant elements (i.e. children, children’s children, etc.)
|
|
258
259
|
*/
|
|
259
|
-
public *descendants(element: M['DeploymentOrFqn']): DeploymentElementsIterator<M> {
|
|
260
|
+
public *descendants(element: M['DeploymentOrFqn'], sort: 'asc' | 'desc' = 'desc'): DeploymentElementsIterator<M> {
|
|
260
261
|
for (const child of this.children(element)) {
|
|
261
|
-
|
|
262
|
-
|
|
262
|
+
if (sort === 'asc') {
|
|
263
|
+
yield child
|
|
264
|
+
yield* this.descendants(child.id)
|
|
265
|
+
} else {
|
|
266
|
+
yield* this.descendants(child.id)
|
|
267
|
+
yield child
|
|
268
|
+
}
|
|
263
269
|
}
|
|
264
270
|
return
|
|
265
271
|
}
|
|
@@ -270,7 +276,7 @@ export class LikeC4DeploymentModel<M extends AnyAux = AnyAux> {
|
|
|
270
276
|
*/
|
|
271
277
|
public *incoming(
|
|
272
278
|
element: M['DeploymentOrFqn'],
|
|
273
|
-
filter: IncomingFilter = 'all'
|
|
279
|
+
filter: IncomingFilter = 'all',
|
|
274
280
|
): IteratorLike<DeploymentRelationModel<M>> {
|
|
275
281
|
const id = getId(element)
|
|
276
282
|
for (const rel of this.#incoming.get(id)) {
|
|
@@ -291,7 +297,7 @@ export class LikeC4DeploymentModel<M extends AnyAux = AnyAux> {
|
|
|
291
297
|
*/
|
|
292
298
|
public *outgoing(
|
|
293
299
|
element: M['DeploymentOrFqn'],
|
|
294
|
-
filter: OutgoingFilter = 'all'
|
|
300
|
+
filter: OutgoingFilter = 'all',
|
|
295
301
|
): IteratorLike<DeploymentRelationModel<M>> {
|
|
296
302
|
const id = getId(element)
|
|
297
303
|
for (const rel of this.#outgoing.get(id)) {
|
|
@@ -311,8 +317,8 @@ export class LikeC4DeploymentModel<M extends AnyAux = AnyAux> {
|
|
|
311
317
|
throw new Error(`Element ${element.id} already exists`)
|
|
312
318
|
}
|
|
313
319
|
const el = DeploymentElement.isDeploymentNode(element)
|
|
314
|
-
? new DeploymentNodeModel(this, element)
|
|
315
|
-
: new DeployedInstanceModel(this, element, this.$model.element(element.element))
|
|
320
|
+
? new DeploymentNodeModel(this, Object.freeze(element))
|
|
321
|
+
: new DeployedInstanceModel(this, Object.freeze(element), this.$model.element(element.element))
|
|
316
322
|
this.#elements.set(el.id, el)
|
|
317
323
|
const parentId = parentFqn(el.id)
|
|
318
324
|
if (parentId) {
|
|
@@ -332,7 +338,7 @@ export class LikeC4DeploymentModel<M extends AnyAux = AnyAux> {
|
|
|
332
338
|
}
|
|
333
339
|
const rel = new DeploymentRelationModel(
|
|
334
340
|
this,
|
|
335
|
-
relation
|
|
341
|
+
Object.freeze(relation),
|
|
336
342
|
)
|
|
337
343
|
this.#relations.set(rel.id, rel)
|
|
338
344
|
this.#incoming.get(rel.target.id).add(rel)
|