UNPKG

reactive-react

Version:

RR - Reactive React. A super tiny but purely reactive implementation of Flux architecture.

130 lines (129 loc) 4.17 kB
"use strict"; var Rx = require("rx"); var _observablePool = {}; function _replicate(source, subject) { return source.subscribe(function onOnNext(x) { setTimeout(function () { subject.onNext(x); }, 0); }, function onError(err) { subject.onError(err); }, function onComplete() { subject.onCompleted(); }); } function _getObservable(name) { return (_observablePool[name] = _observablePool[name] || new Rx.Subject()); } function _replicatedSubject(source) { return RR.replicate(source); } function getArgumentsNames(fn) { return fn .toString() .replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/)|(\s))/gm, '') .match(/^function\s*[^\(]*\(\s*([^\)]*)\)/m)[1] .split(/,/); } function argumentsAre(args, types) { return types .map(function (type, idx) { if (type == 'object') { return !!args[idx] && !('length' in args[idx]) && typeof args[idx] == 'object'; } else if (type == 'array') { return !!args[idx] && 'length' in args[idx]; } else if (type == 'function') { return !!args[idx] && typeof args[idx] == 'function'; } else { return !!args[idx]; } }) .reduce(function (sofar, curr) { return sofar && curr; }, true); } function defineMemorizedGetter(obj, name, getter) { var val; Object.defineProperty(obj, name, { get: function () { if (!val) { val = getter.call(obj); } return val; }, }); } function _assignReplicatedSubject(context) { return function (observable, prop) { return (context[prop] = _replicatedSubject(observable)); }; } var Observable = { createAction: function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var dependencies = [], register, extend; var action = {}; if (argumentsAre(args, ['object'])) { var config_1 = args[0]; action = Object.keys(config_1).reduce(function (ext, key) { defineMemorizedGetter(ext, key, function () { var deps = getArgumentsNames(config_1[key]).map(_getObservable); return _replicatedSubject(config_1[key].apply(ext, deps)); }); return ext; }, action); } else { if (argumentsAre(args, ['array', 'function'])) { dependencies = args[0]; register = args[1]; } else if (argumentsAre(args, ['function'])) { register = args[0]; dependencies = getArgumentsNames(register); } extend = register.apply(action, dependencies.map(_getObservable)); for (var prop in extend) { _assignReplicatedSubject(action)(extend[prop], prop); } } return action; }, bind: function (observableName, transform) { var subject = new Rx.Subject(), trans = transform || (function (x) { return x; }), context = null, disposable = null; return function (obj) { if (context !== this) { if (disposable) { disposable.dispose(); subject = new Rx.Subject(); } disposable = _replicate(trans.apply(this, [subject, this]), _getObservable(observableName)); context = this; } return subject.onNext(obj); }; }, }; var RR = { replicate: function (source, name) { if (name === void 0) { name = null; } var sub = name ? _getObservable(name) : new Rx.Subject(); var ret = Object.create(sub); Object.defineProperties(ret, { subject: { value: sub }, disposable: { value: _replicate(source, sub) }, }); return ret; }, getObservable: function (name) { return _getObservable(name); }, Observable: Observable, }; module.exports = RR;