@likec4/core 1.31.0 → 1.32.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.
Files changed (185) hide show
  1. package/README.md +407 -5
  2. package/dist/builder/index.d.mts +221 -42
  3. package/dist/builder/index.mjs +118 -65
  4. package/dist/compute-view/index.d.mts +23 -7
  5. package/dist/compute-view/index.mjs +11 -6
  6. package/dist/compute-view/relationships-view/index.d.mts +9 -7
  7. package/dist/compute-view/relationships-view/index.mjs +3 -2
  8. package/dist/index.d.mts +10 -14
  9. package/dist/index.mjs +9 -6
  10. package/dist/model/index.d.mts +173 -19
  11. package/dist/model/index.mjs +6 -1
  12. package/dist/shared/core.BaYE_r29.d.mts +258 -0
  13. package/dist/shared/core.Bk7wEZFG.mjs +276 -0
  14. package/dist/shared/core.BrCnZFTn.mjs +32 -0
  15. package/dist/shared/core.BuO4ncfY.d.mts +146 -0
  16. package/dist/shared/{core.Bq753SYD.mjs → core.CBpKAlhj.mjs} +2012 -4422
  17. package/dist/shared/core.CUYDgv2-.mjs +214 -0
  18. package/dist/shared/{core.Cu-UdkSl.mjs → core.CpXlRyE5.mjs} +7 -494
  19. package/dist/shared/{core.C-YXI-43.mjs → core.Cy9smucx.mjs} +3 -1
  20. package/dist/shared/core.CywrQs86.d.mts +31 -0
  21. package/dist/shared/core.DXzRBkuI.d.mts +1264 -0
  22. package/dist/shared/core.DoK86JEe.mjs +518 -0
  23. package/dist/shared/{core.D2830qgg.d.mts → core.Pf5I9o0e.d.mts} +1 -1
  24. package/dist/shared/core.cbA9VZ02.mjs +2681 -0
  25. package/dist/shared/{core.CQXU9DF7.mjs → core.rmvsy0n3.mjs} +23 -32
  26. package/dist/shared/core.znRaUX_A.d.mts +920 -0
  27. package/dist/types/aux.d.mts +3 -0
  28. package/dist/types/aux.mjs +1 -0
  29. package/dist/types/index.d.mts +7 -45
  30. package/dist/types/index.mjs +130 -3
  31. package/dist/utils/index.d.mts +221 -53
  32. package/dist/utils/index.mjs +14 -10
  33. package/package.json +16 -8
  34. package/src/builder/Builder.deploymentModel.ts +82 -18
  35. package/src/builder/Builder.element.ts +40 -20
  36. package/src/builder/Builder.model.ts +66 -17
  37. package/src/builder/Builder.ts +168 -76
  38. package/src/builder/Builder.view-common.ts +35 -17
  39. package/src/builder/Builder.view-deployment.ts +25 -25
  40. package/src/builder/Builder.view-element.ts +13 -12
  41. package/src/builder/Builder.views.ts +12 -7
  42. package/src/builder/__snapshots__/Builder-style1.spec.ts.snap +62 -34
  43. package/src/builder/__snapshots__/Builder-style2.compute-model.json5 +319 -0
  44. package/src/builder/__snapshots__/Builder-style2.spec.ts.snap +45 -24
  45. package/src/builder/_types.ts +34 -27
  46. package/src/compute-view/compute-view.ts +31 -34
  47. package/src/compute-view/deployment-view/__test__/TestHelper.ts +27 -14
  48. package/src/compute-view/deployment-view/__test__/fixture.ts +15 -13
  49. package/src/compute-view/deployment-view/_types.ts +10 -10
  50. package/src/compute-view/deployment-view/clean-connections.ts +5 -7
  51. package/src/compute-view/deployment-view/compute.ts +16 -13
  52. package/src/compute-view/deployment-view/memory/memory.ts +5 -6
  53. package/src/compute-view/deployment-view/predicates/deploymentRefs.ts +4 -5
  54. package/src/compute-view/deployment-view/predicates/relation-direct.ts +25 -50
  55. package/src/compute-view/deployment-view/predicates/relation-in-out.ts +5 -7
  56. package/src/compute-view/deployment-view/predicates/relation-incoming.ts +7 -11
  57. package/src/compute-view/deployment-view/predicates/relation-outgoing.ts +7 -10
  58. package/src/compute-view/deployment-view/predicates/utils.ts +37 -31
  59. package/src/compute-view/deployment-view/predicates/wildcard.ts +3 -2
  60. package/src/compute-view/deployment-view/stages/stage-final.ts +2 -2
  61. package/src/compute-view/deployment-view/stages/stage-include.ts +1 -1
  62. package/src/compute-view/deployment-view/utils.ts +79 -72
  63. package/src/compute-view/dynamic-view/__test__/fixture.ts +20 -11
  64. package/src/compute-view/dynamic-view/compute.ts +60 -53
  65. package/src/compute-view/element-view/__test__/TestHelper.ts +53 -29
  66. package/src/compute-view/element-view/__test__/__snapshots__/legacy.spec.ts.snap +26 -26
  67. package/src/compute-view/element-view/__test__/fixture.ts +134 -83
  68. package/src/compute-view/element-view/_types.ts +14 -19
  69. package/src/compute-view/element-view/clean-connections.ts +12 -8
  70. package/src/compute-view/element-view/compute.ts +61 -51
  71. package/src/compute-view/element-view/memory/NodeGroup.ts +8 -9
  72. package/src/compute-view/element-view/memory/memory.ts +22 -22
  73. package/src/compute-view/element-view/memory/stage-include.ts +5 -3
  74. package/src/compute-view/element-view/predicates/_utils.ts +18 -14
  75. package/src/compute-view/element-view/predicates/element-expand.ts +4 -5
  76. package/src/compute-view/element-view/predicates/element-kind-tag.ts +3 -4
  77. package/src/compute-view/element-view/predicates/element-ref.ts +3 -4
  78. package/src/compute-view/element-view/predicates/relation-direct.ts +16 -12
  79. package/src/compute-view/element-view/predicates/relation-in-out.ts +7 -8
  80. package/src/compute-view/element-view/predicates/relation-in.ts +19 -26
  81. package/src/compute-view/element-view/predicates/relation-out.ts +20 -21
  82. package/src/compute-view/element-view/predicates/wildcard.ts +3 -3
  83. package/src/compute-view/element-view/utils.ts +25 -23
  84. package/src/compute-view/index.ts +1 -1
  85. package/src/compute-view/memory/AbstractStageExclude.ts +3 -4
  86. package/src/compute-view/memory/AbstractStageInclude.ts +1 -1
  87. package/src/compute-view/memory/_types.ts +3 -2
  88. package/src/compute-view/relationships-view/_types.ts +3 -4
  89. package/src/compute-view/relationships-view/compute.ts +8 -11
  90. package/src/compute-view/relationships-view/layout.ts +6 -6
  91. package/src/compute-view/relationships-view/utils.ts +4 -4
  92. package/src/compute-view/utils/ancestorsOfNode.ts +7 -7
  93. package/src/compute-view/utils/applyCustomElementProperties.ts +16 -8
  94. package/src/compute-view/utils/applyCustomRelationProperties.ts +19 -9
  95. package/src/compute-view/utils/applyViewRuleStyles.ts +18 -10
  96. package/src/compute-view/utils/buildComputedNodes.ts +40 -40
  97. package/src/compute-view/utils/buildElementNotations.ts +14 -14
  98. package/src/compute-view/utils/elementExpressionToPredicate.ts +14 -15
  99. package/src/compute-view/utils/link-nodes-with-edges.ts +6 -4
  100. package/src/compute-view/utils/merge-props-from-relationships.ts +52 -20
  101. package/src/compute-view/utils/relationExpressionToPredicates.ts +19 -19
  102. package/src/compute-view/utils/resolve-extended-views.ts +8 -7
  103. package/src/compute-view/utils/resolve-global-rules.ts +31 -26
  104. package/src/compute-view/utils/topological-sort.ts +14 -14
  105. package/src/compute-view/utils/view-hash.ts +2 -2
  106. package/src/compute-view/utils/with-readable-edges.ts +9 -5
  107. package/src/index.ts +0 -32
  108. package/src/model/DeploymentElementModel.ts +171 -144
  109. package/src/model/DeploymentModel.ts +88 -65
  110. package/src/model/ElementModel.ts +85 -74
  111. package/src/model/LikeC4Model.ts +430 -241
  112. package/src/model/RelationModel.ts +63 -29
  113. package/src/model/__test__/fixture.ts +50 -36
  114. package/src/model/connection/Connection.ts +2 -2
  115. package/src/model/connection/deployment/DeploymentConnectionModel.ts +21 -24
  116. package/src/model/connection/deployment/find.ts +1 -1
  117. package/src/model/connection/model/ConnectionModel.ts +21 -20
  118. package/src/model/connection/model/find.ts +7 -7
  119. package/src/model/connection/ops.ts +6 -6
  120. package/src/model/guards.ts +66 -14
  121. package/src/model/index.ts +20 -7
  122. package/src/model/types.ts +41 -97
  123. package/src/model/view/EdgeModel.ts +47 -41
  124. package/src/model/view/LikeC4ViewModel.ts +130 -80
  125. package/src/model/view/NodeModel.ts +102 -96
  126. package/src/theme/element.ts +1 -1
  127. package/src/theme/index.ts +9 -9
  128. package/src/theme/relationships.ts +1 -1
  129. package/src/types/_common.ts +21 -15
  130. package/src/types/aux.ts +285 -0
  131. package/src/types/const.ts +34 -0
  132. package/src/types/expression-model.ts +292 -0
  133. package/src/types/expression.ts +311 -0
  134. package/src/types/fqnRef.ts +88 -0
  135. package/src/types/geometry.ts +131 -0
  136. package/src/types/global.ts +10 -8
  137. package/src/types/index.ts +39 -201
  138. package/src/types/model-data.ts +52 -84
  139. package/src/types/model-deployment.ts +87 -0
  140. package/src/types/model-dump.ts +72 -0
  141. package/src/types/model-logical.ts +111 -0
  142. package/src/types/model-spec.ts +81 -0
  143. package/src/types/operators.ts +51 -52
  144. package/src/types/scalar.ts +114 -0
  145. package/src/types/{theme.ts → styles.ts} +55 -15
  146. package/src/types/view-changes.ts +4 -5
  147. package/src/types/view-common.ts +157 -0
  148. package/src/types/view-computed.ts +113 -0
  149. package/src/types/view-layouted.ts +82 -0
  150. package/src/types/view-parsed.deployment.ts +40 -0
  151. package/src/types/view-parsed.dynamic.ts +78 -0
  152. package/src/types/view-parsed.element.ts +65 -0
  153. package/src/types/view.ts +122 -542
  154. package/src/utils/compare-natural.ts +43 -1
  155. package/src/utils/getOrCreate.ts +0 -34
  156. package/src/utils/index.ts +7 -12
  157. package/src/utils/iterable/filter.ts +1 -1
  158. package/src/utils/iterable/find.ts +3 -1
  159. package/src/utils/iterable/head.ts +22 -0
  160. package/src/utils/iterable/index.ts +1 -0
  161. package/src/utils/iterable/map.ts +1 -1
  162. package/src/utils/iterable/reduce.ts +1 -1
  163. package/src/utils/iterable/some.ts +1 -1
  164. package/src/utils/memoize-prop.ts +30 -0
  165. package/src/utils/object-hash.ts +1 -1
  166. package/src/utils/relations.ts +14 -11
  167. package/src/utils/string-hash.ts +1 -1
  168. package/dist/shared/core.CQDU11hR.d.mts +0 -753
  169. package/dist/shared/core.DJvmfnEi.d.mts +0 -1153
  170. package/dist/shared/core.DgfwjBtu.mjs +0 -495
  171. package/dist/shared/core.Dx7siloV.d.mts +0 -146
  172. package/dist/shared/core.SjLhMA7a.d.mts +0 -62
  173. package/src/builder/__snapshots__/Builder.spec.ts.snap +0 -374
  174. package/src/compute-view/element-view/predicates.ts +0 -520
  175. package/src/compute-view/utils/uniqueTags.ts +0 -21
  176. package/src/types/deployments.ts +0 -170
  177. package/src/types/element.ts +0 -109
  178. package/src/types/expression-v2-model.ts +0 -314
  179. package/src/types/expression-v2.ts +0 -392
  180. package/src/types/overview-graph.ts +0 -43
  181. package/src/types/relation.ts +0 -61
  182. package/src/types/scalars.ts +0 -39
  183. package/src/types/view-notation.ts +0 -9
  184. package/src/utils/graphlib.ts +0 -10
  185. /package/src/{errors/index.ts → utils/invariant.ts} +0 -0
