UNPKG

dash-renderer

Version:

render dash components in react

895 lines (889 loc) 42.8 kB
"use strict"; 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 } }); } }