dash-renderer
Version:
render dash components in react
895 lines (889 loc) • 42.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.aggregateCallbacks = exports.addWatchedCallbacks = exports.addStoredCallbacks = exports.addRequestedCallbacks = exports.addPrioritizedCallbacks = exports.addExecutingCallbacks = exports.addExecutedCallbacks = exports.addCompletedCallbacks = exports.addBlockedCallbacks = void 0;
exports.executeCallback = executeCallback;
exports.removeWatchedCallbacks = exports.removeStoredCallbacks = exports.removeRequestedCallbacks = exports.removePrioritizedCallbacks = exports.removeExecutingCallbacks = exports.removeExecutedCallbacks = exports.removeBlockedCallbacks = void 0;
var _ramda = require("ramda");
var _constants = require("../constants/constants");
var _constants2 = require("./constants");
var _callbacks = require("../reducers/callbacks");
var _dependencies = require("./dependencies");
var _utils = require("./utils");
var _2 = require(".");
var _reduxActions = require("redux-actions");
var _actions = require("../actions");
var _index = require("./index");
var _patch = require("./patch");
var _paths = require("./paths");
var _requestDependencies = require("./requestDependencies");
var _libraries = require("../utils/libraries");
var _patternMatching = require("./patternMatching");
var _loading = require("./loading");
var _wrapping = require("../wrapper/wrapping");
function _regeneratorValues(e) { if (null != e) { var t = e["function" == typeof Symbol && Symbol.iterator || "@@iterator"], r = 0; if (t) return t.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) return { next: function next() { return e && r >= e.length && (e = void 0), { value: e && e[r++], done: !e }; } }; } throw new TypeError(typeof e + " is not iterable"); }
function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i.return) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
var addBlockedCallbacks = exports.addBlockedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.AddBlocked);
var addCompletedCallbacks = exports.addCompletedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackAggregateActionType.AddCompleted);
var addExecutedCallbacks = exports.addExecutedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.AddExecuted);
var addExecutingCallbacks = exports.addExecutingCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.AddExecuting);
var addPrioritizedCallbacks = exports.addPrioritizedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.AddPrioritized);
var addRequestedCallbacks = exports.addRequestedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.AddRequested);
var addStoredCallbacks = exports.addStoredCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.AddStored);
var addWatchedCallbacks = exports.addWatchedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.AddWatched);
var removeExecutedCallbacks = exports.removeExecutedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.RemoveExecuted);
var removeBlockedCallbacks = exports.removeBlockedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.RemoveBlocked);
var removeExecutingCallbacks = exports.removeExecutingCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.RemoveExecuting);
var removePrioritizedCallbacks = exports.removePrioritizedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.RemovePrioritized);
var removeRequestedCallbacks = exports.removeRequestedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.RemoveRequested);
var removeStoredCallbacks = exports.removeStoredCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.RemoveStored);
var removeWatchedCallbacks = exports.removeWatchedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.RemoveWatched);
var aggregateCallbacks = exports.aggregateCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackAggregateActionType.Aggregate);
var updateResourceUsage = (0, _reduxActions.createAction)('UPDATE_RESOURCE_USAGE');
var addCallbackJob = (0, _reduxActions.createAction)('ADD_CALLBACK_JOB');
var removeCallbackJob = (0, _reduxActions.createAction)('REMOVE_CALLBACK_JOB');
var setCallbackJobOutdated = (0, _reduxActions.createAction)('CALLBACK_JOB_OUTDATED');
function unwrapIfNotMulti(paths, idProps, spec, anyVals, depType) {
var msg = '';
if ((0, _dependencies.isMultiValued)(spec)) {
return [idProps, msg];
}
if (idProps.length !== 1) {
if (!idProps.length) {
if (spec.allow_optional) {
idProps = [_objectSpread(_objectSpread({}, spec), {}, {
value: null
})];
msg = '';
} else {
var isStr = typeof spec.id === 'string';
msg = 'A nonexistent object was used in an `' + depType + '` of a Dash callback. The id of this object is ' + (isStr ? '`' + spec.id + '`' : JSON.stringify(spec.id) + (anyVals ? ' with MATCH values ' + anyVals : '')) + ' and the property is `' + spec.property + (isStr ? '`. The string ids in the current layout are: [' + (0, _ramda.keys)(paths.strs).join(', ') + ']' : '`. The wildcard ids currently available are logged above.');
}
} else {
msg = 'Multiple objects were found for an `' + depType + '` of a callback that only takes one value. The id spec is ' + JSON.stringify(spec.id) + (anyVals ? ' with MATCH values ' + anyVals : '') + ' and the property is `' + spec.property + '`. The objects we found are: ' + JSON.stringify((0, _ramda.map)((0, _ramda.pick)(['id', 'property']), idProps));
}
}
return [idProps[0], msg];
}
function fillVals(paths, layout, cb, specs, depType) {
var allowAllMissing = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
var getter = depType === 'Input' ? cb.getInputs : cb.getState;
var errors = [];
var emptyMultiValues = 0;
var inputVals = getter(paths).map((inputList, i) => {
var _unwrapIfNotMulti = unwrapIfNotMulti(paths, inputList.map(_ref => {
var id = _ref.id,
property = _ref.property,
path_ = _ref.path;
return {
id,
property,
value: (0, _ramda.path)([...path_, 'props', property], layout)
};
}), specs[i], cb.anyVals, depType),
_unwrapIfNotMulti2 = _slicedToArray(_unwrapIfNotMulti, 2),
inputs = _unwrapIfNotMulti2[0],
inputError = _unwrapIfNotMulti2[1];
if ((0, _dependencies.isMultiValued)(specs[i]) && !inputs.length) {
emptyMultiValues++;
}
if (inputError) {
errors.push(inputError);
}
return inputs;
});
if (errors.length) {
if (allowAllMissing && errors.length + emptyMultiValues === inputVals.length) {
// We have at least one non-multivalued input, but all simple and
// multi-valued inputs are missing.
// (if all inputs are multivalued and all missing we still return
// them as normal, and fire the callback.)
return null;
}
// If we get here we have some missing and some present inputs.
// Or all missing in a context that doesn't allow this.
// That's a real problem, so throw the first message as an error.
refErr(errors, paths);
}
return inputVals;
}
function refErr(errors, paths) {
var err = errors[0];
if (err.indexOf('logged above') !== -1) {
// Wildcard reference errors mention a list of wildcard specs logged
// TODO: unwrapped list of wildcard ids?
// eslint-disable-next-line no-console
console.error(paths.objs);
}
throw new ReferenceError(err);
}
var getVals = input => Array.isArray(input) ? (0, _ramda.pluck)('value', input) : input.value;
var zipIfArray = (a, b) => {
if (Array.isArray(a)) {
// For client-side callbacks with multiple Outputs, only return a single dash_clientside.no_update
if (b === window.dash_clientside.no_update) {
return (0, _ramda.zip)(a, [b]);
}
return (0, _ramda.zip)(a, b);
}
return [[a, b]];
};
function cleanOutputProp(property) {
return property.split('@')[0];
}
function handleClientside(_x, _x2, _x3, _x4) {
return _handleClientside.apply(this, arguments);
}
function _handleClientside() {
_handleClientside = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(dispatch, clientside_function, config, payload) {
var dc, inputs, outputs, state, requestTime, inputDict, stateDict, result, status, _returnValue, namespace, function_name, args, returnValue, totalTime, resources, _t4;
return _regenerator().w(function (_context3) {
while (1) switch (_context3.p = _context3.n) {
case 0:
dc = window.dash_clientside = window.dash_clientside || {};
if (!dc.no_update) {
Object.defineProperty(dc, 'no_update', {
value: {
description: 'Return to prevent updating an Output.'
},
writable: false
});
Object.defineProperty(dc, 'PreventUpdate', {
value: {
description: 'Throw to prevent updating all Outputs.'
},
writable: false
});
}
inputs = payload.inputs, outputs = payload.outputs, state = payload.state;
requestTime = Date.now();
inputDict = inputsToDict(inputs);
stateDict = inputsToDict(state);
result = {};
status = _constants.STATUS.OK;
_context3.p = 1;
namespace = clientside_function.namespace, function_name = clientside_function.function_name;
args = inputs.map(getVals);
if (state) {
args = (0, _ramda.concat)(args, state.map(getVals));
}
// setup callback context
dc.callback_context = {};
dc.callback_context.triggered = payload.changedPropIds.map(prop_id => ({
prop_id: prop_id,
value: inputDict[prop_id]
}));
dc.callback_context.triggered_id = getTriggeredId(payload.changedPropIds);
dc.callback_context.inputs_list = inputs;
dc.callback_context.inputs = inputDict;
dc.callback_context.states_list = state;
dc.callback_context.states = stateDict;
dc.callback_context.outputs_list = outputs;
returnValue = dc[namespace][function_name](...args);
delete dc.callback_context;
if (!(typeof ((_returnValue = returnValue) === null || _returnValue === void 0 ? void 0 : _returnValue.then) === 'function')) {
_context3.n = 3;
break;
}
_context3.n = 2;
return returnValue;
case 2:
returnValue = _context3.v;
case 3:
if (outputs) {
zipIfArray(outputs, returnValue).forEach(_ref10 => {
var _ref11 = _slicedToArray(_ref10, 2),
outi = _ref11[0],
reti = _ref11[1];
zipIfArray(outi, reti).forEach(_ref12 => {
var _ref13 = _slicedToArray(_ref12, 2),
outij = _ref13[0],
retij = _ref13[1];
var id = outij.id,
property = outij.property;
var idStr = (0, _dependencies.stringifyId)(id);
var dataForId = result[idStr] = result[idStr] || {};
if (retij !== dc.no_update) {
dataForId[cleanOutputProp(property)] = retij;
}
});
});
}
_context3.n = 6;
break;
case 4:
_context3.p = 4;
_t4 = _context3.v;
if (!(_t4 === dc.PreventUpdate)) {
_context3.n = 5;
break;
}
status = _constants.STATUS.PREVENT_UPDATE;
_context3.n = 6;
break;
case 5:
status = _constants.STATUS.CLIENTSIDE_ERROR;
throw _t4;
case 6:
_context3.p = 6;
delete dc.callback_context;
// Setting server = client forces network = 0
totalTime = Date.now() - requestTime;
resources = {
__dash_server: totalTime,
__dash_client: totalTime,
__dash_upload: 0,
__dash_download: 0
};
if (config.ui) {
dispatch(updateResourceUsage({
id: payload.output,
usage: resources,
status,
result,
inputs,
state
}));
}
return _context3.f(6);
case 7:
return _context3.a(2, result);
}
}, _callee2, null, [[1, 4, 6, 7]]);
}));
return _handleClientside.apply(this, arguments);
}
function updateComponent(component_id, props, cb) {
return function (dispatch, getState) {
var _getState = getState(),
paths = _getState.paths,
config = _getState.config;
var componentPath = (0, _paths.getPath)(paths, component_id);
if (!componentPath) {
if (!config.suppress_callback_exceptions) {
(0, _2.dispatchError)(dispatch)('ID running component not found in layout', ['Component defined in running keyword not found in layout.', "Component id: \"".concat((0, _dependencies.stringifyId)(component_id), "\""), 'This ID was used in the callback(s) for Output(s):', "".concat(cb.output), 'You can suppress this exception by setting', '`suppress_callback_exceptions=True`.']);
}
// We need to stop further processing because functions further on
// can't operate on an 'undefined' object, and they will throw an
// error.
return;
}
dispatch((0, _index.updateProps)({
props,
itempath: componentPath,
renderType: 'callback'
}));
dispatch((0, _index.notifyObservers)({
id: component_id,
props
}));
};
}
/**
* Update a component props with `running`/`progress`/`set_props` calls.
*
* @param outputs Props to update.
* @param cb The originating callback info.
* @returns
*/
function sideUpdate(outputs, cb) {
return function (dispatch, getState) {
(0, _ramda.toPairs)(outputs).reduce((acc, _ref2, i) => {
var _ref3 = _slicedToArray(_ref2, 2),
id = _ref3[0],
value = _ref3[1];
var componentId = id,
propName,
replacedIds = [];
if (id.startsWith('{')) {
var _parsePMCId = (0, _patternMatching.parsePMCId)(id);
var _parsePMCId2 = _slicedToArray(_parsePMCId, 2);
componentId = _parsePMCId2[0];
propName = _parsePMCId2[1];
replacedIds = (0, _patternMatching.replacePMC)(componentId, cb, i, getState);
} else if (id.includes('.')) {
var _id$split = id.split('.');
var _id$split2 = _slicedToArray(_id$split, 2);
componentId = _id$split2[0];
propName = _id$split2[1];
}
var props = propName ? {
[propName]: value
} : value;
if (replacedIds.length === 0) {
acc.push([componentId, props]);
} else if (replacedIds.length === 1) {
acc.push([replacedIds[0], props]);
} else {
replacedIds.forEach(rep => {
acc.push([rep, props]);
});
}
return acc;
}, []).forEach(_ref4 => {
var _oldComponent;
var _ref5 = _slicedToArray(_ref4, 2),
id = _ref5[0],
idProps = _ref5[1];
var state = getState();
var componentPath = (0, _paths.getPath)(state.paths, id);
var oldComponent = {
props: {}
};
if (componentPath) {
oldComponent = (0, _wrapping.getComponentLayout)(componentPath, state);
}
var oldProps = ((_oldComponent = oldComponent) === null || _oldComponent === void 0 ? void 0 : _oldComponent.props) || {};
var patchedProps = (0, _patch.parsePatchProps)(idProps, oldProps);
dispatch(updateComponent(id, patchedProps, cb));
if (!componentPath) {
// Component doesn't exist, doesn't matter just allow the
// callback to continue.
return;
}
dispatch((0, _2.setPaths)((0, _paths.computePaths)(_objectSpread(_objectSpread({}, oldComponent), {}, {
props: _objectSpread(_objectSpread({}, oldComponent.props), patchedProps)
}), [...componentPath], state.paths, state.paths.events)));
});
};
}
function handleServerside(dispatch, hooks, config, payload, background, additionalArgs, getState, running) {
if (hooks.request_pre) {
hooks.request_pre(payload);
}
var requestTime = Date.now();
var body = JSON.stringify(payload);
var cacheKey;
var job;
var runningOff;
var progressDefault;
var moreArgs = additionalArgs;
if (running) {
dispatch(sideUpdate(running.running, payload));
runningOff = running.runningOff;
}
var fetchCallback = () => {
var headers = (0, _2.getCSRFHeader)();
var url = "".concat((0, _utils.urlBase)(config), "_dash-update-component");
var newBody = body;
var addArg = (name, value) => {
var delim = '?';
if (url.includes('?')) {
delim = '&';
}
url = "".concat(url).concat(delim).concat(name, "=").concat(value);
};
if (cacheKey || job) {
if (cacheKey) addArg('cacheKey', cacheKey);
if (job) addArg('job', job);
// clear inputs as background callback doesnt need inputs, just verify for context
var tmpBody = JSON.parse(newBody);
for (var i = 0; i < tmpBody.inputs.length; i++) {
tmpBody.inputs[i]['value'] = null;
}
for (var _i = 0; _i < ((tmpBody === null || tmpBody === void 0 ? void 0 : tmpBody.state) || []).length; _i++) {
tmpBody.state[_i]['value'] = null;
}
newBody = JSON.stringify(tmpBody);
}
if (moreArgs) {
moreArgs.forEach(_ref6 => {
var _ref7 = _slicedToArray(_ref6, 2),
key = _ref7[0],
value = _ref7[1];
return addArg(key, value);
});
moreArgs = moreArgs.filter(_ref8 => {
var _ref9 = _slicedToArray(_ref8, 3),
_ = _ref9[0],
__ = _ref9[1],
single = _ref9[2];
return !single;
});
}
return fetch(url, (0, _ramda.mergeDeepRight)(config.fetch, {
method: 'POST',
headers,
body: newBody
}));
};
return new Promise((resolve, reject) => {
var handleOutput = res => {
var status = res.status;
if (job) {
var callbackJob = getState().callbackJobs[job];
if (callbackJob !== null && callbackJob !== void 0 && callbackJob.outdated) {
dispatch(removeCallbackJob({
jobId: job
}));
return resolve({});
}
}
function recordProfile(result) {
if (config.ui) {
// Callback profiling - only relevant if we're showing the debug ui
var resources = {
__dash_server: 0,
__dash_client: Date.now() - requestTime,
__dash_upload: body.length,
__dash_download: Number(res.headers.get('Content-Length'))
};
var timingHeaders = res.headers.get('Server-Timing') || '';
timingHeaders.split(',').forEach(header => {
var name = header.split(';')[0];
var dur = header.match(/;dur=[0-9.]+/);
if (dur) {
resources[name] = Number(dur[0].slice(5));
}
});
dispatch(updateResourceUsage({
id: payload.output,
usage: resources,
status,
result,
inputs: payload.inputs,
state: payload.state
}));
}
}
var finishLine = data => {
var multi = data.multi,
response = data.response;
if (hooks.request_post) {
hooks.request_post(payload, response);
}
var result;
if (multi) {
result = response;
} else {
var output = payload.output;
var id = output.substr(0, output.lastIndexOf('.'));
result = {
[id]: response.props
};
}
recordProfile(result);
resolve(result);
};
var completeJob = () => {
if (job) {
dispatch(removeCallbackJob({
jobId: job
}));
}
if (runningOff) {
dispatch(sideUpdate(runningOff, payload));
}
if (progressDefault) {
dispatch(sideUpdate(progressDefault, payload));
}
};
if (status === _constants.STATUS.OK) {
res.json().then(data => {
if (!cacheKey && data.cacheKey) {
cacheKey = data.cacheKey;
}
if (!job && data.job) {
var jobInfo = {
jobId: data.job,
cacheKey: data.cacheKey,
cancelInputs: data.cancel,
progressDefault: data.progressDefault,
output: JSON.stringify(payload.outputs)
};
dispatch(addCallbackJob(jobInfo));
job = data.job;
}
if (data.sideUpdate) {
dispatch(sideUpdate(data.sideUpdate, payload));
}
if (data.progress) {
dispatch(sideUpdate(data.progress, payload));
}
if (!progressDefault && data.progressDefault) {
progressDefault = data.progressDefault;
}
if (!background || data.response !== undefined) {
if (data.dist) {
Promise.all(data.dist.map(_libraries.loadLibrary)).then(() => {
completeJob();
finishLine(data);
});
} else {
completeJob();
finishLine(data);
}
} else {
// Poll chain.
setTimeout(handle, background.interval !== undefined ? background.interval : 500);
}
});
} else if (status === _constants.STATUS.PREVENT_UPDATE) {
completeJob();
recordProfile({});
resolve({});
} else {
completeJob();
reject(res);
}
};
var handleError = () => {
if (config.ui) {
dispatch(updateResourceUsage({
id: payload.output,
status: _constants.STATUS.NO_RESPONSE,
result: {},
inputs: payload.inputs,
state: payload.state
}));
}
reject(new Error('Callback failed: the server did not respond.'));
};
var handle = () => {
fetchCallback().then(handleOutput, handleError);
};
handle();
});
}
function inputsToDict(inputs_list) {
// Ported directly from _utils.py, inputs_to_dict
// takes an array of inputs (some inputs may be an array)
// returns an Object (map):
// keys of the form `id.property` or `{"id": 0}.property`
// values contain the property value
if (!inputs_list) {
return {};
}
var inputs = {};
for (var i = 0; i < inputs_list.length; i++) {
if (Array.isArray(inputs_list[i])) {
var inputsi = inputs_list[i];
for (var ii = 0; ii < inputsi.length; ii++) {
var _inputsi$ii$value;
var id_str = "".concat((0, _dependencies.stringifyId)(inputsi[ii].id), ".").concat(inputsi[ii].property);
inputs[id_str] = (_inputsi$ii$value = inputsi[ii].value) !== null && _inputsi$ii$value !== void 0 ? _inputsi$ii$value : null;
}
} else {
var _inputs_list$i$value;
var _id_str = "".concat((0, _dependencies.stringifyId)(inputs_list[i].id), ".").concat(inputs_list[i].property);
inputs[_id_str] = (_inputs_list$i$value = inputs_list[i].value) !== null && _inputs_list$i$value !== void 0 ? _inputs_list$i$value : null;
}
}
return inputs;
}
function getTriggeredId(triggered) {
// for regular callbacks, takes the first triggered prop_id, e.g. "btn.n_clicks" and returns "btn"
// for pattern matching callback, e.g. '{"index":0, "type":"btn"}' and returns {index:0, type: "btn"}'
if (triggered && triggered.length) {
var trig = triggered[0];
var componentId;
if (trig.startsWith('{')) {
componentId = JSON.parse(trig.substring(0, trig.lastIndexOf('}') + 1));
} else {
componentId = trig.split('.')[0];
}
return componentId;
}
}
function executeCallback(cb, config, hooks, paths, layout, _ref0, dispatch, getState) {
var allOutputs = _ref0.allOutputs;
var _cb$callback = cb.callback,
output = _cb$callback.output,
inputs = _cb$callback.inputs,
state = _cb$callback.state,
clientside_function = _cb$callback.clientside_function,
background = _cb$callback.background,
dynamic_creator = _cb$callback.dynamic_creator;
try {
var inVals = fillVals(paths, layout, cb, inputs, 'Input', true);
/* Prevent callback if there's no inputs */
if (inVals === null) {
return _objectSpread(_objectSpread({}, cb), {}, {
executionPromise: null
});
}
var outputs = [];
var outputErrors = [];
allOutputs.forEach((out, i) => {
var _unwrapIfNotMulti3 = unwrapIfNotMulti(paths, (0, _ramda.map)((0, _ramda.pick)(['id', 'property']), out), cb.callback.outputs[i], cb.anyVals, 'Output'),
_unwrapIfNotMulti4 = _slicedToArray(_unwrapIfNotMulti3, 2),
outi = _unwrapIfNotMulti4[0],
erri = _unwrapIfNotMulti4[1];
outputs.push(outi);
if (erri) {
outputErrors.push(erri);
}
});
if (outputErrors.length) {
if ((0, _ramda.flatten)(inVals).length) {
refErr(outputErrors, paths);
}
// This case is all-empty multivalued wildcard inputs,
// which we would normally fire the callback for, except
// some outputs are missing. So instead we treat it like
// regular missing inputs and just silently prevent it.
return _objectSpread(_objectSpread({}, cb), {}, {
executionPromise: null
});
}
var __execute = /*#__PURE__*/function () {
var _ref1 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
var loadingOutputs, changedPropIds, parsedChangedPropsIds, payload, data, currentLayout, newConfig, newHeaders, lastError, additionalArgs, jsonOutput, _loop, _ret, retry, _t2, _t3;
return _regenerator().w(function (_context2) {
while (1) switch (_context2.p = _context2.n) {
case 0:
loadingOutputs = outputs.map(out => {
var _out$property;
return {
path: (0, _paths.getPath)(paths, out.id),
property: (_out$property = out.property) === null || _out$property === void 0 ? void 0 : _out$property.split('@')[0],
id: (0, _dependencies.stringifyId)(out.id)
};
});
dispatch((0, _loading.loading)(loadingOutputs));
_context2.p = 1;
changedPropIds = (0, _ramda.keys)(cb.changedPropIds);
parsedChangedPropsIds = changedPropIds.map(propId => {
if (propId.startsWith('{')) {
return (0, _patternMatching.parsePMCId)(propId)[0];
}
return propId;
});
payload = {
output,
outputs: (0, _dependencies.isMultiOutputProp)(output) ? outputs : outputs[0],
inputs: inVals,
changedPropIds,
parsedChangedPropsIds,
state: cb.callback.state.length ? fillVals(paths, layout, cb, state, 'State') : undefined
};
if (!clientside_function) {
_context2.n = 5;
break;
}
_context2.p = 2;
_context2.n = 3;
return handleClientside(dispatch, clientside_function, config, payload);
case 3:
data = _context2.v;
// Patch methodology: always run through parsePatchProps for each output
currentLayout = getState().layout;
(0, _ramda.flatten)(outputs).forEach(out => {
var propName = cleanOutputProp(out.property);
var outputPath = (0, _paths.getPath)(paths, out.id);
var dataPath = [(0, _dependencies.stringifyId)(out.id), propName];
var outputValue = (0, _ramda.path)(dataPath, data);
if (outputValue === undefined) {
return;
}
var oldProps = (0, _ramda.path)(outputPath.concat(['props']), currentLayout) || {};
var newProps = (0, _patch.parsePatchProps)({
[propName]: outputValue
}, oldProps);
data = (0, _ramda.assocPath)(dataPath, newProps[propName], data);
});
return _context2.a(2, {
data,
payload
});
case 4:
_context2.p = 4;
_t2 = _context2.v;
return _context2.a(2, {
error: _t2,
payload
});
case 5:
newConfig = config;
newHeaders = null;
additionalArgs = [];
jsonOutput = JSON.stringify(payload.outputs);
(0, _ramda.values)(getState().callbackJobs).forEach(job => {
if (jsonOutput === job.output) {
// Terminate the old jobs that are not completed
// set as outdated for the callback promise to
// resolve and remove after.
additionalArgs.push(['oldJob', job.jobId, true]);
dispatch(setCallbackJobOutdated({
jobId: job.jobId
}));
}
if (!job.cancelInputs) {
return;
}
var inter = (0, _ramda.intersection)(job.cancelInputs, cb.callback.inputs);
if (inter.length) {
additionalArgs.push(['cancelJob', job.jobId]);
if (job.progressDefault) {
dispatch(sideUpdate(job.progressDefault, payload));
}
}
});
_loop = /*#__PURE__*/_regenerator().m(function _loop() {
var _data, _currentLayout, body, oldJwt, newJwt, _t;
return _regenerator().w(function (_context) {
while (1) switch (_context.p = _context.n) {
case 0:
_context.p = 0;
_context.n = 1;
return handleServerside(dispatch, hooks, newConfig, payload, background, additionalArgs.length ? additionalArgs : undefined, getState, cb.callback.running);
case 1:
_data = _context.v;
if (newHeaders) {
dispatch((0, _actions.addHttpHeaders)(newHeaders));
}
// Layout may have changed.
// DRY: Always run through parsePatchProps for each output
_currentLayout = getState().layout;
(0, _ramda.flatten)(outputs).forEach(out => {
var propName = cleanOutputProp(out.property);
var outputPath = (0, _paths.getPath)(paths, out.id);
var dataPath = [(0, _dependencies.stringifyId)(out.id), propName];
var outputValue = (0, _ramda.path)(dataPath, _data);
if (outputValue === undefined) {
return;
}
var oldProps = (0, _ramda.path)(outputPath.concat(['props']), _currentLayout) || {};
var newProps = (0, _patch.parsePatchProps)({
[propName]: outputValue
}, oldProps);
_data = (0, _ramda.assocPath)(dataPath, newProps[propName], _data);
});
if (dynamic_creator) {
setTimeout(() => dispatch((0, _requestDependencies.requestDependencies)()), 0);
}
return _context.a(2, {
v: {
data: _data,
payload
}
});
case 2:
_context.p = 2;
_t = _context.v;
lastError = _t;
if (!(retry <= _constants2.MAX_AUTH_RETRIES && (_t.status === _constants.STATUS.UNAUTHORIZED || _t.status === _constants.STATUS.BAD_REQUEST))) {
_context.n = 5;
break;
}
_context.n = 3;
return _t.text();
case 3:
body = _context.v;
if (!body.includes(_constants.JWT_EXPIRED_MESSAGE)) {
_context.n = 5;
break;
}
if (!(hooks.request_refresh_jwt !== null)) {
_context.n = 5;
break;
}
oldJwt = null;
if (config.fetch.headers.Authorization) {
oldJwt = config.fetch.headers.Authorization.substr('Bearer '.length);
}
_context.n = 4;
return hooks.request_refresh_jwt(oldJwt);
case 4:
newJwt = _context.v;
if (!newJwt) {
_context.n = 5;
break;
}
newHeaders = {
Authorization: "Bearer ".concat(newJwt)
};
newConfig = (0, _ramda.mergeDeepRight)(config, {
fetch: {
headers: newHeaders
}
});
return _context.a(2, 0);
case 5:
return _context.a(2, 1);
}
}, _loop, null, [[0, 2]]);
});
retry = 0;
case 6:
if (!(retry <= _constants2.MAX_AUTH_RETRIES)) {
_context2.n = 11;
break;
}
return _context2.d(_regeneratorValues(_loop()), 7);
case 7:
_ret = _context2.v;
if (!(_ret === 0)) {
_context2.n = 8;
break;
}
return _context2.a(3, 10);
case 8:
if (!(_ret === 1)) {
_context2.n = 9;
break;
}
return _context2.a(3, 11);
case 9:
if (!_ret) {
_context2.n = 10;
break;
}
return _context2.a(2, _ret.v);
case 10:
retry++;
_context2.n = 6;
break;
case 11:
return _context2.a(2, {
error: lastError,
payload: null
});
case 12:
_context2.p = 12;
_t3 = _context2.v;
return _context2.a(2, {
error: _t3,
payload: null
});
case 13:
_context2.p = 13;
dispatch((0, _loading.loaded)(loadingOutputs));
return _context2.f(13);
case 14:
return _context2.a(2);
}
}, _callee, null, [[2, 4], [1, 12, 13, 14]]);
}));
return function __execute() {
return _ref1.apply(this, arguments);
};
}();
var newCb = _objectSpread(_objectSpread({}, cb), {}, {
executionPromise: __execute()
});
return newCb;
} catch (error) {
return _objectSpread(_objectSpread({}, cb), {}, {
executionPromise: {
error,
payload: null
}
});
}
}