iobroker.statechart 0.0.0-stage → 0.2.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.
@@ -0,0 +1,4 @@
1
+ {
2
+ "option1": "Option 1",
3
+ "option2": "Option 2"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "option1": "Option 1",
3
+ "option2": "Option 2"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "option1": "Option 1",
3
+ "option2": "Option 2"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "option1": "Option 1",
3
+ "option2": "Option 2"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "option1": "Option 1",
3
+ "option2": "Option 2"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "option1": "Option 1",
3
+ "option2": "Option 2"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "option1": "Option 1",
3
+ "option2": "Option 2"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "option1": "Option 1",
3
+ "option2": "Option 2"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "option1": "Option 1",
3
+ "option2": "Option 2"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "option1": "Option 1",
3
+ "option2": "Option 2"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "option1": "Option 1",
3
+ "option2": "Option 2"
4
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "i18n": true,
3
+ "type": "panel",
4
+ "items": {
5
+ "option1": {
6
+ "type": "checkbox",
7
+ "label": "option1",
8
+ "sm": 12
9
+ },
10
+ "option2": {
11
+ "type": "text",
12
+ "label": "option2",
13
+ "newLine": true,
14
+ "sm": 12,
15
+ "md": 6,
16
+ "lg": 4
17
+ }
18
+ }
19
+ }
Binary file
@@ -0,0 +1,38 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="320" height="320" viewBox="0 0 320 320">
2
+ <defs>
3
+ <linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
4
+ <stop offset="0" stop-color="#1e3a8a"/>
5
+ <stop offset="1" stop-color="#0f766e"/>
6
+ </linearGradient>
7
+ <marker id="arr" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="5" markerHeight="5" orient="auto-start-reverse">
8
+ <path d="M0,0 L10,5 L0,10 z" fill="#e2e8f0"/>
9
+ </marker>
10
+ <marker id="arrA" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="5" markerHeight="5" orient="auto-start-reverse">
11
+ <path d="M0,0 L10,5 L0,10 z" fill="#fbbf24"/>
12
+ </marker>
13
+ </defs>
14
+
15
+ <rect x="0" y="0" width="320" height="320" rx="64" fill="url(#bg)"/>
16
+
17
+ <!-- start indicator -->
18
+ <circle cx="44" cy="96" r="9" fill="#e2e8f0"/>
19
+ <path d="M55 96 L82 96" stroke="#e2e8f0" stroke-width="6" fill="none" marker-end="url(#arr)"/>
20
+
21
+ <!-- transitions -->
22
+ <path d="M128 78 Q 172 40 212 78" stroke="#fbbf24" stroke-width="7" fill="none" stroke-linecap="round" marker-end="url(#arrA)"/>
23
+ <path d="M232 138 L 192 210" stroke="#e2e8f0" stroke-width="7" fill="none" stroke-linecap="round" marker-end="url(#arr)"/>
24
+ <path d="M138 222 L 108 140" stroke="#e2e8f0" stroke-width="7" fill="none" stroke-linecap="round" marker-end="url(#arr)"/>
25
+ <path d="M212 116 Q 172 140 132 116" stroke="#e2e8f0" stroke-width="5" fill="none" stroke-linecap="round" stroke-dasharray="2 10" marker-end="url(#arr)"/>
26
+
27
+ <!-- states -->
28
+ <circle cx="104" cy="98" r="30" fill="#f8fafc"/>
29
+ <circle cx="236" cy="98" r="30" fill="#fbbf24"/>
30
+ <circle cx="236" cy="98" r="38" fill="none" stroke="#fbbf24" stroke-width="4" opacity="0.55"/>
31
+ <circle cx="168" cy="244" r="30" fill="#f8fafc"/>
32
+ <circle cx="168" cy="244" r="22" fill="none" stroke="#0f766e" stroke-width="4"/>
33
+
34
+ <!-- state labels -->
35
+ <text x="104" y="107" font-family="DejaVu Sans, Arial, sans-serif" font-size="26" font-weight="700" fill="#1e3a8a" text-anchor="middle">A</text>
36
+ <text x="236" y="107" font-family="DejaVu Sans, Arial, sans-serif" font-size="26" font-weight="700" fill="#1e3a8a" text-anchor="middle">B</text>
37
+ <text x="168" y="253" font-family="DejaVu Sans, Arial, sans-serif" font-size="22" font-weight="700" fill="#1e3a8a" text-anchor="middle">C</text>
38
+ </svg>
@@ -0,0 +1,14 @@
1
+ * {
2
+ box-sizing: border-box;
3
+ }
4
+
5
+ html,
6
+ body,
7
+ #root {
8
+ /* let the tab fill the whole admin frame */
9
+ height: 100%;
10
+ width: 100%;
11
+ margin: 0;
12
+ }
13
+
14
+ /* Add your styles here */
@@ -0,0 +1,34 @@
1
+ <html>
2
+ <head>
3
+ <meta charset="utf-8" />
4
+
5
+ <!-- Load the ioBroker socket connection -->
6
+ <script
7
+ type="text/javascript"
8
+ src="../../lib/js/socket.io.js"
9
+ ></script>
10
+
11
+ <!-- Load our own files -->
12
+ <link
13
+ rel="stylesheet"
14
+ type="text/css"
15
+ href="build/tab.css"
16
+ />
17
+ <link
18
+ rel="stylesheet"
19
+ type="text/css"
20
+ href="style.css"
21
+ />
22
+ </head>
23
+
24
+ <body>
25
+ <!-- this is where the React components are loaded into -->
26
+ <div id="root"></div>
27
+
28
+ <!-- load compiled React scripts -->
29
+ <script
30
+ type="text/javascript"
31
+ src="build/tab.js"
32
+ ></script>
33
+ </body>
34
+ </html>
@@ -0,0 +1,338 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var chart_codegen_exports = {};
20
+ __export(chart_codegen_exports, {
21
+ generateChartCode: () => generateChartCode
22
+ });
23
+ module.exports = __toCommonJS(chart_codegen_exports);
24
+ var import_chart_helpers = require("./chart-helpers");
25
+ var import_chart_model = require("./chart-model");
26
+ var import_chart_structure = require("./chart-structure");
27
+ const INDENT = " ";
28
+ function indent(text, level) {
29
+ const prefix = INDENT.repeat(level);
30
+ return text.split("\n").map((line) => line.trim() ? prefix + line : "").join("\n");
31
+ }
32
+ function oneLine(text) {
33
+ return (text || "").replace(/\s+/g, " ").trim();
34
+ }
35
+ function commentLines(text, prefix = "", indentation = "") {
36
+ if (!text?.trim()) {
37
+ return [];
38
+ }
39
+ return text.trim().split("\n").map((line, i) => `${indentation}// ${i ? " ".repeat(prefix.length) : prefix}${line.trimEnd()}`.trimEnd());
40
+ }
41
+ function identifier(id) {
42
+ const name = id.replace(/[^\w$]/g, "_");
43
+ return /^\d/.test(name) ? `_${name}` : name;
44
+ }
45
+ function propertyKey(key) {
46
+ return /^[A-Za-z_$][\w$]*$/.test(key) ? key : JSON.stringify(key);
47
+ }
48
+ function dedent(code) {
49
+ const lines = code.replace(/\s+$/, "").replace(/^\s*\n/, "").split("\n");
50
+ const common = Math.min(...lines.filter((l) => l.trim()).map((l) => /^\s*/.exec(l)?.[0].length ?? 0));
51
+ return lines.map((l) => l.substring(Number.isFinite(common) ? common : 0)).join("\n");
52
+ }
53
+ function actionFunction(code, level) {
54
+ if (!code?.trim()) {
55
+ return null;
56
+ }
57
+ return `() => {
58
+ ${indent(dedent(code), level + 1)}
59
+ ${INDENT.repeat(level)}}`;
60
+ }
61
+ function generateChartCode(chart, chartId) {
62
+ const structure = new import_chart_structure.ChartStructure(chart);
63
+ const stateName = (id) => structure.statesById.get(id)?.name ?? id;
64
+ const parse = (transition) => {
65
+ if (!structure.statesById.has(transition.target)) {
66
+ return { error: "unknown target" };
67
+ }
68
+ try {
69
+ return { label: (0, import_chart_model.parseTransitionLabel)(transition.label) };
70
+ } catch (err) {
71
+ return { error: err.message };
72
+ }
73
+ };
74
+ const describe = (transition) => `${stateName(transition.source)} -> ${stateName(transition.target)}${transition.label?.trim() ? `: ${oneLine(transition.label)}` : ""}`;
75
+ const lines = [
76
+ `// Code generated from the chart "${oneLine(chart.name)}" by the statechart adapter.`,
77
+ "// It shows how the adapter executes the chart. It is not executed itself, changes here have no effect.",
78
+ "",
79
+ ...chart.comment?.trim() ? [...commentLines(chart.comment), ""] : [],
80
+ ...(chart.notes || []).flatMap((note) => [...commentLines(note.text, "Note: "), ""]),
81
+ 'const { createActor, createMachine } = require("xstate");',
82
+ ""
83
+ ];
84
+ lines.push("// ---------- Variables ----------", "");
85
+ const outputs = chart.symbols.filter((s) => s.scope === "output" && s.stateId);
86
+ if (!chart.symbols.length) {
87
+ lines.push("// no variables");
88
+ }
89
+ for (const symbol of chart.symbols) {
90
+ if (symbol.scope === "local") {
91
+ lines.push(`let ${symbol.name} = ${JSON.stringify(symbol.initial) ?? "undefined"}; // local`);
92
+ } else if (!symbol.stateId) {
93
+ lines.push(`let ${symbol.name}; // ${symbol.scope} without state`);
94
+ } else if (symbol.scope === "input") {
95
+ const trigger = [
96
+ symbol.trigger === "change" ? "on value changes" : "on every update",
97
+ symbol.ack === "ack" ? "only confirmed values (ack = true)" : "",
98
+ symbol.ack === "command" ? "only commands (ack = false)" : "",
99
+ symbol.debounceMs ? `after ${symbol.debounceMs} ms without updates` : ""
100
+ ].filter(Boolean).join(", ");
101
+ lines.push(
102
+ `let ${symbol.name} = getState(${JSON.stringify(symbol.stateId)}); // input, wakes up the chart ${trigger}`
103
+ );
104
+ } else {
105
+ lines.push(
106
+ `let ${symbol.name} = getState(${JSON.stringify(symbol.stateId)}); // output, see writeChangedOutputs()`
107
+ );
108
+ }
109
+ }
110
+ if (outputs.length) {
111
+ lines.push("", "// the last written value of each output");
112
+ lines.push(`const written = { ${outputs.map((s) => s.name).join(", ")} };`);
113
+ }
114
+ lines.push("");
115
+ for (const fn of chart.functions || []) {
116
+ if (fn.code.trim()) {
117
+ lines.push("// ---------- Function block ----------", "", ...commentLines(fn.comment), dedent(fn.code), "");
118
+ }
119
+ }
120
+ lines.push(
121
+ "// ---------- State machine ----------",
122
+ "",
123
+ "// The transitions are selected by the process functions below (Stateflow order),",
124
+ "// XState only executes them: exit actions, transition action, entry actions.",
125
+ "const machine = createMachine({",
126
+ `${INDENT}id: ${JSON.stringify(`chart_${chartId}`)},`
127
+ );
128
+ const transitionConfig = (transition, kind, label, level) => {
129
+ const parts = [`target: ${JSON.stringify(`#${transition.target}`)}`];
130
+ if (kind.reenter) {
131
+ parts.push("reenter: true");
132
+ }
133
+ const action = actionFunction(label.action, level);
134
+ if (action) {
135
+ parts.push(`actions: ${action}`);
136
+ }
137
+ return `{ ${parts.join(", ")} }`;
138
+ };
139
+ const buildState = (state, level) => {
140
+ const i1 = INDENT.repeat(level);
141
+ const i2 = INDENT.repeat(level + 1);
142
+ const i3 = INDENT.repeat(level + 2);
143
+ lines.push(
144
+ `${i1}// ${oneLine(state.name)}`,
145
+ ...commentLines(state.comment, "", i1),
146
+ `${i1}${propertyKey(state.id)}: {`
147
+ );
148
+ lines.push(`${i2}id: ${JSON.stringify(state.id)},`);
149
+ for (const field of ["entry", "exit"]) {
150
+ const action = actionFunction(state[field], level + 1);
151
+ if (action) {
152
+ lines.push(`${i2}${field}: ${action},`);
153
+ }
154
+ }
155
+ const on = [];
156
+ for (const transition of structure.getTransitions(state.id)) {
157
+ const parsed = parse(transition);
158
+ if ("error" in parsed) {
159
+ on.push(`${i3}// ${describe(transition)}: ignored, ${parsed.error}`);
160
+ continue;
161
+ }
162
+ const config = transitionConfig(
163
+ transition,
164
+ structure.getTransitionKind(transition),
165
+ parsed.label,
166
+ level + 2
167
+ );
168
+ on.push(
169
+ `${i3}// ${describe(transition)}`,
170
+ ...commentLines(transition.comment, "", i3),
171
+ `${i3}${JSON.stringify(`T.${transition.id}`)}: ${config},`
172
+ );
173
+ }
174
+ if (on.length) {
175
+ lines.push(`${i2}on: {`, ...on, `${i2}},`);
176
+ }
177
+ const children = structure.getChildren(state.id);
178
+ if (children.length) {
179
+ lines.push(`${i2}initial: ${JSON.stringify(structure.getInitialChild(state.id))},`, `${i2}states: {`);
180
+ for (const child of children) {
181
+ buildState(child, level + 2);
182
+ }
183
+ lines.push(`${i2}},`);
184
+ }
185
+ lines.push(`${i1}},`);
186
+ };
187
+ const topLevel = structure.getChildren(null);
188
+ if (topLevel.length) {
189
+ lines.push(`${INDENT}initial: ${JSON.stringify(structure.getInitialChild(null))},`, `${INDENT}states: {`);
190
+ for (const state of topLevel) {
191
+ buildState(state, 2);
192
+ }
193
+ lines.push(`${INDENT}},`);
194
+ }
195
+ lines.push(
196
+ "});",
197
+ "",
198
+ "const actor = createActor(machine);",
199
+ "actor.start();",
200
+ "// once right after the start, so transitions without event are taken without waiting for an input",
201
+ "wakeup(null);",
202
+ ""
203
+ );
204
+ const callActive = (states, level, prefix) => states.map(
205
+ (s) => `${INDENT.repeat(level)}if (isActive(${JSON.stringify(s.id)})) {
206
+ ${INDENT.repeat(level + 1)}${prefix}process_${identifier(s.id)}(input);
207
+ ${INDENT.repeat(level)}}`
208
+ );
209
+ lines.push(
210
+ "// ---------- Wakeup ----------",
211
+ "",
212
+ "/**",
213
+ " * Called once for every change of an input, after its variable got the new value,",
214
+ " * when the time of an after(...) of an active state has come, and once after the start",
215
+ " * (input is null for the last two).",
216
+ " * Starting with the outermost active state, each active state is processed, see process_...().",
217
+ " *",
218
+ " * @param {string | null} input name of the changed input",
219
+ " */",
220
+ "function wakeup(input) {",
221
+ ...chart.superStep ? [
222
+ `${INDENT}// super step: take transitions until none is valid anymore, at most ${import_chart_model.MAX_SUPER_STEPS}.`,
223
+ `${INDENT}// The event of the input is only present in the first step.`,
224
+ `${INDENT}for (let steps = 0; steps < ${import_chart_model.MAX_SUPER_STEPS} && step(input); steps++) {`,
225
+ `${INDENT}${INDENT}input = null;`,
226
+ `${INDENT}}`
227
+ ] : [`${INDENT}step(input);`],
228
+ `${INDENT}writeChangedOutputs();`,
229
+ "}",
230
+ "",
231
+ "/**",
232
+ " * Processes the active states once",
233
+ " *",
234
+ " * @param {string | null} input name of the changed input, null if the step has no event",
235
+ " * @returns {boolean} true if a transition was taken",
236
+ " */",
237
+ "function step(input) {",
238
+ ...callActive(topLevel, 1, "return "),
239
+ `${INDENT}return false;`,
240
+ "}",
241
+ ""
242
+ );
243
+ const check = (transition, label) => {
244
+ const conditions = [];
245
+ if (label.event) {
246
+ conditions.push(`input === ${JSON.stringify(label.event)}`);
247
+ }
248
+ if (label.afterMs !== void 0) {
249
+ conditions.push(`elapsed(${JSON.stringify(transition.source)}) >= ${label.afterMs}`);
250
+ }
251
+ if (label.condition) {
252
+ conditions.push(`(${label.condition})`);
253
+ }
254
+ return [
255
+ `${INDENT}// ${describe(transition)}`,
256
+ ...commentLines(transition.comment, "", INDENT),
257
+ `${INDENT}if (${conditions.join(" && ") || "true"}) {`,
258
+ `${INDENT}${INDENT}actor.send({ type: ${JSON.stringify(`T.${transition.id}`)} });`,
259
+ `${INDENT}${INDENT}return true;`,
260
+ `${INDENT}}`
261
+ ];
262
+ };
263
+ for (const state of chart.states) {
264
+ const outer = [];
265
+ const inner = [];
266
+ for (const transition of structure.getTransitions(state.id)) {
267
+ const parsed = parse(transition);
268
+ if ("error" in parsed) {
269
+ continue;
270
+ }
271
+ (structure.getTransitionKind(transition).inner ? inner : outer).push(...check(transition, parsed.label));
272
+ }
273
+ const children = structure.getChildren(state.id);
274
+ lines.push(
275
+ "/**",
276
+ ` * ${oneLine(state.name)}`,
277
+ ...state.comment?.trim() ? [
278
+ " *",
279
+ // "*/" would end the comment
280
+ ...state.comment.trim().split("\n").map((line) => ` * ${line.trimEnd().replace(/\*\//g, "* /")}`.trimEnd())
281
+ ] : [],
282
+ " *",
283
+ " * @param {string | null} input name of the changed input, null for timers",
284
+ " * @returns {boolean} true if a transition was taken",
285
+ " */",
286
+ `function process_${identifier(state.id)}(input) {`,
287
+ `${INDENT}// 1. transitions leaving the state`,
288
+ ...outer.length ? outer : [`${INDENT}// none`],
289
+ `${INDENT}// 2. during action`,
290
+ state.during?.trim() ? `${INDENT}{
291
+ ${indent(dedent(state.during), 2)}
292
+ ${INDENT}}` : `${INDENT}// none`,
293
+ `${INDENT}// 3. inner transitions (to own sub states, the state stays active)`,
294
+ ...inner.length ? inner : [`${INDENT}// none`],
295
+ `${INDENT}// 4. active sub state`,
296
+ ...children.length ? callActive(children, 1, "return ") : [`${INDENT}// none`],
297
+ `${INDENT}return false;`,
298
+ "}",
299
+ ""
300
+ );
301
+ }
302
+ lines.push(
303
+ "// ---------- Helpers ----------",
304
+ "",
305
+ "/** Writes every output whose value was changed by an action */",
306
+ "function writeChangedOutputs() {",
307
+ ...outputs.map(
308
+ (s) => `${INDENT}if (${s.name} !== written.${s.name}) {
309
+ ${INDENT}${INDENT}written.${s.name} = ${s.name};
310
+ ${INDENT}${INDENT}setState(${JSON.stringify(s.stateId)}, ${s.name});
311
+ ${INDENT}}`
312
+ ),
313
+ "}",
314
+ "",
315
+ "// Provided by the adapter:",
316
+ "// getState(id) current value of an ioBroker state",
317
+ "// isActive(stateId) true if the state of the chart is active",
318
+ "// elapsed(stateId) milliseconds since the state was entered; when it reaches the delay of an",
319
+ "// after(...) of the state, a timer calls wakeup(null)",
320
+ "// At the start of each wakeup, the adapter stores the values of the variables used in hasChanged(),",
321
+ "// hasChangedFrom() and hasChangedTo(), these compare them with the values of the previous wakeup.",
322
+ "//",
323
+ "// Helper functions for conditions, actions and function blocks:",
324
+ ...Object.values(import_chart_helpers.HELPERS).map((helper) => `// ${helper.signature}
325
+ // ${helper.description}`),
326
+ "//",
327
+ "// The adapter stores the active states, the times they were entered and the locals in the state",
328
+ "// charts.<chart>.snapshot. After a restart of the adapter it continues with them, without executing the",
329
+ "// entry actions again, if the chart was not changed meanwhile. Then it wakes up once, like after a start.",
330
+ ""
331
+ );
332
+ return lines.join("\n");
333
+ }
334
+ // Annotate the CommonJS export names for ESM import in node:
335
+ 0 && (module.exports = {
336
+ generateChartCode
337
+ });
338
+ //# sourceMappingURL=chart-codegen.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/lib/chart-codegen.ts"],
4
+ "sourcesContent": ["/*\n * Generates readable JavaScript from a chart. It shows how the runtime executes the chart:\n * the XState machine, and the functions which select the transitions in Stateflow order.\n * The code is only shown to the user, the runtime does not execute it.\n */\n\nimport { HELPERS } from \"./chart-helpers\";\nimport { MAX_SUPER_STEPS, parseTransitionLabel } from \"./chart-model\";\nimport type { Chart, ChartState, ChartTransition, TransitionLabel } from \"./chart-model\";\nimport { ChartStructure } from \"./chart-structure\";\nimport type { TransitionKind } from \"./chart-structure\";\n\nconst INDENT = \" \";\n\nfunction indent(text: string, level: number): string {\n const prefix = INDENT.repeat(level);\n return text\n .split(\"\\n\")\n .map(line => (line.trim() ? prefix + line : \"\"))\n .join(\"\\n\");\n}\n\n/**\n * Text for a // comment, on one line\n *\n * @param text The text, may have several lines\n */\nfunction oneLine(text: string | undefined): string {\n return (text || \"\").replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * A comment or note as // lines\n *\n * @param text The comment\n * @param prefix Indentation and optional text before the first line, e.g. \"Note: \"\n * @param indentation Added before each line\n * @returns no lines for an empty text\n */\nfunction commentLines(text: string | undefined, prefix = \"\", indentation = \"\"): string[] {\n if (!text?.trim()) {\n return [];\n }\n return text\n .trim()\n .split(\"\\n\")\n .map((line, i) => `${indentation}// ${i ? \" \".repeat(prefix.length) : prefix}${line.trimEnd()}`.trimEnd());\n}\n\n/**\n * Converts a state ID to a valid identifier for the names of the generated functions\n *\n * @param id ID of the state\n */\nfunction identifier(id: string): string {\n const name = id.replace(/[^\\w$]/g, \"_\");\n return /^\\d/.test(name) ? `_${name}` : name;\n}\n\n/**\n * @param key The property name\n * @returns the key for an object literal, in quotes only if necessary\n */\nfunction propertyKey(key: string): string {\n return /^[A-Za-z_$][\\w$]*$/.test(key) ? key : JSON.stringify(key);\n}\n\n/**\n * Removes the indentation all lines have in common, so the code can be indented again\n *\n * @param code The code\n */\nfunction dedent(code: string): string {\n const lines = code\n .replace(/\\s+$/, \"\")\n .replace(/^\\s*\\n/, \"\")\n .split(\"\\n\");\n const common = Math.min(...lines.filter(l => l.trim()).map(l => /^\\s*/.exec(l)?.[0].length ?? 0));\n return lines.map(l => l.substring(Number.isFinite(common) ? common : 0)).join(\"\\n\");\n}\n\n/**\n * An arrow function executing an action, or null if there is no action\n *\n * @param code The action\n * @param level Indentation level of the line the function starts in\n */\nfunction actionFunction(code: string | undefined, level: number): string | null {\n if (!code?.trim()) {\n return null;\n }\n return `() => {\\n${indent(dedent(code), level + 1)}\\n${INDENT.repeat(level)}}`;\n}\n\n/**\n * Generates the code of a chart\n *\n * @param chart The chart\n * @param chartId ID of the chart object, used for the machine ID like in the runtime\n */\nexport function generateChartCode(chart: Chart, chartId: string): string {\n const structure = new ChartStructure(chart);\n const stateName = (id: string): string => structure.statesById.get(id)?.name ?? id;\n\n /**\n * Parses a label, null if it is invalid or the target is unknown (the runtime ignores these transitions)\n *\n * @param transition The transition\n */\n const parse = (transition: ChartTransition): { label: TransitionLabel } | { error: string } => {\n if (!structure.statesById.has(transition.target)) {\n return { error: \"unknown target\" };\n }\n try {\n return { label: parseTransitionLabel(transition.label) };\n } catch (err) {\n return { error: err.message };\n }\n };\n\n /**\n * @param transition The transition\n * @returns e.g. \"Off -> On: motion[motion]\"\n */\n const describe = (transition: ChartTransition): string =>\n `${stateName(transition.source)} -> ${stateName(transition.target)}${\n transition.label?.trim() ? `: ${oneLine(transition.label)}` : \"\"\n }`;\n\n const lines = [\n `// Code generated from the chart \"${oneLine(chart.name)}\" by the statechart adapter.`,\n \"// It shows how the adapter executes the chart. It is not executed itself, changes here have no effect.\",\n \"\",\n ...(chart.comment?.trim() ? [...commentLines(chart.comment), \"\"] : []),\n ...(chart.notes || []).flatMap(note => [...commentLines(note.text, \"Note: \"), \"\"]),\n 'const { createActor, createMachine } = require(\"xstate\");',\n \"\",\n ];\n\n // variables\n lines.push(\"// ---------- Variables ----------\", \"\");\n const outputs = chart.symbols.filter(s => s.scope === \"output\" && s.stateId);\n if (!chart.symbols.length) {\n lines.push(\"// no variables\");\n }\n for (const symbol of chart.symbols) {\n if (symbol.scope === \"local\") {\n lines.push(`let ${symbol.name} = ${JSON.stringify(symbol.initial) ?? \"undefined\"}; // local`);\n } else if (!symbol.stateId) {\n lines.push(`let ${symbol.name}; // ${symbol.scope} without state`);\n } else if (symbol.scope === \"input\") {\n const trigger = [\n symbol.trigger === \"change\" ? \"on value changes\" : \"on every update\",\n symbol.ack === \"ack\" ? \"only confirmed values (ack = true)\" : \"\",\n symbol.ack === \"command\" ? \"only commands (ack = false)\" : \"\",\n symbol.debounceMs ? `after ${symbol.debounceMs} ms without updates` : \"\",\n ]\n .filter(Boolean)\n .join(\", \");\n lines.push(\n `let ${symbol.name} = getState(${JSON.stringify(symbol.stateId)}); // input, wakes up the chart ${trigger}`,\n );\n } else {\n lines.push(\n `let ${symbol.name} = getState(${JSON.stringify(symbol.stateId)}); // output, see writeChangedOutputs()`,\n );\n }\n }\n if (outputs.length) {\n lines.push(\"\", \"// the last written value of each output\");\n lines.push(`const written = { ${outputs.map(s => s.name).join(\", \")} };`);\n }\n lines.push(\"\");\n\n // function blocks\n for (const fn of chart.functions || []) {\n if (fn.code.trim()) {\n lines.push(\"// ---------- Function block ----------\", \"\", ...commentLines(fn.comment), dedent(fn.code), \"\");\n }\n }\n\n // machine\n lines.push(\n \"// ---------- State machine ----------\",\n \"\",\n \"// The transitions are selected by the process functions below (Stateflow order),\",\n \"// XState only executes them: exit actions, transition action, entry actions.\",\n \"const machine = createMachine({\",\n `${INDENT}id: ${JSON.stringify(`chart_${chartId}`)},`,\n );\n\n const transitionConfig = (\n transition: ChartTransition,\n kind: TransitionKind,\n label: TransitionLabel,\n level: number,\n ): string => {\n const parts = [`target: ${JSON.stringify(`#${transition.target}`)}`];\n if (kind.reenter) {\n parts.push(\"reenter: true\");\n }\n const action = actionFunction(label.action, level);\n if (action) {\n parts.push(`actions: ${action}`);\n }\n return `{ ${parts.join(\", \")} }`;\n };\n\n const buildState = (state: ChartState, level: number): void => {\n const i1 = INDENT.repeat(level);\n const i2 = INDENT.repeat(level + 1);\n const i3 = INDENT.repeat(level + 2);\n lines.push(\n `${i1}// ${oneLine(state.name)}`,\n ...commentLines(state.comment, \"\", i1),\n `${i1}${propertyKey(state.id)}: {`,\n );\n lines.push(`${i2}id: ${JSON.stringify(state.id)},`);\n for (const field of [\"entry\", \"exit\"] as const) {\n const action = actionFunction(state[field], level + 1);\n if (action) {\n lines.push(`${i2}${field}: ${action},`);\n }\n }\n\n const on: string[] = [];\n for (const transition of structure.getTransitions(state.id)) {\n const parsed = parse(transition);\n if (\"error\" in parsed) {\n on.push(`${i3}// ${describe(transition)}: ignored, ${parsed.error}`);\n continue;\n }\n const config = transitionConfig(\n transition,\n structure.getTransitionKind(transition),\n parsed.label,\n level + 2,\n );\n on.push(\n `${i3}// ${describe(transition)}`,\n ...commentLines(transition.comment, \"\", i3),\n `${i3}${JSON.stringify(`T.${transition.id}`)}: ${config},`,\n );\n }\n if (on.length) {\n lines.push(`${i2}on: {`, ...on, `${i2}},`);\n }\n\n const children = structure.getChildren(state.id);\n if (children.length) {\n lines.push(`${i2}initial: ${JSON.stringify(structure.getInitialChild(state.id))},`, `${i2}states: {`);\n for (const child of children) {\n buildState(child, level + 2);\n }\n lines.push(`${i2}},`);\n }\n lines.push(`${i1}},`);\n };\n\n const topLevel = structure.getChildren(null);\n if (topLevel.length) {\n lines.push(`${INDENT}initial: ${JSON.stringify(structure.getInitialChild(null))},`, `${INDENT}states: {`);\n for (const state of topLevel) {\n buildState(state, 2);\n }\n lines.push(`${INDENT}},`);\n }\n lines.push(\n \"});\",\n \"\",\n \"const actor = createActor(machine);\",\n \"actor.start();\",\n \"// once right after the start, so transitions without event are taken without waiting for an input\",\n \"wakeup(null);\",\n \"\",\n );\n\n // wakeup and process functions\n /**\n * @param states The states which may be active\n * @param level Indentation level\n * @param prefix \"return \" inside process functions\n */\n const callActive = (states: ChartState[], level: number, prefix: string): string[] =>\n states.map(\n s =>\n `${INDENT.repeat(level)}if (isActive(${JSON.stringify(s.id)})) {\\n` +\n `${INDENT.repeat(level + 1)}${prefix}process_${identifier(s.id)}(input);\\n` +\n `${INDENT.repeat(level)}}`,\n );\n\n lines.push(\n \"// ---------- Wakeup ----------\",\n \"\",\n \"/**\",\n \" * Called once for every change of an input, after its variable got the new value,\",\n \" * when the time of an after(...) of an active state has come, and once after the start\",\n \" * (input is null for the last two).\",\n \" * Starting with the outermost active state, each active state is processed, see process_...().\",\n \" *\",\n \" * @param {string | null} input name of the changed input\",\n \" */\",\n \"function wakeup(input) {\",\n ...(chart.superStep\n ? [\n `${INDENT}// super step: take transitions until none is valid anymore, at most ${MAX_SUPER_STEPS}.`,\n `${INDENT}// The event of the input is only present in the first step.`,\n `${INDENT}for (let steps = 0; steps < ${MAX_SUPER_STEPS} && step(input); steps++) {`,\n `${INDENT}${INDENT}input = null;`,\n `${INDENT}}`,\n ]\n : [`${INDENT}step(input);`]),\n `${INDENT}writeChangedOutputs();`,\n \"}\",\n \"\",\n \"/**\",\n \" * Processes the active states once\",\n \" *\",\n \" * @param {string | null} input name of the changed input, null if the step has no event\",\n \" * @returns {boolean} true if a transition was taken\",\n \" */\",\n \"function step(input) {\",\n // only one state of the top level is active\n ...callActive(topLevel, 1, \"return \"),\n `${INDENT}return false;`,\n \"}\",\n \"\",\n );\n\n /**\n * A check of a transition in a process function\n *\n * @param transition The transition\n * @param label Its parsed label\n */\n const check = (transition: ChartTransition, label: TransitionLabel): string[] => {\n const conditions: string[] = [];\n if (label.event) {\n conditions.push(`input === ${JSON.stringify(label.event)}`);\n }\n if (label.afterMs !== undefined) {\n // valid from the moment on, not only when the timer expires\n conditions.push(`elapsed(${JSON.stringify(transition.source)}) >= ${label.afterMs}`);\n }\n if (label.condition) {\n conditions.push(`(${label.condition})`);\n }\n return [\n `${INDENT}// ${describe(transition)}`,\n ...commentLines(transition.comment, \"\", INDENT),\n `${INDENT}if (${conditions.join(\" && \") || \"true\"}) {`,\n `${INDENT}${INDENT}actor.send({ type: ${JSON.stringify(`T.${transition.id}`)} });`,\n `${INDENT}${INDENT}return true;`,\n `${INDENT}}`,\n ];\n };\n\n for (const state of chart.states) {\n const outer: string[] = [];\n const inner: string[] = [];\n for (const transition of structure.getTransitions(state.id)) {\n const parsed = parse(transition);\n if (\"error\" in parsed) {\n continue;\n }\n (structure.getTransitionKind(transition).inner ? inner : outer).push(...check(transition, parsed.label));\n }\n const children = structure.getChildren(state.id);\n lines.push(\n \"/**\",\n ` * ${oneLine(state.name)}`,\n ...(state.comment?.trim()\n ? [\n \" *\",\n // \"*/\" would end the comment\n ...state.comment\n .trim()\n .split(\"\\n\")\n .map(line => ` * ${line.trimEnd().replace(/\\*\\//g, \"* /\")}`.trimEnd()),\n ]\n : []),\n \" *\",\n \" * @param {string | null} input name of the changed input, null for timers\",\n \" * @returns {boolean} true if a transition was taken\",\n \" */\",\n `function process_${identifier(state.id)}(input) {`,\n `${INDENT}// 1. transitions leaving the state`,\n ...(outer.length ? outer : [`${INDENT}// none`]),\n `${INDENT}// 2. during action`,\n state.during?.trim() ? `${INDENT}{\\n${indent(dedent(state.during), 2)}\\n${INDENT}}` : `${INDENT}// none`,\n `${INDENT}// 3. inner transitions (to own sub states, the state stays active)`,\n ...(inner.length ? inner : [`${INDENT}// none`]),\n `${INDENT}// 4. active sub state`,\n ...(children.length ? callActive(children, 1, \"return \") : [`${INDENT}// none`]),\n `${INDENT}return false;`,\n \"}\",\n \"\",\n );\n }\n\n // helpers\n lines.push(\n \"// ---------- Helpers ----------\",\n \"\",\n \"/** Writes every output whose value was changed by an action */\",\n \"function writeChangedOutputs() {\",\n ...outputs.map(\n s =>\n `${INDENT}if (${s.name} !== written.${s.name}) {\\n` +\n `${INDENT}${INDENT}written.${s.name} = ${s.name};\\n` +\n `${INDENT}${INDENT}setState(${JSON.stringify(s.stateId)}, ${s.name});\\n` +\n `${INDENT}}`,\n ),\n \"}\",\n \"\",\n \"// Provided by the adapter:\",\n \"// getState(id) current value of an ioBroker state\",\n \"// isActive(stateId) true if the state of the chart is active\",\n \"// elapsed(stateId) milliseconds since the state was entered; when it reaches the delay of an\",\n \"// after(...) of the state, a timer calls wakeup(null)\",\n \"// At the start of each wakeup, the adapter stores the values of the variables used in hasChanged(),\",\n \"// hasChangedFrom() and hasChangedTo(), these compare them with the values of the previous wakeup.\",\n \"//\",\n \"// Helper functions for conditions, actions and function blocks:\",\n ...Object.values(HELPERS).map(helper => `// ${helper.signature}\\n// ${helper.description}`),\n \"//\",\n \"// The adapter stores the active states, the times they were entered and the locals in the state\",\n \"// charts.<chart>.snapshot. After a restart of the adapter it continues with them, without executing the\",\n \"// entry actions again, if the chart was not changed meanwhile. Then it wakes up once, like after a start.\",\n \"\",\n );\n return lines.join(\"\\n\");\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }