Mostly source-compatible release: one major, breaking architectural change (PortType extraction to top-level) and three user-facing features:
Public API
PortTypeis now a top-level type, no longer nested underNodeTemplate.Port.PortType.ColorComponentsmoves with it.NodeTemplate.Portreferences its type bytypeIdentifier: Stringso multiple templates can share one registeredPortType. Source-compatible via a convenience init onNodeTemplate.Port, so existing.init(id:, kind:, type: .double, ...)calls keep working.PortTypeRegistryis now@Observable @MainActor(was anactor). The editor resolvestypeIdentifiers through it for display hints (colour, name); connection compatibility compares identifier strings directly on the drag/hover hot path so unresolved ports still wire up correctly.GraphEditor.initgainsportTypeRegistry: PortTypeRegistry = .init()betweentemplateRegistryandportEditorRegistry. Defaulted, so existing call sites still compile.NodeTemplate.reusable: Bool = true— set tofalseto refuse a second instance of the same template in a graph (singleton templates like a "Document Properties" node).
Behaviour
- Missing-template placeholder rendering. Nodes that reference a
templateIdentifiertheTemplateRegistrycan't resolve now render as a dimmed "Missing template" card (selectable, movable, deletable) instead of being silently omitted from the canvas. Data is preserved across saves; re-registering the template restores normal rendering and any edges incident to its ports. - Unresolved port-type rendering. Ports whose
typeIdentifierisn't registered inPortTypeRegistryrender dimmer in a neutral colour. Connections still wire up via identifier matching.
Docs
- Concurrency-and-ordering notes added to
TemplateRegistry,PortEditorRegistry, andPortTypeRegistry: synchronousregister/unregisterare FIFO from MainActor code; from outside MainActor they should be treated as asynchronous (the call hops isolation), and multiple async registrations aren't ordered by call site — await between calls if you need a specific sequence. Node.templateIdentifierdocuments what happens when the template isn't registered.CustomPortTypesandGettingStartedguides +READMEquick-start + the in-package preview seed all showPortTypeRegistryconstruction and the new third arg onGraphEditor.- Demo app (
NodeKit Demo) updated to demonstrate registering a customPortTypeand passing both registries through.
Update
.package(url: "https://github.com/itspolly/NodeKit.git", from: "1.0.0"),No source changes required for callers that only use built-in port types and don't reference NodeTemplate.Port.PortType / NodeTemplate.Port.ColorComponents by their nested paths.