Compare commits

...

4 Commits

Author SHA1 Message Date
Glary-Bot
25234055c6 refactor: relocate PRIMITIVE_NODE_CATEGORY to src/constants
Move the shared category constant to src/constants/primitiveNodes.ts so
extensions and stores import a static value without pulling the Pinia
store into extension code. Mirrors the existing pattern used by
ESSENTIALS_CATEGORY_CANONICAL in src/constants/essentialsNodes.

Drop the change-detector test that re-asserted the constant against its
literal value; the SYSTEM_NODE_DEFS contract test now compares directly
to 'utils/primitive', which is the meaningful behavioral assertion. The
tree-routing test continues to cover the runtime placement.

Addresses CodeRabbit follow-up review.
2026-05-06 18:12:05 +00:00
Glary-Bot
cb5adaeae7 refactor: share PRIMITIVE_NODE_CATEGORY constant between sync points
Extract 'utils/primitive' to a single PRIMITIVE_NODE_CATEGORY constant
exported from nodeDefStore.ts so widgetInputs.ts and SYSTEM_NODE_DEFS
reference one symbol. Prevents silent desync between the runtime
LiteGraph registration and the SYSTEM_NODE_DEFS descriptor if either
site is edited in isolation. Addresses CodeRabbit review feedback.
2026-05-06 18:02:40 +00:00
Glary-Bot
3aaa5ff72c test: assert PrimitiveNode lands in utils/primitive tree branch
Add a behavior test that builds the node tree from SYSTEM_NODE_DEFS
and verifies PrimitiveNode is routed under utils/primitive while the
remaining frontend-only virtual nodes (Reroute, Note, MarkdownNote)
stay flat under utils. Addresses code review feedback that the prior
test only asserted the constant value.
2026-05-06 17:41:34 +00:00
Glary-Bot
d4a6d02fcd feat: move PrimitiveNode to utils/primitive subcategory
Reassign the frontend-registered PrimitiveNode from the flat 'utils'
category to a 'utils/primitive' subcategory, keeping the runtime
LiteGraph registration (widgetInputs.ts) and the SYSTEM_NODE_DEFS
descriptor (nodeDefStore.ts) in sync.

The 'primitive' translation key already exists in all 12 locales, and
runtime category resolution splits on '/' and translates each segment
independently, so no new i18n entries are required.

Add unit tests asserting the PrimitiveNode subcategory and that the
remaining frontend-only virtual nodes (Reroute, Note, MarkdownNote)
remain under the flat 'utils' category.
2026-05-06 04:04:05 +00:00
4 changed files with 53 additions and 3 deletions

View File

@@ -0,0 +1 @@
export const PRIMITIVE_NODE_CATEGORY = 'utils/primitive'

View File

@@ -23,6 +23,7 @@ import {
} from '@/scripts/widgets'
import { isPrimitiveNode } from '@/renderer/utils/nodeTypeGuards'
import { CONFIG, GET_CONFIG } from '@/services/litegraphService'
import { PRIMITIVE_NODE_CATEGORY } from '@/constants/primitiveNodes'
import { mergeInputSpec } from '@/utils/nodeDefUtil'
import { applyTextReplacements } from '@/utils/searchAndReplace'
@@ -624,6 +625,6 @@ app.registerExtension({
title: 'Primitive'
})
)
PrimitiveNode.category = 'utils'
PrimitiveNode.category = PRIMITIVE_NODE_CATEGORY
}
})

View File

@@ -3,7 +3,12 @@ import { setActivePinia } from 'pinia'
import { beforeEach, describe, expect, it } from 'vitest'
import type { ComfyNodeDef } from '@/schemas/nodeDefSchema'
import { useNodeDefStore } from '@/stores/nodeDefStore'
import {
ComfyNodeDefImpl,
SYSTEM_NODE_DEFS,
buildNodeDefTree,
useNodeDefStore
} from '@/stores/nodeDefStore'
import type { NodeDefFilter } from '@/stores/nodeDefStore'
describe('useNodeDefStore', () => {
@@ -359,4 +364,46 @@ describe('useNodeDefStore', () => {
expect(filterCallCount).toBe(10 * 5)
})
})
describe('SYSTEM_NODE_DEFS', () => {
it('places PrimitiveNode under the utils/primitive subcategory', () => {
expect(SYSTEM_NODE_DEFS.PrimitiveNode.category).toBe('utils/primitive')
})
it('keeps remaining frontend-only virtual nodes under the flat utils category', () => {
expect(SYSTEM_NODE_DEFS.Reroute.category).toBe('utils')
expect(SYSTEM_NODE_DEFS.Note.category).toBe('utils')
expect(SYSTEM_NODE_DEFS.MarkdownNote.category).toBe('utils')
})
it('routes PrimitiveNode into the utils/primitive branch of the node tree', () => {
const systemDefs = Object.values(SYSTEM_NODE_DEFS).map(
(def) => new ComfyNodeDefImpl(def)
)
const tree = buildNodeDefTree(systemDefs)
const utilsBranch = tree.children?.find(
(child) => child.label === 'utils'
)
expect(utilsBranch).toBeDefined()
const primitiveBranch = utilsBranch?.children?.find(
(child) => child.label === 'primitive'
)
expect(primitiveBranch).toBeDefined()
const primitiveLeaf = primitiveBranch?.children?.find(
(child) => child.data?.name === 'PrimitiveNode'
)
expect(primitiveLeaf).toBeDefined()
const flatUtilsLeaves =
utilsBranch?.children
?.filter((child) => child.label !== 'primitive')
.map((child) => child.data?.name) ?? []
expect(flatUtilsLeaves).toEqual(
expect.arrayContaining(['Reroute', 'Note', 'MarkdownNote'])
)
})
})
})

View File

@@ -25,6 +25,7 @@ import { useSettingStore } from '@/platform/settings/settingStore'
import { NodeSearchService } from '@/services/nodeSearchService'
import { useSubgraphStore } from '@/stores/subgraphStore'
import { ESSENTIALS_CATEGORY_CANONICAL } from '@/constants/essentialsNodes'
import { PRIMITIVE_NODE_CATEGORY } from '@/constants/primitiveNodes'
import { CORE_NODE_MODULES, getNodeSource } from '@/types/nodeSource'
import type { NodeSource } from '@/types/nodeSource'
import type { TreeNode } from '@/types/treeExplorerTypes'
@@ -212,7 +213,7 @@ export const SYSTEM_NODE_DEFS: Record<string, ComfyNodeDefV1> = {
PrimitiveNode: {
name: 'PrimitiveNode',
display_name: 'Primitive',
category: 'utils',
category: PRIMITIVE_NODE_CATEGORY,
input: { required: {}, optional: {} },
output: ['*'],
output_name: ['connect to widget input'],