Socket
Socket
Sign inDemoInstall

redux-saga

Package Overview
Dependencies
Maintainers
1
Versions
74
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

redux-saga - npm Package Compare versions

Comparing version 0.6.1 to 0.7.0

157

dist/redux-saga.js

@@ -64,3 +64,3 @@ (function webpackUniversalModuleDefinition(root, factory) {

var _proc = __webpack_require__(3);
var _proc = __webpack_require__(4);

@@ -183,7 +183,7 @@ Object.defineProperty(exports, 'CANCEL', {

var _SagaCancellationException2 = __webpack_require__(4);
var _SagaCancellationException2 = __webpack_require__(2);
var _SagaCancellationException3 = _interopRequireDefault(_SagaCancellationException2);
var _monitorActions = __webpack_require__(2);
var _monitorActions = __webpack_require__(3);

@@ -304,2 +304,35 @@ var monitorActions = _interopRequireWildcard(_monitorActions);

});
exports.default = SagaCancellationException;
/**
* Creates an instance of a cancellation error
* used internally by the Library to handle Cancellations effects
* params:
* type: PARALLEL_AUTO_CANCEL | RACE_AUTO_CANCEL | MANUAL_CANCEL
* saga: current saga where the cancellation is to be thrown
* origin: Origin saga from which the cancellation originated
*/
function SagaCancellationException(type, saga, origin) {
var message = 'SagaCancellationException; type: ' + type + ', saga: ' + saga + ', origin: ' + origin;
this.name = 'SagaCancellationException';
this.message = message;
this.type = type;
this.saga = saga;
this.origin = origin;
this.stack = new Error().stack;
}
SagaCancellationException.prototype = Object.create(Error.prototype);
SagaCancellationException.prototype.constructor = SagaCancellationException;
/***/ },
/* 3 */
/***/ function(module, exports) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.effectTriggered = effectTriggered;

@@ -335,3 +368,3 @@ exports.effectResolved = effectResolved;

/***/ },
/* 3 */
/* 4 */
/***/ function(module, exports, __webpack_require__) {

@@ -344,3 +377,3 @@

});
exports.MANUAL_CANCEL = exports.RACE_AUTO_CANCEL = exports.PARALLEL_AUTO_CANCEL = exports.CANCEL = exports.NOT_ITERATOR_ERROR = undefined;
exports.MANUAL_CANCEL = exports.RACE_AUTO_CANCEL = exports.PARALLEL_AUTO_CANCEL = exports.CANCEL = exports.undefindInputError = exports.NOT_ITERATOR_ERROR = undefined;
exports.default = proc;

@@ -352,7 +385,7 @@

var _monitorActions = __webpack_require__(2);
var _monitorActions = __webpack_require__(3);
var monitorActions = _interopRequireWildcard(_monitorActions);
var _SagaCancellationException = __webpack_require__(4);
var _SagaCancellationException = __webpack_require__(2);

@@ -368,2 +401,6 @@ var _SagaCancellationException2 = _interopRequireDefault(_SagaCancellationException);

var NOT_ITERATOR_ERROR = exports.NOT_ITERATOR_ERROR = 'proc first argument (Saga function result) must be an iterator';
var undefindInputError = exports.undefindInputError = function undefindInputError(name) {
return '\n ' + name + ' saga was provided with an undefined input action\n Hints :\n - check that your Action Creator returns a non undefined value\n - if the Saga was started using runSaga, check that your subscribe source provides the action to its listeners\n';
};
var CANCEL = exports.CANCEL = Symbol('@@redux-saga/cancelPromise');

@@ -387,2 +424,4 @@ var PARALLEL_AUTO_CANCEL = exports.PARALLEL_AUTO_CANCEL = 'PARALLEL_AUTO_CANCEL';

var UNDEFINED_INPUT_ERROR = undefindInputError(name);
// tracks the current `take` effects

@@ -396,2 +435,4 @@ var deferredInputs = [];

