Skip to content

SY-4140: Schematic Type Reorganization and Diagram Optimizations#2281

Open
emilbon99 wants to merge 40 commits intorcfrom
sy-4140-schematic-type-re-organization-and-diagram-optimizations
Open

SY-4140: Schematic Type Reorganization and Diagram Optimizations#2281
emilbon99 wants to merge 40 commits intorcfrom
sy-4140-schematic-type-re-organization-and-diagram-optimizations

Conversation

@emilbon99
Copy link
Copy Markdown
Contributor

@emilbon99 emilbon99 commented Apr 29, 2026

Issue Pull Request

Linear Issue

SY-4140

Description

Reorganizes the schematic type system and lifts diagram rendering up into pluto, in service of strongly-typed schematics. The change is intentionally scoped to not depend on the planned shift of schematic state out of Redux into a flux store, or on the server-side schematic typing pipeline — both of which will land separately on top of this work.

Pluto — Diagram factory + typed change protocol.

  • Diagram.create({ node, edge?, connectionLine? }) replaces the runtime <NodeRenderer> / <EdgeRenderer> registration. The use() hook is removed; the diagram is now controlled-only.
  • onNodesChange / onEdgesChange receive typed NodeChange[] / EdgeChange[] mutations (position / remove / select / dimensions, add / remove / select) instead of whole arrays. Selection is promoted to a first-class selected / onSelectionChange controlled prop.
  • Edge endpoints become Handle = { node, param } objects. Renderer contracts are tightened ({ edgeKey, source, target, sourceNode, targetNode, selected } for edges; { source, target, status, style } for connection lines).
  • Background, ToggleEdit, FitView, SelectViewportMode move into a controls/ namespace.

Pluto — Schematic.create factory with hooks API.

  • Schematic.create({ useNodeProps, useEdgeProps, useSetElementProps }) returns a Diagram-backed FC. Pluto owns all rendering: it looks up symbols via Symbol.REGISTRY[variant], renders the edge component (drag handles + path routing), and the connection line. Consumers only provide three small hooks for read/write of element props.
  • Schematic.Provider / Schematic.useKey give consumers a context channel for layout-key scoping.
  • The schematic edge component now takes { segments, color, variant, onSegmentsChange } as props (no flux dependency). New connector helpers (stitchEdge, extractMiddle, buildNewFromState, updateSegmentsForPositionChanges, resolveOrientation, connectPoints) handle the three-zone source-stump / middle-segments / target-stump routing.
  • Path variants gain interactionWidth = 30 for easier hit-testing.
  • Symbol props gain data: P namespacing (separates structural props from configuration), nodeKey rename, and memo wrapping.

Pluto — Arc.create factory.

  • Arc.create(renderers) mirrors the new Diagram.create / Schematic.create pattern.

Console — schematic slice + selectors adapted to new shape.

  • New applyNodeChanges / applyEdgeChanges / setSelected reducers consume the typed change protocol directly. setNodes / setEdges retained for compatibility but no longer carry selection.
  • Top-level state.selected: string[] replaces per-node / per-edge selected flags.
  • props map now stores both node and edge props (keyed by element key); edge { segments, color, variant } shifts out of edge.data into the props record.
  • New useSelectSelected, useSelectElementProps, useSelectEdgeProps selectors.

Console — schematic v6 migration.

  • v0 frozen-snapshot uses standalone zod schemas (no Diagram.nodeZ / edgeZ references) so old persisted state still parses through the chain.
  • v6 transforms: edge endpoints flat → Handle, edge data → entry in props map, nodePropsZ.keyvariant, top-level selected: [] added. Copy buffer migrates with the same transforms.

Console — schematic / arc consumers.

  • Schematic.tsx shrinks dramatically: provides the three hooks, wraps <Schematic.Provider value={layoutKey}>, no longer hosts a SymbolRenderer or React-flow integration.
  • arc/editor/graph/Editor.tsx adopts Arc.create({ node }), the typed change reducers, and setSelected. Arc state migrates to v1 (selection extracted).
  • Properties.tsx renames props.keyprops.variant, adds an edge-properties block backed by the new useSelectEdgeProps, and guards the Color.Swatch against non-hex (CSS-variable) colors carried from migration defaults.

Test coverage.

  • All 438 console tests pass; 2097 / 2102 pluto tests pass (the 5 remaining were a pre-existing OffPageReference CSS-variable spec; restored the base-branch impl on this branch). Schematic migration tests cover the v0–v6 chain plus shape-transform spot checks (key→variant, edge-handle reshape, edge-data→props extraction).

Basic Readiness

  • I have performed a self-review of my code.
  • I have added relevant, automated tests to cover the changes.
  • I have updated documentation to reflect the changes.

Greptile Summary

This PR reorganizes the schematic and arc type systems: Diagram.create / Schematic.create / Arc.create factories replace runtime renderer registration, a typed NodeChange[] / EdgeChange[] protocol replaces whole-array updates, edge endpoints become Handle objects, and selection is lifted to a first-class controlled prop. A v6 migration transforms all persisted state to the new shape. Several previously-flagged bugs are addressed in this PR (color reference-equality comparison, syncDispatch for selection changes, color.equals for edge color sync).

