| 
									
										
										
										
											2016-08-26 06:00:19 +03:00
										 |  |  | # Actions
 | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Actions are an extension to the JavaScript object model tailored for | 
					
						
							|  |  |  | a set of specific tasks. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-25 01:59:52 +03:00
										 |  |  | To distinguish this from the native JavaScript elements we introduce new | 
					
						
							|  |  |  | terminology, an _action_ is an extended _method_ while an _action set_ is | 
					
						
							|  |  |  | a _mixin object_ (stateless, including only functionality) both usable  | 
					
						
							|  |  |  | stand-alone as well as _mixed_ into other objects. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Here is a trivial use-case to illustrate the motivation for this tool set: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-23 18:04:43 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-24 02:08:20 +03:00
										 |  |  | #### The problem:
 | 
					
						
							| 
									
										
										
										
											2016-08-24 00:48:40 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | ```javascript | 
					
						
							|  |  |  | var N = { | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |     times: function(n){ | 
					
						
							|  |  |  |         this.value *= n | 
					
						
							|  |  |  |         return this | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-08-24 00:48:40 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var n = Object.create(N) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-24 01:17:27 +03:00
										 |  |  | n.value = 3 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-24 01:55:46 +03:00
										 |  |  | n | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |     .times(3) | 
					
						
							|  |  |  |     .times(2) | 
					
						
							| 
									
										
										
										
											2016-08-24 01:17:27 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-24 00:48:40 +03:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | To extend this object we'll need to: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-24 01:17:27 +03:00
										 |  |  | ```javascript | 
					
						
							|  |  |  | n.times = function(n){ | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |     console.log(this.value, 'times', n) | 
					
						
							| 
									
										
										
										
											2016-08-24 01:17:27 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |     var res = N.times.call(this, n) | 
					
						
							| 
									
										
										
										
											2016-08-24 01:17:27 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |     console.log('    ->', this.value) | 
					
						
							|  |  |  |     return res | 
					
						
							| 
									
										
										
										
											2016-08-24 01:17:27 +03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-08-24 00:48:40 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-24 01:17:27 +03:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Note that we are manually calling the _super_ method and manually  | 
					
						
							| 
									
										
										
										
											2016-08-24 02:16:40 +03:00
										 |  |  | returning and re-returning `this` in each implementation of `.times(..)`. | 
					
						
							| 
									
										
										
										
											2016-08-24 01:17:27 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | Another thing to note here is that the code above, though quite simple is | 
					
						
							|  |  |  | not reusable, i.e.: | 
					
						
							|  |  |  | - we can't simply use the extending method for any other parent unless we | 
					
						
							|  |  |  |   either copy/rewrite it or complicate the code. | 
					
						
							| 
									
										
										
										
											2017-07-03 02:34:24 +03:00
										 |  |  |   ES5/ES6 only partially fixes this issue as `super` can only be used in  | 
					
						
							|  |  |  |   some cases (literal methods) and not others (functions and functions as | 
					
						
							|  |  |  |   methods) which complicates things and makes them non-uniform.  | 
					
						
							| 
									
										
										
										
											2016-08-24 01:17:27 +03:00
										 |  |  | - we can't use the extending method stand-alone, for example for testing | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-24 03:05:40 +03:00
										 |  |  | It is possible to go around these issues but not without introducing | 
					
						
							|  |  |  | complicated and/or redundant code, _Actions_ implements one approach to | 
					
						
							|  |  |  | abstract this... | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-24 01:17:27 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-24 02:08:20 +03:00
										 |  |  | #### The solution:
 | 
					
						
							| 
									
										
										
										
											2016-08-24 01:17:27 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-25 01:59:52 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-24 01:17:27 +03:00
										 |  |  | ```javascript | 
					
						
							|  |  |  | var N = Actions({ | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |     // Notice the brackets around the function... | 
					
						
							|  |  |  |     times: [function(n){ | 
					
						
							|  |  |  |         this.value *= n | 
					
						
							|  |  |  |     }] | 
					
						
							| 
									
										
										
										
											2016-08-24 01:17:27 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-24 02:16:40 +03:00
										 |  |  | // Now we extend .times(..) | 
					
						
							| 
									
										
										
										
											2016-08-24 01:55:46 +03:00
										 |  |  | var ExtendedN = Actions({ | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |     times: [function(n){ | 
					
						
							|  |  |  |         console.log(this.value, 'times', n) | 
					
						
							| 
									
										
										
										
											2016-08-24 01:17:27 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |         return function(){ | 
					
						
							|  |  |  |             console.log('    ->', this.value) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }] | 
					
						
							| 
									
										
										
										
											2016-08-24 01:17:27 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | And both objects can be used in the same way as before: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```javascript | 
					
						
							| 
									
										
										
										
											2016-08-24 03:14:23 +03:00
										 |  |  | var n = mix(N, ExtendedN) // or Object.create(N) or Object.create(ExtendedN)... | 
					
						
							| 
									
										
										
										
											2016-08-24 01:17:27 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | n.value = 3 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-24 01:55:46 +03:00
										 |  |  | n | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |     .times(3) | 
					
						
							|  |  |  |     .times(2) | 
					
						
							| 
									
										
										
										
											2016-08-24 01:17:27 +03:00
										 |  |  | ``` | 
					
						
							| 
									
										
										
										
											2016-08-24 00:48:40 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-24 02:16:40 +03:00
										 |  |  | - `this` is returned automatically enabling us to chain calls to `.times(..)` | 
					
						
							|  |  |  | - the _super_ method is resolved and called automatically | 
					
						
							|  |  |  | - both `N` and `ExtendedN` are independent of each other and reusable  | 
					
						
							|  |  |  |   in different inheritance chains without any extra work needed. | 
					
						
							|  |  |  | - _and more... (see below)_ | 
					
						
							| 
									
										
										
										
											2016-08-24 01:55:46 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-24 00:48:40 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-24 02:16:40 +03:00
										 |  |  | ### What we get:
 | 
					
						
							| 
									
										
										
										
											2016-08-24 03:52:17 +03:00
										 |  |  | - **Call parent (_extended_) actions automatically**   | 
					
						
							| 
									
										
										
										
											2016-08-23 18:28:06 +03:00
										 |  |  |   All actions (methods) in a chain are guaranteed to get called if the  | 
					
						
							|  |  |  |   action is called. | 
					
						
							|  |  |  | - **Thread arguments up the call chain**   | 
					
						
							|  |  |  |   All actions in a chain will get the set of arguments passed to the  | 
					
						
							|  |  |  |   action when called. | 
					
						
							|  |  |  | - **Thread the return value down the call chain**   | 
					
						
							|  |  |  |   The return value will get passed through all the actions in a chain  | 
					
						
							|  |  |  |   before returning to the action caller. | 
					
						
							| 
									
										
										
										
											2016-08-24 02:43:51 +03:00
										 |  |  | - **Return `this` by default** | 
					
						
							| 
									
										
										
										
											2016-08-24 04:10:56 +03:00
										 |  |  | - **Organise and reuse actions**   | 
					
						
							| 
									
										
										
										
											2016-08-24 03:17:45 +03:00
										 |  |  |   Actions organized into action sets can be reused (_mixed-in_) in multiple | 
					
						
							|  |  |  |   inheritance chains without any extra work. | 
					
						
							| 
									
										
										
										
											2016-08-23 18:28:06 +03:00
										 |  |  | - **Unified way to document actions** | 
					
						
							|  |  |  | - **Introspection and inspection API** | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-23 18:42:38 +03:00
										 |  |  | ### Restrictions comparing to native JavaScript:
 | 
					
						
							| 
									
										
										
										
											2016-08-23 18:04:43 +03:00
										 |  |  | - **No method shadowing**   | 
					
						
							|  |  |  |   The _extending_ action can not "shadow" the _extended_ action in a  | 
					
						
							| 
									
										
										
										
											2016-08-23 18:10:59 +03:00
										 |  |  |   non destructive manner (e.g. via a `throw`), all actions in a chain are  | 
					
						
							| 
									
										
										
										
											2016-08-23 18:04:43 +03:00
										 |  |  |   guaranteed to be called, unless a fatal error condition. | 
					
						
							|  |  |  | - **No argument shadowing**   | 
					
						
							| 
									
										
										
										
											2016-09-27 15:45:23 +03:00
										 |  |  |   The _extending_ action has access to all the arguments that the user  | 
					
						
							|  |  |  |   passed but can not modify or reformat them before the _extended_ action | 
					
						
							|  |  |  |   gets them. | 
					
						
							| 
									
										
										
										
											2016-08-24 03:14:23 +03:00
										 |  |  | - **No return shadowing / Single return point**   | 
					
						
							| 
									
										
										
										
											2016-08-23 18:04:43 +03:00
										 |  |  |   The _extending_ action can not replace the object returned by the  | 
					
						
							| 
									
										
										
										
											2016-08-23 18:10:59 +03:00
										 |  |  |   _extended_ action, though it can _cooperatively_ update/modify it if  | 
					
						
							| 
									
										
										
										
											2016-08-24 03:14:23 +03:00
										 |  |  |   needed. | 
					
						
							|  |  |  |   Only the _root_ action can return a value, any other returns in chain | 
					
						
							|  |  |  |   are ignored | 
					
						
							| 
									
										
										
										
											2016-08-24 02:43:51 +03:00
										 |  |  | - **No state transferred via mixin**   | 
					
						
							|  |  |  |   The only two things _inherited_ from the object defining the actions  | 
					
						
							| 
									
										
										
										
											2017-09-13 01:39:45 +03:00
										 |  |  |   via the mixin methods or `mix` function are properties and methods/actions,  | 
					
						
							|  |  |  |   all data is discarded.   | 
					
						
							| 
									
										
										
										
											2016-08-23 18:10:59 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-25 01:59:52 +03:00
										 |  |  | **Notes:** | 
					
						
							|  |  |  | - By design this tool-set promotes a _cooperative_ model and makes it | 
					
						
							|  |  |  |   hard to change/modify existing signatures / _contracts_ in _extending_  | 
					
						
							|  |  |  |   code, hence the restrictions. | 
					
						
							| 
									
										
										
										
											2016-08-28 01:23:03 +03:00
										 |  |  | - `mix(..)` and the `.mix*(..)` (MetaActions/ActionSet) method family  | 
					
						
							| 
									
										
										
										
											2016-08-27 14:46:55 +03:00
										 |  |  |   usually copy references to actions to the target object, this is done  | 
					
						
							|  |  |  |   to go around the lack of multiple inheritance support in JavaScript  | 
					
						
							|  |  |  |   and to enable clean action set reuse. | 
					
						
							| 
									
										
										
										
											2016-09-27 16:02:35 +03:00
										 |  |  | - `mix(..)` _mixes_ actions in order, i.e. later overloads the former, | 
					
						
							|  |  |  |   this is not the same as the traditional multiple inheritance order in  | 
					
						
							|  |  |  |   languages such as Python where the order is reversed. | 
					
						
							| 
									
										
										
										
											2016-08-27 01:39:16 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-25 01:59:52 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | ### The main entities:
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-23 18:59:19 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | **Action set** | 
					
						
							| 
									
										
										
										
											2016-08-24 02:54:25 +03:00
										 |  |  | ```javascript | 
					
						
							|  |  |  | var empty_full = new ActionSet() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var minimal = Actions({ | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |     // action and prop definitions... | 
					
						
							| 
									
										
										
										
											2016-08-24 02:54:25 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var full = Actions(ActionSet(), { | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |     // ... | 
					
						
							| 
									
										
										
										
											2016-08-24 02:54:25 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var inherited = Actions(full, { | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |     // ... | 
					
						
							| 
									
										
										
										
											2016-08-24 02:54:25 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2016-08-23 18:59:19 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | - an object containing a number of actions, | 
					
						
							| 
									
										
										
										
											2016-08-23 17:31:06 +03:00
										 |  |  | - optionally, directly or indirectly inherited from `MetaActions` | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  |   and/or other action sets, | 
					
						
							| 
									
										
										
										
											2016-08-23 17:31:06 +03:00
										 |  |  | - the action handlers are bound relative to it (`._action_handlers`) | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | **Action** | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-24 02:57:44 +03:00
										 |  |  | Defined inside an action-set: | 
					
						
							| 
									
										
										
										
											2016-08-24 02:43:51 +03:00
										 |  |  | ```javascript | 
					
						
							|  |  |  |     // ... | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     minimal: [function(){ | 
					
						
							|  |  |  |         // ... | 
					
						
							| 
									
										
										
										
											2016-08-24 02:43:51 +03:00
										 |  |  |     }], | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |     full: ['Short info string', | 
					
						
							|  |  |  |         'Long documentation string, describing the action (optional)', | 
					
						
							|  |  |  |         function(){ | 
					
						
							|  |  |  |             // pre code | 
					
						
							|  |  |  |             //    run before the parent action... | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |             return function(res){ | 
					
						
							|  |  |  |                 // post code | 
					
						
							|  |  |  |                 //     run after the parent action or directly after  | 
					
						
							|  |  |  |                 //     the pre-code of this is the root action... | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // ... | 
					
						
							| 
									
										
										
										
											2016-08-24 02:43:51 +03:00
										 |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The call diagram: | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | ``` | 
					
						
							|  |  |  |                         +  pre  +  pre  +       +  post +  post + | 
					
						
							|  |  |  | Action event handler:   o-------x                       o-------x | 
					
						
							|  |  |  |                                 v                       ^ | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | Actions:                        o-------x       o-------x | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  |                                         v       ^ | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | Root Action:                            o---|---x | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-03 02:34:24 +03:00
										 |  |  | - `Action(..)` creates a method (an _action_), | 
					
						
							|  |  |  | - an _action_ calls all the shadowed/overloaded actions in the inheritance  | 
					
						
							| 
									
										
										
										
											2016-08-23 21:49:58 +03:00
										 |  |  |   chain in sequence implicitly,   | 
					
						
							| 
									
										
										
										
											2016-08-23 21:49:36 +03:00
										 |  |  |   **Notes:**    | 
					
						
							|  |  |  |     - there is no way to prevent an action in the chain from | 
					
						
							|  |  |  | 		  running, this is by design, i.e. no way to fully shadow. | 
					
						
							| 
									
										
										
										
											2017-07-03 02:34:24 +03:00
										 |  |  | - top actions in the inheritance chain are called _base_ or _root actions_. | 
					
						
							|  |  |  | - an action returns the action set (`this`) by default (for call chaining), | 
					
						
							| 
									
										
										
										
											2016-08-23 21:49:58 +03:00
										 |  |  | - the base/root action can return any value.   | 
					
						
							| 
									
										
										
										
											2016-08-23 21:49:36 +03:00
										 |  |  |   **Notes:**   | 
					
						
							|  |  |  |     - if undefined is returned, it will be replaced by the  | 
					
						
							| 
									
										
										
										
											2018-10-25 17:35:58 +03:00
										 |  |  | 		  action context/action set, | 
					
						
							|  |  |  | 	- if a function is returned it is treated as a post phase action, | 
					
						
							|  |  |  | 	- to return a reserved value (undefined, function) wrap it in  | 
					
						
							|  |  |  | 		  `actions.ASIS(..)` | 
					
						
							|  |  |  | 	- any other return value is returned as-is, | 
					
						
							| 
									
										
										
										
											2016-08-23 21:49:36 +03:00
										 |  |  |     - there is no distinction between root and other actions | 
					
						
							|  |  |  | 		  other than that root action's return values are not  | 
					
						
							|  |  |  | 		  ignored. | 
					
						
							| 
									
										
										
										
											2017-10-08 18:01:13 +03:00
										 |  |  | - if the root action returns a `Promise`, the post phase is run  | 
					
						
							|  |  |  |   when that promise is resolved or rejected. This can be disabled by  | 
					
						
							|  |  |  |   setting the 'await' action attribute to `false` (default: `true`). | 
					
						
							| 
									
										
										
										
											2017-07-03 02:34:24 +03:00
										 |  |  | - an action can consist of two parts: the first is called before the  | 
					
						
							|  |  |  |   next action in chain (_pre-callback_) and the second after (_post-callback_). | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | - post-callback has access to the return value and can modify it | 
					
						
							|  |  |  |   but not replace it. | 
					
						
							| 
									
										
										
										
											2017-07-03 02:34:24 +03:00
										 |  |  | - an action can be bound to, a-la an event, calling the handlers when it is  | 
					
						
							| 
									
										
										
										
											2016-08-24 03:14:23 +03:00
										 |  |  |   called (_see below_),  | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | **Action (event) handler** | 
					
						
							| 
									
										
										
										
											2016-08-24 02:57:44 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | When `actionSet` object is inherited from a `ActionSet` object or  | 
					
						
							| 
									
										
										
										
											2016-08-24 02:57:44 +03:00
										 |  |  | from `MetaActions`: | 
					
						
							| 
									
										
										
										
											2016-08-24 02:54:25 +03:00
										 |  |  | ```javascript | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | actionSet.on('action_name', function(){ | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |     // post code... | 
					
						
							| 
									
										
										
										
											2016-08-24 02:54:25 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | actionSet.on('action_name.post', function(){ | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |     // post code... | 
					
						
							| 
									
										
										
										
											2016-08-24 02:54:25 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | actionSet.on('action_name.pre', function(){ | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |     // pre code... | 
					
						
							| 
									
										
										
										
											2016-08-24 02:54:25 +03:00
										 |  |  | }) | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-03 02:34:24 +03:00
										 |  |  | - a handler is a function, | 
					
						
							|  |  |  | - it can be bound to run before and/or after the action itself, | 
					
						
							|  |  |  | - it is local to an action set it was bound via, | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | - when an action is triggered from an action set, all the pre  | 
					
						
							|  |  |  |   handlers in its inheritance chain will be called before the  | 
					
						
							|  |  |  |   respective actions they are bound to and all the post handlers | 
					
						
							|  |  |  |   are called directly after. | 
					
						
							|  |  |  | - pre handlers are passed the same arguments the original actions | 
					
						
							|  |  |  |   got when it was called. | 
					
						
							|  |  |  | - post action handlers will get the root action result as first  | 
					
						
							|  |  |  |   argument succeeded by the action arguments. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 05:11:31 +03:00
										 |  |  | **Alias** | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 05:29:06 +03:00
										 |  |  | ```javascript | 
					
						
							|  |  |  |     fullAlias: ['Alias to .full(..) action...', | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  |         `This alias will call the .full(..) action and pass it a couple of | 
					
						
							|  |  |  |         arguments`, | 
					
						
							| 
									
										
										
										
											2017-09-12 05:30:08 +03:00
										 |  |  |         // the alias code... | 
					
						
							| 
									
										
										
										
											2017-09-12 05:29:06 +03:00
										 |  |  |         'full: "argument" 1'], | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 05:11:31 +03:00
										 |  |  | - an action created by `Alias(..)`, | 
					
						
							|  |  |  | - identical to an action with one key difference: instead of a  | 
					
						
							|  |  |  |   function `Alias(..)` expects a string/code, | 
					
						
							|  |  |  | - code syntax is configurable, defaulting to the defined by | 
					
						
							|  |  |  |   `parseActionCall(..)`, | 
					
						
							|  |  |  | - aliases are designed to be defined and managed in runtime while | 
					
						
							|  |  |  |   actions are mainly load-time entities. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 05:29:06 +03:00
										 |  |  | XXX add doc about the code format... | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | ### The action system main protocols:
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-24 02:08:20 +03:00
										 |  |  | By default `Actions(..)` defines no additional methods. Most of the API | 
					
						
							|  |  |  | methods are defined in `MetaActions` and can be optionally inherited  | 
					
						
							|  |  |  | from an instance of `ActionSet`. In general this includes all | 
					
						
							|  |  |  | `ActionSet / object` level methods while anything accessible from the  | 
					
						
							|  |  |  | _action_ is build-in. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | #### 1. Documentation generation and introspection (`MetaActions`)
 | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | ``` | 
					
						
							|  |  |  | <action>.toString() | 
					
						
							|  |  |  |     -> code of original action function | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | <action-set>.getDoc() | 
					
						
							|  |  |  | <action-set>.getDoc(<action-name>[, ..]) | 
					
						
							|  |  |  |     -> dict of action-name, doc | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | <action-set>.getHandlerDocStr(<action-name>) | 
					
						
							|  |  |  |     -> formated string of action handlers | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | <action-set>.actions | 
					
						
							|  |  |  |     -> list of action names | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | #### 2. Event-like callbacks for actions (`MetaActions`, `Action`)
 | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | ``` | 
					
						
							|  |  |  | <action-set>.on('action', function(){ ... }) | 
					
						
							|  |  |  | <action-set>.on('action.post', function(){ ... }) | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | <action-set>.on('action.pre', function(){ ... }) | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | #### 3. A mechanism to define and extend already defined actions
 | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | This replaces / complements the standard JavaScript overloading  | 
					
						
							|  |  |  | mechanisms (`Action`, `Actions`) | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | ```javascript | 
					
						
							|  |  |  | // Actions... | 
					
						
							|  |  |  | var X = Actions({ | 
					
						
							|  |  |  |     m: [function(){ console.log('m') }] | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | var O = Actions(X, { | 
					
						
							|  |  |  |     m: [function(){ | 
					
						
							|  |  |  |         console.log('pre') | 
					
						
							|  |  |  |         return function(res){ | 
					
						
							|  |  |  |             console.log('post') | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }] | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | **Notes:** | 
					
						
							|  |  |  | - what is done here is similar to calling `O.__proto__.m.call(..)` | 
					
						
							|  |  |  |   but is implicit, and not dependant on the original containing  | 
					
						
							|  |  |  |   object name/reference (`O`), thus enabling an action to be  | 
					
						
							|  |  |  |   referenced and called from any object and still chain correctly. | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ### Secondary action protocols:
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | #### 1. A mechanism to manually call the pre/post stages of an action
 | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | Pre phase... | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | <action>.pre(<context>) | 
					
						
							|  |  |  | <action>.pre(<context>, [<arg>, ..]) | 
					
						
							|  |  |  |     -> <call-data> | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | Post phase... | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | <action>.post(<context>, <call-data>) | 
					
						
							|  |  |  |     -> <result> | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | This is internally used to implement the action call as well as the | 
					
						
							|  |  |  | chaining callbacks (see below). | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | All action protocol details apply. | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | **Notes:** | 
					
						
							|  |  |  | - there is no reliable way to call the post phase without first | 
					
						
							|  |  |  |   calling the pre phase due to how the pre phase is defined (i.e. | 
					
						
							|  |  |  |   pre phase functions can return post phase functions). | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | #### 2. A mechanism to chain/wrap actions or an action and a function.
 | 
					
						
							|  |  |  | This enables us to call a callback or another action (inner) between  | 
					
						
							|  |  |  | the root action's (outer) pre and post stages. | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | ``` | 
					
						
							|  |  |  | Outer action                o-------x       o-------x | 
					
						
							|  |  |  |                                     v       ^ | 
					
						
							|  |  |  | Inner action/callback               o---|---x | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2016-08-23 17:25:55 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | A trivial example: | 
					
						
							| 
									
										
										
										
											2016-08-23 17:25:55 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | ```javascript | 
					
						
							|  |  |  | actionSet.someAction.chainApply(actionsSet,  | 
					
						
							|  |  |  |     function(){ | 
					
						
							|  |  |  |         // this gets run between someAction's pre and post  | 
					
						
							|  |  |  |         // stages... | 
					
						
							|  |  |  |     },  | 
					
						
							|  |  |  |     args) | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2016-08-23 17:25:55 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | This is intended to implement protocols where a single action is | 
					
						
							|  |  |  | intended to act as a hook point (outer) and multiple different  | 
					
						
							|  |  |  | implementations (inner) within a single action set can be used as | 
					
						
							|  |  |  | entry points. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ```javascript | 
					
						
							|  |  |  |     // Protocol root action (outer) definition... | 
					
						
							|  |  |  |     protocolAction: [function(){}], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Implementation actions (inner)... | 
					
						
							|  |  |  |     implementationAction1: [function(){ | 
					
						
							|  |  |  |         return this.protocolAction.chainApply(this, function(){ | 
					
						
							|  |  |  |             ... | 
					
						
							|  |  |  |         }, ..) | 
					
						
							|  |  |  |     }], | 
					
						
							| 
									
										
										
										
											2016-08-23 17:25:55 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  |     implementationAction2: [function(){ | 
					
						
							|  |  |  |         return this.protocolAction.chainApply(this, function(){ | 
					
						
							|  |  |  |             ... | 
					
						
							|  |  |  |         }, ..) | 
					
						
							|  |  |  |     }], | 
					
						
							|  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2016-08-23 17:25:55 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | Now calling any of the 'implementation' actions will execute code | 
					
						
							|  |  |  | in the following order: | 
					
						
							|  |  |  | 1. pre phase of protocol action (outer) | 
					
						
							|  |  |  | 2. implementation action (inner) | 
					
						
							|  |  |  | 3. post phase of protocol action (outer) | 
					
						
							| 
									
										
										
										
											2016-08-23 17:25:55 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | **Notes:** | 
					
						
							|  |  |  | - this will not affect to protocol/signature of the outer action | 
					
						
							|  |  |  |   in any way. | 
					
						
							|  |  |  | - both the inner and outer actions will get passed the same  | 
					
						
							|  |  |  |   arguments. | 
					
						
							|  |  |  | - another use-case is testing/debugging actions. | 
					
						
							|  |  |  | - this is effectively the inside-out of normal action overloading. | 
					
						
							|  |  |  | - there is intentionally no shorthand for this feature, to avoid  | 
					
						
							|  |  |  |   confusion and to discourage the use of this feature unless | 
					
						
							|  |  |  |   really necessary. | 
					
						
							| 
									
										
										
										
											2016-08-23 17:25:55 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | #### 3. `.__call__` action / handler
 | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | This action if defined is called for every action called. It behaves | 
					
						
							|  |  |  | like any other action but with a fixed signature, it always receives  | 
					
						
							|  |  |  | the action name as first argument and a list of action arguments as | 
					
						
							|  |  |  | the second arguments, and as normal a result on the post phase. | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | **Notes:** | 
					
						
							|  |  |  | - it is not necessary to define the actual action, binding to a | 
					
						
							|  |  |  |   handler will also work. | 
					
						
							|  |  |  | - one should not call actions directly from within a __call__  | 
					
						
							|  |  |  |   handler as that will result in infinite recursion.   | 
					
						
							|  |  |  | - one should use this with extreme care as this will introduce  | 
					
						
							|  |  |  |   an overhead on all the actions if not done carefully. | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 05:11:31 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | #### 4. Action attributes
 | 
					
						
							| 
									
										
										
										
											2017-09-12 05:11:31 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | XXX | 
					
						
							| 
									
										
										
										
											2017-10-08 18:01:13 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-12 02:10:53 +03:00
										 |  |  | ``` | 
					
						
							|  |  |  | <action-set>.getActionAttr('action', 'attr') | 
					
						
							|  |  |  |     -> <value> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <action-set>.getRootActionAttr('action', 'attr') | 
					
						
							|  |  |  |     -> <value> | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #### 5. Scheduling a call after the running action
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This enables the action code to schedule a call after the current  | 
					
						
							|  |  |  | action level or the root action is done. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | <action-set>.afterAction(func) | 
					
						
							|  |  |  | <action-set>.afterAction('top', func) | 
					
						
							|  |  |  |     -> this | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <action-set>.afterAction('local', func) | 
					
						
							|  |  |  |     -> this | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Example: | 
					
						
							|  |  |  | ```javascript | 
					
						
							|  |  |  |     someAction: [ | 
					
						
							|  |  |  |         function(){ | 
					
						
							|  |  |  |             ... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // the function passed will get called after the root action  | 
					
						
							|  |  |  |             // and all it's handlers are done. | 
					
						
							|  |  |  |             this.afterAction(function(){ ... }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             ... | 
					
						
							|  |  |  |         }], | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | **Notes:**  | 
					
						
							|  |  |  | - The functions are executed in order of registration. | 
					
						
							| 
									
										
										
										
											2019-06-14 16:56:45 +03:00
										 |  |  | - This is pointless outside of an action call, thus an exception will be thrown. | 
					
						
							| 
									
										
										
										
											2017-09-12 05:11:31 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-10 02:34:50 +03:00
										 |  |  | #### 6. Calling action handlers sorted independently of the prototype chain
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This sorts action handlers by priority `.sortedActionPriority` then  | 
					
						
							|  |  |  | order and calls them. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This protocol enables us to call actions in a deterministic order  | 
					
						
							|  |  |  | independent of the order the handlers are defined in the prototype chain. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | <action-set>.callSortedAction(name, ...args) | 
					
						
							|  |  |  | 	-> this | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Example action: | 
					
						
							|  |  |  | ```javascript | 
					
						
							|  |  |  |     someAction: [ | 
					
						
							|  |  |  |         { sortedActionPriority: 'high' }, | 
					
						
							|  |  |  |         function(){ | 
					
						
							|  |  |  |             ... | 
					
						
							|  |  |  |         }], | 
					
						
							|  |  |  | ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `sortedActionPriority` can take the following values: | 
					
						
							|  |  |  | - *number* | 
					
						
							|  |  |  | - `'high'` (equivalent to `50`) | 
					
						
							|  |  |  | - `'normal'` (equivalent to `0`) | 
					
						
							|  |  |  | - `'low'` (equivalent to `-50`) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The greater the priority the earlier the handler is called. Handlers with  | 
					
						
							|  |  |  | prioorities greater than `0` will always precede the unprioretized (i.e.  | 
					
						
							|  |  |  | `.sortedActionPriority` unset, `null` or `0`) handlers; Handlers with  | 
					
						
							|  |  |  | prioorities less than `0` will always follow the unprioretized handlers.  | 
					
						
							|  |  |  | Unprioretized handlers keep their relative order. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | **Notes:**  | 
					
						
							|  |  |  | - `.callSortedAction(..)` ignores handler return values by design. This is  | 
					
						
							|  |  |  | done to prevent actions competing to return a value. | 
					
						
							|  |  |  | - if action name does not exist this will do nothing and return normally  | 
					
						
							|  |  |  | (without error)... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 05:11:31 +03:00
										 |  |  | ### Alias protocols:
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 1. Defining aliases in runtime (MetaActions) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-14 16:56:45 +03:00
										 |  |  |   An alias is a mechanism to call an action (or alias) passing it a fixed | 
					
						
							|  |  |  |   set of arguments. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-12 05:11:31 +03:00
										 |  |  |   ``` | 
					
						
							|  |  |  |   <action-set>.alias('alias', 'action: args') | 
					
						
							|  |  |  |   <action-set>.alias('alias', .., 'action: args') | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |       -> <action-set> | 
					
						
							| 
									
										
										
										
											2017-09-12 05:11:31 +03:00
										 |  |  |   ``` | 
					
						
							| 
									
										
										
										
											2019-06-14 16:56:45 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |   Aliases can be defined inline: | 
					
						
							|  |  |  |   ``` | 
					
						
							|  |  |  |   someAction: [ | 
					
						
							|  |  |  |   	'action: arg'], | 
					
						
							|  |  |  |   ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Alias code syntax: | 
					
						
							|  |  |  |   ```BNF | 
					
						
							|  |  |  |   ALIAS ::=  | 
					
						
							|  |  |  |       <action-name> | 
					
						
							|  |  |  |       | <action-name>: <args> | 
					
						
							|  |  |  |       | <action-name>: <args> <comment> | 
					
						
							|  |  |  |   <args> ::= | 
					
						
							|  |  |  |       <arg> | 
					
						
							|  |  |  |       | <arg> <args> | 
					
						
							|  |  |  |   <arg> ::= | 
					
						
							|  |  |  |       Number|String|Array|Object | 
					
						
							|  |  |  |       | IDENTIFIER | 
					
						
							|  |  |  |       | ... | 
					
						
							|  |  |  |       | '$[0-9]' | 
					
						
							|  |  |  |   <comment> ::= | 
					
						
							|  |  |  |       '--.*$' | 
					
						
							|  |  |  |  			 | 
					
						
							|  |  |  |   ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Special arguments: | 
					
						
							| 
									
										
										
										
											2019-06-14 16:57:43 +03:00
										 |  |  |   - *IDENTIFIER*   | 
					
						
							| 
									
										
										
										
											2019-06-14 16:56:45 +03:00
										 |  |  |     expanded to `context[IDENTIFIER]` | 
					
						
							| 
									
										
										
										
											2019-06-14 16:57:43 +03:00
										 |  |  |   - *$N*   | 
					
						
							| 
									
										
										
										
											2019-06-14 16:56:45 +03:00
										 |  |  |     expanded to an instance of `parseStringAction.Argument` | 
					
						
							| 
									
										
										
										
											2019-06-14 16:57:43 +03:00
										 |  |  |   - *...*   | 
					
						
							| 
									
										
										
										
											2019-06-14 16:56:45 +03:00
										 |  |  |     expanded to `parseStringAction.ALLARGS` (singleton) | 
					
						
							|  |  |  |  			 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Example: | 
					
						
							|  |  |  |   ```javascript | 
					
						
							|  |  |  |   go: [ | 
					
						
							|  |  |  |       function(direction, ...opts){ | 
					
						
							|  |  |  |           // ... | 
					
						
							|  |  |  |       }], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // aliases to go... | 
					
						
							|  |  |  |   north: ['go: "north" -- Go north...'],  | 
					
						
							|  |  |  |   south: ['go: "south" -- Go south...'],  | 
					
						
							|  |  |  |   east: ['go: "east" -- Go east...'],  | 
					
						
							|  |  |  |   west: ['go: "west" -- Go west...'],  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ``` | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2017-09-12 05:11:31 +03:00
										 |  |  | 	 | 
					
						
							|  |  |  |   **Notes:**  | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |   - `.alias(..)` is signature compatible to `Action(..)` / `Alias(..)`, | 
					
						
							| 
									
										
										
										
											2017-09-12 05:11:31 +03:00
										 |  |  | 	supporting all the documentation and attribute definition. | 
					
						
							| 
									
										
										
										
											2019-06-14 16:56:45 +03:00
										 |  |  |   - To enable extending in runtime .alias(..) itself is implemented as  | 
					
						
							|  |  |  |     an action, thus all action protocols also apply. | 
					
						
							| 
									
										
										
										
											2017-09-12 05:11:31 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 2. Deleting aliases in runtime (MetaActions) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ``` | 
					
						
							|  |  |  |   <action-set>.alias('alias', null) | 
					
						
							|  |  |  |   <action-set>.alias('alias', false) | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |       -> <action-set> | 
					
						
							| 
									
										
										
										
											2017-09-12 05:11:31 +03:00
										 |  |  |   ``` | 
					
						
							|  |  |  |   			 | 
					
						
							|  |  |  |   **Notes:** | 
					
						
							|  |  |  |   - only own aliases can be deleted via .alias(.., null|false) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 3. Documentation generation and introspection (MetaActions, Alias) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Alias code... | 
					
						
							|  |  |  |   ``` | 
					
						
							|  |  |  |   <alias>.alias | 
					
						
							|  |  |  |   <alias>.toString() | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |       -> <code> | 
					
						
							| 
									
										
										
										
											2017-09-12 05:11:31 +03:00
										 |  |  |   ``` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   List own aliases... | 
					
						
							|  |  |  |   ``` | 
					
						
							|  |  |  |   <action-set>.aliases | 
					
						
							| 
									
										
										
										
											2017-09-12 05:22:58 +03:00
										 |  |  |       -> <action-set> | 
					
						
							| 
									
										
										
										
											2017-09-12 05:11:31 +03:00
										 |  |  |   ``` | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-03 02:36:09 +03:00
										 |  |  | XXX need docs on mix(..) and .mix*(..) protocols... | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-03 19:46:54 +03:00
										 |  |  | ## License
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [BSD 3-Clause License](./LICENSE) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Copyright (c) 2018, Alex A. Naanou, | 
					
						
							|  |  |  | All rights reserved. | 
					
						
							| 
									
										
										
										
											2016-08-23 18:04:43 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-23 17:21:35 +03:00
										 |  |  | <!-- vim:set ts=4 sw=4 spell : --> |