Observable.observe(...) accepts an optional third argument — an options object. The only currently supported option is filters: a non-empty array of Filter instances. Changes that survive all filters (logical AND) are delivered to the observer.
import { Observable, Filter } from '@gullerya/object-observer';
Observable.observe(obs, callback, {
filters: [Filter.directChildrenOf('address'), Filter.pathsStartWith('address.city')]
});
Filter instances are created via static factory methods only; the constructor is private.
Filter.exactPaths(paths: string[]): FilterDelivers only changes whose path (as a dotted string) is an exact match for one of the provided paths. paths MUST be a non-empty array.
Filter.exactPaths(['firstName', 'address.city'])
Filter.pathsStartWith(prefix: string): FilterDelivers changes whose path string starts with prefix. prefix MUST be a non-empty string.
Filter.pathsStartWith('address')
// matches 'address', 'address.city', 'address.extra.data', ...
Filter.directChildrenOf(path: string): FilterDelivers changes whose path is a direct child of path (exactly one level deeper). path MUST be a string (may be empty — empty string means the root). REVERSE and SHUFFLE changes at path itself are also delivered, because they are semantically mutations of the container’s children.
Filter.directChildrenOf('address')
// matches 'address.city', 'address.block' — but NOT 'address' or 'address.extra.data'
Filter.directChildrenOf('')
// matches any top-level property change
Filter.custom(fn: (changes: Change[]) => Change[]): FilterWraps an arbitrary function. fn receives the (already-narrowed) array of Change objects and returns a filtered array. fn MUST be a function.
Filter.custom(changes => changes.filter(c => c.type === 'update'))
When multiple filters are provided, they run in order and each narrows the result of the previous one. Equivalent to logical AND:
// direct children of 'a' AND whose path starts with 'a.x'
// → only changes to 'a.x'
{ filters: [Filter.directChildrenOf('a'), Filter.pathsStartWith('a.x')] }
filters (when provided) MUST be a non-empty array.Filter instance — bare functions are rejected. Use Filter.custom(fn) to wrap a function.