Skip to content

Commit ee03616

Browse files
committed
useNodeManager Hook
1 parent 34446e1 commit ee03616

File tree

1 file changed

+229
-0
lines changed

1 file changed

+229
-0
lines changed

src/hooks/useNodeManager.ts

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
import type { Node } from "@xyflow/react";
2+
import { useCallback, useMemo } from "react";
3+
4+
import type { NodeType } from "@/nodeManager";
5+
import { useComponentSpec } from "@/providers/ComponentSpecProvider";
6+
7+
export const useNodeManager = () => {
8+
const { nodeManager } = useComponentSpec();
9+
10+
// Core NodeManager operations
11+
const getStableNodeId = useCallback(
12+
(taskId: string, nodeType: NodeType): string => {
13+
return nodeManager.getNodeId(taskId, nodeType);
14+
},
15+
[nodeManager],
16+
);
17+
18+
const getTaskIdFromNodeId = useCallback(
19+
(nodeId: string): string | undefined => {
20+
return nodeManager.getTaskId(nodeId);
21+
},
22+
[nodeManager],
23+
);
24+
25+
const updateTaskId = useCallback(
26+
(oldTaskId: string, newTaskId: string): void => {
27+
nodeManager.updateTaskId(oldTaskId, newTaskId);
28+
},
29+
[nodeManager],
30+
);
31+
32+
const removeNode = useCallback(
33+
(taskId: string): void => {
34+
nodeManager.removeNode(taskId);
35+
},
36+
[nodeManager],
37+
);
38+
39+
const isManaged = useCallback(
40+
(nodeId: string): boolean => {
41+
return nodeManager.isManaged(nodeId);
42+
},
43+
[nodeManager],
44+
);
45+
46+
const getNodeType = useCallback(
47+
(nodeId: string): NodeType | undefined => {
48+
return nodeManager.getNodeType(nodeId);
49+
},
50+
[nodeManager],
51+
);
52+
53+
// Migration utilities
54+
const migrateNodes = useCallback(
55+
(
56+
nodes: Node[],
57+
): { updatedNodes: Node[]; migrationMap: Record<string, string> } => {
58+
return nodeManager.migrateExistingNodes(nodes);
59+
},
60+
[nodeManager],
61+
);
62+
63+
const migrateNodeToStableId = useCallback(
64+
(legacyNodeId: string, nodeType: NodeType): string => {
65+
let taskId: string;
66+
67+
switch (nodeType) {
68+
case "task":
69+
taskId = legacyNodeId.replace(/^task_/, "");
70+
break;
71+
case "input":
72+
taskId = legacyNodeId.replace(/^input_/, "");
73+
break;
74+
case "output":
75+
taskId = legacyNodeId.replace(/^output_/, "");
76+
break;
77+
case "taskInput":
78+
taskId = legacyNodeId.replace(/^taskInput_/, "");
79+
break;
80+
case "taskOutput":
81+
taskId = legacyNodeId.replace(/^taskOutput_/, "");
82+
break;
83+
default:
84+
throw new Error(`Unknown node type: ${nodeType}`);
85+
}
86+
87+
return nodeManager.getNodeId(taskId, nodeType);
88+
},
89+
[nodeManager],
90+
);
91+
92+
// Batch operations
93+
const batchUpdateTaskIds = useCallback(
94+
(
95+
updates: Array<{
96+
oldTaskId: string;
97+
newTaskId: string;
98+
nodeType: NodeType;
99+
}>,
100+
): void => {
101+
nodeManager.batchUpdateTaskIds(updates);
102+
},
103+
[nodeManager],
104+
);
105+
106+
// Input/Output specific utilities
107+
const getInputNodeId = useCallback(
108+
(inputName: string): string => {
109+
return nodeManager.getNodeId(inputName, "input");
110+
},
111+
[nodeManager],
112+
);
113+
114+
const getOutputNodeId = useCallback(
115+
(outputName: string): string => {
116+
return nodeManager.getNodeId(outputName, "output");
117+
},
118+
[nodeManager],
119+
);
120+
121+
const getTaskNodeId = useCallback(
122+
(taskId: string): string => {
123+
return nodeManager.getNodeId(taskId, "task");
124+
},
125+
[nodeManager],
126+
);
127+
128+
const getTaskInputNodeId = useCallback(
129+
(taskId: string, inputName: string): string => {
130+
return nodeManager.getTaskHandleNodeId(taskId, inputName, "taskInput");
131+
},
132+
[nodeManager],
133+
);
134+
135+
const getTaskOutputNodeId = useCallback(
136+
(taskId: string, outputName: string): string => {
137+
return nodeManager.getTaskHandleNodeId(taskId, outputName, "taskOutput");
138+
},
139+
[nodeManager],
140+
);
141+
142+
// Helper to get handle info from node ID
143+
const getHandleInfo = useCallback(
144+
(nodeId: string): { taskId: string; handleName: string } | undefined => {
145+
return nodeManager.getHandleInfo(nodeId);
146+
},
147+
[nodeManager],
148+
);
149+
150+
// Renaming utilities with automatic sync
151+
const renameTask = useCallback(
152+
(oldTaskId: string, newTaskId: string): void => {
153+
updateTaskId(oldTaskId, newTaskId);
154+
// NodeManager sync will happen automatically in ComponentSpecProvider
155+
},
156+
[updateTaskId],
157+
);
158+
159+
const renameInput = useCallback(
160+
(oldInputName: string, newInputName: string): void => {
161+
updateTaskId(oldInputName, newInputName); // Inputs use 1:1 mapping
162+
},
163+
[updateTaskId],
164+
);
165+
166+
const renameOutput = useCallback(
167+
(oldOutputName: string, newOutputName: string): void => {
168+
updateTaskId(oldOutputName, newOutputName); // Outputs use 1:1 mapping
169+
},
170+
[updateTaskId],
171+
);
172+
173+
// Return all utilities as a stable object
174+
return useMemo(
175+
() => ({
176+
// Core operations
177+
getStableNodeId,
178+
getTaskIdFromNodeId,
179+
updateTaskId,
180+
removeNode,
181+
isManaged,
182+
getNodeType,
183+
184+
// Migration
185+
migrateNodes,
186+
migrateNodeToStableId,
187+
188+
// Batch operations
189+
batchUpdateTaskIds,
190+
191+
// Specific node type utilities
192+
getInputNodeId,
193+
getOutputNodeId,
194+
getTaskNodeId,
195+
getTaskInputNodeId,
196+
getTaskOutputNodeId,
197+
getHandleInfo,
198+
199+
// Renaming
200+
renameTask,
201+
renameInput,
202+
renameOutput,
203+
204+
// Direct access to NodeManager for advanced use cases
205+
nodeManager,
206+
}),
207+
[
208+
getStableNodeId,
209+
getTaskIdFromNodeId,
210+
updateTaskId,
211+
removeNode,
212+
isManaged,
213+
getNodeType,
214+
migrateNodes,
215+
migrateNodeToStableId,
216+
batchUpdateTaskIds,
217+
getInputNodeId,
218+
getOutputNodeId,
219+
getTaskNodeId,
220+
getTaskInputNodeId,
221+
getTaskOutputNodeId,
222+
getHandleInfo,
223+
renameTask,
224+
renameInput,
225+
renameOutput,
226+
nodeManager,
227+
],
228+
);
229+
};

0 commit comments

Comments
 (0)