"use strict";

function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }

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");

function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }

function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }

function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }

function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }

function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return exports; }; var exports = {}, Op = Object.prototype, hasOwn = Op.hasOwnProperty, $Symbol = "function" == typeof Symbol ? Symbol : {}, iteratorSymbol = $Symbol.iterator || "@@iterator", asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator", toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; function define(obj, key, value) { return Object.defineProperty(obj, key, { value: value, enumerable: !0, configurable: !0, writable: !0 }), obj[key]; } try { define({}, ""); } catch (err) { define = function define(obj, key, value) { return obj[key] = value; }; } function wrap(innerFn, outerFn, self, tryLocsList) { var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator, generator = Object.create(protoGenerator.prototype), context = new Context(tryLocsList || []); return generator._invoke = function (innerFn, self, context) { var state = "suspendedStart"; return function (method, arg) { if ("executing" === state) throw new Error("Generator is already running"); if ("completed" === state) { if ("throw" === method) throw arg; return doneResult(); } for (context.method = method, context.arg = arg;;) { var delegate = context.delegate; if (delegate) { var delegateResult = maybeInvokeDelegate(delegate, context); if (delegateResult) { if (delegateResult === ContinueSentinel) continue; return delegateResult; } } if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) { if ("suspendedStart" === state) throw state = "completed", context.arg; context.dispatchException(context.arg); } else "return" === context.method && context.abrupt("return", context.arg); state = "executing"; var record = tryCatch(innerFn, self, context); if ("normal" === record.type) { if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue; return { value: record.arg, done: context.done }; } "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg); } }; }(innerFn, self, context), generator; } function tryCatch(fn, obj, arg) { try { return { type: "normal", arg: fn.call(obj, arg) }; } catch (err) { return { type: "throw", arg: err }; } } exports.wrap = wrap; var ContinueSentinel = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var IteratorPrototype = {}; define(IteratorPrototype, iteratorSymbol, function () { return this; }); var getProto = Object.getPrototypeOf, NativeIteratorPrototype = getProto && getProto(getProto(values([]))); NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype); var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype); function defineIteratorMethods(prototype) { ["next", "throw", "return"].forEach(function (method) { define(prototype, method, function (arg) { return this._invoke(method, arg); }); }); } function AsyncIterator(generator, PromiseImpl) { function invoke(method, arg, resolve, reject) { var record = tryCatch(generator[method], generator, arg); if ("throw" !== record.type) { var result = record.arg, value = result.value; return value && "object" == _typeof(value) && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) { invoke("next", value, resolve, reject); }, function (err) { invoke("throw", err, resolve, reject); }) : PromiseImpl.resolve(value).then(function (unwrapped) { result.value = unwrapped, resolve(result); }, function (error) { return invoke("throw", error, resolve, reject); }); } reject(record.arg); } var previousPromise; this._invoke = function (method, arg) { function callInvokeWithMethodAndArg() { return new PromiseImpl(function (resolve, reject) { invoke(method, arg, resolve, reject); }); } return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); }; } function maybeInvokeDelegate(delegate, context) { var method = delegate.iterator[context.method]; if (undefined === method) { if (context.delegate = null, "throw" === context.method) { if (delegate.iterator["return"] && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method)) return ContinueSentinel; context.method = "throw", context.arg = new TypeError("The iterator does not provide a 'throw' method"); } return ContinueSentinel; } var record = tryCatch(method, delegate.iterator, context.arg); if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel; var info = record.arg; return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel); } function pushTryEntry(locs) { var entry = { tryLoc: locs[0] }; 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry); } function resetTryEntry(entry) { var record = entry.completion || {}; record.type = "normal", delete record.arg, entry.completion = record; } function Context(tryLocsList) { this.tryEntries = [{ tryLoc: "root" }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0); } function values(iterable) { if (iterable) { var iteratorMethod = iterable[iteratorSymbol]; if (iteratorMethod) return iteratorMethod.call(iterable); if ("function" == typeof iterable.next) return iterable; if (!isNaN(iterable.length)) { var i = -1, next = function next() { for (; ++i < iterable.length;) { if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next; } return next.value = undefined, next.done = !0, next; }; return next.next = next; } } return { next: doneResult }; } function doneResult() { return { value: undefined, done: !0 }; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, "constructor", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) { var ctor = "function" == typeof genFun && genFun.constructor; return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name)); }, exports.mark = function (genFun) { return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun; }, exports.awrap = function (arg) { return { __await: arg }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () { return this; }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) { void 0 === PromiseImpl && (PromiseImpl = Promise); var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl); return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) { return result.done ? result.value : iter.next(); }); }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () { return this; }), define(Gp, "toString", function () { return "[object Generator]"; }), exports.keys = function (object) { var keys = []; for (var key in object) { keys.push(key); } return keys.reverse(), function next() { for (; keys.length;) { var key = keys.pop(); if (key in object) return next.value = key, next.done = !1, next; } return next.done = !0, next; }; }, exports.values = values, Context.prototype = { constructor: Context, reset: function reset(skipTempReset) { if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) { "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined); } }, stop: function stop() { this.done = !0; var rootRecord = this.tryEntries[0].completion; if ("throw" === rootRecord.type) throw rootRecord.arg; return this.rval; }, dispatchException: function dispatchException(exception) { if (this.done) throw exception; var context = this; function handle(loc, caught) { return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught; } for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i], record = entry.completion; if ("root" === entry.tryLoc) return handle("end"); if (entry.tryLoc <= this.prev) { var hasCatch = hasOwn.call(entry, "catchLoc"), hasFinally = hasOwn.call(entry, "finallyLoc"); if (hasCatch && hasFinally) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } else if (hasCatch) { if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0); } else { if (!hasFinally) throw new Error("try statement without catch or finally"); if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc); } } } }, abrupt: function abrupt(type, arg) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) { var finallyEntry = entry; break; } } finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null); var record = finallyEntry ? finallyEntry.completion : {}; return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record); }, complete: function complete(record, afterLoc) { if ("throw" === record.type) throw record.arg; return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel; }, finish: function finish(finallyLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel; } }, "catch": function _catch(tryLoc) { for (var i = this.tryEntries.length - 1; i >= 0; --i) { var entry = this.tryEntries[i]; if (entry.tryLoc === tryLoc) { var record = entry.completion; if ("throw" === record.type) { var thrown = record.arg; resetTryEntry(entry); } return thrown; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(iterable, resultName, nextLoc) { return this.delegate = { iterator: values(iterable), resultName: resultName, nextLoc: nextLoc }, "next" === this.method && (this.arg = undefined), ContinueSentinel; } }, exports; }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _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(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_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"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }

function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }

var addBlockedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.AddBlocked);
exports.addBlockedCallbacks = addBlockedCallbacks;
var addCompletedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackAggregateActionType.AddCompleted);
exports.addCompletedCallbacks = addCompletedCallbacks;
var addExecutedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.AddExecuted);
exports.addExecutedCallbacks = addExecutedCallbacks;
var addExecutingCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.AddExecuting);
exports.addExecutingCallbacks = addExecutingCallbacks;
var addPrioritizedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.AddPrioritized);
exports.addPrioritizedCallbacks = addPrioritizedCallbacks;
var addRequestedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.AddRequested);
exports.addRequestedCallbacks = addRequestedCallbacks;
var addStoredCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.AddStored);
exports.addStoredCallbacks = addStoredCallbacks;
var addWatchedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.AddWatched);
exports.addWatchedCallbacks = addWatchedCallbacks;
var removeExecutedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.RemoveExecuted);
exports.removeExecutedCallbacks = removeExecutedCallbacks;
var removeBlockedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.RemoveBlocked);
exports.removeBlockedCallbacks = removeBlockedCallbacks;
var removeExecutingCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.RemoveExecuting);
exports.removeExecutingCallbacks = removeExecutingCallbacks;
var removePrioritizedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.RemovePrioritized);
exports.removePrioritizedCallbacks = removePrioritizedCallbacks;
var removeRequestedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.RemoveRequested);
exports.removeRequestedCallbacks = removeRequestedCallbacks;
var removeStoredCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.RemoveStored);
exports.removeStoredCallbacks = removeStoredCallbacks;
var removeWatchedCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackActionType.RemoveWatched);
exports.removeWatchedCallbacks = removeWatchedCallbacks;
var aggregateCallbacks = (0, _reduxActions.createAction)(_callbacks.CallbackAggregateActionType.Aggregate);
exports.aggregateCallbacks = aggregateCallbacks;
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) {
      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(function (inputList, i) {
    var _unwrapIfNotMulti = unwrapIfNotMulti(paths, inputList.map(function (_ref) {
      var id = _ref.id,
          property = _ref.property,
          path_ = _ref.path;
      return {
        id: id,
        property: property,
        value: (0, _ramda.path)(path_, layout).props[property]
      };
    }), 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 = function getVals(input) {
  return Array.isArray(input) ? (0, _ramda.pluck)('value', input) : input.value;
};

var zipIfArray = function zipIfArray(a, b) {
  return Array.isArray(a) ? (0, _ramda.zip)(a, b) : [[a, b]];
};

function handleClientside(_x, _x2, _x3, _x4) {
  return _handleClientside.apply(this, arguments);
}

function _handleClientside() {
  _handleClientside = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(dispatch, clientside_function, config, payload) {
    var dc, inputs, outputs, state, requestTime, inputDict, stateDict, result, status, _dc$namespace, _returnValue, namespace, function_name, args, returnValue, totalTime, resources;

    return _regeneratorRuntime().wrap(function _callee2$(_context2) {
      while (1) {
        switch (_context2.prev = _context2.next) {
          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;
            _context2.prev = 8;
            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(function (prop_id) {
              return {
                prop_id: prop_id,
                value: inputDict[prop_id]
              };
            });
            dc.callback_context.inputs_list = inputs;
            dc.callback_context.inputs = inputDict;
            dc.callback_context.states_list = state;
            dc.callback_context.states = stateDict;
            returnValue = (_dc$namespace = dc[namespace])[function_name].apply(_dc$namespace, _toConsumableArray(args));
            delete dc.callback_context;

            if (!(typeof ((_returnValue = returnValue) === null || _returnValue === void 0 ? void 0 : _returnValue.then) === 'function')) {
              _context2.next = 24;
              break;
            }

            _context2.next = 23;
            return returnValue;

          case 23:
            returnValue = _context2.sent;

          case 24:
            zipIfArray(outputs, returnValue).forEach(function (_ref10) {
              var _ref11 = _slicedToArray(_ref10, 2),
                  outi = _ref11[0],
                  reti = _ref11[1];

              zipIfArray(outi, reti).forEach(function (_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[property] = retij;
                }
              });
            });
            _context2.next = 35;
            break;

          case 27:
            _context2.prev = 27;
            _context2.t0 = _context2["catch"](8);

            if (!(_context2.t0 === dc.PreventUpdate)) {
              _context2.next = 33;
              break;
            }

            status = _constants.STATUS.PREVENT_UPDATE;
            _context2.next = 35;
            break;

          case 33:
            status = _constants.STATUS.CLIENTSIDE_ERROR;
            throw _context2.t0;

          case 35:
            _context2.prev = 35;
            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: status,
                result: result,
                inputs: inputs,
                state: state
              }));
            }

            return _context2.finish(35);

          case 41:
            return _context2.abrupt("return", result);

          case 42:
          case "end":
            return _context2.stop();
        }
      }
    }, _callee2, null, [[8, 27, 35, 41]]);
  }));
  return _handleClientside.apply(this, arguments);
}

