state-machine-cat 10.1.6 → 10.1.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.
- package/bin/smcat.mjs +5 -4
- package/dist/commonjs/bundle.js +67 -67
- package/{src → dist/esm}/cli/actions.mjs +24 -40
- package/dist/esm/cli/attributes-parser.mjs +981 -0
- package/dist/esm/cli/file-name-to-stream.mjs +13 -0
- package/dist/esm/cli/make-description.mjs +21 -0
- package/dist/esm/cli/normalize.mjs +95 -0
- package/dist/esm/cli/validations.mjs +70 -0
- package/dist/esm/index-node.mjs +16 -0
- package/dist/esm/index.mjs +19 -0
- package/dist/esm/options.mjs +61 -0
- package/dist/esm/parse/index.mjs +27 -0
- package/dist/esm/parse/parser-helpers.mjs +175 -0
- package/dist/esm/parse/scxml/index.mjs +136 -0
- package/dist/esm/parse/scxml/normalize-machine.mjs +44 -0
- package/dist/esm/parse/smcat/smcat-parser.mjs +2924 -0
- package/dist/esm/parse/smcat-ast.schema.mjs +170 -0
- package/dist/esm/render/dot/attributebuilder.mjs +51 -0
- package/dist/esm/render/dot/counter.mjs +16 -0
- package/dist/esm/render/dot/dot.states.template.js +26 -0
- package/dist/esm/render/dot/dot.template.js +14 -0
- package/dist/esm/render/dot/index.mjs +106 -0
- package/dist/esm/render/dot/render-dot-from-ast.js +29 -0
- package/dist/esm/render/dot/state-transformers.mjs +113 -0
- package/dist/esm/render/dot/transition-transformers.mjs +49 -0
- package/dist/esm/render/dot/utl.mjs +29 -0
- package/dist/esm/render/index-node.mjs +28 -0
- package/dist/esm/render/index.mjs +20 -0
- package/dist/esm/render/scjson/index.mjs +121 -0
- package/dist/esm/render/scjson/make-valid-event-names.mjs +27 -0
- package/dist/esm/render/scjson/make-valid-xml-name.mjs +19 -0
- package/dist/esm/render/scxml/index.mjs +4 -0
- package/dist/esm/render/scxml/render-from-scjson.js +9 -0
- package/dist/esm/render/scxml/scxml.states.template.js +14 -0
- package/dist/esm/render/scxml/scxml.template.js +6 -0
- package/dist/esm/render/smcat/index.js +63 -0
- package/dist/esm/render/smcat/smcat.template.js +13 -0
- package/dist/esm/render/vector/dot-to-vector-native.mjs +35 -0
- package/dist/esm/render/vector/vector-native-dot-with-fallback.mjs +37 -0
- package/dist/esm/render/vector/vector-with-viz-js.mjs +13 -0
- package/dist/esm/state-machine-model.mjs +58 -0
- package/dist/esm/transform/desugar.mjs +77 -0
- package/dist/esm/transform/utl.mjs +16 -0
- package/dist/esm/version.mjs +1 -0
- package/package.json +32 -41
- package/src/render/dot/dot.states.template.js +1 -1
- package/src/render/dot/index.mjs +14 -14
- package/types/state-machine-cat.d.ts +4 -4
- package/src/cli/file-name-to-stream.mjs +0 -25
- package/src/cli/make-description.mjs +0 -45
- package/src/cli/normalize.mjs +0 -204
- package/src/cli/validations.mjs +0 -140
- package/src/index-node.mjs +0 -55
- package/src/index.mjs +0 -58
- package/src/options.mjs +0 -78
- package/src/parse/index.mjs +0 -47
- package/src/parse/parser-helpers.mjs +0 -297
- package/src/parse/scxml/normalize-machine.mjs +0 -73
- package/src/parse/smcat-ast.schema.mjs +0 -187
- package/src/render/dot/attributebuilder.mjs +0 -68
- package/src/render/dot/counter.mjs +0 -33
- package/src/render/dot/render-dot-from-ast.js +0 -70
- package/src/render/dot/state-transformers.mjs +0 -128
- package/src/render/dot/transition-transformers.mjs +0 -52
- package/src/render/dot/utl.mjs +0 -56
- package/src/render/index-node.mjs +0 -36
- package/src/render/index.mjs +0 -22
- package/src/render/scjson/index.mjs +0 -175
- package/src/render/scjson/make-valid-event-names.mjs +0 -71
- package/src/render/scjson/make-valid-xml-name.mjs +0 -70
- package/src/render/scxml/index.mjs +0 -8
- package/src/render/smcat/index.js +0 -129
- package/src/render/vector/dot-to-vector-native.mjs +0 -60
- package/src/render/vector/vector-native-dot-with-fallback.mjs +0 -55
- package/src/render/vector/vector-with-viz-js.mjs +0 -18
- package/src/state-machine-model.mjs +0 -124
- package/src/transform/desugar.mjs +0 -222
- package/src/transform/utl.mjs +0 -26
- package/src/version.mjs +0 -2
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
/* eslint-disable security/detect-object-injection */
|
|
3
|
-
import StateMachineModel from "../state-machine-model.mjs";
|
|
4
|
-
|
|
5
|
-
const TRIGGER_RE_AS_A_STRING =
|
|
6
|
-
"^(entry|activity|exit)\\s*/\\s*([^\\n$]*)(\\n|$)";
|
|
7
|
-
/* eslint security/detect-non-literal-regexp:0 */
|
|
8
|
-
const TRIGGER_RE = new RegExp(TRIGGER_RE_AS_A_STRING);
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* @param {string[]} pKnownStateNames
|
|
12
|
-
* @param {string} pName
|
|
13
|
-
* @returns {boolean}
|
|
14
|
-
*/
|
|
15
|
-
function stateExists(pKnownStateNames, pName) {
|
|
16
|
-
return pKnownStateNames.includes(pName);
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* @type {{
|
|
20
|
-
* re:RegExp;
|
|
21
|
-
* stateType: import("../../types/state-machine-cat.js").StateType;
|
|
22
|
-
* }[]}
|
|
23
|
-
*/
|
|
24
|
-
const RE2STATE_TYPE = [
|
|
25
|
-
{
|
|
26
|
-
re: /initial/,
|
|
27
|
-
stateType: "initial",
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
re: /final/,
|
|
31
|
-
stateType: "final",
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
re: /parallel/,
|
|
35
|
-
stateType: "parallel",
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
re: /(deep.*history)|(history.*deep)/,
|
|
39
|
-
stateType: "deephistory",
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
re: /history/,
|
|
43
|
-
stateType: "history",
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
re: /^\^.*/,
|
|
47
|
-
stateType: "choice",
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
re: /^].*/,
|
|
51
|
-
stateType: "forkjoin",
|
|
52
|
-
},
|
|
53
|
-
];
|
|
54
|
-
|
|
55
|
-
function matches(pName) {
|
|
56
|
-
return (pEntry) => pEntry.re.test(pName);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* @param {string} [pName]
|
|
61
|
-
* @returns {import("../../types/state-machine-cat.js").StateType}
|
|
62
|
-
*/
|
|
63
|
-
function getStateType(pName) {
|
|
64
|
-
return (RE2STATE_TYPE.find(matches(pName)) || { stateType: "regular" })
|
|
65
|
-
.stateType;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* @param {string} pName
|
|
70
|
-
* @returns {import("../../types/state-machine-cat.js").IState}
|
|
71
|
-
*/
|
|
72
|
-
function initState(pName) {
|
|
73
|
-
return {
|
|
74
|
-
name: pName,
|
|
75
|
-
type: getStateType(pName),
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* @param {import("../../types/state-machine-cat.js").IState} pState
|
|
81
|
-
* @returns {boolean}
|
|
82
|
-
*/
|
|
83
|
-
function isComposite(pState) {
|
|
84
|
-
return Boolean(pState.statemachine);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* @param {import("../../types/state-machine-cat.js").IStateMachine} [pStateMachine]
|
|
89
|
-
* @returns {string[]}
|
|
90
|
-
*/
|
|
91
|
-
function getAlreadyDeclaredStates(pStateMachine) {
|
|
92
|
-
const lStates = pStateMachine?.states ?? [];
|
|
93
|
-
|
|
94
|
-
return lStates.filter(isComposite).reduce(
|
|
95
|
-
(pAllStateNames, pThisState) =>
|
|
96
|
-
pAllStateNames.concat(getAlreadyDeclaredStates(pThisState.statemachine)),
|
|
97
|
-
lStates.map(({ name }) => name)
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* @param {import("../../types/state-machine-cat.js").IStateMachine} pStateMachine
|
|
103
|
-
* @param {string[]} pKnownStateNames
|
|
104
|
-
* @returns {import("../../types/state-machine-cat.js").IState[]}
|
|
105
|
-
*/
|
|
106
|
-
function extractUndeclaredStates(pStateMachine, pKnownStateNames) {
|
|
107
|
-
pKnownStateNames = pKnownStateNames
|
|
108
|
-
? pKnownStateNames
|
|
109
|
-
: getAlreadyDeclaredStates(pStateMachine);
|
|
110
|
-
|
|
111
|
-
pStateMachine.states = pStateMachine?.states ?? [];
|
|
112
|
-
const lTransitions = pStateMachine?.transitions ?? [];
|
|
113
|
-
|
|
114
|
-
pStateMachine.states.filter(isComposite).forEach((pState) => {
|
|
115
|
-
// @ts-expect-error isComposite guarantees the statemachine attribute exists, TS doesn't understand that yet, though
|
|
116
|
-
pState.statemachine.states = extractUndeclaredStates(
|
|
117
|
-
// @ts-expect-error isComposite guarantees the statemachine attribute exists, TS doesn't understand that yet, though
|
|
118
|
-
pState.statemachine,
|
|
119
|
-
pKnownStateNames
|
|
120
|
-
);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
lTransitions.forEach((pTransition) => {
|
|
124
|
-
if (!stateExists(pKnownStateNames, pTransition.from)) {
|
|
125
|
-
pKnownStateNames.push(pTransition.from);
|
|
126
|
-
pStateMachine.states.push(initState(pTransition.from));
|
|
127
|
-
}
|
|
128
|
-
if (!stateExists(pKnownStateNames, pTransition.to)) {
|
|
129
|
-
pKnownStateNames.push(pTransition.to);
|
|
130
|
-
pStateMachine.states.push(initState(pTransition.to));
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
return pStateMachine.states;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* @param {number} pInComingCount
|
|
138
|
-
* @param {number} pOutGoingCount
|
|
139
|
-
* @returns {import("../../types/state-machine-cat.js").StateType}
|
|
140
|
-
*/
|
|
141
|
-
function classifyForkJoin(pInComingCount, pOutGoingCount) {
|
|
142
|
-
/** @type {import("../../types/state-machine-cat.js").StateType} */
|
|
143
|
-
let lReturnValue = "junction";
|
|
144
|
-
|
|
145
|
-
if (pInComingCount <= 1 && pOutGoingCount > 1) {
|
|
146
|
-
lReturnValue = "fork";
|
|
147
|
-
}
|
|
148
|
-
if (pInComingCount > 1 && pOutGoingCount <= 1) {
|
|
149
|
-
lReturnValue = "join";
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return lReturnValue;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* @param {import("../../types/state-machine-cat.js").IStateMachine} pStateMachine
|
|
157
|
-
* @param {StateMachineModel} pFlattenedStateMachineModel
|
|
158
|
-
* @returns {import("../../types/state-machine-cat.js").IStateMachine}
|
|
159
|
-
*/
|
|
160
|
-
function classifyForkJoins(
|
|
161
|
-
pStateMachine,
|
|
162
|
-
pFlattenedStateMachineModel = new StateMachineModel(pStateMachine)
|
|
163
|
-
) {
|
|
164
|
-
// TODO: mutates parameter
|
|
165
|
-
pStateMachine.states = pStateMachine.states.map((pState) => {
|
|
166
|
-
if (pState.type === "forkjoin" && !pState.typeExplicitlySet) {
|
|
167
|
-
const lInComingCount = pFlattenedStateMachineModel.findTransitionsByTo(
|
|
168
|
-
pState.name
|
|
169
|
-
).length;
|
|
170
|
-
const lOutGoingCount = pFlattenedStateMachineModel.findTransitionsByFrom(
|
|
171
|
-
pState.name
|
|
172
|
-
).length;
|
|
173
|
-
|
|
174
|
-
pState.type = classifyForkJoin(lInComingCount, lOutGoingCount);
|
|
175
|
-
}
|
|
176
|
-
if (pState.statemachine) {
|
|
177
|
-
pState.statemachine = classifyForkJoins(
|
|
178
|
-
pState.statemachine,
|
|
179
|
-
pFlattenedStateMachineModel
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
return pState;
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
return pStateMachine;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* @param {import("../../types/state-machine-cat.js").IState} pStateOne
|
|
190
|
-
* @param {import("../../types/state-machine-cat.js").IState} pStateTwo
|
|
191
|
-
* @returns {boolean}
|
|
192
|
-
*/
|
|
193
|
-
function stateEqual(pStateOne, pStateTwo) {
|
|
194
|
-
return pStateOne.name === pStateTwo.name;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
function uniq(pArray, pEqualFunction) {
|
|
198
|
-
return pArray.reduce((pBag, pMarble) => {
|
|
199
|
-
const lMarbleIndex = pBag.findIndex((pBagItem) =>
|
|
200
|
-
pEqualFunction(pBagItem, pMarble)
|
|
201
|
-
);
|
|
202
|
-
|
|
203
|
-
if (lMarbleIndex > -1) {
|
|
204
|
-
// ensures the _last_ marble we find is in the bag on that position
|
|
205
|
-
pBag[lMarbleIndex] = pMarble;
|
|
206
|
-
return pBag;
|
|
207
|
-
}
|
|
208
|
-
return pBag.concat(pMarble);
|
|
209
|
-
}, []);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* @param {String} pString
|
|
214
|
-
* @returns {{event?: string; cond?: string; action?: string}}
|
|
215
|
-
*/
|
|
216
|
-
function parseTransitionExpression(pString) {
|
|
217
|
-
// eslint-disable-next-line security/detect-unsafe-regex, unicorn/no-unsafe-regex
|
|
218
|
-
const lTransitionExpressionRe = /([^[/]+)?(\[[^\]]+\])?[^/]*(\/.+)?/;
|
|
219
|
-
const lReturnValue = {};
|
|
220
|
-
|
|
221
|
-
/** @type {RegExpMatchArray} */
|
|
222
|
-
// @ts-expect-error match has no fallback because lTransitionExpressionRe will match
|
|
223
|
-
// any string (every part is optional)
|
|
224
|
-
const lMatchResult = pString.match(lTransitionExpressionRe);
|
|
225
|
-
const lEventPos = 1;
|
|
226
|
-
const lConditionPos = 2;
|
|
227
|
-
const lActionPos = 3;
|
|
228
|
-
|
|
229
|
-
if (lMatchResult[lEventPos]) {
|
|
230
|
-
lReturnValue.event = lMatchResult[lEventPos].trim();
|
|
231
|
-
}
|
|
232
|
-
if (lMatchResult[lConditionPos]) {
|
|
233
|
-
lReturnValue.cond = lMatchResult[lConditionPos].slice(1, -1).trim();
|
|
234
|
-
}
|
|
235
|
-
if (lMatchResult[lActionPos]) {
|
|
236
|
-
lReturnValue.action = lMatchResult[lActionPos]
|
|
237
|
-
.slice(1, lMatchResult[lActionPos].length)
|
|
238
|
-
.trim();
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
return lReturnValue;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
function setIf(pObject, pProperty, pValue, pCondition = (pX) => pX) {
|
|
245
|
-
if (pCondition(pValue)) {
|
|
246
|
-
pObject[pProperty] = pValue;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
function setIfNotEmpty(pObject, pProperty, pValue) {
|
|
251
|
-
setIf(pObject, pProperty, pValue, (pX) => pX && pX.length > 0);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* @param {string} pActivityCandidate
|
|
256
|
-
* @returns {{type: string; body: string}}
|
|
257
|
-
*/
|
|
258
|
-
function extractAction(pActivityCandidate) {
|
|
259
|
-
const lMatch = pActivityCandidate.match(TRIGGER_RE);
|
|
260
|
-
const lTypePos = 1;
|
|
261
|
-
const lBodyPos = 2;
|
|
262
|
-
|
|
263
|
-
if (lMatch) {
|
|
264
|
-
return {
|
|
265
|
-
type: lMatch[lTypePos],
|
|
266
|
-
body: lMatch[lBodyPos],
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
return {
|
|
270
|
-
type: "activity",
|
|
271
|
-
body: pActivityCandidate,
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* @param {string} pString
|
|
277
|
-
* @returns {{type: string; body: string}[]}
|
|
278
|
-
*/
|
|
279
|
-
function extractActions(pString) {
|
|
280
|
-
return pString
|
|
281
|
-
.split(/\n\s*/g)
|
|
282
|
-
.map((pActivityCandidate) => pActivityCandidate.trim())
|
|
283
|
-
.map(extractAction);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
export default {
|
|
287
|
-
initState,
|
|
288
|
-
extractUndeclaredStates,
|
|
289
|
-
classifyForkJoins,
|
|
290
|
-
getStateType,
|
|
291
|
-
stateEqual,
|
|
292
|
-
uniq,
|
|
293
|
-
parseTransitionExpression,
|
|
294
|
-
extractActions,
|
|
295
|
-
setIf,
|
|
296
|
-
setIfNotEmpty,
|
|
297
|
-
};
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import castArray from "lodash/castArray.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @param {Partial<import("./scxml").ISCXMLInitialState>} pInitialObject
|
|
5
|
-
* @param {string} [pId]
|
|
6
|
-
* @returns {import("./scxml").ISCXMLInitialState}
|
|
7
|
-
*/
|
|
8
|
-
function normalizeInitialFromObject(pInitialObject, pId) {
|
|
9
|
-
const lReturnValue = {
|
|
10
|
-
// ensure the 'initial' state has a unique name
|
|
11
|
-
id: pId ? `${pId}.initial` : "initial",
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
if (pInitialObject.transition) {
|
|
15
|
-
Object.assign(lReturnValue, {
|
|
16
|
-
transition: [pInitialObject.transition],
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return lReturnValue;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* @param {string} pString
|
|
25
|
-
* @returns {import("./scxml").ISCXMLInitialState}
|
|
26
|
-
*/
|
|
27
|
-
function normalizeInitialFromString(pString) {
|
|
28
|
-
return {
|
|
29
|
-
id: "initial",
|
|
30
|
-
transition: [
|
|
31
|
-
{
|
|
32
|
-
target: pString,
|
|
33
|
-
},
|
|
34
|
-
],
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* @param {any} pMachine
|
|
40
|
-
* @returns {import("./scxml").ISCXMLInitialState[]}
|
|
41
|
-
*/
|
|
42
|
-
function normalizeInitial(pMachine) {
|
|
43
|
-
const lReturnValue = [];
|
|
44
|
-
|
|
45
|
-
if (pMachine.initial) {
|
|
46
|
-
if (typeof pMachine.initial === "string") {
|
|
47
|
-
lReturnValue.push(normalizeInitialFromString(pMachine.initial));
|
|
48
|
-
} else {
|
|
49
|
-
lReturnValue.push(
|
|
50
|
-
normalizeInitialFromObject(pMachine.initial, pMachine.id)
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return lReturnValue;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Massages SCXML-as-json to be uniform:
|
|
59
|
-
*
|
|
60
|
-
* @param {any} pMachine SCXML-as-json state machine
|
|
61
|
-
* @returns {import("./scxml").INormalizedSCXMLMachine} Still an SCXML-as-json state machine,
|
|
62
|
-
* but more consistent and easier to use
|
|
63
|
-
*/
|
|
64
|
-
export function normalizeMachine(pMachine) {
|
|
65
|
-
return {
|
|
66
|
-
...pMachine,
|
|
67
|
-
initial: normalizeInitial(pMachine),
|
|
68
|
-
state: castArray(pMachine?.state ?? []),
|
|
69
|
-
parallel: castArray(pMachine?.parallel ?? []),
|
|
70
|
-
history: castArray(pMachine?.history ?? []),
|
|
71
|
-
final: castArray(pMachine?.final ?? []),
|
|
72
|
-
};
|
|
73
|
-
}
|
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
export default {
|
|
2
|
-
$schema: "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
title: "state-machine-cat abstract syntax tree schema",
|
|
4
|
-
$ref: "#/definitions/StateMachineType",
|
|
5
|
-
$id: "org.js.state-machine-cat/v7.4.0",
|
|
6
|
-
definitions: {
|
|
7
|
-
StateType: {
|
|
8
|
-
type: "string",
|
|
9
|
-
enum: [
|
|
10
|
-
"regular",
|
|
11
|
-
"initial",
|
|
12
|
-
"terminate",
|
|
13
|
-
"final",
|
|
14
|
-
"parallel",
|
|
15
|
-
"history",
|
|
16
|
-
"deephistory",
|
|
17
|
-
"choice",
|
|
18
|
-
"forkjoin",
|
|
19
|
-
"fork",
|
|
20
|
-
"join",
|
|
21
|
-
"junction",
|
|
22
|
-
],
|
|
23
|
-
},
|
|
24
|
-
TransitionType: {
|
|
25
|
-
type: "string",
|
|
26
|
-
enum: ["internal", "external"],
|
|
27
|
-
},
|
|
28
|
-
NoteType: {
|
|
29
|
-
type: "array",
|
|
30
|
-
items: {
|
|
31
|
-
type: "string",
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
ActionTypeType: {
|
|
35
|
-
type: "string",
|
|
36
|
-
enum: ["entry", "activity", "exit"],
|
|
37
|
-
},
|
|
38
|
-
ActionType: {
|
|
39
|
-
type: "object",
|
|
40
|
-
required: ["type", "body"],
|
|
41
|
-
additionalProperties: false,
|
|
42
|
-
properties: {
|
|
43
|
-
type: { $ref: "#/definitions/ActionTypeType" },
|
|
44
|
-
body: { type: "string" },
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
ClassType: {
|
|
48
|
-
type: "string",
|
|
49
|
-
pattern: "^[a-zA-Z0-9_\\- ]*$",
|
|
50
|
-
},
|
|
51
|
-
StateMachineType: {
|
|
52
|
-
type: "object",
|
|
53
|
-
additionalProperties: false,
|
|
54
|
-
required: ["states"],
|
|
55
|
-
properties: {
|
|
56
|
-
states: {
|
|
57
|
-
type: "array",
|
|
58
|
-
items: {
|
|
59
|
-
type: "object",
|
|
60
|
-
required: ["name", "type"],
|
|
61
|
-
additionalProperties: false,
|
|
62
|
-
properties: {
|
|
63
|
-
name: {
|
|
64
|
-
description:
|
|
65
|
-
"The name and identifier of the state. Unique within the root state machine.",
|
|
66
|
-
type: "string",
|
|
67
|
-
},
|
|
68
|
-
type: {
|
|
69
|
-
description:
|
|
70
|
-
"What kind of state (or pseudo state) this state is. E.g. 'regular' for normal states or 'initial', 'final', 'choice' etc for pseudo states. Most UML (pseudo-) states are supported.",
|
|
71
|
-
$ref: "#/definitions/StateType",
|
|
72
|
-
},
|
|
73
|
-
label: {
|
|
74
|
-
description:
|
|
75
|
-
"The display label of the state. If it's not present, most renderers will use the states' name in stead.",
|
|
76
|
-
type: "string",
|
|
77
|
-
},
|
|
78
|
-
color: {
|
|
79
|
-
description:
|
|
80
|
-
'Color to use for rendering the state. Accepts all css color names ("blue") and hex notation - with ("#0000FF77") or without ("#0000FF") transparency.',
|
|
81
|
-
type: "string",
|
|
82
|
-
},
|
|
83
|
-
class: {
|
|
84
|
-
description:
|
|
85
|
-
"Class name to give the state in dot and svg output.",
|
|
86
|
-
$ref: "#/definitions/ClassType",
|
|
87
|
-
},
|
|
88
|
-
active: {
|
|
89
|
-
description:
|
|
90
|
-
"If true the state is considered to be active and rendered as such.",
|
|
91
|
-
type: "boolean",
|
|
92
|
-
},
|
|
93
|
-
typeExplicitlySet: {
|
|
94
|
-
description:
|
|
95
|
-
"The default parser derives the `type` from the `name` with inband signaling. The user can override that behavior by explicitly setting the `type`. This attribute is there to express that (and make sure that on next parses & processing it doesn't get accidentily re-derived from the name again).",
|
|
96
|
-
type: "boolean",
|
|
97
|
-
},
|
|
98
|
-
isComposite: {
|
|
99
|
-
description:
|
|
100
|
-
"convenience, derived attribute - set to true if there's a state machine inside the state; false in all other cases. For internal use - @deprecated",
|
|
101
|
-
type: "boolean",
|
|
102
|
-
},
|
|
103
|
-
actions: {
|
|
104
|
-
type: "array",
|
|
105
|
-
description:
|
|
106
|
-
"A series of actions and their types. The type describe when the action takes place (on entry, exit, or otherwise ('activity'))",
|
|
107
|
-
items: { $ref: "#/definitions/ActionType" },
|
|
108
|
-
},
|
|
109
|
-
note: {
|
|
110
|
-
description:
|
|
111
|
-
"Comments related to this state. Some renderers will use the note attribute to render a note (i.e. as a post-it) attached to the state.",
|
|
112
|
-
$ref: "#/definitions/NoteType",
|
|
113
|
-
},
|
|
114
|
-
statemachine: {
|
|
115
|
-
description: "state machine nested within the state.",
|
|
116
|
-
$ref: "#/definitions/StateMachineType",
|
|
117
|
-
},
|
|
118
|
-
},
|
|
119
|
-
},
|
|
120
|
-
},
|
|
121
|
-
transitions: {
|
|
122
|
-
type: "array",
|
|
123
|
-
items: {
|
|
124
|
-
type: "object",
|
|
125
|
-
required: ["from", "to"],
|
|
126
|
-
additionalProperties: false,
|
|
127
|
-
properties: {
|
|
128
|
-
from: {
|
|
129
|
-
description:
|
|
130
|
-
"The name of the state this transition transitions from",
|
|
131
|
-
type: "string",
|
|
132
|
-
},
|
|
133
|
-
to: {
|
|
134
|
-
description:
|
|
135
|
-
"The name of the state this transition transitions to",
|
|
136
|
-
type: "string",
|
|
137
|
-
},
|
|
138
|
-
label: {
|
|
139
|
-
description:
|
|
140
|
-
"A display label to represent this transition. Parsers can parse this label into events conditions and actions.",
|
|
141
|
-
type: "string",
|
|
142
|
-
},
|
|
143
|
-
event: {
|
|
144
|
-
description: "Event triggering the transition",
|
|
145
|
-
type: "string",
|
|
146
|
-
},
|
|
147
|
-
cond: {
|
|
148
|
-
description: "Condition for the transition to occur.",
|
|
149
|
-
type: "string",
|
|
150
|
-
},
|
|
151
|
-
action: {
|
|
152
|
-
description: "Action to execute when the transition occurs.",
|
|
153
|
-
type: "string",
|
|
154
|
-
},
|
|
155
|
-
note: {
|
|
156
|
-
description: "Comments related to this transition",
|
|
157
|
-
$ref: "#/definitions/NoteType",
|
|
158
|
-
},
|
|
159
|
-
color: {
|
|
160
|
-
description:
|
|
161
|
-
'Color to use for rendering the transition. Accepts all css color names ("blue") and hex notation - with ("#0000FF77") or without ("#0000FF") transparency.',
|
|
162
|
-
type: "string",
|
|
163
|
-
},
|
|
164
|
-
width: {
|
|
165
|
-
description:
|
|
166
|
-
"The line width to use for rendering the transition",
|
|
167
|
-
type: "number",
|
|
168
|
-
minimum: 0,
|
|
169
|
-
maximum: 30,
|
|
170
|
-
},
|
|
171
|
-
class: {
|
|
172
|
-
description:
|
|
173
|
-
"Class name to give the state in dot and svg output.",
|
|
174
|
-
$ref: "#/definitions/ClassType",
|
|
175
|
-
},
|
|
176
|
-
type: {
|
|
177
|
-
description:
|
|
178
|
-
"Whether the transition is external (default) or internal. See https://www.w3.org/TR/scxml/#transition for details.",
|
|
179
|
-
$ref: "#/definitions/TransitionType",
|
|
180
|
-
},
|
|
181
|
-
},
|
|
182
|
-
},
|
|
183
|
-
},
|
|
184
|
-
},
|
|
185
|
-
},
|
|
186
|
-
},
|
|
187
|
-
};
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/* eslint-disable security/detect-object-injection */
|
|
2
|
-
const GENERIC_GRAPH_ATTRIBUTES = [
|
|
3
|
-
{ name: "fontname", value: '"Helvetica"' },
|
|
4
|
-
{ name: "fontsize", value: "12" },
|
|
5
|
-
{ name: "penwidth", value: "2.0" },
|
|
6
|
-
];
|
|
7
|
-
|
|
8
|
-
const GRAPH_ATTRIBUTES = {
|
|
9
|
-
dot: [
|
|
10
|
-
{ name: "splines", value: "true" },
|
|
11
|
-
{ name: "ordering", value: "out" },
|
|
12
|
-
{ name: "compound", value: "true" },
|
|
13
|
-
{ name: "overlap", value: "scale" },
|
|
14
|
-
{ name: "nodesep", value: "0.3" },
|
|
15
|
-
{ name: "ranksep", value: "0.1" },
|
|
16
|
-
],
|
|
17
|
-
fdp: [{ name: "K", value: "0.9" }],
|
|
18
|
-
osage: [{ name: "pack", value: "42" }],
|
|
19
|
-
neato: [{ name: "epsilon", value: "0.9" }],
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const DIRECTION_ATTRIBUTES = {
|
|
23
|
-
"bottom-top": [{ name: "rankdir", value: "BT" }],
|
|
24
|
-
"left-right": [{ name: "rankdir", value: "LR" }],
|
|
25
|
-
"right-left": [{ name: "rankdir", value: "RL" }],
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const NODE_ATTRIBUTES = [
|
|
29
|
-
{ name: "shape", value: "plaintext" },
|
|
30
|
-
{ name: "style", value: "filled" },
|
|
31
|
-
{ name: "fillcolor", value: '"#FFFFFF01"' },
|
|
32
|
-
{ name: "fontname", value: "Helvetica" },
|
|
33
|
-
{ name: "fontsize", value: 12 },
|
|
34
|
-
{ name: "penwidth", value: "2.0" },
|
|
35
|
-
];
|
|
36
|
-
|
|
37
|
-
const EDGE_ATTRIBUTES = [
|
|
38
|
-
{ name: "fontname", value: "Helvetica" },
|
|
39
|
-
{ name: "fontsize", value: 10 },
|
|
40
|
-
];
|
|
41
|
-
|
|
42
|
-
function toNameValueString(pAttribute) {
|
|
43
|
-
return `${pAttribute.name}=${pAttribute.value}`;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export default {
|
|
47
|
-
/**
|
|
48
|
-
*
|
|
49
|
-
* @param {string} pEngine
|
|
50
|
-
* @param {string} pDirection
|
|
51
|
-
* @param {*} pDotGraphAttributes
|
|
52
|
-
* @returns {string}
|
|
53
|
-
*/
|
|
54
|
-
buildGraphAttributes: (pEngine, pDirection, pDotGraphAttributes) =>
|
|
55
|
-
GENERIC_GRAPH_ATTRIBUTES.concat(GRAPH_ATTRIBUTES[pEngine] || [])
|
|
56
|
-
.concat(DIRECTION_ATTRIBUTES[pDirection] || [])
|
|
57
|
-
.concat(pDotGraphAttributes || [])
|
|
58
|
-
.map(toNameValueString)
|
|
59
|
-
.join(" "),
|
|
60
|
-
buildNodeAttributes: (pDotNodeAttributes) =>
|
|
61
|
-
NODE_ATTRIBUTES.concat(pDotNodeAttributes || [])
|
|
62
|
-
.map(toNameValueString)
|
|
63
|
-
.join(" "),
|
|
64
|
-
buildEdgeAttributes: (pDotEdgeAttributes) =>
|
|
65
|
-
EDGE_ATTRIBUTES.concat(pDotEdgeAttributes || [])
|
|
66
|
-
.map(toNameValueString)
|
|
67
|
-
.join(" "),
|
|
68
|
-
};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
export default class Counter {
|
|
3
|
-
constructor() {
|
|
4
|
-
this.reset();
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @returns {void}
|
|
9
|
-
*/
|
|
10
|
-
reset() {
|
|
11
|
-
this.COUNTER = 0;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* @returns {number}
|
|
16
|
-
*/
|
|
17
|
-
next() {
|
|
18
|
-
// @ts-expect-error TS thinks COUNTER can possibly be null as it doesn't
|
|
19
|
-
// see that the function the constructor calls ensures it won't
|
|
20
|
-
// eslint-disable-next-line no-plusplus
|
|
21
|
-
return ++this.COUNTER;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @returns {string}
|
|
26
|
-
*/
|
|
27
|
-
nextAsString() {
|
|
28
|
-
/** @type {number} */
|
|
29
|
-
const lBase = 10;
|
|
30
|
-
|
|
31
|
-
return this.next().toString(lBase);
|
|
32
|
-
}
|
|
33
|
-
}
|