state-machine-cat 12.0.5 → 12.0.7

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 (46) hide show
  1. package/dist/cli/actions.mjs +34 -31
  2. package/dist/cli/attributes-parser.mjs +914 -976
  3. package/dist/cli/execute-command-line.mjs +98 -48
  4. package/dist/cli/file-name-to-stream.mjs +8 -8
  5. package/dist/cli/normalize.mjs +89 -70
  6. package/dist/cli/validations.mjs +72 -52
  7. package/dist/index-node.mjs +12 -9
  8. package/dist/index.mjs +10 -7
  9. package/dist/options.mjs +53 -53
  10. package/dist/parse/index.mjs +17 -17
  11. package/dist/parse/parser-helpers.mjs +159 -139
  12. package/dist/parse/scxml/index.mjs +152 -129
  13. package/dist/parse/scxml/normalize-machine.mjs +36 -35
  14. package/dist/parse/scxml/utl.mjs +1 -1
  15. package/dist/parse/smcat/smcat-parser.mjs +2794 -2897
  16. package/dist/parse/smcat-ast.schema.mjs +185 -168
  17. package/dist/render/dot/attributebuilder.mjs +40 -37
  18. package/dist/render/dot/counter.mjs +14 -14
  19. package/dist/render/dot/dot.states.template.js +1 -26
  20. package/dist/render/dot/dot.template.js +1 -14
  21. package/dist/render/dot/index.mjs +129 -82
  22. package/dist/render/dot/render-dot-from-ast.mjs +33 -16
  23. package/dist/render/dot/state-transformers.mjs +96 -85
  24. package/dist/render/dot/transition-transformers.mjs +39 -41
  25. package/dist/render/dot/utl.mjs +21 -19
  26. package/dist/render/index-node.mjs +16 -16
  27. package/dist/render/index.mjs +9 -9
  28. package/dist/render/scjson/index.mjs +111 -94
  29. package/dist/render/scjson/make-valid-event-names.mjs +21 -18
  30. package/dist/render/scjson/make-valid-xml-name.mjs +17 -13
  31. package/dist/render/scxml/index.mjs +2 -1
  32. package/dist/render/scxml/render-from-scjson.mjs +5 -2
  33. package/dist/render/scxml/scxml.states.template.js +1 -14
  34. package/dist/render/scxml/scxml.template.js +1 -6
  35. package/dist/render/smcat/index.mjs +54 -39
  36. package/dist/render/smcat/smcat.template.js +1 -13
  37. package/dist/render/vector/dot-to-vector-native.mjs +30 -26
  38. package/dist/render/vector/vector-native-dot-with-fallback.mjs +27 -20
  39. package/dist/render/vector/vector-with-wasm.mjs +13 -6
  40. package/dist/state-machine-model.mjs +67 -52
  41. package/dist/transform/desugar.mjs +115 -66
  42. package/dist/transform/utl.mjs +12 -12
  43. package/dist/version.mjs +1 -1
  44. package/package.json +74 -74
  45. package/types/state-machine-cat.d.mts +209 -209
  46. package/types/state-machine-cat.d.ts +0 -296
