Repository navigation
Conversation
…t carried (#4576) A derivation that is lane work (it reads an optimistic guess) and is served the committed value of a refreshing store drops that refresh from its own pending sources (`laneServed`, #4397). The render effect the refresh's pending had propagated onto through it kept the mark: the refresh's landing walk stopped at the derivation, which no longer carried the source, so the effect stayed pending on a flight that had already landed. A filter change held with it never committed once the second async memo answered last. The drop now retires the source from the dependents that carried it through the derivation (`settlePendingSource`, which keeps it where another path still reaches it). A hold lasts only while an on-screen reader observes a flight it waits on (D-11), so the change commits once every ask has answered (F-2), settling as one with what shares the screen (D-9) and whole on the way (F-1). Lanes engine only; no core-path change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117BoWNSSgtemsSYsaX2hXE
Merging this PR will improve performance by 5.77%1 warning
Performance Changes
Tip Curious why performance improved? Comment Comparing Footnotes
|
|
CodSpeed's two flagged benches aren't from this change:
No perf fix is needed. Generated by Claude Code |
🦋 Changeset detectedLatest commit: ff4eeaa 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 |
Coverage Report for CI Build 41298035558Coverage remained the same at 78.134%Details
Uncovered ChangesNo uncovered changes found. Coverage RegressionsNo coverage regressions found. Coverage Stats
💛 - Coveralls |
Size (brotli, eager entry chunk)
|
…d on the committed world (#4577) Re-derived at the seam, a re-based lane pass paired the frame's new rows with the old filter, and the landing then showed that beside the new filter (F-1, D-34 ¶3). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117BoWNSSgtemsSYsaX2hXE
|
The red Generated by Claude Code |
… through merges (#4577) A second async change merged into the parked filter frame mid-hold; the lane's later passes then read the screen and re-asked over the old filter, and the landing committed that beside the new one (F-1, D-9). This also covers #4576, so laneServed is back to its next form. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117BoWNSSgtemsSYsaX2hXE
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117BoWNSSgtemsSYsaX2hXE
Without it a nested action's refresh answers were lost (the store ended [2, 5] instead of [5]). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0117BoWNSSgtemsSYsaX2hXE
Requested by Ryan · project thread
Summary
A filter change held with an optimistic action never committed when a second async memo's answer to the new filter came in after the action's refresh had answered (#4576, the
shared, memoprobe variant; the other bindings already settled onnextafter #4564).Root cause
The list derivation (
createMemoover the store) counts as lane work because it reads the guess. While the action'srefresh(issues)was running, that derivation got the committed rows throughframeRead, solaneServeddropped the refresh from its own pending sources (#4397). The render effect that the refresh's pending had already reached through the derivation kept the mark. When the refresh landed, its settle walk stopped at the derivation, which no longer carried that source, so it never reached the effect. The filter's transaction stayed blocked on a reader pending on a flight that had already landed, with nothing left to wake it.Fix
A lane re-based over a transaction's answer (#4536) reads that transaction's world in every flush, including when the transaction has merged since. Before, it only did so in that transaction's own flush (core.ts
frameRead, which comparesresolveTx(passLane.over)with the transaction). Lane passes run in other flushes: the action'srefresh, the refetch landing, or another change merged into the frame. There they read the screen, so the landing committed values derived over the old inputs.The first commit on this PR retired the carried pending in
laneServed. That turned out to treat a symptom of the same cause, and it has been reverted:laneServedis back to itsnextform.The
laneSeamsre-derive also skips lane work re-based over the parked frame (liveTx(l.over) === t), because its rows already belong to that frame's answer.Rules
Tests
optimistic-refresh-late-shared-memo-4576.test.tscovers shared/split × inline/memo bindings. It checks the final frame (closed: [#2] | O-closed), that no ask is left, and that every recorded frame is whole. The failing pin isshared, memo: it fails onnextand passes here. The other three already pass onnextand stay as regression pins.optimistic-guess-second-async-memo-4577.test.tsis the [2.0] Filter change never commits when a second async memo reads the optimistically guessed list #4577 shape. Every frame must be whole: one memo's two readers agree, the shared memo's filter matches the screen's, andothermatches the filter. It passes onnext, which stays stuck on the old but whole screen. It failed on this PR's first commit atclosed|[#2]|[#2]|open:[#2]|O-open, and passes now.optimistic-guess-entangled-async-4577.test.ts: review's mid-holdsetTagrepro plus a 12-case matrix (whensetTagruns × whetherotherreads the list × shared/split). The repro and the 6 list-reading cases fail atclosed: [#2] | O-openon 4844d77 and pass now.npx vitest run): 6216 passed. The only failures aredist-artifacts.test.ts, which needs a builtdist/.#4577 (the second memo reads the guessed list)
It has the same cause. A second async memo reads the guessed list, the lane's passes outside the filter's flush re-asked
other:open, and the landing showedopen:[#2]andO-openbesideclosed. It also tore when another async change (setTag) merged into the frame mid-hold.Following the batch process, this PR leaves
scripts/sizealone.Fixes #4576
Fixes #4577
Generated by Claude Code