Files
ai-video-fullstack/frontend/src/components/workflow/useNodeSpecs.ts
T
Xin Wang c2a39257ff Add workflow editor and node types support in frontend and backend
- Introduce a new workflow editor component for visualizing and managing workflows, allowing users to add nodes and define connections.
- Implement backend support for node types, including validation and constraints for workflow graphs.
- Add new API endpoints for retrieving node types and their specifications.
- Enhance the AssistantPage to integrate the workflow editor, enabling users to create and edit workflows directly.
- Update frontend components to support new workflow functionalities, including condition edges and generic nodes.
- Refactor existing code to accommodate the new workflow features and improve overall structure.
2026-06-15 10:12:41 +08:00

62 lines
1.5 KiB
TypeScript

"use client";
/**
* 拉取并缓存 /api/node-types 节点目录(每会话一次,模块级缓存)。
* 对齐 dograh 的 useNodeSpecs:规格随后端 + 刷新生效。
*/
import { useEffect, useRef, useState } from "react";
import { nodeTypesApi, type NodeTypesResponse } from "@/lib/api";
import {
toRuntimeSpec,
type NodeSpecMap,
type RuntimeNodeSpec,
} from "./specs";
let _cache: NodeTypesResponse | null = null;
type State = {
specs: RuntimeNodeSpec[];
byType: NodeSpecMap;
loading: boolean;
error: string | null;
};
function build(data: NodeTypesResponse | null): {
specs: RuntimeNodeSpec[];
byType: NodeSpecMap;
} {
const specs = (data?.nodeTypes ?? []).map(toRuntimeSpec);
const byType: NodeSpecMap = {};
for (const spec of specs) byType[spec.type] = spec;
return { specs, byType };
}
export function useNodeSpecs(): State {
const fetched = useRef(false);
const [state, setState] = useState<State>(() => {
const { specs, byType } = build(_cache);
return { specs, byType, loading: !_cache, error: null };
});
useEffect(() => {
if (_cache || fetched.current) return;
fetched.current = true;
nodeTypesApi
.list()
.then((data) => {
_cache = data;
const { specs, byType } = build(data);
setState({ specs, byType, loading: false, error: null });
})
.catch((err: unknown) => {
const message = err instanceof Error ? err.message : String(err);
setState((s) => ({ ...s, loading: false, error: message }));
});
}, []);
return state;
}