added MetaActions.callSortedAction(..)...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2019-10-10 02:34:50 +03:00
parent fd15b37cd3
commit fca286be32
3 changed files with 93 additions and 1 deletions

View File

@ -522,6 +522,48 @@ Example:
- This is pointless outside of an action call, thus an exception will be thrown.
#### 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)...
### Alias protocols:
1. Defining aliases in runtime (MetaActions)

View File

@ -1821,6 +1821,56 @@ module.MetaActions = {
chainCall: function(outer, inner){
return this[outer].chainApply(this, inner, args2array(arguments).slice(2)) },
// Call action handlers serted by .sortedActionPriority...
//
// NOTE: this by design ignores the action call results to avoid
// actions competing on who will return a value...
// NOTE: if action name does not exist this will do nothing and
// return normally (without error)...
// NOTE: this essentially re-implements parts of the .pre(..)/.post(..)
// action protocol...
// NOTE: this may not support some legacy action protocol features...
callSortedAction: function(name, ...args){
var that = this
this.getHandlers(name)
.map(function(h, i){
var p = (h.pre || {}).sortedActionPriority
// normalize priority...
p = p == 'high' ?
50
: p == 'normal' ?
0
: p == 'low' ?
-50
: p
return [i, p, h] })
// sort by .sortedActionPriority ascending...
.sort(function([ia, pa, a], [ib, pb, b]){
return (pa != null && pb != null) ?
pa - pb
: (pa > 0 || pb < 0) ?
1
: (pb > 0 || pa < 0) ?
-1
: ia - ib })
// the list should be ordered descending form highest
// priority or closeness to root action...
.reverse()
// call the actions (pre)...
.map(function([i, p, a]){
return a.pre ?
a.pre.call(that, ...args)
: a.post })
.reverse()
// call the actions (post)...
// NOTE: we do not care about call results here...
.forEach(function(func){
func instanceof Function
&& func.call(that, ...args) }) },
// Get action/method resolution order...
//
// List mixin tags...

View File

@ -1,6 +1,6 @@
{
"name": "ig-actions",
"version": "3.23.0",
"version": "3.24.0",
"description": "",
"main": "actions.js",
"scripts": {