Browse Source

feat(43-01): add RouterNodeData type, defaults, and executor

- Add 'router' to NodeType union in types/nodes.ts
- Add RouterNodeData interface (extends BaseNodeData, no internal state)
- Add RouterNodeData to WorkflowNodeData union
- Add router dimensions (200x80) to nodeDefaults.ts and validation.ts
- Add router default data (empty object) to both files
- Add executeRouter pure passthrough function to simpleNodeExecutors.ts
- Add RouterNode export to components/nodes/index.ts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
handoff-20260429-1057
shrimbly 5 months ago
parent
commit
88f66b58a3
  1. 1
      src/components/nodes/index.ts
  2. 4
      src/lib/quickstart/validation.ts
  3. 11
      src/store/execution/simpleNodeExecutors.ts
  4. 4
      src/store/utils/nodeDefaults.ts
  5. 9
      src/types/nodes.ts

1
src/components/nodes/index.ts

@ -17,4 +17,5 @@ export { VideoStitchNode } from "./VideoStitchNode";
export { EaseCurveNode } from "./EaseCurveNode"; export { EaseCurveNode } from "./EaseCurveNode";
export { VideoTrimNode } from "./VideoTrimNode"; export { VideoTrimNode } from "./VideoTrimNode";
export { VideoFrameGrabNode } from "./VideoFrameGrabNode"; export { VideoFrameGrabNode } from "./VideoFrameGrabNode";
export { RouterNode } from "./RouterNode";
export { GroupNode } from "./GroupNode"; export { GroupNode } from "./GroupNode";

4
src/lib/quickstart/validation.ts

@ -31,6 +31,7 @@ const VALID_NODE_TYPES: NodeType[] = [
"easeCurve", "easeCurve",
"videoTrim", "videoTrim",
"videoFrameGrab", "videoFrameGrab",
"router",
"glbViewer", "glbViewer",
]; ];
@ -57,6 +58,7 @@ const DEFAULT_DIMENSIONS: Record<NodeType, { width: number; height: number }> =
easeCurve: { width: 340, height: 480 }, easeCurve: { width: 340, height: 480 },
videoTrim: { width: 360, height: 360 }, videoTrim: { width: 360, height: 360 },
videoFrameGrab: { width: 320, height: 320 }, videoFrameGrab: { width: 320, height: 320 },
router: { width: 200, height: 80 },
glbViewer: { width: 360, height: 380 }, glbViewer: { width: 360, height: 380 },
}; };
@ -387,6 +389,8 @@ function createDefaultNodeData(type: NodeType): WorkflowNodeData {
status: "idle", status: "idle",
error: null, error: null,
}; };
case "router":
return {};
case "glbViewer": case "glbViewer":
return { return {
glbUrl: null, glbUrl: null,

11
src/store/execution/simpleNodeExecutors.ts

@ -315,6 +315,17 @@ export async function executeImageCompare(ctx: NodeExecutionContext): Promise<vo
}); });
} }
/**
* Router node: pure passthrough with brief status flash.
*/
export async function executeRouter(ctx: NodeExecutionContext): Promise<void> {
// Router is pure passthrough — data flows via edge traversal in getConnectedInputs.
// Brief status flash to show execution occurred.
ctx.updateNodeData(ctx.node.id, { status: "loading" });
await new Promise(resolve => setTimeout(resolve, 50));
ctx.updateNodeData(ctx.node.id, { status: "complete" });
}
/** /**
* GLB Viewer node: receives 3D model URL from upstream, fetches and loads it. * GLB Viewer node: receives 3D model URL from upstream, fetches and loads it.
*/ */

4
src/store/utils/nodeDefaults.ts

@ -18,6 +18,7 @@ import {
EaseCurveNodeData, EaseCurveNodeData,
VideoTrimNodeData, VideoTrimNodeData,
VideoFrameGrabNodeData, VideoFrameGrabNodeData,
RouterNodeData,
GLBViewerNodeData, GLBViewerNodeData,
WorkflowNodeData, WorkflowNodeData,
GroupColor, GroupColor,
@ -49,6 +50,7 @@ export const defaultNodeDimensions: Record<NodeType, { width: number; height: nu
easeCurve: { width: 340, height: 480 }, easeCurve: { width: 340, height: 480 },
videoTrim: { width: 360, height: 360 }, videoTrim: { width: 360, height: 360 },
videoFrameGrab: { width: 320, height: 320 }, videoFrameGrab: { width: 320, height: 320 },
router: { width: 200, height: 80 },
glbViewer: { width: 360, height: 380 }, glbViewer: { width: 360, height: 380 },
}; };
@ -283,6 +285,8 @@ export const createDefaultNodeData = (type: NodeType): WorkflowNodeData => {
status: "idle", status: "idle",
error: null, error: null,
} as VideoFrameGrabNodeData; } as VideoFrameGrabNodeData;
case "router":
return {} as RouterNodeData;
case "glbViewer": case "glbViewer":
return { return {
glbUrl: null, glbUrl: null,

9
src/types/nodes.ts

@ -41,6 +41,7 @@ export type NodeType =
| "easeCurve" | "easeCurve"
| "videoTrim" | "videoTrim"
| "videoFrameGrab" | "videoFrameGrab"
| "router"
| "generate3d" | "generate3d"
| "glbViewer"; | "glbViewer";
@ -349,6 +350,13 @@ export interface VideoFrameGrabNodeData extends BaseNodeData {
error: string | null; error: string | null;
} }
/**
* Router node - pure passthrough routing node with dynamic multi-type handles
*/
export interface RouterNodeData extends BaseNodeData {
// No internal state - all routing is derived from edge connections
}
/** /**
* Split Grid node - splits image into grid cells for parallel processing * Split Grid node - splits image into grid cells for parallel processing
*/ */
@ -407,6 +415,7 @@ export type WorkflowNodeData =
| EaseCurveNodeData | EaseCurveNodeData
| VideoTrimNodeData | VideoTrimNodeData
| VideoFrameGrabNodeData | VideoFrameGrabNodeData
| RouterNodeData
| GLBViewerNodeData; | GLBViewerNodeData;
/** /**

Loading…
Cancel
Save