From 544a88f6a553e140a4d2d9c04bacbec670d9ff32 Mon Sep 17 00:00:00 2001 From: bymyself Date: Mon, 28 Jul 2025 22:06:14 -0700 Subject: [PATCH] [fix] only create frontend_only node definitions for nodes without backend definitions Fixes #4566 The previous implementation created frontend_only definitions for ALL LiteGraph registered nodes, then relied on object spreading to overwrite them with backend definitions. This fragile pattern could fail in certain conditions, particularly in subgraphs, causing all nodes to show 'frontend_only' badges. The fix now only creates frontend_only definitions for nodes that genuinely lack backend definitions, eliminating the reliance on object spread ordering and preventing incorrect badge display. --- src/scripts/app.ts | 41 ++++++++++++++++++++++---------------- src/stores/nodeDefStore.ts | 6 ++++-- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/scripts/app.ts b/src/scripts/app.ts index 39b2d14a00..7feee17dcb 100644 --- a/src/scripts/app.ts +++ b/src/scripts/app.ts @@ -887,26 +887,33 @@ export class ComfyApp { private updateVueAppNodeDefs(defs: Record) { // Frontend only nodes registered by custom nodes. // Example: https://github.com/rgthree/rgthree-comfy/blob/dd534e5384be8cf0c0fa35865afe2126ba75ac55/src_web/comfyui/fast_groups_bypasser.ts#L10 - const rawDefs: Record = Object.fromEntries( - Object.entries(LiteGraph.registered_node_types).map(([name, node]) => [ + + // Only create frontend_only definitions for nodes that don't have backend definitions + const frontendOnlyDefs: Record = {} + for (const [name, node] of Object.entries( + LiteGraph.registered_node_types + )) { + // Skip if we already have a backend definition or system definition + if (name in defs || name in SYSTEM_NODE_DEFS) { + continue + } + + frontendOnlyDefs[name] = { name, - { - name, - display_name: name, - category: node.category || '__frontend_only__', - input: { required: {}, optional: {} }, - output: [], - output_name: [], - output_is_list: [], - output_node: false, - python_module: 'custom_nodes.frontend_only', - description: `Frontend only node for ${name}` - } as ComfyNodeDefV1 - ]) - ) + display_name: name, + category: node.category || '__frontend_only__', + input: { required: {}, optional: {} }, + output: [], + output_name: [], + output_is_list: [], + output_node: false, + python_module: 'custom_nodes.frontend_only', + description: `Frontend only node for ${name}` + } as ComfyNodeDefV1 + } const allNodeDefs = { - ...rawDefs, + ...frontendOnlyDefs, ...defs, ...SYSTEM_NODE_DEFS } diff --git a/src/stores/nodeDefStore.ts b/src/stores/nodeDefStore.ts index fe836110f2..8a5a46ade4 100644 --- a/src/stores/nodeDefStore.ts +++ b/src/stores/nodeDefStore.ts @@ -334,8 +334,10 @@ export const useNodeDefStore = defineStore('nodeDef', () => { } function fromLGraphNode(node: LGraphNode): ComfyNodeDefImpl | null { // Frontend-only nodes don't have nodeDef - // @ts-expect-error Optional chaining used in index - return nodeDefsByName.value[node.constructor?.nodeData?.name] ?? null + const nodeTypeName = node.constructor?.nodeData?.name + if (!nodeTypeName) return null + const nodeDef = nodeDefsByName.value[nodeTypeName] ?? null + return nodeDef } /**