package/dist/options.mjs CHANGED
@@ -1,61 +1,61 @@
1
1
  const ALLOWED_VALUES = Object.freeze({
2
- inputType: {
3
- default: "smcat",
4
- values: [{ name: "smcat" }, { name: "json" }, { name: "scxml" }],
5
- },
6
- outputType: {
7
- default: "svg",
8
- values: [
9
- { name: "ast" },
10
- { name: "dot" },
11
- { name: "eps" },
12
- { name: "json" },
13
- { name: "oldeps" },
14
- { name: "oldps" },
15
- { name: "oldps2" },
16
- { name: "oldsvg" },
17
- { name: "pdf" },
18
- { name: "png" },
19
- { name: "ps" },
20
- { name: "ps2" },
21
- { name: "scjson" },
22
- { name: "scxml" },
23
- { name: "smcat" },
24
- { name: "svg" },
25
- ],
26
- },
27
- engine: {
28
- default: "dot",
29
- values: [
30
- { name: "dot" },
31
- { name: "circo" },
32
- { name: "fdp" },
33
- { name: "neato" },
34
- { name: "osage" },
35
- { name: "twopi" },
36
- ],
37
- },
38
- direction: {
39
- default: "top-down",
40
- values: [
41
- { name: "top-down" },
42
- { name: "bottom-top" },
43
- { name: "left-right" },
44
- { name: "right-left" },
45
- ],
46
- },
47
- desugar: {
48
- default: false,
49
- values: [{ name: true }, { name: false }],
50
- },
2
+ inputType: {
3
+ default: "smcat",
4
+ values: [{ name: "smcat" }, { name: "json" }, { name: "scxml" }],
5
+ },
6
+ outputType: {
7
+ default: "svg",
8
+ values: [
9
+ { name: "ast" },
10
+ { name: "dot" },
11
+ { name: "eps" },
12
+ { name: "json" },
13
+ { name: "oldeps" },
14
+ { name: "oldps" },
15
+ { name: "oldps2" },
16
+ { name: "oldsvg" },
17
+ { name: "pdf" },
18
+ { name: "png" },
19
+ { name: "ps" },
20
+ { name: "ps2" },
21
+ { name: "scjson" },
22
+ { name: "scxml" },
23
+ { name: "smcat" },
24
+ { name: "svg" },
25
+ ],
26
+ },
27
+ engine: {
28
+ default: "dot",
29
+ values: [
30
+ { name: "dot" },
31
+ { name: "circo" },
32
+ { name: "fdp" },
33
+ { name: "neato" },
34
+ { name: "osage" },
35
+ { name: "twopi" },
36
+ ],
37
+ },
38
+ direction: {
39
+ default: "top-down",
40
+ values: [
41
+ { name: "top-down" },
42
+ { name: "bottom-top" },
43
+ { name: "left-right" },
44
+ { name: "right-left" },
45
+ ],
46
+ },
47
+ desugar: {
48
+ default: false,
49
+ values: [{ name: true }, { name: false }],
50
+ },
51
51
  });
52
52
  function getOptionValue(pOptions, pOptionName) {
53
- return pOptions?.[pOptionName] ?? ALLOWED_VALUES[pOptionName].default;
53
+ return pOptions?.[pOptionName] ?? ALLOWED_VALUES[pOptionName].default;
54
54
  }
55
55
  function getAllowedValues() {
56
- return ALLOWED_VALUES;
56
+ return ALLOWED_VALUES;
57
57
  }
58
58
  export default {
59
- getAllowedValues,
60
- getOptionValue,
59
+ getAllowedValues,
60
+ getOptionValue,
61
61
  };
@@ -5,23 +5,23 @@ import { parse as parseSCXML } from "./scxml/index.mjs";
5
5
  import $schema from "./smcat-ast.schema.mjs";
6
6
  const ajv = new Ajv();
7
7
  function validateAgainstSchema(pSchema, pObject) {
8
- if (!ajv.validate(pSchema, pObject)) {
9
- throw new Error(`The provided JSON is not a valid state-machine-cat AST: ${ajv.errorsText()}.\n`);
10
- }
8
+ if (!ajv.validate(pSchema, pObject)) {
9
+ throw new Error(
10
+ `The provided JSON is not a valid state-machine-cat AST: ${ajv.errorsText()}.\n`,
11
+ );
12
+ }
11
13
  }
12
14
  export default {
13
- getAST(pScript, pOptions) {
14
- let lReturnValue = pScript;
15
- if (options.getOptionValue(pOptions, "inputType") === "smcat") {
16
- lReturnValue = parseSmCat(pScript);
17
- }
18
- else if (options.getOptionValue(pOptions, "inputType") === "scxml") {
19
- lReturnValue = parseSCXML(pScript);
20
- }
21
- else if (typeof pScript === "string") {
22
- lReturnValue = JSON.parse(pScript);
23
- }
24
- validateAgainstSchema($schema, lReturnValue);
25
- return lReturnValue;
26
- },
15
+ getAST(pScript, pOptions) {
16
+ let lReturnValue = pScript;
17
+ if (options.getOptionValue(pOptions, "inputType") === "smcat") {
18
+ lReturnValue = parseSmCat(pScript);
19
+ } else if (options.getOptionValue(pOptions, "inputType") === "scxml") {
20
+ lReturnValue = parseSCXML(pScript);
21
+ } else if (typeof pScript === "string") {
22
+ lReturnValue = JSON.parse(pScript);
23
+ }
24
+ validateAgainstSchema($schema, lReturnValue);
25
+ return lReturnValue;
26
+ },
27
27
  };
@@ -1,175 +1,195 @@
1
1
  import StateMachineModel from "../state-machine-model.mjs";
2
- const TRIGGER_RE_AS_A_STRING = "^(entry|activity|exit)\\s*/\\s*([^\\n$]*)(\\n|$)";
2
+ const TRIGGER_RE_AS_A_STRING =
3
+ "^(entry|activity|exit)\\s*/\\s*([^\\n$]*)(\\n|$)";
3
4
  const TRIGGER_RE = new RegExp(TRIGGER_RE_AS_A_STRING);
