Repository navigation
fix(signals): keep isPending until a changed lane answer reveals (#4685) - #4692
santhiprakash wants to merge 2 commits into
Conversation
…idjs#4685) A lane derivation's flight could land while its lane stayed blocked by a sibling's pending work: laneValueOf already held the new answer but the reader's screen still showed the old value. verdictValue only probed flying, so isPending cleared in that window — reporting no pending change while the displayed value was still stale. Now the verdict probe also checks whether the lane's latest answer differs from what the reader sees (the display, or the latest view inside latest()); a differing unrevealed answer keeps the probe pending, and the tracked reader parks on the lane's reruns so it re-derives at the lane's seam rather than only at the parent's landing. In reruns, a verdict-only reader (no REACTIVE_FRAME_READ) no longer marks the rerun frame-producing, so its re-derivation doesn't delay the landing's releases.
🦋 Changeset detectedLatest commit: 788a0af The changes in this PR will be included in the next version bump. This PR includes changesets to release 15 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Merging this PR will not alter performance1 warning, 1 note
Comparing Footnotes
|
Keeping isPending true over an unrevealed changed lane answer costs +29 B minified where the rerun guard alone is retained and +121-129 B where the verdict path is. Raise the six moved scenario caps and their recorded minified at the CI measurements (Size run 42031370774), with the mechanism and the rejected smaller shapes in scenarios.js; the frozen page floor goes under the Size-Exception line in the PR body.
b685aed to
788a0af
Compare
Summary
Fixes #4685.
isPending(m)cleared as soon as a lane derivation's flight landed, even when the lane was still blocked by a sibling's pending work — so the new answer sat inlaneValueOfwhile the screen still showed the old value, andisPendingreported no pending change over a stale display.The verdict probe now also compares the lane's latest answer (
laneValueOf) against what the reader sees (v— the display, or the latest view insidelatest()). A differing, unrevealed answer keeps the probe pending; an equal one still clears early (A24). The tracked probe parks on the lane's_rerunsso it re-derives at the lane's seam — the flip happens at the reveal, which can precede and outlive the parent's landing.In
reruns, a verdict-only reader (CONFIG_VERDICTwithoutREACTIVE_FRAME_READ) no longer marks the rerun frame-producing — it only re-derives a verdict beside the screen, so the landing's releases need not wait for it. Without that, parking the probe would delay the parent by a round and eat the first reveal frame (latest-first-one-pass-4402).Three
createOptimisticassertions updated — they pinned the reported buggy window rather than the ruled semantics:isPending(m)isfalsein the window wherem's changed answer has landed into a lane still blocked by a sibling flight — the exact shape 2.0.0-rc.21: isPending clears before a changed optimistic result is revealed #4685 reports as a bug.isPending holds until merged lane completes, not just individual asyncdescribes the desired behavior in its own comment ("isPending for each path should stay true until the ENTIRE merged lane resolves") while asserting the opposite.If per-flight clearing is the intended contract for merged lanes after all, I'm happy to rework — these assertions can be restored and the issue triaged accordingly.
How did you test this change?
New regression test
ispending-unrevealed-lane-landing-4685.test.tsmodels the issue's repro: an optimistic guess under a never-resolving action,leftlanding before the sharedrightflight:pnpm buildclean;pnpm vitest runinpackages/signals: 480 files / 6694 tests pass (14 expected-fail, 2 skipped).rerunsis retained without the verdict path (the floors,+ createStore, observe + attribution,base + router); the probe's lane-answer comparison brings it to +128–129 B minified where the verdict path is (+ isPending/latest, the live pages). Caps for the rerun-guard-only scenarios are raised measured by CI (Size run 42031370774); after the rebase over fix(signals): a lane reveals whole beside its parent's landing (#4677) #4687 three scenarios are re-recorded over the new base measured by CI (run 42092720174:+ isPending/latest12.29 KB / 33,743 B minified; the live-page floor 40.35 KB / 121,282 B — see the Size-Exception below; run 42133064937:+ every store primitive family33.44 KB / 100,576 B minified).scenarios.jsrecords the smaller shapes rejected for changing semantics — a stale-reader park delays the landing's releases, and averdictReadpark re-routes the reader's pass into the lane.docs/RULES-INDEX.mdregenerated (verdict.tsA24 citation count);node scripts/rules-index.mjs --checkpasses.Size-Exception:
page: live server componentsis a frozen floor; the +129 B minified there is the fix's verdict-probe cost described above, not slack — the smaller shapes change semantics.