dash-renderer
Version:
render dash components in react
252 lines (238 loc) • 20.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _ramda = require("ramda");
var _callbacks = require("../actions/callbacks");
var _dependencies = require("../actions/dependencies");
var _dependencies_ts = require("../actions/dependencies_ts");
var _wait = _interopRequireDefault(require("./../utils/wait"));
var _callbacks2 = require("../utils/callbacks");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
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 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); }
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); }); }; }
var observer = {
observer: function () {
var _observer = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(_ref) {
var dispatch, getState, _getState, callbacks, _getState$callbacks, prioritized, blocked, executing, watched, stored, paths, graphs, _getState2, requested, initialRequested, pendingCallbacks, rCirculars, rDuplicates, rMergedDuplicates, pDuplicates, bDuplicates, eDuplicates, wDuplicates, _pruneCallbacks, rAdded, rRemoved, _pruneCallbacks2, pAdded, pRemoved, _pruneCallbacks3, bAdded, bRemoved, _pruneCallbacks4, eAdded, eRemoved, _pruneCallbacks5, wAdded, wRemoved, readyCallbacks, oldBlocked, newBlocked, candidates, _loop, pendingGroups, dropped, added, removed;
return _regenerator().w(function (_context2) {
while (1) switch (_context2.n) {
case 0:
dispatch = _ref.dispatch, getState = _ref.getState;
_context2.n = 1;
return (0, _wait.default)(0);
case 1:
_getState = getState(), callbacks = _getState.callbacks, _getState$callbacks = _getState.callbacks, prioritized = _getState$callbacks.prioritized, blocked = _getState$callbacks.blocked, executing = _getState$callbacks.executing, watched = _getState$callbacks.watched, stored = _getState$callbacks.stored, paths = _getState.paths, graphs = _getState.graphs;
_getState2 = getState(), requested = _getState2.callbacks.requested;
initialRequested = requested.slice(0);
pendingCallbacks = (0, _callbacks2.getPendingCallbacks)(callbacks);
/*
0. Prune circular callbacks that have completed the loop
- cb.callback included in cb.predecessors
*/
rCirculars = (0, _ramda.filter)(cb => {
var _cb$predecessors;
return (0, _ramda.includes)(cb.callback, (_cb$predecessors = cb.predecessors) !== null && _cb$predecessors !== void 0 ? _cb$predecessors : []);
}, requested);
/*
TODO?
Clean up the `requested` list - during the dispatch phase,
circulars will be removed for real
*/
requested = (0, _ramda.difference)(requested, rCirculars);
/*
1. Remove duplicated `requested` callbacks - give precedence to newer callbacks over older ones
*/
rDuplicates = [];
rMergedDuplicates = [];
(0, _ramda.values)((0, _ramda.groupBy)(_dependencies_ts.getUniqueIdentifier, requested)).forEach(group => {
if (group.length === 1) {
// keep callback if its the only one of its kind
rMergedDuplicates.push(group[0]);
} else {
var initial = group.find(cb => cb.initialCall);
if (initial) {
// drop the initial callback if it's not alone
rDuplicates.push(initial);
}
var groupWithoutInitial = group.filter(cb => cb !== initial);
if (groupWithoutInitial.length === 1) {
// if there's only one callback beside the initial one, keep that callback
rMergedDuplicates.push(groupWithoutInitial[0]);
} else {
// otherwise merge all remaining callbacks together
rDuplicates = (0, _ramda.concat)(rDuplicates, groupWithoutInitial);
rMergedDuplicates.push((0, _ramda.mergeLeft)({
changedPropIds: (0, _ramda.reduce)((0, _ramda.mergeWith)(Math.max), {}, (0, _ramda.pluck)('changedPropIds', groupWithoutInitial)),
executionGroup: (0, _ramda.filter)(exg => Boolean(exg), (0, _ramda.pluck)('executionGroup', groupWithoutInitial)).slice(-1)[0]
}, groupWithoutInitial.slice(-1)[0]));
}
}
});
/*
TODO?
Clean up the `requested` list - during the dispatch phase,
duplicates will be removed for real
*/
requested = rMergedDuplicates;
/*
2. Remove duplicated `prioritized`, `executing` and `watching` callbacks
*/
/*
Extract all but the first callback from each IOS-key group
these callbacks are `prioritized` and duplicates.
*/
pDuplicates = (0, _ramda.flatten)((0, _ramda.map)(group => group.slice(0, -1), (0, _ramda.values)((0, _ramda.groupBy)(_dependencies_ts.getUniqueIdentifier, (0, _ramda.concat)(prioritized, requested)))));
bDuplicates = (0, _ramda.flatten)((0, _ramda.map)(group => group.slice(0, -1), (0, _ramda.values)((0, _ramda.groupBy)(_dependencies_ts.getUniqueIdentifier, (0, _ramda.concat)(blocked, requested)))));
eDuplicates = (0, _ramda.flatten)((0, _ramda.map)(group => group.slice(0, -1), (0, _ramda.values)((0, _ramda.groupBy)(_dependencies_ts.getUniqueIdentifier, (0, _ramda.concat)(executing, requested)))));
wDuplicates = (0, _ramda.flatten)((0, _ramda.map)(group => group.slice(0, -1), (0, _ramda.values)((0, _ramda.groupBy)(_dependencies_ts.getUniqueIdentifier, (0, _ramda.concat)(watched, requested)))));
/*
3. Modify or remove callbacks that are outputting to non-existing layout `id`.
*/
_pruneCallbacks = (0, _dependencies_ts.pruneCallbacks)(requested, paths), rAdded = _pruneCallbacks.added, rRemoved = _pruneCallbacks.removed;
_pruneCallbacks2 = (0, _dependencies_ts.pruneCallbacks)(prioritized, paths), pAdded = _pruneCallbacks2.added, pRemoved = _pruneCallbacks2.removed;
_pruneCallbacks3 = (0, _dependencies_ts.pruneCallbacks)(blocked, paths), bAdded = _pruneCallbacks3.added, bRemoved = _pruneCallbacks3.removed;
_pruneCallbacks4 = (0, _dependencies_ts.pruneCallbacks)(executing, paths), eAdded = _pruneCallbacks4.added, eRemoved = _pruneCallbacks4.removed;
_pruneCallbacks5 = (0, _dependencies_ts.pruneCallbacks)(watched, paths), wAdded = _pruneCallbacks5.added, wRemoved = _pruneCallbacks5.removed;
/*
TODO?
Clean up the `requested` list - during the dispatch phase,
it will be updated for real
*/
requested = (0, _ramda.concat)((0, _ramda.difference)(requested, rRemoved), rAdded);
/*
4. Find `requested` callbacks that do not depend on a outstanding output (as either input or state)
*/
readyCallbacks = (0, _dependencies_ts.getReadyCallbacks)(paths, requested, pendingCallbacks, graphs);
oldBlocked = [];
newBlocked = [];
/**
* If there is :
* - no ready callbacks
* - at least one requested callback
* - no additional pending callbacks
*
* can assume:
* - the requested callbacks are part of a circular dependency loop
*
* then recursively:
* - assume the first callback in the list is ready (the entry point for the loop)
* - check what callbacks are blocked / ready with the assumption
* - update the missing predecessors based on assumptions
* - continue until there are no remaining candidates
*
*/
if (!(!readyCallbacks.length && requested.length && requested.length === pendingCallbacks.length)) {
_context2.n = 4;
break;
}
candidates = requested.slice(0);
_loop = /*#__PURE__*/_regenerator().m(function _loop() {
var readyCallback, blockedByAssumptions, modified;
return _regenerator().w(function (_context) {
while (1) switch (_context.n) {
case 0:
// Assume 1st callback is ready and
// update candidates / readyCallbacks accordingly
readyCallback = candidates[0];
readyCallbacks.push(readyCallback);
candidates = candidates.slice(1);
// Remaining candidates are not blocked by current assumptions
candidates = (0, _dependencies_ts.getReadyCallbacks)(paths, candidates, readyCallbacks);
// Blocked requests need to make sure they have the callback as a predecessor
blockedByAssumptions = (0, _ramda.difference)(candidates, candidates);
modified = (0, _ramda.filter)(cb => !cb.predecessors || !(0, _ramda.includes)(readyCallback.callback, cb.predecessors), blockedByAssumptions);
oldBlocked = (0, _ramda.concat)(oldBlocked, modified);
newBlocked = (0, _ramda.concat)(newBlocked, modified.map(cb => {
var _cb$predecessors2;
return _objectSpread(_objectSpread({}, cb), {}, {
predecessors: (0, _ramda.concat)((_cb$predecessors2 = cb.predecessors) !== null && _cb$predecessors2 !== void 0 ? _cb$predecessors2 : [], [readyCallback.callback])
});
}));
case 1:
return _context.a(2);
}
}, _loop);
});
case 2:
if (!candidates.length) {
_context2.n = 4;
break;
}
return _context2.d(_regeneratorValues(_loop()), 3);
case 3:
_context2.n = 2;
break;
case 4:
/*
TODO?
Clean up the `requested` list - during the dispatch phase,
it will be updated for real
*/
requested = (0, _ramda.concat)((0, _ramda.difference)(requested, oldBlocked), newBlocked);
/*
5. Prune callbacks that became irrelevant in their `executionGroup`
*/
// Group by executionGroup, drop non-executionGroup callbacks
// those were not triggered by layout changes and don't have "strong" interdependency for
// callback chain completion
pendingGroups = (0, _ramda.groupBy)(cb => cb.executionGroup, (0, _ramda.filter)(cb => !(0, _ramda.isNil)(cb.executionGroup), stored));
dropped = (0, _ramda.filter)(cb => {
// If there is no `stored` callback for the group, no outputs were dropped -> `cb` is kept
if (!cb.executionGroup || !pendingGroups[cb.executionGroup] || !pendingGroups[cb.executionGroup].length) {
return false;
}
// Get all inputs for `cb`
var inputs = (0, _ramda.map)(_dependencies_ts.combineIdAndProp, (0, _ramda.flatten)(cb.getInputs(paths)));
// Get all the potentially updated props for the group so far
var allProps = (0, _ramda.flatten)((0, _ramda.map)(gcb => gcb.executionMeta.allProps, pendingGroups[cb.executionGroup]));
// Get all the updated props for the group so far
var updated = (0, _ramda.flatten)((0, _ramda.map)(gcb => gcb.executionMeta.updatedProps, pendingGroups[cb.executionGroup]));
// If there's no overlap between the updated props and the inputs,
// + there's no props that aren't covered by the potentially updated props,
// and not all inputs are multi valued
// -> drop `cb`
var res = (0, _ramda.isEmpty)((0, _ramda.intersection)(inputs, updated)) && (0, _ramda.isEmpty)((0, _ramda.difference)(inputs, allProps)) && !(0, _ramda.all)(_dependencies.isMultiValued, cb.callback.inputs);
return res;
}, readyCallbacks);
/*
TODO?
Clean up the `requested` list - during the dispatch phase,
it will be updated for real
*/
requested = (0, _ramda.difference)(requested, dropped);
readyCallbacks = (0, _ramda.difference)(readyCallbacks, dropped);
requested = (0, _ramda.difference)(requested, readyCallbacks);
added = (0, _ramda.difference)(requested, initialRequested);
removed = (0, _ramda.difference)(initialRequested, requested);
dispatch((0, _callbacks.aggregateCallbacks)([
// Clean up requested callbacks
added.length ? (0, _callbacks.addRequestedCallbacks)(added) : null, removed.length ? (0, _callbacks.removeRequestedCallbacks)(removed) : null,
// Clean up duplicated callbacks
pDuplicates.length ? (0, _callbacks.removePrioritizedCallbacks)(pDuplicates) : null, bDuplicates.length ? (0, _callbacks.removeBlockedCallbacks)(bDuplicates) : null, eDuplicates.length ? (0, _callbacks.removeExecutingCallbacks)(eDuplicates) : null, wDuplicates.length ? (0, _callbacks.removeWatchedCallbacks)(wDuplicates) : null,
// Prune callbacks
pRemoved.length ? (0, _callbacks.removePrioritizedCallbacks)(pRemoved) : null, pAdded.length ? (0, _callbacks.addPrioritizedCallbacks)(pAdded) : null, bRemoved.length ? (0, _callbacks.removeBlockedCallbacks)(bRemoved) : null, bAdded.length ? (0, _callbacks.addBlockedCallbacks)(bAdded) : null, eRemoved.length ? (0, _callbacks.removeExecutingCallbacks)(eRemoved) : null, eAdded.length ? (0, _callbacks.addExecutingCallbacks)(eAdded) : null, wRemoved.length ? (0, _callbacks.removeWatchedCallbacks)(wRemoved) : null, wAdded.length ? (0, _callbacks.addWatchedCallbacks)(wAdded) : null,
// Promote callbacks
readyCallbacks.length ? (0, _callbacks.addPrioritizedCallbacks)(readyCallbacks) : null]));
case 5:
return _context2.a(2);
}
}, _callee);
}));
function observer(_x) {
return _observer.apply(this, arguments);
}
return observer;
}(),
inputs: ['callbacks.requested', 'callbacks.completed']
};
var _default = exports.default = observer;