fix: graph correctly restore html refs after exiting node group

This commit is contained in:
2026-05-04 12:45:45 +02:00
parent 78439b19e9
commit 317d1552ce
3 changed files with 18 additions and 8 deletions
@@ -486,7 +486,7 @@ export class GraphManager extends EventEmitter<{
getNodeType(node: NodeInstance) { getNodeType(node: NodeInstance) {
if (!node) { if (!node) {
console.trace('failed to get node type'); console.trace('failed to get node type', { node });
return; return;
} }
@@ -685,9 +685,18 @@ export class GraphManager extends EventEmitter<{
exitGroup(): { camera: [number, number, number]; nodeId: number } | false { exitGroup(): { camera: [number, number, number]; nodeId: number } | false {
if (!this.graphStack.length) return false; if (!this.graphStack.length) return false;
const { savedNodes, savedEdges, outerGraph, groupId, nodeId, cameraPosition } = this.graphStack.pop()!; const { savedNodes, savedEdges, outerGraph, groupId, nodeId, cameraPosition } = this.graphStack
.pop()!;
const internalState = this.serialize(); const internalState = this.serialize();
// Clear stale DOM/mesh refs so the remounting components register fresh ones.
// The $effect guards in NodeHTML/Node only set these when undefined, so without
// this clear they'd keep pointing to the detached elements from before group entry.
for (const node of savedNodes.values()) {
node.state.ref = undefined;
node.state.mesh = undefined;
}
// Restore live reactive nodes and edges so drag-reactivity is preserved // Restore live reactive nodes and edges so drag-reactivity is preserved
this.nodes.clear(); this.nodes.clear();
for (const [id, node] of savedNodes) { for (const [id, node] of savedNodes) {
@@ -97,7 +97,6 @@
function getSocketType(node: NodeInstance, index: number | string): string { function getSocketType(node: NodeInstance, index: number | string): string {
const nodeType = graph.getNodeType(node); const nodeType = graph.getNodeType(node);
console.log({ nodeType, index });
if (typeof index === 'string') { if (typeof index === 'string') {
return nodeType?.inputs?.[index].type || 'unknown'; return nodeType?.inputs?.[index].type || 'unknown';
} }
+4 -2
View File
@@ -19,7 +19,7 @@
}; };
let { node = $bindable(), inView }: Props = $props(); let { node = $bindable(), inView }: Props = $props();
const nodeType = $derived(graph.getNodeType(node)!); const nodeType = $derived(node ? graph.getNodeType(node) : undefined);
const isActive = $derived(graphState.activeNodeId === node.id); const isActive = $derived(graphState.activeNodeId === node.id);
const isSelected = $derived(graphState.selectedNodes.has(node.id)); const isSelected = $derived(graphState.selectedNodes.has(node.id));
@@ -33,10 +33,12 @@
); );
const sectionHeights = $derived( const sectionHeights = $derived(
Object nodeType
? Object
.keys(nodeType?.inputs || {}) .keys(nodeType?.inputs || {})
.map(key => getParameterHeight(nodeType, key) / 10) .map(key => getParameterHeight(nodeType, key) / 10)
.filter(b => !!b) .filter(b => !!b)
: [5]
); );
let meshRef: Mesh | undefined = $state(); let meshRef: Mesh | undefined = $state();