Skip to content

Commit

Permalink
refactor(withAtomEffect)
Browse files Browse the repository at this point in the history
  • Loading branch information
David Maskasky committed Aug 26, 2024
1 parent 458b14e commit fa0f231
Showing 1 changed file with 15 additions and 24 deletions.
39 changes: 15 additions & 24 deletions src/withAtomEffect.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,19 @@
import type { Atom, Getter, Setter, WritableAtom } from 'jotai/vanilla'
import { atom } from 'jotai/vanilla'
import type { EffectFn } from './atomEffect'
import { atomEffect } from './atomEffect'
import type { Atom } from 'jotai/vanilla'
import { type EffectFn, atomEffect } from './atomEffect'

export function withAtomEffect<Value, Args extends unknown[], Result>(
targetAtom: WritableAtom<Value, Args, Result>,
export function withAtomEffect<T extends Atom<any>>(
targetAtom: T,
effectFn: EffectFn
): WritableAtom<Value, Args, Result>

export function withAtomEffect<Value>(
targetAtom: Atom<Value>,
effectFn: EffectFn
): Atom<Value>

export function withAtomEffect<Value, Args extends unknown[], Result>(
targetAtom: Atom<Value> | WritableAtom<Value, Args, Result>,
effectFn: EffectFn
): Atom<Value> | WritableAtom<Value, Args, Result> {
const effect = atomEffect(effectFn)
const readFn = (get: Getter) => void get(effect) ?? get(targetAtom)
if ('write' in targetAtom) {
type WriteFn = (get: Getter, set: Setter, ...args: Args) => Result
const writeFn: WriteFn = (_, set, ...args) => set(targetAtom, ...args)
return atom(readFn, writeFn)
): T {
const effectAtom = atomEffect(effectFn)
const descriptors = Object.getOwnPropertyDescriptors(targetAtom)
descriptors.read.value = (get, options) => {
try {
return targetAtom.read(get, options)
} finally {
get(effectAtom)
}
}
return atom(readFn)
// avoid reading `init` to preserve lazy initialization
return Object.create(Object.getPrototypeOf(targetAtom), descriptors)
}

0 comments on commit fa0f231

Please sign in to comment.