@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/screens.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { FlowViewer } from './chunk-
|
|
2
|
-
export { FlowViewer } from './chunk-
|
|
3
|
-
import './chunk-
|
|
1
|
+
import { FlowViewer } from './chunk-LYYQO7EY.js';
|
|
2
|
+
export { FlowViewer } from './chunk-LYYQO7EY.js';
|
|
3
|
+
import './chunk-3RXQGYGH.js';
|
|
4
4
|
import './chunk-F5RPRB7A.js';
|
|
5
5
|
import './chunk-OWENS2H5.js';
|
|
6
6
|
import './chunk-UEOE6B52.js';
|
|
7
|
-
import './chunk-
|
|
7
|
+
import './chunk-EX34GCKK.js';
|
|
8
8
|
import './chunk-2QXKDLGT.js';
|
|
9
9
|
import { registerSchemaComponents } from '@particle-academy/fancy-screens';
|
|
10
10
|
|
package/dist/ux.cjs
CHANGED
|
@@ -142,24 +142,6 @@ function resolveNodePorts(node, kind) {
|
|
|
142
142
|
};
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
// src/expressions/variables.ts
|
|
146
|
-
function outputFieldsFor(node) {
|
|
147
|
-
const kindName = node.data?.kind ?? node.type;
|
|
148
|
-
if (!kindName) return [];
|
|
149
|
-
const kind = getNodeKind(kindName);
|
|
150
|
-
const shape = kind?.outputShape;
|
|
151
|
-
if (!shape) return [];
|
|
152
|
-
if (typeof shape === "function") {
|
|
153
|
-
try {
|
|
154
|
-
const config = node.data?.config ?? {};
|
|
155
|
-
return shape(config) ?? [];
|
|
156
|
-
} catch {
|
|
157
|
-
return [];
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
return shape;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
145
|
// src/runtime/run-identity.ts
|
|
164
146
|
function escapeSegment(value) {
|
|
165
147
|
return value.replace(/%/g, "%25").replace(/\//g, "%2F").replace(/#/g, "%23");
|
|
@@ -503,6 +485,81 @@ function specForLane(lane) {
|
|
|
503
485
|
};
|
|
504
486
|
}
|
|
505
487
|
|
|
488
|
+
// src/expressions/variables.ts
|
|
489
|
+
function outputFieldsFor(node) {
|
|
490
|
+
const kindName = node.data?.kind ?? node.type;
|
|
491
|
+
if (!kindName) return [];
|
|
492
|
+
const kind = getNodeKind(kindName);
|
|
493
|
+
const shape = kind?.outputShape;
|
|
494
|
+
if (!shape) return [];
|
|
495
|
+
if (typeof shape === "function") {
|
|
496
|
+
try {
|
|
497
|
+
const config = node.data?.config ?? {};
|
|
498
|
+
return shape(config) ?? [];
|
|
499
|
+
} catch {
|
|
500
|
+
return [];
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
return shape;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// src/runtime/undelivered-edges.ts
|
|
507
|
+
function undeliveredEdgeWarnings(target, incoming, portValues, completed, nodesById) {
|
|
508
|
+
const events = [];
|
|
509
|
+
for (const e of incoming) {
|
|
510
|
+
const handle = e.sourceHandle ?? "out";
|
|
511
|
+
if (portValues.has(`${e.source}:${handle}`) || !completed.has(e.source)) continue;
|
|
512
|
+
if (possiblePortIds(nodesById.get(e.source)).includes(handle)) continue;
|
|
513
|
+
events.push({
|
|
514
|
+
type: "log",
|
|
515
|
+
nodeId: target.id,
|
|
516
|
+
level: "warn",
|
|
517
|
+
message: undeliveredEdgeMessage(e, target, portValues, nodesById),
|
|
518
|
+
detail: { edge: e.id, source: e.source, sourceHandle: handle }
|
|
519
|
+
});
|
|
520
|
+
}
|
|
521
|
+
return events;
|
|
522
|
+
}
|
|
523
|
+
function possiblePortIds(node) {
|
|
524
|
+
if (!node) return ["out"];
|
|
525
|
+
const own = node.data?.outputs;
|
|
526
|
+
if (Array.isArray(own)) return own.map((p) => p.id);
|
|
527
|
+
const kind = getNodeKind(node.data?.kind ?? node.type ?? "");
|
|
528
|
+
if (!kind) return ["out"];
|
|
529
|
+
const config = nodeConfig(node);
|
|
530
|
+
const representative = typeof kind.outputs === "function" && !configDeclaresPorts(kind.name, config);
|
|
531
|
+
const ids = (resolvePortSpec(kind.outputs, representative ? defaultConfigFor(kind) : config) ?? []).map((p) => p.id);
|
|
532
|
+
return ids.length > 0 ? ids : ["out"];
|
|
533
|
+
}
|
|
534
|
+
function configDeclaresPorts(kindName, config) {
|
|
535
|
+
const bare = kindName.startsWith("@") ? kindName.slice(kindName.lastIndexOf("/") + 1) : kindName;
|
|
536
|
+
if (bare === "switch_case") {
|
|
537
|
+
const cases = config.cases;
|
|
538
|
+
return !!cases && typeof cases === "object" && Object.values(cases).some((port) => typeof port === "string" && port !== "");
|
|
539
|
+
}
|
|
540
|
+
if (bare === "llm_router") {
|
|
541
|
+
const routes = config.routes;
|
|
542
|
+
return Array.isArray(routes) && routes.some((route) => route?.port != null && route.port !== "");
|
|
543
|
+
}
|
|
544
|
+
return true;
|
|
545
|
+
}
|
|
546
|
+
function undeliveredEdgeMessage(edge, target, portValues, nodesById) {
|
|
547
|
+
const handle = edge.sourceHandle ?? "out";
|
|
548
|
+
const prefix = `${edge.source}:`;
|
|
549
|
+
const available = [];
|
|
550
|
+
for (const key of portValues.keys()) {
|
|
551
|
+
if (key.startsWith(prefix)) available.push(key.slice(prefix.length));
|
|
552
|
+
}
|
|
553
|
+
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.`;
|
|
554
|
+
if (available.length > 0) message += ` Available: ${available.join(", ")}.`;
|
|
555
|
+
const source = nodesById.get(edge.source);
|
|
556
|
+
if (source && outputFieldsFor(source).some((field) => field?.path === handle)) {
|
|
557
|
+
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.`;
|
|
558
|
+
}
|
|
559
|
+
if (edge.sourceHandle != null) message += " Leave sourceHandle off to read the node's output.";
|
|
560
|
+
return message;
|
|
561
|
+
}
|
|
562
|
+
|
|
506
563
|
// src/runtime/workflow-props.ts
|
|
507
564
|
function typeOf(value) {
|
|
508
565
|
if (value === null) return "null";
|
|
@@ -561,7 +618,7 @@ function resolveWorkflowProps(declared, passed) {
|
|
|
561
618
|
// src/runtime/run-flow.ts
|
|
562
619
|
async function runFlow(graph, executors, onEvent = () => {
|
|
563
620
|
}, options = {}) {
|
|
564
|
-
const { signal, initialInputs = {}, timeoutMs, depth = 0, resumeOutputs = {}, entryNodes } = options;
|
|
621
|
+
const { signal, initialInputs = {}, timeoutMs, depth = 0, resumeOutputs = {}, entryNodes, nodeExecutors } = options;
|
|
565
622
|
const run = options.run === void 0 ? void 0 : RunIdentity.from(options.run);
|
|
566
623
|
const outputs = {};
|
|
567
624
|
const portValues = /* @__PURE__ */ new Map();
|
|
@@ -624,17 +681,8 @@ async function runFlow(graph, executors, onEvent = () => {
|
|
|
624
681
|
onEvent({ type: "node-status", nodeId: node.id, status: "idle", text: "skipped" });
|
|
625
682
|
continue;
|
|
626
683
|
}
|
|
627
|
-
for (const
|
|
628
|
-
|
|
629
|
-
if (portValues.has(`${e.source}:${handle}`) || !completed.has(e.source)) continue;
|
|
630
|
-
if (possiblePortIds(nodesById.get(e.source)).includes(handle)) continue;
|
|
631
|
-
onEvent({
|
|
632
|
-
type: "log",
|
|
633
|
-
nodeId: node.id,
|
|
634
|
-
level: "warn",
|
|
635
|
-
message: undeliveredEdgeMessage(e, node, portValues, nodesById),
|
|
636
|
-
detail: { edge: e.id, source: e.source, sourceHandle: handle }
|
|
637
|
-
});
|
|
684
|
+
for (const warning of undeliveredEdgeWarnings(node, incoming, portValues, completed, nodesById)) {
|
|
685
|
+
onEvent(warning);
|
|
638
686
|
}
|
|
639
687
|
if (incoming.length > 0) {
|
|
640
688
|
const anyActive = incoming.some((e) => portValues.has(`${e.source}:${e.sourceHandle ?? "out"}`));
|
|
@@ -658,7 +706,7 @@ async function runFlow(graph, executors, onEvent = () => {
|
|
|
658
706
|
onEvent({ type: "node-status", nodeId: node.id, status: "running" });
|
|
659
707
|
announce(onEvent, node, "start");
|
|
660
708
|
const inputs = collectInputs(node, incoming, portValues, initialInputs, props, declaresProps);
|
|
661
|
-
const exec = pickExecutor(executors, node);
|
|
709
|
+
const exec = pickExecutor(executors, node, nodeExecutors);
|
|
662
710
|
if (!exec) {
|
|
663
711
|
const tried = executorLookupIds(node);
|
|
664
712
|
const msg = `No executor registered for kind=${node.type} \u2014 tried ${tried.map((id) => `"${id}"`).join(", ")}. Key your registry by one of those.`;
|
|
@@ -778,7 +826,9 @@ function executorLookupIds(node) {
|
|
|
778
826
|
ids.push("*");
|
|
779
827
|
return [...new Set(ids)];
|
|
780
828
|
}
|
|
781
|
-
function pickExecutor(executors, node) {
|
|
829
|
+
function pickExecutor(executors, node, nodeExecutors) {
|
|
830
|
+
const pinned = nodeExecutors && Object.prototype.hasOwnProperty.call(nodeExecutors, node.id) ? nodeExecutors[node.id] : void 0;
|
|
831
|
+
if (pinned) return pinned;
|
|
782
832
|
for (const id of executorLookupIds(node)) {
|
|
783
833
|
if (executors[id]) return executors[id];
|
|
784
834
|
}
|
|
@@ -798,45 +848,6 @@ function activatedPorts(node, result) {
|
|
|
798
848
|
const declared = resolveNodePorts(node, kind).outputs?.map((p) => p.id);
|
|
799
849
|
return { ports: declared?.length ? declared : ["out"], value: result };
|
|
800
850
|
}
|
|
801
|
-
function possiblePortIds(node) {
|
|
802
|
-
if (!node) return ["out"];
|
|
803
|
-
const own = node.data?.outputs;
|
|
804
|
-
if (Array.isArray(own)) return own.map((p) => p.id);
|
|
805
|
-
const kind = getNodeKind(node.data?.kind ?? node.type ?? "");
|
|
806
|
-
if (!kind) return ["out"];
|
|
807
|
-
const config = nodeConfig(node);
|
|
808
|
-
const representative = typeof kind.outputs === "function" && !configDeclaresPorts(kind.name, config);
|
|
809
|
-
const ids = (resolvePortSpec(kind.outputs, representative ? defaultConfigFor(kind) : config) ?? []).map((p) => p.id);
|
|
810
|
-
return ids.length > 0 ? ids : ["out"];
|
|
811
|
-
}
|
|
812
|
-
function configDeclaresPorts(kindName, config) {
|
|
813
|
-
const bare = kindName.startsWith("@") ? kindName.slice(kindName.lastIndexOf("/") + 1) : kindName;
|
|
814
|
-
if (bare === "switch_case") {
|
|
815
|
-
const cases = config.cases;
|
|
816
|
-
return !!cases && typeof cases === "object" && Object.values(cases).some((port) => typeof port === "string" && port !== "");
|
|
817
|
-
}
|
|
818
|
-
if (bare === "llm_router") {
|
|
819
|
-
const routes = config.routes;
|
|
820
|
-
return Array.isArray(routes) && routes.some((route) => route?.port != null && route.port !== "");
|
|
821
|
-
}
|
|
822
|
-
return true;
|
|
823
|
-
}
|
|
824
|
-
function undeliveredEdgeMessage(edge, target, portValues, nodesById) {
|
|
825
|
-
const handle = edge.sourceHandle ?? "out";
|
|
826
|
-
const prefix = `${edge.source}:`;
|
|
827
|
-
const available = [];
|
|
828
|
-
for (const key of portValues.keys()) {
|
|
829
|
-
if (key.startsWith(prefix)) available.push(key.slice(prefix.length));
|
|
830
|
-
}
|
|
831
|
-
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.`;
|
|
832
|
-
if (available.length > 0) message += ` Available: ${available.join(", ")}.`;
|
|
833
|
-
const source = nodesById.get(edge.source);
|
|
834
|
-
if (source && outputFieldsFor(source).some((field) => field?.path === handle)) {
|
|
835
|
-
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.`;
|
|
836
|
-
}
|
|
837
|
-
if (edge.sourceHandle != null) message += " Leave sourceHandle off to read the node's output.";
|
|
838
|
-
return message;
|
|
839
|
-
}
|
|
840
851
|
function announce(onEvent, node, phase) {
|
|
841
852
|
const data = node.data;
|
|
842
853
|
const raw = phase === "start" ? data?.startingMsg : data?.stoppingMsg;
|