diff options
Diffstat (limited to 'web/src/js/ducks/msgQueue.js')
-rw-r--r-- | web/src/js/ducks/msgQueue.js | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/web/src/js/ducks/msgQueue.js b/web/src/js/ducks/msgQueue.js new file mode 100644 index 00000000..6d82f4c2 --- /dev/null +++ b/web/src/js/ducks/msgQueue.js @@ -0,0 +1,113 @@ +import { fetchApi } from '../utils' +import * as websocketActions from './websocket' +import * as eventLogActions from './eventLog' +import * as flowsActions from './flows' +import * as settingsActions from './settings' + +export const INIT = 'MSG_QUEUE_INIT' +export const ENQUEUE = 'MSG_QUEUE_ENQUEUE' +export const CLEAR = 'MSG_QUEUE_CLEAR' +export const FETCH_ERROR = 'MSG_QUEUE_FETCH_ERROR' + +const handlers = { + [eventLogActions.MSG_TYPE] : eventLogActions, + [flowsActions.MSG_TYPE] : flowsActions, + [settingsActions.MSG_TYPE] : settingsActions, +} + +const defaultState = {} + +export default function reduce(state = defaultState, action) { + switch (action.type) { + + case INIT: + return { + ...state, + [action.queue]: [], + } + + case ENQUEUE: + return { + ...state, + [action.queue]: [...state[action.queue], action.msg], + } + + case CLEAR: + return { + ...state, + [action.queue]: null, + } + + default: + return state + } +} + +/** + * @public websocket + */ +export function handleWsMsg(msg) { + return (dispatch, getState) => { + const handler = handlers[msg.type] + if (msg.cmd === websocketActions.CMD_RESET) { + return dispatch(fetchData(handler.MSG_TYPE)) + } + if (getState().msgQueue[handler.MSG_TYPE]) { + return dispatch({ type: ENQUEUE, queue: handler.MSG_TYPE, msg }) + } + return dispatch(handler.handleWsMsg(msg)) + } +} + +/** + * @public + */ +export function fetchData(type) { + return dispatch => { + const handler = handlers[type] + + dispatch(init(handler.MSG_TYPE)) + + fetchApi(handler.DATA_URL) + .then(res => res.json()) + .then(json => dispatch(receive(type, json))) + .catch(error => dispatch(fetchError(type, error))) + } +} + +/** + * @private + */ +export function receive(type, res) { + return (dispatch, getState) => { + const handler = handlers[type] + const queue = getState().msgQueue[handler.MSG_TYPE] || [] + + dispatch(clear(handler.MSG_TYPE)) + dispatch(handler.receiveData(res.data)) + for (const msg of queue) { + dispatch(handler.handleWsMsg(msg)) + } + } +} + +/** + * @private + */ +export function init(queue) { + return { type: INIT, queue } +} + +/** + * @private + */ +export function clear(queue) { + return { type: CLEAR, queue } +} + +/** + * @private + */ +export function fetchError(type, error) { + return { type: FETCH_ERROR, type, error } +} |