Skip to content

fix(free-layout-core): recompute line path when version unchanged but path is empty - #1147

Open
zyh94946 wants to merge 1 commit into
bytedance:mainfrom
zyh94946:fix/free-layout-line-render-version-guard
Open

fix(free-layout-core): recompute line path when version unchanged but path is empty#1147
zyh94946 wants to merge 1 commit into
bytedance:mainfrom
zyh94946:fix/free-layout-line-render-version-guard

Conversation

@zyh94946

Copy link
Copy Markdown

Summary

In the free layout editor, some connection lines fail to render (their SVG path
stays empty) after loading a graph via fromJSON. It only happens on initial load —
dragging nodes or creating connections manually works fine. Same problem as #1070.

Root cause

WorkflowLineRenderData.update() skips recomputation when the position version is
unchanged (a performance optimization), and path comes from the line contribution:
get path() { return this.currentLine?.path ?? ''; }.

When a line entity is created before its line contribution (bezier/fold/straight,
registered by free-lines-plugin in onReady) is available:

  1. The first update() writes the real coordinates into version, but currentLine
    is still undefined, so path is left empty.
  2. Once the contribution registers, the coordinates are unchanged, so the recomputed
    version equals the stored one.
  3. oldVersion === newVersion is true, the guard returns early, currentLine.update()
    is never called, and the empty path is locked in permanently — the line never
    renders.

This matches #1070's observation that it's specific to initial fromJSON loading
(manual drag/connect happens after contributions are registered).

Fix

Skip recomputation only when the version is unchanged and a path has already been
computed:

if (oldVersion === newVersion && this.currentLine?.path) {
  return;
}

A line whose path is still empty is recomputed once its contribution becomes
available. Lines that already have a non-empty path are unaffected, preserving the
original optimization.

Testing

Added __tests__/workflow-line-render-data.test.ts:

  • Regression test reproducing the late-contribution case — verified red/green:
    fails without the fix (path stays ''), passes with the fix.
  • Guard test: a redundant update() on a line that already has a path is a no-op.

rush build --to @flowgram.ai/free-layout-core succeeds; free-layout-core tests all
pass (86 cases, incl. the 2 new ones).

Refs #1070

… path is empty

WorkflowLineRenderData.update() skips recomputation when the position version is
unchanged. However, when a line entity is created before its line contribution
(bezier/fold/straight, registered by free-lines-plugin onReady) is available, the first
update() sets the version to the real coordinates while currentLine is still undefined, so
the computed path stays empty. Once the contribution becomes available the version is
already up to date, so the guard permanently skips recomputation and the path remains
empty - the line never renders.

This reproduces the initial-load-only failure described in bytedance#1070 (lines fail to render
after fromJSON; drag-and-drop and manual connections are unaffected).

Fix: only skip recomputation when the version is unchanged AND a path has already been
computed. A line whose path is still empty is recomputed once its contribution becomes
available. Lines with a non-empty path are unaffected, preserving the original performance
optimization.

Refs bytedance#1070
@CLAassistant

CLAassistant commented Jun 26, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

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