The remaining findings are all P2: a missing CSS-variable safeParse guard for edge colors in the multi-element properties panel (the single-element path was already fixed), a missing null guard in arc's pasteSelection (present in the schematic's equivalent), and a stale theme entry in handleDrop's deps array.

Confidence Score: 5/5

Safe to merge; all findings are P2 (style/defensive gaps), no blocking issues found.

Only P2 findings remain — a missed CSS-variable guard in multi-element properties, a defensive null check gap in arc paste, and a stale dep. All previously flagged P1s were addressed in this PR.

console/src/schematic/toolbar/Properties.tsx (missing edge color guard in multi-selection path)

Important Files Changed

Filename Overview
console/src/schematic/toolbar/Properties.tsx New EdgeProperties block added with CSS-variable safeParse guard (single-edge); MultiElementProperties path is missing the same guard for edge colors.
console/src/arc/slice.ts Parallel refactor to typed change protocol; pasteSelection assigns props without null check (P2); setActiveTabFromSelection correctly added.
console/src/schematic/Schematic.tsx Significantly slimmed; SchematicComponent wired via three-hook factory; handleNodesChange correctly routes dragging through syncDispatch; handleDrop has a leftover stale theme dep.
console/src/schematic/slice.ts Refactored to typed change protocol; syncEdgeColorFromEndpoints now uses color.equals() fixing the previous reference-equality bug.
console/src/arc/editor/graph/Editor.tsx Adopts Arc.create factory; handleSelectionChange correctly uses plain dispatch (not undoable); handleNodesChange still routes all changes through undoableDispatch including mid-drag positions.
console/src/schematic/types/v6.ts Well-structured v6 migration: edge endpoints flattened to Handle, edge data extracted to props map, key→variant rename, selected[] initialized to [].
pluto/src/schematic/edge/connector/connector.ts New three-zone routing helpers (stitchEdge, extractMiddle, buildNewFromState, updateSegmentsForPositionChanges); double-processing when both endpoints move in same batch noted in previous thread.
pluto/src/vis/diagram/Diagram.tsx Major refactor to Diagram.create factory; controlled-only architecture; typed NodeChange/EdgeChange protocol; selection promoted to first-class prop.

Sequence Diagram

sequenceDiagram
    participant Consumer as Console (Schematic.tsx)
    participant Factory as Schematic.create()
    participant Diagram as Diagram.tsx
    participant Redux as Redux Slice

    Consumer->>Factory: create({ useNodeProps, useEdgeProps, useSetElementProps })
    Factory-->>Consumer: SchematicComponent (FC)

    Consumer->>Diagram: SchematicComponent nodes edges selected onNodesChange onEdgesChange

    Diagram->>Redux: onNodesChange(NodeChange[]) applyNodeChanges
    Note over Diagram,Redux: dragging=true syncDispatch (no undo)<br/>other changes undoableDispatch

    Diagram->>Redux: onEdgesChange(EdgeChange[]) applyEdgeChanges
    Note over Diagram,Redux: add case calls syncEdgeColorFromEndpoints

    Diagram->>Redux: onSelectionChange(string[]) setSelected syncDispatch

    Factory->>Redux: useNodeProps(entryKey, nodeKey) REGISTRY[variant]
    Factory->>Redux: useEdgeProps(entryKey, edgeKey) segments color variant
    Factory->>Redux: useSetElementProps(entryKey) setElementProps dispatch
Loading

Comments Outside Diff (1)

  1. console/src/arc/editor/graph/Editor.tsx, line 143-146 (link)

    P1 Drag positions flood undo history

    handleNodesChange routes every node change — including intermediate drag positions (type: "position" with dragging: true) — through undoableDispatch. The schematic counterpart correctly uses syncDispatch for in-flight drag changes to avoid polluting the undo stack. A user dragging a single node across the canvas will generate dozens of undo entries, making Ctrl-Z nearly useless after any drag.

    The schematic's handleNodesChange (in console/src/schematic/Schematic.tsx) uses a dragging check to route to syncDispatch, and the same pattern should be applied here.

Reviews (13): Last reviewed commit: "Merge branch 'rc' of https://github.com/..." | Re-trigger Greptile

These pb.go and codec_gen_test.go changes were proto-descriptor reordering
noise unrelated to the spatial-types work. Reverting to keep the PR diff
focused.
These case "numeric" arms in constraintToGo, formatTypeParamsDecl, and
the test-fixture concrete-type helpers can't fire: the analyzer requires
every numeric-constrained type-param to have a numeric default, and
every Go-emitting call site filters through NonDefaultedTypeParams
before reaching these functions. The arms were added as completeness
hedges; remove them to keep the codebase to live paths only.
…b generator

