import { create } from "zustand"; import type { CanvasNodeDefinition } from "@/types/canvas-plugin"; import { CanvasNodeType } from "@/types/canvas"; const definitions = new Map(); const ownerByType = new Map(); // type -> pluginId(内置为 "builtin") // 注册表版本号,注册/卸载时自增,驱动创建菜单等 UI 重渲染 export const useNodeRegistryVersion = create<{ version: number }>(() => ({ version: 0 })); function bump() { useNodeRegistryVersion.setState((state) => ({ version: state.version + 1 })); } export function registerNodeDefinitions(defs: CanvasNodeDefinition[], pluginId = "builtin") { defs.forEach((def) => { definitions.set(def.type, def); ownerByType.set(def.type, pluginId); }); bump(); } export function unregisterPluginNodes(pluginId: string) { for (const [type, owner] of ownerByType) { if (owner !== pluginId) continue; definitions.delete(type); ownerByType.delete(type); } bump(); } export function getNodeDefinition(type: string) { return definitions.get(type); } export function getNodePluginId(type: string) { return ownerByType.get(type) || "builtin"; } export function listNodeDefinitions() { return Array.from(definitions.values()); } export function isRegisteredNodeType(type: string) { return definitions.has(type); } const FALLBACK_SPEC = { width: 340, height: 240, title: "节点", metadata: {} as CanvasNodeDefinition["defaultMetadata"] }; // 提供默认尺寸/标题/初始 metadata,createCanvasNode 与 agent-ops 复用 export function getNodeSpec(type: string) { const def = definitions.get(type); if (!def) return FALLBACK_SPEC; return { width: def.defaultSize.width, height: def.defaultSize.height, title: def.title, metadata: def.defaultMetadata }; } export function isBuiltinNodeType(type: string) { return (Object.values(CanvasNodeType) as string[]).includes(type); }