@peter.naydenov/fsm 4.0.1 → 5.0.0

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.
Files changed (49) hide show
  1. package/Changelog.md +90 -0
  2. package/LICENSE +21 -0
  3. package/Migration.guide.md +86 -0
  4. package/README.md +96 -173
  5. package/README_v.4.x.x.md +491 -0
  6. package/blueprint.md +22 -0
  7. package/coverage/lcov-report/index.html +1 -1
  8. package/coverage/lcov-report/src/index.html +1 -1
  9. package/coverage/lcov-report/src/index.js.html +1 -1
  10. package/coverage/lcov-report/src/methods/_getChain.js.html +1 -1
  11. package/coverage/lcov-report/src/methods/_onUpdateTask.js.html +1 -1
  12. package/coverage/lcov-report/src/methods/_setTransitions.js.html +1 -1
  13. package/coverage/lcov-report/src/methods/_transit.js.html +1 -1
  14. package/coverage/lcov-report/src/methods/_triggerCacheUpdate.js.html +1 -1
  15. package/coverage/lcov-report/src/methods/_updateStep.js.html +1 -1
  16. package/coverage/lcov-report/src/methods/_warn.js.html +1 -1
  17. package/coverage/lcov-report/src/methods/exportState.js.html +1 -1
  18. package/coverage/lcov-report/src/methods/getState.js.html +1 -1
  19. package/coverage/lcov-report/src/methods/ignoreCacheUpdates.js.html +1 -1
  20. package/coverage/lcov-report/src/methods/importState.js.html +1 -1
  21. package/coverage/lcov-report/src/methods/index.html +1 -1
  22. package/coverage/lcov-report/src/methods/index.js.html +1 -1
  23. package/coverage/lcov-report/src/methods/off.js.html +1 -1
  24. package/coverage/lcov-report/src/methods/on.js.html +1 -1
  25. package/coverage/lcov-report/src/methods/reset.js.html +1 -1
  26. package/coverage/lcov-report/src/methods/setDependencies.js.html +1 -1
  27. package/coverage/lcov-report/src/methods/update.js.html +1 -1
  28. package/coverage/tmp/coverage-51040-1691437648869-0.json +1 -0
  29. package/package.json +8 -7
  30. package/src/main.js +75 -0
  31. package/src/methods/_getChain.js +3 -2
  32. package/src/methods/_onUpdateTask.js +1 -1
  33. package/src/methods/_setTransitions.js +3 -3
  34. package/src/methods/_transit.js +7 -4
  35. package/src/methods/_triggerCacheUpdate.js +2 -0
  36. package/src/methods/_updateStateData.js +43 -0
  37. package/src/methods/_updateStep.js +10 -13
  38. package/src/methods/_warn.js +1 -1
  39. package/src/methods/exportState.js +5 -8
  40. package/src/methods/extractList.js +26 -0
  41. package/src/methods/getDependencies.js +10 -0
  42. package/src/methods/importState.js +3 -1
  43. package/src/methods/index.js +23 -15
  44. package/src/methods/reset.js +3 -2
  45. package/src/methods/setDependencies.js +1 -1
  46. package/src/methods/update.js +14 -4
  47. package/src/queryStateUpdate.js +38 -0
  48. package/coverage/tmp/coverage-29775-1668580484020-0.json +0 -1
  49. package/src/index.js +0 -41
