From dbfeb226473bdd05ef8740d8d3cf5cc972a2b3dd Mon Sep 17 00:00:00 2001 From: shrimbly Date: Wed, 25 Feb 2026 22:50:40 +1300 Subject: [PATCH] feat(44-02): add Switch execution and toggle-aware data flow - Export executeSwitch from execution/index.ts - Import executeSwitch in workflowStore.ts - Add switch case to executeWorkflow (after router) - Add switch case to regenerateNode (after router) - Import SwitchNodeData in connectedInputs.ts - Add Switch passthrough logic with toggle filtering in connectedInputs.ts - Disabled outputs block data flow (no downstream input) - Enabled outputs recursively traverse upstream (same pattern as Router) - Edge type determined by switch inputType field Co-Authored-By: Claude Opus 4.6 --- src/store/execution/index.ts | 1 + src/store/utils/connectedInputs.ts | 32 ++++++++++++++++++++++++++++++ src/store/workflowStore.ts | 7 +++++++ 3 files changed, 40 insertions(+) diff --git a/src/store/execution/index.ts b/src/store/execution/index.ts index 3f3c2466..5e5776e2 100644 --- a/src/store/execution/index.ts +++ b/src/store/execution/index.ts @@ -18,6 +18,7 @@ export { executeImageCompare, executeGlbViewer, executeRouter, + executeSwitch, } from "./simpleNodeExecutors"; export { executeNanoBanana } from "./nanoBananaExecutor"; diff --git a/src/store/utils/connectedInputs.ts b/src/store/utils/connectedInputs.ts index 72d4443f..e4824603 100644 --- a/src/store/utils/connectedInputs.ts +++ b/src/store/utils/connectedInputs.ts @@ -24,6 +24,7 @@ import { PromptConstructorNodeData, LLMGenerateNodeData, GLBViewerNodeData, + SwitchNodeData, } from "@/types"; /** @@ -191,6 +192,37 @@ export function getConnectedInputsPure( return; // Skip normal getSourceOutput processing for this edge } + // Switch passthrough — traverse upstream if output is enabled + if (sourceNode.type === "switch") { + const switchData = sourceNode.data as SwitchNodeData; + const switchId = edge.sourceHandle; // Handle ID matches switch entry id + const switchEntry = switchData.switches?.find(s => s.id === switchId); + + // Skip disabled outputs — data does not flow through disabled switches + if (!switchEntry || !switchEntry.enabled) { + return; // Block this path + } + + // Enabled switch: recursively get upstream data (same pattern as router) + const switchInputs = getConnectedInputsPure(sourceNode.id, nodes, edges, _visited); + const edgeType = switchData.inputType; + + if (edgeType === "image") { + images.push(...switchInputs.images); + } else if (edgeType === "text") { + if (switchInputs.text) text = switchInputs.text; + } else if (edgeType === "video") { + videos.push(...switchInputs.videos); + } else if (edgeType === "audio") { + audio.push(...switchInputs.audio); + } else if (edgeType === "3d") { + if (switchInputs.model3d) model3d = switchInputs.model3d; + } else if (edgeType === "easeCurve") { + if (switchInputs.easeCurve) easeCurve = switchInputs.easeCurve; + } + return; // Skip normal getSourceOutput processing + } + const handleId = edge.targetHandle; const { type, value } = getSourceOutput( sourceNode, diff --git a/src/store/workflowStore.ts b/src/store/workflowStore.ts index 45cafc2f..29e3026c 100644 --- a/src/store/workflowStore.ts +++ b/src/store/workflowStore.ts @@ -78,6 +78,7 @@ import { executeVideoFrameGrab, executeGlbViewer, executeRouter, + executeSwitch, } from "./execution"; import type { NodeExecutionContext } from "./execution"; export type { LevelGroup } from "./utils/executionUtils"; @@ -1012,6 +1013,9 @@ const workflowStoreImpl: StateCreator = (set, get) => ({ case "router": await executeRouter(executionCtx); break; + case "switch": + await executeSwitch(executionCtx); + break; } }; // End of executeSingleNode helper @@ -1333,6 +1337,9 @@ const workflowStoreImpl: StateCreator = (set, get) => ({ case "router": await executeRouter(executionCtx); break; + case "switch": + await executeSwitch(executionCtx); + break; } };