UNPKG

atom-nuclide

Version:

A unified developer experience for web and mobile development, built as a suite of features on top of Atom to provide hackability and the support of an active community.

386 lines (316 loc) 15.2 kB
Object.defineProperty(exports, '__esModule', { value: true }); /* * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. */ 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; }; exports.createPanelEpic = createPanelEpic; exports.destroyPanelEpic = destroyPanelEpic; exports.registerTaskRunnerEpic = registerTaskRunnerEpic; exports.runTaskEpic = runTaskEpic; exports.setProjectRootEpic = setProjectRootEpic; exports.setToolbarVisibilityEpic = setToolbarVisibilityEpic; exports.stopTaskEpic = stopTaskEpic; exports.toggleToolbarVisibilityEpic = toggleToolbarVisibilityEpic; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } var _commonsNodeTasks2; function _commonsNodeTasks() { return _commonsNodeTasks2 = require('../../../commons-node/tasks'); } var _commonsNodeEvent2; function _commonsNodeEvent() { return _commonsNodeEvent2 = require('../../../commons-node/event'); } var _nuclideUiLibBindObservableAsProps2; function _nuclideUiLibBindObservableAsProps() { return _nuclideUiLibBindObservableAsProps2 = require('../../../nuclide-ui/lib/bindObservableAsProps'); } var _uiToolbar2; function _uiToolbar() { return _uiToolbar2 = require('../ui/Toolbar'); } var _getActiveTaskRunner2; function _getActiveTaskRunner() { return _getActiveTaskRunner2 = require('../getActiveTaskRunner'); } var _getTaskMetadata2; function _getTaskMetadata() { return _getTaskMetadata2 = require('../getTaskMetadata'); } var _Actions2; function _Actions() { return _Actions2 = _interopRequireWildcard(require('./Actions')); } var _assert2; function _assert() { return _assert2 = _interopRequireDefault(require('assert')); } var _lodashMemoize2; function _lodashMemoize() { return _lodashMemoize2 = _interopRequireDefault(require('lodash.memoize')); } var _reactForAtom2; function _reactForAtom() { return _reactForAtom2 = require('react-for-atom'); } var _rxjsBundlesRxUmdMinJs2; function _rxjsBundlesRxUmdMinJs() { return _rxjsBundlesRxUmdMinJs2 = require('rxjs/bundles/Rx.umd.min.js'); } // We expect a store here because we want to subscribe to it. The one we get as an argument if we // return a function here doesn't have Symbol.observable. function createPanelEpic(actions) { return actions.ofType((_Actions2 || _Actions()).CREATE_PANEL).map(function (action) { (0, (_assert2 || _assert()).default)(action.type === (_Actions2 || _Actions()).CREATE_PANEL); // Ideally we would just use the store that's passed to the epic (and not have to include // it with the action), however that store doesn't have the full functionality (see // @reactjs/redux#1834) var store = action.payload.store; var staticProps = { runTask: function runTask(taskId) { store.dispatch((_Actions2 || _Actions()).runTask(taskId)); }, selectTask: function selectTask(taskId) { store.dispatch((_Actions2 || _Actions()).selectTask(taskId)); }, stopTask: function stopTask() { store.dispatch((_Actions2 || _Actions()).stopTask()); }, getActiveTaskRunnerIcon: function getActiveTaskRunnerIcon() { var activeTaskRunner = (0, (_getActiveTaskRunner2 || _getActiveTaskRunner()).getActiveTaskRunner)(store.getState()); return activeTaskRunner && activeTaskRunner.getIcon(); } }; // Delay the inital render. This way we (probably) won't wind up rendering the wrong task // runner before the correct one is registered. var props = (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.interval(300).first().switchMap(function () { return (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.from(store); }).map(function (state) { var activeTaskRunner = (0, (_getActiveTaskRunner2 || _getActiveTaskRunner()).getActiveTaskRunner)(state); return _extends({}, staticProps, { taskRunnerInfo: Array.from(state.taskRunners.values()), getExtraUi: getExtraUiFactory(activeTaskRunner), progress: state.taskStatus && state.taskStatus.progress, visible: state.visible, activeTaskId: state.activeTaskId, taskIsRunning: state.taskStatus != null, taskLists: state.taskLists }); }); var StatefulToolbar = (0, (_nuclideUiLibBindObservableAsProps2 || _nuclideUiLibBindObservableAsProps()).bindObservableAsProps)(props, (_uiToolbar2 || _uiToolbar()).Toolbar); var container = document.createElement('div'); // $FlowIssue: bindObservableAsProps doesn't handle props exactly right. (_reactForAtom2 || _reactForAtom()).ReactDOM.render((_reactForAtom2 || _reactForAtom()).React.createElement(StatefulToolbar, null), container); var panel = atom.workspace.addTopPanel({ item: container }); return { type: (_Actions2 || _Actions()).PANEL_CREATED, payload: { panel: panel } }; }); } function destroyPanelEpic(actions, store) { return actions.ofType((_Actions2 || _Actions()).DESTROY_PANEL).switchMap(function (action) { var _store$getState = store.getState(); var panel = _store$getState.panel; if (panel == null) { return (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.empty(); } var item = panel.getItem(); (_reactForAtom2 || _reactForAtom()).ReactDOM.unmountComponentAtNode(item); panel.destroy(); return (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.of({ type: (_Actions2 || _Actions()).PANEL_DESTROYED }); }); } function registerTaskRunnerEpic(actions, store) { return actions.ofType((_Actions2 || _Actions()).REGISTER_TASK_RUNNER).flatMap(function (action) { (0, (_assert2 || _assert()).default)(action.type === (_Actions2 || _Actions()).REGISTER_TASK_RUNNER); var taskRunner = action.payload.taskRunner; // Set the project root on the new task runner. var setProjectRoot = taskRunner.setProjectRoot; if (typeof setProjectRoot === 'function') { var projectRoot = store.getState().projectRoot; setProjectRoot.call(taskRunner, projectRoot); } var taskListToAction = function taskListToAction(taskList) { return { type: (_Actions2 || _Actions()).TASK_LIST_UPDATED, payload: { taskRunnerId: taskRunner.id, taskList: taskList } }; }; var unregistrationEvents = actions.filter(function (a) { return a.type === (_Actions2 || _Actions()).UNREGISTER_TASK_RUNNER && a.payload.id === taskRunner.id; }); return (0, (_commonsNodeEvent2 || _commonsNodeEvent()).observableFromSubscribeFunction)(taskRunner.observeTaskList.bind(taskRunner)).map(taskListToAction).takeUntil(unregistrationEvents); }); } function runTaskEpic(actions, store) { return actions.ofType((_Actions2 || _Actions()).RUN_TASK).switchMap(function (action) { (0, (_assert2 || _assert()).default)(action.type === (_Actions2 || _Actions()).RUN_TASK); var taskToRun = action.payload.taskId || store.getState().activeTaskId; // Don't do anything if there's no active task. if (taskToRun == null) { return (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.empty(); } // Don't do anything if a task is already running. if (store.getState().taskStatus != null) { return (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.empty(); } return (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.concat(taskIdsAreEqual(store.getState().activeTaskId, taskToRun) ? (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.empty() : (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.of((_Actions2 || _Actions()).selectTask(taskToRun)), (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.defer(function () { var state = store.getState(); var activeTaskRunner = (0, (_getActiveTaskRunner2 || _getActiveTaskRunner()).getActiveTaskRunner)(state); if (activeTaskRunner == null) { return (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.empty(); } var taskMeta = (0, (_getTaskMetadata2 || _getTaskMetadata()).getTaskMetadata)(taskToRun, state.taskLists); (0, (_assert2 || _assert()).default)(taskMeta != null); if (!taskMeta.enabled) { return (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.empty(); } return createTaskObservable(activeTaskRunner, taskMeta, function () { return store.getState(); }) // Stop listening once the task is done. .takeUntil(actions.ofType((_Actions2 || _Actions()).TASK_COMPLETED, (_Actions2 || _Actions()).TASK_ERRORED, (_Actions2 || _Actions()).TASK_STOPPED)); })); }); } function setProjectRootEpic(actions, store) { return actions.ofType((_Actions2 || _Actions()).SET_PROJECT_ROOT).do(function (action) { (0, (_assert2 || _assert()).default)(action.type === (_Actions2 || _Actions()).SET_PROJECT_ROOT); var projectRoot = action.payload.projectRoot; // Set the project root on all registered task runners. store.getState().taskRunners.forEach(function (taskRunner) { if (typeof taskRunner.setProjectRoot === 'function') { taskRunner.setProjectRoot(projectRoot); } }); }) // This is just for side-effects .ignoreElements(); } function setToolbarVisibilityEpic(actions, store) { return actions.ofType((_Actions2 || _Actions()).SET_TOOLBAR_VISIBILITY).map(function (action) { (0, (_assert2 || _assert()).default)(action.type === (_Actions2 || _Actions()).SET_TOOLBAR_VISIBILITY); var visible = action.payload.visible; return { type: (_Actions2 || _Actions()).TOOLBAR_VISIBILITY_UPDATED, payload: { visible: visible } }; }); } function stopTaskEpic(actions, store) { return actions.ofType((_Actions2 || _Actions()).STOP_TASK).switchMap(function (action) { var _store$getState2 = store.getState(); var taskStatus = _store$getState2.taskStatus; var task = taskStatus == null ? null : taskStatus.task; if (task == null) { return (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.empty(); } return (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.of({ type: (_Actions2 || _Actions()).TASK_STOPPED, payload: { task: task } }); }); } function toggleToolbarVisibilityEpic(actions, store) { return actions.ofType((_Actions2 || _Actions()).TOGGLE_TOOLBAR_VISIBILITY).switchMap(function (action) { (0, (_assert2 || _assert()).default)(action.type === (_Actions2 || _Actions()).TOGGLE_TOOLBAR_VISIBILITY); var state = store.getState(); var taskRunnerId = action.payload.taskRunnerId; // If no taskRunnerId is provided, just toggle the visibility. if (taskRunnerId == null) { return (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.of((_Actions2 || _Actions()).setToolbarVisibility(!state.visible)); } // If the active task corresponds to the task runner you want to toggle, just toggle the // visibility. var activeTaskId = state.activeTaskId; if (activeTaskId != null && activeTaskId.taskRunnerId === taskRunnerId) { return (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.of((_Actions2 || _Actions()).setToolbarVisibility(!state.visible)); } // Choose the first task for that task runner. var taskListForRunner = state.taskLists.get(taskRunnerId) || []; var taskIdToSelect = taskListForRunner.length > 0 ? taskListForRunner[0] : null; if (taskIdToSelect == null) { var taskRunner = state.taskRunners.get(taskRunnerId); (0, (_assert2 || _assert()).default)(taskRunner != null); atom.notifications.addWarning('The ' + taskRunner.name + ' task runner doesn\'t have any tasks!'); } return (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.concat( // Make sure the toolbar is shown. (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.of((_Actions2 || _Actions()).setToolbarVisibility(true)), // Select the task. taskIdToSelect == null ? (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.empty() : (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.of((_Actions2 || _Actions()).selectTask(taskIdToSelect))); }); } /** * Run a task and transform its output into domain-specific actions. */ function createTaskObservable(taskRunner, taskMeta, getState) { return (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.defer(function () { var task = taskRunner.runTask(taskMeta.type); var events = (0, (_commonsNodeTasks2 || _commonsNodeTasks()).observableFromTask)(task); return (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.of({ type: (_Actions2 || _Actions()).TASK_STARTED, payload: { task: task } }).concat(events.filter(function (event) { return event.type === 'progress'; }).map(function (event) { return { type: (_Actions2 || _Actions()).TASK_PROGRESS, payload: { progress: event.progress } }; })).concat((_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.of({ type: (_Actions2 || _Actions()).TASK_COMPLETED, payload: { task: task } })); }).catch(function (error) { atom.notifications.addError('The task "' + taskMeta.label + '" failed', { detail: error.stack, dismissable: true }); var _getState = getState(); var taskStatus = _getState.taskStatus; return (_rxjsBundlesRxUmdMinJs2 || _rxjsBundlesRxUmdMinJs()).Observable.of({ type: (_Actions2 || _Actions()).TASK_ERRORED, payload: { error: error, task: taskStatus == null ? null : taskStatus.task } }); }).share(); } function taskIdsAreEqual(a, b) { if (a == null || b == null) { return false; } return a.type === b.type && a.taskRunnerId === b.taskRunnerId; } /** * Since `getExtraUi` may create a React class dynamically, we want to ensure that we only ever call * it once. To do that, we memoize the function and cache the result. */ var extraUiFactories = new WeakMap(); function getExtraUiFactory(taskRunner) { var getExtraUi = extraUiFactories.get(taskRunner); if (getExtraUi != null) { return getExtraUi; } if (taskRunner == null) { return null; } if (taskRunner.getExtraUi == null) { return null; } getExtraUi = (0, (_lodashMemoize2 || _lodashMemoize()).default)(taskRunner.getExtraUi.bind(taskRunner)); extraUiFactories.set(taskRunner, getExtraUi); return getExtraUi; }