redux-saga-tools
Version:
A set of utility functions to write saga and reducers easily
101 lines (100 loc) • 4.12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const redux_saga_1 = require("redux-saga");
const effects_1 = require("redux-saga/effects");
const progress_action_1 = require("./progress-action");
function* genericActionSaga(actionType, sagaConfig, action) {
try {
yield effects_1.put(progress_action_1.ProgressActions.startAction(actionType));
const state = yield effects_1.select();
if (sagaConfig.processor == undefined) {
throw new Error(`Saga failed: no processor function found for ${actionType}`);
}
const response = yield effects_1.call(sagaConfig.processor, action.payload || {}, state);
if (sagaConfig.successActionType != undefined) {
yield effects_1.put({ type: sagaConfig.successActionType, payload: response });
}
yield effects_1.put(progress_action_1.ProgressActions.endAction(actionType));
}
catch (e) {
if (sagaConfig.failureActionType != undefined) {
yield effects_1.put({ error: e.message, type: sagaConfig.failureActionType });
}
yield effects_1.put(progress_action_1.ProgressActions.failAction(actionType, e.message));
}
}
function createSaga(actionType, processor, successActionType, failureActionType) {
return effects_1.takeLatest(actionType, genericActionSaga, actionType, {
processor,
successActionType: successActionType || `${actionType}_SUCCESS`,
failureActionType: failureActionType || `${actionType}_ERROR`,
});
}
exports.createSaga = createSaga;
function createSagaForEvery(actionType, processor, successActionType, failureActionType) {
return effects_1.takeEvery(actionType, genericActionSaga, actionType, {
processor,
successActionType: successActionType || `${actionType}_SUCCESS`,
failureActionType: failureActionType || `${actionType}_ERROR`,
});
}
exports.createSagaForEvery = createSagaForEvery;
function* createSagaStream(callback, saga, action) {
let channel;
const actionType = (typeof saga === 'string') ? saga : undefined;
try {
if (actionType != undefined) {
yield effects_1.put(progress_action_1.ProgressActions.startAction(actionType));
}
channel = redux_saga_1.eventChannel(emit => callback(emit, (action ? action.payload : undefined) || {}));
while (true) {
const update = yield effects_1.take(channel);
if (typeof saga === 'string') {
try {
yield effects_1.put({ type: saga, payload: update });
}
catch (e) {
if (actionType != undefined) {
yield effects_1.put(progress_action_1.ProgressActions.failAction(actionType, e.message));
}
}
if (actionType != undefined) {
yield effects_1.put(progress_action_1.ProgressActions.endAction(actionType));
}
}
else {
yield effects_1.call(saga, update);
}
}
}
catch (e) {
if (actionType != undefined) {
yield effects_1.put(progress_action_1.ProgressActions.failAction(actionType, e.message));
}
channel && channel.close();
console.error(e);
}
finally {
if (yield effects_1.cancelled()) {
channel && channel.close();
}
}
}
exports.createSagaStream = createSagaStream;
function* createSagaChannel(actionType, callback, saga) {
let task;
while (true) {
const action = yield effects_1.take(actionType);
const stopAction = actionType instanceof Array && actionType[1] === (action && action.type);
if (!stopAction) {
if (task) {
yield effects_1.cancel(task);
}
task = yield effects_1.fork(createSagaStream, callback, saga, action);
}
else if (task != undefined) {
yield effects_1.cancel(task);
}
}
}
exports.createSagaChannel = createSagaChannel;