import { $ALIVE , $O , definePrivate , isArray , isObject } from '../shared' ; import { getObservable } from './Observable' ; import { OProps } from './OProps' ; import { revise } from './revise' ; /**
 * An observable object or property wrapped in a function.
 *
 * Can be observed with the `useObserved` and `tap` functions.
 */ export interface OLens < T = any > { /** Get the latest value */ ( ) : T ; /** Update the latest value */ ( newValue ) : T ; } export function bind < T extends object > ( state ) ; export function bind < T extends object , P extends keyof T > ( state , prop ) ; /**
 * Wrap an observable object or property in a getter/setter function.
 *
 * The returned function is also observable.
 *
 * For object values, the setter merges any objects passed to it, instead of
 * replacing the entire object value.
 */ export function bind ( state , prop ? ) { const target = getObservable ( state ) ; if ( ! ( target instanceof OProps ) ) { throw Error ( 'Expected an observable object' ) ; } const lens = ( ... args ) => { const state = target . get ( ) ; if ( ! args . length ) { return prop == null ? state : state [ prop ] ; } const newValue = args [ 0 ] ; if ( prop == null ) { return revise ( state , newValue ) ; } const oldValue = state [ prop ] ; if ( oldValue && oldValue [ $O ] && isObject ( newValue ) && ! isArray ( newValue ) ) { return revise ( oldValue , newValue ) ; } revise ( state , { [ prop ] : newValue } ) ; return newValue ; } ; definePrivate ( lens , $O , prop == null ? target : target . watch ( prop ) ) ; definePrivate ( lens , $ALIVE , true ) ; return lens ; }