Skip to content

Commit

Permalink
chore: cleanup readme and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
David Maskasky committed Jan 30, 2024
1 parent 1f579fe commit cedf152
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 14 deletions.
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
## install

```
yarn add jotai-effect
npm i jotai-effect
```

## atomEffect
Expand All @@ -17,9 +17,12 @@ yarn add jotai-effect
```ts
type CleanupFn = () => void

type EffectFn = (get: Getter, set: Setter & { recurse: Setter }) => CleanupFn | void
type EffectFn = (
get: Getter,
set: Setter & { recurse: Setter },
) => CleanupFn | void

function atomEffect(effectFn: EffectFn): Atom<void>
declare function atomEffect(effectFn: EffectFn): Atom<void>
```

**effectFn** (required): A function for listening to state updates with `get` and writing state updates with `set`. The `effectFn` is useful for creating side effects that interact with other Jotai atoms. You can cleanup these side effects by returning a cleanup function.
Expand Down Expand Up @@ -104,6 +107,9 @@ function MyComponent() {
set(countAtom, increment)
})
```

</details>

- **Supports Recursion:**
Recursion is supported with `set.recurse` for both sync and async use cases, but is not supported in the cleanup function.

Expand Down Expand Up @@ -254,8 +260,8 @@ Aside from mount events, the effect runs when any of its dependencies change val
try {
await delay(1000)
abortController.signal.throwIfAborted()
get(dataAtom); // dataAtom is not an atom dependency
} catch(e) {
get(dataAtom) // dataAtom is not an atom dependency
} catch (e) {
if (e instanceof AbortError) {
// async cleanup logic here
} else {
Expand Down
18 changes: 9 additions & 9 deletions __tests__/atomEffect.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ it('should not cause infinite loops when effect updates the watched atom asynchr
expect(runCount).toBe(2)
})

it('should allow synchronous infinite loops with opt-in for first run', async () => {
it('should allow synchronous recursion with set.recurse for first run', async () => {
expect.assertions(1)
let runCount = 0
const watchedAtom = atom(0)
Expand All @@ -200,7 +200,7 @@ it('should allow synchronous infinite loops with opt-in for first run', async ()
})
})

it('should allow synchronous infinite loops with opt-in', async () => {
it('should allow synchronous recursion with set.recurse', async () => {
expect.assertions(2)
let runCount = 0
const watchedAtom = atom(0)
Expand All @@ -224,7 +224,7 @@ it('should allow synchronous infinite loops with opt-in', async () => {
expect(runCount).toBe(6)
})

it('should allow multiple synchronous infinite loops with opt-in', async () => {
it('should allow multiple synchronous recursion with set.recurse', async () => {
expect.assertions(1)
let runCount = 0
const watchedAtom = atom(0)
Expand All @@ -251,7 +251,7 @@ it('should allow multiple synchronous infinite loops with opt-in', async () => {
})
})

it('should batch while synchronous recursing', async () => {
it('should batch updates during synchronous recursion with set.recurse', async () => {
expect.assertions(2)
let runCount = 0
const lettersAtom = atom('a')
Expand Down Expand Up @@ -288,7 +288,7 @@ it('should batch while synchronous recursing', async () => {
expect(runCount).toBe(4)
})

it('should allow asynchronous infinite loops with task delay', async () => {
it('should allow asynchronous recursion with task delay with set.recurse', async () => {
expect.assertions(2)
let runCount = 0
const watchedAtom = atom(0)
Expand All @@ -311,7 +311,7 @@ it('should allow asynchronous infinite loops with task delay', async () => {
expect(runCount).toBe(4)
})

it('should allow asynchronous infinite loops with microtask delay', async () => {
it('should allow asynchronous recursion with microtask delay with set.recurse', async () => {
expect.assertions(2)
let runCount = 0
const watchedAtom = atom(0)
Expand All @@ -337,7 +337,7 @@ it('should allow asynchronous infinite loops with microtask delay', async () =>
expect(runCount).toBe(4)
})

it('should work with both recurse and set', async () => {
it('should work with both set.recurse and set', async () => {
expect.assertions(3)
let runCount = 0
const watchedAtom = atom(0)
Expand All @@ -361,7 +361,7 @@ it('should work with both recurse and set', async () => {
expect(runCount).toBe(4)
})

it('should disallow synchronous infinite loops in cleanup', async () => {
it('should disallow synchronous set.recurse in cleanup', async () => {
expect.assertions(3)
const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {})
let runCount = 0
Expand All @@ -388,7 +388,7 @@ it('should disallow synchronous infinite loops in cleanup', async () => {

// FIXME: is there a way to disallow asynchronous infinite loops in cleanup?

it('should return value from recurse', async () => {
it('should return value from set.recurse', async () => {
expect.assertions(1)
const countAtom = atom(0)
const incrementCountAtom = atom(null, (get, set) => {
Expand Down

0 comments on commit cedf152

Please sign in to comment.