elliptical-observe-inline
Version:
Dynamic sideways Data Loading for Elliptical
113 lines (96 loc) • 3.55 kB
JavaScript
import _typeof from 'babel-runtime/helpers/typeof';
import _slicedToArray from 'babel-runtime/helpers/slicedToArray';
import _ from 'lodash';
export default function createProcessor(register, processor) {
function observe(source) {
if (processor) {
source = processor(source);
}
return register(source);
}
function process(element) {
var newElement = _.assign({}, element, { observe: observe });
// Don't worry about builtins, or Phrases with a visit
if (_.isString(element.type) || !element.type.describe) {
return newElement;
}
function describeAndTrackObserve() {
var sources = [];
var values = [];
function trackedObserve(source) {
if (processor) {
source = processor(source);
}
var value = register(source);
sources.push(source);
values.push(value);
return value;
}
var description = element.type.describe(_.assign({}, element, { observe: trackedObserve }));
return { description: description, sources: sources, values: values };
}
var _describeAndTrackObse = describeAndTrackObserve();
var firstDescription = _describeAndTrackObse.description;
var firstSources = _describeAndTrackObse.sources;
var firstValues = _describeAndTrackObse.values;
var firstRun = true;
// If it never called observe, it never WILL call observe during
// a normal describe. It may with 'dynamic' or a child value,
// but we can't track and optimize that - so we'll just
// pass a naive observe
if (firstSources.length === 0) {
return newElement;
} else {
var _ret = function () {
var visit = function visit(option, e, traverse) {
var sources = void 0,
values = void 0,
description = void 0;
if (firstRun) {
sources = firstSources;
values = firstValues;
description = firstDescription;
firstRun = false;
} else {
;
var _describeAndTrackObse2 = describeAndTrackObserve();
sources = _describeAndTrackObse2.sources;
values = _describeAndTrackObse2.values;
description = _describeAndTrackObse2.description;
}
if (oldDescription == null && description != null || values.length !== oldValues.length || // perf opt
_.some(_.unzip([values, oldValues]), function (_ref) {
var _ref2 = _slicedToArray(_ref, 2);
var a = _ref2[0];
var b = _ref2[1];
return a !== b;
}) || _.some(_.unzip([sources, oldSources]), function (_ref3) {
var _ref4 = _slicedToArray(_ref3, 2);
var a = _ref4[0];
var b = _ref4[1];
return !_.isEqual(a, b);
})) {
oldValues = values;
oldSources = sources;
oldDescription = description;
}
return traverse(oldDescription, option);
};
var oldValues = firstValues;
var oldSources = firstSources;
var oldDescription = firstDescription;
var type = _.assign({}, element.type, {
visit: visit,
_oldVisit: element.type.visit,
describe: undefined
});
return {
v: _.assign({}, newElement, { type: type })
};
}();
if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
}
}
process.observe = observe;
return process;
}