UNPKG

@difizen/mana-observable

Version:

78 lines (72 loc) 2.01 kB
import { Disposable, Event } from '@difizen/mana-common'; import type { Notify } from './core'; import { Notifier } from './notifier'; import { observable } from './observable'; import { getOrigin, Observability } from './utils'; function tryObservable<T>(target: T) { const data = getOrigin(target); if (!Observability.canBeObservable(data)) { return data; } if (!Observability.marked(data)) { return observable(data); } return data; } function watchAll<T>(target: T, callback: Notify): Disposable { const data = getOrigin(target); if (!Observability.canBeObservable(data)) { return Disposable.NONE; } tryObservable(data); const event = Notifier.toEvent(data); if (event === Event.None) { console.warn('Cannot add watcher for unobservable target', target); return Disposable.NONE; } const props: string[] = Object.keys(data); if (props) { props.forEach((prop) => Notifier.find(target, prop)); } return event(callback); } function watchProp<T>( target: T, prop: Extract<keyof T, string>, callback: Notify, ): Disposable { const origin = getOrigin(target); tryObservable(origin); const event = Notifier.toEvent(origin, prop); if (event === Event.None) { console.warn( `Cannot add watcher for unobservable property ${prop.toString()}`, target, ); return Disposable.NONE; } return event(callback); } export function watch<T>(target: T, callback: Notify): Disposable; export function watch<T>( target: T, prop: Extract<keyof T, string>, callback: Notify, ): Disposable; export function watch<T>( target: T, prop: Extract<keyof T, string> | Notify, callback?: Notify, ): Disposable { let cb: Notify; if (typeof prop === 'function') { cb = prop; return watchAll(target, cb); } if (typeof prop === 'string' && callback) { cb = callback; return watchProp(target, prop, cb); } console.warn(`Invalid arguments for watch ${prop.toString()}`, target); return Disposable.NONE; }