Decor Architecture

General notes on decor design goals and architectural decisions.

Observable

Observable is a "value-holder" object working as a shim of ES7 Object.observe(). A "value-holder" object sometimes requires decoration/undecoration from/to plain object, and triggering observation requires specific way to set a property on an object, but such "specific way" ensures the best performance, without needing to go through all observed objects to see what objects are changed at ends of micro-tasks.

For triggering observation, Stateful, a class on top of Observable, decorates declared properties with ES5 accessors. Observable itself provides .set(name, value) method which allows to trigger observation without declaraing properties. Alternatively Observable.getNotifier(observable).notify(changeRecord) can be used.

Observable and ES7 Object.observe()

Observable attemps to provide high fidelity shim of ES7 Object.observe(), but there is one difference between them, which is:

Stateful

The design goals of Stateful were:

Behind the scenes, Stateful implements the observe() method by extending decor/Observable shim of Object.observe().

But then, decor/Stateful notes all the properties defined in the prototype, direct and inherited, and calls Object.defineProperty() on the prototype to add native ES5 setters and getters for those properties. For properties where the subclass doesn't define a custom setter, Stateful will generate one on-the-fly that just calls this._set(...) to save the new value and notify Observable that the value changed.

Using custom setters means that there's no polling required to detect when properties have changed. Also, putting the custom setters on the prototype means that there's no performance issue when many instances of the class are created.

Ideally ES5 native accessors would be supported via dcl but we are still waiting for that.