@eventcatalog/core 5.0.0-beta.8 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +234 -134
- package/README.md +5 -5
- package/dist/analytics/analytics.cjs +18 -3
- package/dist/analytics/analytics.d.cts +1 -1
- package/dist/analytics/analytics.d.ts +1 -1
- package/dist/analytics/analytics.js +3 -2
- package/dist/analytics/log-build.cjs +157 -76
- package/dist/analytics/log-build.d.cts +2 -2
- package/dist/analytics/log-build.d.ts +2 -2
- package/dist/analytics/log-build.js +7 -5
- package/dist/analytics/studio-usage.cjs +90 -0
- package/dist/analytics/studio-usage.d.cts +5 -0
- package/dist/analytics/studio-usage.d.ts +5 -0
- package/dist/analytics/studio-usage.js +10 -0
- package/dist/analytics/telemetry.cjs +42 -0
- package/dist/analytics/telemetry.d.cts +20 -0
- package/dist/analytics/telemetry.d.ts +20 -0
- package/dist/analytics/telemetry.js +8 -0
- package/dist/catalog-runtime.cjs +1 -1
- package/dist/{chunk-RFIXKATC.js → chunk-4G7FSRPN.js} +35 -42
- package/dist/{chunk-AWOO63ME.js → chunk-AD7CL772.js} +11 -4
- package/dist/chunk-CA6WCQ2T.js +54 -0
- package/dist/chunk-CPW6G62V.js +17 -0
- package/dist/{chunk-PU25TOOJ.js → chunk-JZN4RSMF.js} +1 -1
- package/dist/{chunk-4W55ZOOS.js → chunk-NEAVAFSJ.js} +66 -35
- package/dist/{chunk-C6T2AAFR.js → chunk-NIVST4WY.js} +9 -3
- package/dist/{chunk-ENAG6UH7.js → chunk-NKNOXQ62.js} +1 -6
- package/dist/{chunk-AYNZXUB5.js → chunk-OX6TSVHY.js} +5 -5
- package/dist/{chunk-36RYTYT5.js → chunk-PD7KTSYN.js} +1 -1
- package/dist/{chunk-RDIZJ7UT.js → chunk-RE7UTPWH.js} +1 -1
- package/dist/chunk-S5GWAUG5.js +29 -0
- package/dist/{chunk-T4G3VVZ4.js → chunk-YQGRMDRB.js} +4 -2
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/docs/api/02-config.md +57 -7
- package/dist/docs/development/00-why-eventcatalog.md +11 -11
- package/dist/docs/development/01-fundamentals.md +20 -13
- package/dist/docs/development/01-getting-started/configuration-overview.md +2 -2
- package/dist/docs/development/01-getting-started/installation.md +9 -1
- package/dist/docs/development/_getting-started.mdx +1 -1
- package/dist/docs/development/ask-your-architecture/01-intro.md +5 -5
- package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/01-what-is-eventcatalog-assistant.md +0 -4
- package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/02-configuration.md +15 -3
- package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/03-bring-your-own-tools.md +0 -3
- package/dist/docs/development/ask-your-architecture/02-eventcatalog-assistant/_category_.json +1 -1
- package/dist/docs/development/ask-your-architecture/02-llms.txt.md +1 -1
- package/dist/docs/development/ask-your-architecture/{05-skills/01-introduction.md → 03-install-skills.md} +57 -7
- package/dist/docs/development/ask-your-architecture/03-mcp-server/_category_.json +1 -1
- package/dist/docs/development/ask-your-architecture/03-mcp-server/getting-started.md +86 -33
- package/dist/docs/development/ask-your-architecture/03-mcp-server/introduction.md +14 -4
- package/dist/docs/development/ask-your-architecture/03-schemas.txt.md +1 -1
- package/dist/docs/development/ask-your-architecture/04-agents/_category_.json +1 -1
- package/dist/docs/development/authentication/01-introduction.md +2 -23
- package/dist/docs/development/authentication/02-enabling-authentication.md +0 -20
- package/dist/docs/development/authentication/07-rbac-middleware.md +0 -2
- package/dist/docs/development/authentication/providers/03-setting-up-github.md +0 -2
- package/dist/docs/development/authentication/providers/03a-setting-up-google.md +0 -2
- package/dist/docs/development/authentication/providers/04-setting-up-azure-ad.md +0 -2
- package/dist/docs/development/authentication/providers/05-setting-up-okta.md +0 -3
- package/dist/docs/development/authentication/providers/06-setting-up-auth0.md +0 -2
- package/dist/docs/development/bring-your-own-documentation/01-introduction.md +0 -4
- package/dist/docs/development/bring-your-own-documentation/custom-pages/01-introduction.md +0 -3
- package/dist/docs/development/bring-your-own-documentation/custom-pages/02-adding-custom-docs.md +0 -17
- package/dist/docs/development/bring-your-own-documentation/custom-pages/03-components.md +0 -4
- package/dist/docs/development/bring-your-own-documentation/custom-pages/04-owners.md +0 -2
- package/dist/docs/development/bring-your-own-documentation/resource-docs/01-introduction.md +1 -3
- package/dist/docs/development/bring-your-own-documentation/resource-docs/02-adding-resource-docs.md +1 -4
- package/dist/docs/development/bring-your-own-documentation/resource-docs/03-categories.md +0 -2
- package/dist/docs/development/bring-your-own-documentation/resource-docs/04-versioning.md +1 -3
- package/dist/docs/development/components/components/11-flow.md +17 -0
- package/dist/docs/development/components/components/15-nodegraph.md +43 -10
- package/dist/docs/development/components/components/18-remote-schema.md +1 -4
- package/dist/docs/development/components/custom-components/07-reference.md +14 -0
- package/dist/docs/development/customization/02-themes.md +0 -5
- package/dist/docs/development/customization/03-search.md +1 -1
- package/dist/docs/development/customization/05-custom-pages-and-api-routes/01-introduction.md +0 -2
- package/dist/docs/development/customization/05-custom-pages-and-api-routes/04-reference.md +7 -1
- package/dist/docs/development/customization/05-resource-sidebar.md +1 -1
- package/dist/docs/development/customization/09-embed-eventcatalog.md +20 -25
- package/dist/docs/development/deployment/hosting-options.md +7 -2
- package/dist/docs/development/developer-tools/eventcatalog-linter/how-to/05-fix-common-problems.md +16 -0
- package/dist/docs/development/developer-tools/eventcatalog-linter/reference/03-rules.md +31 -1
- package/dist/docs/development/developer-tools/eventcatalog-linter/reference/05-supported-resources.md +1 -1
- package/dist/docs/development/governance/architecture-change-detection/01-introduction.md +0 -10
- package/dist/docs/development/governance/architecture-change-detection/06-pipeline-gates.md +0 -4
- package/dist/docs/development/guides/97-architecture-graph.md +1 -1
- package/dist/docs/development/guides/99-adding-analytics.md +0 -7
- package/dist/docs/development/guides/domains/03-model-subdomains.md +2 -2
- package/dist/docs/development/guides/domains/04-add-resources-to-domains/01-add-systems-to-domains.md +3 -1
- package/dist/docs/development/guides/domains/04-add-resources-to-domains/02-add-services-to-domains.md +5 -1
- package/dist/docs/development/guides/domains/04-add-resources-to-domains/03-add-messages-to-domains.md +2 -2
- package/dist/docs/development/guides/domains/04-add-resources-to-domains/05-add-entities-to-domains.md +1 -1
- package/dist/docs/development/guides/domains/04-add-resources-to-domains/06-domain-resources-page.md +40 -0
- package/dist/docs/development/guides/domains/06-visualize-domains/01-domain-diagram.md +89 -0
- package/dist/docs/development/guides/domains/06-visualize-domains/_category_.json +1 -2
- package/dist/docs/development/guides/domains/09-reference.md +4 -4
- package/dist/docs/development/guides/owners/automated-teams-and-users/create-your-own-connector.md +0 -2
- package/dist/docs/development/guides/owners/automated-teams-and-users/sync-from-github.md +0 -3
- package/dist/docs/development/guides/owners/automated-teams-and-users/sync-from-microsoft-entra.md +0 -2
- package/dist/docs/development/guides/resources/adrs/03-linking-resources.md +8 -0
- package/dist/docs/development/guides/resources/adrs/06-reference.md +4 -4
- package/dist/docs/development/guides/resources/agents/11-reference.md +1 -1
- package/dist/docs/development/guides/resources/data/04-reference.md +1 -1
- package/dist/docs/development/guides/resources/data-products/07-reference.md +1 -1
- package/dist/docs/development/guides/resources/entities/05-entity-maps.md +1 -1
- package/dist/docs/development/guides/resources/entities/06-reference.md +2 -2
- package/dist/docs/development/guides/resources/flows/01-introduction.md +11 -1
- package/dist/docs/development/guides/resources/flows/03-model-flow-steps.md +65 -6
- package/dist/docs/development/guides/resources/flows/05-explore-flows.md +112 -0
- package/dist/docs/development/guides/resources/flows/06-reference.md +25 -4
- package/dist/docs/development/guides/resources/messages/01-what-are-messages.md +19 -0
- package/dist/docs/development/guides/resources/messages/04-message-channels/01-introduction.md +16 -0
- package/dist/docs/development/guides/resources/messages/04-message-channels/05-reference.md +2 -1
- package/dist/docs/development/guides/resources/messages/10-reference.md +6 -3
- package/dist/docs/development/guides/resources/schemas/04-explore-schemas/01-schema-explorer.md +2 -2
- package/dist/docs/development/guides/resources/schemas/04-explore-schemas/02-fields-explorer.md +0 -9
- package/dist/docs/development/guides/resources/schemas/05-schema-api.md +0 -3
- package/dist/docs/development/guides/resources/schemas/06-schema-mcp.md +11 -3
- package/dist/docs/development/guides/resources/services/04-add-resources-to-services/03-add-entities-to-services.md +1 -1
- package/dist/docs/development/guides/resources/services/05-resources-page.md +50 -0
- package/dist/docs/development/guides/resources/services/08-reference.md +2 -1
- package/dist/docs/development/guides/systems/01-introduction.md +1 -1
- package/dist/docs/development/guides/systems/02-create-system.md +2 -2
- package/dist/docs/development/guides/systems/03-add-resources-to-systems.md +35 -9
- package/dist/docs/development/guides/systems/04-model-relationships-and-actors.md +5 -3
- package/dist/docs/development/guides/systems/05-system-context-maps.md +39 -22
- package/dist/docs/development/guides/systems/06-reference.md +4 -4
- package/dist/docs/development/license/01-license-file.md +151 -0
- package/dist/docs/development/license/_category_.json +12 -0
- package/dist/docs/development/license-keys/_category_.json +3 -3
- package/dist/docs/development/license-keys/integrations.md +7 -37
- package/dist/docs/development/license-keys/license-validation.md +4 -0
- package/dist/docs/development/license-keys/overview.md +5 -1
- package/dist/docs/development/license-keys/plans.md +4 -2
- package/dist/docs/development/studio/01-introduction.md +60 -0
- package/dist/docs/development/studio/02-create-a-canvas.md +103 -0
- package/dist/docs/development/studio/03-set-up-persistent-storage.md +59 -0
- package/dist/docs/development/studio/04-collaborate-on-a-canvas.md +78 -0
- package/dist/docs/development/studio/05-connect-your-agent.md +102 -0
- package/dist/docs/development/studio/06-run-studio-in-production.md +54 -0
- package/dist/docs/development/studio/07-reference.md +294 -0
- package/dist/docs/development/studio/_category_.json +12 -0
- package/dist/docs/development/upgrading/v5.md +345 -0
- package/dist/docs/federation/00-overview.md +2 -8
- package/dist/docs/federation/01-first-federation.md +6 -18
- package/dist/docs/federation/explanation/how-it-works.md +0 -4
- package/dist/docs/federation/explanation/lockfile-and-cache.md +0 -4
- package/dist/docs/federation/explanation/mvp-status-and-feedback.md +0 -4
- package/dist/docs/federation/explanation/ownership-and-references.md +0 -4
- package/dist/docs/federation/how-to/configure-github-sources.md +6 -5
- package/dist/docs/federation/how-to/configure-validation-rules.md +0 -4
- package/dist/docs/federation/how-to/run-in-ci.md +2 -9
- package/dist/docs/federation/how-to/share-assets-and-components.md +0 -4
- package/dist/docs/federation/how-to/use-local-sources.md +0 -4
- package/dist/docs/federation/legacy-federation/00-introduction.md +4 -22
- package/dist/docs/federation/legacy-federation/01-installation.md +7 -58
- package/dist/docs/federation/legacy-federation/02-plugin-configuration.md +3 -21
- package/dist/docs/federation/legacy-federation/03-examples.md +3 -5
- package/dist/docs/federation/legacy-federation/04-configuration.md +3 -8
- package/dist/docs/federation/legacy-federation/05-setup-team-catalog.md +3 -6
- package/dist/docs/federation/reference/cli.md +2 -8
- package/dist/docs/federation/reference/configuration.md +0 -4
- package/dist/docs/federation/reference/diagnostic-rules.md +0 -5
- package/dist/docs/federation/reference/generated-output.md +0 -4
- package/dist/docs/federation/reference/supported-content.md +0 -4
- package/dist/docs/federation/reference/troubleshooting.md +0 -14
- package/dist/docs/plugins/02-generators.md +1 -1
- package/dist/docs/plugins/amazon-apigateway/00-intro.md +3 -28
- package/dist/docs/plugins/amazon-apigateway/01-installation.md +4 -56
- package/dist/docs/plugins/amazon-apigateway/02-plugin-configuration.md +1 -6
- package/dist/docs/plugins/apicurio/00-intro.md +2 -31
- package/dist/docs/plugins/apicurio/01-installation.md +2 -26
- package/dist/docs/plugins/apicurio/02-plugin-configuration.md +5 -13
- package/dist/docs/plugins/apicurio/03-features.md +1 -3
- package/dist/docs/plugins/asyncapi/00-intro.md +2 -28
- package/dist/docs/plugins/asyncapi/01-installation.md +3 -54
- package/dist/docs/plugins/asyncapi/02-plugin-configuration.md +2 -1
- package/dist/docs/plugins/aws-glue-registry/00-intro.md +4 -32
- package/dist/docs/plugins/aws-glue-registry/00a-installation.md +3 -53
- package/dist/docs/plugins/azure-schema-registry/00-intro.md +4 -32
- package/dist/docs/plugins/azure-schema-registry/01-installation.md +6 -33
- package/dist/docs/plugins/azure-schema-registry/02-plugin-configuration.md +1 -14
- package/dist/docs/plugins/azure-schema-registry/04-examples.md +0 -2
- package/dist/docs/plugins/backstage/00-overview.md +1 -7
- package/dist/docs/plugins/backstage/01-get-started.md +6 -15
- package/dist/docs/plugins/backstage/06-configuration.md +2 -8
- package/dist/docs/plugins/confluent-schema-registry/00-intro.md +2 -29
- package/dist/docs/plugins/confluent-schema-registry/01-installation.md +2 -26
- package/dist/docs/plugins/eventbridge/00-intro.md +0 -4
- package/dist/docs/plugins/eventbridge/00a-installation.md +1 -87
- package/dist/docs/plugins/eventbridge/03-api.md +2 -20
- package/dist/docs/plugins/github/00-intro.md +0 -31
- package/dist/docs/plugins/github/01-installation.md +2 -34
- package/dist/docs/plugins/graphql/00-intro.md +0 -30
- package/dist/docs/plugins/graphql/01-installation.md +1 -53
- package/dist/docs/plugins/graphql/02-plugin-configuration.md +0 -1
- package/dist/docs/plugins/hookdeck/01-intro.md +1 -1
- package/dist/docs/plugins/openapi/00-intro.md +0 -30
- package/dist/docs/plugins/openapi/01-installation.md +1 -57
- package/dist/docs/plugins/openapi/02-plugin-configuration.md +0 -5
- package/dist/docs/plugins/openapi/03-features.md +0 -4
- package/dist/eventcatalog-config-file-utils.cjs +34 -41
- package/dist/eventcatalog-config-file-utils.d.cts +56 -58
- package/dist/eventcatalog-config-file-utils.d.ts +56 -58
- package/dist/eventcatalog-config-file-utils.js +1 -1
- package/dist/eventcatalog.cjs +408 -281
- package/dist/eventcatalog.config.d.cts +26 -15
- package/dist/eventcatalog.config.d.ts +26 -15
- package/dist/eventcatalog.js +46 -27
- package/dist/features.cjs +36 -49
- package/dist/features.d.cts +1 -3
- package/dist/features.d.ts +1 -3
- package/dist/features.js +4 -6
- package/dist/federation/federate.cjs +37 -44
- package/dist/federation/federate.js +5 -5
- package/dist/federation/source-provider.js +2 -2
- package/dist/generate.cjs +37 -42
- package/dist/generate.js +4 -4
- package/dist/resolve-catalog-dependencies.cjs +34 -41
- package/dist/resolve-catalog-dependencies.js +2 -2
- package/dist/runtime-dependencies/@eventcatalog__visualiser__studio-fonts.css.mjs +3 -0
- package/dist/runtime-dependencies/@eventcatalog__visualiser__studio.css.mjs +3 -0
- package/dist/runtime-dependencies/@eventcatalog__visualiser__studio.mjs +3 -0
- package/dist/runtime-dependencies/htmlparser2.mjs +3 -0
- package/dist/runtime-dependencies/manifest.json +5 -1
- package/dist/runtime-dependencies/react-syntax-highlighter__dist__cjs__create-element.js.mjs +3 -0
- package/dist/utils/child-process-signals.cjs +53 -0
- package/dist/utils/child-process-signals.d.cts +19 -0
- package/dist/utils/child-process-signals.d.ts +19 -0
- package/dist/utils/child-process-signals.js +6 -0
- package/dist/utils/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/dist/utils/license-status.cjs +11 -4
- package/dist/utils/license-status.d.cts +3 -2
- package/dist/utils/license-status.d.ts +3 -2
- package/dist/utils/license-status.js +1 -1
- package/eventcatalog/astro.config.mjs +21 -1
- package/eventcatalog/integrations/config-loader.mjs +56 -58
- package/eventcatalog/integrations/skip-startup-reload.mjs +31 -0
- package/eventcatalog/integrations/stable-dependency-order.mjs +29 -0
- package/eventcatalog/integrations/storage.mjs +20 -0
- package/eventcatalog/integrations/studio-server.mjs +4 -1
- package/eventcatalog/src/components/CatalogGraph/CatalogForceGraph.tsx +39 -0
- package/eventcatalog/src/components/ChatPanel/ChatPanel.tsx +2 -0
- package/eventcatalog/src/components/Homepage/CatalogDashboard.astro +342 -0
- package/eventcatalog/src/components/MDX/NodeGraph/AstroNodeGraph.tsx +60 -4
- package/eventcatalog/src/components/MDX/NodeGraph/NodeGraph.astro +5 -1
- package/eventcatalog/src/components/NavigationProgress.astro +7 -0
- package/eventcatalog/src/components/SchemaExplorer/ApiContentViewer.tsx +2 -0
- package/eventcatalog/src/components/SchemaExplorer/ExamplesViewer.tsx +2 -0
- package/eventcatalog/src/components/SchemaExplorer/SchemaCodeModal.tsx +2 -0
- package/eventcatalog/src/components/SchemaExplorer/SchemaContentViewer.tsx +2 -0
- package/eventcatalog/src/components/Search/SearchDataLoader.astro +16 -28
- package/eventcatalog/src/components/Search/SearchModal.tsx +2 -10
- package/eventcatalog/src/components/Search/search-utils.ts +26 -0
- package/eventcatalog/src/components/Seo.astro +5 -1
- package/eventcatalog/src/components/Settings/AssistantSettingsForm.tsx +53 -48
- package/eventcatalog/src/components/Settings/GeneralSettingsForm.tsx +183 -178
- package/eventcatalog/src/components/Settings/LicenseSettings.tsx +140 -31
- package/eventcatalog/src/components/Settings/LlmAccessSettingsForm.tsx +40 -35
- package/eventcatalog/src/components/Settings/LogoUpload.tsx +1 -1
- package/eventcatalog/src/components/Settings/McpSettingsForm.tsx +9 -8
- package/eventcatalog/src/components/Settings/Row.tsx +7 -4
- package/eventcatalog/src/components/Settings/SettingsShared.tsx +3 -3
- package/eventcatalog/src/components/SideNav/NestedSideBar/index.tsx +37 -76
- package/eventcatalog/src/components/SideNav/NestedSideBar/storage.ts +2 -0
- package/eventcatalog/src/components/SideNav/NestedSideBar/utils.ts +122 -1
- package/eventcatalog/src/components/SideNav/SideNav.astro +9 -1
- package/eventcatalog/src/components/TrialBadge.astro +20 -9
- package/eventcatalog/src/content.config.ts +19 -2
- package/eventcatalog/src/features/auth/error.astro +4 -2
- package/eventcatalog/src/features/auth/login.astro +2 -1
- package/eventcatalog/src/features/auth/middleware/middleware-auth.ts +21 -1
- package/eventcatalog/src/features/auth/unauthorized.astro +1 -1
- package/eventcatalog/src/features/fields/pages/fields.astro +1 -1
- package/eventcatalog/src/features/integrations/eventcatalog-features.ts +13 -7
- package/eventcatalog/src/features/mcp/apps/architecture-diagram/node-chat.tsx +6 -45
- package/eventcatalog/src/features/mcp/apps/canvas/shared.ts +3 -3
- package/eventcatalog/src/features/mcp/apps/canvas/styles.css +3 -1
- package/eventcatalog/src/features/mcp/apps/canvas/view.tsx +7 -5
- package/eventcatalog/src/features/mcp/apps/generated/canvas.html +123 -98
- package/eventcatalog/src/features/mcp/apps/generated/viewer.html +118 -101
- package/eventcatalog/src/features/mcp/mcp-server.ts +20 -4
- package/eventcatalog/src/features/server/start.ts +25 -0
- package/eventcatalog/src/features/storage/database.ts +88 -0
- package/eventcatalog/src/features/storage/migrations.ts +85 -0
- package/eventcatalog/src/features/storage/sql/database.sql +5 -0
- package/eventcatalog/src/features/storage/sql/migrations/0001-studio-canvases.sql +12 -0
- package/eventcatalog/src/features/storage/sql/migrations.sql +15 -0
- package/eventcatalog/src/features/storage/sql.ts +28 -0
- package/eventcatalog/src/features/studio/agent-choreography.ts +13 -10
- package/eventcatalog/src/features/studio/agents.ts +28 -0
- package/eventcatalog/src/features/studio/api/canvases-api.ts +219 -0
- package/eventcatalog/src/features/studio/api/canvases.ts +25 -0
- package/eventcatalog/src/features/studio/api/client.ts +40 -0
- package/eventcatalog/src/features/studio/canvas-actions.ts +160 -34
- package/eventcatalog/src/features/studio/canvas-preview.ts +1 -2
- package/eventcatalog/src/features/studio/catalog.ts +16 -14
- package/eventcatalog/src/features/studio/components/CanvasHeader.tsx +274 -105
- package/eventcatalog/src/features/studio/components/CanvasStatusMenu.tsx +15 -14
- package/eventcatalog/src/features/studio/components/ConnectAgentDialog.tsx +272 -119
- package/eventcatalog/src/features/studio/components/ConnectionsChooser.tsx +1 -2
- package/eventcatalog/src/features/studio/components/DeleteCanvasDialog.tsx +65 -0
- package/eventcatalog/src/features/studio/components/Dialog.tsx +60 -0
- package/eventcatalog/src/features/studio/components/JoinForm.tsx +101 -26
- package/eventcatalog/src/features/studio/components/LeftPanel.tsx +122 -230
- package/eventcatalog/src/features/studio/components/NodeDetails.tsx +183 -0
- package/eventcatalog/src/features/studio/components/OpenInStudioDialog.tsx +79 -0
- package/eventcatalog/src/features/studio/components/Presence.tsx +52 -45
- package/eventcatalog/src/features/studio/components/ShareDialog.tsx +277 -141
- package/eventcatalog/src/features/studio/components/ShortcutsDialog.tsx +41 -0
- package/eventcatalog/src/features/studio/components/StudioDesigner.tsx +1314 -385
- package/eventcatalog/src/features/studio/components/StudioNotice.astro +24 -0
- package/eventcatalog/src/features/studio/document-name.ts +7 -0
- package/eventcatalog/src/features/studio/from-visualiser.ts +138 -0
- package/eventcatalog/src/features/studio/hooks/presence-sender.ts +19 -2
- package/eventcatalog/src/features/studio/hooks/use-canvas-webmcp.ts +9 -3
- package/eventcatalog/src/features/studio/hooks/use-comments.ts +2 -2
- package/eventcatalog/src/features/studio/hooks/use-follow-camera.ts +8 -3
- package/eventcatalog/src/features/studio/hooks/use-studio-flow.ts +244 -32
- package/eventcatalog/src/features/studio/identity.ts +25 -1
- package/eventcatalog/src/features/studio/limits.ts +2 -0
- package/eventcatalog/src/features/studio/pages/[id].astro +42 -16
- package/eventcatalog/src/features/studio/pages/index.astro +596 -373
- package/eventcatalog/src/features/studio/pages/webmcp-relay.ts +12 -15
- package/eventcatalog/src/features/studio/server/canvas-mcp.ts +8 -23
- package/eventcatalog/src/features/studio/server/runtime.ts +150 -46
- package/eventcatalog/src/features/studio/server/sql/storage.sql +18 -0
- package/eventcatalog/src/features/studio/server/storage.ts +53 -73
- package/eventcatalog/src/features/studio/webmcp-relay/LICENSE +21 -0
- package/eventcatalog/src/features/studio/webmcp-relay/README.md +5 -0
- package/eventcatalog/src/features/studio/webmcp-relay/embed.js +2 -0
- package/eventcatalog/src/features/studio/webmcp-relay/widget.html +10 -0
- package/eventcatalog/src/features/studio/webmcp-relay/widget.js +1 -0
- package/eventcatalog/src/features/tools/catalog-tools.ts +3 -1
- package/eventcatalog/src/layouts/BaseLayout.astro +4 -4
- package/eventcatalog/src/layouts/SettingsLayout.astro +2 -2
- package/eventcatalog/src/layouts/VerticalSideBarLayout.astro +3 -2
- package/eventcatalog/src/pages/_index.astro +5 -342
- package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.spec.ts +2 -3
- package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/architecture/[type]/[id]/[version]/index.astro +3 -1
- package/eventcatalog/src/pages/diagrams/[id]/[version]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/diagrams/[id]/[version]/embed.astro +1 -0
- package/eventcatalog/src/pages/diagrams/[id]/[version]/index.astro +1 -0
- package/eventcatalog/src/pages/directory/[type]/_index.data.ts +5 -7
- package/eventcatalog/src/pages/directory/[type]/index.astro +3 -1
- package/eventcatalog/src/pages/discover/[type]/_index.data.ts +5 -7
- package/eventcatalog/src/pages/discover/[type]/index.astro +3 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/[docVersion]/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/[docType]/[docId]/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/[filename].astro +3 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/asyncapi/_[filename].data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/changelog/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/examples/[...filename].astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/examples/_[...filename].data.ts +0 -4
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/field-lineage/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/field-lineage/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/[filename].astro +3 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/graphql/_[filename].data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.spec.ts +2 -3
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/resources/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/[filename].astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/[version]/spec/_[filename].data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/index.astro +2 -1
- package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/language/[dictionaryId]/index.astro +1 -0
- package/eventcatalog/src/pages/docs/[type]/[id]/language/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/[type]/[id]/language/index.astro +1 -0
- package/eventcatalog/src/pages/docs/custom/[...path]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/custom/[...path]/index.astro +1 -0
- package/eventcatalog/src/pages/docs/services/[id]/[docType]/[docId]/index.astro +1 -1
- package/eventcatalog/src/pages/docs/services/[id]/[version]/resources/index.astro +1 -0
- package/eventcatalog/src/pages/docs/services/[id]/asyncapi/[filename].astro +1 -1
- package/eventcatalog/src/pages/docs/services/[id]/changelog/index.astro +1 -1
- package/eventcatalog/src/pages/docs/services/[id]/graphql/[filename].astro +1 -1
- package/eventcatalog/src/pages/docs/services/[id]/spec/[filename].astro +1 -1
- package/eventcatalog/src/pages/docs/teams/[id]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/teams/[id]/index.astro +1 -0
- package/eventcatalog/src/pages/docs/users/[id]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/docs/users/[id]/index.astro +1 -0
- package/eventcatalog/src/pages/index.astro +4 -2
- package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/schemas/[type]/[id]/[version]/index.astro +9 -1
- package/eventcatalog/src/pages/schemas/explorer/_index.data.ts +0 -7
- package/eventcatalog/src/pages/schemas/explorer/index.astro +4 -2
- package/eventcatalog/src/pages/settings/license.astro +9 -1
- package/eventcatalog/src/pages/triggers/[type]/[id]/[version]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/triggers/[type]/[id]/[version]/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/data/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/entity-map/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/[version]/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/_index.data.ts +38 -0
- package/eventcatalog/src/pages/visualiser/[type]/[id]/index.astro +18 -41
- package/eventcatalog/src/pages/visualiser/designs/[id]/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/designs/[id]/index.astro +2 -1
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/entity-map/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/domains/[id]/[version]/systems-context/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/_index.data.ts +0 -7
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/context/index.astro +1 -0
- package/eventcatalog/src/pages/visualiser/systems/[id]/[version]/index.astro +1 -0
- package/eventcatalog/src/types/react-syntax-highlighter.d.ts +10 -0
- package/eventcatalog/src/utils/collections/flows.ts +20 -7
- package/eventcatalog/src/utils/collections/resource-owners.ts +8 -2
- package/eventcatalog/src/utils/collections/resources.ts +2 -0
- package/eventcatalog/src/utils/collections/util.ts +8 -4
- package/eventcatalog/src/utils/git.ts +11 -0
- package/eventcatalog/src/utils/homepage-dashboard.ts +143 -0
- package/eventcatalog/src/utils/license.ts +1 -1
- package/eventcatalog/src/utils/link-validation.ts +25 -19
- package/eventcatalog/src/utils/node-graphs/domain-entity-map.ts +3 -1
- package/eventcatalog/src/utils/node-graphs/domain-levels-node-graph.ts +3 -3
- package/eventcatalog/src/utils/node-graphs/field-node-graph.ts +4 -2
- package/eventcatalog/src/utils/node-graphs/layout-node-graph.ts +20 -1
- package/eventcatalog/src/utils/node-graphs/node-resource.ts +67 -0
- package/eventcatalog/src/utils/node-graphs/systems-node-graph.ts +1 -1
- package/eventcatalog/src/utils/page-loaders/hybrid-page.ts +4 -15
- package/eventcatalog/src/utils/page-title.ts +15 -0
- package/eventcatalog/src/utils/syntax-highlighter-renderer.ts +64 -0
- package/eventcatalog/src/utils/trial.ts +13 -0
- package/package.json +11 -11
- package/dist/docs/development/ask-your-architecture/05-skills/02-installation.md +0 -60
- package/dist/docs/development/ask-your-architecture/05-skills/_category_.json +0 -11
- package/dist/docs/development/ask-your-architecture/06-slack-integration/01-introduction.md +0 -63
- package/dist/docs/development/ask-your-architecture/06-slack-integration/02-slack-app-setup.md +0 -154
- package/dist/docs/development/ask-your-architecture/06-slack-integration/03-installation.md +0 -169
- package/dist/docs/development/ask-your-architecture/06-slack-integration/04-deployment.md +0 -236
- package/dist/docs/development/ask-your-architecture/06-slack-integration/05-usage.md +0 -140
- package/dist/docs/development/ask-your-architecture/06-slack-integration/06-troubleshooting.md +0 -268
- package/dist/docs/development/ask-your-architecture/06-slack-integration/_category_.json +0 -13
- package/dist/docs/development/guides/domains/06-visualize-domains/01-domain-integration-map.md +0 -40
- package/dist/runtime-dependencies/@mcp-b__webmcp-local-relay.mjs +0 -3
- package/eventcatalog/src/features/studio/canvas-doc.ts +0 -409
- package/eventcatalog/src/features/studio/clipboard.ts +0 -97
- package/eventcatalog/src/features/studio/components/CanvasControls.tsx +0 -154
- package/eventcatalog/src/features/studio/components/Comments.tsx +0 -770
- package/eventcatalog/src/features/studio/components/ContainerChooser.tsx +0 -145
- package/eventcatalog/src/features/studio/components/DragGhost.tsx +0 -115
- package/eventcatalog/src/features/studio/components/Picture.tsx +0 -21
- package/eventcatalog/src/features/studio/components/PropertiesPanel.tsx +0 -212
- package/eventcatalog/src/features/studio/components/canvas-nodes.tsx +0 -255
- package/eventcatalog/src/features/studio/components/icons.ts +0 -53
- package/eventcatalog/src/features/studio/components/status.ts +0 -51
- package/eventcatalog/src/features/studio/edges.ts +0 -56
- package/eventcatalog/src/features/studio/flow-state.ts +0 -92
- package/eventcatalog/src/features/studio/grouping.ts +0 -226
- package/eventcatalog/src/features/studio/layout.ts +0 -42
- package/eventcatalog/src/features/studio/levels.ts +0 -282
- package/eventcatalog/src/features/studio/node-types.ts +0 -205
- package/eventcatalog/src/features/studio/pages/new.astro +0 -24
- package/eventcatalog/src/features/studio/pages/wake.ts +0 -15
- package/eventcatalog/src/features/studio/placement.ts +0 -197
- package/eventcatalog/src/features/studio/studio.css +0 -273
- package/dist/{chunk-A2RZR3U4.js → chunk-6K7XZAYI.js} +3 -3
|
@@ -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
|
-
};
|