Comfy-Org / Comfy-Org/ComfyUI_frontend
Vue node renderer ignores CORE_JOIN_ORDER: badges render as 'BETA #1' where the canvas renders '#1 BETA'
- Dominant language
- TypeScript
- Stars
- 2k
- Forks
- 699
- Avg merge
- 1d 7h
- Merged PRs (30d)
- 490
Description
### Summary
In Vue-nodes mode, a node's core badges render in a different order than on the classic canvas. Vue
shows `BETA #1 my_pack`; the canvas shows `#1 BETA my_pack`.
This is pre-existing on `main` and is already pinned by three `it.fails` in
`src/composables/node/badgeRendererParity.test.ts`. Filing it so the marker has an issue behind it.
### Reproduction
Flip the three `it.fails` to `it` in `src/composables/node/badgeRendererParity.test.ts` and run it:
```
AssertionError: expected 'BETA #1 my_pack' to be '#1 BETA my_pack'
Expected: "#1 BETA my_pack"
Received: "BETA #1 my_pack"
```
Three cases: custom node under ShowAll, custom node under HideBuiltIn, core node under ShowAll.
### Root cause
`computeBadges` emits core rows in array order — **lifecycle, id, source**:
```ts
// src/systems/badgeSystem.ts:69-71
const coreParts: [CoreBadgePart, NodeBadgeMode, string][] = [
['lifecycle', badgeModes.lifecycle, nodeDef?.lifecycleText ?? ''],
['id', badgeModes.id, `#${nodeId}`],
['source', badgeModes.source, nodeDef?.sourceText ?? '']
]
```
The classic canvas **re-sorts** them before drawing:
```ts
// src/types/badgeData.ts:2
export const CORE_JOIN_ORDER = ['id', 'lifecycle', 'source'] as const
// src/lib/litegraph/src/nodeBadgeDraw.ts:24-32 (joinedCoreText)
CORE_JOIN_ORDER.map((part) => byPart.get(part) ?? '').filter(...).join(' ')
```
`usePartitionedBadges` iterates `nodeBadges(node)` in **emission order** and pushes straight into
`core[]`, never applying `CORE_JOIN_ORDER`:
```ts
// src/renderer/extensions/vueNodes/composables/usePartitionedBadges.ts:43-53
for (const row of node ? nodeBadges(node) : []) {
...
core.push({ text: ... })
}
```
So `CORE_JOIN_ORDER` is documented as *"Legacy canvas joins the core parts into a single badge in this
order"* and is honoured by exactly one of the two renderers.
### Suggested fix
Sort `core` by `CORE_JOIN_ORDER` in `usePartitionedBadges`, so the ordering contract lives with the
data rather than in each renderer. That would flip the three `it.fails` to passing tests.
### Scope
`Comfy.VueNodes.Enabled` is `defaultValue: false` but
`defaultsByInstallVersion: { '1.41.0': isCloud || isDesktop }`
(`src/platform/settings/constants/coreSettings.ts:1197-1207`), so OSS browser users see the correct
order and **Cloud/Desktop users see `BETA #1` today**. Cosmetic only.
### Context
Found while root-causing the badge-parity failure on #14246. Not introduced by that PR — the branch
actually fixes one adjacent case (`hides built-in Vue badges` is `it.fails` on `main` and passes on
the branch, i.e. #15567).
Related: #15567, #15619, #15568.
Contributor guide
Assessment
This issue has not been assessed yet.