function sideUpdate(outputs, dispatch, paths) {
  (0, _ramda.toPairs)(outputs).forEach(function (_ref2) {
    var _ref3 = _slicedToArray(_ref2, 2),
        id = _ref3[0],
        value = _ref3[1];

    var _id$split = id.split('.'),
        _id$split2 = _slicedToArray(_id$split, 2),
        componentId = _id$split2[0],
        propName = _id$split2[1];

    var componentPath = paths.strs[componentId];
    dispatch((0, _index.updateProps)({
      props: _defineProperty({}, propName, value),
      itempath: componentPath
    }));
    dispatch((0, _index.notifyObservers)({
      id: componentId,
      props: _defineProperty({}, propName, value)
    }));
  });
}

function handleServerside(dispatch, hooks, config, payload, paths, _long, additionalArgs, getState, output) {
  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;

  var fetchCallback = function fetchCallback() {
    var headers = (0, _2.getCSRFHeader)();
    var url = "".concat((0, _utils.urlBase)(config), "_dash-update-component");

    var addArg = function addArg(name, value) {
      var delim = '?';

      if (url.includes('?')) {
        delim = '&';
      }

      url = "".concat(url).concat(delim).concat(name, "=").concat(value);
    };

    if (cacheKey) {
      addArg('cacheKey', cacheKey);
    }

    if (job) {
      addArg('job', job);
    }

    if (moreArgs) {
      moreArgs.forEach(function (_ref4) {
        var _ref5 = _slicedToArray(_ref4, 2),
            key = _ref5[0],
            value = _ref5[1];

        return addArg(key, value);
      });
      moreArgs = moreArgs.filter(function (_ref6) {
        var _ref7 = _slicedToArray(_ref6, 3),
            _ = _ref7[0],
            __ = _ref7[1],
            single = _ref7[2];

        return !single;
      });
    }

    return fetch(url, (0, _ramda.mergeDeepRight)(config.fetch, {
      method: 'POST',
      headers: headers,
      body: body
    }));
  };

  return new Promise(function (resolve, reject) {
    var handleOutput = function 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(function (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: status,
            result: result,
            inputs: payload.inputs,
            state: payload.state
          }));
        }
      }

      var finishLine = function 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 = _defineProperty({}, id, response.props);
        }

        recordProfile(result);
        resolve(result);
      };

      var completeJob = function completeJob() {
        if (job) {
          dispatch(removeCallbackJob({
            jobId: job
          }));
        }

        if (runningOff) {
          sideUpdate(runningOff, dispatch, paths);
        }

        if (progressDefault) {
          sideUpdate(progressDefault, dispatch, paths);
        }
      };

      if (status === _constants.STATUS.OK) {
        res.json().then(function (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: output
            };
            dispatch(addCallbackJob(jobInfo));
            job = data.job;
          }

          if (data.progress) {
            sideUpdate(data.progress, dispatch, paths);
          }

          if (data.running) {
            sideUpdate(data.running, dispatch, paths);
          }

          if (!runningOff && data.runningOff) {
            runningOff = data.runningOff;
          }

          if (!progressDefault && data.progressDefault) {
            progressDefault = data.progressDefault;
          }

          if (!_long || data.response !== undefined) {
            completeJob();
            finishLine(data);
          } else {
            // Poll chain.
            setTimeout(handle, _long.interval !== undefined ? _long.interval : 500);
          }
        });
      } else if (status === _constants.STATUS.PREVENT_UPDATE) {
        completeJob();
        recordProfile({});
        resolve({});
      } else {
        completeJob();
        reject(res);
      }
    };

    var handleError = function 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 = function 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 executeCallback(cb, config, hooks, paths, layout, _ref8, dispatch, getState) {
  var allOutputs = _ref8.allOutputs;
  var _cb$callback = cb.callback,
      output = _cb$callback.output,
      inputs = _cb$callback.inputs,
      state = _cb$callback.state,
      clientside_function = _cb$callback.clientside_function,
      _long2 = _cb$callback["long"];

  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(function (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 _ref9 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
        var payload, data, newConfig, newHeaders, lastError, additionalArgs, retry, _data, body, oldJwt, newJwt;

        return _regeneratorRuntime().wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                _context.prev = 0;
                payload = {
                  output: output,
                  outputs: (0, _dependencies.isMultiOutputProp)(output) ? outputs : outputs[0],
                  inputs: inVals,
                  changedPropIds: (0, _ramda.keys)(cb.changedPropIds),
                  state: cb.callback.state.length ? fillVals(paths, layout, cb, state, 'State') : undefined
                };

                if (!clientside_function) {
                  _context.next = 13;
                  break;
                }

                _context.prev = 3;
                _context.next = 6;
                return handleClientside(dispatch, clientside_function, config, payload);

              case 6:
                data = _context.sent;
                return _context.abrupt("return", {
                  data: data,
                  payload: payload
                });

              case 10:
                _context.prev = 10;
                _context.t0 = _context["catch"](3);
                return _context.abrupt("return", {
                  error: _context.t0,
                  payload: payload
                });

              case 13:
                newConfig = config;
                newHeaders = null;
                additionalArgs = [];
                (0, _ramda.values)(getState().callbackJobs).forEach(function (job) {
                  if (cb.callback.output === 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) {
                      sideUpdate(job.progressDefault, dispatch, paths);
                    }
                  }
                });
                retry = 0;

              case 18:
                if (!(retry <= _constants2.MAX_AUTH_RETRIES)) {
                  _context.next = 49;
                  break;
                }

                _context.prev = 19;
                _context.next = 22;
                return handleServerside(dispatch, hooks, newConfig, payload, paths, _long2, additionalArgs.length ? additionalArgs : undefined, getState, cb.callback.output);

              case 22:
                _data = _context.sent;

                if (newHeaders) {
                  dispatch((0, _actions.addHttpHeaders)(newHeaders));
                }

                return _context.abrupt("return", {
                  data: _data,
                  payload: payload
                });

              case 27:
                _context.prev = 27;
                _context.t1 = _context["catch"](19);
                lastError = _context.t1;

                if (!(retry <= _constants2.MAX_AUTH_RETRIES && (_context.t1.status === _constants.STATUS.UNAUTHORIZED || _context.t1.status === _constants.STATUS.BAD_REQUEST))) {
                  _context.next = 45;
                  break;
                }

                _context.next = 33;
                return _context.t1.text();

              case 33:
                body = _context.sent;

                if (!body.includes(_constants.JWT_EXPIRED_MESSAGE)) {
                  _context.next = 45;
                  break;
                }

                if (!(hooks.request_refresh_jwt !== null)) {
                  _context.next = 45;
                  break;
                }

                oldJwt = null;

                if (config.fetch.headers.Authorization) {
                  oldJwt = config.fetch.headers.Authorization.substr('Bearer '.length);
                }

                _context.next = 40;
                return hooks.request_refresh_jwt(oldJwt);

              case 40:
                newJwt = _context.sent;

                if (!newJwt) {
                  _context.next = 45;
                  break;
                }

                newHeaders = {
                  Authorization: "Bearer ".concat(newJwt)
                };
                newConfig = (0, _ramda.mergeDeepRight)(config, {
                  fetch: {
                    headers: newHeaders
                  }
                });
                return _context.abrupt("continue", 46);

              case 45:
                return _context.abrupt("break", 49);

              case 46:
                retry++;
                _context.next = 18;
                break;

              case 49:
                return _context.abrupt("return", {
                  error: lastError,
                  payload: null
                });

              case 52:
                _context.prev = 52;
                _context.t2 = _context["catch"](0);
                return _context.abrupt("return", {
                  error: _context.t2,
                  payload: null
                });

              case 55:
              case "end":
                return _context.stop();
            }
          }
        }, _callee, null, [[0, 52], [3, 10], [19, 27]]);
      }));

      return function __execute() {
        return _ref9.apply(this, arguments);
      };
    }();

    var newCb = _objectSpread(_objectSpread({}, cb), {}, {
      executionPromise: __execute()
    });

    return newCb;
  } catch (error) {
    return _objectSpread(_objectSpread({}, cb), {}, {
      executionPromise: {
        error: error,
        payload: null
      }
    });
  }
}