UNPKG

wana

Version:

Easy observable state for React

57 lines (50 loc) 1.7 kB
import { is } from '@alloc/is' import { useMemoOne as useMemo } from 'use-memo-one' import { emptyArray, getOwnDescriptor } from '../common' import { Derived, isDerived, WithDerived } from '../derive' import { noto } from '../noto' import { o } from '../o' import { useDerived } from './useDerived' export function useO<T extends object>( state: Exclude<T, Function>, deps?: readonly any[] ): WithDerived<T> /** * Create an observable getter that is managed by React. * This lets you memoize an expensive combination of observable values. */ export function useO<T>( create: () => () => T, deps?: readonly any[] ): Derived<T> /** Create observable component state. */ export function useO<T>( create: () => Exclude<T, Function>, deps?: readonly any[] ): T /** Memoize an object and return its observable proxy. Non-objects are returned as-is. */ export function useO<T>(state: T, deps?: readonly any[]): T /** @internal */ export function useO(state: any, deps?: readonly any[]) { const result = useMemo<any>( () => convertDerived(is.function(state) ? noto(state) : state), deps || emptyArray ) // Beware: Never switch between observable getter and observable object. return is.function(result) ? useDerived(result, [result]) : o(result) } // Convert observable getters into property getters. // This is *not* responsible for disposal. function convertDerived(state: any) { if (is.plainObject(state)) { for (const key in state) { const desc = getOwnDescriptor(state, key)! if (isDerived(desc.value) && desc.configurable) { Object.defineProperty(state, key, { get: desc.value, }) } } } return state }