@eventcatalog/core 5.0.0-beta.9 → 5.0.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 (458) hide show
  1. package/LICENSE +13 -12
  2. package/README.md +5 -5
  3. package/dist/analytics/analytics.cjs +1 -1
  4. package/dist/analytics/analytics.js +2 -2
  5. package/dist/analytics/log-build.cjs +91 -44
  6. package/dist/analytics/log-build.d.cts +2 -2
  7. package/dist/analytics/log-build.d.ts +2 -2
  8. package/dist/analytics/log-build.js +6 -5
  9. package/dist/analytics/studio-usage.cjs +90 -0
  10. package/dist/analytics/studio-usage.d.cts +5 -0
  11. package/dist/analytics/studio-usage.d.ts +5 -0
  12. package/dist/analytics/studio-usage.js +10 -0
  13. package/dist/catalog-runtime.cjs +1 -1
  14. package/dist/{chunk-ZEY2XUJN.js → chunk-46TBJZC3.js} +1 -1
  15. package/dist/{chunk-RFIXKATC.js → chunk-4G7FSRPN.js} +35 -42
  16. package/dist/{chunk-AWOO63ME.js → chunk-AD7CL772.js} +11 -4
  17. package/dist/chunk-CA6WCQ2T.js +54 -0
  18. package/dist/{chunk-GAHKCOQM.js → chunk-DVHJTQWQ.js} +1 -1
  19. package/dist/{chunk-TZVDMWQX.js → chunk-HFR5OPHV.js} +4 -2
  20. package/dist/{chunk-4CFZUHGG.js → chunk-KTXSCPEK.js} +1 -1
  21. package/dist/{chunk-ENAG6UH7.js → chunk-NKNOXQ62.js} +1 -6
  22. package/dist/{chunk-36RYTYT5.js → chunk-PD7KTSYN.js} +1 -1
  23. package/dist/chunk-S5GWAUG5.js +29 -0
  24. package/dist/{chunk-EUNQJO3J.js → chunk-UWAXRTAJ.js} +1 -1
  25. package/dist/{chunk-JQMYHZWI.js → chunk-YPWK5ITM.js} +15 -7
  26. package/dist/constants.cjs +1 -1
  27. package/dist/constants.js +1 -1
  28. package/dist/docs/api/02-config.md +57 -7
  29. package/dist/docs/development/00-why-eventcatalog.md +11 -11
  30. package/dist/docs/development/01-fundamentals.md +20 -13
  31. package/dist/docs/development/01-getting-started/configuration-overview.md +2 -2
  32. package/dist/docs/development/01-getting-started/installation.md +9 -1
  33. package/dist/docs/development/_getting-started.mdx +1 -1
  34. package/dist/docs/development/ask-your-architecture/01-intro.md +5 -5
  35. package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/01-what-is-eventcatalog-assistant.md +0 -4
  36. package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/02-configuration.md +15 -3
  37. package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/03-bring-your-own-tools.md +0 -3
  38. package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/_category_.json +1 -1
  39. package/dist/docs/development/ask-your-architecture/02-llms.txt.md +1 -1
  40. package/dist/docs/development/ask-your-architecture/{05-skills/01-introduction.md → 03-install-skills.md} +57 -7
  41. package/dist/docs/development/ask-your-architecture/03-mcp-server/_category_.json +1 -1
  42. package/dist/docs/development/ask-your-architecture/03-mcp-server/getting-started.md +86 -33
  43. package/dist/docs/development/ask-your-architecture/03-mcp-server/introduction.md +14 -4
  44. package/dist/docs/development/ask-your-architecture/03-schemas.txt.md +1 -1
  45. package/dist/docs/development/ask-your-architecture/04-agents/_category_.json +1 -1
  46. package/dist/docs/development/authentication/01-introduction.md +2 -23
  47. package/dist/docs/development/authentication/02-enabling-authentication.md +0 -20
  48. package/dist/docs/development/authentication/07-rbac-middleware.md +0 -2
  49. package/dist/docs/development/authentication/providers/03-setting-up-github.md +0 -2
  50. package/dist/docs/development/authentication/providers/03a-setting-up-google.md +0 -2
  51. package/dist/docs/development/authentication/providers/04-setting-up-azure-ad.md +0 -2
  52. package/dist/docs/development/authentication/providers/05-setting-up-okta.md +0 -3
  53. package/dist/docs/development/authentication/providers/06-setting-up-auth0.md +0 -2
  54. package/dist/docs/development/bring-your-own-documentation/01-introduction.md +0 -4
  55. package/dist/docs/development/bring-your-own-documentation/custom-pages/01-introduction.md +0 -3
  56. package/dist/docs/development/bring-your-own-documentation/custom-pages/02-adding-custom-docs.md +0 -17
  57. package/dist/docs/development/bring-your-own-documentation/custom-pages/03-components.md +0 -4
  58. package/dist/docs/development/bring-your-own-documentation/custom-pages/04-owners.md +0 -2
  59. package/dist/docs/development/bring-your-own-documentation/resource-docs/01-introduction.md +1 -3
  60. package/dist/docs/development/bring-your-own-documentation/resource-docs/02-adding-resource-docs.md +1 -4
  61. package/dist/docs/development/bring-your-own-documentation/resource-docs/03-categories.md +0 -2
  62. package/dist/docs/development/bring-your-own-documentation/resource-docs/04-versioning.md +1 -3
  63. package/dist/docs/development/components/components/11-flow.md +17 -0
  64. package/dist/docs/development/components/components/15-nodegraph.md +43 -10
  65. package/dist/docs/development/components/components/18-remote-schema.md +1 -4
  66. package/dist/docs/development/components/custom-components/07-reference.md +14 -0
  67. package/dist/docs/development/customization/02-themes.md +0 -5
  68. package/dist/docs/development/customization/03-search.md +1 -1
  69. package/dist/docs/development/customization/05-custom-pages-and-api-routes/01-introduction.md +0 -2
  70. package/dist/docs/development/customization/05-custom-pages-and-api-routes/04-reference.md +7 -1
  71. package/dist/docs/development/customization/05-resource-sidebar.md +1 -1
  72. package/dist/docs/development/customization/09-embed-eventcatalog.md +20 -25
  73. package/dist/docs/development/deployment/hosting-options.md +7 -2
  74. package/dist/docs/development/developer-tools/eventcatalog-linter/how-to/05-fix-common-problems.md +16 -0
  75. package/dist/docs/development/developer-tools/eventcatalog-linter/reference/03-rules.md +31 -1
  76. package/dist/docs/development/developer-tools/eventcatalog-linter/reference/05-supported-resources.md +1 -1
  77. package/dist/docs/development/governance/architecture-change-detection/01-introduction.md +0 -10
  78. package/dist/docs/development/governance/architecture-change-detection/06-pipeline-gates.md +0 -4
  79. package/dist/docs/development/guides/97-architecture-graph.md +1 -1
  80. package/dist/docs/development/guides/99-adding-analytics.md +0 -7
  81. package/dist/docs/development/guides/domains/03-model-subdomains.md +2 -2
  82. package/dist/docs/development/guides/domains/04-add-resources-to-domains/01-add-systems-to-domains.md +3 -1
  83. package/dist/docs/development/guides/domains/04-add-resources-to-domains/02-add-services-to-domains.md +5 -1
  84. package/dist/docs/development/guides/domains/04-add-resources-to-domains/03-add-messages-to-domains.md +2 -2
  85. package/dist/docs/development/guides/domains/04-add-resources-to-domains/05-add-entities-to-domains.md +1 -1
  86. package/dist/docs/development/guides/domains/04-add-resources-to-domains/06-domain-resources-page.md +40 -0
  87. package/dist/docs/development/guides/domains/06-visualize-domains/01-domain-diagram.md +89 -0
  88. package/dist/docs/development/guides/domains/06-visualize-domains/_category_.json +1 -2
  89. package/dist/docs/development/guides/domains/09-reference.md +4 -4
  90. package/dist/docs/development/guides/owners/automated-teams-and-users/create-your-own-connector.md +0 -2
  91. package/dist/docs/development/guides/owners/automated-teams-and-users/sync-from-github.md +0 -3
  92. package/dist/docs/development/guides/owners/automated-teams-and-users/sync-from-microsoft-entra.md +0 -2
  93. package/dist/docs/development/guides/resources/adrs/03-linking-resources.md +8 -0
  94. package/dist/docs/development/guides/resources/adrs/06-reference.md +4 -4
  95. package/dist/docs/development/guides/resources/agents/11-reference.md +1 -1
  96. package/dist/docs/development/guides/resources/data/04-reference.md +1 -1
  97. package/dist/docs/development/guides/resources/data-products/07-reference.md +1 -1
  98. package/dist/docs/development/guides/resources/entities/05-entity-maps.md +1 -1
  99. package/dist/docs/development/guides/resources/entities/06-reference.md +2 -2
  100. package/dist/docs/development/guides/resources/flows/01-introduction.md +11 -1
  101. package/dist/docs/development/guides/resources/flows/03-model-flow-steps.md +65 -6
  102. package/dist/docs/development/guides/resources/flows/05-explore-flows.md +112 -0
  103. package/dist/docs/development/guides/resources/flows/06-reference.md +25 -4
  104. package/dist/docs/development/guides/resources/messages/01-what-are-messages.md +19 -0
  105. package/dist/docs/development/guides/resources/messages/04-message-channels/01-introduction.md +16 -0
  106. package/dist/docs/development/guides/resources/messages/04-message-channels/05-reference.md +2 -1
  107. package/dist/docs/development/guides/resources/messages/10-reference.md +6 -3
  108. package/dist/docs/development/guides/resources/schemas/04-explore-schemas/01-schema-explorer.md +2 -2
  109. package/dist/docs/development/guides/resources/schemas/04-explore-schemas/02-fields-explorer.md +0 -9
  110. package/dist/docs/development/guides/resources/schemas/05-schema-api.md +0 -3
  111. package/dist/docs/development/guides/resources/schemas/06-schema-mcp.md +11 -3
  112. package/dist/docs/development/guides/resources/services/04-add-resources-to-services/03-add-entities-to-services.md +1 -1
  113. package/dist/docs/development/guides/resources/services/05-resources-page.md +50 -0
  114. package/dist/docs/development/guides/resources/services/08-reference.md +2 -1
  115. package/dist/docs/development/guides/systems/01-introduction.md +1 -1
  116. package/dist/docs/development/guides/systems/02-create-system.md +2 -2
  117. package/dist/docs/development/guides/systems/03-add-resources-to-systems.md +35 -9
  118. package/dist/docs/development/guides/systems/04-model-relationships-and-actors.md +5 -3
  119. package/dist/docs/development/guides/systems/05-system-context-maps.md +39 -22
  120. package/dist/docs/development/guides/systems/06-reference.md +4 -4
  121. package/dist/docs/development/license/01-license-file.md +151 -0
  122. package/dist/docs/development/license/_category_.json +12 -0
  123. package/dist/docs/development/license-keys/_category_.json +3 -3
  124. package/dist/docs/development/license-keys/integrations.md +7 -37
  125. package/dist/docs/development/license-keys/license-validation.md +4 -0
  126. package/dist/docs/development/license-keys/overview.md +5 -1
  127. package/dist/docs/development/license-keys/plans.md +4 -2
  128. package/dist/docs/development/studio/01-introduction.md +60 -0
  129. package/dist/docs/development/studio/02-create-a-canvas.md +103 -0
  130. package/dist/docs/development/studio/03-set-up-persistent-storage.md +59 -0
  131. package/dist/docs/development/studio/04-collaborate-on-a-canvas.md +78 -0
  132. package/dist/docs/development/studio/05-connect-your-agent.md +102 -0
  133. package/dist/docs/development/studio/06-run-studio-in-production.md +54 -0
  134. package/dist/docs/development/studio/07-reference.md +294 -0
  135. package/dist/docs/development/studio/_category_.json +12 -0
  136. package/dist/docs/development/upgrading/v5.md +345 -0
  137. package/dist/docs/federation/00-overview.md +2 -8
  138. package/dist/docs/federation/01-first-federation.md +6 -18
  139. package/dist/docs/federation/explanation/how-it-works.md +0 -4
  140. package/dist/docs/federation/explanation/lockfile-and-cache.md +0 -4
  141. package/dist/docs/federation/explanation/mvp-status-and-feedback.md +0 -4
  142. package/dist/docs/federation/explanation/ownership-and-references.md +0 -4
  143. package/dist/docs/federation/how-to/configure-github-sources.md +6 -5
  144. package/dist/docs/federation/how-to/configure-validation-rules.md +0 -4
  145. package/dist/docs/federation/how-to/run-in-ci.md +2 -9
  146. package/dist/docs/federation/how-to/share-assets-and-components.md +0 -4
  147. package/dist/docs/federation/how-to/use-local-sources.md +0 -4
  148. package/dist/docs/federation/legacy-federation/00-introduction.md +4 -22
  149. package/dist/docs/federation/legacy-federation/01-installation.md +7 -58
  150. package/dist/docs/federation/legacy-federation/02-plugin-configuration.md +3 -21
  151. package/dist/docs/federation/legacy-federation/03-examples.md +3 -5
  152. package/dist/docs/federation/legacy-federation/04-configuration.md +3 -8
  153. package/dist/docs/federation/legacy-federation/05-setup-team-catalog.md +3 -6
  154. package/dist/docs/federation/reference/cli.md +2 -8
  155. package/dist/docs/federation/reference/configuration.md +0 -4
  156. package/dist/docs/federation/reference/diagnostic-rules.md +0 -5
  157. package/dist/docs/federation/reference/generated-output.md +0 -4
  158. package/dist/docs/federation/reference/supported-content.md +0 -4
  159. package/dist/docs/federation/reference/troubleshooting.md +0 -14
  160. package/dist/docs/plugins/02-generators.md +1 -1
  161. package/dist/docs/plugins/amazon-apigateway/00-intro.md +3 -28
  162. package/dist/docs/plugins/amazon-apigateway/01-installation.md +4 -56
  163. package/dist/docs/plugins/amazon-apigateway/02-plugin-configuration.md +1 -6
  164. package/dist/docs/plugins/apicurio/00-intro.md +2 -31
  165. package/dist/docs/plugins/apicurio/01-installation.md +2 -26
  166. package/dist/docs/plugins/apicurio/02-plugin-configuration.md +5 -13
  167. package/dist/docs/plugins/apicurio/03-features.md +1 -3
  168. package/dist/docs/plugins/asyncapi/00-intro.md +2 -28
  169. package/dist/docs/plugins/asyncapi/01-installation.md +3 -54
  170. package/dist/docs/plugins/asyncapi/02-plugin-configuration.md +2 -1
  171. package/dist/docs/plugins/aws-glue-registry/00-intro.md +4 -32
  172. package/dist/docs/plugins/aws-glue-registry/00a-installation.md +3 -53
  173. package/dist/docs/plugins/azure-schema-registry/00-intro.md +4 -32
  174. package/dist/docs/plugins/azure-schema-registry/01-installation.md +6 -33
  175. package/dist/docs/plugins/azure-schema-registry/02-plugin-configuration.md +1 -14
  176. package/dist/docs/plugins/azure-schema-registry/04-examples.md +0 -2
  177. package/dist/docs/plugins/backstage/00-overview.md +1 -7
  178. package/dist/docs/plugins/backstage/01-get-started.md +6 -15
  179. package/dist/docs/plugins/backstage/06-configuration.md +2 -8
  180. package/dist/docs/plugins/confluent-schema-registry/00-intro.md +2 -29
  181. package/dist/docs/plugins/confluent-schema-registry/01-installation.md +2 -26
  182. package/dist/docs/plugins/eventbridge/00-intro.md +0 -4
  183. package/dist/docs/plugins/eventbridge/00a-installation.md +1 -87
  184. package/dist/docs/plugins/eventbridge/03-api.md +2 -20
  185. package/dist/docs/plugins/github/00-intro.md +0 -31
  186. package/dist/docs/plugins/github/01-installation.md +2 -34
  187. package/dist/docs/plugins/graphql/00-intro.md +0 -30
  188. package/dist/docs/plugins/graphql/01-installation.md +1 -53
  189. package/dist/docs/plugins/graphql/02-plugin-configuration.md +0 -1
  190. package/dist/docs/plugins/hookdeck/01-intro.md +1 -1
  191. package/dist/docs/plugins/openapi/00-intro.md +0 -30
  192. package/dist/docs/plugins/openapi/01-installation.md +1 -57
  193. package/dist/docs/plugins/openapi/02-plugin-configuration.md +0 -5
  194. package/dist/docs/plugins/openapi/03-features.md +0 -4
  195. package/dist/eventcatalog-config-file-utils.cjs +34 -41
  196. package/dist/eventcatalog-config-file-utils.d.cts +56 -58
  197. package/dist/eventcatalog-config-file-utils.d.ts +56 -58
  198. package/dist/eventcatalog-config-file-utils.js +1 -1
  199. package/dist/eventcatalog.cjs +340 -249
  200. package/dist/eventcatalog.config.d.cts +18 -15
  201. package/dist/eventcatalog.config.d.ts +18 -15
  202. package/dist/eventcatalog.js +46 -28
  203. package/dist/features.cjs +36 -49
  204. package/dist/features.d.cts +1 -3
  205. package/dist/features.d.ts +1 -3
  206. package/dist/features.js +4 -6
  207. package/dist/federation/federate.cjs +37 -44
  208. package/dist/federation/federate.js +2 -2
  209. package/dist/generate.cjs +37 -42
  210. package/dist/generate.js +4 -4
  211. package/dist/resolve-catalog-dependencies.cjs +34 -41
  212. package/dist/resolve-catalog-dependencies.js +2 -2
  213. package/dist/runtime-dependencies/@eventcatalog__visualiser__studio-fonts.css.mjs +3 -0
  214. package/dist/runtime-dependencies/@eventcatalog__visualiser__studio.css.mjs +3 -0
  215. package/dist/runtime-dependencies/@eventcatalog__visualiser__studio.mjs +3 -0
  216. package/dist/runtime-dependencies/htmlparser2.mjs +3 -0
  217. package/dist/runtime-dependencies/manifest.json +5 -1
  218. package/dist/runtime-dependencies/react-syntax-highlighter__dist__cjs__create-element.js.mjs +3 -0
  219. package/dist/utils/child-process-signals.cjs +53 -0
  220. package/dist/utils/child-process-signals.d.cts +19 -0
  221. package/dist/utils/child-process-signals.d.ts +19 -0
  222. package/dist/utils/child-process-signals.js +6 -0
  223. package/dist/utils/cli-logger.cjs +1 -1
  224. package/dist/utils/cli-logger.js +2 -2
  225. package/dist/utils/license-status.cjs +11 -4
  226. package/dist/utils/license-status.d.cts +3 -2
  227. package/dist/utils/license-status.d.ts +3 -2
  228. package/dist/utils/license-status.js +1 -1
  229. package/eventcatalog/astro.config.mjs +21 -1
  230. package/eventcatalog/integrations/config-loader.mjs +56 -58
  231. package/eventcatalog/integrations/skip-startup-reload.mjs +31 -0
  232. package/eventcatalog/integrations/stable-dependency-order.mjs +29 -0
  233. package/eventcatalog/integrations/storage.mjs +20 -0
  234. package/eventcatalog/integrations/studio-server.mjs +4 -1
  235. package/eventcatalog/src/components/CatalogGraph/CatalogForceGraph.tsx +39 -0
  236. package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +2 -0
  237. package/eventcatalog/src/components/Homepage/CatalogDashboard.astro +342 -0
  238. package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +60 -4
  239. package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +5 -1
  240. package/eventcatalog/src/components/NavigationProgress.astro +7 -0
  241. package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +2 -0
  242. package/eventcatalog/src/components/SchemaExplorer/ExamplesViewer.tsx +2 -0
  243. package/eventcatalog/src/components/SchemaExplorer/SchemaCodeModal.tsx +2 -0
  244. package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +2 -0
  245. package/eventcatalog/src/components/Search/SearchDataLoader.astro +16 -28
  246. package/eventcatalog/src/components/Search/SearchModal.tsx +2 -10
  247. package/eventcatalog/src/components/Search/search-utils.ts +26 -0
  248. package/eventcatalog/src/components/Seo.astro +5 -1
  249. package/eventcatalog/src/components/Settings/AssistantSettingsForm.tsx +53 -48
  250. package/eventcatalog/src/components/Settings/GeneralSettingsForm.tsx +183 -178
  251. package/eventcatalog/src/components/Settings/LicenseSettings.tsx +140 -31
  252. package/eventcatalog/src/components/Settings/LlmAccessSettingsForm.tsx +40 -35
  253. package/eventcatalog/src/components/Settings/LogoUpload.tsx +1 -1
  254. package/eventcatalog/src/components/Settings/McpSettingsForm.tsx +9 -8
  255. package/eventcatalog/src/components/Settings/Row.tsx +7 -4
  256. package/eventcatalog/src/components/Settings/SettingsShared.tsx +3 -3
  257. package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +37 -76
  258. package/eventcatalog/src/components/SideNav/NestedSideBar/storage.ts +2 -0
  259. package/eventcatalog/src/components/SideNav/NestedSideBar/utils.ts +122 -1
  260. package/eventcatalog/src/components/SideNav/SideNav.astro +9 -1
  261. package/eventcatalog/src/components/TrialBadge.astro +20 -9
  262. package/eventcatalog/src/content.config.ts +19 -2
  263. package/eventcatalog/src/features/auth/error.astro +4 -2
  264. package/eventcatalog/src/features/auth/login.astro +2 -1
  265. package/eventcatalog/src/features/auth/middleware/middleware-auth.ts +21 -1
  266. package/eventcatalog/src/features/auth/unauthorized.astro +1 -1
  267. package/eventcatalog/src/features/fields/pages/fields.astro +1 -1
  268. package/eventcatalog/src/features/integrations/eventcatalog-features.ts +13 -7
  269. package/eventcatalog/src/features/mcp/apps/architecture-diagram/node-chat.tsx +6 -45
  270. package/eventcatalog/src/features/mcp/apps/canvas/shared.ts +3 -3
  271. package/eventcatalog/src/features/mcp/apps/canvas/styles.css +3 -1
  272. package/eventcatalog/src/features/mcp/apps/canvas/view.tsx +7 -5
  273. package/eventcatalog/src/features/mcp/apps/generated/canvas.html +123 -98
  274. package/eventcatalog/src/features/mcp/apps/generated/viewer.html +118 -101
  275. package/eventcatalog/src/features/mcp/mcp-server.ts +20 -4
  276. package/eventcatalog/src/features/server/start.ts +25 -0
  277. package/eventcatalog/src/features/storage/database.ts +88 -0
  278. package/eventcatalog/src/features/storage/migrations.ts +85 -0
  279. package/eventcatalog/src/features/storage/sql/database.sql +5 -0
  280. package/eventcatalog/src/features/storage/sql/migrations/0001-studio-canvases.sql +12 -0
  281. package/eventcatalog/src/features/storage/sql/migrations.sql +15 -0
  282. package/eventcatalog/src/features/storage/sql.ts +28 -0
  283. package/eventcatalog/src/features/studio/agent-choreography.ts +13 -10
  284. package/eventcatalog/src/features/studio/agents.ts +28 -0
  285. package/eventcatalog/src/features/studio/api/canvases-api.ts +219 -0
  286. package/eventcatalog/src/features/studio/api/canvases.ts +25 -0
  287. package/eventcatalog/src/features/studio/api/client.ts +40 -0
  288. package/eventcatalog/src/features/studio/canvas-actions.ts +160 -34
  289. package/eventcatalog/src/features/studio/canvas-preview.ts +1 -2
  290. package/eventcatalog/src/features/studio/catalog.ts +16 -14
  291. package/eventcatalog/src/features/studio/components/CanvasHeader.tsx +274 -105
  292. package/eventcatalog/src/features/studio/components/CanvasStatusMenu.tsx +15 -14
  293. package/eventcatalog/src/features/studio/components/ConnectAgentDialog.tsx +272 -119
  294. package/eventcatalog/src/features/studio/components/ConnectionsChooser.tsx +1 -2
  295. package/eventcatalog/src/features/studio/components/DeleteCanvasDialog.tsx +65 -0
  296. package/eventcatalog/src/features/studio/components/Dialog.tsx +60 -0
  297. package/eventcatalog/src/features/studio/components/JoinForm.tsx +101 -26
  298. package/eventcatalog/src/features/studio/components/LeftPanel.tsx +122 -230
  299. package/eventcatalog/src/features/studio/components/NodeDetails.tsx +183 -0
  300. package/eventcatalog/src/features/studio/components/OpenInStudioDialog.tsx +79 -0
  301. package/eventcatalog/src/features/studio/components/Presence.tsx +52 -45
  302. package/eventcatalog/src/features/studio/components/ShareDialog.tsx +277 -141
  303. package/eventcatalog/src/features/studio/components/ShortcutsDialog.tsx +41 -0
  304. package/eventcatalog/src/features/studio/components/StudioDesigner.tsx +1314 -385
  305. package/eventcatalog/src/features/studio/components/StudioNotice.astro +24 -0
  306. package/eventcatalog/src/features/studio/document-name.ts +7 -0
  307. package/eventcatalog/src/features/studio/from-visualiser.ts +138 -0
  308. package/eventcatalog/src/features/studio/hooks/presence-sender.ts +19 -2
  309. package/eventcatalog/src/features/studio/hooks/use-canvas-webmcp.ts +9 -3
  310. package/eventcatalog/src/features/studio/hooks/use-comments.ts +2 -2
  311. package/eventcatalog/src/features/studio/hooks/use-follow-camera.ts +8 -3
  312. package/eventcatalog/src/features/studio/hooks/use-studio-flow.ts +244 -32
  313. package/eventcatalog/src/features/studio/identity.ts +25 -1
  314. package/eventcatalog/src/features/studio/limits.ts +2 -0
  315. package/eventcatalog/src/features/studio/pages/[id].astro +42 -16
  316. package/eventcatalog/src/features/studio/pages/index.astro +596 -373
  317. package/eventcatalog/src/features/studio/pages/webmcp-relay.ts +12 -15
  318. package/eventcatalog/src/features/studio/server/canvas-mcp.ts +8 -23
  319. package/eventcatalog/src/features/studio/server/runtime.ts +150 -46
  320. package/eventcatalog/src/features/studio/server/sql/storage.sql +18 -0
  321. package/eventcatalog/src/features/studio/server/storage.ts +53 -73
  322. package/eventcatalog/src/features/studio/webmcp-relay/LICENSE +21 -0
  323. package/eventcatalog/src/features/studio/webmcp-relay/README.md +5 -0
  324. package/eventcatalog/src/features/studio/webmcp-relay/embed.js +2 -0
  325. package/eventcatalog/src/features/studio/webmcp-relay/widget.html +10 -0
  326. package/eventcatalog/src/features/studio/webmcp-relay/widget.js +1 -0
  327. package/eventcatalog/src/features/tools/catalog-tools.ts +3 -1
  328. package/eventcatalog/src/layouts/BaseLayout.astro +4 -4
  329. package/eventcatalog/src/layouts/SettingsLayout.astro +2 -2
  330. package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +3 -2
  331. package/eventcatalog/src/pages/_index.astro +5 -342
  332. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.spec.ts +2 -3
  333. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.ts +0 -7
  334. package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +3 -1
  335. package/eventcatalog/src/pages/diagrams/[id]/[version]/_index.data.ts +0 -7
  336. package/eventcatalog/src/pages/diagrams/[id]/[version]/embed.astro +1 -0
  337. package/eventcatalog/src/pages/diagrams/[id]/[version]/index.astro +1 -0
  338. package/eventcatalog/src/pages/directory/[type]/_index.data.ts +5 -7
  339. package/eventcatalog/src/pages/directory/[type]/index.astro +3 -1
  340. package/eventcatalog/src/pages/discover/[type]/_index.data.ts +5 -7
  341. package/eventcatalog/src/pages/discover/[type]/index.astro +3 -1
  342. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/_index.data.ts +0 -7
  343. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +1 -0
  344. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/_index.data.ts +0 -7
  345. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +1 -0
  346. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/_index.data.ts +0 -7
  347. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/[filename].astro +3 -1
  348. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/_[filename].data.ts +0 -7
  349. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/_index.data.ts +0 -7
  350. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/index.astro +1 -0
  351. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/examples/[...filename].astro +1 -0
  352. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/examples/_[...filename].data.ts +0 -4
  353. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/field-lineage/_index.data.ts +0 -7
  354. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/field-lineage/index.astro +1 -0
  355. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/[filename].astro +3 -1
  356. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/_[filename].data.ts +0 -7
  357. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +1 -0
  358. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.spec.ts +2 -3
  359. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.ts +0 -7
  360. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/index.astro +1 -0
  361. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/[filename].astro +1 -0
  362. package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/_[filename].data.ts +0 -7
  363. package/eventcatalog/src/pages/docs/[type]/[id]/_index.data.ts +0 -7
  364. package/eventcatalog/src/pages/docs/[type]/[id]/index.astro +2 -1
  365. package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/_index.data.ts +0 -7
  366. package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/index.astro +1 -0
  367. package/eventcatalog/src/pages/docs/[type]/[id]/language/_index.data.ts +0 -7
  368. package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +1 -0
  369. package/eventcatalog/src/pages/docs/custom/[...path]/_index.data.ts +0 -7
  370. package/eventcatalog/src/pages/docs/custom/[...path]/index.astro +1 -0
  371. package/eventcatalog/src/pages/docs/services/[id]/[docType]/[docId]/index.astro +1 -1
  372. package/eventcatalog/src/pages/docs/services/[id]/[version]/resources/index.astro +1 -0
  373. package/eventcatalog/src/pages/docs/services/[id]/asyncapi/[filename].astro +1 -1
  374. package/eventcatalog/src/pages/docs/services/[id]/changelog/index.astro +1 -1
  375. package/eventcatalog/src/pages/docs/services/[id]/graphql/[filename].astro +1 -1
  376. package/eventcatalog/src/pages/docs/services/[id]/spec/[filename].astro +1 -1
  377. package/eventcatalog/src/pages/docs/teams/[id]/_index.data.ts +0 -7
  378. package/eventcatalog/src/pages/docs/teams/[id]/index.astro +1 -0
  379. package/eventcatalog/src/pages/docs/users/[id]/_index.data.ts +0 -7
  380. package/eventcatalog/src/pages/docs/users/[id]/index.astro +1 -0
  381. package/eventcatalog/src/pages/index.astro +4 -2
  382. package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/_index.data.ts +0 -7
  383. package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/index.astro +9 -1
  384. package/eventcatalog/src/pages/schemas/explorer/_index.data.ts +0 -7
  385. package/eventcatalog/src/pages/schemas/explorer/index.astro +4 -2
  386. package/eventcatalog/src/pages/settings/license.astro +9 -1
  387. package/eventcatalog/src/pages/triggers/[type]/[id]/[version]/_index.data.ts +0 -7
  388. package/eventcatalog/src/pages/triggers/[type]/[id]/[version]/index.astro +1 -0
  389. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/_index.data.ts +0 -7
  390. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/_index.data.ts +0 -7
  391. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/index.astro +1 -0
  392. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/_index.data.ts +0 -7
  393. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/index.astro +1 -0
  394. package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/index.astro +1 -0
  395. package/eventcatalog/src/pages/visualiser/[type]/[id]/_index.data.ts +38 -0
  396. package/eventcatalog/src/pages/visualiser/[type]/[id]/index.astro +18 -41
  397. package/eventcatalog/src/pages/visualiser/designs/[id]/_index.data.ts +0 -7
  398. package/eventcatalog/src/pages/visualiser/designs/[id]/index.astro +2 -1
  399. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/_index.data.ts +0 -7
  400. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/index.astro +1 -0
  401. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/index.astro +1 -0
  402. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/_index.data.ts +0 -7
  403. package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/index.astro +1 -0
  404. package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/_index.data.ts +0 -7
  405. package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/index.astro +1 -0
  406. package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/index.astro +1 -0
  407. package/eventcatalog/src/types/react-syntax-highlighter.d.ts +10 -0
  408. package/eventcatalog/src/utils/collections/flows.ts +20 -7
  409. package/eventcatalog/src/utils/collections/resource-owners.ts +8 -2
  410. package/eventcatalog/src/utils/collections/resources.ts +2 -0
  411. package/eventcatalog/src/utils/collections/util.ts +8 -4
  412. package/eventcatalog/src/utils/git.ts +11 -0
  413. package/eventcatalog/src/utils/homepage-dashboard.ts +143 -0
  414. package/eventcatalog/src/utils/license.ts +1 -1
  415. package/eventcatalog/src/utils/link-validation.ts +25 -19
  416. package/eventcatalog/src/utils/node-graphs/domain-entity-map.ts +3 -1
  417. package/eventcatalog/src/utils/node-graphs/domain-levels-node-graph.ts +3 -3
  418. package/eventcatalog/src/utils/node-graphs/field-node-graph.ts +4 -2
  419. package/eventcatalog/src/utils/node-graphs/layout-node-graph.ts +20 -1
  420. package/eventcatalog/src/utils/node-graphs/node-resource.ts +67 -0
  421. package/eventcatalog/src/utils/node-graphs/systems-node-graph.ts +1 -1
  422. package/eventcatalog/src/utils/page-loaders/hybrid-page.ts +4 -15
  423. package/eventcatalog/src/utils/page-title.ts +15 -0
  424. package/eventcatalog/src/utils/syntax-highlighter-renderer.ts +64 -0
  425. package/eventcatalog/src/utils/trial.ts +13 -0
  426. package/package.json +12 -12
  427. package/dist/docs/development/ask-your-architecture/05-skills/02-installation.md +0 -60
  428. package/dist/docs/development/ask-your-architecture/05-skills/_category_.json +0 -11
  429. package/dist/docs/development/ask-your-architecture/06-slack-integration/01-introduction.md +0 -63
  430. package/dist/docs/development/ask-your-architecture/06-slack-integration/02-slack-app-setup.md +0 -154
  431. package/dist/docs/development/ask-your-architecture/06-slack-integration/03-installation.md +0 -169
  432. package/dist/docs/development/ask-your-architecture/06-slack-integration/04-deployment.md +0 -236
  433. package/dist/docs/development/ask-your-architecture/06-slack-integration/05-usage.md +0 -140
  434. package/dist/docs/development/ask-your-architecture/06-slack-integration/06-troubleshooting.md +0 -268
  435. package/dist/docs/development/ask-your-architecture/06-slack-integration/_category_.json +0 -13
  436. package/dist/docs/development/guides/domains/06-visualize-domains/01-domain-integration-map.md +0 -40
  437. package/dist/runtime-dependencies/@mcp-b__webmcp-local-relay.mjs +0 -3
  438. package/eventcatalog/src/features/studio/canvas-doc.ts +0 -409
  439. package/eventcatalog/src/features/studio/clipboard.ts +0 -97
  440. package/eventcatalog/src/features/studio/components/CanvasControls.tsx +0 -154
  441. package/eventcatalog/src/features/studio/components/Comments.tsx +0 -770
  442. package/eventcatalog/src/features/studio/components/ContainerChooser.tsx +0 -145
  443. package/eventcatalog/src/features/studio/components/DragGhost.tsx +0 -115
  444. package/eventcatalog/src/features/studio/components/Picture.tsx +0 -21
  445. package/eventcatalog/src/features/studio/components/PropertiesPanel.tsx +0 -212
  446. package/eventcatalog/src/features/studio/components/canvas-nodes.tsx +0 -255
  447. package/eventcatalog/src/features/studio/components/icons.ts +0 -53
  448. package/eventcatalog/src/features/studio/components/status.ts +0 -51
  449. package/eventcatalog/src/features/studio/edges.ts +0 -56
  450. package/eventcatalog/src/features/studio/flow-state.ts +0 -92
  451. package/eventcatalog/src/features/studio/grouping.ts +0 -226
  452. package/eventcatalog/src/features/studio/layout.ts +0 -42
  453. package/eventcatalog/src/features/studio/levels.ts +0 -282
  454. package/eventcatalog/src/features/studio/node-types.ts +0 -205
  455. package/eventcatalog/src/features/studio/pages/new.astro +0 -24
  456. package/eventcatalog/src/features/studio/pages/wake.ts +0 -15
  457. package/eventcatalog/src/features/studio/placement.ts +0 -197
  458. package/eventcatalog/src/features/studio/studio.css +0 -273
