UNPKG

thundercats

Version:
214 lines (175 loc) 6.54 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); exports.getActionDef = getActionDef; exports.create = create; exports.createMany = createMany; exports['default'] = Actions; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _stampit = require('stampit'); var _stampit2 = _interopRequireDefault(_stampit); var _warning = require('warning'); var _warning2 = _interopRequireDefault(_warning); var _debug = require('debug'); var _debug2 = _interopRequireDefault(_debug); var _rx = require('rx'); var _waitFor = require('./waitFor'); var _waitFor2 = _interopRequireDefault(_waitFor); var __DEV__ = process.env.NODE_ENV !== 'production'; var checkDisposed = _rx.Disposable.checkDisposed; var assign = Object.assign; var debug = (0, _debug2['default'])('thundercats:actions'); var currentStampSpec = ['methods', 'statics', 'props', 'refs', 'init', 'compose', 'create', 'isStamp']; var protectedProperties = ['shouldBindMethods', 'displayName', 'constructor'].join(currentStampSpec); function getActionDef(ctx) { return Object.getOwnPropertyNames(ctx).filter(function (name) { return protectedProperties.indexOf(name) === -1 && name.indexOf('_') === -1; }).map(function (name) { return { name: name, map: ctx[name] }; }).map(function (def) { if (typeof def.map !== 'function') { def.map = _rx.helpers.identity; } return def; }); } function create(shouldBind, _ref) { var name = _ref.name; var map = _ref.map; var observers = []; var actionDisposable = new _rx.CompositeDisposable(); var actionStart = new _rx.Subject(); var actionEnd = new _rx.Subject(); var maybeBound = shouldBind ? map.bind(this) : map; function action(value) { // throw if disposed observable is retried checkDisposed(action); if (action.isStopped) { debug('%s called after being stopped', name); return value; } // NOTE: if an error is thrown in the mapping function // this will cause the stream to collapse // and the action will no longer be observable // nor will the observers listen as they have been stopped by // the error var mapDisposable = _rx.Observable.just(value).map(maybeBound).flatMap(function (value) { if (_rx.Observable.isObservable(value)) { return value; } return _rx.Observable.just(value); }) // notify of action start ['do'](function (value) { return actionStart.onNext(value); }) // notify action observers .doOnNext(function (value) { return observers.forEach(function (observer) { return observer.onNext(value); }); }).doOnCompleted(function () { return actionEnd.onNext(); }).subscribe(function () { return debug('%s onNext', name); }, function (err) { // observables returned by the mapping function must use // a catch to prevent the action from collapsing the stream action.error = err; action.isStopped = true; action.hasError = true; // notify action observers of error observers.forEach(function (observer) { return observer.onError(err); }); // observers will no longer listen after pushing error // as the stream has collapsed // so we remove them observers.length = 0; }); actionDisposable.add(mapDisposable); return value; } action.isDisposed = false; action.isStopped = false; action.displayName = name; action.observers = observers; assign(action, _rx.Observable.prototype); action.hasObservers = function hasObservers() { // in next major version this should throw if already disposed // in order to better follow RxJS conventions // // checkDisposed(action); return !!(observers.length > 0 || actionStart.observers && actionStart.observers.length > 0); }; action.waitFor = function () { var _arguments = arguments; /* istanbul ignore else */ if (__DEV__) { (0, _warning2['default'])(false, 'action.waitFor is deprecated and will be removed in ' + 'the next version of thundercats'); } return actionStart.flatMap(function (payload) { return _waitFor2['default'].apply(undefined, _arguments).map(function () { return payload; }); }); }; // NOTE: not public API. May change or be removed at any time action.__duration = function __duration() { return actionStart.flatMap(actionEnd).first(); }; action._subscribe = function subscribeToAction(observer) { // in next major version this should check if action // has been stopped or disposed and act accordingly observers.push(observer); return new _rx.Disposable(function () { observers.splice(observers.indexOf(observer), 1); }); }; var subscription = new _rx.Disposable(function () { observers.length = 0; action.isDisposed = true; actionStart.dispose(); actionDisposable.dispose(); }); action.dispose = function () { return subscription.dispose(); }; _rx.Observable.call(action); debug('%s created', action.displayName); return { action: action, subscription: subscription }; } function createMany(shouldBind, instance, compositeDisposable) { return this.map(create.bind(instance, shouldBind)).reduce(function (ctx, _ref2) { var action = _ref2.action; var subscription = _ref2.subscription; compositeDisposable.add(subscription); ctx[action.displayName] = action; return ctx; }, {}); } function Actions() { var obj = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; var shouldBind = obj.shouldBindMethods; var _obj$init = obj.init; var init = _obj$init === undefined ? [] : _obj$init; var _obj$props = obj.props; var props = _obj$props === undefined ? {} : _obj$props; var _obj$refs = obj.refs; var refs = _obj$refs === undefined ? {} : _obj$refs; var _obj$statics = obj.statics; var statics = _obj$statics === undefined ? {} : _obj$statics; return (0, _stampit2['default'])().init(function (_ref3) { var _context; var instance = _ref3.instance; var actionsDisposable = new _rx.CompositeDisposable(); var actionMethods = (_context = getActionDef(obj), createMany).call(_context, shouldBind, instance, actionsDisposable); return assign(instance, actionMethods, { dispose: function dispose() { actionsDisposable.dispose(); } }); }).refs(refs).props(props)['static'](statics).init(init); }