diff --git a/src/vanilla/utils/selectAtom.ts b/src/vanilla/utils/selectAtom.ts index 1e705839d2..e759f5879f 100644 --- a/src/vanilla/utils/selectAtom.ts +++ b/src/vanilla/utils/selectAtom.ts @@ -17,20 +17,20 @@ const memo3 = ( export function selectAtom( anAtom: Atom, - selector: (v: Awaited, prevSlice?: Slice) => Slice, + selector: (v: Value, prevSlice?: Slice) => Slice, equalityFn?: (a: Slice, b: Slice) => boolean, -): Atom ? Promise : Slice> +): Atom export function selectAtom( anAtom: Atom, - selector: (v: Awaited, prevSlice?: Slice) => Slice, - equalityFn: (a: Slice, b: Slice) => boolean = Object.is, + selector: (v: Value, prevSlice?: Slice) => Slice, + equalityFn: (prevSlice: Slice, slice: Slice) => boolean = Object.is, ) { return memo3( () => { const EMPTY = Symbol() const selectValue = ([value, prevSlice]: readonly [ - Awaited, + Value, Slice | typeof EMPTY, ]) => { if (prevSlice === EMPTY) { @@ -39,15 +39,12 @@ export function selectAtom( const slice = selector(value, prevSlice) return equalityFn(prevSlice, slice) ? prevSlice : slice } - const derivedAtom: Atom | typeof EMPTY> & { + const derivedAtom: Atom & { init?: typeof EMPTY } = atom((get) => { const prev = get(derivedAtom) const value = get(anAtom) - if (value instanceof Promise || prev instanceof Promise) { - return Promise.all([value, prev] as const).then(selectValue) - } - return selectValue([value as Awaited, prev] as const) + return selectValue([value, prev] as const) }) // HACK to read derived atom before initialization derivedAtom.init = EMPTY diff --git a/tests/react/vanilla-utils/selectAtom.test.tsx b/tests/react/vanilla-utils/selectAtom.test.tsx index 9dcf10c498..cbd26cde15 100644 --- a/tests/react/vanilla-utils/selectAtom.test.tsx +++ b/tests/react/vanilla-utils/selectAtom.test.tsx @@ -1,7 +1,7 @@ -import { StrictMode, Suspense, useEffect, useRef } from 'react' +import { StrictMode, useEffect, useRef } from 'react' import { fireEvent, render } from '@testing-library/react' import { it } from 'vitest' -import { useAtom, useAtomValue, useSetAtom } from 'jotai/react' +import { useAtomValue, useSetAtom } from 'jotai/react' import { atom } from 'jotai/vanilla' import { selectAtom } from 'jotai/vanilla/utils' @@ -58,54 +58,6 @@ it('selectAtom works as expected', async () => { await findByText('a: 3') }) -it('selectAtom works with async atom', async () => { - const bigAtom = atom({ a: 0, b: 'othervalue' }) - const bigAtomAsync = atom((get) => Promise.resolve(get(bigAtom))) - const littleAtom = selectAtom(bigAtomAsync, (v) => v.a) - - const Parent = () => { - const setValue = useSetAtom(bigAtom) - return ( - <> - - - ) - } - - const Selector = () => { - const a = useAtomValue(littleAtom) - return ( - <> -
a: {a}
- - ) - } - - const { findByText, getByText } = render( - - - - - - , - ) - - await findByText('a: 0') - - fireEvent.click(getByText('increment')) - await findByText('a: 1') - fireEvent.click(getByText('increment')) - await findByText('a: 2') - fireEvent.click(getByText('increment')) - await findByText('a: 3') -}) - it('do not update unless equality function says value has changed', async () => { const bigAtom = atom({ a: 0 }) const littleAtom = selectAtom( @@ -177,57 +129,3 @@ it('do not update unless equality function says value has changed', async () => await findByText('value: {"a":3}') await findByText('commits: 4') }) - -it('equality function works even if suspend', async () => { - const bigAtom = atom({ a: 0 }) - const bigAtomAsync = atom((get) => Promise.resolve(get(bigAtom))) - const littleAtom = selectAtom( - bigAtomAsync, - (value) => value, - (left, right) => left.a === right.a, - ) - - const Controls = () => { - const [value, setValue] = useAtom(bigAtom) - return ( - <> -
bigValue: {JSON.stringify(value)}
- - - - ) - } - - const Selector = () => { - const value = useAtomValue(littleAtom) - return
littleValue: {JSON.stringify(value)}
- } - - const { findByText, getByText } = render( - - - - - - , - ) - - await findByText('bigValue: {"a":0}') - await findByText('littleValue: {"a":0}') - - fireEvent.click(getByText('increment')) - await findByText('bigValue: {"a":1}') - await findByText('littleValue: {"a":1}') - - fireEvent.click(getByText('other')) - await findByText('bigValue: {"a":1,"b":2}') - await findByText('littleValue: {"a":1}') -}) diff --git a/tests/vanilla/utils/types.test.tsx b/tests/vanilla/utils/types.test.tsx index 76db62a09a..8a2a07dd8b 100644 --- a/tests/vanilla/utils/types.test.tsx +++ b/tests/vanilla/utils/types.test.tsx @@ -10,16 +10,6 @@ it('selectAtom() should return the correct types', () => { const syncAtom = atom(0) const syncSelectedAtom = selectAtom(syncAtom, doubleCount) expectType, typeof syncSelectedAtom>>(true) - - const asyncAtom = atom(Promise.resolve(0)) - const asyncSelectedAtom = selectAtom(asyncAtom, doubleCount) - expectType>, typeof asyncSelectedAtom>>(true) - - const maybeAsyncAtom = atom(Promise.resolve(0) as number | Promise) - const maybeAsyncSelectedAtom = selectAtom(maybeAsyncAtom, doubleCount) - expectType< - TypeEqual>, typeof maybeAsyncSelectedAtom> - >(true) }) it('unwrap() should return the correct types', () => {