refactor!: delete the input.link runtime mirror

The linkStore is now the single source for slot connectivity in both
directions. The NodeInputSlot.link field and all runtime write sites are
gone; a read-only prototype getter derives the id from the store and
fires warnDeprecated as extension migration telemetry (no setter, so
writes throw). Wire format unchanged: serialization derives
inputs[].link from the store.

The mirror-carried association machinery is reworked rather than
papered over: fixLinkInputSlots consumes the serialized graph data
(where node.configure reorders inputs in place), dynamicWidgets' group
rebuilds carry slot-to-link association in a WeakMap refreshed from the
store, reorderSubgraphInputs captures outer links by pre-reorder index,
and link deduplication selects survivors from the store registration -
repairInputLinks is deleted because the derived view cannot be
inconsistent.

Extension migration: read via node.isInputConnected(slot) /
node.getInputLink(slot); mutate via node.connect() /
node.disconnectInput().
This commit is contained in:
DrJKL
2026-07-07 16:40:51 -07:00
parent 75ad306a80
commit 3772615fcb
20 changed files with 168 additions and 102 deletions

View File

@@ -105,11 +105,9 @@ subgraph-definition GC unregister whole graphs
This design covers link topology (endpoints, type, chain terminus).
Link visual state (`color`, path caches) and the layout store's link
_geometry_ records are out of scope. The `output.links` mirror has since
been deleted — the store is the single source for output-side
connectivity (see
[output slot connectivity](output-slot-connectivity.md) Decision 6). The
`input.link` slot mirror remains the litegraph-native representation
un-migrated consumers read; extracting it is the `SlotConnection`
component work in the [ECS migration plan](ecs-migration-plan.md), not
part of this store.
_geometry_ records are out of scope. The `output.links` and `input.link`
slot mirrors have since been deleted — the store is the single source
for slot connectivity in both directions (see
[output slot connectivity](output-slot-connectivity.md) Decision 6);
the remaining fields are deprecated warning getters kept as extension
migration telemetry.

View File

@@ -123,10 +123,20 @@ a mirror read plus a `slotFloatingLinks` scan), widget value propagation
(`widgetValuePropagation`), and matchType link revalidation
(`dynamicWidgets.changeOutputType`).
## Decision 6: Delete the mirror (implemented)
## Decision 6: Delete the mirrors (implemented; extended to `input.link`)
The runtime `output.links[]` field and all nine of its write sites are
deleted. The store is the single source; litegraph internals read through
deleted. The same recipe has since been applied to `input.link`: the
field is a deprecated warning getter, litegraph and app code read through
the slotLinks input helpers (`inputHasLink`, `inputLinkId`, `inputLink`)
or `node.isInputConnected` / `node.getInputLink`, serialization derives
`inputs[].link` from the store, and the mirror-carried association
shuffles were reworked — `fixLinkInputSlots` consumes the serialized
graph data, dynamicWidgets' group rebuilds carry slot→link association
in a module-scoped WeakMap refreshed from the store, and link
deduplication selects survivors from the store registration (the
`repairInputLinks` mirror repair is gone; the derived view cannot be
wrong). The store is the single source; litegraph internals read through
the pure helpers in `node/slotLinks.ts` (`outputHasLinks`,
`outputLinkIds`, `outputLinks`), and `NodeOutputSlot.isConnected`,
`serialize`, and `configure` derive from the store. Details:
@@ -193,7 +203,6 @@ sites, and field deletion.
Out of scope, each a piece of the deferred `SlotConnection` phase:
- Deleting the `input.link` mirror field (same recipe as Decision 6).
- Slot entity extraction: `SlotIdentity`, `SlotVisual`, and retiring the
`NodeInputSlot` / `NodeOutputSlot` class instances and their
`shallowReactive` graft.