@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,72 +0,0 @@
1
- export { ElementModel } from './ElementModel'
2
- export { type AnyLikeC4Model, LikeC4Model } from './LikeC4Model'
3
- export { type AnyRelationshipModel, RelationshipModel } from './RelationModel'
4
-
5
- export {
6
- Connection,
7
- ConnectionModel,
8
- deployment as deploymentConnection,
9
- DeploymentConnectionModel,
10
- differenceConnections,
11
- findAscendingConnections,
12
- findDeepestNestedConnection,
13
- findDescendantConnections,
14
- hasSameSource,
15
- hasSameSourceTarget,
16
- hasSameTarget,
17
- isAnyInOut,
18
- isIncoming,
19
- isNestedConnection,
20
- isOutgoing,
21
- mergeConnections,
22
- model as modelConnection,
23
- sortConnectionsByBoundaryHierarchy,
24
- sortDeepestFirst,
25
- } from './connection'
26
-
27
- export {
28
- DeployedInstanceModel,
29
- type DeploymentElementModel,
30
- DeploymentNodeModel,
31
- type DeploymentRelationEndpoint,
32
- DeploymentRelationModel,
33
- RelationshipsAccum,
34
- } from './DeploymentElementModel'
35
- export { LikeC4DeploymentModel } from './DeploymentModel'
36
-
37
- export { EdgeModel } from './view/EdgeModel'
38
- export { LikeC4ViewModel } from './view/LikeC4ViewModel'
39
- export { LikeC4ViewsFolder } from './view/LikeC4ViewsFolder'
40
- export { NodeModel } from './view/NodeModel'
41
-
42
- export type {
43
- DeploymentOrFqn,
44
- EdgeOrId,
45
- ElementOrFqn,
46
- IncomingFilter,
47
- NodeOrId,
48
- OutgoingFilter,
49
- WithMetadata,
50
- WithTags,
51
- } from './types'
52
-
53
- export * from './guards'
54
-
55
- export type {
56
- Any,
57
- AnyAux,
58
- Aux,
59
- aux,
60
- AuxFromDump,
61
- AuxFromLikeC4ModelData,
62
- SpecAux,
63
- } from '../types'
64
-
65
- export { RichText, type RichTextEmpty, type RichTextOrEmpty } from '../types'
66
-
67
- export {
68
- extractViewTitleFromPath,
69
- getViewFolderPath,
70
- normalizeViewPath,
71
- VIEW_FOLDERS_SEPARATOR,
72
- } from './utils'
@@ -1,67 +0,0 @@
1
- import type { Tagged } from 'type-fest'
2
- import type {
3
- AnyAux,
4
- ComputedLikeC4ModelData,
5
- ComputedView,
6
- DiagramView,
7
- LayoutedLikeC4ModelData,
8
- ParsedLikeC4ModelData,
9
- scalar,
10
- ViewType,
11
- ViewWithType,
12
- } from '../types'
13
- import type * as aux from '../types/_aux'
14
- import type { LikeC4ViewModel } from './view/LikeC4ViewModel'
15
-
16
- export type IncomingFilter = 'all' | 'direct' | 'to-descendants'
17
- export type OutgoingFilter = 'all' | 'direct' | 'from-descendants'
18
-
19
- export type AnyScalar<V extends string> =
20
- | Tagged<V, 'Fqn'>
21
- | Tagged<V, 'DeploymentFqn'>
22
- | Tagged<V, 'ViewId'>
23
- | Tagged<V, 'NodeId'>
24
- | Tagged<V, 'EdgeId'>
25
- | Tagged<V, 'RelationId'>
26
-
27
- export type ElementOrFqn<A extends AnyAux> = aux.ElementId<A> | { id: aux.Fqn<A> }
28
-
29
- export type DeploymentOrFqn<A extends AnyAux> = aux.DeploymentId<A> | { id: aux.DeploymentFqn<A> }
30
-
31
- export type ViewOrId<A extends AnyAux> = aux.ViewId<A> | { id: aux.StrictViewId<A> }
32
-
33
- export type NodeOrId = string | { id: scalar.NodeId }
34
- export type EdgeOrId = string | { id: scalar.EdgeId }
35
- export type RelationOrId = string | { id: scalar.RelationId }
36
-
37
- export type $View<A extends AnyAux> = {
38
- parsed: never
39
- computed: ComputedView<A>
40
- layouted: DiagramView<A>
41
- }[aux.Stage<A>]
42
-
43
- export type $ViewWithType<A extends AnyAux, V extends ViewType> = ViewWithType<$View<A>, V>
44
-
45
- export type $ViewModel<A extends AnyAux> = {
46
- parsed: never
47
- computed: LikeC4ViewModel<A>
48
- layouted: LikeC4ViewModel<A>
49
- }[aux.Stage<A>]
50
-
51
- // export type $ModelData<A> = A extends infer T extends Any ? {
52
- export type $ModelData<A extends AnyAux> = {
53
- parsed: ParsedLikeC4ModelData<A>
54
- computed: ComputedLikeC4ModelData<A>
55
- layouted: LayoutedLikeC4ModelData<A>
56
- }[aux.Stage<A>]
57
-
58
- export interface WithTags<A extends AnyAux> {
59
- get tags(): aux.Tags<A>
60
- isTagged(tag: aux.LooseTag<A>): boolean
61
- }
62
-
63
- export interface WithMetadata<A extends AnyAux> {
64
- hasMetadata(): boolean
65
- getMetadata(): aux.Metadata<A>
66
- getMetadata(field: aux.MetadataKey<A>): string | undefined
67
- }
@@ -1,66 +0,0 @@
1
- import { hasAtLeast } from 'remeda'
2
- import type { NonEmptyArray } from '../types'
3
- import { invariant } from '../utils'
4
- import type { AnyScalar } from './types'
5
-
6
- /**
7
- * Utility function to extract `id` from the given element.
8
- */
9
- export const getId = <Id extends string, Scalar extends AnyScalar<Id>>(element: Id | { id: Scalar }): Scalar => {
10
- return typeof element === 'string' ? element as unknown as Scalar : element.id
11
- }
12
-
13
- export const VIEW_FOLDERS_SEPARATOR = '/'
14
-
15
- const splitViewTitle = (title: string): NonEmptyArray<string> => {
16
- invariant(!title.includes('\n'), 'View title cannot contain newlines')
17
- if (title.includes(VIEW_FOLDERS_SEPARATOR)) {
18
- const segments = title
19
- .split(VIEW_FOLDERS_SEPARATOR)
20
- .map(s => s.trim())
21
- .filter(s => s.length > 0)
22
- if (hasAtLeast(segments, 1)) {
23
- return segments
24
- }
25
- return ['']
26
- }
27
- return [title.trim()]
28
- }
29
-
30
- /**
31
- * Normalizes view path by removing spaces from segments, removing empty segments,
32
- * and removing leading/trailing slashes
33
- * @example
34
- * normalizeViewPath('One / Tw o / Thre e') === 'One/Tw o/Thre e'
35
- */
36
- export const normalizeViewPath = (title: string): string => {
37
- return splitViewTitle(title).join(VIEW_FOLDERS_SEPARATOR)
38
- }
39
-
40
- /**
41
- * Returns view group path if it is used as a path
42
- * Returns empty string if it is not a path
43
- * @example
44
- * getViewFolderPath('One / Tw o / Thre e') === 'One/Tw o'
45
- * getViewFolderPath('One') === ''
46
- */
47
- export const getViewFolderPath = (title: string): string | null => {
48
- const segments = splitViewTitle(title)
49
- if (!hasAtLeast(segments, 2)) {
50
- return null
51
- }
52
- return segments.slice(0, -1).join(VIEW_FOLDERS_SEPARATOR)
53
- }
54
-
55
- /**
56
- * Returns view title if it is used as a path
57
- * @example
58
- * getViewTitleFromPath('One / Tw o / Thre e') === 'Thre e'
59
- * getViewTitleFromPath('One') === 'One'
60
- */
61
- export const extractViewTitleFromPath = (title: string): string => {
62
- if (!title.includes(VIEW_FOLDERS_SEPARATOR)) {
63
- return title.trim()
64
- }
65
- return splitViewTitle(title).pop() ?? title
66
- }
@@ -1,121 +0,0 @@
1
- import {
2
- type Any,
3
- type aux,
4
- type Color,
5
- type ComputedEdge,
6
- type DiagramEdge,
7
- type IteratorLike,
8
- type RelationshipLineType,
9
- type RichTextOrEmpty,
10
- type scalar,
11
- type StepEdgeId,
12
- extractStep,
13
- isStepEdgeId,
14
- RichText,
15
- } from '../../types'
16
- import type { DeploymentRelationModel } from '../DeploymentElementModel'
17
- import type { RelationshipModel } from '../RelationModel'
18
- import type { $View, WithTags } from '../types'
19
- import type { LikeC4ViewModel } from './LikeC4ViewModel'
20
- import type { NodeModel } from './NodeModel'
21
-
22
- export type EdgesIterator<A extends Any, V extends $View<A>> = IteratorLike<EdgeModel<A, V>>
23
-
24
- export class EdgeModel<A extends Any = Any, View extends $View<A> = $View<A>> implements WithTags<A> {
25
- #edge: ComputedEdge<A> | DiagramEdge<A>
26
- constructor(
27
- public readonly view: LikeC4ViewModel<A, View>,
28
- public readonly $edge: View['edges'][number],
29
- public readonly source: NodeModel<A, View>,
30
- public readonly target: NodeModel<A, View>,
31
- ) {
32
- this.#edge = $edge
33
- }
34
-
35
- get id(): scalar.EdgeId {
36
- return this.#edge.id
37
- }
38
-
39
- get parent(): NodeModel<A, View> | null {
40
- return this.#edge.parent ? this.view.node(this.#edge.parent) : null
41
- }
42
-
43
- get label(): string | null {
44
- return this.#edge.label ?? null
45
- }
46
-
47
- get description(): RichTextOrEmpty {
48
- return RichText.memoize(this, 'description', this.#edge.description)
49
- }
50
-
51
- get technology(): string | null {
52
- return this.#edge.technology ?? null
53
- }
54
-
55
- public hasParent(): this is EdgeModel.WithParent<A, View> {
56
- return this.#edge.parent !== null
57
- }
58
-
59
- get tags(): aux.Tags<A> {
60
- return this.#edge.tags ?? []
61
- }
62
-
63
- get stepNumber(): number | null {
64
- return this.isStep() ? extractStep(this.id) : null
65
- }
66
-
67
- get navigateTo(): LikeC4ViewModel<A> | null {
68
- return this.#edge.navigateTo ? this.view.$model.view(this.#edge.navigateTo) : null
69
- }
70
-
71
- get color(): Color {
72
- return this.#edge.color ?? 'gray'
73
- }
74
-
75
- get line(): RelationshipLineType {
76
- return this.#edge.line ?? 'dashed'
77
- }
78
-
79
- public isStep(): this is EdgeModel.StepEdge<A, View> {
80
- return isStepEdgeId(this.id)
81
- }
82
-
83
- public relationships(type: 'model'): IteratorLike<RelationshipModel<A>>
84
- public relationships(type: 'deployment'): IteratorLike<DeploymentRelationModel<A>>
85
- public relationships(type?: 'model' | 'deployment'): IteratorLike<RelationshipModel<A> | DeploymentRelationModel<A>>
86
- public *relationships(
87
- type: 'model' | 'deployment' | undefined,
88
- ): IteratorLike<RelationshipModel<A> | DeploymentRelationModel<A>> {
89
- for (const id of this.#edge.relations) {
90
- // if type is provided, then we need to filter relationships
91
- if (type) {
92
- const rel = this.view.$model.findRelationship(id, type)
93
- if (rel) {
94
- yield rel
95
- }
96
- } else {
97
- yield this.view.$model.relationship(id)
98
- }
99
- }
100
- return
101
- }
102
-
103
- public includesRelation(rel: aux.RelationId | { id: aux.RelationId }): boolean {
104
- const id = typeof rel === 'string' ? rel : rel.id
105
- return this.#edge.relations.includes(id)
106
- }
107
-
108
- public isTagged(tag: aux.LooseTag<A>): boolean {
109
- return this.tags.includes(tag as aux.Tag<A>)
110
- }
111
- }
112
-
113
- namespace EdgeModel {
114
- export interface StepEdge<A extends Any, V extends $View<A>> extends EdgeModel<A, V> {
115
- id: StepEdgeId
116
- stepNumber: number
117
- }
118
- export interface WithParent<A extends Any, V extends $View<A>> extends EdgeModel<A, V> {
119
- parent: NodeModel<A, V>
120
- }
121
- }
@@ -1,361 +0,0 @@
1
- import { isTruthy } from 'remeda'
2
- import type {
3
- Any,
4
- AnyView,
5
- DynamicViewDisplayVariant,
6
- IteratorLike,
7
- Link,
8
- scalar,
9
- ViewWithType,
10
- } from '../../types'
11
- import { type RichTextOrEmpty, _stage, _type, RichText } from '../../types'
12
- import type * as aux from '../../types/_aux'
13
- import { DefaultMap, ifind, memoizeProp, nonNullable } from '../../utils'
14
- import type { ElementModel } from '../ElementModel'
15
- import type { LikeC4Model } from '../LikeC4Model'
16
- import {
17
- type $View,
18
- type EdgeOrId,
19
- type NodeOrId,
20
- type WithTags,
21
- } from '../types'
22
- import { extractViewTitleFromPath, getId, normalizeViewPath } from '../utils'
23
- import { type EdgesIterator, EdgeModel } from './EdgeModel'
24
- import type { LikeC4ViewsFolder } from './LikeC4ViewsFolder'
25
- import { type NodesIterator, NodeModel } from './NodeModel'
26
-
27
- export type ViewsIterator<A extends Any, V extends $View<A> = $View<A>> = IteratorLike<LikeC4ViewModel<A, V>>
28
-
29
- export type InferViewType<V> = V extends AnyView<any> ? V[_type] : never
30
-
31
- export class LikeC4ViewModel<A extends Any = Any, V extends $View<A> = $View<A>> implements WithTags<A> {
32
- /**
33
- * Don't use in runtime, only for type inference
34
- */
35
- readonly Aux!: A
36
-
37
- readonly #rootnodes = new Set<NodeModel<A, V>>()
38
- readonly #nodes = new Map<scalar.NodeId, NodeModel<A, V>>()
39
- readonly #edges = new Map<scalar.EdgeId, EdgeModel<A, V>>()
40
- readonly #includeElements = new Set<aux.Fqn<A>>()
41
- readonly #includeDeployments = new Set<aux.DeploymentFqn<A>>()
42
- readonly #includeRelations = new Set<scalar.RelationId>()
43
- readonly #allTags = new DefaultMap((_key: aux.Tag<A>) => new Set<NodeModel<A, V> | EdgeModel<A, V>>())
44
-
45
- public readonly $view: V
46
- public readonly $model: LikeC4Model<A>
47
-
48
- public readonly title: string | null
49
-
50
- /**
51
- * View folder this view belongs to.
52
- * If view is top-level, this is the root folder.
53
- */
54
- public readonly folder: LikeC4ViewsFolder<A>
55
- /**
56
- * Path to this view, processed by {@link normalizeViewPath}
57
- *
58
- * @example
59
- * "Group 1/Group 2/View"
60
- */
61
- public readonly viewPath: string
62
-
63
- constructor(
64
- model: LikeC4Model<A>,
65
- view: V,
66
- folder: LikeC4ViewsFolder<A>,
67
- ) {
68
- this.$model = model
69
- this.$view = view
70
- this.folder = folder
71
- for (const node of view.nodes) {
72
- const el = new NodeModel<A, V>(this, Object.freeze(node))
73
- this.#nodes.set(node.id, el)
74
- if (!node.parent) {
75
- this.#rootnodes.add(el)
76
- }
77
- if (el.hasDeployment()) {
78
- this.#includeDeployments.add(el.deployment.id)
79
- }
80
- if (el.hasElement()) {
81
- this.#includeElements.add(el.element.id)
82
- }
83
- for (const tag of el.tags) {
84
- this.#allTags.get(tag).add(el)
85
- }
86
- }
87
-
88
- for (const edge of view.edges) {
89
- const edgeModel = new EdgeModel(
90
- this,
91
- Object.freeze(edge),
92
- this.node(edge.source),
93
- this.node(edge.target),
94
- )
95
- for (const tag of edgeModel.tags) {
96
- this.#allTags.get(tag).add(edgeModel)
97
- }
98
- for (const rel of edge.relations) {
99
- this.#includeRelations.add(rel)
100
- }
101
- this.#edges.set(edge.id, edgeModel)
102
- }
103
-
104
- this.title = this.$view.title ? extractViewTitleFromPath(this.$view.title) : null
105
- this.viewPath = this.$view.title ? normalizeViewPath(this.$view.title) : this.$view.id
106
- }
107
-
108
- get _type(): V[_type] {
109
- return this.$view[_type]
110
- }
111
-
112
- get id(): aux.StrictViewId<A> {
113
- return this.$view.id
114
- }
115
-
116
- /**
117
- * Returns title if defined, otherwise returns title of the element it is based on, otherwise returns its {@link id}
118
- */
119
- get titleOrId(): string {
120
- return this.title ?? this.viewOf?.title ?? this.id
121
- }
122
-
123
- /**
124
- * Returns title if defined, otherwise returns `Untitled`.
125
- */
126
- get titleOrUntitled(): string {
127
- return this.title ?? 'Untitled'
128
- }
129
-
130
- /**
131
- * Returns path to this view as an array of groups and this view as the last element
132
- * If view is top-level, returns only this view.
133
- *
134
- * @example
135
- * viewPath = "Group 1/Group 2/View"
136
- *
137
- * breadcrumbs = [
138
- * "Group 1", // folder
139
- * "Group 1/Group 2", // folder
140
- * "Group 1/Group 2/View" // view
141
- * ]
142
- */
143
- get breadcrumbs(): [...LikeC4ViewsFolder<A>[], this] {
144
- return memoizeProp(this, 'breadcrumbs', () => {
145
- if (!this.folder.isRoot) {
146
- return [...this.folder.breadcrumbs, this]
147
- }
148
- return [this]
149
- })
150
- }
151
-
152
- get description(): RichTextOrEmpty {
153
- return RichText.memoize(this, 'description', this.$view.description)
154
- }
155
-
156
- get tags(): aux.Tags<A> {
157
- return this.$view.tags ?? []
158
- }
159
-
160
- get links(): ReadonlyArray<Link> {
161
- return this.$view.links ?? []
162
- }
163
-
164
- get viewOf(): ElementModel<A> | null {
165
- if (this.isElementView()) {
166
- const viewOf = this.$view.viewOf
167
- return viewOf ? this.$model.element(viewOf) : null
168
- }
169
- return null
170
- }
171
-
172
- /**
173
- * Available for dynamic views only
174
- * throws error if view is not dynamic
175
- */
176
- get mode(): DynamicViewDisplayVariant {
177
- if (this.isDynamicView()) {
178
- return this.$view.variant ?? 'diagram'
179
- }
180
- throw new Error('View is not dynamic')
181
- }
182
-
183
- /**
184
- * All tags from nodes and edges.
185
- */
186
- get includedTags(): aux.Tags<A> {
187
- return [...this.#allTags.keys()] as unknown as aux.Tags<A>
188
- }
189
-
190
- public roots(): NodesIterator<A, V> {
191
- return this.#rootnodes.values()
192
- }
193
-
194
- /**
195
- * Iterate over all nodes that have children.
196
- */
197
- public *compounds(): NodesIterator<A, V> {
198
- for (const node of this.#nodes.values()) {
199
- if (node.hasChildren()) {
200
- yield node
201
- }
202
- }
203
- return
204
- }
205
-
206
- /**
207
- * Get node by id.
208
- * @throws Error if node is not found.
209
- */
210
- public node(node: NodeOrId): NodeModel<A, V> {
211
- const nodeId = getId(node)
212
- return nonNullable(this.#nodes.get(nodeId), `Node ${nodeId} not found in view ${this.$view.id}`)
213
- }
214
-
215
- /**
216
- * Find node by id.
217
- */
218
- public findNode(node: NodeOrId): NodeModel<A, V> | null {
219
- return this.#nodes.get(getId(node)) ?? null
220
- }
221
-
222
- public findNodeWithElement(element: aux.LooseElementId<A> | { id: aux.Fqn<A> }): NodeModel.WithElement<A, V> | null {
223
- const id = getId(element)
224
- return ifind(
225
- this.#nodes.values(),
226
- (node): node is NodeModel.WithElement<A, V> => node.hasElement() && node.element.id === id,
227
- ) ?? null
228
- }
229
-
230
- /**
231
- * Iterate over all nodes.
232
- */
233
- public nodes(): NodesIterator<A, V> {
234
- return this.#nodes.values()
235
- }
236
-
237
- /**
238
- * Get edge by id, throws error if edge is not found.
239
- * Use {@link findEdge} if you are not sure if the edge exists.
240
- *
241
- * @param edge Edge or id
242
- * @returns {@link EdgeModel}
243
- */
244
- public edge(edge: EdgeOrId): EdgeModel<A, V> {
245
- const edgeId = getId(edge)
246
- return nonNullable(this.#edges.get(edgeId), `Edge ${edgeId} not found in view ${this.$view.id}`)
247
- }
248
-
249
- /**
250
- * Find edge by id.
251
- * @param edge Edge or id
252
- * @returns {@link EdgeModel} or null if edge is not found
253
- */
254
- public findEdge(edge: EdgeOrId): EdgeModel<A, V> | null {
255
- return this.#edges.get(getId(edge)) ?? null
256
- }
257
-
258
- /**
259
- * Iterate over all edges.
260
- */
261
- public edges(): EdgesIterator<A, V> {
262
- return this.#edges.values()
263
- }
264
-
265
- /**
266
- * Iterate over all edges.
267
- */
268
- public *edgesWithRelation(relation: aux.RelationId): EdgesIterator<A, V> {
269
- for (const edge of this.#edges.values()) {
270
- if (edge.includesRelation(relation)) {
271
- yield edge
272
- }
273
- }
274
- return
275
- }
276
-
277
- /**
278
- * Nodes that have references to elements from logical model.
279
- */
280
- public *elements(): IteratorLike<NodeModel.WithElement<A, V>> {
281
- // return this.#nodes.values().filter(node => node.hasElement())
282
- for (const node of this.#nodes.values()) {
283
- if (node.hasElement()) {
284
- yield node
285
- }
286
- }
287
- return
288
- }
289
-
290
- /**
291
- * Checks if the view has the given tag.
292
- */
293
- public isTagged(tag: aux.LooseTag<A>): boolean {
294
- return this.tags.includes(tag as aux.Tag<A>)
295
- }
296
-
297
- public includesElement(element: aux.LooseElementId<A> | { id: aux.Fqn<A> }): boolean {
298
- return this.#includeElements.has(getId(element))
299
- }
300
-
301
- public includesDeployment(deployment: aux.LooseDeploymentId<A> | { id: aux.DeploymentFqn<A> }): boolean {
302
- return this.#includeDeployments.has(getId(deployment))
303
- }
304
-
305
- public includesRelation(relation: scalar.RelationId | { id: scalar.RelationId }): boolean {
306
- return this.#includeRelations.has(getId(relation))
307
- }
308
-
309
- /**
310
- * Below are type guards.
311
- */
312
- public isComputed(
313
- this: LikeC4ViewModel<any, any>,
314
- ): this is LikeC4ViewModel<aux.toComputed<A>> {
315
- return this.$view[_stage] === 'computed'
316
- }
317
-
318
- public isDiagram(
319
- this: LikeC4ViewModel<any, any>,
320
- ): this is LikeC4ViewModel<aux.toLayouted<A>> {
321
- return this.$view[_stage] === 'layouted'
322
- }
323
-
324
- public isElementView(this: LikeC4ViewModel<any, any>): this is LikeC4ViewModel.ElementView<A, V> {
325
- return this.$view[_type] === 'element'
326
- }
327
-
328
- public isScopedElementView(
329
- this: LikeC4ViewModel<any, any>,
330
- ): this is LikeC4ViewModel.ScopedElementView<A> {
331
- return this.$view[_type] === 'element' && isTruthy(this.$view.viewOf)
332
- }
333
-
334
- public isDeploymentView(this: LikeC4ViewModel<any, any>): this is LikeC4ViewModel.DeploymentView<A, V> {
335
- return this.$view[_type] === 'deployment'
336
- }
337
-
338
- public isDynamicView(this: LikeC4ViewModel<any, any>): this is LikeC4ViewModel.DynamicView<A, V> {
339
- return this.$view[_type] === 'dynamic'
340
- }
341
- }
342
-
343
- export namespace LikeC4ViewModel {
344
- export interface ElementView<A extends Any, V extends $View<A> = $View<A>>
345
- extends LikeC4ViewModel<A, ViewWithType<V, 'element'>>
346
- {
347
- }
348
-
349
- export interface ScopedElementView<A extends Any>
350
- extends LikeC4ViewModel<A, ViewWithType<$View<A>, 'element'> & { viewOf: aux.StrictFqn<A> }>
351
- {
352
- viewOf: ElementModel<A>
353
- }
354
-
355
- export interface DeploymentView<A extends Any, V extends $View<A> = $View<A>>
356
- extends LikeC4ViewModel<A, ViewWithType<V, 'deployment'>>
357
- {
358
- }
359
-
360
- export type DynamicView<A extends Any, V extends $View<A> = $View<A>> = LikeC4ViewModel<A, ViewWithType<V, 'dynamic'>>
361
- }