ancient-funicular
Version:
Just async mounting, updating and unmounting hierarchical carriages.
269 lines (213 loc) • 15.2 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Home - 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>
<li class="nav-link nav-home-link"><a href="index.html">Home</a></li><li class="nav-heading">Classes</li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="ancient-funicular.Carriage.html">Carriage</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ancient-funicular.Carriage.html#disable">disable</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ancient-funicular.Carriage.html#enable">enable</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ancient-funicular.Carriage.html#mount">mount</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ancient-funicular.Carriage.html#mountChild">mountChild</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ancient-funicular.Carriage.html#remount">remount</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ancient-funicular.Carriage.html#shouldRemount">shouldRemount</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ancient-funicular.Carriage.html#tieChild">tieChild</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ancient-funicular.Carriage.html#unique">unique</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ancient-funicular.Carriage.html#unmount">unmount</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ancient-funicular.Carriage.html#unmountChilds">unmountChilds</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ancient-funicular.Carriage.html#untieChild">untieChild</a></span></li><li class="nav-heading"><span class="nav-item-type type-class">C</span><span class="nav-item-name"><a href="ancient-funicular.Funicular.html">Funicular</a></span></li><li class="nav-item"><span class="nav-item-type type-function">F</span><span class="nav-item-name"><a href="ancient-funicular.Funicular.html#mount">mount</a></span></li><li class="nav-heading">Modules</li><li class="nav-heading"><span class="nav-item-type type-module">M</span><span class="nav-item-name"><a href="module-ancient-funicular.html">ancient-funicular</a></span></li><li class="nav-heading">Interfaces</li><li class="nav-heading"><span class="nav-item-type type-interface">I</span><span class="nav-item-name"><a href="module-ancient-funicular-CarriageListsByNames.html">CarriageListsByNames</a></span></li><li class="nav-heading"><span class="nav-item-type type-interface">I</span><span class="nav-item-name"><a href="module-ancient-funicular-CarriagesByIds.html">CarriagesByIds</a></span></li><li class="nav-heading"><span class="nav-item-type type-interface">I</span><span class="nav-item-name"><a href="module-ancient-funicular-CarriagesByNames.html">CarriagesByNames</a></span></li>
</nav>
<div id="main">
<section class="readme">
<article><h1>Funicular</h1><p><a href="https://badge.fury.io/js/ancient-funicular"><img src="https://badge.fury.io/js/ancient-funicular.svg" alt="npm version"></a>
<a href="https://gitter.im/AncientSouls/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img src="https://badges.gitter.im/Join%20Chat.svg" alt="Join the chat at https://gitter.im/AncientSouls/Lobby"></a></p>
<p>Executions with mount, unmount and update logics.</p>
<h2>Install</h2><pre class="prettyprint source lang-bash"><code>npm install --save ancient-funicular</code></pre><h2>Theory</h2><p>The carriage represents the period of life of some data. Coaches are named and not named. Unnamed carriages serve as the roots of a mointing tree. There can be as many as you need. Named carriages try to be unique.</p>
<p>To work with the carriages, it is necessary to prepare a class for <code>Funicular</code> and class <code>Carriage</code>.
You must override methods <code>enable</code> and<code>disable</code> in <code>Carriage</code>, that would describe what in your application means mount and unmount data.</p>
<pre class="prettyprint source lang-js"><code>import NativeFunicular from 'ancient-funicular';
import async from 'async';
var memory = {
a: { childs: ['b'] },
b: {},
};
class Funicular extends NativeFunicular {
constructor() {
super();
this.Carriage = extends class this.Carriage {
enable(callback) {
// Here it is necessary to subscribe to your data, get them and use the `carriage.mountChild` method to inform the parent carriage that this is her child.
// In code below we just gets childs from example memory.
if (this.data.childs) {
async.each(this.data.childs, (child, next) => {
this.mountChild(child, memory[child], (error) => {
next(error);
});
}, (error) => {
if (error) {
this.error = new Error('Broken child.');
each(this.childs, (child, next) => {
child.unmount();
}, () => {
callback();
});
} else {
// Place here, before callback, useful work of current parent carriage.
callback();
}
});
} else callback();
}
disable(callback) {
// Here it is necessary to unsubscribe of your data, forget and disable any processes.
}
}
}
}
var funicular = new Funicular();</code></pre><p>Any coach is created and tracked using the <code>funicular.mount</code>. Named carriages will not be mount again, they will be taken from memory. If carriage no longer matches the actual data, you can use <code>this.remount</code> from <code>enable</code> method. It mount new carriage of this name, and mark previously version of carriage as invalid.
Any unmounting occurs by calling <code>carriage.unmount</code>. Calling to <code>carriage.unmount</code> does not mean that it does happen.
This means that the coach will check whether there are other dependent parental carriage, and only if they are not exists, unmount self. If the carriage is unmount, it tries to unmount all her children. If childs do not have other parents, they too will be unmounted.</p>
<pre class="prettyprint source lang-js"><code>funicular.mount('a', memory.a,
// mountedCallback - Calls after this carriage fully mounted with childs.
(error, a) => {
a.id // 1
a.unique() // true
a.childs.b // Contains mounted b carriage.
a.childs.b.id // 2
funicular.namedCarriages.a[1] == a // true
funicular.namedCarriages.b[2] == a.childs.b // true
// We can try to unmount child, but it not work if parents still mounted.
a.childs.b.unmount();
a.remount();
},
// remountedCallback - Calls when called remount method, new carriage fully mounted and old carriage fully unmounted.
(unmountError, olda, mountError, newa) => {
olda.id // 1
olda.unique() // false
newa.id // 3
newa.unique() // true
olda.childs // After old carriage is unmounted, childs object clears.
newa.childs.b // New carriage contains mounted b carriage too.
newa.childs.b.id // 2 // Child not remount when parent is remounted.
funicular.namedCarriages.a[1] // undefined
funicular.namedCarriages.a[3] == newa // true
funicular.namedCarriages.b[2] == newa.childs.b // true
a.unmount(); // Unmount this parent with all childs if they not have other parents.
},
// unmountedCallback - Calls after this carriage fully unmunted (not remounted but namely unmounted)
(error, a) => {
a.id // 3
a.childs // After unmounted, childs object clears.
funicular.namedCarriages.a[1] // undefined
funicular.namedCarriages.a[3] // undefined
funicular.namedCarriages.b[2] // undefined
// All cariages are unmounted.
}
);</code></pre><p>In practice, it can be very useful to use unnamed carriages, which can also act as parents to other carriages, but can not be child of other carriages. Since the same class of <code>Carriage</code> is applied to it, data can be transmitted to it in the same form.</p>
<pre class="prettyprint source lang-js"><code>var memory = {
a: { childs: ['b'] },
b: {},
};
var funicular = new Funicular();
funicular.mount(undefined, { childs: ['a'] },
(error, root) => {
root.id // 1
root.childs.a.id // 2
root.childs.a.childs.b.id // 3
funicular.unnamedCarriages[1] == this // true
this.remount();
},
(unmountError, oldRoot, mountError, newRoot) => {
oldRoot.id // 1
newRoot.id // 4
newRoot.childs.a.id // 2
newRoot.childs.a.childs.b.id // 3
funicular.unnamedCarriages[1] // undefined
funicular.unnamedCarriages[4] == this // true
newRoot.unmount();
},
(error, root) => {
root.id // 4
funicular.unnamedCarriages[4] // undefined
}
);</code></pre><p>In this example, the data <code>a</code> will be remounted when the children are remounted.</p>
<pre class="prettyprint source lang-js"><code>var memory = {
a: { childs: ['b'], childRemount: true },
b: {},
};
var funicular = new Funicular();
funicular.Carriage = class extends funicular.Carriage {
// By default, this event is ignored, but it can be determined.
childDidRemount(unmountError, oldRoot, mountError, newRoot) {
this.remount();
}
};
funicular.mount('a', memory.a,
(error, a) => {
a.id // 1
a.childs.b.id // 2
a.childs.b.remount();
},
(unmountError, olda, mountError, newa) => {
newa.id // 4
newa.childs.b // 3
// Our `a` remounted.
newa.unmount();
},
(error, a) => {
// All unmounted.
}
);</code></pre><h2>Lifecycle</h2><ul>
<li><a href="https://ancientsouls.github.io/Funicular/Funicular.html#mount"><code>funicular.mount(name, data, mountedCallback, remoutedCallback, unmountedCallback)</code></a><ul>
<li><a href="https://ancientsouls.github.io/Funicular/Carriage.html"><code>var carriage = new funicular.Carriage(funicular, name, data)</code></a><ul>
<li><a href="https://ancientsouls.github.io/Funicular/Carriage.html#mount"><code>carriage.mount()</code></a><ul>
<li><a href="https://ancientsouls.github.io/Funicular/Carriage.html#enable"><code>carriage.enable(callback)</code></a> <strong>to override</strong><ul>
<li><code>carriage.mountedCallbacks</code> call all mount callback handlers of this carriage setted from multiple mounts</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="https://ancientsouls.github.io/Funicular/Carriage.html#remount"><code>carriage.remount()</code></a><ul>
<li><a href="https://ancientsouls.github.io/Funicular/Funicular.html#mount"><code>funicular.mount(name, data, mountedCallback, remoutedCallback, unmountedCallback)</code></a><ul>
<li><a href="https://ancientsouls.github.io/Funicular/Carriage.html#unmount"><code>carriage.unmount()</code></a><ul>
<li><code>carriage.remountedCallbacks</code> call all mount callback handlers of this carriage setted from multiple mounts</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="https://ancientsouls.github.io/Funicular/Funicular.html#unmount"><code>carriage.unmount()</code></a><ul>
<li><a href="https://ancientsouls.github.io/Funicular/Carriage.html#disable"><code>carriage.disable(callback)</code></a> <strong>to override</strong><ul>
<li><code>carriage.unmountedCallbacks</code> call all mount callback handlers of this carriage setted from multiple mounts</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>Errors</h2><p>If at any stage an error occurs it can be written in <code>carriage.error</code> or sended into callback in <code>enable</code> and <code>disable</code> methods. It is used as invalid carriage marker.</p>
<h2>Tests</h2><p>Tests can be started with comand <code>npm install ancient-funicular && cd ./node_modules/ancient-funicular && npm run compile && npm test</code>. For more information lern <a href="https://github.com/AncientSouls/Funicular/blob/master/src/tests/index.js">src/tests/index.js</a>.</p>
<h2>License</h2><p>The MIT License (MIT)
Copyright (c) 2016 Ivan S Glazunov <a href="mailto:ivansglazunov@gmail.com">ivansglazunov@gmail.com</a></p>
<p>Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:</p>
<p>The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.</p>
<p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</p></article>
</section>
</div>
<br class="clear">
<footer>
Generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> on Thu May 11 2017 11:27:05 GMT+0000 (UTC) using the Minami theme.
</footer>
<script>prettyPrint();</script>
<script src="scripts/linenumber.js"></script>
</body>
</html>