Repository navigation
fix(reactivity): preserve updates with repeated dependencies (fix #16174) - #16178
Narek-Khachikyan wants to merge 2 commits into
Conversation
Track successful propagation generations so repeated dependency links do not consume Recursed state twice within the same push. Preserve newer nested notifications when an older traversal resumes after onTrigger. Cover the lost-update reproduction, longer read gaps, conditional cleanup and nested notification order without changing dependency tracking. Closes vuejs#16174
Allow an older traversal to invalidate a clean subscriber when its incoming dependency is still dirty or pending. A newer nested notification cannot cover a computed branch that has not yet been invalidated. Keep generation-based suppression for duplicate links whose dependencies have already been read clean.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the
|
When a computed reads the same dependency non-adjacently, duplicate links can consume its recursion state twice during one push. An effect that writes a dependency of the computed it reads can then miss a later update: the reproduction produces
[1, 4]instead of[1, 4, 0].Record successful propagation transitions per invocation before callback-capable flag writes. This preserves legal duplicate links while preventing repeated state advancement, including after newer nested pushes. A clean subscriber still receives an invalidation from a dirty or pending dependency that the nested push did not cover.
Targets
minor: the affected 3.6 reactivity implementation differs from stable 3.5.Closes #16174
Evidence
CI=true pnpm test-unit --maxWorkers=2: 288 files pass; 9328 passed, 2 expected fail, 3 skipped, 17 todo. Explicit GC: 4 passed, 2 existing todo, no skips.Trade-offs
Extra propagation bookkeeping adds 165 raw / 49 gzip bytes to the production reactivity esm-browser build. A historical 35% sequential large-ref throughput loss did not consistently reproduce under paired comparisons; a few-percent cost remains uncertain on the shared host. The unchanged default 30 ms computed timing guard passed in the final focused run; an earlier loaded run failed at about 300 ms.