@peter.naydenov/fsm-hub 1.0.2 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -4
- package/package.json +13 -7
- package/src/index.js +29 -182
- package/src/methods/_callback.js +69 -0
- package/src/methods/_debugger.js +10 -0
- package/src/methods/_setTransitions.js +59 -0
- package/src/methods/addFsm.js +68 -0
- package/src/methods/addFunctions.js +16 -0
- package/src/methods/index.js +23 -0
- package/src/msg.js +12 -0
- package/test/{hub.js → 01-basics.js} +35 -127
- package/test/02-multipleSystem.js +159 -0
package/README.md
CHANGED
|
@@ -175,7 +175,7 @@ const
|
|
|
175
175
|
return {
|
|
176
176
|
second : 'second'
|
|
177
177
|
, state
|
|
178
|
-
, 'answer' : resultResponseData
|
|
178
|
+
, 'answer' : resultResponseData.response
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
181
|
}
|
|
@@ -186,17 +186,44 @@ const
|
|
|
186
186
|
|
|
187
187
|
function showme (transitionResult) {
|
|
188
188
|
console.log ( 'ShowMe' )
|
|
189
|
-
console.log (transitionResult)
|
|
189
|
+
console.log ( transitionResult.answer )
|
|
190
190
|
} // showme func.
|
|
191
191
|
|
|
192
192
|
hub.addFsm ({ one, two })
|
|
193
193
|
hub.addFunctions ( { showme })
|
|
194
194
|
|
|
195
195
|
// Start!
|
|
196
|
-
oneFsm.update ( 'activate', 'try' )
|
|
196
|
+
oneFsm.update ( 'activate', { response:'try'} )
|
|
197
197
|
|
|
198
198
|
// Result on the screen:
|
|
199
199
|
// ShowMe
|
|
200
200
|
// { second: 'second', state: 'active', answer: 'try' }
|
|
201
201
|
|
|
202
|
-
```
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
## Release History
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
### 1.0.4 ( 2021-04-02 )
|
|
211
|
+
- [x] Fix: Duplicated update callback if logic contain a chainAction.
|
|
212
|
+
|
|
213
|
+
### 1.0.3 ( 2021-03-26 )
|
|
214
|
+
- [x] Massive code refactoring;
|
|
215
|
+
- [ ] Bug: Duplicated update callback if logic contain a chainAction.
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
## Credits
|
|
223
|
+
'@peter.naydenov/fsm-hub' was created by Peter Naydenov.
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
## License
|
|
227
|
+
'@peter.naydenov/fsm-hub' is released under the MIT License.
|
|
228
|
+
|
|
229
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peter.naydenov/fsm-hub",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "FSM orchestration and state-managment tool",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -9,13 +9,19 @@
|
|
|
9
9
|
},
|
|
10
10
|
"author": "Peter Naydenov",
|
|
11
11
|
"license": "MIT",
|
|
12
|
-
"dependencies": {
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@peter.naydenov/stack": "1.0.0",
|
|
14
|
+
"ask-for-promise": "1.3.1"
|
|
15
|
+
},
|
|
13
16
|
"devDependencies": {
|
|
14
|
-
"@peter.naydenov/fsm": "2.2.
|
|
15
|
-
"chai": "4.
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
|
|
17
|
+
"@peter.naydenov/fsm": "2.2.4",
|
|
18
|
+
"chai": "4.3.6",
|
|
19
|
+
"mocha": "10.0.0",
|
|
20
|
+
"nyc": "15.1.0"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/PeterNaydenov/fsm-hub.git"
|
|
19
25
|
},
|
|
20
26
|
"keywords": [
|
|
21
27
|
"fsm",
|
package/src/index.js
CHANGED
|
@@ -1,186 +1,33 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
constructor ( machine, transformerLib ) {
|
|
16
|
-
const hub = this;
|
|
17
|
-
hub.fsm = {} // Fsm's placeholder
|
|
18
|
-
hub.fnCallbacks = {} // Callback functions place
|
|
1
|
+
const
|
|
2
|
+
methods = require ( './methods/index' )
|
|
3
|
+
, msg = require ( './msg' )
|
|
4
|
+
, askForPromise = require ( 'ask-for-promise' )
|
|
5
|
+
, stack = require ( '@peter.naydenov/stack' )
|
|
6
|
+
;
|
|
7
|
+
|
|
8
|
+
function FsmHub ( machine, transformerLib ) {
|
|
9
|
+
const
|
|
10
|
+
hub = this
|
|
11
|
+
, fnKeys = Object.keys ( methods )
|
|
12
|
+
;
|
|
13
|
+
hub.fsm = {} // Fsm's placeholder
|
|
14
|
+
hub.fnCallbacks = {} // Callback functions place
|
|
19
15
|
hub.debug = machine.debug || false
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
hub.
|
|
23
|
-
hub.
|
|
24
|
-
hub.
|
|
25
|
-
hub.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
, subscribers = {}
|
|
36
|
-
, actions = {}
|
|
37
|
-
, callbacks = {}
|
|
38
|
-
;
|
|
39
|
-
|
|
40
|
-
reactivity.forEach ( (ruleLine,i) => {
|
|
41
|
-
const hub = this;
|
|
42
|
-
const // ruleLine elements:
|
|
43
|
-
fsmName = 0
|
|
44
|
-
, onState = 1
|
|
45
|
-
, listener = 2
|
|
46
|
-
, listenerAct = 3
|
|
47
|
-
, isArray = ruleLine instanceof Array
|
|
48
|
-
;
|
|
49
|
-
|
|
50
|
-
if ( !isArray ) {
|
|
51
|
-
hub._debuger ( WRONG_REACTIVITY_RECORD, i+1 )
|
|
52
|
-
return
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
length = ruleLine.length
|
|
57
|
-
, hasCorrectLength = (length == 4 || length == 3 ) ? true : false
|
|
58
|
-
;
|
|
59
|
-
|
|
60
|
-
if ( !hasCorrectLength ) {
|
|
61
|
-
hub._debuger ( WRONG_REACTIVITY_RECORD, i+1 )
|
|
62
|
-
return
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const key = `${ruleLine[fsmName]}/${ruleLine[onState]}`; // fsmName/state
|
|
66
|
-
if ( length == 4 ) { // ruleLine with fsm
|
|
67
|
-
if ( !subscribers[key] ) subscribers[key] = []
|
|
68
|
-
subscribers [key].push ( ruleLine[listener] )
|
|
69
|
-
|
|
70
|
-
const actKey = `${key}/${ruleLine[listener]}`; // fsmName/state/fsmSubscriberName
|
|
71
|
-
actions [actKey] = ruleLine[listenerAct]
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if ( length == 3 ) { // ruleLine with function callback
|
|
75
|
-
if ( !callbacks[key] ) callbacks[key] = []
|
|
76
|
-
callbacks[key].push ( ruleLine[listener] )
|
|
77
|
-
}
|
|
78
|
-
}) // forEach ruleLine
|
|
79
|
-
if ( transformers ) {
|
|
80
|
-
Object.keys ( transformers ).forEach ( key => {
|
|
81
|
-
const
|
|
82
|
-
keyFn = transformers [key]
|
|
83
|
-
, fn = transformerLib [ keyFn]
|
|
84
|
-
;
|
|
85
|
-
if ( fn ) mod[key] = fn
|
|
86
|
-
})
|
|
87
|
-
}
|
|
88
|
-
return { transformers: mod, subscribers, callbacks, actions }
|
|
89
|
-
} // _setTransitions func.
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
addFsm ( ins ) {
|
|
96
|
-
const hub = this;
|
|
97
|
-
Object.keys(ins).forEach ( name => {
|
|
98
|
-
if ( hub.fsm[name] ) {
|
|
99
|
-
hub._debuger ( REGISTERED_FSM_NAME, name )
|
|
100
|
-
return
|
|
101
|
-
}
|
|
102
|
-
hub.fsm [name] = ins[name]
|
|
103
|
-
hub.fsm [name].on ( 'update', (state, response ) => {
|
|
104
|
-
hub._callback ( name, state, response )
|
|
105
|
-
})
|
|
106
|
-
})
|
|
107
|
-
} // addFsm func.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
addFunctions ( ins ) {
|
|
114
|
-
const hub = this;
|
|
115
|
-
Object.keys(ins).forEach ( name => {
|
|
116
|
-
if ( hub.fnCallbacks[name] ) {
|
|
117
|
-
hub._debuger ( REGISTERED_FUNCTION_NAME, name )
|
|
118
|
-
return
|
|
119
|
-
}
|
|
120
|
-
hub.fnCallbacks [name] = ins[name]
|
|
121
|
-
})
|
|
122
|
-
} // addFunctions func.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
_debuger ( str, data ) {
|
|
129
|
-
const hub = this;
|
|
130
|
-
if ( hub.debug ) console.log ( str, data )
|
|
131
|
-
} // debuger func.
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
_callback ( fsmName, state, response ) {
|
|
137
|
-
const
|
|
138
|
-
hub = this
|
|
139
|
-
, itemKey = `${fsmName}/${state}`
|
|
140
|
-
, fsmSubscriber = hub.subscribers[itemKey] || false
|
|
141
|
-
, callbackNames = hub.callbacks[itemKey] || false
|
|
142
|
-
, fnCallbacks = hub.fnCallbacks
|
|
143
|
-
, act = hub.actions
|
|
144
|
-
;
|
|
145
|
-
let data, wait;
|
|
146
|
-
|
|
147
|
-
if ( fsmSubscriber ) {
|
|
148
|
-
fsmSubscriber.forEach ( subscriberName => {
|
|
149
|
-
if ( !hub.fsm[ subscriberName ] ) {
|
|
150
|
-
hub._debuger ( MISSING_FSM, fsmSubscriber )
|
|
151
|
-
return
|
|
152
|
-
}
|
|
153
|
-
const
|
|
154
|
-
actionKey = `${itemKey}/${subscriberName}`
|
|
155
|
-
, action = act [actionKey]
|
|
156
|
-
, transformerKey = `${fsmName}/${subscriberName}`
|
|
157
|
-
, transformFn = hub.transformers [transformerKey]
|
|
158
|
-
;
|
|
159
|
-
if ( typeof transformFn == 'function' ) data = transformFn (state, response )
|
|
160
|
-
else data = response
|
|
161
|
-
hub.wait = hub.fsm [ subscriberName ].update ( action, data )
|
|
162
|
-
})
|
|
163
|
-
} // if fsmSubscriber
|
|
164
|
-
if ( callbackNames ) {
|
|
165
|
-
if ( hub.wait ) wait = hub.wait
|
|
166
|
-
else wait = Promise.resolve ()
|
|
167
|
-
wait.then ( () => {
|
|
168
|
-
hub.wait = false
|
|
169
|
-
callbackNames.forEach ( cbName => {
|
|
170
|
-
const
|
|
171
|
-
fn = fnCallbacks[cbName]
|
|
172
|
-
, transformerKey = `${fsmName}/${cbName}`
|
|
173
|
-
, transformFn = hub.transformers [ transformerKey ]
|
|
174
|
-
;
|
|
175
|
-
if ( typeof transformFn == 'function' ) data = transformFn (state, response )
|
|
176
|
-
else data = response
|
|
177
|
-
if ( typeof fn == 'function' ) fn(data)
|
|
178
|
-
else hub._debuger ( MISSING_FN, cbName )
|
|
179
|
-
})
|
|
180
|
-
})
|
|
181
|
-
} // if fnCallback
|
|
182
|
-
} // _callback func.
|
|
183
|
-
|
|
16
|
+
hub.cache = stack ( 'FIFO' )
|
|
17
|
+
hub.cacheInternal = stack ( 'FIFO' )
|
|
18
|
+
hub.wait = []
|
|
19
|
+
hub.lock = false
|
|
20
|
+
hub.haveInternalRequest = false
|
|
21
|
+
hub.reactivityTask = false
|
|
22
|
+
hub.askForPromise = askForPromise
|
|
23
|
+
|
|
24
|
+
fnKeys.forEach ( k => hub[k] = methods[k](hub,msg) ) // Attach methods to fsmHub
|
|
25
|
+
|
|
26
|
+
const { transformers, subscribers, actions, callbacks } = hub._setTransitions ( machine, transformerLib );
|
|
27
|
+
hub.transformers = transformers // Data transformation function with format 'fsm/fsmListener' or 'fsm/function'
|
|
28
|
+
hub.subscribers = subscribers // List of fsm names that are listening for 'fsm/state' changes
|
|
29
|
+
hub.actions = actions // Fsm action that should be applied on 'fsm/state/listener'
|
|
30
|
+
hub.callbacks = callbacks // List of functional callbacks
|
|
184
31
|
} // FsmHub class
|
|
185
32
|
|
|
186
33
|
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const askForPromise = require("ask-for-promise");
|
|
2
|
+
|
|
3
|
+
function _callback ( hub, msg ) {
|
|
4
|
+
return function _callback ( task, fsmName, state, response ) {
|
|
5
|
+
const
|
|
6
|
+
itemKey = `${fsmName}/${state}`
|
|
7
|
+
, fsmSubscriber = hub.subscribers[itemKey] || false
|
|
8
|
+
, callbackNames = hub.callbacks[itemKey] || false
|
|
9
|
+
, fnCallbacks = hub.fnCallbacks
|
|
10
|
+
, act = hub.actions
|
|
11
|
+
, wait = []
|
|
12
|
+
;
|
|
13
|
+
let data;
|
|
14
|
+
|
|
15
|
+
if ( !fsmSubscriber && !callbackNames ) {
|
|
16
|
+
task.done ()
|
|
17
|
+
return
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if ( fsmSubscriber ) {
|
|
21
|
+
fsmSubscriber.forEach ( subscriberName => {
|
|
22
|
+
if ( !hub.fsm[ subscriberName ] ) {
|
|
23
|
+
hub._debugger ( msg.MISSING_FSM, fsmSubscriber )
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
const
|
|
27
|
+
actionKey = `${itemKey}/${subscriberName}`
|
|
28
|
+
, action = act [actionKey]
|
|
29
|
+
, transformerKey = `${fsmName}/${subscriberName}`
|
|
30
|
+
, transformFn = hub.transformers [transformerKey]
|
|
31
|
+
;
|
|
32
|
+
if ( typeof transformFn == 'function' ) data = transformFn (state, response )
|
|
33
|
+
else data = response
|
|
34
|
+
|
|
35
|
+
if ( !data ) data = {}
|
|
36
|
+
data.___internalFlag = true
|
|
37
|
+
const updatePromise = hub.fsm [ subscriberName ].update ( action, data );
|
|
38
|
+
wait.push ( updatePromise )
|
|
39
|
+
})
|
|
40
|
+
} // if fsmSubscriber
|
|
41
|
+
|
|
42
|
+
if ( callbackNames ) {
|
|
43
|
+
let startFunctions = askForPromise ();
|
|
44
|
+
wait.push ( startFunctions.promise )
|
|
45
|
+
|
|
46
|
+
callbackNames.forEach ( cbName => {
|
|
47
|
+
const
|
|
48
|
+
fn = fnCallbacks[cbName]
|
|
49
|
+
, transformerKey = `${fsmName}/${cbName}`
|
|
50
|
+
, transformFn = hub.transformers [ transformerKey ]
|
|
51
|
+
;
|
|
52
|
+
if ( typeof transformFn == 'function' ) data = transformFn (state, response )
|
|
53
|
+
else data = response
|
|
54
|
+
if ( typeof fn == 'function' ) fn(data)
|
|
55
|
+
else hub._debugger ( msg.MISSING_FN, cbName )
|
|
56
|
+
|
|
57
|
+
})
|
|
58
|
+
startFunctions.done ()
|
|
59
|
+
} // if fnCallback
|
|
60
|
+
Promise.all ( wait ).then ( () => task.done () )
|
|
61
|
+
}} // _callback func.
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
module.exports = _callback
|
|
68
|
+
|
|
69
|
+
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
function _setTransitions ( hub, msg ) {
|
|
2
|
+
return function ( {reactivity, transformers}, transformerLib={} ) {
|
|
3
|
+
let
|
|
4
|
+
mod = {}
|
|
5
|
+
, subscribers = {}
|
|
6
|
+
, actions = {}
|
|
7
|
+
, callbacks = {}
|
|
8
|
+
;
|
|
9
|
+
|
|
10
|
+
reactivity.forEach ( (ruleLine,i) => {
|
|
11
|
+
const isArray = ruleLine instanceof Array;
|
|
12
|
+
|
|
13
|
+
if ( !isArray ) {
|
|
14
|
+
hub._debugger ( msg.WRONG_REACTIVITY_RECORD, i+1 )
|
|
15
|
+
return
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const
|
|
19
|
+
length = ruleLine.length
|
|
20
|
+
, [ fsmName, onState, listener, listenerAct ]= ruleLine // RuleLine elements
|
|
21
|
+
, hasCorrectLength = (length == 4 || length == 3 ) ? true : false
|
|
22
|
+
;
|
|
23
|
+
|
|
24
|
+
if ( !hasCorrectLength ) {
|
|
25
|
+
hub._debugger ( msg.WRONG_REACTIVITY_RECORD, i+1 )
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const key = `${fsmName}/${onState}`; // fsmName/state
|
|
30
|
+
if ( length == 4 ) { // ruleLine with fsm
|
|
31
|
+
if ( !subscribers[key] ) subscribers[key] = []
|
|
32
|
+
subscribers [key].push ( listener )
|
|
33
|
+
|
|
34
|
+
const actKey = `${key}/${listener}`; // fsmName/state/fsmSubscriberName
|
|
35
|
+
actions [actKey] = listenerAct
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if ( length == 3 ) { // ruleLine with function callback
|
|
39
|
+
if ( !callbacks[key] ) callbacks[key] = []
|
|
40
|
+
callbacks[key].push ( listener )
|
|
41
|
+
}
|
|
42
|
+
}) // forEach ruleLine
|
|
43
|
+
if ( transformers ) {
|
|
44
|
+
Object.keys ( transformers ).forEach ( key => {
|
|
45
|
+
const
|
|
46
|
+
keyFn = transformers [key]
|
|
47
|
+
, fn = transformerLib [ keyFn]
|
|
48
|
+
;
|
|
49
|
+
if ( fn ) mod[key] = fn
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
return { transformers: mod, subscribers, callbacks, actions }
|
|
53
|
+
}} // _setTransitions func.
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
module.exports = _setTransitions
|
|
58
|
+
|
|
59
|
+
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
const askForPromise = require("ask-for-promise")
|
|
2
|
+
|
|
3
|
+
function addFsm ( hub, msg ) {
|
|
4
|
+
return function ( ins ) {
|
|
5
|
+
Object.keys(ins).forEach ( name => {
|
|
6
|
+
if ( hub.fsm[name] ) {
|
|
7
|
+
hub._debugger ( msg.REGISTERED_FSM_NAME, name )
|
|
8
|
+
return
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function reactivityComplete ( isInternalRequest ) {
|
|
12
|
+
|
|
13
|
+
if ( isInternalRequest ) hub.haveInternalRequest = false
|
|
14
|
+
if ( hub.haveInternalRequest ) return
|
|
15
|
+
|
|
16
|
+
let
|
|
17
|
+
emptyInternalCache = hub.cacheInternal.isEmpty ()
|
|
18
|
+
, emptyCache = hub.cache.isEmpty ()
|
|
19
|
+
, emptyBoth = emptyCache && emptyInternalCache
|
|
20
|
+
;
|
|
21
|
+
if ( emptyBoth ) {
|
|
22
|
+
hub.lock = false
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
let [ name, state, response ] = ( !emptyInternalCache ) ? hub.cacheInternal.pull () : hub.cache.pull ()
|
|
26
|
+
if ( hub.cache.isEmpty () ) hub.lock = false
|
|
27
|
+
if ( hub.cacheInternal.isEmpty () ) hub.haveInternalRequest = false
|
|
28
|
+
hubUpdateWatcher ( name, state, response )
|
|
29
|
+
} // reactivityComplete func.
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
function hubUpdateWatcher (name,state,response) {
|
|
34
|
+
let executeReactivity;
|
|
35
|
+
if ( !hub.lock ) {
|
|
36
|
+
hub.lock = true
|
|
37
|
+
executeReactivity = askForPromise ()
|
|
38
|
+
executeReactivity.onComplete ( z => reactivityComplete ( false ) ) // complete of external reaction
|
|
39
|
+
hub._callback ( executeReactivity, name, state, response )
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if ( response && response.___internalFlag ) {
|
|
44
|
+
if ( hub.haveInternalRequest ) {
|
|
45
|
+
hub.cacheInternal.push ( [[ name, state, response ]])
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
let reactivityTask = askForPromise ();
|
|
49
|
+
reactivityTask.onComplete ( z => reactivityComplete ( true ) ) // complete of internal reaction
|
|
50
|
+
hub.haveInternalRequest = true;
|
|
51
|
+
hub._callback ( reactivityTask, name, state, response )
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
hub.cache.push ( [[ name, state, response ]])
|
|
55
|
+
} // hubUpdateWatcher func.
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
hub.fsm [name] = ins[name]
|
|
60
|
+
hub.fsm [name].on ( 'update', (state,response) => hubUpdateWatcher (name,state,response) )
|
|
61
|
+
})
|
|
62
|
+
}} // addFsm func.
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
module.exports = addFsm
|
|
67
|
+
|
|
68
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
function addFunctions ( hub, msg ) {
|
|
2
|
+
return function ( ins ) {
|
|
3
|
+
Object.keys(ins).forEach ( name => {
|
|
4
|
+
if ( hub.fnCallbacks[name] ) {
|
|
5
|
+
hub._debugger ( msg.REGISTERED_FUNCTION_NAME, name )
|
|
6
|
+
return
|
|
7
|
+
}
|
|
8
|
+
hub.fnCallbacks [name] = ins[name]
|
|
9
|
+
})
|
|
10
|
+
}} // addFunctions func.
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
module.exports = addFunctions
|
|
15
|
+
|
|
16
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const
|
|
2
|
+
_setTransitions = require ( './_setTransitions' )
|
|
3
|
+
, _debugger = require ( './_debugger' )
|
|
4
|
+
, _callback = require ( './_callback' )
|
|
5
|
+
|
|
6
|
+
, addFsm = require ( './addFsm' )
|
|
7
|
+
, addFunctions = require ( './addFunctions' )
|
|
8
|
+
;
|
|
9
|
+
|
|
10
|
+
const fn = {
|
|
11
|
+
_setTransitions
|
|
12
|
+
, _debugger
|
|
13
|
+
, _callback
|
|
14
|
+
|
|
15
|
+
, addFsm
|
|
16
|
+
, addFunctions
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
module.exports = fn
|
|
22
|
+
|
|
23
|
+
|
package/src/msg.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const msg = { // Error and warnings messages
|
|
2
|
+
WRONG_REACTIVITY_RECORD : 'Error: Wrong reactivity record on row %s.'
|
|
3
|
+
, REGISTERED_FSM_NAME : 'Warning: FSM "%s" is already registered.'
|
|
4
|
+
, REGISTERED_FUNCTION_NAME : 'Warning: Function "%s" is already registered.'
|
|
5
|
+
, MISSING_FSM : 'Warning: Fsm "%s" is not registered to the hub.'
|
|
6
|
+
, MISSING_FN : 'Warning: Function "%s" is not registered to the hub.'
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
module.exports = msg
|
|
11
|
+
|
|
12
|
+
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
const
|
|
2
2
|
FsmHub = require ('../src/index.js')
|
|
3
3
|
, Fsm = require ( '@peter.naydenov/fsm')
|
|
4
|
-
,
|
|
5
|
-
, expect = require ( 'expect.js')
|
|
4
|
+
, expect = require ( 'chai' ).expect
|
|
6
5
|
;
|
|
7
6
|
|
|
8
7
|
|
|
@@ -14,7 +13,7 @@ const
|
|
|
14
13
|
, MISSING_FN = 'Warning: Function "%s" is not registered to the hub.'
|
|
15
14
|
;
|
|
16
15
|
|
|
17
|
-
describe ( '
|
|
16
|
+
describe ( 'Fsm Hub', () => {
|
|
18
17
|
|
|
19
18
|
|
|
20
19
|
it ( 'Hub structure', () => {
|
|
@@ -26,7 +25,7 @@ it ( 'Hub structure', () => {
|
|
|
26
25
|
};
|
|
27
26
|
|
|
28
27
|
const hub = new FsmHub ( hubDetails )
|
|
29
|
-
|
|
28
|
+
|
|
30
29
|
expect ( hub ).to.have.property ( 'fsm' )
|
|
31
30
|
expect ( hub ).to.have.property ('fnCallbacks')
|
|
32
31
|
expect ( hub ).to.have.property ( 'transformers' )
|
|
@@ -35,7 +34,7 @@ it ( 'Hub structure', () => {
|
|
|
35
34
|
expect ( hub ).to.have.property ( 'callbacks' )
|
|
36
35
|
|
|
37
36
|
expect ( hub.subscribers ).to.have.property ( 'one/active' )
|
|
38
|
-
expect ( hub.subscribers['one/active'] ).to.be.an
|
|
37
|
+
expect ( hub.subscribers['one/active'] ).to.be.an ( 'array' )
|
|
39
38
|
expect ( hub.subscribers['one/active'][0] ).to.be.equal ( 'two' )
|
|
40
39
|
|
|
41
40
|
expect ( hub.actions ).to.have.property ( 'one/active/two' )
|
|
@@ -98,7 +97,7 @@ it ( 'Add a callback function', () => {
|
|
|
98
97
|
expect ( activeCallbacks.length ).to.be.equal ( 1 ) // function 'more' should be register only in fnCallbacks.
|
|
99
98
|
|
|
100
99
|
expect ( hub.callbacks ).to.have.property ( 'two/active' )
|
|
101
|
-
expect ( hub.callbacks['two/active']).to.be.an
|
|
100
|
+
expect ( hub.callbacks['two/active']).to.be.an ( 'array' )
|
|
102
101
|
expect ( hub.callbacks['two/active'][0]).to.be.equal ( 'showme' )
|
|
103
102
|
|
|
104
103
|
expect ( hub.fnCallbacks ).to.have.property ( 'showme' )
|
|
@@ -169,7 +168,7 @@ it ( 'Use hub-tranformer', done => {
|
|
|
169
168
|
|
|
170
169
|
// Define hub
|
|
171
170
|
const
|
|
172
|
-
|
|
171
|
+
hubMachine = {
|
|
173
172
|
reactivity : [
|
|
174
173
|
[ 'one', 'active', 'two', 'activate' ]
|
|
175
174
|
, [ 'two', 'active', 'showme' ]
|
|
@@ -190,8 +189,8 @@ it ( 'Use hub-tranformer', done => {
|
|
|
190
189
|
}
|
|
191
190
|
;
|
|
192
191
|
// Initialize the hub
|
|
193
|
-
const hub = new FsmHub (
|
|
194
|
-
|
|
192
|
+
const hub = new FsmHub ( hubMachine, transformerLib );
|
|
193
|
+
|
|
195
194
|
function showme (transitionResult) {
|
|
196
195
|
const {
|
|
197
196
|
second
|
|
@@ -229,15 +228,15 @@ it ( 'Wrong length of reactivity record', () => {
|
|
|
229
228
|
'two/showme' : 'simple'
|
|
230
229
|
}
|
|
231
230
|
};
|
|
232
|
-
const
|
|
233
|
-
FsmHub.prototype.
|
|
231
|
+
const originalDebugger = FsmHub.prototype._debugger;
|
|
232
|
+
FsmHub.prototype._debugger = function ( str, data ) {
|
|
234
233
|
expect ( str ).to.be.equal ( WRONG_REACTIVITY_RECORD )
|
|
235
234
|
}
|
|
236
235
|
const hub = new FsmHub ( hubDetails );
|
|
237
236
|
|
|
238
237
|
expect ( hub.callbacks ).to.have.property ( 'two/active' )
|
|
239
238
|
expect ( hub.callbacks ['two/active'][0]).to.be.equal ( 'showme' )
|
|
240
|
-
FsmHub.prototype.
|
|
239
|
+
FsmHub.prototype._debugger = originalDebugger
|
|
241
240
|
}) // it wrong reactivity record
|
|
242
241
|
|
|
243
242
|
|
|
@@ -256,15 +255,15 @@ it ( 'Wrong type of reactivity record', () => {
|
|
|
256
255
|
'two/showme' : 'simple'
|
|
257
256
|
}
|
|
258
257
|
};
|
|
259
|
-
const
|
|
260
|
-
FsmHub.prototype.
|
|
258
|
+
const originalDebugger = FsmHub.prototype._debugger;
|
|
259
|
+
FsmHub.prototype._debugger = function ( str, data ) {
|
|
261
260
|
expect ( str ).to.be.equal ( WRONG_REACTIVITY_RECORD )
|
|
262
261
|
}
|
|
263
262
|
const hub = new FsmHub ( hubDetails );
|
|
264
263
|
|
|
265
264
|
expect ( hub.callbacks ).to.have.property ( 'two/active' )
|
|
266
265
|
expect ( hub.callbacks ['two/active'][0]).to.be.equal ( 'showme' )
|
|
267
|
-
FsmHub.prototype.
|
|
266
|
+
FsmHub.prototype._debugger = originalDebugger
|
|
268
267
|
}) // it wrong reactivity record
|
|
269
268
|
|
|
270
269
|
|
|
@@ -292,7 +291,7 @@ it ( 'Try to add FSM name that is already registered', () => {
|
|
|
292
291
|
};
|
|
293
292
|
// Initialize the hub
|
|
294
293
|
const hub = new FsmHub ( hubDescription );
|
|
295
|
-
hub.
|
|
294
|
+
hub._debugger = function ( str, data ) {
|
|
296
295
|
expect ( str ).to.be.equal ( REGISTERED_FSM_NAME )
|
|
297
296
|
}
|
|
298
297
|
|
|
@@ -317,7 +316,7 @@ it ( 'Try to add function name that is already registered', () => {
|
|
|
317
316
|
]
|
|
318
317
|
};
|
|
319
318
|
const hub = new FsmHub ( machine );
|
|
320
|
-
hub.
|
|
319
|
+
hub._debugger = function ( str, data ) {
|
|
321
320
|
expect ( str ).to.be.equal ( REGISTERED_FUNCTION_NAME )
|
|
322
321
|
}
|
|
323
322
|
|
|
@@ -390,7 +389,7 @@ it ( 'Not registered fsm subscriber', done => {
|
|
|
390
389
|
const hub = new FsmHub ( machine, transformerLib );
|
|
391
390
|
|
|
392
391
|
hub.addFsm ({ one })
|
|
393
|
-
hub.
|
|
392
|
+
hub._debugger = function ( str, data ) {
|
|
394
393
|
expect ( str ).to.be.equal ( MISSING_FSM )
|
|
395
394
|
done ()
|
|
396
395
|
}
|
|
@@ -448,7 +447,7 @@ it ( 'Transformer is not a function', () => {
|
|
|
448
447
|
const hub = new FsmHub ( machine, transformerLib );
|
|
449
448
|
|
|
450
449
|
hub.addFsm ({ one, two })
|
|
451
|
-
// hub.
|
|
450
|
+
// hub._debugger = function ( str, data ) {
|
|
452
451
|
// expect ( str ).to.be.equal ( MISSING_FSM )
|
|
453
452
|
// done ()
|
|
454
453
|
// }
|
|
@@ -507,13 +506,13 @@ it ( 'Callback-function with data argument', done => {
|
|
|
507
506
|
}
|
|
508
507
|
}
|
|
509
508
|
, transformerLib = {
|
|
510
|
-
simple ( state, data ) { return `simple-${state}-${data}` }
|
|
509
|
+
simple ( state, data ) { return { try: `simple-${state}-${data.try}`} }
|
|
511
510
|
}
|
|
512
511
|
;
|
|
513
512
|
// Initialize the hub
|
|
514
513
|
const hub = new FsmHub ( machine, transformerLib );
|
|
515
514
|
function showme ( data ) {
|
|
516
|
-
expect ( data ).to.equal ( 'simple-active-try' )
|
|
515
|
+
expect ( data.try ).to.equal ( 'simple-active-try' )
|
|
517
516
|
expect ( two.state == 'active' )
|
|
518
517
|
one.update ( 'stop' )
|
|
519
518
|
} // showme func.
|
|
@@ -526,119 +525,28 @@ it ( 'Callback-function with data argument', done => {
|
|
|
526
525
|
hub.addFsm ({ one, two })
|
|
527
526
|
hub.addFunctions ({ showme, final })
|
|
528
527
|
// Start!
|
|
529
|
-
one.update ( 'activate', 'try' )
|
|
528
|
+
one.update ( 'activate', { try:'try'} )
|
|
530
529
|
}) // it callback-function with data argument
|
|
531
530
|
|
|
532
531
|
|
|
533
532
|
|
|
534
533
|
|
|
534
|
+
it ( 'Test a Debugger', () => {
|
|
535
|
+
const
|
|
536
|
+
machine = {
|
|
537
|
+
reactivity : [
|
|
538
|
+
[ 'one', 'active', 'two', 'activate' ]
|
|
539
|
+
, [ 'two', 'active', 'showme' ]
|
|
540
|
+
]
|
|
541
|
+
, debug : true
|
|
542
|
+
};
|
|
543
|
+
const hub = new FsmHub ( machine );
|
|
544
|
+
hub._debugger ( 'Test for %s', 'debugger' )
|
|
545
|
+
}) // it Test debugger
|
|
535
546
|
|
|
536
|
-
it ( 'Check multiple systems'
|
|
537
|
-
// , () => {
|
|
538
|
-
// const
|
|
539
|
-
// userDescription = {
|
|
540
|
-
// init : 'none'
|
|
541
|
-
// , table : [
|
|
542
|
-
// [ 'none' , 'start' , 'inProgress' , 'setupUser' , [ 'ifSpecial', false ] ]
|
|
543
|
-
// , [ 'inProgress' , 'ifSpecial' , 'special' , 'setupSpecialUser', [ false, 'setupNormal'] ]
|
|
544
|
-
// , [ 'inProgress' , 'setupNormal' , 'active' , 'setupActiveUser' ]
|
|
545
|
-
// , [ 'active' , 'test' , 'testUser' , 'setupTestUser' ]
|
|
546
|
-
// ]
|
|
547
|
-
// }
|
|
548
|
-
// , screenDescription = {
|
|
549
|
-
// init : 'none'
|
|
550
|
-
// , table : [
|
|
551
|
-
// [ 'none', 'start', 'browse', 'startScreen' ]
|
|
552
|
-
// , [ 'browse', 'page', 'browse', 'loadPage' ]
|
|
553
|
-
|
|
554
|
-
// , [ 'none' , 'sync', 'browse', 'syncUserState', [ 'page', false ] ]
|
|
555
|
-
// , [ 'browse', 'sync', 'browse', 'syncUserState', [ 'page', false ] ]
|
|
556
|
-
// ]
|
|
557
|
-
// , stateData : {
|
|
558
|
-
// user : 'N/A' // sync with user state
|
|
559
|
-
// , page : 'N/A' // current active page
|
|
560
|
-
// }
|
|
561
|
-
// }
|
|
562
|
-
// , hubDescription = {
|
|
563
|
-
// reactivity : [
|
|
564
|
-
// [ 'user' , 'none' , 'screen', 'sync' ]
|
|
565
|
-
// , [ 'user' , 'active' , 'screen', 'sync' ]
|
|
566
|
-
// , [ 'user', 'testUser', 'screen', 'sync' ]
|
|
567
|
-
// ]
|
|
568
|
-
// , transformers : {
|
|
569
|
-
// 'user/screen' : 'transferUserState'
|
|
570
|
-
// }
|
|
571
|
-
// }
|
|
572
|
-
// ;
|
|
573
|
-
|
|
574
|
-
// const userLib = {
|
|
575
|
-
// setupUser ( task, dependencies, stateData, dt) {
|
|
576
|
-
// console.log ( 'setupUser' )
|
|
577
|
-
// task.done ({ success : true })
|
|
578
|
-
// } // setupUser func.
|
|
579
|
-
// , setupSpecialUser ( task, dependencies, stateData, dt) {
|
|
580
|
-
// console.log ( 'setupSpecialUser' )
|
|
581
|
-
// task.done({ success : false })
|
|
582
|
-
// } // setupSpecialUser func.
|
|
583
|
-
// , setupActiveUser ( task, dependencies, stateData, dt) {
|
|
584
|
-
// console.log ( 'setup Active User' )
|
|
585
|
-
// task.done ({ success : true })
|
|
586
|
-
// } // setupActiveUser func.
|
|
587
|
-
// , setupTestUser ( task, dependencies, stateData, dt ) {
|
|
588
|
-
// console.log ( 'USER: setup test user' )
|
|
589
|
-
// task.done ({ success : true })
|
|
590
|
-
// }
|
|
591
|
-
// } // userLib
|
|
592
|
-
// const screenLib = {
|
|
593
|
-
// startScreen (task, dependencies, stateData, dt) {
|
|
594
|
-
// console.log ( 'SCREEN: startScreen' )
|
|
595
|
-
// task.done ({ success : true })
|
|
596
|
-
// }
|
|
597
|
-
// , loadPage (task, dependencies, stateData, dt) {
|
|
598
|
-
// console.log ( `SCREEN: loadPage, user - ${stateData.user}`)
|
|
599
|
-
// task.done ({ success : true })
|
|
600
|
-
// }
|
|
601
|
-
// , syncUserState (task, dependencies, stateData, dt) {
|
|
602
|
-
// console.log ( `SCREEN: Sync user state. ${dt}`)
|
|
603
|
-
// stateData.user = dt
|
|
604
|
-
// task.done ({ success : true, stateData })
|
|
605
|
-
// }
|
|
606
|
-
// } // screenLib
|
|
607
|
-
// const hubTransormers = {
|
|
608
|
-
// transferUserState ( state, response ) {
|
|
609
|
-
// return state
|
|
610
|
-
// }
|
|
611
|
-
// } // hubTransformers
|
|
612
|
-
|
|
613
|
-
// const
|
|
614
|
-
// user = new Fsm ( userDescription, userLib )
|
|
615
|
-
// , screen = new Fsm ( screenDescription, screenLib )
|
|
616
|
-
// , hub = new FsmHub ( hubDescription, hubTransormers )
|
|
617
|
-
// ;
|
|
618
|
-
|
|
619
|
-
// hub.addFsm ({ user, screen })
|
|
620
|
-
// user.update ( 'start' )
|
|
621
|
-
// setTimeout ( () => user.update ('test'), 300 )
|
|
622
|
-
// }
|
|
623
|
-
) // it check multiple systems
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
it ( 'Test a Debuger', () => {
|
|
630
|
-
const
|
|
631
|
-
machine = {
|
|
632
|
-
reactivity : [
|
|
633
|
-
[ 'one', 'active', 'two', 'activate' ]
|
|
634
|
-
, [ 'two', 'active', 'showme' ]
|
|
635
|
-
]
|
|
636
|
-
, debug : true
|
|
637
|
-
};
|
|
638
|
-
const hub = new FsmHub ( machine );
|
|
639
|
-
hub._debuger ( 'Test for %s', 'debuger' )
|
|
640
|
-
}) // it Test debuger
|
|
641
547
|
|
|
548
|
+
|
|
549
|
+
|
|
642
550
|
}) // describe
|
|
643
551
|
|
|
644
552
|
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
const
|
|
2
|
+
FsmHub = require ('../src/index.js')
|
|
3
|
+
, Fsm = require ( '@peter.naydenov/fsm')
|
|
4
|
+
, expect = require ( 'chai' ).expect
|
|
5
|
+
;
|
|
6
|
+
|
|
7
|
+
describe ( 'Fsm Hub', () => {
|
|
8
|
+
|
|
9
|
+
it ( 'Check multiple systems', done => {
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Description:
|
|
13
|
+
* Create a 3 fsm systems - human, spy, and recorder
|
|
14
|
+
* - Human: Can receive good and bad news and change his mood according the news;
|
|
15
|
+
* - Spy: Spy on human and sends to recorder the messages that make him unhappy;
|
|
16
|
+
* - Recorder: Storage for bad news. When messages are 3 will stop with the recording and will call function "TimeForChange"
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const
|
|
20
|
+
recorderDescription = { // Description of the recorder
|
|
21
|
+
init : 'empty'
|
|
22
|
+
, table : [
|
|
23
|
+
[ 'empty' , 'write' , 'used' , 'add_a_warning' ]
|
|
24
|
+
, [ 'used' , 'write' , 'used' , 'add_a_warning', [ 'isFull?', false ] ]
|
|
25
|
+
, [ 'used' , 'isFull?' , 'full' , 'check_if_full' ]
|
|
26
|
+
]
|
|
27
|
+
, stateData : {
|
|
28
|
+
reasons: []
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
, humanDescription = { // Very weak description of human emotions. Just for testing purposes
|
|
32
|
+
init : 'happy'
|
|
33
|
+
, table : [
|
|
34
|
+
[ 'happy' , 'goodNews', 'happy' , 'feel_happy' ]
|
|
35
|
+
, [ 'happy' , 'badNews' , 'unhappy' , 'feel_bad' ]
|
|
36
|
+
, [ 'unhappy' , 'badNews' , 'unhappy' , 'feel_bad' ]
|
|
37
|
+
, [ 'unhappy' , 'goodNews', 'happy' , 'feel_bad' ]
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
, spyDescription = {
|
|
41
|
+
init: 'positive'
|
|
42
|
+
, table : [
|
|
43
|
+
[ 'positive', 'bad' , 'negative' , 'onBad' ]
|
|
44
|
+
, [ 'negative', 'good' , 'positive' , 'onGood' ]
|
|
45
|
+
, [ 'negative', 'bad' , 'negative' , 'onBad' ]
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
, hubDescription = {
|
|
49
|
+
reactivity : [
|
|
50
|
+
[ 'human' , 'unhappy' , 'spy' , 'bad' ]
|
|
51
|
+
, [ 'spy' , 'negative' , 'recorder' , 'write' ]
|
|
52
|
+
, [ 'recorder' , 'full' , 'timeForChange' ]
|
|
53
|
+
, [ 'recorder' , 'full' , 'test' ]
|
|
54
|
+
]
|
|
55
|
+
, transformers : {
|
|
56
|
+
'human/spy' : 'emotion2spy'
|
|
57
|
+
, 'spy/recorder' : 'spy2record'
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
;
|
|
61
|
+
// Define libs
|
|
62
|
+
const
|
|
63
|
+
humanLib = {
|
|
64
|
+
feel_happy (task,dependencies, stateData, data ) {
|
|
65
|
+
task.done ({
|
|
66
|
+
success : true
|
|
67
|
+
, response : data
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
, feel_bad ( task, dependencies, stateData, data ) {
|
|
71
|
+
task.done ({
|
|
72
|
+
success : true
|
|
73
|
+
, response: data
|
|
74
|
+
})
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
, spyLib = {
|
|
78
|
+
onBad ( task, dependencies, stateData, data ) {
|
|
79
|
+
task.done ({
|
|
80
|
+
success : true
|
|
81
|
+
, response : data
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
, onGood ( task, dependencies, stateData, data ) {
|
|
85
|
+
task.done ({
|
|
86
|
+
success : true
|
|
87
|
+
, response : data
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
, recorderLib = {
|
|
92
|
+
add_a_warning ( task, dependencies, stateData, data ) {
|
|
93
|
+
const { reasons } = stateData;
|
|
94
|
+
if ( !reasons.includes(data.response) ) stateData.reasons.push ( data.response )
|
|
95
|
+
task.done ({
|
|
96
|
+
success : true
|
|
97
|
+
, stateData
|
|
98
|
+
, response : data
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
, check_if_full ( task, dependencies, stateData, data ) {
|
|
102
|
+
const { reasons } = stateData;
|
|
103
|
+
if ( reasons.length >= 3 ) task.done ({ success : true, response: data })
|
|
104
|
+
else task.done ({ success : false, response: data })
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
, hubLib = {
|
|
108
|
+
emotion2spy ( state,response) {
|
|
109
|
+
return { response }
|
|
110
|
+
}
|
|
111
|
+
, spy2record ( state, response ) { return response }
|
|
112
|
+
}
|
|
113
|
+
;
|
|
114
|
+
// Define machines and the hub
|
|
115
|
+
const
|
|
116
|
+
human = new Fsm ( humanDescription , humanLib )
|
|
117
|
+
, spy = new Fsm ( spyDescription , spyLib )
|
|
118
|
+
, recorder = new Fsm ( recorderDescription, recorderLib )
|
|
119
|
+
, theHub = new FsmHub ( hubDescription , hubLib )
|
|
120
|
+
;
|
|
121
|
+
let result = false
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
function timeForChange ( state, response ) {
|
|
125
|
+
result = 'DONE'
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function test ( state, response ) {
|
|
129
|
+
expect ( result ).to.be.equal ( 'DONE' )
|
|
130
|
+
expect ( theHub.cache.isEmpty () ).to.be.true
|
|
131
|
+
expect ( theHub.cacheInternal.isEmpty () ).to.be.true
|
|
132
|
+
let rec = recorder.exportState ().stateData.reasons
|
|
133
|
+
|
|
134
|
+
expect ( rec ).to.be.an ( 'array' )
|
|
135
|
+
expect ( rec ).to.have.length ( 3 )
|
|
136
|
+
expect ( rec[0] ).to.be.equal ( 'Car crash' )
|
|
137
|
+
expect ( rec[1] ).to.be.equal ( 'Airplane crash' )
|
|
138
|
+
expect ( rec[2] ).to.be.equal ( 'Storm' )
|
|
139
|
+
done ()
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
theHub.addFsm ({ human, spy, recorder })
|
|
143
|
+
theHub.addFunctions ({ timeForChange, test })
|
|
144
|
+
|
|
145
|
+
human.update ( 'goodNews', 'friends' )
|
|
146
|
+
human.update ( 'badNews', 'Car crash' )
|
|
147
|
+
human.update ( 'badNews', 'Airplane crash' )
|
|
148
|
+
human.update ( 'badNews', 'Storm' )
|
|
149
|
+
|
|
150
|
+
}) // it check multiple systems
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
}) // describe
|
|
158
|
+
|
|
159
|
+
|