var unsubscribe = subscribe(function (input) {
if (input === undefined) throw UNDEFINED_INPUT_ERROR;
for (var i = 0; i < deferredInputs.length; i++) {

@@ -787,3 +828,8 @@ var def = deferredInputs[i];

return _ref5 = {}, _defineProperty(_ref5, _utils.TASK, true), _defineProperty(_ref5, 'id', id), _defineProperty(_ref5, 'name', name), _defineProperty(_ref5, 'done', done), _defineProperty(_ref5, 'forked', forked), _defineProperty(_ref5, 'isRunning', function isRunning() {
return _ref5 = {}, _defineProperty(_ref5, _utils.TASK, true), _defineProperty(_ref5, 'id', id), _defineProperty(_ref5, 'name', name), _defineProperty(_ref5, 'done', done), _defineProperty(_ref5, 'forked', forked), _defineProperty(_ref5, 'cancel', function cancel(error) {
if (!(error instanceof _SagaCancellationException2.default)) {
error = new _SagaCancellationException2.default(MANUAL_CANCEL, name, error);
}
done[CANCEL](error);
}), _defineProperty(_ref5, 'isRunning', function isRunning() {
return iterator._isRunning;

@@ -799,35 +845,2 @@ }), _defineProperty(_ref5, 'getResult', function getResult() {

/***/ },
/* 4 */
/***/ function(module, exports) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = SagaCancellationException;
/**
* Creates an instance of a cancellation error
* used internally by the Library to handle Cancellations effects
* params:
* type: PARALLEL_AUTO_CANCEL | RACE_AUTO_CANCEL | MANUAL_CANCEL
* saga: current saga where the cancellation is to be thrown
* origin: Origin saga from which the cancellation originated
*/
function SagaCancellationException(type, saga, origin) {
var message = 'SagaCancellationException; type: ' + type + ', saga: ' + saga + ', origin: ' + origin;
this.name = 'SagaCancellationException';
this.message = message;
this.type = type;
this.saga = saga;
this.origin = origin;
this.stack = new Error().stack;
}
SagaCancellationException.prototype = Object.create(Error.prototype);
SagaCancellationException.prototype.constructor = SagaCancellationException;
/***/ },
/* 5 */

@@ -1063,6 +1076,8 @@ /***/ function(module, exports, __webpack_require__) {

});
exports.RUN_SAGA_DYNAMIC_ERROR = undefined;
exports.default = sagaMiddlewareFactory;
var _utils = __webpack_require__(1);
var _proc = __webpack_require__(3);
var _proc = __webpack_require__(4);

@@ -1075,7 +1090,13 @@ var _proc2 = _interopRequireDefault(_proc);

var _monitorActions = __webpack_require__(2);
var _monitorActions = __webpack_require__(3);
var _SagaCancellationException = __webpack_require__(2);
var _SagaCancellationException2 = _interopRequireDefault(_SagaCancellationException);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.default = function () {
var RUN_SAGA_DYNAMIC_ERROR = exports.RUN_SAGA_DYNAMIC_ERROR = 'Before running a Saga dynamically using middleware.run, you must mount the Saga middleware on the Store using applyMiddleware';
function sagaMiddlewareFactory() {
for (var _len = arguments.length, sagas = Array(_len), _key = 0; _key < _len; _key++) {

@@ -1085,3 +1106,5 @@ sagas[_key] = arguments[_key];

return function (_ref) {
var runSagaDynamically = undefined;
function sagaMiddleware(_ref) {
var getState = _ref.getState;

@@ -1097,6 +1120,14 @@ var dispatch = _ref.dispatch;

sagas.forEach(function (saga) {
(0, _proc2.default)(saga(getState), sagaEmitter.subscribe, dispatch, monitor, 0, saga.name);
});
function runSaga(saga) {
for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
args[_key2 - 1] = arguments[_key2];
}
return (0, _proc2.default)(saga.apply(undefined, [getState].concat(args)), sagaEmitter.subscribe, dispatch, monitor, 0, saga.name);
}
runSagaDynamically = runSaga;
sagas.forEach(runSaga);
return function (next) {

@@ -1111,5 +1142,22 @@ return function (action) {

};
}
sagaMiddleware.run = function (saga) {
for (var _len3 = arguments.length, args = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
args[_key3 - 1] = arguments[_key3];
}
if (!runSagaDynamically) {
throw new Error(RUN_SAGA_DYNAMIC_ERROR);
}
var task = runSagaDynamically.apply(undefined, [saga].concat(args));
task.done.catch(function (err) {
if (!(err instanceof _SagaCancellationException2.default)) throw err;
});
return task;
};
};
return sagaMiddleware;
}
/***/ },

@@ -1130,3 +1178,3 @@ /* 8 */

var _proc = __webpack_require__(3);
var _proc = __webpack_require__(4);

@@ -1144,2 +1192,6 @@ var _proc2 = _interopRequireDefault(_proc);

/**
@deprecated
ATTENTION! this method can have some potential issues
For more infos, see issue https://github.com/yelouafi/redux-saga/issues/48
memoize the result of storeChannel. It avoids monkey patching the same store

@@ -1151,2 +1203,7 @@ multiple times unnecessarly. We need only one channel per store

if (_utils.isDev) {
/* eslint-disable no-console */
console.warn('storeIO is deprecated, to run Saga dynamically, use \'run\' method of the middleware');
}
if (store[IO]) return store[IO];

@@ -1153,0 +1210,0 @@

@@ -1,1 +0,1 @@

!function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.ReduxSaga=n():e.ReduxSaga=n()}(this,function(){return function(e){function n(r){if(t[r])return t[r].exports;var u=t[r]={exports:{},id:r,loaded:!1};return e[r].call(u.exports,u,u.exports,n),u.loaded=!0,u.exports}var t={};return n.m=e,n.c=t,n.p="",n(0)}([function(e,n,t){"use strict";function r(e){if(e&&e.__esModule)return e;var n={};if(null!=e)for(var t in e)Object.prototype.hasOwnProperty.call(e,t)&&(n[t]=e[t]);return n.default=e,n}function u(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(n,"__esModule",{value:!0}),n.monitorActions=n.storeIO=n.runSaga=n.as=n.cancel=n.join=n.fork=n.cps=n.apply=n.call=n.race=n.put=n.take=n.is=n.SagaCancellationException=n.MANUAL_CANCEL=n.PARALLEL_AUTO_CANCEL=n.RACE_AUTO_CANCEL=n.CANCEL=void 0;var o=t(3);Object.defineProperty(n,"CANCEL",{enumerable:!0,get:function(){return o.CANCEL}}),Object.defineProperty(n,"RACE_AUTO_CANCEL",{enumerable:!0,get:function(){return o.RACE_AUTO_CANCEL}}),Object.defineProperty(n,"PARALLEL_AUTO_CANCEL",{enumerable:!0,get:function(){return o.PARALLEL_AUTO_CANCEL}}),Object.defineProperty(n,"MANUAL_CANCEL",{enumerable:!0,get:function(){return o.MANUAL_CANCEL}});var a=t(1);Object.defineProperty(n,"is",{enumerable:!0,get:function(){return a.is}});var i=t(6);Object.defineProperty(n,"take",{enumerable:!0,get:function(){return i.take}}),Object.defineProperty(n,"put",{enumerable:!0,get:function(){return i.put}}),Object.defineProperty(n,"race",{enumerable:!0,get:function(){return i.race}}),Object.defineProperty(n,"call",{enumerable:!0,get:function(){return i.call}}),Object.defineProperty(n,"apply",{enumerable:!0,get:function(){return i.apply}}),Object.defineProperty(n,"cps",{enumerable:!0,get:function(){return i.cps}}),Object.defineProperty(n,"fork",{enumerable:!0,get:function(){return i.fork}}),Object.defineProperty(n,"join",{enumerable:!0,get:function(){return i.join}}),Object.defineProperty(n,"cancel",{enumerable:!0,get:function(){return i.cancel}}),Object.defineProperty(n,"as",{enumerable:!0,get:function(){return i.as}});var c=t(8);Object.defineProperty(n,"runSaga",{enumerable:!0,get:function(){return c.runSaga}}),Object.defineProperty(n,"storeIO",{enumerable:!0,get:function(){return c.storeIO}});var f=t(7),s=u(f),l=t(4),d=u(l),p=t(2),g=r(p);n.default=s.default;n.SagaCancellationException=d.default;n.monitorActions=g},function(e,n,t){(function(e){"use strict";function t(e,n,t){if(!n(e))throw new Error(t)}function r(e,n){var t=e.indexOf(n);t>=0&&e.splice(t,1)}function u(){var e=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],n=c({},e),t=new Promise(function(e,t){n.resolve=e,n.reject=t});return n.promise=t,n}function o(e){for(var n=[],t=0;e>t;t++)n.push(u());return n}function a(){var e=arguments.length<=0||void 0===arguments[0]?0:arguments[0];return function(){return++e}}function i(e){return Promise.resolve(1).then(function(){return e()})}var c=Object.assign||function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e};Object.defineProperty(n,"__esModule",{value:!0}),n.check=t,n.remove=r,n.deferred=u,n.arrayOfDeffered=o,n.autoInc=a,n.asap=i;var f=n.TASK=Symbol("TASK"),s=(n.kTrue=function(){return!0},n.noop=function(){},n.isDev="undefined"!=typeof e&&e.env&&!1,n.is={undef:function(e){return null===e||void 0===e},notUndef:function(e){return null!==e&&void 0!==e},func:function(e){return"function"==typeof e},array:Array.isArray,promise:function(e){return e&&s.func(e.then)},iterator:function(e){return e&&s.func(e.next)&&s.func(e[Symbol.iterator])},"throw":function(e){return e&&s.func(e.throw)},task:function(e){return e&&e[f]}})}).call(n,t(9))},function(e,n){"use strict";function t(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n,r,u){var o;return o={},t(o,a,!0),t(o,"type",i),t(o,"effectId",e),t(o,"parentEffectId",n),t(o,"label",r),t(o,"effect",u),o}function u(e,n){var r;return r={},t(r,a,!0),t(r,"type",c),t(r,"effectId",e),t(r,"result",n),r}function o(e,n){var r;return r={},t(r,a,!0),t(r,"type",f),t(r,"effectId",e),t(r,"error",n),r}Object.defineProperty(n,"__esModule",{value:!0}),n.effectTriggered=r,n.effectResolved=u,n.effectRejected=o;var a=n.MONITOR_ACTION="MONITOR_ACTION",i=n.EFFECT_TRIGGERED="EFFECT_TRIGGERED",c=n.EFFECT_RESOLVED="EFFECT_RESOLVED",f=n.EFFECT_REJECTED="EFFECT_REJECTED"},function(e,n,t){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function u(e){if(e&&e.__esModule)return e;var n={};if(null!=e)for(var t in e)Object.prototype.hasOwnProperty.call(e,t)&&(n[t]=e[t]);return n.default=e,n}function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e){function n(u,o){if(!e._isRunning)throw new Error("Trying to resume an already finished generator");try{if(u&&!x)throw u;var a=u?e.throw(u):e.next(o);a.done?t(a.value):r(a.value,P,"",n)}catch(u){i.isDev&&console.warn(I+": uncaught",u),t(u,!0)}}function t(n,t){e._isRunning=!1,t?(e._error=n,U.reject(n)):(e._result=n,U.resolve(n)),S()}function r(e,n){function t(e,n){d||(d=!0,o.cancel=i.noop,w(e?s.effectRejected(a,e):s.effectResolved(a,n)),o(e,n))}var r=arguments.length<=2||void 0===arguments[2]?"":arguments[2],o=arguments[3],a=E();w(s.effectTriggered(a,n,r,e));var d=void 0;t.cancel=i.noop,o.cancel=function(e){if(!d){d=!0;try{t.cancel(e)}catch(n){}t.cancel=i.noop,o(e),w(s.effectRejected(a,e))}};var p=void 0;return i.is.promise(e)?u(e,t):i.is.iterator(e)?f(e,a,I,t):i.is.array(e)?C(e,a,t):i.is.notUndef(p=c.as.take(e))?l(p,t):i.is.notUndef(p=c.as.put(e))?_(p,t):i.is.notUndef(p=c.as.race(e))?L(p,a,t):i.is.notUndef(p=c.as.call(e))?y(p,a,t):i.is.notUndef(p=c.as.cps(e))?h(p,t):i.is.notUndef(p=c.as.fork(e))?O(p,a,t):i.is.notUndef(p=c.as.join(e))?b(p,t):i.is.notUndef(p=c.as.cancel(e))?R(p,t):t(null,e)}function u(e,n){var t=e[g];"function"==typeof t&&(n.cancel=t),e.then(function(e){return n(null,e)},function(e){return n(e)})}function f(e,n,t,r){u(a(e,N,j,w,n,t).done,r)}function l(e,n){var t={match:(0,c.matcher)(e),pattern:e,resolve:function(e){return n(null,e)}};k.push(t),n.cancel=function(){return(0,i.remove)(k,t)}}function _(e,n){(0,i.asap)(function(){return n(null,j(e))})}function y(e,n,t){var r=e.context,o=e.fn,a=e.args,c=o.apply(r,a);return i.is.promise(c)?u(c,t):i.is.iterator(c)?f(c,n,o.name,t):t(null,c)}function h(e,n){var t=e.context,r=e.fn,u=e.args;r.apply(t,u.concat(n))}function O(e,n,t){var r=e.context,u=e.fn,o=e.args,c=void 0,f=void 0;c=u.apply(r,o),f=i.is.iterator(c)?c:regeneratorRuntime.mark(function s(){return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,c;case 2:return e.abrupt("return",e.sent);case 3:case"end":return e.stop()}},s,this)})(),t(null,a(f,N,j,w,n,u.name,!0))}function b(e,n){u(e.done,n)}function R(e,n){e.done[g](new d.default(A,I,I)),n()}function C(e,n,t){function u(){o===c.length&&(a=!0,t(null,c))}if(!e.length)return void t(null,[]);var o=0,a=void 0,c=Array(e.length),f=e.map(function(e,n){var r=function(e,r){if(!a)if(e){try{t.cancel(new d.default(v,I,I))}catch(e){}t(e)}else c[n]=r,o++,u()};return r.cancel=i.noop,r});t.cancel=function(e){a||(a=!0,f.forEach(function(n){return n.cancel(e)}))},e.forEach(function(e,t){return r(e,n,t,f[t])})}function L(e,n,t){var u=void 0,a=Object.keys(e),c={};a.forEach(function(e){var n=function(n,r){if(!u)if(n){try{t.cancel(new d.default(m,I,I))}catch(n){}t(o({},e,n))}else{try{t.cancel(new d.default(m,I,I))}catch(n){}u=!0,t(null,o({},e,r))}};n.cancel=i.noop,c[e]=n}),t.cancel=function(e){u||(u=!0,a.forEach(function(n){return c[n].cancel(e)}))},a.forEach(function(t){return r(e[t],n,t,c[t])})}function T(e,n,t,r,u){var a;return a={},o(a,i.TASK,!0),o(a,"id",e),o(a,"name",n),o(a,"done",r),o(a,"forked",u),o(a,"isRunning",function(){return t._isRunning}),o(a,"getResult",function(){return t._result}),o(a,"getError",function(){return t._error}),a}var N=arguments.length<=1||void 0===arguments[1]?function(){return i.noop}:arguments[1],j=arguments.length<=2||void 0===arguments[2]?i.noop:arguments[2],w=arguments.length<=3||void 0===arguments[3]?i.noop:arguments[3],P=arguments.length<=4||void 0===arguments[4]?0:arguments[4],I=arguments.length<=5||void 0===arguments[5]?"anonymous":arguments[5];(0,i.check)(e,i.is.iterator,p);var k=[],x=i.is.throw(e),U=(0,i.deferred)(),S=N(function(e){for(var n=0;n<k.length;n++){var t=k[n];t.match(e)&&(k=[],t.resolve(e))}});n.cancel=i.noop;var M=T(P,I,e,U.promise);return M.done[g]=function(e){var t=e.type,r=e.origin;n.cancel(new d.default(t,I,r))},e._isRunning=!0,n(),M}Object.defineProperty(n,"__esModule",{value:!0}),n.MANUAL_CANCEL=n.RACE_AUTO_CANCEL=n.PARALLEL_AUTO_CANCEL=n.CANCEL=n.NOT_ITERATOR_ERROR=void 0,n.default=a;var i=t(1),c=t(6),f=t(2),s=u(f),l=t(4),d=r(l),p=n.NOT_ITERATOR_ERROR="proc first argument (Saga function result) must be an iterator",g=n.CANCEL=Symbol("@@redux-saga/cancelPromise"),v=n.PARALLEL_AUTO_CANCEL="PARALLEL_AUTO_CANCEL",m=n.RACE_AUTO_CANCEL="RACE_AUTO_CANCEL",A=n.MANUAL_CANCEL="MANUAL_CANCEL",E=(0,i.autoInc)()},function(e,n){"use strict";function t(e,n,t){var r="SagaCancellationException; type: "+e+", saga: "+n+", origin: "+t;this.name="SagaCancellationException",this.message=r,this.type=e,this.saga=n,this.origin=t,this.stack=(new Error).stack}Object.defineProperty(n,"__esModule",{value:!0}),n.default=t,t.prototype=Object.create(Error.prototype),t.prototype.constructor=t},function(e,n,t){"use strict";function r(){function e(e){return t.push(e),function(){return(0,u.remove)(t,e)}}function n(e){t.slice().forEach(function(n){return n(e)})}var t=[];return{subscribe:e,emit:n}}Object.defineProperty(n,"__esModule",{value:!0}),n.default=r;var u=t(1)},function(e,n,t){"use strict";function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function u(e){return("*"===e?P.wildcard:m.is.array(e)?P.array:m.is.func(e)?P.predicate:P.default)(e)}function o(e){if(arguments.length>0&&m.is.undef(e))throw new Error(y);return w(O,m.is.undef(e)?"*":e)}function a(e){return w(b,e)}function i(e){return w(R,e)}function c(e,n){(0,m.check)(e,m.is.notUndef,A);var t=null;if(m.is.array(e)){var r=e,u=v(r,2);t=u[0],e=u[1]}else if(e.fn){var o=e;t=o.context,e=o.fn}return(0,m.check)(e,m.is.func,A),{context:t,fn:e,args:n}}function f(e){for(var n=arguments.length,t=Array(n>1?n-1:0),r=1;n>r;r++)t[r-1]=arguments[r];return w(C,c(e,t))}function s(e,n){var t=arguments.length<=2||void 0===arguments[2]?[]:arguments[2];return w(C,c({context:e,fn:n},t))}function l(e){for(var n=arguments.length,t=Array(n>1?n-1:0),r=1;n>r;r++)t[r-1]=arguments[r];return w(L,c(e,t))}function d(e){for(var n=arguments.length,t=Array(n>1?n-1:0),r=1;n>r;r++)t[r-1]=arguments[r];return w(T,c(e,t))}function p(e){if(!I(e))throw new Error(E);return w(N,e)}function g(e){if(!I(e))throw new Error(_);return w(j,e)}var v=function(){function e(e,n){var t=[],r=!0,u=!1,o=void 0;try{for(var a,i=e[Symbol.iterator]();!(r=(a=i.next()).done)&&(t.push(a.value),!n||t.length!==n);r=!0);}catch(c){u=!0,o=c}finally{try{!r&&i.return&&i.return()}finally{if(u)throw o}}return t}return function(n,t){if(Array.isArray(n))return n;if(Symbol.iterator in Object(n))return e(n,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}();Object.defineProperty(n,"__esModule",{value:!0}),n.as=n.INVALID_PATTERN=n.CANCEL_ARG_ERROR=n.JOIN_ARG_ERROR=n.FORK_ARG_ERROR=n.CALL_FUNCTION_ARG_ERROR=void 0,n.matcher=u,n.take=o,n.put=a,n.race=i,n.call=f,n.apply=s,n.cps=l,n.fork=d,n.join=p,n.cancel=g;var m=t(1),A=n.CALL_FUNCTION_ARG_ERROR="call/cps/fork first argument must be a function, an array [context, function] or an object {context, fn}",E=(n.FORK_ARG_ERROR="fork first argument must be a generator function or an iterator",n.JOIN_ARG_ERROR="join argument must be a valid task (a result of a fork)"),_=n.CANCEL_ARG_ERROR="cancel argument must be a valid task (a result of a fork)",y=n.INVALID_PATTERN="Invalid pattern passed to `take` (HINT: check if you didn't mispell a constant)",h=Symbol("IO"),O="TAKE",b="PUT",R="RACE",C="CALL",L="CPS",T="FORK",N="JOIN",j="CANCEL",w=function(e,n){var t;return t={},r(t,h,!0),r(t,e,n),t},P={wildcard:function(){return m.kTrue},"default":function(e){return function(n){return n.type===e}},array:function(e){return function(n){return e.some(function(e){return e===n.type})}},predicate:function(e){return function(n){return e(n)}}},I=function(e){return e[m.TASK]};n.as={take:function(e){return e&&e[h]&&e[O]},put:function(e){return e&&e[h]&&e[b]},race:function(e){return e&&e[h]&&e[R]},call:function(e){return e&&e[h]&&e[C]},cps:function(e){return e&&e[h]&&e[L]},fork:function(e){return e&&e[h]&&e[T]},join:function(e){return e&&e[h]&&e[N]},cancel:function(e){return e&&e[h]&&e[j]}}},function(e,n,t){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(n,"__esModule",{value:!0});var u=t(1),o=t(3),a=r(o),i=t(5),c=r(i),f=t(2);n.default=function(){for(var e=arguments.length,n=Array(e),t=0;e>t;t++)n[t]=arguments[t];return function(e){var t=e.getState,r=e.dispatch,o=(0,c.default)(),i=u.isDev?function(e){return(0,u.asap)(function(){return r(e)})}:void 0;return n.forEach(function(e){(0,a.default)(e(t),o.subscribe,r,i,0,e.name)}),function(e){return function(n){var t=e(n);return n[f.MONITOR_ACTION]||o.emit(n),t}}}}},function(e,n,t){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function u(e){if(e[d])return e[d];var n=(0,s.default)(),t=e.dispatch;return e.dispatch=function(e){var r=t(e);return n.emit(e),r},e[d]={subscribe:n.subscribe,dispatch:e.dispatch},e[d]}function o(e,n){var t=n.subscribe,r=n.dispatch,u=arguments.length<=2||void 0===arguments[2]?a.noop:arguments[2];return(0,a.check)(e,a.is.iterator,l),(0,c.default)(e,t,r,u)}Object.defineProperty(n,"__esModule",{value:!0}),n.NOT_ITERATOR_ERROR=void 0,n.storeIO=u,n.runSaga=o;var a=t(1),i=t(3),c=r(i),f=t(5),s=r(f),l=n.NOT_ITERATOR_ERROR="runSaga must be called on an iterator",d=Symbol("IO")},function(e,n){function t(){f=!1,a.length?c=a.concat(c):s=-1,c.length&&r()}function r(){if(!f){var e=setTimeout(t);f=!0;for(var n=c.length;n;){for(a=c,c=[];++s<n;)a&&a[s].run();s=-1,n=c.length}a=null,f=!1,clearTimeout(e)}}function u(e,n){this.fun=e,this.array=n}function o(){}var a,i=e.exports={},c=[],f=!1,s=-1;i.nextTick=function(e){var n=new Array(arguments.length-1);if(arguments.length>1)for(var t=1;t<arguments.length;t++)n[t-1]=arguments[t];c.push(new u(e,n)),1!==c.length||f||setTimeout(r,0)},u.prototype.run=function(){this.fun.apply(null,this.array)},i.title="browser",i.browser=!0,i.env={},i.argv=[],i.version="",i.versions={},i.on=o,i.addListener=o,i.once=o,i.off=o,i.removeListener=o,i.removeAllListeners=o,i.emit=o,i.binding=function(e){throw new Error("process.binding is not supported")},i.cwd=function(){return"/"},i.chdir=function(e){throw new Error("process.chdir is not supported")},i.umask=function(){return 0}}])});
!function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.ReduxSaga=n():e.ReduxSaga=n()}(this,function(){return function(e){function n(r){if(t[r])return t[r].exports;var u=t[r]={exports:{},id:r,loaded:!1};return e[r].call(u.exports,u,u.exports,n),u.loaded=!0,u.exports}var t={};return n.m=e,n.c=t,n.p="",n(0)}([function(e,n,t){"use strict";function r(e){if(e&&e.__esModule)return e;var n={};if(null!=e)for(var t in e)Object.prototype.hasOwnProperty.call(e,t)&&(n[t]=e[t]);return n.default=e,n}function u(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(n,"__esModule",{value:!0}),n.monitorActions=n.storeIO=n.runSaga=n.as=n.cancel=n.join=n.fork=n.cps=n.apply=n.call=n.race=n.put=n.take=n.is=n.SagaCancellationException=n.MANUAL_CANCEL=n.PARALLEL_AUTO_CANCEL=n.RACE_AUTO_CANCEL=n.CANCEL=void 0;var o=t(4);Object.defineProperty(n,"CANCEL",{enumerable:!0,get:function(){return o.CANCEL}}),Object.defineProperty(n,"RACE_AUTO_CANCEL",{enumerable:!0,get:function(){return o.RACE_AUTO_CANCEL}}),Object.defineProperty(n,"PARALLEL_AUTO_CANCEL",{enumerable:!0,get:function(){return o.PARALLEL_AUTO_CANCEL}}),Object.defineProperty(n,"MANUAL_CANCEL",{enumerable:!0,get:function(){return o.MANUAL_CANCEL}});var a=t(1);Object.defineProperty(n,"is",{enumerable:!0,get:function(){return a.is}});var i=t(6);Object.defineProperty(n,"take",{enumerable:!0,get:function(){return i.take}}),Object.defineProperty(n,"put",{enumerable:!0,get:function(){return i.put}}),Object.defineProperty(n,"race",{enumerable:!0,get:function(){return i.race}}),Object.defineProperty(n,"call",{enumerable:!0,get:function(){return i.call}}),Object.defineProperty(n,"apply",{enumerable:!0,get:function(){return i.apply}}),Object.defineProperty(n,"cps",{enumerable:!0,get:function(){return i.cps}}),Object.defineProperty(n,"fork",{enumerable:!0,get:function(){return i.fork}}),Object.defineProperty(n,"join",{enumerable:!0,get:function(){return i.join}}),Object.defineProperty(n,"cancel",{enumerable:!0,get:function(){return i.cancel}}),Object.defineProperty(n,"as",{enumerable:!0,get:function(){return i.as}});var c=t(8);Object.defineProperty(n,"runSaga",{enumerable:!0,get:function(){return c.runSaga}}),Object.defineProperty(n,"storeIO",{enumerable:!0,get:function(){return c.storeIO}});var f=t(7),s=u(f),l=t(2),d=u(l),p=t(3),g=r(p);n.default=s.default;n.SagaCancellationException=d.default;n.monitorActions=g},function(e,n,t){(function(e){"use strict";function t(e,n,t){if(!n(e))throw new Error(t)}function r(e,n){var t=e.indexOf(n);t>=0&&e.splice(t,1)}function u(){var e=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],n=c({},e),t=new Promise(function(e,t){n.resolve=e,n.reject=t});return n.promise=t,n}function o(e){for(var n=[],t=0;e>t;t++)n.push(u());return n}function a(){var e=arguments.length<=0||void 0===arguments[0]?0:arguments[0];return function(){return++e}}function i(e){return Promise.resolve(1).then(function(){return e()})}var c=Object.assign||function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e};Object.defineProperty(n,"__esModule",{value:!0}),n.check=t,n.remove=r,n.deferred=u,n.arrayOfDeffered=o,n.autoInc=a,n.asap=i;var f=n.TASK=Symbol("TASK"),s=(n.kTrue=function(){return!0},n.noop=function(){},n.isDev="undefined"!=typeof e&&e.env&&!1,n.is={undef:function(e){return null===e||void 0===e},notUndef:function(e){return null!==e&&void 0!==e},func:function(e){return"function"==typeof e},array:Array.isArray,promise:function(e){return e&&s.func(e.then)},iterator:function(e){return e&&s.func(e.next)&&s.func(e[Symbol.iterator])},"throw":function(e){return e&&s.func(e.throw)},task:function(e){return e&&e[f]}})}).call(n,t(9))},function(e,n){"use strict";function t(e,n,t){var r="SagaCancellationException; type: "+e+", saga: "+n+", origin: "+t;this.name="SagaCancellationException",this.message=r,this.type=e,this.saga=n,this.origin=t,this.stack=(new Error).stack}Object.defineProperty(n,"__esModule",{value:!0}),n.default=t,t.prototype=Object.create(Error.prototype),t.prototype.constructor=t},function(e,n){"use strict";function t(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function r(e,n,r,u){var o;return o={},t(o,a,!0),t(o,"type",i),t(o,"effectId",e),t(o,"parentEffectId",n),t(o,"label",r),t(o,"effect",u),o}function u(e,n){var r;return r={},t(r,a,!0),t(r,"type",c),t(r,"effectId",e),t(r,"result",n),r}function o(e,n){var r;return r={},t(r,a,!0),t(r,"type",f),t(r,"effectId",e),t(r,"error",n),r}Object.defineProperty(n,"__esModule",{value:!0}),n.effectTriggered=r,n.effectResolved=u,n.effectRejected=o;var a=n.MONITOR_ACTION="MONITOR_ACTION",i=n.EFFECT_TRIGGERED="EFFECT_TRIGGERED",c=n.EFFECT_RESOLVED="EFFECT_RESOLVED",f=n.EFFECT_REJECTED="EFFECT_REJECTED"},function(e,n,t){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function u(e){if(e&&e.__esModule)return e;var n={};if(null!=e)for(var t in e)Object.prototype.hasOwnProperty.call(e,t)&&(n[t]=e[t]);return n.default=e,n}function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e){function n(u,o){if(!e._isRunning)throw new Error("Trying to resume an already finished generator");try{if(u&&!x)throw u;var a=u?e.throw(u):e.next(o);a.done?t(a.value):r(a.value,I,"",n)}catch(u){i.isDev&&console.warn(k+": uncaught",u),t(u,!0)}}function t(n,t){e._isRunning=!1,t?(e._error=n,M.reject(n)):(e._result=n,M.resolve(n)),F()}function r(e,n){function t(e,n){d||(d=!0,o.cancel=i.noop,P(e?s.effectRejected(a,e):s.effectResolved(a,n)),o(e,n))}var r=arguments.length<=2||void 0===arguments[2]?"":arguments[2],o=arguments[3],a=y();P(s.effectTriggered(a,n,r,e));var d=void 0;t.cancel=i.noop,o.cancel=function(e){if(!d){d=!0;try{t.cancel(e)}catch(n){}t.cancel=i.noop,o(e),P(s.effectRejected(a,e))}};var p=void 0;return i.is.promise(e)?u(e,t):i.is.iterator(e)?f(e,a,k,t):i.is.array(e)?L(e,a,t):i.is.notUndef(p=c.as.take(e))?l(p,t):i.is.notUndef(p=c.as.put(e))?E(p,t):i.is.notUndef(p=c.as.race(e))?T(p,a,t):i.is.notUndef(p=c.as.call(e))?_(p,a,t):i.is.notUndef(p=c.as.cps(e))?R(p,t):i.is.notUndef(p=c.as.fork(e))?O(p,a,t):i.is.notUndef(p=c.as.join(e))?b(p,t):i.is.notUndef(p=c.as.cancel(e))?C(p,t):t(null,e)}function u(e,n){var t=e[v];"function"==typeof t&&(n.cancel=t),e.then(function(e){return n(null,e)},function(e){return n(e)})}function f(e,n,t,r){u(a(e,N,j,P,n,t).done,r)}function l(e,n){var t={match:(0,c.matcher)(e),pattern:e,resolve:function(e){return n(null,e)}};U.push(t),n.cancel=function(){return(0,i.remove)(U,t)}}function E(e,n){(0,i.asap)(function(){return n(null,j(e))})}function _(e,n,t){var r=e.context,o=e.fn,a=e.args,c=o.apply(r,a);return i.is.promise(c)?u(c,t):i.is.iterator(c)?f(c,n,o.name,t):t(null,c)}function R(e,n){var t=e.context,r=e.fn,u=e.args;r.apply(t,u.concat(n))}function O(e,n,t){var r=e.context,u=e.fn,o=e.args,c=void 0,f=void 0;c=u.apply(r,o),f=i.is.iterator(c)?c:regeneratorRuntime.mark(function s(){return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,c;case 2:return e.abrupt("return",e.sent);case 3:case"end":return e.stop()}},s,this)})(),t(null,a(f,N,j,P,n,u.name,!0))}function b(e,n){u(e.done,n)}function C(e,n){e.done[v](new d.default(h,k,k)),n()}function L(e,n,t){function u(){o===c.length&&(a=!0,t(null,c))}if(!e.length)return void t(null,[]);var o=0,a=void 0,c=Array(e.length),f=e.map(function(e,n){var r=function(e,r){if(!a)if(e){try{t.cancel(new d.default(m,k,k))}catch(e){}t(e)}else c[n]=r,o++,u()};return r.cancel=i.noop,r});t.cancel=function(e){a||(a=!0,f.forEach(function(n){return n.cancel(e)}))},e.forEach(function(e,t){return r(e,n,t,f[t])})}function T(e,n,t){var u=void 0,a=Object.keys(e),c={};a.forEach(function(e){var n=function(n,r){if(!u)if(n){try{t.cancel(new d.default(A,k,k))}catch(n){}t(o({},e,n))}else{try{t.cancel(new d.default(A,k,k))}catch(n){}u=!0,t(null,o({},e,r))}};n.cancel=i.noop,c[e]=n}),t.cancel=function(e){u||(u=!0,a.forEach(function(n){return c[n].cancel(e)}))},a.forEach(function(t){return r(e[t],n,t,c[t])})}function w(e,n,t,r,u){var a;return a={},o(a,i.TASK,!0),o(a,"id",e),o(a,"name",n),o(a,"done",r),o(a,"forked",u),o(a,"cancel",function(e){e instanceof d.default||(e=new d.default(h,n,e)),r[v](e)}),o(a,"isRunning",function(){return t._isRunning}),o(a,"getResult",function(){return t._result}),o(a,"getError",function(){return t._error}),a}var N=arguments.length<=1||void 0===arguments[1]?function(){return i.noop}:arguments[1],j=arguments.length<=2||void 0===arguments[2]?i.noop:arguments[2],P=arguments.length<=3||void 0===arguments[3]?i.noop:arguments[3],I=arguments.length<=4||void 0===arguments[4]?0:arguments[4],k=arguments.length<=5||void 0===arguments[5]?"anonymous":arguments[5];(0,i.check)(e,i.is.iterator,p);var S=g(k),U=[],x=i.is.throw(e),M=(0,i.deferred)(),F=N(function(e){if(void 0===e)throw S;for(var n=0;n<U.length;n++){var t=U[n];t.match(e)&&(U=[],t.resolve(e))}});n.cancel=i.noop;var D=w(I,k,e,M.promise);return D.done[v]=function(e){var t=e.type,r=e.origin;n.cancel(new d.default(t,k,r))},e._isRunning=!0,n(),D}Object.defineProperty(n,"__esModule",{value:!0}),n.MANUAL_CANCEL=n.RACE_AUTO_CANCEL=n.PARALLEL_AUTO_CANCEL=n.CANCEL=n.undefindInputError=n.NOT_ITERATOR_ERROR=void 0,n.default=a;var i=t(1),c=t(6),f=t(3),s=u(f),l=t(2),d=r(l),p=n.NOT_ITERATOR_ERROR="proc first argument (Saga function result) must be an iterator",g=n.undefindInputError=function(e){return"\n "+e+" saga was provided with an undefined input action\n Hints :\n - check that your Action Creator returns a non undefined value\n - if the Saga was started using runSaga, check that your subscribe source provides the action to its listeners\n"},v=n.CANCEL=Symbol("@@redux-saga/cancelPromise"),m=n.PARALLEL_AUTO_CANCEL="PARALLEL_AUTO_CANCEL",A=n.RACE_AUTO_CANCEL="RACE_AUTO_CANCEL",h=n.MANUAL_CANCEL="MANUAL_CANCEL",y=(0,i.autoInc)()},function(e,n,t){"use strict";function r(){function e(e){return t.push(e),function(){return(0,u.remove)(t,e)}}function n(e){t.slice().forEach(function(n){return n(e)})}var t=[];return{subscribe:e,emit:n}}Object.defineProperty(n,"__esModule",{value:!0}),n.default=r;var u=t(1)},function(e,n,t){"use strict";function r(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function u(e){return("*"===e?P.wildcard:m.is.array(e)?P.array:m.is.func(e)?P.predicate:P.default)(e)}function o(e){if(arguments.length>0&&m.is.undef(e))throw new Error(E);return j(R,m.is.undef(e)?"*":e)}function a(e){return j(O,e)}function i(e){return j(b,e)}function c(e,n){(0,m.check)(e,m.is.notUndef,A);var t=null;if(m.is.array(e)){var r=e,u=v(r,2);t=u[0],e=u[1]}else if(e.fn){var o=e;t=o.context,e=o.fn}return(0,m.check)(e,m.is.func,A),{context:t,fn:e,args:n}}function f(e){for(var n=arguments.length,t=Array(n>1?n-1:0),r=1;n>r;r++)t[r-1]=arguments[r];return j(C,c(e,t))}function s(e,n){var t=arguments.length<=2||void 0===arguments[2]?[]:arguments[2];return j(C,c({context:e,fn:n},t))}function l(e){for(var n=arguments.length,t=Array(n>1?n-1:0),r=1;n>r;r++)t[r-1]=arguments[r];return j(L,c(e,t))}function d(e){for(var n=arguments.length,t=Array(n>1?n-1:0),r=1;n>r;r++)t[r-1]=arguments[r];return j(T,c(e,t))}function p(e){if(!I(e))throw new Error(h);return j(w,e)}function g(e){if(!I(e))throw new Error(y);return j(N,e)}var v=function(){function e(e,n){var t=[],r=!0,u=!1,o=void 0;try{for(var a,i=e[Symbol.iterator]();!(r=(a=i.next()).done)&&(t.push(a.value),!n||t.length!==n);r=!0);}catch(c){u=!0,o=c}finally{try{!r&&i.return&&i.return()}finally{if(u)throw o}}return t}return function(n,t){if(Array.isArray(n))return n;if(Symbol.iterator in Object(n))return e(n,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}();Object.defineProperty(n,"__esModule",{value:!0}),n.as=n.INVALID_PATTERN=n.CANCEL_ARG_ERROR=n.JOIN_ARG_ERROR=n.FORK_ARG_ERROR=n.CALL_FUNCTION_ARG_ERROR=void 0,n.matcher=u,n.take=o,n.put=a,n.race=i,n.call=f,n.apply=s,n.cps=l,n.fork=d,n.join=p,n.cancel=g;var m=t(1),A=n.CALL_FUNCTION_ARG_ERROR="call/cps/fork first argument must be a function, an array [context, function] or an object {context, fn}",h=(n.FORK_ARG_ERROR="fork first argument must be a generator function or an iterator",n.JOIN_ARG_ERROR="join argument must be a valid task (a result of a fork)"),y=n.CANCEL_ARG_ERROR="cancel argument must be a valid task (a result of a fork)",E=n.INVALID_PATTERN="Invalid pattern passed to `take` (HINT: check if you didn't mispell a constant)",_=Symbol("IO"),R="TAKE",O="PUT",b="RACE",C="CALL",L="CPS",T="FORK",w="JOIN",N="CANCEL",j=function(e,n){var t;return t={},r(t,_,!0),r(t,e,n),t},P={wildcard:function(){return m.kTrue},"default":function(e){return function(n){return n.type===e}},array:function(e){return function(n){return e.some(function(e){return e===n.type})}},predicate:function(e){return function(n){return e(n)}}},I=function(e){return e[m.TASK]};n.as={take:function(e){return e&&e[_]&&e[R]},put:function(e){return e&&e[_]&&e[O]},race:function(e){return e&&e[_]&&e[b]},call:function(e){return e&&e[_]&&e[C]},cps:function(e){return e&&e[_]&&e[L]},fork:function(e){return e&&e[_]&&e[T]},join:function(e){return e&&e[_]&&e[w]},cancel:function(e){return e&&e[_]&&e[N]}}},function(e,n,t){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function u(){function e(e){function n(e){for(var n=arguments.length,t=Array(n>1?n-1:0),u=1;n>u;u++)t[u-1]=arguments[u];return(0,i.default)(e.apply(void 0,[r].concat(t)),c.subscribe,a,l,0,e.name)}var r=e.getState,a=e.dispatch,c=(0,f.default)(),l=o.isDev?function(e){return(0,o.asap)(function(){return a(e)})}:void 0;return u=n,t.forEach(n),function(e){return function(n){var t=e(n);return n[s.MONITOR_ACTION]||c.emit(n),t}}}for(var n=arguments.length,t=Array(n),r=0;n>r;r++)t[r]=arguments[r];var u=void 0;return e.run=function(e){for(var n=arguments.length,t=Array(n>1?n-1:0),r=1;n>r;r++)t[r-1]=arguments[r];if(!u)throw new Error(p);var o=u.apply(void 0,[e].concat(t));return o.done.catch(function(e){if(!(e instanceof d.default))throw e}),o},e}Object.defineProperty(n,"__esModule",{value:!0}),n.RUN_SAGA_DYNAMIC_ERROR=void 0,n.default=u;var o=t(1),a=t(4),i=r(a),c=t(5),f=r(c),s=t(3),l=t(2),d=r(l),p=n.RUN_SAGA_DYNAMIC_ERROR="Before running a Saga dynamically using middleware.run, you must mount the Saga middleware on the Store using applyMiddleware"},function(e,n,t){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function u(e){if(a.isDev&&console.warn("storeIO is deprecated, to run Saga dynamically, use 'run' method of the middleware"),e[d])return e[d];var n=(0,s.default)(),t=e.dispatch;return e.dispatch=function(e){var r=t(e);return n.emit(e),r},e[d]={subscribe:n.subscribe,dispatch:e.dispatch},e[d]}function o(e,n){var t=n.subscribe,r=n.dispatch,u=arguments.length<=2||void 0===arguments[2]?a.noop:arguments[2];return(0,a.check)(e,a.is.iterator,l),(0,c.default)(e,t,r,u)}Object.defineProperty(n,"__esModule",{value:!0}),n.NOT_ITERATOR_ERROR=void 0,n.storeIO=u,n.runSaga=o;var a=t(1),i=t(4),c=r(i),f=t(5),s=r(f),l=n.NOT_ITERATOR_ERROR="runSaga must be called on an iterator",d=Symbol("IO")},function(e,n){function t(){f=!1,a.length?c=a.concat(c):s=-1,c.length&&r()}function r(){if(!f){var e=setTimeout(t);f=!0;for(var n=c.length;n;){for(a=c,c=[];++s<n;)a&&a[s].run();s=-1,n=c.length}a=null,f=!1,clearTimeout(e)}}function u(e,n){this.fun=e,this.array=n}function o(){}var a,i=e.exports={},c=[],f=!1,s=-1;i.nextTick=function(e){var n=new Array(arguments.length-1);if(arguments.length>1)for(var t=1;t<arguments.length;t++)n[t-1]=arguments[t];c.push(new u(e,n)),1!==c.length||f||setTimeout(r,0)},u.prototype.run=function(){this.fun.apply(null,this.array)},i.title="browser",i.browser=!0,i.env={},i.argv=[],i.version="",i.versions={},i.on=o,i.addListener=o,i.once=o,i.off=o,i.removeListener=o,i.removeAllListeners=o,i.emit=o,i.binding=function(e){throw new Error("process.binding is not supported")},i.cwd=function(){return"/"},i.chdir=function(e){throw new Error("process.chdir is not supported")},i.umask=function(){return 0}}])});

