@likec4/core 1.41.0 → 1.42.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/builder/package.json +4 -0
- package/compute-view/package.json +4 -0
- package/compute-view/relationships/package.json +4 -0
- package/dist/builder/index.d.mts +13 -11
- package/dist/builder/index.mjs +111 -91
- package/dist/compute-view/index.d.mts +8 -7
- package/dist/compute-view/index.mjs +14 -11
- package/dist/compute-view/relationships-view/index.d.mts +9 -8
- package/dist/compute-view/relationships-view/index.mjs +6 -6
- package/dist/index.d.mts +7 -7
- package/dist/index.mjs +11 -11
- package/dist/model/connection/deployment/index.d.mts +11 -10
- package/dist/model/connection/deployment/index.mjs +2 -2
- package/dist/model/connection/index.d.mts +12 -11
- package/dist/model/connection/index.mjs +3 -3
- package/dist/model/connection/model/index.d.mts +11 -10
- package/dist/model/connection/model/index.mjs +2 -2
- package/dist/model/index.d.mts +14 -14
- package/dist/model/index.mjs +4 -5
- package/dist/shared/{core.Ae86Y3tB.mjs → core.01VTr9qu.mjs} +8 -26
- package/dist/shared/core.1vX5a9AY.mjs +86 -0
- package/dist/shared/{core.BVNaR17u.mjs → core.B7KhhkRY.mjs} +1 -1
- package/dist/shared/core.B85MJLTf.mjs +5 -0
- package/dist/shared/{core.DA5vzwZ9.mjs → core.BIqHjQiH.mjs} +56 -42
- package/dist/shared/core.BKlholso.mjs +3 -0
- package/dist/shared/core.BR4zXDH-.mjs +13 -0
- package/dist/shared/{core.CXy1NLUG.mjs → core.BYNkXQ8A.mjs} +21 -12
- package/dist/shared/{core.BuoXfSMj.mjs → core.BbE4y-yl.mjs} +1 -1
- package/dist/shared/core.BoYfZOBm.mjs +3 -0
- package/dist/shared/core.BsSXS-_R.mjs +7 -0
- package/dist/shared/{core.DJp8fgok.mjs → core.BzTakU3I.mjs} +14 -10
- package/dist/shared/{core.4u1dVmfX.mjs → core.C2TiyjI6.mjs} +2 -2
- package/dist/shared/{core.DLpidoWc.mjs → core.C3JowhaZ.mjs} +3 -3
- package/dist/shared/{core.CNGyqkJh.mjs → core.C4x8aaWa.mjs} +3 -1
- package/dist/shared/{core.BB6zA-UU.mjs → core.C8YY6Uub.mjs} +38 -9
- package/dist/shared/{core.Asc11Mjy.mjs → core.C8sl5Y8Z.mjs} +122 -58
- package/dist/shared/{core.BvMRMo7Z.mjs → core.CNgZvKb8.mjs} +3 -5198
- package/dist/shared/{core.CUG6vpyL.d.mts → core.CQngdcuj.d.mts} +85 -4
- package/dist/shared/{core.Be1n9a0i.mjs → core.C_Ni6yHl.mjs} +5 -4
- package/dist/shared/core.CbT8JVYL.mjs +5 -0
- package/dist/shared/core.CqAJJpK_.mjs +3 -0
- package/dist/shared/{core.BXsxn-hf.d.mts → core.D0PjZzIS.d.mts} +27 -15
- package/dist/shared/{core.DgesAwC8.d.mts → core.D5fzJWbF.d.mts} +2 -2
- package/dist/shared/{core.hfOE3RfK.d.mts → core.DACpKp35.d.mts} +5 -5
- package/dist/shared/core.DFi2dOTl.mjs +39548 -0
- package/dist/shared/{core.xSQO0XYD.d.mts → core.DIol3syK.d.mts} +2 -2
- package/dist/shared/{core.DlG1xWt2.mjs → core.DMMOWQqc.mjs} +3 -2
- package/dist/shared/core.DNbUPnve.mjs +3990 -0
- package/dist/shared/{core.CCD1ID81.mjs → core.DRJma0Ol.mjs} +4 -3
- package/dist/shared/{core.DgttqsJc.mjs → core.DRhg-gVU.mjs} +9 -9
- package/dist/shared/core.DSO_rTC2.mjs +5322 -0
- package/dist/shared/{core.FUPplpae.d.mts → core.D_vkffV4.d.mts} +4 -2
- package/dist/shared/core.DdMJk7nx.d.mts +476 -0
- package/dist/shared/{core.BhpgpOep.d.mts → core.Dgs6-nuz.d.mts} +2 -2
- package/dist/shared/{core.Be4Jy9Qx.mjs → core.FZ305VYd.mjs} +2 -2
- package/dist/shared/core.OHD4KXm9.mjs +5 -0
- package/dist/shared/{core.GTgsmXS_.mjs → core.QJD_fcrc.mjs} +2 -2
- package/dist/shared/core.RfnaEmgA.mjs +7 -0
- package/dist/shared/core.fHR_8Tnq.d.mts +450 -0
- package/dist/shared/{core.D0EgVMQK.mjs → core.lRvxPoao.mjs} +14 -12
- package/dist/shared/{core.CaT0SUUK.mjs → core.rCeaAqgW.mjs} +1 -84
- package/dist/shared/{core.zxTBF_PD.d.mts → core.s9uwOt60.d.mts} +4 -4
- package/dist/shared/core.yna0OdV5.d.mts +98 -0
- package/dist/styles/index.d.mts +106 -0
- package/dist/styles/index.mjs +1 -0
- package/dist/types/_aux.d.mts +2 -2
- package/dist/types/expression-model.d.mts +3 -4
- package/dist/types/expression.d.mts +3 -4
- package/dist/types/fqnRef.d.mts +2 -2
- package/dist/types/fqnRef.mjs +3 -3
- package/dist/types/index.d.mts +8 -8
- package/dist/types/index.mjs +150 -5
- package/dist/types/scalar.mjs +3 -2
- package/dist/utils/graphology/index.d.mts +1864 -0
- package/dist/utils/graphology/index.mjs +1 -0
- package/dist/utils/index.d.mts +11 -6
- package/dist/utils/index.mjs +21 -37
- package/dist/utils/iterable/index.d.mts +1 -1
- package/dist/utils/iterable/index.mjs +45 -7
- package/model/package.json +4 -0
- package/package.json +42 -24
- package/styles/package.json +4 -0
- package/types/package.json +4 -0
- package/utils/graphology/package.json +4 -0
- package/utils/package.json +4 -0
- package/dist/shared/core.6_Vp2iiN.mjs +0 -172
- package/dist/shared/core.CUw_2J9j.mjs +0 -47
- package/dist/shared/core.CzdwsPmY.d.mts +0 -69
- package/dist/shared/core.D-ZGWDDt.d.mts +0 -831
- package/dist/shared/core.DoM6aM9N.mjs +0 -7
- package/dist/shared/core.ILwny7BV.mjs +0 -38
- package/dist/theme/index.d.mts +0 -11
- package/dist/theme/index.mjs +0 -232
- package/src/builder/Builder.deployment.ts +0 -224
- package/src/builder/Builder.deploymentModel.ts +0 -449
- package/src/builder/Builder.element.ts +0 -241
- package/src/builder/Builder.model.ts +0 -494
- package/src/builder/Builder.ts +0 -946
- package/src/builder/Builder.view-common.ts +0 -273
- package/src/builder/Builder.view-deployment.ts +0 -135
- package/src/builder/Builder.view-element.ts +0 -202
- package/src/builder/Builder.views.ts +0 -399
- package/src/builder/Builder.with.ts +0 -156
- package/src/builder/_types.ts +0 -324
- package/src/builder/index.ts +0 -11
- package/src/compute-view/compute-view.ts +0 -80
- package/src/compute-view/deployment-view/_types.ts +0 -38
- package/src/compute-view/deployment-view/clean-connections.ts +0 -236
- package/src/compute-view/deployment-view/compute.ts +0 -94
- package/src/compute-view/deployment-view/memory/index.ts +0 -9
- package/src/compute-view/deployment-view/memory/memory.ts +0 -96
- package/src/compute-view/deployment-view/predicates/deploymentRefs-where.ts +0 -18
- package/src/compute-view/deployment-view/predicates/deploymentRefs.ts +0 -154
- package/src/compute-view/deployment-view/predicates/index.ts +0 -8
- package/src/compute-view/deployment-view/predicates/relation-direct.ts +0 -243
- package/src/compute-view/deployment-view/predicates/relation-in-out.ts +0 -70
- package/src/compute-view/deployment-view/predicates/relation-incoming.ts +0 -101
- package/src/compute-view/deployment-view/predicates/relation-outgoing.ts +0 -95
- package/src/compute-view/deployment-view/predicates/relation-where.ts +0 -18
- package/src/compute-view/deployment-view/predicates/utils.ts +0 -282
- package/src/compute-view/deployment-view/predicates/wildcard.ts +0 -41
- package/src/compute-view/deployment-view/stages/stage-exclude.ts +0 -5
- package/src/compute-view/deployment-view/stages/stage-final.ts +0 -245
- package/src/compute-view/deployment-view/stages/stage-include.ts +0 -95
- package/src/compute-view/deployment-view/utils.ts +0 -297
- package/src/compute-view/dynamic-view/compute.ts +0 -312
- package/src/compute-view/element-view/_types.ts +0 -47
- package/src/compute-view/element-view/clean-connections.ts +0 -117
- package/src/compute-view/element-view/compute.ts +0 -324
- package/src/compute-view/element-view/memory/NodeGroup.ts +0 -31
- package/src/compute-view/element-view/memory/index.ts +0 -10
- package/src/compute-view/element-view/memory/memory.ts +0 -178
- package/src/compute-view/element-view/memory/stage-exclude.ts +0 -59
- package/src/compute-view/element-view/memory/stage-final.ts +0 -129
- package/src/compute-view/element-view/memory/stage-include.ts +0 -130
- package/src/compute-view/element-view/predicates/_utils.ts +0 -91
- package/src/compute-view/element-view/predicates/element-expand.ts +0 -29
- package/src/compute-view/element-view/predicates/element-kind-tag.ts +0 -27
- package/src/compute-view/element-view/predicates/element-ref.ts +0 -24
- package/src/compute-view/element-view/predicates/relation-direct.ts +0 -321
- package/src/compute-view/element-view/predicates/relation-in-out.ts +0 -64
- package/src/compute-view/element-view/predicates/relation-in.ts +0 -115
- package/src/compute-view/element-view/predicates/relation-out.ts +0 -119
- package/src/compute-view/element-view/predicates/wildcard.ts +0 -88
- package/src/compute-view/element-view/utils.ts +0 -65
- package/src/compute-view/index.ts +0 -4
- package/src/compute-view/memory/AbstractMemory.ts +0 -45
- package/src/compute-view/memory/AbstractStageExclude.ts +0 -215
- package/src/compute-view/memory/AbstractStageInclude.ts +0 -200
- package/src/compute-view/memory/_types.ts +0 -148
- package/src/compute-view/memory/index.ts +0 -5
- package/src/compute-view/memory/ops.ts +0 -43
- package/src/compute-view/relationships-view/_types.ts +0 -16
- package/src/compute-view/relationships-view/compute.ts +0 -159
- package/src/compute-view/relationships-view/index.ts +0 -3
- package/src/compute-view/relationships-view/layout.ts +0 -358
- package/src/compute-view/relationships-view/utils.ts +0 -73
- package/src/compute-view/utils/ancestorsOfNode.ts +0 -19
- package/src/compute-view/utils/applyCustomElementProperties.ts +0 -107
- package/src/compute-view/utils/applyCustomRelationProperties.ts +0 -58
- package/src/compute-view/utils/applyViewRuleStyles.ts +0 -73
- package/src/compute-view/utils/buildComputedNodes.ts +0 -166
- package/src/compute-view/utils/buildElementNotations.ts +0 -64
- package/src/compute-view/utils/elementExpressionToPredicate.ts +0 -50
- package/src/compute-view/utils/link-nodes-with-edges.ts +0 -56
- package/src/compute-view/utils/merge-props-from-relationships.ts +0 -161
- package/src/compute-view/utils/relationExpressionToPredicates.ts +0 -55
- package/src/compute-view/utils/resolve-extended-views.ts +0 -85
- package/src/compute-view/utils/resolve-global-rules.ts +0 -88
- package/src/compute-view/utils/topological-sort.ts +0 -256
- package/src/compute-view/utils/view-hash.ts +0 -45
- package/src/compute-view/utils/with-readable-edges.ts +0 -40
- package/src/index.ts +0 -32
- package/src/model/DeploymentElementModel.ts +0 -712
- package/src/model/DeploymentModel.ts +0 -393
- package/src/model/ElementModel.ts +0 -316
- package/src/model/LikeC4Model.ts +0 -882
- package/src/model/RelationModel.ts +0 -152
- package/src/model/connection/Connection.ts +0 -72
- package/src/model/connection/deployment/DeploymentConnectionModel.ts +0 -185
- package/src/model/connection/deployment/find.ts +0 -120
- package/src/model/connection/deployment/index.ts +0 -8
- package/src/model/connection/index.ts +0 -22
- package/src/model/connection/model/ConnectionModel.ts +0 -158
- package/src/model/connection/model/find.ts +0 -117
- package/src/model/connection/model/index.ts +0 -8
- package/src/model/connection/ops.ts +0 -276
- package/src/model/guards.ts +0 -77
- package/src/model/index.ts +0 -72
- package/src/model/types.ts +0 -67
- package/src/model/utils.ts +0 -66
- package/src/model/view/EdgeModel.ts +0 -121
- package/src/model/view/LikeC4ViewModel.ts +0 -361
- package/src/model/view/LikeC4ViewsFolder.ts +0 -151
- package/src/model/view/NodeModel.ts +0 -247
- package/src/theme/element.ts +0 -61
- package/src/theme/index.ts +0 -127
- package/src/theme/relationships.ts +0 -54
- package/src/types/RichText.ts +0 -205
- package/src/types/_aux.ts +0 -317
- package/src/types/_common.ts +0 -102
- package/src/types/const.ts +0 -34
- package/src/types/expression-model.ts +0 -294
- package/src/types/expression.ts +0 -313
- package/src/types/fqnRef.ts +0 -91
- package/src/types/geometry.ts +0 -159
- package/src/types/global.ts +0 -21
- package/src/types/index.ts +0 -44
- package/src/types/model-data.ts +0 -77
- package/src/types/model-deployment.ts +0 -78
- package/src/types/model-dump.ts +0 -79
- package/src/types/model-logical.ts +0 -126
- package/src/types/model-spec.ts +0 -88
- package/src/types/operators.ts +0 -156
- package/src/types/project.ts +0 -14
- package/src/types/scalar.ts +0 -162
- package/src/types/styles.ts +0 -122
- package/src/types/view-changes.ts +0 -32
- package/src/types/view-common.ts +0 -157
- package/src/types/view-computed.ts +0 -126
- package/src/types/view-layouted.ts +0 -94
- package/src/types/view-parsed.deployment.ts +0 -39
- package/src/types/view-parsed.dynamic.ts +0 -89
- package/src/types/view-parsed.element.ts +0 -65
- package/src/types/view.ts +0 -113
- package/src/utils/common-head.ts +0 -22
- package/src/utils/compare-natural.ts +0 -60
- package/src/utils/const.ts +0 -1
- package/src/utils/fqn.ts +0 -302
- package/src/utils/getOrCreate.ts +0 -8
- package/src/utils/guards.ts +0 -9
- package/src/utils/index.ts +0 -68
- package/src/utils/invariant.ts +0 -29
- package/src/utils/iterable/_types.ts +0 -5
- package/src/utils/iterable/filter.ts +0 -55
- package/src/utils/iterable/find.ts +0 -38
- package/src/utils/iterable/first.ts +0 -48
- package/src/utils/iterable/flat.ts +0 -17
- package/src/utils/iterable/head.ts +0 -22
- package/src/utils/iterable/index.ts +0 -15
- package/src/utils/iterable/map.ts +0 -40
- package/src/utils/iterable/reduce.ts +0 -24
- package/src/utils/iterable/some.ts +0 -36
- package/src/utils/iterable/to.ts +0 -19
- package/src/utils/iterable/unique.ts +0 -23
- package/src/utils/markdown/index.ts +0 -2
- package/src/utils/markdown/to-html.ts +0 -32
- package/src/utils/markdown/to-text.ts +0 -14
- package/src/utils/memoize-prop.ts +0 -30
- package/src/utils/mnemonist.ts +0 -9
- package/src/utils/object-hash.ts +0 -14
- package/src/utils/promises.ts +0 -24
- package/src/utils/relations.ts +0 -36
- package/src/utils/set.ts +0 -83
- package/src/utils/string-hash.ts +0 -16
|
@@ -1,393 +0,0 @@
|
|
|
1
|
-
import { values } from 'remeda'
|
|
2
|
-
import {
|
|
3
|
-
type Any,
|
|
4
|
-
type DeploymentElement,
|
|
5
|
-
type DeploymentRelationship,
|
|
6
|
-
type IteratorLike,
|
|
7
|
-
FqnRef,
|
|
8
|
-
isDeploymentNode,
|
|
9
|
-
} from '../types'
|
|
10
|
-
import * as aux from '../types/_aux'
|
|
11
|
-
import { invariant, nonNullable } from '../utils'
|
|
12
|
-
import { ancestorsFqn, parentFqn, sortParentsFirst } from '../utils/fqn'
|
|
13
|
-
import { getOrCreate } from '../utils/getOrCreate'
|
|
14
|
-
import { DefaultMap } from '../utils/mnemonist'
|
|
15
|
-
import {
|
|
16
|
-
type DeployedInstancesIterator,
|
|
17
|
-
type DeploymentElementModel,
|
|
18
|
-
type DeploymentElementsIterator,
|
|
19
|
-
type DeploymentNodesIterator,
|
|
20
|
-
DeployedInstanceModel,
|
|
21
|
-
DeploymentNodeModel,
|
|
22
|
-
DeploymentRelationModel,
|
|
23
|
-
NestedElementOfDeployedInstanceModel,
|
|
24
|
-
} from './DeploymentElementModel'
|
|
25
|
-
import type { LikeC4Model } from './LikeC4Model'
|
|
26
|
-
import {
|
|
27
|
-
type $ModelData,
|
|
28
|
-
type DeploymentOrFqn,
|
|
29
|
-
type ElementOrFqn,
|
|
30
|
-
type IncomingFilter,
|
|
31
|
-
type OutgoingFilter,
|
|
32
|
-
type RelationOrId,
|
|
33
|
-
} from './types'
|
|
34
|
-
import { getId } from './utils'
|
|
35
|
-
import type { LikeC4ViewModel } from './view/LikeC4ViewModel'
|
|
36
|
-
|
|
37
|
-
export class LikeC4DeploymentModel<A extends Any = Any> {
|
|
38
|
-
readonly #elements = new Map<aux.DeploymentFqn<A>, DeploymentElementModel<A>>()
|
|
39
|
-
// Parent element for given FQN
|
|
40
|
-
readonly #parents = new Map<aux.DeploymentFqn<A>, DeploymentNodeModel<A>>()
|
|
41
|
-
// Children elements for given FQN
|
|
42
|
-
readonly #children = new DefaultMap<aux.DeploymentFqn<A>, Set<DeploymentElementModel<A>>>(() => new Set())
|
|
43
|
-
|
|
44
|
-
// Keep track of instances of the logical element
|
|
45
|
-
readonly #instancesOf = new DefaultMap<aux.Fqn<A>, Set<DeployedInstanceModel<A>>>(() => new Set())
|
|
46
|
-
|
|
47
|
-
readonly #rootElements = new Set<DeploymentNodeModel<A>>()
|
|
48
|
-
|
|
49
|
-
readonly #relations = new Map<aux.RelationId, DeploymentRelationModel<A>>()
|
|
50
|
-
|
|
51
|
-
// Incoming to an element or its descendants
|
|
52
|
-
readonly #incoming = new DefaultMap<aux.DeploymentFqn<A>, Set<DeploymentRelationModel<A>>>(() => new Set())
|
|
53
|
-
|
|
54
|
-
// Outgoing from an element or its descendants
|
|
55
|
-
readonly #outgoing = new DefaultMap<aux.DeploymentFqn<A>, Set<DeploymentRelationModel<A>>>(() => new Set())
|
|
56
|
-
|
|
57
|
-
// Relationships inside the element, among descendants
|
|
58
|
-
readonly #internal = new DefaultMap<aux.DeploymentFqn<A>, Set<DeploymentRelationModel<A>>>(() => new Set())
|
|
59
|
-
|
|
60
|
-
// readonly #views = new Map<ViewID, LikeC4ViewModel<A>>()
|
|
61
|
-
|
|
62
|
-
readonly #allTags = new DefaultMap<aux.Tag<A>, Set<DeploymentElementModel<A> | DeploymentRelationModel<A>>>(
|
|
63
|
-
() => new Set(),
|
|
64
|
-
)
|
|
65
|
-
|
|
66
|
-
readonly #nestedElementsOfDeployment = new Map<
|
|
67
|
-
`${aux.DeploymentId<A>}@${aux.ElementId<A>}`,
|
|
68
|
-
NestedElementOfDeployedInstanceModel<A>
|
|
69
|
-
>()
|
|
70
|
-
|
|
71
|
-
public readonly $deployments: $ModelData<A>['deployments']
|
|
72
|
-
|
|
73
|
-
constructor(
|
|
74
|
-
public readonly $model: LikeC4Model<A>,
|
|
75
|
-
) {
|
|
76
|
-
const $deployments = this.$deployments = $model.$data.deployments
|
|
77
|
-
const elements = values($deployments.elements as Record<string, DeploymentElement<A>>)
|
|
78
|
-
for (const element of sortParentsFirst(elements)) {
|
|
79
|
-
const el = this.addElement(element)
|
|
80
|
-
for (const tag of el.tags) {
|
|
81
|
-
this.#allTags.get(tag).add(el)
|
|
82
|
-
}
|
|
83
|
-
if (el.isInstance()) {
|
|
84
|
-
this.#instancesOf.get(el.element.id).add(el)
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
for (const relation of values($deployments.relations)) {
|
|
88
|
-
const el = this.addRelation(relation)
|
|
89
|
-
for (const tag of el.tags) {
|
|
90
|
-
this.#allTags.get(tag).add(el)
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
public element(el: DeploymentOrFqn<A>): DeploymentElementModel<A> {
|
|
96
|
-
if (el instanceof DeploymentNodeModel || el instanceof DeployedInstanceModel) {
|
|
97
|
-
return el
|
|
98
|
-
}
|
|
99
|
-
const id = getId(el)
|
|
100
|
-
return nonNullable(this.#elements.get(id), `Element ${id} not found`)
|
|
101
|
-
}
|
|
102
|
-
public findElement(el: aux.LooseDeploymentId<A>): DeploymentElementModel<A> | null {
|
|
103
|
-
return this.#elements.get(el as aux.DeploymentFqn<A>) ?? null
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
public node(el: DeploymentOrFqn<A>): DeploymentNodeModel<A> {
|
|
107
|
-
const element = this.element(el)
|
|
108
|
-
invariant(element.isDeploymentNode(), `Element ${element.id} is not a deployment node`)
|
|
109
|
-
return element
|
|
110
|
-
}
|
|
111
|
-
public findNode(el: aux.LooseDeploymentId<A>): DeploymentNodeModel<A> | null {
|
|
112
|
-
const element = this.findElement(el)
|
|
113
|
-
if (!element) {
|
|
114
|
-
return null
|
|
115
|
-
}
|
|
116
|
-
invariant(element.isDeploymentNode(), `Element ${element?.id} is not a deployment node`)
|
|
117
|
-
return element
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
public instance(el: DeploymentOrFqn<A>): DeployedInstanceModel<A> {
|
|
121
|
-
const element = this.element(el)
|
|
122
|
-
invariant(element.isInstance(), `Element ${element.id} is not a deployed instance`)
|
|
123
|
-
return element
|
|
124
|
-
}
|
|
125
|
-
public findInstance(el: aux.LooseDeploymentId<A>): DeployedInstanceModel<A> | null {
|
|
126
|
-
const element = this.findElement(el)
|
|
127
|
-
if (!element) {
|
|
128
|
-
return null
|
|
129
|
-
}
|
|
130
|
-
invariant(element.isInstance(), `Element ${element?.id} is not a deployed instance`)
|
|
131
|
-
return element
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Returns the root elements of the model.
|
|
136
|
-
*/
|
|
137
|
-
public roots(): DeploymentNodesIterator<A> {
|
|
138
|
-
return this.#rootElements.values()
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Returns all elements in the model.
|
|
143
|
-
*/
|
|
144
|
-
public elements(): DeploymentElementsIterator<A> {
|
|
145
|
-
return this.#elements.values()
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Returns all elements in the model.
|
|
150
|
-
*/
|
|
151
|
-
public *nodes(): DeploymentNodesIterator<A> {
|
|
152
|
-
for (const element of this.#elements.values()) {
|
|
153
|
-
if (element.isDeploymentNode()) {
|
|
154
|
-
yield element
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
return
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
public *nodesOfKind(kind: aux.DeploymentKind<A>): DeploymentNodesIterator<A> {
|
|
161
|
-
for (const node of this.#elements.values()) {
|
|
162
|
-
if (node.isDeploymentNode() && node.kind === kind) {
|
|
163
|
-
yield node
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
return
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
public *instances(): DeployedInstancesIterator<A> {
|
|
170
|
-
for (const element of this.#elements.values()) {
|
|
171
|
-
if (element.isInstance()) {
|
|
172
|
-
yield element
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
return
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Iterate over all instances of the given logical element.
|
|
180
|
-
*/
|
|
181
|
-
public *instancesOf(element: ElementOrFqn<A>): DeployedInstancesIterator<A> {
|
|
182
|
-
const id = getId(element)
|
|
183
|
-
const instances = this.#instancesOf.get(id)
|
|
184
|
-
if (instances) {
|
|
185
|
-
yield* instances
|
|
186
|
-
}
|
|
187
|
-
return
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
public deploymentRef(
|
|
191
|
-
ref: FqnRef.DeploymentRef<A>,
|
|
192
|
-
): DeploymentElementModel<A> | NestedElementOfDeployedInstanceModel<A> {
|
|
193
|
-
if (FqnRef.isInsideInstanceRef(ref)) {
|
|
194
|
-
const { deployment, element } = ref
|
|
195
|
-
return getOrCreate(this.#nestedElementsOfDeployment, `${deployment}@${element}`, () => {
|
|
196
|
-
return new NestedElementOfDeployedInstanceModel(this.instance(deployment), this.$model.element(element))
|
|
197
|
-
})
|
|
198
|
-
}
|
|
199
|
-
return this.element(ref.deployment)
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Returns all relationships in the model.
|
|
204
|
-
*/
|
|
205
|
-
public relationships(): IteratorLike<DeploymentRelationModel<A>> {
|
|
206
|
-
return this.#relations.values()
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Returns a specific relationship by its ID.
|
|
211
|
-
*/
|
|
212
|
-
public relationship(id: RelationOrId): DeploymentRelationModel<A> {
|
|
213
|
-
return nonNullable(this.#relations.get(getId(id)), `DeploymentRelationModel ${id} not found`)
|
|
214
|
-
}
|
|
215
|
-
public findRelationship(id: string): DeploymentRelationModel<A> | null {
|
|
216
|
-
return this.#relations.get(id as aux.RelationId) ?? null
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Returns all deployment views in the model.
|
|
221
|
-
*/
|
|
222
|
-
public *views(): IteratorLike<LikeC4ViewModel.DeploymentView<A>> {
|
|
223
|
-
for (const view of this.$model.views()) {
|
|
224
|
-
if (view.isDeploymentView()) {
|
|
225
|
-
yield view
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
return
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Returns the parent element of given element.
|
|
233
|
-
* @see ancestors
|
|
234
|
-
*/
|
|
235
|
-
public parent(element: DeploymentOrFqn<A>): DeploymentNodeModel<A> | null {
|
|
236
|
-
const id = getId(element)
|
|
237
|
-
return this.#parents.get(id) || null
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Get all children of the element (only direct children),
|
|
242
|
-
* @see descendants
|
|
243
|
-
*/
|
|
244
|
-
public children(element: DeploymentOrFqn<A>): ReadonlySet<DeploymentElementModel<A>> {
|
|
245
|
-
const id = getId(element)
|
|
246
|
-
return this.#children.get(id)
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Get all sibling (i.e. same parent)
|
|
251
|
-
*/
|
|
252
|
-
public *siblings(element: DeploymentOrFqn<A>): DeploymentElementsIterator<A> {
|
|
253
|
-
const id = getId(element)
|
|
254
|
-
const siblings = this.parent(element)?.children() ?? this.roots()
|
|
255
|
-
for (const sibling of siblings) {
|
|
256
|
-
if (sibling.id !== id) {
|
|
257
|
-
yield sibling
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
return
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Get all ancestor elements (i.e. parent, parent’s parent, etc.)
|
|
265
|
-
* (from closest to root)
|
|
266
|
-
*/
|
|
267
|
-
public *ancestors(element: DeploymentOrFqn<A>): DeploymentNodesIterator<A> {
|
|
268
|
-
let id = getId(element)
|
|
269
|
-
let parent
|
|
270
|
-
while (parent = this.#parents.get(id)) {
|
|
271
|
-
yield parent
|
|
272
|
-
id = parent.id
|
|
273
|
-
}
|
|
274
|
-
return
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Get all descendant elements (i.e. children, children’s children, etc.)
|
|
279
|
-
*/
|
|
280
|
-
public *descendants(
|
|
281
|
-
element: DeploymentOrFqn<A>,
|
|
282
|
-
sort: 'asc' | 'desc' = 'desc',
|
|
283
|
-
): DeploymentElementsIterator<A> {
|
|
284
|
-
for (const child of this.children(element)) {
|
|
285
|
-
if (sort === 'asc') {
|
|
286
|
-
yield child
|
|
287
|
-
yield* this.descendants(child.id)
|
|
288
|
-
} else {
|
|
289
|
-
yield* this.descendants(child.id)
|
|
290
|
-
yield child
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
return
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
/**
|
|
297
|
-
* Incoming relationships to the element and its descendants
|
|
298
|
-
* @see incomers
|
|
299
|
-
*/
|
|
300
|
-
public *incoming(
|
|
301
|
-
element: DeploymentOrFqn<A>,
|
|
302
|
-
filter: IncomingFilter = 'all',
|
|
303
|
-
): IteratorLike<DeploymentRelationModel<A>> {
|
|
304
|
-
const id = getId(element)
|
|
305
|
-
for (const rel of this.#incoming.get(id)) {
|
|
306
|
-
switch (true) {
|
|
307
|
-
case filter === 'all':
|
|
308
|
-
case filter === 'direct' && rel.target.id === id:
|
|
309
|
-
case filter === 'to-descendants' && rel.target.id !== id:
|
|
310
|
-
yield rel
|
|
311
|
-
break
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
return
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
/**
|
|
318
|
-
* Outgoing relationships from the element and its descendants
|
|
319
|
-
* @see outgoers
|
|
320
|
-
*/
|
|
321
|
-
public *outgoing(
|
|
322
|
-
element: DeploymentOrFqn<A>,
|
|
323
|
-
filter: OutgoingFilter = 'all',
|
|
324
|
-
): IteratorLike<DeploymentRelationModel<A>> {
|
|
325
|
-
const id = getId(element)
|
|
326
|
-
for (const rel of this.#outgoing.get(id)) {
|
|
327
|
-
switch (true) {
|
|
328
|
-
case filter === 'all':
|
|
329
|
-
case filter === 'direct' && rel.source.id === id:
|
|
330
|
-
case filter === 'from-descendants' && rel.source.id !== id:
|
|
331
|
-
yield rel
|
|
332
|
-
break
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
return
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
private addElement(element: DeploymentElement<A>) {
|
|
339
|
-
if (this.#elements.has(element.id)) {
|
|
340
|
-
throw new Error(`Element ${element.id} already exists`)
|
|
341
|
-
}
|
|
342
|
-
const el = isDeploymentNode(element)
|
|
343
|
-
? new DeploymentNodeModel(this, Object.freeze(element))
|
|
344
|
-
: new DeployedInstanceModel(this, Object.freeze(element), this.$model.element(element.element))
|
|
345
|
-
this.#elements.set(el.id, el)
|
|
346
|
-
const parentId = parentFqn(el.id)
|
|
347
|
-
if (parentId) {
|
|
348
|
-
invariant(this.#elements.has(parentId), `Parent ${parentId} of ${el.id} not found`)
|
|
349
|
-
this.#parents.set(el.id, this.node(parentId))
|
|
350
|
-
this.#children.get(parentId).add(el)
|
|
351
|
-
} else {
|
|
352
|
-
invariant(el.isDeploymentNode(), `Root element ${el.id} is not a deployment node`)
|
|
353
|
-
this.#rootElements.add(el)
|
|
354
|
-
}
|
|
355
|
-
return el
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
private addRelation(relation: DeploymentRelationship<A>) {
|
|
359
|
-
if (this.#relations.has(relation.id)) {
|
|
360
|
-
throw new Error(`Relation ${relation.id} already exists`)
|
|
361
|
-
}
|
|
362
|
-
const rel = new DeploymentRelationModel(
|
|
363
|
-
this,
|
|
364
|
-
Object.freeze(relation),
|
|
365
|
-
)
|
|
366
|
-
this.#relations.set(rel.id, rel)
|
|
367
|
-
this.#incoming.get(rel.target.id).add(rel)
|
|
368
|
-
this.#outgoing.get(rel.source.id).add(rel)
|
|
369
|
-
|
|
370
|
-
const relParent = rel.boundary?.id ?? null
|
|
371
|
-
// Process internal relationships
|
|
372
|
-
if (relParent) {
|
|
373
|
-
for (const ancestor of [relParent, ...ancestorsFqn(relParent)]) {
|
|
374
|
-
this.#internal.get(ancestor).add(rel)
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
// Process source hierarchy
|
|
378
|
-
for (const sourceAncestor of ancestorsFqn(rel.source.id)) {
|
|
379
|
-
if (sourceAncestor === relParent) {
|
|
380
|
-
break
|
|
381
|
-
}
|
|
382
|
-
this.#outgoing.get(sourceAncestor).add(rel)
|
|
383
|
-
}
|
|
384
|
-
// Process target hierarchy
|
|
385
|
-
for (const targetAncestor of ancestorsFqn(rel.target.id)) {
|
|
386
|
-
if (targetAncestor === relParent) {
|
|
387
|
-
break
|
|
388
|
-
}
|
|
389
|
-
this.#incoming.get(targetAncestor).add(rel)
|
|
390
|
-
}
|
|
391
|
-
return rel
|
|
392
|
-
}
|
|
393
|
-
}
|
|
@@ -1,316 +0,0 @@
|
|
|
1
|
-
import { isEmpty, isShallowEqual, isTruthy, unique } from 'remeda'
|
|
2
|
-
import type { SetRequired } from 'type-fest'
|
|
3
|
-
import type { Any, AnyAux, Color, IteratorLike } from '../types'
|
|
4
|
-
import {
|
|
5
|
-
type Element as C4Element,
|
|
6
|
-
type ElementShape as C4ElementShape,
|
|
7
|
-
type ElementStyle,
|
|
8
|
-
type IconUrl,
|
|
9
|
-
type Link,
|
|
10
|
-
type ProjectId,
|
|
11
|
-
type RichTextOrEmpty,
|
|
12
|
-
DefaultElementShape,
|
|
13
|
-
DefaultShapeSize,
|
|
14
|
-
DefaultThemeColor,
|
|
15
|
-
preferDescription,
|
|
16
|
-
preferSummary,
|
|
17
|
-
RichText,
|
|
18
|
-
splitGlobalFqn,
|
|
19
|
-
} from '../types'
|
|
20
|
-
import * as aux from '../types/_aux'
|
|
21
|
-
import { commonAncestor, hierarchyLevel, ihead, isAncestor, memoizeProp, nameFromFqn, sortNaturalByFqn } from '../utils'
|
|
22
|
-
import { type DeployedInstancesIterator } from './DeploymentElementModel'
|
|
23
|
-
import type { LikeC4Model } from './LikeC4Model'
|
|
24
|
-
import type { RelationshipModel, RelationshipsIterator } from './RelationModel'
|
|
25
|
-
import type { IncomingFilter, OutgoingFilter, WithMetadata, WithTags } from './types'
|
|
26
|
-
import type { LikeC4ViewModel } from './view/LikeC4ViewModel'
|
|
27
|
-
|
|
28
|
-
export type ElementsIterator<M extends AnyAux> = IteratorLike<ElementModel<M>>
|
|
29
|
-
|
|
30
|
-
export class ElementModel<A extends AnyAux = Any> implements WithTags<A>, WithMetadata<A> {
|
|
31
|
-
readonly id: aux.Fqn<A>
|
|
32
|
-
readonly _literalId: aux.ElementId<A>
|
|
33
|
-
readonly hierarchyLevel: number
|
|
34
|
-
|
|
35
|
-
readonly imported: null | {
|
|
36
|
-
from: ProjectId
|
|
37
|
-
fqn: aux.Fqn<A>
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
constructor(
|
|
41
|
-
public readonly $model: LikeC4Model<A>,
|
|
42
|
-
public readonly $element: C4Element<A>,
|
|
43
|
-
) {
|
|
44
|
-
this.id = this.$element.id
|
|
45
|
-
this._literalId = this.$element.id
|
|
46
|
-
const [projectId, fqn] = splitGlobalFqn(this.id)
|
|
47
|
-
if (projectId) {
|
|
48
|
-
this.imported = {
|
|
49
|
-
from: projectId,
|
|
50
|
-
fqn,
|
|
51
|
-
}
|
|
52
|
-
this.hierarchyLevel = hierarchyLevel(fqn)
|
|
53
|
-
} else {
|
|
54
|
-
this.imported = null
|
|
55
|
-
this.hierarchyLevel = hierarchyLevel(this.id)
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
get name(): string {
|
|
60
|
-
return nameFromFqn(this.id)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
get parent(): ElementModel<A> | null {
|
|
64
|
-
return this.$model.parent(this)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
get kind(): aux.ElementKind<A> {
|
|
68
|
-
return this.$element.kind
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
get shape(): C4ElementShape {
|
|
72
|
-
return this.$element.shape ?? DefaultElementShape
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
get color(): Color {
|
|
76
|
-
return this.$element.color as Color ?? DefaultThemeColor
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
get icon(): IconUrl | null {
|
|
80
|
-
return this.$element.icon ?? null
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Returns all tags of the element.
|
|
85
|
-
* It includes tags from the element and its kind.
|
|
86
|
-
*/
|
|
87
|
-
get tags(): aux.Tags<A> {
|
|
88
|
-
return memoizeProp(this, Symbol.for('tags'), () => {
|
|
89
|
-
return unique([
|
|
90
|
-
...(this.$element.tags ?? []),
|
|
91
|
-
...(this.$model.specification.elements[this.$element.kind]?.tags ?? []),
|
|
92
|
-
] as aux.Tags<A>)
|
|
93
|
-
})
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
get title(): string {
|
|
97
|
-
return this.$element.title
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Returns true if the element has a summary and a description
|
|
102
|
-
* (if one is missing - it falls back to another)
|
|
103
|
-
*/
|
|
104
|
-
get hasSummary(): boolean {
|
|
105
|
-
return !!this.$element.summary && !!this.$element.description &&
|
|
106
|
-
!isShallowEqual(this.$element.summary, this.$element.description)
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Short description of the element.
|
|
111
|
-
* Falls back to description if summary is not provided.
|
|
112
|
-
*/
|
|
113
|
-
get summary(): RichTextOrEmpty {
|
|
114
|
-
return RichText.memoize(this, 'summary', preferSummary(this.$element))
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Long description of the element.
|
|
119
|
-
* Falls back to summary if description is not provided.
|
|
120
|
-
*/
|
|
121
|
-
get description(): RichTextOrEmpty {
|
|
122
|
-
return RichText.memoize(this, 'description', preferDescription(this.$element))
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
get technology(): string | null {
|
|
126
|
-
return this.$element.technology ?? null
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
get links(): ReadonlyArray<Link> {
|
|
130
|
-
return this.$element.links ?? []
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
get defaultView(): LikeC4ViewModel.ScopedElementView<A> | null {
|
|
134
|
-
return memoizeProp(this, Symbol.for('defaultView'), () => ihead(this.scopedViews()) ?? null)
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
get isRoot(): boolean {
|
|
138
|
-
return this.parent === null
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
get style(): SetRequired<ElementStyle, 'size'> {
|
|
142
|
-
return {
|
|
143
|
-
size: DefaultShapeSize,
|
|
144
|
-
...this.$element.style,
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
public isAncestorOf(another: ElementModel<A>): boolean {
|
|
149
|
-
return isAncestor(this, another)
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
public isDescendantOf(another: ElementModel<A>): boolean {
|
|
153
|
-
return isAncestor(another, this)
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Get all ancestor elements (i.e. parent, parent’s parent, etc.)
|
|
158
|
-
* (from closest to root)
|
|
159
|
-
*/
|
|
160
|
-
public ancestors(): ElementsIterator<A> {
|
|
161
|
-
return this.$model.ancestors(this)
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Returns the common ancestor of this element and another element.
|
|
166
|
-
*/
|
|
167
|
-
public commonAncestor(another: ElementModel<A>): ElementModel<A> | null {
|
|
168
|
-
const common = commonAncestor(this.id, another.id)
|
|
169
|
-
return common ? this.$model.element(common) : null
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
public children(): ReadonlySet<ElementModel<A>> {
|
|
173
|
-
return this.$model.children(this)
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Get all descendant elements (i.e. children, children’s children, etc.)
|
|
178
|
-
*/
|
|
179
|
-
public descendants(sort?: 'asc' | 'desc'): ElementsIterator<A> {
|
|
180
|
-
if (sort) {
|
|
181
|
-
const sorted = sortNaturalByFqn([...this.$model.descendants(this)], sort)
|
|
182
|
-
return sorted[Symbol.iterator]()
|
|
183
|
-
}
|
|
184
|
-
return this.$model.descendants(this)
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Get all sibling (i.e. same parent)
|
|
189
|
-
*/
|
|
190
|
-
public siblings(): ElementsIterator<A> {
|
|
191
|
-
return this.$model.siblings(this)
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Resolve siblings of the element and its ancestors
|
|
196
|
-
* (from closest parent to root)
|
|
197
|
-
*/
|
|
198
|
-
public *ascendingSiblings(): ElementsIterator<A> {
|
|
199
|
-
yield* this.siblings()
|
|
200
|
-
for (const ancestor of this.ancestors()) {
|
|
201
|
-
yield* ancestor.siblings()
|
|
202
|
-
}
|
|
203
|
-
return
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Resolve siblings of the element and its ancestors
|
|
208
|
-
* (from root to closest)
|
|
209
|
-
*/
|
|
210
|
-
public *descendingSiblings(): ElementsIterator<A> {
|
|
211
|
-
for (const ancestor of [...this.ancestors()].reverse()) {
|
|
212
|
-
yield* ancestor.siblings()
|
|
213
|
-
}
|
|
214
|
-
yield* this.siblings()
|
|
215
|
-
return
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
public incoming(filter: IncomingFilter = 'all'): RelationshipsIterator<A> {
|
|
219
|
-
return this.$model.incoming(this, filter)
|
|
220
|
-
}
|
|
221
|
-
public *incomers(filter: IncomingFilter = 'all'): ElementsIterator<A> {
|
|
222
|
-
const unique = new Set<aux.StrictFqn<A>>()
|
|
223
|
-
for (const r of this.incoming(filter)) {
|
|
224
|
-
if (unique.has(r.source.id)) {
|
|
225
|
-
continue
|
|
226
|
-
}
|
|
227
|
-
unique.add(r.source.id)
|
|
228
|
-
yield r.source
|
|
229
|
-
}
|
|
230
|
-
return
|
|
231
|
-
}
|
|
232
|
-
public outgoing(filter: OutgoingFilter = 'all'): RelationshipsIterator<A> {
|
|
233
|
-
return this.$model.outgoing(this, filter)
|
|
234
|
-
}
|
|
235
|
-
public *outgoers(filter: OutgoingFilter = 'all'): ElementsIterator<A> {
|
|
236
|
-
const unique = new Set<aux.StrictFqn<A>>()
|
|
237
|
-
for (const r of this.outgoing(filter)) {
|
|
238
|
-
if (unique.has(r.target.id)) {
|
|
239
|
-
continue
|
|
240
|
-
}
|
|
241
|
-
unique.add(r.target.id)
|
|
242
|
-
yield r.target
|
|
243
|
-
}
|
|
244
|
-
return
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
public get allOutgoing(): ReadonlySet<RelationshipModel<A>> {
|
|
248
|
-
return memoizeProp(this, Symbol.for('allOutgoing'), () => new Set(this.outgoing()))
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
public get allIncoming(): ReadonlySet<RelationshipModel<A>> {
|
|
252
|
-
return memoizeProp(this, Symbol.for('allIncoming'), () => new Set(this.incoming()))
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Iterate over all views that include this element.
|
|
257
|
-
*/
|
|
258
|
-
public views(): ReadonlySet<LikeC4ViewModel<A>> {
|
|
259
|
-
return memoizeProp(this, Symbol.for('views'), () => {
|
|
260
|
-
const views = new Set<LikeC4ViewModel<A>>()
|
|
261
|
-
for (const view of this.$model.views()) {
|
|
262
|
-
if (view.includesElement(this.id)) {
|
|
263
|
-
views.add(view)
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
return views
|
|
267
|
-
})
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* Iterate over all views that scope this element.
|
|
272
|
-
* It is possible that element is not included in the view.
|
|
273
|
-
*/
|
|
274
|
-
public scopedViews(): ReadonlySet<LikeC4ViewModel.ScopedElementView<A>> {
|
|
275
|
-
return memoizeProp(this, Symbol.for('scopedViews'), () => {
|
|
276
|
-
const views = new Set<LikeC4ViewModel.ScopedElementView<A>>()
|
|
277
|
-
for (const vm of this.$model.views()) {
|
|
278
|
-
if (vm.isScopedElementView() && vm.viewOf.id === this.id) {
|
|
279
|
-
views.add(vm)
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
return views
|
|
283
|
-
})
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* @returns true if the element is deployed
|
|
288
|
-
*/
|
|
289
|
-
public isDeployed(): boolean {
|
|
290
|
-
return isTruthy(ihead(this.deployments()))
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
public deployments(): DeployedInstancesIterator<A> {
|
|
294
|
-
return this.$model.deployment.instancesOf(this)
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
public hasMetadata(): boolean {
|
|
298
|
-
return !!this.$element.metadata && !isEmpty(this.$element.metadata)
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
public getMetadata(): aux.Metadata<A>
|
|
302
|
-
public getMetadata(field: aux.MetadataKey<A>): string | undefined
|
|
303
|
-
public getMetadata(field?: aux.MetadataKey<A>) {
|
|
304
|
-
if (field) {
|
|
305
|
-
return this.$element.metadata?.[field]
|
|
306
|
-
}
|
|
307
|
-
return this.$element.metadata ?? {}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* Checks if the element has the given tag.
|
|
312
|
-
*/
|
|
313
|
-
public isTagged(tag: aux.LooseTag<A>): boolean {
|
|
314
|
-
return this.tags.includes(tag as aux.Tag<A>)
|
|
315
|
-
}
|
|
316
|
-
}
|