UNPKG

concern

Version:

A library for seperating your application logic into concerns.

369 lines (236 loc) 9.72 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: RefState.js</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="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <div id="main"> <h1 class="page-title">Source: RefState.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>import Promise from 'bluebird'; import beof from 'beof'; import Concern from './Concern'; import Context from './Context'; import StateProvider from './StateProvider'; import UnhandledMessage from './UnhandledMessage'; import ReceiveError from './ReceiveError'; import Signal from './Signal'; import IgnoredMessage from './IgnoredMessage'; import StoppedConcernError from './StoppedConcernError'; const keyify = function(msg) { switch (typeof msg) { case 'function': return msg.name; case 'object': return msg.constructor.name; default: return '' + msg; } } /** * RefState is really a Concern's state but because we abstract away the * state management to the Reference implementation subclasses of this class * refer to the state the Reference is in. * @abstract * @param {string} path * @param {Concern} concern * @param {Context} context * @param {StateProvider} states */ class RefState { constructor(path, concern, context, states) { beof({ path }).string(); beof({ concern }).interface(Concern); beof({ context }).interface(Context); beof({ states }).interface(StateProvider); this._path = path; this._concern = concern; this._context = context; this._states = states; } static equals(o, state) { //example //{ // type: 'state', // state: 'Active', // path: '/lib/tasks/generate_events.js#/main/posts/comments', //} if (typeof o === 'object') if (o.type === 'state') if (typeof o.path === 'string') if (o.state === state.name) return true; } path() { return this._path; } toString() { return JSON.stringify({ type: 'state', state: this.constructor.name, path: this.path() }); } } /** * Paused */ class Paused extends RefState { constructor(path, concern, context, states) { super(path, concern, context, states); this._q = []; } getState(m) { var nextState = this; if (m instanceof Signal.Resume) { nextState = new this._states.provide(RefState.ACTIVE_STATE, this._path, this._concern, this._context); return Promise.resolve(this._q). each((mcb) => mcb(nextState)). then(() => nextState); } if (m instanceof Signal.Stop) return Promise.resolve(this._states.provide(RefState.STOPPED_STATE, this._path, this._concern, this._context)); return Promise.resolve(nextState); } accept(msg, sender) { this._q.push(function do_accept(active) { active.accept(msg, sender); }); } acceptAndPromise(msg, sender) { var q = this._q; return new Promise(function accept_and_promise_promise_fn(resolve, reject) { q.push(function do_accept_and_promise(active) { return resolve(active.acceptAndPromise(msg, sender)); }); }); } } /** * Active represents the Concern in an active state, meaning it is able to * do whatever it was created to do. From this state the Concern can * become Paused or Stopped. * */ class Active extends RefState { action(msg, sender) { return receiver.receive(msg, sender); } _handle(sender, msg, receiver) { var actions = this.action(msg, sender); var action; if (!actions) return null; if (typeof actions === 'object') action = actions[keyify(msg)]; if (typeof actions === 'function') action = actions; if (typeof action === 'function') return action(msg, sender); return null; } getState(m) { var nextState = this; if (m instanceof Signal.Pause) nextState = this._states.provide(RefState.PAUSED_STATE, this._path, this._concern, this._context); if (m instanceof Signal.Stop) nextState = this._states.provide(RefState.STOPPED_STATE, this._path, this._concern, this._context); return Promise.resolve(nextState); } accept(msg, sender) { this._promise = this.acceptAndPromise(msg, sender); this._promise.catch(e => this._context.publish(new ReceiveError(e, sender, msg, this))); } acceptAndPromise(msg, sender) { return this._promise = this._promise. then(Promise.resolve(this._handle(sender, msg, this._concern))); } } /** * Ready */ class Ready extends RefState { getState(m) { var nextState = this; if (m instanceof Signal.Start) { nextState = this._states.provide(RefState.ACTIVE_STATE, this._path, this._concern, this._context); return Promise.resolve(this._concern.onStart()).then(() => nextState); } if (m instanceof Signal.Stop) return this._states.provide(RefState.STOPPED_STATE, this._path, this._concern, this._context); return nextState; } accept(msg, sender) { this._context.publish(new IgnoredMessage(sender, msg, this._concern)); } acceptAndPromise(msg, sender) { return Promise.resolve(this.accept(msg, sender)); } } /** * Stopped */ class Stopped extends RefState { accept(msg, sender) { this._context.publish(new StoppedConcernError(sender, msg, this._concern)); } acceptAndPromise(msg, sender) { return Promise.resolve(this.accept(msg, sender)); } } /** * Unknown represents the state Concern we could not find or don't know about. * This state can not transition to another state and serves only to avoid * throwing errors. */ class Unknown extends RefState { getState(m) { return Promise.resolve(this); } accept(msg, sender) { this._context.publish(new IgnoredMessage(sender, msg, this._concern)); } acceptAndPromise(msg, sender) { return Promise.resolve(this.accept(msg, sender)); } } RefState.Ready = Ready; RefState.Active = Active; RefState.Paused = Paused; RefState.Stopped = Stopped; RefState.Unknown = Unknown; RefState.ACTIVE_STATE = 'Active'; RefState.READY_STATE = 'Ready'; RefState.PAUSED_STATE = 'Paused'; RefState.STOPPED_STATE = 'Stopped'; RefState.UNKNOWN_STATE = 'Unknown'; export default RefState </code></pre> </article> </section> </div> <nav> <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Active.html">Active</a></li><li><a href="Address.html">Address</a></li><li><a href="ChildActiveState.html">ChildActiveState</a></li><li><a href="ChildReference.html">ChildReference</a></li><li><a href="ChildReferenceProvider.html">ChildReferenceProvider</a></li><li><a href="ChildStateProvider.html">ChildStateProvider</a></li><li><a href="Envelope.html">Envelope</a></li><li><a href="IgnoredMessage.html">IgnoredMessage</a></li><li><a href="InvalidMessageError.html">InvalidMessageError</a></li><li><a href="MailDispatcher.html">MailDispatcher</a></li><li><a href="MemoryStateProvider.html">MemoryStateProvider</a></li><li><a href="ParentReference.html">ParentReference</a></li><li><a href="Pause.html">Pause</a></li><li><a href="Paused.html">Paused</a></li><li><a href="ProcessRouter.html">ProcessRouter</a></li><li><a href="Ready.html">Ready</a></li><li><a href="ReceiveError.html">ReceiveError</a></li><li><a href="Reference.html">Reference</a></li><li><a href="RefState.html">RefState</a></li><li><a href="RemoteMessage.html">RemoteMessage</a></li><li><a href="RemoteteTerminatedError.html">RemoteteTerminatedError</a></li><li><a href="Resume.html">Resume</a></li><li><a href="Signal.html">Signal</a></li><li><a href="SimpleMailBox.html">SimpleMailBox</a></li><li><a href="SpawnChildProcessError.html">SpawnChildProcessError</a></li><li><a href="Start.html">Start</a></li><li><a href="Stop.html">Stop</a></li><li><a href="Stopped.html">Stopped</a></li><li><a href="StoppedConcernError.html">StoppedConcernError</a></li><li><a href="System.html">System</a></li><li><a href="UnhandledMessage.html">UnhandledMessage</a></li><li><a href="Unknown.html">Unknown</a></li></ul><h3>Interfaces</h3><ul><li><a href="Concern.html">Concern</a></li><li><a href="Context.html">Context</a></li><li><a href="EnqueueListener.html">EnqueueListener</a></li><li><a href="MailBox.html">MailBox</a></li><li><a href="ReferenceProvider.html">ReferenceProvider</a></li><li><a href="StateProvider.html">StateProvider</a></li></ul> </nav> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.0-dev</a> on Mon Sep 26 2016 02:55:49 GMT-0400 (AST) </footer> <script> prettyPrint(); </script> <script src="scripts/linenumber.js"> </script> </body> </html>