@@ -1,226 +0,0 @@
1
- import type { Node, XYPosition } from '@xyflow/react';
2
- import { canGoInContainer, getNodeSize, isGroupType } from './node-types';
3
-
4
- /**
5
- * Containers: domains and systems shown as boxes that other nodes sit in.
6
- * A node inside one has its parentId, and its position is relative to the container.
7
- */
8
-
9
- /** Room around what's in a container, and for its header */
10
- export const GROUP_PADDING = { top: 80, right: 40, bottom: 40, left: 40 };
11
-
12
- type Rect = { x: number; y: number; width: number; height: number };
13
-
14
- const byId = (nodes: Node[]) => new Map(nodes.map((node) => [node.id, node]));
15
-
16
- /** A node's size: as rendered (in the browser), as set (containers, notes), or what its type renders at */
17
- export const sizeOf = (node: Node) => ({
18
- width: node.measured?.width ?? node.width ?? getNodeSize(node.type).width,
19
- height: node.measured?.height ?? node.height ?? getNodeSize(node.type).height,
20
- });
21
-
22
- /** Nodes are positioned relative to their container, so walk up the chain to get the canvas position */
23
- export const getAbsolutePosition = (node: Node, lookup: Map<string, Node>): XYPosition => {
24
- const parent = node.parentId ? lookup.get(node.parentId) : undefined;
25
- if (!parent) return node.position;
26
- const parentPosition = getAbsolutePosition(parent, lookup);
27
- return { x: parentPosition.x + node.position.x, y: parentPosition.y + node.position.y };
28
- };
29
-
30
- export const getAbsoluteRect = (node: Node, lookup: Map<string, Node>): Rect => ({
31
- ...getAbsolutePosition(node, lookup),
32
- ...sizeOf(node),
33
- });
34
-
35
- const getDepth = (node: Node, lookup: Map<string, Node>): number => {
36
- const parent = node.parentId ? lookup.get(node.parentId) : undefined;
37
- return parent ? 1 + getDepth(parent, lookup) : 0;
38
- };
39
-
40
- const isDescendantOf = (node: Node, ancestorId: string, lookup: Map<string, Node>): boolean => {
41
- if (!node.parentId) return false;
42
- if (node.parentId === ancestorId) return true;
43
- const parent = lookup.get(node.parentId);
44
- return parent ? isDescendantOf(parent, ancestorId, lookup) : false;
45
- };
46
-
47
- const containsPoint = (rect: Rect, point: XYPosition) =>
48
- point.x >= rect.x && point.x <= rect.x + rect.width && point.y >= rect.y && point.y <= rect.y + rect.height;
49
-
50
- /** React Flow needs containers before what's in them in the nodes array */
51
- export const sortByHierarchy = (nodes: Node[]): Node[] => {
52
- const lookup = byId(nodes);
53
- return nodes
54
- .map((node, index) => ({ node, index, depth: getDepth(node, lookup) }))
55
- .sort((a, b) => a.depth - b.depth || a.index - b.index)
56
- .map(({ node }) => node);
57
- };
58
-
59
- /** The innermost container under the centre of a node (never itself, or one of its own children) */
60
- export const findDropTarget = (nodeId: string, nodes: Node[]): Node | undefined => {
61
- const lookup = byId(nodes);
62
- const node = lookup.get(nodeId);
63
- // Sticky notes go anywhere, never in a container (one that's in one is taken out when it's next moved)
64
- if (!node || !canGoInContainer(node.type)) return undefined;
65
- const rect = getAbsoluteRect(node, lookup);
66
- const center = { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 };
67
- return nodes
68
- .filter((candidate) => isGroupType(candidate.type) && candidate.id !== nodeId && !isDescendantOf(candidate, nodeId, lookup))
69
- .filter((candidate) => containsPoint(getAbsoluteRect(candidate, lookup), center))
70
- .sort((a, b) => getDepth(b, lookup) - getDepth(a, lookup))[0];
71
- };
72
-
73
- /** The innermost container at a canvas point, for things dropped there */
74
- export const findGroupAtPoint = (point: XYPosition, nodes: Node[]): Node | undefined => {
75
- const lookup = byId(nodes);
76
- return nodes
77
- .filter((candidate) => isGroupType(candidate.type) && containsPoint(getAbsoluteRect(candidate, lookup), point))
78
- .sort((a, b) => getDepth(b, lookup) - getDepth(a, lookup))[0];
79
- };
80
-
81
- /** A node moved into (or out of, without a parentId) a container, staying in the same place on the canvas */
82
- export const withParent = (node: Node, parentId: string | undefined, nodes: Node[]): Node => {
83
- const lookup = byId(nodes);
84
- const absolute = getAbsolutePosition(node, lookup);
85
- const parent = parentId ? lookup.get(parentId) : undefined;
86
- const parentPosition = parent ? getAbsolutePosition(parent, lookup) : { x: 0, y: 0 };
87
- const { parentId: _, extent: __, ...rest } = node;
88
- return {
89
- ...rest,
90
- ...(parent && { parentId: parent.id }),
91
- position: { x: absolute.x - parentPosition.x, y: absolute.y - parentPosition.y },
92
- };
93
- };
94
-
95
- /** A canvas point, relative to a container */
96
- export const toRelativePosition = (point: XYPosition, parentId: string, nodes: Node[]): XYPosition => {
97
- const lookup = byId(nodes);
98
- const parent = lookup.get(parentId);
99
- if (!parent) return point;
100
- const parentPosition = getAbsolutePosition(parent, lookup);
101
- return { x: point.x - parentPosition.x, y: point.y - parentPosition.y };
102
- };
103
-
104
- /** Nodes and everything inside them (deleted with their container) */
105
- export const withDescendants = (ids: string[], nodes: Node[]): Set<string> => {
106
- const lookup = byId(nodes);
107
- const result = new Set(ids);
108
- nodes.forEach((node) => {
109
- if (ids.some((id) => isDescendantOf(node, id, lookup))) result.add(node.id);
110
- });
111
- return result;
112
- };
113
-
114
- /**
115
- * The size a container needs to fit what's inside it, never smaller than it is, and how far its children
116
- * must shift when some sit above or left of its content area (so the header stays clear).
117
- */
118
- export const fitGroup = (groupId: string, nodes: Node[]) => {
119
- const lookup = byId(nodes);
120
- const group = lookup.get(groupId);
121
- const children = nodes.filter((node) => node.parentId === groupId);
122
- if (!group || children.length === 0) return undefined;
123
- const rects = children.map((child) => ({ ...child.position, ...sizeOf(child) }));
124
- const shift = {
125
- x: Math.max(0, GROUP_PADDING.left - Math.min(...rects.map((rect) => rect.x))),
126
- y: Math.max(0, GROUP_PADDING.top - Math.min(...rects.map((rect) => rect.y))),
127
- };
128
- const current = sizeOf(group);
129
- return {
130
- shift,
131
- width: Math.max(current.width, Math.max(...rects.map((rect) => rect.x + rect.width)) + shift.x + GROUP_PADDING.right),
132
- height: Math.max(current.height, Math.max(...rects.map((rect) => rect.y + rect.height)) + shift.y + GROUP_PADDING.bottom),
133
- };
134
- };
135
-
136
- /** How far a dragged node's middle can go past a container's edge and still be kept in it (growing it) */
137
- export const KEEP_IN_CONTAINER_MARGIN = 160;
138
-
139
- type Size = { width: number; height: number };
140
- /** A node's place and size as shown while something's dragged */
141
- export type NodePreview = { position: XYPosition; width?: number; height?: number };
142
-
143
- /**
144
- * Containers growing to fit what's being dragged in them, on every side, as a preview of where things will be.
145
- * `containerIds` are the containers around what's dragged, innermost first. `start` is the canvas when the drag
146
- * started, and `now` the canvas as shown (with the dragged nodes where they are now). A dragged node is kept in a
147
- * container while its middle is within `KEEP_IN_CONTAINER_MARGIN` of where the container was, and dropping it
148
- * further away takes it out, so the container goes back to its size. A container growing up or left moves, and
149
- * what's in it moves the other way, so nothing moves on the canvas.
150
- *
151
- * Returns, by id, where containers and the nodes in them that aren't dragged go (positions relative to their
152
- * containers), and their sizes for containers.
153
- */
154
- export const previewContainerGrowth = (
155
- containerIds: string[],
156
- draggedIds: ReadonlySet<string>,
157
- start: ReadonlyMap<string, Node>,
158
- now: ReadonlyMap<string, Node>
159
- ): Map<string, NodePreview> => {
160
- const previews = new Map<string, NodePreview>();
161
- // Where each container's top left was on the canvas when the drag started (moving a container grown up or
162
- // left is offset by what's in it moving the other way, so only its own shift changes it)
163
- const startOrigin = (id: string) => getAbsolutePosition(start.get(id)!, start as Map<string, Node>);
164
- const shifts = new Map<string, XYPosition>();
165
-
166
- for (const id of containerIds) {
167
- const container = start.get(id);
168
- if (!container) continue;
169
- const origin = startOrigin(id);
170
- const startSize = sizeOf(container);
171
- // Everything in it, in its coordinates when the drag started
172
- const items: { rect: Rect }[] = [];
173
- for (const node of start.values()) {
174
- if (node.parentId !== id) continue;
175
- if (draggedIds.has(node.id)) {
176
- const current = now.get(node.id);
177
- if (!current) continue;
178
- const at = getAbsoluteRect(current, now as Map<string, Node>);
179
- const middle = { x: at.x + at.width / 2, y: at.y + at.height / 2 };
180
- const kept =
181
- middle.x >= origin.x - KEEP_IN_CONTAINER_MARGIN &&
182
- middle.x <= origin.x + startSize.width + KEEP_IN_CONTAINER_MARGIN &&
183
- middle.y >= origin.y - KEEP_IN_CONTAINER_MARGIN &&
184
- middle.y <= origin.y + startSize.height + KEEP_IN_CONTAINER_MARGIN;
185
- if (kept) items.push({ rect: { ...at, x: at.x - origin.x, y: at.y - origin.y } });
186
- continue;
187
- }
188
- // A container inside it that's grown: where it's grown to
189
- const inner = previews.get(node.id);
190
- const innerShift = shifts.get(node.id) ?? { x: 0, y: 0 };
191
- items.push({
192
- rect: {
193
- x: node.position.x - innerShift.x,
194
- y: node.position.y - innerShift.y,
195
- ...(inner?.width && inner.height ? { width: inner.width, height: inner.height } : sizeOf(node)),
196
- },
197
- });
198
- }
199
-
200
- const shift = { x: 0, y: 0 };
201
- let width = startSize.width;
202
- let height = startSize.height;
203
- if (items.length > 0) {
204
- shift.x = Math.max(0, GROUP_PADDING.left - Math.min(...items.map(({ rect }) => rect.x)));
205
- shift.y = Math.max(0, GROUP_PADDING.top - Math.min(...items.map(({ rect }) => rect.y)));
206
- width =
207
- Math.max(startSize.width, Math.max(...items.map(({ rect }) => rect.x + rect.width)) + GROUP_PADDING.right) + shift.x;
208
- height =
209
- Math.max(startSize.height, Math.max(...items.map(({ rect }) => rect.y + rect.height)) + GROUP_PADDING.bottom) + shift.y;
210
- }
211
- shifts.set(id, shift);
212
- previews.set(id, {
213
- position: { x: container.position.x - shift.x, y: container.position.y - shift.y },
214
- width,
215
- height,
216
- });
217
- // What's in it moves the other way. Not what's dragged: React Flow places it against the container as it is.
218
- for (const node of start.values()) {
219
- if (node.parentId !== id || draggedIds.has(node.id)) continue;
220
- const own = previews.get(node.id);
221
- const base = own?.position ?? node.position;
222
- previews.set(node.id, { ...own, position: { x: base.x + shift.x, y: base.y + shift.y } });
223
- }
224
- }
225
- return previews;
226
- };
@@ -1,42 +0,0 @@
1
- import type { Edge, Node, XYPosition } from '@xyflow/react';
2
- import { layoutWithElk } from '@eventcatalog/visualiser/layout';
3
- import { isGroupType, isOnLevel } from './node-types';
4
-
5
- /**
6
- * Lays a canvas out with the same ELK layout as EventCatalog's visualiser (left to right, edges routed
7
- * around nodes, containers laid out with what's in them and sized to fit). Nodes are sized as rendered when
8
- * they have been (in the browser), or by their type.
9
- */
10
- export const layoutGraph = (nodes: Node[], edges: Edge[]) => layoutWithElk({ nodes, edges });
11
-
12
- /** The layout sizes containers with style.width/height; the canvas sizes them with width/height */
13
- export const withGroupSizes = (nodes: Node[]) =>
14
- nodes.map((node) => {
15
- const { width, height, ...style } = node.style ?? {};
16
- if (typeof width !== 'number' || typeof height !== 'number') return node;
17
- return { ...node, width, height, style };
18
- });
19
-
20
- export type LayoutResult = Map<string, { position: XYPosition; size?: { width: number; height: number } }>;
21
-
22
- /**
23
- * New positions (relative to their container, if they're in one) for the nodes on a canvas, and new sizes for
24
- * containers. Only these are kept for the canvas people edit: the edge routes ELK draws would be out of date
25
- * as soon as someone moves a node. Notes added on L1 or L2 aren't on this canvas, so they stay where they are.
26
- */
27
- export const getLayoutPositions = async (nodes: Node[], edges: Edge[]): Promise<LayoutResult> => {
28
- const onCanvas = nodes.filter((node) => isOnLevel(node, 3));
29
- if (onCanvas.length === 0) return new Map();
30
- const ids = new Set(onCanvas.map((node) => node.id));
31
- const between = edges.filter((edge) => ids.has(edge.source) && ids.has(edge.target));
32
- const laidOut = withGroupSizes((await layoutGraph(onCanvas, between)).nodes);
33
- return new Map(
34
- laidOut.map((node) => [
35
- node.id,
36
- {
37
- position: node.position,
38
- ...(isGroupType(node.type) && node.width && node.height && { size: { width: node.width, height: node.height } }),
39
- },
40
- ])
41
- );
42
- };
@@ -1,282 +0,0 @@
1
- import { MarkerType, type Edge, type Node } from '@xyflow/react';
2
- import { getMessagesLabel } from '@eventcatalog/visualiser/layout';
3
- import { MESSAGE_COLLECTIONS } from './edges';
4
- import { GROUP_TYPES, isGroupType, isWrittenOnCanvas } from './node-types';
5
-
6
- /**
7
- * Levels of detail, the same as EventCatalog's diagrams:
8
- * - L1: domains, systems and how they relate (services folded into the system or domain that contains them)
9
- * - L2: services and data stores, with messages and channels hidden (the nodes either side connected directly)
10
- * - L3: everything, including messages and channels (the canvas people edit)
11
- *
12
- * What a domain or system contains is what sits inside it (as a container), or what it's connected to with
13
- * "contains" (as a card, which catalog domains and systems get when their services are on the canvas).
14
- */
15
- export type Level = 1 | 2 | 3;
16
-
17
- export const LEVELS: { level: Level; description: string }[] = [
18
- { level: 1, description: 'Domains, systems and their relationships' },
19
- { level: 2, description: 'Services and data stores' },
20
- { level: 3, description: 'Everything, including messages and channels' },
21
- ];
22
-
23
- // Domains and systems: as cards (what they contain is connected with "contains") or containers (it's inside)
24
- const CONTAINER_TYPES = new Set(['system', 'context-domain', GROUP_TYPES.system, GROUP_TYPES.domain]);
25
- const isSystem = (node: Node) => node.type === 'system' || node.type === GROUP_TYPES.system;
26
- const isDomain = (node: Node) => node.type === 'context-domain' || node.type === GROUP_TYPES.domain;
27
-
28
- const isMessage = (node: Node) => !!MESSAGE_COLLECTIONS[node.type ?? ''];
29
- const isCarrier = (node: Node) => isMessage(node) || node.type === 'channel';
30
- const isContainer = (node: Node) => CONTAINER_TYPES.has(node.type ?? '');
31
- const messageName = (node: Node) => String((node.data as { message?: { name?: string } }).message?.name ?? node.id);
32
-
33
- // Edges as the visualiser's levels draw them: what's folded together is joined by a plain line, and what was joined
34
- // through hidden messages or channels by a dashed, muted one ("bridged"), each with the visualiser's arrow
35
- const EDGE_STROKE = 'var(--ec-edge-stroke, #6b7280)';
36
- const MUTED = 'rgb(var(--ec-page-text-muted))';
37
- const FOLDED_EDGE = {
38
- type: 'smoothstep',
39
- style: { strokeWidth: 1, stroke: EDGE_STROKE },
40
- markerEnd: { type: MarkerType.ArrowClosed, width: 20, height: 20 },
41
- } satisfies Partial<Edge>;
42
- const BRIDGED_EDGE = {
43
- type: 'smoothstep',
44
- style: { strokeWidth: 1.5, stroke: MUTED, strokeDasharray: '5 5' },
45
- markerEnd: { type: MarkerType.ArrowClosed, width: 20, height: 20, color: MUTED },
46
- } satisfies Partial<Edge>;
47
-
48
- /** What a node becomes at a level: kept (as itself or another node), carried through (messages, channels) or dropped */
49
- type Representative = { kind: 'node'; id: string } | { kind: 'carrier' } | { kind: 'drop' };
50
-
51
- /**
52
- * Collapse a graph: each node is kept, replaced by another node (e.g. a service by its system), carried through
53
- * (messages and channels: the nodes either side get connected directly, "bridged") or dropped. Edges between two
54
- * nodes that are kept as they are stay as they were (`keepDirect`, for L2); the rest are merged per pair and kind
55
- * (folded or bridged), labelled with the messages they carry.
56
- */
57
- const collapseGraph = (
58
- nodes: Node[],
59
- edges: Edge[],
60
- representativeOf: (node: Node) => Representative,
61
- { keepDirect = false }: { keepDirect?: boolean } = {}
62
- ) => {
63
- const byId = new Map(nodes.map((node) => [node.id, node]));
64
- // Whether one node is inside another (e.g. a system in its domain): they're not connected, one holds the other
65
- const isInside = (id: string, containerId: string) => {
66
- for (let node = byId.get(id); node?.parentId; node = byId.get(node.parentId)) if (node.parentId === containerId) return true;
67
- return false;
68
- };
69
- const representatives = new Map(nodes.map((node) => [node.id, representativeOf(node)]));
70
- const outgoing = new Map<string, Edge[]>();
71
- edges.forEach((edge) => outgoing.set(edge.source, [...(outgoing.get(edge.source) ?? []), edge]));
72
-
73
- type Merged = { source: string; target: string; bridged: boolean; messages: Map<string, string>; labels: string[] };
74
- const merged = new Map<string, Merged>();
75
- const kept: Edge[] = [];
76
- const addMessage = (messages: Map<string, string>, node: Node) => {
77
- if (isMessage(node)) messages.set(messageName(node), MESSAGE_COLLECTIONS[node.type!]);
78
- };
79
-
80
- edges.forEach((edge) => {
81
- const from = representatives.get(edge.source);
82
- if (from?.kind !== 'node') return;
83
- const to = representatives.get(edge.target);
84
- if (keepDirect && from.id === edge.source && to?.kind === 'node' && to.id === edge.target) return kept.push(edge);
85
- // Follow the edge through carried nodes to the node(s) it reaches, collecting the messages on the way
86
- const stack = [{ id: edge.target, messages: new Map<string, string>(), labels: [String(edge.label ?? '')], bridged: false }];
87
- const visited = new Set<string>();
88
- addMessage(stack[0].messages, byId.get(edge.source)!);
89
- while (stack.length) {
90
- const current = stack.pop()!;
91
- if (visited.has(current.id)) continue;
92
- visited.add(current.id);
93
- const node = byId.get(current.id);
94
- const reached = representatives.get(current.id);
95
- if (!node || !reached || reached.kind === 'drop') continue;
96
- const messages = new Map(current.messages);
97
- addMessage(messages, node);
98
- if (reached.kind === 'carrier') {
99
- (outgoing.get(current.id) ?? []).forEach((next) =>
100
- stack.push({ id: next.target, messages, labels: [] as string[], bridged: true })
101
- );
102
- continue;
103
- }
104
- // Edges inside what was collapsed disappear, and so do edges to what a node is in (e.g. a service loose in a
105
- // domain, folded into it, and a system in the same domain)
106
- if (from.id === reached.id || isInside(from.id, reached.id) || isInside(reached.id, from.id)) continue;
107
- const key = `${current.bridged ? 'bridged' : 'level'}-${from.id}-${reached.id}`;
108
- const entry: Merged = merged.get(key) ?? {
109
- source: from.id,
110
- target: reached.id,
111
- bridged: current.bridged,
112
- messages: new Map(),
113
- labels: [],
114
- };
115
- messages.forEach((collection, name) => entry.messages.set(name, collection));
116
- entry.labels.push(...current.labels.filter(Boolean));
117
- merged.set(key, entry);
118
- }
119
- });
120
-
121
- const keptIds = new Set([...representatives.values()].flatMap((rep) => (rep.kind === 'node' ? [rep.id] : [])));
122
- // Actors' connections are relationships, labelled as they were (like the visualiser's context relationships)
123
- const isActor = (id: string) => byId.get(id)?.type === 'actor';
124
- return {
125
- nodes: nodes.filter((node) => keptIds.has(node.id)),
126
- edges: [
127
- ...kept,
128
- ...[...merged.entries()].map(([id, { source, target, bridged, messages, labels }]): Edge => {
129
- const label =
130
- getMessagesLabel(messages) ??
131
- (!bridged && (isActor(source) || isActor(target)) && labels.length ? [...new Set(labels)].join(', ') : undefined);
132
- return { id, source, target, ...(bridged ? BRIDGED_EDGE : FOLDED_EDGE), ...(label && { label }) };
133
- }),
134
- ],
135
- };
136
- };
137
-
138
- /**
139
- * The system and domain each node is in: the containers it sits inside, or the domain and system cards
140
- * connected to it with "contains"
141
- */
142
- const getContainers = (nodes: Node[], edges: Edge[]) => {
143
- const byId = new Map(nodes.map((node) => [node.id, node]));
144
- const containers = new Map<string, { system?: string; domain?: string }>();
145
- const add = (nodeId: string, container: Node) => {
146
- const entry = containers.get(nodeId) ?? {};
147
- if (isSystem(container)) entry.system ??= container.id;
148
- else entry.domain ??= container.id;
149
- containers.set(nodeId, entry);
150
- };
151
- for (const node of nodes) {
152
- for (
153
- let parent = node.parentId ? byId.get(node.parentId) : undefined;
154
- parent;
155
- parent = parent.parentId ? byId.get(parent.parentId) : undefined
156
- ) {
157
- if (isContainer(parent)) add(node.id, parent);
158
- }
159
- }
160
- for (const edge of edges) {
161
- const container = byId.get(edge.source);
162
- if (container && isContainer(container) && edge.label === 'contains') add(edge.target, container);
163
- }
164
- return containers;
165
- };
166
-
167
- /**
168
- * Containers are sized by the layout: to fit what's in them, or (empty) the size the visualiser lays empty groups
169
- * out at. Same ids, so switching levels grows and shrinks them.
170
- */
171
- const sizedByLayout = ({ nodes, edges }: { nodes: Node[]; edges: Edge[] }) => ({
172
- edges,
173
- nodes: nodes.map((node) =>
174
- isGroupType(node.type) ? { ...node, width: undefined, height: undefined, measured: undefined } : node
175
- ),
176
- });
177
-
178
- /** L2: messages and channels hidden, the nodes either side connected directly */
179
- const level2 = (nodes: Node[], edges: Edge[]) =>
180
- collapseGraph(nodes, edges, (node) => (isCarrier(node) ? { kind: 'carrier' } : { kind: 'node', id: node.id }), {
181
- keepDirect: true,
182
- });
183
-
184
- /** Whether a node is inside a container, at any depth */
185
- const isWithin = (node: Node, containerId: string, byId: Map<string, Node>) => {
186
- for (let parent = node.parentId; parent; parent = byId.get(parent)?.parentId) if (parent === containerId) return true;
187
- return false;
188
- };
189
-
190
- /**
191
- * L1 as EventCatalog's diagrams draw it: systems as cards with what's in them counted, and domains with no system in
192
- * them (or in their subdomains) as domain cards
193
- */
194
- const asSystemsLevel = (
195
- { nodes, edges }: { nodes: Node[]; edges: Edge[] },
196
- { all, allEdges, containers }: { all: Node[]; allEdges: Edge[]; containers: ReturnType<typeof getContainers> }
197
- ) => {
198
- const byId = new Map(all.map((node) => [node.id, node]));
199
- const count = (id: string, matches: (node: Node) => boolean) =>
200
- all.filter((node) => matches(node) && containers.get(node.id)?.system === id).length;
201
- // The messages a system's services send and receive
202
- const messagesOf = (id: string) => {
203
- const services = new Set(all.filter((node) => containers.get(node.id)?.system === id).map((node) => node.id));
204
- const messages = new Set<string>();
205
- for (const edge of allEdges) {
206
- const [inside, other] = services.has(edge.source) ? [edge.source, edge.target] : [edge.target, edge.source];
207
- if (services.has(inside) && byId.get(other) && isMessage(byId.get(other)!)) messages.add(other);
208
- }
209
- return messages.size;
210
- };
211
- return {
212
- edges,
213
- nodes: nodes.map((node): Node => {
214
- const { id, parentId, position, data } = node;
215
- if (node.type === GROUP_TYPES.system)
216
- return {
217
- id,
218
- type: 'system',
219
- position,
220
- ...(parentId && { parentId }),
221
- data: {
222
- mode: 'full',
223
- ...data,
224
- servicesCount: count(id, (child) => child.type === 'service' || child.type === 'agent'),
225
- containersCount: count(id, (child) => child.type === 'data'),
226
- messagesCount: messagesOf(id),
227
- },
228
- };
229
- if (node.type === GROUP_TYPES.domain && !all.some((other) => isSystem(other) && isWithin(other, id, byId)))
230
- return {
231
- id,
232
- type: 'context-domain',
233
- position,
234
- ...(parentId && { parentId }),
235
- data: {
236
- mode: 'full',
237
- ...data,
238
- subdomain: !!parentId,
239
- systemsCount: 0,
240
- servicesCount: all.filter((other) => other.type === 'service' && isWithin(other, id, byId)).length,
241
- },
242
- };
243
- return node;
244
- }),
245
- };
246
- };
247
-
248
- /** L1: services folded into their system (or domain); actors, external systems and loose services stay */
249
- const level1 = (nodes: Node[], edges: Edge[]) => {
250
- const containers = getContainers(nodes, edges);
251
- const collapsed = collapseGraph(nodes, edges, (node) => {
252
- const container = containers.get(node.id);
253
- // Systems stay (inside their domain's container, if they're in one); everything else folds into its system or domain
254
- if (isContainer(node) && (isSystem(node) || !container?.system)) return { kind: 'node', id: node.id };
255
- if (container?.system) return { kind: 'node', id: container.system };
256
- // Messages and channels connect the systems either side, even when they sit in a domain rather than a system
257
- // (the visualiser has them outside its domains; catalog domains on a canvas hold their messages)
258
- if (isCarrier(node)) return { kind: 'carrier' };
259
- if (container?.domain) return { kind: 'node', id: container.domain };
260
- if (node.type === 'data' || isWrittenOnCanvas(node.type)) return { kind: 'drop' };
261
- return { kind: 'node', id: node.id };
262
- });
263
- return asSystemsLevel(collapsed, { all: nodes, allEdges: edges, containers });
264
- };
265
-
266
- /**
267
- * The graph for a level (not laid out: positions come from the layout). Notes aren't in it: the ones added on the
268
- * level are shown where they were put, over its layout.
269
- */
270
- export const getLevelGraph = (nodes: Node[], edges: Edge[], level: Level) => {
271
- if (level === 3) return { nodes, edges };
272
- const withoutNotes = nodes.filter((node) => node.type !== 'note');
273
- return sizedByLayout(level === 1 ? level1(withoutNotes, edges) : level2(withoutNotes, edges));
274
- };
275
-
276
- /** Why a level can't be shown for this canvas, if it can't */
277
- export const getLevelUnavailableReason = (nodes: Node[], level: Level): string | undefined => {
278
- // Like the visualiser: L1 needs systems, or domains to relate (one domain on its own has nothing to show)
279
- if (level === 1 && !nodes.some(isSystem) && nodes.filter(isDomain).length < 2)
280
- return 'Not available: add a system, or more than one domain, to see how they relate';
281
- return undefined;
282
- };