package/Changelog.md ADDED
@@ -0,0 +1,90 @@
1
+ ## Release History
2
+
3
+
4
+
5
+ ### 5.0.0 ( 2023-09-16 )
6
+ - [x] Machine description `table` was renamed to `behavior`;
7
+ - [x] All default dependencies are available on top level: Fsm.dependencies;
8
+ - [x] stateData is a dt-object(uses dt-toolbox library);
9
+ - [x] Transition functions have different arrangement of arguments;
10
+ - [x] Transition functions can receive multiple data arguments(single is still the preference);
11
+ - [x] Transition functions can update only defined stateData fields. Not defined data-segments or properties will be ignored;
12
+ - [x] Method `exportState` returns an object with two properties: `state` and `stateData`. `state` is a string. `stateData` is a DT-model. Method `importState` expect exact same object as argument;
13
+ - [x] Method `importState` will filter the imported stateData to only predefined fields;
14
+ - [x] Transion result.command was removed permanently from the code. Was depricated in version 4;
15
+ - [x] Internal fsm data is hidden. Only public methods are available;
16
+ - [x] Changes in stateData can be provided as standard javascript object, DT-model or dt-object. Automatic detection is implemented;
17
+ - [x] Method `fsm.extractList` will return a list of requested stateData properties;
18
+ - [x] Method `extractList` is available as argument in transition functions.
19
+
20
+
21
+
22
+
23
+
24
+
25
+ ### 4.0.1 ( 2022-11-16)
26
+ - [x] Walk was removed. Generates a lot of problems with objects in stateData(HTMLElement, Date, URL). StateData is using a shallow copy. Developer should take care of immutability himself;
27
+
28
+
29
+
30
+
31
+ ### 4.0.0 (2022-11-15)
32
+ - [x] The library become a ES module;
33
+
34
+
35
+
36
+ ### 3.0.0 (2022-10-14)
37
+ - [x] Dependency "@peter.naydenov/walk" was upgraded to version 3.0.0;
38
+
39
+
40
+
41
+ ### 2.2.4 ( 2022-05-27 )
42
+ - [x] New dependency was added - walk ("@peter.naydenov/walk");
43
+ - [x] "Walk" is loaded by default in fsm dependency object;
44
+ - [x] "Ask-for-promise" is loaded by default in fsm dependency object;
45
+ - [x] Deep copy for stateData on each update with "walk" library;
46
+
47
+
48
+
49
+ ### 2.2.3 ( 2021-04-02 )
50
+ - [x] Fix: Duplicated update callback if logic contain a chainAction;
51
+
52
+
53
+
54
+ ### 2.2.2 ( 2021-03-26 )
55
+ - [x] Internal code refactoring;
56
+ - [ ] Bug: Duplicated update callback if logic contain a chainAction;
57
+
58
+
59
+
60
+ ### 2.2.0 (2019-01-20)
61
+ - [x] Fix: Cached transitions are starting before callback functions for already executed transitions;
62
+ - [x] New method 'ignoreCachedUpdates()'. Ignore all cached updates;
63
+
64
+
65
+
66
+ ### 2.1.0 (2019-01-19)
67
+ - [x] Export fsm state as an object - externalState;
68
+ - [x] Import externalState;
69
+ - [x] Lock updates during update process execution;
70
+ - [x] Prevent simultaneous updates;
71
+ - [x] Cache new updates during update process execution;
72
+ - [x] Execute cached updates in a row;
73
+ - [ ] Error: Cached transitions are starting before callback functions for already executed transitions;
74
+
75
+
76
+
77
+ ### 2.0.0 (2018-12-01)
78
+ - [x] Transition function could contain asynchronous code;
79
+ - [x] Chain-actions in **transaction conditions** (Optional);
80
+ - [x] Chain-actions are possible on **positive** and *negative* transition-end;
81
+
82
+
83
+
84
+ ### 1.0.0 (2018-11-21)
85
+ - [x] FSM;
86
+ - [x] Set FSM external dependencies;
87
+ - [x] Chain-actions by using `command` in transition response object;
88
+ - [x] Internal state flags and values with stateData;
89
+
90
+
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Peter Naydenov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,86 @@
1
+ ## Migration Guides
2
+
3
+
4
+ ## Migration from v.4.x.x to v.5.x.x.
5
+
6
+ ### FSM Description
7
+ - FSM description property 'table' was renamed to `behavior`;
8
+ - Data fields for stateData should be in fsm machine definition. Missing keys will be ignored;
9
+
10
+ ### Transition functions
11
+ - Transition functions have different set and arrangment of arguments;
12
+
13
+ ```js
14
+ // ver. 4 ->
15
+ function transitionFunction ( task, dependencies, stateData, data ) {
16
+ // ...code here
17
+ return task.done(transitionResult);
18
+ }
19
+ // ver. 5 ->
20
+ // stateData is not directly available. Use the function extractList to get the data you need;
21
+ // look at the example below:
22
+ function transitionFunction ( {task, state, dependencies, extractList }, data ) {
23
+ // ...code here
24
+ const [ top, something, else ] = extractList ([ 'a', 'b', 'c' ]);
25
+ // get 'a' from stateData and write in variable 'top';
26
+ // get 'b' from stateData and write in variable 'something';
27
+ // get 'c' from stateData and write in variable 'else';
28
+ const transitionResult = {
29
+ success : true
30
+ , stateData : {
31
+ // ...setup stateData changes here
32
+ }
33
+ , result :
34
+ };
35
+ task.done(transitionResult);
36
+ }
37
+
38
+ ```
39
+ - Transition functions can update only defined stateData fields. Not defined data-segments or properties will be ignored;
40
+ ```js
41
+ const machine = {
42
+ behavior : [
43
+ // transition condition rows here..
44
+ ]
45
+ stateData : {
46
+ a : 1 // <- this is the only allowed field in stateData;
47
+ }
48
+ }
49
+
50
+ const lib = {
51
+ trans ({task}) { // transition function
52
+ stateData = { a : 2, b : 3, c : 4 }; // <- only 'a' is defined in machine.stateData;
53
+ task.done({ success : true, stateData }) // 'b' and 'c' will be ignored;
54
+ }
55
+ }
56
+ ```
57
+ - If you don't know what is defined in stateData, just request a extractList without any arguments;
58
+ ```
59
+ function trans ({task, extractList}) {
60
+ const stateDataCopy = extractList(); // <- will return state fields from stateData wrapped in object
61
+ }
62
+ ```
63
+ - Fill stateData with primitive values and objects that are JSON compatible!
64
+
65
+
66
+ ## Migration from v.1 to v.2
67
+ Project was started with simplest posible implementation. I like the approach and want to extend it. Reasons:
68
+ - Some of my transition function contain asynchronous events;
69
+ - Describe chain of actions inside the transition condition records;
70
+ - Chain of action on positive and negative transition end;
71
+
72
+ So... about changes:
73
+ ### Transition complete
74
+ - **Version 1**: Transition function should return **transitionResult** object.
75
+ - **Version 2**: Transition function receives as first param **task**. Task is askForPromise object. Transition is complete on `task.done(transitionResult)`.
76
+ - **Changes**: Find return statement and convert it to task.done:
77
+
78
+ ```js
79
+ // ver. 1 ->
80
+ ...
81
+ return { success : true }
82
+ // ver. 2 ->
83
+ ...
84
+ task.done ({ success : true })
85
+
86
+ ```
package/README.md CHANGED
@@ -1,23 +1,47 @@
1
1
  # FSM (@peter.naydenov/fsm)
