@particle-academy/fancy-flow 0.7.0 → 0.9.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.
Files changed (47) hide show
  1. package/README.md +93 -0
  2. package/dist/{chunk-BCXECQUC.js → chunk-6GGFEZH7.js} +3 -3
  3. package/dist/{chunk-BCXECQUC.js.map → chunk-6GGFEZH7.js.map} +1 -1
  4. package/dist/{chunk-M2XKGQQL.js → chunk-6RHAQ2LP.js} +228 -17
  5. package/dist/chunk-6RHAQ2LP.js.map +1 -0
  6. package/dist/{chunk-WNVBXXOL.js → chunk-CPSOC27D.js} +43 -2
  7. package/dist/chunk-CPSOC27D.js.map +1 -0
  8. package/dist/{chunk-NVULCEDX.js → chunk-HNBO4HP3.js} +8 -4
  9. package/dist/chunk-HNBO4HP3.js.map +1 -0
  10. package/dist/chunk-TITD5W4Y.js +26 -0
  11. package/dist/chunk-TITD5W4Y.js.map +1 -0
  12. package/dist/{chunk-QSSQRQN4.js → chunk-VEI743ZX.js} +3 -3
  13. package/dist/{chunk-QSSQRQN4.js.map → chunk-VEI743ZX.js.map} +1 -1
  14. package/dist/engine.cjs +32 -2
  15. package/dist/engine.cjs.map +1 -1
  16. package/dist/engine.js +3 -1
  17. package/dist/index.cjs +717 -40
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +45 -6
  20. package/dist/index.d.ts +45 -6
  21. package/dist/index.js +415 -23
  22. package/dist/index.js.map +1 -1
  23. package/dist/registry/index.d.cts +111 -4
  24. package/dist/registry/index.d.ts +111 -4
  25. package/dist/registry.cjs +313 -31
  26. package/dist/registry.cjs.map +1 -1
  27. package/dist/registry.js +3 -2
  28. package/dist/runtime.cjs +32 -2
  29. package/dist/runtime.cjs.map +1 -1
  30. package/dist/runtime.js +4 -2
  31. package/dist/schema.cjs +41 -0
  32. package/dist/schema.cjs.map +1 -1
  33. package/dist/schema.js +2 -2
  34. package/dist/styles.css +191 -0
  35. package/dist/styles.css.map +1 -1
  36. package/dist/types-BocBFh6l.d.ts +221 -0
  37. package/dist/types-DKqaUjF_.d.cts +221 -0
  38. package/dist/ux.cjs.map +1 -1
  39. package/dist/ux.d.cts +1 -1
  40. package/dist/ux.d.ts +1 -1
  41. package/dist/ux.js +1 -1
  42. package/package.json +4 -4
  43. package/dist/chunk-M2XKGQQL.js.map +0 -1
  44. package/dist/chunk-NVULCEDX.js.map +0 -1
  45. package/dist/chunk-WNVBXXOL.js.map +0 -1
  46. package/dist/types-C0wdN6QX.d.cts +0 -121
  47. package/dist/types-DnMe9Vsf.d.ts +0 -121
