@cratis/scene.engine 4.2.0 → 4.3.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/dist/cjs/editing/DescriptorCatalog.js +42 -0
- package/dist/cjs/editing/DescriptorCatalog.js.map +1 -0
- package/dist/cjs/editing/EditSession.js +44 -0
- package/dist/cjs/editing/EditSession.js.map +1 -0
- package/dist/cjs/editing/applyEdit.js +83 -0
- package/dist/cjs/editing/applyEdit.js.map +1 -0
- package/dist/cjs/editing/applyEffectiveConfiguration.js +62 -0
- package/dist/cjs/editing/applyEffectiveConfiguration.js.map +1 -0
- package/dist/cjs/editing/collectComponents.js +34 -0
- package/dist/cjs/editing/collectComponents.js.map +1 -0
- package/dist/cjs/editing/describeNode.js +63 -0
- package/dist/cjs/editing/describeNode.js.map +1 -0
- package/dist/cjs/editing/diagnostics.js +36 -0
- package/dist/cjs/editing/diagnostics.js.map +1 -0
- package/dist/cjs/editing/documentPaths.js +45 -0
- package/dist/cjs/editing/documentPaths.js.map +1 -0
- package/dist/cjs/editing/exposureEdits.js +106 -0
- package/dist/cjs/editing/exposureEdits.js.map +1 -0
- package/dist/cjs/editing/exposureGrants.js +115 -0
- package/dist/cjs/editing/exposureGrants.js.map +1 -0
- package/dist/cjs/editing/indexDocument.js +400 -0
- package/dist/cjs/editing/indexDocument.js.map +1 -0
- package/dist/cjs/editing/inspect.js +127 -0
- package/dist/cjs/editing/inspect.js.map +1 -0
- package/dist/cjs/editing/instanceEdits.js +255 -0
- package/dist/cjs/editing/instanceEdits.js.map +1 -0
- package/dist/cjs/editing/layoutTypeDescriptors.js +425 -0
- package/dist/cjs/editing/layoutTypeDescriptors.js.map +1 -0
- package/dist/cjs/editing/layoutTypeEdits.js +141 -0
- package/dist/cjs/editing/layoutTypeEdits.js.map +1 -0
- package/dist/cjs/editing/nodeIds.js +115 -0
- package/dist/cjs/editing/nodeIds.js.map +1 -0
- package/dist/cjs/editing/pathAccess.js +53 -0
- package/dist/cjs/editing/pathAccess.js.map +1 -0
- package/dist/cjs/editing/propertyEdits.js +118 -0
- package/dist/cjs/editing/propertyEdits.js.map +1 -0
- package/dist/cjs/editing/resolveEffectiveConfiguration.js +200 -0
- package/dist/cjs/editing/resolveEffectiveConfiguration.js.map +1 -0
- package/dist/cjs/editing/resolveTemplateChain.js +100 -0
- package/dist/cjs/editing/resolveTemplateChain.js.map +1 -0
- package/dist/cjs/editing/structureEdits.js +231 -0
- package/dist/cjs/editing/structureEdits.js.map +1 -0
- package/dist/cjs/editing/validateBinding.js +111 -0
- package/dist/cjs/editing/validateBinding.js.map +1 -0
- package/dist/cjs/editing/validateValue.js +114 -0
- package/dist/cjs/editing/validateValue.js.map +1 -0
- package/dist/cjs/index.js +51 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/editing/DescriptorCatalog.d.ts +9 -0
- package/dist/esm/editing/DescriptorCatalog.d.ts.map +1 -0
- package/dist/esm/editing/DescriptorCatalog.js +38 -0
- package/dist/esm/editing/DescriptorCatalog.js.map +1 -0
- package/dist/esm/editing/DocumentIndex.d.ts +31 -0
- package/dist/esm/editing/DocumentIndex.d.ts.map +1 -0
- package/dist/esm/editing/DocumentIndex.js +2 -0
- package/dist/esm/editing/DocumentIndex.js.map +1 -0
- package/dist/esm/editing/EditOutcome.d.ts +7 -0
- package/dist/esm/editing/EditOutcome.d.ts.map +1 -0
- package/dist/esm/editing/EditOutcome.js +2 -0
- package/dist/esm/editing/EditOutcome.js.map +1 -0
- package/dist/esm/editing/EditSession.d.ts +20 -0
- package/dist/esm/editing/EditSession.d.ts.map +1 -0
- package/dist/esm/editing/EditSession.js +42 -0
- package/dist/esm/editing/EditSession.js.map +1 -0
- package/dist/esm/editing/EditingContext.d.ts +8 -0
- package/dist/esm/editing/EditingContext.d.ts.map +1 -0
- package/dist/esm/editing/EditingContext.js +2 -0
- package/dist/esm/editing/EditingContext.js.map +1 -0
- package/dist/esm/editing/TemplateChain.d.ts +13 -0
- package/dist/esm/editing/TemplateChain.d.ts.map +1 -0
- package/dist/esm/editing/TemplateChain.js +2 -0
- package/dist/esm/editing/TemplateChain.js.map +1 -0
- package/dist/esm/editing/applyEdit.d.ts +5 -0
- package/dist/esm/editing/applyEdit.d.ts.map +1 -0
- package/dist/esm/editing/applyEdit.js +81 -0
- package/dist/esm/editing/applyEdit.js.map +1 -0
- package/dist/esm/editing/applyEffectiveConfiguration.d.ts +3 -0
- package/dist/esm/editing/applyEffectiveConfiguration.d.ts.map +1 -0
- package/dist/esm/editing/applyEffectiveConfiguration.js +60 -0
- package/dist/esm/editing/applyEffectiveConfiguration.js.map +1 -0
- package/dist/esm/editing/collectComponents.d.ts +3 -0
- package/dist/esm/editing/collectComponents.d.ts.map +1 -0
- package/dist/esm/editing/collectComponents.js +32 -0
- package/dist/esm/editing/collectComponents.js.map +1 -0
- package/dist/esm/editing/describeNode.d.ts +11 -0
- package/dist/esm/editing/describeNode.d.ts.map +1 -0
- package/dist/esm/editing/describeNode.js +60 -0
- package/dist/esm/editing/describeNode.js.map +1 -0
- package/dist/esm/editing/diagnostics.d.ts +6 -0
- package/dist/esm/editing/diagnostics.d.ts.map +1 -0
- package/dist/esm/editing/diagnostics.js +32 -0
- package/dist/esm/editing/diagnostics.js.map +1 -0
- package/dist/esm/editing/documentPaths.d.ts +8 -0
- package/dist/esm/editing/documentPaths.d.ts.map +1 -0
- package/dist/esm/editing/documentPaths.js +41 -0
- package/dist/esm/editing/documentPaths.js.map +1 -0
- package/dist/esm/editing/exposureEdits.d.ts +5 -0
- package/dist/esm/editing/exposureEdits.d.ts.map +1 -0
- package/dist/esm/editing/exposureEdits.js +103 -0
- package/dist/esm/editing/exposureEdits.js.map +1 -0
- package/dist/esm/editing/exposureGrants.d.ts +21 -0
- package/dist/esm/editing/exposureGrants.d.ts.map +1 -0
- package/dist/esm/editing/exposureGrants.js +112 -0
- package/dist/esm/editing/exposureGrants.js.map +1 -0
- package/dist/esm/editing/given/a_layout_document.d.ts +14 -0
- package/dist/esm/editing/given/a_layout_document.d.ts.map +1 -0
- package/dist/esm/editing/given/a_layout_document.js +67 -0
- package/dist/esm/editing/given/a_layout_document.js.map +1 -0
- package/dist/esm/editing/given/a_scene_document.d.ts +20 -0
- package/dist/esm/editing/given/a_scene_document.d.ts.map +1 -0
- package/dist/esm/editing/given/a_scene_document.js +110 -0
- package/dist/esm/editing/given/a_scene_document.js.map +1 -0
- package/dist/esm/editing/index.d.ts +19 -0
- package/dist/esm/editing/index.d.ts.map +1 -0
- package/dist/esm/editing/index.js +19 -0
- package/dist/esm/editing/index.js.map +1 -0
- package/dist/esm/editing/indexDocument.d.ts +6 -0
- package/dist/esm/editing/indexDocument.d.ts.map +1 -0
- package/dist/esm/editing/indexDocument.js +396 -0
- package/dist/esm/editing/indexDocument.js.map +1 -0
- package/dist/esm/editing/inspect.d.ts +8 -0
- package/dist/esm/editing/inspect.d.ts.map +1 -0
- package/dist/esm/editing/inspect.js +124 -0
- package/dist/esm/editing/inspect.js.map +1 -0
- package/dist/esm/editing/instanceEdits.d.ts +9 -0
- package/dist/esm/editing/instanceEdits.d.ts.map +1 -0
- package/dist/esm/editing/instanceEdits.js +248 -0
- package/dist/esm/editing/instanceEdits.js.map +1 -0
- package/dist/esm/editing/layoutTypeDescriptors.d.ts +5 -0
- package/dist/esm/editing/layoutTypeDescriptors.d.ts.map +1 -0
- package/dist/esm/editing/layoutTypeDescriptors.js +421 -0
- package/dist/esm/editing/layoutTypeDescriptors.js.map +1 -0
- package/dist/esm/editing/layoutTypeEdits.d.ts +4 -0
- package/dist/esm/editing/layoutTypeEdits.d.ts.map +1 -0
- package/dist/esm/editing/layoutTypeEdits.js +139 -0
- package/dist/esm/editing/layoutTypeEdits.js.map +1 -0
- package/dist/esm/editing/nodeIds.d.ts +14 -0
- package/dist/esm/editing/nodeIds.d.ts.map +1 -0
- package/dist/esm/editing/nodeIds.js +102 -0
- package/dist/esm/editing/nodeIds.js.map +1 -0
- package/dist/esm/editing/pathAccess.d.ts +7 -0
- package/dist/esm/editing/pathAccess.d.ts.map +1 -0
- package/dist/esm/editing/pathAccess.js +48 -0
- package/dist/esm/editing/pathAccess.js.map +1 -0
- package/dist/esm/editing/propertyEdits.d.ts +15 -0
- package/dist/esm/editing/propertyEdits.d.ts.map +1 -0
- package/dist/esm/editing/propertyEdits.js +113 -0
- package/dist/esm/editing/propertyEdits.js.map +1 -0
- package/dist/esm/editing/resolveEffectiveConfiguration.d.ts +5 -0
- package/dist/esm/editing/resolveEffectiveConfiguration.d.ts.map +1 -0
- package/dist/esm/editing/resolveEffectiveConfiguration.js +198 -0
- package/dist/esm/editing/resolveEffectiveConfiguration.js.map +1 -0
- package/dist/esm/editing/resolveTemplateChain.d.ts +4 -0
- package/dist/esm/editing/resolveTemplateChain.d.ts.map +1 -0
- package/dist/esm/editing/resolveTemplateChain.js +98 -0
- package/dist/esm/editing/resolveTemplateChain.js.map +1 -0
- package/dist/esm/editing/structureEdits.d.ts +6 -0
- package/dist/esm/editing/structureEdits.d.ts.map +1 -0
- package/dist/esm/editing/structureEdits.js +227 -0
- package/dist/esm/editing/structureEdits.js.map +1 -0
- package/dist/esm/editing/validateBinding.d.ts +7 -0
- package/dist/esm/editing/validateBinding.d.ts.map +1 -0
- package/dist/esm/editing/validateBinding.js +108 -0
- package/dist/esm/editing/validateBinding.js.map +1 -0
- package/dist/esm/editing/validateValue.d.ts +8 -0
- package/dist/esm/editing/validateValue.d.ts.map +1 -0
- package/dist/esm/editing/validateValue.js +111 -0
- package/dist/esm/editing/validateValue.js.map +1 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +14 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/editing/DescriptorCatalog.ts +51 -0
- package/editing/DocumentIndex.ts +73 -0
- package/editing/EditOutcome.ts +21 -0
- package/editing/EditSession.ts +50 -0
- package/editing/EditingContext.ts +23 -0
- package/editing/TemplateChain.ts +36 -0
- package/editing/applyEdit.ts +69 -0
- package/editing/applyEffectiveConfiguration.ts +53 -0
- package/editing/collectComponents.ts +36 -0
- package/editing/describeNode.ts +61 -0
- package/editing/diagnostics.ts +30 -0
- package/editing/documentPaths.ts +40 -0
- package/editing/exposureEdits.ts +119 -0
- package/editing/exposureGrants.ts +159 -0
- package/editing/given/a_layout_document.ts +88 -0
- package/editing/given/a_scene_document.ts +135 -0
- package/editing/index.ts +21 -0
- package/editing/indexDocument.ts +237 -0
- package/editing/inspect.ts +142 -0
- package/editing/instanceEdits.ts +243 -0
- package/editing/layoutTypeDescriptors.ts +191 -0
- package/editing/layoutTypeEdits.ts +135 -0
- package/editing/nodeIds.ts +111 -0
- package/editing/pathAccess.ts +81 -0
- package/editing/propertyEdits.ts +119 -0
- package/editing/resolveEffectiveConfiguration.ts +202 -0
- package/editing/resolveTemplateChain.ts +109 -0
- package/editing/structureEdits.ts +234 -0
- package/editing/validateBinding.ts +103 -0
- package/editing/validateValue.ts +130 -0
- package/index.ts +1 -0
- package/package.json +5 -4
- package/dist/esm/for_aggregateContributions/when_aggregating_by_contribution_point.d.ts +0 -2
- package/dist/esm/for_aggregateContributions/when_aggregating_by_contribution_point.d.ts.map +0 -1
- package/dist/esm/for_aggregateContributions/when_aggregating_by_contribution_point.js +0 -23
- package/dist/esm/for_aggregateContributions/when_aggregating_by_contribution_point.js.map +0 -1
- package/dist/esm/for_buildStarterProfile/when_checking_against_the_shared_fixture_corpus.d.ts +0 -2
- package/dist/esm/for_buildStarterProfile/when_checking_against_the_shared_fixture_corpus.d.ts.map +0 -1
- package/dist/esm/for_buildStarterProfile/when_checking_against_the_shared_fixture_corpus.js +0 -16
- package/dist/esm/for_buildStarterProfile/when_checking_against_the_shared_fixture_corpus.js.map +0 -1
- package/dist/esm/for_computeSizeClass/when_computing_the_size_class.d.ts +0 -2
- package/dist/esm/for_computeSizeClass/when_computing_the_size_class.d.ts.map +0 -1
- package/dist/esm/for_computeSizeClass/when_computing_the_size_class.js +0 -17
- package/dist/esm/for_computeSizeClass/when_computing_the_size_class.js.map +0 -1
- package/dist/esm/for_evaluateFlowArrangement/when_evaluating_against_the_shared_fixture_corpus.d.ts +0 -2
- package/dist/esm/for_evaluateFlowArrangement/when_evaluating_against_the_shared_fixture_corpus.d.ts.map +0 -1
- package/dist/esm/for_evaluateFlowArrangement/when_evaluating_against_the_shared_fixture_corpus.js +0 -43
- package/dist/esm/for_evaluateFlowArrangement/when_evaluating_against_the_shared_fixture_corpus.js.map +0 -1
- package/dist/esm/for_evaluateFreeformArrangement/when_evaluating_against_the_shared_fixture_corpus.d.ts +0 -2
- package/dist/esm/for_evaluateFreeformArrangement/when_evaluating_against_the_shared_fixture_corpus.d.ts.map +0 -1
- package/dist/esm/for_evaluateFreeformArrangement/when_evaluating_against_the_shared_fixture_corpus.js +0 -46
- package/dist/esm/for_evaluateFreeformArrangement/when_evaluating_against_the_shared_fixture_corpus.js.map +0 -1
- package/dist/esm/for_evaluateFreeformSlotArrangement/when_evaluating_against_the_shared_fixture_corpus.d.ts +0 -2
- package/dist/esm/for_evaluateFreeformSlotArrangement/when_evaluating_against_the_shared_fixture_corpus.d.ts.map +0 -1
- package/dist/esm/for_evaluateFreeformSlotArrangement/when_evaluating_against_the_shared_fixture_corpus.js +0 -25
- package/dist/esm/for_evaluateFreeformSlotArrangement/when_evaluating_against_the_shared_fixture_corpus.js.map +0 -1
- package/dist/esm/for_incompatibleStarterThemes/when_checking_against_the_shared_fixture_corpus.d.ts +0 -2
- package/dist/esm/for_incompatibleStarterThemes/when_checking_against_the_shared_fixture_corpus.d.ts.map +0 -1
- package/dist/esm/for_incompatibleStarterThemes/when_checking_against_the_shared_fixture_corpus.js +0 -17
- package/dist/esm/for_incompatibleStarterThemes/when_checking_against_the_shared_fixture_corpus.js.map +0 -1
- package/dist/esm/for_packageCatalog/when_querying_against_the_shared_fixture_corpus.d.ts +0 -2
- package/dist/esm/for_packageCatalog/when_querying_against_the_shared_fixture_corpus.d.ts.map +0 -1
- package/dist/esm/for_packageCatalog/when_querying_against_the_shared_fixture_corpus.js +0 -22
- package/dist/esm/for_packageCatalog/when_querying_against_the_shared_fixture_corpus.js.map +0 -1
- package/dist/esm/for_packageDependencies/fixtures.d.ts +0 -38
- package/dist/esm/for_packageDependencies/fixtures.d.ts.map +0 -1
- package/dist/esm/for_packageDependencies/fixtures.js +0 -5
- package/dist/esm/for_packageDependencies/fixtures.js.map +0 -1
- package/dist/esm/for_packageDependencies/when_resolving_against_the_shared_fixture_corpus.d.ts +0 -2
- package/dist/esm/for_packageDependencies/when_resolving_against_the_shared_fixture_corpus.d.ts.map +0 -1
- package/dist/esm/for_packageDependencies/when_resolving_against_the_shared_fixture_corpus.js +0 -29
- package/dist/esm/for_packageDependencies/when_resolving_against_the_shared_fixture_corpus.js.map +0 -1
- package/dist/esm/for_packageVersionRange/when_checking_against_the_shared_fixture_corpus.d.ts +0 -2
- package/dist/esm/for_packageVersionRange/when_checking_against_the_shared_fixture_corpus.d.ts.map +0 -1
- package/dist/esm/for_packageVersionRange/when_checking_against_the_shared_fixture_corpus.js +0 -10
- package/dist/esm/for_packageVersionRange/when_checking_against_the_shared_fixture_corpus.js.map +0 -1
- package/dist/esm/for_panelKind/when_telling_the_panels_apart.d.ts +0 -2
- package/dist/esm/for_panelKind/when_telling_the_panels_apart.d.ts.map +0 -1
- package/dist/esm/for_panelKind/when_telling_the_panels_apart.js +0 -38
- package/dist/esm/for_panelKind/when_telling_the_panels_apart.js.map +0 -1
- package/dist/esm/for_renderElement/when_rendering_a_mixed_tree.d.ts +0 -2
- package/dist/esm/for_renderElement/when_rendering_a_mixed_tree.d.ts.map +0 -1
- package/dist/esm/for_renderElement/when_rendering_a_mixed_tree.js +0 -46
- package/dist/esm/for_renderElement/when_rendering_a_mixed_tree.js.map +0 -1
- package/dist/esm/for_resolveBehaviors/when_resolving_additive_attachments.d.ts +0 -2
- package/dist/esm/for_resolveBehaviors/when_resolving_additive_attachments.d.ts.map +0 -1
- package/dist/esm/for_resolveBehaviors/when_resolving_additive_attachments.js +0 -68
- package/dist/esm/for_resolveBehaviors/when_resolving_additive_attachments.js.map +0 -1
- package/dist/esm/for_resolveComponentName/when_resolving_against_the_shared_fixture_corpus.d.ts +0 -2
- package/dist/esm/for_resolveComponentName/when_resolving_against_the_shared_fixture_corpus.d.ts.map +0 -1
- package/dist/esm/for_resolveComponentName/when_resolving_against_the_shared_fixture_corpus.js +0 -20
- package/dist/esm/for_resolveComponentName/when_resolving_against_the_shared_fixture_corpus.js.map +0 -1
- package/dist/esm/for_resolveScreenTemplates/when_resolving_against_the_shared_fixture_corpus.d.ts +0 -2
- package/dist/esm/for_resolveScreenTemplates/when_resolving_against_the_shared_fixture_corpus.d.ts.map +0 -1
- package/dist/esm/for_resolveScreenTemplates/when_resolving_against_the_shared_fixture_corpus.js +0 -30
- package/dist/esm/for_resolveScreenTemplates/when_resolving_against_the_shared_fixture_corpus.js.map +0 -1
- package/dist/esm/for_resolveStrings/when_resolving_a_strings_reference.d.ts +0 -2
- package/dist/esm/for_resolveStrings/when_resolving_a_strings_reference.d.ts.map +0 -1
- package/dist/esm/for_resolveStrings/when_resolving_a_strings_reference.js +0 -69
- package/dist/esm/for_resolveStrings/when_resolving_a_strings_reference.js.map +0 -1
- package/dist/esm/for_runActions/given/a_recording_dispatcher.d.ts +0 -21
- package/dist/esm/for_runActions/given/a_recording_dispatcher.d.ts.map +0 -1
- package/dist/esm/for_runActions/given/a_recording_dispatcher.js +0 -45
- package/dist/esm/for_runActions/given/a_recording_dispatcher.js.map +0 -1
- package/dist/esm/for_runActions/when_running_a_sequence_of_actions.d.ts +0 -2
- package/dist/esm/for_runActions/when_running_a_sequence_of_actions.d.ts.map +0 -1
- package/dist/esm/for_runActions/when_running_a_sequence_of_actions.js +0 -126
- package/dist/esm/for_runActions/when_running_a_sequence_of_actions.js.map +0 -1
- package/dist/esm/for_runActions/when_running_against_the_shared_fixture_corpus.d.ts +0 -2
- package/dist/esm/for_runActions/when_running_against_the_shared_fixture_corpus.d.ts.map +0 -1
- package/dist/esm/for_runActions/when_running_against_the_shared_fixture_corpus.js +0 -61
- package/dist/esm/for_runActions/when_running_against_the_shared_fixture_corpus.js.map +0 -1
- package/dist/esm/for_themeCompatibility/when_checking_against_the_shared_fixture_corpus.d.ts +0 -2
- package/dist/esm/for_themeCompatibility/when_checking_against_the_shared_fixture_corpus.d.ts.map +0 -1
- package/dist/esm/for_themeCompatibility/when_checking_against_the_shared_fixture_corpus.js +0 -18
- package/dist/esm/for_themeCompatibility/when_checking_against_the_shared_fixture_corpus.js.map +0 -1
- package/for_aggregateContributions/when_aggregating_by_contribution_point.ts +0 -31
- package/for_buildStarterProfile/when_checking_against_the_shared_fixture_corpus.ts +0 -32
- package/for_computeSizeClass/when_computing_the_size_class.ts +0 -23
- package/for_evaluateFlowArrangement/when_evaluating_against_the_shared_fixture_corpus.ts +0 -67
- package/for_evaluateFreeformArrangement/when_evaluating_against_the_shared_fixture_corpus.ts +0 -68
- package/for_evaluateFreeformSlotArrangement/when_evaluating_against_the_shared_fixture_corpus.ts +0 -47
- package/for_incompatibleStarterThemes/when_checking_against_the_shared_fixture_corpus.ts +0 -34
- package/for_packageCatalog/when_querying_against_the_shared_fixture_corpus.ts +0 -26
- package/for_packageDependencies/fixtures.ts +0 -44
- package/for_packageDependencies/when_resolving_against_the_shared_fixture_corpus.ts +0 -39
- package/for_packageVersionRange/when_checking_against_the_shared_fixture_corpus.ts +0 -13
- package/for_panelKind/when_telling_the_panels_apart.ts +0 -47
- package/for_renderElement/when_rendering_a_mixed_tree.ts +0 -58
- package/for_resolveBehaviors/when_resolving_additive_attachments.ts +0 -100
- package/for_resolveComponentName/when_resolving_against_the_shared_fixture_corpus.ts +0 -36
- package/for_resolveScreenTemplates/when_resolving_against_the_shared_fixture_corpus.ts +0 -49
- package/for_resolveStrings/when_resolving_a_strings_reference.ts +0 -85
- package/for_runActions/given/a_recording_dispatcher.ts +0 -72
- package/for_runActions/when_running_a_sequence_of_actions.ts +0 -226
- package/for_runActions/when_running_against_the_shared_fixture_corpus.ts +0 -124
- package/for_themeCompatibility/when_checking_against_the_shared_fixture_corpus.ts +0 -37
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { ComponentDescriptor, LayoutTypeDescriptor } from '@cratis/scene.model';
|
|
5
|
+
import { layoutTypeDescriptors } from './layoutTypeDescriptors';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Everything an editor knows how to describe: the component descriptors packages contribute, and the layout types
|
|
9
|
+
* the model itself defines.
|
|
10
|
+
*
|
|
11
|
+
* It is a derived view over what packages ship - not a registry anything registers into. Build one from the
|
|
12
|
+
* descriptors of the packages a profile lists, and rebuild it when the list changes.
|
|
13
|
+
*/
|
|
14
|
+
export interface DescriptorCatalog {
|
|
15
|
+
components: ComponentDescriptor[];
|
|
16
|
+
layoutTypes: LayoutTypeDescriptor[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Builds a catalog from the component descriptors of the active packages, plus the built-in layout types.
|
|
21
|
+
*
|
|
22
|
+
* When two descriptors name the same component the later one wins, which is the same override-priority rule
|
|
23
|
+
* the profile's package order already means for components.
|
|
24
|
+
*/
|
|
25
|
+
export function createDescriptorCatalog(componentDescriptors: ComponentDescriptor[] = []): DescriptorCatalog {
|
|
26
|
+
const byComponent = new Map<string, ComponentDescriptor>();
|
|
27
|
+
for (const descriptor of componentDescriptors) byComponent.set(descriptor.component, descriptor);
|
|
28
|
+
|
|
29
|
+
return { components: [...byComponent.values()], layoutTypes: layoutTypeDescriptors };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Finds the descriptor of a component by the name an element carries.
|
|
34
|
+
*
|
|
35
|
+
* An exact match wins. Otherwise a bare name (`dataTable`) finds the one descriptor whose component ends in
|
|
36
|
+
* `:dataTable`; a bare name that several packages describe has no single answer, so it finds none.
|
|
37
|
+
*/
|
|
38
|
+
export function findComponentDescriptor(catalog: DescriptorCatalog, componentName: string): ComponentDescriptor | undefined {
|
|
39
|
+
const exact = catalog.components.find(descriptor => descriptor.component === componentName);
|
|
40
|
+
if (exact) return exact;
|
|
41
|
+
|
|
42
|
+
const matches = catalog.components.filter(descriptor => descriptor.component.endsWith(`:${componentName}`));
|
|
43
|
+
return matches.length === 1 ? matches[0] : undefined;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Finds the descriptor of a layout type.
|
|
48
|
+
*/
|
|
49
|
+
export function findLayoutTypeDescriptor(catalog: DescriptorCatalog, type: string): LayoutTypeDescriptor | undefined {
|
|
50
|
+
return catalog.layoutTypes.find(descriptor => descriptor.type === type);
|
|
51
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { SceneDiagnostic, SceneNodeKind } from '@cratis/scene.model';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A route into a {@link SceneDocument}: property names and array indexes, outermost first.
|
|
8
|
+
*/
|
|
9
|
+
export type DocumentPath = (string | number)[];
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Where a node sits in an array it can be inserted into, removed from or moved within.
|
|
13
|
+
*/
|
|
14
|
+
export interface ListLocation {
|
|
15
|
+
/** The path of the array. */
|
|
16
|
+
path: DocumentPath;
|
|
17
|
+
|
|
18
|
+
/** The node's index in the array. */
|
|
19
|
+
index: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Everything the engine knows about one addressable node.
|
|
24
|
+
*/
|
|
25
|
+
export interface NodeRecord {
|
|
26
|
+
id: string;
|
|
27
|
+
kind: SceneNodeKind;
|
|
28
|
+
|
|
29
|
+
/** A `LayoutType` for a layout node, the component name for a component, otherwise the kind of element. */
|
|
30
|
+
typeId: string;
|
|
31
|
+
|
|
32
|
+
/** A name for a tree or an inspector title. */
|
|
33
|
+
label: string;
|
|
34
|
+
|
|
35
|
+
/** Where the node's value is in the document. */
|
|
36
|
+
path: DocumentPath;
|
|
37
|
+
value: unknown;
|
|
38
|
+
|
|
39
|
+
parentId?: string;
|
|
40
|
+
|
|
41
|
+
/** The name of the layout, template, dialog template or screen that physically contains the node. */
|
|
42
|
+
owner: string;
|
|
43
|
+
ownerKind: SceneNodeKind;
|
|
44
|
+
|
|
45
|
+
/** Set when the node is an item of an array: a child list or a slot's content. */
|
|
46
|
+
list?: ListLocation;
|
|
47
|
+
|
|
48
|
+
/** For an element held by a flow leaf: the id of that leaf. Removing or moving the element does so to the leaf. */
|
|
49
|
+
leafId?: string;
|
|
50
|
+
|
|
51
|
+
/** For an element positioned freeform: the ids of its placements, one per size-class variant. */
|
|
52
|
+
placementIds?: string[];
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* For nodes inside a freeform element, whose content repeats in every size-class variant: the path prefix of
|
|
56
|
+
* the copy this record describes, and the same prefix in each other variant. Edits are applied to every copy.
|
|
57
|
+
*/
|
|
58
|
+
mirror?: { prefix: DocumentPath; others: DocumentPath[] };
|
|
59
|
+
|
|
60
|
+
/** For a slot: the name. */
|
|
61
|
+
slotName?: string;
|
|
62
|
+
|
|
63
|
+
/** For a slot: where its content array is (or would be, when empty). */
|
|
64
|
+
contentPath?: DocumentPath;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Every addressable node of a document, by id, with the problems found while indexing.
|
|
69
|
+
*/
|
|
70
|
+
export interface DocumentIndex {
|
|
71
|
+
nodes: Map<string, NodeRecord>;
|
|
72
|
+
diagnostics: SceneDiagnostic[];
|
|
73
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { SceneDiagnostic, SceneDocument } from '@cratis/scene.model';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The outcome of {@link applyEdit}.
|
|
8
|
+
*/
|
|
9
|
+
export interface EditOutcome {
|
|
10
|
+
/**
|
|
11
|
+
* The document after the edit - a new object. When the edit was refused this is the document that was passed
|
|
12
|
+
* in, unchanged and the very same object.
|
|
13
|
+
*/
|
|
14
|
+
model: SceneDocument;
|
|
15
|
+
|
|
16
|
+
/** What was found: errors when the edit was refused, warnings when it went ahead with a caveat. */
|
|
17
|
+
diagnostics: SceneDiagnostic[];
|
|
18
|
+
|
|
19
|
+
/** Whether the edit was applied. */
|
|
20
|
+
applied: boolean;
|
|
21
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { ProvenanceKind, SceneDocument } from '@cratis/scene.model';
|
|
5
|
+
import { EditingContext } from './EditingContext';
|
|
6
|
+
import { DocumentIndex, NodeRecord } from './DocumentIndex';
|
|
7
|
+
import { ExposureGrant, ExposureGrants, computeExposureGrants } from './exposureGrants';
|
|
8
|
+
import { indexDocument } from './indexDocument';
|
|
9
|
+
import { provenanceOf } from './inspect';
|
|
10
|
+
import { resolveEffectiveConfiguration } from './resolveEffectiveConfiguration';
|
|
11
|
+
import { resolveTemplateChain } from './resolveTemplateChain';
|
|
12
|
+
import { TemplateChain } from './TemplateChain';
|
|
13
|
+
import { EffectiveConfiguration } from '@cratis/scene.model';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Everything an edit needs to decide whether it is allowed, worked out once against the document as it was.
|
|
17
|
+
*/
|
|
18
|
+
export class EditSession {
|
|
19
|
+
readonly index: DocumentIndex;
|
|
20
|
+
readonly chain: TemplateChain;
|
|
21
|
+
readonly grants: ExposureGrants;
|
|
22
|
+
readonly configuration: EffectiveConfiguration;
|
|
23
|
+
|
|
24
|
+
constructor(readonly document: SceneDocument, readonly context: EditingContext) {
|
|
25
|
+
this.index = indexDocument(document);
|
|
26
|
+
this.chain = resolveTemplateChain(document, context.scope);
|
|
27
|
+
this.grants = computeExposureGrants(this.chain, context.catalog);
|
|
28
|
+
this.configuration = resolveEffectiveConfiguration(this.chain, document.instanceContributions, context.catalog);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** The instance id the scope contributes as, or `undefined` when the scope was not found. */
|
|
32
|
+
get scopeInstance(): string | undefined {
|
|
33
|
+
return this.chain.levels.at(-1)?.instance;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** What the scope's instance may configure on inherited components. */
|
|
37
|
+
get scopeGrants(): Map<string, ExposureGrant> {
|
|
38
|
+
return (this.scopeInstance === undefined ? undefined : this.grants.byInstance.get(this.scopeInstance)) ?? new Map();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Whether the scope itself owns the node. */
|
|
42
|
+
isLocal(record: NodeRecord): boolean {
|
|
43
|
+
return provenanceOf(record, this.chain, this.scopeGrants).kind === ProvenanceKind.Local;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Where an inherited node comes from, for a message. */
|
|
47
|
+
sourceOf(record: NodeRecord): string {
|
|
48
|
+
return record.owner;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { EditingScope, QueryCandidate } from '@cratis/scene.model';
|
|
5
|
+
import { DescriptorCatalog } from './DescriptorCatalog';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* What inspection and editing need to know besides the document: what can be described, what is being edited,
|
|
9
|
+
* and which queries the host offers.
|
|
10
|
+
*/
|
|
11
|
+
export interface EditingContext {
|
|
12
|
+
/** The descriptors of the components and layout types in play. */
|
|
13
|
+
catalog: DescriptorCatalog;
|
|
14
|
+
|
|
15
|
+
/** The screen, template or layout being edited; it decides what is local. */
|
|
16
|
+
scope: EditingScope;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The queries a property may be bound to, as the host discovered them. When a `QueryReference` value is
|
|
20
|
+
* edited it is checked against these; without them it is checked for shape only.
|
|
21
|
+
*/
|
|
22
|
+
queryCandidates?: QueryCandidate[];
|
|
23
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { ExposedProperty, ExternalComponent, SceneDiagnostic, SceneNodeKind } from '@cratis/scene.model';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* One owner in a template chain: a layout, a template or the screen at the end.
|
|
8
|
+
*/
|
|
9
|
+
export interface TemplateChainLevel {
|
|
10
|
+
/** The name of the layout, template, dialog template or screen. */
|
|
11
|
+
owner: string;
|
|
12
|
+
|
|
13
|
+
kind: SceneNodeKind;
|
|
14
|
+
|
|
15
|
+
/** The instance this level contributes as: `layout:<name>`, `template:<name>`, `dialog:<name>` or `screen:<name>`. */
|
|
16
|
+
instance: string;
|
|
17
|
+
|
|
18
|
+
/** The components the owner contains, each once, by element id. */
|
|
19
|
+
elements: ExternalComponent[];
|
|
20
|
+
|
|
21
|
+
/** What the owner exposes - and, for a nested template, re-exposes - to what sits inside it. */
|
|
22
|
+
exposures: ExposedProperty[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The nesting a configuration resolves over: the application layout first, then each template down to the one the
|
|
27
|
+
* screen fills, then the screen. A level can only configure what the levels above it exposed, and only reaches
|
|
28
|
+
* past its immediate parent when everything in between re-exposed it.
|
|
29
|
+
*/
|
|
30
|
+
export interface TemplateChain {
|
|
31
|
+
/** Outermost first. */
|
|
32
|
+
levels: TemplateChainLevel[];
|
|
33
|
+
|
|
34
|
+
/** Problems found assembling the chain, such as a template that could not be placed. */
|
|
35
|
+
diagnostics: SceneDiagnostic[];
|
|
36
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { DiagnosticCode, SceneDiagnostic, SceneDocument, SceneEdit, SceneEditKind } from '@cratis/scene.model';
|
|
5
|
+
import { errorDiagnostic, hasErrors } from './diagnostics';
|
|
6
|
+
import { EditOutcome } from './EditOutcome';
|
|
7
|
+
import { EditingContext } from './EditingContext';
|
|
8
|
+
import { EditSession } from './EditSession';
|
|
9
|
+
import { applyExposeProperty, applyUnexposeProperty } from './exposureEdits';
|
|
10
|
+
import {
|
|
11
|
+
applyAddCollectionItem, applyEditCollectionItem, applyRemoveCollectionItem, applyReorderCollectionItem,
|
|
12
|
+
applyResetInstanceValue, applySetInstanceValue,
|
|
13
|
+
} from './instanceEdits';
|
|
14
|
+
import { applyChangeLayoutType } from './layoutTypeEdits';
|
|
15
|
+
import { cloneData } from './pathAccess';
|
|
16
|
+
import { applyResetProperty, applySetProperty } from './propertyEdits';
|
|
17
|
+
import { applyInsertNode, applyMoveNode, applyRemoveNode } from './structureEdits';
|
|
18
|
+
|
|
19
|
+
type Handler<TEdit extends SceneEdit> = (session: EditSession, edit: TEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]) => void;
|
|
20
|
+
|
|
21
|
+
function run(session: EditSession, edit: SceneEdit, clone: SceneDocument, diagnostics: SceneDiagnostic[]): void {
|
|
22
|
+
const handle = <TEdit extends SceneEdit>(handler: Handler<TEdit>) => handler(session, edit as TEdit, clone, diagnostics);
|
|
23
|
+
|
|
24
|
+
switch (edit.kind) {
|
|
25
|
+
case SceneEditKind.SetProperty: return handle(applySetProperty);
|
|
26
|
+
case SceneEditKind.ResetProperty: return handle(applyResetProperty);
|
|
27
|
+
case SceneEditKind.ChangeLayoutType: return handle(applyChangeLayoutType);
|
|
28
|
+
case SceneEditKind.InsertNode: return handle(applyInsertNode);
|
|
29
|
+
case SceneEditKind.MoveNode: return handle(applyMoveNode);
|
|
30
|
+
case SceneEditKind.RemoveNode: return handle(applyRemoveNode);
|
|
31
|
+
case SceneEditKind.SetInstanceValue: return handle(applySetInstanceValue);
|
|
32
|
+
case SceneEditKind.ResetInstanceValue: return handle(applyResetInstanceValue);
|
|
33
|
+
case SceneEditKind.AddCollectionItem: return handle(applyAddCollectionItem);
|
|
34
|
+
case SceneEditKind.RemoveCollectionItem: return handle(applyRemoveCollectionItem);
|
|
35
|
+
case SceneEditKind.ReorderCollectionItem: return handle(applyReorderCollectionItem);
|
|
36
|
+
case SceneEditKind.EditCollectionItem: return handle(applyEditCollectionItem);
|
|
37
|
+
case SceneEditKind.ExposeProperty: return handle(applyExposeProperty);
|
|
38
|
+
case SceneEditKind.UnexposeProperty: return handle(applyUnexposeProperty);
|
|
39
|
+
default:
|
|
40
|
+
diagnostics.push(errorDiagnostic(DiagnosticCode.InvalidEdit, `'${(edit as { kind?: string }).kind}' is not an edit this engine knows.`));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Applies one edit to a document.
|
|
46
|
+
*
|
|
47
|
+
* Pure and immutable: the document passed in is never changed, and the result is a new document. Edits are plain
|
|
48
|
+
* data, so a host can persist them and build undo and redo by keeping the documents either side. On any error the
|
|
49
|
+
* prior document comes back - the same object - together with the diagnostics, so a refused edit leaves nothing
|
|
50
|
+
* half done.
|
|
51
|
+
*
|
|
52
|
+
* What an edit may touch follows the editing scope. Nodes the scope owns are edited directly; inherited nodes are
|
|
53
|
+
* read-only, and their exposed properties are configured with the instance edits, which are checked against what
|
|
54
|
+
* each owner exposed.
|
|
55
|
+
*
|
|
56
|
+
* @param model The document to edit.
|
|
57
|
+
* @param edit What to do.
|
|
58
|
+
* @param context The catalog and the editing scope.
|
|
59
|
+
*/
|
|
60
|
+
export function applyEdit(model: SceneDocument, edit: SceneEdit, context: EditingContext): EditOutcome {
|
|
61
|
+
const session = new EditSession(model, context);
|
|
62
|
+
const clone = cloneData(model);
|
|
63
|
+
const diagnostics: SceneDiagnostic[] = [];
|
|
64
|
+
|
|
65
|
+
run(session, edit, clone, diagnostics);
|
|
66
|
+
|
|
67
|
+
if (hasErrors(diagnostics)) return { model, diagnostics, applied: false };
|
|
68
|
+
return { model: clone, diagnostics, applied: true };
|
|
69
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { ContentControl, EffectiveConfiguration, ExternalComponent, ItemsControl, Panel, SceneElement } from '@cratis/scene.model';
|
|
5
|
+
import { isContentControl, isExternalComponent, isItemsControl, isPanel } from '../elementKind';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Returns the element tree a renderer should draw once effective configuration is applied: each configurable
|
|
9
|
+
* component carries its resolved properties.
|
|
10
|
+
*
|
|
11
|
+
* Pure, and structure-sharing - an element with nothing to change comes back as the same object, so a renderer
|
|
12
|
+
* that memoizes on identity does not redraw what did not change. There is no design-time flag here or anywhere
|
|
13
|
+
* downstream: a screen being edited and a screen being played go through this same function.
|
|
14
|
+
*
|
|
15
|
+
* @param element The element tree from the template or screen.
|
|
16
|
+
* @param configuration What {@link resolveEffectiveConfiguration} produced for the chain the tree sits in.
|
|
17
|
+
*/
|
|
18
|
+
export function applyEffectiveConfiguration(element: SceneElement, configuration: EffectiveConfiguration): SceneElement {
|
|
19
|
+
if (isExternalComponent(element)) {
|
|
20
|
+
const resolved = configuration.components.find(candidate => candidate.component === element.id);
|
|
21
|
+
let changed = resolved !== undefined;
|
|
22
|
+
|
|
23
|
+
const slots: typeof element.slots = {};
|
|
24
|
+
for (const [name, children] of Object.entries(element.slots)) {
|
|
25
|
+
const mapped = children.map(child => applyEffectiveConfiguration(child, configuration));
|
|
26
|
+
if (mapped.some((child, index) => child !== children[index])) changed = true;
|
|
27
|
+
slots[name] = mapped;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const updated: ExternalComponent = { ...element, properties: resolved?.properties ?? element.properties, slots };
|
|
31
|
+
return changed ? updated : element;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (isContentControl(element)) {
|
|
35
|
+
const content = applyEffectiveConfiguration(element.content, configuration);
|
|
36
|
+
const updated: ContentControl = { ...element, content };
|
|
37
|
+
return content === element.content ? element : updated;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (isItemsControl(element)) {
|
|
41
|
+
const itemTemplate = applyEffectiveConfiguration(element.itemTemplate, configuration);
|
|
42
|
+
const updated: ItemsControl = { ...element, itemTemplate };
|
|
43
|
+
return itemTemplate === element.itemTemplate ? element : updated;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (isPanel(element)) {
|
|
47
|
+
const children = element.children.map(child => applyEffectiveConfiguration(child, configuration));
|
|
48
|
+
const updated: Panel = { ...element, children };
|
|
49
|
+
return children.some((child, index) => child !== element.children[index]) ? updated : element;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return element;
|
|
53
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { ExternalComponent } from '@cratis/scene.model';
|
|
5
|
+
|
|
6
|
+
function isExternalComponentValue(value: object): value is ExternalComponent {
|
|
7
|
+
const candidate = value as Partial<ExternalComponent>;
|
|
8
|
+
return typeof candidate.id === 'string' && typeof candidate.componentName === 'string'
|
|
9
|
+
&& candidate.properties !== null && typeof candidate.properties === 'object';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Finds every external component anywhere inside a layout, template, dialog template or screen, each once by id.
|
|
14
|
+
*
|
|
15
|
+
* It scans the value's structure rather than following a fixed list of properties, so a component is found
|
|
16
|
+
* wherever the model keeps it - slot content, a flow leaf, a freeform placement, a panel's children, another
|
|
17
|
+
* component's slot. A freeform arrangement repeats an element across its size-class variants; the first copy
|
|
18
|
+
* is the one returned.
|
|
19
|
+
*/
|
|
20
|
+
export function collectComponents(owner: unknown): ExternalComponent[] {
|
|
21
|
+
const found = new Map<string, ExternalComponent>();
|
|
22
|
+
|
|
23
|
+
const visit = (value: unknown): void => {
|
|
24
|
+
if (value === null || typeof value !== 'object') return;
|
|
25
|
+
if (Array.isArray(value)) {
|
|
26
|
+
for (const item of value) visit(item);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (isExternalComponentValue(value) && !found.has(value.id)) found.set(value.id, value);
|
|
31
|
+
for (const child of Object.values(value)) visit(child);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
visit(owner);
|
|
35
|
+
return [...found.values()];
|
|
36
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
DiagnosticCode, LayoutCapabilities, LayoutType, PropertyDescriptor, SceneDiagnostic, SceneNodeKind,
|
|
6
|
+
} from '@cratis/scene.model';
|
|
7
|
+
import { DescriptorCatalog, findComponentDescriptor, findLayoutTypeDescriptor } from './DescriptorCatalog';
|
|
8
|
+
import { NodeRecord } from './DocumentIndex';
|
|
9
|
+
import { warningDiagnostic } from './diagnostics';
|
|
10
|
+
import { getValueAtPath } from './pathAccess';
|
|
11
|
+
import { placementProperties, templateProperties } from './layoutTypeDescriptors';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* What describes a node: its editable properties, and for a layout node what the type can do.
|
|
15
|
+
*/
|
|
16
|
+
export interface NodeDescription {
|
|
17
|
+
properties: PropertyDescriptor[];
|
|
18
|
+
capabilities?: LayoutCapabilities;
|
|
19
|
+
diagnostics: SceneDiagnostic[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const layoutTypes = new Set<string>(Object.values(LayoutType));
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Works out which descriptors apply to a node.
|
|
26
|
+
*
|
|
27
|
+
* A component takes its descriptor from the catalog by the name it carries; a layout node takes its layout type's;
|
|
28
|
+
* a placement and a template have their own fixed sets. A component nothing describes has no editable
|
|
29
|
+
* properties, and says so rather than failing.
|
|
30
|
+
*/
|
|
31
|
+
export function describeNode(record: NodeRecord, catalog: DescriptorCatalog): NodeDescription {
|
|
32
|
+
const diagnostics: SceneDiagnostic[] = [];
|
|
33
|
+
|
|
34
|
+
if (record.kind === SceneNodeKind.Placement) return { properties: placementProperties, diagnostics };
|
|
35
|
+
if (record.kind === SceneNodeKind.ScreenTemplate || record.kind === SceneNodeKind.DialogTemplate) return { properties: templateProperties, diagnostics };
|
|
36
|
+
|
|
37
|
+
if (layoutTypes.has(record.typeId)) {
|
|
38
|
+
const descriptor = findLayoutTypeDescriptor(catalog, record.typeId);
|
|
39
|
+
return { properties: descriptor?.properties ?? [], capabilities: descriptor?.capabilities, diagnostics };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (record.kind === SceneNodeKind.Element && (record.value as { componentName?: unknown }).componentName !== undefined) {
|
|
43
|
+
const descriptor = findComponentDescriptor(catalog, record.typeId);
|
|
44
|
+
if (!descriptor) {
|
|
45
|
+
diagnostics.push(warningDiagnostic(DiagnosticCode.MissingComponentDescriptor, `Nothing describes the component '${record.typeId}', so none of its properties can be edited.`, { nodeId: record.id }));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return { properties: descriptor?.properties ?? [], diagnostics };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return { properties: [], diagnostics };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Reads a descriptor's value from a node: from the property bag of a component, from the node itself otherwise.
|
|
56
|
+
*/
|
|
57
|
+
export function readNodeValue(record: NodeRecord, path: string): unknown {
|
|
58
|
+
const value = record.value as Record<string, unknown>;
|
|
59
|
+
const isComponent = record.kind === SceneNodeKind.Element && value.componentName !== undefined;
|
|
60
|
+
return getValueAtPath(isComponent ? (value.properties as Record<string, unknown>) : value, path);
|
|
61
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { DiagnosticCode, DiagnosticSeverity, SceneDiagnostic } from '@cratis/scene.model';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The context a diagnostic can carry besides its code and message.
|
|
8
|
+
*/
|
|
9
|
+
export type DiagnosticContext = Partial<Omit<SceneDiagnostic, 'code' | 'severity' | 'message'>>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Builds an error diagnostic: the edit or resolution step that produced it did not happen.
|
|
13
|
+
*/
|
|
14
|
+
export function errorDiagnostic(code: DiagnosticCode, message: string, context: DiagnosticContext = {}): SceneDiagnostic {
|
|
15
|
+
return { code, severity: DiagnosticSeverity.Error, message, ...context };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Builds a warning diagnostic: the work went ahead, and the author should know something about it.
|
|
20
|
+
*/
|
|
21
|
+
export function warningDiagnostic(code: DiagnosticCode, message: string, context: DiagnosticContext = {}): SceneDiagnostic {
|
|
22
|
+
return { code, severity: DiagnosticSeverity.Warning, message, ...context };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Whether any diagnostic is an error.
|
|
27
|
+
*/
|
|
28
|
+
export function hasErrors(diagnostics: SceneDiagnostic[]): boolean {
|
|
29
|
+
return diagnostics.some(diagnostic => diagnostic.severity === DiagnosticSeverity.Error);
|
|
30
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { DocumentPath } from './DocumentIndex';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Reads the value at a document path.
|
|
8
|
+
*/
|
|
9
|
+
export function getAtPath(root: unknown, path: DocumentPath): unknown {
|
|
10
|
+
let current = root;
|
|
11
|
+
for (const key of path) {
|
|
12
|
+
if (current === null || typeof current !== 'object') return undefined;
|
|
13
|
+
current = (current as Record<string | number, unknown>)[key];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return current;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Reads the array at a path, creating it - and any objects on the way - when it is not there yet. Mutates `root`,
|
|
21
|
+
* which callers hold a copy of.
|
|
22
|
+
*/
|
|
23
|
+
export function ensureArrayAt(root: unknown, path: DocumentPath): unknown[] {
|
|
24
|
+
let current = root as Record<string | number, unknown>;
|
|
25
|
+
path.forEach((key, position) => {
|
|
26
|
+
if (current[key] === undefined) current[key] = position === path.length - 1 ? [] : {};
|
|
27
|
+
current = current[key] as Record<string | number, unknown>;
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
return current as unknown as unknown[];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The paths a change to `path` must be made at: the path itself and, for a node inside a freeform element, the same
|
|
35
|
+
* place in every other size-class variant's copy.
|
|
36
|
+
*/
|
|
37
|
+
export function mirroredPaths(mirror: { prefix: DocumentPath; others: DocumentPath[] } | undefined, path: DocumentPath): DocumentPath[] {
|
|
38
|
+
if (!mirror || mirror.prefix.some((key, position) => path[position] !== key)) return [path];
|
|
39
|
+
return [path, ...mirror.others.map(other => [...other, ...path.slice(mirror.prefix.length)])];
|
|
40
|
+
}
|