import { is } from '@alloc/is'
import {
Change,
Observable,
ObservedSlot,
Observer,
ObserverTarget,
} from './observable'
import { $O } from './symbols'
type WatchedState = ObserverTarget & {
forEach?: (cb: (value: any, key: any, ctx: any) => void) => void
}
type ChangeHandler = (change: Change) => void
/**
* Watch a single property.
* If its value is observable, watch it recursively.
*/
export function watch
(
root: Map
,
key: P,
onChange: (change: Change) => void
): Watcher
export function watch(
root: T,
key: P,
onChange: (change: Change) => void
): Watcher
/**
* Watch an observable tree for changes.
* Only observable objects are searched for watchable values.
*/
export function watch(root: object, onChange: ChangeHandler): Watcher
export function watch(
root: object & { [$O]?: Observable },
arg2: unknown,
arg3?: ChangeHandler
) {
return arg3
? new Watcher(root, arg3, arg2)
: new Watcher(root, arg2 as ChangeHandler)
}
/** An observer of deep changes */
export class Watcher extends Observer {
observed = new Set()
counts = new Map