4
5
  function stateExists(pKnownStateNames, pName) {
5
- return pKnownStateNames.includes(pName);
6
+ return pKnownStateNames.includes(pName);
6
7
  }
7
8
  const RE2STATE_TYPE = [
8
- {
9
- re: /initial/,
10
- stateType: "initial",
11
- },
12
- {
13
- re: /final/,
14
- stateType: "final",
15
- },
16
- {
17
- re: /parallel/,
18
- stateType: "parallel",
19
- },
20
- {
21
- re: /(deep.*history)|(history.*deep)/,
22
- stateType: "deephistory",
23
- },
24
- {
25
- re: /history/,
26
- stateType: "history",
27
- },
28
- {
29
- re: /^\^.*/,
30
- stateType: "choice",
31
- },
32
- {
33
- re: /^].*/,
34
- stateType: "forkjoin",
35
- },
9
+ {
10
+ re: /initial/,
11
+ stateType: "initial",
12
+ },
13
+ {
14
+ re: /final/,
15
+ stateType: "final",
16
+ },
17
+ {
18
+ re: /parallel/,
19
+ stateType: "parallel",
20
+ },
21
+ {
22
+ re: /(deep.*history)|(history.*deep)/,
23
+ stateType: "deephistory",
24
+ },
25
+ {
26
+ re: /history/,
27
+ stateType: "history",
28
+ },
29
+ {
30
+ re: /^\^.*/,
31
+ stateType: "choice",
32
+ },
33
+ {
34
+ re: /^].*/,
35
+ stateType: "forkjoin",
36
+ },
36
37
  ];
37
38
  function matches(pName) {
38
- return (pEntry) => pEntry.re.test(pName);
39
+ return (pEntry) => pEntry.re.test(pName);
39
40
  }
40
41
  function getStateType(pName) {
41
- return (RE2STATE_TYPE.find(matches(pName)) || { stateType: "regular" })
42
- .stateType;
42
+ return (RE2STATE_TYPE.find(matches(pName)) || { stateType: "regular" })
43
+ .stateType;
43
44
  }
44
45
  function initState(pName) {
45
- return {
46
- name: pName,
47
- type: getStateType(pName),
48
- };
46
+ return {
47
+ name: pName,
48
+ type: getStateType(pName),
49
+ };
49
50
  }
50
51
  function isComposite(pState) {
51
- return Boolean(pState.statemachine);
52
+ return Boolean(pState.statemachine);
52
53
  }
53
54
  function getAlreadyDeclaredStates(pStateMachine) {
54
- const lStates = pStateMachine?.states ?? [];
55
- return lStates.filter(isComposite).reduce((pAllStateNames, pThisState) => pAllStateNames.concat(getAlreadyDeclaredStates(pThisState.statemachine)), lStates.map(({ name }) => name));
55
+ const lStates = pStateMachine?.states ?? [];
56
+ return lStates.filter(isComposite).reduce(
57
+ (pAllStateNames, pThisState) =>
58
+ pAllStateNames.concat(getAlreadyDeclaredStates(pThisState.statemachine)),
59
+ lStates.map(({ name }) => name),
60
+ );
56
61
  }
57
62
  function extractUndeclaredStates(pStateMachine, pKnownStateNames) {
58
- pKnownStateNames = pKnownStateNames
59
- ? pKnownStateNames
60
- : getAlreadyDeclaredStates(pStateMachine);
61
- pStateMachine.states = pStateMachine?.states ?? [];
62
- const lTransitions = pStateMachine?.transitions ?? [];
63
- pStateMachine.states.filter(isComposite).forEach((pState) => {
64
- pState.statemachine.states = extractUndeclaredStates(pState.statemachine, pKnownStateNames);
65
- });
66
- lTransitions.forEach((pTransition) => {
67
- if (!stateExists(pKnownStateNames, pTransition.from)) {
68
- pKnownStateNames.push(pTransition.from);
69
- pStateMachine.states.push(initState(pTransition.from));
70
- }
71
- if (!stateExists(pKnownStateNames, pTransition.to)) {
72
- pKnownStateNames.push(pTransition.to);
73
- pStateMachine.states.push(initState(pTransition.to));
74
- }
75
- });
76
- return pStateMachine.states;
63
+ pKnownStateNames = pKnownStateNames
64
+ ? pKnownStateNames
65
+ : getAlreadyDeclaredStates(pStateMachine);
66
+ pStateMachine.states = pStateMachine?.states ?? [];
67
+ const lTransitions = pStateMachine?.transitions ?? [];
68
+ pStateMachine.states.filter(isComposite).forEach((pState) => {
69
+ pState.statemachine.states = extractUndeclaredStates(
70
+ pState.statemachine,
71
+ pKnownStateNames,
72
+ );
73
+ });
74
+ lTransitions.forEach((pTransition) => {
75
+ if (!stateExists(pKnownStateNames, pTransition.from)) {
76
+ pKnownStateNames.push(pTransition.from);
77
+ pStateMachine.states.push(initState(pTransition.from));
78
+ }
79
+ if (!stateExists(pKnownStateNames, pTransition.to)) {
80
+ pKnownStateNames.push(pTransition.to);
81
+ pStateMachine.states.push(initState(pTransition.to));
82
+ }
83
+ });
84
+ return pStateMachine.states;
77
85
  }
