Skip to content

Commit

Permalink
fix(lens): lensed atom distinct changes (#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
Fyzu authored May 26, 2022
1 parent e0c1886 commit d56fd2b
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 8 deletions.
24 changes: 24 additions & 0 deletions packages/lens/src/lensed-atom.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,28 @@ describe('view', () => {
expect(ao.next).toHaveBeenCalledTimes(1)
expect(bo.next).toHaveBeenCalledTimes(1)
})
it('distinct changes', () => {
const a = newLensedAtom({ foo: 0, bar: 'bar' })
const foo = a.view(prop('foo'))
const bar = a.view(prop('bar'))
const fooObserver = {
next: jest.fn(),
}
const barObserver = {
next: jest.fn(),
}
foo.subscribe(fooObserver)
bar.subscribe(barObserver)
// imitate consumer to warm up the cache
foo.get()
bar.get()

foo.set(2)
expect(fooObserver.next).toHaveBeenCalledTimes(1)
expect(barObserver.next).toHaveBeenCalledTimes(0)

bar.set('baz')
expect(barObserver.next).toHaveBeenCalledTimes(1)
expect(fooObserver.next).toHaveBeenCalledTimes(1)
})
})
13 changes: 5 additions & 8 deletions packages/lens/src/lensed-atom.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Atom, newAtom, newProperty } from '@frp-ts/core'
import { Atom, combine, newAtom } from '@frp-ts/core'

export interface Lens<S, A> {
readonly get: (s: S) => A
Expand All @@ -12,18 +12,15 @@ export interface LensedAtom<A> extends Atom<A> {
export const newLensedAtom = <A>(initial: A): LensedAtom<A> => toLensedAtom(newAtom(initial))

export const toLensedAtom = <A>(atom: Atom<A>): LensedAtom<A> => {
const { set, get, subscribe } = atom

const view = <B>(lens: Lens<A, B>): LensedAtom<B> => {
const lensedGet = () => lens.get(get())
const lensedSet = (b: B) => set(lens.set(b)(get()))

const lensedSet = (b: B) => atom.set(lens.set(b)(atom.get()))
const lensedProperty = combine(atom, lens.get)
return {
...newProperty(lensedGet, subscribe),
...lensedProperty,
set: lensedSet,
view: (bc) => view(composeLens(lens, bc)),
modify: (...updates) => {
let value = lensedGet()
let value = lensedProperty.get()
for (const update of updates) {
value = update(value)
}
Expand Down

0 comments on commit d56fd2b

Please sign in to comment.