UNPKG

state-updater-on-actions

Version:

Update a shared state by asynchronous actions which execute over a system which responds when the state isn't up to date and expose a refresh operation which returns the value which represents that updated state for enabling the action to proceed.

235 lines (197 loc) 7.5 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: state-updater.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: state-updater.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>/** * The state-updater-on-actions interface. * &lt;br>&lt;br> * &lt;b>NOTE this isn't a real class&lt;/b>, it's an interface because of JSDoc * limitations. * [Related StackOverflow thread]{@link https://stackoverflow.com/questions/23095975/jsdoc-object-methods-with-method-or-property} * * @name StateUpdaterOnActions * @class */ /** * Calls an action with the passed parameters. * * @method * @name StateUpdaterOnActions#call * @param {Action} action - The action to call. * @param {*} params - The parameters to pass to the action when it will be called. * @return {Promise} - The promise that the action returns, or if it returns a * promise with the value returned by the &lt;code>updateState&lt;/code>, it will * call the &lt;code>updateAction&lt;/code> function passed to the constructor by * parameter and if it returns a rejected promise, then it will be returned * such rejected promise. */ /** * Calls an action using the specified context (e.g obj.action()) and the * passed parameters. * * @method * @name StateUpdaterOnActions#callCtx * @param {Action} action - The action to call. * @param {*} ctx - The context to use for calling the action (i.e. `this` * pointer). * @param {*} params - The parameters to pass to the action when it will be called. * @return {Promise} - The promise that the action returns, or if it returns a * promise with the value returned by the &lt;code>updateState&lt;/code> method, it * will call the &lt;code>updateAction&lt;/code> function passed to the constructor * by parameter and if it returns a rejected promise then it will be returned * such rejected promise. */ /** * Returns the value which the actions must resolve their returned promises when * they require an state update. * * @method * @name StateUpdaterOnActions#updateState * @return {*} - The value DOES NOT matter as it's used internally to identify * that the update state action must be called. */ /** * Action is a function which returns a promise; in order to notify that the * state must be updated, it MUST return a resolved promise which the value * returned by the * [&lt;code>updateState&lt;/code> method of the &lt;code>StateUpdaterOnActions&lt;/code> instance which is used to call the action]{@link StateUpdaterOnActions#updateState}. * * @async * @typedef {Function} Action */ /** * Create an instance of state updater that uses an action function, which * doesn't require to be executed in any context (e.g. a method of an * object, or a function which use `this` pointer) and requires the passed * parameters. * * @param {Action} updateAction - The function which update the shared state * require by the actions which will be executed by the returned instance. * The function MUST return a promise. * @param {*} params - The parameters to pass to the &lt;code>updateAction&lt;/code> * each time that it will be executed. * @return {StateUpdaterOnActions} - The instance which will call the * &lt;code>updateAction&lt;/code> with the passed parameters when required. */ export function createStateUpdater (updateAction, ...params) { if (typeof updateAction !== 'function') { throw new TypeError('updateAction must be a function') } return create(updateAction, null, ...params) } /** * Create an instance of state updater that uses an action function, which * requires to be executed in any context (e.g. a method of an object, or a * function which use &lt;code>this&lt;/code> pointer) and requires the passed * parameters. * * @param {Action} updateAction - The function which update the shared state * require by the actions which will be executed by the returned instance. * The function MUST return a promise. * @param {*} ctx - The context to use for calling the action (i.e. * &lt;code>this&lt;/code> pointer). * @param {*} params - The parameters to pass to the &lt;code>updateAction&lt;/code> * each time that will be executed. * @return {StateUpdaterOnActions} - The instance which will call the * &lt;code>updateAction&lt;/code> with the passed parameters when required. */ export function createStateUpdaterCtx (updateAction, ctx, ...params) { if (typeof updateAction !== 'function') { throw new TypeError('updateAction must be a function') } if (!ctx) { switch (typeof ctx) { case 'undefined': throw new TypeError('context is required') case 'object': throw new TypeError('context cannot be null') } } return create(updateAction, ctx, ...params) } function create (updateAction, ctx, ...params) { // Empty object to have a reference to compare and detect that a updateState // has been called const updateID = {} let updatingPromise = null const updater = updateAction.bind(ctx, ...params) async function caller (action, ctx, ...params) { if (updatingPromise) { try { await updatingPromise } catch (err) { throw err } finally { updatingPromise = null } } let actPromise if (ctx === null) { actPromise = action(...params) } else { actPromise = action.call(ctx, ...params) } const res = await actPromise if (res !== updateID) { return res } if (!updatingPromise) { updatingPromise = updater() } return caller(action, ctx, ...params) } return { call: function (action, ...params) { if (typeof action !== 'function') { throw new TypeError('action must be a function') } return caller(action, null, ...params) }, callCtx: function (action, ctx, ...params) { if (typeof action !== 'function') { throw new TypeError('action must be a function') } if (!ctx) { switch (typeof ctx) { case 'undefined': throw new TypeError('context is required') case 'object': throw new TypeError('context cannot be null') } } return caller(action, ctx, ...params) }, updateState: function () { return updateID } } } </code></pre> </article> </section> </div> <nav> <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="StateUpdaterOnActions.html">StateUpdaterOnActions</a></li></ul><h3>Global</h3><ul><li><a href="global.html#createStateUpdater">createStateUpdater</a></li><li><a href="global.html#createStateUpdaterCtx">createStateUpdaterCtx</a></li></ul> </nav> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Mon May 07 2018 16:34:40 GMT+0000 (UTC) </footer> <script> prettyPrint(); </script> <script src="scripts/linenumber.js"> </script> </body> </html>