@jarenjs/mermaid 0.72.2 → 0.73.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.
- package/README.md +2 -0
- package/dist/types/parser/state.d.ts +2 -3
- package/docs/MERMAID-FORMAT.md +16 -1
- package/package.json +4 -4
- package/src/parser/state.js +9 -8
- package/src/to-mermaid.js +28 -0
- package/stylesheets/state-to-statechart.jslt.json +168 -0
- package/stylesheets/statechart-to-state.jslt.json +240 -0
package/README.md
CHANGED
|
@@ -360,7 +360,9 @@ Every subpath a consumer can import, derived from the manifest by
|
|
|
360
360
|
| `@jarenjs/mermaid/schemas/jaren-workflow.schema.json` | schema | — |
|
|
361
361
|
| `@jarenjs/mermaid/stylesheets/dag-to-flowchart.jslt.json` | asset | — |
|
|
362
362
|
| `@jarenjs/mermaid/stylesheets/flowchart-to-dag.jslt.json` | asset | — |
|
|
363
|
+
| `@jarenjs/mermaid/stylesheets/state-to-statechart.jslt.json` | asset | — |
|
|
363
364
|
| `@jarenjs/mermaid/stylesheets/state-to-workflow.jslt.json` | asset | — |
|
|
365
|
+
| `@jarenjs/mermaid/stylesheets/statechart-to-state.jslt.json` | asset | — |
|
|
364
366
|
| `@jarenjs/mermaid/stylesheets/workflow-to-state.jslt.json` | asset | — |
|
|
365
367
|
| `@jarenjs/mermaid/package.json` | metadata | — |
|
|
366
368
|
<!--/fact-->
|
|
@@ -11,9 +11,8 @@
|
|
|
11
11
|
* fits no UML pattern reads whole as the event, so plain labels keep
|
|
12
12
|
* their historical meaning byte for byte.
|
|
13
13
|
*
|
|
14
|
-
* Composite states (`state Foo { … }`)
|
|
15
|
-
*
|
|
16
|
-
* AST geometry-free.
|
|
14
|
+
* Composite states (`state Foo { … }`) stay in a flat table with parent
|
|
15
|
+
* ids on both states and transitions, at arbitrary nesting depth.
|
|
17
16
|
*/
|
|
18
17
|
/**
|
|
19
18
|
* @param {string[]} lines
|
package/docs/MERMAID-FORMAT.md
CHANGED
|
@@ -261,7 +261,7 @@ primitive.
|
|
|
261
261
|
|
|
262
262
|
### 5.1 Semantic projections
|
|
263
263
|
|
|
264
|
-
The geometry-free AST doubles as a domain model, and
|
|
264
|
+
The geometry-free AST doubles as a domain model, and six JSLT
|
|
265
265
|
stylesheets in [`stylesheets/`](../stylesheets/) project it both ways —
|
|
266
266
|
plain data documents, no code:
|
|
267
267
|
|
|
@@ -269,6 +269,8 @@ plain data documents, no code:
|
|
|
269
269
|
|---|---|
|
|
270
270
|
| `state-to-workflow.jslt.json` | state DiagramDocument → executable machine (`@jarenjs/flow`'s jaren-fsm superset shape) |
|
|
271
271
|
| `workflow-to-state.jslt.json` | machine document → state AST (print with `toMermaid`) |
|
|
272
|
+
| `state-to-statechart.jslt.json` | compound state DiagramDocument → jaren-fsm 0.2 (`compileStatechart`) |
|
|
273
|
+
| `statechart-to-state.jslt.json` | statechart document → state AST, preserving compound parents, initials and finals |
|
|
272
274
|
| `flowchart-to-dag.jslt.json` | flowchart DiagramDocument → jaren-dag **skeleton** (every node a `task` stub named by its id; edge labels become `port`s verbatim) |
|
|
273
275
|
| `dag-to-flowchart.jslt.json` | jaren-dag document → flowchart AST |
|
|
274
276
|
|
|
@@ -278,6 +280,19 @@ The forward state projection maps the parsed UML parts: `event` and
|
|
|
278
280
|
registry name by convention. The reverse composes the label from the
|
|
279
281
|
machine's parts and stays consistent with the parser by construction.
|
|
280
282
|
|
|
283
|
+
The compound projection uses `parent` on states as well as transitions;
|
|
284
|
+
the parser records arbitrary nesting depth and the printer retains transition
|
|
285
|
+
order while reopening compound scopes when necessary. A scope's unlabelled
|
|
286
|
+
`[*]` entry supplies its `initial`; an unlabelled edge to `[*]` declares its
|
|
287
|
+
source terminal. Missing or ambiguous initials, a terminal with other outgoing
|
|
288
|
+
transitions, or labelled pseudo-state edges refuse at statechart compilation.
|
|
289
|
+
The 0.1 projection keeps its original flat behavior. Statechart history,
|
|
290
|
+
parallel types, internal/external distinctions, delays, completion/eventless
|
|
291
|
+
triggers and state entry/exit effects have no lossless spelling in this
|
|
292
|
+
projection: author and retain those in JSON. The reverse is a display
|
|
293
|
+
projection outside the compound/initial/final subset, not a serialization
|
|
294
|
+
format for a full statechart.
|
|
295
|
+
|
|
281
296
|
The dag projection renders each node kind as a fixed flowchart shape:
|
|
282
297
|
|
|
283
298
|
| kind | shape |
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jarenjs/mermaid",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.73.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
7
7
|
"types": "./dist/types/index.d.ts",
|
|
@@ -77,8 +77,8 @@
|
|
|
77
77
|
"prepack": "npm run build:types"
|
|
78
78
|
},
|
|
79
79
|
"dependencies": {
|
|
80
|
-
"@jarenjs/charts": "^0.
|
|
81
|
-
"@jarenjs/core": "^0.
|
|
82
|
-
"@jarenjs/view": "^0.
|
|
80
|
+
"@jarenjs/charts": "^0.73.0",
|
|
81
|
+
"@jarenjs/core": "^0.73.0",
|
|
82
|
+
"@jarenjs/view": "^0.73.0"
|
|
83
83
|
}
|
|
84
84
|
}
|
package/src/parser/state.js
CHANGED
|
@@ -12,9 +12,8 @@
|
|
|
12
12
|
* fits no UML pattern reads whole as the event, so plain labels keep
|
|
13
13
|
* their historical meaning byte for byte.
|
|
14
14
|
*
|
|
15
|
-
* Composite states (`state Foo { … }`)
|
|
16
|
-
*
|
|
17
|
-
* AST geometry-free.
|
|
15
|
+
* Composite states (`state Foo { … }`) stay in a flat table with parent
|
|
16
|
+
* ids on both states and transitions, at arbitrary nesting depth.
|
|
18
17
|
*/
|
|
19
18
|
|
|
20
19
|
/** `A --> B` / `A --> B : label`. */
|
|
@@ -79,17 +78,19 @@ export function parseState(lines) {
|
|
|
79
78
|
/** @type {string[]} */
|
|
80
79
|
const parentStack = [];
|
|
81
80
|
|
|
82
|
-
const ensure = (id, label) => {
|
|
81
|
+
const ensure = (id, label, declaration = false) => {
|
|
83
82
|
if (id === '[*]') return;
|
|
84
83
|
let st = stateMap.get(id);
|
|
85
84
|
if (st === undefined) {
|
|
86
|
-
st = { id, label: label ?? id
|
|
85
|
+
st = { id, label: label ?? id,
|
|
86
|
+
...(parentStack.length ? { parent: parentStack.at(-1) } : {}) };
|
|
87
87
|
stateMap.set(id, st);
|
|
88
88
|
order.push(id);
|
|
89
89
|
}
|
|
90
90
|
else if (label != null) {
|
|
91
91
|
st.label = label;
|
|
92
92
|
}
|
|
93
|
+
if (declaration && parentStack.length) st.parent = parentStack.at(-1);
|
|
93
94
|
};
|
|
94
95
|
|
|
95
96
|
for (let li = 0; li < lines.length; li++) {
|
|
@@ -101,13 +102,13 @@ export function parseState(lines) {
|
|
|
101
102
|
if (line.startsWith('state ') && line.endsWith('{')) {
|
|
102
103
|
const inner = line.slice('state '.length, -1).trim();
|
|
103
104
|
const id = inner.split(/\s+/)[0];
|
|
104
|
-
ensure(id,
|
|
105
|
+
ensure(id, null, true);
|
|
105
106
|
parentStack.push(id);
|
|
106
107
|
continue;
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
const sa = RE_STATE_AS.exec(line);
|
|
110
|
-
if (sa !== null) { ensure(sa[2], sa[1]); continue; }
|
|
111
|
+
if (sa !== null) { ensure(sa[2], sa[1], true); continue; }
|
|
111
112
|
|
|
112
113
|
const tr = RE_TRANSITION.exec(line);
|
|
113
114
|
if (tr !== null) {
|
|
@@ -127,7 +128,7 @@ export function parseState(lines) {
|
|
|
127
128
|
continue;
|
|
128
129
|
}
|
|
129
130
|
|
|
130
|
-
if (line.startsWith('state ')) { ensure(line.slice('state '.length).trim(), null); continue; }
|
|
131
|
+
if (line.startsWith('state ')) { ensure(line.slice('state '.length).trim(), null, true); continue; }
|
|
131
132
|
|
|
132
133
|
const sd = RE_STATE_DESC.exec(line);
|
|
133
134
|
if (sd !== null && sd[1] !== '[*]') { ensure(sd[1], sd[2].trim()); continue; }
|
package/src/to-mermaid.js
CHANGED
|
@@ -253,6 +253,34 @@ function printClass(ast) {
|
|
|
253
253
|
*/
|
|
254
254
|
function printState(ast) {
|
|
255
255
|
const out = ['stateDiagram-v2'];
|
|
256
|
+
if (ast.states.some((s) => s.parent != null) || ast.transitions.some((t) => t.parent != null)) {
|
|
257
|
+
const states = new Map(ast.states.map((s) => [s.id, s]));
|
|
258
|
+
let opened = [];
|
|
259
|
+
const scope = (parent) => {
|
|
260
|
+
const target = [];
|
|
261
|
+
for (let id = parent; id != null; id = states.get(id)?.parent) {
|
|
262
|
+
if (target.includes(id)) throw new TypeError('cyclic state-diagram parent');
|
|
263
|
+
target.unshift(id);
|
|
264
|
+
}
|
|
265
|
+
let shared = 0;
|
|
266
|
+
while (shared < opened.length && opened[shared] === target[shared]) shared++;
|
|
267
|
+
for (let i = opened.length; i > shared; i--) out.push(' '.repeat(i - 1) + '}');
|
|
268
|
+
for (let i = shared; i < target.length; i++) out.push(' '.repeat(i) + `state ${target[i]} {`);
|
|
269
|
+
opened = target;
|
|
270
|
+
};
|
|
271
|
+
// Declare every id first, then retain transition document order even
|
|
272
|
+
// when that requires reopening a compound scope. Priority survives print.
|
|
273
|
+
for (const s of ast.states) {
|
|
274
|
+
scope(s.parent);
|
|
275
|
+
out.push(' '.repeat(opened.length) + (s.label !== s.id ? `${s.id} : ${s.label}` : `state ${s.id}`));
|
|
276
|
+
}
|
|
277
|
+
for (const t of ast.transitions) {
|
|
278
|
+
scope(t.parent);
|
|
279
|
+
out.push(' '.repeat(opened.length) + `${t.from} --> ${t.to}${t.label ? ' : ' + t.label : ''}`);
|
|
280
|
+
}
|
|
281
|
+
scope(null);
|
|
282
|
+
return out.join('\n') + '\n';
|
|
283
|
+
}
|
|
256
284
|
// an id-only state no transition mentions must still be DECLARED, or
|
|
257
285
|
// the canonical round trip silently drops it (`state x` is the
|
|
258
286
|
// parser's own spelling for exactly that)
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$jslt": "0.1",
|
|
3
|
+
"rules": [
|
|
4
|
+
{
|
|
5
|
+
"match": "$",
|
|
6
|
+
"body": {
|
|
7
|
+
"$map": [
|
|
8
|
+
[
|
|
9
|
+
"$$fsm",
|
|
10
|
+
"0.2"
|
|
11
|
+
],
|
|
12
|
+
[
|
|
13
|
+
"initial",
|
|
14
|
+
{
|
|
15
|
+
"$for": {
|
|
16
|
+
"t": "$.ast.transitions[*]"
|
|
17
|
+
},
|
|
18
|
+
"$where": {
|
|
19
|
+
"$and": [
|
|
20
|
+
{
|
|
21
|
+
"$eq": [
|
|
22
|
+
"$t.from",
|
|
23
|
+
"[*]"
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"$eq": [
|
|
28
|
+
"$t.parent",
|
|
29
|
+
null
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
"$return": "$t.to"
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
[
|
|
38
|
+
"states",
|
|
39
|
+
[
|
|
40
|
+
{
|
|
41
|
+
"$for": {
|
|
42
|
+
"s": "$.ast.states[*]"
|
|
43
|
+
},
|
|
44
|
+
"$return": {
|
|
45
|
+
"id": "$s.id",
|
|
46
|
+
"parent": {
|
|
47
|
+
"$if": [
|
|
48
|
+
"$s.parent",
|
|
49
|
+
"$s.parent"
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
"initial": {
|
|
53
|
+
"$for": {
|
|
54
|
+
"t": "$.ast.transitions[*]"
|
|
55
|
+
},
|
|
56
|
+
"$where": {
|
|
57
|
+
"$and": [
|
|
58
|
+
{
|
|
59
|
+
"$eq": [
|
|
60
|
+
"$t.from",
|
|
61
|
+
"[*]"
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"$eq": [
|
|
66
|
+
"$t.parent",
|
|
67
|
+
"$s.id"
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
"$return": "$t.to"
|
|
73
|
+
},
|
|
74
|
+
"final": {
|
|
75
|
+
"$if": [
|
|
76
|
+
{
|
|
77
|
+
"$exists": {
|
|
78
|
+
"$for": {
|
|
79
|
+
"t": "$.ast.transitions[*]"
|
|
80
|
+
},
|
|
81
|
+
"$where": {
|
|
82
|
+
"$and": [
|
|
83
|
+
{
|
|
84
|
+
"$eq": [
|
|
85
|
+
"$t.to",
|
|
86
|
+
"[*]"
|
|
87
|
+
]
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"$eq": [
|
|
91
|
+
"$t.from",
|
|
92
|
+
"$s.id"
|
|
93
|
+
]
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
},
|
|
97
|
+
"$return": "$t.from"
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
true
|
|
101
|
+
]
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
],
|
|
107
|
+
[
|
|
108
|
+
"transitions",
|
|
109
|
+
[
|
|
110
|
+
{
|
|
111
|
+
"$for": {
|
|
112
|
+
"t": "$.ast.transitions[*]"
|
|
113
|
+
},
|
|
114
|
+
"$return": {
|
|
115
|
+
"from": "$t.from",
|
|
116
|
+
"event": "$t.event",
|
|
117
|
+
"guard": {
|
|
118
|
+
"$if": [
|
|
119
|
+
"$t.guard",
|
|
120
|
+
"$t.guard"
|
|
121
|
+
]
|
|
122
|
+
},
|
|
123
|
+
"to": "$t.to",
|
|
124
|
+
"effects": {
|
|
125
|
+
"$if": [
|
|
126
|
+
"$t.effect",
|
|
127
|
+
[
|
|
128
|
+
{
|
|
129
|
+
"run": "$t.effect"
|
|
130
|
+
}
|
|
131
|
+
]
|
|
132
|
+
]
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
"$where": {
|
|
136
|
+
"$or": [
|
|
137
|
+
{
|
|
138
|
+
"$and": [
|
|
139
|
+
{
|
|
140
|
+
"$ne": [
|
|
141
|
+
"$t.from",
|
|
142
|
+
"[*]"
|
|
143
|
+
]
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"$ne": [
|
|
147
|
+
"$t.to",
|
|
148
|
+
"[*]"
|
|
149
|
+
]
|
|
150
|
+
}
|
|
151
|
+
]
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"$ne": [
|
|
155
|
+
"$t.label",
|
|
156
|
+
null
|
|
157
|
+
]
|
|
158
|
+
}
|
|
159
|
+
]
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
]
|
|
163
|
+
]
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
]
|
|
168
|
+
}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$jslt": "0.1",
|
|
3
|
+
"rules": [
|
|
4
|
+
{
|
|
5
|
+
"match": "$",
|
|
6
|
+
"body": {
|
|
7
|
+
"states": [
|
|
8
|
+
{
|
|
9
|
+
"$for": {
|
|
10
|
+
"s": "$.states[*]"
|
|
11
|
+
},
|
|
12
|
+
"$return": {
|
|
13
|
+
"id": {
|
|
14
|
+
"$if": [
|
|
15
|
+
{
|
|
16
|
+
"$is-string": "$s"
|
|
17
|
+
},
|
|
18
|
+
"$s",
|
|
19
|
+
"$s.id"
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
"label": {
|
|
23
|
+
"$if": [
|
|
24
|
+
{
|
|
25
|
+
"$is-string": "$s"
|
|
26
|
+
},
|
|
27
|
+
"$s",
|
|
28
|
+
"$s.id"
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
"parent": {
|
|
32
|
+
"$if": [
|
|
33
|
+
"$s.parent",
|
|
34
|
+
"$s.parent"
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"transitions": [
|
|
41
|
+
{
|
|
42
|
+
"$if": [
|
|
43
|
+
"$.initial",
|
|
44
|
+
{
|
|
45
|
+
"from": "[*]",
|
|
46
|
+
"to": "$.initial",
|
|
47
|
+
"label": null,
|
|
48
|
+
"event": null,
|
|
49
|
+
"guard": null,
|
|
50
|
+
"effect": null,
|
|
51
|
+
"parent": null
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"$for": {
|
|
57
|
+
"s": "$.states[*]"
|
|
58
|
+
},
|
|
59
|
+
"$where": {
|
|
60
|
+
"$exists": "$s.initial"
|
|
61
|
+
},
|
|
62
|
+
"$return": {
|
|
63
|
+
"from": "[*]",
|
|
64
|
+
"to": "$s.initial",
|
|
65
|
+
"label": null,
|
|
66
|
+
"event": null,
|
|
67
|
+
"guard": null,
|
|
68
|
+
"effect": null,
|
|
69
|
+
"parent": "$s.id"
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"$for": {
|
|
74
|
+
"t": "$.transitions[*]"
|
|
75
|
+
},
|
|
76
|
+
"$return": {
|
|
77
|
+
"$let": {
|
|
78
|
+
"guardText": {
|
|
79
|
+
"$if": [
|
|
80
|
+
"$t.guard",
|
|
81
|
+
{
|
|
82
|
+
"$concat": [
|
|
83
|
+
"[",
|
|
84
|
+
{
|
|
85
|
+
"$if": [
|
|
86
|
+
{
|
|
87
|
+
"$is-string": "$t.guard"
|
|
88
|
+
},
|
|
89
|
+
"$t.guard",
|
|
90
|
+
"…"
|
|
91
|
+
]
|
|
92
|
+
},
|
|
93
|
+
"]"
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
]
|
|
97
|
+
},
|
|
98
|
+
"effectText": {
|
|
99
|
+
"$if": [
|
|
100
|
+
{
|
|
101
|
+
"$exists": "$t.effects[*]"
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"$concat": [
|
|
105
|
+
"/ ",
|
|
106
|
+
{
|
|
107
|
+
"$string-join": [
|
|
108
|
+
"$t.effects[*].run",
|
|
109
|
+
", "
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
]
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
"$return": {
|
|
118
|
+
"$let": {
|
|
119
|
+
"pieces": {
|
|
120
|
+
"$seq": [
|
|
121
|
+
{
|
|
122
|
+
"$if": [
|
|
123
|
+
"$t.event",
|
|
124
|
+
"$t.event"
|
|
125
|
+
]
|
|
126
|
+
},
|
|
127
|
+
"$guardText",
|
|
128
|
+
"$effectText"
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
"$return": {
|
|
133
|
+
"from": "$t.from",
|
|
134
|
+
"to": "$t.to",
|
|
135
|
+
"label": {
|
|
136
|
+
"$coalesce": [
|
|
137
|
+
{
|
|
138
|
+
"$if": [
|
|
139
|
+
{
|
|
140
|
+
"$exists": "$pieces"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"$string-join": [
|
|
144
|
+
"$pieces",
|
|
145
|
+
" "
|
|
146
|
+
]
|
|
147
|
+
}
|
|
148
|
+
]
|
|
149
|
+
},
|
|
150
|
+
null
|
|
151
|
+
]
|
|
152
|
+
},
|
|
153
|
+
"event": {
|
|
154
|
+
"$coalesce": [
|
|
155
|
+
"$t.event",
|
|
156
|
+
null
|
|
157
|
+
]
|
|
158
|
+
},
|
|
159
|
+
"guard": {
|
|
160
|
+
"$coalesce": [
|
|
161
|
+
{
|
|
162
|
+
"$if": [
|
|
163
|
+
"$t.guard",
|
|
164
|
+
{
|
|
165
|
+
"$if": [
|
|
166
|
+
{
|
|
167
|
+
"$is-string": "$t.guard"
|
|
168
|
+
},
|
|
169
|
+
"$t.guard",
|
|
170
|
+
"…"
|
|
171
|
+
]
|
|
172
|
+
}
|
|
173
|
+
]
|
|
174
|
+
},
|
|
175
|
+
null
|
|
176
|
+
]
|
|
177
|
+
},
|
|
178
|
+
"effect": {
|
|
179
|
+
"$coalesce": [
|
|
180
|
+
{
|
|
181
|
+
"$if": [
|
|
182
|
+
{
|
|
183
|
+
"$exists": "$t.effects[*]"
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"$string-join": [
|
|
187
|
+
"$t.effects[*].run",
|
|
188
|
+
", "
|
|
189
|
+
]
|
|
190
|
+
}
|
|
191
|
+
]
|
|
192
|
+
},
|
|
193
|
+
null
|
|
194
|
+
]
|
|
195
|
+
},
|
|
196
|
+
"parent": null
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"$for": {
|
|
203
|
+
"s": "$.states[*]"
|
|
204
|
+
},
|
|
205
|
+
"$where": {
|
|
206
|
+
"$or": [
|
|
207
|
+
{
|
|
208
|
+
"$eq": [
|
|
209
|
+
"$s.final",
|
|
210
|
+
true
|
|
211
|
+
]
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"$eq": [
|
|
215
|
+
"$s.type",
|
|
216
|
+
"final"
|
|
217
|
+
]
|
|
218
|
+
}
|
|
219
|
+
]
|
|
220
|
+
},
|
|
221
|
+
"$return": {
|
|
222
|
+
"from": "$s.id",
|
|
223
|
+
"to": "[*]",
|
|
224
|
+
"label": null,
|
|
225
|
+
"event": null,
|
|
226
|
+
"guard": null,
|
|
227
|
+
"effect": null,
|
|
228
|
+
"parent": {
|
|
229
|
+
"$coalesce": [
|
|
230
|
+
"$s.parent",
|
|
231
|
+
null
|
|
232
|
+
]
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
]
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
]
|
|
240
|
+
}
|