UNPKG

fluorine-lib

Version:

Reactive state and side effect management for React using a single stream of actions

215 lines (139 loc) 5.53 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.Dispatcher = Dispatcher; exports.default = createDispatcher; var _Subject = require('rxjs/Subject'); var Subject = _Subject.Subject; var _Observable = require('rxjs/Observable'); var Observable = _Observable.Observable; var _BehaviorSubject = require('rxjs/BehaviorSubject'); var BehaviorSubject = _BehaviorSubject.BehaviorSubject; var _of = require('rxjs/observable/of'); var of = _of.of; var _concat = require('rxjs/operator/concat'); var concat = _concat.concat; var _map = require('rxjs/operator/map'); var map = _map.map; var _mergeMap = require('rxjs/operator/mergeMap'); var mergeMap = _mergeMap.mergeMap; var _distinctUntilChanged = require('rxjs/operator/distinctUntilChanged'); var distinctUntilChanged = _distinctUntilChanged.distinctUntilChanged; var _publishReplay = require('rxjs/operator/publishReplay'); var publishReplay = _publishReplay.publishReplay; var _subscribeOn = require('rxjs/operator/subscribeOn'); var subscribeOn = _subscribeOn.subscribeOn; var _share = require('rxjs/operator/share'); var share = _share.share; var _filter = require('rxjs/operator/filter'); var filter = _filter.filter; var _catch2 = require('rxjs/operator/catch'); var _catch = _catch2._catch; var _state = require('./util/state'); var createState = _state.createState; var filterActions = _state.filterActions; var _logger = require('./util/logger'); var parseOpts = _logger.parseOpts; var logAgendas = _logger.logAgendas; var logStore = _logger.logStore; var _assert = require('./util/assert'); var assert = _interopRequireDefault(_assert).default; var _wrapActions = require('./util/wrapActions'); var wrapActions = _interopRequireDefault(_wrapActions).default; var _toObservable = require('./util/toObservable'); var toObservable = _interopRequireDefault(_toObservable).default; var _isObservable = require('./util/isObservable'); var isObservable = _interopRequireDefault(_isObservable).default; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var KICKSTART_ACTION = { type: '_INIT_' }; function Dispatcher() { var _this = this; var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var middlewares = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; Subject.call(this); this.keyCache = []; this.valCache = []; this.middlewares = [].concat(middlewares).map(function (x) { return x(_this); }); // Options: Logging this.logging = parseOpts(opts.logging); if (this.logging.agendas) { logAgendas(this); } this.reduce = this.reduce.bind(this); this.rawNext = this.rawNext.bind(this); this.next = this.next.bind(this); } // Inherit from Rx.Subject Dispatcher.prototype = Object.create(Subject.prototype); Dispatcher.prototype.constructor = Dispatcher; Dispatcher.prototype.reduce = function reduce(fn, init) { var _context; var keyCache = this.keyCache, valCache = this.valCache, logging = this.logging; var index = keyCache.indexOf(fn); if (index > -1) { return valCache[index].store; } // Create cursor pointing to the state history var cursor = createState(fn, fn(init, KICKSTART_ACTION)); // Describe states using the series of agendas var store = (_context = (_context = (_context = of(cursor.state), concat).call(_context, mergeMap.call(this, function (agenda) { var _context2; // Reference agenda's root state var anchor = cursor; // Collect agenda's actions var actions = []; // Prepare agenda logger if necessary var logger = logging.stores ? logStore(fn.name || index, agenda) : null; // Map Agenda to consecutive states and catch errors return (_context2 = (_context2 = map.call(agenda, function (action) { cursor = cursor.doNext(action); actions.push(action); if (logger) { logger.change(action, cursor.state); // Logging new state by action } return cursor.state; }), _catch).call(_context2, function (err) { if (!logger) { console.error(err); } // Filter past actions by all of the failed agenda var previousState = cursor.state; filterActions(anchor, function (x) { return actions.indexOf(x) === -1; }); if (logger) { logger.revert([previousState, cursor.state], err, actions); // Logging reversion } return of(cursor.state); }), distinctUntilChanged).call(_context2); })), distinctUntilChanged).call(_context), publishReplay).call(_context, 1); var subscription = store.connect(); // Cache the store var key = keyCache.length; keyCache.push(fn); valCache[key] = { store: store, subscription: subscription }; return store; }; // Save subject's normal next method Dispatcher.prototype.rawNext = Dispatcher.prototype.next; Dispatcher.prototype.next = function next(arg) { var _context3; var middlewares = this.middlewares; var agenda = (_context3 = toObservable(arg), share).call(_context3); for (var i = 0; i < middlewares.length; i++) { var middleware = middlewares[i]; agenda = middleware(agenda); if (!isObservable(agenda)) { return undefined; } } return this.rawNext((_context3 = (_context3 = agenda, filter).call(_context3, Boolean), publishReplay).call(_context3).refCount()); }; function createDispatcher(opts, middlewares) { return new Dispatcher(opts, middlewares); }