import { AffineFold , Equivalence , get , Getter , Iso , Lens , modify , optic , preview , Prism , set , } from 'optics-ts' ; import { atom } from './atom' ; import { Atom , PrismAtom , ReadableAtom , Updater } from '../types' ; export function focusAtom < Value , FocusedValue > ( atom , opticCallback ) ; export function focusAtom < Value , FocusedValue > ( atom , opticCallback ) ; export function focusAtom < Value , FocusedValue > ( atom , opticCallback ) ; export function focusAtom < Value , FocusedValue > ( atom , opticCallback ) ; export function focusAtom < Value , FocusedValue > ( baseAtom , opticCallback ) { const focus = opticCallback ( optic < Value > ( ) ) ; switch ( focus . _tag ) { case 'Iso' : case 'Equivalence' : case 'Lens' : return atom ( getAtomValue => get ( focus ) ( getAtomValue ( baseAtom ) ) , ( update ) => { const nextValue = ( update instanceof Function ? modify ( focus ) ( update ) : set ( focus ) ( update ) ) ( baseAtom . getValue ( ) ) ; baseAtom . update ( nextValue ) ; } ) ; case 'Getter' : return atom ( getAtomValue => get ( focus ) ( getAtomValue ( baseAtom ) ) ) ; case 'AffineFold' : return atom ( getAtomValue => preview ( focus ) ( getAtomValue ( baseAtom ) ) ) ; case 'Prism' : return atom ( getAtomValue => preview ( focus ) ( getAtomValue ( baseAtom ) ) , ( update ) => { const nextValue = ( update instanceof Function ? modify ( focus ) ( update ) : set ( focus ) ( update ) ) ( baseAtom . getValue ( ) ) ; baseAtom . update ( nextValue ) ; } ) ; } }