redux-saga
Advanced tools
Comparing version 0.6.0 to 0.6.1
@@ -580,5 +580,6 @@ (function webpackUniversalModuleDefinition(root, factory) { | ||
function runPutEffect(action, cb) { | ||
// TODO check why synchronously nested dispatches aren't forwarded to the store | ||
// For now, this workaround allows the dispatch to occur on the next microtask | ||
// But could have side effect on a sync interleaved take/dispatch flow (ARGGHHHHHHH) | ||
//synchronously nested dispatches can not be performed | ||
// because on a sync interleaved take/put the receiver will dispatch the | ||
// action before the sender can take the aknowledge | ||
// this workaround allows the dispatch to occur on the next microtask | ||
(0, _utils.asap)(function () { | ||
@@ -666,2 +667,7 @@ return cb(null, dispatch(action)); | ||
function runParallelEffect(effects, effectId, cb) { | ||
if (!effects.length) { | ||
cb(null, []); | ||
return; | ||
} | ||
var completedCount = 0; | ||
@@ -671,2 +677,9 @@ var completed = undefined; | ||
function checkEffectEnd() { | ||
if (completedCount === results.length) { | ||
completed = true; | ||
cb(null, results); | ||
} | ||
} | ||
var childCbs = effects.map(function (eff, idx) { | ||
@@ -692,6 +705,3 @@ var chCbAtIdx = function chCbAtIdx(err, res) { | ||
completedCount++; | ||
if (completedCount === results.length) { | ||
completed = true; | ||
cb(null, results); | ||
} | ||
checkEffectEnd(); | ||
} | ||
@@ -698,0 +708,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){var u=0,o=void 0,a=Array(e.length),c=e.map(function(e,n){var r=function(e,r){if(!o)if(e){try{t.cancel(new d.default(v,I,I))}catch(e){}t(e)}else a[n]=r,u++,u===a.length&&(o=!0,t(null,a))};return r.cancel=i.noop,r});t.cancel=function(e){o||(o=!0,c.forEach(function(n){return n.cancel(e)}))},e.forEach(function(e,t){return r(e,n,t,c[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(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}}])}); |
@@ -246,5 +246,6 @@ 'use strict'; | ||
function runPutEffect(action, cb) { | ||
// TODO check why synchronously nested dispatches aren't forwarded to the store | ||
// For now, this workaround allows the dispatch to occur on the next microtask | ||
// But could have side effect on a sync interleaved take/dispatch flow (ARGGHHHHHHH) | ||
//synchronously nested dispatches can not be performed | ||
// because on a sync interleaved take/put the receiver will dispatch the | ||
// action before the sender can take the aknowledge | ||
// this workaround allows the dispatch to occur on the next microtask | ||
(0, _utils.asap)(function () { | ||
@@ -332,2 +333,7 @@ return cb(null, dispatch(action)); | ||
function runParallelEffect(effects, effectId, cb) { | ||
if (!effects.length) { | ||
cb(null, []); | ||
return; | ||
} | ||
var completedCount = 0; | ||
@@ -337,2 +343,9 @@ var completed = undefined; | ||
function checkEffectEnd() { | ||
if (completedCount === results.length) { | ||
completed = true; | ||
cb(null, results); | ||
} | ||
} | ||
var childCbs = effects.map(function (eff, idx) { | ||
@@ -358,6 +371,3 @@ var chCbAtIdx = function chCbAtIdx(err, res) { | ||
completedCount++; | ||
if (completedCount === results.length) { | ||
completed = true; | ||
cb(null, results); | ||
} | ||
checkEffectEnd(); | ||
} | ||
@@ -364,0 +374,0 @@ }; |
{ | ||
"name": "redux-saga", | ||
"version": "0.6.0", | ||
"version": "0.6.1", | ||
"description": "Saga middleware for Redux to handle Side Effects", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -550,3 +550,3 @@ # redux-saga | ||
// 使用者點選了停止。取消背景任務 | ||
// 這將會拋出一個 SagaCancellationException 錯誤到任務中 | ||
// 這會拋出 SagaCancellationException 例外到背景執行的任務 | ||
yield cancel(bgSyncTask) | ||
@@ -557,3 +557,3 @@ } | ||
`yield cancel(bgSyncTask)` 將會拋出 `SagaCancellationException` 在目前執行的任務之中。在上述範例中,例外由 `bgSync` 捕獲。否則,它將會傳播到 `main`。如果 `main` 沒有處理它,它將會在呼叫鏈持續往上,如同一般 JavaScript 的錯誤,持續在同步函式呼叫鏈中傳播。 | ||
`yield cancel(bgSyncTask)` 將會拋出 `SagaCancellationException` 在目前執行的任務之中。在上述範例中,例外由 `bgSync` 捕獲。**注意**:未被捕獲的 SagaCancellationException 不會向上冒起。如上述範例,若 `bgSync` 未捕獲取消例外,則例外將不會傳播到 `main`(因為 `main` 已經繼續往下執行)。 | ||
@@ -585,3 +585,3 @@ 取消執行中任務也會取消目前 effect,也就是取消當下的任務。 | ||
`yield cancel(task)` 將觸發取消 `subtask` ,接著觸發取消 `subtask2`。`SagaCancellationException` 將會拋到 `subtask2` 之中,接著拋到 `subtask` 之中。如果 `subtask` 省略對取消例外的處理,它將會傳播到 `main`。 | ||
`yield cancel(task)` 將觸發取消 `subtask` ,接著觸發取消 `subtask2`。`SagaCancellationException` 將會拋到 `subtask2` 之中,接著拋到 `subtask` 之中。如果 `subtask` 省略對取消例外的處理,console 將會顯示顯示警告訊息來警告開發者(訊息只有當變數 `process.env.NODE_ENV` 設定為 `'development'` 的時候才會顯示) | ||
@@ -601,4 +601,2 @@ 取消例外的主要用意在於,讓被取消的任務可以執行清理邏輯。這讓應用程式不會在狀態不一致狀況下離開,在上述背景同步的範例中,透過捕獲取消例外,`bgSync` 能夠分派 `requestFailure` action 到 store。否則,store 可能留下一種不一致的狀態(例如,等候待定請求的結果) | ||
不同於手動取消,未掌控的取消例外不會傳播到實際執行 race/parallel effect 的 saga。不過,console 會有個警告訊息,以防某個取消的任務省略了掌控取消例外。 | ||
#動態啟動 Sagas — runSaga | ||
@@ -605,0 +603,0 @@ |
144
README.md
@@ -6,22 +6,22 @@ # redux-saga | ||
An alternative Side Effect model for Redux applications. Instead of dispatching thunks | ||
which get handled by the redux-thunk middleware. You create *Sagas* to gather all your | ||
which get handled by the redux-thunk middleware, you create *Sagas* to gather all your | ||
Side Effects logic in a central place. | ||
This means the logic of the application lives in 2 places | ||
This means the logic of the application lives in 2 places: | ||
- Reducers are responsible of handling state transitions between actions | ||
- Reducers are responsible for handling state transitions between actions | ||
- Sagas are responsible of orchestrating complex/asynchronous operations. | ||
- Sagas are responsible for orchestrating complex/asynchronous operations. | ||
Sagas are created using Generator functions. | ||
> As you'll see in the rest of this README. Generators, while they seem lower level than ES7 async | ||
functions, allow some features like declarative effects, cancellation. Which are harder, if Not | ||
impossible, to implement with simple async functions. | ||
> As you'll see in the rest of this README, Generators, while seemingly more low-level than ES7 async | ||
functions, allow some features like declarative effects and cancellation which are harder—if not | ||
impossible—to implement with simple async functions. | ||
What this middleware proposes is | ||
What this middleware proposes is: | ||
- A composable abstraction **Effect**: waiting for an action, triggering State updates (by dispatching | ||
actions to the store), calling a remote service are all different forms of Effects. A Saga composes those | ||
- A composable abstraction **Effect**: waiting for an action, triggering state updates (by dispatching | ||
actions to the store), and calling a remote service are all different forms of Effects. A Saga composes those | ||
Effects using familiar control flow constructs (if, while, for, try/catch). | ||
@@ -36,4 +36,4 @@ | ||
- You can implement complex operations with logic that spans across multiple actions (e.g. User onBoarding, Wizard | ||
dialogs, complex Game rules ...), which are not trivial to express using other effects middlewares. | ||
- You can implement complex operations with logic that spans across multiple actions (e.g. User onboarding, wizard | ||
dialogs, complex Game rules, etc.), which are non-trivial to express using other effects middlewares. | ||
@@ -107,8 +107,8 @@ | ||
In the previous example we created an `incrementAsync` Saga. The call `yield take(INCREMENT_ASYNC)` is a | ||
typical illustration of how Sagas work. | ||
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. redux-gen handles generators by | ||
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 | ||
@@ -130,3 +130,3 @@ same 'call on each action' pattern. They will be called again and again each time an action happens, | ||
- If PATTERN is undefined or `'*'`. All incoming actions are matched (e.g. `take()` will match all actions) | ||
- If PATTERN is undefined or `'*'` all incoming actions are matched (e.g. `take()` will match all actions) | ||
@@ -136,6 +136,6 @@ - If PATTERN is a function, the action is matched if PATTERN(action) is true (e.g. `take(action => action.entities)` | ||
- If PATTERN is a string, the action is matched if action.type === PATTERN (as used above `take(INCREMENT_ASYNC)` | ||
- 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`.) | ||
match either actions of type `INCREMENT` or `DECREMENT`). | ||
@@ -145,3 +145,3 @@ #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 be resolved after 1 second. This is a blocking call, so the Saga | ||
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. | ||
@@ -151,3 +151,3 @@ | ||
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 | ||
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). | ||
@@ -157,9 +157,9 @@ | ||
To generalize, waiting for a future action, waiting for the future result of a function call like | ||
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 composing all those effects together to implement the desired control flow. | ||
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 | ||
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 [...]). | ||
@@ -169,5 +169,5 @@ 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 all the application lifetime. | ||
for the entirety of the application's lifetime. | ||
You can also create Sagas that last only for a limited amount of time. For example, the following Saga | ||
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. | ||
@@ -187,3 +187,3 @@ | ||
Sagas Generators can yield Effects in multiple forms. The simplest way is to yield a Promise | ||
Sagas Generators can yield Effects in multiple forms. The simplest way is to yield a Promise. | ||
@@ -202,6 +202,6 @@ ```javascript | ||
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 ... | ||
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 | ||
Suppose we want to test generator above: | ||
@@ -214,10 +214,10 @@ ```javascript | ||
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 not a viable nor a practical approach, so we have to | ||
`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, we can use a simple `equal()` to check the result.This is the way to write the most reliable tests. | ||
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] | ||
Not convinced? I encourage you to read this [Eric Elliott' article] | ||
(https://medium.com/javascript-scene/what-every-unit-test-needs-f6cd34d9836d#.4ttnnzpgc) | ||
@@ -231,3 +231,3 @@ | ||
What we need actually, is just to make sure the `fetchSaga` yields a call with the right function and the right | ||
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 | ||
@@ -244,3 +244,3 @@ easy to test the Saga logic | ||
We're using now `call(fn, ...args)` function. **The difference from the precedent example is that now we're not | ||
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 | ||
@@ -261,3 +261,3 @@ Redux you use action creators to create a plain object describing the action that will get executed by the Store, | ||
Now, we don't need to mock anything, a simple equality test will suffice. | ||
Now we don't need to mock anything, and a simple equality test will suffice. | ||
@@ -267,6 +267,6 @@ The advantage of declarative effects is that we can test all the logic inside a Saga/Generator | ||
yielded successively. This is a real benefit, as your complex asynchronous operations are no longer | ||
black boxes, you can test in detail their logic of operation no matter how complex it is. | ||
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 | ||
invoked functions using the following form: | ||
@@ -285,3 +285,3 @@ ```javascript | ||
`cps` can be used to handle Node style functions (e.g. `fn(...args, callback)` where `callback` | ||
is of the form `(error, result) => ()`). For example | ||
is of the form `(error, result) => ()`). For example: | ||
@@ -294,3 +294,3 @@ ```javascript | ||
and of course you can test it just like you test call | ||
and of course you can test it just like you test call: | ||
@@ -304,3 +304,3 @@ ```javascript | ||
`cps` supports also the same method invocation form as `call` | ||
`cps` supports also the same method invocation form as `call`. | ||
@@ -327,4 +327,4 @@ #Error handling | ||
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 | ||
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. | ||
@@ -353,4 +353,4 @@ ```javascript | ||
The `yield` statements are 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 | ||
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: | ||
@@ -363,3 +363,3 @@ ```javascript | ||
Because the 2nd effect will not get executed until the first call resolves. Instead we have to write | ||
Because the 2nd effect will not get executed until the first call resolves. Instead we have to write: | ||
@@ -405,3 +405,3 @@ ```javascript | ||
#Sequencing Sagas via yield* | ||
#Sequencing Sagas via `yield*` | ||
@@ -438,13 +438,13 @@ You can use the builtin `yield*` operator to compose multiple sagas in a sequential way. | ||
While using `yield*` provides an idiomatic way of composing Sagas. This approach has some limits: | ||
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 an overhead of the duplicated execution. We don't want to execute a nested generator | ||
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, you can only | ||
- 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 resumes | ||
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). | ||
@@ -477,6 +477,6 @@ | ||
In fact, yielding Sagas is no more different than yielding other effects (future actions, timeouts ...). | ||
It means you can combine those Sagas with all the other types using the effect combinators. | ||
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 finish some game in a limited amount of time | ||
For example you may want the user to finish some game in a limited amount of time: | ||
@@ -506,3 +506,3 @@ ```javascript | ||
the `yield` statement causes the generator to pause until the yielded effect resolves or rejects. | ||
If you look closely at this example | ||
If you look closely at this example: | ||
@@ -525,3 +525,3 @@ ```javascript | ||
But what happens if the application allows the user to click on `Refresh` without waiting for the | ||
current request to terminate ? | ||
current request to terminate? | ||
@@ -546,4 +546,4 @@ The following example illustrates a possible sequence of the events | ||
To express non blocking calls, we can use the `fork` function. A possible rewrite of the previous example | ||
with `fork` can be | ||
To express non-blocking calls, we can use the `fork` function. A possible rewrite of the previous example | ||
with `fork` can be: | ||
@@ -677,3 +677,3 @@ ```javascript | ||
For example, suppose that at a certain point in application lifetime, we had this pending call chain | ||
For example, suppose that at a certain point in an application's lifetime, we had this pending call chain: | ||
@@ -709,6 +709,6 @@ ```javascript | ||
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 | ||
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) | ||
state (e.g. waiting for the result of a pending request). | ||
@@ -722,9 +722,9 @@ | ||
task lives now as a separate process, and there is no way for it to rejoin the main | ||
control flow (except dispatching actions other tasks via the Redux store. However | ||
this will lead to complicated control flows that ae hard to reason about. It's always preferable | ||
to terminate a cancelled task asap). | ||
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 | ||
Besides manual cancellation there are cases where cancellation is triggered automatically | ||
@@ -734,3 +734,3 @@ 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 | ||
sub-effects is rejected (as implied by `Promise.all`). In this case, all the other sub-effects | ||
are automatically cancelled. | ||
@@ -744,3 +744,3 @@ | ||
For example, you can start a Saga on the server using | ||
For example, you can start a Saga on the server using: | ||
@@ -782,3 +782,3 @@ ```javascript | ||
- `unsubscribe()` : used by `runSaga` to unsubscribe from the input source once it | ||
has completed (either by normal return or thrown exception) | ||
has completed (either by normal return or a thrown exception) | ||
@@ -794,3 +794,3 @@ - `dispatch(action) => result`: used to fulfill `put` effects. Each time a `yield put(action)` is issued, `dispatch` | ||
The `subscribe` argument is used to fulfill `take(action)` effects. Each time `subscribe` emits an action | ||
to its callbacks, all sagas blocked on `take(PATTERN)`, and whose take pattern matches the currently incoming 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. | ||
@@ -807,3 +807,3 @@ | ||
Below the examples ported (so far) from the Redux repos | ||
Below are the examples ported (so far) from the Redux repos | ||
@@ -842,4 +842,4 @@ Counter example | ||
There's an **umd** build of `redux-saga` available in `dist/` folder. 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). | ||
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: | ||
@@ -846,0 +846,0 @@ |
@@ -242,5 +242,6 @@ import { noop, is, isDev, check, remove, deferred, autoInc, asap, TASK } from './utils' | ||
function runPutEffect(action, cb) { | ||
// TODO check why synchronously nested dispatches aren't forwarded to the store | ||
// For now, this workaround allows the dispatch to occur on the next microtask | ||
// But could have side effect on a sync interleaved take/dispatch flow (ARGGHHHHHHH) | ||
//synchronously nested dispatches can not be performed | ||
// because on a sync interleaved take/put the receiver will dispatch the | ||
// action before the sender can take the aknowledge | ||
// this workaround allows the dispatch to occur on the next microtask | ||
asap(() => cb(null, dispatch(action))) | ||
@@ -307,2 +308,7 @@ // Put effects are non cancellables | ||
function runParallelEffect(effects, effectId, cb) { | ||
if(!effects.length) { | ||
cb(null, []) | ||
return | ||
} | ||
let completedCount = 0 | ||
@@ -312,2 +318,9 @@ let completed | ||
function checkEffectEnd() { | ||
if(completedCount === results.length) { | ||
completed = true | ||
cb(null, results) | ||
} | ||
} | ||
const childCbs = effects.map( (eff, idx) => { | ||
@@ -334,6 +347,3 @@ const chCbAtIdx = (err, res) => { | ||
completedCount++ | ||
if(completedCount === results.length) { | ||
completed = true | ||
cb(null, results) | ||
} | ||
checkEffectEnd() | ||
} | ||
@@ -340,0 +350,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
202786
2629