@particle-academy/fancy-flow 0.24.0 → 0.26.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-OHVSEHDC.js → chunk-N5ICD2WZ.js} +3 -3
- package/dist/{chunk-OHVSEHDC.js.map → chunk-N5ICD2WZ.js.map} +1 -1
- package/dist/{chunk-ZS6DVGB3.js → chunk-OFW7GN3Y.js} +4 -4
- package/dist/{chunk-ZS6DVGB3.js.map → chunk-OFW7GN3Y.js.map} +1 -1
- package/dist/{chunk-YXRLIV7A.js → chunk-Q6IPK64P.js} +4 -2
- package/dist/chunk-Q6IPK64P.js.map +1 -0
- package/dist/{chunk-KDHLKBL2.js → chunk-U2VJB7HR.js} +7 -5
- package/dist/chunk-U2VJB7HR.js.map +1 -0
- package/dist/{chunk-QAA4CA22.js → chunk-YOFCVO2W.js} +118 -6
- package/dist/chunk-YOFCVO2W.js.map +1 -0
- package/dist/engine.cjs +4 -2
- package/dist/engine.cjs.map +1 -1
- package/dist/engine.js +3 -3
- package/dist/index.cjs +287 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -8
- package/dist/index.d.ts +3 -8
- package/dist/index.js +180 -33
- 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 +111 -2
- package/dist/registry.cjs.map +1 -1
- package/dist/registry.js +3 -3
- package/dist/runtime.cjs +4 -2
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +3 -3
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.js +2 -2
- package/dist/styles.css +198 -0
- package/dist/styles.css.map +1 -1
- package/dist/{types-DwRpXXNy.d.ts → types-BGtR3k9J.d.ts} +1 -1
- package/dist/{types-BekE5JTG.d.cts → types-B_pxRqfw.d.cts} +1 -1
- package/dist/ux.cjs.map +1 -1
- package/dist/ux.d.cts +1 -1
- package/dist/ux.d.ts +1 -1
- package/dist/ux.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-KDHLKBL2.js.map +0 -1
- package/dist/chunk-QAA4CA22.js.map +0 -1
- package/dist/chunk-YXRLIV7A.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -9,8 +9,8 @@ import { WorkflowSchema, WorkflowMetadata } from './schema/index.cjs';
|
|
|
9
9
|
export { ImportIssue, ImportOptions, ImportResult, WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, WorkflowSchemaEdge, WorkflowSchemaNode, exportWorkflow, importWorkflow, migrateSchema, workflowToBlob } from './schema/index.cjs';
|
|
10
10
|
import { AutoLayoutOptions } from './layout/index.cjs';
|
|
11
11
|
export { AutoLayoutDirection } from './layout/index.cjs';
|
|
12
|
-
import { N as NodeCategory, a as NodeKindDefinition, C as ConfigField } from './types-
|
|
13
|
-
export { D as DocumentConfigField, K as KeyValueConfigField, P as PortSpec, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField } from './types-
|
|
12
|
+
import { N as NodeCategory, a as NodeKindDefinition, C as ConfigField } from './types-B_pxRqfw.cjs';
|
|
13
|
+
export { D as DocumentConfigField, K as KeyValueConfigField, P as PortSpec, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField } from './types-B_pxRqfw.cjs';
|
|
14
14
|
import { FlowRunFeedEntry } from './runtime/index.cjs';
|
|
15
15
|
export { HistoryController, UseFlowHistoryReturn, UseFlowRunOptions, UseFlowRunReturn, UseFlowStateReturn, applyOutputsToNodes, applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './runtime/index.cjs';
|
|
16
16
|
export { R as RunOptions, a as RunResult, r as runFlow } from './run-flow-AXzOR-Wq.cjs';
|
|
@@ -423,12 +423,7 @@ declare const DecisionNode: react.MemoExoticComponent<typeof DecisionNodeInner>;
|
|
|
423
423
|
declare function OutputNodeInner(props: NodeProps<FlowNode>): react.JSX.Element;
|
|
424
424
|
declare const OutputNode: react.MemoExoticComponent<typeof OutputNodeInner>;
|
|
425
425
|
|
|
426
|
-
|
|
427
|
-
* NoteNode — annotation card with no ports. Useful for documenting graphs.
|
|
428
|
-
* Body is plain text; hosts can wire onChange via the editor's onNodesChange
|
|
429
|
-
* if they want it editable.
|
|
430
|
-
*/
|
|
431
|
-
declare function NoteNodeInner({ data, selected }: NodeProps<FlowNode>): react.JSX.Element;
|
|
426
|
+
declare function NoteNodeInner(props: NodeProps<FlowNode>): react.JSX.Element;
|
|
432
427
|
declare const NoteNode: react.MemoExoticComponent<typeof NoteNodeInner>;
|
|
433
428
|
|
|
434
429
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -9,8 +9,8 @@ import { WorkflowSchema, WorkflowMetadata } from './schema/index.js';
|
|
|
9
9
|
export { ImportIssue, ImportOptions, ImportResult, WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, WorkflowSchemaEdge, WorkflowSchemaNode, exportWorkflow, importWorkflow, migrateSchema, workflowToBlob } from './schema/index.js';
|
|
10
10
|
import { AutoLayoutOptions } from './layout/index.js';
|
|
11
11
|
export { AutoLayoutDirection } from './layout/index.js';
|
|
12
|
-
import { N as NodeCategory, a as NodeKindDefinition, C as ConfigField } from './types-
|
|
13
|
-
export { D as DocumentConfigField, K as KeyValueConfigField, P as PortSpec, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField } from './types-
|
|
12
|
+
import { N as NodeCategory, a as NodeKindDefinition, C as ConfigField } from './types-BGtR3k9J.js';
|
|
13
|
+
export { D as DocumentConfigField, K as KeyValueConfigField, P as PortSpec, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField } from './types-BGtR3k9J.js';
|
|
14
14
|
import { FlowRunFeedEntry } from './runtime/index.js';
|
|
15
15
|
export { HistoryController, UseFlowHistoryReturn, UseFlowRunOptions, UseFlowRunReturn, UseFlowStateReturn, applyOutputsToNodes, applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './runtime/index.js';
|
|
16
16
|
export { R as RunOptions, a as RunResult, r as runFlow } from './run-flow-9U-gaYVF.js';
|
|
@@ -423,12 +423,7 @@ declare const DecisionNode: react.MemoExoticComponent<typeof DecisionNodeInner>;
|
|
|
423
423
|
declare function OutputNodeInner(props: NodeProps<FlowNode>): react.JSX.Element;
|
|
424
424
|
declare const OutputNode: react.MemoExoticComponent<typeof OutputNodeInner>;
|
|
425
425
|
|
|
426
|
-
|
|
427
|
-
* NoteNode — annotation card with no ports. Useful for documenting graphs.
|
|
428
|
-
* Body is plain text; hosts can wire onChange via the editor's onNodesChange
|
|
429
|
-
* if they want it editable.
|
|
430
|
-
*/
|
|
431
|
-
declare function NoteNodeInner({ data, selected }: NodeProps<FlowNode>): react.JSX.Element;
|
|
426
|
+
declare function NoteNodeInner(props: NodeProps<FlowNode>): react.JSX.Element;
|
|
432
427
|
declare const NoteNode: react.MemoExoticComponent<typeof NoteNodeInner>;
|
|
433
428
|
|
|
434
429
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { useFlowState, useFlowRun, useFlowHistory, applyOutputsToNodes, applyStatusesToNodes } from './chunk-
|
|
2
|
-
export { applyOutputsToNodes, applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './chunk-
|
|
3
|
-
import { buildNodeTypes, registerBuiltinKinds, createConnectionValidator } from './chunk-
|
|
4
|
-
export { ANY_PORT_TYPE, BUILTIN_KINDS, LaneNode, RegistryNode, buildNodeTypes, createConnectionValidator, defaultPortCompatibility, registerBuiltinKinds } from './chunk-
|
|
1
|
+
import { useFlowState, useFlowRun, useFlowHistory, applyOutputsToNodes, applyStatusesToNodes } from './chunk-OFW7GN3Y.js';
|
|
2
|
+
export { applyOutputsToNodes, applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './chunk-OFW7GN3Y.js';
|
|
3
|
+
import { buildNodeTypes, FlowEditorProvider, registerBuiltinKinds, NoteNode, createConnectionValidator } from './chunk-YOFCVO2W.js';
|
|
4
|
+
export { ANY_PORT_TYPE, BUILTIN_KINDS, LaneNode, NoteNode, RegistryNode, buildNodeTypes, createConnectionValidator, defaultPortCompatibility, registerBuiltinKinds, useFlowEditor, useFlowEditorOptional } from './chunk-YOFCVO2W.js';
|
|
5
5
|
import { ReactFlowProvider, useReactFlow, addEdge, applyEdgeChanges, applyNodeChanges, Position, Handle, reconnectEdge, index, BackgroundVariant, Background, Controls, MiniMap, ViewportPortal } from './chunk-OWENS2H5.js';
|
|
6
6
|
export { LEGACY_PAUSE_PREFIXES, PAUSE_PREFIX, decodePause, encodePause, isPause, pauseForHuman } from './chunk-UEOE6B52.js';
|
|
7
7
|
import './chunk-USL4FMFU.js';
|
|
8
|
-
export { runFlow } from './chunk-
|
|
9
|
-
import { workflowToBlob, importWorkflow, exportWorkflow } from './chunk-
|
|
10
|
-
export { WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, exportWorkflow, importWorkflow, migrateSchema, workflowToBlob } from './chunk-
|
|
8
|
+
export { runFlow } from './chunk-U2VJB7HR.js';
|
|
9
|
+
import { workflowToBlob, importWorkflow, exportWorkflow } from './chunk-N5ICD2WZ.js';
|
|
10
|
+
export { WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, exportWorkflow, importWorkflow, migrateSchema, workflowToBlob } from './chunk-N5ICD2WZ.js';
|
|
11
11
|
export { resolveNodePorts, resolvePortSpec } from './chunk-TITD5W4Y.js';
|
|
12
|
-
import { onNodeKindsChanged, listNodeKinds, getNodeKind, defaultConfigFor, validateConfig, categoryAccent } from './chunk-
|
|
13
|
-
export { categoryAccent, defaultConfigFor, getNodeKind, listNodeKinds, onNodeKindsChanged, registerNodeKind, validateConfig } from './chunk-
|
|
12
|
+
import { onNodeKindsChanged, listNodeKinds, getNodeKind, defaultConfigFor, validateConfig, categoryAccent } from './chunk-Q6IPK64P.js';
|
|
13
|
+
export { categoryAccent, defaultConfigFor, getNodeKind, listNodeKinds, onNodeKindsChanged, registerNodeKind, validateConfig } from './chunk-Q6IPK64P.js';
|
|
14
14
|
import { getRichInputAdapter } from './chunk-F5RPRB7A.js';
|
|
15
15
|
export { RichInputPreview, getRichInputAdapter, isRichInputEnabled, onRichInputAdapterChanged, registerRichInputAdapter } from './chunk-F5RPRB7A.js';
|
|
16
|
-
import { memo,
|
|
16
|
+
import { memo, forwardRef, useState, useMemo, useEffect, useCallback, useRef, useImperativeHandle } from 'react';
|
|
17
17
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
18
18
|
|
|
19
19
|
function NodeShellInner({
|
|
@@ -108,14 +108,6 @@ function OutputNodeInner(props) {
|
|
|
108
108
|
return /* @__PURE__ */ jsx(NodeShell, { node: props, accent: "#a855f7", tag: "OUTPUT", icon: "\u25CF", showOutputs: false });
|
|
109
109
|
}
|
|
110
110
|
var OutputNode = memo(OutputNodeInner);
|
|
111
|
-
function NoteNodeInner({ data, selected }) {
|
|
112
|
-
const noteData = data;
|
|
113
|
-
return /* @__PURE__ */ jsxs("div", { className: `ff-note ${selected ? "ff-note--selected" : ""}`, children: [
|
|
114
|
-
noteData.label && /* @__PURE__ */ jsx("div", { className: "ff-note__title", children: noteData.label }),
|
|
115
|
-
noteData.body && /* @__PURE__ */ jsx("p", { className: "ff-note__body", children: noteData.body })
|
|
116
|
-
] });
|
|
117
|
-
}
|
|
118
|
-
var NoteNode = memo(NoteNodeInner);
|
|
119
111
|
function SubgraphNodeInner(props) {
|
|
120
112
|
const data = props.data;
|
|
121
113
|
const childCount = data.childIds?.length ?? 0;
|
|
@@ -468,7 +460,7 @@ function FlowCanvas({
|
|
|
468
460
|
}
|
|
469
461
|
);
|
|
470
462
|
}
|
|
471
|
-
var CATEGORY_ORDER = ["trigger", "logic", "data", "ai", "io", "human", "output", "layout", "custom"];
|
|
463
|
+
var CATEGORY_ORDER = ["trigger", "logic", "data", "ai", "io", "human", "output", "layout", "annotation", "custom"];
|
|
472
464
|
var CATEGORY_LABELS = {
|
|
473
465
|
trigger: "Triggers",
|
|
474
466
|
logic: "Logic",
|
|
@@ -478,6 +470,7 @@ var CATEGORY_LABELS = {
|
|
|
478
470
|
human: "Human",
|
|
479
471
|
output: "Output",
|
|
480
472
|
layout: "Layout",
|
|
473
|
+
annotation: "Notes",
|
|
481
474
|
custom: "Custom"
|
|
482
475
|
};
|
|
483
476
|
function NodePalette({ categories, onPick, className, style }) {
|
|
@@ -1069,17 +1062,132 @@ function formatTime(at) {
|
|
|
1069
1062
|
const d = new Date(at);
|
|
1070
1063
|
return `${d.getMinutes().toString().padStart(2, "0")}:${d.getSeconds().toString().padStart(2, "0")}.${Math.floor(d.getMilliseconds() / 100)}`;
|
|
1071
1064
|
}
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1065
|
+
function humanInputFields(config) {
|
|
1066
|
+
const raw = Array.isArray(config?.fields) ? config.fields : [];
|
|
1067
|
+
const fields = raw.filter((f) => f && typeof f === "object" && typeof f.key === "string" && f.key).map((f) => ({
|
|
1068
|
+
key: f.key,
|
|
1069
|
+
label: typeof f.label === "string" && f.label ? f.label : f.key,
|
|
1070
|
+
type: ["text", "textarea", "number", "select", "switch"].includes(f.type) ? f.type : "text",
|
|
1071
|
+
required: !!f.required,
|
|
1072
|
+
placeholder: typeof f.placeholder === "string" ? f.placeholder : void 0,
|
|
1073
|
+
options: Array.isArray(f.options) ? f.options : void 0,
|
|
1074
|
+
default: f.default
|
|
1075
|
+
}));
|
|
1076
|
+
if (fields.length) return fields;
|
|
1077
|
+
const title = typeof config?.title === "string" && config.title ? config.title : "Your answer";
|
|
1078
|
+
return [{ key: "value", label: title, type: "textarea", required: true }];
|
|
1079
|
+
}
|
|
1080
|
+
function initialValues(fields) {
|
|
1081
|
+
const v = {};
|
|
1082
|
+
for (const f of fields) v[f.key] = f.type === "switch" ? !!f.default : f.default ?? "";
|
|
1083
|
+
return v;
|
|
1084
|
+
}
|
|
1085
|
+
function HumanPrompt({ request, onCancel }) {
|
|
1086
|
+
const firstRef = useRef(null);
|
|
1087
|
+
useEffect(() => {
|
|
1088
|
+
firstRef.current?.focus();
|
|
1089
|
+
const onKey = (e) => {
|
|
1090
|
+
if (e.key === "Escape") onCancel();
|
|
1091
|
+
};
|
|
1092
|
+
window.addEventListener("keydown", onKey);
|
|
1093
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
1094
|
+
}, [onCancel]);
|
|
1095
|
+
return /* @__PURE__ */ jsx("div", { className: "ff-prompt-overlay", role: "dialog", "aria-modal": "true", "aria-label": request.title, children: /* @__PURE__ */ jsxs("div", { className: "ff-prompt", onClick: (e) => e.stopPropagation(), children: [
|
|
1096
|
+
/* @__PURE__ */ jsx("div", { className: "ff-prompt__title", children: request.title }),
|
|
1097
|
+
request.kind === "approval" ? /* @__PURE__ */ jsx(ApprovalBody, { request, onCancel }) : /* @__PURE__ */ jsx(InputBody, { request, onCancel, firstRef })
|
|
1098
|
+
] }) });
|
|
1099
|
+
}
|
|
1100
|
+
function ApprovalBody({ request, onCancel }) {
|
|
1101
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1102
|
+
request.description && /* @__PURE__ */ jsx("p", { className: "ff-prompt__desc", children: request.description }),
|
|
1103
|
+
/* @__PURE__ */ jsxs("div", { className: "ff-prompt__actions", children: [
|
|
1104
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "ff-prompt__btn ff-prompt__btn--ghost", onClick: onCancel, children: "Cancel" }),
|
|
1105
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "ff-prompt__btn ff-prompt__btn--danger", onClick: () => request.resolve(false), children: "Deny" }),
|
|
1106
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "ff-prompt__btn ff-prompt__btn--primary", onClick: () => request.resolve(true), children: "Approve" })
|
|
1107
|
+
] })
|
|
1108
|
+
] });
|
|
1109
|
+
}
|
|
1110
|
+
function InputBody({
|
|
1111
|
+
request,
|
|
1112
|
+
onCancel,
|
|
1113
|
+
firstRef
|
|
1114
|
+
}) {
|
|
1115
|
+
const [values, setValues] = useState(() => initialValues(request.fields));
|
|
1116
|
+
const set = (k, v) => setValues((prev) => ({ ...prev, [k]: v }));
|
|
1117
|
+
const missing = request.fields.filter((f) => f.required && (values[f.key] === void 0 || values[f.key] === ""));
|
|
1118
|
+
const submit = () => {
|
|
1119
|
+
if (missing.length === 0) request.resolve(values);
|
|
1120
|
+
};
|
|
1121
|
+
return /* @__PURE__ */ jsxs(
|
|
1122
|
+
"form",
|
|
1123
|
+
{
|
|
1124
|
+
onSubmit: (e) => {
|
|
1125
|
+
e.preventDefault();
|
|
1126
|
+
submit();
|
|
1127
|
+
},
|
|
1128
|
+
onKeyDown: (e) => {
|
|
1129
|
+
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
|
|
1130
|
+
e.preventDefault();
|
|
1131
|
+
submit();
|
|
1132
|
+
}
|
|
1133
|
+
},
|
|
1134
|
+
children: [
|
|
1135
|
+
/* @__PURE__ */ jsx("div", { className: "ff-prompt__fields", children: request.fields.map((f, i) => /* @__PURE__ */ jsxs("label", { className: "ff-prompt__field", children: [
|
|
1136
|
+
/* @__PURE__ */ jsxs("span", { className: "ff-prompt__label", children: [
|
|
1137
|
+
f.label ?? f.key,
|
|
1138
|
+
f.required && /* @__PURE__ */ jsx("span", { className: "ff-prompt__req", children: " *" })
|
|
1139
|
+
] }),
|
|
1140
|
+
renderControl(f, values[f.key], (v) => set(f.key, v), i === 0 ? firstRef : void 0)
|
|
1141
|
+
] }, f.key)) }),
|
|
1142
|
+
/* @__PURE__ */ jsxs("div", { className: "ff-prompt__actions", children: [
|
|
1143
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "ff-prompt__btn ff-prompt__btn--ghost", onClick: onCancel, children: "Cancel" }),
|
|
1144
|
+
/* @__PURE__ */ jsx("button", { type: "submit", className: "ff-prompt__btn ff-prompt__btn--primary", disabled: missing.length > 0, children: request.submitLabel || "Continue" })
|
|
1145
|
+
] })
|
|
1146
|
+
]
|
|
1147
|
+
}
|
|
1148
|
+
);
|
|
1080
1149
|
}
|
|
1081
|
-
function
|
|
1082
|
-
|
|
1150
|
+
function renderControl(f, value, onChange, ref) {
|
|
1151
|
+
const common = { className: "ff-prompt__input", placeholder: f.placeholder };
|
|
1152
|
+
if (f.type === "textarea") {
|
|
1153
|
+
return /* @__PURE__ */ jsx(
|
|
1154
|
+
"textarea",
|
|
1155
|
+
{
|
|
1156
|
+
...common,
|
|
1157
|
+
ref,
|
|
1158
|
+
rows: 3,
|
|
1159
|
+
value: String(value ?? ""),
|
|
1160
|
+
onChange: (e) => onChange(e.target.value)
|
|
1161
|
+
}
|
|
1162
|
+
);
|
|
1163
|
+
}
|
|
1164
|
+
if (f.type === "switch") {
|
|
1165
|
+
return /* @__PURE__ */ jsx(
|
|
1166
|
+
"input",
|
|
1167
|
+
{
|
|
1168
|
+
type: "checkbox",
|
|
1169
|
+
className: "ff-prompt__switch",
|
|
1170
|
+
checked: !!value,
|
|
1171
|
+
onChange: (e) => onChange(e.target.checked)
|
|
1172
|
+
}
|
|
1173
|
+
);
|
|
1174
|
+
}
|
|
1175
|
+
if (f.type === "select" && f.options && f.options.length) {
|
|
1176
|
+
return /* @__PURE__ */ jsxs("select", { className: "ff-prompt__input", value: String(value ?? ""), onChange: (e) => onChange(e.target.value), children: [
|
|
1177
|
+
/* @__PURE__ */ jsx("option", { value: "", disabled: true, children: "Choose\u2026" }),
|
|
1178
|
+
f.options.map((o) => /* @__PURE__ */ jsx("option", { value: o.value, children: o.label }, o.value))
|
|
1179
|
+
] });
|
|
1180
|
+
}
|
|
1181
|
+
return /* @__PURE__ */ jsx(
|
|
1182
|
+
"input",
|
|
1183
|
+
{
|
|
1184
|
+
...common,
|
|
1185
|
+
ref,
|
|
1186
|
+
type: f.type === "number" ? "number" : "text",
|
|
1187
|
+
value: String(value ?? ""),
|
|
1188
|
+
onChange: (e) => onChange(f.type === "number" ? e.target.value === "" ? "" : Number(e.target.value) : e.target.value)
|
|
1189
|
+
}
|
|
1190
|
+
);
|
|
1083
1191
|
}
|
|
1084
1192
|
var FlowEditor = forwardRef(function FlowEditor2(props, ref) {
|
|
1085
1193
|
return /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsx(
|
|
@@ -1114,6 +1222,41 @@ function FlowEditorInner({
|
|
|
1114
1222
|
const internal = useFlowState(initial);
|
|
1115
1223
|
const runner = useFlowRun();
|
|
1116
1224
|
const rf = useReactFlow();
|
|
1225
|
+
const [prompt, setPrompt] = useState(null);
|
|
1226
|
+
const humanExecutors = useMemo(
|
|
1227
|
+
() => ({
|
|
1228
|
+
user_input: ({ node }) => new Promise((resolve) => {
|
|
1229
|
+
const cfg = node.data?.config ?? {};
|
|
1230
|
+
setPrompt({
|
|
1231
|
+
kind: "input",
|
|
1232
|
+
title: typeof cfg.title === "string" && cfg.title || "Your input",
|
|
1233
|
+
submitLabel: typeof cfg.submitLabel === "string" ? cfg.submitLabel : void 0,
|
|
1234
|
+
fields: humanInputFields(cfg),
|
|
1235
|
+
resolve: (values) => {
|
|
1236
|
+
setPrompt(null);
|
|
1237
|
+
resolve(values);
|
|
1238
|
+
}
|
|
1239
|
+
});
|
|
1240
|
+
}),
|
|
1241
|
+
human_approval: ({ node }) => new Promise((resolve) => {
|
|
1242
|
+
const cfg = node.data?.config ?? {};
|
|
1243
|
+
setPrompt({
|
|
1244
|
+
kind: "approval",
|
|
1245
|
+
title: typeof cfg.title === "string" && cfg.title || "Approve action",
|
|
1246
|
+
description: typeof cfg.description === "string" ? cfg.description : void 0,
|
|
1247
|
+
resolve: (approved) => {
|
|
1248
|
+
setPrompt(null);
|
|
1249
|
+
resolve({ branch: approved ? "approved" : "denied" });
|
|
1250
|
+
}
|
|
1251
|
+
});
|
|
1252
|
+
})
|
|
1253
|
+
}),
|
|
1254
|
+
[]
|
|
1255
|
+
);
|
|
1256
|
+
const runExecutors = useMemo(() => ({ ...humanExecutors, ...executors }), [humanExecutors, executors]);
|
|
1257
|
+
useEffect(() => {
|
|
1258
|
+
if (!runner.running) setPrompt(null);
|
|
1259
|
+
}, [runner.running]);
|
|
1117
1260
|
const controlled = value !== void 0;
|
|
1118
1261
|
const baseFlow = controlled ? makeControlledFlowAdapter(value, onChange) : internal;
|
|
1119
1262
|
const hist = useFlowHistory(baseFlow);
|
|
@@ -1423,7 +1566,7 @@ function FlowEditorInner({
|
|
|
1423
1566
|
({ autoLayout }) => flow.setGraph({ nodes: autoLayout({ nodes: flow.nodes, edges: flow.edges }, { scope: laneId }), edges: flow.edges })
|
|
1424
1567
|
);
|
|
1425
1568
|
},
|
|
1426
|
-
run: () => runner.run({ nodes: flow.nodes, edges: flow.edges },
|
|
1569
|
+
run: () => runner.run({ nodes: flow.nodes, edges: flow.edges }, runExecutors),
|
|
1427
1570
|
cancel: runner.cancel,
|
|
1428
1571
|
reset: runner.reset,
|
|
1429
1572
|
toWorkflow,
|
|
@@ -1435,7 +1578,7 @@ function FlowEditorInner({
|
|
|
1435
1578
|
canUndo: hist.canUndo,
|
|
1436
1579
|
canRedo: hist.canRedo
|
|
1437
1580
|
};
|
|
1438
|
-
}, [flow, selectedId, selected, selectedEdgeId, selectedEdge, selectedIds, selectedNodes, runner,
|
|
1581
|
+
}, [flow, selectedId, selected, selectedEdgeId, selectedEdge, selectedIds, selectedNodes, runner, runExecutors, metadata, addNode, deleteNodes, deleteEdges, duplicateSelected, alignSelected, distributeSelected, copySelection, pasteClipboard, addLane, hist, rf]);
|
|
1439
1582
|
useImperativeHandle(apiRef, () => api, [api]);
|
|
1440
1583
|
const dropHandlers = paletteDropHandlers((kindName, evt) => {
|
|
1441
1584
|
const point = rf.screenToFlowPosition({ x: evt.clientX, y: evt.clientY });
|
|
@@ -1609,7 +1752,11 @@ function FlowEditorInner({
|
|
|
1609
1752
|
onCancel: () => setLabelEdit(null)
|
|
1610
1753
|
}
|
|
1611
1754
|
),
|
|
1612
|
-
showFeed && (slots.feed ? slots.feed(api) : /* @__PURE__ */ jsx(FlowRunFeed, { entries: runner.feed, className: "ff-editor__feed" }))
|
|
1755
|
+
showFeed && (slots.feed ? slots.feed(api) : /* @__PURE__ */ jsx(FlowRunFeed, { entries: runner.feed, className: "ff-editor__feed" })),
|
|
1756
|
+
prompt && /* @__PURE__ */ jsx(HumanPrompt, { request: prompt, onCancel: () => {
|
|
1757
|
+
setPrompt(null);
|
|
1758
|
+
runner.cancel();
|
|
1759
|
+
} })
|
|
1613
1760
|
] }),
|
|
1614
1761
|
showPanel && (slots.panel ? slots.panel(api) : /* @__PURE__ */ jsxs("div", { className: "ff-editor__panel-wrap", children: [
|
|
1615
1762
|
/* @__PURE__ */ jsx(
|
|
@@ -1769,6 +1916,6 @@ function NodePort({ side, type, id, style, title, className }) {
|
|
|
1769
1916
|
// src/index.ts
|
|
1770
1917
|
registerBuiltinKinds();
|
|
1771
1918
|
|
|
1772
|
-
export { ActionNode, ConfigFieldRenderer, DecisionNode, FlowCanvas, FlowEditor, FlowRunControls, FlowRunFeed, NodeConfigPanel, NodePalette, NodePort, NodeShell,
|
|
1919
|
+
export { ActionNode, ConfigFieldRenderer, DecisionNode, FlowCanvas, FlowEditor, FlowRunControls, FlowRunFeed, NodeConfigPanel, NodePalette, NodePort, NodeShell, OutputNode, SubgraphNode, TriggerNode, alignNodes, cloneSubgraph, defaultNodeTypes, defineNode, distributeNodes, paletteDropHandlers, reconnectEdge2 as reconnectEdge };
|
|
1773
1920
|
//# sourceMappingURL=index.js.map
|
|
1774
1921
|
//# sourceMappingURL=index.js.map
|