@particle-academy/fancy-flow 0.5.3 → 0.6.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/README.md +125 -1
- package/dist/engine.d.cts +2 -2
- package/dist/engine.d.ts +2 -2
- package/dist/index.cjs +223 -127
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +131 -13
- package/dist/index.d.ts +131 -13
- package/dist/index.js +228 -134
- package/dist/index.js.map +1 -1
- package/dist/registry/index.d.cts +3 -3
- package/dist/registry/index.d.ts +3 -3
- package/dist/runtime/index.d.cts +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/schema/index.d.cts +1 -1
- package/dist/schema/index.d.ts +1 -1
- package/dist/styles.css +30 -1
- package/dist/styles.css.map +1 -1
- package/dist/{types-TemTtb04.d.cts → types-BS3Gwnkq.d.cts} +1 -1
- package/dist/{types-TemTtb04.d.ts → types-BS3Gwnkq.d.ts} +1 -1
- package/dist/{types-D5RERHIP.d.cts → types-C0wdN6QX.d.cts} +1 -1
- package/dist/{types-BodwZiST.d.ts → types-DnMe9Vsf.d.ts} +1 -1
- package/dist/ux.d.cts +2 -2
- package/dist/ux.d.ts +2 -2
- package/package.json +5 -2
package/dist/index.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { useFlowState, useFlowRun, applyStatusesToNodes } from './chunk-QSSQRQN4.js';
|
|
2
2
|
export { applyStatusesToNodes, useFlowRun, useFlowState } from './chunk-QSSQRQN4.js';
|
|
3
3
|
export { runFlow } from './chunk-NVULCEDX.js';
|
|
4
|
-
import {
|
|
4
|
+
import { buildNodeTypes, registerBuiltinKinds } from './chunk-M2XKGQQL.js';
|
|
5
5
|
export { BUILTIN_KINDS, RegistryNode, buildNodeTypes, registerBuiltinKinds } from './chunk-M2XKGQQL.js';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { ReactFlowProvider, useReactFlow, addEdge, applyEdgeChanges, applyNodeChanges, Position, Handle, index, BackgroundVariant, Background, Controls, MiniMap } from './chunk-NF6NPY5N.js';
|
|
7
|
+
import { workflowToBlob, importWorkflow, exportWorkflow } from './chunk-BCXECQUC.js';
|
|
8
8
|
export { WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, exportWorkflow, importWorkflow, workflowToBlob } from './chunk-BCXECQUC.js';
|
|
9
|
-
import { onNodeKindsChanged, listNodeKinds,
|
|
9
|
+
import { onNodeKindsChanged, listNodeKinds, getNodeKind, defaultConfigFor, validateConfig, categoryAccent } from './chunk-WNVBXXOL.js';
|
|
10
10
|
export { categoryAccent, defaultConfigFor, getNodeKind, listNodeKinds, onNodeKindsChanged, registerNodeKind, validateConfig } from './chunk-WNVBXXOL.js';
|
|
11
|
-
import { memo,
|
|
12
|
-
import {
|
|
11
|
+
import { memo, createContext, forwardRef, useState, useEffect, useMemo, useCallback, useImperativeHandle, useRef, useContext } from 'react';
|
|
12
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
13
13
|
|
|
14
14
|
function NodeShellInner({
|
|
15
15
|
node,
|
|
@@ -508,16 +508,52 @@ function formatTime(at) {
|
|
|
508
508
|
const d = new Date(at);
|
|
509
509
|
return `${d.getMinutes().toString().padStart(2, "0")}:${d.getSeconds().toString().padStart(2, "0")}.${Math.floor(d.getMilliseconds() / 100)}`;
|
|
510
510
|
}
|
|
511
|
-
|
|
511
|
+
|
|
512
|
+
// src/components/FlowEditor/graph-ops.ts
|
|
513
|
+
function removeNodes(graph, ids) {
|
|
514
|
+
if (ids.length === 0) return graph;
|
|
515
|
+
const doomed = new Set(ids);
|
|
516
|
+
return {
|
|
517
|
+
nodes: graph.nodes.filter((n) => !doomed.has(n.id)),
|
|
518
|
+
edges: graph.edges.filter((e) => !doomed.has(e.source) && !doomed.has(e.target))
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
function removeEdges(edges, ids) {
|
|
522
|
+
if (ids.length === 0) return edges;
|
|
523
|
+
const doomed = new Set(ids);
|
|
524
|
+
return edges.filter((e) => !doomed.has(e.id));
|
|
525
|
+
}
|
|
526
|
+
function duplicateNode(node, id, offset = 40) {
|
|
527
|
+
return {
|
|
528
|
+
...node,
|
|
529
|
+
id,
|
|
530
|
+
position: { x: node.position.x + offset, y: node.position.y + offset },
|
|
531
|
+
// Deep copy so the clone's config edits don't mutate the original.
|
|
532
|
+
data: JSON.parse(JSON.stringify(node.data ?? {}))
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
var FlowEditorContext = createContext(null);
|
|
536
|
+
var FlowEditorProvider = FlowEditorContext.Provider;
|
|
537
|
+
function useFlowEditor() {
|
|
538
|
+
const api = useContext(FlowEditorContext);
|
|
539
|
+
if (api === null) {
|
|
540
|
+
throw new Error("useFlowEditor() must be called inside <FlowEditor>.");
|
|
541
|
+
}
|
|
542
|
+
return api;
|
|
543
|
+
}
|
|
544
|
+
function useFlowEditorOptional() {
|
|
545
|
+
return useContext(FlowEditorContext);
|
|
546
|
+
}
|
|
547
|
+
var FlowEditor = forwardRef(function FlowEditor2(props, ref) {
|
|
512
548
|
return /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsx(
|
|
513
549
|
"div",
|
|
514
550
|
{
|
|
515
551
|
className: ["ff-editor", props.className ?? ""].filter(Boolean).join(" "),
|
|
516
552
|
style: { height: props.height ?? 720, ...props.style },
|
|
517
|
-
children: /* @__PURE__ */ jsx(FlowEditorInner, { ...props })
|
|
553
|
+
children: /* @__PURE__ */ jsx(FlowEditorInner, { ...props, apiRef: ref })
|
|
518
554
|
}
|
|
519
555
|
) });
|
|
520
|
-
}
|
|
556
|
+
});
|
|
521
557
|
function FlowEditorInner({
|
|
522
558
|
initial = { nodes: [], edges: [] },
|
|
523
559
|
value,
|
|
@@ -527,10 +563,18 @@ function FlowEditorInner({
|
|
|
527
563
|
showPanel = true,
|
|
528
564
|
showFeed = true,
|
|
529
565
|
extraToolbar,
|
|
530
|
-
|
|
566
|
+
actions = [],
|
|
567
|
+
builtins = {},
|
|
568
|
+
slots = {},
|
|
569
|
+
canvasProps = {},
|
|
570
|
+
onChange,
|
|
571
|
+
onSelectionChange,
|
|
572
|
+
onDelete,
|
|
573
|
+
apiRef
|
|
531
574
|
}) {
|
|
532
575
|
const internal = useFlowState(initial);
|
|
533
576
|
const runner = useFlowRun();
|
|
577
|
+
const rf = useReactFlow();
|
|
534
578
|
const controlled = value !== void 0;
|
|
535
579
|
const flow = controlled ? makeControlledFlowAdapter(value, onChange) : internal;
|
|
536
580
|
const [, force] = useState(0);
|
|
@@ -542,29 +586,187 @@ function FlowEditorInner({
|
|
|
542
586
|
);
|
|
543
587
|
const [selectedId, setSelectedId] = useState(null);
|
|
544
588
|
const selected = useMemo(() => flow.nodes.find((n) => n.id === selectedId) ?? null, [flow.nodes, selectedId]);
|
|
589
|
+
useEffect(() => onSelectionChange?.(selected), [selected, onSelectionChange]);
|
|
545
590
|
const handleNodeClick = (_e, node) => setSelectedId(node.id);
|
|
546
591
|
useEffect(() => {
|
|
547
592
|
if (!controlled) onChange?.({ nodes: flow.nodes, edges: flow.edges });
|
|
548
593
|
}, [flow.nodes, flow.edges, onChange, controlled]);
|
|
594
|
+
const addNode = useCallback(
|
|
595
|
+
(kindName, position) => {
|
|
596
|
+
const kind = getNodeKind(kindName);
|
|
597
|
+
if (!kind) return null;
|
|
598
|
+
const at = position ?? { x: 80, y: 80 };
|
|
599
|
+
const id = newNodeId();
|
|
600
|
+
flow.setNodes((all) => [
|
|
601
|
+
...all,
|
|
602
|
+
{
|
|
603
|
+
id,
|
|
604
|
+
type: kind.name,
|
|
605
|
+
position: at,
|
|
606
|
+
data: { kind: kind.name, label: kind.label, config: defaultConfigFor(kind) }
|
|
607
|
+
}
|
|
608
|
+
]);
|
|
609
|
+
setSelectedId(id);
|
|
610
|
+
return id;
|
|
611
|
+
},
|
|
612
|
+
[flow]
|
|
613
|
+
);
|
|
614
|
+
const deleteNodes = useCallback(
|
|
615
|
+
(ids) => {
|
|
616
|
+
if (ids.length === 0) return;
|
|
617
|
+
const doomed = new Set(ids);
|
|
618
|
+
flow.setNodes((all) => removeNodes({ nodes: all, edges: [] }, ids).nodes);
|
|
619
|
+
flow.setEdges((all) => removeNodes({ nodes: [], edges: all }, ids).edges);
|
|
620
|
+
setSelectedId((cur) => cur !== null && doomed.has(cur) ? null : cur);
|
|
621
|
+
onDelete?.(ids);
|
|
622
|
+
},
|
|
623
|
+
[flow, onDelete]
|
|
624
|
+
);
|
|
625
|
+
const api = useMemo(() => {
|
|
626
|
+
const toWorkflow = () => exportWorkflow({ nodes: flow.nodes, edges: flow.edges }, metadata);
|
|
627
|
+
return {
|
|
628
|
+
graph: { nodes: flow.nodes, edges: flow.edges },
|
|
629
|
+
nodes: flow.nodes,
|
|
630
|
+
edges: flow.edges,
|
|
631
|
+
selectedId,
|
|
632
|
+
selected,
|
|
633
|
+
running: runner.running,
|
|
634
|
+
statuses: runner.statuses,
|
|
635
|
+
select: setSelectedId,
|
|
636
|
+
addNode,
|
|
637
|
+
updateNode: (next) => flow.setNodes((all) => all.map((x) => x.id === next.id ? next : x)),
|
|
638
|
+
deleteNodes,
|
|
639
|
+
deleteSelected: () => deleteNodes(selectedId ? [selectedId] : []),
|
|
640
|
+
deleteEdges: (ids) => flow.setEdges((all) => removeEdges(all, ids)),
|
|
641
|
+
duplicateNode: (id) => {
|
|
642
|
+
const src = flow.nodes.find((n) => n.id === id);
|
|
643
|
+
if (!src) return null;
|
|
644
|
+
const copy = duplicateNode(src, newNodeId());
|
|
645
|
+
flow.setNodes((all) => [...all, copy]);
|
|
646
|
+
setSelectedId(copy.id);
|
|
647
|
+
return copy.id;
|
|
648
|
+
},
|
|
649
|
+
setGraph: (graph) => {
|
|
650
|
+
flow.setNodes(graph.nodes);
|
|
651
|
+
flow.setEdges(graph.edges);
|
|
652
|
+
},
|
|
653
|
+
run: () => runner.run({ nodes: flow.nodes, edges: flow.edges }, executors),
|
|
654
|
+
cancel: runner.cancel,
|
|
655
|
+
reset: runner.reset,
|
|
656
|
+
toWorkflow,
|
|
657
|
+
exportWorkflow: () => downloadWorkflow(toWorkflow(), metadata),
|
|
658
|
+
importWorkflow: () => pickWorkflow((graph) => {
|
|
659
|
+
flow.setNodes(graph.nodes);
|
|
660
|
+
flow.setEdges(graph.edges);
|
|
661
|
+
}),
|
|
662
|
+
fitView: () => rf.fitView({ padding: 0.2 })
|
|
663
|
+
};
|
|
664
|
+
}, [flow, selectedId, selected, runner, executors, metadata, addNode, deleteNodes, rf]);
|
|
665
|
+
useImperativeHandle(apiRef, () => api, [api]);
|
|
666
|
+
const dropHandlers = paletteDropHandlers((kindName, evt) => {
|
|
667
|
+
const point = rf.screenToFlowPosition({ x: evt.clientX, y: evt.clientY });
|
|
668
|
+
addNode(kindName, { x: point.x - 100, y: point.y - 30 });
|
|
669
|
+
});
|
|
670
|
+
const startActions = actions.filter((a) => a.placement === "start");
|
|
671
|
+
const endActions = actions.filter((a) => a.placement !== "start");
|
|
672
|
+
const toolbar = slots.toolbar ? slots.toolbar(api) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
673
|
+
startActions.map((a) => renderAction(a, api)),
|
|
674
|
+
builtins.run !== false && /* @__PURE__ */ jsx(FlowRunControls, { running: api.running, onRun: api.run, onCancel: api.cancel, onReset: api.reset }),
|
|
675
|
+
(builtins.delete !== false || builtins.export !== false || builtins.import !== false) && /* @__PURE__ */ jsx("span", { className: "ff-editor__sep" }),
|
|
676
|
+
builtins.delete !== false && /* @__PURE__ */ jsx(
|
|
677
|
+
"button",
|
|
678
|
+
{
|
|
679
|
+
className: "ff-editor__btn",
|
|
680
|
+
"data-action": "delete",
|
|
681
|
+
onClick: api.deleteSelected,
|
|
682
|
+
disabled: api.selected === null,
|
|
683
|
+
title: "Delete the selected node (Del / Backspace)",
|
|
684
|
+
children: "\u2715 Delete"
|
|
685
|
+
}
|
|
686
|
+
),
|
|
687
|
+
builtins.export !== false && /* @__PURE__ */ jsx("button", { className: "ff-editor__btn", "data-action": "export", onClick: api.exportWorkflow, children: "\u2193 Export" }),
|
|
688
|
+
builtins.import !== false && /* @__PURE__ */ jsx("button", { className: "ff-editor__btn", "data-action": "import", onClick: api.importWorkflow, children: "\u2191 Import" }),
|
|
689
|
+
endActions.map((a) => renderAction(a, api)),
|
|
690
|
+
extraToolbar,
|
|
691
|
+
builtins.count !== false && /* @__PURE__ */ jsxs("span", { className: "ff-editor__count", children: [
|
|
692
|
+
api.nodes.length,
|
|
693
|
+
" nodes \xB7 ",
|
|
694
|
+
api.edges.length,
|
|
695
|
+
" edges"
|
|
696
|
+
] })
|
|
697
|
+
] });
|
|
698
|
+
return /* @__PURE__ */ jsxs(FlowEditorProvider, { value: api, children: [
|
|
699
|
+
showPalette && (slots.palette ? slots.palette(api) : /* @__PURE__ */ jsx(NodePalette, { className: "ff-editor__palette" })),
|
|
700
|
+
/* @__PURE__ */ jsxs("div", { className: "ff-editor__main", ...dropHandlers, children: [
|
|
701
|
+
/* @__PURE__ */ jsx(
|
|
702
|
+
FlowCanvas,
|
|
703
|
+
{
|
|
704
|
+
nodes: renderedNodes,
|
|
705
|
+
edges: flow.edges,
|
|
706
|
+
nodeTypes,
|
|
707
|
+
onNodesChange: flow.onNodesChange,
|
|
708
|
+
onEdgesChange: flow.onEdgesChange,
|
|
709
|
+
onConnect: flow.onConnect,
|
|
710
|
+
onNodeClick: handleNodeClick,
|
|
711
|
+
onNodesDelete: (deleted) => onDelete?.(deleted.map((n) => n.id)),
|
|
712
|
+
deleteKeyCode: ["Delete", "Backspace"],
|
|
713
|
+
height: "100%",
|
|
714
|
+
toolbar,
|
|
715
|
+
...canvasProps
|
|
716
|
+
}
|
|
717
|
+
),
|
|
718
|
+
slots.empty && api.nodes.length === 0 && /* @__PURE__ */ jsx("div", { className: "ff-editor__empty", children: slots.empty(api) }),
|
|
719
|
+
showFeed && (slots.feed ? slots.feed(api) : /* @__PURE__ */ jsx(FlowRunFeed, { entries: runner.feed, className: "ff-editor__feed" }))
|
|
720
|
+
] }),
|
|
721
|
+
showPanel && (slots.panel ? slots.panel(api) : /* @__PURE__ */ jsxs("div", { className: "ff-editor__panel-wrap", children: [
|
|
722
|
+
/* @__PURE__ */ jsx(NodeConfigPanel, { className: "ff-editor__panel", node: api.selected, onChange: api.updateNode }),
|
|
723
|
+
slots.panelFooter && /* @__PURE__ */ jsx("div", { className: "ff-editor__panel-footer", children: slots.panelFooter(api) })
|
|
724
|
+
] }))
|
|
725
|
+
] });
|
|
726
|
+
}
|
|
727
|
+
function renderAction(action, api) {
|
|
728
|
+
if (action.visible && !action.visible(api)) return null;
|
|
729
|
+
const disabled = action.disabled ? action.disabled(api) : action.requiresSelection === true && api.selected === null;
|
|
549
730
|
return /* @__PURE__ */ jsx(
|
|
550
|
-
|
|
731
|
+
"button",
|
|
551
732
|
{
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
renderedNodes,
|
|
561
|
-
selected,
|
|
562
|
-
setSelectedId,
|
|
563
|
-
handleNodeClick,
|
|
564
|
-
extraToolbar
|
|
565
|
-
}
|
|
733
|
+
className: "ff-editor__btn",
|
|
734
|
+
"data-action": action.id,
|
|
735
|
+
title: action.title,
|
|
736
|
+
disabled,
|
|
737
|
+
onClick: () => action.onSelect(api),
|
|
738
|
+
children: action.label
|
|
739
|
+
},
|
|
740
|
+
action.id
|
|
566
741
|
);
|
|
567
742
|
}
|
|
743
|
+
function newNodeId() {
|
|
744
|
+
return `n_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;
|
|
745
|
+
}
|
|
746
|
+
function downloadWorkflow(schema, metadata) {
|
|
747
|
+
const url = URL.createObjectURL(workflowToBlob(schema));
|
|
748
|
+
const a = document.createElement("a");
|
|
749
|
+
a.href = url;
|
|
750
|
+
a.download = `${metadata?.id ?? "workflow"}.json`;
|
|
751
|
+
a.click();
|
|
752
|
+
URL.revokeObjectURL(url);
|
|
753
|
+
}
|
|
754
|
+
function pickWorkflow(onLoad) {
|
|
755
|
+
const input = document.createElement("input");
|
|
756
|
+
input.type = "file";
|
|
757
|
+
input.accept = "application/json";
|
|
758
|
+
input.onchange = async () => {
|
|
759
|
+
const file = input.files?.[0];
|
|
760
|
+
if (!file) return;
|
|
761
|
+
try {
|
|
762
|
+
const result = importWorkflow(JSON.parse(await file.text()), { lenient: true });
|
|
763
|
+
onLoad(result.graph);
|
|
764
|
+
} catch (e) {
|
|
765
|
+
console.error("import failed", e);
|
|
766
|
+
}
|
|
767
|
+
};
|
|
768
|
+
input.click();
|
|
769
|
+
}
|
|
568
770
|
function makeControlledFlowAdapter(value, onChange) {
|
|
569
771
|
const apply = (next) => onChange?.(next);
|
|
570
772
|
return {
|
|
@@ -590,114 +792,6 @@ function makeControlledFlowAdapter(value, onChange) {
|
|
|
590
792
|
toGraph: () => value
|
|
591
793
|
};
|
|
592
794
|
}
|
|
593
|
-
function FlowEditorBody({
|
|
594
|
-
showPalette,
|
|
595
|
-
showPanel,
|
|
596
|
-
showFeed,
|
|
597
|
-
flow,
|
|
598
|
-
runner,
|
|
599
|
-
executors,
|
|
600
|
-
metadata,
|
|
601
|
-
nodeTypes,
|
|
602
|
-
renderedNodes,
|
|
603
|
-
selected,
|
|
604
|
-
setSelectedId,
|
|
605
|
-
handleNodeClick,
|
|
606
|
-
extraToolbar
|
|
607
|
-
}) {
|
|
608
|
-
const rf = useReactFlow();
|
|
609
|
-
const dropHandlers = paletteDropHandlers((kindName, evt) => {
|
|
610
|
-
const kind = getNodeKind(kindName);
|
|
611
|
-
if (!kind) return;
|
|
612
|
-
const point = rf.screenToFlowPosition({ x: evt.clientX, y: evt.clientY });
|
|
613
|
-
const id = `n_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 7)}`;
|
|
614
|
-
flow.setNodes((all) => [
|
|
615
|
-
...all,
|
|
616
|
-
{
|
|
617
|
-
id,
|
|
618
|
-
type: kind.name,
|
|
619
|
-
position: { x: point.x - 100, y: point.y - 30 },
|
|
620
|
-
data: { kind: kind.name, label: kind.label, config: defaultConfigFor(kind) }
|
|
621
|
-
}
|
|
622
|
-
]);
|
|
623
|
-
setSelectedId(id);
|
|
624
|
-
});
|
|
625
|
-
const doExport = () => {
|
|
626
|
-
const schema = exportWorkflow({ nodes: flow.nodes, edges: flow.edges }, metadata);
|
|
627
|
-
const url = URL.createObjectURL(workflowToBlob(schema));
|
|
628
|
-
const a = document.createElement("a");
|
|
629
|
-
a.href = url;
|
|
630
|
-
a.download = `${metadata?.id ?? "workflow"}.json`;
|
|
631
|
-
a.click();
|
|
632
|
-
URL.revokeObjectURL(url);
|
|
633
|
-
};
|
|
634
|
-
const doImport = () => {
|
|
635
|
-
const input = document.createElement("input");
|
|
636
|
-
input.type = "file";
|
|
637
|
-
input.accept = "application/json";
|
|
638
|
-
input.onchange = async () => {
|
|
639
|
-
const file = input.files?.[0];
|
|
640
|
-
if (!file) return;
|
|
641
|
-
const text = await file.text();
|
|
642
|
-
try {
|
|
643
|
-
const result = importWorkflow(JSON.parse(text), { lenient: true });
|
|
644
|
-
flow.setNodes(result.graph.nodes);
|
|
645
|
-
flow.setEdges(result.graph.edges);
|
|
646
|
-
} catch (e) {
|
|
647
|
-
console.error("import failed", e);
|
|
648
|
-
}
|
|
649
|
-
};
|
|
650
|
-
input.click();
|
|
651
|
-
};
|
|
652
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
653
|
-
showPalette && /* @__PURE__ */ jsx(NodePalette, { className: "ff-editor__palette" }),
|
|
654
|
-
/* @__PURE__ */ jsxs("div", { className: "ff-editor__main", ...dropHandlers, children: [
|
|
655
|
-
/* @__PURE__ */ jsx(
|
|
656
|
-
FlowCanvas,
|
|
657
|
-
{
|
|
658
|
-
nodes: renderedNodes,
|
|
659
|
-
edges: flow.edges,
|
|
660
|
-
nodeTypes,
|
|
661
|
-
onNodesChange: flow.onNodesChange,
|
|
662
|
-
onEdgesChange: flow.onEdgesChange,
|
|
663
|
-
onConnect: flow.onConnect,
|
|
664
|
-
onNodeClick: handleNodeClick,
|
|
665
|
-
height: "100%",
|
|
666
|
-
toolbar: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
667
|
-
/* @__PURE__ */ jsx(
|
|
668
|
-
FlowRunControls,
|
|
669
|
-
{
|
|
670
|
-
running: runner.running,
|
|
671
|
-
onRun: () => runner.run({ nodes: flow.nodes, edges: flow.edges }, executors),
|
|
672
|
-
onCancel: runner.cancel,
|
|
673
|
-
onReset: runner.reset
|
|
674
|
-
}
|
|
675
|
-
),
|
|
676
|
-
/* @__PURE__ */ jsx("span", { className: "ff-editor__sep" }),
|
|
677
|
-
/* @__PURE__ */ jsx("button", { className: "ff-editor__btn", onClick: doExport, children: "\u2193 Export" }),
|
|
678
|
-
/* @__PURE__ */ jsx("button", { className: "ff-editor__btn", onClick: doImport, children: "\u2191 Import" }),
|
|
679
|
-
extraToolbar,
|
|
680
|
-
/* @__PURE__ */ jsxs("span", { className: "ff-editor__count", children: [
|
|
681
|
-
flow.nodes.length,
|
|
682
|
-
" nodes \xB7 ",
|
|
683
|
-
flow.edges.length,
|
|
684
|
-
" edges"
|
|
685
|
-
] })
|
|
686
|
-
] })
|
|
687
|
-
}
|
|
688
|
-
),
|
|
689
|
-
showFeed && /* @__PURE__ */ jsx(FlowRunFeed, { entries: runner.feed, className: "ff-editor__feed" })
|
|
690
|
-
] }),
|
|
691
|
-
showPanel && /* @__PURE__ */ jsx(
|
|
692
|
-
NodeConfigPanel,
|
|
693
|
-
{
|
|
694
|
-
className: "ff-editor__panel",
|
|
695
|
-
node: selected,
|
|
696
|
-
onChange: (next) => flow.setNodes((all) => all.map((x) => x.id === next.id ? next : x))
|
|
697
|
-
}
|
|
698
|
-
)
|
|
699
|
-
] });
|
|
700
|
-
}
|
|
701
795
|
function defineNode(render) {
|
|
702
796
|
function Wrapped(props) {
|
|
703
797
|
return render({
|
|
@@ -732,6 +826,6 @@ function NodePort({ side, type, id, style, title, className }) {
|
|
|
732
826
|
// src/index.ts
|
|
733
827
|
registerBuiltinKinds();
|
|
734
828
|
|
|
735
|
-
export { ActionNode, ConfigFieldRenderer, DecisionNode, FlowCanvas, FlowEditor, FlowRunControls, FlowRunFeed, NodeConfigPanel, NodePalette, NodePort, NodeShell, NoteNode, OutputNode, SubgraphNode, TriggerNode, defaultNodeTypes, defineNode, paletteDropHandlers };
|
|
829
|
+
export { ActionNode, ConfigFieldRenderer, DecisionNode, FlowCanvas, FlowEditor, FlowRunControls, FlowRunFeed, NodeConfigPanel, NodePalette, NodePort, NodeShell, NoteNode, OutputNode, SubgraphNode, TriggerNode, defaultNodeTypes, defineNode, paletteDropHandlers, useFlowEditor, useFlowEditorOptional };
|
|
736
830
|
//# sourceMappingURL=index.js.map
|
|
737
831
|
//# sourceMappingURL=index.js.map
|