Perhaps using a proxy is an option, although it needs to replace the original object
const { Subject } = require('rxjs'); // Take an object, and return a proxy with an 'observation$' stream const toObservableObject = targetObject => { const observation$ = new Subject(); return new Proxy(targetObject, { set: (target, name, value) => { const oldValue = target[name]; const newValue = value; target[name] = value; observation$.next({ name, oldValue, newValue }); }, get: (target, name) => name == 'observation$' ? observation$ : target[name] }); } const observableObject = toObservableObject({ }); observableObject.observation$ .filter(modification => modification.name == 'something') .subscribe(({ name, oldValue, newValue }) => console.log(`${name} changed from ${oldValue} to ${newValue}`)); observableObject.something = 1; observableObject.something = 2;
Output
something changed from undefined to 1 something changed from 1 to 2
Look for proxies in the compatibility table, current versions of node have full support) https://kangax.imtqy.com/compat-table/es6/
And the proxy documentation at https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy
source share