@particle-academy/fancy-flow 0.71.0 → 0.72.1
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/{chunk-3L47KJ6Q.js → chunk-3RXQGYGH.js} +3 -3
- package/dist/{chunk-3L47KJ6Q.js.map → chunk-3RXQGYGH.js.map} +1 -1
- package/dist/{chunk-PNTDTSMR.js → chunk-7DJ56PUA.js} +4 -4
- package/dist/{chunk-PNTDTSMR.js.map → chunk-7DJ56PUA.js.map} +1 -1
- package/dist/{chunk-EVGSL2EM.js → chunk-EX34GCKK.js} +162 -151
- package/dist/chunk-EX34GCKK.js.map +1 -0
- package/dist/{chunk-XI4AZD2S.js → chunk-GQ5LEA7Q.js} +3 -3
- package/dist/{chunk-XI4AZD2S.js.map → chunk-GQ5LEA7Q.js.map} +1 -1
- package/dist/{chunk-D2OBU3CE.js → chunk-K7KO3UJ3.js} +3 -3
- package/dist/{chunk-D2OBU3CE.js.map → chunk-K7KO3UJ3.js.map} +1 -1
- package/dist/{chunk-FPWJYSXX.js → chunk-LYYQO7EY.js} +4 -4
- package/dist/{chunk-FPWJYSXX.js.map → chunk-LYYQO7EY.js.map} +1 -1
- package/dist/{chunk-KQCX6KN7.js → chunk-VAF2SWTC.js} +3 -3
- package/dist/{chunk-KQCX6KN7.js.map → chunk-VAF2SWTC.js.map} +1 -1
- package/dist/durable/index.d.cts +90 -16
- package/dist/durable/index.d.ts +90 -16
- package/dist/durable.cjs +160 -83
- package/dist/durable.cjs.map +1 -1
- package/dist/durable.js +79 -14
- package/dist/durable.js.map +1 -1
- package/dist/engine.cjs +82 -71
- package/dist/engine.cjs.map +1 -1
- package/dist/engine.d.cts +2 -2
- package/dist/engine.d.ts +2 -2
- package/dist/engine.js +4 -4
- package/dist/index.cjs +128 -117
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +12 -12
- package/dist/registry.cjs +82 -71
- package/dist/registry.cjs.map +1 -1
- package/dist/registry.js +2 -2
- package/dist/{run-cohort-DL9JzzPU.d.cts → run-cohort-DNpPa0mq.d.cts} +1 -1
- package/dist/{run-cohort-CjUBWg6X.d.ts → run-cohort-rgT_FX3V.d.ts} +1 -1
- package/dist/{run-flow-B_8hgO5_.d.cts → run-flow-BLP9rXfO.d.ts} +22 -1
- package/dist/{run-flow-CxEGBOxd.d.ts → run-flow-pW0PllaZ.d.cts} +22 -1
- package/dist/runtime/index.d.cts +3 -3
- package/dist/runtime/index.d.ts +3 -3
- package/dist/runtime.cjs +82 -71
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +3 -3
- package/dist/schema.cjs +82 -71
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.js +3 -3
- package/dist/screens.cjs +82 -71
- package/dist/screens.cjs.map +1 -1
- package/dist/screens.js +4 -4
- package/dist/ux.cjs +82 -71
- package/dist/ux.cjs.map +1 -1
- package/dist/ux.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-EVGSL2EM.js.map +0 -1
package/dist/runtime.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { applyOutputsToNodes, applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './chunk-
|
|
2
|
-
export { runCohort } from './chunk-
|
|
1
|
+
export { applyOutputsToNodes, applyStatusesToNodes, createHistory, useFlowHistory, useFlowRun, useFlowState } from './chunk-GQ5LEA7Q.js';
|
|
2
|
+
export { runCohort } from './chunk-K7KO3UJ3.js';
|
|
3
3
|
import './chunk-OWENS2H5.js';
|
|
4
|
-
export { RunIdentity, escapeSegment, runFlow } from './chunk-
|
|
4
|
+
export { RunIdentity, escapeSegment, runFlow } from './chunk-EX34GCKK.js';
|
|
5
5
|
import './chunk-2QXKDLGT.js';
|
|
6
6
|
//# sourceMappingURL=runtime.js.map
|
|
7
7
|
//# sourceMappingURL=runtime.js.map
|
package/dist/schema.cjs
CHANGED
|
@@ -137,24 +137,6 @@ function resolveNodePorts(node, kind) {
|
|
|
137
137
|
};
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
// src/expressions/variables.ts
|
|
141
|
-
function outputFieldsFor(node) {
|
|
142
|
-
const kindName = node.data?.kind ?? node.type;
|
|
143
|
-
if (!kindName) return [];
|
|
144
|
-
const kind = getNodeKind(kindName);
|
|
145
|
-
const shape = kind?.outputShape;
|
|
146
|
-
if (!shape) return [];
|
|
147
|
-
if (typeof shape === "function") {
|
|
148
|
-
try {
|
|
149
|
-
const config = node.data?.config ?? {};
|
|
150
|
-
return shape(config) ?? [];
|
|
151
|
-
} catch {
|
|
152
|
-
return [];
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
return shape;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
140
|
// src/runtime/run-identity.ts
|
|
159
141
|
function escapeSegment(value) {
|
|
160
142
|
return value.replace(/%/g, "%25").replace(/\//g, "%2F").replace(/#/g, "%23");
|
|
@@ -498,6 +480,81 @@ function specForLane(lane) {
|
|
|
498
480
|
};
|
|
499
481
|
}
|
|
500
482
|
|
|
483
|
+
// src/expressions/variables.ts
|
|
484
|
+
function outputFieldsFor(node) {
|
|
485
|
+
const kindName = node.data?.kind ?? node.type;
|
|
486
|
+
if (!kindName) return [];
|
|
487
|
+
const kind = getNodeKind(kindName);
|
|
488
|
+
const shape = kind?.outputShape;
|
|
489
|
+
if (!shape) return [];
|
|
490
|
+
if (typeof shape === "function") {
|
|
491
|
+
try {
|
|
492
|
+
const config = node.data?.config ?? {};
|
|
493
|
+
return shape(config) ?? [];
|
|
494
|
+
} catch {
|
|
495
|
+
return [];
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
return shape;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// src/runtime/undelivered-edges.ts
|
|
502
|
+
function undeliveredEdgeWarnings(target, incoming, portValues, completed, nodesById) {
|
|
503
|
+
const events = [];
|
|
504
|
+
for (const e of incoming) {
|
|
505
|
+
const handle = e.sourceHandle ?? "out";
|
|
506
|
+
if (portValues.has(`${e.source}:${handle}`) || !completed.has(e.source)) continue;
|
|
507
|
+
if (possiblePortIds(nodesById.get(e.source)).includes(handle)) continue;
|
|
508
|
+
events.push({
|
|
509
|
+
type: "log",
|
|
510
|
+
nodeId: target.id,
|
|
511
|
+
level: "warn",
|
|
512
|
+
message: undeliveredEdgeMessage(e, target, portValues, nodesById),
|
|
513
|
+
detail: { edge: e.id, source: e.source, sourceHandle: handle }
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
return events;
|
|
517
|
+
}
|
|
518
|
+
function possiblePortIds(node) {
|
|
519
|
+
if (!node) return ["out"];
|
|
520
|
+
const own = node.data?.outputs;
|
|
521
|
+
if (Array.isArray(own)) return own.map((p) => p.id);
|
|
522
|
+
const kind = getNodeKind(node.data?.kind ?? node.type ?? "");
|
|
523
|
+
if (!kind) return ["out"];
|
|
524
|
+
const config = nodeConfig(node);
|
|
525
|
+
const representative = typeof kind.outputs === "function" && !configDeclaresPorts(kind.name, config);
|
|
526
|
+
const ids = (resolvePortSpec(kind.outputs, representative ? defaultConfigFor(kind) : config) ?? []).map((p) => p.id);
|
|
527
|
+
return ids.length > 0 ? ids : ["out"];
|
|
528
|
+
}
|
|
529
|
+
function configDeclaresPorts(kindName, config) {
|
|
530
|
+
const bare = kindName.startsWith("@") ? kindName.slice(kindName.lastIndexOf("/") + 1) : kindName;
|
|
531
|
+
if (bare === "switch_case") {
|
|
532
|
+
const cases = config.cases;
|
|
533
|
+
return !!cases && typeof cases === "object" && Object.values(cases).some((port) => typeof port === "string" && port !== "");
|
|
534
|
+
}
|
|
535
|
+
if (bare === "llm_router") {
|
|
536
|
+
const routes = config.routes;
|
|
537
|
+
return Array.isArray(routes) && routes.some((route) => route?.port != null && route.port !== "");
|
|
538
|
+
}
|
|
539
|
+
return true;
|
|
540
|
+
}
|
|
541
|
+
function undeliveredEdgeMessage(edge, target, portValues, nodesById) {
|
|
542
|
+
const handle = edge.sourceHandle ?? "out";
|
|
543
|
+
const prefix = `${edge.source}:`;
|
|
544
|
+
const available = [];
|
|
545
|
+
for (const key of portValues.keys()) {
|
|
546
|
+
if (key.startsWith(prefix)) available.push(key.slice(prefix.length));
|
|
547
|
+
}
|
|
548
|
+
let message = `Edge ${edge.id} reads port "${handle}" from node ${edge.source}, which never publishes it \u2014 nothing would reach ${target.id} at run time.`;
|
|
549
|
+
if (available.length > 0) message += ` Available: ${available.join(", ")}.`;
|
|
550
|
+
const source = nodesById.get(edge.source);
|
|
551
|
+
if (source && outputFieldsFor(source).some((field) => field?.path === handle)) {
|
|
552
|
+
message += ` Note: "${handle}" is a FIELD this node emits, not a port \u2014 read it downstream as {{ in.${handle} }} rather than naming it as a source handle.`;
|
|
553
|
+
}
|
|
554
|
+
if (edge.sourceHandle != null) message += " Leave sourceHandle off to read the node's output.";
|
|
555
|
+
return message;
|
|
556
|
+
}
|
|
557
|
+
|
|
501
558
|
// src/runtime/workflow-props.ts
|
|
502
559
|
function typeOf(value) {
|
|
503
560
|
if (value === null) return "null";
|
|
@@ -556,7 +613,7 @@ function resolveWorkflowProps(declared, passed) {
|
|
|
556
613
|
// src/runtime/run-flow.ts
|
|
557
614
|
async function runFlow(graph, executors, onEvent = () => {
|
|
558
615
|
}, options = {}) {
|
|
559
|
-
const { signal, initialInputs = {}, timeoutMs, depth = 0, resumeOutputs = {}, entryNodes } = options;
|
|
616
|
+
const { signal, initialInputs = {}, timeoutMs, depth = 0, resumeOutputs = {}, entryNodes, nodeExecutors } = options;
|
|
560
617
|
const run = options.run === void 0 ? void 0 : RunIdentity.from(options.run);
|
|
561
618
|
const outputs = {};
|
|
562
619
|
const portValues = /* @__PURE__ */ new Map();
|
|
@@ -619,17 +676,8 @@ async function runFlow(graph, executors, onEvent = () => {
|
|
|
619
676
|
onEvent({ type: "node-status", nodeId: node.id, status: "idle", text: "skipped" });
|
|
620
677
|
continue;
|
|
621
678
|
}
|
|
622
|
-
for (const
|
|
623
|
-
|
|
624
|
-
if (portValues.has(`${e.source}:${handle}`) || !completed.has(e.source)) continue;
|
|
625
|
-
if (possiblePortIds(nodesById.get(e.source)).includes(handle)) continue;
|
|
626
|
-
onEvent({
|
|
627
|
-
type: "log",
|
|
628
|
-
nodeId: node.id,
|
|
629
|
-
level: "warn",
|
|
630
|
-
message: undeliveredEdgeMessage(e, node, portValues, nodesById),
|
|
631
|
-
detail: { edge: e.id, source: e.source, sourceHandle: handle }
|
|
632
|
-
});
|
|
679
|
+
for (const warning of undeliveredEdgeWarnings(node, incoming, portValues, completed, nodesById)) {
|
|
680
|
+
onEvent(warning);
|
|
633
681
|
}
|
|
634
682
|
if (incoming.length > 0) {
|
|
635
683
|
const anyActive = incoming.some((e) => portValues.has(`${e.source}:${e.sourceHandle ?? "out"}`));
|
|
@@ -653,7 +701,7 @@ async function runFlow(graph, executors, onEvent = () => {
|
|
|
653
701
|
onEvent({ type: "node-status", nodeId: node.id, status: "running" });
|
|
654
702
|
announce(onEvent, node, "start");
|
|
655
703
|
const inputs = collectInputs(node, incoming, portValues, initialInputs, props, declaresProps);
|
|
656
|
-
const exec = pickExecutor(executors, node);
|
|
704
|
+
const exec = pickExecutor(executors, node, nodeExecutors);
|
|
657
705
|
if (!exec) {
|
|
658
706
|
const tried = executorLookupIds(node);
|
|
659
707
|
const msg = `No executor registered for kind=${node.type} \u2014 tried ${tried.map((id) => `"${id}"`).join(", ")}. Key your registry by one of those.`;
|
|
@@ -773,7 +821,9 @@ function executorLookupIds(node) {
|
|
|
773
821
|
ids.push("*");
|
|
774
822
|
return [...new Set(ids)];
|
|
775
823
|
}
|
|
776
|
-
function pickExecutor(executors, node) {
|
|
824
|
+
function pickExecutor(executors, node, nodeExecutors) {
|
|
825
|
+
const pinned = nodeExecutors && Object.prototype.hasOwnProperty.call(nodeExecutors, node.id) ? nodeExecutors[node.id] : void 0;
|
|
826
|
+
if (pinned) return pinned;
|
|
777
827
|
for (const id of executorLookupIds(node)) {
|
|
778
828
|
if (executors[id]) return executors[id];
|
|
779
829
|
}
|
|
@@ -793,45 +843,6 @@ function activatedPorts(node, result) {
|
|
|
793
843
|
const declared = resolveNodePorts(node, kind).outputs?.map((p) => p.id);
|
|
794
844
|
return { ports: declared?.length ? declared : ["out"], value: result };
|
|
795
845
|
}
|
|
796
|
-
function possiblePortIds(node) {
|
|
797
|
-
if (!node) return ["out"];
|
|
798
|
-
const own = node.data?.outputs;
|
|
799
|
-
if (Array.isArray(own)) return own.map((p) => p.id);
|
|
800
|
-
const kind = getNodeKind(node.data?.kind ?? node.type ?? "");
|
|
801
|
-
if (!kind) return ["out"];
|
|
802
|
-
const config = nodeConfig(node);
|
|
803
|
-
const representative = typeof kind.outputs === "function" && !configDeclaresPorts(kind.name, config);
|
|
804
|
-
const ids = (resolvePortSpec(kind.outputs, representative ? defaultConfigFor(kind) : config) ?? []).map((p) => p.id);
|
|
805
|
-
return ids.length > 0 ? ids : ["out"];
|
|
806
|
-
}
|
|
807
|
-
function configDeclaresPorts(kindName, config) {
|
|
808
|
-
const bare = kindName.startsWith("@") ? kindName.slice(kindName.lastIndexOf("/") + 1) : kindName;
|
|
809
|
-
if (bare === "switch_case") {
|
|
810
|
-
const cases = config.cases;
|
|
811
|
-
return !!cases && typeof cases === "object" && Object.values(cases).some((port) => typeof port === "string" && port !== "");
|
|
812
|
-
}
|
|
813
|
-
if (bare === "llm_router") {
|
|
814
|
-
const routes = config.routes;
|
|
815
|
-
return Array.isArray(routes) && routes.some((route) => route?.port != null && route.port !== "");
|
|
816
|
-
}
|
|
817
|
-
return true;
|
|
818
|
-
}
|
|
819
|
-
function undeliveredEdgeMessage(edge, target, portValues, nodesById) {
|
|
820
|
-
const handle = edge.sourceHandle ?? "out";
|
|
821
|
-
const prefix = `${edge.source}:`;
|
|
822
|
-
const available = [];
|
|
823
|
-
for (const key of portValues.keys()) {
|
|
824
|
-
if (key.startsWith(prefix)) available.push(key.slice(prefix.length));
|
|
825
|
-
}
|
|
826
|
-
let message = `Edge ${edge.id} reads port "${handle}" from node ${edge.source}, which never publishes it \u2014 nothing would reach ${target.id} at run time.`;
|
|
827
|
-
if (available.length > 0) message += ` Available: ${available.join(", ")}.`;
|
|
828
|
-
const source = nodesById.get(edge.source);
|
|
829
|
-
if (source && outputFieldsFor(source).some((field) => field?.path === handle)) {
|
|
830
|
-
message += ` Note: "${handle}" is a FIELD this node emits, not a port \u2014 read it downstream as {{ in.${handle} }} rather than naming it as a source handle.`;
|
|
831
|
-
}
|
|
832
|
-
if (edge.sourceHandle != null) message += " Leave sourceHandle off to read the node's output.";
|
|
833
|
-
return message;
|
|
834
|
-
}
|
|
835
846
|
function announce(onEvent, node, phase) {
|
|
836
847
|
const data = node.data;
|
|
837
848
|
const raw = phase === "start" ? data?.startingMsg : data?.stoppingMsg;
|