1 | 'use strict';
|
2 |
|
3 | exports.__esModule = true;
|
4 | exports.UNDEFINED_INPUT_ERROR = exports.INVALID_BUFFER = exports.isEnd = exports.END = undefined;
|
5 |
|
6 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
7 |
|
8 | exports.emitter = emitter;
|
9 | exports.channel = channel;
|
10 | exports.eventChannel = eventChannel;
|
11 | exports.stdChannel = stdChannel;
|
12 |
|
13 | var _utils = require('./utils');
|
14 |
|
15 | var _buffers = require('./buffers');
|
16 |
|
17 | var _scheduler = require('./scheduler');
|
18 |
|
19 | var CHANNEL_END_TYPE = '@@redux-saga/CHANNEL_END';
|
20 | var END = exports.END = { type: CHANNEL_END_TYPE };
|
21 | var isEnd = exports.isEnd = function isEnd(a) {
|
22 | return a && a.type === CHANNEL_END_TYPE;
|
23 | };
|
24 |
|
25 | function emitter() {
|
26 | var subscribers = [];
|
27 |
|
28 | function subscribe(sub) {
|
29 | subscribers.push(sub);
|
30 | return function () {
|
31 | return (0, _utils.remove)(subscribers, sub);
|
32 | };
|
33 | }
|
34 |
|
35 | function emit(item) {
|
36 | var arr = subscribers.slice();
|
37 | for (var i = 0, len = arr.length; i < len; i++) {
|
38 | arr[i](item);
|
39 | }
|
40 | }
|
41 |
|
42 | return {
|
43 | subscribe: subscribe,
|
44 | emit: emit
|
45 | };
|
46 | }
|
47 |
|
48 | var INVALID_BUFFER = exports.INVALID_BUFFER = 'invalid buffer passed to channel factory function';
|
49 | var UNDEFINED_INPUT_ERROR = exports.UNDEFINED_INPUT_ERROR = 'Saga was provided with an undefined action';
|
50 |
|
51 | if (process.env.NODE_ENV !== 'production') {
|
52 | exports.UNDEFINED_INPUT_ERROR = 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 ';
|
53 | }
|
54 |
|
55 | function channel() {
|
56 | var buffer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _buffers.buffers.fixed();
|
57 |
|
58 | var closed = false;
|
59 | var takers = [];
|
60 |
|
61 | (0, _utils.check)(buffer, _utils.is.buffer, INVALID_BUFFER);
|
62 |
|
63 | function checkForbiddenStates() {
|
64 | if (closed && takers.length) {
|
65 | throw (0, _utils.internalErr)('Cannot have a closed channel with pending takers');
|
66 | }
|
67 | if (takers.length && !buffer.isEmpty()) {
|
68 | throw (0, _utils.internalErr)('Cannot have pending takers with non empty buffer');
|
69 | }
|
70 | }
|
71 |
|
72 | function put(input) {
|
73 | checkForbiddenStates();
|
74 | (0, _utils.check)(input, _utils.is.notUndef, UNDEFINED_INPUT_ERROR);
|
75 | if (closed) {
|
76 | return;
|
77 | }
|
78 | if (!takers.length) {
|
79 | return buffer.put(input);
|
80 | }
|
81 | for (var i = 0; i < takers.length; i++) {
|
82 | var cb = takers[i];
|
83 | if (!cb[_utils.MATCH] || cb[_utils.MATCH](input)) {
|
84 | takers.splice(i, 1);
|
85 | return cb(input);
|
86 | }
|
87 | }
|
88 | }
|
89 |
|
90 | function take(cb) {
|
91 | checkForbiddenStates();
|
92 | (0, _utils.check)(cb, _utils.is.func, "channel.take's callback must be a function");
|
93 |
|
94 | if (closed && buffer.isEmpty()) {
|
95 | cb(END);
|
96 | } else if (!buffer.isEmpty()) {
|
97 | cb(buffer.take());
|
98 | } else {
|
99 | takers.push(cb);
|
100 | cb.cancel = function () {
|
101 | return (0, _utils.remove)(takers, cb);
|
102 | };
|
103 | }
|
104 | }
|
105 |
|
106 | function flush(cb) {
|
107 | checkForbiddenStates();
|
108 | (0, _utils.check)(cb, _utils.is.func, "channel.flush' callback must be a function");
|
109 | if (closed && buffer.isEmpty()) {
|
110 | cb(END);
|
111 | return;
|
112 | }
|
113 | cb(buffer.flush());
|
114 | }
|
115 |
|
116 | function close() {
|
117 | checkForbiddenStates();
|
118 | if (!closed) {
|
119 | closed = true;
|
120 | if (takers.length) {
|
121 | var arr = takers;
|
122 | takers = [];
|
123 | for (var i = 0, len = arr.length; i < len; i++) {
|
124 | arr[i](END);
|
125 | }
|
126 | }
|
127 | }
|
128 | }
|
129 |
|
130 | return {
|
131 | take: take,
|
132 | put: put,
|
133 | flush: flush,
|
134 | close: close,
|
135 | get __takers__() {
|
136 | return takers;
|
137 | },
|
138 | get __closed__() {
|
139 | return closed;
|
140 | }
|
141 | };
|
142 | }
|
143 |
|
144 | function eventChannel(subscribe) {
|
145 | var buffer = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _buffers.buffers.none();
|
146 | var matcher = arguments[2];
|
147 |
|
148 | |
149 |
|
150 |
|
151 |
|
152 | if (arguments.length > 2) {
|
153 | (0, _utils.check)(matcher, _utils.is.func, 'Invalid match function passed to eventChannel');
|
154 | }
|
155 |
|
156 | var chan = channel(buffer);
|
157 | var close = function close() {
|
158 | if (!chan.__closed__) {
|
159 | if (unsubscribe) {
|
160 | unsubscribe();
|
161 | }
|
162 | chan.close();
|
163 | }
|
164 | };
|
165 | var unsubscribe = subscribe(function (input) {
|
166 | if (isEnd(input)) {
|
167 | close();
|
168 | return;
|
169 | }
|
170 | if (matcher && !matcher(input)) {
|
171 | return;
|
172 | }
|
173 | chan.put(input);
|
174 | });
|
175 | if (chan.__closed__) {
|
176 | unsubscribe();
|
177 | }
|
178 |
|
179 | if (!_utils.is.func(unsubscribe)) {
|
180 | throw new Error('in eventChannel: subscribe should return a function to unsubscribe');
|
181 | }
|
182 |
|
183 | return {
|
184 | take: chan.take,
|
185 | flush: chan.flush,
|
186 | close: close
|
187 | };
|
188 | }
|
189 |
|
190 | function stdChannel(subscribe) {
|
191 | var chan = eventChannel(function (cb) {
|
192 | return subscribe(function (input) {
|
193 | if (input[_utils.SAGA_ACTION]) {
|
194 | cb(input);
|
195 | return;
|
196 | }
|
197 | (0, _scheduler.asap)(function () {
|
198 | return cb(input);
|
199 | });
|
200 | });
|
201 | });
|
202 |
|
203 | return _extends({}, chan, {
|
204 | take: function take(cb, matcher) {
|
205 | if (arguments.length > 1) {
|
206 | (0, _utils.check)(matcher, _utils.is.func, "channel.take's matcher argument must be a function");
|
207 | cb[_utils.MATCH] = matcher;
|
208 | }
|
209 | chan.take(cb);
|
210 | }
|
211 | });
|
212 | } |
\ | No newline at end of file |