Version 1.2.1
What's Changed
Fixed
match()stalehandler not firing on re-fetches: Previously,staleonly fired on the first effect run when a task had a seeded value and its initial fetch was in progress. On subsequent re-fetches (when a task source dependency changed), the effect silently becameFLAG_CLEANwithout running:propagate(taskNode)sent onlyFLAG_CHECKto downstream effects, sorefresh(effectNode)calledrefresh(taskNode)→recomputeTask(), which returned synchronously with no value change — the effect saw noFLAG_DIRTYand was cleaned without executing. NowrecomputeTask()callssetState(node.pendingNode, true)immediately after the synchronous fn preamble. This propagatesFLAG_DIRTYto subscribed effects mid-refresh, causing the source-check loop inrefresh()to break and run the effect, which then routes tostaleas expected.task.isPending()is now reactive: Previously a plain boolean read (!!node.controller) that created no graph edges. Now backed by an internalpendingNode: StateNode<boolean>and subscribed viamakeSubscribe— callingisPending()inside a reactive context (effect,match()) creates a dependency edge. The effect re-runs when the task transitions from not-pending to pending (fetch starts) in addition to when it transitions from pending to not-pending (fetch resolves, handled by value propagation). Effects that do not callisPending()are unaffected. Promise.then/.catchhandlers resetpendingNodetofalseinside abatch()alongside any value propagation to prevent double effect runs.
Full Changelog: v1.2.0...v1.2.1