jssm 5.43.2 → 5.45.2
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/dist/es6/jssm.d.ts +5 -1
- package/dist/es6/jssm.js +99 -14
- package/dist/es6/jssm_types.d.ts +25 -1
- package/dist/es6/jssm_util.d.ts +3 -1
- package/dist/es6/jssm_util.js +3 -1
- package/dist/es6/version.js +1 -1
- package/dist/jssm.es5.cjs.js +1 -1
- package/dist/jssm.es5.iife.js +1 -1
- package/jssm.d.ts +5 -1
- package/jssm_types.d.ts +25 -1
- package/jssm_util.d.ts +3 -1
- package/package.json +8 -7
- package/src/ts/jssm.ts +145 -22
- package/src/ts/jssm_types.ts +40 -1
- package/src/ts/jssm_util.ts +18 -1
- package/src/ts/tests/hooks.spec.ts +184 -3
- package/src/ts/version.ts +1 -1
package/jssm.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
declare type StateType = string;
|
|
2
2
|
import { JssmGenericState, JssmGenericConfig, JssmTransition, JssmTransitionList, // JssmTransitionRule,
|
|
3
|
-
JssmMachineInternalState, JssmParseTree, JssmStateDeclaration, JssmArrow, JssmArrowDirection, JssmArrowKind, JssmLayout, FslDirection, FslTheme } from './jssm_types';
|
|
3
|
+
JssmMachineInternalState, JssmParseTree, JssmStateDeclaration, JssmArrow, JssmArrowDirection, JssmArrowKind, JssmLayout, FslDirection, FslTheme, HookDescription } from './jssm_types';
|
|
4
4
|
import { seq, weighted_rand_select, weighted_sample_select, histograph, weighted_histo_key } from './jssm_util';
|
|
5
5
|
import { version } from './version';
|
|
6
6
|
declare function arrow_direction(arrow: JssmArrow): JssmArrowDirection;
|
|
@@ -37,6 +37,9 @@ declare class Machine<mDT> {
|
|
|
37
37
|
_arrange_end_declaration: Array<Array<StateType>>;
|
|
38
38
|
_theme: FslTheme;
|
|
39
39
|
_flow: FslDirection;
|
|
40
|
+
_has_hooks: boolean;
|
|
41
|
+
_hooks: Map<string, Function>;
|
|
42
|
+
_named_hooks: Map<string, Function>;
|
|
40
43
|
constructor({ start_states, complete, transitions, machine_author, machine_comment, machine_contributor, machine_definition, machine_language, machine_license, machine_name, machine_version, state_declaration, fsl_version, dot_preamble, arrange_declaration, arrange_start_declaration, arrange_end_declaration, theme, flow, graph_layout }: JssmGenericConfig<mDT>);
|
|
41
44
|
_new_state(state_config: JssmGenericState): StateType;
|
|
42
45
|
state(): StateType;
|
|
@@ -86,6 +89,7 @@ declare class Machine<mDT> {
|
|
|
86
89
|
is_complete(): boolean;
|
|
87
90
|
state_is_complete(whichState: StateType): boolean;
|
|
88
91
|
has_completes(): boolean;
|
|
92
|
+
set_hook(HookDesc: HookDescription): void;
|
|
89
93
|
action(name: StateType, newData?: mDT): boolean;
|
|
90
94
|
transition(newState: StateType, newData?: mDT): boolean;
|
|
91
95
|
force_transition(newState: StateType, newData?: mDT): boolean;
|
package/jssm_types.d.ts
CHANGED
|
@@ -148,4 +148,28 @@ declare type JssmCompileSeStart<DataType> = {
|
|
|
148
148
|
};
|
|
149
149
|
declare type JssmParseTree = Array<JssmCompileSeStart<StateType>>;
|
|
150
150
|
declare type JssmParseFunctionType = (string: any) => JssmParseTree;
|
|
151
|
-
|
|
151
|
+
declare type BasicHookDescription = {
|
|
152
|
+
kind: 'hook';
|
|
153
|
+
from: string;
|
|
154
|
+
to: string;
|
|
155
|
+
handler: Function;
|
|
156
|
+
};
|
|
157
|
+
declare type HookDescriptionWithAction = {
|
|
158
|
+
kind: 'named';
|
|
159
|
+
from: string;
|
|
160
|
+
to: string;
|
|
161
|
+
action: string;
|
|
162
|
+
handler: Function;
|
|
163
|
+
};
|
|
164
|
+
declare type EntryHook = {
|
|
165
|
+
kind: 'entry';
|
|
166
|
+
to: string;
|
|
167
|
+
handler: Function;
|
|
168
|
+
};
|
|
169
|
+
declare type ExitHook = {
|
|
170
|
+
kind: 'exit';
|
|
171
|
+
from: string;
|
|
172
|
+
handler: Function;
|
|
173
|
+
};
|
|
174
|
+
declare type HookDescription = BasicHookDescription | HookDescriptionWithAction | EntryHook | ExitHook;
|
|
175
|
+
export { JssmColor, JssmTransition, JssmTransitions, JssmTransitionList, JssmTransitionRule, JssmArrow, JssmArrowKind, JssmArrowDirection, JssmGenericConfig, JssmGenericState, JssmGenericMachine, JssmParseTree, JssmCompileSe, JssmCompileSeStart, JssmCompileRule, JssmPermitted, JssmPermittedOpt, JssmResult, JssmStateDeclaration, JssmStateDeclarationRule, JssmLayout, JssmParseFunctionType, JssmMachineInternalState, FslDirection, FslTheme, HookDescription };
|
package/jssm_util.d.ts
CHANGED
|
@@ -5,4 +5,6 @@ declare const seq: Function;
|
|
|
5
5
|
declare const histograph: Function;
|
|
6
6
|
declare const weighted_sample_select: Function;
|
|
7
7
|
declare const weighted_histo_key: Function;
|
|
8
|
-
|
|
8
|
+
declare const hook_name: (from: string, to: string) => string;
|
|
9
|
+
declare const named_hook_name: (from: string, to: string, action: string) => string;
|
|
10
|
+
export { seq, arr_uniq_p, histograph, weighted_histo_key, weighted_rand_select, weighted_sample_select, array_box_if_string, hook_name, named_hook_name };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jssm",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.45.2",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=10.0.0"
|
|
6
6
|
},
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
}
|
|
17
17
|
]
|
|
18
18
|
},
|
|
19
|
-
"description": "A Javascript finite state machine (FSM) with a terse DSL and a simple API. Well tested, and typed with
|
|
19
|
+
"description": "A Javascript finite state machine (FSM) with a terse DSL and a simple API. Well tested, and typed with TypeScript. MIT License.",
|
|
20
20
|
"main": "dist/jssm.es5.cjs.js",
|
|
21
21
|
"module": "dist/es6/jssm.js",
|
|
22
22
|
"types": "./jssm.d.ts",
|
|
@@ -39,8 +39,9 @@
|
|
|
39
39
|
"eslint": "eslint --color src/ts/jssm.ts src/ts/jssm_types.ts src/ts/tests/*.ts",
|
|
40
40
|
"audit": "text_audit -r -t major MAJOR wasteful WASTEFUL any mixed fixme FIXME checkme CHECKME testme TESTME stochable STOCHABLE todo TODO comeback COMEBACK whargarbl WHARGARBL -g ./src/ts/**/*.{js,ts}",
|
|
41
41
|
"vet": "npm run eslint && npm run audit",
|
|
42
|
-
"
|
|
43
|
-
"
|
|
42
|
+
"benny": "node ./src/buildjs/benchmark.js",
|
|
43
|
+
"build": "npm run vet && npm run test && npm run site && npm run docs && npm run benny",
|
|
44
|
+
"ci_build": "npm run vet && npm run test && npm run benny",
|
|
44
45
|
"minify": "mv dist/es6/jssm-dot.js dist/es6/jssm-dot.nonmin.js && terser dist/es6/jssm-dot.nonmin.js > dist/es6/jssm-dot.js",
|
|
45
46
|
"min_iife": "mv dist/jssm.es5.iife.js dist/jssm.es5.iife.nonmin.js && terser dist/jssm.es5.iife.nonmin.js > dist/jssm.es5.iife.js",
|
|
46
47
|
"min_cjs": "mv dist/jssm.es5.cjs.js dist/jssm.es5.cjs.nonmin.js && terser dist/jssm.es5.cjs.nonmin.js > dist/jssm.es5.cjs.js",
|
|
@@ -69,7 +70,6 @@
|
|
|
69
70
|
"tested",
|
|
70
71
|
"typed",
|
|
71
72
|
"typed-js",
|
|
72
|
-
"flowtype",
|
|
73
73
|
"mealy",
|
|
74
74
|
"moore",
|
|
75
75
|
"mealy machine",
|
|
@@ -80,6 +80,7 @@
|
|
|
80
80
|
"viz.js",
|
|
81
81
|
"flowchart",
|
|
82
82
|
"visualization",
|
|
83
|
+
"TypeScript",
|
|
83
84
|
"StoneCypher"
|
|
84
85
|
],
|
|
85
86
|
"author": "John Haugeland <stonecypher@gmail.com>",
|
|
@@ -92,6 +93,7 @@
|
|
|
92
93
|
"@types/jest": "^27.0.2",
|
|
93
94
|
"@typescript-eslint/eslint-plugin": "^4.13.0",
|
|
94
95
|
"@typescript-eslint/parser": "^4.13.0",
|
|
96
|
+
"benny": "^3.7.1",
|
|
95
97
|
"changelog-maker": "^2.3.2",
|
|
96
98
|
"coveralls": "^3.0.11",
|
|
97
99
|
"eslint": "^7.32.0",
|
|
@@ -114,8 +116,7 @@
|
|
|
114
116
|
"text_audit": "^0.9.3",
|
|
115
117
|
"ts-jest": "^27.0.7",
|
|
116
118
|
"typedoc": "^0.22.15",
|
|
117
|
-
"typescript": "^4.1.3"
|
|
118
|
-
"viz.js": "^1.7.1"
|
|
119
|
+
"typescript": "^4.1.3"
|
|
119
120
|
},
|
|
120
121
|
"dependencies": {
|
|
121
122
|
"reduce-to-639-1": "^1.0.4"
|
package/src/ts/jssm.ts
CHANGED
|
@@ -19,7 +19,8 @@ import {
|
|
|
19
19
|
JssmCompileSe, JssmCompileSeStart, JssmCompileRule,
|
|
20
20
|
JssmArrow, JssmArrowDirection, JssmArrowKind,
|
|
21
21
|
JssmLayout,
|
|
22
|
-
FslDirection, FslTheme
|
|
22
|
+
FslDirection, FslTheme,
|
|
23
|
+
HookDescription
|
|
23
24
|
|
|
24
25
|
} from './jssm_types';
|
|
25
26
|
|
|
@@ -29,7 +30,7 @@ import {
|
|
|
29
30
|
|
|
30
31
|
import {
|
|
31
32
|
seq, weighted_rand_select, weighted_sample_select, histograph,
|
|
32
|
-
weighted_histo_key, array_box_if_string
|
|
33
|
+
weighted_histo_key, array_box_if_string, hook_name, named_hook_name
|
|
33
34
|
} from './jssm_util';
|
|
34
35
|
|
|
35
36
|
|
|
@@ -38,7 +39,7 @@ import {
|
|
|
38
39
|
|
|
39
40
|
import { parse } from './jssm-dot'; // TODO FIXME WHARGARBL this could be post-typed
|
|
40
41
|
|
|
41
|
-
import { version } from './version'; // replaced from package.js in build
|
|
42
|
+
import { version } from './version'; // replaced from package.js in build
|
|
42
43
|
|
|
43
44
|
|
|
44
45
|
|
|
@@ -229,7 +230,7 @@ function compile_rule_transition_step<mDT>(
|
|
|
229
230
|
to : string,
|
|
230
231
|
this_se : JssmCompileSe,
|
|
231
232
|
next_se : JssmCompileSe
|
|
232
|
-
) : Array< JssmTransition<mDT> > { // todo
|
|
233
|
+
) : Array< JssmTransition<mDT> > { // todo typescript describe the parser representation of a transition step extension
|
|
233
234
|
|
|
234
235
|
const edges : Array< JssmTransition<mDT> > = [];
|
|
235
236
|
|
|
@@ -260,13 +261,13 @@ function compile_rule_transition_step<mDT>(
|
|
|
260
261
|
|
|
261
262
|
|
|
262
263
|
|
|
263
|
-
function compile_rule_handle_transition(rule: JssmCompileSeStart<StateType>): any { // TODO FIXME no any // todo
|
|
264
|
+
function compile_rule_handle_transition(rule: JssmCompileSeStart<StateType>): any { // TODO FIXME no any // todo typescript describe the parser representation of a transition
|
|
264
265
|
return compile_rule_transition_step([], rule.from, rule.se.to, rule.se, rule.se.se);
|
|
265
266
|
}
|
|
266
267
|
|
|
267
268
|
|
|
268
269
|
|
|
269
|
-
function compile_rule_handler(rule: JssmCompileSeStart<StateType>): JssmCompileRule {
|
|
270
|
+
function compile_rule_handler(rule: JssmCompileSeStart<StateType>): JssmCompileRule {
|
|
270
271
|
|
|
271
272
|
if (rule.key === 'transition') {
|
|
272
273
|
return { agg_as: 'transition', val: compile_rule_handle_transition(rule) };
|
|
@@ -305,7 +306,7 @@ function compile_rule_handler(rule: JssmCompileSeStart<StateType>): JssmCompileR
|
|
|
305
306
|
|
|
306
307
|
|
|
307
308
|
|
|
308
|
-
function compile<mDT>(tree: JssmParseTree): JssmGenericConfig<mDT> {
|
|
309
|
+
function compile<mDT>(tree: JssmParseTree): JssmGenericConfig<mDT> {
|
|
309
310
|
|
|
310
311
|
const results : {
|
|
311
312
|
graph_layout : Array< JssmLayout >,
|
|
@@ -475,11 +476,15 @@ class Machine<mDT> {
|
|
|
475
476
|
_theme : FslTheme;
|
|
476
477
|
_flow : FslDirection;
|
|
477
478
|
|
|
479
|
+
_has_hooks : boolean;
|
|
480
|
+
_hooks : Map<string, Function>;
|
|
481
|
+
_named_hooks : Map<string, Function>;
|
|
482
|
+
|
|
478
483
|
|
|
479
484
|
// whargarbl this badly needs to be broken up, monolith master
|
|
480
485
|
constructor({
|
|
481
486
|
start_states,
|
|
482
|
-
complete
|
|
487
|
+
complete = [],
|
|
483
488
|
transitions,
|
|
484
489
|
machine_author,
|
|
485
490
|
machine_comment,
|
|
@@ -530,6 +535,10 @@ class Machine<mDT> {
|
|
|
530
535
|
this._flow = flow;
|
|
531
536
|
this._graph_layout = graph_layout;
|
|
532
537
|
|
|
538
|
+
this._has_hooks = false;
|
|
539
|
+
this._hooks = new Map();
|
|
540
|
+
this._named_hooks = new Map();
|
|
541
|
+
|
|
533
542
|
|
|
534
543
|
if (state_declaration) {
|
|
535
544
|
state_declaration.map( (state_decl: JssmStateDeclaration) => {
|
|
@@ -601,7 +610,7 @@ class Machine<mDT> {
|
|
|
601
610
|
|
|
602
611
|
|
|
603
612
|
// forward mapping first by action name
|
|
604
|
-
let actionMap: Map<StateType, number> = this._actions.get(tr.action);
|
|
613
|
+
let actionMap: Map<StateType, number> = this._actions.get(tr.action);
|
|
605
614
|
if (!(actionMap)) {
|
|
606
615
|
actionMap = new Map();
|
|
607
616
|
this._actions.set(tr.action, actionMap);
|
|
@@ -615,7 +624,7 @@ class Machine<mDT> {
|
|
|
615
624
|
|
|
616
625
|
|
|
617
626
|
// reverse mapping first by state origin name
|
|
618
|
-
let rActionMap: Map<StateType, number> = this._reverse_actions.get(tr.from);
|
|
627
|
+
let rActionMap: Map<StateType, number> = this._reverse_actions.get(tr.from);
|
|
619
628
|
if (!(rActionMap)) {
|
|
620
629
|
rActionMap = new Map();
|
|
621
630
|
this._reverse_actions.set(tr.from, rActionMap);
|
|
@@ -975,49 +984,165 @@ class Machine<mDT> {
|
|
|
975
984
|
|
|
976
985
|
|
|
977
986
|
|
|
987
|
+
// basic toolable hook call. convenience wrappers will follow, like
|
|
988
|
+
// hook(from, to, handler) and exit_hook(from, handler) and etc
|
|
989
|
+
set_hook(HookDesc: HookDescription) {
|
|
990
|
+
|
|
991
|
+
switch (HookDesc.kind) {
|
|
992
|
+
|
|
993
|
+
case 'hook':
|
|
994
|
+
this._hooks.set(hook_name(HookDesc.from, HookDesc.to), HookDesc.handler);
|
|
995
|
+
this._has_hooks = true;
|
|
996
|
+
break;
|
|
997
|
+
|
|
998
|
+
case 'named':
|
|
999
|
+
this._named_hooks.set(named_hook_name(HookDesc.from, HookDesc.to, HookDesc.action), HookDesc.handler);
|
|
1000
|
+
this._has_hooks = true;
|
|
1001
|
+
break;
|
|
1002
|
+
|
|
1003
|
+
// case 'entry':
|
|
1004
|
+
// console.log('TODO: Should add entry hook here');
|
|
1005
|
+
// throw 'TODO: Should add entry hook here';
|
|
1006
|
+
|
|
1007
|
+
// case 'exit':
|
|
1008
|
+
// console.log('TODO: Should add exit hook here');
|
|
1009
|
+
// throw 'TODO: Should add exit hook here';
|
|
1010
|
+
|
|
1011
|
+
default:
|
|
1012
|
+
console.log(`Unknown hook type ${(HookDesc as any).kind}, should be impossible`);
|
|
1013
|
+
throw new RangeError(`Unknown hook type ${(HookDesc as any).kind}, should be impossible`);
|
|
1014
|
+
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
// remove_hook(HookDesc: HookDescription) {
|
|
1019
|
+
// throw 'TODO: Should remove hook here';
|
|
1020
|
+
// }
|
|
1021
|
+
|
|
1022
|
+
|
|
1023
|
+
|
|
978
1024
|
action(name: StateType, newData?: mDT): boolean {
|
|
979
1025
|
// todo whargarbl implement hooks
|
|
980
1026
|
// todo whargarbl implement data stuff
|
|
981
1027
|
// todo major incomplete whargarbl comeback
|
|
982
1028
|
if (this.valid_action(name, newData)) {
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
1029
|
+
|
|
1030
|
+
const edge : JssmTransition<mDT> = this.current_action_edge_for(name);
|
|
1031
|
+
|
|
1032
|
+
if (this._has_hooks) {
|
|
1033
|
+
|
|
1034
|
+
let hook_permits : boolean | undefined = undefined;
|
|
1035
|
+
|
|
1036
|
+
const nhn : string = named_hook_name(this._state, edge.to, name),
|
|
1037
|
+
maybe_hook = this._named_hooks.get(nhn);
|
|
1038
|
+
|
|
1039
|
+
if (maybe_hook === undefined) { hook_permits = true; }
|
|
1040
|
+
else { hook_permits = maybe_hook( { from: this._state, to: edge.to, action: name } ); }
|
|
1041
|
+
|
|
1042
|
+
if (hook_permits !== false) {
|
|
1043
|
+
this._state = edge.to;
|
|
1044
|
+
return true;
|
|
1045
|
+
} else {
|
|
1046
|
+
return false;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
} else {
|
|
1050
|
+
this._state = edge.to;
|
|
1051
|
+
return true;
|
|
1052
|
+
}
|
|
1053
|
+
|
|
986
1054
|
} else {
|
|
987
1055
|
return false;
|
|
988
1056
|
}
|
|
989
1057
|
}
|
|
990
1058
|
|
|
1059
|
+
|
|
1060
|
+
|
|
991
1061
|
transition(newState: StateType, newData?: mDT): boolean {
|
|
1062
|
+
|
|
992
1063
|
// todo whargarbl implement hooks
|
|
993
1064
|
// todo whargarbl implement data stuff
|
|
994
1065
|
// todo major incomplete whargarbl comeback
|
|
995
1066
|
if (this.valid_transition(newState, newData)) {
|
|
996
|
-
|
|
997
|
-
|
|
1067
|
+
|
|
1068
|
+
if (this._has_hooks) {
|
|
1069
|
+
|
|
1070
|
+
let hook_permits : boolean | undefined = undefined;
|
|
1071
|
+
|
|
1072
|
+
const hn : string = hook_name(this._state, newState),
|
|
1073
|
+
maybe_hook : Function | undefined = this._hooks.get(hn);
|
|
1074
|
+
|
|
1075
|
+
if (maybe_hook === undefined) { hook_permits = true; }
|
|
1076
|
+
else { hook_permits = maybe_hook( { from: this._state, to: newState } ); }
|
|
1077
|
+
|
|
1078
|
+
if (hook_permits !== false) {
|
|
1079
|
+
this._state = newState;
|
|
1080
|
+
return true;
|
|
1081
|
+
} else {
|
|
1082
|
+
return false;
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
} else {
|
|
1086
|
+
|
|
1087
|
+
this._state = newState;
|
|
1088
|
+
return true;
|
|
1089
|
+
|
|
1090
|
+
}
|
|
1091
|
+
|
|
998
1092
|
} else {
|
|
999
1093
|
return false;
|
|
1000
1094
|
}
|
|
1095
|
+
|
|
1001
1096
|
}
|
|
1002
1097
|
|
|
1098
|
+
|
|
1099
|
+
|
|
1003
1100
|
// can leave machine in inconsistent state. generally do not use
|
|
1101
|
+
|
|
1004
1102
|
force_transition(newState: StateType, newData?: mDT): boolean {
|
|
1103
|
+
|
|
1005
1104
|
// todo whargarbl implement hooks
|
|
1006
1105
|
// todo whargarbl implement data stuff
|
|
1007
1106
|
// todo major incomplete whargarbl comeback
|
|
1008
1107
|
if (this.valid_force_transition(newState, newData)) {
|
|
1009
|
-
|
|
1010
|
-
|
|
1108
|
+
|
|
1109
|
+
if (this._has_hooks) {
|
|
1110
|
+
|
|
1111
|
+
let hook_permits : boolean | undefined = undefined;
|
|
1112
|
+
|
|
1113
|
+
const hn : string = hook_name(this._state, newState),
|
|
1114
|
+
maybe_hook : Function | undefined = this._hooks.get(hn);
|
|
1115
|
+
|
|
1116
|
+
if (maybe_hook === undefined) { hook_permits = true; }
|
|
1117
|
+
else { hook_permits = maybe_hook({ from: this._state, to: newState, forced: true }); }
|
|
1118
|
+
|
|
1119
|
+
if (hook_permits !== false) {
|
|
1120
|
+
this._state = newState;
|
|
1121
|
+
return true;
|
|
1122
|
+
} else {
|
|
1123
|
+
return false;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
} else {
|
|
1127
|
+
|
|
1128
|
+
this._state = newState;
|
|
1129
|
+
return true;
|
|
1130
|
+
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1011
1133
|
} else {
|
|
1012
1134
|
return false;
|
|
1013
1135
|
}
|
|
1136
|
+
|
|
1014
1137
|
}
|
|
1015
1138
|
|
|
1016
1139
|
|
|
1017
1140
|
|
|
1018
1141
|
current_action_for(action: StateType): number {
|
|
1019
1142
|
const action_base: Map<StateType, number> = this._actions.get(action);
|
|
1020
|
-
return action_base
|
|
1143
|
+
return action_base
|
|
1144
|
+
? action_base.get(this.state())
|
|
1145
|
+
: undefined;
|
|
1021
1146
|
}
|
|
1022
1147
|
|
|
1023
1148
|
current_action_edge_for(action: StateType): JssmTransition<mDT> {
|
|
@@ -1027,14 +1152,12 @@ class Machine<mDT> {
|
|
|
1027
1152
|
}
|
|
1028
1153
|
|
|
1029
1154
|
valid_action(action: StateType, _newData?: mDT): boolean { // todo comeback unignore newData
|
|
1030
|
-
// todo whargarbl implement hooks
|
|
1031
1155
|
// todo whargarbl implement data stuff
|
|
1032
1156
|
// todo major incomplete whargarbl comeback
|
|
1033
1157
|
return this.current_action_for(action) !== undefined;
|
|
1034
1158
|
}
|
|
1035
1159
|
|
|
1036
1160
|
valid_transition(newState: StateType, _newData?: mDT): boolean { // todo comeback unignore newData
|
|
1037
|
-
// todo whargarbl implement hooks
|
|
1038
1161
|
// todo whargarbl implement data stuff
|
|
1039
1162
|
// todo major incomplete whargarbl comeback
|
|
1040
1163
|
const transition_for: JssmTransition<mDT> = this.lookup_transition_for(this.state(), newState);
|
|
@@ -1047,7 +1170,6 @@ class Machine<mDT> {
|
|
|
1047
1170
|
}
|
|
1048
1171
|
|
|
1049
1172
|
valid_force_transition(newState: StateType, _newData?: mDT): boolean { // todo comeback unignore newData
|
|
1050
|
-
// todo whargarbl implement hooks
|
|
1051
1173
|
// todo whargarbl implement data stuff
|
|
1052
1174
|
// todo major incomplete whargarbl comeback
|
|
1053
1175
|
return (this.lookup_transition_for(this.state(), newState) !== undefined);
|
|
@@ -1081,7 +1203,8 @@ function sm<mDT>(template_strings: TemplateStringsArray, ... remainder /* , argu
|
|
|
1081
1203
|
// string notation, as designed, it's not really worth the hassle
|
|
1082
1204
|
|
|
1083
1205
|
/* eslint-disable prefer-rest-params */
|
|
1084
|
-
(acc, val, idx): string =>
|
|
1206
|
+
(acc, val, idx): string =>
|
|
1207
|
+
`${acc}${remainder[idx-1]}${val}` // arguments[0] is never loaded, so args doesn't need to be gated
|
|
1085
1208
|
/* eslint-enable prefer-rest-params */
|
|
1086
1209
|
|
|
1087
1210
|
)));
|
package/src/ts/jssm_types.ts
CHANGED
|
@@ -305,6 +305,43 @@ type JssmParseFunctionType =
|
|
|
305
305
|
|
|
306
306
|
|
|
307
307
|
|
|
308
|
+
type BasicHookDescription = {
|
|
309
|
+
kind : 'hook'
|
|
310
|
+
from : string,
|
|
311
|
+
to : string,
|
|
312
|
+
handler : Function
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
type HookDescriptionWithAction = {
|
|
316
|
+
kind : 'named',
|
|
317
|
+
from : string,
|
|
318
|
+
to : string,
|
|
319
|
+
action : string,
|
|
320
|
+
handler : Function
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
type EntryHook = {
|
|
324
|
+
kind : 'entry',
|
|
325
|
+
to : string,
|
|
326
|
+
handler : Function
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
type ExitHook = {
|
|
330
|
+
kind : 'exit',
|
|
331
|
+
from : string,
|
|
332
|
+
handler : Function
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
type HookDescription
|
|
336
|
+
= BasicHookDescription
|
|
337
|
+
| HookDescriptionWithAction
|
|
338
|
+
| EntryHook
|
|
339
|
+
| ExitHook;
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
|
|
308
345
|
export {
|
|
309
346
|
|
|
310
347
|
JssmColor,
|
|
@@ -341,6 +378,8 @@ export {
|
|
|
341
378
|
JssmMachineInternalState,
|
|
342
379
|
|
|
343
380
|
FslDirection,
|
|
344
|
-
FslTheme
|
|
381
|
+
FslTheme,
|
|
382
|
+
|
|
383
|
+
HookDescription
|
|
345
384
|
|
|
346
385
|
};
|
package/src/ts/jssm_util.ts
CHANGED
|
@@ -90,11 +90,28 @@ const weighted_histo_key: Function = (n: number, opts: Array<any>, prob_prop: st
|
|
|
90
90
|
|
|
91
91
|
|
|
92
92
|
|
|
93
|
+
const hook_name = (from: string, to: string): string =>
|
|
94
|
+
|
|
95
|
+
JSON.stringify([from, to]);
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
const named_hook_name = (from: string, to: string, action: string): string =>
|
|
102
|
+
|
|
103
|
+
JSON.stringify([from, to, action]);
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
93
109
|
export {
|
|
94
110
|
seq,
|
|
95
111
|
arr_uniq_p,
|
|
96
112
|
histograph, weighted_histo_key,
|
|
97
113
|
weighted_rand_select, weighted_sample_select,
|
|
98
|
-
array_box_if_string
|
|
114
|
+
array_box_if_string,
|
|
115
|
+
hook_name, named_hook_name
|
|
99
116
|
};
|
|
100
117
|
|