@particle-academy/fancy-flow 0.41.0 → 0.42.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/{ConfigFieldRenderer-4xK9hzvd.d.cts → ConfigFieldRenderer-BHQDZer6.d.ts} +10 -2
- package/dist/{ConfigFieldRenderer-D2TejNY1.d.ts → ConfigFieldRenderer-LotNHeG8.d.cts} +10 -2
- package/dist/{chunk-UX65ML3J.js → chunk-55KQS3LK.js} +25 -2
- package/dist/chunk-55KQS3LK.js.map +1 -0
- package/dist/{chunk-WOO4B7M5.js → chunk-T3VQX3XB.js} +3 -3
- package/dist/{chunk-WOO4B7M5.js.map → chunk-T3VQX3XB.js.map} +1 -1
- package/dist/engine.d.cts +3 -3
- package/dist/engine.d.ts +3 -3
- package/dist/fields/react-fancy.d.cts +3 -3
- package/dist/fields/react-fancy.d.ts +3 -3
- package/dist/index.cjs +272 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +48 -7
- package/dist/index.d.ts +48 -7
- package/dist/index.js +249 -14
- 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/{registry-BNyT66SS.d.cts → registry-C9KMVpn7.d.cts} +1 -1
- package/dist/{registry-CS7kjMto.d.ts → registry-FGCBprcn.d.ts} +1 -1
- package/dist/registry.cjs +23 -0
- package/dist/registry.cjs.map +1 -1
- package/dist/registry.js +1 -1
- package/dist/screens.js +3 -3
- package/dist/styles.css +96 -0
- package/dist/styles.css.map +1 -1
- package/dist/{types-cAdD1Og2.d.cts → types-B78Rm69S.d.cts} +81 -2
- package/dist/{types-Cf75IbxY.d.ts → types-JViq8reb.d.ts} +81 -2
- package/dist/ux.d.cts +1 -1
- package/dist/ux.d.ts +1 -1
- package/package.json +1 -1
- package/dist/chunk-UX65ML3J.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -5,19 +5,19 @@ import { ConnectionValidatorOptions } from './registry/index.cjs';
|
|
|
5
5
|
export { ANY_PORT_TYPE, BUILTIN_KINDS, PortCompatibility, RegistryNode, RichInputAdapter, RichInputPreview, buildNodeTypes, createConnectionValidator, defaultPortCompatibility, getRichInputAdapter, isRichInputEnabled, onRichInputAdapterChanged, registerBuiltinKinds, registerRichInputAdapter, resolveNodePorts, resolvePortSpec } 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
|
-
import { C as ConfigFieldRenderFn } from './ConfigFieldRenderer-
|
|
9
|
-
export { a as ConfigFieldRenderContext, b as ConfigFieldRenderer, c as ConfigFieldRendererProps } from './ConfigFieldRenderer-
|
|
8
|
+
import { C as ConfigFieldRenderFn } from './ConfigFieldRenderer-LotNHeG8.cjs';
|
|
9
|
+
export { a as ConfigFieldRenderContext, b as ConfigFieldRenderer, c as ConfigFieldRendererProps } from './ConfigFieldRenderer-LotNHeG8.cjs';
|
|
10
10
|
import { WorkflowSchema, WorkflowMetadata } from './schema/index.cjs';
|
|
11
11
|
export { ImportIssue, ImportOptions, ImportResult, WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, WorkflowSchemaEdge, WorkflowSchemaNode, exportWorkflow, importWorkflow, migrateSchema, workflowToBlob } from './schema/index.cjs';
|
|
12
12
|
import { AutoLayoutOptions } from './layout/index.cjs';
|
|
13
13
|
export { AutoLayoutDirection } from './layout/index.cjs';
|
|
14
|
-
import { c as NodeCategory, d as NodeKindDefinition } from './types-
|
|
15
|
-
export { a as ConfigField, D as DocumentConfigField, K as KeyValueConfigField, L as LEGACY_PAUSE_PREFIXES, h as PAUSE_PREFIX, P as PauseAwaiting, i as PauseSignal, j as PortSpec, R as RenderBodyContext, t as RepeaterConfigField, u as RepeaterRowField, m as decodePause, n as encodePause, o as isPause, p as pauseForHuman } from './types-
|
|
14
|
+
import { c as NodeCategory, d as NodeKindDefinition } from './types-B78Rm69S.cjs';
|
|
15
|
+
export { A as AvailableVariable, a as ConfigField, D as DocumentConfigField, z as ExpressionForm, B as ExpressionGrammarHelp, K as KeyValueConfigField, L as LEGACY_PAUSE_PREFIXES, O as OutputField, F as OutputShape, h as PAUSE_PREFIX, P as PauseAwaiting, i as PauseSignal, j as PortSpec, R as RenderBodyContext, t as RepeaterConfigField, u as RepeaterRowField, G as availableVariables, H as baseVariables, m as decodePause, I as describeExpressionGrammar, n as encodePause, o as isPause, Q as outputFieldsFor, p as pauseForHuman } from './types-B78Rm69S.cjs';
|
|
16
16
|
export { F as FlowNodeStatus, a as FlowViewer, b as FlowViewerClassNames, c as FlowViewerProps } from './FlowViewer-nLqo7s2E.cjs';
|
|
17
17
|
import { FlowRunFeedEntry } from './runtime/index.cjs';
|
|
18
18
|
export { HistoryController, UseFlowHistoryReturn, UseFlowRunOptions, UseFlowRunReturn, UseFlowStateReturn, applyOutputsToNodes, applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './runtime/index.cjs';
|
|
19
19
|
export { C as CohortGuard, a as CohortOptions, b as CohortPolicy, c as CohortResult, R as RunOptions, d as RunResult, r as runCohort, e as runFlow } from './run-cohort-Bjv2ZU6g.cjs';
|
|
20
|
-
export { N as NodeKindPresentation, c as categoryAccent, b as clearNodeKindOverrides, d as defaultConfigFor, g as getNodeKind, l as listNodeKinds, o as onNodeKindsChanged, e as overrideNodeKind, r as registerNodeKind, v as validateConfig } from './registry-
|
|
20
|
+
export { N as NodeKindPresentation, c as categoryAccent, b as clearNodeKindOverrides, d as defaultConfigFor, g as getNodeKind, l as listNodeKinds, o as onNodeKindsChanged, e as overrideNodeKind, r as registerNodeKind, v as validateConfig } from './registry-C9KMVpn7.cjs';
|
|
21
21
|
import './capabilities-BtJQTbnw.cjs';
|
|
22
22
|
|
|
23
23
|
type FlowCanvasProps = Omit<ReactFlowProps<FlowNode, Edge>, "nodes" | "edges" | "height"> & {
|
|
@@ -98,6 +98,13 @@ type NodeConfigPanelProps = {
|
|
|
98
98
|
*/
|
|
99
99
|
/** Host renderers keyed by field `type`. See {@link ConfigFieldRenderer}. */
|
|
100
100
|
fieldRenderers?: Record<string, ConfigFieldRenderFn>;
|
|
101
|
+
/**
|
|
102
|
+
* The graph the node lives in. Supplying it is what makes the `{{ }}` variable
|
|
103
|
+
* picker context-aware — it reads the UPSTREAM node's declared `outputShape`
|
|
104
|
+
* to list what is actually reachable here (issue #5). Without it the picker
|
|
105
|
+
* still opens, but can only offer the whole input.
|
|
106
|
+
*/
|
|
107
|
+
graph?: FlowGraph;
|
|
101
108
|
renderDocumentField?: (props: {
|
|
102
109
|
documentType?: string;
|
|
103
110
|
value: unknown;
|
|
@@ -110,7 +117,7 @@ type NodeConfigPanelProps = {
|
|
|
110
117
|
* NodeConfigPanel — schema-driven form for the selected node. Defers to
|
|
111
118
|
* `kind.renderPanel` if the kind opts out of the auto-form.
|
|
112
119
|
*/
|
|
113
|
-
declare function NodeConfigPanel({ node, onChange, onDelete, deleteLabel, header, renderCredentialField, renderDocumentField, fieldRenderers, className, style, }: NodeConfigPanelProps): react.JSX.Element;
|
|
120
|
+
declare function NodeConfigPanel({ node, onChange, onDelete, deleteLabel, header, renderCredentialField, renderDocumentField, fieldRenderers, graph, className, style, }: NodeConfigPanelProps): react.JSX.Element;
|
|
114
121
|
|
|
115
122
|
/**
|
|
116
123
|
* Clone a set of nodes AND the edges internal to that set, remapping every id.
|
|
@@ -620,4 +627,38 @@ declare const flowKeys: {
|
|
|
620
627
|
readonly run: (runId: string) => readonly ["flow", "runs", string];
|
|
621
628
|
};
|
|
622
629
|
|
|
623
|
-
|
|
630
|
+
type ExpressionFieldProps = {
|
|
631
|
+
value: string;
|
|
632
|
+
onChange: (next: string) => void;
|
|
633
|
+
placeholder?: string;
|
|
634
|
+
rows?: number;
|
|
635
|
+
/** The panel's field id + agent handle. */
|
|
636
|
+
handle: {
|
|
637
|
+
id?: string;
|
|
638
|
+
"data-ff-field": string;
|
|
639
|
+
};
|
|
640
|
+
/**
|
|
641
|
+
* The graph and the node being edited. Both are needed to answer "what can I
|
|
642
|
+
* write here" — without them the picker can still offer `{{ $json }}` but
|
|
643
|
+
* nothing node-specific, which is the static list issue #5 asked us not to
|
|
644
|
+
* ship.
|
|
645
|
+
*/
|
|
646
|
+
graph?: FlowGraph;
|
|
647
|
+
nodeId?: string;
|
|
648
|
+
};
|
|
649
|
+
/**
|
|
650
|
+
* ExpressionField — a `{{ }}` field that tells the author what it accepts.
|
|
651
|
+
*
|
|
652
|
+
* Issue #5: the panel rendered a bare textarea with a placeholder and nothing
|
|
653
|
+
* else, so writing an expression required already knowing both the grammar and
|
|
654
|
+
* the exact shape of the upstream node's output. Two affordances close that:
|
|
655
|
+
* typing `{{ ` opens a picker of the variables actually reachable at THIS node,
|
|
656
|
+
* and a reference toggle explains the grammar.
|
|
657
|
+
*
|
|
658
|
+
* The picker deliberately lists only what the resolver can reach — see
|
|
659
|
+
* `availableVariables`. A suggestion that resolves to `null` at runtime is
|
|
660
|
+
* worse than no suggestion, because the author has no reason to doubt it.
|
|
661
|
+
*/
|
|
662
|
+
declare function ExpressionField({ value, onChange, placeholder, rows, handle, graph, nodeId, }: ExpressionFieldProps): react.JSX.Element;
|
|
663
|
+
|
|
664
|
+
export { ActionNode, type AlignEdge, AutoLayoutOptions, ConfigFieldRenderFn, ConnectionValidatorOptions, DecisionNode, ExecutorRegistry, ExpressionField, type ExpressionFieldProps, 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, LaneNode, 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, flowKeys, flowLive, paletteDropHandlers, reconnectEdge, useFlowEditor, useFlowEditorOptional };
|
package/dist/index.d.ts
CHANGED
|
@@ -5,19 +5,19 @@ import { ConnectionValidatorOptions } from './registry/index.js';
|
|
|
5
5
|
export { ANY_PORT_TYPE, BUILTIN_KINDS, PortCompatibility, RegistryNode, RichInputAdapter, RichInputPreview, buildNodeTypes, createConnectionValidator, defaultPortCompatibility, getRichInputAdapter, isRichInputEnabled, onRichInputAdapterChanged, registerBuiltinKinds, registerRichInputAdapter, resolveNodePorts, resolvePortSpec } 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
|
-
import { C as ConfigFieldRenderFn } from './ConfigFieldRenderer-
|
|
9
|
-
export { a as ConfigFieldRenderContext, b as ConfigFieldRenderer, c as ConfigFieldRendererProps } from './ConfigFieldRenderer-
|
|
8
|
+
import { C as ConfigFieldRenderFn } from './ConfigFieldRenderer-BHQDZer6.js';
|
|
9
|
+
export { a as ConfigFieldRenderContext, b as ConfigFieldRenderer, c as ConfigFieldRendererProps } from './ConfigFieldRenderer-BHQDZer6.js';
|
|
10
10
|
import { WorkflowSchema, WorkflowMetadata } from './schema/index.js';
|
|
11
11
|
export { ImportIssue, ImportOptions, ImportResult, WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, WorkflowSchemaEdge, WorkflowSchemaNode, exportWorkflow, importWorkflow, migrateSchema, workflowToBlob } from './schema/index.js';
|
|
12
12
|
import { AutoLayoutOptions } from './layout/index.js';
|
|
13
13
|
export { AutoLayoutDirection } from './layout/index.js';
|
|
14
|
-
import { c as NodeCategory, d as NodeKindDefinition } from './types-
|
|
15
|
-
export { a as ConfigField, D as DocumentConfigField, K as KeyValueConfigField, L as LEGACY_PAUSE_PREFIXES, h as PAUSE_PREFIX, P as PauseAwaiting, i as PauseSignal, j as PortSpec, R as RenderBodyContext, t as RepeaterConfigField, u as RepeaterRowField, m as decodePause, n as encodePause, o as isPause, p as pauseForHuman } from './types-
|
|
14
|
+
import { c as NodeCategory, d as NodeKindDefinition } from './types-JViq8reb.js';
|
|
15
|
+
export { A as AvailableVariable, a as ConfigField, D as DocumentConfigField, z as ExpressionForm, B as ExpressionGrammarHelp, K as KeyValueConfigField, L as LEGACY_PAUSE_PREFIXES, O as OutputField, F as OutputShape, h as PAUSE_PREFIX, P as PauseAwaiting, i as PauseSignal, j as PortSpec, R as RenderBodyContext, t as RepeaterConfigField, u as RepeaterRowField, G as availableVariables, H as baseVariables, m as decodePause, I as describeExpressionGrammar, n as encodePause, o as isPause, Q as outputFieldsFor, p as pauseForHuman } from './types-JViq8reb.js';
|
|
16
16
|
export { F as FlowNodeStatus, a as FlowViewer, b as FlowViewerClassNames, c as FlowViewerProps } from './FlowViewer-C4QAVgWv.js';
|
|
17
17
|
import { FlowRunFeedEntry } from './runtime/index.js';
|
|
18
18
|
export { HistoryController, UseFlowHistoryReturn, UseFlowRunOptions, UseFlowRunReturn, UseFlowStateReturn, applyOutputsToNodes, applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './runtime/index.js';
|
|
19
19
|
export { C as CohortGuard, a as CohortOptions, b as CohortPolicy, c as CohortResult, R as RunOptions, d as RunResult, r as runCohort, e as runFlow } from './run-cohort-BnP6ErHi.js';
|
|
20
|
-
export { N as NodeKindPresentation, c as categoryAccent, b as clearNodeKindOverrides, d as defaultConfigFor, g as getNodeKind, l as listNodeKinds, o as onNodeKindsChanged, e as overrideNodeKind, r as registerNodeKind, v as validateConfig } from './registry-
|
|
20
|
+
export { N as NodeKindPresentation, c as categoryAccent, b as clearNodeKindOverrides, d as defaultConfigFor, g as getNodeKind, l as listNodeKinds, o as onNodeKindsChanged, e as overrideNodeKind, r as registerNodeKind, v as validateConfig } from './registry-FGCBprcn.js';
|
|
21
21
|
import './capabilities-CkhKj_U_.js';
|
|
22
22
|
|
|
23
23
|
type FlowCanvasProps = Omit<ReactFlowProps<FlowNode, Edge>, "nodes" | "edges" | "height"> & {
|
|
@@ -98,6 +98,13 @@ type NodeConfigPanelProps = {
|
|
|
98
98
|
*/
|
|
99
99
|
/** Host renderers keyed by field `type`. See {@link ConfigFieldRenderer}. */
|
|
100
100
|
fieldRenderers?: Record<string, ConfigFieldRenderFn>;
|
|
101
|
+
/**
|
|
102
|
+
* The graph the node lives in. Supplying it is what makes the `{{ }}` variable
|
|
103
|
+
* picker context-aware — it reads the UPSTREAM node's declared `outputShape`
|
|
104
|
+
* to list what is actually reachable here (issue #5). Without it the picker
|
|
105
|
+
* still opens, but can only offer the whole input.
|
|
106
|
+
*/
|
|
107
|
+
graph?: FlowGraph;
|
|
101
108
|
renderDocumentField?: (props: {
|
|
102
109
|
documentType?: string;
|
|
103
110
|
value: unknown;
|
|
@@ -110,7 +117,7 @@ type NodeConfigPanelProps = {
|
|
|
110
117
|
* NodeConfigPanel — schema-driven form for the selected node. Defers to
|
|
111
118
|
* `kind.renderPanel` if the kind opts out of the auto-form.
|
|
112
119
|
*/
|
|
113
|
-
declare function NodeConfigPanel({ node, onChange, onDelete, deleteLabel, header, renderCredentialField, renderDocumentField, fieldRenderers, className, style, }: NodeConfigPanelProps): react.JSX.Element;
|
|
120
|
+
declare function NodeConfigPanel({ node, onChange, onDelete, deleteLabel, header, renderCredentialField, renderDocumentField, fieldRenderers, graph, className, style, }: NodeConfigPanelProps): react.JSX.Element;
|
|
114
121
|
|
|
115
122
|
/**
|
|
116
123
|
* Clone a set of nodes AND the edges internal to that set, remapping every id.
|
|
@@ -620,4 +627,38 @@ declare const flowKeys: {
|
|
|
620
627
|
readonly run: (runId: string) => readonly ["flow", "runs", string];
|
|
621
628
|
};
|
|
622
629
|
|
|
623
|
-
|
|
630
|
+
type ExpressionFieldProps = {
|
|
631
|
+
value: string;
|
|
632
|
+
onChange: (next: string) => void;
|
|
633
|
+
placeholder?: string;
|
|
634
|
+
rows?: number;
|
|
635
|
+
/** The panel's field id + agent handle. */
|
|
636
|
+
handle: {
|
|
637
|
+
id?: string;
|
|
638
|
+
"data-ff-field": string;
|
|
639
|
+
};
|
|
640
|
+
/**
|
|
641
|
+
* The graph and the node being edited. Both are needed to answer "what can I
|
|
642
|
+
* write here" — without them the picker can still offer `{{ $json }}` but
|
|
643
|
+
* nothing node-specific, which is the static list issue #5 asked us not to
|
|
644
|
+
* ship.
|
|
645
|
+
*/
|
|
646
|
+
graph?: FlowGraph;
|
|
647
|
+
nodeId?: string;
|
|
648
|
+
};
|
|
649
|
+
/**
|
|
650
|
+
* ExpressionField — a `{{ }}` field that tells the author what it accepts.
|
|
651
|
+
*
|
|
652
|
+
* Issue #5: the panel rendered a bare textarea with a placeholder and nothing
|
|
653
|
+
* else, so writing an expression required already knowing both the grammar and
|
|
654
|
+
* the exact shape of the upstream node's output. Two affordances close that:
|
|
655
|
+
* typing `{{ ` opens a picker of the variables actually reachable at THIS node,
|
|
656
|
+
* and a reference toggle explains the grammar.
|
|
657
|
+
*
|
|
658
|
+
* The picker deliberately lists only what the resolver can reach — see
|
|
659
|
+
* `availableVariables`. A suggestion that resolves to `null` at runtime is
|
|
660
|
+
* worse than no suggestion, because the author has no reason to doubt it.
|
|
661
|
+
*/
|
|
662
|
+
declare function ExpressionField({ value, onChange, placeholder, rows, handle, graph, nodeId, }: ExpressionFieldProps): react.JSX.Element;
|
|
663
|
+
|
|
664
|
+
export { ActionNode, type AlignEdge, AutoLayoutOptions, ConfigFieldRenderFn, ConnectionValidatorOptions, DecisionNode, ExecutorRegistry, ExpressionField, type ExpressionFieldProps, 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, LaneNode, 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, flowKeys, flowLive, paletteDropHandlers, reconnectEdge, useFlowEditor, useFlowEditorOptional };
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { removeNodes, removeEdges, cloneSubgraph, alignNodes, distributeNodes, reconnectEdge, assignToLane, removeFromLane, duplicateNode, setEdgeLabel, FlowCanvas } from './chunk-
|
|
2
|
-
export { ActionNode, DecisionNode, FlowCanvas, FlowViewer, NodeShell, OutputNode, SubgraphNode, TriggerNode, alignNodes, cloneSubgraph, defaultNodeTypes, distributeNodes, reconnectEdge } from './chunk-
|
|
1
|
+
import { removeNodes, removeEdges, cloneSubgraph, alignNodes, distributeNodes, reconnectEdge, assignToLane, removeFromLane, duplicateNode, setEdgeLabel, FlowCanvas } from './chunk-T3VQX3XB.js';
|
|
2
|
+
export { ActionNode, DecisionNode, FlowCanvas, FlowViewer, NodeShell, OutputNode, SubgraphNode, TriggerNode, alignNodes, cloneSubgraph, defaultNodeTypes, distributeNodes, reconnectEdge } from './chunk-T3VQX3XB.js';
|
|
3
3
|
import { useFlowState, useFlowRun, useFlowHistory, applyOutputsToNodes, applyStatusesToNodes } from './chunk-A6RFLGWV.js';
|
|
4
4
|
export { applyOutputsToNodes, applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './chunk-A6RFLGWV.js';
|
|
5
5
|
export { runCohort } from './chunk-QZTGV3ZL.js';
|
|
6
|
-
import { buildNodeTypes, FlowEditorProvider, registerBuiltinKinds } from './chunk-
|
|
7
|
-
export { ANY_PORT_TYPE, BUILTIN_KINDS, LaneNode, NoteNode, RegistryNode, buildNodeTypes, createConnectionValidator, defaultPortCompatibility, registerBuiltinKinds, useFlowEditor, useFlowEditorOptional } from './chunk-
|
|
6
|
+
import { buildNodeTypes, FlowEditorProvider, registerBuiltinKinds } from './chunk-55KQS3LK.js';
|
|
7
|
+
export { ANY_PORT_TYPE, BUILTIN_KINDS, LaneNode, NoteNode, RegistryNode, buildNodeTypes, createConnectionValidator, defaultPortCompatibility, registerBuiltinKinds, useFlowEditor, useFlowEditorOptional } from './chunk-55KQS3LK.js';
|
|
8
8
|
import { ReactFlowProvider, useReactFlow, addEdge, applyEdgeChanges, applyNodeChanges, Position, Handle } from './chunk-OWENS2H5.js';
|
|
9
9
|
export { LEGACY_PAUSE_PREFIXES, PAUSE_PREFIX, decodePause, encodePause, isPause, pauseForHuman } from './chunk-UEOE6B52.js';
|
|
10
10
|
import './chunk-USL4FMFU.js';
|
|
@@ -109,6 +109,230 @@ function paletteDropHandlers(onDrop) {
|
|
|
109
109
|
}
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
|
+
|
|
113
|
+
// src/expressions/variables.ts
|
|
114
|
+
var ROOT = "$json";
|
|
115
|
+
function expr(path) {
|
|
116
|
+
return `{{ ${path} }}`;
|
|
117
|
+
}
|
|
118
|
+
function outputFieldsFor(node) {
|
|
119
|
+
const kindName = node.data?.kind ?? node.type;
|
|
120
|
+
if (!kindName) return [];
|
|
121
|
+
const kind = getNodeKind(kindName);
|
|
122
|
+
const shape = kind?.outputShape;
|
|
123
|
+
if (!shape) return [];
|
|
124
|
+
if (typeof shape === "function") {
|
|
125
|
+
try {
|
|
126
|
+
const config = node.data?.config ?? {};
|
|
127
|
+
return shape(config) ?? [];
|
|
128
|
+
} catch {
|
|
129
|
+
return [];
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return shape;
|
|
133
|
+
}
|
|
134
|
+
function baseVariables() {
|
|
135
|
+
return [
|
|
136
|
+
{ expression: expr(ROOT), path: ROOT, type: "unknown", description: "The whole incoming value." }
|
|
137
|
+
];
|
|
138
|
+
}
|
|
139
|
+
function availableVariables(graph, nodeId) {
|
|
140
|
+
const out = baseVariables();
|
|
141
|
+
const seen = /* @__PURE__ */ new Set([ROOT]);
|
|
142
|
+
const byId = new Map(graph.nodes.map((n) => [n.id, n]));
|
|
143
|
+
const upstreamIds = graph.edges.filter((e) => e.target === nodeId).map((e) => e.source);
|
|
144
|
+
for (const id of upstreamIds) {
|
|
145
|
+
if (id === nodeId) continue;
|
|
146
|
+
const upstream = byId.get(id);
|
|
147
|
+
if (!upstream) continue;
|
|
148
|
+
const kindName = upstream.data?.kind ?? upstream.type;
|
|
149
|
+
const label = upstream.data?.label ?? (kindName ? getNodeKind(kindName)?.label : void 0);
|
|
150
|
+
for (const field of outputFieldsFor(upstream)) {
|
|
151
|
+
const path = `${ROOT}.${field.path}`;
|
|
152
|
+
if (seen.has(path)) continue;
|
|
153
|
+
seen.add(path);
|
|
154
|
+
out.push({
|
|
155
|
+
expression: expr(path),
|
|
156
|
+
path,
|
|
157
|
+
type: field.type,
|
|
158
|
+
description: field.description,
|
|
159
|
+
source: label
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return out;
|
|
164
|
+
}
|
|
165
|
+
function describeExpressionGrammar() {
|
|
166
|
+
return {
|
|
167
|
+
forms: [
|
|
168
|
+
{ syntax: "{{ $json }}", meaning: "The whole value arriving on this node's input." },
|
|
169
|
+
{ syntax: "{{ $json.field }}", meaning: "One key of that value. Dot-paths nest: $json.user.email." },
|
|
170
|
+
{ syntax: "{{ $input.field }}", meaning: "An alias for $json \u2014 the same value, either spelling." },
|
|
171
|
+
{ syntax: "{{ in }}", meaning: "The input by its context key, rather than through the alias." }
|
|
172
|
+
],
|
|
173
|
+
note: "Dot-paths only \u2014 no arithmetic, comparisons or function calls; anything else resolves to nothing. A field that is exactly one expression keeps the resolved value's type; mixed text interpolates as a string. fancy-flow's own runFlow does not interpolate: it hands config to your executor verbatim, and the fancy-flow-php runtime is what resolves these."
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
function findTrigger(text, caret) {
|
|
177
|
+
const before = text.slice(0, caret);
|
|
178
|
+
const open = before.lastIndexOf("{{");
|
|
179
|
+
if (open === -1) return null;
|
|
180
|
+
if (before.indexOf("}}", open) !== -1) return null;
|
|
181
|
+
return { open, query: before.slice(open + 2).trim() };
|
|
182
|
+
}
|
|
183
|
+
function filterVariables(vars, query) {
|
|
184
|
+
const q = query.trim().toLowerCase();
|
|
185
|
+
if (q === "") return vars;
|
|
186
|
+
return vars.filter((v) => v.path.toLowerCase().includes(q));
|
|
187
|
+
}
|
|
188
|
+
function applyCompletion(text, caret, trigger, variable) {
|
|
189
|
+
const head = text.slice(0, trigger.open);
|
|
190
|
+
const tail = text.slice(caret);
|
|
191
|
+
return { value: `${head}${variable.expression}${tail}`, caret: head.length + variable.expression.length };
|
|
192
|
+
}
|
|
193
|
+
function ExpressionField({
|
|
194
|
+
value,
|
|
195
|
+
onChange,
|
|
196
|
+
placeholder,
|
|
197
|
+
rows = 2,
|
|
198
|
+
handle,
|
|
199
|
+
graph,
|
|
200
|
+
nodeId
|
|
201
|
+
}) {
|
|
202
|
+
const ref = useRef(null);
|
|
203
|
+
const [trigger, setTrigger] = useState(null);
|
|
204
|
+
const [active, setActive] = useState(0);
|
|
205
|
+
const [showHelp, setShowHelp] = useState(false);
|
|
206
|
+
const variables = useMemo(
|
|
207
|
+
() => graph && nodeId ? availableVariables(graph, nodeId) : baseVariables(),
|
|
208
|
+
[graph, nodeId]
|
|
209
|
+
);
|
|
210
|
+
const matches = useMemo(
|
|
211
|
+
() => trigger ? filterVariables(variables, trigger.query) : [],
|
|
212
|
+
[trigger, variables]
|
|
213
|
+
);
|
|
214
|
+
const help = useMemo(() => describeExpressionGrammar(), []);
|
|
215
|
+
const open = trigger !== null && matches.length > 0;
|
|
216
|
+
const sync = (el) => {
|
|
217
|
+
const next = findTrigger(el.value, el.selectionStart ?? el.value.length);
|
|
218
|
+
setTrigger(next);
|
|
219
|
+
setActive(0);
|
|
220
|
+
};
|
|
221
|
+
const choose = (variable) => {
|
|
222
|
+
const el = ref.current;
|
|
223
|
+
if (!el || !trigger) return;
|
|
224
|
+
const { value: next, caret } = applyCompletion(
|
|
225
|
+
el.value,
|
|
226
|
+
el.selectionStart ?? el.value.length,
|
|
227
|
+
trigger,
|
|
228
|
+
variable
|
|
229
|
+
);
|
|
230
|
+
onChange(next);
|
|
231
|
+
setTrigger(null);
|
|
232
|
+
requestAnimationFrame(() => {
|
|
233
|
+
el.focus();
|
|
234
|
+
el.setSelectionRange(caret, caret);
|
|
235
|
+
});
|
|
236
|
+
};
|
|
237
|
+
const onKeyDown = (e) => {
|
|
238
|
+
if (!open) return;
|
|
239
|
+
if (e.key === "ArrowDown") {
|
|
240
|
+
e.preventDefault();
|
|
241
|
+
setActive((i) => (i + 1) % matches.length);
|
|
242
|
+
} else if (e.key === "ArrowUp") {
|
|
243
|
+
e.preventDefault();
|
|
244
|
+
setActive((i) => (i - 1 + matches.length) % matches.length);
|
|
245
|
+
} else if (e.key === "Enter" || e.key === "Tab") {
|
|
246
|
+
e.preventDefault();
|
|
247
|
+
choose(matches[active] ?? matches[0]);
|
|
248
|
+
} else if (e.key === "Escape") {
|
|
249
|
+
e.preventDefault();
|
|
250
|
+
setTrigger(null);
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
return /* @__PURE__ */ jsxs("div", { className: "ff-expression", "data-ff-expression": handle["data-ff-field"], children: [
|
|
254
|
+
/* @__PURE__ */ jsx(
|
|
255
|
+
"textarea",
|
|
256
|
+
{
|
|
257
|
+
...handle,
|
|
258
|
+
ref,
|
|
259
|
+
className: "ff-panel__input ff-panel__input--expression",
|
|
260
|
+
rows,
|
|
261
|
+
value: value ?? "",
|
|
262
|
+
placeholder: placeholder ?? "{{ $json.field }}",
|
|
263
|
+
spellCheck: false,
|
|
264
|
+
role: "combobox",
|
|
265
|
+
"aria-expanded": open,
|
|
266
|
+
"aria-autocomplete": "list",
|
|
267
|
+
"aria-controls": open ? `${handle.id ?? handle["data-ff-field"]}-vars` : void 0,
|
|
268
|
+
onChange: (e) => {
|
|
269
|
+
onChange(e.target.value);
|
|
270
|
+
sync(e.target);
|
|
271
|
+
},
|
|
272
|
+
onKeyDown,
|
|
273
|
+
onClick: (e) => sync(e.currentTarget),
|
|
274
|
+
onBlur: () => {
|
|
275
|
+
window.setTimeout(() => setTrigger(null), 120);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
),
|
|
279
|
+
/* @__PURE__ */ jsxs("div", { className: "ff-expression__bar", children: [
|
|
280
|
+
/* @__PURE__ */ jsxs(
|
|
281
|
+
"button",
|
|
282
|
+
{
|
|
283
|
+
type: "button",
|
|
284
|
+
className: "ff-expression__helpbtn",
|
|
285
|
+
"aria-expanded": showHelp,
|
|
286
|
+
onClick: () => setShowHelp((s) => !s),
|
|
287
|
+
children: [
|
|
288
|
+
"{{ }}",
|
|
289
|
+
" reference"
|
|
290
|
+
]
|
|
291
|
+
}
|
|
292
|
+
),
|
|
293
|
+
variables.length > 1 && /* @__PURE__ */ jsxs("span", { className: "ff-expression__hint", children: [
|
|
294
|
+
"type ",
|
|
295
|
+
/* @__PURE__ */ jsx("code", { children: "{{" }),
|
|
296
|
+
" for ",
|
|
297
|
+
variables.length,
|
|
298
|
+
" variables"
|
|
299
|
+
] })
|
|
300
|
+
] }),
|
|
301
|
+
open && /* @__PURE__ */ jsx(
|
|
302
|
+
"ul",
|
|
303
|
+
{
|
|
304
|
+
className: "ff-expression__menu",
|
|
305
|
+
id: `${handle.id ?? handle["data-ff-field"]}-vars`,
|
|
306
|
+
role: "listbox",
|
|
307
|
+
"data-ff-expression-menu": handle["data-ff-field"],
|
|
308
|
+
children: matches.map((v, i) => /* @__PURE__ */ jsx("li", { role: "option", "aria-selected": i === active, children: /* @__PURE__ */ jsxs(
|
|
309
|
+
"button",
|
|
310
|
+
{
|
|
311
|
+
type: "button",
|
|
312
|
+
className: `ff-expression__option${i === active ? " is-active" : ""}`,
|
|
313
|
+
"data-ff-expression-option": v.path,
|
|
314
|
+
onMouseDown: (e) => {
|
|
315
|
+
e.preventDefault();
|
|
316
|
+
choose(v);
|
|
317
|
+
},
|
|
318
|
+
children: [
|
|
319
|
+
/* @__PURE__ */ jsx("code", { className: "ff-expression__path", children: v.path }),
|
|
320
|
+
v.source && /* @__PURE__ */ jsx("span", { className: "ff-expression__source", children: v.source }),
|
|
321
|
+
v.description && /* @__PURE__ */ jsx("span", { className: "ff-expression__desc", children: v.description })
|
|
322
|
+
]
|
|
323
|
+
}
|
|
324
|
+
) }, v.expression))
|
|
325
|
+
}
|
|
326
|
+
),
|
|
327
|
+
showHelp && /* @__PURE__ */ jsxs("div", { className: "ff-expression__help", role: "note", "data-ff-expression-help": true, children: [
|
|
328
|
+
/* @__PURE__ */ jsx("dl", { children: help.forms.map((f) => /* @__PURE__ */ jsxs("div", { children: [
|
|
329
|
+
/* @__PURE__ */ jsx("dt", { children: /* @__PURE__ */ jsx("code", { children: f.syntax }) }),
|
|
330
|
+
/* @__PURE__ */ jsx("dd", { children: f.meaning })
|
|
331
|
+
] }, f.syntax)) }),
|
|
332
|
+
/* @__PURE__ */ jsx("p", { className: "ff-expression__note", children: help.note })
|
|
333
|
+
] })
|
|
334
|
+
] });
|
|
335
|
+
}
|
|
112
336
|
function ConfigFieldRenderer({
|
|
113
337
|
field,
|
|
114
338
|
value,
|
|
@@ -116,7 +340,9 @@ function ConfigFieldRenderer({
|
|
|
116
340
|
id,
|
|
117
341
|
renderCredentialField,
|
|
118
342
|
renderDocumentField,
|
|
119
|
-
fieldRenderers
|
|
343
|
+
fieldRenderers,
|
|
344
|
+
graph,
|
|
345
|
+
nodeId
|
|
120
346
|
}) {
|
|
121
347
|
const handle = { id, "data-ff-field": field.key };
|
|
122
348
|
const custom = fieldRenderers?.[field.type];
|
|
@@ -198,15 +424,14 @@ function ConfigFieldRenderer({
|
|
|
198
424
|
return /* @__PURE__ */ jsx(JsonField, { value, onChange, rows: field.rows, handle });
|
|
199
425
|
case "expression":
|
|
200
426
|
return /* @__PURE__ */ jsx(
|
|
201
|
-
|
|
427
|
+
ExpressionField,
|
|
202
428
|
{
|
|
203
|
-
|
|
204
|
-
className: "ff-panel__input ff-panel__input--expression",
|
|
205
|
-
rows: 2,
|
|
429
|
+
handle,
|
|
206
430
|
value: value ?? "",
|
|
431
|
+
onChange,
|
|
207
432
|
placeholder: field.example ?? "{{ $json.field }}",
|
|
208
|
-
|
|
209
|
-
|
|
433
|
+
graph,
|
|
434
|
+
nodeId
|
|
210
435
|
}
|
|
211
436
|
);
|
|
212
437
|
case "credential":
|
|
@@ -233,7 +458,9 @@ function ConfigFieldRenderer({
|
|
|
233
458
|
onChange,
|
|
234
459
|
renderCredentialField,
|
|
235
460
|
renderDocumentField,
|
|
236
|
-
fieldRenderers
|
|
461
|
+
fieldRenderers,
|
|
462
|
+
graph,
|
|
463
|
+
nodeId
|
|
237
464
|
}
|
|
238
465
|
);
|
|
239
466
|
case "keyvalue":
|
|
@@ -286,6 +513,8 @@ function RepeaterField({
|
|
|
286
513
|
field,
|
|
287
514
|
value,
|
|
288
515
|
onChange,
|
|
516
|
+
graph,
|
|
517
|
+
nodeId,
|
|
289
518
|
renderCredentialField,
|
|
290
519
|
renderDocumentField,
|
|
291
520
|
fieldRenderers
|
|
@@ -366,6 +595,8 @@ function RepeaterField({
|
|
|
366
595
|
/* @__PURE__ */ jsx(
|
|
367
596
|
ConfigFieldRenderer,
|
|
368
597
|
{
|
|
598
|
+
graph,
|
|
599
|
+
nodeId,
|
|
369
600
|
field: sub,
|
|
370
601
|
value: row[sub.key],
|
|
371
602
|
onChange: (cell) => setCell(i, sub.key, cell),
|
|
@@ -547,6 +778,7 @@ function NodeConfigPanel({
|
|
|
547
778
|
renderCredentialField,
|
|
548
779
|
renderDocumentField,
|
|
549
780
|
fieldRenderers,
|
|
781
|
+
graph,
|
|
550
782
|
className,
|
|
551
783
|
style
|
|
552
784
|
}) {
|
|
@@ -652,7 +884,9 @@ function NodeConfigPanel({
|
|
|
652
884
|
onChange: (v) => setConfigValue(field.key, v),
|
|
653
885
|
renderCredentialField,
|
|
654
886
|
renderDocumentField: documentField,
|
|
655
|
-
fieldRenderers
|
|
887
|
+
fieldRenderers,
|
|
888
|
+
graph,
|
|
889
|
+
nodeId: node.id
|
|
656
890
|
}
|
|
657
891
|
)
|
|
658
892
|
] }, field.key))
|
|
@@ -1416,6 +1650,7 @@ function FlowEditorInner({
|
|
|
1416
1650
|
node: api.selected,
|
|
1417
1651
|
onChange: api.updateNode,
|
|
1418
1652
|
fieldRenderers,
|
|
1653
|
+
graph: flow,
|
|
1419
1654
|
onDelete: builtins.delete === false ? void 0 : (n) => api.deleteNodes([n.id])
|
|
1420
1655
|
}
|
|
1421
1656
|
),
|
|
@@ -1591,6 +1826,6 @@ var flowKeys = {
|
|
|
1591
1826
|
// src/index.ts
|
|
1592
1827
|
registerBuiltinKinds();
|
|
1593
1828
|
|
|
1594
|
-
export { ConfigFieldRenderer, FlowEditor, FlowRunControls, FlowRunFeed, NodeConfigPanel, NodePalette, NodePort, defineNode, flowKeys, flowLive, paletteDropHandlers };
|
|
1829
|
+
export { ConfigFieldRenderer, ExpressionField, FlowEditor, FlowRunControls, FlowRunFeed, NodeConfigPanel, NodePalette, NodePort, availableVariables, baseVariables, defineNode, describeExpressionGrammar, flowKeys, flowLive, outputFieldsFor, paletteDropHandlers };
|
|
1595
1830
|
//# sourceMappingURL=index.js.map
|
|
1596
1831
|
//# sourceMappingURL=index.js.map
|