@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/schema.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, exportWorkflow, importWorkflow, migrateSchema, workflowToBlob } from './chunk-
|
|
2
|
-
import './chunk-
|
|
3
|
-
import './chunk-
|
|
1
|
+
export { WORKFLOW_SCHEMA_URL, WORKFLOW_SCHEMA_VERSION, exportWorkflow, importWorkflow, migrateSchema, workflowToBlob } from './chunk-LBE4L3DS.js';
|
|
2
|
+
import './chunk-KMONOPAK.js';
|
|
3
|
+
import './chunk-OZHBAXMA.js';
|
|
4
4
|
import './chunk-2QXKDLGT.js';
|
|
5
5
|
//# sourceMappingURL=schema.js.map
|
|
6
6
|
//# sourceMappingURL=schema.js.map
|
package/dist/screens.cjs
CHANGED
|
@@ -9921,6 +9921,9 @@ async function runFlow(graph, executors, onEvent = () => {
|
|
|
9921
9921
|
executors,
|
|
9922
9922
|
depth,
|
|
9923
9923
|
run,
|
|
9924
|
+
// Structural executors derive a nested lane from the graph they are
|
|
9925
|
+
// in; `for_each`'s `item` port cannot be implemented without it.
|
|
9926
|
+
graph,
|
|
9924
9927
|
terminal: terminalAccessorFor(node)
|
|
9925
9928
|
})
|
|
9926
9929
|
);
|
|
@@ -10355,6 +10358,7 @@ var branchExecutor = (ctx) => {
|
|
|
10355
10358
|
const inputs = ctx.inputs;
|
|
10356
10359
|
let taken;
|
|
10357
10360
|
const raw = config.condition;
|
|
10361
|
+
validateRoutingExpression(ctx, raw, "branch", "condition");
|
|
10358
10362
|
if (typeof raw === "string" && raw.trim() !== "") {
|
|
10359
10363
|
taken = truthy(resolve(raw, inputs));
|
|
10360
10364
|
warnIfUnresolved(ctx, raw, taken ? "true" : "false");
|
|
@@ -10409,14 +10413,102 @@ var mergeExecutor = (ctx) => {
|
|
|
10409
10413
|
}
|
|
10410
10414
|
return merged;
|
|
10411
10415
|
};
|
|
10412
|
-
var
|
|
10413
|
-
|
|
10416
|
+
var FOR_EACH_DEFAULT_MAX_ITEMS = 1e3;
|
|
10417
|
+
var FOR_EACH_HARD_MAX_ITEMS = 1e4;
|
|
10418
|
+
function reachable(adjacency, starts) {
|
|
10419
|
+
const seen = /* @__PURE__ */ new Set();
|
|
10420
|
+
const queue = [...starts];
|
|
10421
|
+
for (let cursor = 0; cursor < queue.length; cursor += 1) {
|
|
10422
|
+
const id2 = queue[cursor];
|
|
10423
|
+
if (seen.has(id2)) continue;
|
|
10424
|
+
seen.add(id2);
|
|
10425
|
+
for (const target of adjacency.get(id2) ?? []) queue.push(target);
|
|
10426
|
+
}
|
|
10427
|
+
return seen;
|
|
10428
|
+
}
|
|
10429
|
+
function forEachLane(graph, nodeId) {
|
|
10430
|
+
const handleOf = (edge) => edge.sourceHandle ?? "out";
|
|
10431
|
+
const itemEdges = graph.edges.filter((e) => e.source === nodeId && handleOf(e) === "item");
|
|
10432
|
+
if (itemEdges.length === 0) return null;
|
|
10433
|
+
const adjacency = /* @__PURE__ */ new Map();
|
|
10434
|
+
for (const edge of graph.edges) {
|
|
10435
|
+
const list = adjacency.get(edge.source) ?? [];
|
|
10436
|
+
list.push(edge.target);
|
|
10437
|
+
adjacency.set(edge.source, list);
|
|
10438
|
+
}
|
|
10439
|
+
const done = reachable(
|
|
10440
|
+
adjacency,
|
|
10441
|
+
graph.edges.filter((e) => e.source === nodeId && handleOf(e) === "done").map((e) => e.target)
|
|
10442
|
+
);
|
|
10443
|
+
const body = new Set(
|
|
10444
|
+
[...reachable(adjacency, itemEdges.map((e) => e.target))].filter(
|
|
10445
|
+
(id2) => !done.has(id2) && id2 !== nodeId
|
|
10446
|
+
)
|
|
10447
|
+
);
|
|
10448
|
+
return {
|
|
10449
|
+
graph: {
|
|
10450
|
+
nodes: graph.nodes.filter((n) => body.has(n.id)),
|
|
10451
|
+
edges: graph.edges.filter((e) => body.has(e.source) && body.has(e.target)),
|
|
10452
|
+
...graph.inputs === void 0 ? {} : { inputs: graph.inputs }
|
|
10453
|
+
},
|
|
10454
|
+
entries: itemEdges.filter((e) => body.has(e.target))
|
|
10455
|
+
};
|
|
10456
|
+
}
|
|
10457
|
+
var forEachExecutor = async (ctx) => {
|
|
10458
|
+
const config = configOf(ctx.node);
|
|
10459
|
+
const source = resolve(config.source, ctx.inputs);
|
|
10414
10460
|
let items;
|
|
10415
10461
|
if (Array.isArray(source)) items = source;
|
|
10416
10462
|
else if (source === null || source === void 0) items = [];
|
|
10417
10463
|
else if (typeof source === "object") items = Object.values(source);
|
|
10418
10464
|
else items = [source];
|
|
10419
|
-
|
|
10465
|
+
const lane = ctx.graph ? forEachLane(ctx.graph, ctx.node.id) : null;
|
|
10466
|
+
if (lane === null || config.mode === "collect") {
|
|
10467
|
+
return { items, count: items.length };
|
|
10468
|
+
}
|
|
10469
|
+
if (lane.graph.nodes.length === 0) {
|
|
10470
|
+
ctx.abort(`for_each "${ctx.node.id}" has an item edge but its derived lane is empty`);
|
|
10471
|
+
}
|
|
10472
|
+
const maxItems = Number(config.maxItems ?? FOR_EACH_DEFAULT_MAX_ITEMS);
|
|
10473
|
+
if (!Number.isFinite(maxItems) || maxItems < 1 || maxItems > FOR_EACH_HARD_MAX_ITEMS) {
|
|
10474
|
+
ctx.abort(`for_each "${ctx.node.id}" maxItems must be between 1 and ${FOR_EACH_HARD_MAX_ITEMS}`);
|
|
10475
|
+
}
|
|
10476
|
+
if (items.length > maxItems) {
|
|
10477
|
+
ctx.abort(
|
|
10478
|
+
`for_each "${ctx.node.id}" resolved ${items.length} items exceeds its maxItems cap of ${maxItems}`
|
|
10479
|
+
);
|
|
10480
|
+
}
|
|
10481
|
+
const results = [];
|
|
10482
|
+
const failures = [];
|
|
10483
|
+
for (const [index2, item] of items.entries()) {
|
|
10484
|
+
const initialInputs = {};
|
|
10485
|
+
for (const edge of lane.entries) {
|
|
10486
|
+
initialInputs[edge.target] = {
|
|
10487
|
+
...initialInputs[edge.target] ?? {},
|
|
10488
|
+
[edge.targetHandle ?? "in"]: item
|
|
10489
|
+
};
|
|
10490
|
+
}
|
|
10491
|
+
const nested = await runFlow(lane.graph, { ...ctx.executors ?? {} }, () => {
|
|
10492
|
+
}, {
|
|
10493
|
+
initialInputs,
|
|
10494
|
+
depth: (ctx.depth ?? 0) + 1,
|
|
10495
|
+
// The index rides on the identity, so a node in iteration 3 cannot share
|
|
10496
|
+
// an idempotency key with the same node in iteration 4.
|
|
10497
|
+
run: ctx.run?.descend(ctx.node.id, index2)
|
|
10498
|
+
});
|
|
10499
|
+
if (!nested.ok) {
|
|
10500
|
+
const reason = nested.error ?? "unknown error";
|
|
10501
|
+
if (decodePause(reason)) ctx.abort(reason);
|
|
10502
|
+
results.push(null);
|
|
10503
|
+
failures.push({ index: index2, item, error: reason });
|
|
10504
|
+
continue;
|
|
10505
|
+
}
|
|
10506
|
+
results.push(nested.outputs);
|
|
10507
|
+
}
|
|
10508
|
+
return {
|
|
10509
|
+
__port: "done",
|
|
10510
|
+
value: { items, results, failures, count: items.length }
|
|
10511
|
+
};
|
|
10420
10512
|
};
|
|
10421
10513
|
var manualTriggerExecutor = (ctx) => ctx.inputs;
|
|
10422
10514
|
var outputExecutor = (ctx) => {
|
|
@@ -10436,6 +10528,7 @@ var switchCaseExecutor = (ctx) => {
|
|
|
10436
10528
|
const config = configOf(ctx.node);
|
|
10437
10529
|
const inputs = ctx.inputs;
|
|
10438
10530
|
const expression = config.value;
|
|
10531
|
+
validateRoutingExpression(ctx, expression, "switch_case", "value");
|
|
10439
10532
|
const value = text(resolve(expression, inputs));
|
|
10440
10533
|
const cases = config.cases ?? {};
|
|
10441
10534
|
const matched = Object.prototype.hasOwnProperty.call(cases, value);
|
|
@@ -10443,6 +10536,21 @@ var switchCaseExecutor = (ctx) => {
|
|
|
10443
10536
|
warnIfUnresolved(ctx, expression, port, "value");
|
|
10444
10537
|
return { __port: port, value: inputs.in ?? inputs };
|
|
10445
10538
|
};
|
|
10539
|
+
function validateRoutingExpression(ctx, value, kind, field) {
|
|
10540
|
+
if (typeof value !== "string" || value.trim() === "") return;
|
|
10541
|
+
const bare = value.trim();
|
|
10542
|
+
const subject = `${kind} "${ctx.node.id}" ${field} "${bare}"`;
|
|
10543
|
+
if (!value.includes("{{")) {
|
|
10544
|
+
ctx.abort(`${subject} is not an expression -- wrap it: {{ ${bare} }}`);
|
|
10545
|
+
}
|
|
10546
|
+
let open = 0;
|
|
10547
|
+
for (const [delimiter] of value.matchAll(/\{\{|\}\}/g)) {
|
|
10548
|
+
open = delimiter === "{{" ? open + 1 : Math.max(0, open - 1);
|
|
10549
|
+
}
|
|
10550
|
+
if (open > 0) {
|
|
10551
|
+
ctx.abort(`${subject} has an unclosed expression -- close every {{ with }}`);
|
|
10552
|
+
}
|
|
10553
|
+
}
|
|
10446
10554
|
|
|
10447
10555
|
// src/registry/terminal-nodes.ts
|
|
10448
10556
|
var DEFAULT_TIMEOUT_MS = 12e4;
|
|
@@ -10934,7 +11042,7 @@ var KINDS = [
|
|
|
10934
11042
|
key: "condition",
|
|
10935
11043
|
label: "Raw expression (advanced)",
|
|
10936
11044
|
example: "{{ $json.active && $json.score > 10 }}",
|
|
10937
|
-
description: "Escape hatch for logic the builder can't express. Overrides the conditions above when set."
|
|
11045
|
+
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."
|
|
10938
11046
|
}
|
|
10939
11047
|
]
|
|
10940
11048
|
},
|
|
@@ -10954,7 +11062,7 @@ var KINDS = [
|
|
|
10954
11062
|
// moves the ports on the canvas and the ports the runtime activates.
|
|
10955
11063
|
outputs: (config) => casePorts(config?.cases),
|
|
10956
11064
|
configSchema: [
|
|
10957
|
-
{ type: "expression", key: "value", label: "Switch on", example: "{{ $json.kind }}", required: true },
|
|
11065
|
+
{ 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 },
|
|
10958
11066
|
{
|
|
10959
11067
|
type: "keyvalue",
|
|
10960
11068
|
key: "cases",
|
|
@@ -10973,6 +11081,15 @@ var KINDS = [
|
|
|
10973
11081
|
name: "@particle-academy/for_each",
|
|
10974
11082
|
outputShape: [
|
|
10975
11083
|
{ path: "items", type: "array" },
|
|
11084
|
+
// `results` and `failures` are the WIRED shape -- what a lane produces
|
|
11085
|
+
// when the `item` port is connected. Declared unconditionally because a
|
|
11086
|
+
// declaration describes the kind, not one graph's use of it, and because
|
|
11087
|
+
// the shared table requires them: fancy-conformance 0.30.0 added
|
|
11088
|
+
// `results` and 0.31.0 added `failures`, both BREAKING, both so that a
|
|
11089
|
+
// runtime which has not implemented iteration fails here rather than
|
|
11090
|
+
// reporting surface parity it does not have.
|
|
11091
|
+
{ path: "results", type: "array" },
|
|
11092
|
+
{ path: "failures", type: "array" },
|
|
10976
11093
|
{ path: "count", type: "number" }
|
|
10977
11094
|
],
|
|
10978
11095
|
aliases: ["for_each", "@fancy/for_each"],
|
|
@@ -10981,7 +11098,7 @@ var KINDS = [
|
|
|
10981
11098
|
executor: forEachExecutor,
|
|
10982
11099
|
category: "logic",
|
|
10983
11100
|
label: "For Each",
|
|
10984
|
-
description: "
|
|
11101
|
+
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.",
|
|
10985
11102
|
icon: "\u21BB",
|
|
10986
11103
|
inputs: [{ id: "in" }],
|
|
10987
11104
|
outputs: [{ id: "item", label: "item" }, { id: "done", label: "done" }],
|