Release Announcement: v1.3.0 #150
draedful
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
This release fixes long‑standing issues and makes the library easier to extend.
Features
Unified Selection service — PR #133
Originally the graph exposed only three entity types: blocks, connections, and anchors. After we introduced the public
LayerAPI, it became natural to add custom entities too — groups, comments, and other UI elements. We wanted them to be selectable the same way as the built‑in ones, but selection logic was spread across different stores. We had to duplicate it, reset state per entity type by hand, and keep everything in sync. That was fragile and slowed development.SelectionServicefixes this in a single place. It centralizes selection across the app and defines consistent rules. ASelectionBucketis a per‑entity‑type selection store that encapsulates selection rules. Together they make selection predictable, extensible, and ready for new entity types. See: Selection ManagerComponent roles:
REPLACEclears other buckets), exposes a unified API, and provides an aggregated reactive selection state across all types.Usage examples:
CameraService: viewport insets — PR #141
In many apps, side panels can cover part of the canvas. The graph’s geometry stays the same, but the perceived center shifts, so fit/center and zoom feel off. Previously we resized the canvas to work around this, which affected math and performance. Now the camera supports
viewportInsets: a “focus frame” that defines a virtual center for user actions (zoom, fit/center). Insets affect only centering and fit calculations. They do not change camera geometry and are ignored by spatial culling.Short example (see more in Camera Service):
Non‑interactive components and affectsUsableRect
Some layer components are purely decorative: a grid, a watermark, or background frames. For these, it’s important they don’t intercept events and don’t enlarge the graph’s working area.
interactive: false— the component does not take part in the event model. Events that hit it are not handled by the component and effectively bubble to the parent. In HTML mode, we also disable pointer‑events so clicks and hovers reach interactive elements underneath.affectsUsableRect: false— the component does not affect the overall usable rectangle (usableRect). This lets you place it “behind the background” and exclude it from scene‑size calculations.Side effects:
zoomToViewportcalculations (those useusableRect). If you want an element to be included in auto‑centering, keepaffectsUsableRect: trueor apply your own zoom‑to‑rect logic.Example in a custom layer component:
Ports system — PR #128
Originally, connections were created between blocks and anchors. As the system evolved, we needed to connect arbitrary entities (groups, custom components, and more). Extending
BaseConnectionforever would be costly and fragile. We introduced ports instead — abstract connection endpoints. Now connections are made between ports, while blocks, anchors, and custom entities create and own their ports.Ports also remove the strict initialization order. Before, it had to be “blocks first, then connections” because connections accessed block components. Now a port can exist on its own and be observed. When the owner appears and claims the port, it starts updating coordinates and the connection just works. This simplifies the lifecycle and makes the system more robust.
Ports are also created lazily. A connection can create a port even before its owner (block/anchor/custom entity) exists. Such a port stays in a temporary “lookup” (ownerless) state. Once the owner registers and claims it, the owner takes over coordinate updates and the connection uses the new data automatically.
More details: Canvas connection system.
Short examples:
Fixes
Correct lodash dependency declaration — PR #139
We used to declare
lodash-esinpackage.json, while the code importedlodash. It often worked becauselodasharrived transitively from other packages and happened to be innode_modules. This was brittle: in some setups the dependency could be missing. We now declarelodash, matching the code. This removes a hidden source of instability and makes dependencies predictable.Beta Was this translation helpful? Give feedback.
All reactions