Replace node definition string-based lookups with DefinitionIdentifier instances (#3451)

* create definition identifier and integrate it

* Bug fixes and code review

* formatting

* Fix migrations

* Fix remove handles migration

* formatting

* Fix test

* Fix tests 2

* fix deserialization

* Code review

* Small fixes

* Consolidate 'Morph' node migrations

* Add old SamplePointsNode name to migrations list

* Fix tests

* Unrelated small fix

* Fix migration crashes

* Fix tests

* Final code review

* fmt

* Add metadata

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
Adam Gerhant
2026-01-12 23:09:43 -08:00
committed by GitHub
co-authored by Keavon Chambers
parent 4fea2b0fe7
commit a6052c5819
63 changed files with 843 additions and 802 deletions
@@ -1,7 +1,7 @@
<script lang="ts">
import { createEventDispatcher, getContext, onMount } from "svelte";
import type { FrontendNodeType } from "@graphite/messages";
import type { DefinitionIdentifier, FrontendNodeType } from "@graphite/messages";
import type { NodeGraphState } from "@graphite/state-providers/node-graph";
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
@@ -9,7 +9,7 @@
import TextInput from "@graphite/components/widgets/inputs/TextInput.svelte";
import TextLabel from "@graphite/components/widgets/labels/TextLabel.svelte";
const dispatch = createEventDispatcher<{ selectNodeType: string }>();
const dispatch = createEventDispatcher<{ selectNodeType: DefinitionIdentifier }>();
const nodeGraph = getContext<NodeGraphState>("nodeGraph");
// Content
@@ -125,8 +125,8 @@
{disabled}
label={nodeType.name}
tooltipLabel={nodeType.name}
tooltipDescription={$nodeGraph.nodeDescriptions.get(nodeType.name)}
action={() => dispatch("selectNodeType", nodeType.name)}
tooltipDescription={$nodeGraph.nodeDescriptions.get(nodeType.identifier)}
action={() => dispatch("selectNodeType", nodeType.identifier)}
/>
{/each}
</details>
+2 -2
View File
@@ -644,7 +644,7 @@
{@html $nodeGraph.thumbnails.get(listing.entry.id)}
{/if}
</div>
{#if listing.entry.reference === "Artboard"}
{#if listing.entry.reference.type === "Network" && listing.entry.reference.data === "Artboard"}
<IconLabel icon="Artboard" class="layer-type-icon" tooltipLabel="Artboard" />
{/if}
<LayoutRow class="layer-name" on:dblclick={() => onEditLayerName(listing)}>
@@ -652,7 +652,7 @@
data-text-input
type="text"
value={listing.entry.alias}
placeholder={listing.entry.reference}
placeholder={listing.entry.reference.data}
disabled={!listing.editingName}
on:blur={() => onEditLayerNameDeselect(listing)}
on:keydown={(e) => e.key === "Escape" && onEditLayerNameDeselect(listing)}
+9 -16
View File
@@ -4,8 +4,7 @@
import { fade } from "svelte/transition";
import type { Editor } from "@graphite/editor";
import type { IconName } from "@graphite/icons";
import type { FrontendGraphInput, FrontendGraphOutput } from "@graphite/messages";
import type { DefinitionIdentifier, FrontendGraphInput, FrontendGraphOutput, FrontendNode } from "@graphite/messages";
import type { NodeGraphState } from "@graphite/state-providers/node-graph";
import NodeCatalog from "@graphite/components/floating-menus/NodeCatalog.svelte";
@@ -13,7 +12,6 @@
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
import IconButton from "@graphite/components/widgets/buttons/IconButton.svelte";
import TextButton from "@graphite/components/widgets/buttons/TextButton.svelte";
import IconLabel from "@graphite/components/widgets/labels/IconLabel.svelte";
import TextLabel from "@graphite/components/widgets/labels/TextLabel.svelte";
const GRID_COLLAPSE_SPACING = 10;
@@ -102,18 +100,10 @@
return sparse;
}
function nodeIcon(icon?: string): IconName {
if (!icon) return "NodeNodes";
const iconMap: Record<string, IconName> = {
Output: "NodeOutput",
};
return iconMap[icon] || "NodeNodes";
}
function createNode(nodeType: string) {
function createNode(identifier: DefinitionIdentifier) {
if ($nodeGraph.contextMenuInformation === undefined) return;
editor.handle.createNode(nodeType, $nodeGraph.contextMenuInformation.contextMenuCoordinates.x, $nodeGraph.contextMenuInformation.contextMenuCoordinates.y);
editor.handle.createNode(identifier, $nodeGraph.contextMenuInformation.contextMenuCoordinates.x, $nodeGraph.contextMenuInformation.contextMenuCoordinates.y);
}
function nodeBorderMask(nodeWidth: number, primaryInputExists: boolean, exposedSecondaryInputs: number, primaryOutputExists: boolean, exposedSecondaryOutputs: number): string {
@@ -166,6 +156,10 @@
return `Data Type: ${value.resolvedType}`;
}
function nodeNameTooltipLabel(node: FrontendNode): string {
return node.displayName === node.implementationName ? node.displayName : `${node.displayName} (${node.implementationName})`;
}
function validTypesText(value: FrontendGraphInput): string {
const validTypes = value.validTypes.length > 0 ? value.validTypes.map((x) => `• ${x}`).join("\n") : "None";
return `Valid Types:\n${validTypes}`;
@@ -501,7 +495,7 @@
style:--data-color-dim={`var(--color-data-${(node.primaryOutput?.dataType || "General").toLowerCase()}-dim)`}
style:--layer-area-width={layerAreaWidth}
style:--node-chain-area-left-extension={layerChainWidth !== 0 ? layerChainWidth + 0.5 : 0}
data-tooltip-label={node.displayName === node.reference || !node.reference ? node.displayName : `${node.displayName} (${node.reference})`}
data-tooltip-label={nodeNameTooltipLabel(node)}
data-tooltip-description={`
${(description || "").trim()}${editor.handle.inDevelopmentMode() ? `\n\nID: ${node.id}. Position: (${node.position.x}, ${node.position.y}).` : ""}
`.trim()}
@@ -651,7 +645,7 @@
style:--clip-path-id={`url(#${clipPathId})`}
style:--data-color={`var(--color-data-${(node.primaryOutput?.dataType || "General").toLowerCase()})`}
style:--data-color-dim={`var(--color-data-${(node.primaryOutput?.dataType || "General").toLowerCase()}-dim)`}
data-tooltip-label={node.displayName === node.reference || !node.reference ? node.displayName : `${node.displayName} (${node.reference})`}
data-tooltip-label={nodeNameTooltipLabel(node)}
data-tooltip-description={`
${(description || "").trim()}${editor.handle.inDevelopmentMode() ? `\n\nID: ${node.id}. Position: (${node.position.x}, ${node.position.y}).` : ""}
`.trim()}
@@ -659,7 +653,6 @@
>
<!-- Primary row -->
<div class="primary" class:in-selected-network={$nodeGraph.inSelectedNetwork} class:no-secondary-section={exposedInputsOutputs.length === 0}>
<IconLabel icon={nodeIcon(node.reference)} />
<!-- TODO: Allow the user to edit the name, just like in the Layers panel -->
<TextLabel>{node.displayName}</TextLabel>
</div>
@@ -24,7 +24,7 @@
</tbody>
</table>
<style lang="scss">
<style lang="scss" global>
table:not(.unstyled) {
background: var(--color-3-darkgray);
border: none;
@@ -120,6 +120,8 @@
<style lang="scss" global>
.shortcut-label {
align-items: center;
.key-label {
display: flex;
align-items: center;