@particle-academy/fancy-flow 0.41.0 → 0.43.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 +351 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +126 -7
- package/dist/index.d.ts +126 -7
- package/dist/index.js +318 -22
- 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 +2 -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,116 @@ 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
|
+
/**
|
|
665
|
+
* `{{ }}` resolution — the TypeScript twin of `FancyFlow\Nodes\Support\Expr`.
|
|
666
|
+
*
|
|
667
|
+
* ## Why this is opt-in and not wired into `runFlow`
|
|
668
|
+
*
|
|
669
|
+
* The PHP runtime resolves expressions inside its batteries-included executors.
|
|
670
|
+
* The JS runtime never has: `runFlow` hands `node.data.config` to your executor
|
|
671
|
+
* verbatim, so every host that uses `{{ }}` today already resolves it itself.
|
|
672
|
+
* Turning resolution on inside `runFlow` would interpolate a second time over
|
|
673
|
+
* values those hosts had already substituted — silently, and only for graphs
|
|
674
|
+
* that happen to contain `{{` in their DATA.
|
|
675
|
+
*
|
|
676
|
+
* So this exports the semantics and changes no behaviour. Call it yourself:
|
|
677
|
+
*
|
|
678
|
+
* ```ts
|
|
679
|
+
* const url = evaluateExpression(node.data.config.url, inputs);
|
|
680
|
+
* ```
|
|
681
|
+
*
|
|
682
|
+
* ## The semantics are the PHP file's, deliberately
|
|
683
|
+
*
|
|
684
|
+
* This is not a general expression language and must not grow into one. It
|
|
685
|
+
* resolves a dot-path against a context and nothing else — no arithmetic, no
|
|
686
|
+
* comparisons, no calls. Hosts that want real expressions override the executor
|
|
687
|
+
* (the PHP docblock points at symfony/expression-language for the same reason).
|
|
688
|
+
*
|
|
689
|
+
* Divergence here is a correctness bug rather than a style difference: the same
|
|
690
|
+
* graph is authored once and may run on either runtime. `suites/shared/expr`
|
|
691
|
+
* in `@particle-academy/fancy-conformance` is the fixture table both sides run,
|
|
692
|
+
* so parity is a test result instead of a claim.
|
|
693
|
+
*/
|
|
694
|
+
/** Anything a context or a resolved value can be. */
|
|
695
|
+
type ExprValue = unknown;
|
|
696
|
+
/** The context an expression resolves against — the executor's `inputs`. */
|
|
697
|
+
type ExprContext = Record<string, ExprValue>;
|
|
698
|
+
/**
|
|
699
|
+
* Resolve a dot-path against the context, honouring the `$json` / `$input`
|
|
700
|
+
* alias.
|
|
701
|
+
*
|
|
702
|
+
* Both aliases point at the `in` port value when the context has one, and at
|
|
703
|
+
* the whole context otherwise — the same fallback the PHP does, which is what
|
|
704
|
+
* makes `{{ $json.x }}` work on a trigger node that has no upstream input.
|
|
705
|
+
*
|
|
706
|
+
* A path that does not resolve returns `null`, never `undefined`: PHP has one
|
|
707
|
+
* absent value and JS has two, and letting the difference leak would make the
|
|
708
|
+
* two runtimes disagree about `{{ missing }}` for no useful reason.
|
|
709
|
+
*/
|
|
710
|
+
declare function resolvePath(path: string, context: ExprContext): ExprValue;
|
|
711
|
+
/**
|
|
712
|
+
* Evaluate a template against a context.
|
|
713
|
+
*
|
|
714
|
+
* A string that is EXACTLY one expression returns the resolved value with its
|
|
715
|
+
* type intact — `{{ $json.count }}` gives you a number, not `"3"`. Anything
|
|
716
|
+
* else interpolates each run as text. That distinction is load-bearing: it is
|
|
717
|
+
* what lets a config field carry either a value or a sentence.
|
|
718
|
+
*
|
|
719
|
+
* Non-string templates pass through untouched, so this is safe to map over a
|
|
720
|
+
* whole config object.
|
|
721
|
+
*/
|
|
722
|
+
declare function evaluateExpression(template: ExprValue, context: ExprContext): ExprValue;
|
|
723
|
+
/**
|
|
724
|
+
* Truthiness for branch / switch decisions.
|
|
725
|
+
*
|
|
726
|
+
* Mirrors PHP's rules rather than JavaScript's, because the graph is authored
|
|
727
|
+
* once and may run on either side. The two disagree in exactly the places a
|
|
728
|
+
* workflow hits: `"0"` and `"false"` are truthy in JS and falsy here, and an
|
|
729
|
+
* empty array is truthy in JS and falsy here.
|
|
730
|
+
*/
|
|
731
|
+
declare function truthy(value: ExprValue): boolean;
|
|
732
|
+
/** Coerce a value to text the way interpolation does. */
|
|
733
|
+
declare function text(value: ExprValue): string;
|
|
734
|
+
/**
|
|
735
|
+
* Resolve every string in a config object, one level of nesting at a time.
|
|
736
|
+
*
|
|
737
|
+
* The convenience most hosts actually want, and the shape their hand-rolled
|
|
738
|
+
* version usually takes. Opt-in like the rest of this module.
|
|
739
|
+
*/
|
|
740
|
+
declare function evaluateConfig<T extends Record<string, ExprValue>>(config: T, context: ExprContext): T;
|
|
741
|
+
|
|
742
|
+
export { ActionNode, type AlignEdge, AutoLayoutOptions, ConfigFieldRenderFn, ConnectionValidatorOptions, DecisionNode, ExecutorRegistry, type ExprContext, type ExprValue, 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, evaluateConfig, evaluateExpression, flowKeys, flowLive, paletteDropHandlers, reconnectEdge, resolvePath, text, truthy, 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,116 @@ 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
|
+
/**
|
|
665
|
+
* `{{ }}` resolution — the TypeScript twin of `FancyFlow\Nodes\Support\Expr`.
|
|
666
|
+
*
|
|
667
|
+
* ## Why this is opt-in and not wired into `runFlow`
|
|
668
|
+
*
|
|
669
|
+
* The PHP runtime resolves expressions inside its batteries-included executors.
|
|
670
|
+
* The JS runtime never has: `runFlow` hands `node.data.config` to your executor
|
|
671
|
+
* verbatim, so every host that uses `{{ }}` today already resolves it itself.
|
|
672
|
+
* Turning resolution on inside `runFlow` would interpolate a second time over
|
|
673
|
+
* values those hosts had already substituted — silently, and only for graphs
|
|
674
|
+
* that happen to contain `{{` in their DATA.
|
|
675
|
+
*
|
|
676
|
+
* So this exports the semantics and changes no behaviour. Call it yourself:
|
|
677
|
+
*
|
|
678
|
+
* ```ts
|
|
679
|
+
* const url = evaluateExpression(node.data.config.url, inputs);
|
|
680
|
+
* ```
|
|
681
|
+
*
|
|
682
|
+
* ## The semantics are the PHP file's, deliberately
|
|
683
|
+
*
|
|
684
|
+
* This is not a general expression language and must not grow into one. It
|
|
685
|
+
* resolves a dot-path against a context and nothing else — no arithmetic, no
|
|
686
|
+
* comparisons, no calls. Hosts that want real expressions override the executor
|
|
687
|
+
* (the PHP docblock points at symfony/expression-language for the same reason).
|
|
688
|
+
*
|
|
689
|
+
* Divergence here is a correctness bug rather than a style difference: the same
|
|
690
|
+
* graph is authored once and may run on either runtime. `suites/shared/expr`
|
|
691
|
+
* in `@particle-academy/fancy-conformance` is the fixture table both sides run,
|
|
692
|
+
* so parity is a test result instead of a claim.
|
|
693
|
+
*/
|
|
694
|
+
/** Anything a context or a resolved value can be. */
|
|
695
|
+
type ExprValue = unknown;
|
|
696
|
+
/** The context an expression resolves against — the executor's `inputs`. */
|
|
697
|
+
type ExprContext = Record<string, ExprValue>;
|
|
698
|
+
/**
|
|
699
|
+
* Resolve a dot-path against the context, honouring the `$json` / `$input`
|
|
700
|
+
* alias.
|
|
701
|
+
*
|
|
702
|
+
* Both aliases point at the `in` port value when the context has one, and at
|
|
703
|
+
* the whole context otherwise — the same fallback the PHP does, which is what
|
|
704
|
+
* makes `{{ $json.x }}` work on a trigger node that has no upstream input.
|
|
705
|
+
*
|
|
706
|
+
* A path that does not resolve returns `null`, never `undefined`: PHP has one
|
|
707
|
+
* absent value and JS has two, and letting the difference leak would make the
|
|
708
|
+
* two runtimes disagree about `{{ missing }}` for no useful reason.
|
|
709
|
+
*/
|
|
710
|
+
declare function resolvePath(path: string, context: ExprContext): ExprValue;
|
|
711
|
+
/**
|
|
712
|
+
* Evaluate a template against a context.
|
|
713
|
+
*
|
|
714
|
+
* A string that is EXACTLY one expression returns the resolved value with its
|
|
715
|
+
* type intact — `{{ $json.count }}` gives you a number, not `"3"`. Anything
|
|
716
|
+
* else interpolates each run as text. That distinction is load-bearing: it is
|
|
717
|
+
* what lets a config field carry either a value or a sentence.
|
|
718
|
+
*
|
|
719
|
+
* Non-string templates pass through untouched, so this is safe to map over a
|
|
720
|
+
* whole config object.
|
|
721
|
+
*/
|
|
722
|
+
declare function evaluateExpression(template: ExprValue, context: ExprContext): ExprValue;
|
|
723
|
+
/**
|
|
724
|
+
* Truthiness for branch / switch decisions.
|
|
725
|
+
*
|
|
726
|
+
* Mirrors PHP's rules rather than JavaScript's, because the graph is authored
|
|
727
|
+
* once and may run on either side. The two disagree in exactly the places a
|
|
728
|
+
* workflow hits: `"0"` and `"false"` are truthy in JS and falsy here, and an
|
|
729
|
+
* empty array is truthy in JS and falsy here.
|
|
730
|
+
*/
|
|
731
|
+
declare function truthy(value: ExprValue): boolean;
|
|
732
|
+
/** Coerce a value to text the way interpolation does. */
|
|
733
|
+
declare function text(value: ExprValue): string;
|
|
734
|
+
/**
|
|
735
|
+
* Resolve every string in a config object, one level of nesting at a time.
|
|
736
|
+
*
|
|
737
|
+
* The convenience most hosts actually want, and the shape their hand-rolled
|
|
738
|
+
* version usually takes. Opt-in like the rest of this module.
|
|
739
|
+
*/
|
|
740
|
+
declare function evaluateConfig<T extends Record<string, ExprValue>>(config: T, context: ExprContext): T;
|
|
741
|
+
|
|
742
|
+
export { ActionNode, type AlignEdge, AutoLayoutOptions, ConfigFieldRenderFn, ConnectionValidatorOptions, DecisionNode, ExecutorRegistry, type ExprContext, type ExprValue, 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, evaluateConfig, evaluateExpression, flowKeys, flowLive, paletteDropHandlers, reconnectEdge, resolvePath, text, truthy, useFlowEditor, useFlowEditorOptional };
|