fix(signals): a released projection leaf leaves its firewall's companion set (#3503) - #3506
Merged
Merged
Conversation
🦋 Changeset detectedLatest commit: 6e9243c The changes in this PR will be included in the next version bump. This PR includes changesets to release 11 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 |
…ion set (solidjs#3503) A store leaf read only through latest()/isPending() joins its projection's `_companionChildren` set so the post-recompute snap can find it. The unobserved sweep drops the leaf from the store cache and the firewall child chain, but the set kept it — and with it the leaf's last value and its companion nodes — for the projection's lifetime. `unlinkFirewallChild` now removes the leaf from the set too (and from the test-only INV-4 registry, which otherwise pins it under __TEST__). Pin: gc.test.ts `releases an obsolete leaf value after a latest()/isPending() reader is disposed (solidjs#3503)` — fails on next 191a572, passes with the fix. Size: `+ createStore` 16.45 -> 16.50 KB, measured 16,477 B vs next's 16,426 (+51 brotli for one `?.delete(n)`; next had 24 B of headroom). Other scenarios unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Co-authored-by: Cursor <cursoragent@cursor.com>
ryansolid
force-pushed
the
fix/companion-leaf-release-3503
branch
from
September 17, 2026 04:51
86f4bc4 to
6e9243c
Compare
This was referenced Sep 17, 2026
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.
Fixes #3503.
markFirewallChildCompanionsregisters a leaf on its projection's permanent_companionChildrenset the first time it is read throughlatest()orisPending(). When the last reader is disposed, the unobserved sweep removes the leaf from the store's node cache andunlinkFirewallChildtakes it off the firewall child chain (#3351), but nothing removed it from the companion set. Later writes address a fresh leaf, so the obsolete leaf, its last value, and its companion signal/computed stayed reachable from the live projection.The fix removes the leaf from the set inside
unlinkFirewallChild. The set exists only so the snap can iterate the children someone asked verdicts of; a leaf the store no longer addresses can never be asked again, so dropping it changes no verdict. Under__TEST__the INV-4companionOwnersregistry is released at the same point so the in-suite GC test can observe the runtime behaviour (the issue notes this registry would otherwise mask it).Reproduced the issue's script (ordinary / latest / isPending / nested, delete and overwrite variants) against the prod build on
next191a572: ordinary passes, the rest fail; all pass with this change.packages/signals/tests/gc.test.ts(two cases, run withNODE_OPTIONS=--expose-gc npx vitest run tests/gc.test.ts; the existingshould gc effect lazilycase is broken onnextindependently andpnpm test:gcno longer finds the file under vitest 4).signals: + createStorecap 16.45 -> 16.50 KB (measured 16,477 B;nextmeasures 16,426). Core floor and+ isPending/latestunchanged.🤖 Generated with Claude Code