ucsc-xena-client
Version:
UCSC Xena Client. Functional genomics visualizations.
106 lines (86 loc) • 4.06 kB
JavaScript
;
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }
var Rx = require('./rx');
var _ = require('./underscore_ext');
var _require = require('./errors'),
getErrorProps = _require.getErrorProps,
logError = _require.logError;
var _require2 = require('./notifications'),
getNotifications = _require2.getNotifications;
var _require3 = require('./defaultServers'),
defaultServers = _require3.defaultServers;
var enabledServer = { user: true };
var defaultServerState = _.object(defaultServers, defaultServers.map(function () {
return enabledServer;
}));
module.exports = function () {
// Create a channel for messages from the server. We want to avoid out-of-order
// responses. To do that, we have to allocate somewhere. We can manage it by
// doing using a unique tag for the type of request, and using groupBy, then
// switchLatest. groupBy is leaky, groups last forever.
var serverBus = new Rx.Subject();
// Allow a slot to be an array, in which case the groupBy key is
// the joined strings of the array, and the issued action is the
// 1st value of the array. maps ['widget-data', id] to slot
// widget-data-{id}, and issues action 'widge-data'.
var slotId = function slotId(slot) {
return _.isArray(slot) ? slot.join('-') : slot;
};
var actionId = function actionId(slot) {
return _.isArray(slot) ? slot : [slot];
};
var errorId = function errorId(slot) {
var _actionId = actionId(slot),
_actionId2 = _toArray(_actionId),
action = _actionId2[0],
args = _actionId2.slice(1);
return [action + '-error'].concat(_toConsumableArray(args));
};
function wrapSlotRequest(_ref) {
var _ref2 = _toArray(_ref),
slot = _ref2[0],
req = _ref2[1],
args = _ref2.slice(2);
return req.map(function (result) {
return [].concat(_toConsumableArray(actionId(slot)), [result], _toConsumableArray(args));
}).catch(function (err) {
return Rx.Observable.of([].concat(_toConsumableArray(errorId(slot)), [getErrorProps(logError(err))], _toConsumableArray(args)), Rx.Scheduler.asap);
});
}
// XXX Note that serverCh.onNext can push stuff that causes us to throw in
// wrapSlotRequest, etc. There's no handler. Where should we catch such
// errors & how to handle them?
// Subject of [slot, obs]. We group by slot and apply switchLatest.
var serverCh = serverBus.groupBy(function (_ref3) {
var _ref4 = _slicedToArray(_ref3, 1),
slot = _ref4[0];
return slotId(slot);
}).map(function (g) {
return g.switchMap(wrapSlotRequest);
}).mergeAll();
var uiBus = new Rx.Subject();
var uiCh = uiBus;
var initialState = {
version: 1,
spreadsheet: {
columnOrder: [],
columns: {},
mode: 'heatmap',
notifications: getNotifications(),
servers: defaultServerState,
showWelcome: true,
wizardMode: true,
zoom: { height: 460 // 460px forces visualizations to match min height of variable select card, required to maintain consistent heights across cohort/disease and variable select during wizard mode
} },
wizard: {}
};
return {
uiCh: uiCh,
uiBus: uiBus,
serverCh: serverCh,
serverBus: serverBus,
initialState: initialState
};
};