@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.
Files changed (255) hide show
  1. package/builder/package.json +4 -0
  2. package/compute-view/package.json +4 -0
  3. package/compute-view/relationships/package.json +4 -0
  4. package/dist/builder/index.d.mts +13 -11
  5. package/dist/builder/index.mjs +111 -91
  6. package/dist/compute-view/index.d.mts +8 -7
  7. package/dist/compute-view/index.mjs +14 -11
  8. package/dist/compute-view/relationships-view/index.d.mts +9 -8
  9. package/dist/compute-view/relationships-view/index.mjs +6 -6
  10. package/dist/index.d.mts +7 -7
  11. package/dist/index.mjs +11 -11
  12. package/dist/model/connection/deployment/index.d.mts +11 -10
  13. package/dist/model/connection/deployment/index.mjs +2 -2
  14. package/dist/model/connection/index.d.mts +12 -11
  15. package/dist/model/connection/index.mjs +3 -3
  16. package/dist/model/connection/model/index.d.mts +11 -10
  17. package/dist/model/connection/model/index.mjs +2 -2
  18. package/dist/model/index.d.mts +14 -14
  19. package/dist/model/index.mjs +4 -5
  20. package/dist/shared/{core.Ae86Y3tB.mjs → core.01VTr9qu.mjs} +8 -26
  21. package/dist/shared/core.1vX5a9AY.mjs +86 -0
  22. package/dist/shared/{core.BVNaR17u.mjs → core.B7KhhkRY.mjs} +1 -1
  23. package/dist/shared/core.B85MJLTf.mjs +5 -0
  24. package/dist/shared/{core.DA5vzwZ9.mjs → core.BIqHjQiH.mjs} +56 -42
  25. package/dist/shared/core.BKlholso.mjs +3 -0
  26. package/dist/shared/core.BR4zXDH-.mjs +13 -0
  27. package/dist/shared/{core.CXy1NLUG.mjs → core.BYNkXQ8A.mjs} +21 -12
  28. package/dist/shared/{core.BuoXfSMj.mjs → core.BbE4y-yl.mjs} +1 -1
  29. package/dist/shared/core.BoYfZOBm.mjs +3 -0
  30. package/dist/shared/core.BsSXS-_R.mjs +7 -0
  31. package/dist/shared/{core.DJp8fgok.mjs → core.BzTakU3I.mjs} +14 -10
  32. package/dist/shared/{core.4u1dVmfX.mjs → core.C2TiyjI6.mjs} +2 -2
  33. package/dist/shared/{core.DLpidoWc.mjs → core.C3JowhaZ.mjs} +3 -3
  34. package/dist/shared/{core.CNGyqkJh.mjs → core.C4x8aaWa.mjs} +3 -1
  35. package/dist/shared/{core.BB6zA-UU.mjs → core.C8YY6Uub.mjs} +38 -9
  36. package/dist/shared/{core.Asc11Mjy.mjs → core.C8sl5Y8Z.mjs} +122 -58
  37. package/dist/shared/{core.BvMRMo7Z.mjs → core.CNgZvKb8.mjs} +3 -5198
  38. package/dist/shared/{core.CUG6vpyL.d.mts → core.CQngdcuj.d.mts} +85 -4
  39. package/dist/shared/{core.Be1n9a0i.mjs → core.C_Ni6yHl.mjs} +5 -4
  40. package/dist/shared/core.CbT8JVYL.mjs +5 -0
  41. package/dist/shared/core.CqAJJpK_.mjs +3 -0
  42. package/dist/shared/{core.BXsxn-hf.d.mts → core.D0PjZzIS.d.mts} +27 -15
  43. package/dist/shared/{core.DgesAwC8.d.mts → core.D5fzJWbF.d.mts} +2 -2
  44. package/dist/shared/{core.hfOE3RfK.d.mts → core.DACpKp35.d.mts} +5 -5
  45. package/dist/shared/core.DFi2dOTl.mjs +39548 -0
  46. package/dist/shared/{core.xSQO0XYD.d.mts → core.DIol3syK.d.mts} +2 -2
  47. package/dist/shared/{core.DlG1xWt2.mjs → core.DMMOWQqc.mjs} +3 -2
  48. package/dist/shared/core.DNbUPnve.mjs +3990 -0
  49. package/dist/shared/{core.CCD1ID81.mjs → core.DRJma0Ol.mjs} +4 -3
  50. package/dist/shared/{core.DgttqsJc.mjs → core.DRhg-gVU.mjs} +9 -9
  51. package/dist/shared/core.DSO_rTC2.mjs +5322 -0
  52. package/dist/shared/{core.FUPplpae.d.mts → core.D_vkffV4.d.mts} +4 -2
  53. package/dist/shared/core.DdMJk7nx.d.mts +476 -0
  54. package/dist/shared/{core.BhpgpOep.d.mts → core.Dgs6-nuz.d.mts} +2 -2
  55. package/dist/shared/{core.Be4Jy9Qx.mjs → core.FZ305VYd.mjs} +2 -2
  56. package/dist/shared/core.OHD4KXm9.mjs +5 -0
  57. package/dist/shared/{core.GTgsmXS_.mjs → core.QJD_fcrc.mjs} +2 -2
  58. package/dist/shared/core.RfnaEmgA.mjs +7 -0
  59. package/dist/shared/core.fHR_8Tnq.d.mts +450 -0
  60. package/dist/shared/{core.D0EgVMQK.mjs → core.lRvxPoao.mjs} +14 -12
  61. package/dist/shared/{core.CaT0SUUK.mjs → core.rCeaAqgW.mjs} +1 -84
  62. package/dist/shared/{core.zxTBF_PD.d.mts → core.s9uwOt60.d.mts} +4 -4
  63. package/dist/shared/core.yna0OdV5.d.mts +98 -0
  64. package/dist/styles/index.d.mts +106 -0
  65. package/dist/styles/index.mjs +1 -0
  66. package/dist/types/_aux.d.mts +2 -2
  67. package/dist/types/expression-model.d.mts +3 -4
  68. package/dist/types/expression.d.mts +3 -4
  69. package/dist/types/fqnRef.d.mts +2 -2
  70. package/dist/types/fqnRef.mjs +3 -3
  71. package/dist/types/index.d.mts +8 -8
  72. package/dist/types/index.mjs +150 -5
  73. package/dist/types/scalar.mjs +3 -2
  74. package/dist/utils/graphology/index.d.mts +1864 -0
  75. package/dist/utils/graphology/index.mjs +1 -0
  76. package/dist/utils/index.d.mts +11 -6
  77. package/dist/utils/index.mjs +21 -37
  78. package/dist/utils/iterable/index.d.mts +1 -1
  79. package/dist/utils/iterable/index.mjs +45 -7
  80. package/model/package.json +4 -0
  81. package/package.json +42 -24
  82. package/styles/package.json +4 -0
  83. package/types/package.json +4 -0
  84. package/utils/graphology/package.json +4 -0
  85. package/utils/package.json +4 -0
  86. package/dist/shared/core.6_Vp2iiN.mjs +0 -172
  87. package/dist/shared/core.CUw_2J9j.mjs +0 -47
  88. package/dist/shared/core.CzdwsPmY.d.mts +0 -69
  89. package/dist/shared/core.D-ZGWDDt.d.mts +0 -831
  90. package/dist/shared/core.DoM6aM9N.mjs +0 -7
  91. package/dist/shared/core.ILwny7BV.mjs +0 -38
  92. package/dist/theme/index.d.mts +0 -11
  93. package/dist/theme/index.mjs +0 -232
  94. package/src/builder/Builder.deployment.ts +0 -224
  95. package/src/builder/Builder.deploymentModel.ts +0 -449
  96. package/src/builder/Builder.element.ts +0 -241
  97. package/src/builder/Builder.model.ts +0 -494
  98. package/src/builder/Builder.ts +0 -946
  99. package/src/builder/Builder.view-common.ts +0 -273
  100. package/src/builder/Builder.view-deployment.ts +0 -135
  101. package/src/builder/Builder.view-element.ts +0 -202
  102. package/src/builder/Builder.views.ts +0 -399
  103. package/src/builder/Builder.with.ts +0 -156
  104. package/src/builder/_types.ts +0 -324
  105. package/src/builder/index.ts +0 -11
  106. package/src/compute-view/compute-view.ts +0 -80
  107. package/src/compute-view/deployment-view/_types.ts +0 -38
  108. package/src/compute-view/deployment-view/clean-connections.ts +0 -236
  109. package/src/compute-view/deployment-view/compute.ts +0 -94
  110. package/src/compute-view/deployment-view/memory/index.ts +0 -9
  111. package/src/compute-view/deployment-view/memory/memory.ts +0 -96
  112. package/src/compute-view/deployment-view/predicates/deploymentRefs-where.ts +0 -18
  113. package/src/compute-view/deployment-view/predicates/deploymentRefs.ts +0 -154
  114. package/src/compute-view/deployment-view/predicates/index.ts +0 -8
  115. package/src/compute-view/deployment-view/predicates/relation-direct.ts +0 -243
  116. package/src/compute-view/deployment-view/predicates/relation-in-out.ts +0 -70
  117. package/src/compute-view/deployment-view/predicates/relation-incoming.ts +0 -101
  118. package/src/compute-view/deployment-view/predicates/relation-outgoing.ts +0 -95
  119. package/src/compute-view/deployment-view/predicates/relation-where.ts +0 -18
  120. package/src/compute-view/deployment-view/predicates/utils.ts +0 -282
  121. package/src/compute-view/deployment-view/predicates/wildcard.ts +0 -41
  122. package/src/compute-view/deployment-view/stages/stage-exclude.ts +0 -5
  123. package/src/compute-view/deployment-view/stages/stage-final.ts +0 -245
  124. package/src/compute-view/deployment-view/stages/stage-include.ts +0 -95
  125. package/src/compute-view/deployment-view/utils.ts +0 -297
  126. package/src/compute-view/dynamic-view/compute.ts +0 -312
  127. package/src/compute-view/element-view/_types.ts +0 -47
  128. package/src/compute-view/element-view/clean-connections.ts +0 -117
  129. package/src/compute-view/element-view/compute.ts +0 -324
  130. package/src/compute-view/element-view/memory/NodeGroup.ts +0 -31
  131. package/src/compute-view/element-view/memory/index.ts +0 -10
  132. package/src/compute-view/element-view/memory/memory.ts +0 -178
  133. package/src/compute-view/element-view/memory/stage-exclude.ts +0 -59
  134. package/src/compute-view/element-view/memory/stage-final.ts +0 -129
  135. package/src/compute-view/element-view/memory/stage-include.ts +0 -130
  136. package/src/compute-view/element-view/predicates/_utils.ts +0 -91
  137. package/src/compute-view/element-view/predicates/element-expand.ts +0 -29
  138. package/src/compute-view/element-view/predicates/element-kind-tag.ts +0 -27
  139. package/src/compute-view/element-view/predicates/element-ref.ts +0 -24
  140. package/src/compute-view/element-view/predicates/relation-direct.ts +0 -321
  141. package/src/compute-view/element-view/predicates/relation-in-out.ts +0 -64
  142. package/src/compute-view/element-view/predicates/relation-in.ts +0 -115
  143. package/src/compute-view/element-view/predicates/relation-out.ts +0 -119
  144. package/src/compute-view/element-view/predicates/wildcard.ts +0 -88
  145. package/src/compute-view/element-view/utils.ts +0 -65
  146. package/src/compute-view/index.ts +0 -4
  147. package/src/compute-view/memory/AbstractMemory.ts +0 -45
  148. package/src/compute-view/memory/AbstractStageExclude.ts +0 -215
  149. package/src/compute-view/memory/AbstractStageInclude.ts +0 -200
  150. package/src/compute-view/memory/_types.ts +0 -148
  151. package/src/compute-view/memory/index.ts +0 -5
  152. package/src/compute-view/memory/ops.ts +0 -43
  153. package/src/compute-view/relationships-view/_types.ts +0 -16
  154. package/src/compute-view/relationships-view/compute.ts +0 -159
  155. package/src/compute-view/relationships-view/index.ts +0 -3
  156. package/src/compute-view/relationships-view/layout.ts +0 -358
  157. package/src/compute-view/relationships-view/utils.ts +0 -73
  158. package/src/compute-view/utils/ancestorsOfNode.ts +0 -19
  159. package/src/compute-view/utils/applyCustomElementProperties.ts +0 -107
  160. package/src/compute-view/utils/applyCustomRelationProperties.ts +0 -58
  161. package/src/compute-view/utils/applyViewRuleStyles.ts +0 -73
  162. package/src/compute-view/utils/buildComputedNodes.ts +0 -166
  163. package/src/compute-view/utils/buildElementNotations.ts +0 -64
  164. package/src/compute-view/utils/elementExpressionToPredicate.ts +0 -50
  165. package/src/compute-view/utils/link-nodes-with-edges.ts +0 -56
  166. package/src/compute-view/utils/merge-props-from-relationships.ts +0 -161
  167. package/src/compute-view/utils/relationExpressionToPredicates.ts +0 -55
  168. package/src/compute-view/utils/resolve-extended-views.ts +0 -85
  169. package/src/compute-view/utils/resolve-global-rules.ts +0 -88
  170. package/src/compute-view/utils/topological-sort.ts +0 -256
  171. package/src/compute-view/utils/view-hash.ts +0 -45
  172. package/src/compute-view/utils/with-readable-edges.ts +0 -40
  173. package/src/index.ts +0 -32
  174. package/src/model/DeploymentElementModel.ts +0 -712
  175. package/src/model/DeploymentModel.ts +0 -393
  176. package/src/model/ElementModel.ts +0 -316
  177. package/src/model/LikeC4Model.ts +0 -882
  178. package/src/model/RelationModel.ts +0 -152
  179. package/src/model/connection/Connection.ts +0 -72
  180. package/src/model/connection/deployment/DeploymentConnectionModel.ts +0 -185
  181. package/src/model/connection/deployment/find.ts +0 -120
  182. package/src/model/connection/deployment/index.ts +0 -8
  183. package/src/model/connection/index.ts +0 -22
  184. package/src/model/connection/model/ConnectionModel.ts +0 -158
  185. package/src/model/connection/model/find.ts +0 -117
  186. package/src/model/connection/model/index.ts +0 -8
  187. package/src/model/connection/ops.ts +0 -276
  188. package/src/model/guards.ts +0 -77
  189. package/src/model/index.ts +0 -72
  190. package/src/model/types.ts +0 -67
  191. package/src/model/utils.ts +0 -66
  192. package/src/model/view/EdgeModel.ts +0 -121
  193. package/src/model/view/LikeC4ViewModel.ts +0 -361
  194. package/src/model/view/LikeC4ViewsFolder.ts +0 -151
  195. package/src/model/view/NodeModel.ts +0 -247
  196. package/src/theme/element.ts +0 -61
  197. package/src/theme/index.ts +0 -127
  198. package/src/theme/relationships.ts +0 -54
  199. package/src/types/RichText.ts +0 -205
  200. package/src/types/_aux.ts +0 -317
  201. package/src/types/_common.ts +0 -102
  202. package/src/types/const.ts +0 -34
  203. package/src/types/expression-model.ts +0 -294
  204. package/src/types/expression.ts +0 -313
  205. package/src/types/fqnRef.ts +0 -91
  206. package/src/types/geometry.ts +0 -159
  207. package/src/types/global.ts +0 -21
  208. package/src/types/index.ts +0 -44
  209. package/src/types/model-data.ts +0 -77
  210. package/src/types/model-deployment.ts +0 -78
  211. package/src/types/model-dump.ts +0 -79
  212. package/src/types/model-logical.ts +0 -126
  213. package/src/types/model-spec.ts +0 -88
  214. package/src/types/operators.ts +0 -156
  215. package/src/types/project.ts +0 -14
  216. package/src/types/scalar.ts +0 -162
  217. package/src/types/styles.ts +0 -122
  218. package/src/types/view-changes.ts +0 -32
  219. package/src/types/view-common.ts +0 -157
  220. package/src/types/view-computed.ts +0 -126
  221. package/src/types/view-layouted.ts +0 -94
  222. package/src/types/view-parsed.deployment.ts +0 -39
  223. package/src/types/view-parsed.dynamic.ts +0 -89
  224. package/src/types/view-parsed.element.ts +0 -65
  225. package/src/types/view.ts +0 -113
  226. package/src/utils/common-head.ts +0 -22
  227. package/src/utils/compare-natural.ts +0 -60
  228. package/src/utils/const.ts +0 -1
  229. package/src/utils/fqn.ts +0 -302
  230. package/src/utils/getOrCreate.ts +0 -8
  231. package/src/utils/guards.ts +0 -9
  232. package/src/utils/index.ts +0 -68
  233. package/src/utils/invariant.ts +0 -29
  234. package/src/utils/iterable/_types.ts +0 -5
  235. package/src/utils/iterable/filter.ts +0 -55
  236. package/src/utils/iterable/find.ts +0 -38
  237. package/src/utils/iterable/first.ts +0 -48
  238. package/src/utils/iterable/flat.ts +0 -17
  239. package/src/utils/iterable/head.ts +0 -22
  240. package/src/utils/iterable/index.ts +0 -15
  241. package/src/utils/iterable/map.ts +0 -40
  242. package/src/utils/iterable/reduce.ts +0 -24
  243. package/src/utils/iterable/some.ts +0 -36
  244. package/src/utils/iterable/to.ts +0 -19
  245. package/src/utils/iterable/unique.ts +0 -23
  246. package/src/utils/markdown/index.ts +0 -2
  247. package/src/utils/markdown/to-html.ts +0 -32
  248. package/src/utils/markdown/to-text.ts +0 -14
  249. package/src/utils/memoize-prop.ts +0 -30
  250. package/src/utils/mnemonist.ts +0 -9
  251. package/src/utils/object-hash.ts +0 -14
  252. package/src/utils/promises.ts +0 -24
  253. package/src/utils/relations.ts +0 -36
  254. package/src/utils/set.ts +0 -83
  255. package/src/utils/string-hash.ts +0 -16
