fix(viewer): recompute related traits on client-side navigation#258
Open
jamesdabbs wants to merge 3 commits into
Open
fix(viewer): recompute related traits on client-side navigation#258jamesdabbs wants to merge 3 commits into
jamesdabbs wants to merge 3 commits into
Conversation
Related.svelte derives its rows via `$: all = related($traits)`, which
only re-runs when the `related` prop or the traits store changes
identity. Both callers passed hoisted function declarations that closed
over their space/property prop, so navigating between two spaces (or
properties) reused the mounted component and kept showing the previous
entity's traits table. Declare the closures reactively so a new function
is passed whenever the entity changes.
Also make the `rel` tab-link prop reactive on the space page, matching
the property and theorem pages.
Adds a fixture-only Cypress regression spec driving the exact flow from
the issue: an in-description space link (unpadded id), asserting the
traits table recomputes, including on browser back. S000001's fixture
description now links to {S4} to support it; "Indiscrete" is asserted
false for S000001 and true for S000004, so the value icon flips iff the
table recomputes (deduction can add traits but never contradict asserted
ones). Verified red against the unfixed code, green with the fix.
Closes #255
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Document the fixtureIt convention for specs that depend on fixture-pinned content, and two traps when running fixture mode against a production-style build (also what CI runs): the bundle is baked in and SSR-injected so cy.intercept on main.json is inert, and the preview server must be restarted after every rebuild to avoid serving HTML that references the previous build's hashed chunks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
graphs | ce5ec72 | Commit Preview URL Branch Preview URL |
Jul 07 2026, 02:04 AM |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
topology | ce5ec72 | Commit Preview URL Branch Preview URL |
Jul 07 2026, 02:04 AM |
Deploying topology with
|
| Latest commit: |
ce5ec72
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://60b1423f.topology.pages.dev |
| Branch Preview URL: | https://fix-255-stale-traits-on-navi.topology.pages.dev |
Related took a `(traits) => rows` closure prop, leaving its real data dependency (the space or property being viewed) invisible to Svelte's reactivity — the trap behind #255, avoidable only by every caller remembering to re-create the closure reactively. Take the anchor entity itself as a discriminated-union prop and compute the rows inside Related: the object literal at the call sites is re-evaluated whenever the entity changes, so recomputation falls out of ordinary prop flow and the stale-closure mistake is no longer expressible. This also subsumes the separate `mode` prop. Covered end-to-end by the navigation regression spec (17/17 fixture suite passing). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #255
Root cause
Related.sveltederives its rows via$: all = related($traits), which only re-runs when therelatedprop or the traits store changes identity. Both callers (Spaces/Properties.svelte,Properties/Spaces.svelte) passed hoistedfunctiondeclarations that closed over theirspace/propertyprop — a data dependency Svelte's reactivity can't see. On client-side navigation between two spaces, SvelteKit reuses the mounted component tree: the name/description updated (they read the prop directly) but the traits table never recomputed, so S27's page showed S29's traits — and after a refresh, back-navigation showed the reverse.Fix
relatedclosures reactively ($:) in both callers, so a new function identity is passed whenever the entity changes.reltab-link prop reactive on the space page (it was captured once at mount), matching the property/theorem pages.Regression test
New fixture-only Cypress spec drives the exact flow from the issue: visit a space, click an in-description space link (unpadded id, like the live
{S27}links), assert the traits table recomputes, then assert it recomputes again on browser back. To support it, S000001's fixture description now links to{S4}; "Indiscrete" is asserted false for S000001 and true for S000004, so the value icon flips iff the table actually recomputes (client-side deduction can add traits but never contradict asserted ones).Since live descriptions differ from the fixture (live S000001's description is empty), the spec is declared with a
fixtureIthelper and shows as pending in live runs;doc/testing.mddocuments the convention plus two fixture-mode gotchas discovered while verifying (the bundle is baked in + SSR-injected for localhost builds, socy.interceptonmain.jsonis inert; the preview server must be restarted after rebuilds).Verification
A follow-up commit on this branch refactors
Relatedto take the anchor entity as data instead of a closure prop, making this bug class unrepresentable.🤖 Generated with Claude Code