@particle-academy/fancy-flow 0.77.1 → 0.79.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/{FlowViewer-Ak8kbY0e.d.cts → FlowViewer-BqYQl2vS.d.cts} +1 -1
- package/dist/{FlowViewer-BAV29Zpi.d.ts → FlowViewer-_Fq8AX9V.d.ts} +1 -1
- package/dist/{HumanPrompt-xYPCL2jO.d.cts → HumanPrompt-Sl1wD9Bx.d.cts} +2 -2
- package/dist/{HumanPrompt-Ge_ccCgS.d.ts → HumanPrompt-_SKIdSpx.d.ts} +2 -2
- package/dist/{chunk-T6WIIGSK.js → chunk-I5EPWHNM.js} +3 -3
- package/dist/{chunk-T6WIIGSK.js.map → chunk-I5EPWHNM.js.map} +1 -1
- package/dist/{chunk-EGXA4SYJ.js → chunk-J66LOLJR.js} +4 -4
- package/dist/{chunk-EGXA4SYJ.js.map → chunk-J66LOLJR.js.map} +1 -1
- package/dist/{chunk-G5RAGPVD.js → chunk-KMONOPAK.js} +3 -3
- package/dist/{chunk-G5RAGPVD.js.map → chunk-KMONOPAK.js.map} +1 -1
- package/dist/{chunk-ARSOSEJV.js → chunk-LBE4L3DS.js} +4 -4
- package/dist/{chunk-ARSOSEJV.js.map → chunk-LBE4L3DS.js.map} +1 -1
- package/dist/{chunk-EEIWAIXW.js → chunk-OZHBAXMA.js} +125 -8
- package/dist/chunk-OZHBAXMA.js.map +1 -0
- package/dist/{chunk-2VI24UPB.js → chunk-QMJVUT7C.js} +3 -3
- package/dist/{chunk-2VI24UPB.js.map → chunk-QMJVUT7C.js.map} +1 -1
- package/dist/{chunk-CQAMEPPI.js → chunk-R4G7SPLD.js} +3 -3
- package/dist/{chunk-CQAMEPPI.js.map → chunk-R4G7SPLD.js.map} +1 -1
- package/dist/connectors.d.cts +2 -2
- package/dist/connectors.d.ts +2 -2
- package/dist/durable/index.d.cts +2 -2
- package/dist/durable/index.d.ts +2 -2
- package/dist/durable.cjs +123 -6
- package/dist/durable.cjs.map +1 -1
- package/dist/durable.js +1 -1
- package/dist/engine.cjs +123 -6
- package/dist/engine.cjs.map +1 -1
- package/dist/engine.d.cts +6 -6
- package/dist/engine.d.ts +6 -6
- package/dist/engine.js +4 -4
- package/dist/fields/react-fancy.d.cts +3 -3
- package/dist/fields/react-fancy.d.ts +3 -3
- package/dist/index.cjs +123 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +12 -12
- package/dist/layout/index.d.cts +1 -1
- package/dist/layout/index.d.ts +1 -1
- package/dist/llm/prism.d.cts +1 -1
- package/dist/llm/prism.d.ts +1 -1
- package/dist/llm/vercel-ai.d.cts +1 -1
- package/dist/llm/vercel-ai.d.ts +1 -1
- package/dist/registry/index.d.cts +5 -5
- package/dist/registry/index.d.ts +5 -5
- package/dist/{registry-JUcN_xWK.d.ts → registry-C4GcH583.d.ts} +1 -1
- package/dist/{registry-B6SiTaLZ.d.cts → registry-DWIY3bMP.d.cts} +1 -1
- package/dist/registry.cjs +123 -6
- package/dist/registry.cjs.map +1 -1
- package/dist/registry.js +2 -2
- package/dist/{run-cohort-rgT_FX3V.d.ts → run-cohort-DAfhZm-p.d.ts} +2 -2
- package/dist/{run-cohort-DNpPa0mq.d.cts → run-cohort-DRJvUWO9.d.cts} +2 -2
- package/dist/{run-flow-pW0PllaZ.d.cts → run-flow-Bdrn4lQV.d.cts} +1 -1
- package/dist/{run-flow-BLP9rXfO.d.ts → run-flow-D2iOjWsj.d.ts} +1 -1
- package/dist/runtime/index.d.cts +5 -5
- package/dist/runtime/index.d.ts +5 -5
- package/dist/runtime.cjs +123 -6
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +3 -3
- package/dist/schema/index.d.cts +1 -1
- package/dist/schema/index.d.ts +1 -1
- package/dist/schema.cjs +123 -6
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.js +3 -3
- package/dist/screens.cjs +123 -6
- package/dist/screens.cjs.map +1 -1
- package/dist/screens.d.cts +2 -2
- package/dist/screens.d.ts +2 -2
- package/dist/screens.js +4 -4
- package/dist/terminal/fancy-term-host.d.cts +1 -1
- package/dist/terminal/fancy-term-host.d.ts +1 -1
- package/dist/{types-BdkXxjFh.d.cts → types-B1jftRa9.d.cts} +1 -1
- package/dist/{types-CbekKMMO.d.ts → types-D5SBBpbe.d.ts} +1 -1
- package/dist/{types-B-Syk9-M.d.ts → types-E48Dpesq.d.cts} +20 -0
- package/dist/{types-B-Syk9-M.d.cts → types-E48Dpesq.d.ts} +20 -0
- package/dist/ux.cjs +123 -6
- package/dist/ux.cjs.map +1 -1
- package/dist/ux.d.cts +2 -2
- package/dist/ux.d.ts +2 -2
- package/dist/ux.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-EEIWAIXW.js.map +0 -1
package/dist/engine.d.cts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { R as RunOptions, a as RunResult, r as runFlow } from './run-flow-
|
|
2
|
-
import { F as FlowGraph, R as RunEvent, N as NodeExecutor, W as WorkflowResolver, a as FlowNode } from './types-
|
|
3
|
-
export { A as ActionNodeData, B as BaseNodeData, D as DecisionNodeData, E as ExecutorRegistry, e as FlowEdge, f as FlowNodeData, g as FlowNodeKind, h as NodeRunStatus, i as NoteNodeData, O as OutputNodeData, P as PortDescriptor, c as RunIdentity, d as RunIdentityJson, S as SubgraphNodeData, j as TriggerNodeData, k as escapeSegment } from './types-
|
|
4
|
-
export { C as CohortGuard, a as CohortOptions, b as CohortPolicy, c as CohortResult, r as runCohort } from './run-cohort-
|
|
5
|
-
export { K as KindSchemaOverlay, a as KindSchemaOverlayResult, b as applyKindSchemaOverlay, c as clearKindSchemaOverlays, d as defaultConfigFor, g as getNodeKind, k as kindIds, l as listNodeKinds, r as registerNodeKind, e as resolveKindId, u as unregisterNodeKind, v as validateConfig } from './registry-
|
|
6
|
-
export { b as CapabilityRequirement, C as ConfigField, E as EmitsRelation, M as ManifestProblem, c as ManifestValidation, d as NODE_MANIFEST_SCHEMA_VERSION, a as NodeCategory, N as NodeKindDefinition, e as NodePackageManifest, f as NodeRuntimeId, g as NodeRuntimeSpec, O as OutputField, h as OutputShape, P as PortSpec, S as SideEffects, i as checkCapabilities, j as checkRuntimeSupport, s as satisfiesRange, v as validateNodeManifest } from './types-
|
|
1
|
+
export { R as RunOptions, a as RunResult, r as runFlow } from './run-flow-Bdrn4lQV.cjs';
|
|
2
|
+
import { F as FlowGraph, R as RunEvent, N as NodeExecutor, W as WorkflowResolver, a as FlowNode } from './types-E48Dpesq.cjs';
|
|
3
|
+
export { A as ActionNodeData, B as BaseNodeData, D as DecisionNodeData, E as ExecutorRegistry, e as FlowEdge, f as FlowNodeData, g as FlowNodeKind, h as NodeRunStatus, i as NoteNodeData, O as OutputNodeData, P as PortDescriptor, c as RunIdentity, d as RunIdentityJson, S as SubgraphNodeData, j as TriggerNodeData, k as escapeSegment } from './types-E48Dpesq.cjs';
|
|
4
|
+
export { C as CohortGuard, a as CohortOptions, b as CohortPolicy, c as CohortResult, r as runCohort } from './run-cohort-DRJvUWO9.cjs';
|
|
5
|
+
export { K as KindSchemaOverlay, a as KindSchemaOverlayResult, b as applyKindSchemaOverlay, c as clearKindSchemaOverlays, d as defaultConfigFor, g as getNodeKind, k as kindIds, l as listNodeKinds, r as registerNodeKind, e as resolveKindId, u as unregisterNodeKind, v as validateConfig } from './registry-DWIY3bMP.cjs';
|
|
6
|
+
export { b as CapabilityRequirement, C as ConfigField, E as EmitsRelation, M as ManifestProblem, c as ManifestValidation, d as NODE_MANIFEST_SCHEMA_VERSION, a as NodeCategory, N as NodeKindDefinition, e as NodePackageManifest, f as NodeRuntimeId, g as NodeRuntimeSpec, O as OutputField, h as OutputShape, P as PortSpec, S as SideEffects, i as checkCapabilities, j as checkRuntimeSupport, s as satisfiesRange, v as validateNodeManifest } from './types-B1jftRa9.cjs';
|
|
7
7
|
export { E as EvaluateOptions, a as ExprContext, b as ExprValue, R as Resolution, U as UnresolvedPathError, c as UnresolvedPolicy, e as evaluateConfig, d as evaluateExpression, r as resolvePath, t as text, f as truthy, g as tryResolvePath } from './expr-BfXDrs4H.cjs';
|
|
8
8
|
import { P as PauseAwaiting } from './pause-9iT4tCEV.cjs';
|
|
9
9
|
export { L as LEGACY_PAUSE_PREFIXES, a as PAUSE_PREFIX, b as PauseSignal, d as decodePause, e as encodePause, i as isPause, p as pauseForHuman } from './pause-9iT4tCEV.cjs';
|
package/dist/engine.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export { R as RunOptions, a as RunResult, r as runFlow } from './run-flow-
|
|
2
|
-
import { F as FlowGraph, R as RunEvent, N as NodeExecutor, W as WorkflowResolver, a as FlowNode } from './types-
|
|
3
|
-
export { A as ActionNodeData, B as BaseNodeData, D as DecisionNodeData, E as ExecutorRegistry, e as FlowEdge, f as FlowNodeData, g as FlowNodeKind, h as NodeRunStatus, i as NoteNodeData, O as OutputNodeData, P as PortDescriptor, c as RunIdentity, d as RunIdentityJson, S as SubgraphNodeData, j as TriggerNodeData, k as escapeSegment } from './types-
|
|
4
|
-
export { C as CohortGuard, a as CohortOptions, b as CohortPolicy, c as CohortResult, r as runCohort } from './run-cohort-
|
|
5
|
-
export { K as KindSchemaOverlay, a as KindSchemaOverlayResult, b as applyKindSchemaOverlay, c as clearKindSchemaOverlays, d as defaultConfigFor, g as getNodeKind, k as kindIds, l as listNodeKinds, r as registerNodeKind, e as resolveKindId, u as unregisterNodeKind, v as validateConfig } from './registry-
|
|
6
|
-
export { b as CapabilityRequirement, C as ConfigField, E as EmitsRelation, M as ManifestProblem, c as ManifestValidation, d as NODE_MANIFEST_SCHEMA_VERSION, a as NodeCategory, N as NodeKindDefinition, e as NodePackageManifest, f as NodeRuntimeId, g as NodeRuntimeSpec, O as OutputField, h as OutputShape, P as PortSpec, S as SideEffects, i as checkCapabilities, j as checkRuntimeSupport, s as satisfiesRange, v as validateNodeManifest } from './types-
|
|
1
|
+
export { R as RunOptions, a as RunResult, r as runFlow } from './run-flow-D2iOjWsj.js';
|
|
2
|
+
import { F as FlowGraph, R as RunEvent, N as NodeExecutor, W as WorkflowResolver, a as FlowNode } from './types-E48Dpesq.js';
|
|
3
|
+
export { A as ActionNodeData, B as BaseNodeData, D as DecisionNodeData, E as ExecutorRegistry, e as FlowEdge, f as FlowNodeData, g as FlowNodeKind, h as NodeRunStatus, i as NoteNodeData, O as OutputNodeData, P as PortDescriptor, c as RunIdentity, d as RunIdentityJson, S as SubgraphNodeData, j as TriggerNodeData, k as escapeSegment } from './types-E48Dpesq.js';
|
|
4
|
+
export { C as CohortGuard, a as CohortOptions, b as CohortPolicy, c as CohortResult, r as runCohort } from './run-cohort-DAfhZm-p.js';
|
|
5
|
+
export { K as KindSchemaOverlay, a as KindSchemaOverlayResult, b as applyKindSchemaOverlay, c as clearKindSchemaOverlays, d as defaultConfigFor, g as getNodeKind, k as kindIds, l as listNodeKinds, r as registerNodeKind, e as resolveKindId, u as unregisterNodeKind, v as validateConfig } from './registry-C4GcH583.js';
|
|
6
|
+
export { b as CapabilityRequirement, C as ConfigField, E as EmitsRelation, M as ManifestProblem, c as ManifestValidation, d as NODE_MANIFEST_SCHEMA_VERSION, a as NodeCategory, N as NodeKindDefinition, e as NodePackageManifest, f as NodeRuntimeId, g as NodeRuntimeSpec, O as OutputField, h as OutputShape, P as PortSpec, S as SideEffects, i as checkCapabilities, j as checkRuntimeSupport, s as satisfiesRange, v as validateNodeManifest } from './types-D5SBBpbe.js';
|
|
7
7
|
export { E as EvaluateOptions, a as ExprContext, b as ExprValue, R as Resolution, U as UnresolvedPathError, c as UnresolvedPolicy, e as evaluateConfig, d as evaluateExpression, r as resolvePath, t as text, f as truthy, g as tryResolvePath } from './expr-BfXDrs4H.js';
|
|
8
8
|
import { P as PauseAwaiting } from './pause-9iT4tCEV.js';
|
|
9
9
|
export { L as LEGACY_PAUSE_PREFIXES, a as PAUSE_PREFIX, b as PauseSignal, d as decodePause, e as encodePause, i as isPause, p as pauseForHuman } from './pause-9iT4tCEV.js';
|
package/dist/engine.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { runCohort } from './chunk-
|
|
2
|
-
export { checkGraphConnectivity, mayFloat } from './chunk-
|
|
3
|
-
import { runFlow, decodePause, getNodeKind, resolveNodePorts } from './chunk-
|
|
4
|
-
export { LEGACY_PAUSE_PREFIXES, PAUSE_PREFIX, RunIdentity, UnresolvedPathError, applyKindSchemaOverlay, clearKindSchemaOverlays, decodePause, defaultConfigFor, encodePause, escapeSegment, evaluateConfig, evaluateExpression, getNodeKind, isPause, kindIds, listNodeKinds, pauseForHuman, registerNodeKind, resolveKindId, resolvePath, runFlow, text, truthy, tryResolvePath, unregisterNodeKind, validateConfig } from './chunk-
|
|
1
|
+
export { runCohort } from './chunk-R4G7SPLD.js';
|
|
2
|
+
export { checkGraphConnectivity, mayFloat } from './chunk-KMONOPAK.js';
|
|
3
|
+
import { runFlow, decodePause, getNodeKind, resolveNodePorts } from './chunk-OZHBAXMA.js';
|
|
4
|
+
export { LEGACY_PAUSE_PREFIXES, PAUSE_PREFIX, RunIdentity, UnresolvedPathError, applyKindSchemaOverlay, clearKindSchemaOverlays, decodePause, defaultConfigFor, encodePause, escapeSegment, evaluateConfig, evaluateExpression, getNodeKind, isPause, kindIds, listNodeKinds, pauseForHuman, registerNodeKind, resolveKindId, resolvePath, runFlow, text, truthy, tryResolvePath, unregisterNodeKind, validateConfig } from './chunk-OZHBAXMA.js';
|
|
5
5
|
import { isResolutionFailure, registerLlmClient, registerWorkflowResolver } from './chunk-2QXKDLGT.js';
|
|
6
6
|
|
|
7
7
|
// src/marketplace/manifest.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { H as HumanFieldRenderers, C as ConfigFieldRenderFn } from '../HumanPrompt-
|
|
1
|
+
import { H as HumanFieldRenderers, C as ConfigFieldRenderFn } from '../HumanPrompt-Sl1wD9Bx.cjs';
|
|
2
2
|
import 'react';
|
|
3
|
-
import '../types-
|
|
3
|
+
import '../types-E48Dpesq.cjs';
|
|
4
4
|
import '@xyflow/react';
|
|
5
|
-
import '../types-
|
|
5
|
+
import '../types-B1jftRa9.cjs';
|
|
6
6
|
import '../pause-9iT4tCEV.cjs';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { H as HumanFieldRenderers, C as ConfigFieldRenderFn } from '../HumanPrompt-
|
|
1
|
+
import { H as HumanFieldRenderers, C as ConfigFieldRenderFn } from '../HumanPrompt-_SKIdSpx.js';
|
|
2
2
|
import 'react';
|
|
3
|
-
import '../types-
|
|
3
|
+
import '../types-E48Dpesq.js';
|
|
4
4
|
import '@xyflow/react';
|
|
5
|
-
import '../types-
|
|
5
|
+
import '../types-D5SBBpbe.js';
|
|
6
6
|
import '../pause-9iT4tCEV.js';
|
|
7
7
|
|
|
8
8
|
/**
|
package/dist/index.cjs
CHANGED
|
@@ -2532,6 +2532,9 @@ async function runFlow(graph, executors, onEvent = () => {
|
|
|
2532
2532
|
executors,
|
|
2533
2533
|
depth,
|
|
2534
2534
|
run,
|
|
2535
|
+
// Structural executors derive a nested lane from the graph they are
|
|
2536
|
+
// in; `for_each`'s `item` port cannot be implemented without it.
|
|
2537
|
+
graph,
|
|
2535
2538
|
terminal: terminalAccessorFor(node)
|
|
2536
2539
|
})
|
|
2537
2540
|
);
|
|
@@ -2986,6 +2989,7 @@ var branchExecutor = (ctx) => {
|
|
|
2986
2989
|
const inputs = ctx.inputs;
|
|
2987
2990
|
let taken;
|
|
2988
2991
|
const raw = config.condition;
|
|
2992
|
+
validateRoutingExpression(ctx, raw, "branch", "condition");
|
|
2989
2993
|
if (typeof raw === "string" && raw.trim() !== "") {
|
|
2990
2994
|
taken = truthy(resolve(raw, inputs));
|
|
2991
2995
|
warnIfUnresolved(ctx, raw, taken ? "true" : "false");
|
|
@@ -3040,14 +3044,102 @@ var mergeExecutor = (ctx) => {
|
|
|
3040
3044
|
}
|
|
3041
3045
|
return merged;
|
|
3042
3046
|
};
|
|
3043
|
-
var
|
|
3044
|
-
|
|
3047
|
+
var FOR_EACH_DEFAULT_MAX_ITEMS = 1e3;
|
|
3048
|
+
var FOR_EACH_HARD_MAX_ITEMS = 1e4;
|
|
3049
|
+
function reachable(adjacency, starts) {
|
|
3050
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3051
|
+
const queue = [...starts];
|
|
3052
|
+
for (let cursor = 0; cursor < queue.length; cursor += 1) {
|
|
3053
|
+
const id2 = queue[cursor];
|
|
3054
|
+
if (seen.has(id2)) continue;
|
|
3055
|
+
seen.add(id2);
|
|
3056
|
+
for (const target of adjacency.get(id2) ?? []) queue.push(target);
|
|
3057
|
+
}
|
|
3058
|
+
return seen;
|
|
3059
|
+
}
|
|
3060
|
+
function forEachLane(graph, nodeId) {
|
|
3061
|
+
const handleOf = (edge) => edge.sourceHandle ?? "out";
|
|
3062
|
+
const itemEdges = graph.edges.filter((e) => e.source === nodeId && handleOf(e) === "item");
|
|
3063
|
+
if (itemEdges.length === 0) return null;
|
|
3064
|
+
const adjacency = /* @__PURE__ */ new Map();
|
|
3065
|
+
for (const edge of graph.edges) {
|
|
3066
|
+
const list = adjacency.get(edge.source) ?? [];
|
|
3067
|
+
list.push(edge.target);
|
|
3068
|
+
adjacency.set(edge.source, list);
|
|
3069
|
+
}
|
|
3070
|
+
const done = reachable(
|
|
3071
|
+
adjacency,
|
|
3072
|
+
graph.edges.filter((e) => e.source === nodeId && handleOf(e) === "done").map((e) => e.target)
|
|
3073
|
+
);
|
|
3074
|
+
const body = new Set(
|
|
3075
|
+
[...reachable(adjacency, itemEdges.map((e) => e.target))].filter(
|
|
3076
|
+
(id2) => !done.has(id2) && id2 !== nodeId
|
|
3077
|
+
)
|
|
3078
|
+
);
|
|
3079
|
+
return {
|
|
3080
|
+
graph: {
|
|
3081
|
+
nodes: graph.nodes.filter((n) => body.has(n.id)),
|
|
3082
|
+
edges: graph.edges.filter((e) => body.has(e.source) && body.has(e.target)),
|
|
3083
|
+
...graph.inputs === void 0 ? {} : { inputs: graph.inputs }
|
|
3084
|
+
},
|
|
3085
|
+
entries: itemEdges.filter((e) => body.has(e.target))
|
|
3086
|
+
};
|
|
3087
|
+
}
|
|
3088
|
+
var forEachExecutor = async (ctx) => {
|
|
3089
|
+
const config = configOf(ctx.node);
|
|
3090
|
+
const source = resolve(config.source, ctx.inputs);
|
|
3045
3091
|
let items;
|
|
3046
3092
|
if (Array.isArray(source)) items = source;
|
|
3047
3093
|
else if (source === null || source === void 0) items = [];
|
|
3048
3094
|
else if (typeof source === "object") items = Object.values(source);
|
|
3049
3095
|
else items = [source];
|
|
3050
|
-
|
|
3096
|
+
const lane = ctx.graph ? forEachLane(ctx.graph, ctx.node.id) : null;
|
|
3097
|
+
if (lane === null || config.mode === "collect") {
|
|
3098
|
+
return { items, count: items.length };
|
|
3099
|
+
}
|
|
3100
|
+
if (lane.graph.nodes.length === 0) {
|
|
3101
|
+
ctx.abort(`for_each "${ctx.node.id}" has an item edge but its derived lane is empty`);
|
|
3102
|
+
}
|
|
3103
|
+
const maxItems = Number(config.maxItems ?? FOR_EACH_DEFAULT_MAX_ITEMS);
|
|
3104
|
+
if (!Number.isFinite(maxItems) || maxItems < 1 || maxItems > FOR_EACH_HARD_MAX_ITEMS) {
|
|
3105
|
+
ctx.abort(`for_each "${ctx.node.id}" maxItems must be between 1 and ${FOR_EACH_HARD_MAX_ITEMS}`);
|
|
3106
|
+
}
|
|
3107
|
+
if (items.length > maxItems) {
|
|
3108
|
+
ctx.abort(
|
|
3109
|
+
`for_each "${ctx.node.id}" resolved ${items.length} items exceeds its maxItems cap of ${maxItems}`
|
|
3110
|
+
);
|
|
3111
|
+
}
|
|
3112
|
+
const results = [];
|
|
3113
|
+
const failures = [];
|
|
3114
|
+
for (const [index2, item] of items.entries()) {
|
|
3115
|
+
const initialInputs = {};
|
|
3116
|
+
for (const edge of lane.entries) {
|
|
3117
|
+
initialInputs[edge.target] = {
|
|
3118
|
+
...initialInputs[edge.target] ?? {},
|
|
3119
|
+
[edge.targetHandle ?? "in"]: item
|
|
3120
|
+
};
|
|
3121
|
+
}
|
|
3122
|
+
const nested = await runFlow(lane.graph, { ...ctx.executors ?? {} }, () => {
|
|
3123
|
+
}, {
|
|
3124
|
+
initialInputs,
|
|
3125
|
+
depth: (ctx.depth ?? 0) + 1,
|
|
3126
|
+
// The index rides on the identity, so a node in iteration 3 cannot share
|
|
3127
|
+
// an idempotency key with the same node in iteration 4.
|
|
3128
|
+
run: ctx.run?.descend(ctx.node.id, index2)
|
|
3129
|
+
});
|
|
3130
|
+
if (!nested.ok) {
|
|
3131
|
+
const reason = nested.error ?? "unknown error";
|
|
3132
|
+
if (decodePause(reason)) ctx.abort(reason);
|
|
3133
|
+
results.push(null);
|
|
3134
|
+
failures.push({ index: index2, item, error: reason });
|
|
3135
|
+
continue;
|
|
3136
|
+
}
|
|
3137
|
+
results.push(nested.outputs);
|
|
3138
|
+
}
|
|
3139
|
+
return {
|
|
3140
|
+
__port: "done",
|
|
3141
|
+
value: { items, results, failures, count: items.length }
|
|
3142
|
+
};
|
|
3051
3143
|
};
|
|
3052
3144
|
var manualTriggerExecutor = (ctx) => ctx.inputs;
|
|
3053
3145
|
var outputExecutor = (ctx) => {
|
|
@@ -3067,6 +3159,7 @@ var switchCaseExecutor = (ctx) => {
|
|
|
3067
3159
|
const config = configOf(ctx.node);
|
|
3068
3160
|
const inputs = ctx.inputs;
|
|
3069
3161
|
const expression = config.value;
|
|
3162
|
+
validateRoutingExpression(ctx, expression, "switch_case", "value");
|
|
3070
3163
|
const value = text(resolve(expression, inputs));
|
|
3071
3164
|
const cases = config.cases ?? {};
|
|
3072
3165
|
const matched = Object.prototype.hasOwnProperty.call(cases, value);
|
|
@@ -3074,6 +3167,21 @@ var switchCaseExecutor = (ctx) => {
|
|
|
3074
3167
|
warnIfUnresolved(ctx, expression, port, "value");
|
|
3075
3168
|
return { __port: port, value: inputs.in ?? inputs };
|
|
3076
3169
|
};
|
|
3170
|
+
function validateRoutingExpression(ctx, value, kind, field) {
|
|
3171
|
+
if (typeof value !== "string" || value.trim() === "") return;
|
|
3172
|
+
const bare = value.trim();
|
|
3173
|
+
const subject = `${kind} "${ctx.node.id}" ${field} "${bare}"`;
|
|
3174
|
+
if (!value.includes("{{")) {
|
|
3175
|
+
ctx.abort(`${subject} is not an expression -- wrap it: {{ ${bare} }}`);
|
|
3176
|
+
}
|
|
3177
|
+
let open = 0;
|
|
3178
|
+
for (const [delimiter] of value.matchAll(/\{\{|\}\}/g)) {
|
|
3179
|
+
open = delimiter === "{{" ? open + 1 : Math.max(0, open - 1);
|
|
3180
|
+
}
|
|
3181
|
+
if (open > 0) {
|
|
3182
|
+
ctx.abort(`${subject} has an unclosed expression -- close every {{ with }}`);
|
|
3183
|
+
}
|
|
3184
|
+
}
|
|
3077
3185
|
|
|
3078
3186
|
// src/registry/terminal-nodes.ts
|
|
3079
3187
|
var DEFAULT_TIMEOUT_MS = 12e4;
|
|
@@ -3565,7 +3673,7 @@ var KINDS = [
|
|
|
3565
3673
|
key: "condition",
|
|
3566
3674
|
label: "Raw expression (advanced)",
|
|
3567
3675
|
example: "{{ $json.active && $json.score > 10 }}",
|
|
3568
|
-
description: "Escape hatch for logic the builder can't express. Overrides the conditions above when set."
|
|
3676
|
+
description: "Escape hatch for logic the builder can't express. Overrides the conditions above when set. String values must be {{ }}-wrapped expressions; bare strings and unclosed templates abort the run."
|
|
3569
3677
|
}
|
|
3570
3678
|
]
|
|
3571
3679
|
},
|
|
@@ -3585,7 +3693,7 @@ var KINDS = [
|
|
|
3585
3693
|
// moves the ports on the canvas and the ports the runtime activates.
|
|
3586
3694
|
outputs: (config) => casePorts(config?.cases),
|
|
3587
3695
|
configSchema: [
|
|
3588
|
-
{ type: "expression", key: "value", label: "Switch on", example: "{{ $json.kind }}", required: true },
|
|
3696
|
+
{ type: "expression", key: "value", label: "Switch on", description: "String values must be {{ }}-wrapped expressions; bare strings and unclosed templates abort the run.", example: "{{ $json.kind }}", required: true },
|
|
3589
3697
|
{
|
|
3590
3698
|
type: "keyvalue",
|
|
3591
3699
|
key: "cases",
|
|
@@ -3604,6 +3712,15 @@ var KINDS = [
|
|
|
3604
3712
|
name: "@particle-academy/for_each",
|
|
3605
3713
|
outputShape: [
|
|
3606
3714
|
{ path: "items", type: "array" },
|
|
3715
|
+
// `results` and `failures` are the WIRED shape -- what a lane produces
|
|
3716
|
+
// when the `item` port is connected. Declared unconditionally because a
|
|
3717
|
+
// declaration describes the kind, not one graph's use of it, and because
|
|
3718
|
+
// the shared table requires them: fancy-conformance 0.30.0 added
|
|
3719
|
+
// `results` and 0.31.0 added `failures`, both BREAKING, both so that a
|
|
3720
|
+
// runtime which has not implemented iteration fails here rather than
|
|
3721
|
+
// reporting surface parity it does not have.
|
|
3722
|
+
{ path: "results", type: "array" },
|
|
3723
|
+
{ path: "failures", type: "array" },
|
|
3607
3724
|
{ path: "count", type: "number" }
|
|
3608
3725
|
],
|
|
3609
3726
|
aliases: ["for_each", "@fancy/for_each"],
|
|
@@ -3612,7 +3729,7 @@ var KINDS = [
|
|
|
3612
3729
|
executor: forEachExecutor,
|
|
3613
3730
|
category: "logic",
|
|
3614
3731
|
label: "For Each",
|
|
3615
|
-
description: "
|
|
3732
|
+
description: "Wire `item` to a lane and it runs once per item, aggregating `results` and `failures` on `done`. Leave `item` unwired (or set `mode: collect`) and it just publishes the list and its size -- one node, one checkpoint.",
|
|
3616
3733
|
icon: "\u21BB",
|
|
3617
3734
|
inputs: [{ id: "in" }],
|
|
3618
3735
|
outputs: [{ id: "item", label: "item" }, { id: "done", label: "done" }],
|