@particle-academy/fancy-flow 0.19.0 → 0.21.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/{chunk-PHX4SBOD.js → chunk-G3WHXMZ3.js} +3 -3
- package/dist/{chunk-PHX4SBOD.js.map → chunk-G3WHXMZ3.js.map} +1 -1
- package/dist/{chunk-D6W5FMCT.js → chunk-HMWYJIRP.js} +22 -4
- package/dist/chunk-HMWYJIRP.js.map +1 -0
- package/dist/{chunk-FSC64BPD.js → chunk-JE4ENQSE.js} +14 -4
- package/dist/chunk-JE4ENQSE.js.map +1 -0
- package/dist/{chunk-NF6NPY5N.js → chunk-ZB4HHQMR.js} +158 -32
- package/dist/chunk-ZB4HHQMR.js.map +1 -0
- package/dist/index.cjs +346 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +51 -5
- package/dist/index.d.ts +51 -5
- package/dist/index.js +165 -10
- package/dist/index.js.map +1 -1
- package/dist/registry/index.d.cts +2 -2
- package/dist/registry/index.d.ts +2 -2
- package/dist/registry.cjs +138 -30
- package/dist/registry.cjs.map +1 -1
- package/dist/registry.js +2 -2
- package/dist/runtime.js +2 -2
- package/dist/schema/index.d.cts +20 -1
- package/dist/schema/index.d.ts +20 -1
- package/dist/schema.cjs +20 -1
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.js +1 -1
- package/dist/styles.css +20 -0
- package/dist/styles.css.map +1 -1
- package/dist/{types-D_jOR3Z2.d.cts → types-LG-YckGh.d.cts} +22 -0
- package/dist/{types-NerkPtHS.d.ts → types-VGkCXEO6.d.ts} +22 -0
- package/dist/ux.d.cts +1 -1
- package/dist/ux.d.ts +1 -1
- package/package.json +23 -3
- package/dist/chunk-D6W5FMCT.js.map +0 -1
- package/dist/chunk-FSC64BPD.js.map +0 -1
- package/dist/chunk-NF6NPY5N.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, CSSProperties, ComponentType } from 'react';
|
|
3
|
-
import { ReactFlowProps, Edge, BackgroundVariant, NodeProps, NodeTypes } from '@xyflow/react';
|
|
3
|
+
import { ReactFlowProps, Edge, BackgroundVariant, Connection, NodeProps, NodeTypes } from '@xyflow/react';
|
|
4
4
|
import { ConnectionValidatorOptions } from './registry/index.cjs';
|
|
5
5
|
export { ANY_PORT_TYPE, BUILTIN_KINDS, PortCompatibility, RegistryNode, RichInputAdapter, RichInputPreview, buildNodeTypes, categoryAccent, createConnectionValidator, defaultConfigFor, defaultPortCompatibility, getNodeKind, getRichInputAdapter, isRichInputEnabled, listNodeKinds, onNodeKindsChanged, onRichInputAdapterChanged, registerBuiltinKinds, registerNodeKind, registerRichInputAdapter, resolveNodePorts, resolvePortSpec, validateConfig } from './registry/index.cjs';
|
|
6
6
|
import { b as FlowNode, F as FlowGraph, e as NodeRunStatus, E as ExecutorRegistry } from './types-sOmpCitB.cjs';
|
|
7
7
|
export { A as ActionNodeData, B as BaseNodeData, D as DecisionNodeData, a as FlowEdge, c as FlowNodeData, d as FlowNodeKind, N as NodeExecutor, f as NoteNodeData, O as OutputNodeData, P as PortDescriptor, R as RunEvent, S as SubgraphNodeData, T as TriggerNodeData } from './types-sOmpCitB.cjs';
|
|
8
8
|
import { WorkflowSchema, WorkflowMetadata } from './schema/index.cjs';
|
|
9
|
-
export { ImportIssue, ImportOptions, ImportResult, WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, WorkflowSchemaEdge, WorkflowSchemaNode, exportWorkflow, importWorkflow, workflowToBlob } from './schema/index.cjs';
|
|
10
|
-
import { N as NodeCategory, a as NodeKindDefinition, C as ConfigField } from './types-
|
|
11
|
-
export { D as DocumentConfigField, K as KeyValueConfigField, P as PortSpec, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField } from './types-
|
|
9
|
+
export { ImportIssue, ImportOptions, ImportResult, WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, WorkflowSchemaEdge, WorkflowSchemaNode, exportWorkflow, importWorkflow, migrateSchema, workflowToBlob } from './schema/index.cjs';
|
|
10
|
+
import { N as NodeCategory, a as NodeKindDefinition, C as ConfigField } from './types-LG-YckGh.cjs';
|
|
11
|
+
export { D as DocumentConfigField, K as KeyValueConfigField, P as PortSpec, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField } from './types-LG-YckGh.cjs';
|
|
12
12
|
import { FlowRunFeedEntry } from './runtime/index.cjs';
|
|
13
13
|
export { HistoryController, UseFlowHistoryReturn, UseFlowRunOptions, UseFlowRunReturn, UseFlowStateReturn, applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './runtime/index.cjs';
|
|
14
14
|
export { R as RunOptions, a as RunResult, r as runFlow } from './run-flow-VKm57Hcj.cjs';
|
|
@@ -50,6 +50,33 @@ type FlowCanvasProps = Omit<ReactFlowProps<FlowNode, Edge>, "nodes" | "edges" |
|
|
|
50
50
|
*/
|
|
51
51
|
declare function FlowCanvas({ nodes, edges, background, showControls, showMinimap, height, validateConnections, isValidConnection, toolbar, nodeTypes, edgeTypes, className, style, ...rest }: FlowCanvasProps): react.JSX.Element;
|
|
52
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Clone a set of nodes AND the edges internal to that set, remapping every id.
|
|
55
|
+
* This is the piece `duplicateNode` lacks: a copy/paste (or duplicate-selection)
|
|
56
|
+
* that preserves the wiring *between* the copied nodes. Edges with an endpoint
|
|
57
|
+
* outside the set are dropped (they'd dangle). A `parentId` pointing inside the
|
|
58
|
+
* set is remapped; one pointing outside is detached.
|
|
59
|
+
*/
|
|
60
|
+
declare function cloneSubgraph(nodes: FlowNode[], edges: Edge[], opts: {
|
|
61
|
+
makeId: () => string;
|
|
62
|
+
offset?: number;
|
|
63
|
+
}): {
|
|
64
|
+
nodes: FlowNode[];
|
|
65
|
+
edges: Edge[];
|
|
66
|
+
idMap: Map<string, string>;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Rewire one edge's endpoint(s) — wraps xyflow's `reconnectEdge`. Keeps the
|
|
70
|
+
* edge's id (`shouldReplaceId: false`) so its label and identity survive the
|
|
71
|
+
* rewire instead of being regenerated from the new endpoints.
|
|
72
|
+
*/
|
|
73
|
+
declare function reconnectEdge(edges: Edge[], oldEdge: Edge, newConnection: Connection): Edge[];
|
|
74
|
+
type AlignEdge = "left" | "hcenter" | "right" | "top" | "vcenter" | "bottom";
|
|
75
|
+
/** Align a selection to a shared edge/center of its bounding box. */
|
|
76
|
+
declare function alignNodes(nodes: FlowNode[], edge: AlignEdge): FlowNode[];
|
|
77
|
+
/** Evenly distribute a selection's gaps along an axis (needs 3+ nodes). */
|
|
78
|
+
declare function distributeNodes(nodes: FlowNode[], axis: "h" | "v"): FlowNode[];
|
|
79
|
+
|
|
53
80
|
/**
|
|
54
81
|
* Everything the editor knows and can do, handed to every extension point.
|
|
55
82
|
*
|
|
@@ -71,6 +98,10 @@ type FlowEditorApi = {
|
|
|
71
98
|
selectedEdgeId: string | null;
|
|
72
99
|
/** Currently selected edge, or null. */
|
|
73
100
|
selectedEdge: Edge | null;
|
|
101
|
+
/** All multi-selected node ids (xyflow box / shift selection). */
|
|
102
|
+
selectedIds: string[];
|
|
103
|
+
/** All multi-selected nodes. */
|
|
104
|
+
selectedNodes: FlowNode[];
|
|
74
105
|
/** True while a run is in flight. */
|
|
75
106
|
running: boolean;
|
|
76
107
|
/** Per-node run status, keyed by node id. */
|
|
@@ -99,6 +130,21 @@ type FlowEditorApi = {
|
|
|
99
130
|
duplicateNode: (id: string) => string | null;
|
|
100
131
|
/** Replace the whole graph. */
|
|
101
132
|
setGraph: (graph: FlowGraph) => void;
|
|
133
|
+
/** Duplicate the current multi-selection, preserving edges between them. */
|
|
134
|
+
duplicateSelected: () => void;
|
|
135
|
+
/** Align the multi-selection to a shared edge/center of its bounding box. */
|
|
136
|
+
alignSelected: (edge: AlignEdge) => void;
|
|
137
|
+
/** Evenly distribute the multi-selection's gaps along an axis (needs 3+). */
|
|
138
|
+
distributeSelected: (axis: "h" | "v") => void;
|
|
139
|
+
/** Copy the current selection to the editor clipboard. */
|
|
140
|
+
copy: () => void;
|
|
141
|
+
/** Copy then delete the current selection. */
|
|
142
|
+
cut: () => void;
|
|
143
|
+
/** Paste the clipboard (optionally at a flow position) and select the result. */
|
|
144
|
+
paste: (at?: {
|
|
145
|
+
x: number;
|
|
146
|
+
y: number;
|
|
147
|
+
}) => void;
|
|
102
148
|
run: () => void;
|
|
103
149
|
cancel: () => void;
|
|
104
150
|
reset: () => void;
|
|
@@ -476,4 +522,4 @@ type FlowRunFeedProps = {
|
|
|
476
522
|
/** FlowRunFeed — scrolling log panel. Auto-scrolls to bottom on new entries. */
|
|
477
523
|
declare function FlowRunFeed({ entries, className, style }: FlowRunFeedProps): react.JSX.Element;
|
|
478
524
|
|
|
479
|
-
export { ActionNode, ConfigField, ConfigFieldRenderer, type ConfigFieldRendererProps, ConnectionValidatorOptions, DecisionNode, ExecutorRegistry, FlowCanvas, type FlowCanvasProps, FlowEditor, type FlowEditorAction, type FlowEditorApi, type FlowEditorBuiltins, type FlowEditorProps, type FlowEditorSlots, FlowGraph, FlowNode, type FlowNodeRenderProps, FlowRunControls, type FlowRunControlsProps, FlowRunFeed, FlowRunFeedEntry, type FlowRunFeedProps, NodeCategory, NodeConfigPanel, type NodeConfigPanelProps, NodeKindDefinition, NodePalette, type NodePaletteProps, NodePort, type NodePortProps, type NodePortSide, type NodePortType, NodeRunStatus, NodeShell, type NodeShellProps, NoteNode, OutputNode, SubgraphNode, TriggerNode, WorkflowMetadata, WorkflowSchema, defaultNodeTypes, defineNode, paletteDropHandlers, useFlowEditor, useFlowEditorOptional };
|
|
525
|
+
export { ActionNode, type AlignEdge, ConfigField, ConfigFieldRenderer, type ConfigFieldRendererProps, ConnectionValidatorOptions, DecisionNode, ExecutorRegistry, FlowCanvas, type FlowCanvasProps, FlowEditor, type FlowEditorAction, type FlowEditorApi, type FlowEditorBuiltins, type FlowEditorProps, type FlowEditorSlots, FlowGraph, FlowNode, type FlowNodeRenderProps, FlowRunControls, type FlowRunControlsProps, FlowRunFeed, FlowRunFeedEntry, type FlowRunFeedProps, NodeCategory, NodeConfigPanel, type NodeConfigPanelProps, NodeKindDefinition, NodePalette, type NodePaletteProps, NodePort, type NodePortProps, type NodePortSide, type NodePortType, NodeRunStatus, NodeShell, type NodeShellProps, NoteNode, OutputNode, SubgraphNode, TriggerNode, WorkflowMetadata, WorkflowSchema, alignNodes, cloneSubgraph, defaultNodeTypes, defineNode, distributeNodes, paletteDropHandlers, reconnectEdge, useFlowEditor, useFlowEditorOptional };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, CSSProperties, ComponentType } from 'react';
|
|
3
|
-
import { ReactFlowProps, Edge, BackgroundVariant, NodeProps, NodeTypes } from '@xyflow/react';
|
|
3
|
+
import { ReactFlowProps, Edge, BackgroundVariant, Connection, NodeProps, NodeTypes } from '@xyflow/react';
|
|
4
4
|
import { ConnectionValidatorOptions } from './registry/index.js';
|
|
5
5
|
export { ANY_PORT_TYPE, BUILTIN_KINDS, PortCompatibility, RegistryNode, RichInputAdapter, RichInputPreview, buildNodeTypes, categoryAccent, createConnectionValidator, defaultConfigFor, defaultPortCompatibility, getNodeKind, getRichInputAdapter, isRichInputEnabled, listNodeKinds, onNodeKindsChanged, onRichInputAdapterChanged, registerBuiltinKinds, registerNodeKind, registerRichInputAdapter, resolveNodePorts, resolvePortSpec, validateConfig } from './registry/index.js';
|
|
6
6
|
import { b as FlowNode, F as FlowGraph, e as NodeRunStatus, E as ExecutorRegistry } from './types-sOmpCitB.js';
|
|
7
7
|
export { A as ActionNodeData, B as BaseNodeData, D as DecisionNodeData, a as FlowEdge, c as FlowNodeData, d as FlowNodeKind, N as NodeExecutor, f as NoteNodeData, O as OutputNodeData, P as PortDescriptor, R as RunEvent, S as SubgraphNodeData, T as TriggerNodeData } from './types-sOmpCitB.js';
|
|
8
8
|
import { WorkflowSchema, WorkflowMetadata } from './schema/index.js';
|
|
9
|
-
export { ImportIssue, ImportOptions, ImportResult, WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, WorkflowSchemaEdge, WorkflowSchemaNode, exportWorkflow, importWorkflow, workflowToBlob } from './schema/index.js';
|
|
10
|
-
import { N as NodeCategory, a as NodeKindDefinition, C as ConfigField } from './types-
|
|
11
|
-
export { D as DocumentConfigField, K as KeyValueConfigField, P as PortSpec, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField } from './types-
|
|
9
|
+
export { ImportIssue, ImportOptions, ImportResult, WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, WorkflowSchemaEdge, WorkflowSchemaNode, exportWorkflow, importWorkflow, migrateSchema, workflowToBlob } from './schema/index.js';
|
|
10
|
+
import { N as NodeCategory, a as NodeKindDefinition, C as ConfigField } from './types-VGkCXEO6.js';
|
|
11
|
+
export { D as DocumentConfigField, K as KeyValueConfigField, P as PortSpec, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField } from './types-VGkCXEO6.js';
|
|
12
12
|
import { FlowRunFeedEntry } from './runtime/index.js';
|
|
13
13
|
export { HistoryController, UseFlowHistoryReturn, UseFlowRunOptions, UseFlowRunReturn, UseFlowStateReturn, applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './runtime/index.js';
|
|
14
14
|
export { R as RunOptions, a as RunResult, r as runFlow } from './run-flow-ChBi6q-W.js';
|
|
@@ -50,6 +50,33 @@ type FlowCanvasProps = Omit<ReactFlowProps<FlowNode, Edge>, "nodes" | "edges" |
|
|
|
50
50
|
*/
|
|
51
51
|
declare function FlowCanvas({ nodes, edges, background, showControls, showMinimap, height, validateConnections, isValidConnection, toolbar, nodeTypes, edgeTypes, className, style, ...rest }: FlowCanvasProps): react.JSX.Element;
|
|
52
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Clone a set of nodes AND the edges internal to that set, remapping every id.
|
|
55
|
+
* This is the piece `duplicateNode` lacks: a copy/paste (or duplicate-selection)
|
|
56
|
+
* that preserves the wiring *between* the copied nodes. Edges with an endpoint
|
|
57
|
+
* outside the set are dropped (they'd dangle). A `parentId` pointing inside the
|
|
58
|
+
* set is remapped; one pointing outside is detached.
|
|
59
|
+
*/
|
|
60
|
+
declare function cloneSubgraph(nodes: FlowNode[], edges: Edge[], opts: {
|
|
61
|
+
makeId: () => string;
|
|
62
|
+
offset?: number;
|
|
63
|
+
}): {
|
|
64
|
+
nodes: FlowNode[];
|
|
65
|
+
edges: Edge[];
|
|
66
|
+
idMap: Map<string, string>;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Rewire one edge's endpoint(s) — wraps xyflow's `reconnectEdge`. Keeps the
|
|
70
|
+
* edge's id (`shouldReplaceId: false`) so its label and identity survive the
|
|
71
|
+
* rewire instead of being regenerated from the new endpoints.
|
|
72
|
+
*/
|
|
73
|
+
declare function reconnectEdge(edges: Edge[], oldEdge: Edge, newConnection: Connection): Edge[];
|
|
74
|
+
type AlignEdge = "left" | "hcenter" | "right" | "top" | "vcenter" | "bottom";
|
|
75
|
+
/** Align a selection to a shared edge/center of its bounding box. */
|
|
76
|
+
declare function alignNodes(nodes: FlowNode[], edge: AlignEdge): FlowNode[];
|
|
77
|
+
/** Evenly distribute a selection's gaps along an axis (needs 3+ nodes). */
|
|
78
|
+
declare function distributeNodes(nodes: FlowNode[], axis: "h" | "v"): FlowNode[];
|
|
79
|
+
|
|
53
80
|
/**
|
|
54
81
|
* Everything the editor knows and can do, handed to every extension point.
|
|
55
82
|
*
|
|
@@ -71,6 +98,10 @@ type FlowEditorApi = {
|
|
|
71
98
|
selectedEdgeId: string | null;
|
|
72
99
|
/** Currently selected edge, or null. */
|
|
73
100
|
selectedEdge: Edge | null;
|
|
101
|
+
/** All multi-selected node ids (xyflow box / shift selection). */
|
|
102
|
+
selectedIds: string[];
|
|
103
|
+
/** All multi-selected nodes. */
|
|
104
|
+
selectedNodes: FlowNode[];
|
|
74
105
|
/** True while a run is in flight. */
|
|
75
106
|
running: boolean;
|
|
76
107
|
/** Per-node run status, keyed by node id. */
|
|
@@ -99,6 +130,21 @@ type FlowEditorApi = {
|
|
|
99
130
|
duplicateNode: (id: string) => string | null;
|
|
100
131
|
/** Replace the whole graph. */
|
|
101
132
|
setGraph: (graph: FlowGraph) => void;
|
|
133
|
+
/** Duplicate the current multi-selection, preserving edges between them. */
|
|
134
|
+
duplicateSelected: () => void;
|
|
135
|
+
/** Align the multi-selection to a shared edge/center of its bounding box. */
|
|
136
|
+
alignSelected: (edge: AlignEdge) => void;
|
|
137
|
+
/** Evenly distribute the multi-selection's gaps along an axis (needs 3+). */
|
|
138
|
+
distributeSelected: (axis: "h" | "v") => void;
|
|
139
|
+
/** Copy the current selection to the editor clipboard. */
|
|
140
|
+
copy: () => void;
|
|
141
|
+
/** Copy then delete the current selection. */
|
|
142
|
+
cut: () => void;
|
|
143
|
+
/** Paste the clipboard (optionally at a flow position) and select the result. */
|
|
144
|
+
paste: (at?: {
|
|
145
|
+
x: number;
|
|
146
|
+
y: number;
|
|
147
|
+
}) => void;
|
|
102
148
|
run: () => void;
|
|
103
149
|
cancel: () => void;
|
|
104
150
|
reset: () => void;
|
|
@@ -476,4 +522,4 @@ type FlowRunFeedProps = {
|
|
|
476
522
|
/** FlowRunFeed — scrolling log panel. Auto-scrolls to bottom on new entries. */
|
|
477
523
|
declare function FlowRunFeed({ entries, className, style }: FlowRunFeedProps): react.JSX.Element;
|
|
478
524
|
|
|
479
|
-
export { ActionNode, ConfigField, ConfigFieldRenderer, type ConfigFieldRendererProps, ConnectionValidatorOptions, DecisionNode, ExecutorRegistry, FlowCanvas, type FlowCanvasProps, FlowEditor, type FlowEditorAction, type FlowEditorApi, type FlowEditorBuiltins, type FlowEditorProps, type FlowEditorSlots, FlowGraph, FlowNode, type FlowNodeRenderProps, FlowRunControls, type FlowRunControlsProps, FlowRunFeed, FlowRunFeedEntry, type FlowRunFeedProps, NodeCategory, NodeConfigPanel, type NodeConfigPanelProps, NodeKindDefinition, NodePalette, type NodePaletteProps, NodePort, type NodePortProps, type NodePortSide, type NodePortType, NodeRunStatus, NodeShell, type NodeShellProps, NoteNode, OutputNode, SubgraphNode, TriggerNode, WorkflowMetadata, WorkflowSchema, defaultNodeTypes, defineNode, paletteDropHandlers, useFlowEditor, useFlowEditorOptional };
|
|
525
|
+
export { ActionNode, type AlignEdge, ConfigField, ConfigFieldRenderer, type ConfigFieldRendererProps, ConnectionValidatorOptions, DecisionNode, ExecutorRegistry, FlowCanvas, type FlowCanvasProps, FlowEditor, type FlowEditorAction, type FlowEditorApi, type FlowEditorBuiltins, type FlowEditorProps, type FlowEditorSlots, FlowGraph, FlowNode, type FlowNodeRenderProps, FlowRunControls, type FlowRunControlsProps, FlowRunFeed, FlowRunFeedEntry, type FlowRunFeedProps, NodeCategory, NodeConfigPanel, type NodeConfigPanelProps, NodeKindDefinition, NodePalette, type NodePaletteProps, NodePort, type NodePortProps, type NodePortSide, type NodePortType, NodeRunStatus, NodeShell, type NodeShellProps, NoteNode, OutputNode, SubgraphNode, TriggerNode, WorkflowMetadata, WorkflowSchema, alignNodes, cloneSubgraph, defaultNodeTypes, defineNode, distributeNodes, paletteDropHandlers, reconnectEdge, useFlowEditor, useFlowEditorOptional };
|
package/dist/index.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { useFlowState, useFlowRun, useFlowHistory, applyStatusesToNodes } from './chunk-
|
|
2
|
-
export { applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './chunk-
|
|
3
|
-
import { buildNodeTypes, registerBuiltinKinds, createConnectionValidator } from './chunk-
|
|
4
|
-
export { ANY_PORT_TYPE, BUILTIN_KINDS, RegistryNode, buildNodeTypes, createConnectionValidator, defaultPortCompatibility, registerBuiltinKinds } from './chunk-
|
|
5
|
-
import { ReactFlowProvider, useReactFlow, addEdge, applyEdgeChanges, applyNodeChanges, Position, Handle, index, BackgroundVariant, Background, Controls, MiniMap } from './chunk-
|
|
1
|
+
import { useFlowState, useFlowRun, useFlowHistory, applyStatusesToNodes } from './chunk-G3WHXMZ3.js';
|
|
2
|
+
export { applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './chunk-G3WHXMZ3.js';
|
|
3
|
+
import { buildNodeTypes, registerBuiltinKinds, createConnectionValidator } from './chunk-JE4ENQSE.js';
|
|
4
|
+
export { ANY_PORT_TYPE, BUILTIN_KINDS, RegistryNode, buildNodeTypes, createConnectionValidator, defaultPortCompatibility, registerBuiltinKinds } from './chunk-JE4ENQSE.js';
|
|
5
|
+
import { ReactFlowProvider, useReactFlow, addEdge, applyEdgeChanges, applyNodeChanges, Position, Handle, reconnectEdge, index, BackgroundVariant, Background, Controls, MiniMap } from './chunk-ZB4HHQMR.js';
|
|
6
6
|
export { LEGACY_PAUSE_PREFIXES, PAUSE_PREFIX, decodePause, encodePause, isPause, pauseForHuman } from './chunk-UEOE6B52.js';
|
|
7
7
|
export { runFlow } from './chunk-L4AX73Q6.js';
|
|
8
|
-
import { workflowToBlob, importWorkflow, exportWorkflow } from './chunk-
|
|
9
|
-
export { WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, exportWorkflow, importWorkflow, workflowToBlob } from './chunk-
|
|
8
|
+
import { workflowToBlob, importWorkflow, exportWorkflow } from './chunk-HMWYJIRP.js';
|
|
9
|
+
export { WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, exportWorkflow, importWorkflow, migrateSchema, workflowToBlob } from './chunk-HMWYJIRP.js';
|
|
10
10
|
export { resolveNodePorts, resolvePortSpec } from './chunk-TITD5W4Y.js';
|
|
11
11
|
import { onNodeKindsChanged, listNodeKinds, getNodeKind, defaultConfigFor, validateConfig, categoryAccent } from './chunk-U5F22BHV.js';
|
|
12
12
|
export { categoryAccent, defaultConfigFor, getNodeKind, listNodeKinds, onNodeKindsChanged, registerNodeKind, validateConfig } from './chunk-U5F22BHV.js';
|
|
13
13
|
import { getRichInputAdapter } from './chunk-F5RPRB7A.js';
|
|
14
14
|
export { RichInputPreview, getRichInputAdapter, isRichInputEnabled, onRichInputAdapterChanged, registerRichInputAdapter } from './chunk-F5RPRB7A.js';
|
|
15
15
|
import './chunk-USL4FMFU.js';
|
|
16
|
-
import { memo, createContext, forwardRef, useState, useEffect, useMemo, useCallback,
|
|
16
|
+
import { memo, createContext, forwardRef, useState, useEffect, useMemo, useCallback, useRef, useImperativeHandle, useContext } from 'react';
|
|
17
17
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
18
18
|
|
|
19
19
|
function NodeShellInner({
|
|
@@ -839,6 +839,65 @@ function duplicateNode(node, id, offset = 40) {
|
|
|
839
839
|
data: JSON.parse(JSON.stringify(node.data ?? {}))
|
|
840
840
|
};
|
|
841
841
|
}
|
|
842
|
+
function cloneSubgraph(nodes, edges, opts) {
|
|
843
|
+
const offset = opts.offset ?? 40;
|
|
844
|
+
const idMap = /* @__PURE__ */ new Map();
|
|
845
|
+
for (const n of nodes) idMap.set(n.id, opts.makeId());
|
|
846
|
+
const clonedNodes = nodes.map((n) => {
|
|
847
|
+
const cloned = duplicateNode(n, idMap.get(n.id), offset);
|
|
848
|
+
const parentId = n.parentId;
|
|
849
|
+
if (parentId && idMap.has(parentId)) cloned.parentId = idMap.get(parentId);
|
|
850
|
+
else if (parentId) delete cloned.parentId;
|
|
851
|
+
return cloned;
|
|
852
|
+
});
|
|
853
|
+
const clonedEdges = edges.filter((e) => idMap.has(e.source) && idMap.has(e.target)).map((e) => ({ ...e, id: opts.makeId(), source: idMap.get(e.source), target: idMap.get(e.target) }));
|
|
854
|
+
return { nodes: clonedNodes, edges: clonedEdges, idMap };
|
|
855
|
+
}
|
|
856
|
+
function reconnectEdge2(edges, oldEdge, newConnection) {
|
|
857
|
+
return reconnectEdge(oldEdge, newConnection, edges, { shouldReplaceId: false });
|
|
858
|
+
}
|
|
859
|
+
var nodeW = (n) => n.width ?? n.measured?.width ?? 0;
|
|
860
|
+
var nodeH = (n) => n.height ?? n.measured?.height ?? 0;
|
|
861
|
+
function alignNodes(nodes, edge) {
|
|
862
|
+
if (nodes.length < 2) return nodes;
|
|
863
|
+
const minL = Math.min(...nodes.map((n) => n.position.x));
|
|
864
|
+
const maxR = Math.max(...nodes.map((n) => n.position.x + nodeW(n)));
|
|
865
|
+
const minT = Math.min(...nodes.map((n) => n.position.y));
|
|
866
|
+
const maxB = Math.max(...nodes.map((n) => n.position.y + nodeH(n)));
|
|
867
|
+
const cx = (minL + maxR) / 2;
|
|
868
|
+
const cy = (minT + maxB) / 2;
|
|
869
|
+
return nodes.map((n) => {
|
|
870
|
+
let { x, y } = n.position;
|
|
871
|
+
if (edge === "left") x = minL;
|
|
872
|
+
else if (edge === "right") x = maxR - nodeW(n);
|
|
873
|
+
else if (edge === "hcenter") x = cx - nodeW(n) / 2;
|
|
874
|
+
else if (edge === "top") y = minT;
|
|
875
|
+
else if (edge === "bottom") y = maxB - nodeH(n);
|
|
876
|
+
else if (edge === "vcenter") y = cy - nodeH(n) / 2;
|
|
877
|
+
return { ...n, position: { x, y } };
|
|
878
|
+
});
|
|
879
|
+
}
|
|
880
|
+
function distributeNodes(nodes, axis) {
|
|
881
|
+
if (nodes.length < 3) return nodes;
|
|
882
|
+
const size = (n) => axis === "h" ? nodeW(n) : nodeH(n);
|
|
883
|
+
const coord = (n) => axis === "h" ? n.position.x : n.position.y;
|
|
884
|
+
const sorted = [...nodes].sort((a, b) => coord(a) - coord(b));
|
|
885
|
+
const start = coord(sorted[0]);
|
|
886
|
+
const last = sorted[sorted.length - 1];
|
|
887
|
+
const end = coord(last) + size(last);
|
|
888
|
+
const totalSize = sorted.reduce((s, n) => s + size(n), 0);
|
|
889
|
+
const gap = (end - start - totalSize) / (sorted.length - 1);
|
|
890
|
+
const posById = /* @__PURE__ */ new Map();
|
|
891
|
+
let cursor = start;
|
|
892
|
+
for (const n of sorted) {
|
|
893
|
+
posById.set(n.id, cursor);
|
|
894
|
+
cursor += size(n) + gap;
|
|
895
|
+
}
|
|
896
|
+
return nodes.map((n) => {
|
|
897
|
+
const p = posById.get(n.id);
|
|
898
|
+
return { ...n, position: axis === "h" ? { ...n.position, x: p } : { ...n.position, y: p } };
|
|
899
|
+
});
|
|
900
|
+
}
|
|
842
901
|
var FlowEditorContext = createContext(null);
|
|
843
902
|
var FlowEditorProvider = FlowEditorContext.Provider;
|
|
844
903
|
function useFlowEditor() {
|
|
@@ -1008,6 +1067,89 @@ function FlowEditorInner({
|
|
|
1008
1067
|
},
|
|
1009
1068
|
[flow, onEdgeDelete, confirmDelete]
|
|
1010
1069
|
);
|
|
1070
|
+
const selectedNodes = useMemo(() => flow.nodes.filter((n) => n.selected), [flow.nodes]);
|
|
1071
|
+
const selectedIds = useMemo(() => selectedNodes.map((n) => n.id), [selectedNodes]);
|
|
1072
|
+
const clipboard = useRef(null);
|
|
1073
|
+
const copySelection = useCallback(() => {
|
|
1074
|
+
const sel = flow.nodes.filter((n) => n.selected);
|
|
1075
|
+
if (sel.length === 0) return;
|
|
1076
|
+
const ids = new Set(sel.map((n) => n.id));
|
|
1077
|
+
const edges = flow.edges.filter((e) => ids.has(e.source) && ids.has(e.target));
|
|
1078
|
+
clipboard.current = { nodes: sel.map((n) => ({ ...n })), edges: edges.map((e) => ({ ...e })) };
|
|
1079
|
+
}, [flow]);
|
|
1080
|
+
const pasteClipboard = useCallback(
|
|
1081
|
+
(at) => {
|
|
1082
|
+
const clip = clipboard.current;
|
|
1083
|
+
if (!clip || clip.nodes.length === 0) return;
|
|
1084
|
+
const { nodes: clones, edges: cloneEdges } = cloneSubgraph(clip.nodes, clip.edges, { makeId: newNodeId, offset: 40 });
|
|
1085
|
+
let placed = clones;
|
|
1086
|
+
if (at) {
|
|
1087
|
+
const minX = Math.min(...clones.map((n) => n.position.x));
|
|
1088
|
+
const minY = Math.min(...clones.map((n) => n.position.y));
|
|
1089
|
+
placed = clones.map((n) => ({ ...n, position: { x: n.position.x - minX + at.x, y: n.position.y - minY + at.y } }));
|
|
1090
|
+
}
|
|
1091
|
+
flow.setGraph({
|
|
1092
|
+
nodes: [...flow.nodes.map((n) => ({ ...n, selected: false })), ...placed.map((n) => ({ ...n, selected: true }))],
|
|
1093
|
+
edges: [...flow.edges, ...cloneEdges]
|
|
1094
|
+
});
|
|
1095
|
+
},
|
|
1096
|
+
[flow]
|
|
1097
|
+
);
|
|
1098
|
+
const duplicateSelected = useCallback(() => {
|
|
1099
|
+
const sel = flow.nodes.filter((n) => n.selected);
|
|
1100
|
+
if (sel.length === 0) return;
|
|
1101
|
+
const ids = new Set(sel.map((n) => n.id));
|
|
1102
|
+
const internal2 = flow.edges.filter((e) => ids.has(e.source) && ids.has(e.target));
|
|
1103
|
+
const { nodes: clones, edges: cloneEdges } = cloneSubgraph(sel, internal2, { makeId: newNodeId, offset: 40 });
|
|
1104
|
+
flow.setGraph({
|
|
1105
|
+
nodes: [...flow.nodes.map((n) => ({ ...n, selected: false })), ...clones.map((n) => ({ ...n, selected: true }))],
|
|
1106
|
+
edges: [...flow.edges, ...cloneEdges]
|
|
1107
|
+
});
|
|
1108
|
+
}, [flow]);
|
|
1109
|
+
const alignSelected = useCallback(
|
|
1110
|
+
(edge) => {
|
|
1111
|
+
const sel = flow.nodes.filter((n) => n.selected);
|
|
1112
|
+
if (sel.length < 2) return;
|
|
1113
|
+
const byId = new Map(alignNodes(sel, edge).map((n) => [n.id, n]));
|
|
1114
|
+
flow.setNodes((all) => all.map((n) => byId.get(n.id) ?? n));
|
|
1115
|
+
},
|
|
1116
|
+
[flow]
|
|
1117
|
+
);
|
|
1118
|
+
const distributeSelected = useCallback(
|
|
1119
|
+
(axis) => {
|
|
1120
|
+
const sel = flow.nodes.filter((n) => n.selected);
|
|
1121
|
+
if (sel.length < 3) return;
|
|
1122
|
+
const byId = new Map(distributeNodes(sel, axis).map((n) => [n.id, n]));
|
|
1123
|
+
flow.setNodes((all) => all.map((n) => byId.get(n.id) ?? n));
|
|
1124
|
+
},
|
|
1125
|
+
[flow]
|
|
1126
|
+
);
|
|
1127
|
+
const onReconnect = useCallback(
|
|
1128
|
+
(oldEdge, conn) => flow.setEdges((eds) => reconnectEdge2(eds, oldEdge, conn)),
|
|
1129
|
+
[flow]
|
|
1130
|
+
);
|
|
1131
|
+
useEffect(() => {
|
|
1132
|
+
const onKey = (e) => {
|
|
1133
|
+
const t = e.target;
|
|
1134
|
+
if (t && (t.tagName === "INPUT" || t.tagName === "TEXTAREA" || t.isContentEditable)) return;
|
|
1135
|
+
if (!(e.ctrlKey || e.metaKey)) return;
|
|
1136
|
+
const key = e.key.toLowerCase();
|
|
1137
|
+
if (key === "c") copySelection();
|
|
1138
|
+
else if (key === "x") {
|
|
1139
|
+
e.preventDefault();
|
|
1140
|
+
copySelection();
|
|
1141
|
+
deleteNodes(selectedIds);
|
|
1142
|
+
} else if (key === "v") {
|
|
1143
|
+
e.preventDefault();
|
|
1144
|
+
pasteClipboard();
|
|
1145
|
+
} else if (key === "d") {
|
|
1146
|
+
e.preventDefault();
|
|
1147
|
+
duplicateSelected();
|
|
1148
|
+
}
|
|
1149
|
+
};
|
|
1150
|
+
window.addEventListener("keydown", onKey);
|
|
1151
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
1152
|
+
}, [copySelection, pasteClipboard, duplicateSelected, deleteNodes, selectedIds]);
|
|
1011
1153
|
const api = useMemo(() => {
|
|
1012
1154
|
const toWorkflow = () => exportWorkflow({ nodes: flow.nodes, edges: flow.edges }, metadata);
|
|
1013
1155
|
return {
|
|
@@ -1018,6 +1160,8 @@ function FlowEditorInner({
|
|
|
1018
1160
|
selected,
|
|
1019
1161
|
selectedEdgeId,
|
|
1020
1162
|
selectedEdge,
|
|
1163
|
+
selectedIds,
|
|
1164
|
+
selectedNodes,
|
|
1021
1165
|
running: runner.running,
|
|
1022
1166
|
statuses: runner.statuses,
|
|
1023
1167
|
select: setSelectedId,
|
|
@@ -1038,6 +1182,15 @@ function FlowEditorInner({
|
|
|
1038
1182
|
return copy.id;
|
|
1039
1183
|
},
|
|
1040
1184
|
setGraph: (graph) => flow.setGraph(graph),
|
|
1185
|
+
duplicateSelected,
|
|
1186
|
+
alignSelected,
|
|
1187
|
+
distributeSelected,
|
|
1188
|
+
copy: copySelection,
|
|
1189
|
+
cut: () => {
|
|
1190
|
+
copySelection();
|
|
1191
|
+
deleteNodes(selectedIds);
|
|
1192
|
+
},
|
|
1193
|
+
paste: pasteClipboard,
|
|
1041
1194
|
run: () => runner.run({ nodes: flow.nodes, edges: flow.edges }, executors),
|
|
1042
1195
|
cancel: runner.cancel,
|
|
1043
1196
|
reset: runner.reset,
|
|
@@ -1050,7 +1203,7 @@ function FlowEditorInner({
|
|
|
1050
1203
|
canUndo: hist.canUndo,
|
|
1051
1204
|
canRedo: hist.canRedo
|
|
1052
1205
|
};
|
|
1053
|
-
}, [flow, selectedId, selected, selectedEdgeId, selectedEdge, runner, executors, metadata, addNode, deleteNodes, deleteEdges, hist, rf]);
|
|
1206
|
+
}, [flow, selectedId, selected, selectedEdgeId, selectedEdge, selectedIds, selectedNodes, runner, executors, metadata, addNode, deleteNodes, deleteEdges, duplicateSelected, alignSelected, distributeSelected, copySelection, pasteClipboard, hist, rf]);
|
|
1054
1207
|
useImperativeHandle(apiRef, () => api, [api]);
|
|
1055
1208
|
const dropHandlers = paletteDropHandlers((kindName, evt) => {
|
|
1056
1209
|
const point = rf.screenToFlowPosition({ x: evt.clientX, y: evt.clientY });
|
|
@@ -1110,6 +1263,8 @@ function FlowEditorInner({
|
|
|
1110
1263
|
onNodesChange: flow.onNodesChange,
|
|
1111
1264
|
onEdgesChange: flow.onEdgesChange,
|
|
1112
1265
|
onConnect: flow.onConnect,
|
|
1266
|
+
onReconnect,
|
|
1267
|
+
edgesReconnectable: true,
|
|
1113
1268
|
onNodeDragStart: hist.onNodeDragStart,
|
|
1114
1269
|
onNodeClick: handleNodeClick,
|
|
1115
1270
|
onNodeContextMenu: builtins.contextMenu === false ? void 0 : handleNodeContextMenu,
|
|
@@ -1376,6 +1531,6 @@ function NodePort({ side, type, id, style, title, className }) {
|
|
|
1376
1531
|
// src/index.ts
|
|
1377
1532
|
registerBuiltinKinds();
|
|
1378
1533
|
|
|
1379
|
-
export { ActionNode, ConfigFieldRenderer, DecisionNode, FlowCanvas, FlowEditor, FlowRunControls, FlowRunFeed, NodeConfigPanel, NodePalette, NodePort, NodeShell, NoteNode, OutputNode, SubgraphNode, TriggerNode, defaultNodeTypes, defineNode, paletteDropHandlers, useFlowEditor, useFlowEditorOptional };
|
|
1534
|
+
export { ActionNode, ConfigFieldRenderer, DecisionNode, FlowCanvas, FlowEditor, FlowRunControls, FlowRunFeed, NodeConfigPanel, NodePalette, NodePort, NodeShell, NoteNode, OutputNode, SubgraphNode, TriggerNode, alignNodes, cloneSubgraph, defaultNodeTypes, defineNode, distributeNodes, paletteDropHandlers, reconnectEdge2 as reconnectEdge, useFlowEditor, useFlowEditorOptional };
|
|
1380
1535
|
//# sourceMappingURL=index.js.map
|
|
1381
1536
|
//# sourceMappingURL=index.js.map
|