UNPKG

web-ui-pack

Version:
57 lines (56 loc) 3.03 kB
export declare namespace Observer { interface IObserver { /** Returns @true if object is observed (converted via observer.make()) */ isObserved(obj: any): boolean; /** Make observable object to detect changes; * @see {@link Proxy} */ make<T extends object>(obj: T, opts?: Options<T>): Observer.Observed<T>; /** Listen for any props changing on the observed; callback is called per each prop-changing * @returns callback to removeListener */ onPropChanged<T extends Observer.Observed<object>>(target: T, callback: Observer.PropCallback<T>): () => void; /** Listen for any changing on the observed; callback is called single time per bunch of props-changing * @returns callback to removeListener */ onChanged<T extends Observer.Observed<object>>(target: T, callback: Observer.Callback<T>): () => void; } interface Options<T> { /** Point array of nested prop-names to exclude from observer or true to exclude every nested property of object * @tutorial Troubleshooting * * point ['items'] to exclude any nested props of property with name `items` from obsserved of obj.items * * obj.nested.items - will be also fit the rule * * point `true` to exclude all nested */ excludeNested?: Array<keyof T> | boolean; } type Observed<T extends object = object> = { [K in keyof T]: T[K] extends Record<string, unknown> ? Observed<T[K]> : T[K]; }; type BasicPropEvent<T, K extends keyof T> = { /** Previous value */ prev: T[K] extends Func ? ReturnType<T[K]> : T[K] | undefined; /** Current/next value */ next: T[K] extends Func ? ReturnType<T[K]> : T[K] | undefined; /** Prop that is changed; For arrays it can be `length`, for Set,MapSet - `size` */ prop: K; /** Object to that prop related */ target: T; }; type DateEvent<T extends Date> = BasicPropEvent<T, "valueOf">; type MapSetEvent<T extends Set<any> | Map<any, any>> = BasicPropEvent<T, "size">; type PropEvent<T, K extends keyof T> = T extends Date ? DateEvent<T> : T extends Set<any> | Map<any, any> ? MapSetEvent<T> : BasicPropEvent<T, K>; type PropCallback<T> = <K extends keyof T>(event: PropEvent<T, K>) => void; type ObjectEvent<T> = { props: T extends Date ? Array<"valueOf"> : T extends Set<any> | Map<any, any> ? Array<"size"> : Array<keyof T>; target: T; }; type Callback<T> = (event: ObjectEvent<T>) => void; } /** Helper to detect object changes; * @example * const raw = { date: new Date(), period: 3, nestedObj: { val: 1} }; * const obj = observer.make(raw); * const removeListener = observer.onPropChanged(obj, (e) => console.warn(e)); * const removeListener2 = observer.onChanged(obj, (e) => console.warn(e)); * obj.period = 5; // events are fired after 1ms * removeListener(); * removeListener2(); */ declare const observer: Observer.IObserver; export default observer;