@likec4/core 1.30.0 → 1.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) 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 +10 -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.CAcZ6_cP.mjs → core.CBpKAlhj.mjs} +1742 -4128
  17. package/dist/shared/core.CCWXGc6G.d.mts +920 -0
  18. package/dist/shared/core.CUYDgv2-.mjs +214 -0
  19. package/dist/shared/{core.Cu-UdkSl.mjs → core.CpXlRyE5.mjs} +7 -494
  20. package/dist/shared/{core.C-YXI-43.mjs → core.Cy9smucx.mjs} +3 -1
  21. package/dist/shared/core.CywrQs86.d.mts +31 -0
  22. package/dist/shared/core.DoK86JEe.mjs +518 -0
  23. package/dist/shared/core.Dpq3P3YJ.d.mts +1265 -0
  24. package/dist/shared/{core.D2830qgg.d.mts → core.Pf5I9o0e.d.mts} +1 -1
  25. package/dist/shared/core.cbA9VZ02.mjs +2681 -0
  26. package/dist/shared/{core.CQXU9DF7.mjs → core.rmvsy0n3.mjs} +23 -32
  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 +19 -10
  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 +182 -137
  109. package/src/model/DeploymentModel.ts +88 -65
  110. package/src/model/ElementModel.ts +92 -72
  111. package/src/model/LikeC4Model.ts +430 -241
  112. package/src/model/RelationModel.ts +69 -26
  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/styles.ts +123 -0
  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.CZR9J1Qx.d.mts +0 -146
  169. package/dist/shared/core.CiFKryGW.d.mts +0 -745
  170. package/dist/shared/core.DJvmfnEi.d.mts +0 -1153
  171. package/dist/shared/core.DgfwjBtu.mjs +0 -495
  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/theme.ts +0 -82
  184. package/src/types/view-notation.ts +0 -9
  185. package/src/utils/graphlib.ts +0 -10
  186. /package/src/{errors/index.ts → utils/invariant.ts} +0 -0
@@ -1,24 +1,17 @@
1
1
  import { anyPass, unique } from 'remeda'
2
- import { nonexhaustive } from '../../../errors'
3
- import type { LikeC4Model } from '../../../model'
4
- import {
5
- type ConnectionModel,
6
- Connection,
7
- findConnection,
8
- findConnectionsBetween,
9
- } from '../../../model/connection/model'
10
- import type { RelationshipModel } from '../../../model/RelationModel'
11
- import type { AnyAux } from '../../../model/types'
12
- import { ModelLayer } from '../../../types/expression-v2-model'
2
+ import { type ConnectionModel, type LikeC4Model, type RelationshipModel, Connection } from '../../../model'
3
+ import type { ModelRelationExpr } from '../../../types'
4
+ import { type AnyAux, FqnRef, ModelFqnExpr } from '../../../types'
5
+ import { nonexhaustive } from '../../../utils'
13
6
  import { elementExprToPredicate } from '../../utils/elementExpressionToPredicate'
14
7
  import type { ConnectionWhere, PredicateExecutor } from '../_types'
15
- import { resolveAndIncludeFromMemory, resolveElements } from './_utils'
8
+ import { findConnection, findConnectionsBetween, resolveAndIncludeFromMemory, resolveElements } from './_utils'
16
9
 
