1 | 'use strict';
|
2 |
|
3 | exports.__esModule = true;
|
4 |
|
5 | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
6 |
|
7 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
8 |
|
9 | exports.default = devToolsEnhancer;
|
10 | exports.preEnhancer = preEnhancer;
|
11 | exports.composeWithDevTools = composeWithDevTools;
|
12 |
|
13 | var _jsan = require('jsan');
|
14 |
|
15 | var _socketclusterClient = require('socketcluster-client');
|
16 |
|
17 | var _socketclusterClient2 = _interopRequireDefault(_socketclusterClient);
|
18 |
|
19 | var _configureStore = require('./configureStore');
|
20 |
|
21 | var _configureStore2 = _interopRequireDefault(_configureStore);
|
22 |
|
23 | var _constants = require('./constants');
|
24 |
|
25 | var _rnHostDetect = require('rn-host-detect');
|
26 |
|
27 | var _rnHostDetect2 = _interopRequireDefault(_rnHostDetect);
|
28 |
|
29 | var _remotedevUtils = require('remotedev-utils');
|
30 |
|
31 | var _catchErrors = require('remotedev-utils/lib/catchErrors');
|
32 |
|
33 | var _catchErrors2 = _interopRequireDefault(_catchErrors);
|
34 |
|
35 | var _filters = require('remotedev-utils/lib/filters');
|
36 |
|
37 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
38 |
|
39 | var instanceId = void 0;
|
40 | var instanceName = void 0;
|
41 | var suppressConnectErrors = void 0;
|
42 | var errorCounts = {};
|
43 | var socketOptions = void 0;
|
44 | var socket = void 0;
|
45 | var channel = void 0;
|
46 | var store = {};
|
47 | var lastAction = void 0;
|
48 | var filters = void 0;
|
49 | var isExcess = void 0;
|
50 | var isMonitored = void 0;
|
51 | var started = void 0;
|
52 | var startOn = void 0;
|
53 | var stopOn = void 0;
|
54 | var sendOn = void 0;
|
55 | var sendOnError = void 0;
|
56 | var sendTo = void 0;
|
57 | var lastErrorMsg = void 0;
|
58 | var locked = void 0;
|
59 | var paused = void 0;
|
60 | var actionCreators = void 0;
|
61 | var stateSanitizer = void 0;
|
62 | var actionSanitizer = void 0;
|
63 |
|
64 | function getLiftedState() {
|
65 | return (0, _filters.filterStagedActions)(store.liftedStore.getState(), filters);
|
66 | }
|
67 |
|
68 | function send() {
|
69 | if (!instanceId) instanceId = socket && socket.id || Math.random().toString(36).substr(2);
|
70 | try {
|
71 | fetch(sendTo, {
|
72 | method: 'POST',
|
73 | headers: {
|
74 | 'content-type': 'application/json'
|
75 | },
|
76 | body: JSON.stringify({
|
77 | type: 'STATE',
|
78 | id: instanceId,
|
79 | name: instanceName,
|
80 | payload: (0, _jsan.stringify)(getLiftedState())
|
81 | })
|
82 | }).catch(function (err) {
|
83 | console.log(err);
|
84 | });
|
85 | } catch (err) {
|
86 | console.log(err);
|
87 | }
|
88 | }
|
89 |
|
90 | function relay(type, state, action, nextActionId) {
|
91 | var message = {
|
92 | type: type,
|
93 | id: socket.id,
|
94 | name: instanceName
|
95 | };
|
96 | if (state) {
|
97 | message.payload = type === 'ERROR' ? state : (0, _jsan.stringify)((0, _filters.filterState)(state, type, filters, stateSanitizer, actionSanitizer, nextActionId));
|
98 | }
|
99 | if (type === 'ACTION') {
|
100 | message.action = (0, _jsan.stringify)(!actionSanitizer ? action : actionSanitizer(action.action, nextActionId - 1));
|
101 | message.isExcess = isExcess;
|
102 | message.nextActionId = nextActionId;
|
103 | } else if (action) {
|
104 | message.action = action;
|
105 | }
|
106 | socket.emit(socket.id ? 'log' : 'log-noid', message);
|
107 | }
|
108 |
|
109 | function dispatchRemotely(action) {
|
110 | try {
|
111 | var result = (0, _remotedevUtils.evalAction)(action, actionCreators);
|
112 | store.dispatch(result);
|
113 | } catch (e) {
|
114 | relay('ERROR', e.message);
|
115 | }
|
116 | }
|
117 |
|
118 | function handleMessages(message) {
|
119 | if (message.type === 'IMPORT' || message.type === 'SYNC' && socket.id && message.id !== socket.id) {
|
120 | store.liftedStore.dispatch({
|
121 | type: 'IMPORT_STATE', nextLiftedState: (0, _jsan.parse)(message.state)
|
122 | });
|
123 | } else if (message.type === 'UPDATE') {
|
124 | relay('STATE', getLiftedState());
|
125 | } else if (message.type === 'START') {
|
126 | isMonitored = true;
|
127 | if (typeof actionCreators === 'function') actionCreators = actionCreators();
|
128 | relay('STATE', getLiftedState(), actionCreators);
|
129 | } else if (message.type === 'STOP' || message.type === 'DISCONNECTED') {
|
130 | isMonitored = false;
|
131 | relay('STOP');
|
132 | } else if (message.type === 'ACTION') {
|
133 | dispatchRemotely(message.action);
|
134 | } else if (message.type === 'DISPATCH') {
|
135 | store.liftedStore.dispatch(message.action);
|
136 | }
|
137 | }
|
138 |
|
139 | function async(fn) {
|
140 | setTimeout(fn, 0);
|
141 | }
|
142 |
|
143 | function sendError(errorAction) {
|
144 |
|
145 | if (errorAction.message && errorAction.message === lastErrorMsg) return;
|
146 | lastErrorMsg = errorAction.message;
|
147 |
|
148 | async(function () {
|
149 | store.dispatch(errorAction);
|
150 | if (!started) send();
|
151 | });
|
152 | }
|
153 |
|
154 | function str2array(str) {
|
155 | return typeof str === 'string' ? [str] : str && str.length;
|
156 | }
|
157 |
|
158 | function init(options) {
|
159 | instanceName = options.name;
|
160 |
|
161 | var _ref = options.filters || {},
|
162 | blacklist = _ref.blacklist,
|
163 | whitelist = _ref.whitelist;
|
164 |
|
165 | filters = (0, _filters.getLocalFilter)({
|
166 | actionsBlacklist: blacklist || options.actionsBlacklist,
|
167 | actionsWhitelist: whitelist || options.actionsWhitelist
|
168 | });
|
169 | if (options.port) {
|
170 | socketOptions = {
|
171 | port: options.port,
|
172 | hostname: options.hostname || 'localhost',
|
173 | secure: options.secure
|
174 | };
|
175 | } else socketOptions = _constants.defaultSocketOptions;
|
176 |
|
177 | suppressConnectErrors = options.suppressConnectErrors !== undefined ? options.suppressConnectErrors : true;
|
178 |
|
179 | startOn = str2array(options.startOn);
|
180 | stopOn = str2array(options.stopOn);
|
181 | sendOn = str2array(options.sendOn);
|
182 | sendOnError = options.sendOnError;
|
183 | if (sendOn || sendOnError) {
|
184 | sendTo = options.sendTo || (socketOptions.secure ? 'https' : 'http') + '://' + socketOptions.hostname + ':' + socketOptions.port;
|
185 | instanceId = options.id;
|
186 | }
|
187 | if (sendOnError === 1) (0, _catchErrors2.default)(sendError);
|
188 |
|
189 | if (options.actionCreators) actionCreators = function actionCreators() {
|
190 | return (0, _remotedevUtils.getActionsArray)(options.actionCreators);
|
191 | };
|
192 | stateSanitizer = options.stateSanitizer;
|
193 | actionSanitizer = options.actionSanitizer;
|
194 | }
|
195 |
|
196 | function login() {
|
197 | socket.emit('login', 'master', function (err, channelName) {
|
198 | if (err) {
|
199 | console.log(err);return;
|
200 | }
|
201 | channel = channelName;
|
202 | socket.subscribe(channelName).watch(handleMessages);
|
203 | socket.on(channelName, handleMessages);
|
204 | });
|
205 | started = true;
|
206 | relay('START');
|
207 | }
|
208 |
|
209 | function stop(keepConnected) {
|
210 | started = false;
|
211 | isMonitored = false;
|
212 | if (!socket) return;
|
213 | socket.destroyChannel(channel);
|
214 | if (keepConnected) {
|
215 | socket.off(channel, handleMessages);
|
216 | } else {
|
217 | socket.off();
|
218 | socket.disconnect();
|
219 | }
|
220 | }
|
221 |
|
222 | function start() {
|
223 | if (started || socket && socket.getState() === socket.CONNECTING) return;
|
224 |
|
225 | socket = _socketclusterClient2.default.connect(socketOptions);
|
226 |
|
227 | socket.on('error', function (err) {
|
228 |
|
229 | errorCounts[err.name] = errorCounts.hasOwnProperty(err.name) ? errorCounts[err.name] + 1 : 1;
|
230 |
|
231 | if (suppressConnectErrors) {
|
232 | if (errorCounts[err.name] === 1) {
|
233 | console.log('remote-redux-devtools: Socket connection errors are being suppressed. ' + '\n' + 'This can be disabled by setting suppressConnectErrors to \'false\'.');
|
234 | console.log(err);
|
235 | }
|
236 | } else {
|
237 | console.log(err);
|
238 | }
|
239 | });
|
240 | socket.on('connect', function () {
|
241 | console.log('connected to remotedev-server');
|
242 | errorCounts = {};
|
243 | login();
|
244 | });
|
245 | socket.on('disconnect', function () {
|
246 | stop(true);
|
247 | });
|
248 | }
|
249 |
|
250 | function checkForReducerErrors() {
|
251 | var liftedState = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : store.liftedStore.getState();
|
252 |
|
253 | if (liftedState.computedStates[liftedState.currentStateIndex].error) {
|
254 | if (started) relay('STATE', (0, _filters.filterStagedActions)(liftedState, filters));else send();
|
255 | return true;
|
256 | }
|
257 | return false;
|
258 | }
|
259 |
|
260 | function monitorReducer() {
|
261 | var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
262 | var action = arguments[1];
|
263 |
|
264 | lastAction = action.type;
|
265 | if (!started && sendOnError === 2 && store.liftedStore) async(checkForReducerErrors);else if (action.action) {
|
266 | if (startOn && !started && startOn.indexOf(action.action.type) !== -1) async(start);else if (stopOn && started && stopOn.indexOf(action.action.type) !== -1) async(stop);else if (sendOn && !started && sendOn.indexOf(action.action.type) !== -1) async(send);
|
267 | }
|
268 | return state;
|
269 | }
|
270 |
|
271 | function handleChange(state, liftedState, maxAge) {
|
272 | if (checkForReducerErrors(liftedState)) return;
|
273 |
|
274 | if (lastAction === 'PERFORM_ACTION') {
|
275 | var nextActionId = liftedState.nextActionId;
|
276 | var liftedAction = liftedState.actionsById[nextActionId - 1];
|
277 | if ((0, _filters.isFiltered)(liftedAction.action, filters)) return;
|
278 | relay('ACTION', state, liftedAction, nextActionId);
|
279 | if (!isExcess && maxAge) isExcess = liftedState.stagedActionIds.length >= maxAge;
|
280 | } else {
|
281 | if (lastAction === 'JUMP_TO_STATE') return;
|
282 | if (lastAction === 'PAUSE_RECORDING') {
|
283 | paused = liftedState.isPaused;
|
284 | } else if (lastAction === 'LOCK_CHANGES') {
|
285 | locked = liftedState.isLocked;
|
286 | }
|
287 | if (paused || locked) {
|
288 | if (lastAction) lastAction = undefined;else return;
|
289 | }
|
290 | relay('STATE', (0, _filters.filterStagedActions)(liftedState, filters));
|
291 | }
|
292 | }
|
293 |
|
294 | function devToolsEnhancer() {
|
295 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
296 |
|
297 | init(_extends({}, options, {
|
298 | hostname: (0, _rnHostDetect2.default)(options.hostname || 'localhost')
|
299 | }));
|
300 | var realtime = typeof options.realtime === 'undefined' ? process.env.NODE_ENV === 'development' : options.realtime;
|
301 | if (!realtime && !(startOn || sendOn || sendOnError)) return function (f) {
|
302 | return f;
|
303 | };
|
304 |
|
305 | var maxAge = options.maxAge || 30;
|
306 | return function (next) {
|
307 | return function (reducer, initialState) {
|
308 | store = (0, _configureStore2.default)(next, monitorReducer, {
|
309 | maxAge: maxAge,
|
310 | shouldCatchErrors: !!sendOnError,
|
311 | shouldHotReload: options.shouldHotReload,
|
312 | shouldRecordChanges: options.shouldRecordChanges,
|
313 | shouldStartLocked: options.shouldStartLocked,
|
314 | pauseActionType: options.pauseActionType || '@@PAUSED'
|
315 | })(reducer, initialState);
|
316 |
|
317 | if (realtime) start();
|
318 | store.subscribe(function () {
|
319 | if (isMonitored) handleChange(store.getState(), store.liftedStore.getState(), maxAge);
|
320 | });
|
321 | return store;
|
322 | };
|
323 | };
|
324 | }
|
325 |
|
326 | function preEnhancer(createStore) {
|
327 | return function (reducer, preloadedState, enhancer) {
|
328 | store = createStore(reducer, preloadedState, enhancer);
|
329 | return _extends({}, store, {
|
330 | dispatch: function dispatch(action) {
|
331 | return locked ? action : store.dispatch(action);
|
332 | }
|
333 | });
|
334 | };
|
335 | }
|
336 |
|
337 | devToolsEnhancer.updateStore = function (newStore) {
|
338 | console.warn('devTools.updateStore is deprecated use composeWithDevTools instead: ' + 'https://github.com/zalmoxisus/remote-redux-devtools#use-devtools-compose-helper');
|
339 | store = newStore;
|
340 | };
|
341 |
|
342 | var compose = function compose(options) {
|
343 | return function () {
|
344 | for (var _len = arguments.length, funcs = Array(_len), _key = 0; _key < _len; _key++) {
|
345 | funcs[_key] = arguments[_key];
|
346 | }
|
347 |
|
348 | return function () {
|
349 | return [preEnhancer].concat(funcs).reduceRight(function (composed, f) {
|
350 | return f(composed);
|
351 | }, devToolsEnhancer(options).apply(undefined, arguments));
|
352 | };
|
353 | };
|
354 | };
|
355 |
|
356 | function composeWithDevTools() {
|
357 | if (arguments.length === 0) {
|
358 | return devToolsEnhancer();
|
359 | }
|
360 | if (arguments.length === 1 && _typeof(arguments.length <= 0 ? undefined : arguments[0]) === 'object') {
|
361 | return compose(arguments.length <= 0 ? undefined : arguments[0]);
|
362 | }
|
363 | return compose({}).apply(undefined, arguments);
|
364 | } |
\ | No newline at end of file |