@mindlogic-ai/logician-ui 3.1.0-alpha.9 → 3.2.0-alpha.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/components/Icon/_constants/iconList.d.ts +1 -1
- package/dist/components/Icon/_constants/iconList.d.ts.map +1 -1
- package/dist/components/Icon/_constants/iconList.js +18 -0
- package/dist/components/Icon/_constants/iconList.js.map +1 -1
- package/dist/components/Icon/_constants/iconList.mjs +20 -2
- package/dist/components/Icon/_constants/iconList.mjs.map +1 -1
- package/dist/components/Icon/index.d.ts +2 -1
- package/dist/components/Icon/index.d.ts.map +1 -1
- package/dist/components/Icon/index.js +20 -1
- package/dist/components/Icon/index.js.map +1 -1
- package/dist/components/Icon/index.mjs +4 -2
- package/dist/components/Icon/index.mjs.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.d.ts.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.js +20 -4
- package/dist/components/SegmentedControl/SegmentedControl.js.map +1 -1
- package/dist/components/SegmentedControl/SegmentedControl.mjs +20 -4
- package/dist/components/SegmentedControl/SegmentedControl.mjs.map +1 -1
- package/dist/components/Workflow/Workflow.d.ts +3 -0
- package/dist/components/Workflow/Workflow.d.ts.map +1 -0
- package/dist/components/Workflow/Workflow.js +109 -0
- package/dist/components/Workflow/Workflow.js.map +1 -0
- package/dist/components/Workflow/Workflow.mjs +107 -0
- package/dist/components/Workflow/Workflow.mjs.map +1 -0
- package/dist/components/Workflow/Workflow.translations.json.js +164 -0
- package/dist/components/Workflow/Workflow.translations.json.js.map +1 -0
- package/dist/components/Workflow/Workflow.translations.json.mjs +138 -0
- package/dist/components/Workflow/Workflow.translations.json.mjs.map +1 -0
- package/dist/components/Workflow/Workflow.types.d.ts +435 -0
- package/dist/components/Workflow/Workflow.types.d.ts.map +1 -0
- package/dist/components/Workflow/Workflow.types.js +19 -0
- package/dist/components/Workflow/Workflow.types.js.map +1 -0
- package/dist/components/Workflow/Workflow.types.mjs +16 -0
- package/dist/components/Workflow/Workflow.types.mjs.map +1 -0
- package/dist/components/Workflow/WorkflowContext/WorkflowContext.d.ts +10 -0
- package/dist/components/Workflow/WorkflowContext/WorkflowContext.d.ts.map +1 -0
- package/dist/components/Workflow/WorkflowContext/WorkflowContext.js +163 -0
- package/dist/components/Workflow/WorkflowContext/WorkflowContext.js.map +1 -0
- package/dist/components/Workflow/WorkflowContext/WorkflowContext.mjs +159 -0
- package/dist/components/Workflow/WorkflowContext/WorkflowContext.mjs.map +1 -0
- package/dist/components/Workflow/WorkflowContext/WorkflowContext.types.d.ts +117 -0
- package/dist/components/Workflow/WorkflowContext/WorkflowContext.types.d.ts.map +1 -0
- package/dist/components/Workflow/WorkflowContext/index.d.ts +3 -0
- package/dist/components/Workflow/WorkflowContext/index.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/Canvas/BranchLabelBadge.d.ts +19 -0
- package/dist/components/Workflow/canvas/Canvas/BranchLabelBadge.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/Canvas/BranchLabelBadge.js +44 -0
- package/dist/components/Workflow/canvas/Canvas/BranchLabelBadge.js.map +1 -0
- package/dist/components/Workflow/canvas/Canvas/BranchLabelBadge.mjs +42 -0
- package/dist/components/Workflow/canvas/Canvas/BranchLabelBadge.mjs.map +1 -0
- package/dist/components/Workflow/canvas/Canvas/Canvas.d.ts +10 -0
- package/dist/components/Workflow/canvas/Canvas/Canvas.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/Canvas/Canvas.js +531 -0
- package/dist/components/Workflow/canvas/Canvas/Canvas.js.map +1 -0
- package/dist/components/Workflow/canvas/Canvas/Canvas.mjs +529 -0
- package/dist/components/Workflow/canvas/Canvas/Canvas.mjs.map +1 -0
- package/dist/components/Workflow/canvas/Canvas/Canvas.styles.d.ts +53 -0
- package/dist/components/Workflow/canvas/Canvas/Canvas.styles.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/Canvas/Canvas.styles.js +96 -0
- package/dist/components/Workflow/canvas/Canvas/Canvas.styles.js.map +1 -0
- package/dist/components/Workflow/canvas/Canvas/Canvas.styles.mjs +93 -0
- package/dist/components/Workflow/canvas/Canvas/Canvas.styles.mjs.map +1 -0
- package/dist/components/Workflow/canvas/Canvas/CanvasControls.d.ts +27 -0
- package/dist/components/Workflow/canvas/Canvas/CanvasControls.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/Canvas/CanvasControls.js +70 -0
- package/dist/components/Workflow/canvas/Canvas/CanvasControls.js.map +1 -0
- package/dist/components/Workflow/canvas/Canvas/CanvasControls.mjs +68 -0
- package/dist/components/Workflow/canvas/Canvas/CanvasControls.mjs.map +1 -0
- package/dist/components/Workflow/canvas/Canvas/LabeledEdge.d.ts +10 -0
- package/dist/components/Workflow/canvas/Canvas/LabeledEdge.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/Canvas/LabeledEdge.js +106 -0
- package/dist/components/Workflow/canvas/Canvas/LabeledEdge.js.map +1 -0
- package/dist/components/Workflow/canvas/Canvas/LabeledEdge.mjs +104 -0
- package/dist/components/Workflow/canvas/Canvas/LabeledEdge.mjs.map +1 -0
- package/dist/components/Workflow/canvas/Canvas/edgeLabelVariant.d.ts +13 -0
- package/dist/components/Workflow/canvas/Canvas/edgeLabelVariant.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/Canvas/edgeLabelVariant.js +18 -0
- package/dist/components/Workflow/canvas/Canvas/edgeLabelVariant.js.map +1 -0
- package/dist/components/Workflow/canvas/Canvas/edgeLabelVariant.mjs +16 -0
- package/dist/components/Workflow/canvas/Canvas/edgeLabelVariant.mjs.map +1 -0
- package/dist/components/Workflow/canvas/Canvas/index.d.ts +2 -0
- package/dist/components/Workflow/canvas/Canvas/index.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/CollapsibleSection/CollapsibleSection.d.ts +30 -0
- package/dist/components/Workflow/canvas/CollapsibleSection/CollapsibleSection.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/CollapsibleSection/CollapsibleSection.js +34 -0
- package/dist/components/Workflow/canvas/CollapsibleSection/CollapsibleSection.js.map +1 -0
- package/dist/components/Workflow/canvas/CollapsibleSection/CollapsibleSection.mjs +32 -0
- package/dist/components/Workflow/canvas/CollapsibleSection/CollapsibleSection.mjs.map +1 -0
- package/dist/components/Workflow/canvas/CollapsibleSection/index.d.ts +2 -0
- package/dist/components/Workflow/canvas/CollapsibleSection/index.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/DrawerShell/DrawerHeader.d.ts +37 -0
- package/dist/components/Workflow/canvas/DrawerShell/DrawerHeader.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/DrawerShell/DrawerHeader.js +33 -0
- package/dist/components/Workflow/canvas/DrawerShell/DrawerHeader.js.map +1 -0
- package/dist/components/Workflow/canvas/DrawerShell/DrawerHeader.mjs +31 -0
- package/dist/components/Workflow/canvas/DrawerShell/DrawerHeader.mjs.map +1 -0
- package/dist/components/Workflow/canvas/DrawerShell/DrawerIssues.d.ts +16 -0
- package/dist/components/Workflow/canvas/DrawerShell/DrawerIssues.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/DrawerShell/DrawerIssues.js +54 -0
- package/dist/components/Workflow/canvas/DrawerShell/DrawerIssues.js.map +1 -0
- package/dist/components/Workflow/canvas/DrawerShell/DrawerIssues.mjs +52 -0
- package/dist/components/Workflow/canvas/DrawerShell/DrawerIssues.mjs.map +1 -0
- package/dist/components/Workflow/canvas/DrawerShell/DrawerShell.d.ts +27 -0
- package/dist/components/Workflow/canvas/DrawerShell/DrawerShell.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/DrawerShell/DrawerShell.js +178 -0
- package/dist/components/Workflow/canvas/DrawerShell/DrawerShell.js.map +1 -0
- package/dist/components/Workflow/canvas/DrawerShell/DrawerShell.mjs +176 -0
- package/dist/components/Workflow/canvas/DrawerShell/DrawerShell.mjs.map +1 -0
- package/dist/components/Workflow/canvas/DrawerShell/index.d.ts +3 -0
- package/dist/components/Workflow/canvas/DrawerShell/index.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/EdgeInspector/BuiltInEdgeInspector.d.ts +12 -0
- package/dist/components/Workflow/canvas/EdgeInspector/BuiltInEdgeInspector.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/EdgeInspector/BuiltInEdgeInspector.js +68 -0
- package/dist/components/Workflow/canvas/EdgeInspector/BuiltInEdgeInspector.js.map +1 -0
- package/dist/components/Workflow/canvas/EdgeInspector/BuiltInEdgeInspector.mjs +66 -0
- package/dist/components/Workflow/canvas/EdgeInspector/BuiltInEdgeInspector.mjs.map +1 -0
- package/dist/components/Workflow/canvas/EdgeInspector/endpointTitle.d.ts +19 -0
- package/dist/components/Workflow/canvas/EdgeInspector/endpointTitle.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/EdgeInspector/endpointTitle.js +35 -0
- package/dist/components/Workflow/canvas/EdgeInspector/endpointTitle.js.map +1 -0
- package/dist/components/Workflow/canvas/EdgeInspector/endpointTitle.mjs +32 -0
- package/dist/components/Workflow/canvas/EdgeInspector/endpointTitle.mjs.map +1 -0
- package/dist/components/Workflow/canvas/EdgeInspector/index.d.ts +3 -0
- package/dist/components/Workflow/canvas/EdgeInspector/index.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/FieldWrapper/FieldWrapper.d.ts +54 -0
- package/dist/components/Workflow/canvas/FieldWrapper/FieldWrapper.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/FieldWrapper/FieldWrapper.js +56 -0
- package/dist/components/Workflow/canvas/FieldWrapper/FieldWrapper.js.map +1 -0
- package/dist/components/Workflow/canvas/FieldWrapper/FieldWrapper.mjs +54 -0
- package/dist/components/Workflow/canvas/FieldWrapper/FieldWrapper.mjs.map +1 -0
- package/dist/components/Workflow/canvas/FieldWrapper/index.d.ts +3 -0
- package/dist/components/Workflow/canvas/FieldWrapper/index.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/FloatingCard/FloatingCard.d.ts +16 -0
- package/dist/components/Workflow/canvas/FloatingCard/FloatingCard.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/FloatingCard/FloatingCard.js +25 -0
- package/dist/components/Workflow/canvas/FloatingCard/FloatingCard.js.map +1 -0
- package/dist/components/Workflow/canvas/FloatingCard/FloatingCard.mjs +22 -0
- package/dist/components/Workflow/canvas/FloatingCard/FloatingCard.mjs.map +1 -0
- package/dist/components/Workflow/canvas/FloatingCard/index.d.ts +2 -0
- package/dist/components/Workflow/canvas/FloatingCard/index.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/GenericNode/GenericNode.d.ts +14 -0
- package/dist/components/Workflow/canvas/GenericNode/GenericNode.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/GenericNode/GenericNode.js +61 -0
- package/dist/components/Workflow/canvas/GenericNode/GenericNode.js.map +1 -0
- package/dist/components/Workflow/canvas/GenericNode/GenericNode.mjs +59 -0
- package/dist/components/Workflow/canvas/GenericNode/GenericNode.mjs.map +1 -0
- package/dist/components/Workflow/canvas/GenericNode/GenericNode.types.d.ts +11 -0
- package/dist/components/Workflow/canvas/GenericNode/GenericNode.types.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/GenericNode/index.d.ts +3 -0
- package/dist/components/Workflow/canvas/GenericNode/index.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/GraphErrorBanner/GraphErrorBanner.d.ts +15 -0
- package/dist/components/Workflow/canvas/GraphErrorBanner/GraphErrorBanner.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/GraphErrorBanner/GraphErrorBanner.js +145 -0
- package/dist/components/Workflow/canvas/GraphErrorBanner/GraphErrorBanner.js.map +1 -0
- package/dist/components/Workflow/canvas/GraphErrorBanner/GraphErrorBanner.mjs +143 -0
- package/dist/components/Workflow/canvas/GraphErrorBanner/GraphErrorBanner.mjs.map +1 -0
- package/dist/components/Workflow/canvas/GraphErrorBanner/index.d.ts +2 -0
- package/dist/components/Workflow/canvas/GraphErrorBanner/index.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/IconTile/IconTile.d.ts +10 -0
- package/dist/components/Workflow/canvas/IconTile/IconTile.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/IconTile/IconTile.js +21 -0
- package/dist/components/Workflow/canvas/IconTile/IconTile.js.map +1 -0
- package/dist/components/Workflow/canvas/IconTile/IconTile.mjs +19 -0
- package/dist/components/Workflow/canvas/IconTile/IconTile.mjs.map +1 -0
- package/dist/components/Workflow/canvas/IconTile/IconTile.styles.d.ts +18 -0
- package/dist/components/Workflow/canvas/IconTile/IconTile.styles.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/IconTile/IconTile.styles.js +40 -0
- package/dist/components/Workflow/canvas/IconTile/IconTile.styles.js.map +1 -0
- package/dist/components/Workflow/canvas/IconTile/IconTile.styles.mjs +37 -0
- package/dist/components/Workflow/canvas/IconTile/IconTile.styles.mjs.map +1 -0
- package/dist/components/Workflow/canvas/IconTile/IconTile.types.d.ts +15 -0
- package/dist/components/Workflow/canvas/IconTile/IconTile.types.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/IconTile/index.d.ts +4 -0
- package/dist/components/Workflow/canvas/IconTile/index.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/IssueList/IssueList.d.ts +24 -0
- package/dist/components/Workflow/canvas/IssueList/IssueList.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/IssueList/IssueList.js +34 -0
- package/dist/components/Workflow/canvas/IssueList/IssueList.js.map +1 -0
- package/dist/components/Workflow/canvas/IssueList/IssueList.mjs +32 -0
- package/dist/components/Workflow/canvas/IssueList/IssueList.mjs.map +1 -0
- package/dist/components/Workflow/canvas/IssueList/index.d.ts +2 -0
- package/dist/components/Workflow/canvas/IssueList/index.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/NodePalette/NodePalette.d.ts +9 -0
- package/dist/components/Workflow/canvas/NodePalette/NodePalette.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/NodePalette/NodePalette.js +94 -0
- package/dist/components/Workflow/canvas/NodePalette/NodePalette.js.map +1 -0
- package/dist/components/Workflow/canvas/NodePalette/NodePalette.mjs +92 -0
- package/dist/components/Workflow/canvas/NodePalette/NodePalette.mjs.map +1 -0
- package/dist/components/Workflow/canvas/NodePalette/NodePalette.styles.d.ts +7 -0
- package/dist/components/Workflow/canvas/NodePalette/NodePalette.styles.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/NodePalette/NodePalette.styles.js +13 -0
- package/dist/components/Workflow/canvas/NodePalette/NodePalette.styles.js.map +1 -0
- package/dist/components/Workflow/canvas/NodePalette/NodePalette.styles.mjs +10 -0
- package/dist/components/Workflow/canvas/NodePalette/NodePalette.styles.mjs.map +1 -0
- package/dist/components/Workflow/canvas/NodePalette/NodePaletteToggle.d.ts +10 -0
- package/dist/components/Workflow/canvas/NodePalette/NodePaletteToggle.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/NodePalette/NodePaletteToggle.js +28 -0
- package/dist/components/Workflow/canvas/NodePalette/NodePaletteToggle.js.map +1 -0
- package/dist/components/Workflow/canvas/NodePalette/NodePaletteToggle.mjs +26 -0
- package/dist/components/Workflow/canvas/NodePalette/NodePaletteToggle.mjs.map +1 -0
- package/dist/components/Workflow/canvas/NodePalette/index.d.ts +4 -0
- package/dist/components/Workflow/canvas/NodePalette/index.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/NodeShell/NodeShell.d.ts +3 -0
- package/dist/components/Workflow/canvas/NodeShell/NodeShell.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/NodeShell/NodeShell.js +137 -0
- package/dist/components/Workflow/canvas/NodeShell/NodeShell.js.map +1 -0
- package/dist/components/Workflow/canvas/NodeShell/NodeShell.mjs +135 -0
- package/dist/components/Workflow/canvas/NodeShell/NodeShell.mjs.map +1 -0
- package/dist/components/Workflow/canvas/NodeShell/NodeShell.styles.d.ts +66 -0
- package/dist/components/Workflow/canvas/NodeShell/NodeShell.styles.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/NodeShell/NodeShell.styles.js +87 -0
- package/dist/components/Workflow/canvas/NodeShell/NodeShell.styles.js.map +1 -0
- package/dist/components/Workflow/canvas/NodeShell/NodeShell.styles.mjs +77 -0
- package/dist/components/Workflow/canvas/NodeShell/NodeShell.styles.mjs.map +1 -0
- package/dist/components/Workflow/canvas/NodeShell/NodeShell.types.d.ts +35 -0
- package/dist/components/Workflow/canvas/NodeShell/NodeShell.types.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/NodeShell/index.d.ts +4 -0
- package/dist/components/Workflow/canvas/NodeShell/index.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/SeverityDot/SeverityDot.d.ts +15 -0
- package/dist/components/Workflow/canvas/SeverityDot/SeverityDot.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/SeverityDot/SeverityDot.js +14 -0
- package/dist/components/Workflow/canvas/SeverityDot/SeverityDot.js.map +1 -0
- package/dist/components/Workflow/canvas/SeverityDot/SeverityDot.mjs +12 -0
- package/dist/components/Workflow/canvas/SeverityDot/SeverityDot.mjs.map +1 -0
- package/dist/components/Workflow/canvas/SeverityDot/index.d.ts +2 -0
- package/dist/components/Workflow/canvas/SeverityDot/index.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/issueSeverity.d.ts +23 -0
- package/dist/components/Workflow/canvas/issueSeverity.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/issueSeverity.js +51 -0
- package/dist/components/Workflow/canvas/issueSeverity.js.map +1 -0
- package/dist/components/Workflow/canvas/issueSeverity.mjs +47 -0
- package/dist/components/Workflow/canvas/issueSeverity.mjs.map +1 -0
- package/dist/components/Workflow/canvas/useFieldFocusRequest.d.ts +14 -0
- package/dist/components/Workflow/canvas/useFieldFocusRequest.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/useFieldFocusRequest.js +48 -0
- package/dist/components/Workflow/canvas/useFieldFocusRequest.js.map +1 -0
- package/dist/components/Workflow/canvas/useFieldFocusRequest.mjs +46 -0
- package/dist/components/Workflow/canvas/useFieldFocusRequest.mjs.map +1 -0
- package/dist/components/Workflow/canvas/workflowLabelProps.d.ts +12 -0
- package/dist/components/Workflow/canvas/workflowLabelProps.d.ts.map +1 -0
- package/dist/components/Workflow/canvas/workflowLabelProps.js +17 -0
- package/dist/components/Workflow/canvas/workflowLabelProps.js.map +1 -0
- package/dist/components/Workflow/canvas/workflowLabelProps.mjs +15 -0
- package/dist/components/Workflow/canvas/workflowLabelProps.mjs.map +1 -0
- package/dist/components/Workflow/connectionRules.d.ts +59 -0
- package/dist/components/Workflow/connectionRules.d.ts.map +1 -0
- package/dist/components/Workflow/connectionRules.js +150 -0
- package/dist/components/Workflow/connectionRules.js.map +1 -0
- package/dist/components/Workflow/connectionRules.mjs +145 -0
- package/dist/components/Workflow/connectionRules.mjs.map +1 -0
- package/dist/components/Workflow/createNode.d.ts +27 -0
- package/dist/components/Workflow/createNode.d.ts.map +1 -0
- package/dist/components/Workflow/createNode.js +66 -0
- package/dist/components/Workflow/createNode.js.map +1 -0
- package/dist/components/Workflow/createNode.mjs +62 -0
- package/dist/components/Workflow/createNode.mjs.map +1 -0
- package/dist/components/Workflow/graphHistory.d.ts +23 -0
- package/dist/components/Workflow/graphHistory.d.ts.map +1 -0
- package/dist/components/Workflow/graphHistory.js +73 -0
- package/dist/components/Workflow/graphHistory.js.map +1 -0
- package/dist/components/Workflow/graphHistory.mjs +70 -0
- package/dist/components/Workflow/graphHistory.mjs.map +1 -0
- package/dist/components/Workflow/graphObserver.d.ts +13 -0
- package/dist/components/Workflow/graphObserver.d.ts.map +1 -0
- package/dist/components/Workflow/graphObserver.js +11 -0
- package/dist/components/Workflow/graphObserver.js.map +1 -0
- package/dist/components/Workflow/graphObserver.mjs +8 -0
- package/dist/components/Workflow/graphObserver.mjs.map +1 -0
- package/dist/components/Workflow/graphReducer.d.ts +75 -0
- package/dist/components/Workflow/graphReducer.d.ts.map +1 -0
- package/dist/components/Workflow/graphReducer.js +122 -0
- package/dist/components/Workflow/graphReducer.js.map +1 -0
- package/dist/components/Workflow/graphReducer.mjs +119 -0
- package/dist/components/Workflow/graphReducer.mjs.map +1 -0
- package/dist/components/Workflow/index.d.ts +22 -0
- package/dist/components/Workflow/index.d.ts.map +1 -0
- package/dist/components/Workflow/layout/autoLayout.d.ts +49 -0
- package/dist/components/Workflow/layout/autoLayout.d.ts.map +1 -0
- package/dist/components/Workflow/layout/autoLayout.js +149 -0
- package/dist/components/Workflow/layout/autoLayout.js.map +1 -0
- package/dist/components/Workflow/layout/autoLayout.mjs +146 -0
- package/dist/components/Workflow/layout/autoLayout.mjs.map +1 -0
- package/dist/components/Workflow/stories/toyNodeTypes.d.ts +40 -0
- package/dist/components/Workflow/stories/toyNodeTypes.d.ts.map +1 -0
- package/dist/components/Workflow/useWorkflowIssueMessage.d.ts +15 -0
- package/dist/components/Workflow/useWorkflowIssueMessage.d.ts.map +1 -0
- package/dist/components/Workflow/useWorkflowIssueMessage.js +45 -0
- package/dist/components/Workflow/useWorkflowIssueMessage.js.map +1 -0
- package/dist/components/Workflow/useWorkflowIssueMessage.mjs +43 -0
- package/dist/components/Workflow/useWorkflowIssueMessage.mjs.map +1 -0
- package/dist/components/Workflow/useWorkflowKeyboard.d.ts +10 -0
- package/dist/components/Workflow/useWorkflowKeyboard.d.ts.map +1 -0
- package/dist/components/Workflow/useWorkflowKeyboard.js +116 -0
- package/dist/components/Workflow/useWorkflowKeyboard.js.map +1 -0
- package/dist/components/Workflow/useWorkflowKeyboard.mjs +114 -0
- package/dist/components/Workflow/useWorkflowKeyboard.mjs.map +1 -0
- package/dist/icons.js +17 -0
- package/dist/icons.js.map +1 -1
- package/dist/icons.mjs +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +14 -0
- package/dist/index.mjs.map +1 -1
- package/dist/test-support/setup.d.ts +5 -0
- package/dist/test-support/setup.d.ts.map +1 -0
- package/dist/theme/colors.d.ts +196 -44
- package/dist/theme/colors.d.ts.map +1 -1
- package/dist/theme/colors.js +184 -22
- package/dist/theme/colors.js.map +1 -1
- package/dist/theme/colors.mjs +184 -22
- package/dist/theme/colors.mjs.map +1 -1
- package/dist/theme/global.d.ts.map +1 -1
- package/dist/theme/global.js +30 -2
- package/dist/theme/global.js.map +1 -1
- package/dist/theme/global.mjs +30 -2
- package/dist/theme/global.mjs.map +1 -1
- package/package.json +10 -2
- package/src/components/Icon/_constants/iconList.ts +35 -0
- package/src/components/Icon/index.tsx +20 -0
- package/src/components/SegmentedControl/SegmentedControl.tsx +21 -4
- package/src/components/Workflow/README.md +362 -0
- package/src/components/Workflow/Workflow.translations.json +112 -0
- package/src/components/Workflow/Workflow.tsx +189 -0
- package/src/components/Workflow/Workflow.types.ts +496 -0
- package/src/components/Workflow/WorkflowContext/WorkflowContext.tsx +215 -0
- package/src/components/Workflow/WorkflowContext/WorkflowContext.types.ts +122 -0
- package/src/components/Workflow/WorkflowContext/index.ts +10 -0
- package/src/components/Workflow/WorkflowContext/workflowSelection.test.tsx +93 -0
- package/src/components/Workflow/canvas/Canvas/BranchLabelBadge.tsx +69 -0
- package/src/components/Workflow/canvas/Canvas/Canvas.styles.ts +91 -0
- package/src/components/Workflow/canvas/Canvas/Canvas.tsx +773 -0
- package/src/components/Workflow/canvas/Canvas/CanvasControls.tsx +178 -0
- package/src/components/Workflow/canvas/Canvas/LabeledEdge.tsx +198 -0
- package/src/components/Workflow/canvas/Canvas/edgeLabelVariant.test.ts +26 -0
- package/src/components/Workflow/canvas/Canvas/edgeLabelVariant.ts +23 -0
- package/src/components/Workflow/canvas/Canvas/index.ts +1 -0
- package/src/components/Workflow/canvas/CollapsibleSection/CollapsibleSection.tsx +96 -0
- package/src/components/Workflow/canvas/CollapsibleSection/index.ts +4 -0
- package/src/components/Workflow/canvas/DrawerShell/DrawerHeader.tsx +104 -0
- package/src/components/Workflow/canvas/DrawerShell/DrawerIssues.tsx +115 -0
- package/src/components/Workflow/canvas/DrawerShell/DrawerShell.tsx +408 -0
- package/src/components/Workflow/canvas/DrawerShell/index.ts +2 -0
- package/src/components/Workflow/canvas/EdgeInspector/BuiltInEdgeInspector.tsx +135 -0
- package/src/components/Workflow/canvas/EdgeInspector/endpointTitle.ts +38 -0
- package/src/components/Workflow/canvas/EdgeInspector/index.ts +2 -0
- package/src/components/Workflow/canvas/FieldWrapper/FieldWrapper.tsx +118 -0
- package/src/components/Workflow/canvas/FieldWrapper/index.ts +6 -0
- package/src/components/Workflow/canvas/FloatingCard/FloatingCard.tsx +37 -0
- package/src/components/Workflow/canvas/FloatingCard/index.ts +1 -0
- package/src/components/Workflow/canvas/GenericNode/GenericNode.tsx +114 -0
- package/src/components/Workflow/canvas/GenericNode/GenericNode.types.ts +10 -0
- package/src/components/Workflow/canvas/GenericNode/index.ts +5 -0
- package/src/components/Workflow/canvas/GraphErrorBanner/GraphErrorBanner.tsx +284 -0
- package/src/components/Workflow/canvas/GraphErrorBanner/index.ts +1 -0
- package/src/components/Workflow/canvas/IconTile/IconTile.styles.ts +40 -0
- package/src/components/Workflow/canvas/IconTile/IconTile.tsx +36 -0
- package/src/components/Workflow/canvas/IconTile/IconTile.types.ts +13 -0
- package/src/components/Workflow/canvas/IconTile/index.ts +7 -0
- package/src/components/Workflow/canvas/IssueList/IssueList.tsx +84 -0
- package/src/components/Workflow/canvas/IssueList/index.ts +1 -0
- package/src/components/Workflow/canvas/NodePalette/NodePalette.styles.ts +7 -0
- package/src/components/Workflow/canvas/NodePalette/NodePalette.tsx +180 -0
- package/src/components/Workflow/canvas/NodePalette/NodePaletteToggle.tsx +39 -0
- package/src/components/Workflow/canvas/NodePalette/index.ts +3 -0
- package/src/components/Workflow/canvas/NodeShell/NodeShell.styles.ts +84 -0
- package/src/components/Workflow/canvas/NodeShell/NodeShell.tsx +321 -0
- package/src/components/Workflow/canvas/NodeShell/NodeShell.types.ts +45 -0
- package/src/components/Workflow/canvas/NodeShell/index.ts +8 -0
- package/src/components/Workflow/canvas/SeverityDot/SeverityDot.tsx +33 -0
- package/src/components/Workflow/canvas/SeverityDot/index.ts +1 -0
- package/src/components/Workflow/canvas/issueSeverity.ts +48 -0
- package/src/components/Workflow/canvas/useFieldFocusRequest.ts +54 -0
- package/src/components/Workflow/canvas/workflowLabelProps.ts +11 -0
- package/src/components/Workflow/connectionRules.test.ts +326 -0
- package/src/components/Workflow/connectionRules.ts +190 -0
- package/src/components/Workflow/createNode.test.ts +61 -0
- package/src/components/Workflow/createNode.ts +67 -0
- package/src/components/Workflow/graphHistory.test.ts +178 -0
- package/src/components/Workflow/graphHistory.ts +91 -0
- package/src/components/Workflow/graphObserver.ts +21 -0
- package/src/components/Workflow/graphReducer.test.ts +314 -0
- package/src/components/Workflow/graphReducer.ts +196 -0
- package/src/components/Workflow/index.ts +74 -0
- package/src/components/Workflow/layout/autoLayout.test.ts +170 -0
- package/src/components/Workflow/layout/autoLayout.ts +200 -0
- package/src/components/Workflow/stories/Workflow.stories.tsx +111 -0
- package/src/components/Workflow/stories/toyNodeTypes.tsx +146 -0
- package/src/components/Workflow/useWorkflowIssueMessage.test.ts +101 -0
- package/src/components/Workflow/useWorkflowIssueMessage.ts +49 -0
- package/src/components/Workflow/useWorkflowKeyboard.ts +126 -0
- package/src/index.ts +1 -0
- package/src/test-support/setup.ts +11 -0
- package/src/theme/SemanticTokens.mdx +61 -7
- package/src/theme/colors.ts +216 -26
- package/src/theme/global.ts +31 -2
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
existingEdgeFromHandle,
|
|
5
|
+
isValidConnection,
|
|
6
|
+
renamedOutputHandle,
|
|
7
|
+
soleEdgeToHandle,
|
|
8
|
+
} from './connectionRules';
|
|
9
|
+
import type {
|
|
10
|
+
Graph,
|
|
11
|
+
GraphNode,
|
|
12
|
+
HandleDef,
|
|
13
|
+
NodeTypeDef,
|
|
14
|
+
} from './Workflow.types';
|
|
15
|
+
|
|
16
|
+
// Minimal stand-in registry that mirrors the real adapters' handle shapes
|
|
17
|
+
// (start: out only, end: in only, agent: in+out, classify: in + cat_* fan-out).
|
|
18
|
+
// Built inline so the test stays pure — importing the real `factchatNodeTypes`
|
|
19
|
+
// pulls in logician-ui render components that can't load in the test env.
|
|
20
|
+
const handlesByKind: Record<
|
|
21
|
+
string,
|
|
22
|
+
(config: unknown) => { inputs: HandleDef[]; outputs: HandleDef[] }
|
|
23
|
+
> = {
|
|
24
|
+
start: () => ({ inputs: [], outputs: [{ id: 'out' }] }),
|
|
25
|
+
end: () => ({ inputs: [{ id: 'in' }], outputs: [] }),
|
|
26
|
+
agent: () => ({ inputs: [{ id: 'in' }], outputs: [{ id: 'out' }] }),
|
|
27
|
+
classify: (config) => ({
|
|
28
|
+
inputs: [{ id: 'in' }],
|
|
29
|
+
outputs: (config as { categories: { name: string }[] }).categories.map(
|
|
30
|
+
(c) => ({ id: `cat_${c.name}`, label: c.name })
|
|
31
|
+
),
|
|
32
|
+
}),
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const getNodeType = (kind: string): NodeTypeDef | undefined => {
|
|
36
|
+
const handles = handlesByKind[kind];
|
|
37
|
+
if (!handles) return undefined;
|
|
38
|
+
return { kind, handles } as unknown as NodeTypeDef;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const node = (
|
|
42
|
+
id: string,
|
|
43
|
+
kind: string,
|
|
44
|
+
x = 0,
|
|
45
|
+
y = 0,
|
|
46
|
+
config: unknown = {}
|
|
47
|
+
): GraphNode => ({ id, kind, position: { x, y }, config });
|
|
48
|
+
|
|
49
|
+
const graphOf = (nodes: GraphNode[], edges: Graph['edges'] = []): Graph => ({
|
|
50
|
+
nodes,
|
|
51
|
+
edges,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const classifyConfig = { categories: [{ name: 'a' }, { name: 'b' }] };
|
|
55
|
+
|
|
56
|
+
describe('isValidConnection', () => {
|
|
57
|
+
const graph = graphOf([
|
|
58
|
+
node('start', 'start'),
|
|
59
|
+
node('agent_1', 'agent'),
|
|
60
|
+
node('end_1', 'end'),
|
|
61
|
+
]);
|
|
62
|
+
|
|
63
|
+
it('rejects self-connections', () => {
|
|
64
|
+
expect(
|
|
65
|
+
isValidConnection(
|
|
66
|
+
{
|
|
67
|
+
source: 'agent_1',
|
|
68
|
+
target: 'agent_1',
|
|
69
|
+
sourceHandle: null,
|
|
70
|
+
targetHandle: null,
|
|
71
|
+
},
|
|
72
|
+
graph,
|
|
73
|
+
getNodeType
|
|
74
|
+
)
|
|
75
|
+
).toBe(false);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('rejects connecting into start (start has no input handle)', () => {
|
|
79
|
+
expect(
|
|
80
|
+
isValidConnection(
|
|
81
|
+
{
|
|
82
|
+
source: 'agent_1',
|
|
83
|
+
target: 'start',
|
|
84
|
+
sourceHandle: null,
|
|
85
|
+
targetHandle: null,
|
|
86
|
+
},
|
|
87
|
+
graph,
|
|
88
|
+
getNodeType
|
|
89
|
+
)
|
|
90
|
+
).toBe(false);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('rejects connecting out of end (end has no output handle)', () => {
|
|
94
|
+
expect(
|
|
95
|
+
isValidConnection(
|
|
96
|
+
{
|
|
97
|
+
source: 'end_1',
|
|
98
|
+
target: 'agent_1',
|
|
99
|
+
sourceHandle: null,
|
|
100
|
+
targetHandle: null,
|
|
101
|
+
},
|
|
102
|
+
graph,
|
|
103
|
+
getNodeType
|
|
104
|
+
)
|
|
105
|
+
).toBe(false);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('accepts start -> agent', () => {
|
|
109
|
+
expect(
|
|
110
|
+
isValidConnection(
|
|
111
|
+
{
|
|
112
|
+
source: 'start',
|
|
113
|
+
target: 'agent_1',
|
|
114
|
+
sourceHandle: null,
|
|
115
|
+
targetHandle: null,
|
|
116
|
+
},
|
|
117
|
+
graph,
|
|
118
|
+
getNodeType
|
|
119
|
+
)
|
|
120
|
+
).toBe(true);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('rejects an unknown named source handle', () => {
|
|
124
|
+
expect(
|
|
125
|
+
isValidConnection(
|
|
126
|
+
{
|
|
127
|
+
source: 'agent_1',
|
|
128
|
+
target: 'end_1',
|
|
129
|
+
sourceHandle: 'nope',
|
|
130
|
+
targetHandle: null,
|
|
131
|
+
},
|
|
132
|
+
graph,
|
|
133
|
+
getNodeType
|
|
134
|
+
)
|
|
135
|
+
).toBe(false);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('accepts a classify category handle into an agent', () => {
|
|
139
|
+
const g = graphOf([
|
|
140
|
+
node('classify_1', 'classify', 0, 0, classifyConfig),
|
|
141
|
+
node('agent_1', 'agent', 100, 0),
|
|
142
|
+
]);
|
|
143
|
+
expect(
|
|
144
|
+
isValidConnection(
|
|
145
|
+
{
|
|
146
|
+
source: 'classify_1',
|
|
147
|
+
target: 'agent_1',
|
|
148
|
+
sourceHandle: 'cat_a',
|
|
149
|
+
targetHandle: null,
|
|
150
|
+
},
|
|
151
|
+
g,
|
|
152
|
+
getNodeType
|
|
153
|
+
)
|
|
154
|
+
).toBe(true);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('rejects using an input handle id as the source (exit→exit / reversed)', () => {
|
|
158
|
+
// 'in' is an input of agent_1; it must never be accepted as a sourceHandle.
|
|
159
|
+
expect(
|
|
160
|
+
isValidConnection(
|
|
161
|
+
{
|
|
162
|
+
source: 'agent_1',
|
|
163
|
+
target: 'end_1',
|
|
164
|
+
sourceHandle: 'in',
|
|
165
|
+
targetHandle: null,
|
|
166
|
+
},
|
|
167
|
+
graph,
|
|
168
|
+
getNodeType
|
|
169
|
+
)
|
|
170
|
+
).toBe(false);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it('rejects using an output handle id as the target (exit→exit)', () => {
|
|
174
|
+
// 'out' is an output of agent_1; it must never be accepted as a targetHandle.
|
|
175
|
+
expect(
|
|
176
|
+
isValidConnection(
|
|
177
|
+
{
|
|
178
|
+
source: 'start',
|
|
179
|
+
target: 'agent_1',
|
|
180
|
+
sourceHandle: null,
|
|
181
|
+
targetHandle: 'out',
|
|
182
|
+
},
|
|
183
|
+
graph,
|
|
184
|
+
getNodeType
|
|
185
|
+
)
|
|
186
|
+
).toBe(false);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
describe('existingEdgeFromHandle', () => {
|
|
191
|
+
it('finds the edge leaving a named exit handle', () => {
|
|
192
|
+
const graph = graphOf(
|
|
193
|
+
[
|
|
194
|
+
node('classify_1', 'classify', 0, 0, classifyConfig),
|
|
195
|
+
node('agent_1', 'agent', 100, 0),
|
|
196
|
+
],
|
|
197
|
+
[
|
|
198
|
+
{
|
|
199
|
+
id: 'e1',
|
|
200
|
+
source: 'classify_1',
|
|
201
|
+
target: 'agent_1',
|
|
202
|
+
sourceHandle: 'cat_a',
|
|
203
|
+
},
|
|
204
|
+
]
|
|
205
|
+
);
|
|
206
|
+
expect(
|
|
207
|
+
existingEdgeFromHandle(graph, getNodeType, 'classify_1', 'cat_a')?.id
|
|
208
|
+
).toBe('e1');
|
|
209
|
+
expect(
|
|
210
|
+
existingEdgeFromHandle(graph, getNodeType, 'classify_1', 'cat_b')
|
|
211
|
+
).toBeUndefined();
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('treats a default (unset) exit as taken by any handleless edge', () => {
|
|
215
|
+
const graph = graphOf(
|
|
216
|
+
[node('start', 'start', 0, 0), node('agent_1', 'agent', 100, 0)],
|
|
217
|
+
[{ id: 'e1', source: 'start', target: 'agent_1' }]
|
|
218
|
+
);
|
|
219
|
+
expect(
|
|
220
|
+
existingEdgeFromHandle(graph, getNodeType, 'start', undefined)?.id
|
|
221
|
+
).toBe('e1');
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it('matches a handleless edge queried by the concrete default handle id', () => {
|
|
225
|
+
// Loaded graphs omit the handle id for default ports; the canvas grabs them
|
|
226
|
+
// by the rendered id ('out'). Both must resolve to the same port.
|
|
227
|
+
const graph = graphOf(
|
|
228
|
+
[node('start', 'start', 0, 0), node('agent_1', 'agent', 100, 0)],
|
|
229
|
+
[{ id: 'e1', source: 'start', target: 'agent_1' }]
|
|
230
|
+
);
|
|
231
|
+
expect(existingEdgeFromHandle(graph, getNodeType, 'start', 'out')?.id).toBe(
|
|
232
|
+
'e1'
|
|
233
|
+
);
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
describe('soleEdgeToHandle', () => {
|
|
238
|
+
it('returns the edge when an input handle holds exactly one', () => {
|
|
239
|
+
const graph = graphOf(
|
|
240
|
+
[node('start', 'start'), node('agent_1', 'agent', 100, 0)],
|
|
241
|
+
[{ id: 'e1', source: 'start', target: 'agent_1', targetHandle: 'in' }]
|
|
242
|
+
);
|
|
243
|
+
expect(soleEdgeToHandle(graph, getNodeType, 'agent_1', 'in')?.id).toBe(
|
|
244
|
+
'e1'
|
|
245
|
+
);
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
it('returns the edge for a default (unset) input handle', () => {
|
|
249
|
+
const graph = graphOf(
|
|
250
|
+
[node('start', 'start'), node('agent_1', 'agent', 100, 0)],
|
|
251
|
+
[{ id: 'e1', source: 'start', target: 'agent_1' }]
|
|
252
|
+
);
|
|
253
|
+
expect(soleEdgeToHandle(graph, getNodeType, 'agent_1', undefined)?.id).toBe(
|
|
254
|
+
'e1'
|
|
255
|
+
);
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
it('matches a handleless edge grabbed by the concrete default handle id', () => {
|
|
259
|
+
// Regression: edge stored without targetHandle (loaded graph) but grabbed
|
|
260
|
+
// from the rendered input port id 'in' — must still be found and re-routed
|
|
261
|
+
// rather than spawning a duplicate fan-in edge.
|
|
262
|
+
const graph = graphOf(
|
|
263
|
+
[node('start', 'start'), node('agent_1', 'agent', 100, 0)],
|
|
264
|
+
[{ id: 'e1', source: 'start', target: 'agent_1' }]
|
|
265
|
+
);
|
|
266
|
+
expect(soleEdgeToHandle(graph, getNodeType, 'agent_1', 'in')?.id).toBe(
|
|
267
|
+
'e1'
|
|
268
|
+
);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it('returns undefined when the input has no edge', () => {
|
|
272
|
+
const graph = graphOf([node('agent_1', 'agent')]);
|
|
273
|
+
expect(
|
|
274
|
+
soleEdgeToHandle(graph, getNodeType, 'agent_1', 'in')
|
|
275
|
+
).toBeUndefined();
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
it('returns undefined on fan-in (2+ edges) — no single edge to grab', () => {
|
|
279
|
+
const graph = graphOf(
|
|
280
|
+
[
|
|
281
|
+
node('a1', 'agent', 0, 0),
|
|
282
|
+
node('a2', 'agent', 0, 100),
|
|
283
|
+
node('end_1', 'end', 100, 50),
|
|
284
|
+
],
|
|
285
|
+
[
|
|
286
|
+
{ id: 'e1', source: 'a1', target: 'end_1', targetHandle: 'in' },
|
|
287
|
+
{ id: 'e2', source: 'a2', target: 'end_1', targetHandle: 'in' },
|
|
288
|
+
]
|
|
289
|
+
);
|
|
290
|
+
expect(soleEdgeToHandle(graph, getNodeType, 'end_1', 'in')).toBeUndefined();
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
describe('renamedOutputHandle', () => {
|
|
295
|
+
const handles = handlesByKind.classify;
|
|
296
|
+
|
|
297
|
+
it('detects a 1:1 category rename', () => {
|
|
298
|
+
expect(
|
|
299
|
+
renamedOutputHandle(
|
|
300
|
+
handles,
|
|
301
|
+
{ categories: [{ name: 'a' }] },
|
|
302
|
+
{ categories: [{ name: 'b' }] }
|
|
303
|
+
)
|
|
304
|
+
).toEqual({ from: 'cat_a', to: 'cat_b' });
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
it('returns undefined for an added category (no orphan to move)', () => {
|
|
308
|
+
expect(
|
|
309
|
+
renamedOutputHandle(
|
|
310
|
+
handles,
|
|
311
|
+
{ categories: [{ name: 'a' }] },
|
|
312
|
+
{ categories: [{ name: 'a' }, { name: 'b' }] }
|
|
313
|
+
)
|
|
314
|
+
).toBeUndefined();
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
it('returns undefined for a removed category (edge prunes normally)', () => {
|
|
318
|
+
expect(
|
|
319
|
+
renamedOutputHandle(
|
|
320
|
+
handles,
|
|
321
|
+
{ categories: [{ name: 'a' }, { name: 'b' }] },
|
|
322
|
+
{ categories: [{ name: 'a' }] }
|
|
323
|
+
)
|
|
324
|
+
).toBeUndefined();
|
|
325
|
+
});
|
|
326
|
+
});
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import type { Connection } from '@xyflow/react';
|
|
2
|
+
|
|
3
|
+
import type { Graph, GraphEdge, NodeTypeDef } from './Workflow.types';
|
|
4
|
+
|
|
5
|
+
/** Resolves a node-type definition by kind. */
|
|
6
|
+
type GetNodeType = (kind: string) => NodeTypeDef | undefined;
|
|
7
|
+
|
|
8
|
+
/** A prospective connection; mirrors React Flow's `Connection` (handles nullable). */
|
|
9
|
+
type ProposedConnection = Pick<
|
|
10
|
+
Connection,
|
|
11
|
+
'source' | 'target' | 'sourceHandle' | 'targetHandle'
|
|
12
|
+
>;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Validates a proposed connection against node-type handle declarations and the
|
|
16
|
+
* optional `canConnect` rules of both endpoints. Shared by the canvas
|
|
17
|
+
* `isValidConnection`, manual `onConnect`, edge reconnect, and palette
|
|
18
|
+
* auto-connect so every path enforces the same constraints:
|
|
19
|
+
* - no self-connections,
|
|
20
|
+
* - the source must expose an output handle (Start/Agent/etc., never End),
|
|
21
|
+
* - the target must expose an input handle (End/Agent/etc., never Start),
|
|
22
|
+
* - a named `sourceHandle`/`targetHandle` must be a declared handle id,
|
|
23
|
+
* - connections run exit→entry only: the `sourceHandle` must be an output of
|
|
24
|
+
* the source and the `targetHandle` an input of the target — never the
|
|
25
|
+
* reverse (no exit→exit / entry→entry wiring),
|
|
26
|
+
* - any node-type `canConnect` hook on either endpoint must return `true`.
|
|
27
|
+
*/
|
|
28
|
+
export function isValidConnection(
|
|
29
|
+
connection: ProposedConnection,
|
|
30
|
+
graph: Graph,
|
|
31
|
+
getNodeType: GetNodeType
|
|
32
|
+
): boolean {
|
|
33
|
+
if (!connection.source || !connection.target) return false;
|
|
34
|
+
if (connection.source === connection.target) return false;
|
|
35
|
+
|
|
36
|
+
const source = graph.nodes.find((n) => n.id === connection.source);
|
|
37
|
+
const target = graph.nodes.find((n) => n.id === connection.target);
|
|
38
|
+
if (!source || !target) return false;
|
|
39
|
+
|
|
40
|
+
const sourceDef = getNodeType(source.kind);
|
|
41
|
+
const targetDef = getNodeType(target.kind);
|
|
42
|
+
if (!sourceDef || !targetDef) return false;
|
|
43
|
+
|
|
44
|
+
const sourceHandles = sourceDef.handles(source.config);
|
|
45
|
+
const targetHandles = targetDef.handles(target.config);
|
|
46
|
+
const sourceOutputs = sourceHandles.outputs;
|
|
47
|
+
const targetInputs = targetHandles.inputs;
|
|
48
|
+
// Source must be able to emit and target must be able to receive.
|
|
49
|
+
if (sourceOutputs.length === 0) return false;
|
|
50
|
+
if (targetInputs.length === 0) return false;
|
|
51
|
+
// A requested named handle must actually exist on the node.
|
|
52
|
+
if (
|
|
53
|
+
connection.sourceHandle &&
|
|
54
|
+
!sourceOutputs.some((h) => h.id === connection.sourceHandle)
|
|
55
|
+
) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
if (
|
|
59
|
+
connection.targetHandle &&
|
|
60
|
+
!targetInputs.some((h) => h.id === connection.targetHandle)
|
|
61
|
+
) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
// Exit→entry only. React Flow's strict connection mode already blocks
|
|
65
|
+
// output↔output (exit→exit) and input↔input drags, but enforce it here too so
|
|
66
|
+
// every path — manual connect, reconnect, programmatic edges — agrees: reject
|
|
67
|
+
// a `sourceHandle` that is actually an input of the source, or a `targetHandle`
|
|
68
|
+
// that is actually an output of the target.
|
|
69
|
+
if (
|
|
70
|
+
connection.sourceHandle &&
|
|
71
|
+
sourceHandles.inputs.some((h) => h.id === connection.sourceHandle)
|
|
72
|
+
) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
if (
|
|
76
|
+
connection.targetHandle &&
|
|
77
|
+
targetHandles.outputs.some((h) => h.id === connection.targetHandle)
|
|
78
|
+
) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const ctx = {
|
|
83
|
+
source,
|
|
84
|
+
sourceHandle: connection.sourceHandle ?? undefined,
|
|
85
|
+
target,
|
|
86
|
+
targetHandle: connection.targetHandle ?? undefined,
|
|
87
|
+
graph,
|
|
88
|
+
};
|
|
89
|
+
for (const def of [sourceDef, targetDef]) {
|
|
90
|
+
if (def.canConnect && def.canConnect(ctx) !== true) return false;
|
|
91
|
+
}
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Resolves a possibly-omitted handle id to the port it actually attaches to.
|
|
97
|
+
* Edges loaded from the backend / fixtures may omit the handle id for a node's
|
|
98
|
+
* default port, while the canvas renders every port with a concrete id (see
|
|
99
|
+
* `NodeShell`). React Flow attaches a handle-less edge to the node's first port
|
|
100
|
+
* of that type, so `undefined` and that first id denote the same port — collapse
|
|
101
|
+
* them before comparing or the lookup misses the edge (and we'd duplicate it).
|
|
102
|
+
*/
|
|
103
|
+
function resolveHandle(
|
|
104
|
+
handle: string | undefined,
|
|
105
|
+
ports: { id: string }[]
|
|
106
|
+
): string | undefined {
|
|
107
|
+
return handle ?? ports[0]?.id;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* The existing outbound edge from a node's given handle, if any. Each exit
|
|
112
|
+
* point holds at most one edge: a single-output node is "taken" once it has any
|
|
113
|
+
* outbound edge; named handles (classify categories, if/else branches,
|
|
114
|
+
* guardrail pass/fail) are tracked individually by their `sourceHandle` id.
|
|
115
|
+
*
|
|
116
|
+
* Used by the canvas to decide whether a fresh drag from an exit should create
|
|
117
|
+
* a new edge or MOVE the one already there.
|
|
118
|
+
*/
|
|
119
|
+
export function existingEdgeFromHandle(
|
|
120
|
+
graph: Graph,
|
|
121
|
+
getNodeType: GetNodeType,
|
|
122
|
+
source: string,
|
|
123
|
+
sourceHandle: string | undefined
|
|
124
|
+
): GraphEdge | undefined {
|
|
125
|
+
const node = graph.nodes.find((n) => n.id === source);
|
|
126
|
+
const outputs = node
|
|
127
|
+
? (getNodeType(node.kind)?.handles(node.config).outputs ?? [])
|
|
128
|
+
: [];
|
|
129
|
+
const want = resolveHandle(sourceHandle, outputs);
|
|
130
|
+
return graph.edges.find(
|
|
131
|
+
(e) =>
|
|
132
|
+
e.source === source &&
|
|
133
|
+
resolveHandle(e.sourceHandle ?? undefined, outputs) === want
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* The sole inbound edge to a node's given input handle, or `undefined` when the
|
|
139
|
+
* handle has zero or more than one. Unlike exits (one edge each), entries allow
|
|
140
|
+
* fan-in: several sources can converge on one input. So "grab the existing edge
|
|
141
|
+
* and re-route it" is only unambiguous when exactly one edge points at the
|
|
142
|
+
* handle — with two or more there's no single edge to grab, and the drag should
|
|
143
|
+
* fall back to adding another fan-in edge.
|
|
144
|
+
*
|
|
145
|
+
* Used by the canvas to decide whether a drag that *starts* from an occupied
|
|
146
|
+
* entry should move that edge's source endpoint instead of creating a new edge.
|
|
147
|
+
*/
|
|
148
|
+
export function soleEdgeToHandle(
|
|
149
|
+
graph: Graph,
|
|
150
|
+
getNodeType: GetNodeType,
|
|
151
|
+
target: string,
|
|
152
|
+
targetHandle: string | undefined
|
|
153
|
+
): GraphEdge | undefined {
|
|
154
|
+
const node = graph.nodes.find((n) => n.id === target);
|
|
155
|
+
const inputs = node
|
|
156
|
+
? (getNodeType(node.kind)?.handles(node.config).inputs ?? [])
|
|
157
|
+
: [];
|
|
158
|
+
const want = resolveHandle(targetHandle, inputs);
|
|
159
|
+
const inbound = graph.edges.filter(
|
|
160
|
+
(e) =>
|
|
161
|
+
e.target === target &&
|
|
162
|
+
resolveHandle(e.targetHandle ?? undefined, inputs) === want
|
|
163
|
+
);
|
|
164
|
+
return inbound.length === 1 ? inbound[0] : undefined;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Detects a single output-handle id rename between two configs of the same
|
|
169
|
+
* node, so the edge on that handle can move with it instead of being orphaned.
|
|
170
|
+
* Handle ids that derive from mutable config (Classify's `cat_<name>`) change
|
|
171
|
+
* when the author edits a name; diffing the declared outputs yields the rename.
|
|
172
|
+
*
|
|
173
|
+
* Returns the pair only for an unambiguous 1:1 rename — a pure add or remove
|
|
174
|
+
* (which the per-field drawer does one at a time) yields `undefined`, leaving
|
|
175
|
+
* edges to their normal add/prune behaviour.
|
|
176
|
+
*/
|
|
177
|
+
export function renamedOutputHandle(
|
|
178
|
+
handles: NodeTypeDef['handles'],
|
|
179
|
+
oldConfig: unknown,
|
|
180
|
+
newConfig: unknown
|
|
181
|
+
): { from: string; to: string } | undefined {
|
|
182
|
+
const oldIds = handles(oldConfig).outputs.map((h) => h.id);
|
|
183
|
+
const newIds = handles(newConfig).outputs.map((h) => h.id);
|
|
184
|
+
const removed = oldIds.filter((id) => !newIds.includes(id));
|
|
185
|
+
const added = newIds.filter((id) => !oldIds.includes(id));
|
|
186
|
+
if (removed.length === 1 && added.length === 1) {
|
|
187
|
+
return { from: removed[0], to: added[0] };
|
|
188
|
+
}
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { nextNodeId } from './createNode';
|
|
4
|
+
import type { GraphNode } from './Workflow.types';
|
|
5
|
+
|
|
6
|
+
const node = (id: string, kind: string): GraphNode => ({
|
|
7
|
+
id,
|
|
8
|
+
kind,
|
|
9
|
+
position: { x: 0, y: 0 },
|
|
10
|
+
config: {},
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
describe('nextNodeId', () => {
|
|
14
|
+
it('returns the singleton id for start', () => {
|
|
15
|
+
expect(nextNodeId('start', [])).toBe('start');
|
|
16
|
+
expect(nextNodeId('start', [node('start', 'start')])).toBe('start');
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('returns kind_1 when no nodes of that kind exist', () => {
|
|
20
|
+
expect(nextNodeId('agent', [])).toBe('agent_1');
|
|
21
|
+
expect(nextNodeId('classify', [node('agent_1', 'agent')])).toBe(
|
|
22
|
+
'classify_1'
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('continues the per-kind counter past the highest existing number', () => {
|
|
27
|
+
const nodes = [
|
|
28
|
+
node('agent_1', 'agent'),
|
|
29
|
+
node('agent_2', 'agent'),
|
|
30
|
+
node('agent_5', 'agent'),
|
|
31
|
+
];
|
|
32
|
+
expect(nextNodeId('agent', nodes)).toBe('agent_6');
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('ignores hand-named seed ids that do not match {kind}_<digits>', () => {
|
|
36
|
+
// Chatbot 3814's seed uses agent_main / guard_out / end_pass — those
|
|
37
|
+
// must NOT count toward the per-kind counter, otherwise a fresh agent
|
|
38
|
+
// next to agent_main would jump to agent_2 instead of agent_1.
|
|
39
|
+
const nodes = [
|
|
40
|
+
node('agent_main', 'agent'),
|
|
41
|
+
node('guard_out', 'guardrail'),
|
|
42
|
+
node('end_pass', 'end'),
|
|
43
|
+
];
|
|
44
|
+
expect(nextNodeId('agent', nodes)).toBe('agent_1');
|
|
45
|
+
expect(nextNodeId('guardrail', nodes)).toBe('guardrail_1');
|
|
46
|
+
expect(nextNodeId('end', nodes)).toBe('end_1');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('counts only nodes whose id matches the queried kind', () => {
|
|
50
|
+
const nodes = [node('agent_1', 'agent'), node('classify_3', 'classify')];
|
|
51
|
+
expect(nextNodeId('agent', nodes)).toBe('agent_2');
|
|
52
|
+
expect(nextNodeId('classify', nodes)).toBe('classify_4');
|
|
53
|
+
expect(nextNodeId('guardrail', nodes)).toBe('guardrail_1');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('handles gaps in the per-kind sequence', () => {
|
|
57
|
+
// The user deleted agent_2; the next add still continues past the max.
|
|
58
|
+
const nodes = [node('agent_1', 'agent'), node('agent_3', 'agent')];
|
|
59
|
+
expect(nextNodeId('agent', nodes)).toBe('agent_4');
|
|
60
|
+
});
|
|
61
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { GraphNode } from './Workflow.types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Unique id for edges and other internal graph elements that aren't referenced
|
|
5
|
+
* by name in user content. Node IDs use `nextNodeId` for memorable
|
|
6
|
+
* `{kind}_{N}` ids instead.
|
|
7
|
+
*/
|
|
8
|
+
export function genId(prefix: string): string {
|
|
9
|
+
if (typeof crypto !== 'undefined' && 'randomUUID' in crypto) {
|
|
10
|
+
return `${prefix}_${crypto.randomUUID()}`;
|
|
11
|
+
}
|
|
12
|
+
return `${prefix}_${Date.now().toString(36)}_${Math.random()
|
|
13
|
+
.toString(36)
|
|
14
|
+
.slice(2, 8)}`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Next sequential id for a node of the given kind, given the current node
|
|
19
|
+
* list. Returns ids like `agent_1`, `classify_2`, `guardrail_1`, etc., so
|
|
20
|
+
* authors can type them verbatim into `{{...}}` references.
|
|
21
|
+
*
|
|
22
|
+
* Start is a singleton — always `start`. Existing seeded graphs use hand-named
|
|
23
|
+
* ids like `agent_main` / `guard_out`; those don't match the `kind_<digits>`
|
|
24
|
+
* pattern and are ignored when computing the next number, so a fresh `agent`
|
|
25
|
+
* dropped next to `agent_main` becomes `agent_1`, not `agent_2`.
|
|
26
|
+
*/
|
|
27
|
+
export function nextNodeId(
|
|
28
|
+
kind: string,
|
|
29
|
+
nodes: ReadonlyArray<GraphNode>
|
|
30
|
+
): string {
|
|
31
|
+
if (kind === 'start') return 'start';
|
|
32
|
+
const re = new RegExp(`^${kind}_(\\d+)$`);
|
|
33
|
+
let max = 0;
|
|
34
|
+
for (const n of nodes) {
|
|
35
|
+
const m = re.exec(n.id);
|
|
36
|
+
if (m) {
|
|
37
|
+
const v = Number.parseInt(m[1], 10);
|
|
38
|
+
if (Number.isFinite(v) && v > max) max = v;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return `${kind}_${max + 1}`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Offset applied to a duplicated node so it doesn't sit exactly on top. */
|
|
45
|
+
const DUPLICATE_OFFSET = 40;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* A copy of `node` with a fresh sequential id, a deep-cloned config, and a
|
|
49
|
+
* slight offset. Pass the current node list so the duplicate's id continues
|
|
50
|
+
* the per-kind counter. If two duplicates race within the same React batch
|
|
51
|
+
* the second collides and the reducer's existing `addNode` dedupe drops it
|
|
52
|
+
* — one missing duplicate, no corrupt state.
|
|
53
|
+
*/
|
|
54
|
+
export function cloneNode(
|
|
55
|
+
node: GraphNode,
|
|
56
|
+
nodes: ReadonlyArray<GraphNode>
|
|
57
|
+
): GraphNode {
|
|
58
|
+
return {
|
|
59
|
+
id: nextNodeId(node.kind, nodes),
|
|
60
|
+
kind: node.kind,
|
|
61
|
+
position: {
|
|
62
|
+
x: node.position.x + DUPLICATE_OFFSET,
|
|
63
|
+
y: node.position.y + DUPLICATE_OFFSET,
|
|
64
|
+
},
|
|
65
|
+
config: structuredClone(node.config),
|
|
66
|
+
};
|
|
67
|
+
}
|