@@ -6,2 +6,4 @@ 'use strict';

});
exports.RUN_SAGA_DYNAMIC_ERROR = undefined;
exports.default = sagaMiddlewareFactory;

@@ -20,5 +22,11 @@ var _utils = require('./utils');

var _SagaCancellationException = require('./SagaCancellationException');
var _SagaCancellationException2 = _interopRequireDefault(_SagaCancellationException);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.default = function () {
var RUN_SAGA_DYNAMIC_ERROR = exports.RUN_SAGA_DYNAMIC_ERROR = 'Before running a Saga dynamically using middleware.run, you must mount the Saga middleware on the Store using applyMiddleware';
function sagaMiddlewareFactory() {
for (var _len = arguments.length, sagas = Array(_len), _key = 0; _key < _len; _key++) {

@@ -28,3 +36,5 @@ sagas[_key] = arguments[_key];

return function (_ref) {
var runSagaDynamically = undefined;
function sagaMiddleware(_ref) {
var getState = _ref.getState;

@@ -40,6 +50,14 @@ var dispatch = _ref.dispatch;

sagas.forEach(function (saga) {
(0, _proc2.default)(saga(getState), sagaEmitter.subscribe, dispatch, monitor, 0, saga.name);
});
function runSaga(saga) {
for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
args[_key2 - 1] = arguments[_key2];
}
return (0, _proc2.default)(saga.apply(undefined, [getState].concat(args)), sagaEmitter.subscribe, dispatch, monitor, 0, saga.name);
}
runSagaDynamically = runSaga;
sagas.forEach(runSaga);
return function (next) {

@@ -54,3 +72,20 @@ return function (action) {

};
}
sagaMiddleware.run = function (saga) {
for (var _len3 = arguments.length, args = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
args[_key3 - 1] = arguments[_key3];
}
if (!runSagaDynamically) {
throw new Error(RUN_SAGA_DYNAMIC_ERROR);
}
var task = runSagaDynamically.apply(undefined, [saga].concat(args));
task.done.catch(function (err) {
if (!(err instanceof _SagaCancellationException2.default)) throw err;
});
return task;
};
};
return sagaMiddleware;
}

@@ -6,3 +6,3 @@ 'use strict';

});
exports.MANUAL_CANCEL = exports.RACE_AUTO_CANCEL = exports.PARALLEL_AUTO_CANCEL = exports.CANCEL = exports.NOT_ITERATOR_ERROR = undefined;
exports.MANUAL_CANCEL = exports.RACE_AUTO_CANCEL = exports.PARALLEL_AUTO_CANCEL = exports.CANCEL = exports.undefindInputError = exports.NOT_ITERATOR_ERROR = undefined;
exports.default = proc;

