refactor: remove unnecessary promotionList wrapper

Move null-guard into parseProxyWidgets and inline calls directly.

Delete promotionList.ts and its test file.

Amp-Thread-ID: https://ampcode.com/threads/T-019c554d-3032-771f-88e4-5ec40472504c
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Alexander Brown
2026-02-12 20:42:26 -08:00
parent dde845bbfd
commit 5de9eaccf4
5 changed files with 7 additions and 72 deletions

View File

@@ -1,52 +0,0 @@
import { describe, expect, it } from 'vitest'
import type { ProxyWidgetsProperty } from '@/core/schemas/proxyWidget'
import type { NodeProperty } from '@/lib/litegraph/src/LGraphNode'
import type { SubgraphNode } from '@/lib/litegraph/src/subgraph/SubgraphNode'
import { getPromotionList } from './promotionList'
function mockSubgraphNode(proxyWidgets?: NodeProperty) {
return {
properties: { proxyWidgets }
} satisfies Partial<
Omit<SubgraphNode, 'constructor'>
> as unknown as SubgraphNode
}
describe('getPromotionList', () => {
it('returns empty array for node with no proxyWidgets property', () => {
const node = mockSubgraphNode(undefined)
expect(getPromotionList(node)).toEqual([])
})
it('returns empty array for empty proxyWidgets', () => {
const node = mockSubgraphNode([])
expect(getPromotionList(node)).toEqual([])
})
it('parses valid promotion entries', () => {
const entries = [
['42', 'seed'],
['7', 'steps']
] satisfies ProxyWidgetsProperty
const node = mockSubgraphNode(entries)
expect(getPromotionList(node)).toEqual(entries)
})
it('handles string-serialized proxyWidgets (JSON)', () => {
const entries = [['42', 'seed']] satisfies ProxyWidgetsProperty
const node = mockSubgraphNode(JSON.stringify(entries))
expect(getPromotionList(node)).toEqual(entries)
})
it('throws on invalid format', () => {
const node = mockSubgraphNode('not-valid-json{{{')
expect(() => getPromotionList(node)).toThrow()
})
it('throws on structurally invalid data', () => {
const node = mockSubgraphNode([['only-one-element']])
expect(() => getPromotionList(node)).toThrow()
})
})

View File

@@ -1,15 +0,0 @@
import type { ProxyWidgetsProperty } from '@/core/schemas/proxyWidget'
import { parseProxyWidgets } from '@/core/schemas/proxyWidget'
import type { SubgraphNode } from '@/lib/litegraph/src/subgraph/SubgraphNode'
/**
* Returns the list of promoted widget entries from a SubgraphNode.
* Each entry is a [nodeId, widgetName] tuple referencing an interior widget.
*
* This is the single entry point for reading the promotion list,
* replacing direct access to `node.properties.proxyWidgets`.
*/
export function getPromotionList(node: SubgraphNode): ProxyWidgetsProperty {
if (node.properties.proxyWidgets == null) return []
return parseProxyWidgets(node.properties.proxyWidgets)
}

View File

@@ -1,6 +1,5 @@
import { parseProxyWidgets } from '@/core/schemas/proxyWidget'
import type { ProxyWidgetsProperty } from '@/core/schemas/proxyWidget'
import { getPromotionList } from '@/core/graph/subgraph/promotionList'
import { parseProxyWidgets } from '@/core/schemas/proxyWidget'
import { t } from '@/i18n'
import type {
IContextMenuValue,
@@ -180,7 +179,7 @@ export function promoteRecommendedWidgets(subgraphNode: SubgraphNode) {
export function pruneDisconnected(subgraphNode: SubgraphNode) {
const { resolvePromotedWidget } = useWidgetValueStore()
const promotionList = getPromotionList(subgraphNode)
const promotionList = parseProxyWidgets(subgraphNode.properties.proxyWidgets)
subgraphNode.properties.proxyWidgets = promotionList.filter(
([nodeId, widgetName]) =>
resolvePromotedWidget(subgraphNode.subgraph, nodeId, widgetName) !== null

View File

@@ -9,6 +9,7 @@ export type ProxyWidgetsProperty = z.infer<typeof proxyWidgetsPropertySchema>
export function parseProxyWidgets(
property: NodeProperty | undefined
): ProxyWidgetsProperty {
if (property == null) return []
if (typeof property === 'string') property = JSON.parse(property)
const result = proxyWidgetsPropertySchema.safeParse(
typeof property === 'string' ? JSON.parse(property) : property

View File

@@ -4,7 +4,7 @@ import { defineStore } from 'pinia'
import { computed, ref, watchEffect } from 'vue'
import { t } from '@/i18n'
import { getPromotionList } from '@/core/graph/subgraph/promotionList'
import { parseProxyWidgets } from '@/core/schemas/proxyWidget'
import { LiteGraph } from '@/lib/litegraph/src/litegraph'
import type { LGraphNode } from '@/lib/litegraph/src/litegraph'
import { transformNodeDefV1ToV2 } from '@/schemas/nodeDef/migration'
@@ -401,7 +401,9 @@ export const useNodeDefStore = defineStore('nodeDef', () => {
}
// For subgraph nodes, find the interior node via the promotion list
const entry = getPromotionList(node).find(([, name]) => name === widgetName)
const entry = parseProxyWidgets(node.properties.proxyWidgets).find(
([, name]) => name === widgetName
)
if (entry) {
const [nodeId] = entry
const subNode = node.subgraph.getNodeById(nodeId)