Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .changes/draw-start-batch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "type": "user-facing", "releaseNoteId": "release:0.28.4" }
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ All notable Loop Studio releases, newest first. Behavioral changes are pinned
in versioned spec documents (see the [README](README.md#technical-reference));
this file is the narrative history, not the contract.

## v0.28.4 — 2026-10-17

Starting and finishing a connection drag responds faster ([`docs/edge-routing.md`](docs/edge-routing.md) §ER17.1).

- **What was slow.** While a connection or an end grip is dragged, every node shows all of its sides so the drop can choose one, and when the drag ends the unused ones go. Each node then measured its handles again on its own — one update of the canvas's state per node, each passed to everything listening to it — so the start and the end of a drag grew slow on large diagrams.
- **Now.** One measurement covers every node: at the start at once, before anything is drawn; at the end on the next frame, as before. A new drag started right after one ends is measured on its own. While drawing, every side of every node is still offered.
- **How much.** On one machine's production build, the 63-node 3-zone gacha banner comparison started a drag in about 70–80 ms instead of 100–120 ms, and in about 370–460 ms instead of 800–850 ms with the processor slowed four times; releasing the drag on the empty canvas improved about as much; Coffee roastery operations flow did not get slower. Only those two gestures were timed: a release that makes a connection and an end grip drag take the same path and were checked to work as before, not timed. The full measurement is kept with the work, not in the app.

**Notes.** Three What's new lines in 18 languages: the translation contract tests pass, and none had native-speaker review.

## v0.28.3 — 2026-10-15

Undo and Redo leave nothing selected, on the canvas as in the Inspector ([`docs/large-graph-readability.md`](docs/large-graph-readability.md) LGR-D17); a module insert restores its own selection ([`docs/module-system.md`](docs/module-system.md) §MS3.5).
Expand Down
30 changes: 12 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,16 @@ Additional feature-specific design documents (localization, mobile, module
system, large-graph readability, simulation playback, edge routing, data
import, …) live under [`docs/`](docs/).

## Latest — v0.28.3
## Latest — v0.28.4

Starting and finishing a connection responds faster.

- **Starting to draw**: responds faster, with a larger improvement in large diagrams
- **Releasing on the empty canvas**: a connection drag released there also responds faster
- **Every side stays available**: while drawing a connection, handles on every side of every
node remain available

## v0.28.3

Undo and Redo leave nothing selected.

Expand Down Expand Up @@ -176,23 +185,8 @@ A connection's label keeps off the bend points you placed on it, where its line
- **Early MMO example**: no longer listed under Templates; it stays as developer test material
for large diagrams, and a document you already made from it still opens and works as before

## v0.28.0

A connection can be turned around without drawing it again.

- **Reverse a connection**: select it and press Reverse beside Ends in the Inspector; its
amount, condition, colour and line shape stay as they were and are read in the new
direction, the bends you placed keep their places, and one undo step takes it back
- **What may look different**: the automatic route, the line next to each end and the
label's place may be drawn differently after a reversal
- **Refused reversals say why**: a reversal that would end a connection at a node with no
input, start it at a node with no output, repeat a connection drawn the same way, or leave a
state connection with no effect is not applied, and the reason is shown

On a phone the diagram stays read-only. Curves you shape yourself and moving a connection's
label are not in this release.

See [`CHANGELOG.md`](CHANGELOG.md) for the full notes of these releases, v0.27.0 (a
See [`CHANGELOG.md`](CHANGELOG.md) for the full notes of these releases, v0.28.0 (a
connection turned around without drawing it again), v0.27.0 (a
connection's end moves without drawing the connection again), v0.26.2 (playback
in the chosen colours, and the moving `+N` badges kept off the nodes), v0.26.0 (the
compact node with its name outside, connections from any side, notices under the toolbar),
Expand Down
33 changes: 33 additions & 0 deletions docs/edge-routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,39 @@ on purpose: a face is placement, and taking the whole document away from an olde
to protect it would cost more than it saves (decision D-A). The user-facing change note
of the release that ships this says the same in one sentence.

### ER17.1 The face handles and when they are measured

A node mounts the handle of a face only when it is needed: a face one of its
connections uses (always, hidden — React Flow draws no edge whose handle id is
missing), and every face while a connection or an end grip is dragged (every
node, so the drop can choose a face) or while the node is selected or
keyboard-focused (`src/components/nodes/nodes.tsx`, `facesOn`). A mount or
unmount without a size change is invisible to React Flow's ResizeObserver, so
the handles' bounds are measured again:

- a change that ADDS a handle — at once, in the node's layout effect: before
paint and before React Flow's edges reach its store (a passive effect), so the
connection that needs the handle finds it (React Flow error 008 otherwise);
- a change that only REMOVES handles — on the next animation frame: a store
update in the layout effect would run React Flow's edge selectors of the
previous render, which still look for the removed handle;
- **the start and the end of a drag change every node in the same commit and
are measured ONCE for all nodes** (`src/components/nodes/faceBatch.ts`): the
first node whose layout effect sees the drag state change measures every
node in one `updateNodeInternals` call — at the start at once (the commit's
DOM is complete, nothing painted), at the end on the next frame (only
removals) — and a new drag cancels an end's frame that has not run yet (a
frame left when the canvas goes away still runs, finds no canvas and
measures nothing). The state is each canvas's, keyed by the store's own
`getState` (`useStoreApi()` gives every component its own wrapper object),
and a drag also ends when React Flow's `connection.inProgress` goes false,
so the next drag is measured even when no node saw the last one end (every
node gone during the drag, e.g. its insert undone).
Measured one node at a time, each was one React Flow store update run
through every subscriber, and starting or ending a drag on the 63-node gacha
banner Template took about 1.5 to 2.5 times as long, on the production build
of one machine at CPU × 1 and × 4 (share note 58).

## ER18. Moving a connection's end (line editing, first unit)

An existing connection's source or target end can be moved to another side of the
Expand Down
Loading
Loading