78
86
  function classifyForkJoin(pInComingCount, pOutGoingCount) {
79
- let lReturnValue = "junction";
80
- if (pInComingCount <= 1 && pOutGoingCount > 1) {
81
- lReturnValue = "fork";
82
- }
83
- if (pInComingCount > 1 && pOutGoingCount <= 1) {
84
- lReturnValue = "join";
85
- }
86
- return lReturnValue;
87
- }
88
- function classifyForkJoins(pStateMachine, pFlattenedStateMachineModel = new StateMachineModel(pStateMachine)) {
89
- pStateMachine.states = pStateMachine.states.map((pState) => {
90
- if (pState.type === "forkjoin" && !pState.typeExplicitlySet) {
91
- const lInComingCount = pFlattenedStateMachineModel.findTransitionsByTo(pState.name).length;
92
- const lOutGoingCount = pFlattenedStateMachineModel.findTransitionsByFrom(pState.name).length;
93
- pState.type = classifyForkJoin(lInComingCount, lOutGoingCount);
94
- }
95
- if (pState.statemachine) {
96
- pState.statemachine = classifyForkJoins(pState.statemachine, pFlattenedStateMachineModel);
97
- }
98
- return pState;
99
- });
100
- return pStateMachine;
87
+ let lReturnValue = "junction";
88
+ if (pInComingCount <= 1 && pOutGoingCount > 1) {
89
+ lReturnValue = "fork";
90
+ }
91
+ if (pInComingCount > 1 && pOutGoingCount <= 1) {
92
+ lReturnValue = "join";
93
+ }
94
+ return lReturnValue;
95
+ }
96
+ function classifyForkJoins(
97
+ pStateMachine,
98
+ pFlattenedStateMachineModel = new StateMachineModel(pStateMachine),
99
+ ) {
100
+ pStateMachine.states = pStateMachine.states.map((pState) => {
101
+ if (pState.type === "forkjoin" && !pState.typeExplicitlySet) {
102
+ const lInComingCount = pFlattenedStateMachineModel.findTransitionsByTo(
103
+ pState.name,
104
+ ).length;
105
+ const lOutGoingCount = pFlattenedStateMachineModel.findTransitionsByFrom(
106
+ pState.name,
107
+ ).length;
108
+ pState.type = classifyForkJoin(lInComingCount, lOutGoingCount);
109
+ }
110
+ if (pState.statemachine) {
111
+ pState.statemachine = classifyForkJoins(
112
+ pState.statemachine,
113
+ pFlattenedStateMachineModel,
114
+ );
115
+ }
116
+ return pState;
117
+ });
118
+ return pStateMachine;
101
119
  }
102
120
  function stateEqual(pStateOne, pStateTwo) {
103
- return pStateOne.name === pStateTwo.name;
121
+ return pStateOne.name === pStateTwo.name;
104
122
  }
105
123
  function uniq(pArray, pEqualFunction) {
106
- return pArray.reduce((pBag, pMarble) => {
107
- const lMarbleIndex = pBag.findIndex((pBagItem) => pEqualFunction(pBagItem, pMarble));
108
- if (lMarbleIndex > -1) {
109
- pBag[lMarbleIndex] = pMarble;
110
- return pBag;
111
- }
112
- return pBag.concat(pMarble);
113
- }, []);
124
+ return pArray.reduce((pBag, pMarble) => {
125
+ const lMarbleIndex = pBag.findIndex((pBagItem) =>
126
+ pEqualFunction(pBagItem, pMarble),
127
+ );
128
+ if (lMarbleIndex > -1) {
129
+ pBag[lMarbleIndex] = pMarble;
130
+ return pBag;
131
+ }
132
+ return pBag.concat(pMarble);
133
+ }, []);
114
134
  }