@@ -1,190 +1,289 @@
1
- import { entries, mapValues, pipe, sort, values } from 'remeda'
2
- import type { LiteralUnion } from 'type-fest'
3
- import { computeView, unsafeComputeView } from '../compute-view'
4
- import type { ComputeViewResult } from '../compute-view/compute-view'
5
- import { invariant, nonNullable } from '../errors'
6
- import type { IteratorLike } from '../types/_common'
7
- import type { Element } from '../types/element'
8
- import type { ModelGlobals } from '../types/global'
9
- import type { AnyParsedLikeC4ModelData, GenericLikeC4ModelData, LikeC4ModelDump } from '../types/model-data'
10
- import type { ModelRelation } from '../types/relation'
11
- import { type ProjectId, type Tag as C4Tag, GlobalFqn, isGlobalFqn } from '../types/scalars'
12
- import type { ComputedView, DiagramView, LikeC4View } from '../types/view'
13
- import { compareNatural } from '../utils'
1
+ import { entries, map, pipe, prop, sort, sortBy, values } from 'remeda'
2
+ import type {
3
+ Any,
4
+ Aux,
5
+ AuxFromDump,
6
+ ComputedLikeC4ModelData,
7
+ Element,
8
+ IteratorLike,
9
+ LayoutedLikeC4ModelData,
10
+ LikeC4ModelDump,
11
+ ModelGlobals,
12
+ ParsedLikeC4ModelData,
13
+ Relationship,
14
+ scalar,
15
+ Specification,
16
+ WhereOperator,
17
+ } from '../types'
18
+ import { type ProjectId, _stage, GlobalFqn, isGlobalFqn, isOnStage, whereOperatorAsPredicate } from '../types'
19
+ import type * as aux from '../types/aux'
20
+ import { compareNatural, ifilter, invariant, memoizeProp, nonNullable } from '../utils'
14
21
  import { ancestorsFqn, commonAncestor, parentFqn, sortParentsFirst } from '../utils/fqn'