2
2
 
3
- Finite state machine(FSM) is an abstract machine that can be in exactly one of a finite number of **states** at any given time. The FSM can change from one state to another in response to some external inputs(**actions**). The change from state to another is called a **transition**. An FSM is defined by a list of its states, its initial state, and the conditions for each transition.
3
+ ![version](https://img.shields.io/github/package-json/v/peterNaydenov/fsm)
4
+ ![license](https://img.shields.io/github/license/peterNaydenov/fsm)
5
+
6
+ ## What's new in version 5.x.x
7
+ - For fast upgrade, checkout the [Migration Guide](https://github.com/PeterNaydenov/fsm/blob/master/Migration.guide.md)
8
+ - List of [all changes are available in Changelog file](https://github.com/PeterNaydenov/fsm/blob/master/Changelog.md)
9
+ - Documentation is updated to reflect the changes in version 5.x.x;
10
+
11
+ ## Description
12
+ Finite state machine(FSM) is an abstract machine that can be in exactly one of a finite number of **states** at any given time. The FSM can change from one state to another in response to some external inputs(**actions**). The change from state to another is called a **transition**.
13
+ An FSM definition includes:
14
+
15
+
4
16
  ```js
5
- const myFsm = {
17
+ const fsmDefinition = {
6
18
  init : 'none' // initial fsm state
7
- , table : [
8
- // [ fromState, action , nextState, transitionFx ]
19
+ , behavior : [
20
+ // [ fromState, action , nextState, transitionFx, chaining ]
9
21
  [ 'none' , 'activate', 'active' , 'switchON' ] // transition condition
10
22
  , [ 'active' , 'stop' , 'none' , 'switchOFF' ] // transition condition
11
23
  ]
24
+ , stateData : {
25
+ // ... all stateData flags are here
26
+ }
27
+ }
12
28
  }
13
29
  ```
14
- - **init**: string. Initial state for the FSM;
15
- - **table**: array of transitionConditions. Describe relation among fsm state, action and transition;
30
+ - **init**: string. Initial state of the FSM;
31
+ - **stateData**: Container for all stateData required by the FSM.
32
+ - **behavior**: array of transition conditions. Describe relation among fsm state, action and transition;
16
33
  - **transitionCondition**: Array [fromState action nextState transitionFx];
17
34
  - **fromState**: string. State as starting point for transition;
18
35
  - **action**: string. External input signal. Transition could happen only when fromState and action are described in transitionCondition record;
19
- - **nextState**: string. The FSM state if transition is successful;
36
+ - **nextState**: string. The next FSM state if transition become successful;
20
37
  - **transitionFx**: string. The function name that will be executed on 'state/action' conditions. Transition should return **transitionResult** object where parameter "**success**" will represent transition success. Result of transition will be evaluated by FSM. Positive response will change actual state to 'nextState' from transitionCondition record. Negative result will keep actual state;
38
+ - **chaining**(optional): Array [ positive, negative ]. Optional element of `transition condition`. It's a mechanism to trigger next action based on the result of the transition. If transition result is positive, FSM will trigger action from `positive` position. If transition result is negative, FSM will trigger action from `negative` position. If only one position will use chaining, set the other as 'false'.
39
+ ```js
40
+ // ... transition conditions
41
+ , [ 'ready', 'activate', 'active', 'switchOFF', [ false, 'generator' ] ]
42
+ // Chaining will trigger 'generator' action on negative transition result and will do nothing on positive result.
43
+ // ... transition conditions
44
+ ```
21
45
 
22
46
  **Transitions** are functions and they are provided to FSM as functional library - javascript object with functions.
23
47
  ```js
@@ -32,13 +56,13 @@ const transitionLibrary = {
32
56
  ```
33
57
 
34
58
  It's simple and clean way to represent system behaviour but practice shows that is not enough. This implementation was extended to cover some aditional program needs like:
35
- - Transition function could contain asynchronous code(Available after version 2.0);
36
- - Chain-actions in **transaction conditions** (Optional after version 2.0);
37
- - Chain-actions are possible on **positive** and *negative* transition-end (After version 2.0);
38
- - Export fsm state as an object: externalState. (Available after version 2.1);
39
- - Import externalState (Available after version 2.1);
40
- - Prevent simultaneous updates (Available after version 2.1);
41
- - Cache stack for fsm-updates and postponed execution (Available after version 2.1);
59
+ - Transition function could contain asynchronous code;
60
+ - Chain-actions in **transaction conditions**(Optional);
61
+ - Chain-actions are possible on **positive** and *negative* transition-end;
62
+ - Export fsm state as an object: externalState;
63
+ - Import externalState;
64
+ - Prevent simultaneous updates;
65
+ - Fsm-updates cache mechanism and execution in a row;
42
66
 
43
67
 
44
68
 
@@ -65,24 +89,24 @@ If your project is commonJS, use a dynamic `import` function or use version v.3.
65
89
 
66
90
 
67
91
  ## Fsm Description
68
- Fsm description is an object that define fsm business logic. Every fsm description should contain **init** and **table** properties.:
92
+ Fsm description is an object that define fsm business logic. Every fsm description should contain **init** and **behavior** properties.:
69
93
  ```js
70
94
  const machine = {
71
95
  init : 'stopped'
72
- , table: [
96
+ , behavior: [
73
97
  // [ state , action , nextState, functionName, chainAction(optional) ]
74
- [ 'stopped', 'activate', 'active', 'fnActivate' ]
75
- , [ 'stopped', 'activate', 'active', 'fnActivate' ]
98
+ [ 'stopped', 'activate', 'active', 'fnActivate' ] // transition condition
99
+ , [ 'active' , 'stop' , 'stoped', 'fnStop' ]
76
100
  ]
77
101
  , stateData : { greeting: 'hi' }
78
- /** Parameter 'stateData' is optional parameter. Data will be
79
- * provided to each transition function. You can read and modify
80
- * stateData values.
102
+ /** Parameter 'stateData' is not a required parameter. It's a data storage space.
103
+ * Storaged data is available in every transition function by using a function 'extractList'.
104
+ * Only a predefined state-data-names can be saved in 'stateData'
81
105
  * /
82
106
  }
83
107
  ```
84
108
 
85
- Property '**init**' is the initial state of the system. Property '**table**' describes how system reacts. Every row contain 5 elements:
109
+ Property '**init**' is the initial state of the system. Property '**behavior**' describes how system reacts. Every row(transition condition) contains 5 elements:
86
110
  1. Current active state;
87
111
  2. Action;
88
112
  3. Next state;
@@ -93,7 +117,7 @@ Property '**init**' is the initial state of the system. Property '**table**' des
93
117
  [ 'stopped', 'activate', 'active', 'fnActivate' ]
94
118
  // Read this transition condition like:
95
119
  /**
96
- * When state is 'stopped' and external input 'activate' comes, transition 'fnActivate' will be executed. On success state will become 'active'. No chain-actions are defined.
120
+ * When state is 'stopped' and action 'activate' comes, transition 'fnActivate' will be executed. On success state will become 'active'. No chain-actions are defined.
97
121
  */
98
122
  ```
99
123
 
@@ -117,19 +141,20 @@ Object that will contain all transition functions:
117
141
 
118
142
  ## Fsm Transition Function
119
143
 
120
- Fsm transition function is a function, member of transition library. Transition functions is kind of middleware. Every function receives 4 arguments:
144
+ Fsm transition function is a function, member of transition library. Transition functions is kind of middleware. Every function receives this arguments:
121
145
  ```js
122
146
  const lib = {
123
- fnActivate ( task, dependencies, stateObject, dt ) {
147
+ fnActivate ( {task, state, dependencies, extractList}, data ) {
124
148
  // function code is here...
125
149
  task.done ( end ) // end is a transitionResult {}
126
150
  }
127
151
  }
128
152
  ```
129
153
  - task - askForPromise object; [AskForPromise documentation](https://github.com/PeterNaydenov/ask-for-promise). Represents asynchronous transition execution. Finish by providing to task object, the transition result object. `task.done( transitionResult )`;
154
+ - state - string. Current state of the FSM;
130
155
  - dependencies - object. Contain all external dependencies. Set fsm dependencies by fsm.setDependencies();
131
- - stateObject - object. Contains all helper params needed to support the FSM state;
132
- - dt - object. External data provided from fsm.update( action, **dt**);
156
+ - extractList - function. Extract data from FSM stateData;
157
+ - data - any(Prefered: object). External data provided from fsm.update( action, **data**);
133
158
 
134
159
  Execution of transition function will end on `task.done(end)` where **end** is an **transitionResult** object.
135
160
 
@@ -145,7 +170,6 @@ Only one of the params in this object is required:
145
170
  success : true // Required. Boolean. Transition success;
146
171
  , response : {} // Optional. Object. update answer response;
147
172
  , stateData : {} // Optional. Object. 'stateData' if there is stateData changes;
148
- , command : null // Optional. String|null|undefined. Next action if chaining is required (depricated). Use "chainActions" in table instead;
149
173
  }
150
174
  ```
151
175
 
@@ -155,17 +179,19 @@ Only one of the params in this object is required:
155
179
 
156
180
  ```js
157
181
  setDependencies : 'Insert all external dependencies'
158
- , getState : 'Returns actual state'
182
+ , getDependencies : 'Returns all external dependencies'
159
183
  , update : 'Trigger an action'
160
- , exportState : 'Export state and stateData as a single object (externalState)'
161
184
  , importState : 'Import externalState object.'
185
+ , exportState : 'Export state and stateData as a single object (externalState)'
162
186
  , reset : 'Revert state and stateData to initial values described during initialization'
163
187
  , ignoreCachedUpdates : 'Ignore all cached updates'
188
+ , getState : 'Returns actual state'
189
+ , extractList : 'Extract list of state segments or properties'
164
190
  ```
165
191
 
166
192
 
167
193
  ### fsm.setDependencies ()
168
- Set dependencies for FSM. Dependency object will be provided to every transition function. With **dependency injection** code will stay testable. Don't forget to add here all **window** based objects and functions that are available only in the browser environment.
194
+ Set dependencies for FSM. Dependency object will be provided to every transition function. With **dependency injection** code will stay testable. Method could be called multiple times. All dependencies will be merged in one object.
169
195
 
170
196
  ```js
171
197
  const
@@ -179,31 +205,58 @@ Set dependencies for FSM. Dependency object will be provided to every transition
179
205
 
180
206
  fsm.setDependencies ( deps )
181
207
  ```
208
+ - deps: object. Object with external dependencies;
182
209
  - **Method returns**: void;
183
210
 
184
211
 
185
212
 
186
- ### fsm.getState ()
187
- Will return current current FSM state.
213
+ ### fsm.getDependencies ()
214
+ Returns all external dependencies.
188
215
 
189
216
  ```js
190
- let currentState = fsm.getState ()
217
+ const
218
+ moment = require ( 'moment' )
219
+ , fsm = new Fsm ()
220
+ , deps = {
221
+ scrollTo : window.scrollTo
222
+ , moment
223
+ }
224
+ ;
225
+
226
+ fsm.setDependencies ( deps )
227
+ const allDeps = fsm.getDependencies ()
191
228
  ```
192
- - **Method returns**: string. Current FSM state;
193
229
 
194
230
 
195
231
 
196
232
  ### fsm.update ()
197
233
  Provide actions to FSM. If conditions 'state/action' exist in description table, FSM will react.
234
+ - If action name does not exist in behavior table, FSM will ignore the action;
235
+ - If action name exist in behavior table but current state is different, FSM will ignore the action;
236
+ - If transition function is not provided, FSM will ignore the action;
237
+
198
238
  ```js
199
- fsm.update ( action, altData)
239
+ fsm.update ( action, altData )
200
240
  .then ( r => {
201
241
  // ...do something with the response
202
242
  })
203
243
  ```
204
- - **action**(required): string. The action.
244
+ - **action**(required): string. The action name.
205
245
  - **altData**(optional): any. Additional data provided to the transition;
206
- - **Method returns**: Promise of any. Returned value is equal to transitionResult.response;
246
+ - **Method returns**: Promise<any>. Returned value is equal to transitionResult.response;
247
+
248
+
249
+
250
+ ### fsm.getState ()
251
+ Will return current current FSM state.
252
+
253
+ ```js
254
+ let currentState = fsm.getState ()
255
+ ```
256
+ - **Method returns**: string. Current FSM state;
257
+
258
+
259
+
207
260
 
208
261
 
209
262
 
@@ -311,13 +364,14 @@ const
311
364
  }
312
365
  , machine = {
313
366
  init : 'none'
314
- , table : [
367
+ , behavior : [
315
368
  [ 'none' , 'start' , 'active' , 'switchON', [ false, 'generator'] ]
316
369
  , [ 'none' , 'generator' , 'altSrc' , 'altOn' ]
317
370
  , [ 'active' , 'stop' , 'none' , 'switchOFF' ]
318
371
  , [ 'altSrc' , 'stop' , 'none' , 'switchOFF' ]
319
372
  , [ 'altSrc' , 'electricity' , 'active', 'primarySource' ]
320
373
  ]
374
+ , stateData : {}
321
375
  }
322
376
  ;
323
377
  const fsm = new Fsm ( machine, lib );
@@ -332,141 +386,10 @@ fsm.update ( 'activate' )
332
386
 
333
387
 
334
388
 
389
+ ## External Links
335
390
 
336
- ## Migration from v.1 to v.2
337
- Project was started with simplest posible implementation. I like the approach and want to extend it. Reasons:
338
- - Some of my transition function contain asynchronous events;
339
- - Describe chain of actions inside the transition condition records;
340
- - Chain of action on positive and negative transition end;
341
-
342
- So... about changes:
343
- ### Transition complete
344
- - **Version 1**: Transition function should return **transitionResult** object.
345
- - **Version 2**: Transition function receives as first param **task**. Task is askForPromise object. Transition is complete on `task.done(transitionResult)`.
346
- - **Changes**: Find return statement and convert it to task.done:
347
-
348
- ```js
349
- // ver. 1 ->
350
- ...
351
- return { success : true }
352
- // ver. 2 ->
353
- ...
354
- task.done ({ success : true })
355
-
356
- ```
357
-
358
-
359
-
360
- ### Transition params
361
-
362
- ```js
363
- // ver. 1 ->
364
- transition ( dependencies, stateData, dt )
365
-
366
- // ver. 2 ->
367
- transition ( task, dependencies, stateData, dt )
368
-
369
- ```
370
-
371
- - **Change**: Open transition library and add 'task' argument to all transitioin functions.
372
-
373
-
374
-
375
- ### Description table
376
- - **Version 1**: Transition condition in description table:
377
- ```js
378
- [ 'state', 'action', 'nextState', 'transitionFx' ]
379
- ```
380
- All fields are string and are required.
381
-
382
- - **Version 2**: Fields in description table record:
383
- ```js
384
- [ 'state', 'action', 'nextState', 'transitionFx', 'chainActions' ]
385
- // chainAction is array [ nextAction, nextAction ]
386
- // If we need chaining only on positive/negative result of transition we can use "false"
387
- // Example:
388
- // We need chain transition only if transition failed:
389
- // [ false, nextAction ]
390
- // This chainAction will trigger nextAction only if transition failed.
391
-
392
- ```
393
- ChainActions is an array with two values. First value represents next action on success transition.
394
- Second on failed transition. ChainAction is optional.
395
-
396
- - **Changes**: As ChainActions is an optional parameter, no changes needed.
397
-
398
-
399
-
400
- ### Chaining
401
- - Version 1:
402
- TransitionResult should contain property "command", that will link to next transition.
403
- - Version 2:
404
- TransitionResult with property 'command' still works. Chaining in description-table is more powerfull and will overwrite transitionResult's "command" property.
405
- - Changes: No changes needed but is much better to describe chains in description table instead in transition functions. Keep all logic flows on one place for easy reading and manipulating.
406
-
407
-
408
-
409
-
410
-
411
- ## Release History
412
-
413
-
414
- ### 4.0.1 ( 2022-11-16)
415
- - [x] Walk was removed. Generates a lot of problems with objects in stateData(HTMLElement, Date, URL). StateData is using a shallow copy. Developer should take care of immutability himself;
416
-
417
- ### 4.0.0 (2022-11-15)
418
- - [x] The library become a ES module;
419
-
420
-
421
-
422
- ### 3.0.0 (2022-10-14)
423
- - [x] Dependency "@peter.naydenov/walk" was upgraded to version 3.0.0;
424
-
425
-
426
-
427
- ### 2.2.4 ( 2022-05-27 )
428
- - [x] New dependency was added - walk ("@peter.naydenov/walk");
429
- - [x] "Walk" is loaded by default in fsm dependency object;
430
- - [x] "Ask-for-promise" is loaded by default in fsm dependency object;
431
- - [x] Deep copy for stateData on each update with "walk" library;
432
-
433
-
434
-
435
- ### 2.2.3 ( 2021-04-02 )
436
- - [x] Fix: Duplicated update callback if logic contain a chainAction;
437
-
438
-
439
-
440
-
441
- ### 2.2.2 ( 2021-03-26 )
442
- - [x] Internal code refactoring;
443
- - [ ] Bug: Duplicated update callback if logic contain a chainAction;
444
-
445
-
446
-
447
- ### 2.2.0 (2019-01-20)
448
- - [x] Fix: Cached transitions are starting before callback functions for already executed transitions;
449
- - [x] New method 'ignoreCachedUpdates()'. Ignore all cached updates;
450
-
451
- ### 2.1.0 (2019-01-19)
452
- - [x] Export fsm state as an object - externalState;
453
- - [x] Import externalState;
454
- - [x] Lock updates during update process execution;
455
- - [x] Prevent simultaneous updates;
456
- - [x] Cache new updates during update process execution;
457
- - [x] Execute cached updates in a row;
458
- - [ ] Error: Cached transitions are starting before callback functions for already executed transitions;
459
-
460
- ### 2.0.0 (2018-12-01)
461
- - [x] Transition function could contain asynchronous code;
462
- - [x] Chain-actions in **transaction conditions** (Optional);
463
- - [x] Chain-actions are possible on **positive** and *negative* transition-end;
464
-
465
- ### 1.0.0 (2018-11-21)
466
- - [x] FSM;
467
- - [x] Set FSM external dependencies;
468
- - [x] Chain-actions by using `command` in transition response object;
469
- - [x] Internal state flags and values with stateData;
391
+ - [Fsm version 4.x.x - previous version](https://github.com/PeterNaydenov/fsm/tree/4.x.x)
392
+ - [AskForPromise - a promise library](https://github.com/PeterNaydenov/ask-for-promise)
470
393
 
471
394
 
472
395