17
- export const IncomingExprPredicate: PredicateExecutor<ModelLayer.RelationExpr.Incoming> = {
10
+ export const IncomingExprPredicate: PredicateExecutor<ModelRelationExpr.Incoming<AnyAux>> = {
18
11
  include: ({ expr, scope, model, memory, stage, filterWhere }) => {
19
12
  const target = expr.incoming
20
13
  const connections = [] as ConnectionModel<AnyAux>[]
21
- if (ModelLayer.FqnExpr.isWildcard(target)) {
14
+ if (ModelFqnExpr.isWildcard(target)) {
22
15
  if (!scope) {
23
16
  return
24
17
  }
@@ -61,7 +54,7 @@ export const IncomingExprPredicate: PredicateExecutor<ModelLayer.RelationExpr.In
61
54
  },
62
55
  exclude: ({ expr: { incoming }, model, scope, stage, where }) => {
63
56
  const excluded = [] as RelationshipModel[]
64
- if (ModelLayer.FqnExpr.isWildcard(incoming)) {
57
+ if (ModelFqnExpr.isWildcard(incoming)) {
65
58
  if (!scope) {
66
59
  return
67
60
  }
@@ -80,24 +73,24 @@ export const IncomingExprPredicate: PredicateExecutor<ModelLayer.RelationExpr.In
80
73
 
81
74
  export function incomingConnectionPredicate(
82
75
  model: LikeC4Model,
83
- expr: ModelLayer.FqnExpr.NonWildcard,
76
+ expr: ModelFqnExpr.NonWildcard,
84
77
  ): ConnectionWhere {
85
78
  switch (true) {
86
- case ModelLayer.FqnExpr.isElementKindExpr(expr):
87
- case ModelLayer.FqnExpr.isElementTagExpr(expr): {
79
+ case ModelFqnExpr.isElementKindExpr(expr):
80
+ case ModelFqnExpr.isElementTagExpr(expr): {
88
81
  const isElement = elementExprToPredicate(expr)
89
82
  return (connection) => isElement(connection.target)
90
83
  }
91
- case ModelLayer.FqnExpr.isModelRef(expr) && expr.selector === 'children': {
92
- const fqn = ModelLayer.FqnRef.toFqn(expr.ref)
84
+ case ModelFqnExpr.isModelRef(expr) && expr.selector === 'children': {
85
+ const fqn = FqnRef.flatten(expr.ref)
93
86
  return anyPass(
94
87
  [...model.children(fqn)].map(
95
88
  el => Connection.isIncoming(el.id),
96
89
  ),
97
90
  )
98
91
  }
99
- case ModelLayer.FqnExpr.isModelRef(expr) && expr.selector === 'descendants': {
100
- const fqn = ModelLayer.FqnRef.toFqn(expr.ref)
92
+ case ModelFqnExpr.isModelRef(expr) && expr.selector === 'descendants': {
93
+ const fqn = FqnRef.flatten(expr.ref)
101
94
  return anyPass([
102
95
  Connection.isInside(fqn),
103
96
  ...[...model.children(fqn)].map(
@@ -105,15 +98,15 @@ export function incomingConnectionPredicate(
105
98
  ),
106
99
  ])
107
100
  }
108
- case ModelLayer.FqnExpr.isModelRef(expr) && expr.selector === 'expanded': {
109
- const fqn = ModelLayer.FqnRef.toFqn(expr.ref)
101
+ case ModelFqnExpr.isModelRef(expr) && expr.selector === 'expanded': {
102
+ const fqn = FqnRef.flatten(expr.ref)
110
103
  return anyPass([
111
104
  Connection.isIncoming(fqn),
112
105
  Connection.isInside(fqn),
113
106
  ])
114
107
  }
115
- case ModelLayer.FqnExpr.isModelRef(expr): {
116
- const fqn = ModelLayer.FqnRef.toFqn(expr.ref)
108
+ case ModelFqnExpr.isModelRef(expr): {
109
+ const fqn = FqnRef.flatten(expr.ref)
117
110
  return Connection.isIncoming(fqn)
118
111
  }
119
112
  default:
@@ -1,20 +1,19 @@
1
1
  import { anyPass, unique } from 'remeda'
2
- import { nonexhaustive } from '../../../errors'
3
- import { type ConnectionModel, Connection, findConnectionsBetween } from '../../../model/connection/model'
4
- import type { LikeC4Model } from '../../../model/LikeC4Model'
5
- import type { RelationshipModel } from '../../../model/RelationModel'
6
- import type { AnyAux } from '../../../model/types'
7
- import { ModelLayer } from '../../../types/expression-v2-model'
2
+ import type { LikeC4Model, RelationshipModel } from '../../../model'
3
+ import { type ConnectionModel, Connection } from '../../../model'
4
+ import type { AnyAux } from '../../../types'
5
+ import { type ModelRelationExpr, FqnRef, ModelFqnExpr } from '../../../types'
6
+ import { nonexhaustive } from '../../../utils'
8
7
  import { toSet } from '../../../utils/iterable/to'
9
8
  import { elementExprToPredicate } from '../../utils/elementExpressionToPredicate'
10
9
  import type { ConnectionWhere, PredicateExecutor } from '../_types'
11
- import { resolveAndIncludeFromMemory, resolveElements } from './_utils'
10
+ import { findConnectionsBetween, resolveAndIncludeFromMemory, resolveElements } from './_utils'
12
11
 
13
- export const OutgoingExprPredicate: PredicateExecutor<ModelLayer.RelationExpr.Outgoing> = {
12
+ export const OutgoingExprPredicate: PredicateExecutor<ModelRelationExpr.Outgoing<AnyAux>> = {
14
13
  include: ({ expr, scope, model, memory, stage, filterWhere }) => {
15
14
  const target = expr.outgoing
16
15
  const connections = [] as ConnectionModel<AnyAux>[]
17
- if (ModelLayer.FqnExpr.isWildcard(target)) {
16
+ if (ModelFqnExpr.isWildcard(target)) {
18
17
  if (!scope) {
19
18
  return
20
19
  }
@@ -57,7 +56,7 @@ export const OutgoingExprPredicate: PredicateExecutor<ModelLayer.RelationExpr.Ou
57
56
  },
58
57
  exclude: ({ expr: { outgoing }, model, scope, stage, where }) => {
59
58
  const excluded = [] as RelationshipModel[]
60
- if (ModelLayer.FqnExpr.isWildcard(outgoing)) {
59
+ if (ModelFqnExpr.isWildcard(outgoing)) {
61
60
  if (!scope) {
62
61
  return
63
62
  }
@@ -78,24 +77,24 @@ export const OutgoingExprPredicate: PredicateExecutor<ModelLayer.RelationExpr.Ou
78
77
 
79
78
  export function outgoingConnectionPredicate(
80
79
  model: LikeC4Model,
81
- expr: ModelLayer.FqnExpr.NonWildcard,
80
+ expr: ModelFqnExpr.NonWildcard,
82
81
  ): ConnectionWhere {
83
82
  switch (true) {
84
- case ModelLayer.FqnExpr.isElementKindExpr(expr):
85
- case ModelLayer.FqnExpr.isElementTagExpr(expr): {
83
+ case ModelFqnExpr.isElementKindExpr(expr):
84
+ case ModelFqnExpr.isElementTagExpr(expr): {
86
85
  const isElement = elementExprToPredicate(expr)
87
86
  return (connection) => isElement(connection.source)
88
87
  }
89
- case ModelLayer.FqnExpr.isModelRef(expr) && expr.selector === 'children': {
90
- const fqn = ModelLayer.FqnRef.toFqn(expr.ref)
88
+ case ModelFqnExpr.isModelRef(expr) && expr.selector === 'children': {
89
+ const fqn = FqnRef.flatten(expr.ref)
91
90
  return anyPass(
92
91
  [...model.children(fqn)].map(
93
92
  el => Connection.isOutgoing(el.id),
94
93
  ),
95
94
  )
96
95
  }
97
- case ModelLayer.FqnExpr.isModelRef(expr) && expr.selector === 'descendants': {
98
- const fqn = ModelLayer.FqnRef.toFqn(expr.ref)
96
+ case ModelFqnExpr.isModelRef(expr) && expr.selector === 'descendants': {
97
+ const fqn = FqnRef.flatten(expr.ref)
99
98
  return anyPass([
100
99
  Connection.isInside(fqn),
101
100
  ...[...model.children(fqn)].map(
@@ -103,15 +102,15 @@ export function outgoingConnectionPredicate(
103
102
  ),
104
103
  ])
105
104
  }
106
- case ModelLayer.FqnExpr.isModelRef(expr) && expr.selector === 'expanded': {
107
- const fqn = ModelLayer.FqnRef.toFqn(expr.ref)
105
+ case ModelFqnExpr.isModelRef(expr) && expr.selector === 'expanded': {
106
+ const fqn = FqnRef.flatten(expr.ref)
108
107
  return anyPass([
109
108
  Connection.isOutgoing(fqn),
110
109
  Connection.isInside(fqn),
111
110
  ])
112
111
  }
113
- case ModelLayer.FqnExpr.isModelRef(expr): {
114
- const fqn = ModelLayer.FqnRef.toFqn(expr.ref)
112
+ case ModelFqnExpr.isModelRef(expr): {
113
+ const fqn = FqnRef.flatten(expr.ref)
115
114
  return Connection.isOutgoing(fqn)
116
115
  }
117
116
  default:
@@ -1,12 +1,12 @@
1
1
  import { filter } from 'remeda'
2
- import { findConnectionsBetween, findConnectionsWithin } from '../../../model/connection/model'
3
- import type { ModelLayer } from '../../../types/expression-v2-model'
2
+ import type { ModelFqnExpr } from '../../../types'
4
3
  import { ifilter, toArray } from '../../../utils/iterable'
5
4
  import { toSet } from '../../../utils/iterable/to'
6
5
  import { type PredicateExecutor, Memory } from '../_types'
7
6
  import { NoWhere } from '../utils'
7
+ import { findConnectionsBetween, findConnectionsWithin } from './_utils'
8
8
 
9
- export const WildcardPredicate: PredicateExecutor<ModelLayer.FqnExpr.Wildcard> = {
9
+ export const WildcardPredicate: PredicateExecutor<ModelFqnExpr.Wildcard> = {
10
10
  include: ({ scope, model, stage, memory, where }) => {
11
11
  if (!scope) {
12
12
  const rootElements = [...model.roots()].filter(where)
@@ -1,23 +1,22 @@
1
1
  import { filter, hasAtLeast, only } from 'remeda'
2
- import { invariant } from '../../errors'
3
- import { type ComputedEdge, type ComputedNode, type Fqn } from '../../types'
4
- import { type ComputedNodeSource, buildComputedNodes } from '../utils/buildComputedNodes'
2
+ import type { ConnectionModel } from '../../model'
3
+ import {
4
+ type AnyAux,
5
+ type ComputedEdge,
6
+ type ComputedNode,
7
+ type scalar,
8
+ } from '../../types'
9
+ import { invariant } from '../../utils'
10
+ import { buildComputedNodes, elementModelToNodeSource } from '../utils/buildComputedNodes'
5
11
  import { mergePropsFromRelationships } from '../utils/merge-props-from-relationships'
6
- import type { Connection, Elem, Memory } from './_types'
12
+ import type { Memory } from './_types'
7
13
 
8
14
  export const NoWhere = () => true
9
15
  export const NoFilter = <T>(x: T[] | readonly T[]): T[] => x as T[]
10
16
 
11
- export function toNodeSource(el: Elem): ComputedNodeSource {
12
- return {
13
- ...el.$element,
14
- modelRef: 1,
15
- }
16
- }
17
-
18
- export function toComputedEdges(
19
- connections: ReadonlyArray<Connection>,
20
- ): ComputedEdge[] {
17
+ export function toComputedEdges<A extends AnyAux>(
18
+ connections: ReadonlyArray<ConnectionModel<A>>,
19
+ ): ComputedEdge<A>[] {
21
20
  return connections.reduce((acc, e) => {
22
21
  // const modelRelations = []
23
22
  // const deploymentRelations = []
@@ -41,11 +40,11 @@ export function toComputedEdges(
41
40
  )?.$relationship,
42
41
  )
43
42
 
44
- const edge: ComputedEdge = {
43
+ const edge: ComputedEdge<A> = {
45
44
  id: e.id,
46
- parent: e.boundary?.id ?? null,
47
- source,
48
- target,
45
+ parent: e.boundary?.id as scalar.NodeId ?? null,
46
+ source: source as scalar.NodeId,
47
+ target: target as scalar.NodeId,
49
48
  label: title ?? null,
50
49
  relations: relations.map((r) => r.id),
51
50
  ...props,
@@ -53,11 +52,14 @@ export function toComputedEdges(
53
52
 
54
53
  acc.push(edge)
55
54
  return acc
56
- }, [] as ComputedEdge[])
55
+ }, [] as ComputedEdge<A>[])
57
56
  }
58
57
 
59
- export function buildNodes(memory: Memory): ReadonlyMap<Fqn, ComputedNode> {
60
- // typecast to MutableMemory
61
- // invariant(memory instanceof MutableMemory, 'Expected MutableMemory')
62
- return buildComputedNodes([...memory.final].map(toNodeSource), memory.groups)
58
+ export function buildNodes<A extends AnyAux>(
59
+ memory: Memory,
60
+ ): ReadonlyMap<scalar.NodeId, ComputedNode<A>> {
61
+ return buildComputedNodes(
62
+ [...memory.final].map(elementModelToNodeSource),
63
+ memory.groups,
64
+ )
63
65
  }
@@ -1,4 +1,4 @@
1
- export { computeView, computeViews, unsafeComputeView } from './compute-view'
1
+ export { computeLikeC4Model, computeParsedModelData, computeView, unsafeComputeView } from './compute-view'
2
2
  export type { ComputeViewResult } from './compute-view'
3
3
  export { resolveRulesExtendedViews } from './utils/resolve-extended-views'
4
4
  export { viewsWithReadableEdges, withReadableEdges } from './utils/with-readable-edges'
@@ -1,7 +1,6 @@
1
1
  import { isBoolean, pipe } from 'remeda'
2
- import { invariant } from '../../errors'
3
- import { findAscendingConnections } from '../../model/connection'
4
- import { difference, intersection, isDescendantOf, isIterable } from '../../utils'
2
+ import { findAscendingConnections } from '../../model'
3
+ import { difference, intersection, invariant, isDescendantOf, isIterable } from '../../utils'
5
4
  import { ifilter, isome, toSet } from '../../utils/iterable'
6
5
  import type { AnyCtx, CtxConnection, CtxElement, MutableState, StageExclude, StageExpression } from './_types'
7
6
 
@@ -209,7 +208,7 @@ export abstract class AbstractStageExclude<T extends AnyCtx> implements StageExc
209
208
  state = this.removeElements(state)
210
209
  }
211
210
 
212
- //state = this.moveDisconnectedExplicitsToImplicits(state)
211
+ // state = this.moveDisconnectedExplicitsToImplicits(state)
213
212
 
214
213
  return this.memory.update(this.postcommit(state))
215
214
  }
@@ -1,5 +1,5 @@
1
1
  import { partition } from 'remeda'
2
- import { mergeConnections } from '../../model/connection'
2
+ import { mergeConnections } from '../../model'
3
3
  import { intersection, isIterable, union } from '../../utils'
4
4
  import type {
5
5
  AnyCtx,
@@ -1,11 +1,12 @@
1
1
  import type { Connection } from '../../model/connection'
2
2
  import type { DeploymentElementModel } from '../../model/DeploymentElementModel'
3
3
  import type { ElementModel } from '../../model/ElementModel'
4
+ import type { AnyAux } from '../../types'
4
5
 
5
- type Element = ElementModel | DeploymentElementModel
6
+ type Element<A extends AnyAux> = ElementModel<A> | DeploymentElementModel<A>
6
7
 
7
8
  export interface ComputeCtx<
8
- E extends Element,
9
+ E extends Element<AnyAux>,
9
10
  C extends Connection<E, any>,
10
11
  M extends ComputeMemory<any>,
11
12
  Inc extends StageInclude<any>,
@@ -1,6 +1,5 @@
1
- import { type ElementModel } from '../../model/ElementModel'
2
- import type { RelationshipModel } from '../../model/RelationModel'
3
- import type { AnyAux } from '../../model/types'
1
+ import type { ElementModel, RelationshipModel } from '../../model'
2
+ import type { AnyAux, Unknown } from '../../types'
4
3
 
5
4
  // type Pair = {
6
5
  // left: ReadonlySet<ElementModel>
@@ -8,7 +7,7 @@ import type { AnyAux } from '../../model/types'
8
7
  // right: ReadonlySet<ElementModel>
9
8
  // }
10
9
 
11
- export type RelationshipsViewData<M extends AnyAux = AnyAux> = {
10
+ export type RelationshipsViewData<M extends AnyAux = Unknown> = {
12
11
  incomers: ReadonlySet<ElementModel<M>>
13
12
  incoming: ReadonlySet<RelationshipModel<M>>
14
13
  subjects: ReadonlySet<ElementModel<M>>
@@ -1,10 +1,7 @@
1
1
  import { pipe } from 'remeda'
2
- import { invariant } from '../../errors'
3
- import type { ElementModel } from '../../model/ElementModel'
4
- import type { LikeC4Model } from '../../model/LikeC4Model'
5
- import type { RelationshipModel } from '../../model/RelationModel'
6
- import type { AnyAux } from '../../model/types'
7
- import type { LikeC4ViewModel } from '../../model/view/LikeC4ViewModel'
2
+ import type { ElementModel, LikeC4Model, LikeC4ViewModel, RelationshipModel } from '../../model'
3
+ import type { AnyAux, aux } from '../../types'
4
+ import { invariant } from '../../utils'
8
5
  import { isDescendantOf, sortParentsFirst } from '../../utils/fqn'
9
6
  import { ifilter, imap, toArray, toSet } from '../../utils/iterable'
10
7
  import type { RelationshipsViewData } from './_types'
@@ -104,10 +101,10 @@ function computeRelationships<const M extends AnyAux>(
104
101
  }
105
102
  }
106
103
 
107
- export function computeRelationshipsView<const M extends AnyAux>(
108
- subjectId: NoInfer<M['Element']>,
104
+ export function computeRelationshipsView<M extends AnyAux>(
105
+ subjectId: aux.ElementId<M>,
109
106
  likec4model: LikeC4Model<M>,
110
- scopeViewId: NoInfer<M['View']> | null,
107
+ scopeViewId: aux.ViewId<M> | null,
111
108
  scope: 'global' | 'view' = 'global',
112
109
  ): RelationshipsViewData<M> {
113
110
  let subjectExistsInScope = true
@@ -132,8 +129,8 @@ export function computeRelationshipsView<const M extends AnyAux>(
132
129
  )
133
130
  }
134
131
 
135
- function computeScopedRelationshipsView<const M extends AnyAux>(
136
- subjectId: NoInfer<M['Element']>,
132
+ function computeScopedRelationshipsView<M extends AnyAux>(
133
+ subjectId: NoInfer<aux.ElementId<M>>,
137
134
  view: LikeC4ViewModel<M>,
138
135
  likec4model: LikeC4Model<M>,
139
136
  ): RelationshipsViewData<M> {
@@ -1,10 +1,9 @@
1
1
  import dagre, { type EdgeConfig, type GraphLabel } from '@dagrejs/dagre'
2
2
  import { concat, filter, forEachObj, groupBy, map, mapToObj, pipe, prop, reduce, tap } from 'remeda'
3
- import { invariant } from '../../errors'
4
3
  import type { ElementModel } from '../../model/ElementModel'
5
4
  import type { RelationshipModel } from '../../model/RelationModel'
6
5
  import type { DiagramNode, DiagramView, Fqn, NodeId } from '../../types'
7
- import { sortParentsFirst } from '../../utils'
6
+ import { invariant, sortParentsFirst } from '../../utils'
8
7
  import { toArray } from '../../utils/iterable'
9
8
  import { DefaultMap } from '../../utils/mnemonist'
10
9
  import type { RelationshipsViewData } from './_types'
@@ -43,7 +42,7 @@ const Sizes = {
43
42
  }
44
43
  type NodeData = {
45
44
  portId: string
46
- element: ElementModel
45
+ element: ElementModel<any>
47
46
  isCompound: boolean
48
47
  }
49
48
  function createGraph() {
@@ -80,7 +79,7 @@ const PortSuffix = '-port'
80
79
 
81
80
  function createNodes(
82
81
  prefix: string,
83
- elements: ReadonlySet<ElementModel>,
82
+ elements: ReadonlySet<ElementModel<any>>,
84
83
  g: G,
85
84
  ) {
86
85
  const graphNodes = new DefaultMap<Fqn, { id: string; portId: string }>(key => ({
@@ -315,11 +314,12 @@ export function layoutRelationshipsView(data: RelationshipsViewData): Pick<Diagr
315
314
  return {
316
315
  id: id as NodeId,
317
316
  parent: parentId as NodeId ?? null,
318
- position: [position.x, position.y],
319
317
  title: element.title,
318
+ ...position,
319
+ position: [position.x, position.y],
320
320
  description: element.description,
321
321
  technology: element.technology,
322
- tags: null,
322
+ tags: [],
323
323
  links: null,
324
324
  color: element.color,
325
325
  shape: element.shape,
@@ -1,10 +1,10 @@
1
- import { nonNullable } from '../../errors'
2
1
  import type { ElementModel } from '../../model/ElementModel'
3
- import type { AnyAux } from '../../model/types'
2
+ import type { AnyAux, aux } from '../../types'
3
+ import { nonNullable } from '../../utils'
4
4
  import { isAncestor, isDescendantOf, sortParentsFirst } from '../../utils/fqn'
5
5
  import { DefaultMap } from '../../utils/mnemonist'
6
6
 
7
- export function treeFromElements<const M extends AnyAux>(elements: Iterable<ElementModel<M>>) {
7
+ export function treeFromElements<M extends AnyAux>(elements: Iterable<ElementModel<M>>) {
8
8
  const sorted = sortParentsFirst([...elements]) as ReadonlyArray<ElementModel<M>>
9
9
  const root = new Set(sorted)
10
10
  const map = new Map(sorted.map(e => [e._literalId, e]))
@@ -32,7 +32,7 @@ export function treeFromElements<const M extends AnyAux>(elements: Iterable<Elem
32
32
 
33
33
  return {
34
34
  sorted,
35
- byId: (id: M['Element']): ElementModel<M> => nonNullable(map.get(id), `Element not found by id: ${id}`),
35
+ byId: (id: aux.ElementId<M>): ElementModel<M> => nonNullable(map.get(id), `Element not found by id: ${id}`),
36
36
  root: root as ReadonlySet<ElementModel<M>>,
37
37
  parent: (el: ElementModel<M>): ElementModel<M> | null => parents.get(el),
38
38
  children: (el: ElementModel<M>): ReadonlyArray<ElementModel<M>> => children.get(el),
@@ -1,14 +1,14 @@
1
- import { nonNullable } from '../../errors'
2
- import type { ComputedNode, Fqn } from '../../types'
1
+ import type { AnyAux, ComputedNode } from '../../types'
2
+ import { nonNullable } from '../../utils'
3
3
 
4
4
  /**
5
5
  * Returns the ancestors of given computed node, starting with the direct parent and ending with the root node.
6
6
  */
7
- export function ancestorsOfNode(
8
- node: ComputedNode,
9
- nodes: ReadonlyMap<Fqn, ComputedNode>
10
- ): ReadonlyArray<ComputedNode> {
11
- const ancestors = [] as ComputedNode[]
7
+ export function ancestorsOfNode<A extends AnyAux>(
8
+ node: ComputedNode<A>,
9
+ nodes: ReadonlyMap<string, ComputedNode<A>>,
10
+ ): ReadonlyArray<ComputedNode<A>> {
11
+ const ancestors = [] as ComputedNode<A>[]
12
12
  let parentId = node.parent
13
13
  while (parentId) {
14
14
  const parentNode = nonNullable(nodes.get(parentId), `Parent node ${parentId} not found`)
@@ -1,15 +1,20 @@
1
1
  import { isEmpty, isNullish, omitBy } from 'remeda'
2
2
  import {
3
- type ViewRule,
4
- ComputedNode,
3
+ type AnyAux,
4
+ type ComputedNode,
5
+ type ElementViewRule,
6
+ type ModelExpression,
7
+ isGroupElementKind,
5
8
  isViewRuleGroup,
6
9
  isViewRulePredicate,
7
- ModelLayer,
10
+ ModelFqnExpr,
8
11
  } from '../../types'
9
12
  import { elementExprToPredicate } from './elementExpressionToPredicate'
10
13
 
11
- export function flattenGroupRules<T extends ModelLayer.Expression>(guard: (expr: ModelLayer.Expression) => expr is T) {
12
- return (rule: ViewRule): Array<T> => {
14
+ export function flattenGroupRules<A extends AnyAux, T extends ModelExpression<A>>(
15
+ guard: (expr: ModelExpression<A>) => expr is T,
16
+ ) {
17
+ return (rule: ElementViewRule<A>): Array<T> => {
13
18
  if (isViewRuleGroup(rule)) {
14
19
  return rule.groupRules.flatMap(flattenGroupRules(guard))
15
20
  }
@@ -21,8 +26,11 @@ export function flattenGroupRules<T extends ModelLayer.Expression>(guard: (expr:
21
26
  }
22
27
  }
23
28
 
24
- export function applyCustomElementProperties(_rules: ViewRule[], _nodes: ComputedNode[]) {
25
- const rules = _rules.flatMap(flattenGroupRules(ModelLayer.FqnExpr.isCustom))
29
+ export function applyCustomElementProperties<A extends AnyAux>(
30
+ _rules: ElementViewRule<A>[],
31
+ _nodes: ComputedNode<A>[],
32
+ ) {
33
+ const rules = _rules.flatMap(flattenGroupRules(ModelFqnExpr.isCustom))
26
34
  if (rules.length === 0) {
27
35
  return _nodes
28
36
  }
@@ -44,7 +52,7 @@ export function applyCustomElementProperties(_rules: ViewRule[], _nodes: Compute
44
52
  const notEmpty = !isEmpty(rest)
45
53
  const satisfies = elementExprToPredicate(expr)
46
54
  nodes.forEach((node, i) => {
47
- if (ComputedNode.isNodesGroup(node) || !satisfies(node)) {
55
+ if (isGroupElementKind(node) || !satisfies(node)) {
48
56
  return
49
57
  }
50
58
  if (notEmpty) {
@@ -1,14 +1,14 @@
1
1
  import { isNullish, omitBy, pick } from 'remeda'
2
- import { type ComputedEdge, type ComputedNode, type ViewRule, ModelLayer } from '../../types'
2
+ import { type AnyAux, type ComputedEdge, type ComputedNode, type ElementViewRule, ModelRelationExpr } from '../../types'
3
3
  import { flattenGroupRules } from './applyCustomElementProperties'
4
4
  import { relationExpressionToPredicates } from './relationExpressionToPredicates'
5
5
 
6
- export function applyCustomRelationProperties(
7
- _rules: ViewRule[],
8
- nodes: ComputedNode[],
9
- _edges: Iterable<ComputedEdge>,
10
- ): ComputedEdge[] {
11
- const rules = _rules.flatMap(flattenGroupRules(ModelLayer.RelationExpr.isCustom))
6
+ export function applyCustomRelationProperties<A extends AnyAux>(
7
+ _rules: ElementViewRule<A>[],
8
+ nodes: ComputedNode<A>[],
9
+ _edges: Iterable<ComputedEdge<A>>,
10
+ ): ComputedEdge<A>[] {
11
+ const rules = _rules.flatMap(flattenGroupRules(ModelRelationExpr.isCustom))
12
12
  const edges = Array.from(_edges)
13
13
  if (rules.length === 0 || edges.length === 0) {
14
14
  return edges
@@ -25,8 +25,18 @@ export function applyCustomRelationProperties(
25
25
  const props = omitBy(customprops, isNullish)
26
26
  const satisfies = relationExpressionToPredicates(expr)
27
27
  edges.forEach((edge, i) => {
28
- const source = nodes.find(n => n.id === edge.source)
29
- const target = nodes.find(n => n.id === edge.target)
28
+ let source, target
29
+ for (const node of nodes) {
30
+ if (node.id === edge.source) {
31
+ source = node
32
+ }
33
+ if (node.id === edge.target) {
34
+ target = node
35
+ }
36
+ if (source && target) {
37
+ break
38
+ }
39
+ }
30
40
  if (!source || !target) {
31
41
  return
32
42
  }
@@ -1,19 +1,24 @@
1
1
  import { anyPass, filter, forEach, isDefined, isNot, pipe } from 'remeda'
2
- import { type ViewRule, type ViewRuleStyle, ComputedNode, isViewRuleStyle } from '../../types'
2
+ import {
3
+ type AnyAux,
4
+ type AnyViewRuleStyle,
5
+ type ComputedNode,
6
+ type ElementViewRule,
7
+ isGroupElementKind,
8
+ isViewRuleStyle,
9
+ } from '../../types'
3
10
  import { elementExprToPredicate } from './elementExpressionToPredicate'
4
11
 
5
12
  type Predicate<T> = (x: T) => boolean
6
13
 
7
- type CommonViewRuleStyle = Pick<ViewRuleStyle, 'style' | 'notation'>
8
-
9
- export function applyViewRuleStyle<Rule extends CommonViewRuleStyle>(
10
- rule: Rule,
11
- predicates: Predicate<ComputedNode>[],
12
- nodes: ComputedNode[],
13
- ) {
14
+ export function applyViewRuleStyle<A extends AnyAux>(
15
+ rule: Pick<AnyViewRuleStyle<A>, 'style' | 'notation'>,
16
+ predicates: Predicate<ComputedNode<A>>[],
17
+ nodes: ComputedNode<A>[],
18
+ ): void {
14
19
  pipe(
15
20
  nodes,
16
- filter(isNot(ComputedNode.isNodesGroup)),
21
+ filter(isNot(isGroupElementKind)),
17
22
  filter(anyPass(predicates)),
18
23
  forEach(n => {
19
24
  n.shape = rule.style.shape ?? n.shape
@@ -53,7 +58,10 @@ export function applyViewRuleStyle<Rule extends CommonViewRuleStyle>(
53
58
  )
54
59
  }
55
60
 
56
- export function applyViewRuleStyles(rules: ViewRule[], nodes: ComputedNode[]) {
61
+ export function applyViewRuleStyles<A extends AnyAux, N extends ComputedNode<A>[]>(
62
+ rules: ElementViewRule<A>[],
63
+ nodes: N,
64
+ ): N {
57
65
  for (const rule of rules) {
58
66
  if (!isViewRuleStyle(rule) || rule.targets.length === 0) {
59
67
  continue