chain-able
Version:
interfaces that describe their intentions.
122 lines (108 loc) • 11.7 kB
JavaScript
var toarr = require('../deps/to-arr')
var traverse = require('../deps/traverse')
var eq = require('../deps/traversers/eq')
var match = require('../deps/matcher')
var getPathSegments = require('../deps/dot/segments')
var dot = require('../deps/dot')
var OBSERVERS_KEY = require('../deps/meta/observers')
/**
* scoped clones
* @private
* @type {Map}
*/
var objs = new Map()
/**
* @desc > subscribe to changes
* ❗ called only on **change**
* observers are only called when data they subscribe to changes
*
* @since 3.0.1
* @class Observe
* @member Observe
* @extends {ChainedMap}
* @extends {DotProp}
* @memberOf compose
* @category Chainable
*
* @param {Class | Composable} SuperClass composable class
* @return {Observe} class
*
* @tests Observe
* @types Observe
*
* @see ChainedMap
* @see DotProp
* @see deps/matcher
* @see deps/traversers/eq
* @see deps/traverse
* @see DotProp
*
* {@link https://github.com/iluwatar/java-design-patterns/tree/master/observer observer-pattern}
* {@link https://github.com/ReactiveX/rxjs/blob/master/src/Subscriber.ts reactivex}
* {@link https://github.com/sindresorhus/awesome-observables awesome-observables}
* {@link https://medium.com/@benlesh/learning-observable-by-building-observable-d5da57405d87 building-observables}
* {@link https://github.com/addyosmani/essential-js-design-patterns/blob/master/diagrams/observer.png js-observer-png}
* {@link https://github.com/addyosmani/essential-js-design-patterns/blob/master/diagrams/publishsubscribe.png pubsub-png}
* @see {@link reactivex}
* @see {@link awesome-observables}
* @see {@link building-observables}
* @see {@link observer-pattern}
*
* @example
*
* const {compose} = require('chain-able')
* const {DotProp} = compose
* new DotProp()
* //=> DotProp
*
*/
module.exports = function (SuperClass) {
return (function (SuperClass) {
function Observe () {
SuperClass.apply(this, arguments);
}
if ( SuperClass ) Observe.__proto__ = SuperClass;
Observe.prototype = Object.create( SuperClass && SuperClass.prototype );
Observe.prototype.constructor = Observe;
Observe.prototype.observe = function observe (properties, fn) {
var this$1 = this;
var props = toarr(properties)
var hashKey = props.join('_')
var data = {}
/* prettier-ignore */
return this.meta(OBSERVERS_KEY, function (changed) {
/**
* match the keys, make the data out of it
*/
var m = match(changed.key, props)
// @@debugger
for (var i = 0; i < m.length; i++) {
var segments = getPathSegments(m[i])
dot.set(data, segments, this$1.get(segments))
}
/**
* if we have called it at least once...
* and it has not changed, leave it
* else
* clone it
* call the observer
*/
if (objs.has(hashKey) && eq(objs.get(hashKey), data)) {
// @@debugger
return
}
// @@debugger
/**
* it did change - clone it for next deepEquals check
*/
objs.set(hashKey, traverse(data).clone())
/**
* call the observer - it matched & data changed
*/
fn.call(this$1, data, this$1)
})
};
return Observe;
}(SuperClass))
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiT2JzZXJ2ZS5qcyIsInNvdXJjZXMiOlsiT2JzZXJ2ZS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCB0b2FyciA9IHJlcXVpcmUoJy4uL2RlcHMvdG8tYXJyJylcbmNvbnN0IHRyYXZlcnNlID0gcmVxdWlyZSgnLi4vZGVwcy90cmF2ZXJzZScpXG5jb25zdCBlcSA9IHJlcXVpcmUoJy4uL2RlcHMvdHJhdmVyc2Vycy9lcScpXG5jb25zdCBtYXRjaCA9IHJlcXVpcmUoJy4uL2RlcHMvbWF0Y2hlcicpXG5jb25zdCBnZXRQYXRoU2VnbWVudHMgPSByZXF1aXJlKCcuLi9kZXBzL2RvdC9zZWdtZW50cycpXG5jb25zdCBkb3QgPSByZXF1aXJlKCcuLi9kZXBzL2RvdCcpXG5jb25zdCBPQlNFUlZFUlNfS0VZID0gcmVxdWlyZSgnLi4vZGVwcy9tZXRhL29ic2VydmVycycpXG5cbi8qKlxuICogc2NvcGVkIGNsb25lc1xuICogQHByaXZhdGVcbiAqIEB0eXBlIHtNYXB9XG4gKi9cbmxldCBvYmpzID0gbmV3IE1hcCgpXG5cbi8qKlxuICogQGRlc2MgPiBzdWJzY3JpYmUgdG8gY2hhbmdlc1xuICogICAgICAg4p2XIGNhbGxlZCBvbmx5IG9uICoqY2hhbmdlKipcbiAqICAgICAgIG9ic2VydmVycyBhcmUgb25seSBjYWxsZWQgd2hlbiBkYXRhIHRoZXkgc3Vic2NyaWJlIHRvIGNoYW5nZXNcbiAqXG4gKiBAc2luY2UgMy4wLjFcbiAqIEBjbGFzcyBPYnNlcnZlXG4gKiBAbWVtYmVyIE9ic2VydmVcbiAqIEBleHRlbmRzIHtDaGFpbmVkTWFwfVxuICogQGV4dGVuZHMge0RvdFByb3B9XG4gKiBAbWVtYmVyT2YgY29tcG9zZVxuICogQGNhdGVnb3J5IENoYWluYWJsZVxuICpcbiAqIEBwYXJhbSAge0NsYXNzIHwgQ29tcG9zYWJsZX0gU3VwZXJDbGFzcyBjb21wb3NhYmxlIGNsYXNzXG4gKiBAcmV0dXJuIHtPYnNlcnZlfSBjbGFzc1xuICpcbiAqIEB0ZXN0cyBPYnNlcnZlXG4gKiBAdHlwZXMgT2JzZXJ2ZVxuICpcbiAqIEBzZWUgQ2hhaW5lZE1hcFxuICogQHNlZSBEb3RQcm9wXG4gKiBAc2VlIGRlcHMvbWF0Y2hlclxuICogQHNlZSBkZXBzL3RyYXZlcnNlcnMvZXFcbiAqIEBzZWUgZGVwcy90cmF2ZXJzZVxuICogQHNlZSBEb3RQcm9wXG4gKlxuICoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9pbHV3YXRhci9qYXZhLWRlc2lnbi1wYXR0ZXJucy90cmVlL21hc3Rlci9vYnNlcnZlciBvYnNlcnZlci1wYXR0ZXJufVxuICoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9SZWFjdGl2ZVgvcnhqcy9ibG9iL21hc3Rlci9zcmMvU3Vic2NyaWJlci50cyByZWFjdGl2ZXh9XG4gKiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL3NpbmRyZXNvcmh1cy9hd2Vzb21lLW9ic2VydmFibGVzIGF3ZXNvbWUtb2JzZXJ2YWJsZXN9XG4gKiB7QGxpbmsgaHR0cHM6Ly9tZWRpdW0uY29tL0BiZW5sZXNoL2xlYXJuaW5nLW9ic2VydmFibGUtYnktYnVpbGRpbmctb2JzZXJ2YWJsZS1kNWRhNTc0MDVkODcgYnVpbGRpbmctb2JzZXJ2YWJsZXN9XG4gKiB7QGxpbmsgaHR0cHM6Ly9naXRodWIuY29tL2FkZHlvc21hbmkvZXNzZW50aWFsLWpzLWRlc2lnbi1wYXR0ZXJucy9ibG9iL21hc3Rlci9kaWFncmFtcy9vYnNlcnZlci5wbmcganMtb2JzZXJ2ZXItcG5nfVxuICoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9hZGR5b3NtYW5pL2Vzc2VudGlhbC1qcy1kZXNpZ24tcGF0dGVybnMvYmxvYi9tYXN0ZXIvZGlhZ3JhbXMvcHVibGlzaHN1YnNjcmliZS5wbmcgcHVic3ViLXBuZ31cbiAqIEBzZWUge0BsaW5rIHJlYWN0aXZleH1cbiAqIEBzZWUge0BsaW5rIGF3ZXNvbWUtb2JzZXJ2YWJsZXN9XG4gKiBAc2VlIHtAbGluayBidWlsZGluZy1vYnNlcnZhYmxlc31cbiAqIEBzZWUge0BsaW5rIG9ic2VydmVyLXBhdHRlcm59XG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiAgICBjb25zdCB7Y29tcG9zZX0gPSByZXF1aXJlKCdjaGFpbi1hYmxlJylcbiAqICAgIGNvbnN0IHtEb3RQcm9wfSA9IGNvbXBvc2VcbiAqICAgIG5ldyBEb3RQcm9wKClcbiAqICAgIC8vPT4gRG90UHJvcFxuICpcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBTdXBlckNsYXNzID0+IHtcbiAgcmV0dXJuIGNsYXNzIE9ic2VydmUgZXh0ZW5kcyBTdXBlckNsYXNzIHtcbiAgICAvKipcbiAgICAgKiBAZGVzYyBvYnNlcnZlIHByb3BlcnRpZXMgd2hlbiB0aGV5IGNoYW5nZVxuICAgICAqXG4gICAgICogQG1ldGhvZFxuICAgICAqIEBtZW1iZXJPZiBPYnNlcnZlXG4gICAgICogQHNpbmNlIDQuMC4wIDwtIHJlZmFjdG9yZWQgd2l0aCBkb3QtcHJvcFxuICAgICAqIEBzaW5jZSAxLjAuMFxuICAgICAqXG4gICAgICogQHBhcmFtICB7TWF0Y2hhYmxlfSBwcm9wZXJ0aWVzIE1hdGNoYWJsZSBwcm9wZXJ0aWVzIHRvIG9ic2VydmVcbiAgICAgKiBAcGFyYW0gIHtGdW5jdGlvbn0gZm4gb25DaGFuZ2VkXG4gICAgICogQHJldHVybiB7Q2hhaW59IEBjaGFpbmFibGVcbiAgICAgKlxuICAgICAqIEBzZWUgdHJhdmVyc2Vycy9lcVxuICAgICAqIEBzZWUgdG9hcnJcbiAgICAgKiBAc2VlIG1hdGNoZXJcbiAgICAgKlxuICAgICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vanNmaWRkbGUubmV0L3dxeHVhZ3MyLzI4L30gZm9yIGEgRGVtbyBDbG9jayB3aXRoIG9ic2VydmFibGVcbiAgICAgKiBAc2VlIHtAbGluayBleGFtcGxlcy9wbGF5Z3JvdW5kL1RvZG9TdG9yZX0gVG9kb1N0b3JlXG4gICAgICpcbiAgICAgKiBAVE9ETyBnb3R0YSB1cGRhdGUgYGRhdGFgIGlmIGBkZWxldGluZ2AgdG9vLi4uXG4gICAgICogQFRPRE8gdW4tb2JzZXJ2ZVxuICAgICAqIEBUT0RPIHNob3VsZCBoYXNoIHRoZXNlIGNhbGxiYWNrIHByb3BlcnRpZXNcbiAgICAgKiBAVE9ETyBqdXN0IHRocm90dGxlIHRoZSBgLnNldGAgdG8gYWxsb3cgZWFzaWVyIHZlcnNpb24gb2YgLmNvbW1pdFxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqICAgY29uc3QgQ2hhaW4gPSByZXF1aXJlKCdjaGFpbi1hYmxlJylcbiAgICAgKlxuICAgICAqICAgY29uc3QgY2hhaW4gPSBuZXcgQ2hhaW4oKVxuICAgICAqICAgY29uc3QgbG9nID0gYXJnID0+IGNvbnNvbGUubG9nKGFyZylcbiAgICAgKlxuICAgICAqICAgY2hhaW5cbiAgICAgKiAgICAgLmV4dGVuZChbJ2VoJ10pXG4gICAgICogICAgIC5vYnNlcnZlKCdlaCcsIGRhdGEgPT4gbG9nKGRhdGEpKVxuICAgICAqICAgICAuZWgodHJ1ZSlcbiAgICAgKiAgIC8vPT4ge2VoOiB0cnVlfVxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKlxuICAgICAqICAgIGNoYWluXG4gICAgICogICAgICAuZXh0ZW5kKFsnY2FuYWRhJywgJ3RpbWJ1Y2snXSlcbiAgICAgKiAgICAgIC5vYnNlcnZlKFsnY2FuYWQqJ10sIGRhdGEgPT4gY29uc29sZS5sb2coZGF0YS5jYW5hZGEpKVxuICAgICAqICAgICAgLmNhbmFkYSh0cnVlKVxuICAgICAqICAgICAgLmNhbmFkYSh0cnVlKVxuICAgICAqICAgICAgLnRpbWJ1Y2soZmFsc2UpXG4gICAgICpcbiAgICAgKiAgICAvLz0+IHRydWVcbiAgICAgKiAgICAvLz0+IGZhbHNlXG4gICAgICpcbiAgICAgKiAgICAvLyBvbmx5IGNhbGxlZCB3aGVuIGNoYW5nZWQsXG4gICAgICogICAgLy8gb3RoZXJ3aXNlIGl0IHdvdWxkIGJlIDIgYHRydWVgICYgMSBgZmFsc2VgXG4gICAgICovXG4gICAgb2JzZXJ2ZShwcm9wZXJ0aWVzLCBmbikge1xuICAgICAgY29uc3QgcHJvcHMgPSB0b2Fycihwcm9wZXJ0aWVzKVxuICAgICAgY29uc3QgaGFzaEtleSA9IHByb3BzLmpvaW4oJ18nKVxuICAgICAgbGV0IGRhdGEgPSB7fVxuXG4gICAgICAvKiBwcmV0dGllci1pZ25vcmUgKi9cbiAgICAgIHJldHVybiB0aGlzLm1ldGEoT0JTRVJWRVJTX0tFWSwgY2hhbmdlZCA9PiB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBtYXRjaCB0aGUga2V5cywgbWFrZSB0aGUgZGF0YSBvdXQgb2YgaXRcbiAgICAgICAgICovXG4gICAgICAgIGNvbnN0IG0gPSBtYXRjaChjaGFuZ2VkLmtleSwgcHJvcHMpXG5cbiAgICAgICAgLy8gQEBkZWJ1Z2dlclxuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGNvbnN0IHNlZ21lbnRzID0gZ2V0UGF0aFNlZ21lbnRzKG1baV0pXG4gICAgICAgICAgZG90LnNldChkYXRhLCBzZWdtZW50cywgdGhpcy5nZXQoc2VnbWVudHMpKVxuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIGlmIHdlIGhhdmUgY2FsbGVkIGl0IGF0IGxlYXN0IG9uY2UuLi5cbiAgICAgICAgICogICAgYW5kIGl0IGhhcyBub3QgY2hhbmdlZCwgbGVhdmUgaXRcbiAgICAgICAgICogZWxzZVxuICAgICAgICAgKiAgICBjbG9uZSBpdFxuICAgICAgICAgKiAgICBjYWxsIHRoZSBvYnNlcnZlclxuICAgICAgICAgKi9cbiAgICAgICAgaWYgKG9ianMuaGFzKGhhc2hLZXkpICYmIGVxKG9ianMuZ2V0KGhhc2hLZXkpLCBkYXRhKSkge1xuICAgICAgICAgIC8vIEBAZGVidWdnZXJcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEBAZGVidWdnZXJcblxuICAgICAgICAvKipcbiAgICAgICAgICogaXQgZGlkIGNoYW5nZSAtIGNsb25lIGl0IGZvciBuZXh0IGRlZXBFcXVhbHMgY2hlY2tcbiAgICAgICAgICovXG4gICAgICAgIG9ianMuc2V0KGhhc2hLZXksIHRyYXZlcnNlKGRhdGEpLmNsb25lKCkpXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIGNhbGwgdGhlIG9ic2VydmVyIC0gaXQgbWF0Y2hlZCAmIGRhdGEgY2hhbmdlZFxuICAgICAgICAgKi9cbiAgICAgICAgZm4uY2FsbCh0aGlzLCBkYXRhLCB0aGlzKVxuICAgICAgfSlcbiAgICB9XG4gIH1cbn1cbiJdLCJuYW1lcyI6WyJjb25zdCIsImxldCIsInRoaXMiXSwibWFwcGluZ3MiOiJBQUFBQSxHQUFLLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQztBQUN2Q0EsR0FBSyxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUM7QUFDNUNBLEdBQUssQ0FBQyxFQUFFLEdBQUcsT0FBTyxDQUFDLHVCQUF1QixDQUFDO0FBQzNDQSxHQUFLLENBQUMsS0FBSyxHQUFHLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQztBQUN4Q0EsR0FBSyxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUMsc0JBQXNCLENBQUM7QUFDdkRBLEdBQUssQ0FBQyxHQUFHLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQztBQUNsQ0EsR0FBSyxDQUFDLGFBQWEsR0FBRyxPQUFPLENBQUMsd0JBQXdCLENBQUM7Ozs7Ozs7QUFPdkRDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxHQUFHLEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBK0NwQixNQUFNLENBQUMsT0FBTyxHQUFHLFVBQUEsVUFBVSxDQUFBLENBQUMsQUFBRztFQUM3QixPQUFPO0lBQUEsQUFBZ0MsQUFBQzs7Ozs7Ozs7SUFBQSxBQXFEdEMsa0JBQUEsT0FBTyxvQkFBQSxDQUFDLFVBQVUsRUFBRSxFQUFFLEVBQUUsQ0FBQzs7QUFBQTtNQUN2QkQsR0FBSyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFDO01BQy9CQSxHQUFLLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO01BQy9CQyxHQUFHLENBQUMsSUFBSSxHQUFHLEVBQUU7OztNQUdiLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsVUFBQSxPQUFPLENBQUEsQ0FBQyxBQUFHOzs7O1FBSXpDRCxHQUFLLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQzs7OztRQUluQyxLQUFLQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtVQUNqQ0QsR0FBSyxDQUFDLFFBQVEsR0FBRyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1VBQ3RDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRUUsTUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztTQUM1Qzs7Ozs7Ozs7O1FBU0QsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFFOztVQUVwRCxNQUFNO1NBQ1A7Ozs7Ozs7UUFPRCxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7Ozs7O1FBS3pDLEVBQUUsQ0FBQyxJQUFJLENBQUNBLE1BQUksRUFBRSxJQUFJLEVBQUVBLE1BQUksQ0FBQztPQUMxQixDQUFDO0tBQ0gsQ0FBQSxBQUNGOzs7SUFqRzRCLFVBaUc1QixFQUFBO0NBQ0Y7In0=