@documentation-robotics/cli 0.1.0 → 0.1.5
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 +21 -0
- package/README.md +466 -693
- package/dist/analysis/data-model-analyzer.js +189 -0
- package/dist/analysis/data-model-analyzer.js.map +7 -0
- package/dist/analysis/index.js +3 -0
- package/dist/analysis/index.js.map +7 -0
- package/dist/analysis/relationship-classifier.js +181 -0
- package/dist/analysis/relationship-classifier.js.map +7 -0
- package/dist/analyzers/base-analyzer.js +1 -0
- package/dist/analyzers/base-analyzer.js.map +7 -0
- package/dist/analyzers/call-graph-utils.js +39 -0
- package/dist/analyzers/call-graph-utils.js.map +7 -0
- package/dist/analyzers/cbm-analyzer.js +1205 -0
- package/dist/analyzers/cbm-analyzer.js.map +7 -0
- package/dist/analyzers/heuristic-utils.js +55 -0
- package/dist/analyzers/heuristic-utils.js.map +7 -0
- package/dist/analyzers/mapping-loader.js +146 -0
- package/dist/analyzers/mapping-loader.js.map +7 -0
- package/dist/analyzers/registry.js +124 -0
- package/dist/analyzers/registry.js.map +7 -0
- package/dist/analyzers/session-state.js +176 -0
- package/dist/analyzers/session-state.js.map +7 -0
- package/dist/analyzers/stdio-client.js +206 -0
- package/dist/analyzers/stdio-client.js.map +7 -0
- package/dist/analyzers/types.js +15 -0
- package/dist/analyzers/types.js.map +7 -0
- package/dist/analyzers/verify-engine.js +209 -0
- package/dist/analyzers/verify-engine.js.map +7 -0
- package/dist/analyzers/verify-ignore.js +130 -0
- package/dist/analyzers/verify-ignore.js.map +7 -0
- package/dist/analyzers/version.js +8 -0
- package/dist/analyzers/version.js.map +7 -0
- package/dist/audit/ai/runner.js +41 -0
- package/dist/audit/ai/runner.js.map +7 -0
- package/dist/audit/differential-analyzer.js +183 -0
- package/dist/audit/differential-analyzer.js.map +7 -0
- package/dist/audit/index.js +32 -0
- package/dist/audit/index.js.map +7 -0
- package/dist/audit/nodes/ai/evaluator.js +49 -0
- package/dist/audit/nodes/ai/evaluator.js.map +7 -0
- package/dist/audit/nodes/ai/parser.js +55 -0
- package/dist/audit/nodes/ai/parser.js.map +7 -0
- package/dist/audit/nodes/ai/prompts.js +103 -0
- package/dist/audit/nodes/ai/prompts.js.map +7 -0
- package/dist/audit/nodes/analysis/node-completeness-checker.js +32 -0
- package/dist/audit/nodes/analysis/node-completeness-checker.js.map +7 -0
- package/dist/audit/nodes/analysis/node-definition-analyzer.js +47 -0
- package/dist/audit/nodes/analysis/node-definition-analyzer.js.map +7 -0
- package/dist/audit/nodes/analysis/node-overlap-detector.js +79 -0
- package/dist/audit/nodes/analysis/node-overlap-detector.js.map +7 -0
- package/dist/audit/nodes/model/orchestrator.js +82 -0
- package/dist/audit/nodes/model/orchestrator.js.map +7 -0
- package/dist/audit/nodes/spec/loader.js +116 -0
- package/dist/audit/nodes/spec/loader.js.map +7 -0
- package/dist/audit/nodes/spec/orchestrator.js +68 -0
- package/dist/audit/nodes/spec/orchestrator.js.map +7 -0
- package/dist/audit/nodes/types.js +1 -0
- package/dist/audit/nodes/types.js.map +7 -0
- package/dist/audit/pipeline/index.js +5 -0
- package/dist/audit/pipeline/index.js.map +7 -0
- package/dist/audit/pipeline/pipeline-orchestrator.js +218 -0
- package/dist/audit/pipeline/pipeline-orchestrator.js.map +7 -0
- package/dist/audit/relationships/ai/evaluator.js +235 -0
- package/dist/audit/relationships/ai/evaluator.js.map +7 -0
- package/dist/audit/relationships/ai/parser.js +197 -0
- package/dist/audit/relationships/ai/parser.js.map +7 -0
- package/dist/audit/relationships/ai/prompts.js +274 -0
- package/dist/audit/relationships/ai/prompts.js.map +7 -0
- package/dist/audit/relationships/analysis/balance-assessor.js +115 -0
- package/dist/audit/relationships/analysis/balance-assessor.js.map +7 -0
- package/dist/audit/relationships/analysis/coverage-analyzer.js +99 -0
- package/dist/audit/relationships/analysis/coverage-analyzer.js.map +7 -0
- package/dist/audit/relationships/analysis/duplicate-detector.js +95 -0
- package/dist/audit/relationships/analysis/duplicate-detector.js.map +7 -0
- package/dist/audit/relationships/analysis/gap-analyzer.js +99 -0
- package/dist/audit/relationships/analysis/gap-analyzer.js.map +7 -0
- package/dist/audit/relationships/analysis/layer-templates.js +294 -0
- package/dist/audit/relationships/analysis/layer-templates.js.map +7 -0
- package/dist/audit/relationships/graph/connectivity.js +129 -0
- package/dist/audit/relationships/graph/connectivity.js.map +7 -0
- package/dist/audit/relationships/graph/relationship-graph.js +179 -0
- package/dist/audit/relationships/graph/relationship-graph.js.map +7 -0
- package/dist/audit/relationships/model/balance-assessor.js +49 -0
- package/dist/audit/relationships/model/balance-assessor.js.map +7 -0
- package/dist/audit/relationships/model/coverage-analyzer.js +34 -0
- package/dist/audit/relationships/model/coverage-analyzer.js.map +7 -0
- package/dist/audit/relationships/model/duplicate-detector.js +68 -0
- package/dist/audit/relationships/model/duplicate-detector.js.map +7 -0
- package/dist/audit/relationships/model/gap-analyzer.js +41 -0
- package/dist/audit/relationships/model/gap-analyzer.js.map +7 -0
- package/dist/audit/relationships/model/orchestrator.js +126 -0
- package/dist/audit/relationships/model/orchestrator.js.map +7 -0
- package/dist/audit/relationships/spec/orchestrator.js +157 -0
- package/dist/audit/relationships/spec/orchestrator.js.map +7 -0
- package/dist/audit/reports/index.js +5 -0
- package/dist/audit/reports/index.js.map +7 -0
- package/dist/audit/reports/report-generator.js +118 -0
- package/dist/audit/reports/report-generator.js.map +7 -0
- package/dist/audit/snapshot-storage.js +163 -0
- package/dist/audit/snapshot-storage.js.map +7 -0
- package/dist/audit/types.js +21 -0
- package/dist/audit/types.js.map +7 -0
- package/dist/cli.js +223 -92
- package/dist/cli.js.map +3 -3
- package/dist/coding-agents/agents/claude-code.js +147 -0
- package/dist/coding-agents/agents/claude-code.js.map +7 -0
- package/dist/coding-agents/agents/index.js +5 -0
- package/dist/coding-agents/agents/index.js.map +7 -0
- package/dist/coding-agents/agents/types.js +1 -0
- package/dist/coding-agents/agents/types.js.map +7 -0
- package/dist/coding-agents/base-chat-client.js +45 -0
- package/dist/coding-agents/base-chat-client.js.map +7 -0
- package/dist/coding-agents/chat-utils.js +23 -0
- package/dist/coding-agents/chat-utils.js.map +7 -0
- package/dist/coding-agents/claude-code-client.js +246 -0
- package/dist/coding-agents/claude-code-client.js.map +7 -0
- package/dist/coding-agents/copilot-client.js +209 -0
- package/dist/coding-agents/copilot-client.js.map +7 -0
- package/dist/commands/add.js +95 -33
- package/dist/commands/add.js.map +2 -2
- package/dist/commands/analyzer.js +511 -0
- package/dist/commands/analyzer.js.map +7 -0
- package/dist/commands/audit-diff.js +49 -0
- package/dist/commands/audit-diff.js.map +7 -0
- package/dist/commands/audit-snapshots.js +62 -0
- package/dist/commands/audit-snapshots.js.map +7 -0
- package/dist/commands/audit.js +81 -0
- package/dist/commands/audit.js.map +7 -0
- package/dist/commands/catalog.js +248 -0
- package/dist/commands/catalog.js.map +7 -0
- package/dist/commands/changeset.js +577 -66
- package/dist/commands/changeset.js.map +2 -2
- package/dist/commands/chat.js +106 -83
- package/dist/commands/chat.js.map +2 -2
- package/dist/commands/claude.js +74 -0
- package/dist/commands/claude.js.map +7 -0
- package/dist/commands/conformance.js +71 -68
- package/dist/commands/conformance.js.map +2 -2
- package/dist/commands/copilot.js +75 -0
- package/dist/commands/copilot.js.map +7 -0
- package/dist/commands/delete.js +125 -11
- package/dist/commands/delete.js.map +3 -3
- package/dist/commands/discover-logic.js +44 -0
- package/dist/commands/discover-logic.js.map +7 -0
- package/dist/commands/docs.js +87 -0
- package/dist/commands/docs.js.map +7 -0
- package/dist/commands/element.js +14 -20
- package/dist/commands/element.js.map +2 -2
- package/dist/commands/export.js +13 -3
- package/dist/commands/export.js.map +2 -2
- package/dist/commands/import.js +51 -0
- package/dist/commands/import.js.map +7 -0
- package/dist/commands/info.js +30 -24
- package/dist/commands/info.js.map +2 -2
- package/dist/commands/init.js +27 -11
- package/dist/commands/init.js.map +2 -2
- package/dist/commands/list.js +63 -13
- package/dist/commands/list.js.map +3 -3
- package/dist/commands/relationship.js +225 -37
- package/dist/commands/relationship.js.map +2 -2
- package/dist/commands/report.js +54 -0
- package/dist/commands/report.js.map +7 -0
- package/dist/commands/reports.js +45 -0
- package/dist/commands/reports.js.map +7 -0
- package/dist/commands/schema.js +135 -0
- package/dist/commands/schema.js.map +7 -0
- package/dist/commands/search.js +40 -12
- package/dist/commands/search.js.map +2 -2
- package/dist/commands/show.js +58 -27
- package/dist/commands/show.js.map +2 -2
- package/dist/commands/stats.js +35 -0
- package/dist/commands/stats.js.map +7 -0
- package/dist/commands/trace.js +39 -16
- package/dist/commands/trace.js.map +2 -2
- package/dist/commands/update.js +141 -14
- package/dist/commands/update.js.map +2 -2
- package/dist/commands/upgrade.js +210 -46
- package/dist/commands/upgrade.js.map +3 -3
- package/dist/commands/validate.js +142 -23
- package/dist/commands/validate.js.map +3 -3
- package/dist/commands/version.js +8 -12
- package/dist/commands/version.js.map +2 -2
- package/dist/commands/visualize.js +155 -25
- package/dist/commands/visualize.js.map +2 -2
- package/dist/core/base-snapshot-manager.js +84 -0
- package/dist/core/base-snapshot-manager.js.map +7 -0
- package/dist/core/changeset-exporter.js +305 -0
- package/dist/core/changeset-exporter.js.map +7 -0
- package/dist/core/changeset-validator.js +41 -0
- package/dist/core/changeset-validator.js.map +7 -0
- package/dist/core/changeset.js +88 -173
- package/dist/core/changeset.js.map +2 -2
- package/dist/core/dependency-tracker.js +4 -2
- package/dist/core/dependency-tracker.js.map +2 -2
- package/dist/core/element.js +98 -27
- package/dist/core/element.js.map +2 -2
- package/dist/core/golden-copy-cache.js +290 -0
- package/dist/core/golden-copy-cache.js.map +7 -0
- package/dist/core/graph-model.js +266 -0
- package/dist/core/graph-model.js.map +7 -0
- package/dist/core/layer.js +159 -16
- package/dist/core/layer.js.map +2 -2
- package/dist/core/layers.js +32 -0
- package/dist/core/layers.js.map +7 -0
- package/dist/core/manifest.js +32 -11
- package/dist/core/manifest.js.map +2 -2
- package/dist/core/migration-registry.js +56 -1
- package/dist/core/migration-registry.js.map +2 -2
- package/dist/core/model.js +424 -217
- package/dist/core/model.js.map +3 -3
- package/dist/core/mutation-handler.js +179 -0
- package/dist/core/mutation-handler.js.map +7 -0
- package/dist/core/reference-registry.js +29 -21
- package/dist/core/reference-registry.js.map +2 -2
- package/dist/core/relationship-catalog.js +189 -0
- package/dist/core/relationship-catalog.js.map +7 -0
- package/dist/core/relationship-registry.js.map +2 -2
- package/dist/core/relationships.js.map +1 -1
- package/dist/core/report-data-model.js +285 -0
- package/dist/core/report-data-model.js.map +7 -0
- package/dist/core/spec-data-service.js +185 -0
- package/dist/core/spec-data-service.js.map +7 -0
- package/dist/core/spec-loader-types.js +1 -0
- package/dist/core/spec-loader-types.js.map +7 -0
- package/dist/core/spec-loader.js +234 -0
- package/dist/core/spec-loader.js.map +7 -0
- package/dist/core/staged-changeset-storage.js +282 -0
- package/dist/core/staged-changeset-storage.js.map +7 -0
- package/dist/core/staging-area.js +1002 -0
- package/dist/core/staging-area.js.map +7 -0
- package/dist/core/stats-collector.js +169 -0
- package/dist/core/stats-collector.js.map +7 -0
- package/dist/core/virtual-projection.js +443 -0
- package/dist/core/virtual-projection.js.map +7 -0
- package/dist/export/archimate-exporter.js +99 -60
- package/dist/export/archimate-exporter.js.map +2 -2
- package/dist/export/audit-formatters.js +479 -0
- package/dist/export/audit-formatters.js.map +7 -0
- package/dist/export/diff-formatters.js +99 -0
- package/dist/export/diff-formatters.js.map +7 -0
- package/dist/export/export-manager.js.map +2 -2
- package/dist/export/graphml-exporter.js +44 -27
- package/dist/export/graphml-exporter.js.map +2 -2
- package/dist/export/index.js +4 -0
- package/dist/export/index.js.map +2 -2
- package/dist/export/json-schema-exporter.js +55 -42
- package/dist/export/json-schema-exporter.js.map +2 -2
- package/dist/export/markdown-exporter.js +92 -70
- package/dist/export/markdown-exporter.js.map +2 -2
- package/dist/export/markdown-generator.js +248 -0
- package/dist/export/markdown-generator.js.map +7 -0
- package/dist/export/markdown-utils.js +30 -0
- package/dist/export/markdown-utils.js.map +7 -0
- package/dist/export/mermaid-markdown-exporter.js +37 -0
- package/dist/export/mermaid-markdown-exporter.js.map +7 -0
- package/dist/export/openapi-exporter.js +119 -71
- package/dist/export/openapi-exporter.js.map +2 -2
- package/dist/export/plantuml-exporter.js +104 -39
- package/dist/export/plantuml-exporter.js.map +2 -2
- package/dist/export/report-formatters.js +111 -0
- package/dist/export/report-formatters.js.map +7 -0
- package/dist/export/stats-formatters.js +98 -0
- package/dist/export/stats-formatters.js.map +7 -0
- package/dist/export/types.js +2 -14
- package/dist/export/types.js.map +2 -2
- package/dist/export/verify-formatters.js +153 -0
- package/dist/export/verify-formatters.js.map +7 -0
- package/dist/generated/compiled-validators.js +17 -0
- package/dist/generated/compiled-validators.js.map +7 -0
- package/dist/generated/index.js +31 -0
- package/dist/generated/index.js.map +7 -0
- package/dist/generated/layer-registry.js +190 -0
- package/dist/generated/layer-registry.js.map +7 -0
- package/dist/generated/layer-types.js +7 -0
- package/dist/generated/layer-types.js.map +7 -0
- package/dist/generated/node-types.js +1719 -0
- package/dist/generated/node-types.js.map +7 -0
- package/dist/generated/relationship-index.js +14552 -0
- package/dist/generated/relationship-index.js.map +7 -0
- package/dist/import/archimate-importer.js +166 -0
- package/dist/import/archimate-importer.js.map +7 -0
- package/dist/import/index.js +47 -0
- package/dist/import/index.js.map +7 -0
- package/dist/import/openapi-importer.js +143 -0
- package/dist/import/openapi-importer.js.map +7 -0
- package/dist/import/types.js +1 -0
- package/dist/import/types.js.map +7 -0
- package/dist/integrations/base-manager.js +311 -0
- package/dist/integrations/base-manager.js.map +7 -0
- package/dist/integrations/claude-manager.js +360 -0
- package/dist/integrations/claude-manager.js.map +7 -0
- package/dist/integrations/claude_code/agents/dr-advisor.md +253 -0
- package/dist/integrations/claude_code/agents/dr-architect.md +278 -0
- package/dist/integrations/claude_code/agents/dr-extractor.md +286 -0
- package/dist/integrations/claude_code/commands/dr-changeset.md +657 -0
- package/dist/integrations/claude_code/commands/dr-design.md +373 -0
- package/dist/integrations/claude_code/commands/dr-info.md +132 -0
- package/dist/integrations/claude_code/commands/dr-init.md +251 -0
- package/dist/integrations/claude_code/commands/dr-map.md +936 -0
- package/dist/integrations/claude_code/commands/dr-model.md +493 -0
- package/dist/integrations/claude_code/commands/dr-relate.md +814 -0
- package/dist/integrations/claude_code/commands/dr-sync.md +279 -0
- package/dist/integrations/claude_code/commands/dr-validate.md +654 -0
- package/dist/integrations/claude_code/commands/dr-verify.md +559 -0
- package/dist/integrations/claude_code/docs/END_TO_END_WALKTHROUGH.md +903 -0
- package/dist/integrations/claude_code/docs/QUICK_START.md +271 -0
- package/dist/integrations/claude_code/docs/README.md +347 -0
- package/dist/integrations/claude_code/skills/dr_01_motivation_layer/SKILL.md +550 -0
- package/dist/integrations/claude_code/skills/dr_02_business_layer/SKILL.md +620 -0
- package/dist/integrations/claude_code/skills/dr_03_security_layer/SKILL.md +642 -0
- package/dist/integrations/claude_code/skills/dr_04_application_layer/SKILL.md +911 -0
- package/dist/integrations/claude_code/skills/dr_05_technology_layer/SKILL.md +836 -0
- package/dist/integrations/claude_code/skills/dr_06_api_layer/SKILL.md +933 -0
- package/dist/integrations/claude_code/skills/dr_07_data_model_layer/SKILL.md +210 -0
- package/dist/integrations/claude_code/skills/dr_08_dataset_layer/SKILL.md +319 -0
- package/dist/integrations/claude_code/skills/dr_09_ux_layer/SKILL.md +319 -0
- package/dist/integrations/claude_code/skills/dr_10_navigation_layer/SKILL.md +318 -0
- package/dist/integrations/claude_code/skills/dr_11_apm_layer/SKILL.md +273 -0
- package/dist/integrations/claude_code/skills/dr_12_testing_layer/SKILL.md +273 -0
- package/dist/integrations/claude_code/skills/dr_changeset_reviewer/SKILL.md +187 -0
- package/dist/integrations/claude_code/skills/dr_codebase_memory/SKILL.md +590 -0
- package/dist/integrations/claude_code/skills/dr_engineering_guide/SKILL.md +295 -0
- package/dist/integrations/copilot-manager.js +328 -0
- package/dist/integrations/copilot-manager.js.map +7 -0
- package/dist/integrations/github_copilot/agents/dr-advisor.md +243 -0
- package/dist/integrations/github_copilot/agents/dr-architect.md +1567 -0
- package/dist/integrations/github_copilot/skills/dr_01_motivation_layer/SKILL.md +491 -0
- package/dist/integrations/github_copilot/skills/dr_02_business_layer/SKILL.md +539 -0
- package/dist/integrations/github_copilot/skills/dr_03_security_layer/SKILL.md +667 -0
- package/dist/integrations/github_copilot/skills/dr_04_application_layer/SKILL.md +670 -0
- package/dist/integrations/github_copilot/skills/dr_05_technology_layer/SKILL.md +660 -0
- package/dist/integrations/github_copilot/skills/dr_06_api_layer/SKILL.md +855 -0
- package/dist/integrations/github_copilot/skills/dr_07_data_model_layer/SKILL.md +171 -0
- package/dist/integrations/github_copilot/skills/dr_08_dataset_layer/SKILL.md +216 -0
- package/dist/integrations/github_copilot/skills/dr_09_ux_layer/SKILL.md +230 -0
- package/dist/integrations/github_copilot/skills/dr_10_navigation_layer/SKILL.md +228 -0
- package/dist/integrations/github_copilot/skills/dr_11_apm_layer/SKILL.md +234 -0
- package/dist/integrations/github_copilot/skills/dr_12_testing_layer/SKILL.md +230 -0
- package/dist/integrations/github_copilot/skills/dr_changeset_reviewer/SKILL.md +187 -0
- package/dist/integrations/hash-utils.js +51 -0
- package/dist/integrations/hash-utils.js.map +7 -0
- package/dist/integrations/types.js +16 -0
- package/dist/integrations/types.js.map +7 -0
- package/dist/reports/model-layer-report-generator.js +278 -0
- package/dist/reports/model-layer-report-generator.js.map +7 -0
- package/dist/reports/model-report-data.js +57 -0
- package/dist/reports/model-report-data.js.map +7 -0
- package/dist/reports/model-report-orchestrator.js +103 -0
- package/dist/reports/model-report-orchestrator.js.map +7 -0
- package/dist/schemas/bundled/analyzers/cbm.json +595 -0
- package/dist/schemas/bundled/analyzers/manifest.json +9 -0
- package/dist/schemas/bundled/api.json +3411 -0
- package/dist/schemas/bundled/apm.json +2371 -0
- package/dist/schemas/bundled/application.json +1253 -0
- package/dist/schemas/bundled/base.json +1622 -0
- package/dist/schemas/bundled/business.json +1279 -0
- package/dist/schemas/bundled/data-model.json +1298 -0
- package/dist/schemas/bundled/data-store.json +2025 -0
- package/dist/schemas/bundled/manifest.json +93 -0
- package/dist/schemas/bundled/motivation.json +1360 -0
- package/dist/schemas/bundled/navigation.json +1874 -0
- package/dist/schemas/bundled/security.json +3488 -0
- package/dist/schemas/bundled/technology.json +2067 -0
- package/dist/schemas/bundled/testing.json +3120 -0
- package/dist/schemas/bundled/ux.json +3592 -0
- package/dist/server/schemas.js +202 -0
- package/dist/server/schemas.js.map +7 -0
- package/dist/server/server.js +1336 -252
- package/dist/server/server.js.map +3 -3
- package/dist/server/telemetry-middleware.js +22 -15
- package/dist/server/telemetry-middleware.js.map +2 -2
- package/dist/server-entry.js +65 -0
- package/dist/server-entry.js.map +7 -0
- package/dist/telemetry/config.js +89 -0
- package/dist/telemetry/config.js.map +7 -0
- package/dist/telemetry/console-interceptor.js.map +1 -1
- package/dist/telemetry/detect.js +24 -0
- package/dist/telemetry/detect.js.map +7 -0
- package/dist/telemetry/fetch-otlp-exporter.js +112 -0
- package/dist/telemetry/fetch-otlp-exporter.js.map +7 -0
- package/dist/telemetry/index.js +153 -3
- package/dist/telemetry/index.js.map +2 -2
- package/dist/telemetry/resilient-exporter.js +22 -8
- package/dist/telemetry/resilient-exporter.js.map +2 -2
- package/dist/telemetry/resilient-log-exporter.js +17 -8
- package/dist/telemetry/resilient-log-exporter.js.map +2 -2
- package/dist/telemetry/test-instrumentation.js.map +2 -2
- package/dist/types/index.js +84 -0
- package/dist/types/index.js.map +3 -3
- package/dist/types/source-reference.js +1 -0
- package/dist/types/source-reference.js.map +7 -0
- package/dist/utils/chat-logger.js +292 -0
- package/dist/utils/chat-logger.js.map +7 -0
- package/dist/utils/claude-stream.js +8 -0
- package/dist/utils/claude-stream.js.map +7 -0
- package/dist/utils/date-utils.js +7 -0
- package/dist/utils/date-utils.js.map +7 -0
- package/dist/utils/element-utils.js.map +1 -1
- package/dist/utils/errors.js +88 -15
- package/dist/utils/errors.js.map +3 -3
- package/dist/utils/export-python-annotations.js +82 -0
- package/dist/utils/export-python-annotations.js.map +7 -0
- package/dist/utils/file-io.js +7 -2
- package/dist/utils/file-io.js.map +2 -2
- package/dist/utils/file-lock.js +156 -0
- package/dist/utils/file-lock.js.map +7 -0
- package/dist/utils/id-generator.js +18 -0
- package/dist/utils/id-generator.js.map +7 -0
- package/dist/utils/layer-name-formatter.js +16 -0
- package/dist/utils/layer-name-formatter.js.map +7 -0
- package/dist/utils/markdown-anchor.js +7 -0
- package/dist/utils/markdown-anchor.js.map +7 -0
- package/dist/utils/markdown-link.js +12 -0
- package/dist/utils/markdown-link.js.map +7 -0
- package/dist/utils/markdown-table.js +17 -0
- package/dist/utils/markdown-table.js.map +7 -0
- package/dist/utils/mermaid-utils.js +11 -0
- package/dist/utils/mermaid-utils.js.map +7 -0
- package/dist/utils/project-paths.js.map +2 -2
- package/dist/utils/source-reference.js +52 -0
- package/dist/utils/source-reference.js.map +7 -0
- package/dist/utils/spec-installer.js +40 -53
- package/dist/utils/spec-installer.js.map +2 -2
- package/dist/utils/spec-version.js +5 -1
- package/dist/utils/spec-version.js.map +2 -2
- package/dist/utils/string-utils.js +12 -0
- package/dist/utils/string-utils.js.map +7 -0
- package/dist/utils/table-formatting.js +19 -0
- package/dist/utils/table-formatting.js.map +7 -0
- package/dist/validators/index.js +4 -0
- package/dist/validators/index.js.map +2 -2
- package/dist/validators/naming-validator.js +20 -23
- package/dist/validators/naming-validator.js.map +2 -2
- package/dist/validators/reference-validator.js +23 -38
- package/dist/validators/reference-validator.js.map +2 -2
- package/dist/validators/relationship-schema-validator.js +243 -0
- package/dist/validators/relationship-schema-validator.js.map +7 -0
- package/dist/validators/schema-validator.js +168 -68
- package/dist/validators/schema-validator.js.map +2 -2
- package/dist/validators/semantic-validator.js +36 -60
- package/dist/validators/semantic-validator.js.map +2 -2
- package/dist/validators/types.js.map +2 -2
- package/dist/validators/validation-formatter.js +159 -0
- package/dist/validators/validation-formatter.js.map +7 -0
- package/dist/validators/validator.js +24 -38
- package/dist/validators/validator.js.map +2 -2
- package/dist/viewer/README.md +139 -0
- package/dist/viewer/assets/main-CY0Xufuj.css +1 -0
- package/dist/viewer/assets/main-DtgErnwF.js +81 -0
- package/dist/viewer/assets/vendor-CxKvDp2x.js +17 -0
- package/dist/viewer/favicon.svg +11 -0
- package/dist/viewer/fonts/inter/Inter-Black.woff2 +0 -0
- package/dist/viewer/fonts/inter/Inter-Bold.woff2 +0 -0
- package/dist/viewer/fonts/inter/Inter-ExtraBold.woff2 +0 -0
- package/dist/viewer/fonts/inter/Inter-Light.woff2 +0 -0
- package/dist/viewer/fonts/inter/Inter-Medium.woff2 +0 -0
- package/dist/viewer/fonts/inter/Inter-Regular.woff2 +0 -0
- package/dist/viewer/fonts/inter/Inter-SemiBold.woff2 +0 -0
- package/dist/viewer/fonts/jetbrains-mono/JetBrainsMono-Medium.woff2 +0 -0
- package/dist/viewer/fonts/jetbrains-mono/JetBrainsMono-Regular.woff2 +0 -0
- package/dist/viewer/fonts/jetbrains-mono/JetBrainsMono-SemiBold.woff2 +0 -0
- package/dist/viewer/index.html +15 -0
- package/dist/viewer/manifest.json +99 -0
- package/dist/viewer/version.json +1 -0
- package/package.json +37 -13
- package/PYTHON_CLI_PARITY.md +0 -265
- package/PYTHON_CLI_STRUCTURE_UPDATE.md +0 -246
- package/biome.json +0 -42
- package/bunfig.toml +0 -3
- package/dist/ai/claude-client.js +0 -71
- package/dist/ai/claude-client.js.map +0 -7
- package/dist/ai/context-provider.js +0 -129
- package/dist/ai/context-provider.js.map +0 -7
- package/dist/ai/tools.js +0 -231
- package/dist/ai/tools.js.map +0 -7
- package/dist/commands/migrate.js +0 -36
- package/dist/commands/migrate.js.map +0 -7
- package/dist/commands/project.js +0 -74
- package/dist/commands/project.js.map +0 -7
- package/dist/core/active-changeset.js +0 -52
- package/dist/core/active-changeset.js.map +0 -7
- package/dist/core/projection-engine.js +0 -288
- package/dist/core/projection-engine.js.map +0 -7
- package/dist/schemas/bundled/01-motivation-layer.schema.json +0 -942
- package/dist/schemas/bundled/02-business-layer.schema.json +0 -1293
- package/dist/schemas/bundled/03-security-layer.schema.json +0 -2177
- package/dist/schemas/bundled/04-application-layer.schema.json +0 -1328
- package/dist/schemas/bundled/05-technology-layer.schema.json +0 -1465
- package/dist/schemas/bundled/06-api-layer.schema.json +0 -1743
- package/dist/schemas/bundled/07-data-model-layer.schema.json +0 -1253
- package/dist/schemas/bundled/08-datastore-layer.schema.json +0 -892
- package/dist/schemas/bundled/09-ux-layer.schema.json +0 -1506
- package/dist/schemas/bundled/10-navigation-layer.schema.json +0 -843
- package/dist/schemas/bundled/11-apm-observability-layer.schema.json +0 -1430
- package/dist/schemas/bundled/12-testing-layer.schema.json +0 -1091
- package/dist/schemas/bundled/common/layer-extensions.schema.json +0 -266
- package/dist/schemas/bundled/common/predicates.schema.json +0 -493
- package/dist/schemas/bundled/common/relationships.schema.json +0 -791
- package/dist/schemas/bundled/common/source-references.schema.json +0 -71
- package/dist/schemas/bundled/link-registry.json +0 -1839
- package/dist/schemas/bundled/link-registry.schema.json +0 -339
- package/dist/schemas/bundled/relationship-catalog.json +0 -1302
- package/dist/schemas/bundled/relationship-type.schema.json +0 -221
- package/dist/utils/model-path.js +0 -22
- package/dist/utils/model-path.js.map +0 -7
- package/docs/TEST-INSTRUMENTATION.md +0 -405
- package/docs/telemetry.md +0 -427
- package/test-debug.js +0 -33
- package/test-special.mjs +0 -46
- package/test_runner.ts +0 -7
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
class GraphModel {
|
|
2
|
+
nodes;
|
|
3
|
+
edges;
|
|
4
|
+
indices;
|
|
5
|
+
nodesVersion = 0;
|
|
6
|
+
constructor() {
|
|
7
|
+
this.nodes = /* @__PURE__ */ new Map(), this.edges = /* @__PURE__ */ new Map(), this.indices = {
|
|
8
|
+
nodesByLayer: /* @__PURE__ */ new Map(),
|
|
9
|
+
nodesByType: /* @__PURE__ */ new Map(),
|
|
10
|
+
edgesBySource: /* @__PURE__ */ new Map(),
|
|
11
|
+
edgesByDestination: /* @__PURE__ */ new Map(),
|
|
12
|
+
edgesByPredicate: /* @__PURE__ */ new Map()
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Get the current version of the nodes (for cache invalidation)
|
|
17
|
+
*/
|
|
18
|
+
getNodesVersion() {
|
|
19
|
+
return this.nodesVersion;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Add a node to the graph and update indices
|
|
23
|
+
* If a node with the same ID exists, its old index entries are cleaned up
|
|
24
|
+
*/
|
|
25
|
+
addNode(node) {
|
|
26
|
+
const existingNode = this.nodes.get(node.id);
|
|
27
|
+
if (existingNode) {
|
|
28
|
+
const oldLayerSet = this.indices.nodesByLayer.get(existingNode.layer);
|
|
29
|
+
oldLayerSet && (oldLayerSet.delete(node.id), oldLayerSet.size === 0 && this.indices.nodesByLayer.delete(existingNode.layer));
|
|
30
|
+
const oldTypeSet = this.indices.nodesByType.get(existingNode.type);
|
|
31
|
+
oldTypeSet && (oldTypeSet.delete(node.id), oldTypeSet.size === 0 && this.indices.nodesByType.delete(existingNode.type));
|
|
32
|
+
}
|
|
33
|
+
this.nodes.set(node.id, node), this.indices.nodesByLayer.has(node.layer) || this.indices.nodesByLayer.set(node.layer, /* @__PURE__ */ new Set());
|
|
34
|
+
const layerSet = this.indices.nodesByLayer.get(node.layer);
|
|
35
|
+
layerSet && layerSet.add(node.id), this.indices.nodesByType.has(node.type) || this.indices.nodesByType.set(node.type, /* @__PURE__ */ new Set());
|
|
36
|
+
const typeSet = this.indices.nodesByType.get(node.type);
|
|
37
|
+
typeSet && typeSet.add(node.id), this.nodesVersion++;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Remove a node from the graph
|
|
41
|
+
* Also removes all associated edges
|
|
42
|
+
*/
|
|
43
|
+
removeNode(nodeId) {
|
|
44
|
+
const node = this.nodes.get(nodeId);
|
|
45
|
+
if (!node)
|
|
46
|
+
return !1;
|
|
47
|
+
this.nodes.delete(nodeId);
|
|
48
|
+
const layerSet = this.indices.nodesByLayer.get(node.layer);
|
|
49
|
+
layerSet && (layerSet.delete(nodeId), layerSet.size === 0 && this.indices.nodesByLayer.delete(node.layer));
|
|
50
|
+
const typeSet = this.indices.nodesByType.get(node.type);
|
|
51
|
+
typeSet && (typeSet.delete(nodeId), typeSet.size === 0 && this.indices.nodesByType.delete(node.type));
|
|
52
|
+
const edgesInvolving = [];
|
|
53
|
+
for (const [edgeId, edge] of this.edges.entries())
|
|
54
|
+
(edge.source === nodeId || edge.destination === nodeId) && edgesInvolving.push(edgeId);
|
|
55
|
+
for (const edgeId of edgesInvolving)
|
|
56
|
+
this.removeEdge(edgeId);
|
|
57
|
+
return this.nodesVersion++, !0;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Update node properties
|
|
61
|
+
*/
|
|
62
|
+
updateNode(nodeId, updates) {
|
|
63
|
+
const node = this.nodes.get(nodeId);
|
|
64
|
+
if (!node)
|
|
65
|
+
return !1;
|
|
66
|
+
if (updates.layer && updates.layer !== node.layer) {
|
|
67
|
+
const oldLayerSet = this.indices.nodesByLayer.get(node.layer);
|
|
68
|
+
oldLayerSet && (oldLayerSet.delete(nodeId), oldLayerSet.size === 0 && this.indices.nodesByLayer.delete(node.layer)), this.indices.nodesByLayer.has(updates.layer) || this.indices.nodesByLayer.set(updates.layer, /* @__PURE__ */ new Set());
|
|
69
|
+
const newLayerSet = this.indices.nodesByLayer.get(updates.layer);
|
|
70
|
+
newLayerSet && newLayerSet.add(nodeId);
|
|
71
|
+
}
|
|
72
|
+
if (updates.type && updates.type !== node.type) {
|
|
73
|
+
const oldTypeSet = this.indices.nodesByType.get(node.type);
|
|
74
|
+
oldTypeSet && (oldTypeSet.delete(nodeId), oldTypeSet.size === 0 && this.indices.nodesByType.delete(node.type)), this.indices.nodesByType.has(updates.type) || this.indices.nodesByType.set(updates.type, /* @__PURE__ */ new Set());
|
|
75
|
+
const newTypeSet = this.indices.nodesByType.get(updates.type);
|
|
76
|
+
newTypeSet && newTypeSet.add(nodeId);
|
|
77
|
+
}
|
|
78
|
+
return Object.assign(node, updates), this.nodesVersion++, !0;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Add an edge to the graph and update indices
|
|
82
|
+
* Validates that both source and destination nodes exist
|
|
83
|
+
* @throws Error if source or destination node does not exist
|
|
84
|
+
*/
|
|
85
|
+
addEdge(edge) {
|
|
86
|
+
if (!this.nodes.has(edge.source))
|
|
87
|
+
throw new Error(`Cannot add edge: source node "${edge.source}" does not exist`);
|
|
88
|
+
if (!this.nodes.has(edge.destination))
|
|
89
|
+
throw new Error(`Cannot add edge: destination node "${edge.destination}" does not exist`);
|
|
90
|
+
this.edges.set(edge.id, edge), this.indices.edgesBySource.has(edge.source) || this.indices.edgesBySource.set(edge.source, /* @__PURE__ */ new Set());
|
|
91
|
+
const sourceSet = this.indices.edgesBySource.get(edge.source);
|
|
92
|
+
sourceSet && sourceSet.add(edge.id), this.indices.edgesByDestination.has(edge.destination) || this.indices.edgesByDestination.set(edge.destination, /* @__PURE__ */ new Set());
|
|
93
|
+
const destSet = this.indices.edgesByDestination.get(edge.destination);
|
|
94
|
+
destSet && destSet.add(edge.id), this.indices.edgesByPredicate.has(edge.predicate) || this.indices.edgesByPredicate.set(edge.predicate, /* @__PURE__ */ new Set());
|
|
95
|
+
const predicateSet = this.indices.edgesByPredicate.get(edge.predicate);
|
|
96
|
+
predicateSet && predicateSet.add(edge.id);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Remove an edge from the graph
|
|
100
|
+
*/
|
|
101
|
+
removeEdge(edgeId) {
|
|
102
|
+
const edge = this.edges.get(edgeId);
|
|
103
|
+
if (!edge)
|
|
104
|
+
return !1;
|
|
105
|
+
this.edges.delete(edgeId);
|
|
106
|
+
const sourceSet = this.indices.edgesBySource.get(edge.source);
|
|
107
|
+
sourceSet && (sourceSet.delete(edgeId), sourceSet.size === 0 && this.indices.edgesBySource.delete(edge.source));
|
|
108
|
+
const destSet = this.indices.edgesByDestination.get(edge.destination);
|
|
109
|
+
destSet && (destSet.delete(edgeId), destSet.size === 0 && this.indices.edgesByDestination.delete(edge.destination));
|
|
110
|
+
const predicateSet = this.indices.edgesByPredicate.get(edge.predicate);
|
|
111
|
+
return predicateSet && (predicateSet.delete(edgeId), predicateSet.size === 0 && this.indices.edgesByPredicate.delete(edge.predicate)), !0;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Update edge properties
|
|
115
|
+
*/
|
|
116
|
+
updateEdge(edgeId, updates) {
|
|
117
|
+
const edge = this.edges.get(edgeId);
|
|
118
|
+
if (!edge)
|
|
119
|
+
return !1;
|
|
120
|
+
if (updates.predicate && updates.predicate !== edge.predicate) {
|
|
121
|
+
const oldPredicateSet = this.indices.edgesByPredicate.get(edge.predicate);
|
|
122
|
+
oldPredicateSet && (oldPredicateSet.delete(edgeId), oldPredicateSet.size === 0 && this.indices.edgesByPredicate.delete(edge.predicate)), this.indices.edgesByPredicate.has(updates.predicate) || this.indices.edgesByPredicate.set(updates.predicate, /* @__PURE__ */ new Set());
|
|
123
|
+
const newPredicateSet = this.indices.edgesByPredicate.get(updates.predicate);
|
|
124
|
+
newPredicateSet && newPredicateSet.add(edgeId);
|
|
125
|
+
}
|
|
126
|
+
return Object.assign(edge, updates), !0;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get a node by its ID
|
|
130
|
+
*/
|
|
131
|
+
getNode(id) {
|
|
132
|
+
return this.nodes.get(id);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Get all nodes in a specific layer
|
|
136
|
+
*/
|
|
137
|
+
getNodesByLayer(layer) {
|
|
138
|
+
const nodeIds = this.indices.nodesByLayer.get(layer) ?? /* @__PURE__ */ new Set(), result = [];
|
|
139
|
+
for (const id of nodeIds) {
|
|
140
|
+
const node = this.nodes.get(id);
|
|
141
|
+
node && result.push(node);
|
|
142
|
+
}
|
|
143
|
+
return result;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Get all nodes of a specific type
|
|
147
|
+
*/
|
|
148
|
+
getNodesByType(type) {
|
|
149
|
+
const nodeIds = this.indices.nodesByType.get(type) ?? /* @__PURE__ */ new Set(), result = [];
|
|
150
|
+
for (const id of nodeIds) {
|
|
151
|
+
const node = this.nodes.get(id);
|
|
152
|
+
node && result.push(node);
|
|
153
|
+
}
|
|
154
|
+
return result;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Get outgoing edges from a node, optionally filtered by predicate
|
|
158
|
+
*/
|
|
159
|
+
getEdgesFrom(nodeId, predicate) {
|
|
160
|
+
const edgeIds = this.indices.edgesBySource.get(nodeId) ?? /* @__PURE__ */ new Set(), edges = [];
|
|
161
|
+
for (const id of edgeIds) {
|
|
162
|
+
const edge = this.edges.get(id);
|
|
163
|
+
edge && edges.push(edge);
|
|
164
|
+
}
|
|
165
|
+
return predicate ? edges.filter((e) => e.predicate === predicate) : edges;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Get incoming edges to a node, optionally filtered by predicate
|
|
169
|
+
*/
|
|
170
|
+
getEdgesTo(nodeId, predicate) {
|
|
171
|
+
const edgeIds = this.indices.edgesByDestination.get(nodeId) ?? /* @__PURE__ */ new Set(), edges = [];
|
|
172
|
+
for (const id of edgeIds) {
|
|
173
|
+
const edge = this.edges.get(id);
|
|
174
|
+
edge && edges.push(edge);
|
|
175
|
+
}
|
|
176
|
+
return predicate ? edges.filter((e) => e.predicate === predicate) : edges;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Get edges between two specific nodes
|
|
180
|
+
*/
|
|
181
|
+
getEdgesBetween(sourceId, destinationId, predicate) {
|
|
182
|
+
return this.getEdgesFrom(sourceId, predicate).filter((e) => e.destination === destinationId);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Get all edges in the graph
|
|
186
|
+
*/
|
|
187
|
+
getAllEdges() {
|
|
188
|
+
return Array.from(this.edges.values());
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Traverse the graph starting from a node using breadth-first search
|
|
192
|
+
*/
|
|
193
|
+
traverse(startNodeId, predicate, maxDepth = 1 / 0) {
|
|
194
|
+
const visited = /* @__PURE__ */ new Set(), result = [], queue = [{ nodeId: startNodeId, depth: 0 }];
|
|
195
|
+
for (; queue.length > 0; ) {
|
|
196
|
+
const { nodeId, depth } = queue.shift();
|
|
197
|
+
if (visited.has(nodeId) || depth > maxDepth)
|
|
198
|
+
continue;
|
|
199
|
+
visited.add(nodeId);
|
|
200
|
+
const node = this.nodes.get(nodeId);
|
|
201
|
+
node && result.push(node);
|
|
202
|
+
const edges = this.getEdgesFrom(nodeId, predicate);
|
|
203
|
+
for (const edge of edges)
|
|
204
|
+
visited.has(edge.destination) || queue.push({ nodeId: edge.destination, depth: depth + 1 });
|
|
205
|
+
}
|
|
206
|
+
return result;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Get total number of nodes
|
|
210
|
+
*/
|
|
211
|
+
getNodeCount() {
|
|
212
|
+
return this.nodes.size;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Get total number of edges
|
|
216
|
+
*/
|
|
217
|
+
getEdgeCount() {
|
|
218
|
+
return this.edges.size;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Clear all data from the graph
|
|
222
|
+
*/
|
|
223
|
+
clear() {
|
|
224
|
+
this.nodes.clear(), this.edges.clear(), this.indices.nodesByLayer.clear(), this.indices.nodesByType.clear(), this.indices.edgesBySource.clear(), this.indices.edgesByDestination.clear(), this.indices.edgesByPredicate.clear();
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Convert Element to GraphNode
|
|
228
|
+
* Preserves spec-node fields so they survive graph round-trips
|
|
229
|
+
*/
|
|
230
|
+
/** UUID pattern for detecting actual UUIDs vs slug IDs */
|
|
231
|
+
static UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
232
|
+
static fromElement(element) {
|
|
233
|
+
const graphId = element.path || element.id, isUUID = GraphModel.UUID_PATTERN.test(element.id);
|
|
234
|
+
return {
|
|
235
|
+
id: graphId,
|
|
236
|
+
uuid: isUUID ? element.id : void 0,
|
|
237
|
+
// preserve UUID for round-tripping
|
|
238
|
+
layer: element.layer || "unknown",
|
|
239
|
+
type: element.type,
|
|
240
|
+
name: element.name,
|
|
241
|
+
description: element.description,
|
|
242
|
+
properties: element.attributes || {},
|
|
243
|
+
spec_node_id: element.spec_node_id || void 0,
|
|
244
|
+
layer_id: element.layer_id || void 0,
|
|
245
|
+
attributes: element.attributes && Object.keys(element.attributes).length > 0 ? element.attributes : void 0,
|
|
246
|
+
source_reference: element.source_reference,
|
|
247
|
+
metadata: element.metadata
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Convert Relationship to GraphEdge
|
|
252
|
+
*/
|
|
253
|
+
static relationshipToEdge(relationship, edgeId) {
|
|
254
|
+
return {
|
|
255
|
+
id: edgeId,
|
|
256
|
+
source: relationship.source,
|
|
257
|
+
destination: relationship.target,
|
|
258
|
+
predicate: relationship.predicate,
|
|
259
|
+
properties: relationship.properties
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
export {
|
|
264
|
+
GraphModel
|
|
265
|
+
};
|
|
266
|
+
//# sourceMappingURL=graph-model.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/core/graph-model.ts"],
|
|
4
|
+
"sourcesContent": ["import { Element } from \"./element.js\";\nimport type { ElementMetadata, Relationship, SourceReference } from \"../types/index.js\";\n\n/**\n * Graph node representing a model element\n * Replaces Element class for graph-based storage\n */\nexport interface GraphNode {\n id: string; // Path (slug) used as graph key: {layer}.{type}.{kebab-name}\n uuid?: string; // UUIDv4 preserved for round-tripping (element.id)\n layer: string; // Layer this node belongs to\n type: string; // Element type\n name: string; // Display name\n description?: string; // Optional description\n properties?: Record<string, unknown>; // Custom properties\n // Spec-node aligned fields (preserved through graph round-trip)\n spec_node_id?: string;\n layer_id?: string;\n attributes?: Record<string, unknown>;\n source_reference?: SourceReference;\n metadata?: ElementMetadata;\n}\n\n/**\n * Graph edge representing a relationship between nodes\n */\nexport interface GraphEdge {\n id: string; // Unique identifier\n source: string; // Source node ID\n destination: string; // Destination node ID\n predicate: string; // Relationship type\n properties?: Record<string, unknown>; // Optional properties\n category?: \"structural\" | \"behavioral\";\n}\n\n/**\n * Index structures for efficient querying\n */\ninterface GraphIndices {\n nodesByLayer: Map<string, Set<string>>; // layer -> node IDs\n nodesByType: Map<string, Set<string>>; // type -> node IDs\n edgesBySource: Map<string, Set<string>>; // source node ID -> edge IDs\n edgesByDestination: Map<string, Set<string>>; // destination node ID -> edge IDs\n edgesByPredicate: Map<string, Set<string>>; // predicate -> edge IDs\n}\n\n/**\n * Graph model interface for node/edge storage with query capabilities\n */\nexport interface IGraphModel {\n nodes: Map<string, GraphNode>;\n edges: Map<string, GraphEdge>;\n\n // Query methods\n getNode(id: string): GraphNode | undefined;\n getNodesByLayer(layer: string): GraphNode[];\n getNodesByType(type: string): GraphNode[];\n getEdgesFrom(nodeId: string, predicate?: string): GraphEdge[];\n getEdgesTo(nodeId: string, predicate?: string): GraphEdge[];\n getEdgesBetween(sourceId: string, destinationId: string, predicate?: string): GraphEdge[];\n getAllEdges(): GraphEdge[];\n\n // Mutation methods\n addNode(node: GraphNode): void;\n removeNode(nodeId: string): boolean;\n updateNode(nodeId: string, updates: Partial<GraphNode>): boolean;\n\n addEdge(edge: GraphEdge): void;\n removeEdge(edgeId: string): boolean;\n updateEdge(edgeId: string, updates: Partial<GraphEdge>): boolean;\n\n // Traversal\n traverse(startNodeId: string, predicate?: string, maxDepth?: number): GraphNode[];\n\n // Utility\n getNodeCount(): number;\n getEdgeCount(): number;\n clear(): void;\n}\n\n/**\n * Implementation of graph model with indices for efficient queries\n */\nexport class GraphModel implements IGraphModel {\n nodes: Map<string, GraphNode>;\n edges: Map<string, GraphEdge>;\n private indices: GraphIndices;\n private nodesVersion: number = 0;\n\n constructor() {\n this.nodes = new Map();\n this.edges = new Map();\n this.indices = {\n nodesByLayer: new Map(),\n nodesByType: new Map(),\n edgesBySource: new Map(),\n edgesByDestination: new Map(),\n edgesByPredicate: new Map(),\n };\n }\n\n /**\n * Get the current version of the nodes (for cache invalidation)\n */\n getNodesVersion(): number {\n return this.nodesVersion;\n }\n\n /**\n * Add a node to the graph and update indices\n * If a node with the same ID exists, its old index entries are cleaned up\n */\n addNode(node: GraphNode): void {\n const existingNode = this.nodes.get(node.id);\n\n // Clean up old index entries if node is being replaced\n if (existingNode) {\n // Remove from old layer index\n const oldLayerSet = this.indices.nodesByLayer.get(existingNode.layer);\n if (oldLayerSet) {\n oldLayerSet.delete(node.id);\n if (oldLayerSet.size === 0) {\n this.indices.nodesByLayer.delete(existingNode.layer);\n }\n }\n\n // Remove from old type index\n const oldTypeSet = this.indices.nodesByType.get(existingNode.type);\n if (oldTypeSet) {\n oldTypeSet.delete(node.id);\n if (oldTypeSet.size === 0) {\n this.indices.nodesByType.delete(existingNode.type);\n }\n }\n }\n\n // Add new node\n this.nodes.set(node.id, node);\n\n // Update layer index\n if (!this.indices.nodesByLayer.has(node.layer)) {\n this.indices.nodesByLayer.set(node.layer, new Set());\n }\n const layerSet = this.indices.nodesByLayer.get(node.layer);\n if (layerSet) {\n layerSet.add(node.id);\n }\n\n // Update type index\n if (!this.indices.nodesByType.has(node.type)) {\n this.indices.nodesByType.set(node.type, new Set());\n }\n const typeSet = this.indices.nodesByType.get(node.type);\n if (typeSet) {\n typeSet.add(node.id);\n }\n\n // Increment version to invalidate caches\n this.nodesVersion++;\n }\n\n /**\n * Remove a node from the graph\n * Also removes all associated edges\n */\n removeNode(nodeId: string): boolean {\n const node = this.nodes.get(nodeId);\n if (!node) {\n return false;\n }\n\n // Remove from nodes map\n this.nodes.delete(nodeId);\n\n // Remove from layer index\n const layerSet = this.indices.nodesByLayer.get(node.layer);\n if (layerSet) {\n layerSet.delete(nodeId);\n if (layerSet.size === 0) {\n this.indices.nodesByLayer.delete(node.layer);\n }\n }\n\n // Remove from type index\n const typeSet = this.indices.nodesByType.get(node.type);\n if (typeSet) {\n typeSet.delete(nodeId);\n if (typeSet.size === 0) {\n this.indices.nodesByType.delete(node.type);\n }\n }\n\n // Remove all edges involving this node\n const edgesInvolving: string[] = [];\n for (const [edgeId, edge] of this.edges.entries()) {\n if (edge.source === nodeId || edge.destination === nodeId) {\n edgesInvolving.push(edgeId);\n }\n }\n for (const edgeId of edgesInvolving) {\n this.removeEdge(edgeId);\n }\n\n // Increment version to invalidate caches\n this.nodesVersion++;\n return true;\n }\n\n /**\n * Update node properties\n */\n updateNode(nodeId: string, updates: Partial<GraphNode>): boolean {\n const node = this.nodes.get(nodeId);\n if (!node) {\n return false;\n }\n\n // Handle layer change\n if (updates.layer && updates.layer !== node.layer) {\n const oldLayerSet = this.indices.nodesByLayer.get(node.layer);\n if (oldLayerSet) {\n oldLayerSet.delete(nodeId);\n if (oldLayerSet.size === 0) {\n this.indices.nodesByLayer.delete(node.layer);\n }\n }\n if (!this.indices.nodesByLayer.has(updates.layer)) {\n this.indices.nodesByLayer.set(updates.layer, new Set());\n }\n const newLayerSet = this.indices.nodesByLayer.get(updates.layer);\n if (newLayerSet) {\n newLayerSet.add(nodeId);\n }\n }\n\n // Handle type change\n if (updates.type && updates.type !== node.type) {\n const oldTypeSet = this.indices.nodesByType.get(node.type);\n if (oldTypeSet) {\n oldTypeSet.delete(nodeId);\n if (oldTypeSet.size === 0) {\n this.indices.nodesByType.delete(node.type);\n }\n }\n if (!this.indices.nodesByType.has(updates.type)) {\n this.indices.nodesByType.set(updates.type, new Set());\n }\n const newTypeSet = this.indices.nodesByType.get(updates.type);\n if (newTypeSet) {\n newTypeSet.add(nodeId);\n }\n }\n\n // Apply updates\n Object.assign(node, updates);\n // Increment version to invalidate caches\n this.nodesVersion++;\n return true;\n }\n\n /**\n * Add an edge to the graph and update indices\n * Validates that both source and destination nodes exist\n * @throws Error if source or destination node does not exist\n */\n addEdge(edge: GraphEdge): void {\n // Validate that source node exists\n if (!this.nodes.has(edge.source)) {\n throw new Error(`Cannot add edge: source node \"${edge.source}\" does not exist`);\n }\n\n // Validate that destination node exists\n if (!this.nodes.has(edge.destination)) {\n throw new Error(`Cannot add edge: destination node \"${edge.destination}\" does not exist`);\n }\n\n this.edges.set(edge.id, edge);\n\n // Update source index\n if (!this.indices.edgesBySource.has(edge.source)) {\n this.indices.edgesBySource.set(edge.source, new Set());\n }\n const sourceSet = this.indices.edgesBySource.get(edge.source);\n if (sourceSet) {\n sourceSet.add(edge.id);\n }\n\n // Update destination index\n if (!this.indices.edgesByDestination.has(edge.destination)) {\n this.indices.edgesByDestination.set(edge.destination, new Set());\n }\n const destSet = this.indices.edgesByDestination.get(edge.destination);\n if (destSet) {\n destSet.add(edge.id);\n }\n\n // Update predicate index\n if (!this.indices.edgesByPredicate.has(edge.predicate)) {\n this.indices.edgesByPredicate.set(edge.predicate, new Set());\n }\n const predicateSet = this.indices.edgesByPredicate.get(edge.predicate);\n if (predicateSet) {\n predicateSet.add(edge.id);\n }\n }\n\n /**\n * Remove an edge from the graph\n */\n removeEdge(edgeId: string): boolean {\n const edge = this.edges.get(edgeId);\n if (!edge) {\n return false;\n }\n\n // Remove from edges map\n this.edges.delete(edgeId);\n\n // Remove from source index\n const sourceSet = this.indices.edgesBySource.get(edge.source);\n if (sourceSet) {\n sourceSet.delete(edgeId);\n if (sourceSet.size === 0) {\n this.indices.edgesBySource.delete(edge.source);\n }\n }\n\n // Remove from destination index\n const destSet = this.indices.edgesByDestination.get(edge.destination);\n if (destSet) {\n destSet.delete(edgeId);\n if (destSet.size === 0) {\n this.indices.edgesByDestination.delete(edge.destination);\n }\n }\n\n // Remove from predicate index\n const predicateSet = this.indices.edgesByPredicate.get(edge.predicate);\n if (predicateSet) {\n predicateSet.delete(edgeId);\n if (predicateSet.size === 0) {\n this.indices.edgesByPredicate.delete(edge.predicate);\n }\n }\n\n return true;\n }\n\n /**\n * Update edge properties\n */\n updateEdge(edgeId: string, updates: Partial<GraphEdge>): boolean {\n const edge = this.edges.get(edgeId);\n if (!edge) {\n return false;\n }\n\n // Handle predicate change\n if (updates.predicate && updates.predicate !== edge.predicate) {\n const oldPredicateSet = this.indices.edgesByPredicate.get(edge.predicate);\n if (oldPredicateSet) {\n oldPredicateSet.delete(edgeId);\n if (oldPredicateSet.size === 0) {\n this.indices.edgesByPredicate.delete(edge.predicate);\n }\n }\n if (!this.indices.edgesByPredicate.has(updates.predicate)) {\n this.indices.edgesByPredicate.set(updates.predicate, new Set());\n }\n const newPredicateSet = this.indices.edgesByPredicate.get(updates.predicate);\n if (newPredicateSet) {\n newPredicateSet.add(edgeId);\n }\n }\n\n // Note: Source and destination changes are not supported (use removeEdge + addEdge)\n // Apply updates\n Object.assign(edge, updates);\n return true;\n }\n\n /**\n * Get a node by its ID\n */\n getNode(id: string): GraphNode | undefined {\n return this.nodes.get(id);\n }\n\n /**\n * Get all nodes in a specific layer\n */\n getNodesByLayer(layer: string): GraphNode[] {\n const nodeIds = this.indices.nodesByLayer.get(layer) ?? new Set();\n const result: GraphNode[] = [];\n for (const id of nodeIds) {\n const node = this.nodes.get(id);\n if (node) {\n result.push(node);\n }\n }\n return result;\n }\n\n /**\n * Get all nodes of a specific type\n */\n getNodesByType(type: string): GraphNode[] {\n const nodeIds = this.indices.nodesByType.get(type) ?? new Set();\n const result: GraphNode[] = [];\n for (const id of nodeIds) {\n const node = this.nodes.get(id);\n if (node) {\n result.push(node);\n }\n }\n return result;\n }\n\n /**\n * Get outgoing edges from a node, optionally filtered by predicate\n */\n getEdgesFrom(nodeId: string, predicate?: string): GraphEdge[] {\n const edgeIds = this.indices.edgesBySource.get(nodeId) ?? new Set();\n const edges: GraphEdge[] = [];\n for (const id of edgeIds) {\n const edge = this.edges.get(id);\n if (edge) {\n edges.push(edge);\n }\n }\n\n if (predicate) {\n return edges.filter((e) => e.predicate === predicate);\n }\n return edges;\n }\n\n /**\n * Get incoming edges to a node, optionally filtered by predicate\n */\n getEdgesTo(nodeId: string, predicate?: string): GraphEdge[] {\n const edgeIds = this.indices.edgesByDestination.get(nodeId) ?? new Set();\n const edges: GraphEdge[] = [];\n for (const id of edgeIds) {\n const edge = this.edges.get(id);\n if (edge) {\n edges.push(edge);\n }\n }\n\n if (predicate) {\n return edges.filter((e) => e.predicate === predicate);\n }\n return edges;\n }\n\n /**\n * Get edges between two specific nodes\n */\n getEdgesBetween(sourceId: string, destinationId: string, predicate?: string): GraphEdge[] {\n const outgoing = this.getEdgesFrom(sourceId, predicate);\n return outgoing.filter((e) => e.destination === destinationId);\n }\n\n /**\n * Get all edges in the graph\n */\n getAllEdges(): GraphEdge[] {\n return Array.from(this.edges.values());\n }\n\n /**\n * Traverse the graph starting from a node using breadth-first search\n */\n traverse(startNodeId: string, predicate?: string, maxDepth: number = Infinity): GraphNode[] {\n const visited = new Set<string>();\n const result: GraphNode[] = [];\n const queue: { nodeId: string; depth: number }[] = [{ nodeId: startNodeId, depth: 0 }];\n\n while (queue.length > 0) {\n const { nodeId, depth } = queue.shift()!;\n\n if (visited.has(nodeId) || depth > maxDepth) {\n continue;\n }\n\n visited.add(nodeId);\n const node = this.nodes.get(nodeId);\n if (node) {\n result.push(node);\n }\n\n // Find outgoing edges\n const edges = this.getEdgesFrom(nodeId, predicate);\n for (const edge of edges) {\n if (!visited.has(edge.destination)) {\n queue.push({ nodeId: edge.destination, depth: depth + 1 });\n }\n }\n }\n\n return result;\n }\n\n /**\n * Get total number of nodes\n */\n getNodeCount(): number {\n return this.nodes.size;\n }\n\n /**\n * Get total number of edges\n */\n getEdgeCount(): number {\n return this.edges.size;\n }\n\n /**\n * Clear all data from the graph\n */\n clear(): void {\n this.nodes.clear();\n this.edges.clear();\n this.indices.nodesByLayer.clear();\n this.indices.nodesByType.clear();\n this.indices.edgesBySource.clear();\n this.indices.edgesByDestination.clear();\n this.indices.edgesByPredicate.clear();\n }\n\n /**\n * Convert Element to GraphNode\n * Preserves spec-node fields so they survive graph round-trips\n */\n /** UUID pattern for detecting actual UUIDs vs slug IDs */\n private static readonly UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n static fromElement(element: Element): GraphNode {\n // path is the graph key; fall back to id for elements without a path\n const graphId = element.path || element.id;\n // Only preserve UUID when the id is actually a UUID (not a slug)\n const isUUID = GraphModel.UUID_PATTERN.test(element.id);\n return {\n id: graphId,\n uuid: isUUID ? element.id : undefined, // preserve UUID for round-tripping\n layer: element.layer || \"unknown\",\n type: element.type,\n name: element.name,\n description: element.description,\n properties: element.attributes || {},\n spec_node_id: element.spec_node_id || undefined,\n layer_id: element.layer_id || undefined,\n attributes: element.attributes && Object.keys(element.attributes).length > 0\n ? element.attributes\n : undefined,\n source_reference: element.source_reference,\n metadata: element.metadata,\n };\n }\n\n /**\n * Convert Relationship to GraphEdge\n */\n static relationshipToEdge(relationship: Relationship, edgeId: string): GraphEdge {\n return {\n id: edgeId,\n source: relationship.source,\n destination: relationship.target,\n predicate: relationship.predicate,\n properties: relationship.properties,\n };\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/core/layer.js
CHANGED
|
@@ -1,36 +1,173 @@
|
|
|
1
1
|
import { Element } from "./element.js";
|
|
2
|
+
import { GraphModel } from "./graph-model.js";
|
|
2
3
|
class Layer {
|
|
3
4
|
name;
|
|
4
|
-
|
|
5
|
+
graph;
|
|
5
6
|
metadata;
|
|
6
7
|
dirty = !1;
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
cachedElements = null;
|
|
9
|
+
cachedNodesVersion = 0;
|
|
10
|
+
constructor(name, elementsOrGraph, elementsIfGraphPassed) {
|
|
11
|
+
this.name = name;
|
|
12
|
+
let actualGraph, elementsToAdd = [];
|
|
13
|
+
elementsOrGraph instanceof GraphModel ? (actualGraph = elementsOrGraph, Array.isArray(elementsIfGraphPassed) && (elementsToAdd = elementsIfGraphPassed)) : Array.isArray(elementsOrGraph) ? elementsToAdd = elementsOrGraph : elementsOrGraph === void 0 && Array.isArray(elementsIfGraphPassed) && (elementsToAdd = elementsIfGraphPassed), this.graph = actualGraph || new GraphModel();
|
|
14
|
+
for (const element of elementsToAdd) {
|
|
15
|
+
element.layer = this.name, (!element.layer_id || element.layer_id === "") && (element.layer_id = this.name);
|
|
16
|
+
const node = GraphModel.fromElement(element), nodeProperties = node.properties || {};
|
|
17
|
+
node.properties = nodeProperties, element.references && element.references.length > 0 && (nodeProperties.__references__ = element.references), element.relationships && element.relationships.length > 0 && (nodeProperties.__relationships__ = element.relationships), element.semanticId && (nodeProperties.__semanticId__ = element.semanticId), this.graph.addNode(node);
|
|
18
|
+
}
|
|
9
19
|
}
|
|
10
20
|
/**
|
|
11
|
-
*
|
|
21
|
+
* Get all elements in this layer from the graph
|
|
22
|
+
* Converts graph nodes back to Elements for backward compatibility
|
|
23
|
+
* Results are cached and invalidated when the underlying graph changes
|
|
24
|
+
*/
|
|
25
|
+
get elements() {
|
|
26
|
+
const currentVersion = this.graph.getNodesVersion();
|
|
27
|
+
if (this.cachedElements !== null && this.cachedNodesVersion === currentVersion)
|
|
28
|
+
return this.cachedElements;
|
|
29
|
+
const result = /* @__PURE__ */ new Map(), nodes = this.graph.getNodesByLayer(this.name);
|
|
30
|
+
for (const node of nodes) {
|
|
31
|
+
const element = new Element({
|
|
32
|
+
id: node.uuid || node.id,
|
|
33
|
+
path: node.id,
|
|
34
|
+
spec_node_id: node.spec_node_id,
|
|
35
|
+
layer_id: node.layer_id,
|
|
36
|
+
type: node.type,
|
|
37
|
+
name: node.name,
|
|
38
|
+
description: node.description,
|
|
39
|
+
attributes: node.attributes,
|
|
40
|
+
source_reference: node.source_reference,
|
|
41
|
+
metadata: node.metadata,
|
|
42
|
+
layer: node.layer,
|
|
43
|
+
references: node.properties?.__references__ ?? [],
|
|
44
|
+
relationships: node.properties?.__relationships__ ?? [],
|
|
45
|
+
semanticId: node.properties?.__semanticId__
|
|
46
|
+
});
|
|
47
|
+
result.set(node.id, element);
|
|
48
|
+
}
|
|
49
|
+
return this.cachedElements = result, this.cachedNodesVersion = currentVersion, result;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Add an element to the layer (stores in graph)
|
|
12
53
|
*/
|
|
13
54
|
addElement(element) {
|
|
14
|
-
this.
|
|
55
|
+
element.layer = this.name, (!element.layer_id || element.layer_id === "") && (element.layer_id = this.name);
|
|
56
|
+
const node = GraphModel.fromElement(element), nodeProperties = node.properties || {};
|
|
57
|
+
if (node.properties = nodeProperties, element.references && element.references.length > 0 && (nodeProperties.__references__ = element.references), element.relationships && element.relationships.length > 0 && (nodeProperties.__relationships__ = element.relationships), element.semanticId && (nodeProperties.__semanticId__ = element.semanticId), this.graph.addNode(node), element.references && element.references.length > 0)
|
|
58
|
+
for (const ref of element.references)
|
|
59
|
+
this.graph.nodes.has(ref.source) && this.graph.nodes.has(ref.target) && this.graph.addEdge({
|
|
60
|
+
id: `${ref.source}-${ref.type}-${ref.target}`,
|
|
61
|
+
source: ref.source,
|
|
62
|
+
destination: ref.target,
|
|
63
|
+
predicate: ref.type,
|
|
64
|
+
properties: {}
|
|
65
|
+
});
|
|
66
|
+
if (element.relationships && element.relationships.length > 0)
|
|
67
|
+
for (const rel of element.relationships)
|
|
68
|
+
this.graph.nodes.has(rel.source) && this.graph.nodes.has(rel.target) && this.graph.addEdge({
|
|
69
|
+
id: `${rel.source}-${rel.predicate}-${rel.target}`,
|
|
70
|
+
source: rel.source,
|
|
71
|
+
destination: rel.target,
|
|
72
|
+
predicate: rel.predicate,
|
|
73
|
+
properties: {}
|
|
74
|
+
});
|
|
75
|
+
this.dirty = !0;
|
|
15
76
|
}
|
|
16
77
|
/**
|
|
17
|
-
* Get an element by ID
|
|
78
|
+
* Get an element by UUID or semantic ID from the graph.
|
|
79
|
+
* Supports direct UUID lookup, and falls back to semantic ID lookup for legacy elements.
|
|
80
|
+
*
|
|
81
|
+
* @param id - UUID or semantic ID of the element to get
|
|
82
|
+
* @returns The element if found, undefined if not found
|
|
18
83
|
*/
|
|
19
84
|
getElement(id) {
|
|
20
|
-
|
|
85
|
+
let node = this.graph.nodes.get(id);
|
|
86
|
+
if (!node) {
|
|
87
|
+
for (const candidate of this.graph.nodes.values())
|
|
88
|
+
if (candidate.layer === this.name && (candidate.uuid === id || candidate.properties?.__semanticId__ === id || candidate.id === id)) {
|
|
89
|
+
node = candidate;
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (!(!node || node.layer !== this.name))
|
|
94
|
+
return new Element({
|
|
95
|
+
id: node.uuid || node.id,
|
|
96
|
+
path: node.id,
|
|
97
|
+
spec_node_id: node.spec_node_id,
|
|
98
|
+
layer_id: node.layer_id,
|
|
99
|
+
type: node.type,
|
|
100
|
+
name: node.name,
|
|
101
|
+
description: node.description,
|
|
102
|
+
attributes: node.attributes,
|
|
103
|
+
source_reference: node.source_reference,
|
|
104
|
+
metadata: node.metadata,
|
|
105
|
+
layer: node.layer,
|
|
106
|
+
references: node.properties?.__references__ ?? [],
|
|
107
|
+
relationships: node.properties?.__relationships__ ?? []
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Update an element in the graph
|
|
112
|
+
*/
|
|
113
|
+
updateElement(element) {
|
|
114
|
+
const node = this.graph.nodes.get(element.path || element.id);
|
|
115
|
+
if (!node || node.layer !== this.name)
|
|
116
|
+
return !1;
|
|
117
|
+
const properties = { ...node.properties || {} };
|
|
118
|
+
element.references && element.references.length > 0 ? properties.__references__ = element.references : delete properties.__references__, element.relationships && element.relationships.length > 0 ? properties.__relationships__ = element.relationships : delete properties.__relationships__;
|
|
119
|
+
const updated = this.graph.updateNode(element.path || element.id, {
|
|
120
|
+
type: element.type,
|
|
121
|
+
name: element.name,
|
|
122
|
+
description: element.description,
|
|
123
|
+
properties,
|
|
124
|
+
spec_node_id: element.spec_node_id || void 0,
|
|
125
|
+
layer_id: element.layer_id || void 0,
|
|
126
|
+
attributes: element.attributes,
|
|
127
|
+
source_reference: element.source_reference,
|
|
128
|
+
metadata: element.metadata
|
|
129
|
+
});
|
|
130
|
+
return updated && (this.dirty = !0), updated;
|
|
21
131
|
}
|
|
22
132
|
/**
|
|
23
|
-
* Delete an element by ID
|
|
133
|
+
* Delete an element by ID from the graph
|
|
134
|
+
*
|
|
135
|
+
* @param id - UUID of the element to delete
|
|
136
|
+
* @returns true if element was deleted, false if not found
|
|
24
137
|
*/
|
|
25
138
|
deleteElement(id) {
|
|
26
|
-
|
|
139
|
+
let node = this.graph.nodes.get(id);
|
|
140
|
+
if (!node || node.layer !== this.name) {
|
|
141
|
+
for (const candidate of this.graph.nodes.values())
|
|
142
|
+
if (candidate.layer === this.name && (candidate.uuid === id || candidate.properties?.__semanticId__ === id || candidate.id === id)) {
|
|
143
|
+
node = candidate;
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (!node || node.layer !== this.name)
|
|
148
|
+
return !1;
|
|
149
|
+
const result = this.graph.removeNode(node.id);
|
|
27
150
|
return result && (this.dirty = !0), result;
|
|
28
151
|
}
|
|
29
152
|
/**
|
|
30
|
-
* List all elements in the layer
|
|
153
|
+
* List all elements in the layer from the graph
|
|
31
154
|
*/
|
|
32
155
|
listElements() {
|
|
33
|
-
return
|
|
156
|
+
return this.graph.getNodesByLayer(this.name).map((node) => new Element({
|
|
157
|
+
id: node.uuid || node.id,
|
|
158
|
+
path: node.id,
|
|
159
|
+
spec_node_id: node.spec_node_id,
|
|
160
|
+
layer_id: node.layer_id,
|
|
161
|
+
type: node.type,
|
|
162
|
+
name: node.name,
|
|
163
|
+
description: node.description,
|
|
164
|
+
attributes: node.attributes,
|
|
165
|
+
source_reference: node.source_reference,
|
|
166
|
+
metadata: node.metadata,
|
|
167
|
+
layer: node.layer,
|
|
168
|
+
references: node.properties?.__references__ ?? [],
|
|
169
|
+
relationships: node.properties?.__relationships__ ?? []
|
|
170
|
+
}));
|
|
34
171
|
}
|
|
35
172
|
/**
|
|
36
173
|
* Check if layer has unsaved changes
|
|
@@ -49,23 +186,29 @@ class Layer {
|
|
|
49
186
|
*/
|
|
50
187
|
toJSON() {
|
|
51
188
|
const result = {
|
|
52
|
-
elements:
|
|
189
|
+
elements: this.listElements().map((e) => e.toJSON())
|
|
53
190
|
};
|
|
54
191
|
return this.metadata && (result.metadata = this.metadata), result;
|
|
55
192
|
}
|
|
56
193
|
/**
|
|
57
194
|
* Create Layer from JSON data
|
|
58
195
|
*/
|
|
59
|
-
static fromJSON(name, data) {
|
|
196
|
+
static fromJSON(name, data, graph) {
|
|
60
197
|
const elements = data.elements.map((e) => new Element({
|
|
61
198
|
id: e.id,
|
|
199
|
+
path: e.path,
|
|
200
|
+
spec_node_id: e.spec_node_id,
|
|
201
|
+
layer_id: e.layer_id,
|
|
62
202
|
type: e.type,
|
|
63
203
|
name: e.name,
|
|
64
204
|
description: e.description,
|
|
65
|
-
|
|
205
|
+
attributes: e.attributes,
|
|
206
|
+
source_reference: e.source_reference,
|
|
207
|
+
metadata: e.metadata,
|
|
66
208
|
references: e.references,
|
|
67
|
-
relationships: e.relationships
|
|
68
|
-
|
|
209
|
+
relationships: e.relationships,
|
|
210
|
+
layer: name
|
|
211
|
+
})), layer = new Layer(name, graph, elements);
|
|
69
212
|
return layer.metadata = data.metadata, layer;
|
|
70
213
|
}
|
|
71
214
|
}
|
package/dist/core/layer.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/core/layer.ts"],
|
|
4
|
-
"sourcesContent": ["import { Element } from \"./element.js\";\nimport type { LayerData } from \"../types/index.js\";\n\n/**\n * Layer class representing a container for elements within a layer\n */\nexport class Layer {\n name: string;\n elements: Map<string, Element>;\n metadata?: { layer: string; version: string };\n private dirty: boolean = false;\n\n constructor(name: string, elements: Element[] = []) {\n this.name = name;\n this.elements = new Map(elements.map((e) => [e.id, e]));\n }\n\n /**\n * Add an element to the layer\n */\n addElement(element: Element): void {\n this.elements.set(element.id, element);\n this.dirty = true;\n }\n\n /**\n * Get an element by ID\n */\n getElement(id: string): Element | undefined {\n return this.elements.get(id);\n }\n\n /**\n * Delete an element by ID\n */\n deleteElement(id: string): boolean {\n const result = this.elements.delete(id);\n if (result) {\n this.dirty = true;\n }\n return result;\n }\n\n /**\n * List all elements in the layer\n */\n listElements(): Element[] {\n return Array.from(this.elements.values());\n }\n\n /**\n * Check if layer has unsaved changes\n */\n isDirty(): boolean {\n return this.dirty;\n }\n\n /**\n * Mark layer as clean (no unsaved changes)\n */\n markClean(): void {\n this.dirty = false;\n }\n\n /**\n * Serialize to JSON representation\n */\n toJSON(): LayerData {\n const result: LayerData = {\n elements: Array.from(this.elements.values()).map((e) => e.toJSON()),\n };\n\n if (this.metadata) {\n result.metadata = this.metadata;\n }\n\n return result;\n }\n\n /**\n * Create Layer from JSON data\n */\n static fromJSON(name: string, data: LayerData): Layer {\n const elements = data.elements.map(\n (e) =>\n new Element({\n id: e.id,\n type: e.type,\n name: e.name,\n description: e.description,\n properties: e.properties,\n references: e.references,\n relationships: e.relationships,\n })\n );\n const layer = new Layer(name, elements);\n layer.metadata = data.metadata;\n return layer;\n }\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,eAAe;
|
|
4
|
+
"sourcesContent": ["import { Element } from \"./element.js\";\nimport { GraphModel } from \"./graph-model.js\";\nimport type { LayerData, Reference, Relationship } from \"../types/index.js\";\n\n/**\n * Layer class - thin wrapper over graph model for backward compatibility\n * Queries the graph for elements in a specific layer\n */\nexport class Layer {\n name: string;\n graph: GraphModel;\n metadata?: { layer: string; version: string };\n private dirty: boolean = false;\n private cachedElements: Map<string, Element> | null = null;\n private cachedNodesVersion: number = 0;\n\n constructor(\n name: string,\n elementsOrGraph?: Element[] | GraphModel,\n elementsIfGraphPassed?: Element[]\n ) {\n this.name = name;\n\n // Handle overloaded constructor:\n // new Layer(name) - create with empty graph\n // new Layer(name, elements) - create with elements array\n // new Layer(name, graph) - create with provided graph\n // new Layer(name, undefined, elements) - create with elements\n // new Layer(name, graph, elements) - create with provided graph and elements\n let actualGraph: GraphModel | undefined;\n let elementsToAdd: Element[] = [];\n\n if (elementsOrGraph instanceof GraphModel) {\n // Called with graph as second parameter\n actualGraph = elementsOrGraph;\n // Elements are in the third parameter if provided\n if (Array.isArray(elementsIfGraphPassed)) {\n elementsToAdd = elementsIfGraphPassed;\n }\n } else if (Array.isArray(elementsOrGraph)) {\n // Called with elements as second parameter\n elementsToAdd = elementsOrGraph;\n } else if (elementsOrGraph === undefined && Array.isArray(elementsIfGraphPassed)) {\n // Called with undefined graph and elements in third parameter\n elementsToAdd = elementsIfGraphPassed;\n }\n\n // Use provided graph or create a new one\n this.graph = actualGraph || new GraphModel();\n\n // Add elements to the graph (without marking as dirty during construction)\n for (const element of elementsToAdd) {\n // Ensure element has the correct layer\n element.layer = this.name;\n // Also set layer_id to maintain consistency with layer name\n if (!element.layer_id || element.layer_id === \"\") {\n element.layer_id = this.name;\n }\n const node = GraphModel.fromElement(element);\n\n // Store references and relationships as node properties for preservation\n // Ensure properties object exists; fromElement always initializes it, but type is optional\n const nodeProperties = node.properties || {};\n node.properties = nodeProperties;\n\n if (element.references && element.references.length > 0) {\n nodeProperties[\"__references__\"] = element.references;\n }\n if (element.relationships && element.relationships.length > 0) {\n nodeProperties[\"__relationships__\"] = element.relationships;\n }\n\n // Store semantic ID if present (for legacy format elements converted to UUID)\n if ((element as any).semanticId) {\n nodeProperties[\"__semanticId__\"] = (element as any).semanticId;\n }\n\n this.graph.addNode(node);\n // Don't mark as dirty during construction - elements added in constructor are initial state\n }\n }\n\n /**\n * Get all elements in this layer from the graph\n * Converts graph nodes back to Elements for backward compatibility\n * Results are cached and invalidated when the underlying graph changes\n */\n get elements(): Map<string, Element> {\n const currentVersion = this.graph.getNodesVersion();\n\n // Return cached result if graph hasn't changed\n if (this.cachedElements !== null && this.cachedNodesVersion === currentVersion) {\n return this.cachedElements;\n }\n\n // Rebuild cache\n const result = new Map<string, Element>();\n const nodes = this.graph.getNodesByLayer(this.name);\n\n for (const node of nodes) {\n const element = new Element({\n id: node.uuid || node.id,\n path: node.id,\n spec_node_id: node.spec_node_id,\n layer_id: node.layer_id,\n type: node.type,\n name: node.name,\n description: node.description,\n attributes: node.attributes,\n source_reference: node.source_reference,\n metadata: node.metadata,\n layer: node.layer,\n references: (node.properties?.[\"__references__\"] ?? []) as Reference[],\n relationships: (node.properties?.[\"__relationships__\"] ?? []) as Relationship[],\n semanticId: node.properties?.[\"__semanticId__\"],\n } as any);\n result.set(node.id, element);\n }\n\n this.cachedElements = result;\n this.cachedNodesVersion = currentVersion;\n return result;\n }\n\n /**\n * Add an element to the layer (stores in graph)\n */\n addElement(element: Element): void {\n // Ensure element has the correct layer\n element.layer = this.name;\n // Also set layer_id to maintain consistency with layer name\n if (!element.layer_id || element.layer_id === \"\") {\n element.layer_id = this.name;\n }\n const node = GraphModel.fromElement(element);\n\n // Store references and relationships as node properties for preservation\n // Ensure properties object exists; fromElement always initializes it, but type is optional\n const nodeProperties = node.properties || {};\n node.properties = nodeProperties;\n\n if (element.references && element.references.length > 0) {\n nodeProperties[\"__references__\"] = element.references;\n }\n if (element.relationships && element.relationships.length > 0) {\n nodeProperties[\"__relationships__\"] = element.relationships;\n }\n\n // Store semantic ID if present (for legacy format elements converted to UUID)\n if ((element as any).semanticId) {\n nodeProperties[\"__semanticId__\"] = (element as any).semanticId;\n }\n\n // Add node to graph first\n this.graph.addNode(node);\n\n // Create graph edges from references for export compatibility\n // Only create edges if both source and destination nodes exist\n if (element.references && element.references.length > 0) {\n for (const ref of element.references) {\n if (this.graph.nodes.has(ref.source) && this.graph.nodes.has(ref.target)) {\n this.graph.addEdge({\n id: `${ref.source}-${ref.type}-${ref.target}`,\n source: ref.source,\n destination: ref.target,\n predicate: ref.type,\n properties: {},\n });\n }\n }\n }\n\n // Create graph edges from relationships for export compatibility\n // Only create edges if both source and destination nodes exist\n if (element.relationships && element.relationships.length > 0) {\n for (const rel of element.relationships) {\n if (this.graph.nodes.has(rel.source) && this.graph.nodes.has(rel.target)) {\n this.graph.addEdge({\n id: `${rel.source}-${rel.predicate}-${rel.target}`,\n source: rel.source,\n destination: rel.target,\n predicate: rel.predicate,\n properties: {},\n });\n }\n }\n }\n\n this.dirty = true;\n }\n\n /**\n * Get an element by UUID or semantic ID from the graph.\n * Supports direct UUID lookup, and falls back to semantic ID lookup for legacy elements.\n *\n * @param id - UUID or semantic ID of the element to get\n * @returns The element if found, undefined if not found\n */\n getElement(id: string): Element | undefined {\n // First try direct lookup by path (graph key) or UUID\n let node = this.graph.nodes.get(id);\n\n if (!node) {\n // Fallback: look up by UUID (node.uuid === id) or legacy semanticId\n for (const candidate of this.graph.nodes.values()) {\n if (\n candidate.layer === this.name &&\n (candidate.uuid === id ||\n candidate.properties?.[\"__semanticId__\"] === id ||\n candidate.id === id)\n ) {\n node = candidate;\n break;\n }\n }\n }\n\n if (!node || node.layer !== this.name) {\n return undefined;\n }\n\n return new Element({\n id: node.uuid || node.id,\n path: node.id,\n spec_node_id: node.spec_node_id,\n layer_id: node.layer_id,\n type: node.type,\n name: node.name,\n description: node.description,\n attributes: node.attributes,\n source_reference: node.source_reference,\n metadata: node.metadata,\n layer: node.layer,\n references: (node.properties?.[\"__references__\"] ?? []) as Reference[],\n relationships: (node.properties?.[\"__relationships__\"] ?? []) as Relationship[],\n });\n }\n\n /**\n * Update an element in the graph\n */\n updateElement(element: Element): boolean {\n const node = this.graph.nodes.get(element.path || element.id);\n if (!node || node.layer !== this.name) {\n return false;\n }\n\n // Prepare properties including references and relationships\n // Start with existing node properties to preserve graph metadata fields like __references__ and __relationships__\n const properties = { ...(node.properties || {}) };\n\n // Persist references and relationships as node properties\n if (element.references && element.references.length > 0) {\n properties[\"__references__\"] = element.references;\n } else {\n delete properties[\"__references__\"];\n }\n\n if (element.relationships && element.relationships.length > 0) {\n properties[\"__relationships__\"] = element.relationships;\n } else {\n delete properties[\"__relationships__\"];\n }\n\n // Convert element to graph node and update in place, including spec-node fields\n // so that source_reference and attributes changes aren't lost on the next save cycle\n const updated = this.graph.updateNode(element.path || element.id, {\n type: element.type,\n name: element.name,\n description: element.description,\n properties,\n spec_node_id: element.spec_node_id || undefined,\n layer_id: element.layer_id || undefined,\n attributes: element.attributes,\n source_reference: element.source_reference,\n metadata: element.metadata,\n });\n\n if (updated) {\n this.dirty = true;\n }\n return updated;\n }\n\n /**\n * Delete an element by ID from the graph\n *\n * @param id - UUID of the element to delete\n * @returns true if element was deleted, false if not found\n */\n deleteElement(id: string): boolean {\n let node = this.graph.nodes.get(id);\n\n if (!node || node.layer !== this.name) {\n // Fallback: search by UUID or semanticId if direct path lookup failed\n for (const candidate of this.graph.nodes.values()) {\n if (\n candidate.layer === this.name &&\n (candidate.uuid === id ||\n candidate.properties?.[\"__semanticId__\"] === id ||\n candidate.id === id)\n ) {\n node = candidate;\n break;\n }\n }\n }\n\n if (!node || node.layer !== this.name) {\n return false;\n }\n\n const result = this.graph.removeNode(node.id);\n if (result) {\n this.dirty = true;\n }\n return result;\n }\n\n /**\n * List all elements in the layer from the graph\n */\n listElements(): Element[] {\n const nodes = this.graph.getNodesByLayer(this.name);\n return nodes.map(\n (node) =>\n new Element({\n id: node.uuid || node.id,\n path: node.id,\n spec_node_id: node.spec_node_id,\n layer_id: node.layer_id,\n type: node.type,\n name: node.name,\n description: node.description,\n attributes: node.attributes,\n source_reference: node.source_reference,\n metadata: node.metadata,\n layer: node.layer,\n references: (node.properties?.[\"__references__\"] ?? []) as Reference[],\n relationships: (node.properties?.[\"__relationships__\"] ?? []) as Relationship[],\n })\n );\n }\n\n /**\n * Check if layer has unsaved changes\n */\n isDirty(): boolean {\n return this.dirty;\n }\n\n /**\n * Mark layer as clean (no unsaved changes)\n */\n markClean(): void {\n this.dirty = false;\n }\n\n /**\n * Serialize to JSON representation\n */\n toJSON(): LayerData {\n const result: LayerData = {\n elements: this.listElements().map((e) => e.toJSON()),\n };\n\n if (this.metadata) {\n result.metadata = this.metadata;\n }\n\n return result;\n }\n\n /**\n * Create Layer from JSON data\n */\n static fromJSON(name: string, data: LayerData, graph?: GraphModel): Layer {\n const elements = data.elements.map(\n (e) =>\n new Element({\n id: e.id,\n path: e.path,\n spec_node_id: e.spec_node_id,\n layer_id: e.layer_id,\n type: e.type,\n name: e.name,\n description: e.description,\n attributes: e.attributes,\n source_reference: e.source_reference,\n metadata: e.metadata,\n references: e.references,\n relationships: e.relationships,\n layer: name,\n })\n );\n const layer = new Layer(name, graph, elements);\n layer.metadata = data.metadata;\n return layer;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const CANONICAL_LAYER_NAMES = [
|
|
2
|
+
"motivation",
|
|
3
|
+
"business",
|
|
4
|
+
"security",
|
|
5
|
+
"application",
|
|
6
|
+
"technology",
|
|
7
|
+
"api",
|
|
8
|
+
"data-model",
|
|
9
|
+
"data-store",
|
|
10
|
+
"ux",
|
|
11
|
+
"navigation",
|
|
12
|
+
"apm",
|
|
13
|
+
"testing"
|
|
14
|
+
];
|
|
15
|
+
function getLayerOrder(layerName) {
|
|
16
|
+
const index = CANONICAL_LAYER_NAMES.indexOf(layerName);
|
|
17
|
+
return index >= 0 ? index + 1 : -1;
|
|
18
|
+
}
|
|
19
|
+
function getLayerByOrder(order) {
|
|
20
|
+
if (!(order < 1 || order > CANONICAL_LAYER_NAMES.length))
|
|
21
|
+
return CANONICAL_LAYER_NAMES[order - 1];
|
|
22
|
+
}
|
|
23
|
+
function isValidLayerName(name) {
|
|
24
|
+
return CANONICAL_LAYER_NAMES.includes(name);
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
CANONICAL_LAYER_NAMES,
|
|
28
|
+
getLayerByOrder,
|
|
29
|
+
getLayerOrder,
|
|
30
|
+
isValidLayerName
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=layers.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/core/layers.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Canonical layer names and ordering for the 12-layer architecture model.\n * This is the source of truth for layer naming and ordering.\n */\n\nexport const CANONICAL_LAYER_NAMES = [\n 'motivation',\n 'business',\n 'security',\n 'application',\n 'technology',\n 'api',\n 'data-model',\n 'data-store',\n 'ux',\n 'navigation',\n 'apm',\n 'testing'\n] as const;\n\nexport type CanonicalLayerName = (typeof CANONICAL_LAYER_NAMES)[number];\n\n/**\n * Get the numeric order of a layer (1-12)\n */\nexport function getLayerOrder(layerName: string): number {\n const index = CANONICAL_LAYER_NAMES.indexOf(layerName as CanonicalLayerName);\n return index >= 0 ? index + 1 : -1;\n}\n\n/**\n * Get layer name by numeric order (1-12)\n */\nexport function getLayerByOrder(order: number): string | undefined {\n if (order < 1 || order > CANONICAL_LAYER_NAMES.length) {\n return undefined;\n }\n return CANONICAL_LAYER_NAMES[order - 1];\n}\n\n/**\n * Check if a layer name is valid (type predicate for compile-time narrowing)\n */\nexport function isValidLayerName(name: string): name is CanonicalLayerName {\n return CANONICAL_LAYER_NAMES.includes(name as CanonicalLayerName);\n}\n"],
|
|
5
|
+
"mappings": "AAKO,MAAM,wBAAwB;EACnC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAQI,SAAU,cAAc,WAAiB;AAC7C,QAAM,QAAQ,sBAAsB,QAAQ,SAA+B;AAC3E,SAAO,SAAS,IAAI,QAAQ,IAAI;AAClC;AAKM,SAAU,gBAAgB,OAAa;AAC3C,MAAI,UAAQ,KAAK,QAAQ,sBAAsB;AAG/C,WAAO,sBAAsB,QAAQ,CAAC;AACxC;AAKM,SAAU,iBAAiB,MAAY;AAC3C,SAAO,sBAAsB,SAAS,IAA0B;AAClE;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|