package/dist/index.d.cts CHANGED
@@ -5,11 +5,11 @@ import { F as FlowNode, a as FlowGraph, b as NodeRunStatus, E as ExecutorRegistr
5
5
  export { A as ActionNodeData, B as BaseNodeData, D as DecisionNodeData, c as FlowEdge, d as FlowNodeData, e 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-BS3Gwnkq.cjs';
6
6
  import { WorkflowSchema, WorkflowMetadata } from './schema/index.cjs';
7
7
  export { ImportIssue, ImportOptions, ImportResult, WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, WorkflowSchemaEdge, WorkflowSchemaNode, exportWorkflow, importWorkflow, workflowToBlob } from './schema/index.cjs';
8
- import { N as NodeCategory, a as NodeKindDefinition, C as ConfigField } from './types-C0wdN6QX.cjs';
9
- export { R as RenderBodyContext } from './types-C0wdN6QX.cjs';
8
+ import { N as NodeCategory, a as NodeKindDefinition, C as ConfigField } from './types-DKqaUjF_.cjs';
9
+ export { D as DocumentConfigField, K as KeyValueConfigField, P as PortSpec, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField } from './types-DKqaUjF_.cjs';
10
10
  import { FlowRunFeedEntry } from './runtime/index.cjs';
11
11
  export { UseFlowRunOptions, UseFlowRunReturn, UseFlowStateReturn, applyStatusesToNodes, useFlowRun, useFlowState } from './runtime/index.cjs';
12
- export { BUILTIN_KINDS, RegistryNode, buildNodeTypes, categoryAccent, defaultConfigFor, getNodeKind, listNodeKinds, onNodeKindsChanged, registerBuiltinKinds, registerNodeKind, validateConfig } from './registry/index.cjs';
12
+ export { BUILTIN_KINDS, RegistryNode, RichInputAdapter, RichInputPreview, buildNodeTypes, categoryAccent, defaultConfigFor, getNodeKind, getRichInputAdapter, isRichInputEnabled, listNodeKinds, onNodeKindsChanged, onRichInputAdapterChanged, registerBuiltinKinds, registerNodeKind, registerRichInputAdapter, resolveNodePorts, resolvePortSpec, validateConfig } from './registry/index.cjs';
13
13
  export { RunOptions, RunResult, runFlow } from './engine.cjs';
14
14
 
15
15
  type FlowCanvasProps = Omit<ReactFlowProps<FlowNode, Edge>, "nodes" | "edges" | "height"> & {
@@ -56,11 +56,17 @@ type FlowEditorApi = {
56
56
  selectedId: string | null;
57
57
  /** Currently selected node, or null. */
58
58
  selected: FlowNode | null;
59
+ /** Currently selected edge id, or null. Independent of node selection. */
60
+ selectedEdgeId: string | null;
61
+ /** Currently selected edge, or null. */
62
+ selectedEdge: Edge | null;
59
63
  /** True while a run is in flight. */
60
64
  running: boolean;
61
65
  /** Per-node run status, keyed by node id. */
62
66
  statuses: Record<string, NodeRunStatus>;
63
67
  select: (id: string | null) => void;
68
+ /** Select an edge (the connection between two nodes), or clear with null. */
69
+ selectEdge: (id: string | null) => void;
64
70
  /** Add a node of `kind` at an optional flow position. Returns the new id. */
65
71
  addNode: (kind: string, position?: {
66
72
  x: number;
@@ -72,8 +78,12 @@ type FlowEditorApi = {
72
78
  deleteNodes: (ids: string[]) => void;
73
79
  /** Delete the current selection (no-op when nothing is selected). */
74
80
  deleteSelected: () => void;
75
- /** Delete edges by id. */
81
+ /** Delete edges by id — i.e. break the connections between nodes. */
76
82
  deleteEdges: (ids: string[]) => void;
83
+ /** Delete the selected edge (no-op when no edge is selected). */
84
+ deleteSelectedEdge: () => void;
85
+ /** Label a connection, or clear the label by passing undefined/"". */
86
+ setEdgeLabel: (id: string, label: string | undefined) => void;
77
87
  /** Copy a node (offset slightly) and select the copy. Returns the new id. */
78
88
  duplicateNode: (id: string) => string | null;
79
89
  /** Replace the whole graph. */
@@ -115,6 +125,8 @@ type FlowEditorBuiltins = {
115
125
  delete?: boolean;
116
126
  /** Right-click a node for Delete / Duplicate. Default true. */
117
127
  contextMenu?: boolean;
128
+ /** Right-click a connection for Label / Delete. Default true. */
129
+ edgeContextMenu?: boolean;
118
130
  export?: boolean;
119
131
  import?: boolean;
120
132
  count?: boolean;
@@ -136,6 +148,9 @@ type FlowEditorSlots = {
136
148
  /** Replace the node right-click menu. Receives the right-clicked node id;
137
149
  * call `close` when an item is chosen. */
138
150
  contextMenu?: (api: FlowEditorApi, nodeId: string, close: () => void) => ReactNode;
151
+ /** Replace the connection right-click menu. Receives the right-clicked edge
152
+ * id; call `close` when an item is chosen. */
153
+ edgeContextMenu?: (api: FlowEditorApi, edgeId: string, close: () => void) => ReactNode;
139
154
  };
140
155
  /**
141
156
  * Read the editor API from any child of `<FlowEditor>`. Throws outside one, so
@@ -180,6 +195,8 @@ type FlowEditorProps = {
180
195
  onSelectionChange?: (node: FlowNode | null) => void;
181
196
  /** Called after nodes are deleted, with the deleted ids. */
182
197
  onDelete?: (ids: string[]) => void;
198
+ /** Called after connections are broken, with the deleted edge ids. */
199
+ onEdgeDelete?: (ids: string[]) => void;
183
200
  className?: string;
184
201
  style?: CSSProperties;
185
202
  };
@@ -232,6 +249,16 @@ type NodeConfigPanelProps = {
232
249
  value: unknown;
233
250
  onChange: (next: unknown) => void;
234
251
  }) => ReactNode;
252
+ /**
253
+ * Optional document editor hook — host renders the editor for `document`
254
+ * fields. Lets rich authored content live in node config without fancy-flow
255
+ * taking on a document model.
256
+ */
257
+ renderDocumentField?: (props: {
258
+ documentType?: string;
259
+ value: unknown;
260
+ onChange: (next: unknown) => void;
261
+ }) => ReactNode;
235
262
  className?: string;
236
263
  style?: React.CSSProperties;
237
264
  };
@@ -239,7 +266,7 @@ type NodeConfigPanelProps = {
239
266
  * NodeConfigPanel — schema-driven form for the selected node. Defers to
240
267
  * `kind.renderPanel` if the kind opts out of the auto-form.
241
268
  */
242
- declare function NodeConfigPanel({ node, onChange, header, renderCredentialField, className, style, }: NodeConfigPanelProps): react.JSX.Element;
269
+ declare function NodeConfigPanel({ node, onChange, header, renderCredentialField, renderDocumentField, className, style, }: NodeConfigPanelProps): react.JSX.Element;
243
270
 
244
271
  type ConfigFieldRendererProps = {
245
272
  field: ConfigField;
@@ -250,6 +277,18 @@ type ConfigFieldRendererProps = {
250
277
  value: unknown;
251
278
  onChange: (next: unknown) => void;
252
279
  }) => ReactNode;
280
+ /**
281
+ * Editor for `document` fields. fancy-flow stores the document but never
282
+ * interprets it — the host owns the editing surface, exactly as it does for
283
+ * `credential`. This is the seam for rich human-input steps (authored pages,
284
+ * required reading, multi-section forms) without the package depending on
285
+ * any particular document model.
286
+ */
287
+ renderDocumentField?: (props: {
288
+ documentType?: string;
289
+ value: unknown;
290
+ onChange: (next: unknown) => void;
291
+ }) => ReactNode;
253
292
  };
254
293
  /**
255
294
  * ConfigFieldRenderer — dispatches to the right input element per field
@@ -259,7 +298,7 @@ type ConfigFieldRendererProps = {
259
298
  * Hosts that want to use react-fancy form components can supply their
260
299
  * own field renderers via the kind's `renderPanel`.
261
300
  */
262
- declare function ConfigFieldRenderer({ field, value, onChange, renderCredentialField }: ConfigFieldRendererProps): react.JSX.Element | null;
301
+ declare function ConfigFieldRenderer({ field, value, onChange, renderCredentialField, renderDocumentField, }: ConfigFieldRendererProps): react.JSX.Element | null;
263
302
 
264
303
  /** Entry-point node — outputs only, no inputs. */
265
304
  declare function TriggerNodeInner(props: NodeProps<FlowNode>): react.JSX.Element;
package/dist/index.d.ts CHANGED
@@ -5,11 +5,11 @@ import { F as FlowNode, a as FlowGraph, b as NodeRunStatus, E as ExecutorRegistr
5
5
  export { A as ActionNodeData, B as BaseNodeData, D as DecisionNodeData, c as FlowEdge, d as FlowNodeData, e 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-BS3Gwnkq.js';
6
6
  import { WorkflowSchema, WorkflowMetadata } from './schema/index.js';
7
7
  export { ImportIssue, ImportOptions, ImportResult, WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, WorkflowSchemaEdge, WorkflowSchemaNode, exportWorkflow, importWorkflow, workflowToBlob } from './schema/index.js';
8
- import { N as NodeCategory, a as NodeKindDefinition, C as ConfigField } from './types-DnMe9Vsf.js';
9
- export { R as RenderBodyContext } from './types-DnMe9Vsf.js';
8
+ import { N as NodeCategory, a as NodeKindDefinition, C as ConfigField } from './types-BocBFh6l.js';
9
+ export { D as DocumentConfigField, K as KeyValueConfigField, P as PortSpec, R as RenderBodyContext, d as RepeaterConfigField, e as RepeaterRowField } from './types-BocBFh6l.js';
10
10
  import { FlowRunFeedEntry } from './runtime/index.js';
11
11
  export { UseFlowRunOptions, UseFlowRunReturn, UseFlowStateReturn, applyStatusesToNodes, useFlowRun, useFlowState } from './runtime/index.js';
12
- export { BUILTIN_KINDS, RegistryNode, buildNodeTypes, categoryAccent, defaultConfigFor, getNodeKind, listNodeKinds, onNodeKindsChanged, registerBuiltinKinds, registerNodeKind, validateConfig } from './registry/index.js';
12
+ export { BUILTIN_KINDS, RegistryNode, RichInputAdapter, RichInputPreview, buildNodeTypes, categoryAccent, defaultConfigFor, getNodeKind, getRichInputAdapter, isRichInputEnabled, listNodeKinds, onNodeKindsChanged, onRichInputAdapterChanged, registerBuiltinKinds, registerNodeKind, registerRichInputAdapter, resolveNodePorts, resolvePortSpec, validateConfig } from './registry/index.js';
13
13
  export { RunOptions, RunResult, runFlow } from './engine.js';
14
14
 
15
15
  type FlowCanvasProps = Omit<ReactFlowProps<FlowNode, Edge>, "nodes" | "edges" | "height"> & {
@@ -56,11 +56,17 @@ type FlowEditorApi = {
56
56
  selectedId: string | null;
57
57
  /** Currently selected node, or null. */
58
58
  selected: FlowNode | null;
59
+ /** Currently selected edge id, or null. Independent of node selection. */
60
+ selectedEdgeId: string | null;
61
+ /** Currently selected edge, or null. */
62
+ selectedEdge: Edge | null;
59
63
  /** True while a run is in flight. */
60
64
  running: boolean;
61
65
  /** Per-node run status, keyed by node id. */
62
66
  statuses: Record<string, NodeRunStatus>;
63
67
  select: (id: string | null) => void;
68
+ /** Select an edge (the connection between two nodes), or clear with null. */
69
+ selectEdge: (id: string | null) => void;
64
70
  /** Add a node of `kind` at an optional flow position. Returns the new id. */
65
71
  addNode: (kind: string, position?: {
66
72
  x: number;
@@ -72,8 +78,12 @@ type FlowEditorApi = {
72
78
  deleteNodes: (ids: string[]) => void;
73
79
  /** Delete the current selection (no-op when nothing is selected). */
74
80
  deleteSelected: () => void;
75
- /** Delete edges by id. */
81
+ /** Delete edges by id — i.e. break the connections between nodes. */
76
82
  deleteEdges: (ids: string[]) => void;
83
+ /** Delete the selected edge (no-op when no edge is selected). */
84
+ deleteSelectedEdge: () => void;
85
+ /** Label a connection, or clear the label by passing undefined/"". */
86
+ setEdgeLabel: (id: string, label: string | undefined) => void;
77
87
  /** Copy a node (offset slightly) and select the copy. Returns the new id. */
78
88
  duplicateNode: (id: string) => string | null;
79
89
  /** Replace the whole graph. */
@@ -115,6 +125,8 @@ type FlowEditorBuiltins = {
115
125
  delete?: boolean;
116
126
  /** Right-click a node for Delete / Duplicate. Default true. */
117
127
  contextMenu?: boolean;
128
+ /** Right-click a connection for Label / Delete. Default true. */
129
+ edgeContextMenu?: boolean;
118
130
  export?: boolean;
119
131
  import?: boolean;
120
132
  count?: boolean;
@@ -136,6 +148,9 @@ type FlowEditorSlots = {
136
148
  /** Replace the node right-click menu. Receives the right-clicked node id;
137
149
  * call `close` when an item is chosen. */
138
150
  contextMenu?: (api: FlowEditorApi, nodeId: string, close: () => void) => ReactNode;
151
+ /** Replace the connection right-click menu. Receives the right-clicked edge
152
+ * id; call `close` when an item is chosen. */
153
+ edgeContextMenu?: (api: FlowEditorApi, edgeId: string, close: () => void) => ReactNode;
139
154
  };
140
155
  /**
141
156
  * Read the editor API from any child of `<FlowEditor>`. Throws outside one, so
@@ -180,6 +195,8 @@ type FlowEditorProps = {
180
195
  onSelectionChange?: (node: FlowNode | null) => void;
181
196
  /** Called after nodes are deleted, with the deleted ids. */
182
197
  onDelete?: (ids: string[]) => void;
198
+ /** Called after connections are broken, with the deleted edge ids. */
199
+ onEdgeDelete?: (ids: string[]) => void;
183
200
  className?: string;
184
201
  style?: CSSProperties;
185
202
  };
@@ -232,6 +249,16 @@ type NodeConfigPanelProps = {
232
249
  value: unknown;
233
250
  onChange: (next: unknown) => void;
234
251
  }) => ReactNode;
252
+ /**
253
+ * Optional document editor hook — host renders the editor for `document`
254
+ * fields. Lets rich authored content live in node config without fancy-flow
255
+ * taking on a document model.
256
+ */
257
+ renderDocumentField?: (props: {
258
+ documentType?: string;
259
+ value: unknown;
260
+ onChange: (next: unknown) => void;
261
+ }) => ReactNode;
235
262
  className?: string;
236
263
  style?: React.CSSProperties;
237
264
  };
@@ -239,7 +266,7 @@ type NodeConfigPanelProps = {
239
266
  * NodeConfigPanel — schema-driven form for the selected node. Defers to
240
267
  * `kind.renderPanel` if the kind opts out of the auto-form.
241
268
  */
242
- declare function NodeConfigPanel({ node, onChange, header, renderCredentialField, className, style, }: NodeConfigPanelProps): react.JSX.Element;
269
+ declare function NodeConfigPanel({ node, onChange, header, renderCredentialField, renderDocumentField, className, style, }: NodeConfigPanelProps): react.JSX.Element;
243
270
 
244
271
  type ConfigFieldRendererProps = {
245
272
  field: ConfigField;
@@ -250,6 +277,18 @@ type ConfigFieldRendererProps = {
250
277
  value: unknown;
251
278
  onChange: (next: unknown) => void;
252
279
  }) => ReactNode;
280
+ /**
281
+ * Editor for `document` fields. fancy-flow stores the document but never
282
+ * interprets it — the host owns the editing surface, exactly as it does for
283
+ * `credential`. This is the seam for rich human-input steps (authored pages,
284
+ * required reading, multi-section forms) without the package depending on
285
+ * any particular document model.
286
+ */
287
+ renderDocumentField?: (props: {
288
+ documentType?: string;
289
+ value: unknown;
290
+ onChange: (next: unknown) => void;
291
+ }) => ReactNode;
253
292
  };
254
293
  /**
255
294
  * ConfigFieldRenderer — dispatches to the right input element per field
@@ -259,7 +298,7 @@ type ConfigFieldRendererProps = {
259
298
  * Hosts that want to use react-fancy form components can supply their
260
299
  * own field renderers via the kind's `renderPanel`.
261
300
  */
262
- declare function ConfigFieldRenderer({ field, value, onChange, renderCredentialField }: ConfigFieldRendererProps): react.JSX.Element | null;
301
+ declare function ConfigFieldRenderer({ field, value, onChange, renderCredentialField, renderDocumentField, }: ConfigFieldRendererProps): react.JSX.Element | null;
263
302
 
264
303
  /** Entry-point node — outputs only, no inputs. */
265
304
  declare function TriggerNodeInner(props: NodeProps<FlowNode>): react.JSX.Element;