fix(signals): a run that committed undefined is not WASTED_RECOMPUTE - #3716
Conversation
A projection that mutates its draft, or a memo that does its work by writing a signal, commits undefined on every run, so the equality gate always closed and the re-runs were counted as wasted. The rule that undefined outputs are exempt only applied to effects. recomputeEnd now passes a separate noValue flag to checkWastedRecompute; changed, costs and records are unchanged. Fixes solidjs#3715
🦋 Changeset detectedLatest commit: 7d723f8 The changes in this PR will be included in the next version bump. This PR includes changesets to release 12 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 |
…consumer agrees The exemption for runs that commit `undefined` lived only inside checkWastedRecompute, so the RerunEvent still said `changed: false` and costs().wastedMs, expectNoWaste, the performance tracks and the why-run log kept counting projection and writing-memo runs as waste. Apply it to `changed` in recomputeEnd instead, mirroring the effect-output rule, and drop the noValue parameter. This is the documented behavior: an `undefined`-output compute reports `changed: true` and is exempt. Co-authored-by: Claude via Cursor <noreply@cursor.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Merging this PR will not alter performance
Comparing Footnotes
|
|
Fixes #3715.
Summary
The WASTED_RECOMPUTE diagnostic counted a re-run as wasted whenever the computed's committed value was unchanged. A projection's internal computed always commits
undefined(its work is draft writes or reconciling a returned value), so every projection re-run, and any memo that works by writing, was reported as producing the same value. The change passes anoValueflag into the check and skips the wasted count for runs that committedundefined.How did you test this change?
Added
attribution-wasted-recompute.test.tswith three cases (draft mutation, returned value to reconcile, memo that writes). Before the fix 3 of 8 tests fail; with it all 8 pass.Maintainer addition (commit 7d723f8, pushed on top of the contributor's commit):
Maintainer follow-up
The
undefinedexemption now applies tochangeditself inrecomputeEnd, mirroring the existing effect-output rule, instead of a separatenoValueflag read only bycheckWastedRecompute. Every consumer of the per-run record now agrees with the finding. The draft-projection test also asserts that itsrerunrecords reportchanged: trueand thatcosts().wastedMsis0.Public API Changes
RerunEvent.changedis nowtruefor a plain run that commitsundefined(projections, memos that do their work by writing). This moves every consumer of that field:costs().scopes[].wastedMsno longer counts these runs;expectNoWastein@solidjs/diagnosticsno longer fails on them;unchanged.WASTED_RECOMPUTEno longer fires for these runs.This matches the documented behavior (
documentation/solid-2.0/08-dev-diagnostics.md,WASTED_RECOMPUTE: "a side-effect-only compute (undefinedoutput) reportschanged: trueand is exempt"). No new exports, options or diagnostic codes.