A struct field declared with single "?" in oracle keeps its Go type as a
value, but the proto field is nullable on the wire. The generator was
calling the inner ToPB unconditionally, which errored on a zero-value
struct that contained string-enum fields (e.g. spatial.StickyXY.Root,
arc.ir.Function.Body). Route soft-optional struct fields through
OptionalFields with a zero-value guard in ToPB and a proto-pointer
nil-check in FromPB. The latent same-shape bug in ranger.Range.Color is
fixed by the same path.

Also fix the pluralize package so trailing acronym runs ending in Y
(StickyXY, ClientXY) pluralize as "+s" rather than mangling to "ies".
The previous all-uppercase shortcut only caught fully-acronym names.
Schema fields whose names start with a lowercase letter are now used
verbatim as the JSON / msgpack tag instead of being routed through
SnakeCase. snake_case stays snake_case (data_type) and camelCase stays
camelCase (clientX, signedWidth, targetKey), letting Go round-trip
directly with the TypeScript zod schemas, which use the schema field
name as the property key.

Names that begin with an uppercase letter (PascalCase, screaming-case,
single-letter caps) keep the existing lowercase-snake convention so
WASM -> wasm and OutputMemoryBases -> output_memory_bases are
unchanged. Only six fields across the codebase change tags
(spatial.ClientXY, spatial.SignedDimensions, ir.Transition.TargetKey,
ir.Member.NodeKey); none have shipped data to maintain compatibility
with.
Comment thread console/src/arc/slice.ts
Comment thread pluto/src/schematic/edge/connector/connector.ts Outdated
Comment thread console/src/schematic/slice.ts
Comment thread console/src/arc/editor/graph/Editor.tsx Outdated
Comment thread console/src/schematic/slice.ts
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 29, 2026

Codecov Report

❌ Patch coverage is 20.68966% with 598 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.20%. Comparing base (f2879ed) to head (46b6a8b).

Files with missing lines Patch % Lines
pluto/src/vis/diagram/Diagram.tsx 0.88% 92 Missing and 20 partials ⚠️
console/src/schematic/slice.ts 21.64% 67 Missing and 9 partials ⚠️
pluto/src/schematic/edge/connector/connector.ts 8.97% 52 Missing and 19 partials ⚠️
console/src/arc/slice.ts 0.00% 56 Missing and 7 partials ⚠️
pluto/src/schematic/symbol/Symbols.tsx 25.31% 50 Missing and 9 partials ⚠️
pluto/src/vis/diagram/aether/types.ts 21.42% 29 Missing and 4 partials ⚠️
pluto/src/schematic/edge/Edge.tsx 3.33% 23 Missing and 6 partials ⚠️
pluto/src/schematic/Schematic.tsx 3.57% 24 Missing and 3 partials ⚠️
console/src/schematic/Schematic.tsx 0.00% 18 Missing and 2 partials ⚠️
console/src/schematic/selectors.ts 30.43% 13 Missing and 3 partials ⚠️
... and 16 more
Additional details and impacted files
@@            Coverage Diff             @@
##               rc    #2281      +/-   ##
==========================================
- Coverage   64.31%   64.20%   -0.11%     
==========================================
  Files        2189     2187       -2     
  Lines      111097   110644     -453     
  Branches     8292     8357      +65     
==========================================
- Hits        71455    71042     -413     
+ Misses      33535    33497      -38     
+ Partials     6107     6105       -2     
Flag Coverage Δ
console 20.75% <30.00%> (+0.32%) ⬆️
pluto 55.33% <12.62%> (-0.37%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…8-prepare-oracle-generated-spatial-primitives-for-strongly
@sy-nico sy-nico self-requested a review May 1, 2026 15:37
…-strongly' of https://github.com/synnaxlabs/synnax into sy-4140-schematic-type-re-organization-and-diagram-optimizations
emilbon99 added 2 commits May 1, 2026 11:21
…8-prepare-oracle-generated-spatial-primitives-for-strongly
…-strongly' of https://github.com/synnaxlabs/synnax into sy-4140-schematic-type-re-organization-and-diagram-optimizations
emilbon99 added 2 commits May 1, 2026 11:24
…8-prepare-oracle-generated-spatial-primitives-for-strongly
…-strongly' of https://github.com/synnaxlabs/synnax into sy-4140-schematic-type-re-organization-and-diagram-optimizations
Base automatically changed from sy-4138-prepare-oracle-generated-spatial-primitives-for-strongly to rc May 1, 2026 17:52
…0-schematic-type-re-organization-and-diagram-optimizations
Comment thread console/src/schematic/slice.ts
Copy link
Copy Markdown
Contributor

@sy-nico sy-nico left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While trying to test out the potential regression (see other comment), I noticed that keyboard shortcuts are broken (could not copy, paste, or undo) on both the Arc and Schematic editors.

I would attach a video, but there would be no activity...

Comment thread console/src/arc/editor/graph/Editor.tsx
Comment thread console/src/arc/editor/graph/Editor.tsx
Comment thread console/src/schematic/Schematic.tsx
…0-schematic-type-re-organization-and-diagram-optimizations
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants