@bian-womp/spark-workbench 0.3.6 → 0.3.7
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 +42 -10
- package/lib/cjs/index.cjs.map +1 -1
- package/lib/cjs/src/core/InMemoryWorkbench.d.ts +6 -0
- package/lib/cjs/src/core/InMemoryWorkbench.d.ts.map +1 -1
- package/lib/cjs/src/misc/DefaultNodeHeader.d.ts.map +1 -1
- package/lib/cjs/src/misc/context/WorkbenchContext.provider.d.ts.map +1 -1
- package/lib/cjs/src/misc/context-menu/NodeContextMenu.d.ts.map +1 -1
- package/lib/cjs/src/runtime/RemoteGraphRunner.d.ts.map +1 -1
- package/lib/esm/index.js +43 -11
- package/lib/esm/index.js.map +1 -1
- package/lib/esm/src/core/InMemoryWorkbench.d.ts +6 -0
- package/lib/esm/src/core/InMemoryWorkbench.d.ts.map +1 -1
- package/lib/esm/src/misc/DefaultNodeHeader.d.ts.map +1 -1
- package/lib/esm/src/misc/context/WorkbenchContext.provider.d.ts.map +1 -1
- package/lib/esm/src/misc/context-menu/NodeContextMenu.d.ts.map +1 -1
- package/lib/esm/src/runtime/RemoteGraphRunner.d.ts.map +1 -1
- package/package.json +4 -4
package/lib/cjs/index.cjs
CHANGED
|
@@ -163,6 +163,23 @@ class InMemoryWorkbench extends AbstractWorkbench {
|
|
|
163
163
|
this._registry = registry;
|
|
164
164
|
this.emit("registryChanged", { registry });
|
|
165
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* Check if a node should auto run based on registry node description policy or node definition params policy.
|
|
168
|
+
* @param nodeId - The node ID to check
|
|
169
|
+
* @returns true if the node has autoRun enabled in either registry or params policy
|
|
170
|
+
*/
|
|
171
|
+
shouldNodeAutoRun(nodeId) {
|
|
172
|
+
const node = this._def.nodes.find((n) => n.nodeId === nodeId);
|
|
173
|
+
if (!node)
|
|
174
|
+
return false;
|
|
175
|
+
// Check registry node description policy
|
|
176
|
+
const desc = this._registry.nodes.get(node.typeId);
|
|
177
|
+
const registryAutoRun = desc?.policy?.autoRun === true;
|
|
178
|
+
// Check node definition params policy (takes precedence over registry)
|
|
179
|
+
const paramsAutoRun = node?.params?.policy?.autoRun === true;
|
|
180
|
+
// Node has autoRun if either registry or params sets it
|
|
181
|
+
return registryAutoRun || paramsAutoRun;
|
|
182
|
+
}
|
|
166
183
|
async load(def) {
|
|
167
184
|
this._def = { nodes: [...def.nodes], edges: [...def.edges] };
|
|
168
185
|
if (this.layout) {
|
|
@@ -1436,6 +1453,7 @@ class RemoteGraphRunner extends AbstractGraphRunner {
|
|
|
1436
1453
|
displayName: n.displayName,
|
|
1437
1454
|
inputs: n.inputs || {},
|
|
1438
1455
|
outputs: n.outputs || {},
|
|
1456
|
+
policy: n.policy || {},
|
|
1439
1457
|
impl: () => { },
|
|
1440
1458
|
});
|
|
1441
1459
|
}
|
|
@@ -4513,8 +4531,18 @@ function WorkbenchProvider({ wb, runner, overrides, uiVersion, children, }) {
|
|
|
4513
4531
|
setRunModeState(mode);
|
|
4514
4532
|
}, [runMode, runner]);
|
|
4515
4533
|
const runNodeAction = React.useCallback(async (nodeId) => {
|
|
4516
|
-
|
|
4517
|
-
|
|
4534
|
+
// Check if we're in auto mode or if node has autoRun policy
|
|
4535
|
+
const nodeHasAutoRun = wb.shouldNodeAutoRun(nodeId);
|
|
4536
|
+
const shouldUseTriggerExternal = runMode === "auto" || nodeHasAutoRun;
|
|
4537
|
+
if (shouldUseTriggerExternal) {
|
|
4538
|
+
// In auto mode or when node has autoRun, use triggerExternal with invalidate event
|
|
4539
|
+
await runner.triggerExternal(nodeId, { action: "invalidate" });
|
|
4540
|
+
}
|
|
4541
|
+
else {
|
|
4542
|
+
// In manual mode without autoRun, use computeNode
|
|
4543
|
+
await runner.computeNode(nodeId);
|
|
4544
|
+
}
|
|
4545
|
+
}, [runner, wb, runMode]);
|
|
4518
4546
|
const runFromHereAction = React.useCallback(async (nodeId) => {
|
|
4519
4547
|
await runner.runFromHere(nodeId);
|
|
4520
4548
|
}, [runner]);
|
|
@@ -4736,16 +4764,16 @@ function DefaultNodeHeader({ id, typeId, validation, right, showId, }) {
|
|
|
4736
4764
|
return (jsxRuntime.jsxs("div", { className: "flex items-center justify-center px-2 border-b border-solid border-gray-500 dark:border-gray-400 text-gray-600 dark:text-gray-300", style: {
|
|
4737
4765
|
maxHeight: NODE_HEADER_HEIGHT_PX,
|
|
4738
4766
|
minHeight: NODE_HEADER_HEIGHT_PX,
|
|
4739
|
-
}, children: [isEditing ? (jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: editValue, onChange: (e) => setEditValue(e.target.value), onBlur: handleSave, onKeyDown: handleKeyDown, onClick: (e) => e.stopPropagation(), onMouseDown: (e) => e.stopPropagation(), className: "flex-1 h-full text-sm bg-transparent border border-blue-500 rounded px-1 outline-none wb-nodrag", style: { lineHeight: `${NODE_HEADER_HEIGHT_PX}px` } })) : (jsxRuntime.jsx("strong", { className: `react-flow__node-title flex-1 h-full text-sm select-none truncate ${typeId ? "cursor-text" : ""}`, style: { lineHeight: `${NODE_HEADER_HEIGHT_PX}px` }, onDoubleClick: handleDoubleClick, title: typeId ? "Double-click to rename" : undefined, children: displayName })), jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4767
|
+
}, children: [isEditing ? (jsxRuntime.jsx("input", { ref: inputRef, type: "text", value: editValue, onChange: (e) => setEditValue(e.target.value), onBlur: handleSave, onKeyDown: handleKeyDown, onClick: (e) => e.stopPropagation(), onMouseDown: (e) => e.stopPropagation(), className: "flex-1 h-full text-sm bg-transparent border border-blue-500 rounded px-1 outline-none wb-nodrag", style: { lineHeight: `${NODE_HEADER_HEIGHT_PX}px` } })) : (jsxRuntime.jsx("strong", { className: `react-flow__node-title flex-1 h-full text-sm select-none truncate ${typeId ? "cursor-text" : ""}`, style: { lineHeight: `${NODE_HEADER_HEIGHT_PX}px` }, onDoubleClick: handleDoubleClick, title: typeId ? "Double-click to rename" : undefined, children: displayName })), jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [jsxRuntime.jsx("button", { onClick: (e) => {
|
|
4768
|
+
e.stopPropagation();
|
|
4769
|
+
void ctx.runNode(id);
|
|
4770
|
+
}, className: "w-4 h-4 flex items-center justify-center hover:bg-gray-200 dark:hover:bg-gray-700 rounded text-gray-600 dark:text-gray-400 hover:text-green-600 dark:hover:text-green-400 transition-colors", title: "Run node", children: jsxRuntime.jsx(react$1.PlayIcon, { size: 10, weight: "fill" }) }), ctx.runMode === "manual" && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("button", { onClick: (e) => {
|
|
4743
4771
|
e.stopPropagation();
|
|
4744
4772
|
void ctx.runFromHere(id);
|
|
4745
|
-
}, className: "w-4 h-4 flex items-center justify-center hover:bg-gray-200 dark:hover:bg-gray-700 rounded text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-400 transition-colors", title: "Run from here", children: jsxRuntime.jsx(react$1.
|
|
4773
|
+
}, className: "w-4 h-4 flex items-center justify-center hover:bg-gray-200 dark:hover:bg-gray-700 rounded text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-400 transition-colors", title: "Run from here", children: jsxRuntime.jsx(react$1.FastForwardIcon, { size: 10, weight: "fill" }) }), jsxRuntime.jsx("button", { onClick: (e) => {
|
|
4746
4774
|
e.stopPropagation();
|
|
4747
|
-
|
|
4748
|
-
}, className: "w-4 h-4 flex items-center justify-center hover:bg-gray-200 dark:hover:bg-gray-700 rounded text-gray-600 dark:text-gray-400 hover:text-
|
|
4775
|
+
ctx.abortNode(id);
|
|
4776
|
+
}, className: "w-4 h-4 flex items-center justify-center hover:bg-gray-200 dark:hover:bg-gray-700 rounded text-gray-600 dark:text-gray-400 hover:text-red-600 dark:hover:text-red-400 transition-colors", title: "Abort node", children: jsxRuntime.jsx(react$1.StopIcon, { size: 10, weight: "fill" }) })] })), right, validation.issues && validation.issues.length > 0 && (jsxRuntime.jsx(IssueBadge, { level: validation.issues.some((i) => i.level === "error")
|
|
4749
4777
|
? "error"
|
|
4750
4778
|
: "warning", size: 12, className: "w-3 h-3", title: validation.issues
|
|
4751
4779
|
.map((v) => `${v.code}: ${v.message}`)
|
|
@@ -5556,6 +5584,10 @@ function NodeContextMenu({ open, clientPos, nodeId, handlers, bakeableOutputs, r
|
|
|
5556
5584
|
const isStartNode = wb
|
|
5557
5585
|
? !wb.def.edges.some((e) => e.target.nodeId === nodeId)
|
|
5558
5586
|
: false;
|
|
5587
|
+
// Check if node has outbound edges (required for "Run workflow" / "Run from here")
|
|
5588
|
+
const hasOutboundEdges = wb
|
|
5589
|
+
? wb.def.edges.some((e) => e.source.nodeId === nodeId)
|
|
5590
|
+
: false;
|
|
5559
5591
|
// clamp
|
|
5560
5592
|
const MENU_MIN_WIDTH = 180;
|
|
5561
5593
|
const PADDING = 16;
|
|
@@ -5565,7 +5597,7 @@ function NodeContextMenu({ open, clientPos, nodeId, handlers, bakeableOutputs, r
|
|
|
5565
5597
|
return (jsxRuntime.jsxs("div", { ref: ref, tabIndex: -1, className: "fixed z-[1000] bg-white border border-gray-300 rounded-lg shadow-lg p-1 min-w-[180px] text-sm text-gray-700 select-none", style: { left: x, top: y }, onClick: (e) => e.stopPropagation(), onMouseDown: (e) => e.stopPropagation(), onWheel: (e) => e.stopPropagation(), onContextMenu: (e) => {
|
|
5566
5598
|
e.preventDefault();
|
|
5567
5599
|
e.stopPropagation();
|
|
5568
|
-
}, children: [jsxRuntime.jsxs("div", { className: "px-2 py-1 font-semibold text-gray-700", children: ["Node (", nodeId, ")"] }), jsxRuntime.jsx(ContextMenuButton, { label: "Delete", onClick: handlers.onDelete, shortcut: keyboardShortcuts.delete, enableKeyboardShortcuts: enableKeyboardShortcuts }), jsxRuntime.jsx(ContextMenuButton, { label: "Duplicate", onClick: handlers.onDuplicate, shortcut: keyboardShortcuts.duplicate, enableKeyboardShortcuts: enableKeyboardShortcuts }), jsxRuntime.jsx(ContextMenuButton, { label: "Duplicate with edges", onClick: handlers.onDuplicateWithEdges, shortcut: keyboardShortcuts.duplicateWithEdges, enableKeyboardShortcuts: enableKeyboardShortcuts }),
|
|
5600
|
+
}, children: [jsxRuntime.jsxs("div", { className: "px-2 py-1 font-semibold text-gray-700", children: ["Node (", nodeId, ")"] }), jsxRuntime.jsx(ContextMenuButton, { label: "Delete", onClick: handlers.onDelete, shortcut: keyboardShortcuts.delete, enableKeyboardShortcuts: enableKeyboardShortcuts }), jsxRuntime.jsx(ContextMenuButton, { label: "Duplicate", onClick: handlers.onDuplicate, shortcut: keyboardShortcuts.duplicate, enableKeyboardShortcuts: enableKeyboardShortcuts }), jsxRuntime.jsx(ContextMenuButton, { label: "Duplicate with edges", onClick: handlers.onDuplicateWithEdges, shortcut: keyboardShortcuts.duplicateWithEdges, enableKeyboardShortcuts: enableKeyboardShortcuts }), handlers.onRunNode && (jsxRuntime.jsx("button", { className: "block w-full text-left px-2 py-1 hover:bg-gray-100", onClick: handlers.onRunNode, children: "Run node" })), runMode === "manual" && handlers.onRunFromHere && hasOutboundEdges && (jsxRuntime.jsx("button", { className: "block w-full text-left px-2 py-1 hover:bg-gray-100", onClick: handlers.onRunFromHere, children: isStartNode ? "Run workflow" : "Run from here" })), jsxRuntime.jsx("div", { className: "h-px bg-gray-200 my-1" }), jsxRuntime.jsx(ContextMenuButton, { label: "Copy", onClick: handlers.onCopy, shortcut: keyboardShortcuts.copy, enableKeyboardShortcuts: enableKeyboardShortcuts }), jsxRuntime.jsx("button", { className: "block w-full text-left px-2 py-1 hover:bg-gray-100", onClick: handlers.onCopyId, children: "Copy Node ID" }), bakeableOutputs.length > 0 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: "h-px bg-gray-200 my-1" }), jsxRuntime.jsx("div", { className: "px-2 py-1 font-semibold text-gray-700", children: "Bake" }), bakeableOutputs.map((h) => (jsxRuntime.jsxs("button", { className: "block w-full text-left px-2 py-1 hover:bg-gray-100", onClick: () => handlers.onBake(h), children: ["Bake: ", h] }, h)))] }))] }));
|
|
5569
5601
|
}
|
|
5570
5602
|
|
|
5571
5603
|
function SelectionContextMenu({ open, clientPos, handlers, enableKeyboardShortcuts = true, keyboardShortcuts = {
|