@@ -1,161 +0,0 @@
1
- import { isDeepEqual, isTruthy, only, pickBy, pipe, reduce, unique } from 'remeda'
2
- import type {
3
- AnyAux,
4
- aux,
5
- Color,
6
- DeploymentRelationship,
7
- Link,
8
- NonEmptyArray,
9
- Relationship,
10
- RelationshipArrowType,
11
- RelationshipLineType,
12
- scalar,
13
- } from '../../types'
14
- import { isNonEmptyArray } from '../../utils'
15
-
16
- function pickRelationshipProps<A extends AnyAux>(relation: Relationship<A> | DeploymentRelationship<A>): {
17
- title?: string
18
- description?: scalar.MarkdownOrString | null
19
- technology: string | null
20
- kind: aux.RelationKind<A> | null
21
- color: Color | null
22
- line: RelationshipLineType | null
23
- head: RelationshipArrowType | null
24
- tail: RelationshipArrowType | null
25
- navigateTo: aux.StrictViewId<A> | null
26
- } {
27
- const {
28
- title,
29
- description = null,
30
- technology = null,
31
- kind = null,
32
- color = null,
33
- line = null,
34
- head = null,
35
- tail = null,
36
- navigateTo = null,
37
- } = relation
38
- return {
39
- // Pick description only if title is present
40
- ...(title && {
41
- title,
42
- description,
43
- }),
44
- technology,
45
- kind: kind as aux.RelationKind<A> | null,
46
- color,
47
- line,
48
- head,
49
- tail,
50
- navigateTo: navigateTo as aux.StrictViewId<A> | null,
51
- }
52
- }
53
-
54
- export type MergedRelationshipProps<A extends AnyAux> = {
55
- title?: string | null
56
- description?: scalar.MarkdownOrString | null
57
- technology?: string
58
- kind?: aux.RelationKind<A>
59
- color?: Color
60
- line?: RelationshipLineType
61
- head?: RelationshipArrowType
62
- tail?: RelationshipArrowType
63
- navigateTo?: aux.StrictViewId<A>
64
- tags?: NonEmptyArray<aux.Tag<A>>
65
- links?: NonEmptyArray<Link>
66
- }
67
-
68
- /**
69
- * Merges properties from multiple relationships into a single object.
70
- * @param relations - The relationships to merge.
71
- * @param prefer - The relationship to prefer when merging.
72
- */
73
- export function mergePropsFromRelationships<A extends AnyAux>(
74
- relations: Array<Relationship<A> | DeploymentRelationship<A>>,
75
- prefer?: Relationship<A> | DeploymentRelationship<A>,
76
- ): MergedRelationshipProps<A> {
77
- const allprops = pipe(
78
- relations,
79
- reduce(
80
- (acc, r) => {
81
- if (isTruthy(r.title) && !acc.title.includes(r.title)) {
82
- acc.title.push(r.title)
83
- }
84
- if (isTruthy(r.description) && !acc.description.some(isDeepEqual(r.description))) {
85
- acc.description.push(r.description)
86
- }
87
- if (isTruthy(r.technology) && !acc.technology.includes(r.technology)) {
88
- acc.technology.push(r.technology)
89
- }
90
- if (isTruthy(r.kind) && !acc.kind.includes(r.kind)) {
91
- acc.kind.push(r.kind)
92
- }
93
- if (isTruthy(r.color) && !acc.color.includes(r.color)) {
94
- acc.color.push(r.color)
95
- }
96
- if (isTruthy(r.line) && !acc.line.includes(r.line)) {
97
- acc.line.push(r.line)
98
- }
99
- if (isTruthy(r.head) && !acc.head.includes(r.head)) {
100
- acc.head.push(r.head)
101
- }
102
- if (isTruthy(r.tail) && !acc.tail.includes(r.tail)) {
103
- acc.tail.push(r.tail)
104
- }
105
- if (isTruthy(r.navigateTo) && !acc.navigateTo.includes(r.navigateTo)) {
106
- acc.navigateTo.push(r.navigateTo)
107
- }
108
- if (r.tags) {
109
- acc.tags.push(...r.tags)
110
- }
111
- if (r.links) {
112
- acc.links.push(...r.links)
113
- }
114
- return acc
115
- },
116
- {
117
- title: [] as string[],
118
- description: [] as scalar.MarkdownOrString[],
119
- technology: [] as string[],
120
- kind: [] as aux.RelationKind<A>[],
121
- head: [] as RelationshipArrowType[],
122
- tail: [] as RelationshipArrowType[],
123
- color: [] as Color[],
124
- tags: [] as aux.Tag<A>[],
125
- links: [] as Link[],
126
- line: [] as RelationshipLineType[],
127
- navigateTo: [] as aux.ViewId<A>[],
128
- },
129
- ),
130
- )
131
-
132
- let technology = only(allprops.technology)
133
- let title = only(allprops.title) ?? (allprops.title.length > 1 ? '[...]' : null)
134
-
135
- const tags = unique(allprops.tags)
136
- let merged = pickBy(
137
- {
138
- // If there is no title, but there is technology, use technology as title
139
- title: title ?? (technology ? `[${technology}]` : null),
140
- description: only(allprops.description),
141
- technology,
142
- kind: only(allprops.kind),
143
- head: only(allprops.head),
144
- tail: only(allprops.tail),
145
- color: only(allprops.color),
146
- line: only(allprops.line),
147
- navigateTo: only(allprops.navigateTo),
148
- ...isNonEmptyArray(allprops.links) && { links: allprops.links },
149
- ...isNonEmptyArray(tags) && { tags },
150
- },
151
- isTruthy,
152
- )
153
-
154
- if (prefer) {
155
- return {
156
- ...merged,
157
- ...pickBy(pickRelationshipProps(prefer), isTruthy),
158
- }
159
- }
160
- return merged
161
- }
@@ -1,55 +0,0 @@
1
- import type { AnyAux, aux, ComputedNode } from '../../types'
2
- import { ModelRelationExpr, whereOperatorAsPredicate } from '../../types'
3
- import { nonexhaustive } from '../../utils'
4
- import { elementExprToPredicate } from './elementExpressionToPredicate'
5
-
6
- type Predicate<T> = (x: T) => boolean
7
- export type FilterableEdge<A extends AnyAux> = {
8
- tags?: aux.Tags<A> | null | undefined
9
- kind?: string
10
- source: ComputedNode<A>
11
- target: ComputedNode<A>
12
- }
13
-
14
- export function relationExpressionToPredicates<A extends AnyAux, T extends FilterableEdge<A>>(
15
- expr: ModelRelationExpr.Any<A>,
16
- ): Predicate<T> {
17
- switch (true) {
18
- case ModelRelationExpr.isCustom(expr): {
19
- return relationExpressionToPredicates(expr.customRelation.expr)
20
- }
21
- case ModelRelationExpr.isWhere(expr): {
22
- const predicate = relationExpressionToPredicates(expr.where.expr)
23
- const where = whereOperatorAsPredicate(expr.where.condition)
24
- return e =>
25
- predicate(e) && where({
26
- source: { tags: e.source.tags, kind: e.source.kind as aux.AllKinds<A> },
27
- target: { tags: e.target.tags, kind: e.target.kind as aux.AllKinds<A> },
28
- ...(e.tags && { tags: e.tags }),
29
- ...(e.kind && { kind: e.kind as aux.AllKinds<A> }),
30
- })
31
- }
32
- case ModelRelationExpr.isDirect(expr): {
33
- const isSource = elementExprToPredicate(expr.source)
34
- const isTarget = elementExprToPredicate(expr.target)
35
- return edge => {
36
- return (isSource(edge.source) && isTarget(edge.target))
37
- || (!!expr.isBidirectional && isSource(edge.target) && isTarget(edge.source))
38
- }
39
- }
40
- case ModelRelationExpr.isInOut(expr): {
41
- const isInOut = elementExprToPredicate(expr.inout)
42
- return edge => isInOut(edge.source) || isInOut(edge.target)
43
- }
44
- case ModelRelationExpr.isIncoming(expr): {
45
- const isTarget = elementExprToPredicate(expr.incoming)
46
- return edge => isTarget(edge.target)
47
- }
48
- case ModelRelationExpr.isOutgoing(expr): {
49
- const isSource = elementExprToPredicate(expr.outgoing)
50
- return edge => isSource(edge.source)
51
- }
52
- default:
53
- nonexhaustive(expr)
54
- }
55
- }
@@ -1,85 +0,0 @@
1
- import { unique, values } from 'remeda'
2
- import { type LikeC4View, isElementView, isExtendsElementView } from '../../types/view'
3
-
4
- import Graph from 'graphology'
5
- import { topologicalSort } from 'graphology-dag/topological-sort'
6
- import willCreateCycle from 'graphology-dag/will-create-cycle'
7
- import type { AnyAux, aux, ParsedElementView } from '../../types'
8
- import { isNonEmptyArray } from '../../utils'
9
- /**
10
- * Resolve rules of extended views
11
- * (Removes invalid views)
12
- */
13
- export function resolveRulesExtendedViews<A extends AnyAux, V extends Record<any, LikeC4View<A>>>(
14
- unresolvedViews: V,
15
- ): V {
16
- const g = new Graph<{ view: LikeC4View<A> }>({
17
- type: 'directed',
18
- })
19
- const extendedViews = [] as ParsedElementView<A>[]
20
- for (const view of values(unresolvedViews)) {
21
- g.addNode(view.id, { view })
22
- if (isExtendsElementView(view)) {
23
- extendedViews.push(view)
24
- }
25
- }
26
-
27
- if (extendedViews.length === 0) {
28
- return unresolvedViews
29
- }
30
-
31
- for (const view of extendedViews) {
32
- if (!g.hasNode(view.extends)) {
33
- console.warn(`View "${view.id}" extends from "${view.extends}" which does not exist`)
34
- continue
35
- }
36
- if (willCreateCycle(g, view.id, view.extends)) {
37
- console.warn(`View "${view.id}" extends from "${view.extends}" which creates a cycle`)
38
- continue
39
- }
40
-
41
- // view -> parent
42
- g.addDirectedEdge(view.id, view.extends)
43
- }
44
-
45
- const sorted = topologicalSort(g).reverse()
46
- return sorted.reduce((acc, id) => {
47
- const view = g.getNodeAttribute(id, 'view')
48
- if (!isExtendsElementView(view)) {
49
- acc[view.id] = view
50
- return acc
51
- }
52
-
53
- const extendsFrom = acc[view.extends]
54
- if (!extendsFrom || !isElementView(extendsFrom)) {
55
- return acc
56
- }
57
-
58
- const tags = unique([
59
- ...(extendsFrom.tags ?? []),
60
- ...(view.tags ?? []),
61
- ]) as aux.Tags<A>
62
-
63
- const links = [
64
- ...(extendsFrom.links ?? []),
65
- ...(view.links ?? []),
66
- ]
67
-
68
- acc[view.id] = {
69
- ...extendsFrom,
70
- ...view,
71
- title: view.title ?? extendsFrom.title ?? null,
72
- description: view.description ?? extendsFrom.description ?? null,
73
- tags,
74
- links: isNonEmptyArray(links) ? links : null,
75
- rules: [...extendsFrom.rules, ...view.rules],
76
- }
77
- return acc
78
- }, {} as Record<string, LikeC4View<A>>) as V
79
-
80
- // forEachNodeInTopologicalOrder(g, (_id, { view }) => {
81
-
82
- // })
83
-
84
- // return ordered as V
85
- }
@@ -1,88 +0,0 @@
1
- import { isNullish } from 'remeda'
2
- import {
3
- type AnyAux,
4
- type DynamicViewIncludeRule,
5
- type DynamicViewRule,
6
- type ElementViewPredicate,
7
- type ElementViewRule,
8
- type ModelGlobals,
9
- type ParsedDynamicView,
10
- type ParsedElementView,
11
- type ViewRuleGlobalPredicateRef,
12
- type ViewRuleGlobalStyle,
13
- isDynamicView,
14
- isElementView,
15
- isViewRuleGlobalPredicateRef,
16
- isViewRuleGlobalStyle,
17
- } from '../../types'
18
- import { nonexhaustive } from '../../utils'
19
-
20
- export function resolveGlobalRules<A extends AnyAux>(
21
- view: ParsedElementView<A> | ParsedDynamicView<A>,
22
- globals: ModelGlobals<A>,
23
- ) {
24
- if (isElementView(view)) {
25
- return {
26
- ...view,
27
- rules: resolveGlobalRulesInElementView(view.rules, globals),
28
- }
29
- }
30
-
31
- if (isDynamicView(view)) {
32
- return {
33
- ...view,
34
- rules: resolveGlobalRulesInDynamicView(view.rules, globals),
35
- }
36
- }
37
- nonexhaustive(view)
38
- }
39
-
40
- type ViewRuleGlobal = ViewRuleGlobalPredicateRef | ViewRuleGlobalStyle
41
-
42
- export function resolveGlobalRulesInElementView<M extends AnyAux>(
43
- rules: ElementViewRule<M>[],
44
- globals: ModelGlobals<M>,
45
- ): Array<Exclude<ElementViewRule<M>, ViewRuleGlobal>> {
46
- return rules.reduce((acc, rule) => {
47
- if (isViewRuleGlobalPredicateRef(rule)) {
48
- const globalPredicates = globals.predicates[rule.predicateId]
49
- if (isNullish(globalPredicates)) {
50
- return acc
51
- }
52
- return acc.concat(globalPredicates as ElementViewPredicate<M>[])
53
- }
54
- if (isViewRuleGlobalStyle(rule)) {
55
- const globalStyles = globals.styles[rule.styleId]
56
- if (isNullish(globalStyles)) {
57
- return acc
58
- }
59
- return acc.concat(globalStyles)
60
- }
61
- acc.push(rule)
62
- return acc
63
- }, [] as Array<Exclude<ElementViewRule<M>, ViewRuleGlobal>>)
64
- }
65
-
66
- export function resolveGlobalRulesInDynamicView<M extends AnyAux>(
67
- rules: DynamicViewRule<M>[],
68
- globals: ModelGlobals<M>,
69
- ): Array<Exclude<DynamicViewRule<M>, ViewRuleGlobal>> {
70
- return rules.reduce((acc, rule) => {
71
- if (isViewRuleGlobalPredicateRef(rule)) {
72
- const globalPredicates = globals.dynamicPredicates[rule.predicateId]
73
- if (isNullish(globalPredicates)) {
74
- return acc
75
- }
76
- return acc.concat(globalPredicates as DynamicViewIncludeRule<M>[])
77
- }
78
- if (isViewRuleGlobalStyle(rule)) {
79
- const globalStyles = globals.styles[rule.styleId]
80
- if (isNullish(globalStyles)) {
81
- return acc
82
- }
83
- return acc.concat(globalStyles)
84
- }
85
- acc.push(rule)
86
- return acc
87
- }, [] as Array<Exclude<DynamicViewRule<M>, ViewRuleGlobal>>)
88
- }
@@ -1,256 +0,0 @@
1
- import Graph from 'graphology'
2
- import { topologicalSort as topsort } from 'graphology-dag/topological-sort'
3
- import willCreateCycle from 'graphology-dag/will-create-cycle'
4
- import { forEach, map, partition, pipe, takeWhile } from 'remeda'
5
- import type { AnyAux, ComputedEdge, ComputedNode, NodeId } from '../../types'
6
- import { invariant, nonNullable } from '../../utils'
7
- import { ancestorsOfNode } from './ancestorsOfNode'
8
-
9
- /**
10
- * Keeps initial order of the elements, but ensures parents are placed before children
11
- */
12
- function ensureParentsFirst<T extends { id: string; parent: string | null }>(
13
- array: ReadonlyArray<T>,
14
- ): Array<T> {
15
- const result = [] as T[]
16
- const items = [...array]
17
- let item
18
- while ((item = items.shift())) {
19
- let parent = item.parent
20
- if (parent) {
21
- const ancestors = [] as T[]
22
- while (parent) {
23
- const parentIndx = items.findIndex(i => i.id === parent)
24
- if (parentIndx < 0) {
25
- break
26
- }
27
- const [parentItem] = items.splice(parentIndx, 1)
28
- if (!parentItem) {
29
- throw new Error('Invalid state, should not happen')
30
- }
31
- ancestors.unshift(parentItem)
32
- parent = parentItem.parent
33
- }
34
- result.push(...ancestors)
35
- }
36
- result.push(item)
37
- }
38
- return result as Array<T>
39
- }
40
-
41
- /**
42
- * Side effect, mutates node.children field to preserve same order as in the input
43
- */
44
- function updateChildren<A extends AnyAux = AnyAux>(nodes: ComputedNode<A>[]): ComputedNode<A>[] {
45
- nodes.forEach(parent => {
46
- if (parent.children.length > 0) {
47
- parent.children = nodes.reduce((acc, n) => {
48
- if (n.parent === parent.id) {
49
- acc.push(n.id)
50
- }
51
- return acc
52
- }, [] as NodeId[])
53
- }
54
- })
55
- return nodes
56
- }
57
-
58
- type TopologicalSortParam<A extends AnyAux> = {
59
- nodes: ReadonlyMap<string, ComputedNode<A>>
60
- edges: Iterable<ComputedEdge<A>>
61
- }
62
- export function topologicalSort<A extends AnyAux>(
63
- param: TopologicalSortParam<A>,
64
- ): {
65
- nodes: ComputedNode<A>[]
66
- edges: ComputedEdge<A>[]
67
- } {
68
- let nodes = ensureParentsFirst([...param.nodes.values()])
69
- let edges = [...param.edges]
70
- if (nodes.length < 2 || edges.length === 0) {
71
- return {
72
- nodes,
73
- edges,
74
- }
75
- }
76
-
77
- const getNode = (id: string) => nonNullable(param.nodes.get(id))
78
- // const nodeLevel = (id: string) => getNode(id).level + 1
79
- //
80
-
81
- const g = new Graph({
82
- multi: true,
83
- allowSelfLoops: true,
84
- type: 'directed',
85
- })
86
-
87
- const enrichedEdges = pipe(
88
- edges,
89
- map((edge, __dirname) => {
90
- const source = getNode(edge.source),
91
- target = getNode(edge.target),
92
- parent = edge.parent ? getNode(edge.parent) : null
93
- return ({
94
- id: edge.id,
95
- edge,
96
- parent,
97
- source,
98
- target,
99
- })
100
- }),
101
- // sortBy(
102
- // [prop('sourceIndex'), 'asc'],
103
- // // [prop('sourceInCount'), 'asc'],
104
- // // [prop('sourceLevel'), 'asc'],
105
- // ),
106
- )
107
-
108
- const [edgesBetweenLeafs, edgesWithCompounds] = partition(
109
- enrichedEdges,
110
- ({ source, target }) => source.children.length === 0 && target.children.length === 0,
111
- )
112
-
113
- // edgesBetweenLeafs.sort((a, b) => {
114
- // if (a.source === b.source) {
115
- // return 0
116
- // }
117
- // if (a.source.level === 0 && b.source.level === 0) {
118
- // return 0
119
- // }
120
- // if (isSameHierarchy(a.source, b.target) || isSameHierarchy(a.target, b.source)) {
121
- // return edges.indexOf(a.edge) - edges.indexOf(b.edge)
122
- // }
123
- // const aLevel = a.parent ? a.parent.level + 1 - a.source.level : a.source.level
124
- // const bLevel = b.parent ? b.parent.level + 1 - b.source.level : b.source.level
125
- // return aLevel - bLevel
126
- // // if (a.source.level === 0 && b.source.level === 0) {
127
-
128
- // // // if (a.source.depth)
129
- // // return nodes.indexOf(a.target) - nodes.indexOf(b.target)
130
- // // }
131
- // // if (a.source.level === 0 && b.source.level > 0) {
132
- // // return -1
133
- // // }
134
- // // if (a.parent && b.parent && a.parent !== b.parent) {
135
- // // if (a.parent.level !== b.parent.level) {
136
- // // return b.parent.level - a.parent.level
137
- // // } else {
138
- // // return nodes.indexOf(a.parent) - nodes.indexOf(b.parent)
139
- // // }
140
- // // }
141
- // // return Math.min(nodes.indexOf(a.source), nodes.indexOf(a.target)) - Math.min(nodes.indexOf(b.source), nodes.indexOf(b.target))
142
- // })
143
- const sortedEdges = [] as ComputedEdge<A>[]
144
-
145
- const addEdgeToGraph = (edge: ComputedEdge<A>) => {
146
- g.mergeNode(edge.source)
147
- g.mergeNode(edge.target)
148
- sortedEdges.push(edge)
149
- if (!willCreateCycle(g, edge.source, edge.target)) {
150
- g.mergeDirectedEdge(edge.source, edge.target)
151
- }
152
- }
153
-
154
- for (const { edge, source, target } of edgesBetweenLeafs) {
155
- addEdgeToGraph(edge)
156
- // Strengthen the graph by adding edges to parents
157
- if (target.parent && target.parent !== edge.parent) {
158
- pipe(
159
- ancestorsOfNode(target, param.nodes),
160
- takeWhile(ancestor => ancestor.inEdges.includes(edge.id)),
161
- forEach(ancestor => {
162
- g.mergeNode(ancestor.id)
163
- if (!willCreateCycle(g, edge.source, ancestor.id)) {
164
- g.mergeDirectedEdge(edge.source, ancestor.id)
165
- }
166
- if (!willCreateCycle(g, ancestor.id, edge.target)) {
167
- g.mergeDirectedEdge(ancestor.id, edge.target)
168
- }
169
- }),
170
- )
171
- }
172
- if (source.parent) {
173
- const sourceParent = getNode(source.parent)
174
- g.mergeNode(sourceParent.id)
175
- if (!willCreateCycle(g, sourceParent.id, source.id)) {
176
- g.mergeDirectedEdge(sourceParent.id, source.id)
177
- }
178
- if (target.parent && target.parent !== source.parent) {
179
- if (!willCreateCycle(g, sourceParent.id, target.parent)) {
180
- g.mergeDirectedEdge(sourceParent.id, target.parent)
181
- }
182
- }
183
- }
184
-
185
- // addEdgeToGraph(edge)
186
- }
187
- for (const { edge } of edgesWithCompounds) {
188
- addEdgeToGraph(edge)
189
- }
190
-
191
- invariant(sortedEdges.length === edges.length, 'Not all edges were added to the graph')
192
-
193
- // for (const compound of nodes) {
194
- // if (compound.children.length === 0 || compound.inEdges.length === 0) {
195
- // continue
196
- // }
197
- // // g.mergeNode(compound.id)
198
- // for (const inEdge of compound.inEdges) {
199
- // const { edge, source } = getEdge(inEdge)
200
- // // ignore if this edge is coming from compound node
201
- // if (source.children.length > 0) {
202
- // continue
203
- // }
204
- // // if this edge is coming to the compound node directly
205
- // if (edge.target === compound.id) {
206
- // // for (const child of compound.children) {
207
- // // // g.mergeNode(child)
208
- // // if (!willCreateCycle(g, edge.source, child)) {
209
- // // g.mergeDirectedEdge(edge.source, child)
210
- // // }
211
- // // }
212
- // } else {
213
- // if (!willCreateCycle(g, edge.source, compound.id)) {
214
- // g.mergeDirectedEdge(edge.source, compound.id)
215
- // }
216
- // if (!willCreateCycle(g, compound.id, edge.target)) {
217
- // g.mergeDirectedEdge(compound.id, edge.target)
218
- // }
219
- // }
220
- // }
221
- // }
222
-
223
- const sortedIds = topsort(g)
224
- let sorted = [] as ComputedNode<A>[]
225
- let unsorted = nodes.slice()
226
- for (const sortedId of sortedIds) {
227
- const indx = unsorted.findIndex(n => n.id === sortedId)
228
- invariant(indx >= 0, `Node "${sortedId}" not found`)
229
- sorted.push(...unsorted.splice(indx, 1))
230
- }
231
- // Merge unsorted nodes, keeping their initial order
232
- if (unsorted.length > 0 && sorted.length > 0) {
233
- sorted = sorted.flatMap(node => {
234
- if (unsorted.length === 0) {
235
- return node
236
- }
237
- const wereBefore = nodes
238
- .slice(0, nodes.indexOf(node))
239
- .filter(n => unsorted.includes(n))
240
- if (wereBefore.length > 0) {
241
- unsorted = unsorted.filter(n => !wereBefore.includes(n))
242
- return [...wereBefore, node]
243
- }
244
-
245
- return node
246
- })
247
- }
248
- // Add remaining unsorted nodes
249
- sorted.push(...unsorted)
250
- return {
251
- nodes: updateChildren(
252
- ensureParentsFirst(sorted),
253
- ),
254
- edges: sortedEdges,
255
- }
256
- }
@@ -1,45 +0,0 @@
1
- import { isTruthy, map, mapToObj, pick, pipe } from 'remeda'
2
- import type { SetOptional } from 'type-fest'
3
- import type { ComputedView } from '../../types'
4
- import { objectHash } from '../../utils'
5
-
6
- export function calcViewLayoutHash<V extends ComputedView>(view: SetOptional<V, 'hash'>): V {
7
- const tohash = {
8
- id: view.id,
9
- __: view._type ?? 'element',
10
- autoLayout: view.autoLayout,
11
- nodes: pipe(
12
- view.nodes,
13
- map(n => ({
14
- id: n.id,
15
- icon: isTruthy(n.icon) ? 'Y' : 'N',
16
- title: n.title,
17
- description: n.description?.md ?? n.description?.txt ?? null,
18
- technology: n.technology ?? null,
19
- shape: n.shape,
20
- size: n.style.size ?? null,
21
- textSize: n.style.textSize ?? null,
22
- padding: n.style.padding ?? null,
23
- children: n.children,
24
- })),
25
- mapToObj(({ id, ...node }) => [id, node]),
26
- ),
27
- edges: pipe(
28
- view.edges,
29
- map(e => ({
30
- source: e.source,
31
- target: e.target,
32
- label: e.label,
33
- description: e.description?.md ?? e.description?.txt ?? null,
34
- technology: e.technology ?? null,
35
- dir: e.dir,
36
- head: e.head,
37
- tail: e.tail,
38
- line: e.line,
39
- })),
40
- mapToObj(({ source, target, ...edge }) => [`${source}:${target}`, edge]),
41
- ),
42
- }
43
- view.hash = objectHash(tohash)
44
- return view as unknown as V
45
- }