iobroker.statechart 0.1.1 → 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,353 @@
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_model_exports = {};
20
+ __export(chart_model_exports, {
21
+ CHART_MODEL_VERSION: () => CHART_MODEL_VERSION,
22
+ EXPORT_FORMAT: () => EXPORT_FORMAT,
23
+ LabelSyntaxError: () => LabelSyntaxError,
24
+ MAX_SUPER_STEPS: () => MAX_SUPER_STEPS,
25
+ createChart: () => createChart,
26
+ createExport: () => createExport,
27
+ formatMessage: () => formatMessage,
28
+ nameToId: () => nameToId,
29
+ parseExport: () => parseExport,
30
+ parseTransitionLabel: () => parseTransitionLabel,
31
+ parseTransitionLabelWithRanges: () => parseTransitionLabelWithRanges
32
+ });
33
+ module.exports = __toCommonJS(chart_model_exports);
34
+ const CHART_MODEL_VERSION = 1;
35
+ const MAX_SUPER_STEPS = 100;
36
+ const TIME_UNITS = {
37
+ msec: 1,
38
+ sec: 1e3,
39
+ min: 6e4
40
+ };
41
+ function createChart(name) {
42
+ return {
43
+ version: CHART_MODEL_VERSION,
44
+ name,
45
+ enabled: false,
46
+ symbols: [],
47
+ states: [],
48
+ transitions: [],
49
+ functions: [],
50
+ notes: []
51
+ };
52
+ }
53
+ function nameToId(name) {
54
+ return name.trim().toLowerCase().replace(/ä/g, "ae").replace(/ö/g, "oe").replace(/ü/g, "ue").replace(/ß/g, "ss").replace(/[^a-z0-9_-]+/g, "_").replace(/^_+|_+$/g, "") || "chart";
55
+ }
56
+ function formatMessage(key, args) {
57
+ let i = 0;
58
+ return key.replace(/%s/g, () => args[i++] ?? "");
59
+ }
60
+ class LabelSyntaxError extends Error {
61
+ /**
62
+ * @param key Message with %s placeholders, used to translate the message
63
+ * @param args Values for the placeholders
64
+ * @param from Start of the problem in the label
65
+ * @param to End of the problem in the label
66
+ */
67
+ constructor(key, args, from, to) {
68
+ super(formatMessage(key, args));
69
+ this.key = key;
70
+ this.args = args;
71
+ this.from = from;
72
+ this.to = to;
73
+ }
74
+ }
75
+ function readEnclosed(text, start, open, close) {
76
+ let depth = 0;
77
+ for (let i = start; i < text.length; i++) {
78
+ if (text[i] === open) {
79
+ depth++;
80
+ } else if (text[i] === close) {
81
+ depth--;
82
+ if (depth === 0) {
83
+ const raw = text.substring(start + 1, i);
84
+ const content = raw.trim();
85
+ return { content, from: start + 1 + raw.indexOf(content), end: i + 1 };
86
+ }
87
+ }
88
+ }
89
+ throw new LabelSyntaxError('Missing "%s"', [close], start, text.length);
90
+ }
91
+ function parseTransitionLabelWithRanges(label) {
92
+ const result = {};
93
+ const ranges = {};
94
+ const text = label || "";
95
+ let pos = 0;
96
+ const skipSpace = () => {
97
+ while (pos < text.length && /\s/.test(text[pos])) {
98
+ pos++;
99
+ }
100
+ };
101
+ skipSpace();
102
+ const eventMatch = /[A-Za-z_$][\w$]*/y;
103
+ eventMatch.lastIndex = pos;
104
+ const event = eventMatch.exec(text);
105
+ if (event) {
106
+ const from = pos;
107
+ pos += event[0].length;
108
+ skipSpace();
109
+ if (event[0] === "after" && text[pos] === "(") {
110
+ const { content, end } = readEnclosed(text, pos, "(", ")");
111
+ const afterMatch = /^(\d+(?:\.\d+)?)\s*,\s*(msec|sec|min)$/.exec(content);
112
+ if (!afterMatch) {
113
+ throw new LabelSyntaxError(
114
+ 'Invalid temporal expression "%s", expected e.g. after(5, sec)',
115
+ [`after(${content})`],
116
+ from,
117
+ end
118
+ );
119
+ }
120
+ result.afterMs = parseFloat(afterMatch[1]) * TIME_UNITS[afterMatch[2]];
121
+ ranges.after = { from, to: end };
122
+ pos = end;
123
+ } else {
124
+ result.event = event[0];
125
+ ranges.event = { from, to: from + event[0].length };
126
+ }
127
+ }
128
+ skipSpace();
129
+ if (text[pos] === "[") {
130
+ const { content, from, end } = readEnclosed(text, pos, "[", "]");
131
+ result.condition = content;
132
+ ranges.condition = { from, to: from + content.length };
133
+ pos = end;
134
+ }
135
+ skipSpace();
136
+ if (text[pos] === "{") {
137
+ const { content, from, end } = readEnclosed(text, pos, "{", "}");
138
+ result.action = content;
139
+ ranges.action = { from, to: from + content.length };
140
+ pos = end;
141
+ }
142
+ skipSpace();
143
+ if (pos < text.length) {
144
+ throw new LabelSyntaxError(
145
+ 'Unexpected "%s", expected event[condition]{action}',
146
+ [text.substring(pos).trim()],
147
+ pos,
148
+ text.length
149
+ );
150
+ }
151
+ return { label: result, ranges };
152
+ }
153
+ function parseTransitionLabel(label) {
154
+ return parseTransitionLabelWithRanges(label).label;
155
+ }
156
+ const EXPORT_FORMAT = "iobroker.statechart";
157
+ const LEGACY_EXPORT_FORMATS = ["iobroker.state-machine"];
158
+ function createExport(charts) {
159
+ return { format: EXPORT_FORMAT, version: CHART_MODEL_VERSION, exported: (/* @__PURE__ */ new Date()).toISOString(), charts };
160
+ }
161
+ const IDENTIFIER = /^[A-Za-z_$][\w$]*$/;
162
+ const SCOPES = ["input", "output", "local"];
163
+ function isObject(value) {
164
+ return typeof value === "object" && value !== null && !Array.isArray(value);
165
+ }
166
+ function normalizeChart(data, where) {
167
+ const fail = (message) => {
168
+ throw new Error(`${where}: ${message}`);
169
+ };
170
+ if (!isObject(data)) {
171
+ fail("not an object");
172
+ }
173
+ if (typeof data.version === "number" && data.version > CHART_MODEL_VERSION) {
174
+ fail(`created with a newer version of the adapter (chart version ${data.version})`);
175
+ }
176
+ for (const list of ["states", "transitions", "symbols"]) {
177
+ if (!Array.isArray(data[list])) {
178
+ fail(`"${list}" is missing or no list`);
179
+ }
180
+ }
181
+ for (const list of ["functions", "notes"]) {
182
+ if (data[list] !== void 0 && !Array.isArray(data[list])) {
183
+ fail(`"${list}" is no list`);
184
+ }
185
+ }
186
+ const functions = data.functions || [];
187
+ const notes = data.notes || [];
188
+ const nodeIds = /* @__PURE__ */ new Set();
189
+ const checkId = (item, kind, index) => {
190
+ if (!isObject(item) || typeof item.id !== "string" || !item.id) {
191
+ fail(`${kind} ${index + 1} has no ID`);
192
+ }
193
+ if (nodeIds.has(item.id)) {
194
+ fail(`${kind} ${item.id}: the ID is used more than once`);
195
+ }
196
+ nodeIds.add(item.id);
197
+ return item.id;
198
+ };
199
+ const optionalString = (value, message) => {
200
+ if (value !== void 0 && value !== null && typeof value !== "string") {
201
+ fail(message);
202
+ }
203
+ };
204
+ data.states.forEach((state, i) => checkId(state, "state", i));
205
+ functions.forEach((fn, i) => checkId(fn, "function block", i));
206
+ notes.forEach((note, i) => checkId(note, "note", i));
207
+ const stateIds = new Set(data.states.map((s) => s.id));
208
+ optionalString(data.comment, '"comment" is no text');
209
+ const states = data.states.map((state) => {
210
+ const at = `state ${state.id}`;
211
+ if (state.parent && !stateIds.has(state.parent)) {
212
+ fail(`${at}: unknown parent state "${state.parent}"`);
213
+ }
214
+ for (const field of ["entry", "during", "exit", "initial", "comment"]) {
215
+ optionalString(state[field], `${at}: "${field}" is no text`);
216
+ }
217
+ return {
218
+ ...state,
219
+ name: typeof state.name === "string" && state.name ? state.name : state.id,
220
+ parent: state.parent || null,
221
+ x: Number.isFinite(state.x) ? state.x : 0,
222
+ y: Number.isFinite(state.y) ? state.y : 0
223
+ };
224
+ });
225
+ const parentOf = new Map(states.map((s) => [s.id, s.parent]));
226
+ for (const state of states) {
227
+ let parent = state.parent;
228
+ for (let i = 0; parent; i++) {
229
+ if (parent === state.id || i > states.length) {
230
+ fail(`state ${state.id}: the parent states form a cycle`);
231
+ }
232
+ parent = parentOf.get(parent) ?? null;
233
+ }
234
+ }
235
+ const transitionIds = /* @__PURE__ */ new Set();
236
+ const transitions = data.transitions.map((transition, i) => {
237
+ if (!isObject(transition) || typeof transition.id !== "string" || !transition.id) {
238
+ fail(`transition ${i + 1} has no ID`);
239
+ }
240
+ const at = `transition ${transition.id}`;
241
+ if (transitionIds.has(transition.id)) {
242
+ fail(`${at}: the ID is used more than once`);
243
+ }
244
+ transitionIds.add(transition.id);
245
+ for (const end of ["source", "target"]) {
246
+ if (!stateIds.has(transition[end])) {
247
+ fail(`${at}: unknown ${end} state "${transition[end]}"`);
248
+ }
249
+ }
250
+ optionalString(transition.label, `${at}: "label" is no text`);
251
+ optionalString(transition.comment, `${at}: "comment" is no text`);
252
+ if (transition.priority !== void 0 && !Number.isFinite(transition.priority)) {
253
+ fail(`${at}: "priority" is no number`);
254
+ }
255
+ return { ...transition };
256
+ });
257
+ const symbolNames = /* @__PURE__ */ new Set();
258
+ const symbols = data.symbols.map((symbol, i) => {
259
+ if (!isObject(symbol) || typeof symbol.name !== "string" || !IDENTIFIER.test(symbol.name)) {
260
+ fail(`variable ${i + 1}: invalid name`);
261
+ }
262
+ if (symbolNames.has(symbol.name)) {
263
+ fail(`variable ${symbol.name}: the name is used more than once`);
264
+ }
265
+ symbolNames.add(symbol.name);
266
+ if (!SCOPES.includes(symbol.scope)) {
267
+ fail(`variable ${symbol.name}: invalid kind "${symbol.scope}"`);
268
+ }
269
+ optionalString(symbol.stateId, `variable ${symbol.name}: "stateId" is no text`);
270
+ if (symbol.trigger !== void 0 && !["update", "change"].includes(symbol.trigger)) {
271
+ fail(`variable ${symbol.name}: invalid trigger "${symbol.trigger}"`);
272
+ }
273
+ if (symbol.ack !== void 0 && !["any", "ack", "command"].includes(symbol.ack)) {
274
+ fail(`variable ${symbol.name}: invalid ack filter "${symbol.ack}"`);
275
+ }
276
+ if (symbol.debounceMs !== void 0 && !(Number.isFinite(symbol.debounceMs) && symbol.debounceMs >= 0)) {
277
+ fail(`variable ${symbol.name}: "debounceMs" is no number of 0 or more`);
278
+ }
279
+ return { ...symbol };
280
+ });
281
+ const normalizedFunctions = functions.map((fn) => {
282
+ if (typeof fn.code !== "string") {
283
+ fail(`function block ${fn.id}: "code" is no text`);
284
+ }
285
+ optionalString(fn.comment, `function block ${fn.id}: "comment" is no text`);
286
+ return { ...fn, x: Number.isFinite(fn.x) ? fn.x : 0, y: Number.isFinite(fn.y) ? fn.y : 0 };
287
+ });
288
+ const normalizedNotes = notes.map((note) => {
289
+ optionalString(note.text, `note ${note.id}: "text" is no text`);
290
+ if (note.parent && !stateIds.has(note.parent)) {
291
+ fail(`note ${note.id}: unknown parent state "${note.parent}"`);
292
+ }
293
+ return {
294
+ ...note,
295
+ text: note.text || "",
296
+ parent: note.parent || null,
297
+ x: Number.isFinite(note.x) ? note.x : 0,
298
+ y: Number.isFinite(note.y) ? note.y : 0
299
+ };
300
+ });
301
+ const chart = {
302
+ ...data,
303
+ version: CHART_MODEL_VERSION,
304
+ name: typeof data.name === "string" && data.name.trim() ? data.name.trim() : where,
305
+ initial: typeof data.initial === "string" && stateIds.has(data.initial) ? data.initial : void 0,
306
+ enabled: data.enabled !== false,
307
+ symbols,
308
+ states,
309
+ transitions,
310
+ functions: normalizedFunctions,
311
+ notes: normalizedNotes
312
+ };
313
+ if (chart.superStep !== true) {
314
+ delete chart.superStep;
315
+ }
316
+ return chart;
317
+ }
318
+ function parseExport(text) {
319
+ let data;
320
+ try {
321
+ data = JSON.parse(text);
322
+ } catch (err) {
323
+ throw new Error(`No valid JSON: ${err.message}`);
324
+ }
325
+ if (isObject(data) && (data.format === EXPORT_FORMAT || LEGACY_EXPORT_FORMATS.includes(data.format))) {
326
+ if (typeof data.version === "number" && data.version > CHART_MODEL_VERSION) {
327
+ throw new Error(`The file was created with a newer version of the adapter (version ${data.version})`);
328
+ }
329
+ if (!Array.isArray(data.charts) || !data.charts.length) {
330
+ throw new Error("The file contains no charts");
331
+ }
332
+ return data.charts.map((chart, i) => normalizeChart(chart, `Chart ${i + 1}`));
333
+ }
334
+ if (isObject(data) && Array.isArray(data.states)) {
335
+ return [normalizeChart(data, "Chart")];
336
+ }
337
+ throw new Error("The file contains no charts of the statechart adapter");
338
+ }
339
+ // Annotate the CommonJS export names for ESM import in node:
340
+ 0 && (module.exports = {
341
+ CHART_MODEL_VERSION,
342
+ EXPORT_FORMAT,
343
+ LabelSyntaxError,
344
+ MAX_SUPER_STEPS,
345
+ createChart,
346
+ createExport,
347
+ formatMessage,
348
+ nameToId,
349
+ parseExport,
350
+ parseTransitionLabel,
351
+ parseTransitionLabelWithRanges
352
+ });
353
+ //# sourceMappingURL=chart-model.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/lib/chart-model.ts"],
4
+ "sourcesContent": ["/*\n * The chart model shared by the editor (admin tab) and the runtime (adapter).\n *\n * A chart is stored as object \"statechart.<instance>.charts.<chartId>\" (type \"channel\"),\n * the model itself lives in `native.chart` of that object.\n */\n\n/** Current version of the chart model, increase on incompatible changes */\nexport const CHART_MODEL_VERSION = 1;\n\n/** Maximum number of transitions in one wakeup with super step semantics, protects against loops */\nexport const MAX_SUPER_STEPS = 100;\n\nexport type SymbolScope = \"input\" | \"output\" | \"local\";\n\nexport type InputTrigger = \"update\" | \"change\";\n\n/** \"ack\": only confirmed values, \"command\": only commands (ack=false) */\nexport type AckFilter = \"any\" | \"ack\" | \"command\";\n\n/**\n * A variable which can be used in conditions and actions.\n * Inputs and outputs are mapped to ioBroker states, locals only live inside the chart.\n */\nexport interface ChartSymbol {\n /** Name used in conditions and actions, must be a valid JavaScript identifier */\n name: string;\n /** Input (read from state), output (written to state) or local */\n scope: SymbolScope;\n /** ioBroker state ID for inputs and outputs */\n stateId?: string;\n /** Initial value for locals */\n initial?: any;\n /** Inputs only: wake up the chart on every update (default) or only on changes */\n trigger?: InputTrigger;\n /** Inputs only: which updates are used, depending on their ack flag, default \"any\" */\n ack?: AckFilter;\n /** Inputs only: wake up the chart only after the input had no update for this time */\n debounceMs?: number;\n}\n\nexport interface ChartState {\n /** Unique and stable ID inside the chart */\n id: string;\n /** Display name, also used for the \"activeState\" state */\n name: string;\n /** ID of the parent state, null/undefined for top level states */\n parent?: string | null;\n /** ID of the initial child state (only for states with children) */\n initial?: string;\n /** Action executed when the state is entered */\n entry?: string;\n /** Action executed on every wakeup while the state is active and no transition is taken */\n during?: string;\n /** Action executed when the state is left */\n exit?: string;\n /** Free text for the documentation, no influence on the execution */\n comment?: string;\n /** Position in the editor, relative to the parent state */\n x: number;\n /** Position in the editor, relative to the parent state */\n y: number;\n /** Size in the editor */\n width?: number;\n /** Size in the editor */\n height?: number;\n}\n\nexport interface ChartTransition {\n /** Unique and stable ID inside the chart */\n id: string;\n /** ID of the source state */\n source: string;\n /** ID of the target state */\n target: string;\n /** Transition label in Stateflow syntax: event[condition]{action} */\n label?: string;\n /** Evaluation order of transitions with the same source, lower is first */\n priority?: number;\n /**\n * Only for transitions from a state to one of its own children: leave and enter the source state again.\n * Default is an inner transition, which keeps the source state active.\n */\n reenterParent?: boolean;\n /** Free text for the documentation, no influence on the execution */\n comment?: string;\n /** Side of the source state where the arrow starts (editor only) */\n sourceHandle?: string;\n /** Side of the target state where the arrow ends (editor only) */\n targetHandle?: string;\n /** Where the arrow starts on the border of the source state, automatic if missing (editor only) */\n sourceAnchor?: EdgeAnchor;\n /** Where the arrow ends on the border of the target state, automatic if missing (editor only) */\n targetAnchor?: EdgeAnchor;\n}\n\n/** A point on the border of a state, set by dragging an end of a transition in the editor */\nexport interface EdgeAnchor {\n side: \"top\" | \"right\" | \"bottom\" | \"left\";\n /** Position along the side: 0 = left/top end, 1 = right/bottom end */\n pos: number;\n}\n\n/**\n * A block with JavaScript code, executed once when the chart starts.\n * The functions declared in it can be used in all conditions and actions of the chart.\n */\nexport interface ChartFunction {\n /** Unique and stable ID inside the chart */\n id: string;\n /** JavaScript, usually one or more function declarations */\n code: string;\n /** Free text for the documentation, no influence on the execution */\n comment?: string;\n /** Position in the editor */\n x: number;\n /** Position in the editor */\n y: number;\n /** Size in the editor */\n width?: number;\n /** Size in the editor */\n height?: number;\n}\n\n/**\n * A note on the canvas of the editor, like an annotation in Stateflow. No influence on the execution.\n */\nexport interface ChartNote {\n /** Unique and stable ID inside the chart */\n id: string;\n text: string;\n /** ID of the state the note is placed in, it moves together with it */\n parent?: string | null;\n /** Position in the editor, relative to the parent state */\n x: number;\n /** Position in the editor, relative to the parent state */\n y: number;\n /** Size in the editor */\n width?: number;\n /** Size in the editor */\n height?: number;\n}\n\nexport interface Chart {\n /** Model version, see CHART_MODEL_VERSION */\n version: number;\n /** Display name */\n name: string;\n /** If the chart is executed by the adapter */\n enabled: boolean;\n /** Continue with the state from before a restart of the adapter, default true */\n restoreState?: boolean;\n /**\n * Super step semantics: after a transition, the chart is checked again right away, until no transition is valid\n * anymore (at most MAX_SUPER_STEPS transitions per wakeup). Default false: one transition per wakeup.\n */\n superStep?: boolean;\n /** ID of the initial top level state (default transition) */\n initial?: string;\n symbols: ChartSymbol[];\n states: ChartState[];\n transitions: ChartTransition[];\n /** Missing in charts created before function blocks existed */\n functions?: ChartFunction[];\n /** Missing in charts created before notes existed */\n notes?: ChartNote[];\n /** Free text for the documentation, no influence on the execution */\n comment?: string;\n}\n\nexport interface TransitionLabel {\n /** Name of the triggering event (an input symbol), undefined = any wakeup */\n event?: string;\n /** Delay of a temporal transition after(n, unit) in milliseconds */\n afterMs?: number;\n /** Guard expression */\n condition?: string;\n /** Transition action */\n action?: string;\n}\n\nconst TIME_UNITS: Record<string, number> = {\n msec: 1,\n sec: 1000,\n min: 60_000,\n};\n\n/**\n * Creates a new, empty chart. It is paused, the user starts it when it is ready.\n *\n * @param name Display name\n */\nexport function createChart(name: string): Chart {\n return {\n version: CHART_MODEL_VERSION,\n name,\n enabled: false,\n symbols: [],\n states: [],\n transitions: [],\n functions: [],\n notes: [],\n };\n}\n\n/**\n * Converts a display name to an ID which can be used in ioBroker object IDs\n *\n * @param name Display name\n */\nexport function nameToId(name: string): string {\n return (\n name\n .trim()\n .toLowerCase()\n .replace(/\u00E4/g, \"ae\")\n .replace(/\u00F6/g, \"oe\")\n .replace(/\u00FC/g, \"ue\")\n .replace(/\u00DF/g, \"ss\")\n .replace(/[^a-z0-9_-]+/g, \"_\")\n .replace(/^_+|_+$/g, \"\") || \"chart\"\n );\n}\n\nexport interface TextRange {\n /** Index of the first character */\n from: number;\n /** Index after the last character */\n to: number;\n}\n\n/** Positions of the parts in the label text */\nexport interface TransitionLabelRanges {\n event?: TextRange;\n /** The whole after(...) expression */\n after?: TextRange;\n /** Content of [...] without the brackets */\n condition?: TextRange;\n /** Content of {...} without the brackets */\n action?: TextRange;\n}\n\n/**\n * Fills the %s placeholders of a message\n *\n * @param key Message with %s placeholders\n * @param args Values for the placeholders\n */\nexport function formatMessage(key: string, args: string[]): string {\n let i = 0;\n return key.replace(/%s/g, () => args[i++] ?? \"\");\n}\n\n/**\n * Error in the structure of a transition label, knows where in the label the problem is\n */\nexport class LabelSyntaxError extends Error {\n /**\n * @param key Message with %s placeholders, used to translate the message\n * @param args Values for the placeholders\n * @param from Start of the problem in the label\n * @param to End of the problem in the label\n */\n constructor(\n public readonly key: string,\n public readonly args: string[],\n public readonly from: number,\n public readonly to: number,\n ) {\n super(formatMessage(key, args));\n }\n}\n\n/**\n * Reads a part enclosed in brackets, nested brackets of the same type are allowed\n *\n * @param text The label\n * @param start Index of the opening bracket\n * @param open Opening bracket\n * @param close Closing bracket\n * @returns from is the index of the (trimmed) content, end is the index after the closing bracket\n */\nfunction readEnclosed(\n text: string,\n start: number,\n open: string,\n close: string,\n): { content: string; from: number; end: number } {\n let depth = 0;\n for (let i = start; i < text.length; i++) {\n if (text[i] === open) {\n depth++;\n } else if (text[i] === close) {\n depth--;\n if (depth === 0) {\n const raw = text.substring(start + 1, i);\n const content = raw.trim();\n return { content, from: start + 1 + raw.indexOf(content), end: i + 1 };\n }\n }\n }\n throw new LabelSyntaxError('Missing \"%s\"', [close], start, text.length);\n}\n\n/**\n * Parses a transition label and returns where its parts are, see parseTransitionLabel\n *\n * @param label The label text\n * @throws {LabelSyntaxError}\n */\nexport function parseTransitionLabelWithRanges(label: string | undefined): {\n label: TransitionLabel;\n ranges: TransitionLabelRanges;\n} {\n const result: TransitionLabel = {};\n const ranges: TransitionLabelRanges = {};\n const text = label || \"\";\n let pos = 0;\n\n const skipSpace = (): void => {\n while (pos < text.length && /\\s/.test(text[pos])) {\n pos++;\n }\n };\n\n skipSpace();\n const eventMatch = /[A-Za-z_$][\\w$]*/y;\n eventMatch.lastIndex = pos;\n const event = eventMatch.exec(text);\n if (event) {\n const from = pos;\n pos += event[0].length;\n skipSpace();\n if (event[0] === \"after\" && text[pos] === \"(\") {\n const { content, end } = readEnclosed(text, pos, \"(\", \")\");\n const afterMatch = /^(\\d+(?:\\.\\d+)?)\\s*,\\s*(msec|sec|min)$/.exec(content);\n if (!afterMatch) {\n throw new LabelSyntaxError(\n 'Invalid temporal expression \"%s\", expected e.g. after(5, sec)',\n [`after(${content})`],\n from,\n end,\n );\n }\n result.afterMs = parseFloat(afterMatch[1]) * TIME_UNITS[afterMatch[2]];\n ranges.after = { from, to: end };\n pos = end;\n } else {\n result.event = event[0];\n ranges.event = { from, to: from + event[0].length };\n }\n }\n\n skipSpace();\n if (text[pos] === \"[\") {\n const { content, from, end } = readEnclosed(text, pos, \"[\", \"]\");\n result.condition = content;\n ranges.condition = { from, to: from + content.length };\n pos = end;\n }\n\n skipSpace();\n if (text[pos] === \"{\") {\n const { content, from, end } = readEnclosed(text, pos, \"{\", \"}\");\n result.action = content;\n ranges.action = { from, to: from + content.length };\n pos = end;\n }\n\n skipSpace();\n if (pos < text.length) {\n throw new LabelSyntaxError(\n 'Unexpected \"%s\", expected event[condition]{action}',\n [text.substring(pos).trim()],\n pos,\n text.length,\n );\n }\n return { label: result, ranges };\n}\n\n/**\n * Parses a transition label in Stateflow syntax: event[condition]{action}\n * All parts are optional. Instead of an event, after(n, sec|msec|min) creates a temporal transition.\n *\n * @param label The label text\n * @throws {LabelSyntaxError}\n */\nexport function parseTransitionLabel(label: string | undefined): TransitionLabel {\n return parseTransitionLabelWithRanges(label).label;\n}\n\n/** Identifies files with exported charts */\nexport const EXPORT_FORMAT = \"iobroker.statechart\";\n\n/** Files exported before the adapter was renamed from \"state-machine\" to \"statechart\" */\nconst LEGACY_EXPORT_FORMATS = [\"iobroker.state-machine\"];\n\n/** The content of an export file */\nexport interface ChartExport {\n format: string;\n version: number;\n exported: string;\n charts: Chart[];\n}\n\n/**\n * The content of an export file\n *\n * @param charts The exported charts\n */\nexport function createExport(charts: Chart[]): ChartExport {\n return { format: EXPORT_FORMAT, version: CHART_MODEL_VERSION, exported: new Date().toISOString(), charts };\n}\n\nconst IDENTIFIER = /^[A-Za-z_$][\\w$]*$/;\nconst SCOPES = [\"input\", \"output\", \"local\"];\n\nfunction isObject(value: any): value is Record<string, any> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Checks a chart of an export file and fills in defaults for missing optional values\n *\n * @param data The chart as read from the file\n * @param where Prefix of error messages, e.g. \"Chart 1\"\n * @throws {Error} if the chart is invalid\n */\nfunction normalizeChart(data: any, where: string): Chart {\n const fail = (message: string): never => {\n throw new Error(`${where}: ${message}`);\n };\n if (!isObject(data)) {\n fail(\"not an object\");\n }\n if (typeof data.version === \"number\" && data.version > CHART_MODEL_VERSION) {\n fail(`created with a newer version of the adapter (chart version ${data.version})`);\n }\n for (const list of [\"states\", \"transitions\", \"symbols\"]) {\n if (!Array.isArray(data[list])) {\n fail(`\"${list}\" is missing or no list`);\n }\n }\n for (const list of [\"functions\", \"notes\"]) {\n if (data[list] !== undefined && !Array.isArray(data[list])) {\n fail(`\"${list}\" is no list`);\n }\n }\n const functions: any[] = data.functions || [];\n const notes: any[] = data.notes || [];\n\n // states, function blocks and notes are all nodes in the editor, so their IDs must be unique together\n const nodeIds = new Set<string>();\n const checkId = (item: any, kind: string, index: number): string => {\n if (!isObject(item) || typeof item.id !== \"string\" || !item.id) {\n fail(`${kind} ${index + 1} has no ID`);\n }\n if (nodeIds.has(item.id)) {\n fail(`${kind} ${item.id}: the ID is used more than once`);\n }\n nodeIds.add(item.id);\n return item.id;\n };\n const optionalString = (value: any, message: string): void => {\n if (value !== undefined && value !== null && typeof value !== \"string\") {\n fail(message);\n }\n };\n\n data.states.forEach((state: any, i: number) => checkId(state, \"state\", i));\n functions.forEach((fn, i) => checkId(fn, \"function block\", i));\n notes.forEach((note, i) => checkId(note, \"note\", i));\n const stateIds = new Set(data.states.map((s: any) => s.id));\n optionalString(data.comment, '\"comment\" is no text');\n\n const states: ChartState[] = data.states.map((state: any) => {\n const at = `state ${state.id}`;\n if (state.parent && !stateIds.has(state.parent)) {\n fail(`${at}: unknown parent state \"${state.parent}\"`);\n }\n for (const field of [\"entry\", \"during\", \"exit\", \"initial\", \"comment\"]) {\n optionalString(state[field], `${at}: \"${field}\" is no text`);\n }\n return {\n ...state,\n name: typeof state.name === \"string\" && state.name ? state.name : state.id,\n parent: state.parent || null,\n x: Number.isFinite(state.x) ? state.x : 0,\n y: Number.isFinite(state.y) ? state.y : 0,\n };\n });\n\n // a parent must not be its own (indirect) child\n const parentOf = new Map(states.map(s => [s.id, s.parent]));\n for (const state of states) {\n let parent = state.parent;\n for (let i = 0; parent; i++) {\n if (parent === state.id || i > states.length) {\n fail(`state ${state.id}: the parent states form a cycle`);\n }\n parent = parentOf.get(parent) ?? null;\n }\n }\n\n const transitionIds = new Set<string>();\n const transitions: ChartTransition[] = data.transitions.map((transition: any, i: number) => {\n if (!isObject(transition) || typeof transition.id !== \"string\" || !transition.id) {\n fail(`transition ${i + 1} has no ID`);\n }\n const at = `transition ${transition.id}`;\n if (transitionIds.has(transition.id)) {\n fail(`${at}: the ID is used more than once`);\n }\n transitionIds.add(transition.id);\n for (const end of [\"source\", \"target\"]) {\n if (!stateIds.has(transition[end])) {\n fail(`${at}: unknown ${end} state \"${transition[end]}\"`);\n }\n }\n optionalString(transition.label, `${at}: \"label\" is no text`);\n optionalString(transition.comment, `${at}: \"comment\" is no text`);\n if (transition.priority !== undefined && !Number.isFinite(transition.priority)) {\n fail(`${at}: \"priority\" is no number`);\n }\n return { ...transition };\n });\n\n const symbolNames = new Set<string>();\n const symbols: ChartSymbol[] = data.symbols.map((symbol: any, i: number) => {\n if (!isObject(symbol) || typeof symbol.name !== \"string\" || !IDENTIFIER.test(symbol.name)) {\n fail(`variable ${i + 1}: invalid name`);\n }\n if (symbolNames.has(symbol.name)) {\n fail(`variable ${symbol.name}: the name is used more than once`);\n }\n symbolNames.add(symbol.name);\n if (!SCOPES.includes(symbol.scope)) {\n fail(`variable ${symbol.name}: invalid kind \"${symbol.scope}\"`);\n }\n optionalString(symbol.stateId, `variable ${symbol.name}: \"stateId\" is no text`);\n if (symbol.trigger !== undefined && ![\"update\", \"change\"].includes(symbol.trigger)) {\n fail(`variable ${symbol.name}: invalid trigger \"${symbol.trigger}\"`);\n }\n if (symbol.ack !== undefined && ![\"any\", \"ack\", \"command\"].includes(symbol.ack)) {\n fail(`variable ${symbol.name}: invalid ack filter \"${symbol.ack}\"`);\n }\n if (symbol.debounceMs !== undefined && !(Number.isFinite(symbol.debounceMs) && symbol.debounceMs >= 0)) {\n fail(`variable ${symbol.name}: \"debounceMs\" is no number of 0 or more`);\n }\n return { ...symbol };\n });\n\n const normalizedFunctions: ChartFunction[] = functions.map(fn => {\n if (typeof fn.code !== \"string\") {\n fail(`function block ${fn.id}: \"code\" is no text`);\n }\n optionalString(fn.comment, `function block ${fn.id}: \"comment\" is no text`);\n return { ...fn, x: Number.isFinite(fn.x) ? fn.x : 0, y: Number.isFinite(fn.y) ? fn.y : 0 };\n });\n\n const normalizedNotes: ChartNote[] = notes.map(note => {\n optionalString(note.text, `note ${note.id}: \"text\" is no text`);\n if (note.parent && !stateIds.has(note.parent)) {\n fail(`note ${note.id}: unknown parent state \"${note.parent}\"`);\n }\n return {\n ...note,\n text: note.text || \"\",\n parent: note.parent || null,\n x: Number.isFinite(note.x) ? note.x : 0,\n y: Number.isFinite(note.y) ? note.y : 0,\n };\n });\n\n const chart: Chart = {\n ...data,\n version: CHART_MODEL_VERSION,\n name: typeof data.name === \"string\" && data.name.trim() ? data.name.trim() : where,\n initial: typeof data.initial === \"string\" && stateIds.has(data.initial) ? data.initial : undefined,\n enabled: data.enabled !== false,\n symbols,\n states,\n transitions,\n functions: normalizedFunctions,\n notes: normalizedNotes,\n };\n // the default (off) is not stored, like in the editor\n if (chart.superStep !== true) {\n delete chart.superStep;\n }\n return chart;\n}\n\n/**\n * Reads the charts of an export file. A single chart (without the export wrapper) is accepted as well.\n *\n * @param text Content of the file\n * @throws {Error} if the file is invalid\n */\nexport function parseExport(text: string): Chart[] {\n let data;\n try {\n data = JSON.parse(text);\n } catch (err) {\n throw new Error(`No valid JSON: ${err.message}`);\n }\n if (isObject(data) && (data.format === EXPORT_FORMAT || LEGACY_EXPORT_FORMATS.includes(data.format))) {\n if (typeof data.version === \"number\" && data.version > CHART_MODEL_VERSION) {\n throw new Error(`The file was created with a newer version of the adapter (version ${data.version})`);\n }\n if (!Array.isArray(data.charts) || !data.charts.length) {\n throw new Error(\"The file contains no charts\");\n }\n return data.charts.map((chart: any, i: number) => normalizeChart(chart, `Chart ${i + 1}`));\n }\n if (isObject(data) && Array.isArray(data.states)) {\n return [normalizeChart(data, \"Chart\")];\n }\n throw new Error(\"The file contains no charts of the statechart adapter\");\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }