UNPKG

animiassumenda

Version:

Blox live, desktop app for managing staking accounts

90 lines (82 loc) 2.62 kB
import { eventChannel, END } from 'redux-saga'; import { call, put, take, takeLatest, select } from 'redux-saga/effects'; import * as actions from './actions'; import { getNetwork } from '../Wizard/selectors'; import { PROCESS_SUBSCRIBE } from './actionTypes'; import { Log } from '../../backend/common/logger/logger'; import { processInstantiator, Listener } from './service'; const logger = new Log('startProcess'); function* startProcess(action) { const { payload } = action; const { name, params } = payload; const network = params?.network ?? (yield select(getNetwork)); const processPayload = { ...payload, ...(params || {}), network }; delete processPayload.params; const process = processInstantiator(name, processPayload); const channel = yield call(createChannel, process); let isActive = false; let data; try { while (true) { const result = yield take(channel); const { payload: { isActive: isActiveFromStep, step, state, data: stepData, error }} = result; if (isActiveFromStep) { isActive = isActiveFromStep; } if (stepData) { data = stepData; } step?.name && logger.info(`${step?.num}/${step?.numOf} - ${step?.name}`); let message = step?.name; let currentStep = 0; let overallSteps = 0; if (state === 'fallback') { message = 'Process failed, Rolling back...'; } else { overallSteps = step?.numOf; currentStep = step?.num; } const observePayload = { overallSteps, currentStep, message, isActive: !error && isActive, data: !error && data }; yield put(actions.processObserve(observePayload)); } } catch (e) { console.error('Running process error:', e); yield put(actions.processFailure(e)); channel.close(); } finally { yield put(actions.processUnSubscribe()); channel.close(); } } function createChannel(process) { return eventChannel((emitter) => { const callback = (subject, payload) => { const { error, state } = payload; emitter({ subject, payload }); if (state === 'completed') { process.unsubscribe(listener); if (error) { emitter(error); } else { emitter(END); } } }; const listener = new Listener(callback); process.run(); process.subscribe(listener); const unsubscribeTo = () => { process.unsubscribe(listener); }; return unsubscribeTo; }); } export default function* processRunnerSaga() { yield takeLatest(PROCESS_SUBSCRIBE, startProcess); }