UNPKG

58.4 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3 typeof define === 'function' && define.amd ? define(['exports'], factory) :
4 (factory((global.ReduxSaga = global.ReduxSaga || {})));
5}(this, (function (exports) { 'use strict';
6
7var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
8 return typeof obj;
9} : function (obj) {
10 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
11};
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27var defineEnumerableProperties = function (obj, descs) {
28 for (var key in descs) {
29 var desc = descs[key];
30 desc.configurable = desc.enumerable = true;
31 if ("value" in desc) desc.writable = true;
32 Object.defineProperty(obj, key, desc);
33 }
34
35 return obj;
36};
37
38
39
40
41
42var _extends = Object.assign || function (target) {
43 for (var i = 1; i < arguments.length; i++) {
44 var source = arguments[i];
45
46 for (var key in source) {
47 if (Object.prototype.hasOwnProperty.call(source, key)) {
48 target[key] = source[key];
49 }
50 }
51 }
52
53 return target;
54};
55
56
57
58
59
60
61
62
63
64
65
66
67
68var objectWithoutProperties = function (obj, keys) {
69 var target = {};
70
71 for (var i in obj) {
72 if (keys.indexOf(i) >= 0) continue;
73 if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;
74 target[i] = obj[i];
75 }
76
77 return target;
78};
79
80var sym = function sym(id) {
81 return '@@redux-saga/' + id;
82};
83
84var TASK = sym('TASK');
85var HELPER = sym('HELPER');
86var MATCH = sym('MATCH');
87var CANCEL = sym('CANCEL_PROMISE');
88var SAGA_ACTION = sym('SAGA_ACTION');
89var SELF_CANCELLATION = sym('SELF_CANCELLATION');
90var konst = function konst(v) {
91 return function () {
92 return v;
93 };
94};
95var kTrue = konst(true);
96
97var noop = function noop() {};
98var ident = function ident(v) {
99 return v;
100};
101
102function check(value, predicate, error) {
103 if (!predicate(value)) {
104 log('error', 'uncaught at check', error);
105 throw new Error(error);
106 }
107}
108
109var hasOwnProperty = Object.prototype.hasOwnProperty;
110function hasOwn(object, property) {
111 return is.notUndef(object) && hasOwnProperty.call(object, property);
112}
113
114var is = {
115 undef: function undef(v) {
116 return v === null || v === undefined;
117 },
118 notUndef: function notUndef(v) {
119 return v !== null && v !== undefined;
120 },
121 func: function func(f) {
122 return typeof f === 'function';
123 },
124 number: function number(n) {
125 return typeof n === 'number';
126 },
127 string: function string(s) {
128 return typeof s === 'string';
129 },
130 array: Array.isArray,
131 object: function object(obj) {
132 return obj && !is.array(obj) && (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object';
133 },
134 promise: function promise(p) {
135 return p && is.func(p.then);
136 },
137 iterator: function iterator(it) {
138 return it && is.func(it.next) && is.func(it.throw);
139 },
140 iterable: function iterable(it) {
141 return it && is.func(Symbol) ? is.func(it[Symbol.iterator]) : is.array(it);
142 },
143 task: function task(t) {
144 return t && t[TASK];
145 },
146 observable: function observable(ob) {
147 return ob && is.func(ob.subscribe);
148 },
149 buffer: function buffer(buf) {
150 return buf && is.func(buf.isEmpty) && is.func(buf.take) && is.func(buf.put);
151 },
152 pattern: function pattern(pat) {
153 return pat && (is.string(pat) || (typeof pat === 'undefined' ? 'undefined' : _typeof(pat)) === 'symbol' || is.func(pat) || is.array(pat));
154 },
155 channel: function channel(ch) {
156 return ch && is.func(ch.take) && is.func(ch.close);
157 },
158 helper: function helper(it) {
159 return it && it[HELPER];
160 },
161 stringableFunc: function stringableFunc(f) {
162 return is.func(f) && hasOwn(f, 'toString');
163 }
164};
165
166var object = {
167 assign: function assign(target, source) {
168 for (var i in source) {
169 if (hasOwn(source, i)) {
170 target[i] = source[i];
171 }
172 }
173 }
174};
175
176function remove(array, item) {
177 var index = array.indexOf(item);
178 if (index >= 0) {
179 array.splice(index, 1);
180 }
181}
182
183var array = {
184 'from': function from(obj) {
185 var arr = Array(obj.length);
186 for (var i in obj) {
187 if (hasOwn(obj, i)) {
188 arr[i] = obj[i];
189 }
190 }
191 return arr;
192 }
193};
194
195function deferred() {
196 var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
197
198 var def = _extends({}, props);
199 var promise = new Promise(function (resolve, reject) {
200 def.resolve = resolve;
201 def.reject = reject;
202 });
203 def.promise = promise;
204 return def;
205}
206
207function arrayOfDeffered(length) {
208 var arr = [];
209 for (var i = 0; i < length; i++) {
210 arr.push(deferred());
211 }
212 return arr;
213}
214
215function delay(ms) {
216 var val = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
217
218 var timeoutId = void 0;
219 var promise = new Promise(function (resolve) {
220 timeoutId = setTimeout(function () {
221 return resolve(val);
222 }, ms);
223 });
224
225 promise[CANCEL] = function () {
226 return clearTimeout(timeoutId);
227 };
228
229 return promise;
230}
231
232function createMockTask() {
233 var _ref;
234
235 var running = true;
236 var _result = void 0,
237 _error = void 0;
238
239 return _ref = {}, _ref[TASK] = true, _ref.isRunning = function isRunning() {
240 return running;
241 }, _ref.result = function result() {
242 return _result;
243 }, _ref.error = function error() {
244 return _error;
245 }, _ref.setRunning = function setRunning(b) {
246 return running = b;
247 }, _ref.setResult = function setResult(r) {
248 return _result = r;
249 }, _ref.setError = function setError(e) {
250 return _error = e;
251 }, _ref;
252}
253
254function autoInc() {
255 var seed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
256
257 return function () {
258 return ++seed;
259 };
260}
261
262var uid = autoInc();
263
264var kThrow = function kThrow(err) {
265 throw err;
266};
267var kReturn = function kReturn(value) {
268 return { value: value, done: true };
269};
270function makeIterator(next) {
271 var thro = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : kThrow;
272 var name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
273 var isHelper = arguments[3];
274
275 var iterator = { name: name, next: next, throw: thro, return: kReturn };
276
277 if (isHelper) {
278 iterator[HELPER] = true;
279 }
280 if (typeof Symbol !== 'undefined') {
281 iterator[Symbol.iterator] = function () {
282 return iterator;
283 };
284 }
285 return iterator;
286}
287
288/**
289 Print error in a useful way whether in a browser environment
290 (with expandable error stack traces), or in a node.js environment
291 (text-only log output)
292 **/
293function log(level, message) {
294 var error = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
295
296 /*eslint-disable no-console*/
297 if (typeof window === 'undefined') {
298 console.log('redux-saga ' + level + ': ' + message + '\n' + (error && error.stack || error));
299 } else {
300 console[level](message, error);
301 }
302}
303
304function deprecate(fn, deprecationWarning) {
305 return function () {
306 log('warn', deprecationWarning);
307 return fn.apply(undefined, arguments);
308 };
309}
310
311var updateIncentive = function updateIncentive(deprecated, preferred) {
312 return deprecated + ' has been deprecated in favor of ' + preferred + ', please update your code';
313};
314
315var internalErr = function internalErr(err) {
316 return new Error('\n redux-saga: Error checking hooks detected an inconsistent state. This is likely a bug\n in redux-saga code and not yours. Thanks for reporting this in the project\'s github repo.\n Error: ' + err + '\n');
317};
318
319var createSetContextWarning = function createSetContextWarning(ctx, props) {
320 return (ctx ? ctx + '.' : '') + 'setContext(props): argument ' + props + ' is not a plain object';
321};
322
323var wrapSagaDispatch = function wrapSagaDispatch(dispatch) {
324 return function (action) {
325 return dispatch(Object.defineProperty(action, SAGA_ACTION, { value: true }));
326 };
327};
328
329var cloneableGenerator = function cloneableGenerator(generatorFunc) {
330 return function () {
331 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
332 args[_key] = arguments[_key];
333 }
334
335 var history = [];
336 var gen = generatorFunc.apply(undefined, args);
337 return {
338 next: function next(arg) {
339 history.push(arg);
340 return gen.next(arg);
341 },
342 clone: function clone() {
343 var clonedGen = cloneableGenerator(generatorFunc).apply(undefined, args);
344 history.forEach(function (arg) {
345 return clonedGen.next(arg);
346 });
347 return clonedGen;
348 },
349 return: function _return(value) {
350 return gen.return(value);
351 },
352 throw: function _throw(exception) {
353 return gen.throw(exception);
354 }
355 };
356 };
357};
358
359var BUFFER_OVERFLOW = 'Channel\'s Buffer overflow!';
360
361var ON_OVERFLOW_THROW = 1;
362var ON_OVERFLOW_DROP = 2;
363var ON_OVERFLOW_SLIDE = 3;
364var ON_OVERFLOW_EXPAND = 4;
365
366var zeroBuffer = { isEmpty: kTrue, put: noop, take: noop };
367
368function ringBuffer() {
369 var limit = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 10;
370 var overflowAction = arguments[1];
371
372 var arr = new Array(limit);
373 var length = 0;
374 var pushIndex = 0;
375 var popIndex = 0;
376
377 var push = function push(it) {
378 arr[pushIndex] = it;
379 pushIndex = (pushIndex + 1) % limit;
380 length++;
381 };
382
383 var take = function take() {
384 if (length != 0) {
385 var it = arr[popIndex];
386 arr[popIndex] = null;
387 length--;
388 popIndex = (popIndex + 1) % limit;
389 return it;
390 }
391 };
392
393 var flush = function flush() {
394 var items = [];
395 while (length) {
396 items.push(take());
397 }
398 return items;
399 };
400
401 return {
402 isEmpty: function isEmpty() {
403 return length == 0;
404 },
405 put: function put(it) {
406 if (length < limit) {
407 push(it);
408 } else {
409 var doubledLimit = void 0;
410 switch (overflowAction) {
411 case ON_OVERFLOW_THROW:
412 throw new Error(BUFFER_OVERFLOW);
413 case ON_OVERFLOW_SLIDE:
414 arr[pushIndex] = it;
415 pushIndex = (pushIndex + 1) % limit;
416 popIndex = pushIndex;
417 break;
418 case ON_OVERFLOW_EXPAND:
419 doubledLimit = 2 * limit;
420
421 arr = flush();
422
423 length = arr.length;
424 pushIndex = arr.length;
425 popIndex = 0;
426
427 arr.length = doubledLimit;
428 limit = doubledLimit;
429
430 push(it);
431 break;
432 default:
433 // DROP
434 }
435 }
436 },
437 take: take, flush: flush
438 };
439}
440
441var buffers = {
442 none: function none() {
443 return zeroBuffer;
444 },
445 fixed: function fixed(limit) {
446 return ringBuffer(limit, ON_OVERFLOW_THROW);
447 },
448 dropping: function dropping(limit) {
449 return ringBuffer(limit, ON_OVERFLOW_DROP);
450 },
451 sliding: function sliding(limit) {
452 return ringBuffer(limit, ON_OVERFLOW_SLIDE);
453 },
454 expanding: function expanding(initialSize) {
455 return ringBuffer(initialSize, ON_OVERFLOW_EXPAND);
456 }
457};
458
459var queue = [];
460/**
461 Variable to hold a counting semaphore
462 - Incrementing adds a lock and puts the scheduler in a `suspended` state (if it's not
463 already suspended)
464 - Decrementing releases a lock. Zero locks puts the scheduler in a `released` state. This
465 triggers flushing the queued tasks.
466**/
467var semaphore = 0;
468
469/**
470 Executes a task 'atomically'. Tasks scheduled during this execution will be queued
471 and flushed after this task has finished (assuming the scheduler endup in a released
472 state).
473**/
474function exec(task) {
475 try {
476 suspend();
477 task();
478 } finally {
479 release();
480 }
481}
482
483/**
484 Executes or queues a task depending on the state of the scheduler (`suspended` or `released`)
485**/
486function asap(task) {
487 queue.push(task);
488
489 if (!semaphore) {
490 suspend();
491 flush();
492 }
493}
494
495/**
496 Puts the scheduler in a `suspended` state. Scheduled tasks will be queued until the
497 scheduler is released.
498**/
499function suspend() {
500 semaphore++;
501}
502
503/**
504 Puts the scheduler in a `released` state.
505**/
506function release() {
507 semaphore--;
508}
509
510/**
511 Releases the current lock. Executes all queued tasks if the scheduler is in the released state.
512**/
513function flush() {
514 release();
515
516 var task = void 0;
517 while (!semaphore && (task = queue.shift()) !== undefined) {
518 exec(task);
519 }
520}
521
522var CHANNEL_END_TYPE = '@@redux-saga/CHANNEL_END';
523var END = { type: CHANNEL_END_TYPE };
524var isEnd = function isEnd(a) {
525 return a && a.type === CHANNEL_END_TYPE;
526};
527
528function emitter() {
529 var subscribers = [];
530
531 function subscribe(sub) {
532 subscribers.push(sub);
533 return function () {
534 return remove(subscribers, sub);
535 };
536 }
537
538 function emit(item) {
539 var arr = subscribers.slice();
540 for (var i = 0, len = arr.length; i < len; i++) {
541 arr[i](item);
542 }
543 }
544
545 return {
546 subscribe: subscribe,
547 emit: emit
548 };
549}
550
551var INVALID_BUFFER = 'invalid buffer passed to channel factory function';
552var UNDEFINED_INPUT_ERROR = 'Saga was provided with an undefined action';
553
554{
555 UNDEFINED_INPUT_ERROR += '\nHints:\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 ';
556}
557
558function channel() {
559 var buffer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : buffers.fixed();
560
561 var closed = false;
562 var takers = [];
563
564 check(buffer, is.buffer, INVALID_BUFFER);
565
566 function checkForbiddenStates() {
567 if (closed && takers.length) {
568 throw internalErr('Cannot have a closed channel with pending takers');
569 }
570 if (takers.length && !buffer.isEmpty()) {
571 throw internalErr('Cannot have pending takers with non empty buffer');
572 }
573 }
574
575 function put(input) {
576 checkForbiddenStates();
577 check(input, is.notUndef, UNDEFINED_INPUT_ERROR);
578 if (closed) {
579 return;
580 }
581 if (!takers.length) {
582 return buffer.put(input);
583 }
584 for (var i = 0; i < takers.length; i++) {
585 var cb = takers[i];
586 if (!cb[MATCH] || cb[MATCH](input)) {
587 takers.splice(i, 1);
588 return cb(input);
589 }
590 }
591 }
592
593 function take(cb) {
594 checkForbiddenStates();
595 check(cb, is.func, 'channel.take\'s callback must be a function');
596
597 if (closed && buffer.isEmpty()) {
598 cb(END);
599 } else if (!buffer.isEmpty()) {
600 cb(buffer.take());
601 } else {
602 takers.push(cb);
603 cb.cancel = function () {
604 return remove(takers, cb);
605 };
606 }
607 }
608
609 function flush$$1(cb) {
610 checkForbiddenStates(); // TODO: check if some new state should be forbidden now
611 check(cb, is.func, 'channel.flush\' callback must be a function');
612 if (closed && buffer.isEmpty()) {
613 cb(END);
614 return;
615 }
616 cb(buffer.flush());
617 }
618
619 function close() {
620 checkForbiddenStates();
621 if (!closed) {
622 closed = true;
623 if (takers.length) {
624 var arr = takers;
625 takers = [];
626 for (var i = 0, len = arr.length; i < len; i++) {
627 arr[i](END);
628 }
629 }
630 }
631 }
632
633 return { take: take, put: put, flush: flush$$1, close: close,
634 get __takers__() {
635 return takers;
636 },
637 get __closed__() {
638 return closed;
639 }
640 };
641}
642
643function eventChannel(subscribe) {
644 var buffer = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : buffers.none();
645 var matcher = arguments[2];
646
647 /**
648 should be if(typeof matcher !== undefined) instead?
649 see PR #273 for a background discussion
650 **/
651 if (arguments.length > 2) {
652 check(matcher, is.func, 'Invalid match function passed to eventChannel');
653 }
654
655 var chan = channel(buffer);
656 var close = function close() {
657 if (!chan.__closed__) {
658 if (unsubscribe) {
659 unsubscribe();
660 }
661 chan.close();
662 }
663 };
664 var unsubscribe = subscribe(function (input) {
665 if (isEnd(input)) {
666 close();
667 return;
668 }
669 if (matcher && !matcher(input)) {
670 return;
671 }
672 chan.put(input);
673 });
674 if (chan.__closed__) {
675 unsubscribe();
676 }
677
678 if (!is.func(unsubscribe)) {
679 throw new Error('in eventChannel: subscribe should return a function to unsubscribe');
680 }
681
682 return {
683 take: chan.take,
684 flush: chan.flush,
685 close: close
686 };
687}
688
689function stdChannel(subscribe) {
690 var chan = eventChannel(function (cb) {
691 return subscribe(function (input) {
692 if (input[SAGA_ACTION]) {
693 cb(input);
694 return;
695 }
696 asap(function () {
697 return cb(input);
698 });
699 });
700 });
701
702 return _extends({}, chan, {
703 take: function take(cb, matcher) {
704 if (arguments.length > 1) {
705 check(matcher, is.func, 'channel.take\'s matcher argument must be a function');
706 cb[MATCH] = matcher;
707 }
708 chan.take(cb);
709 }
710 });
711}
712
713var done = { done: true, value: undefined };
714var qEnd = {};
715
716function fsmIterator(fsm, q0) {
717 var name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'iterator';
718
719 var updateState = void 0,
720 qNext = q0;
721
722 function next(arg, error) {
723 if (qNext === qEnd) {
724 return done;
725 }
726
727 if (error) {
728 qNext = qEnd;
729 throw error;
730 } else {
731 updateState && updateState(arg);
732
733 var _fsm$qNext = fsm[qNext](),
734 q = _fsm$qNext[0],
735 output = _fsm$qNext[1],
736 _updateState = _fsm$qNext[2];
737
738 qNext = q;
739 updateState = _updateState;
740 return qNext === qEnd ? done : output;
741 }
742 }
743
744 return makeIterator(next, function (error) {
745 return next(null, error);
746 }, name, true);
747}
748
749function safeName(patternOrChannel) {
750 if (is.channel(patternOrChannel)) {
751 return 'channel';
752 } else if (Array.isArray(patternOrChannel)) {
753 return String(patternOrChannel.map(function (entry) {
754 return String(entry);
755 }));
756 } else {
757 return String(patternOrChannel);
758 }
759}
760
761function takeEveryHelper(patternOrChannel, worker) {
762 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
763 args[_key - 2] = arguments[_key];
764 }
765
766 var yTake = { done: false, value: take(patternOrChannel) };
767 var yFork = function yFork(ac) {
768 return { done: false, value: fork.apply(undefined, [worker].concat(args, [ac])) };
769 };
770
771 var action = void 0,
772 setAction = function setAction(ac) {
773 return action = ac;
774 };
775
776 return fsmIterator({
777 q1: function q1() {
778 return ['q2', yTake, setAction];
779 },
780 q2: function q2() {
781 return action === END ? [qEnd] : ['q1', yFork(action)];
782 }
783 }, 'q1', 'takeEvery(' + safeName(patternOrChannel) + ', ' + worker.name + ')');
784}
785
786function takeLatestHelper(patternOrChannel, worker) {
787 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
788 args[_key2 - 2] = arguments[_key2];
789 }
790
791 var yTake = { done: false, value: take(patternOrChannel) };
792 var yFork = function yFork(ac) {
793 return { done: false, value: fork.apply(undefined, [worker].concat(args, [ac])) };
794 };
795 var yCancel = function yCancel(task) {
796 return { done: false, value: cancel(task) };
797 };
798
799 var task = void 0,
800 action = void 0;
801 var setTask = function setTask(t) {
802 return task = t;
803 };
804 var setAction = function setAction(ac) {
805 return action = ac;
806 };
807
808 return fsmIterator({
809 q1: function q1() {
810 return ['q2', yTake, setAction];
811 },
812 q2: function q2() {
813 return action === END ? [qEnd] : task ? ['q3', yCancel(task)] : ['q1', yFork(action), setTask];
814 },
815 q3: function q3() {
816 return ['q1', yFork(action), setTask];
817 }
818 }, 'q1', 'takeLatest(' + safeName(patternOrChannel) + ', ' + worker.name + ')');
819}
820
821function throttleHelper(delayLength, pattern, worker) {
822 for (var _len3 = arguments.length, args = Array(_len3 > 3 ? _len3 - 3 : 0), _key3 = 3; _key3 < _len3; _key3++) {
823 args[_key3 - 3] = arguments[_key3];
824 }
825
826 var action = void 0,
827 channel$$1 = void 0;
828
829 var yActionChannel = { done: false, value: actionChannel(pattern, buffers.sliding(1)) };
830 var yTake = function yTake() {
831 return { done: false, value: take(channel$$1) };
832 };
833 var yFork = function yFork(ac) {
834 return { done: false, value: fork.apply(undefined, [worker].concat(args, [ac])) };
835 };
836 var yDelay = { done: false, value: call(delay, delayLength) };
837
838 var setAction = function setAction(ac) {
839 return action = ac;
840 };
841 var setChannel = function setChannel(ch) {
842 return channel$$1 = ch;
843 };
844
845 return fsmIterator({
846 q1: function q1() {
847 return ['q2', yActionChannel, setChannel];
848 },
849 q2: function q2() {
850 return ['q3', yTake(), setAction];
851 },
852 q3: function q3() {
853 return action === END ? [qEnd] : ['q4', yFork(action)];
854 },
855 q4: function q4() {
856 return ['q2', yDelay];
857 }
858 }, 'q1', 'throttle(' + safeName(pattern) + ', ' + worker.name + ')');
859}
860
861var deprecationWarning = function deprecationWarning(helperName) {
862 return 'import { ' + helperName + ' } from \'redux-saga\' has been deprecated in favor of import { ' + helperName + ' } from \'redux-saga/effects\'.\nThe latter will not work with yield*, as helper effects are wrapped automatically for you in fork effect.\nTherefore yield ' + helperName + ' will return task descriptor to your saga and execute next lines of code.';
863};
864var takeEvery$1 = deprecate(takeEveryHelper, deprecationWarning('takeEvery'));
865var takeLatest$1 = deprecate(takeLatestHelper, deprecationWarning('takeLatest'));
866var throttle$1 = deprecate(throttleHelper, deprecationWarning('throttle'));
867
868var IO = sym('IO');
869var TAKE = 'TAKE';
870var PUT = 'PUT';
871var ALL = 'ALL';
872var RACE = 'RACE';
873var CALL = 'CALL';
874var CPS = 'CPS';
875var FORK = 'FORK';
876var JOIN = 'JOIN';
877var CANCEL$1 = 'CANCEL';
878var SELECT = 'SELECT';
879var ACTION_CHANNEL = 'ACTION_CHANNEL';
880var CANCELLED = 'CANCELLED';
881var FLUSH = 'FLUSH';
882var GET_CONTEXT = 'GET_CONTEXT';
883var SET_CONTEXT = 'SET_CONTEXT';
884
885var TEST_HINT = '\n(HINT: if you are getting this errors in tests, consider using createMockTask from redux-saga/utils)';
886
887var effect = function effect(type, payload) {
888 var _ref;
889
890 return _ref = {}, _ref[IO] = true, _ref[type] = payload, _ref;
891};
892
893function take() {
894 var patternOrChannel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '*';
895
896 if (arguments.length) {
897 check(arguments[0], is.notUndef, 'take(patternOrChannel): patternOrChannel is undefined');
898 }
899 if (is.pattern(patternOrChannel)) {
900 return effect(TAKE, { pattern: patternOrChannel });
901 }
902 if (is.channel(patternOrChannel)) {
903 return effect(TAKE, { channel: patternOrChannel });
904 }
905 throw new Error('take(patternOrChannel): argument ' + String(patternOrChannel) + ' is not valid channel or a valid pattern');
906}
907
908take.maybe = function () {
909 var eff = take.apply(undefined, arguments);
910 eff[TAKE].maybe = true;
911 return eff;
912};
913
914var takem = deprecate(take.maybe, updateIncentive('takem', 'take.maybe'));
915
916function put(channel, action) {
917 if (arguments.length > 1) {
918 check(channel, is.notUndef, 'put(channel, action): argument channel is undefined');
919 check(channel, is.channel, 'put(channel, action): argument ' + channel + ' is not a valid channel');
920 check(action, is.notUndef, 'put(channel, action): argument action is undefined');
921 } else {
922 check(channel, is.notUndef, 'put(action): argument action is undefined');
923 action = channel;
924 channel = null;
925 }
926 return effect(PUT, { channel: channel, action: action });
927}
928
929put.resolve = function () {
930 var eff = put.apply(undefined, arguments);
931 eff[PUT].resolve = true;
932 return eff;
933};
934
935put.sync = deprecate(put.resolve, updateIncentive('put.sync', 'put.resolve'));
936
937function all(effects) {
938 return effect(ALL, effects);
939}
940
941function race(effects) {
942 return effect(RACE, effects);
943}
944
945function getFnCallDesc(meth, fn, args) {
946 check(fn, is.notUndef, meth + ': argument fn is undefined');
947
948 var context = null;
949 if (is.array(fn)) {
950 var _fn = fn;
951 context = _fn[0];
952 fn = _fn[1];
953 } else if (fn.fn) {
954 var _fn2 = fn;
955 context = _fn2.context;
956 fn = _fn2.fn;
957 }
958 if (context && is.string(fn) && is.func(context[fn])) {
959 fn = context[fn];
960 }
961 check(fn, is.func, meth + ': argument ' + fn + ' is not a function');
962
963 return { context: context, fn: fn, args: args };
964}
965
966function call(fn) {
967 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
968 args[_key - 1] = arguments[_key];
969 }
970
971 return effect(CALL, getFnCallDesc('call', fn, args));
972}
973
974function apply(context, fn) {
975 var args = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
976
977 return effect(CALL, getFnCallDesc('apply', { context: context, fn: fn }, args));
978}
979
980function cps(fn) {
981 for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
982 args[_key2 - 1] = arguments[_key2];
983 }
984
985 return effect(CPS, getFnCallDesc('cps', fn, args));
986}
987
988function fork(fn) {
989 for (var _len3 = arguments.length, args = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
990 args[_key3 - 1] = arguments[_key3];
991 }
992
993 return effect(FORK, getFnCallDesc('fork', fn, args));
994}
995
996function spawn(fn) {
997 for (var _len4 = arguments.length, args = Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
998 args[_key4 - 1] = arguments[_key4];
999 }
1000
1001 var eff = fork.apply(undefined, [fn].concat(args));
1002 eff[FORK].detached = true;
1003 return eff;
1004}
1005
1006function join() {
1007 for (var _len5 = arguments.length, tasks = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
1008 tasks[_key5] = arguments[_key5];
1009 }
1010
1011 if (tasks.length > 1) {
1012 return all(tasks.map(function (t) {
1013 return join(t);
1014 }));
1015 }
1016 var task = tasks[0];
1017 check(task, is.notUndef, 'join(task): argument task is undefined');
1018 check(task, is.task, 'join(task): argument ' + task + ' is not a valid Task object ' + TEST_HINT);
1019 return effect(JOIN, task);
1020}
1021
1022function cancel() {
1023 for (var _len6 = arguments.length, tasks = Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
1024 tasks[_key6] = arguments[_key6];
1025 }
1026
1027 if (tasks.length > 1) {
1028 return all(tasks.map(function (t) {
1029 return cancel(t);
1030 }));
1031 }
1032 var task = tasks[0];
1033 if (tasks.length === 1) {
1034 check(task, is.notUndef, 'cancel(task): argument task is undefined');
1035 check(task, is.task, 'cancel(task): argument ' + task + ' is not a valid Task object ' + TEST_HINT);
1036 }
1037 return effect(CANCEL$1, task || SELF_CANCELLATION);
1038}
1039
1040function select(selector) {
1041 for (var _len7 = arguments.length, args = Array(_len7 > 1 ? _len7 - 1 : 0), _key7 = 1; _key7 < _len7; _key7++) {
1042 args[_key7 - 1] = arguments[_key7];
1043 }
1044
1045 if (arguments.length === 0) {
1046 selector = ident;
1047 } else {
1048 check(selector, is.notUndef, 'select(selector,[...]): argument selector is undefined');
1049 check(selector, is.func, 'select(selector,[...]): argument ' + selector + ' is not a function');
1050 }
1051 return effect(SELECT, { selector: selector, args: args });
1052}
1053
1054/**
1055 channel(pattern, [buffer]) => creates an event channel for store actions
1056**/
1057function actionChannel(pattern, buffer) {
1058 check(pattern, is.notUndef, 'actionChannel(pattern,...): argument pattern is undefined');
1059 if (arguments.length > 1) {
1060 check(buffer, is.notUndef, 'actionChannel(pattern, buffer): argument buffer is undefined');
1061 check(buffer, is.buffer, 'actionChannel(pattern, buffer): argument ' + buffer + ' is not a valid buffer');
1062 }
1063 return effect(ACTION_CHANNEL, { pattern: pattern, buffer: buffer });
1064}
1065
1066function cancelled() {
1067 return effect(CANCELLED, {});
1068}
1069
1070function flush$1(channel) {
1071 check(channel, is.channel, 'flush(channel): argument ' + channel + ' is not valid channel');
1072 return effect(FLUSH, channel);
1073}
1074
1075function getContext(prop) {
1076 check(prop, is.string, 'getContext(prop): argument ' + prop + ' is not a string');
1077 return effect(GET_CONTEXT, prop);
1078}
1079
1080function setContext(props) {
1081 check(props, is.object, createSetContextWarning(null, props));
1082 return effect(SET_CONTEXT, props);
1083}
1084
1085function takeEvery$$1(patternOrChannel, worker) {
1086 for (var _len8 = arguments.length, args = Array(_len8 > 2 ? _len8 - 2 : 0), _key8 = 2; _key8 < _len8; _key8++) {
1087 args[_key8 - 2] = arguments[_key8];
1088 }
1089
1090 return fork.apply(undefined, [takeEveryHelper, patternOrChannel, worker].concat(args));
1091}
1092
1093function takeLatest$$1(patternOrChannel, worker) {
1094 for (var _len9 = arguments.length, args = Array(_len9 > 2 ? _len9 - 2 : 0), _key9 = 2; _key9 < _len9; _key9++) {
1095 args[_key9 - 2] = arguments[_key9];
1096 }
1097
1098 return fork.apply(undefined, [takeLatestHelper, patternOrChannel, worker].concat(args));
1099}
1100
1101function throttle$$1(ms, pattern, worker) {
1102 for (var _len10 = arguments.length, args = Array(_len10 > 3 ? _len10 - 3 : 0), _key10 = 3; _key10 < _len10; _key10++) {
1103 args[_key10 - 3] = arguments[_key10];
1104 }
1105
1106 return fork.apply(undefined, [throttleHelper, ms, pattern, worker].concat(args));
1107}
1108
1109var createAsEffectType = function createAsEffectType(type) {
1110 return function (effect) {
1111 return effect && effect[IO] && effect[type];
1112 };
1113};
1114
1115var asEffect = {
1116 take: createAsEffectType(TAKE),
1117 put: createAsEffectType(PUT),
1118 all: createAsEffectType(ALL),
1119 race: createAsEffectType(RACE),
1120 call: createAsEffectType(CALL),
1121 cps: createAsEffectType(CPS),
1122 fork: createAsEffectType(FORK),
1123 join: createAsEffectType(JOIN),
1124 cancel: createAsEffectType(CANCEL$1),
1125 select: createAsEffectType(SELECT),
1126 actionChannel: createAsEffectType(ACTION_CHANNEL),
1127 cancelled: createAsEffectType(CANCELLED),
1128 flush: createAsEffectType(FLUSH),
1129 getContext: createAsEffectType(GET_CONTEXT),
1130 setContext: createAsEffectType(SET_CONTEXT)
1131};
1132
1133var NOT_ITERATOR_ERROR = 'proc first argument (Saga function result) must be an iterator';
1134
1135var CHANNEL_END = {
1136 toString: function toString() {
1137 return '@@redux-saga/CHANNEL_END';
1138 }
1139};
1140var TASK_CANCEL = {
1141 toString: function toString() {
1142 return '@@redux-saga/TASK_CANCEL';
1143 }
1144};
1145
1146var matchers = {
1147 wildcard: function wildcard() {
1148 return kTrue;
1149 },
1150 default: function _default(pattern) {
1151 return (typeof pattern === 'undefined' ? 'undefined' : _typeof(pattern)) === 'symbol' ? function (input) {
1152 return input.type === pattern;
1153 } : function (input) {
1154 return input.type === String(pattern);
1155 };
1156 },
1157 array: function array$$1(patterns) {
1158 return function (input) {
1159 return patterns.some(function (p) {
1160 return matcher(p)(input);
1161 });
1162 };
1163 },
1164 predicate: function predicate(_predicate) {
1165 return function (input) {
1166 return _predicate(input);
1167 };
1168 }
1169};
1170
1171function matcher(pattern) {
1172 return (pattern === '*' ? matchers.wildcard : is.array(pattern) ? matchers.array : is.stringableFunc(pattern) ? matchers.default : is.func(pattern) ? matchers.predicate : matchers.default)(pattern);
1173}
1174
1175/**
1176 Used to track a parent task and its forks
1177 In the new fork model, forked tasks are attached by default to their parent
1178 We model this using the concept of Parent task && main Task
1179 main task is the main flow of the current Generator, the parent tasks is the
1180 aggregation of the main tasks + all its forked tasks.
1181 Thus the whole model represents an execution tree with multiple branches (vs the
1182 linear execution tree in sequential (non parallel) programming)
1183
1184 A parent tasks has the following semantics
1185 - It completes if all its forks either complete or all cancelled
1186 - If it's cancelled, all forks are cancelled as well
1187 - It aborts if any uncaught error bubbles up from forks
1188 - If it completes, the return value is the one returned by the main task
1189**/
1190function forkQueue(name, mainTask, cb) {
1191 var tasks = [],
1192 result = void 0,
1193 completed = false;
1194 addTask(mainTask);
1195
1196 function abort(err) {
1197 cancelAll();
1198 cb(err, true);
1199 }
1200
1201 function addTask(task) {
1202 tasks.push(task);
1203 task.cont = function (res, isErr) {
1204 if (completed) {
1205 return;
1206 }
1207
1208 remove(tasks, task);
1209 task.cont = noop;
1210 if (isErr) {
1211 abort(res);
1212 } else {
1213 if (task === mainTask) {
1214 result = res;
1215 }
1216 if (!tasks.length) {
1217 completed = true;
1218 cb(result);
1219 }
1220 }
1221 };
1222 // task.cont.cancel = task.cancel
1223 }
1224
1225 function cancelAll() {
1226 if (completed) {
1227 return;
1228 }
1229 completed = true;
1230 tasks.forEach(function (t) {
1231 t.cont = noop;
1232 t.cancel();
1233 });
1234 tasks = [];
1235 }
1236
1237 return {
1238 addTask: addTask,
1239 cancelAll: cancelAll,
1240 abort: abort,
1241 getTasks: function getTasks() {
1242 return tasks;
1243 },
1244 taskNames: function taskNames() {
1245 return tasks.map(function (t) {
1246 return t.name;
1247 });
1248 }
1249 };
1250}
1251
1252function createTaskIterator(_ref) {
1253 var context = _ref.context,
1254 fn = _ref.fn,
1255 args = _ref.args;
1256
1257 if (is.iterator(fn)) {
1258 return fn;
1259 }
1260
1261 // catch synchronous failures; see #152 and #441
1262 var result = void 0,
1263 error = void 0;
1264 try {
1265 result = fn.apply(context, args);
1266 } catch (err) {
1267 error = err;
1268 }
1269
1270 // i.e. a generator function returns an iterator
1271 if (is.iterator(result)) {
1272 return result;
1273 }
1274
1275 // do not bubble up synchronous failures for detached forks
1276 // instead create a failed task. See #152 and #441
1277 return error ? makeIterator(function () {
1278 throw error;
1279 }) : makeIterator(function () {
1280 var pc = void 0;
1281 var eff = { done: false, value: result };
1282 var ret = function ret(value) {
1283 return { done: true, value: value };
1284 };
1285 return function (arg) {
1286 if (!pc) {
1287 pc = true;
1288 return eff;
1289 } else {
1290 return ret(arg);
1291 }
1292 };
1293 }());
1294}
1295
1296var wrapHelper = function wrapHelper(helper) {
1297 return { fn: helper };
1298};
1299
1300function proc(iterator) {
1301 var subscribe = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {
1302 return noop;
1303 };
1304 var dispatch = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : noop;
1305 var getState = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : noop;
1306 var parentContext = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {};
1307 var options = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
1308 var parentEffectId = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : 0;
1309 var name = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 'anonymous';
1310 var cont = arguments[8];
1311
1312 check(iterator, is.iterator, NOT_ITERATOR_ERROR);
1313
1314 var effectsString = '[...effects]';
1315 var runParallelEffect = deprecate(runAllEffect, updateIncentive(effectsString, 'all(' + effectsString + ')'));
1316
1317 var sagaMonitor = options.sagaMonitor,
1318 logger = options.logger,
1319 onError = options.onError;
1320
1321 var log$$1 = logger || log;
1322 var stdChannel$$1 = stdChannel(subscribe);
1323 var taskContext = Object.create(parentContext);
1324 /**
1325 Tracks the current effect cancellation
1326 Each time the generator progresses. calling runEffect will set a new value
1327 on it. It allows propagating cancellation to child effects
1328 **/
1329 next.cancel = noop;
1330
1331 /**
1332 Creates a new task descriptor for this generator, We'll also create a main task
1333 to track the main flow (besides other forked tasks)
1334 **/
1335 var task = newTask(parentEffectId, name, iterator, cont);
1336 var mainTask = { name: name, cancel: cancelMain, isRunning: true };
1337 var taskQueue = forkQueue(name, mainTask, end);
1338
1339 /**
1340 cancellation of the main task. We'll simply resume the Generator with a Cancel
1341 **/
1342 function cancelMain() {
1343 if (mainTask.isRunning && !mainTask.isCancelled) {
1344 mainTask.isCancelled = true;
1345 next(TASK_CANCEL);
1346 }
1347 }
1348
1349 /**
1350 This may be called by a parent generator to trigger/propagate cancellation
1351 cancel all pending tasks (including the main task), then end the current task.
1352 Cancellation propagates down to the whole execution tree holded by this Parent task
1353 It's also propagated to all joiners of this task and their execution tree/joiners
1354 Cancellation is noop for terminated/Cancelled tasks tasks
1355 **/
1356 function cancel$$1() {
1357 /**
1358 We need to check both Running and Cancelled status
1359 Tasks can be Cancelled but still Running
1360 **/
1361 if (iterator._isRunning && !iterator._isCancelled) {
1362 iterator._isCancelled = true;
1363 taskQueue.cancelAll();
1364 /**
1365 Ending with a Never result will propagate the Cancellation to all joiners
1366 **/
1367 end(TASK_CANCEL);
1368 }
1369 }
1370 /**
1371 attaches cancellation logic to this task's continuation
1372 this will permit cancellation to propagate down the call chain
1373 **/
1374 cont && (cont.cancel = cancel$$1);
1375
1376 // tracks the running status
1377 iterator._isRunning = true;
1378
1379 // kicks up the generator
1380 next();
1381
1382 // then return the task descriptor to the caller
1383 return task;
1384
1385 /**
1386 This is the generator driver
1387 It's a recursive async/continuation function which calls itself
1388 until the generator terminates or throws
1389 **/
1390 function next(arg, isErr) {
1391 // Preventive measure. If we end up here, then there is really something wrong
1392 if (!mainTask.isRunning) {
1393 throw new Error('Trying to resume an already finished generator');
1394 }
1395
1396 try {
1397 var result = void 0;
1398 if (isErr) {
1399 result = iterator.throw(arg);
1400 } else if (arg === TASK_CANCEL) {
1401 /**
1402 getting TASK_CANCEL automatically cancels the main task
1403 We can get this value here
1404 - By cancelling the parent task manually
1405 - By joining a Cancelled task
1406 **/
1407 mainTask.isCancelled = true;
1408 /**
1409 Cancels the current effect; this will propagate the cancellation down to any called tasks
1410 **/
1411 next.cancel();
1412 /**
1413 If this Generator has a `return` method then invokes it
1414 This will jump to the finally block
1415 **/
1416 result = is.func(iterator.return) ? iterator.return(TASK_CANCEL) : { done: true, value: TASK_CANCEL };
1417 } else if (arg === CHANNEL_END) {
1418 // We get CHANNEL_END by taking from a channel that ended using `take` (and not `takem` used to trap End of channels)
1419 result = is.func(iterator.return) ? iterator.return() : { done: true };
1420 } else {
1421 result = iterator.next(arg);
1422 }
1423
1424 if (!result.done) {
1425 runEffect(result.value, parentEffectId, '', next);
1426 } else {
1427 /**
1428 This Generator has ended, terminate the main task and notify the fork queue
1429 **/
1430 mainTask.isMainRunning = false;
1431 mainTask.cont && mainTask.cont(result.value);
1432 }
1433 } catch (error) {
1434 if (mainTask.isCancelled) {
1435 log$$1('error', 'uncaught at ' + name, error.message);
1436 }
1437 mainTask.isMainRunning = false;
1438 mainTask.cont(error, true);
1439 }
1440 }
1441
1442 function end(result, isErr) {
1443 iterator._isRunning = false;
1444 stdChannel$$1.close();
1445 if (!isErr) {
1446 if ("development" === 'development' && result === TASK_CANCEL) {
1447 log$$1('info', name + ' has been cancelled', '');
1448 }
1449 iterator._result = result;
1450 iterator._deferredEnd && iterator._deferredEnd.resolve(result);
1451 } else {
1452 if (result instanceof Error) {
1453 result.sagaStack = 'at ' + name + ' \n ' + (result.sagaStack || result.stack);
1454 }
1455 if (!task.cont) {
1456 log$$1('error', 'uncaught', result.sagaStack || result.stack);
1457 if (result instanceof Error && onError) {
1458 onError(result);
1459 }
1460 }
1461 iterator._error = result;
1462 iterator._isAborted = true;
1463 iterator._deferredEnd && iterator._deferredEnd.reject(result);
1464 }
1465 task.cont && task.cont(result, isErr);
1466 task.joiners.forEach(function (j) {
1467 return j.cb(result, isErr);
1468 });
1469 task.joiners = null;
1470 }
1471
1472 function runEffect(effect, parentEffectId) {
1473 var label = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
1474 var cb = arguments[3];
1475
1476 var effectId = uid();
1477 sagaMonitor && sagaMonitor.effectTriggered({ effectId: effectId, parentEffectId: parentEffectId, label: label, effect: effect });
1478
1479 /**
1480 completion callback and cancel callback are mutually exclusive
1481 We can't cancel an already completed effect
1482 And We can't complete an already cancelled effectId
1483 **/
1484 var effectSettled = void 0;
1485
1486 // Completion callback passed to the appropriate effect runner
1487 function currCb(res, isErr) {
1488 if (effectSettled) {
1489 return;
1490 }
1491
1492 effectSettled = true;
1493 cb.cancel = noop; // defensive measure
1494 if (sagaMonitor) {
1495 isErr ? sagaMonitor.effectRejected(effectId, res) : sagaMonitor.effectResolved(effectId, res);
1496 }
1497 cb(res, isErr);
1498 }
1499 // tracks down the current cancel
1500 currCb.cancel = noop;
1501
1502 // setup cancellation logic on the parent cb
1503 cb.cancel = function () {
1504 // prevents cancelling an already completed effect
1505 if (effectSettled) {
1506 return;
1507 }
1508
1509 effectSettled = true;
1510 /**
1511 propagates cancel downward
1512 catch uncaught cancellations errors; since we can no longer call the completion
1513 callback, log errors raised during cancellations into the console
1514 **/
1515 try {
1516 currCb.cancel();
1517 } catch (err) {
1518 log$$1('error', 'uncaught at ' + name, err.message);
1519 }
1520 currCb.cancel = noop; // defensive measure
1521
1522 sagaMonitor && sagaMonitor.effectCancelled(effectId);
1523 };
1524
1525 /**
1526 each effect runner must attach its own logic of cancellation to the provided callback
1527 it allows this generator to propagate cancellation downward.
1528 ATTENTION! effect runners must setup the cancel logic by setting cb.cancel = [cancelMethod]
1529 And the setup must occur before calling the callback
1530 This is a sort of inversion of control: called async functions are responsible
1531 for completing the flow by calling the provided continuation; while caller functions
1532 are responsible for aborting the current flow by calling the attached cancel function
1533 Library users can attach their own cancellation logic to promises by defining a
1534 promise[CANCEL] method in their returned promises
1535 ATTENTION! calling cancel must have no effect on an already completed or cancelled effect
1536 **/
1537 var data = void 0;
1538 return (
1539 // Non declarative effect
1540 is.promise(effect) ? resolvePromise(effect, currCb) : is.helper(effect) ? runForkEffect(wrapHelper(effect), effectId, currCb) : is.iterator(effect) ? resolveIterator(effect, effectId, name, currCb)
1541
1542 // declarative effects
1543 : is.array(effect) ? runParallelEffect(effect, effectId, currCb) : (data = asEffect.take(effect)) ? runTakeEffect(data, currCb) : (data = asEffect.put(effect)) ? runPutEffect(data, currCb) : (data = asEffect.all(effect)) ? runAllEffect(data, effectId, currCb) : (data = asEffect.race(effect)) ? runRaceEffect(data, effectId, currCb) : (data = asEffect.call(effect)) ? runCallEffect(data, effectId, currCb) : (data = asEffect.cps(effect)) ? runCPSEffect(data, currCb) : (data = asEffect.fork(effect)) ? runForkEffect(data, effectId, currCb) : (data = asEffect.join(effect)) ? runJoinEffect(data, currCb) : (data = asEffect.cancel(effect)) ? runCancelEffect(data, currCb) : (data = asEffect.select(effect)) ? runSelectEffect(data, currCb) : (data = asEffect.actionChannel(effect)) ? runChannelEffect(data, currCb) : (data = asEffect.flush(effect)) ? runFlushEffect(data, currCb) : (data = asEffect.cancelled(effect)) ? runCancelledEffect(data, currCb) : (data = asEffect.getContext(effect)) ? runGetContextEffect(data, currCb) : (data = asEffect.setContext(effect)) ? runSetContextEffect(data, currCb) : /* anything else returned as is */currCb(effect)
1544 );
1545 }
1546
1547 function resolvePromise(promise, cb) {
1548 var cancelPromise = promise[CANCEL];
1549 if (typeof cancelPromise === 'function') {
1550 cb.cancel = cancelPromise;
1551 }
1552 promise.then(cb, function (error) {
1553 return cb(error, true);
1554 });
1555 }
1556
1557 function resolveIterator(iterator, effectId, name, cb) {
1558 proc(iterator, subscribe, dispatch, getState, taskContext, options, effectId, name, cb);
1559 }
1560
1561 function runTakeEffect(_ref2, cb) {
1562 var channel$$1 = _ref2.channel,
1563 pattern = _ref2.pattern,
1564 maybe = _ref2.maybe;
1565
1566 channel$$1 = channel$$1 || stdChannel$$1;
1567 var takeCb = function takeCb(inp) {
1568 return inp instanceof Error ? cb(inp, true) : isEnd(inp) && !maybe ? cb(CHANNEL_END) : cb(inp);
1569 };
1570 try {
1571 channel$$1.take(takeCb, matcher(pattern));
1572 } catch (err) {
1573 return cb(err, true);
1574 }
1575 cb.cancel = takeCb.cancel;
1576 }
1577
1578 function runPutEffect(_ref3, cb) {
1579 var channel$$1 = _ref3.channel,
1580 action = _ref3.action,
1581 resolve = _ref3.resolve;
1582
1583 /**
1584 Schedule the put in case another saga is holding a lock.
1585 The put will be executed atomically. ie nested puts will execute after
1586 this put has terminated.
1587 **/
1588 asap(function () {
1589 var result = void 0;
1590 try {
1591 result = (channel$$1 ? channel$$1.put : dispatch)(action);
1592 } catch (error) {
1593 // If we have a channel or `put.resolve` was used then bubble up the error.
1594 if (channel$$1 || resolve) return cb(error, true);
1595 log$$1('error', 'uncaught at ' + name, error.stack || error.message || error);
1596 }
1597
1598 if (resolve && is.promise(result)) {
1599 resolvePromise(result, cb);
1600 } else {
1601 return cb(result);
1602 }
1603 });
1604 // Put effects are non cancellables
1605 }
1606
1607 function runCallEffect(_ref4, effectId, cb) {
1608 var context = _ref4.context,
1609 fn = _ref4.fn,
1610 args = _ref4.args;
1611
1612 var result = void 0;
1613 // catch synchronous failures; see #152
1614 try {
1615 result = fn.apply(context, args);
1616 } catch (error) {
1617 return cb(error, true);
1618 }
1619 return is.promise(result) ? resolvePromise(result, cb) : is.iterator(result) ? resolveIterator(result, effectId, fn.name, cb) : cb(result);
1620 }
1621
1622 function runCPSEffect(_ref5, cb) {
1623 var context = _ref5.context,
1624 fn = _ref5.fn,
1625 args = _ref5.args;
1626
1627 // CPS (ie node style functions) can define their own cancellation logic
1628 // by setting cancel field on the cb
1629
1630 // catch synchronous failures; see #152
1631 try {
1632 var cpsCb = function cpsCb(err, res) {
1633 return is.undef(err) ? cb(res) : cb(err, true);
1634 };
1635 fn.apply(context, args.concat(cpsCb));
1636 if (cpsCb.cancel) {
1637 cb.cancel = function () {
1638 return cpsCb.cancel();
1639 };
1640 }
1641 } catch (error) {
1642 return cb(error, true);
1643 }
1644 }
1645
1646 function runForkEffect(_ref6, effectId, cb) {
1647 var context = _ref6.context,
1648 fn = _ref6.fn,
1649 args = _ref6.args,
1650 detached = _ref6.detached;
1651
1652 var taskIterator = createTaskIterator({ context: context, fn: fn, args: args });
1653
1654 try {
1655 suspend();
1656 var _task = proc(taskIterator, subscribe, dispatch, getState, taskContext, options, effectId, fn.name, detached ? null : noop);
1657
1658 if (detached) {
1659 cb(_task);
1660 } else {
1661 if (taskIterator._isRunning) {
1662 taskQueue.addTask(_task);
1663 cb(_task);
1664 } else if (taskIterator._error) {
1665 taskQueue.abort(taskIterator._error);
1666 } else {
1667 cb(_task);
1668 }
1669 }
1670 } finally {
1671 flush();
1672 }
1673 // Fork effects are non cancellables
1674 }
1675
1676 function runJoinEffect(t, cb) {
1677 if (t.isRunning()) {
1678 var joiner = { task: task, cb: cb };
1679 cb.cancel = function () {
1680 return remove(t.joiners, joiner);
1681 };
1682 t.joiners.push(joiner);
1683 } else {
1684 t.isAborted() ? cb(t.error(), true) : cb(t.result());
1685 }
1686 }
1687
1688 function runCancelEffect(taskToCancel, cb) {
1689 if (taskToCancel === SELF_CANCELLATION) {
1690 taskToCancel = task;
1691 }
1692 if (taskToCancel.isRunning()) {
1693 taskToCancel.cancel();
1694 }
1695 cb();
1696 // cancel effects are non cancellables
1697 }
1698
1699 function runAllEffect(effects, effectId, cb) {
1700 var keys = Object.keys(effects);
1701
1702 if (!keys.length) {
1703 return cb(is.array(effects) ? [] : {});
1704 }
1705
1706 var completedCount = 0;
1707 var completed = void 0;
1708 var results = {};
1709 var childCbs = {};
1710
1711 function checkEffectEnd() {
1712 if (completedCount === keys.length) {
1713 completed = true;
1714 cb(is.array(effects) ? array.from(_extends({}, results, { length: keys.length })) : results);
1715 }
1716 }
1717
1718 keys.forEach(function (key) {
1719 var chCbAtKey = function chCbAtKey(res, isErr) {
1720 if (completed) {
1721 return;
1722 }
1723 if (isErr || isEnd(res) || res === CHANNEL_END || res === TASK_CANCEL) {
1724 cb.cancel();
1725 cb(res, isErr);
1726 } else {
1727 results[key] = res;
1728 completedCount++;
1729 checkEffectEnd();
1730 }
1731 };
1732 chCbAtKey.cancel = noop;
1733 childCbs[key] = chCbAtKey;
1734 });
1735
1736 cb.cancel = function () {
1737 if (!completed) {
1738 completed = true;
1739 keys.forEach(function (key) {
1740 return childCbs[key].cancel();
1741 });
1742 }
1743 };
1744
1745 keys.forEach(function (key) {
1746 return runEffect(effects[key], effectId, key, childCbs[key]);
1747 });
1748 }
1749
1750 function runRaceEffect(effects, effectId, cb) {
1751 var completed = void 0;
1752 var keys = Object.keys(effects);
1753 var childCbs = {};
1754
1755 keys.forEach(function (key) {
1756 var chCbAtKey = function chCbAtKey(res, isErr) {
1757 if (completed) {
1758 return;
1759 }
1760
1761 if (isErr) {
1762 // Race Auto cancellation
1763 cb.cancel();
1764 cb(res, true);
1765 } else if (!isEnd(res) && res !== CHANNEL_END && res !== TASK_CANCEL) {
1766 var _cb;
1767
1768 cb.cancel();
1769 completed = true;
1770 cb((_cb = {}, _cb[key] = res, _cb));
1771 }
1772 };
1773 chCbAtKey.cancel = noop;
1774 childCbs[key] = chCbAtKey;
1775 });
1776
1777 cb.cancel = function () {
1778 // prevents unnecessary cancellation
1779 if (!completed) {
1780 completed = true;
1781 keys.forEach(function (key) {
1782 return childCbs[key].cancel();
1783 });
1784 }
1785 };
1786 keys.forEach(function (key) {
1787 if (completed) {
1788 return;
1789 }
1790 runEffect(effects[key], effectId, key, childCbs[key]);
1791 });
1792 }
1793
1794 function runSelectEffect(_ref7, cb) {
1795 var selector = _ref7.selector,
1796 args = _ref7.args;
1797
1798 try {
1799 var state = selector.apply(undefined, [getState()].concat(args));
1800 cb(state);
1801 } catch (error) {
1802 cb(error, true);
1803 }
1804 }
1805
1806 function runChannelEffect(_ref8, cb) {
1807 var pattern = _ref8.pattern,
1808 buffer = _ref8.buffer;
1809
1810 var match = matcher(pattern);
1811 match.pattern = pattern;
1812 cb(eventChannel(subscribe, buffer || buffers.fixed(), match));
1813 }
1814
1815 function runCancelledEffect(data, cb) {
1816 cb(!!mainTask.isCancelled);
1817 }
1818
1819 function runFlushEffect(channel$$1, cb) {
1820 channel$$1.flush(cb);
1821 }
1822
1823 function runGetContextEffect(prop, cb) {
1824 cb(taskContext[prop]);
1825 }
1826
1827 function runSetContextEffect(props, cb) {
1828 object.assign(taskContext, props);
1829 cb();
1830 }
1831
1832 function newTask(id, name, iterator, cont) {
1833 var _done, _ref9, _mutatorMap;
1834
1835 iterator._deferredEnd = null;
1836 return _ref9 = {}, _ref9[TASK] = true, _ref9.id = id, _ref9.name = name, _done = 'done', _mutatorMap = {}, _mutatorMap[_done] = _mutatorMap[_done] || {}, _mutatorMap[_done].get = function () {
1837 if (iterator._deferredEnd) {
1838 return iterator._deferredEnd.promise;
1839 } else {
1840 var def = deferred();
1841 iterator._deferredEnd = def;
1842 if (!iterator._isRunning) {
1843 iterator._error ? def.reject(iterator._error) : def.resolve(iterator._result);
1844 }
1845 return def.promise;
1846 }
1847 }, _ref9.cont = cont, _ref9.joiners = [], _ref9.cancel = cancel$$1, _ref9.isRunning = function isRunning() {
1848 return iterator._isRunning;
1849 }, _ref9.isCancelled = function isCancelled() {
1850 return iterator._isCancelled;
1851 }, _ref9.isAborted = function isAborted() {
1852 return iterator._isAborted;
1853 }, _ref9.result = function result() {
1854 return iterator._result;
1855 }, _ref9.error = function error() {
1856 return iterator._error;
1857 }, _ref9.setContext = function setContext$$1(props) {
1858 check(props, is.object, createSetContextWarning('task', props));
1859 object.assign(taskContext, props);
1860 }, defineEnumerableProperties(_ref9, _mutatorMap), _ref9;
1861 }
1862}
1863
1864var RUN_SAGA_SIGNATURE = 'runSaga(storeInterface, saga, ...args)';
1865var NON_GENERATOR_ERR = RUN_SAGA_SIGNATURE + ': saga argument must be a Generator function!';
1866
1867function runSaga(storeInterface, saga) {
1868 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
1869 args[_key - 2] = arguments[_key];
1870 }
1871
1872 var iterator = void 0;
1873
1874 if (is.iterator(storeInterface)) {
1875 {
1876 log('warn', 'runSaga(iterator, storeInterface) has been deprecated in favor of ' + RUN_SAGA_SIGNATURE);
1877 }
1878 iterator = storeInterface;
1879 storeInterface = saga;
1880 } else {
1881 check(saga, is.func, NON_GENERATOR_ERR);
1882 iterator = saga.apply(undefined, args);
1883 check(iterator, is.iterator, NON_GENERATOR_ERR);
1884 }
1885
1886 var _storeInterface = storeInterface,
1887 subscribe = _storeInterface.subscribe,
1888 dispatch = _storeInterface.dispatch,
1889 getState = _storeInterface.getState,
1890 context = _storeInterface.context,
1891 sagaMonitor = _storeInterface.sagaMonitor,
1892 logger = _storeInterface.logger,
1893 onError = _storeInterface.onError;
1894
1895
1896 var effectId = uid();
1897
1898 if (sagaMonitor) {
1899 // monitors are expected to have a certain interface, let's fill-in any missing ones
1900 sagaMonitor.effectTriggered = sagaMonitor.effectTriggered || noop;
1901 sagaMonitor.effectResolved = sagaMonitor.effectResolved || noop;
1902 sagaMonitor.effectRejected = sagaMonitor.effectRejected || noop;
1903 sagaMonitor.effectCancelled = sagaMonitor.effectCancelled || noop;
1904 sagaMonitor.actionDispatched = sagaMonitor.actionDispatched || noop;
1905
1906 sagaMonitor.effectTriggered({ effectId: effectId, root: true, parentEffectId: 0, effect: { root: true, saga: saga, args: args } });
1907 }
1908
1909 var task = proc(iterator, subscribe, wrapSagaDispatch(dispatch), getState, context, { sagaMonitor: sagaMonitor, logger: logger, onError: onError }, effectId, saga.name);
1910
1911 if (sagaMonitor) {
1912 sagaMonitor.effectResolved(effectId, task);
1913 }
1914
1915 return task;
1916}
1917
1918function sagaMiddlewareFactory() {
1919 var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1920
1921 var _ref$context = _ref.context,
1922 context = _ref$context === undefined ? {} : _ref$context,
1923 options = objectWithoutProperties(_ref, ['context']);
1924 var sagaMonitor = options.sagaMonitor,
1925 logger = options.logger,
1926 onError = options.onError;
1927
1928
1929 if (is.func(options)) {
1930 {
1931 throw new Error('You passed a function to the Saga middleware. You are likely trying to start a Saga by directly passing it to the middleware. This is no longer possible starting from 0.10.0. To run a Saga, you must do it dynamically AFTER mounting the middleware into the store.\n Example:\n import createSagaMiddleware from \'redux-saga\'\n ... other imports\n\n const sagaMiddleware = createSagaMiddleware()\n const store = createStore(reducer, applyMiddleware(sagaMiddleware))\n sagaMiddleware.run(saga, ...args)\n ');
1932 }
1933 }
1934
1935 if (logger && !is.func(logger)) {
1936 throw new Error('`options.logger` passed to the Saga middleware is not a function!');
1937 }
1938
1939 if ("development" === 'development' && options.onerror) {
1940 throw new Error('`options.onerror` was removed. Use `options.onError` instead.');
1941 }
1942
1943 if (onError && !is.func(onError)) {
1944 throw new Error('`options.onError` passed to the Saga middleware is not a function!');
1945 }
1946
1947 if (options.emitter && !is.func(options.emitter)) {
1948 throw new Error('`options.emitter` passed to the Saga middleware is not a function!');
1949 }
1950
1951 function sagaMiddleware(_ref2) {
1952 var getState = _ref2.getState,
1953 dispatch = _ref2.dispatch;
1954
1955 var sagaEmitter = emitter();
1956 sagaEmitter.emit = (options.emitter || ident)(sagaEmitter.emit);
1957
1958 sagaMiddleware.run = runSaga.bind(null, {
1959 context: context,
1960 subscribe: sagaEmitter.subscribe,
1961 dispatch: dispatch,
1962 getState: getState,
1963 sagaMonitor: sagaMonitor,
1964 logger: logger,
1965 onError: onError
1966 });
1967
1968 return function (next) {
1969 return function (action) {
1970 if (sagaMonitor && sagaMonitor.actionDispatched) {
1971 sagaMonitor.actionDispatched(action);
1972 }
1973 var result = next(action); // hit reducers
1974 sagaEmitter.emit(action);
1975 return result;
1976 };
1977 };
1978 }
1979
1980 sagaMiddleware.run = function () {
1981 throw new Error('Before running a Saga, you must mount the Saga middleware on the Store using applyMiddleware');
1982 };
1983
1984 sagaMiddleware.setContext = function (props) {
1985 check(props, is.object, createSetContextWarning('sagaMiddleware', props));
1986 object.assign(context, props);
1987 };
1988
1989 return sagaMiddleware;
1990}
1991
1992
1993
1994var effects = Object.freeze({
1995 take: take,
1996 takem: takem,
1997 put: put,
1998 all: all,
1999 race: race,
2000 call: call,
2001 apply: apply,
2002 cps: cps,
2003 fork: fork,
2004 spawn: spawn,
2005 join: join,
2006 cancel: cancel,
2007 select: select,
2008 actionChannel: actionChannel,
2009 cancelled: cancelled,
2010 flush: flush$1,
2011 getContext: getContext,
2012 setContext: setContext,
2013 takeEvery: takeEvery$$1,
2014 takeLatest: takeLatest$$1,
2015 throttle: throttle$$1
2016});
2017
2018
2019
2020var utils = Object.freeze({
2021 TASK: TASK,
2022 SAGA_ACTION: SAGA_ACTION,
2023 noop: noop,
2024 is: is,
2025 deferred: deferred,
2026 arrayOfDeffered: arrayOfDeffered,
2027 createMockTask: createMockTask,
2028 cloneableGenerator: cloneableGenerator,
2029 asEffect: asEffect,
2030 CHANNEL_END: CHANNEL_END
2031});
2032
2033exports['default'] = sagaMiddlewareFactory;
2034exports.effects = effects;
2035exports.utils = utils;
2036exports.runSaga = runSaga;
2037exports.END = END;
2038exports.eventChannel = eventChannel;
2039exports.channel = channel;
2040exports.buffers = buffers;
2041exports.takeEvery = takeEvery$1;
2042exports.takeLatest = takeLatest$1;
2043exports.throttle = throttle$1;
2044exports.delay = delay;
2045exports.CANCEL = CANCEL;
2046
2047Object.defineProperty(exports, '__esModule', { value: true });
2048
2049})));