@statewalker/fsm-charts 0.0.5 → 0.1.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.
@@ -40,6 +40,15 @@ type Position = {
40
40
  y: number;
41
41
  };
42
42
 
43
+ /**
44
+ * Information about a state node in the graph.
45
+ */
46
+ type StateGraphNode = Dimensions & Position & {
47
+ id: string;
48
+ key: string;
49
+ state: string;
50
+ } & Record<string, any>;
51
+
43
52
  /**
44
53
  * Information about a state graph edge.
45
54
  */
@@ -51,15 +60,6 @@ type StateGraphEdge = Dimensions & Position & {
51
60
  points: Position[];
52
61
  } & Record<string, any>;
53
62
 
54
- /**
55
- * Information about a state node in the graph.
56
- */
57
- type StateGraphNode = Dimensions & Position & {
58
- id: string;
59
- key: string;
60
- state: string;
61
- } & Record<string, any>;
62
-
63
63
  /**
64
64
  * Coordinates for state nodes and endges corresponding to state transitions.
65
65
  */
@@ -68,9 +68,7 @@ type TransitionsGraph = Position & Dimensions & {
68
68
  edges: StateGraphEdge[];
69
69
  };
70
70
 
71
- type StateChart = TransitionsGraph & {
72
- id: string;
73
- key: string;
71
+ type StateChart = TransitionsGraph & StateGraphNode & {
74
72
  children?: StateChart[];
75
73
  } & Record<string, any>;
76
74
 
@@ -0,0 +1,8 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => {
4
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
+ return value;
6
+ };
7
+
8
+ export { __publicField };
@@ -0,0 +1,150 @@
1
+ import { __publicField } from './chunk-XEO3YXBM.js';
2
+
3
+ // src/runtime/StateChartIndex.ts
4
+ var StateChartIndex = class {
5
+ constructor({ statechart }) {
6
+ __publicField(this, "statechart");
7
+ __publicField(this, "_chartsIndex", {});
8
+ __publicField(this, "_nodesIndex", {});
9
+ __publicField(this, "_nodesParentsIndex", {});
10
+ __publicField(this, "_edgeIndex", {});
11
+ __publicField(this, "_edgesParentsIndex", {});
12
+ this.statechart = statechart;
13
+ this._buildIndexes();
14
+ }
15
+ /**
16
+ * Transforms a stack of state keys to the corresponding identifiers.
17
+ * If a key in the stack was not found then this method returns
18
+ * an empty stack.
19
+ * @param stack a stack of state keys
20
+ * @returns a stack of state identifiers for the given states
21
+ */
22
+ getStatesIds(...stack) {
23
+ let result = [];
24
+ let list = [this.statechart];
25
+ for (let i = 0; list?.length > 0 && i < stack.length; i++) {
26
+ const key = stack[i];
27
+ const node = list.find((node2) => node2.key === key);
28
+ if (!node)
29
+ break;
30
+ result.push(node.id);
31
+ list = node.children;
32
+ if (!list?.length)
33
+ list = node.nodes;
34
+ }
35
+ return result.length === stack.length ? result : [];
36
+ }
37
+ /**
38
+ * Returns graph nodes for the specified identifier.
39
+ * @param id the id of a node
40
+ * @returns a stack of nodes
41
+ */
42
+ getStackByStateId(id) {
43
+ if (!id)
44
+ return [];
45
+ const node = this._chartsIndex[id] || this._nodesIndex[id];
46
+ if (!node)
47
+ return [];
48
+ const parentId = this._nodesParentsIndex[id];
49
+ if (parentId) {
50
+ const parentStack = this.getStackByStateId(parentId);
51
+ if (!parentStack.length)
52
+ return [];
53
+ parentStack.push(node);
54
+ return parentStack;
55
+ } else {
56
+ return [node];
57
+ }
58
+ }
59
+ /**
60
+ * Returns an edge object corresponding to the transition from the state
61
+ * @param stateId identifier of the source state
62
+ * @param event an event triggering the transition
63
+ * @returns graph edge
64
+ */
65
+ getTransition(stateId, event) {
66
+ const stack = this.getStackByStateId(stateId);
67
+ const state = stack.pop();
68
+ if (!state || !stack.length)
69
+ return;
70
+ const parent = stack[stack.length - 1];
71
+ const t = parent.edges.find(
72
+ (t2) => t2.from === state.key && t2.event === event
73
+ );
74
+ return t;
75
+ }
76
+ /**
77
+ * Returns a graph node corresponding to the specified state id.
78
+ * @param stateId identifier of the state
79
+ * @returns graph node
80
+ * @see getStateChart
81
+ */
82
+ getStateNode(stateId) {
83
+ return stateId ? this._nodesIndex[stateId] : void 0;
84
+ }
85
+ /**
86
+ * Returns a chart corresponding to the specified state id.
87
+ * @param stateId identifier of the state
88
+ * @returns graph node
89
+ * @see getStateNode
90
+ */
91
+ getStateChart(stateId) {
92
+ return stateId ? this._chartsIndex[stateId] : void 0;
93
+ }
94
+ /**
95
+ * Returns ids of the previous and next state for the specified transition
96
+ * @param transition a graph edge instance defining transition
97
+ * @returns an array with two identifiers - [sourceStateId, targetStateId] - the source state id and target state id
98
+ */
99
+ getTransitionStateIds(transition) {
100
+ const result = [
101
+ void 0,
102
+ void 0
103
+ ];
104
+ if (!transition)
105
+ return result;
106
+ const parentId = this._edgesParentsIndex[transition.id];
107
+ if (!parentId)
108
+ return result;
109
+ const parent = this._chartsIndex[parentId];
110
+ if (!parent)
111
+ return result;
112
+ parent.nodes.forEach((node) => {
113
+ if (node.key === transition.from) {
114
+ result[0] = node.id;
115
+ }
116
+ if (node.key === transition.to) {
117
+ result[1] = node.id;
118
+ }
119
+ });
120
+ return result;
121
+ }
122
+ // ----------------------------------------------------------
123
+ // Internal methods
124
+ _buildIndexes() {
125
+ const addToIndex = (chart) => {
126
+ const chartId = chart.id;
127
+ this._chartsIndex[chartId] = chart;
128
+ if (!(chartId in this._nodesIndex)) {
129
+ this._nodesIndex[chartId] = chart;
130
+ }
131
+ chart.nodes.forEach((node) => {
132
+ const nodeId = node.id;
133
+ this._nodesIndex[nodeId] = node;
134
+ this._nodesParentsIndex[nodeId] = chartId;
135
+ });
136
+ chart.edges.forEach((edge) => {
137
+ const edgeId = edge.id;
138
+ this._edgeIndex[edgeId] = edge;
139
+ this._edgesParentsIndex[edgeId] = chartId;
140
+ });
141
+ (chart.children || []).forEach((child) => {
142
+ this._nodesParentsIndex[child.id] = chartId;
143
+ addToIndex(child);
144
+ });
145
+ };
146
+ addToIndex(this.statechart);
147
+ }
148
+ };
149
+
150
+ export { StateChartIndex };
@@ -1,4 +1,5 @@
1
1
  import { getPadding } from './chunk-NXWOFQMO.js';
2
+ import { __publicField } from './chunk-XEO3YXBM.js';
2
3
 
3
4
  // src/utils/toKebabCase.ts
4
5
  function toKebabCase2(str) {
@@ -46,7 +47,7 @@ function serializeCss(obj) {
46
47
  }
47
48
  }
48
49
 
49
- // src/svg/buildStatechartStyles.ts
50
+ // src/html/buildStatechartStyles.ts
50
51
  function buildStateDetailsStyle() {
51
52
  return {
52
53
  ".state-details": {
@@ -213,7 +214,7 @@ function buildStatechartStyles({
213
214
  };
214
215
  }
215
216
 
216
- // src/svg/buildStatechartCss.ts
217
+ // src/html/buildStatechartCss.ts
217
218
  function buildStatechartCss({ prefix = "" } = {}) {
218
219
  const cssObject = buildStatechartStyles({ root: prefix || ":root" });
219
220
  return serializeCss(cssObject);
@@ -242,14 +243,14 @@ function serializeAttrs(attrs = {}, {
242
243
 
243
244
  // src/utils/BasisCurve.ts
244
245
  var BasisCurve = class {
245
- _context;
246
- _x0 = 0;
247
- _y0 = 0;
248
- _x1 = 0;
249
- _y1 = 0;
250
- _point = 0;
251
- _line = 0;
252
246
  constructor(context) {
247
+ __publicField(this, "_context");
248
+ __publicField(this, "_x0", 0);
249
+ __publicField(this, "_y0", 0);
250
+ __publicField(this, "_x1", 0);
251
+ __publicField(this, "_y1", 0);
252
+ __publicField(this, "_point", 0);
253
+ __publicField(this, "_line", 0);
253
254
  this._context = context;
254
255
  }
255
256
  $point(x, y) {
@@ -309,7 +310,7 @@ var BasisCurve = class {
309
310
  }
310
311
  };
311
312
 
312
- // src/svg/buildStatechartSvg.ts
313
+ // src/html/buildStatechartSvg.ts
313
314
  function getBoxParams({
314
315
  x,
315
316
  y,
@@ -499,7 +500,7 @@ function buildStatechartSvg({
499
500
  println("</svg>");
500
501
  }
501
502
 
502
- // src/svg/buildStatechartsPanel.ts
503
+ // src/html/buildStatechartsPanel.ts
503
504
  function buildStatechartsPanel({
504
505
  statechart,
505
506
  newId,
@@ -2589,6 +2589,7 @@ function buildCharts({
2589
2589
  return {
2590
2590
  id,
2591
2591
  key: config2.key,
2592
+ state: config2.key,
2592
2593
  ...graph,
2593
2594
  children
2594
2595
  };
@@ -1,4 +1,4 @@
1
- import { S as StateChart, d as TransitionsGraph } from './StateChart-pFSQIvtE.js';
1
+ import { S as StateChart, d as TransitionsGraph } from './StateChart-PdtJDEPy.js';
2
2
 
3
3
  declare function buildStatechartCss({ prefix }?: {
4
4
  prefix?: string | undefined;
@@ -1,2 +1,2 @@
1
- export { D as Dimensions, F as FsmStateConfig, G as GraphParamsProvider, P as Padding, a as Position, S as StateChart, b as StateGraphEdge, c as StateGraphNode, T as Transition, d as TransitionsGraph } from './StateChart-pFSQIvtE.js';
2
- export { b as buildStatechartCss, c as buildStatechartStyles, d as buildStatechartSvg, a as buildStatechartsPanel } from './index-svg-DCwEyX8X.js';
1
+ export { D as Dimensions, F as FsmStateConfig, G as GraphParamsProvider, P as Padding, a as Position, S as StateChart, b as StateGraphEdge, c as StateGraphNode, T as Transition, d as TransitionsGraph } from './StateChart-PdtJDEPy.js';
2
+ export { b as buildStatechartCss, c as buildStatechartStyles, d as buildStatechartSvg, a as buildStatechartsPanel } from './index-html-CbDZzk2n.js';
@@ -1,2 +1,3 @@
1
- export { buildStatechartCss, buildStatechartStyles, buildStatechartSvg, buildStatechartsPanel } from './chunk-3PNSXN5U.js';
1
+ export { buildStatechartCss, buildStatechartStyles, buildStatechartSvg, buildStatechartsPanel } from './chunk-YYNW6Q2T.js';
2
2
  import './chunk-NXWOFQMO.js';
3
+ import './chunk-XEO3YXBM.js';
@@ -1,5 +1,5 @@
1
- import { T as Transition, P as Padding, G as GraphParamsProvider, d as TransitionsGraph, F as FsmStateConfig, S as StateChart } from './StateChart-pFSQIvtE.js';
2
- export { D as Dimensions, a as Position, b as StateGraphEdge, c as StateGraphNode } from './StateChart-pFSQIvtE.js';
1
+ import { T as Transition, P as Padding, G as GraphParamsProvider, d as TransitionsGraph, F as FsmStateConfig, S as StateChart } from './StateChart-PdtJDEPy.js';
2
+ export { D as Dimensions, a as Position, b as StateGraphEdge, c as StateGraphNode } from './StateChart-PdtJDEPy.js';
3
3
 
4
4
  /**
5
5
  * Build graphs corresponding to the specified transitions.
@@ -1,2 +1,3 @@
1
- export { buildCharts, buildFlatCharts, getGraphParamsProvider, getLabelDimensions } from './chunk-IT7GBMYV.js';
1
+ export { buildCharts, buildFlatCharts, getGraphParamsProvider, getLabelDimensions } from './chunk-ZSGS37QH.js';
2
2
  import './chunk-NXWOFQMO.js';
3
+ import './chunk-XEO3YXBM.js';
@@ -1,5 +1,58 @@
1
- export { D as Dimensions, F as FsmStateConfig, G as GraphParamsProvider, P as Padding, a as Position, S as StateChart, b as StateGraphEdge, c as StateGraphNode, T as Transition, d as TransitionsGraph } from './StateChart-pFSQIvtE.js';
1
+ import { S as StateChart, c as StateGraphNode, b as StateGraphEdge } from './StateChart-PdtJDEPy.js';
2
+ export { D as Dimensions, F as FsmStateConfig, G as GraphParamsProvider, P as Padding, a as Position, T as Transition, d as TransitionsGraph } from './StateChart-PdtJDEPy.js';
2
3
 
3
- declare const a = "a";
4
+ declare class StateChartIndex {
5
+ statechart: StateChart;
6
+ _chartsIndex: Record<string, StateChart>;
7
+ _nodesIndex: Record<string, StateGraphNode>;
8
+ _nodesParentsIndex: Record<string, string>;
9
+ _edgeIndex: Record<string, StateGraphEdge>;
10
+ _edgesParentsIndex: Record<string, string>;
11
+ constructor({ statechart }: {
12
+ statechart: StateChart;
13
+ });
14
+ /**
15
+ * Transforms a stack of state keys to the corresponding identifiers.
16
+ * If a key in the stack was not found then this method returns
17
+ * an empty stack.
18
+ * @param stack a stack of state keys
19
+ * @returns a stack of state identifiers for the given states
20
+ */
21
+ getStatesIds(...stack: string[]): string[];
22
+ /**
23
+ * Returns graph nodes for the specified identifier.
24
+ * @param id the id of a node
25
+ * @returns a stack of nodes
26
+ */
27
+ getStackByStateId(id?: string): StateGraphNode[];
28
+ /**
29
+ * Returns an edge object corresponding to the transition from the state
30
+ * @param stateId identifier of the source state
31
+ * @param event an event triggering the transition
32
+ * @returns graph edge
33
+ */
34
+ getTransition(stateId?: string, event?: string): StateGraphEdge | undefined;
35
+ /**
36
+ * Returns a graph node corresponding to the specified state id.
37
+ * @param stateId identifier of the state
38
+ * @returns graph node
39
+ * @see getStateChart
40
+ */
41
+ getStateNode(stateId?: string): StateGraphNode | undefined;
42
+ /**
43
+ * Returns a chart corresponding to the specified state id.
44
+ * @param stateId identifier of the state
45
+ * @returns graph node
46
+ * @see getStateNode
47
+ */
48
+ getStateChart(stateId?: string): StateChart | undefined;
49
+ /**
50
+ * Returns ids of the previous and next state for the specified transition
51
+ * @param transition a graph edge instance defining transition
52
+ * @returns an array with two identifiers - [sourceStateId, targetStateId] - the source state id and target state id
53
+ */
54
+ getTransitionStateIds(transition?: StateGraphEdge): [string | undefined, string | undefined];
55
+ _buildIndexes(): void;
56
+ }
4
57
 
5
- export { a };
58
+ export { StateChart, StateChartIndex, StateGraphEdge, StateGraphNode };
@@ -1 +1,2 @@
1
- export { a } from './chunk-X2UPWZLX.js';
1
+ export { StateChartIndex } from './chunk-XPUWN37Q.js';
2
+ import './chunk-XEO3YXBM.js';
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- export { D as Dimensions, F as FsmStateConfig, G as GraphParamsProvider, P as Padding, a as Position, S as StateChart, b as StateGraphEdge, c as StateGraphNode, T as Transition, d as TransitionsGraph } from './StateChart-pFSQIvtE.js';
1
+ export { D as Dimensions, F as FsmStateConfig, G as GraphParamsProvider, P as Padding, a as Position, S as StateChart, b as StateGraphEdge, c as StateGraphNode, T as Transition, d as TransitionsGraph } from './StateChart-PdtJDEPy.js';
2
2
  export { buildCharts, buildFlatCharts, getGraphParamsProvider, getLabelDimensions } from './index-layout.js';
3
- export { C as CssTree, b as buildStatechartCss, c as buildStatechartStyles, d as buildStatechartSvg, a as buildStatechartsPanel, s as serializeCss } from './index-svg-DCwEyX8X.js';
4
- export { a } from './index-runtime.js';
3
+ export { C as CssTree, b as buildStatechartCss, c as buildStatechartStyles, d as buildStatechartSvg, a as buildStatechartsPanel, s as serializeCss } from './index-html-CbDZzk2n.js';
4
+ export { StateChartIndex } from './index-runtime.js';
5
5
 
6
6
  declare function toKebabCase(str: string): string;
7
7
 
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
- export { buildCharts, buildFlatCharts, getGraphParamsProvider, getLabelDimensions } from './chunk-IT7GBMYV.js';
2
- export { buildStatechartCss, buildStatechartStyles, buildStatechartSvg, buildStatechartsPanel, serializeCss, toKebabCase } from './chunk-3PNSXN5U.js';
1
+ export { buildCharts, buildFlatCharts, getGraphParamsProvider, getLabelDimensions } from './chunk-ZSGS37QH.js';
2
+ export { buildStatechartCss, buildStatechartStyles, buildStatechartSvg, buildStatechartsPanel, serializeCss, toKebabCase } from './chunk-YYNW6Q2T.js';
3
3
  import './chunk-NXWOFQMO.js';
4
- export { a } from './chunk-X2UPWZLX.js';
4
+ export { StateChartIndex } from './chunk-XPUWN37Q.js';
5
+ import './chunk-XEO3YXBM.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statewalker/fsm-charts",
3
- "version": "0.0.5",
3
+ "version": "0.1.0",
4
4
  "description": "HFSM Implementation",
5
5
  "keywords": [],
6
6
  "homepage": "https://github.com/statewalker/statewalker-fsm-charts",
@@ -26,6 +26,7 @@
26
26
  },
27
27
  "devDependencies": {
28
28
  "@statewalker/typescript-config": "*",
29
+ "@types/jsdom": "^21.1.7",
29
30
  "@types/lodash-es": "^4.17.12",
30
31
  "@typescript-eslint/eslint-plugin": "^6.4.0",
31
32
  "eslint": "^8.0.1",
@@ -33,6 +34,7 @@
33
34
  "eslint-plugin-import": "^2.25.2",
34
35
  "eslint-plugin-n": "^15.0.0 || ^16.0.0 ",
35
36
  "eslint-plugin-promise": "^6.0.0",
37
+ "jsdom": "^24.1.0",
36
38
  "lodash": "^4.17.21",
37
39
  "lodash-es": "^4.17.21",
38
40
  "tsup": "^8.0.2",
@@ -1,4 +1,4 @@
1
- import { CssTree } from "../utils/serializeCss";
1
+ import type { CssTree } from "../utils/serializeCss";
2
2
 
3
3
  function buildStateDetailsStyle() {
4
4
  return {
@@ -1,2 +1,2 @@
1
1
  export * from "./types/index.ts";
2
- export * from "./svg/index.ts";
2
+ export * from "./html/index.ts";
package/src/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export * from "./types/index.ts";
2
2
  export * from "./layout/index.ts";
3
- export * from "./svg/index.ts";
3
+ export * from "./html/index.ts";
4
4
  export * from "./runtime/index.ts";
5
5
  export * from "./utils/toKebabCase.ts";
6
6
  export * from "./utils/serializeCss.ts";
@@ -33,7 +33,10 @@ export function buildCharts({
33
33
  } & GraphParamsProvider): StateChart {
34
34
  return buildChart(config);
35
35
 
36
- function buildChart(config: FsmStateConfig, id: string = newId("s")) {
36
+ function buildChart(
37
+ config: FsmStateConfig,
38
+ id: string = newId("s")
39
+ ): StateChart {
37
40
  const graph = buildFlatCharts({
38
41
  lodash,
39
42
  transitions: config.transitions,
@@ -59,6 +62,7 @@ export function buildCharts({
59
62
  return {
60
63
  id,
61
64
  key: config.key,
65
+ state: config.key,
62
66
  ...graph,
63
67
  children,
64
68
  };
@@ -0,0 +1,152 @@
1
+ import type {
2
+ StateChart,
3
+ StateGraphNode,
4
+ StateGraphEdge,
5
+ } from "../types/index.ts";
6
+
7
+ export class StateChartIndex {
8
+ statechart: StateChart;
9
+ _chartsIndex: Record<string, StateChart> = {};
10
+ _nodesIndex: Record<string, StateGraphNode> = {};
11
+ _nodesParentsIndex: Record<string, string> = {};
12
+ _edgeIndex: Record<string, StateGraphEdge> = {};
13
+ _edgesParentsIndex: Record<string, string> = {};
14
+
15
+ constructor({ statechart }: { statechart: StateChart }) {
16
+ this.statechart = statechart;
17
+ this._buildIndexes();
18
+ }
19
+
20
+ /**
21
+ * Transforms a stack of state keys to the corresponding identifiers.
22
+ * If a key in the stack was not found then this method returns
23
+ * an empty stack.
24
+ * @param stack a stack of state keys
25
+ * @returns a stack of state identifiers for the given states
26
+ */
27
+ getStatesIds(...stack: string[]): string[] {
28
+ let result = [];
29
+ let list = [this.statechart] as (StateChart | StateGraphNode)[];
30
+ for (let i = 0; list?.length > 0 && i < stack.length; i++) {
31
+ const key = stack[i];
32
+ const node = list.find((node) => node.key === key);
33
+ if (!node) break;
34
+ result.push(node.id);
35
+ list = node.children;
36
+ if (!list?.length) list = node.nodes;
37
+ }
38
+ return result.length === stack.length ? result : [];
39
+ }
40
+
41
+ /**
42
+ * Returns graph nodes for the specified identifier.
43
+ * @param id the id of a node
44
+ * @returns a stack of nodes
45
+ */
46
+ getStackByStateId(id?: string): StateGraphNode[] {
47
+ if (!id) return [];
48
+ const node = this._chartsIndex[id] || this._nodesIndex[id];
49
+ if (!node) return [];
50
+ const parentId = this._nodesParentsIndex[id];
51
+ if (parentId) {
52
+ const parentStack = this.getStackByStateId(parentId);
53
+ if (!parentStack.length) return [];
54
+ parentStack.push(node);
55
+ return parentStack;
56
+ } else {
57
+ return [node];
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Returns an edge object corresponding to the transition from the state
63
+ * @param stateId identifier of the source state
64
+ * @param event an event triggering the transition
65
+ * @returns graph edge
66
+ */
67
+ getTransition(stateId?: string, event?: string): StateGraphEdge | undefined {
68
+ const stack = this.getStackByStateId(stateId);
69
+ const state = stack.pop();
70
+ if (!state || !stack.length) return;
71
+ const parent = stack[stack.length - 1];
72
+ const t = parent.edges.find(
73
+ (t: StateGraphEdge) => t.from === state.key && t.event === event
74
+ );
75
+ return t;
76
+ }
77
+
78
+ /**
79
+ * Returns a graph node corresponding to the specified state id.
80
+ * @param stateId identifier of the state
81
+ * @returns graph node
82
+ * @see getStateChart
83
+ */
84
+ getStateNode(stateId?: string): StateGraphNode | undefined {
85
+ return stateId ? this._nodesIndex[stateId] : undefined;
86
+ }
87
+
88
+ /**
89
+ * Returns a chart corresponding to the specified state id.
90
+ * @param stateId identifier of the state
91
+ * @returns graph node
92
+ * @see getStateNode
93
+ */
94
+ getStateChart(stateId?: string): StateChart | undefined {
95
+ return stateId ? this._chartsIndex[stateId] : undefined;
96
+ }
97
+
98
+ /**
99
+ * Returns ids of the previous and next state for the specified transition
100
+ * @param transition a graph edge instance defining transition
101
+ * @returns an array with two identifiers - [sourceStateId, targetStateId] - the source state id and target state id
102
+ */
103
+ getTransitionStateIds(
104
+ transition?: StateGraphEdge
105
+ ): [string | undefined, string | undefined] {
106
+ const result: [string | undefined, string | undefined] = [
107
+ undefined,
108
+ undefined,
109
+ ];
110
+ if (!transition) return result;
111
+ const parentId = this._edgesParentsIndex[transition.id];
112
+ if (!parentId) return result;
113
+ const parent = this._chartsIndex[parentId];
114
+ if (!parent) return result;
115
+ parent.nodes.forEach((node: StateGraphNode) => {
116
+ if (node.key === transition.from) {
117
+ result[0] = node.id;
118
+ }
119
+ if (node.key === transition.to) {
120
+ result[1] = node.id;
121
+ }
122
+ });
123
+ return result;
124
+ }
125
+
126
+ // ----------------------------------------------------------
127
+ // Internal methods
128
+ _buildIndexes() {
129
+ const addToIndex = (chart: StateChart) => {
130
+ const chartId = chart.id;
131
+ this._chartsIndex[chartId] = chart;
132
+ if (!(chartId in this._nodesIndex)) {
133
+ this._nodesIndex[chartId] = chart;
134
+ }
135
+ chart.nodes.forEach((node) => {
136
+ const nodeId = node.id;
137
+ this._nodesIndex[nodeId] = node;
138
+ this._nodesParentsIndex[nodeId] = chartId;
139
+ });
140
+ chart.edges.forEach((edge) => {
141
+ const edgeId = edge.id;
142
+ this._edgeIndex[edgeId] = edge;
143
+ this._edgesParentsIndex[edgeId] = chartId;
144
+ });
145
+ (chart.children || []).forEach((child) => {
146
+ this._nodesParentsIndex[child.id] = chartId;
147
+ addToIndex(child);
148
+ });
149
+ };
150
+ addToIndex(this.statechart);
151
+ }
152
+ }
@@ -1,211 +1 @@
1
- export const a = "a";
2
-
3
- // class RuntimeStatechartsApi {
4
- // constructor({ element, statechart }) {
5
- // this.element = element;
6
- // this.statechart = statechart;
7
- // // this._statesIndex = {};
8
- // // this._transitionsIndex = {};
9
- // // this._buildIndexes(this.statechart);
10
- // }
11
-
12
- // _applyStateModifier(cssSelector, modifier = "selected", apply) {
13
- // const detailsModifier = `state-details--${modifier}`;
14
- // const stateLabelsModifier = `state-details__label--${modifier}`;
15
- // const stateModifier = `state--${modifier}`;
16
- // [...this.element.querySelectorAll(cssSelector)].forEach((elm) => {
17
- // if (elm.tagName.toLowerCase() === "details") {
18
- // apply(elm, detailsModifier);
19
- // const labelElm = elm.querySelector(".state-details__label");
20
- // if (labelElm) apply(labelElm, stateLabelsModifier);
21
- // } else {
22
- // apply(elm, stateModifier);
23
- // }
24
- // });
25
- // }
26
-
27
- // _applyTransitionsModifier(cssSelector, modifier = "selected", action) {}
28
-
29
- // deselectAllTransitions() {
30
- // const removeClass = (elm, cls) => elm.classList.remove(cls);
31
- // this._applyTransitionsModifier(
32
- // "[data-transition-id]",
33
- // "selected",
34
- // removeClass
35
- // );
36
- // }
37
- // deselectTransitions(...ids) {
38
- // const removeClass = (elm, cls) => elm.classList.remove(cls);
39
- // for (const id of ids) {
40
- // this._applyTransitionsModifier(
41
- // `[data-transition-id="${id}"]`,
42
- // "selected",
43
- // removeClass
44
- // );
45
- // }
46
- // }
47
- // selectTransitions(...ids) {
48
- // const addClass = (elm, cls) => elm.classList.add(cls);
49
- // for (const id of ids) {
50
- // this._applyTransitionsModifier(
51
- // `[data-transition-id="${id}"]`,
52
- // "selected",
53
- // addClass
54
- // );
55
- // }
56
- // }
57
-
58
- // deselectAllStates() {
59
- // const removeClass = (elm, cls) => elm.classList.remove(cls);
60
- // this._applyStateModifier("[data-state-id]", "selected", removeClass);
61
- // }
62
- // deselectStates(...ids) {
63
- // const removeClass = (elm, cls) => elm.classList.remove(cls);
64
- // for (const id of ids) {
65
- // this._applyStateModifier(
66
- // `[data-state-id="${id}"]`,
67
- // "selected",
68
- // removeClass
69
- // );
70
- // }
71
- // }
72
- // selectStates(...ids) {
73
- // const addClass = (elm, cls) => elm.classList.add(cls);
74
- // for (const id of ids) {
75
- // this._applyStateModifier(`[data-state-id="${id}"]`, "selected", addClass);
76
- // }
77
- // }
78
-
79
- // // -----------------------------------------------
80
- // // Access to charts data
81
- // // - get state ids by stack of state keys
82
- // // - get stack of states by state id
83
- // // - get transitionId by stateId + event
84
- // // - get targetId, sourceId, event by transitionId
85
- // getStatesIds(...stack) {
86
- // let statechart = this.statechart;
87
- // let result = [];
88
- // if (statechart.key === stack[0]) {
89
- // result.push(statechart.id);
90
- // for (let i = 1; i < stack.length; i++) {
91
- // const key = stack[i];
92
- // let id = statechart.graph.nodes.find((node) => node.key === key)?.id;
93
- // if (!id) break;
94
- // result.push(id);
95
- // statechart = (statechart.children || []).find(
96
- // (child) => child.key === key
97
- // );
98
- // }
99
- // }
100
- // return result.length === stack.length ? result : [];
101
- // }
102
-
103
- // getStackByStateId(id) {
104
- // return this._getStack(id, ({ id, key }) => key);
105
- // }
106
-
107
- // getTransition(stateId, event) {
108
- // const stack = this._getStack(stateId);
109
- // const state = stack.pop();
110
- // if (!state || !stack.length) return;
111
- // const parent = stack[stack.length - 1];
112
- // const t = parent.graph.edges.find(
113
- // (t) => t.from === state.key && t.event === event
114
- // );
115
- // if (!t) return;
116
- // const to = parent.graph.nodes.find((n) => n.key === t.to);
117
- // return to && { id: t.id, fromId: state.id, event: t.event, toId: to.id };
118
- // }
119
-
120
- // _getStack(id, get = (d) => d) {
121
- // return findById(this.statechart, id, get);
122
-
123
- // function findById(statechart, id, get, stack = []) {
124
- // try {
125
- // stack.push(get(statechart));
126
- // if (statechart.id === id) {
127
- // return [...stack];
128
- // } else {
129
- // let node = statechart.graph.nodes.find((node) => node.id === id);
130
- // if (node) {
131
- // return [...stack, get(node)];
132
- // } else {
133
- // let result;
134
- // if (statechart.children) {
135
- // for (const child of statechart.children) {
136
- // result = findById(child, id, get, stack);
137
- // if (result) break;
138
- // }
139
- // }
140
- // return result;
141
- // }
142
- // }
143
- // } finally {
144
- // stack.pop();
145
- // }
146
- // }
147
- // }
148
-
149
- // // getTransitionId(stateId, event) {
150
- // // }
151
-
152
- // // const stateInfo = this._statesIndex[stateId];
153
- // // if (!stateInfo) return;
154
- // // if (stateInfo.parent) return ;
155
- // // const targetState = stateInfo.parent.
156
- // // const fromId = stateIds.pop();
157
- // // const parentId = stateIds.pop();
158
- // // const parent = parentId ? this._statesIndex[parentId] : null;
159
- // // return parent
160
- // // ? parent.graph?.edges.find(
161
- // // (edge) => edge.from === fromId && edge.event === event
162
- // // )
163
- // // : undefined;
164
- // // }
165
-
166
- // // _getInfo(index, id, create) {
167
- // // let info = index[id];
168
- // // if (!info && create) {
169
- // // info = index[id] = { id };
170
- // // }
171
- // // return info;
172
- // // }
173
- // // _getStateInfo(id, create) {
174
- // // return this._getInfo(this._statesIndex, id, create);
175
- // // }
176
- // // _getTransitionInfo(id, create) {
177
- // // return this._getInfo(this._transitionsIndex, id, create);
178
- // // }
179
- // // _buildIndexes(statechart) {
180
- // // const { id, key } = statechart;
181
- // // const stateInfo = this._getStateInfo(id, true);
182
- // // stateInfo.key = key;
183
- // // stateInfo.detailsElement = this.element.querySelector(
184
- // // `details[data-state-id="${id}"]`
185
- // // );
186
- // // for (const node of statechart.graph?.nodes || []) {
187
- // // const info = this._getStateInfo(node.id, true);
188
- // // info.parent = stateInfo;
189
- // // // info.parentId = id;
190
- // // info.node = node;
191
- // // info.key = node.key;
192
- // // info.svgGroupElement = this.element.querySelector(
193
- // // `g[data-state-id="${info.id}"]`
194
- // // );
195
- // // }
196
- // // for (const edge of statechart.graph?.edges || []) {
197
- // // const info = this._getTransitionInfo(edge.id, true);
198
- // // info.transition = edge;
199
- // // info.from = edge.from;
200
- // // info.event = edge.event;
201
- // // info.to = edge.to;
202
- // // info.svgGroupElement = this.element.querySelector(
203
- // // `g[data-transition-id="${info.id}"]`
204
- // // );
205
- // // }
206
-
207
- // // for (const child of statechart.children) {
208
- // // this._buildIndexes(child);
209
- // // }
210
- // // }
211
- // }
1
+ export * from "./StateChartIndex.ts";
@@ -1,7 +1,7 @@
1
+ import type { StateGraphNode } from "./StateGraphNode.ts";
1
2
  import type { TransitionsGraph } from "./TransitionsGraph.ts";
2
3
 
3
- export type StateChart = TransitionsGraph & {
4
- id: string;
5
- key: string;
6
- children?: StateChart[];
7
- } & Record<string, any>;
4
+ export type StateChart = TransitionsGraph &
5
+ StateGraphNode & {
6
+ children?: StateChart[];
7
+ } & Record<string, any>;
@@ -1,4 +0,0 @@
1
- // src/runtime/index.ts
2
- var a = "a";
3
-
4
- export { a };
File without changes
File without changes
@@ -1,5 +1,5 @@
1
- import { buildStatechartSvg } from "./buildStatechartSvg.ts";
2
1
  import type { StateChart } from "../types/StateChart.ts";
2
+ import { buildStatechartSvg } from "./buildStatechartSvg.ts";
3
3
 
4
4
  export function buildStatechartsPanel({
5
5
  statechart,
File without changes