@@ -29,2 +29,6 @@

var NOT_ITERATOR_ERROR = exports.NOT_ITERATOR_ERROR = 'proc first argument (Saga function result) must be an iterator';
var undefindInputError = exports.undefindInputError = function undefindInputError(name) {
return '\n ' + name + ' saga was provided with an undefined input action\n Hints :\n - check that your Action Creator returns a non undefined value\n - if the Saga was started using runSaga, check that your subscribe source provides the action to its listeners\n';
};
var CANCEL = exports.CANCEL = Symbol('@@redux-saga/cancelPromise');

@@ -48,2 +52,4 @@ var PARALLEL_AUTO_CANCEL = exports.PARALLEL_AUTO_CANCEL = 'PARALLEL_AUTO_CANCEL';

var UNDEFINED_INPUT_ERROR = undefindInputError(name);
// tracks the current `take` effects

@@ -57,2 +63,4 @@ var deferredInputs = [];

var unsubscribe = subscribe(function (input) {
if (input === undefined) throw UNDEFINED_INPUT_ERROR;
for (var i = 0; i < deferredInputs.length; i++) {

@@ -448,3 +456,8 @@ var def = deferredInputs[i];

return _ref5 = {}, _defineProperty(_ref5, _utils.TASK, true), _defineProperty(_ref5, 'id', id), _defineProperty(_ref5, 'name', name), _defineProperty(_ref5, 'done', done), _defineProperty(_ref5, 'forked', forked), _defineProperty(_ref5, 'isRunning', function isRunning() {
return _ref5 = {}, _defineProperty(_ref5, _utils.TASK, true), _defineProperty(_ref5, 'id', id), _defineProperty(_ref5, 'name', name), _defineProperty(_ref5, 'done', done), _defineProperty(_ref5, 'forked', forked), _defineProperty(_ref5, 'cancel', function cancel(error) {
if (!(error instanceof _SagaCancellationException2.default)) {
error = new _SagaCancellationException2.default(MANUAL_CANCEL, name, error);
}
done[CANCEL](error);
}), _defineProperty(_ref5, 'isRunning', function isRunning() {
return iterator._isRunning;

@@ -451,0 +464,0 @@ }), _defineProperty(_ref5, 'getResult', function getResult() {

@@ -25,2 +25,6 @@ 'use strict';

/**
@deprecated
ATTENTION! this method can have some potential issues
For more infos, see issue https://github.com/yelouafi/redux-saga/issues/48
memoize the result of storeChannel. It avoids monkey patching the same store

@@ -32,2 +36,7 @@ multiple times unnecessarly. We need only one channel per store

if (_utils.isDev) {
/* eslint-disable no-console */
console.warn('storeIO is deprecated, to run Saga dynamically, use \'run\' method of the middleware');
}
if (store[IO]) return store[IO];

@@ -34,0 +43,0 @@

{
"name": "redux-saga",
"version": "0.6.1",
"version": "0.7.0",
"description": "Saga middleware for Redux to handle Side Effects",

@@ -20,3 +20,8 @@ "main": "lib/index.js",

"async": "node examples/async/server.js",
"real-world": "node examples/real-world/server.js"
"real-world": "node examples/real-world/server.js",
"docs:clean": "rimraf _book",
"docs:prepare": "gitbook install",
"docs:build": "npm run docs:prepare && gitbook build -g yelouafi/redux-saga",
"docs:watch": "npm run docs:prepare && gitbook serve",
"docs:publish": "npm run docs:clean && npm run docs:build && cd _book && git init && git commit --allow-empty -m 'update book' && git checkout -b gh-pages && touch .nojekyll && git add . && git commit -am 'update book' && git push git@github.com:yelouafi/redux-saga gh-pages --force"
},

@@ -53,2 +58,3 @@ "repository": {

"express": "^4.13.3",
"gitbook-cli": "1.0.1",
"isomorphic-fetch": "^2.2.0",

@@ -55,0 +61,0 @@ "react": "^0.14.3",

@@ -85,9 +85,9 @@ # redux-saga

const createStoreWithSaga = applyMiddleware(
// ...,
sagaMiddleware(...sagas)
)(createStore)
export default function configureStore(initialState) {
return createStoreWithSaga(reducer, initialState)
// Note: passing middleware as the last argument to createStore requires redux@>=3.1.0
return createStore(
reducer,
initialState,
applyMiddleware(/* other middleware, */sagaMiddleware(...sagas))
}
}

@@ -94,0 +94,0 @@ ```

@@ -83,9 +83,9 @@ # redux-saga

const createStoreWithSaga = applyMiddleware(
// ...,
sagaMiddleware(...sagas)
)(createStore)
export default function configureStore(initialState) {
return createStoreWithSaga(reducer, initialState)
// Note: passing middleware as the last argument to createStore requires redux@>=3.1.0
return createStore(
reducer,
initialState,
applyMiddleware(/* other middleware, */sagaMiddleware(...sagas))
}
}

@@ -92,0 +92,0 @@ ```

@@ -17,3 +17,3 @@ # redux-saga

> As you'll see in the rest of this README, Generators, while seemingly more low-level than ES7 async
> As you'll see in the docs, Generators, while seemingly more low-level than ES7 async
functions, allow some features like declarative effects and cancellation which are harder—if not

@@ -40,21 +40,4 @@ impossible—to implement with simple async functions.

- [Getting started](#getting-started)
- [Waiting for future actions](#waiting-for-future-actions)
- [Dispatching actions to the store](#dispatching-actions-to-the-store)
- [A common abstraction: Effect](#a-common-abstraction-effect)
- [Declarative Effects](#declarative-effects)
- [Error handling](#error-handling)
- [Effect Combinators](#effect-combinators)
- [Sequencing Sagas via yield*](#sequencing-sagas-via-yield)
- [Composing Sagas](#composing-sagas)
- [Non blocking calls with fork/join](#non-blocking-calls-with-forkjoin)
- [Task cancellation](#task-cancellation)
- [Dynamically starting Sagas with runSaga](#dynamically-starting-sagas-with-runsaga)
- [Building examples from sources](#building-examples-from-sources)
- [Using umd build in the browser](#using-umd-build-in-the-browser)
# Install
#Getting started
Install
```

@@ -64,706 +47,39 @@ npm install redux-saga

Create the Saga (using the counter example from Redux)
```javascript
import { take, put } from 'redux-saga'
// sagas/index.js
# Documentation
function* incrementAsync() {
- [Introduction](http://yelouafi.github.io/redux-saga/docs/introduction/index.html)
- [Basic Concepts](http://yelouafi.github.io/redux-saga/docs/basics/index.html)
- [Advanced Concepts](http://yelouafi.github.io/redux-saga/docs/advanced/index.html)
- [Recipes](http://yelouafi.github.io/redux-saga/docs/recipes/index.html)
- [External Resources](http://yelouafi.github.io/redux-saga/docs/ExternalResources.html)
- [Troubleshooting](http://yelouafi.github.io/redux-saga/docs/Troubleshooting.html)
- [Glossary](http://yelouafi.github.io/redux-saga/docs/Glossary.html)
- [API Reference](http://yelouafi.github.io/redux-saga/docs/api/index.html)
while(true) {
# Using umd build in the browser
// wait for each INCREMENT_ASYNC action
const nextAction = yield take(INCREMENT_ASYNC)
There's also an **umd** build of `redux-saga` available in the `dist/` folder. When using the umd build
`redux-saga` is available as `ReduxSaga` in the window object.
// delay is a sample function
// return a Promise that resolves after (ms) milliseconds
yield delay(1000)
The umd version is useful if you don't use Webpack or Browserify. You can access it directly from [npmcdn](npmcdn.com).
// dispatch INCREMENT_COUNTER
yield put( increment() )
}
The following builds are available:
}
- [https://npmcdn.com/redux-saga/dist/redux-saga.js](https://npmcdn.com/redux-saga/dist/redux-saga.js)
- [https://npmcdn.com/redux-saga/dist/redux-saga.min.js](https://npmcdn.com/redux-saga/dist/redux-saga.min.js)
export default [incrementAsync]
```
**Important!** If the browser you are targeting doesn't support _es2015 generators_ you must provide a valid polyfill,
for example the one provided by *babel*:
[browser-polyfill.min.js](https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.25/browser-polyfill.min.js).
The polyfill must be imported before **redux-saga**.
Plug redux-saga in the middleware pipeline
```javascript
// store/configureStore.js
import 'babel-polyfill'
// then
import sagaMiddleware from 'redux-saga'
import sagas from '../sagas'
const createStoreWithSaga = applyMiddleware(
// ...,
sagaMiddleware(...sagas)
)(createStore)
export default function configureStore(initialState) {
return createStoreWithSaga(reducer, initialState)
}
```
#Waiting for future actions
# Building examples from sources
In the previous example we created an `incrementAsync` Saga. The call `yield take(INCREMENT_ASYNC)` is an
illustration of how Sagas typically work.
Typically, actual middlewares handle some Effect form triggered by an Action Creator. For example,
redux-thunk handles *thunks* by calling them with `(getState, dispatch)` as arguments,
redux-promise handles Promises by dispatching their resolved values, and redux-gen handles generators by
dispatching all yielded actions to the store. The common thing that all those middlewares share is the
same 'call on each action' pattern. They will be called again and again each time an action happens,
i.e. they are *scoped* by the *root action* that triggered them.
Sagas work differently, they are not fired from within Action Creators but are started with your
application and choose what user actions to watch. They are like daemon tasks that run in
the background and choose their own logic of progression. In the example above, `incrementAsync` *pulls*
the `INCREMENT_ASYNC` action using `yield take(...)`. This is a *blocking call*, which means the Saga
will not progress until it receives a matching action.
Above, we used the form `take(INCREMENT_ASYNC)`, which means we're waiting for an action whose type
is `INCREMENT_ASYNC`.
`take` support some more patterns to constrain future actions matching. A call of `yield take(PATTERN)` will be
handled using the following rules
- If PATTERN is undefined or `'*'` all incoming actions are matched (e.g. `take()` will match all actions)
- If PATTERN is a function, the action is matched if PATTERN(action) is true (e.g. `take(action => action.entities)`
will match all actions having a (truthy) `entities`field.)
- If PATTERN is a string, the action is matched if `action.type === PATTERN` (as used above `take(INCREMENT_ASYNC)`
- If PATTERN is an array, action.type is matched against all items in the array (e.g. `take([INCREMENT, DECREMENT])` will
match either actions of type `INCREMENT` or `DECREMENT`).
#Dispatching actions to the store
After receiving the queried action, the Saga triggers a call to `delay(1000)`, which in our example
returns a Promise that will resolve after 1 second. This is a blocking call, so the Saga
will wait for 1 second before continuing on.
After the delay, the Saga dispatches an `INCREMENT_COUNTER` action using the `put(action)`
function. Here also, the Saga will wait for the dispatch result. If the dispatch call returns
a normal value, the Saga resumes *immediately* (ASAP), but if the result value is a Promise then the
Saga will wait until the Promise is resolved (or rejected).
#A common abstraction: Effect
To generalize: waiting for a future action, waiting for the future result of a function call like
`yield delay(1000)`, or waiting for the result of a dispatch all are the same concept. In all cases,
we are yielding some form of Effects.
What a Saga does is actually compose all those effects together to implement the desired control flow.
The simplest is to sequence yielded Effects by just putting the yields one after another. You can also use the
familiar control flow operators (`if`, `while`, `for`) to implement more sophisticated control flows. Or you
you can use the provided Effects combinators to express concurrency (yield race) and parallelism (yield [...]).
You can even yield calls to other Sagas, allowing the powerful routine/subroutine pattern.
For example, `incrementAsync` uses an infinite loop `while(true)` which means it will stay alive
for the entirety of the application's lifetime.
You can also create Sagas that last a limited amount of time. For example, the following Saga
waits for the first 3 `INCREMENT_COUNTER` actions, triggers a `showCongratulation()` action and then finishes.
```javascript
function* onBoarding() {
for(let i = 0; i < 3; i++)
yield take(INCREMENT_COUNTER)
yield put( showCongratulation() )
}
```
#Declarative Effects
Sagas Generators can yield Effects in multiple forms. The simplest way is to yield a Promise.
```javascript
function* fetchSaga() {
// fetch is a sample function
// returns a Promise that will resolve with the GET response
const products = yield fetch('/products')
// dispatch a RECEIVE_PRODUCTS action
yield put( receiveProducts(products) )
}
```
In the example above, `fetch('/products')` returns a Promise that will resolve with the GET response,
so the 'fetch effect' will be executed immediately. Simple and idiomatic but...
Suppose we want to test generator above:
```javascript
const iterator = fetchSaga()
assert.deepEqual( iterator.next().value, ?? ) // what do we expect ?
```
We want to check the result of the first value yielded by the generator, which is in our case the result of running
`fetch('/products')`. Executing the real service during tests is neither a viable nor practical approach, so we have to
*mock* the fetch service, i.e. we'll have to replace the real `fetch` method with a fake one which doesn't actually
run the GET request but only checks that we've called `fetch` with the right arguments (`'/products'` in our case).
Mocks make testing more difficult and less reliable. On the other hand, functions that simply return values are
easier to test, since we can use a simple `equal()` to check the result. This is the way to write the most reliable tests.
Not convinced? I encourage you to read this [Eric Elliott' article]
(https://medium.com/javascript-scene/what-every-unit-test-needs-f6cd34d9836d#.4ttnnzpgc)
>(...)`equal()`, by nature answers the two most important questions every unit test must answer, but most don’t:
- What is the actual output?
- What is the expected output?
>If you finish a test without answering those two questions, you don’t have a real unit test. You have a sloppy, half-baked test.
What we actually need is just to make sure the `fetchSaga` yields a call with the right function and the right
arguments. For this reason, the library provides some declarative ways to yield Side Effects while still making it
easy to test the Saga logic
```javascript
import { call } from 'redux-saga'
function* fetchSaga() {
const products = yield call( fetch, '/products' ) // don't run the effect
}
```
We're using now the `call(fn, ...args)` function. **The difference from the preceeding example is that now we're not
executing the fetch call immediately, instead, `call` creates a description of the effect**. Just as in
Redux you use action creators to create a plain object describing the action that will get executed by the Store,
`call` creates a plain object describing the function call. The redux-saga middleware takes care of executing
the function call and resuming the generator with the resolved response.
This allows us to easily test the Generator outside the Redux environment.
```javascript
import { call } from 'redux-saga'
const iterator = fetchSaga()
assert.deepEqual(iterator.next().value, call(fetch, '/products')) // expects a call(...) value
```
Now we don't need to mock anything, and a simple equality test will suffice.
The advantage of declarative effects is that we can test all the logic inside a Saga/Generator
by simply iterating over the resulting iterator and doing a simple equality tests on the values
yielded successively. This is a real benefit, as your complex asynchronous operations are no longer
black boxes, and you can test in detail their operational logic no matter how complex it is.
To invoke methods of some object (i.e. created with `new`), you can provide a `this` context to the
invoked functions using the following form:
```javascript
yield call([obj, obj.method], arg1, arg2, ...) // as if we did obj.method(arg1, arg2 ...)
```
`apply` is an alias for the method invocation form
```javascript
yield apply(obj, obj.method, [arg1, arg2, ...])
```
`call` and `apply` are well suited for functions that return Promise results. Another function
`cps` can be used to handle Node style functions (e.g. `fn(...args, callback)` where `callback`
is of the form `(error, result) => ()`). For example:
```javascript
import { cps } from 'redux-saga'
const content = yield cps(readFile, '/path/to/file')
```
and of course you can test it just like you test call:
```javascript
import { cps } from 'redux-saga'
const iterator = fetchSaga()
assert.deepEqual(iterator.next().value, cps(readFile, '/path/to/file') )
```
`cps` supports also the same method invocation form as `call`.
#Error handling
You can catch errors inside the Generator using the simple try/catch syntax. In the following example,
the Saga catch errors from the `api.buyProducts` call (i.e. a rejected Promise)
```javascript
function* checkout(getState) {
while( yield take(types.CHECKOUT_REQUEST) ) {
try {
const cart = getState().cart
yield call(api.buyProducts, cart)
yield put(actions.checkoutSuccess(cart))
} catch(error) {
yield put(actions.checkoutFailure(error))
}
}
}
```
Of course you're not forced to handle you API errors inside `try`/`catch` blocks, you can also make
your API service return a normal value with some error flag on it.
```javascript
function buyProducts(cart) {
return doPost(...)
.then(result => {result})
.catch(error => {error})
}
function* checkout(getState) {
while( yield take(types.CHECKOUT_REQUEST) ) {
const cart = getState().cart
const {result, error} = yield call(api.buyProducts, cart)
if(!error)
yield put(actions.checkoutSuccess(result))
else
yield put(actions.checkoutFailure(error))
}
}
```
#Effect Combinators
The `yield` statement is great for representing asynchronous control flow in a simple and linear
style, but we also need to do things in parallel. We can't simply write:
```javascript
// Wrong, effects will be executed in sequence
const users = yield call(fetch, '/users'),
repose = yield call(fetch, '/repose')
```
Because the 2nd effect will not get executed until the first call resolves. Instead we have to write:
```javascript
import { call } from 'redux-saga'
// correct, effects will get executed in parallel
const [users, repose] = yield [
call(fetch, '/users'),
call(fetch, '/repose')
]
```
When we yield an array of effects, the generator is blocked until all the effects are resolved (or as soon as
one is rejected, just like how `Promise.all` behaves).
Sometimes we start multiple tasks in parallel but we don't want to wait for all of them, we just need
to get the *winner*: the first one that resolves (or rejects). The `race` function offers a way of
triggering a race between multiple effects.
The following sample shows a Saga that triggers a remote fetch request, and constrain the response with a
1 second timeout.
```javascript
import { race, take, put } from 'redux-saga'
function* fetchPostsWithTimeout() {
while( yield take(FETCH_POSTS) ) {
// starts a race between 2 effects
const {posts, timeout} = yield race({
posts : call(fetchApi, '/posts'),
timeout : call(delay, 1000)
})
if(posts)
put( actions.receivePosts(posts) )
else
put( actions.timeoutError() )
}
}
```
#Sequencing Sagas via `yield*`
You can use the builtin `yield*` operator to compose multiple sagas in a sequential way.
This allows you to sequence your *macro-tasks* in a simple procedural style.
```javascript
function* playLevelOne(getState) { ... }
function* playLevelTwo(getState) { ... }
function* playLevelThree(getState) { ... }
function* game(getState) {
const score1 = yield* playLevelOne(getState)
put(showScore(score1))
const score2 = yield* playLevelTwo(getState)
put(showScore(score2))
const score3 = yield* playLevelThree(getState)
put(showScore(score3))
}
```
Note that using `yield*` will cause the JavaScript runtime to *spread* the whole sequence.
The resulting iterator (from `game()`) will yield all values from the nested
iterators. A more powerful alternative is to use the more generic middleware composition mechanism.
#Composing Sagas
While using `yield*` provides an idiomatic way of composing Sagas, this approach has some limitations:
- You'll likely want to test nested generators separately. This leads to some duplication in the test
code as well as the overhead of the duplicated execution. We don't want to execute a nested generator
but only make sure the call to it was issued with the right argument.
- More importantly, `yield*` allows only for sequential composition of tasks, so you can only
yield* to one generator at a time.
You can simply use `yield` to start one or more subtasks in parallel. When yielding a call to a
generator, the Saga will wait for the generator to terminate before progressing, then resume
with the returned value (or throws if an error propagates from the subtask).
```javascript
function* fetchPosts() {
yield put( actions.requestPosts() )
const products = yield call(fetchApi, '/products')
yield put( actions.receivePosts(products) )
}
function* watchFetch() {
while ( yield take(FETCH_POSTS) ) {
yield call(fetchPosts) // waits for the fetchPosts task to terminate
}
}
```
Yielding to an array of nested generators will start all the sub-generators in parallel and wait
for them to finish. Then resume with all the results
```javascript
function* mainSaga(getState) {
const results = yield [ call(task1), call(task2), ...]
yield put( showResults(results) )
}
```
In fact, yielding Sagas is no different than yielding other effects (future actions, timeouts, etc).
This means you can combine those Sagas with all the other types using the effect combinators.
For example you may want the user to finish some game in a limited amount of time:
```javascript
function* game(getState) {
let finished
while(!finished) {
// has to finish in 60 seconds
const {score, timeout} = yield race({
score : call( play, getState),
timeout : call(delay, 60000)
})
if(!timeout) {
finished = true
yield put( showScore(score) )
}
}
}
```
#Non blocking calls with fork/join
the `yield` statement causes the generator to pause until the yielded effect resolves or rejects.
If you look closely at this example:
```javascript
function* watchFetch() {
while ( yield take(FETCH_POSTS) ) {
yield put( actions.requestPosts() )
const posts = yield call(fetchApi, '/posts') // blocking call
yield put( actions.receivePosts(posts) )
}
}
```
the `watchFetch` generator will wait until `yield call(fetchApi, '/posts')` terminates. Imagine that the
`FETCH_POSTS` action is fired from a `Refresh` button. If our application disables the button between
each fetch (no concurrent fetches) then there is no issue, because we know that no `FETCH_POSTS` action
will occur until we get the response from the `fetchApi` call.
But what happens if the application allows the user to click on `Refresh` without waiting for the
current request to terminate?
The following example illustrates a possible sequence of the events
```
UI watchFetch
--------------------------------------------------------
FETCH_POSTS.....................call fetchApi........... waiting to resolve
........................................................
........................................................
FETCH_POSTS............................................. missed
........................................................
FETCH_POSTS............................................. missed
................................fetchApi returned.......
........................................................
```
When `watchFetch` is blocked on the `fetchApi` call, all `FETCH_POSTS` occurring in between the
call and the response are missed.
To express non-blocking calls, we can use the `fork` function. A possible rewrite of the previous example
with `fork` can be:
```javascript
import { fork, call, take, put } from 'redux-saga'
function* fetchPosts() {
yield put( actions.requestPosts() )
const posts = yield call(fetchApi, '/posts')
yield put( actions.receivePosts(posts) )
}
function* watchFetch() {
while ( yield take(FETCH_POSTS) ) {
yield fork(fetchPosts) // non blocking call
}
}
```
`fork`, just like `call`, accepts function/generator calls.
```javascript
yield fork(func, ...args) // simple async functions (...) -> Promise
yield fork(generator, ...args) // Generator functions
```
The result of `yield fork(api)` is a *Task descriptor*. To get the result of a forked Task
in a later time, we use the `join` function
```javascript
import { fork, join } from 'redux-saga'
function* child() { ... }
function *parent() {
// non blocking call
const task = yield fork(subtask, ...args)
// ... later
// now a blocking call, will resume with the outcome of task
const result = yield join(task)
}
```
the task object exposes some useful methods
<table>
<tr>
<th>method</th>
<th>return value</th>
</tr>
<tr>
<td>task.isRunning()</td>
<td>true if the task hasn't yet returned or throwed an error</td>
</tr>
<tr>
<td>task.result()</td>
<td>task return value. `undefined` if task is still running</td>
</tr>
<tr>
<td>task.error()</td>
<td>task thrown error. `undefined` if task is still running</td>
</tr>
<tr>
<td>task.done</td>
<td>
a Promise which is either
<ul>
<li>resolved with task's return value</li>
<li>rejected with task's thrown error</li>
</ul>
</td>
</tr>
</table>
#Task cancellation
Once a task is forked, you can abort its execution using `yield cancel(task)`. Cancelling
a running task will throw a `SagaCancellationException` inside it.
To see how it works, let's consider a simple example. A background sync which can be
started/stopped by some UI commands. Upon receiving a `START_BACKGROUND_SYNC` action,
we fork a background task that will periodically sync some data from a remote server.
The task will execute continually until a `STOP_BACKGROUND_SYNC` action is triggered.
Then we cancel the background task and wait again for the next `START_BACKGROUND_SYNC` action.
```javascript
import { take, put, call, fork, cancel, SagaCancellationException } from 'redux-saga'
import actions from 'somewhere'
import { someApi, delay } from 'somewhere'
function* bgSync() {
try {
while(true) {
yield put(actions.requestStart())
const result = yield call(someApi)
yield put(actions.requestSuccess(result))
yield call(delay, 5000)
}
} catch(error) {
if(error instanceof SagaCancellationException)
yield put(actions.requestFailure('Sync cancelled!'))
}
}
function* main() {
while( yield take(START_BACKGROUND_SYNC) ) {
// starts the task in the background
const bgSyncTask = yield fork(bgSync)
// wait for the user stop action
yield take(STOP_BACKGROUND_SYNC)
// user clicked stop. cancel the background task
// this will throw a SagaCancellationException into the forked bgSync task
yield cancel(bgSyncTask)
}
}
```
`yield cancel(bgSyncTask)` will throw a `SagaCancellationException`
inside the currently running task. In the above example, the exception is caught by
`bgSync`. **Note that uncaught SagaCancellationException are not bubbled upward**. In the
above example, if `bgSync` doesn't catch the cancellation error, the error will not propagate
to `main` (because `main` has already moved on).
Cancelling a running task will also cancel the current effect where the task is blocked
at the moment of cancellation.
For example, suppose that at a certain point in an application's lifetime, we had this pending call chain:
```javascript
function* main() {
const task = yield fork(subtask)
...
// later
yield cancel(task)
}
function* subtask() {
...
yield call(subtask2) // currently blocked on this call
...
}
function* subtask2() {
...
yield call(someApi) // currently blocked on this all
...
}
```
`yield cancel(task)` will trigger a cancellation on `subtask`, which in turn will trigger
a cancellation on `subtask2`. A `SagaCancellationException` will be thrown inside `subtask2`,
then another `SagaCancellationException` will be thrown inside `subtask`. If `subtask`
omits to handle the cancellation exception, a warning message is printed to the console to
warn the developer (the message is only printed if there is a `process.env.NODE_ENV` variable
set and it's set to `'development'`).
The main purpose of the cancellation exception is to allow cancelled tasks to perform any
cleanup logic, so we wont leave the application in an inconsistent state. In the above example
of background sync, by catching the cancellation exception, `bgSync` is able to dispatch a
`requestFailure` action to the store. Otherwise, the store could be left in a inconsistent
state (e.g. waiting for the result of a pending request).
>It's important to remember that `yield cancel(task)` doesn't wait for the cancelled task
to finish (i.e. to perform its catch block). The cancel effect behave like fork. It returns
as soon as the cancel was initiated.
>Once cancelled, a task should normally return as soon as it finishes its cleanup logic.
In some cases, the cleanup logic could involve some async operations, but the cancelled
task lives now as a separate process, and there is no way for it to rejoin the main
control flow (except dispatching actions for other tasks via the Redux store. However
this will lead to complicated control flows that are hard to reason about. It's always preferable
to terminate a cancelled task ASAP).
##Automatic cancellation
Besides manual cancellation there are cases where cancellation is triggered automatically
1- In a `race` effect. All race competitors, except the winner, are automatically cancelled.
2- In a parallel effect (`yield [...]`). The parallel effect is rejected as soon as one of the
sub-effects is rejected (as implied by `Promise.all`). In this case, all the other sub-effects
are automatically cancelled.
#Dynamically starting Sagas with runSaga
The `runSaga` function allows starting sagas outside the Redux middleware environment. It also
allows you to hook up to external input/output, other than store actions.
For example, you can start a Saga on the server using:
```javascript
import serverSaga from 'somewhere'
import {runSaga, storeIO} from 'redux-saga'
import configureStore from 'somewhere'
import rootReducer from 'somewhere'
const store = configureStore(rootReducer)
runSaga(
serverSaga(store.getState),
storeIO(store)
).done.then(...)
```
`runSaga` returns a task object. Just like the one returned from a `fork` effect.
Besides taking and dispatching actions to the store `runSaga` can also be connected to
other input/output sources. This allows you to exploit all the features of sagas to implement
control flows outside Redux.
The method has the following signature
```javascript
runSaga(iterator, {subscribe, dispatch}, [monitor])
```
Arguments
- `iterator: {next, throw}` : an iterator object, Typically created by invoking a Generator function
- `subscribe(callback) => unsubscribe`: i.e. a function which accepts a callback and returns an unsubscribe function
- `callback(action)` : callback (provided by runSaga) used to subscribe to input events. `subscribe` must
support registering multiple subscriptions
- `unsubscribe()` : used by `runSaga` to unsubscribe from the input source once it
has completed (either by normal return or a thrown exception)
- `dispatch(action) => result`: used to fulfill `put` effects. Each time a `yield put(action)` is issued, `dispatch`
is invoked with `action`. The return value of `dispatch` is used to fulfill the `put` effect. Promise results
are automatically resolved/rejected.
- `monitor(sagaAction)` (optional): a callback which is used to dispatch all Saga related events. In the middleware
version, all actions are dispatched to the Redux store. See the [sagaMonitor example]
(https://github.com/yelouafi/redux-saga/blob/master/examples/sagaMonitor.js) for usage.
The `subscribe` argument is used to fulfill `take(action)` effects. Each time `subscribe` emits an action
to its callbacks, all sagas that are blocked on `take(PATTERN)`, and whose take pattern matches the currently incoming action,
are resumed with that action.
#Building examples from sources
```
git clone https://github.com/yelouafi/redux-saga.git

@@ -777,3 +93,4 @@ cd redux-saga

Counter example
### Counter example
```

@@ -786,3 +103,4 @@ npm run counter

Shopping Cart example
### Shopping Cart example
```

@@ -795,3 +113,4 @@ npm run shop

async example
### async example
```

@@ -803,3 +122,4 @@ npm run async

real-world example (with webpack hot reloading)
### real-world example (with webpack hot reloading)
```

@@ -810,12 +130,1 @@ cd examples/real-world

```
#Using umd build in the browser
There's an **umd** build of `redux-saga` available in the `dist/` folder. When using the umd build `redux-saga` is available as `ReduxSaga` in the window object.
The umd version is useful if you don't use webpack or browserify. You can access it directly from [npmcdn](npmcdn.com).
The following builds are available:
- [https://npmcdn.com/redux-saga/dist/redux-saga.js](https://npmcdn.com/redux-saga/dist/redux-saga.js)
- [https://npmcdn.com/redux-saga/dist/redux-saga.min.js](https://npmcdn.com/redux-saga/dist/redux-saga.min.js)
**Important!** If the browser you are targeting doesn't support _es2015 generators_ you must provide a valid polyfill, for example the one provided by *babel*: [browser-polyfill.min.js](https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.25/browser-polyfill.min.js). The polyfill must be imported before **redux-saga**.

@@ -5,31 +5,52 @@ import { asap, isDev } from './utils'

import { MONITOR_ACTION } from './monitorActions'
import SagaCancellationException from './SagaCancellationException'
export const RUN_SAGA_DYNAMIC_ERROR = 'Before running a Saga dynamically using middleware.run, you must mount the Saga middleware on the Store using applyMiddleware'
export default (...sagas) => ({getState, dispatch}) => {
export default function sagaMiddlewareFactory(...sagas) {
let runSagaDynamically
const sagaEmitter = emitter()
const monitor = isDev ? action => asap(() => dispatch(action)) : undefined
function sagaMiddleware({getState, dispatch}) {
sagas.forEach( saga => {
proc(
saga(getState),
sagaEmitter.subscribe,
dispatch,
monitor,
0,
saga.name
)
})
const sagaEmitter = emitter()
const monitor = isDev ? action => asap(() => dispatch(action)) : undefined
return next => action => {
const result = next(action) // hit reducers
// filter out monitor actions to avoid endless loop
// see https://github.com/yelouafi/redux-saga/issues/61
if(!action[MONITOR_ACTION])
sagaEmitter.emit(action)
return result;
function runSaga(saga, ...args) {
return proc(
saga(getState, ...args),
sagaEmitter.subscribe,
dispatch,
monitor,
0,
saga.name
)
}
runSagaDynamically = runSaga
sagas.forEach(runSaga)
return next => action => {
const result = next(action) // hit reducers
// filter out monitor actions to avoid endless loop
// see https://github.com/yelouafi/redux-saga/issues/61
if(!action[MONITOR_ACTION])
sagaEmitter.emit(action)
return result;
}
}
sagaMiddleware.run = (saga, ...args) => {
if(!runSagaDynamically) {
throw new Error(RUN_SAGA_DYNAMIC_ERROR)
}
const task = runSagaDynamically(saga, ...args)
task.done.catch(err => {
if(!(err instanceof SagaCancellationException))
throw err
})
return task
}
return sagaMiddleware
}

@@ -8,2 +8,9 @@ import { noop, is, isDev, check, remove, deferred, autoInc, asap, TASK } from './utils'

export const NOT_ITERATOR_ERROR = 'proc first argument (Saga function result) must be an iterator'
export const undefindInputError = name => `
${name} saga was provided with an undefined input action
Hints :
- check that your Action Creator returns a non undefined value
- if the Saga was started using runSaga, check that your subscribe source provides the action to its listeners
`
export const CANCEL = Symbol('@@redux-saga/cancelPromise')

@@ -27,2 +34,4 @@ export const PARALLEL_AUTO_CANCEL = 'PARALLEL_AUTO_CANCEL'

const UNDEFINED_INPUT_ERROR = undefindInputError(name)
// tracks the current `take` effects

@@ -36,2 +45,5 @@ let deferredInputs = []

const unsubscribe = subscribe(input => {
if(input === undefined)
throw UNDEFINED_INPUT_ERROR
for (let i = 0; i < deferredInputs.length; i++) {

@@ -420,2 +432,8 @@ const def = deferredInputs[i]

forked,
cancel: error => {
if(!(error instanceof SagaCancellationException)) {
error = new SagaCancellationException(MANUAL_CANCEL, name, error)
}
done[CANCEL](error)
},
isRunning: () => iterator._isRunning,

@@ -422,0 +440,0 @@ getResult: () => iterator._result,

@@ -1,2 +0,2 @@

import { is, check, noop } from './utils'
import { is, check, noop, isDev } from './utils'
import proc from './proc'

@@ -8,2 +8,6 @@ import emitter from './emitter'

/**
@deprecated
ATTENTION! this method can have some potential issues
For more infos, see issue https://github.com/yelouafi/redux-saga/issues/48
memoize the result of storeChannel. It avoids monkey patching the same store

@@ -15,2 +19,7 @@ multiple times unnecessarly. We need only one channel per store

if(isDev) {
/* eslint-disable no-console */
console.warn(`storeIO is deprecated, to run Saga dynamically, use 'run' method of the middleware`)
}
if(store[IO])

@@ -17,0 +26,0 @@ return store[IO]

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc