Files
freeCodeCamp/common/app/utils/redux-epic.js
Berkeley Martinez d511be3332 Add new rx saga
2016-07-28 23:39:17 -07:00

58 lines
1.7 KiB
JavaScript

import { CompositeDisposable, Observable, Subject } from 'rx';
export default (dependencies, ...sagas) => {
if (typeof dependencies === 'function') {
sagas.push(dependencies);
dependencies = {};
}
let action$;
let lifecycle;
let compositeDisposable;
let start;
function sagaMiddleware({ dispatch, getState }) {
start = () => {
compositeDisposable = new CompositeDisposable();
action$ = new Subject();
lifecycle = new Subject();
const sagaSubscription = Observable
.from(sagas)
.map(saga => saga(action$, getState, dependencies))
.doOnNext(result$ => {
if (!Observable.isObservable(result$)) {
throw new Error('saga should returned an observable');
}
if (result$ === action$) {
throw new Error('Saga returned original action stream!');
}
})
.mergeAll()
.filter(action => action && typeof action.type === 'string')
.subscribe(
action => dispatch(action),
err => { throw err; },
() => lifecycle.onCompleted()
);
compositeDisposable.add(sagaSubscription);
};
start();
return next => action => {
const result = next(action);
action$.onNext(action);
return result;
};
}
sagaMiddleware.subscribe =
(...args) => lifecycle.subscribe.apply(lifecycle, args);
sagaMiddleware.subscribeOnCompleted =
(...args) => lifecycle.subscribeOnCompleted.apply(lifecycle, args);
sagaMiddleware.end = () => action$.onCompleted();
sagaMiddleware.dispose = () => compositeDisposable.dispose();
sagaMiddleware.restart = () => {
sagaMiddleware.dispose();
action$.dispose();
start();
};
return sagaMiddleware;
};