Skip to content

Commit

Permalink
fix(store): recompute dependents on eager evaluation in writeAtomState (
Browse files Browse the repository at this point in the history
#2965)

* add failing test

* fix the test

* only recompute the atom we are getting

* include dirty dependencies (deep)

* only recompute if the top is dirty

* beautify

* alternate solution

---------

Co-authored-by: daishi <daishi@axlight.com>
  • Loading branch information
dmaskasky and dai-shi authored Feb 1, 2025
1 parent bcf45c9 commit 644ba5e
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/vanilla/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
return setSelf
},
}
const prevEpochNumber = atomState.n
try {
const valueOrPromise = atomRead(atom, getter, options as never)
setAtomStateValueOrPromise(atom, atomState, valueOrPromise)
Expand All @@ -404,6 +405,14 @@ const buildStore = (...storeArgs: StoreArgs): Store => {
return atomState
} finally {
isSync = false
if (
prevEpochNumber !== atomState.n &&
invalidatedAtoms.get(atom) === prevEpochNumber
) {
invalidatedAtoms.set(atom, atomState.n)
changedAtoms.set(atom, atomState)
atomState.u?.()
}
}
}

Expand Down
19 changes: 19 additions & 0 deletions tests/vanilla/store.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1223,3 +1223,22 @@ it('updates with reading derived atoms (#2959)', () => {
store.set(countUpAtom)
expect(store.get(countDerivedAtom)).toBe(2)
})

it('updates dependents when it eagerly recomputes dirty atoms', () => {
const countAtom = atom(0)
const isActiveAtom = atom(false)
const activeCountAtom = atom((get) =>
get(isActiveAtom) ? get(countAtom) : undefined,
)
const activateAction = atom(null, (get, set, value: boolean) => {
set(isActiveAtom, value)
get(activeCountAtom)
})

const store = createStore()
store.sub(activeCountAtom, () => {})
store.set(activateAction, true)
store.set(countAtom, 1)

expect(store.get(activeCountAtom)).toBe(1)
})

0 comments on commit 644ba5e

Please # to comment.