redux-devtools/packages/redux-devtools-core/src/app/middlewares/api.js

232 lines
5.9 KiB
JavaScript
Raw Normal View History

2019-01-03 17:14:25 +03:00
import socketCluster from 'socketcluster-client';
import { stringify } from 'jsan';
import socketOptions from '../constants/socketOptions';
import * as actions from '../constants/socketActionTypes';
import { getActiveInstance } from '../reducers/instances';
import {
2019-01-10 21:51:14 +03:00
UPDATE_STATE,
REMOVE_INSTANCE,
LIFTED_ACTION,
UPDATE_REPORTS,
GET_REPORT_REQUEST,
GET_REPORT_ERROR,
GET_REPORT_SUCCESS,
2019-01-03 17:14:25 +03:00
} from '../constants/actionTypes';
import { showNotification, importState } from '../actions';
import { nonReduxDispatch } from '../utils/monitorActions';
let socket;
let store;
function emit({ message: type, id, instanceId, action, state }) {
2019-01-10 21:51:14 +03:00
socket.emit(id ? 'sc-' + id : 'respond', { type, action, state, instanceId });
2019-01-03 17:14:25 +03:00
}
function startMonitoring(channel) {
if (channel !== store.getState().socket.baseChannel) return;
store.dispatch({ type: actions.EMIT, message: 'START' });
}
function dispatchRemoteAction({ message, action, state, toAll }) {
const instances = store.getState().instances;
const instanceId = getActiveInstance(instances);
const id = !toAll && instances.options[instanceId].connectionId;
store.dispatch({
type: actions.EMIT,
message,
action,
2019-01-10 21:51:14 +03:00
state: nonReduxDispatch(
store,
message,
instanceId,
action,
state,
instances
),
2019-01-03 17:14:25 +03:00
instanceId,
id,
2019-01-03 17:14:25 +03:00
});
}
function monitoring(request) {
if (request.type === 'DISCONNECTED') {
store.dispatch({
type: REMOVE_INSTANCE,
id: request.id,
2019-01-03 17:14:25 +03:00
});
return;
}
if (request.type === 'START') {
store.dispatch({ type: actions.EMIT, message: 'START', id: request.id });
return;
}
if (request.type === 'ERROR') {
store.dispatch(showNotification(request.payload));
return;
}
store.dispatch({
type: UPDATE_STATE,
request: request.data ? { ...request.data, id: request.id } : request,
2019-01-03 17:14:25 +03:00
});
const instances = store.getState().instances;
const instanceId = request.instanceId || request.id;
if (
2019-01-10 21:51:14 +03:00
instances.sync &&
instanceId === instances.selected &&
2019-01-03 17:14:25 +03:00
(request.type === 'ACTION' || request.type === 'STATE')
) {
socket.emit('respond', {
type: 'SYNC',
state: stringify(instances.states[instanceId]),
id: request.id,
instanceId,
2019-01-03 17:14:25 +03:00
});
}
}
function subscribe(channelName, subscription) {
const channel = socket.subscribe(channelName);
if (subscription === UPDATE_STATE) channel.watch(monitoring);
else {
const watcher = (request) => {
2019-01-03 17:14:25 +03:00
store.dispatch({ type: subscription, request });
};
channel.watch(watcher);
socket.on(channelName, watcher);
}
}
function handleConnection() {
socket.on('connect', (status) => {
2019-01-03 17:14:25 +03:00
store.dispatch({
type: actions.CONNECT_SUCCESS,
payload: {
id: status.id,
authState: socket.authState,
socketState: socket.state,
2019-01-03 17:14:25 +03:00
},
error: status.authError,
2019-01-03 17:14:25 +03:00
});
if (socket.authState !== actions.AUTHENTICATED) {
store.dispatch({ type: actions.AUTH_REQUEST });
}
});
socket.on('disconnect', (code) => {
2019-01-03 17:14:25 +03:00
store.dispatch({ type: actions.DISCONNECTED, code });
});
socket.on('subscribe', (channel) => {
2019-01-03 17:14:25 +03:00
store.dispatch({ type: actions.SUBSCRIBE_SUCCESS, channel });
});
socket.on('unsubscribe', (channel) => {
2019-01-03 17:14:25 +03:00
socket.unsubscribe(channel);
socket.unwatch(channel);
socket.off(channel);
store.dispatch({ type: actions.UNSUBSCRIBE, channel });
});
socket.on('subscribeFail', (error) => {
2019-01-10 21:51:14 +03:00
store.dispatch({
type: actions.SUBSCRIBE_ERROR,
error,
status: 'subscribeFail',
2019-01-10 21:51:14 +03:00
});
2019-01-03 17:14:25 +03:00
});
socket.on('dropOut', (error) => {
2019-01-03 17:14:25 +03:00
store.dispatch({ type: actions.SUBSCRIBE_ERROR, error, status: 'dropOut' });
});
socket.on('error', (error) => {
2019-01-03 17:14:25 +03:00
store.dispatch({ type: actions.CONNECT_ERROR, error });
});
}
function connect() {
if (process.env.NODE_ENV === 'test') return;
const connection = store.getState().connection;
try {
socket = socketCluster.connect(
connection.type === 'remotedev' ? socketOptions : connection.options
);
handleConnection(store);
} catch (error) {
store.dispatch({ type: actions.CONNECT_ERROR, error });
store.dispatch(showNotification(error.message || error));
}
}
function disconnect() {
socket.disconnect();
socket.off();
}
function login() {
socket.emit('login', {}, (error, baseChannel) => {
if (error) {
store.dispatch({ type: actions.AUTH_ERROR, error });
return;
}
store.dispatch({ type: actions.AUTH_SUCCESS, baseChannel });
store.dispatch({
type: actions.SUBSCRIBE_REQUEST,
channel: baseChannel,
subscription: UPDATE_STATE,
2019-01-03 17:14:25 +03:00
});
store.dispatch({
type: actions.SUBSCRIBE_REQUEST,
channel: 'report',
subscription: UPDATE_REPORTS,
2019-01-03 17:14:25 +03:00
});
});
}
function getReport(reportId) {
socket.emit('getReport', reportId, (error, data) => {
if (error) {
store.dispatch({ type: GET_REPORT_ERROR, error });
return;
}
store.dispatch({ type: GET_REPORT_SUCCESS, data });
store.dispatch(importState(data.payload));
});
}
export default function api(inStore) {
store = inStore;
return (next) => (action) => {
2019-01-03 17:14:25 +03:00
const result = next(action);
2019-01-10 21:51:14 +03:00
switch (
action.type // eslint-disable-line default-case
) {
case actions.CONNECT_REQUEST:
connect();
break;
2019-01-03 17:14:25 +03:00
case actions.RECONNECT:
disconnect();
if (action.options.type !== 'disabled') connect();
break;
2019-01-10 21:51:14 +03:00
case actions.AUTH_REQUEST:
login();
break;
case actions.SUBSCRIBE_REQUEST:
subscribe(action.channel, action.subscription);
break;
case actions.SUBSCRIBE_SUCCESS:
startMonitoring(action.channel);
break;
case actions.EMIT:
if (socket) emit(action);
break;
case LIFTED_ACTION:
dispatchRemoteAction(action);
break;
case GET_REPORT_REQUEST:
getReport(action.report);
break;
2019-01-03 17:14:25 +03:00
}
return result;
};
}