15
22
  import { DefaultMap } from '../utils/mnemonist'
16
23
  import type {
17
24
  DeployedInstanceModel,
18
- DeploymentElementModel,
19
25
  DeploymentNodeModel,
20
26
  DeploymentRelationModel,
21
27
  } from './DeploymentElementModel'
22
28
  import { LikeC4DeploymentModel } from './DeploymentModel'
23
29
  import { type ElementsIterator, ElementModel } from './ElementModel'
24
30
  import { type RelationshipsIterator, RelationshipModel } from './RelationModel'
25
- import { type AnyAux, type Aux, type IncomingFilter, type OutgoingFilter, getId } from './types'
26
- import { EdgeModel } from './view/EdgeModel'
31
+ import {
32
+ type $ModelData,
33
+ type $View,
34
+ type $ViewModel,
35
+ type ElementOrFqn,
36
+ type IncomingFilter,
37
+ type OutgoingFilter,
38
+ type RelationOrId,
39
+ getId,
40
+ } from './types'
27
41
  import { LikeC4ViewModel } from './view/LikeC4ViewModel'
28
- import { NodeModel } from './view/NodeModel'
42
+ import type { NodeModel } from './view/NodeModel'
29
43
 
30
- export class LikeC4Model<M extends AnyAux = LikeC4Model.Any> {
44
+ export class LikeC4Model<A extends Any = aux.Unknown> {
31
45
  /**
32
46
  * Don't use in runtime, only for type inference
33
47
  */
34
- readonly Aux: M = {} as M
48
+ readonly Aux!: A
35
49
 
36
- readonly #elements = new Map<M['Element'], ElementModel<M>>()
50
+ protected readonly _elements = new Map<aux.Fqn<A>, ElementModel<A>>()
37
51
  // Parent element for given FQN
38
- readonly #parents = new Map<M['Element'], ElementModel<M>>()
52
+ protected readonly _parents = new Map<aux.Fqn<A>, ElementModel<A>>()
39
53
  // Children elements for given FQN
40
- readonly #children = new DefaultMap<M['Element'], Set<ElementModel<M>>>(() => new Set())
54
+ protected readonly _children = new DefaultMap<aux.Fqn<A>, Set<ElementModel<A>>>(() => new Set())
41
55
 
42
- readonly #rootElements = new Set<ElementModel<M>>()
56
+ protected readonly _rootElements = new Set<ElementModel<A>>()
43
57
 
44
- readonly #relations = new Map<M['RelationId'], RelationshipModel<M>>()
58
+ protected readonly _relations = new Map<scalar.RelationId, RelationshipModel<A>>()
45
59
 
46
60
  // Incoming to an element or its descendants
47
- readonly #incoming = new DefaultMap<M['Element'], Set<RelationshipModel<M>>>(() => new Set())
61
+ protected readonly _incoming = new DefaultMap<aux.Fqn<A>, Set<RelationshipModel<A>>>(() => new Set())
48
62
 
49
63
  // Outgoing from an element or its descendants
50
- readonly #outgoing = new DefaultMap<M['Element'], Set<RelationshipModel<M>>>(() => new Set())
64
+ protected readonly _outgoing = new DefaultMap<aux.Fqn<A>, Set<RelationshipModel<A>>>(() => new Set())
51
65
 
52
66
  // Relationships inside the element, among descendants
53
- readonly #internal = new DefaultMap<M['Element'], Set<RelationshipModel<M>>>(() => new Set())
67
+ protected readonly _internal = new DefaultMap<aux.Fqn<A>, Set<RelationshipModel<A>>>(() => new Set())
54
68
 
55
- readonly #views = new Map<M['ViewId'], LikeC4ViewModel<M>>()
69
+ protected readonly _views = new Map<aux.ViewId<A>, LikeC4ViewModel<A>>()
56
70
 
57
- readonly #allTags = new DefaultMap<C4Tag, Set<ElementModel<M> | RelationshipModel<M> | LikeC4ViewModel<M>>>(() =>
58
- new Set()
71
+ protected readonly _allTags = new DefaultMap<
72
+ aux.Tag<A>,
73
+ Set<ElementModel<A> | RelationshipModel<A> | LikeC4ViewModel<A>>
74
+ >(
75
+ () => new Set(),
59
76
  )
60
77
 
61
- public readonly deployment: LikeC4DeploymentModel<M>
62
-
63
- /**
64
- * Computes views from the parsed model
65
- * Creates a new LikeC4Model instance from a parsed model.
66
- *
67
- * May throw an error if the model is invalid.
68
- *
69
- * @typeParam M - The type of the parsed LikeC4 model, must extend ParsedLikeC4Model
70
- * @param parsed - The parsed LikeC4 model to compute from
71
- * @returns A new LikeC4Model instance with computed relationships and structure
72
- */
73
- static compute<const M extends AnyParsedLikeC4ModelData>(parsed: M): LikeC4Model<Aux.FromParsed<M>> {
74
- let { views, ...rest } = parsed as Omit<M, '__'>
75
- const model = new LikeC4Model({ ...rest, views: {} })
76
- return new LikeC4Model({
77
- ...rest,
78
- views: mapValues(views, view => unsafeComputeView(view as LikeC4View, model)),
79
- } as any)
80
- }
81
-
82
- /**
83
- * Creates a function that computes a view using the data from the model.
84
- *
85
- * @example
86
- * const compute = LikeC4Model.makeCompute(parsedModel);
87
- * const result = compute(viewSource);
88
- */
89
- static makeCompute<M extends AnyParsedLikeC4ModelData>(parsed: M): (viewsource: LikeC4View) => ComputeViewResult {
90
- let { views, ...rest } = parsed as Omit<M, '__'>
91
- const model = new LikeC4Model({ ...rest, views: {} })
92
- return (viewsource) => computeView(viewsource, model)
78
+ static fromParsed<T extends Any>(model: ParsedLikeC4ModelData<T>): LikeC4Model.Parsed<T> {
79
+ return new LikeC4Model<T>(model as any).asParsed
93
80
  }
94
81
 
95
82
  /**
96
83
  * Creates a new LikeC4Model instance from the provided model data.
84
+ * Model with parsed data will not have views, as they must be computed
85
+ * (this model is used for computing views)
97
86
  *
98
87
  * @typeParam M - Type parameter constrained to AnyLikeC4Model
99
88
  * @param model - The model data to create a LikeC4Model from
100
89
  * @returns A new LikeC4Model instance with the type derived from the input model
101
90
  */
102
- static create<const M extends GenericLikeC4ModelData>(model: M): LikeC4Model<Aux.FromModel<M>> {
103
- return new LikeC4Model(model as any)
91
+
92
+ static create<T extends Any>(model: ParsedLikeC4ModelData<T>): LikeC4Model.Parsed<T>
93
+ static create<T extends Any>(model: LayoutedLikeC4ModelData<T>): LikeC4Model.Layouted<T>
94
+ static create<T extends Any>(model: ComputedLikeC4ModelData<T>): LikeC4Model.Computed<T>
95
+ static create<T extends Any>(model: $ModelData<T>): LikeC4Model<T> {
96
+ return new LikeC4Model(model)
104
97
  }
105
98
 
106
99
  /**
107
- * Creates a new LikeC4Model instance from a model dump.
100
+ * Creates a new LikeC4Model instance and infers types from a model dump.\
101
+ * Model dump expected to be computed or layouted.
108
102
  *
109
- * @typeParam M - A constant type parameter extending LikeC4ModelDump
103
+ * @typeParam D - A constant type parameter extending LikeC4ModelDump
110
104
  * @param dump - The model dump to create the instance from
111
- * @returns A new LikeC4Model instance with types inferred from the dump
105
+ * @returns A new LikeC4Model instance with types inferred from the dump
112
106
  */
113
- static fromDump<const M extends LikeC4ModelDump>(dump: M): LikeC4Model<Aux.FromDump<M>> {
114
- return new LikeC4Model(dump as any)
107
+ static fromDump<const D extends LikeC4ModelDump>(dump: D): LikeC4Model<AuxFromDump<D>> {
108
+ const {
109
+ _stage: stage = 'layouted',
110
+ projectId = 'unknown',
111
+ globals,
112
+ imports,
113
+ deployments,
114
+ views,
115
+ relations,
116
+ elements,
117
+ specification,
118
+ } = dump
119
+ return new LikeC4Model({
120
+ [_stage]: stage as 'layouted',
121
+ projectId,
122
+ globals: {
123
+ predicates: globals?.predicates ?? {},
124
+ dynamicPredicates: globals?.dynamicPredicates ?? {},
125
+ styles: globals?.styles ?? {},
126
+ },
127
+ imports: imports ?? {},
128
+ deployments: {
129
+ elements: deployments?.elements ?? {},
130
+ relations: deployments?.relations ?? {},
131
+ },
132
+ views: views ?? {},
133
+ relations: relations ?? {},
134
+ elements: elements ?? {},
135
+ specification,
136
+ } as any)
115
137
  }
116
138
 
117
- private constructor(
118
- public readonly $model: M['Model'],
119
- ) {
120
- for (const element of values($model.elements)) {
139
+ public readonly deployment: LikeC4DeploymentModel<A>
140
+ public readonly $data: $ModelData<A>
141
+
142
+ constructor($data: $ModelData<A>) {
143
+ this.$data = $data
144
+ for (const [, element] of entries($data.elements)) {
121
145
  const el = this.addElement(element)
122
146
  for (const tag of el.tags) {
123
- this.#allTags.get(tag).add(el)
147
+ this._allTags.get(tag).add(el)
124
148
  }
125
149
  }
126
- for (const [projectId, elements] of entries($model.imports ?? {})) {
150
+ for (const [projectId, elements] of entries($data.imports ?? {})) {
127
151
  for (const element of sortParentsFirst(elements)) {
128
- const el = this.addImportedElement(projectId as ProjectId, element)
152
+ const el = this.addImportedElement(projectId as unknown as ProjectId<A>, element)
129
153
  for (const tag of el.tags) {
130
- this.#allTags.get(tag).add(el)
154
+ this._allTags.get(tag).add(el)
131
155
  }
132
156
  }
133
157
  }
134
- for (const relation of values($model.relations)) {
158
+ for (const relation of values($data.relations)) {
135
159
  const el = this.addRelation(relation)
136
160
  for (const tag of el.tags) {
137
- this.#allTags.get(tag).add(el)
161
+ this._allTags.get(tag).add(el)
138
162
  }
139
163
  }
140
- this.deployment = new LikeC4DeploymentModel(this, $model.deployments)
141
- const views = pipe(
142
- values($model.views),
143
- sort((a, b) => compareNatural(a.title ?? 'untitled', b.title ?? 'untitled')),
144
- )
145
- for (const view of views) {
146
- const vm = new LikeC4ViewModel(this, Object.freeze(view as M['ViewType']))
147
- this.#views.set(view.id, vm)
148
- for (const tag of vm.tags) {
149
- this.#allTags.get(tag).add(vm)
164
+
165
+ this.deployment = new LikeC4DeploymentModel(this)
166
+
167
+ if (isOnStage($data, 'computed') || isOnStage($data, 'layouted')) {
168
+ const views = pipe(
169
+ values($data.views as Record<string, $View<A>>),
170
+ sort((a, b) => compareNatural(a.title ?? 'untitled', b.title ?? 'untitled')),
171
+ )
172
+ for (const view of views) {
173
+ const vm = new LikeC4ViewModel(this, view)
174
+ this._views.set(view.id, vm)
175
+ for (const tag of vm.tags) {
176
+ this._allTags.get(tag).add(vm)
177
+ }
150
178
  }
151
179
  }
152
180
  }
153
181
 
154
- get type(): 'computed' | 'layouted' {
155
- return this.$model.__ ?? 'computed'
182
+ /**
183
+ * Type narrows the model to the parsed stage.
184
+ * This is useful for tests
185
+ */
186
+ get asParsed(): LikeC4Model.Parsed<A> {
187
+ return this as any
188
+ }
189
+ /**
190
+ * Type narrows the model to the layouted stage.
191
+ * This is useful for tests
192
+ */
193
+ get asComputed(): LikeC4Model.Computed<A> {
194
+ return this as any
195
+ }
196
+ /**
197
+ * Type narrows the model to the layouted stage.
198
+ * This is useful for tests
199
+ */
200
+ get asLayouted(): LikeC4Model.Layouted<A> {
201
+ return this as any
202
+ }
203
+
204
+ /**
205
+ * Type guard the model to the parsed stage.
206
+ */
207
+ public isParsed(this: LikeC4Model<any>): this is LikeC4Model<aux.toParsed<A>> {
208
+ return this.stage === 'parsed'
209
+ }
210
+ /**
211
+ * Type guard the model to the layouted stage.
212
+ */
213
+ public isLayouted(this: LikeC4Model<any>): this is LikeC4Model<aux.toLayouted<A>> {
214
+ return this.stage === 'layouted'
215
+ }
216
+ /**
217
+ * Type guard the model to the computed stage.
218
+ */
219
+ public isComputed(this: LikeC4Model<any>): this is LikeC4Model<aux.toComputed<A>> {
220
+ return this.stage === 'computed'
221
+ }
222
+
223
+ /**
224
+ * Keeping here for backward compatibility
225
+ * @deprecated use {@link $data}
226
+ */
227
+ get $model(): $ModelData<A> {
228
+ return this.$data
229
+ }
230
+
231
+ get stage(): aux.Stage<A> {
232
+ return this.$data[_stage] as aux.Stage<A>
233
+ }
234
+
235
+ get projectId(): aux.ProjectId<A> {
236
+ return this.$data.projectId ?? 'unknown' as any
237
+ }
238
+
239
+ get specification(): Specification<A> {
240
+ return this.$data.specification
241
+ }
242
+
243
+ get globals(): ModelGlobals {
244
+ return memoizeProp(this, Symbol.for('globals'), (): ModelGlobals => ({
245
+ predicates: {
246
+ ...this.$data.globals?.predicates,
247
+ },
248
+ dynamicPredicates: {
249
+ ...this.$data.globals?.dynamicPredicates,
250
+ },
251
+ styles: {
252
+ ...this.$data.globals?.styles,
253
+ },
254
+ }))
156
255
  }
157
256
 
158
- public element(el: M['ElementOrFqn']): ElementModel<M> {
257
+ public element(el: ElementOrFqn<A>): ElementModel<A> {
159
258
  if (el instanceof ElementModel) {
160
259
  return el
161
260
  }
162
261
  const id = getId(el)
163
- return nonNullable(this.findElement(id), `Element ${getId(el)} not found`)
262
+ return nonNullable(this._elements.get(id), `Element ${id} not found`)
164
263
  }
165
- public findElement(el: LiteralUnion<M['Element'], string>): ElementModel<M> | null {
166
- return this.#elements.get(el) ?? null
264
+ public findElement(el: aux.LooseElementId<A>): ElementModel<A> | null {
265
+ return this._elements.get(getId(el)) ?? null
167
266
  }
168
267
 
169
268
  /**
170
269
  * Returns the root elements of the model.
171
270
  */
172
- public roots(): ElementsIterator<M> {
173
- return this.#rootElements.values()
271
+ public roots(): ElementsIterator<A> {
272
+ return this._rootElements.values()
174
273
  }
175
274
 
176
275
  /**
177
276
  * Returns all elements in the model.
178
277
  */
179
- public elements(): ElementsIterator<M> {
180
- return this.#elements.values()
278
+ public elements(): ElementsIterator<A> {
279
+ return this._elements.values()
181
280
  }
182
281
 
183
282
  /**
184
283
  * Returns all relationships in the model.
185
284
  */
186
- public relationships(): RelationshipsIterator<M> {
187
- return this.#relations.values()
285
+ public relationships(): RelationshipsIterator<A> {
286
+ return this._relations.values()
188
287
  }
189
288
 
190
289
  /**
@@ -192,20 +291,21 @@ export class LikeC4Model<M extends AnyAux = LikeC4Model.Any> {
192
291
  * If the relationship is not found in the model, it will be searched in the deployment model.
193
292
  * Search can be limited to the model or deployment model only.
194
293
  */
195
- public relationship(id: M['RelationId'], type: 'model'): RelationshipModel<M>
196
- public relationship(id: M['RelationId'], type: 'deployment'): DeploymentRelationModel<M>
294
+ public relationship(rel: RelationOrId, type: 'model'): RelationshipModel<A>
295
+ public relationship(rel: RelationOrId, type: 'deployment'): DeploymentRelationModel<A>
197
296
  public relationship(
198
- id: M['RelationId'],
297
+ rel: scalar.RelationId,
199
298
  type?: 'model' | 'deployment',
200
- ): RelationshipModel<M> | DeploymentRelationModel<M>
299
+ ): RelationshipModel<A> | DeploymentRelationModel<A>
201
300
  public relationship(
202
- id: M['RelationId'],
301
+ rel: scalar.RelationId,
203
302
  type: 'model' | 'deployment' | undefined,
204
- ): RelationshipModel<M> | DeploymentRelationModel<M> {
303
+ ): RelationshipModel<A> | DeploymentRelationModel<A> {
205
304
  if (type === 'deployment') {
206
- return this.deployment.relationship(id)
305
+ return this.deployment.relationship(rel)
207
306
  }
208
- let model = this.#relations.get(id) ?? null
307
+ const id = getId(rel)
308
+ let model = this._relations.get(id) ?? null
209
309
  if (model || type === 'model') {
210
310
  return nonNullable(model, `Model relation ${id} not found`)
211
311
  }
@@ -213,23 +313,20 @@ export class LikeC4Model<M extends AnyAux = LikeC4Model.Any> {
213
313
  return nonNullable(this.deployment.findRelationship(id), `No model/deployment relation ${id} not found`)
214
314
  }
215
315
 
216
- public findRelationship(id: LiteralUnion<M['RelationId'], string>, type: 'model'): RelationshipModel<M> | null
316
+ public findRelationship(id: string, type: 'model'): RelationshipModel<A> | null
317
+ public findRelationship(id: string, type: 'deployment'): DeploymentRelationModel<A> | null
217
318
  public findRelationship(
218
- id: LiteralUnion<M['RelationId'], string>,
219
- type: 'deployment',
220
- ): DeploymentRelationModel<M> | null
221
- public findRelationship(
222
- id: LiteralUnion<M['RelationId'], string>,
319
+ id: string,
223
320
  type?: 'model' | 'deployment',
224
- ): RelationshipModel<M> | DeploymentRelationModel<M> | null
321
+ ): RelationshipModel<A> | DeploymentRelationModel<A> | null
225
322
  public findRelationship(
226
- id: LiteralUnion<M['RelationId'], string>,
323
+ id: string,
227
324
  type: 'model' | 'deployment' | undefined,
228
- ): RelationshipModel<M> | DeploymentRelationModel<M> | null {
325
+ ): RelationshipModel<A> | DeploymentRelationModel<A> | null {
229
326
  if (type === 'deployment') {
230
327
  return this.deployment.findRelationship(id)
231
328
  }
232
- let model = this.#relations.get(id as M['RelationId']) ?? null
329
+ let model = this._relations.get(getId(id)) ?? null
233
330
  if (model || type === 'model') {
234
331
  return model
235
332
  }
@@ -239,45 +336,46 @@ export class LikeC4Model<M extends AnyAux = LikeC4Model.Any> {
239
336
  /**
240
337
  * Returns all views in the model.
241
338
  */
242
- public views(): IteratorLike<LikeC4ViewModel<M>> {
243
- return this.#views.values()
339
+ public views(): IteratorLike<LikeC4ViewModel<A, $View<A>>> {
340
+ return this._views.values()
244
341
  }
245
342
 
246
343
  /**
247
344
  * Returns a specific view by its ID.
248
345
  */
249
- public view(viewId: M['View']): LikeC4ViewModel<M> {
250
- return nonNullable(this.#views.get(viewId as any), `View ${viewId} not found`)
346
+ public view(viewId: aux.ViewId<A> | { id: scalar.ViewId<aux.ViewId<A>> }): LikeC4ViewModel<A, $View<A>> {
347
+ const id = getId(viewId)
348
+ return nonNullable(this._views.get(id), `View ${id} not found`)
251
349
  }
252
- public findView(viewId: M['View']): LikeC4ViewModel<M> | null {
253
- return this.#views.get(viewId as M['ViewId']) ?? null
350
+ public findView(viewId: aux.LooseViewId<A>): LikeC4ViewModel<A, $View<A>> | null {
351
+ return this._views.get(viewId as aux.ViewId<A>) ?? null
254
352
  }
255
353
 
256
354
  /**
257
355
  * Returns the parent element of given element.
258
356
  * @see ancestors
259
357
  */
260
- public parent(element: M['ElementOrFqn']): ElementModel<M> | null {
358
+ public parent(element: ElementOrFqn<A>): ElementModel<A> | null {
261
359
  const id = getId(element)
262
- return this.#parents.get(id) || null
360
+ return this._parents.get(id) || null
263
361
  }
264
362
 
265
363
  /**
266
364
  * Get all children of the element (only direct children),
267
365
  * @see descendants
268
366
  */
269
- public children(element: M['ElementOrFqn']): ReadonlySet<ElementModel<M>> {
270
- const id = getId(element) as M['Fqn']
271
- return this.#children.get(id)
367
+ public children(element: ElementOrFqn<A>): ReadonlySet<ElementModel<A>> {
368
+ const id = getId(element)
369
+ return this._children.get(id)
272
370
  }
273
371
 
274
372
  /**
275
373
  * Get all sibling (i.e. same parent)
276
374
  */
277
- public *siblings(element: M['ElementOrFqn']): ElementsIterator<M> {
278
- const id = getId(element) as M['Fqn']
279
- const parent = this.#parents.get(id)
280
- const siblings = parent ? this.#children.get(parent.id).values() : this.roots()
375
+ public *siblings(element: ElementOrFqn<A>): ElementsIterator<A> {
376
+ const id = getId(element)
377
+ const parent = this._parents.get(id)
378
+ const siblings = parent ? this._children.get(parent.id).values() : this.roots()
281
379
  for (const sibling of siblings) {
282
380
  if (sibling.id !== id) {
283
381
  yield sibling
@@ -290,10 +388,10 @@ export class LikeC4Model<M extends AnyAux = LikeC4Model.Any> {
290
388
  * Get all ancestor elements (i.e. parent, parent’s parent, etc.)
291
389
  * (from closest to root)
292
390
  */
293
- public *ancestors(element: M['ElementOrFqn']): ElementsIterator<M> {
294
- let id = getId(element) as M['Fqn']
391
+ public *ancestors(element: ElementOrFqn<A>): ElementsIterator<A> {
392
+ let id = getId(element)
295
393
  let parent
296
- while (parent = this.#parents.get(id)) {
394
+ while (parent = this._parents.get(id)) {
297
395
  yield parent
298
396
  id = parent.id
299
397
  }
@@ -303,7 +401,7 @@ export class LikeC4Model<M extends AnyAux = LikeC4Model.Any> {
303
401
  /**
304
402
  * Get all descendant elements (i.e. children, children’s children, etc.)
305
403
  */
306
- public *descendants(element: M['ElementOrFqn']): ElementsIterator<M> {
404
+ public *descendants(element: ElementOrFqn<A>): ElementsIterator<A> {
307
405
  for (const child of this.children(element)) {
308
406
  yield child
309
407
  yield* this.descendants(child.id)
@@ -316,11 +414,11 @@ export class LikeC4Model<M extends AnyAux = LikeC4Model.Any> {
316
414
  * @see incomers
317
415
  */
318
416
  public *incoming(
319
- element: M['ElementOrFqn'],
417
+ element: ElementOrFqn<A>,
320
418
  filter: IncomingFilter = 'all',
321
- ): RelationshipsIterator<M> {
419
+ ): RelationshipsIterator<A> {
322
420
  const id = getId(element)
323
- for (const rel of this.#incoming.get(id)) {
421
+ for (const rel of this._incoming.get(id)) {
324
422
  switch (true) {
325
423
  case filter === 'all':
326
424
  case filter === 'direct' && rel.target.id === id:
@@ -337,11 +435,11 @@ export class LikeC4Model<M extends AnyAux = LikeC4Model.Any> {
337
435
  * @see outgoers
338
436
  */
339
437
  public *outgoing(
340
- element: M['ElementOrFqn'],
438
+ element: ElementOrFqn<A>,
341
439
  filter: OutgoingFilter = 'all',
342
- ): RelationshipsIterator<M> {
440
+ ): RelationshipsIterator<A> {
343
441
  const id = getId(element)
344
- for (const rel of this.#outgoing.get(id)) {
442
+ for (const rel of this._outgoing.get(id)) {
345
443
  switch (true) {
346
444
  case filter === 'all':
347
445
  case filter === 'direct' && rel.source.id === id:
@@ -353,45 +451,150 @@ export class LikeC4Model<M extends AnyAux = LikeC4Model.Any> {
353
451
  return
354
452
  }
355
453
 
356
- public globals(): ModelGlobals {
357
- return {
358
- predicates: {
359
- ...this.$model.globals?.predicates,
360
- },
361
- dynamicPredicates: {
362
- ...this.$model.globals?.dynamicPredicates,
363
- },
364
- styles: {
365
- ...this.$model.globals?.styles,
366
- },
454
+ /**
455
+ * Returns all tags used in the model, sorted alphabetically.
456
+ */
457
+ get tags(): aux.Tags<A> {
458
+ return memoizeProp(this, 'tags', () => sort([...this._allTags.keys()], compareNatural))
459
+ }
460
+
461
+ /**
462
+ * Returns all tags used in the model, sorted by usage count (descending).
463
+ */
464
+ get tagsSortedByUsage(): ReadonlyArray<{
465
+ tag: aux.Tag<A>
466
+ count: number
467
+ tagged: ReadonlySet<ElementModel<A> | RelationshipModel<A> | LikeC4ViewModel<A>>
468
+ }> {
469
+ return memoizeProp(this, 'tagsSortedByUsage', () =>
470
+ pipe(
471
+ [...this._allTags.entries()],
472
+ map(([tag, tagged]) => ({
473
+ tag,
474
+ count: tagged.size,
475
+ tagged,
476
+ })),
477
+ sort((a, b) => compareNatural(a.tag, b.tag)),
478
+ sortBy(
479
+ [prop('count'), 'desc'],
480
+ ),
481
+ ))
482
+ }
483
+
484
+ /**
485
+ * Returns all elements, relationships and views marked with the given tag.
486
+ */
487
+ public findByTag(tag: aux.Tag<A>): IteratorLike<ElementModel<A> | RelationshipModel<A> | LikeC4ViewModel<A>>
488
+ public findByTag(tag: aux.Tag<A>, type: 'elements'): IteratorLike<ElementModel<A>>
489
+ public findByTag(tag: aux.Tag<A>, type: 'views'): IteratorLike<LikeC4ViewModel<A>>
490
+ public findByTag(tag: aux.Tag<A>, type: 'relationships'): IteratorLike<RelationshipModel<A>>
491
+ public findByTag(
492
+ tag: aux.Tag<A>,
493
+ type?: 'elements' | 'views' | 'relationships' | undefined,
494
+ ) {
495
+ return ifilter(this._allTags.get(tag), (el) => {
496
+ if (type === 'elements') {
497
+ return el instanceof ElementModel
498
+ }
499
+ if (type === 'views') {
500
+ return el instanceof LikeC4ViewModel
501
+ }
502
+ if (type === 'relationships') {
503
+ return el instanceof RelationshipModel
504
+ }
505
+ return true
506
+ })
507
+ }
508
+
509
+ /**
510
+ * Returns all elements of the given kind.
511
+ */
512
+ public *elementsOfKind(kind: aux.ElementKind<A>): IteratorLike<ElementModel<A>> {
513
+ for (const el of this._elements.values()) {
514
+ if (el.kind === kind) {
515
+ yield el
516
+ }
517
+ }
518
+ return
519
+ }
520
+
521
+ /**
522
+ * Returns all elements that match the given where operator.
523
+ *
524
+ * @example
525
+ * ```ts
526
+ * model.where({
527
+ * and: [
528
+ * { kind: 'component' },
529
+ * {
530
+ * or: [
531
+ * { tag: 'old' },
532
+ * { tag: { neq: 'new' } },
533
+ * ],
534
+ * },
535
+ * ],
536
+ * })
537
+ * ```
538
+ */
539
+ public *elementsWhere(where: WhereOperator<A>): IteratorLike<ElementModel<A>> {
540
+ const predicate = whereOperatorAsPredicate(where)
541
+ for (const el of this._elements.values()) {
542
+ if (predicate(el)) {
543
+ yield el
544
+ }
367
545
  }
546
+ return
368
547
  }
369
548
 
370
- public allTags(): ReadonlyArray<C4Tag> {
371
- return Array.from(this.#allTags.keys())
549
+ /**
550
+ * Returns all **model** relationships that match the given where operator.
551
+ *
552
+ * @example
553
+ * ```ts
554
+ * model.relationshipsWhere({
555
+ * and: [
556
+ * { kind: 'uses' },
557
+ * {
558
+ * or: [
559
+ * { tag: 'old' },
560
+ * { tag: { neq: 'new' } },
561
+ * ],
562
+ * },
563
+ * ],
564
+ * })
565
+ * ```
566
+ */
567
+ public *relationshipsWhere(where: WhereOperator<A>): IteratorLike<RelationshipModel<A>> {
568
+ const predicate = whereOperatorAsPredicate(where)
569
+ for (const rel of this._relations.values()) {
570
+ if (predicate(rel)) {
571
+ yield rel
572
+ }
573
+ }
574
+ return
372
575
  }
373
576
 
374
- private addElement(element: Element) {
375
- if (this.#elements.has(element.id)) {
577
+ private addElement(element: Element<A>) {
578
+ if (this._elements.has(element.id)) {
376
579
  throw new Error(`Element ${element.id} already exists`)
377
580
  }
378
581
  const el = new ElementModel(this, Object.freeze(element))
379
- this.#elements.set(el.id, el)
582
+ this._elements.set(el.id, el)
380
583
  const parentId = parentFqn(el.id)
381
584
  if (parentId) {
382
- invariant(this.#elements.has(parentId), `Parent ${parentId} of ${el.id} not found`)
383
- this.#parents.set(el.id, this.element(parentId))
384
- this.#children.get(parentId).add(el)
585
+ invariant(this._elements.has(parentId), `Parent ${parentId} of ${el.id} not found`)
586
+ this._parents.set(el.id, this.element(parentId))
587
+ this._children.get(parentId).add(el)
385
588
  } else {
386
- this.#rootElements.add(el)
589
+ this._rootElements.add(el)
387
590
  }
388
591
  return el
389
592
  }
390
593
 
391
- private addImportedElement(projectId: ProjectId, element: Element) {
594
+ private addImportedElement(projectId: ProjectId<A>, element: Element<A>) {
392
595
  invariant(!isGlobalFqn(element.id), `Imported element already has global FQN`)
393
- const id = GlobalFqn(projectId, element.id)
394
- if (this.#elements.has(id)) {
596
+ const id = GlobalFqn(projectId, element.id) as unknown as aux.StrictFqn<A>
597
+ if (this._elements.has(id)) {
395
598
  throw new Error(`Element ${id} already exists`)
396
599
  }
397
600
  const el = new ElementModel(
@@ -401,24 +604,24 @@ export class LikeC4Model<M extends AnyAux = LikeC4Model.Any> {
401
604
  id,
402
605
  }),
403
606
  )
404
- this.#elements.set(el.id, el)
607
+ this._elements.set(el.id, el)
405
608
  let parentId = parentFqn(el.id)
406
609
  while (parentId) {
407
610
  // For imported elements - id has format `@projectId.fqn`
408
611
  // We need to exclude `@projectId` from the parentId
409
- if (parentId.includes('.') && this.#elements.has(parentId)) {
410
- this.#parents.set(el.id, this.element(parentId))
411
- this.#children.get(parentId).add(el)
612
+ if (parentId.includes('.') && this._elements.has(parentId)) {
613
+ this._parents.set(el.id, this.element(parentId))
614
+ this._children.get(parentId).add(el)
412
615
  return el
413
616
  }
414
617
  parentId = parentFqn(parentId)
415
618
  }
416
- this.#rootElements.add(el)
619
+ this._rootElements.add(el)
417
620
  return el
418
621
  }
419
622
 
420
- private addRelation(relation: ModelRelation) {
421
- if (this.#relations.has(relation.id)) {
623
+ private addRelation(relation: Relationship<A>) {
624
+ if (this._relations.has(relation.id)) {
422
625
  throw new Error(`Relation ${relation.id} already exists`)
423
626
  }
424
627
  const rel = new RelationshipModel(
@@ -426,43 +629,49 @@ export class LikeC4Model<M extends AnyAux = LikeC4Model.Any> {
426
629
  Object.freeze(relation),
427
630
  )
428
631
  const { source, target } = rel
429
- this.#relations.set(rel.id, rel)
430
- this.#incoming.get(target.id).add(rel)
431
- this.#outgoing.get(source.id).add(rel)
632
+ this._relations.set(rel.id, rel)
633
+ this._incoming.get(target.id).add(rel)
634
+ this._outgoing.get(source.id).add(rel)
432
635
 
433
636
  const relParent = commonAncestor(source.id, target.id)
434
637
  // Process internal relationships
435
638
  if (relParent) {
436
639
  for (const ancestor of [relParent, ...ancestorsFqn(relParent)]) {
437
- this.#internal.get(ancestor).add(rel)
640
+ this._internal.get(ancestor).add(rel)
438
641
  }
439
642
  }
440
643
  // Process source hierarchy
441
- for (const sourceAncestor of ancestorsFqn(relation.source)) {
644
+ for (const sourceAncestor of ancestorsFqn(source.id)) {
442
645
  if (sourceAncestor === relParent) {
443
646
  break
444
647
  }
445
- this.#outgoing.get(sourceAncestor).add(rel)
648
+ this._outgoing.get(sourceAncestor).add(rel)
446
649
  }
447
650
  // Process target hierarchy
448
- for (const targetAncestor of ancestorsFqn(relation.target)) {
651
+ for (const targetAncestor of ancestorsFqn(target.id)) {
449
652
  if (targetAncestor === relParent) {
450
653
  break
451
654
  }
452
- this.#incoming.get(targetAncestor).add(rel)
655
+ this._incoming.get(targetAncestor).add(rel)
453
656
  }
454
657
  return rel
455
658
  }
456
659
  }
457
660
 
661
+ /**
662
+ * When you do not need types in the model
663
+ */
664
+ export type AnyLikeC4Model = LikeC4Model<any>
665
+
458
666
  export namespace LikeC4Model {
459
- export const EMPTY = LikeC4Model.create({
460
- projectId: 'default' as ProjectId,
667
+ export const EMPTY = LikeC4Model.create<aux.UnknownComputed>({
668
+ _stage: 'computed',
669
+ projectId: 'default' as never,
461
670
  specification: {
462
671
  elements: {},
463
672
  relationships: {},
464
673
  deployments: {},
465
- tags: [],
674
+ tags: {},
466
675
  },
467
676
  globals: {
468
677
  predicates: {},
@@ -477,60 +686,40 @@ export namespace LikeC4Model {
477
686
  relations: {},
478
687
  views: {},
479
688
  imports: {},
480
- }) as LikeC4Model<AnyAux>
481
-
482
- export type Any = Aux<
483
- string,
484
- string,
485
- string,
486
- ComputedView | DiagramView
487
- >
488
-
489
- export type Element<M extends AnyAux = Any> = ElementModel<M>
490
-
491
- // Relationship in logical model
492
- export type Relation<M extends AnyAux = Any> = RelationshipModel<M>
493
-
494
- // Relationship in logical or deployment model
495
- export type AnyRelation<M extends AnyAux = Any> = RelationshipModel<M> | DeploymentRelationModel<M>
496
-
497
- export type View<
498
- M extends AnyAux = Any,
499
- V extends ComputedView | DiagramView = M['ViewType'],
500
- > = LikeC4ViewModel<M, V>
501
-
502
- export type Node<
503
- M extends AnyAux = Any,
504
- V extends ComputedView | DiagramView = M['ViewType'],
505
- > = NodeModel<M, V>
506
-
507
- export type Edge<
508
- M extends AnyAux = Any,
509
- V extends ComputedView | DiagramView = M['ViewType'],
510
- > = EdgeModel<M, V>
511
-
512
- export type DeploymentModel<M extends AnyAux = AnyAux> = LikeC4DeploymentModel<M>
513
-
514
- export type Deployment<M extends AnyAux = AnyAux> = DeploymentElementModel<M>
515
- export type DeploymentNode<M extends AnyAux = AnyAux> = DeploymentNodeModel<M>
516
- export type DeployedInstance<M extends AnyAux = AnyAux> = DeployedInstanceModel<M>
517
-
518
- export type Typed<
519
- Elements extends string = string,
520
- Deployments extends string = string,
521
- Views extends string = string,
522
- ViewType = DiagramView<Views> | ComputedView<Views>,
523
- > = Aux<Elements, Deployments, Views, ViewType>
524
-
525
- export type Computed<
526
- Elements extends string = string,
527
- Deployments extends string = string,
528
- Views extends string = string,
529
- > = LikeC4Model<Typed<Elements, Deployments, Views, ComputedView<Views>>>
530
-
531
- export type Layouted<
532
- Elements extends string = string,
533
- Deployments extends string = string,
534
- Views extends string = string,
535
- > = LikeC4Model<Typed<Elements, Deployments, Views, DiagramView<Views>>>
689
+ })
690
+
691
+ export type Parsed<A = aux.Unknown> =
692
+ // dprint-ignore
693
+ aux.Unknown extends A
694
+ ? LikeC4Model<aux.UnknownParsed>
695
+ : A extends Aux<any, infer E, infer D, infer V, infer P, infer Spec>
696
+ ? LikeC4Model<Aux<'parsed', E, D, V, P, Spec>>
697
+ : never
698
+
699
+ export type Computed<A = aux.Unknown> =
700
+ // dprint-ignore
701
+ aux.Unknown extends A
702
+ ? LikeC4Model<aux.UnknownComputed>
703
+ : A extends Aux<any, infer E, infer D, infer V, infer P, infer Spec>
704
+ ? LikeC4Model<Aux<'computed', E, D, V, P, Spec>>
705
+ : never
706
+
707
+ export type Layouted<A = aux.Unknown> =
708
+ // dprint-ignore
709
+ aux.Unknown extends A
710
+ ? LikeC4Model<aux.UnknownLayouted>
711
+ : A extends Aux<any, infer E, infer D, infer V, infer P, infer Spec>
712
+ ? LikeC4Model<Aux<'layouted', E, D, V, P, Spec>>
713
+ : never
714
+
715
+ export type Node<A = aux.Unknown> = A extends aux.AnyAux ? NodeModel<A> : never
716
+ export type Element<A = aux.Unknown> = A extends aux.AnyAux ? ElementModel<A> : never
717
+ export type Relationship<A = aux.Unknown> = A extends aux.AnyAux ? RelationshipModel<A> : never
718
+ export type View<A = aux.Unknown> = A extends aux.AnyAux ? $ViewModel<A> : never
719
+
720
+ export type DeploymentNode<A = aux.Unknown> = A extends aux.AnyAux ? DeploymentNodeModel<A> : never
721
+ export type DeployedInstance<A = aux.Unknown> = A extends aux.AnyAux ? DeployedInstanceModel<A> : never
722
+
723
+ export type AnyRelation<M = aux.Unknown> = M extends aux.AnyAux ? RelationshipModel<M> | DeploymentRelationModel<M>
724
+ : never
536
725
  }