UNPKG

elliptical-observe-inline

Version:
91 lines (77 loc) 2.93 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = createProcessor; var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function createProcessor(register, processor) { function observe(source) { if (processor) { source = processor(source); } return register(source); } function process(element) { const newElement = _lodash2.default.assign({}, element, { observe }); // Don't worry about builtins, or Phrases with a visit if (_lodash2.default.isString(element.type) || !element.type.describe) { return newElement; } function describeAndTrackObserve() { const sources = []; const values = []; function trackedObserve(source) { if (processor) { source = processor(source); } const value = register(source); sources.push(source); values.push(value); return value; } const description = element.type.describe(_lodash2.default.assign({}, element, { observe: trackedObserve })); return { description, sources, values }; } const { description: firstDescription, sources: firstSources, values: firstValues } = describeAndTrackObserve(); let 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 { let oldValues = firstValues; let oldSources = firstSources; let oldDescription = firstDescription; function visit(option, e, traverse) { let sources, values, description; if (firstRun) { sources = firstSources; values = firstValues; description = firstDescription; firstRun = false; } else { ;({ sources, values, description } = describeAndTrackObserve()); } if (oldDescription == null && description != null || values.length !== oldValues.length || // perf opt _lodash2.default.some(_lodash2.default.unzip([values, oldValues]), ([a, b]) => a !== b) || _lodash2.default.some(_lodash2.default.unzip([sources, oldSources]), ([a, b]) => !_lodash2.default.isEqual(a, b))) { oldValues = values; oldSources = sources; oldDescription = description; } return traverse(oldDescription, option); } const type = _lodash2.default.assign({}, element.type, { visit, _oldVisit: element.type.visit, describe: undefined }); return _lodash2.default.assign({}, newElement, { type }); } } process.observe = observe; return process; }