115
135
  function parseTransitionExpression(pString) {
116
- const lTransitionExpressionRe = /([^[/]+)?(\[[^\]]+\])?[^/]*(\/.+)?/;
117
- const lReturnValue = {};
118
- const lMatchResult = pString.match(lTransitionExpressionRe);
119
- const lEventPos = 1;
120
- const lConditionPos = 2;
121
- const lActionPos = 3;
122
- if (lMatchResult[lEventPos]) {
123
- lReturnValue.event = lMatchResult[lEventPos].trim();
124
- }
125
- if (lMatchResult[lConditionPos]) {
126
- lReturnValue.cond = lMatchResult[lConditionPos].slice(1, -1).trim();
127
- }
128
- if (lMatchResult[lActionPos]) {
129
- lReturnValue.action = lMatchResult[lActionPos]
130
- .slice(1, lMatchResult[lActionPos].length)
131
- .trim();
132
- }
133
- return lReturnValue;
136
+ const lTransitionExpressionRe = /([^[/]+)?(\[[^\]]+\])?[^/]*(\/.+)?/;
137
+ const lReturnValue = {};
138
+ const lMatchResult = pString.match(lTransitionExpressionRe);
139
+ const lEventPos = 1;
140
+ const lConditionPos = 2;
141
+ const lActionPos = 3;
142
+ if (lMatchResult[lEventPos]) {
143
+ lReturnValue.event = lMatchResult[lEventPos].trim();
144
+ }
145
+ if (lMatchResult[lConditionPos]) {
146
+ lReturnValue.cond = lMatchResult[lConditionPos].slice(1, -1).trim();
147
+ }
148
+ if (lMatchResult[lActionPos]) {
149
+ lReturnValue.action = lMatchResult[lActionPos]
150
+ .slice(1, lMatchResult[lActionPos].length)
151
+ .trim();
152
+ }
153
+ return lReturnValue;
134
154
  }
135
155
  function setIf(pObject, pProperty, pValue, pCondition = Boolean) {
136
- if (pCondition(pValue)) {
137
- pObject[pProperty] = pValue;
138
- }
156
+ if (pCondition(pValue)) {
157
+ pObject[pProperty] = pValue;
158
+ }
139
159
  }
140
160
  function setIfNotEmpty(pObject, pProperty, pValue) {
141
- setIf(pObject, pProperty, pValue, (pX) => pX && pX.length > 0);
161
+ setIf(pObject, pProperty, pValue, (pX) => pX && pX.length > 0);
142
162
  }
143
163
  function extractAction(pActivityCandidate) {
144
- const lMatch = pActivityCandidate.match(TRIGGER_RE);
145
- const lTypePos = 1;
146
- const lBodyPos = 2;
147
- if (lMatch) {
148
- return {
149
- type: lMatch[lTypePos],
150
- body: lMatch[lBodyPos],
151
- };
152
- }
153
- return {
154
- type: "activity",
155
- body: pActivityCandidate,
156
- };
164
+ const lMatch = pActivityCandidate.match(TRIGGER_RE);
165
+ const lTypePos = 1;
166
+ const lBodyPos = 2;
167
+ if (lMatch) {
168
+ return {
169
+ type: lMatch[lTypePos],
170
+ body: lMatch[lBodyPos],
171
+ };
172
+ }
173
+ return {
174
+ type: "activity",
175
+ body: pActivityCandidate,
176
+ };
157
177
  }
158
178
  function extractActions(pString) {
159
- return pString
160
- .split(/\n\s*/g)
161
- .map((pActivityCandidate) => pActivityCandidate.trim())
162
- .map(extractAction);
179
+ return pString
180
+ .split(/\n\s*/g)
181
+ .map((pActivityCandidate) => pActivityCandidate.trim())
182
+ .map(extractAction);
163
183
  }
164
184
  export default {
165
- initState,
166
- extractUndeclaredStates,
167
- classifyForkJoins,
168
- getStateType,
169
- stateEqual,
170
- uniq,
171
- parseTransitionExpression,
172
- extractActions,
173
- setIf,
174
- setIfNotEmpty,
185
+ initState,
186
+ extractUndeclaredStates,
187
+ classifyForkJoins,
188
+ getStateType,
189
+ stateEqual,
190
+ uniq,
191
+ parseTransitionExpression,
192
+ extractActions,
193
+ setIf,
194
+ setIfNotEmpty,
175
195
  };