UNPKG

ancient-graph-spreading

Version:

Automatic maintenance spreading of graph according other graphs.

532 lines (476 loc) 20.5 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>spreading.js - Documentation</title> <script src="scripts/prettify/prettify.js"></script> <script src="scripts/prettify/lang-css.js"></script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css"> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <input type="checkbox" id="nav-trigger" class="nav-trigger" /> <label for="nav-trigger" class="navicon-button x"> <div class="navicon"></div> </label> <label for="nav-trigger" class="overlay"></label> <nav> <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="GraphSpreading.html">GraphSpreading</a><ul class='methods'><li data-type='method'><a href="GraphSpreading.html#_getFromFields">_getFromFields</a></li><li data-type='method'><a href="GraphSpreading.html#_getToFields">_getToFields</a></li><li data-type='method'><a href="GraphSpreading.html#_spreadByPathLink">_spreadByPathLink</a></li><li data-type='method'><a href="GraphSpreading.html#_spreadFromSpreadLinkByPathGraph">_spreadFromSpreadLinkByPathGraph</a></li><li data-type='method'><a href="GraphSpreading.html#_spreadFromSpreadLinkByPathLink">_spreadFromSpreadLinkByPathLink</a></li><li data-type='method'><a href="GraphSpreading.html#_wrapPathQuery">_wrapPathQuery</a></li><li data-type='method'><a href="GraphSpreading.html#_wrapSpreadQuery">_wrapSpreadQuery</a></li><li data-type='method'><a href="GraphSpreading.html#addPathGraph">addPathGraph</a></li><li data-type='method'><a href="GraphSpreading.html#each">each</a></li><li data-type='method'><a href="GraphSpreading.html#spreadByPathLink">spreadByPathLink</a></li><li data-type='method'><a href="GraphSpreading.html#spreadFromSpreadLink">spreadFromSpreadLink</a></li><li data-type='method'><a href="GraphSpreading.html#spreadFromSpreadLinkByPathGraph">spreadFromSpreadLinkByPathGraph</a></li><li data-type='method'><a href="GraphSpreading.html#spreadFromSpreadLinkByPathLink">spreadFromSpreadLinkByPathLink</a></li><li data-type='method'><a href="GraphSpreading.html#spreadNewSpreadLink">spreadNewSpreadLink</a></li><li data-type='method'><a href="GraphSpreading.html#spreadTo">spreadTo</a></li><li data-type='method'><a href="GraphSpreading.html#unspread">unspread</a></li><li data-type='method'><a href="GraphSpreading.html#unspreadByPathId">unspreadByPathId</a></li><li data-type='method'><a href="GraphSpreading.html#unspreadFromRemovedSpreadLinkByPrevId">unspreadFromRemovedSpreadLinkByPrevId</a></li></ul></li><li><a href="PathGraph.html">PathGraph</a></li><li><a href="QueueSpreading.html">QueueSpreading</a><ul class='methods'><li data-type='method'><a href="QueueSpreading.html#_getGraph">_getGraph</a></li><li data-type='method'><a href="QueueSpreading.html#removeFromLaunched">removeFromLaunched</a></li><li data-type='method'><a href="QueueSpreading.html#spreadByPath">spreadByPath</a></li><li data-type='method'><a href="QueueSpreading.html#spreadBySpread">spreadBySpread</a></li><li data-type='method'><a href="QueueSpreading.html#spreadBySpreader">spreadBySpreader</a></li><li data-type='method'><a href="QueueSpreading.html#unspreadByPath">unspreadByPath</a></li><li data-type='method'><a href="QueueSpreading.html#unspreadBySpread">unspreadBySpread</a></li><li data-type='method'><a href="QueueSpreading.html#unspreadBySpreader">unspreadBySpreader</a></li></ul></li><li><a href="SpreaderGraph.html">SpreaderGraph</a></li><li><a href="SpreadGraph.html">SpreadGraph</a><ul class='methods'><li data-type='method'><a href="SpreadGraph.html#_spreadingHandler">_spreadingHandler</a></li><li data-type='method'><a href="SpreadGraph.html#_unspreadingHandler">_unspreadingHandler</a></li><li data-type='method'><a href="SpreadGraph.html#insert">insert</a></li><li data-type='method'><a href="SpreadGraph.html#remove">remove</a></li></ul></li></ul><h3>Global</h3><ul><li><a href="global.html#factoryLaunchedGraph">factoryLaunchedGraph</a></li><li><a href="global.html#factoryPathGraph">factoryPathGraph</a></li><li><a href="global.html#factoryRespreadGraph">factoryRespreadGraph</a></li><li><a href="global.html#factorySpreaderGraph">factorySpreaderGraph</a></li><li><a href="global.html#factorySpreadGraph">factorySpreadGraph</a></li></ul> </nav> <div id="main"> <h1 class="page-title">spreading.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>import async from 'async'; /** * Class with methods for spread and unspread of the spreadGraph on pathGraph(s). * * @class * @description `import { GraphSpreading } from 'ancient-graph-spreading';` */ class GraphSpreading { /** * @param {SpreadGraph} spreadGraph */ constructor(spreadGraph) { this.spreadGraph = spreadGraph; this.pathGraphs = []; } /** * Custom async callbacks support * * @param {Array|Iterable|Object} coll - A collection to iterate over. * @param {function} iteratee - A function to apply to each item in coll. * @param {function} callback - A callback which is called when all iteratee functions have finished. */ each(coll, iteratee, callback) { async.each(coll, iteratee, callback); } /** * @param {PathGraph} pathGraph */ addPathGraph(pathGraph) { this.pathGraphs.push(pathGraph); } /** * Custom wrapper of query to spread graph * * @param {Object} [query] * @param {Object} [context] */ _wrapSpreadQuery(query, context) {} /** * Custom wrapper of query to path graph * * @param {Object} [query] * @param {Object} [pathGraph] * @param {String} [fromField] * @param {String} [toField] * @param {Object} [context] */ _wrapPathQuery(query, pathGraph, fromField, toField, context) {} /** * Custom getter of possible from fields. * * @param {Object} [pathGraph] * @param {Object} [pathLink] * @param {Object} [spreadLink] * @return {String[]} [fromFields] */ _getFromFields(pathGraph, pathLink, spreadLink) { return pathGraph.fromFields; } /** * Custom getter of possible to fields. * * @param {Object} [pathGraph] * @param {Object} [pathLink] * @param {Object} [spreadLink] * @return {String[]} [toFields] */ _getToFields(pathGraph, pathLink, spreadLink) { return pathGraph.toFields; } /** * Spread by pathLink and specified fromField with available spreadLinks. * * @param {string} fromField * @param {PathGraph} pathGraph * @param {PathLink} pathLink * @param {Object} [context] * @param {GraphSpreading~spreadFromSpreadLinkByPathLinkCallback} [handler] * @param {GraphSpreading~spreadByPathLinkCallback} [callback] */ _spreadByPathLink(fromField, pathGraph, pathLink, context, handler, callback) { var query = { [this.spreadGraph.config.aliases[this.spreadGraph.variableField]]: pathLink[pathGraph.config.aliases[fromField]], }; this._wrapSpreadQuery(query, context); this.spreadGraph.fetch(query, undefined, (error, spreadLinks) => { if (spreadLinks.length) { this.each(spreadLinks, (spreadLink, next) => { this.spreadFromSpreadLinkByPathLink(spreadLink, pathGraph, pathLink, context, handler, () => { next(); }); }, () => { if (callback) callback(); }); } else { if (callback) callback(); } }); } /** * Spread by pathLink with available spreadLinks. * * @param {PathGraph} pathGraph * @param {PathLink} pathLink * @param {Object} [context] * @param {GraphSpreading~spreadFromSpreadLinkByPathLinkCallback} [handler] * @param {GraphSpreading~spreadByPathLinkCallback} [callback] */ spreadByPathLink(pathGraph, pathLink, context, handler, callback) { this.each(this._getFromFields(pathGraph, pathLink), (fromField, next) => { this._spreadByPathLink(fromField, pathGraph, pathLink, context, handler, next); }, callback); } /** * Optional callback. * * @callback GraphSpreading~spreadByPathLinkCallback */ /** * Spread root of tree spreadLink. * * @param {SpreadLink} newSpreadLink * @param {Object} [context] * @param {Graph~insertCallback} [callback] */ spreadNewSpreadLink(newSpreadLink, context, callback) { this.spreadGraph._spreadingHandler(undefined, undefined, undefined, newSpreadLink, context, (newSpreadLink) => { if (newSpreadLink) { this.spreadGraph.insert(newSpreadLink, callback, context); } else { if (callback) callback(); } }); } /** * Spread by all available paths from spreadLink. * * @param {SpreadLink} spreadLink * @param {Object} [context] * @param {GraphSpreading~spreadFromSpreadLinkByPathGraphHandler} [handler] * @param {GraphSpreading~spreadFromSpreadLinkByPathGraphCallback} [callback] */ spreadFromSpreadLink(spreadLink, context, handler, callback) { this.each(this.pathGraphs, (pathGraph, next) => { this.spreadFromSpreadLinkByPathGraph(spreadLink, pathGraph, context, handler, next); }, () => { if (callback) callback(); }); } /** * Spread by all available paths in pathGraph from spreadLink and specified fromField. * * @param {string} fromField * @param {SpreadLink} spreadLink * @param {PathGraph} pathGraph * @param {Object} [context] * @param {GraphSpreading~spreadFromSpreadLinkByPathGraphHandler} [handler] * @param {GraphSpreading~spreadFromSpreadLinkByPathGraphCallback} [callback] */ _spreadFromSpreadLinkByPathGraph(fromField, spreadLink, pathGraph, context, handler, callback) { var query = { [pathGraph.config.aliases[fromField]]: spreadLink[this.spreadGraph.variableField], }; this._wrapPathQuery(query, pathGraph, fromField, undefined, context); pathGraph.fetch(query, undefined, (error, pathLinks) => { this.each(pathLinks, (pathLink, next) => { this.spreadFromSpreadLinkByPathLink(spreadLink, pathGraph, pathLink, context, handler, next); }, () => { if (callback) callback(); }); }); } /** * Spread by all available paths in pathGraph from spreadLink. * * @param {SpreadLink} spreadLink * @param {PathGraph} pathGraph * @param {GraphSpreading~spreadFromSpreadLinkByPathGraphHandler} [handler] * @param {GraphSpreading~spreadFromSpreadLinkByPathGraphCallback} [callback] */ spreadFromSpreadLinkByPathGraph(spreadLink, pathGraph, context, handler, callback) { this.each(this._getFromFields(pathGraph, undefined, spreadLink), (fromField, next) => { this._spreadFromSpreadLinkByPathGraph(fromField, spreadLink, pathGraph, context, handler, next); }, callback); } /** * Optional handler. If present, called with an error object as the first argument and, if no error, others arguments with results of spreading. * * @callback GraphSpreading~spreadFromSpreadLinkByPathGraphHandler * @param {Error} [error] * @param {string} [newSpreadLinkId] * @param {SpreadLink} [prevSpreadLink] * @param {PathGraph} [pathGraph] * @param {PathLink} [pathLink] */ /** * Optional callback. * * @callback GraphSpreading~spreadFromSpreadLinkByPathGraphCallback */ /** * Spread by pathLink and specified toField in pathGraph from spreadLink. * * @param {SpreadLink} spreadLink * @param {PathGraph} pathGraph * @param {PathLink} pathLink * @param {Object} [context] * @param {GraphSpreading~spreadFromSpreadLinkByPathLinkCallback} [callback] */ _spreadFromSpreadLinkByPathLink(toField, spreadLink, pathGraph, pathLink, context, callback) { this.spreadGraph._spreadingHandler(spreadLink, pathGraph, pathLink, { [this.spreadGraph.config.aliases[this.spreadGraph.constantField]]: spreadLink[this.spreadGraph.config.aliases[this.spreadGraph.constantField]], [this.spreadGraph.config.aliases[this.spreadGraph.variableField]]: pathLink[pathGraph.config.aliases[toField]], [this.spreadGraph.config.aliases.prev]: spreadLink[this.spreadGraph.config.aliases.id], [this.spreadGraph.config.aliases.path]: pathLink[pathGraph.config.aliases.id], [this.spreadGraph.config.aliases.root]: spreadLink[this.spreadGraph.config.aliases.root]?spreadLink[this.spreadGraph.config.aliases.root]:spreadLink[this.spreadGraph.config.aliases.id] }, context, (newSpreadLink) => { if (newSpreadLink) { this.spreadGraph.insert(newSpreadLink, (error, id) => { if (callback) callback(error, id, spreadLink, pathGraph, pathLink); }, context); } else { if (callback) callback(); } }); } /** * Spread by pathLink in pathGraph from spreadLink. * * @param {SpreadLink} spreadLink * @param {PathGraph} pathGraph * @param {PathLink} pathLink * @param {Object} [context] * @param {GraphSpreading~spreadFromSpreadLinkByPathLinkHandler} [handler] * @param {GraphSpreading~spreadFromSpreadLinkByPathLinkCallback} [callback] */ spreadFromSpreadLinkByPathLink(spreadLink, pathGraph, pathLink, context, handler, callback) { this.each(this._getToFields(pathGraph, pathLink, spreadLink), (toField, next) => { this._spreadFromSpreadLinkByPathLink(toField, spreadLink, pathGraph, pathLink, context, (error, id, prev, pathGraph, pathLink) => { if (handler) handler(error, id, prev, pathGraph, pathLink); next(); }); }, callback); } /** * Optional handler. * * @callback GraphSpreading~spreadFromSpreadLinkByPathLinkCallback * @param {Error} [error] * @param {string} [newSpreadLinkId] * @param {SpreadLink} [prevSpreadLink] * @param {PathGraph} [pathGraph] * @param {PathLink} [pathLink] */ /** * Optional callback. If present, called with an error object as the first argument and, if no error, the unique id of inserted spread link as the second. * * @callback GraphSpreading~spreadFromSpreadLinkByPathLinkCallback */ /** * Remove spreadLinks with specific prev spreadLink id. * * @param {string} spreadLinkId * @param {Object} [context] * @param {GraphSpreading~unspreadFromRemovedSpreadLinkByPrevIdHandler} [handler] * @param {GraphSpreading~unspreadFromRemovedSpreadLinkByPrevIdCallback} [callback] */ unspreadFromRemovedSpreadLinkByPrevId(spreadLinkId, context, handler, callback) { var query = { [this.spreadGraph.config.aliases.prev]: spreadLinkId, }; this._wrapSpreadQuery(query, context); if (handler) { this.spreadGraph.fetch(query, undefined, (error, spreadLinks) => { if (error) { if (callback) callback(error); } else { this.each(spreadLinks, (spreadLink, next) => { this.spreadGraph.remove(spreadLink[this.spreadGraph.config.aliases.id], (error, count) => { handler(error, spreadLink); next(); }, context); }, () => { if (callback) callback(undefined, spreadLinks.length); }); } }); } else { this.spreadGraph.remove(query, callback, context); } } /** * Optional handler. If present, called with an error object as the first argument and, if no error, others arguments with results of unspreading. * * @callback GraphSpreading~unspreadFromRemovedSpreadLinkByPrevIdHandler * @param {Error} [error] * @param {SpreadLink} [spreadLink] */ /** * Optional callback. * * @callback GraphSpreading~unspreadFromRemovedSpreadLinkByPrevIdCallback * @param {Error} [error] * @param {number} [count] */ /** * Remove spreadLinks with specific path pathLink id. * * @param {string} pathLinkId * @param {Object} [context] * @param {GraphSpreading~unspreadByPathIdHandler} [handler] * @param {GraphSpreading~unspreadByPathIdCallback} [callback] */ unspreadByPathId(pathLinkId, context, handler, callback) { var query = { [this.spreadGraph.config.aliases.path]: pathLinkId, }; this._wrapSpreadQuery(query, context); if (handler) { this.spreadGraph.fetch(query, undefined, (error, spreadLinks) => { if (error) { if (callback) callback(error); } else { this.each(spreadLinks, (spreadLink, next) => { this.spreadGraph.remove(spreadLink[this.spreadGraph.config.aliases.id], (error, count) => { handler(error, spreadLink); next(); }, context); }, () => { if (callback) callback(undefined, spreadLinks.length); }); } }); } else { this.spreadGraph.remove(query, callback, context); } } /** * Optional handler. * * @callback GraphSpreading~unspreadByPathIdHandler * @param {Error} [error] * @param {SpreadLink} [spreadLink] */ /** * Optional callback. * * @callback GraphSpreading~unspreadByPathIdCallback * @param {Error} [error] * @param {number} [count] */ /** * Unspread all valid spreadLinks to this id. * * @param {string} id * @param {Object} [context] * @param {GraphSpreading~unspreadToHandler} [handler] * @param {GraphSpreading~unspreadToCallback} [callback] */ unspread(id, context, handler, callback) { var query = { [this.spreadGraph.config.aliases[this.spreadGraph.variableField]]: id, }; this._wrapSpreadQuery(query, context); this.spreadGraph.fetch(query, undefined, (error, spreadLinks) => { if (error) { if (callback) callback(error); } else { this.each(spreadLinks, (spreadLink, next) => { this.spreadGraph._unspreadingHandler(spreadLink, context, (permission) => { if (permission) { this.spreadGraph.remove(spreadLink[this.spreadGraph.config.aliases.id], (error, count) => { if (handler) handler(error, spreadLink); next(); }, context); } }); }, () => { if (callback) callback(undefined, spreadLinks.length); }); } }); } /** * Optional handler. * * @callback GraphSpreading~unspreadToHandler * @param {Error} [error] * @param {SpreadLink} [spreadLink] */ /** * Optional callback. * * @callback GraphSpreading~unspreadToCallback */ /** * Spread all spread links from all available paths to this id. * * @param {string} id * @param {Object} [context] * @param {GraphSpreading~spreadToHandler} [handler] * @param {GraphSpreading~spreadToCallback} [callback] */ spreadTo(id, context, handler, callback) { this.each(this.pathGraphs, (pathGraph, nextPathGraph) => { this.each(this._getToFields(pathGraph), (toField, nextToField) => { var query = { [this.spreadGraph.config.aliases[toField]]: id, }; this._wrapPathQuery(query, pathGraph, undefined, toField, context); pathGraph.fetch(query, undefined, (error, pathLinks) => { this.each(pathLinks, (pathLink, nextPathLink) => { this.spreadByPathLink(pathGraph, pathLink, context, handler, nextPathLink); }, function(error) { nextToField(); }); }); }, nextPathGraph); }, () => { if (callback) callback(); }); } /** * Optional handler. Fires after each processed spread link. * Id can be empty if the `this.spreadGraph._spreadingHandler` banned spreading. * * @callback GraphSpreading~spreadToHandler * @param {Error} [error] * @param {string} [newSpreadLinkId] * @param {SpreadLink} [prevSpreadLink] * @param {PathGraph} [pathGraph] * @param {PathLink} [pathLink] */ /** * Optional callback. * * @callback GraphSpreading~spreadToCallback */ } export { GraphSpreading };</code></pre> </article> </section> </div> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Sun Dec 04 2016 20:09:10 GMT+0000 (UTC) using the Minami theme. </footer> <script>prettyPrint();</script> <script src="scripts/linenumber.js"></script> </body> </html>