import {
fork,
cancel,
take,
call,
put,
select,
race,
all,
takeEvery
} from "redux-saga/effects";
import {createAction} from 'redux-actions'
import {mergePlainObject, renamePlainObjectKey, mapKeys} from './util'
function mergerEffects(modelList) {
return modelList.map(({namespace, effects}) => ({[namespace]: renamePlainObjectKey(namespace, effects)})).reduce(mergePlainObject, {})
}
function getSagas(modelList) {
const effectsModuleMap = mergerEffects(modelList);
return function* () {
const globalTask = yield fork(function* () {
const effectModuleKeyList = mapKeys(effectsModuleMap);
for (let i = 0; i < effectModuleKeyList.length; i++) {
const effectModuleKey = effectModuleKeyList[i];
const effectSagaMap = effectsModuleMap[effectModuleKey];
const effectKeyList = mapKeys(effectSagaMap);
for (let j = 0; j < effectKeyList.length; j++) {
const effectSagaKey = effectKeyList[j];
const effectSaga = effectSagaMap[effectSagaKey];
const defaultArgs = {
call, put, select, race, all
}
const watcher = function* () {
function* f(...args) {
const action = args[1];
if (!action.autoStatus){
yield effectSaga(...args)
} else {
const [namespace, effectName] = effectSagaKey.split('/')
const Status = 'Status'
const currStatus = yield select(
state => state[namespace]["@@status"]
);
const startStatus = {
...currStatus,
[`${effectName}${Status}`]: true
};
const endStatus = {
...currStatus,
[`${effectName}${Status}`]: false
};
const onChangeStatus = createAction(`${namespace}/@@mergeState`, payload => payload)
yield put(onChangeStatus({["@@status"]: startStatus}))
yield effectSaga(...args)
yield put(onChangeStatus({["@@status"]: endStatus}))
}
}
yield takeEvery(effectSagaKey, f, defaultArgs)
}
yield fork(watcher)
}
}
})
const cancelAllFork = function* () {
yield take(`@@teeMoCore/cancel`)
yield cancel(globalTask)
}
yield fork(cancelAllFork)
}
}
export {
getSagas
} |