@bian-womp/spark-workbench 0.2.32 → 0.2.33
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/lib/cjs/index.cjs +36 -6
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/core/contracts.d.ts +1 -0
- package/lib/cjs/src/core/contracts.d.ts.map +1 -1
- package/lib/cjs/src/misc/Inspector.d.ts.map +1 -1
- package/lib/cjs/src/misc/context/WorkbenchContext.provider.d.ts.map +1 -1
- package/lib/esm/index.js +36 -6
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/core/contracts.d.ts +1 -0
- package/lib/esm/src/core/contracts.d.ts.map +1 -1
- package/lib/esm/src/misc/Inspector.d.ts.map +1 -1
- package/lib/esm/src/misc/context/WorkbenchContext.provider.d.ts.map +1 -1
- package/package.json +4 -4
package/lib/cjs/index.cjs
CHANGED
|
@@ -1796,8 +1796,16 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
1796
1796
|
const next = { ...prev };
|
|
1797
1797
|
for (const n of def.nodes) {
|
|
1798
1798
|
const cur = next[n.nodeId] ?? (next[n.nodeId] = {});
|
|
1799
|
+
const updates = {};
|
|
1799
1800
|
if (cur.invalidated === undefined) {
|
|
1800
|
-
|
|
1801
|
+
updates.invalidated = true;
|
|
1802
|
+
}
|
|
1803
|
+
// Ensure activeRunIds is always initialized as an array
|
|
1804
|
+
if (cur.activeRunIds === undefined) {
|
|
1805
|
+
updates.activeRunIds = [];
|
|
1806
|
+
}
|
|
1807
|
+
if (Object.keys(updates).length > 0) {
|
|
1808
|
+
next[n.nodeId] = { ...cur, ...updates };
|
|
1801
1809
|
}
|
|
1802
1810
|
}
|
|
1803
1811
|
return next;
|
|
@@ -2001,13 +2009,23 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
2001
2009
|
return;
|
|
2002
2010
|
if (s.kind === "node-start") {
|
|
2003
2011
|
const id = s.nodeId;
|
|
2012
|
+
const runId = s.runId;
|
|
2013
|
+
// Validate runId is a non-empty string
|
|
2014
|
+
const isValidRunId = runId && typeof runId === "string" && runId.length > 0;
|
|
2015
|
+
if (!isValidRunId) {
|
|
2016
|
+
console.warn(`[WorkbenchContext] node-start event missing or invalid runId for node ${id}`, { runId, event: s });
|
|
2017
|
+
}
|
|
2004
2018
|
setNodeStatus((prev) => {
|
|
2005
2019
|
const current = prev[id]?.activeRuns ?? 0;
|
|
2020
|
+
const currentRunIds = prev[id]?.activeRunIds ?? [];
|
|
2006
2021
|
return {
|
|
2007
2022
|
...prev,
|
|
2008
2023
|
[id]: {
|
|
2009
2024
|
...prev[id],
|
|
2010
2025
|
activeRuns: current + 1,
|
|
2026
|
+
activeRunIds: isValidRunId
|
|
2027
|
+
? [...currentRunIds, runId]
|
|
2028
|
+
: currentRunIds,
|
|
2011
2029
|
progress: 0,
|
|
2012
2030
|
invalidated: false,
|
|
2013
2031
|
},
|
|
@@ -2029,13 +2047,19 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
2029
2047
|
else if (s.kind === "node-done") {
|
|
2030
2048
|
const id = s.nodeId;
|
|
2031
2049
|
const runId = s.runId;
|
|
2050
|
+
// Validate runId is a non-empty string
|
|
2051
|
+
const isValidRunId = runId && typeof runId === "string" && runId.length > 0;
|
|
2032
2052
|
setNodeStatus((prev) => {
|
|
2033
2053
|
const current = prev[id]?.activeRuns ?? 0;
|
|
2034
2054
|
const nextActive = current - 1;
|
|
2035
|
-
const
|
|
2055
|
+
const currentRunIds = prev[id]?.activeRunIds ?? [];
|
|
2056
|
+
const nextRunIds = isValidRunId
|
|
2057
|
+
? currentRunIds.filter((rid) => rid !== runId)
|
|
2058
|
+
: currentRunIds;
|
|
2059
|
+
const hadError = !!(isValidRunId && errorRunsRef.current[id]?.[runId]);
|
|
2036
2060
|
const keepProgress = hadError || nextActive > 0;
|
|
2037
2061
|
// Clear error flag for this runId
|
|
2038
|
-
if (
|
|
2062
|
+
if (isValidRunId && errorRunsRef.current[id]?.[runId]) {
|
|
2039
2063
|
delete errorRunsRef.current[id]?.[runId];
|
|
2040
2064
|
}
|
|
2041
2065
|
return {
|
|
@@ -2043,6 +2067,7 @@ function WorkbenchProvider({ wb, runner, registry, setRegistry, overrides, uiVer
|
|
|
2043
2067
|
[id]: {
|
|
2044
2068
|
...prev[id],
|
|
2045
2069
|
activeRuns: nextActive,
|
|
2070
|
+
activeRunIds: nextRunIds,
|
|
2046
2071
|
progress: keepProgress ? prev[id]?.progress : 0,
|
|
2047
2072
|
lastError: hadError ? prev[id]?.lastError : undefined,
|
|
2048
2073
|
},
|
|
@@ -2354,7 +2379,7 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
2354
2379
|
return String(value ?? "");
|
|
2355
2380
|
}
|
|
2356
2381
|
};
|
|
2357
|
-
const { registry, def, selectedNodeId, selectedEdgeId, inputsMap, outputsMap, outputTypesMap, nodeStatus, validationByNode, validationByEdge, validationGlobal, valuesTick, updateEdgeType, systemErrors, registryErrors, clearSystemErrors, clearRegistryErrors, removeSystemError, removeRegistryError, } = useWorkbenchContext();
|
|
2382
|
+
const { registry, def, selectedNodeId, selectedEdgeId, inputsMap, outputsMap, outputTypesMap, nodeStatus, edgeStatus, validationByNode, validationByEdge, validationGlobal, valuesTick, updateEdgeType, systemErrors, registryErrors, clearSystemErrors, clearRegistryErrors, removeSystemError, removeRegistryError, } = useWorkbenchContext();
|
|
2358
2383
|
const nodeValidationIssues = validationByNode.issues;
|
|
2359
2384
|
const edgeValidationIssues = validationByEdge.issues;
|
|
2360
2385
|
const nodeValidationHandles = validationByNode;
|
|
@@ -2443,7 +2468,10 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
2443
2468
|
return (jsxRuntime.jsxs("div", { className: `${widthClass} border-l border-gray-300 p-3 flex flex-col h-full min-h-0 overflow-auto`, children: [jsxRuntime.jsxs("div", { className: "flex-1 overflow-auto", children: [contextPanel && jsxRuntime.jsx("div", { className: "mb-2", children: contextPanel }), systemErrors.length > 0 && (jsxRuntime.jsxs("div", { className: "mb-2 space-y-1", children: [systemErrors.map((err, i) => (jsxRuntime.jsxs("div", { className: "text-xs text-red-700 bg-red-50 border border-red-200 rounded px-2 py-1 flex items-start justify-between gap-2", children: [jsxRuntime.jsxs("div", { className: "flex-1", children: [jsxRuntime.jsx("div", { className: "font-semibold", children: err.code ? `Error ${err.code}` : "Error" }), jsxRuntime.jsx("div", { className: "break-words", children: err.message })] }), jsxRuntime.jsx("button", { className: "text-red-500 hover:text-red-700 text-[10px] px-1", onClick: () => removeSystemError(i), title: "Dismiss", children: jsxRuntime.jsx(react$1.XIcon, { size: 10 }) })] }, i))), systemErrors.length > 1 && (jsxRuntime.jsx("button", { className: "text-xs text-red-600 hover:text-red-800 underline", onClick: clearSystemErrors, children: "Clear all" }))] })), registryErrors.length > 0 && (jsxRuntime.jsxs("div", { className: "mb-2 space-y-1", children: [registryErrors.map((err, i) => (jsxRuntime.jsxs("div", { className: "text-xs text-amber-700 bg-amber-50 border border-amber-200 rounded px-2 py-1 flex items-start justify-between gap-2", children: [jsxRuntime.jsxs("div", { className: "flex-1", children: [jsxRuntime.jsx("div", { className: "font-semibold", children: "Registry Error" }), jsxRuntime.jsx("div", { className: "break-words", children: err.message }), err.attempt && err.maxAttempts && (jsxRuntime.jsxs("div", { className: "text-[10px] text-amber-600 mt-1", children: ["Attempt ", err.attempt, " of ", err.maxAttempts] }))] }), jsxRuntime.jsx("button", { className: "text-amber-500 hover:text-amber-700 text-[10px] px-1", onClick: () => removeRegistryError(i), title: "Dismiss", children: jsxRuntime.jsx(react$1.XIcon, { size: 10 }) })] }, i))), registryErrors.length > 1 && (jsxRuntime.jsx("button", { className: "text-xs text-amber-600 hover:text-amber-800 underline", onClick: clearRegistryErrors, children: "Clear all" }))] })), jsxRuntime.jsx("div", { className: "font-semibold mb-2", children: "Inspector" }), jsxRuntime.jsxs("div", { className: "text-xs text-gray-500 mb-2", children: ["valuesTick: ", valuesTick] }), jsxRuntime.jsx("div", { className: "flex-1", children: !selectedNode && !selectedEdge ? (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("div", { className: "text-gray-500", children: "Select a node or edge." }), globalValidationIssues && globalValidationIssues.length > 0 && (jsxRuntime.jsxs("div", { className: "mt-2 text-xs bg-red-50 border border-red-200 rounded px-2 py-1", children: [jsxRuntime.jsx("div", { className: "font-semibold mb-1", children: "Validation" }), jsxRuntime.jsx("ul", { className: "list-disc ml-4", children: globalValidationIssues.map((m, i) => (jsxRuntime.jsxs("li", { className: "flex items-center gap-1", children: [jsxRuntime.jsx(IssueBadge, { level: m.level, size: 24, className: "w-6 h-6" }), jsxRuntime.jsx("span", { children: `${m.code}: ${m.message}` }), !!m.data?.edgeId && (jsxRuntime.jsx("button", { className: "ml-2 text-[10px] px-1 py-[2px] border border-red-300 rounded text-red-700 hover:bg-red-50", onClick: (e) => {
|
|
2444
2469
|
e.stopPropagation();
|
|
2445
2470
|
deleteEdgeById(m.data?.edgeId);
|
|
2446
|
-
}, title: "Delete referenced edge", children: "Delete edge" }))] }, i))) })] }))] })) : selectedEdge ? (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs("div", { className: "mb-2", children: [jsxRuntime.jsxs("div", { children: ["Edge: ", selectedEdge.id] }), jsxRuntime.jsxs("div", { children: [selectedEdge.source.nodeId, ".", selectedEdge.source.handle, " \u2192", " ", selectedEdge.target.nodeId, ".", selectedEdge.target.handle] }),
|
|
2471
|
+
}, title: "Delete referenced edge", children: "Delete edge" }))] }, i))) })] }))] })) : selectedEdge ? (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs("div", { className: "mb-2", children: [jsxRuntime.jsxs("div", { children: ["Edge: ", selectedEdge.id] }), jsxRuntime.jsxs("div", { children: [selectedEdge.source.nodeId, ".", selectedEdge.source.handle, " \u2192", " ", selectedEdge.target.nodeId, ".", selectedEdge.target.handle] }), (() => {
|
|
2472
|
+
const status = edgeStatus?.[selectedEdge.id];
|
|
2473
|
+
return status?.activeRuns > 0 ? (jsxRuntime.jsxs("div", { className: "mt-1 text-xs text-blue-700 bg-blue-50 border border-blue-200 rounded px-2 py-1", children: [jsxRuntime.jsxs("div", { className: "font-semibold", children: ["Running (", status.activeRuns, ")"] }), jsxRuntime.jsx("div", { className: "text-[10px] text-blue-600 mt-1", children: "Note: Edge runIds are not available in stats events" })] })) : null;
|
|
2474
|
+
})(), jsxRuntime.jsx("div", { className: "mt-1", children: jsxRuntime.jsx("button", { className: "text-xs px-2 py-1 border border-red-300 rounded text-red-700 hover:bg-red-50", onClick: (e) => {
|
|
2447
2475
|
e.stopPropagation();
|
|
2448
2476
|
deleteEdgeById(selectedEdge.id);
|
|
2449
2477
|
}, title: "Delete this edge", children: "Delete edge" }) }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-1", children: [jsxRuntime.jsxs("label", { className: "w-20 flex flex-col", children: [jsxRuntime.jsx("span", { children: "Type" }), jsxRuntime.jsx("span", { className: "text-gray-500 text-[11px]", children: "DataTypeId" })] }), jsxRuntime.jsxs("select", { className: "border border-gray-300 rounded px-2 py-1 focus:outline-none focus:ring-2 focus:ring-blue-500 w-full", value: selectedEdge.typeId ?? "", onChange: (e) => {
|
|
@@ -2453,7 +2481,9 @@ function Inspector({ debug, autoScroll, hideWorkbench, onAutoScrollChange, onHid
|
|
|
2453
2481
|
}, children: [jsxRuntime.jsx("option", { value: "", children: "(infer from source)" }), Array.from(registry.types.keys()).map((tid) => (jsxRuntime.jsx("option", { value: tid, children: tid }, tid)))] })] })] }), selectedEdgeValidation.length > 0 && (jsxRuntime.jsxs("div", { className: "mt-2 text-xs bg-red-50 border border-red-200 rounded px-2 py-1", children: [jsxRuntime.jsx("div", { className: "font-semibold mb-1", children: "Validation" }), jsxRuntime.jsx("ul", { className: "list-disc ml-4", children: selectedEdgeValidation.map((m, i) => (jsxRuntime.jsxs("li", { className: "flex items-center gap-1", children: [jsxRuntime.jsx(IssueBadge, { level: m.level, size: 24, className: "w-6 h-6" }), jsxRuntime.jsx("span", { children: `${m.code}: ${m.message}` }), jsxRuntime.jsx("button", { className: "ml-2 text-[10px] px-1 py-[2px] border border-red-300 rounded text-red-700 hover:bg-red-50", onClick: (e) => {
|
|
2454
2482
|
e.stopPropagation();
|
|
2455
2483
|
deleteEdgeById(selectedEdge.id);
|
|
2456
|
-
}, title: "Delete this edge", children: "Delete edge" })] }, i))) })] }))] })) : (jsxRuntime.jsxs("div", { children: [selectedNode && (jsxRuntime.jsxs("div", { className: "mb-2", children: [jsxRuntime.jsxs("div", { children: ["Node: ", selectedNode.nodeId] }), jsxRuntime.jsxs("div", { children: ["Type: ", selectedNode.typeId] }),
|
|
2484
|
+
}, title: "Delete this edge", children: "Delete edge" })] }, i))) })] }))] })) : (jsxRuntime.jsxs("div", { children: [selectedNode && (jsxRuntime.jsxs("div", { className: "mb-2", children: [jsxRuntime.jsxs("div", { children: ["Node: ", selectedNode.nodeId] }), jsxRuntime.jsxs("div", { children: ["Type: ", selectedNode.typeId] }), selectedNodeStatus?.activeRuns &&
|
|
2485
|
+
selectedNodeStatus.activeRuns > 0 && (jsxRuntime.jsxs("div", { className: "mt-1 text-xs text-blue-700 bg-blue-50 border border-blue-200 rounded px-2 py-1", children: [jsxRuntime.jsxs("div", { className: "font-semibold", children: ["Running (", selectedNodeStatus.activeRuns, ")"] }), selectedNodeStatus.activeRunIds &&
|
|
2486
|
+
selectedNodeStatus.activeRunIds.length > 0 ? (jsxRuntime.jsxs("div", { className: "mt-1", children: [jsxRuntime.jsx("div", { className: "text-[10px] text-blue-600", children: "RunIds:" }), jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1 mt-1", children: selectedNodeStatus.activeRunIds.map((runId, idx) => (jsxRuntime.jsx("span", { className: "text-[10px] px-1.5 py-0.5 bg-blue-100 border border-blue-300 rounded font-mono", children: runId }, idx))) })] })) : (jsxRuntime.jsx("div", { className: "text-[10px] text-blue-600 mt-1", children: "RunIds not available (some runs may have started without runId)" }))] })), !!selectedNodeStatus?.lastError && (jsxRuntime.jsx("div", { className: "mt-2 text-sm text-red-700 bg-red-50 border border-red-200 rounded px-2 py-1 break-words", children: String(selectedNodeStatus.lastError?.message ??
|
|
2457
2487
|
selectedNodeStatus.lastError) }))] })), jsxRuntime.jsxs("div", { className: "mb-2", children: [jsxRuntime.jsx("div", { className: "font-semibold mb-1", children: "Inputs" }), inputHandles.length === 0 ? (jsxRuntime.jsx("div", { className: "text-gray-500", children: "No inputs" })) : (inputHandles.map((h) => {
|
|
2458
2488
|
const typeId = sparkGraph.getInputTypeId(effectiveHandles.inputs, h);
|
|
2459
2489
|
const isLinked = def.edges.some((e) => e.target.nodeId === selectedNodeId &&
|