@statewalker/fsm-charts 0.1.9 → 0.1.12

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.
@@ -19,12 +19,19 @@ type FsmStateConfig = {
19
19
  states?: FsmStateConfig[];
20
20
  } & Record<string, any>;
21
21
 
22
+ /**
23
+ * Human-readable label
24
+ */
25
+ type Label = {
26
+ text: string;
27
+ };
28
+
22
29
  /**
23
30
  * Provides default functions measuring dimensions for state nodes and transition edges in the graph.
24
31
  */
25
32
  type GraphParamsProvider = {
26
- getStateParams: (stateKey: string, state?: string) => Dimensions & Record<string, any>;
27
- getTransitionParams: (fromStateKey: string, event: string, toStateKey: string) => Dimensions & Record<string, any>;
33
+ getStateParams: (stateKey: string, state?: string) => Dimensions & Label & Record<string, any>;
34
+ getTransitionParams: (fromStateKey: string, event: string, toStateKey: string) => Dimensions & Label & Record<string, any>;
28
35
  };
29
36
 
30
37
  /**
@@ -72,4 +79,4 @@ type StateChart = TransitionsGraph & StateGraphNode & {
72
79
  children?: StateChart[];
73
80
  } & Record<string, any>;
74
81
 
75
- export type { Dimensions as D, FsmStateConfig as F, GraphParamsProvider as G, Padding as P, StateChart as S, Transition as T, Position as a, StateGraphEdge as b, StateGraphNode as c, TransitionsGraph as d };
82
+ export type { Dimensions as D, FsmStateConfig as F, GraphParamsProvider as G, Label as L, Padding as P, StateChart as S, Transition as T, Position as a, StateGraphEdge as b, StateGraphNode as c, TransitionsGraph as d };
@@ -19,7 +19,8 @@ function getStateDescriptionRenderer({
19
19
  const rootStateFilter = getStateDescriptionFilter(splitHeader, rootStateKey);
20
20
  const rootDescription = findSection(docSections, rootStateFilter);
21
21
  if (!rootDescription) {
22
- return () => {
22
+ return (statesStack) => {
23
+ return void 0;
23
24
  };
24
25
  }
25
26
  for (const node of visitSectionNodes(rootDescription)) {
@@ -56,9 +57,12 @@ function getStateDescriptionRenderer({
56
57
  }
57
58
  }
58
59
  function* visitDom(elm) {
60
+ if (isDomElement(elm) && elm.tagName === "TEMPLATE") {
61
+ elm = elm.content;
62
+ }
59
63
  for (let node = elm.firstChild; node; node = node.nextSibling) {
60
64
  if (isDomElement(node)) {
61
- if (node.tagName === "DIV") {
65
+ if (node.tagName === "DIV" || node.tagName === "TEMPLATE") {
62
66
  yield* visitDom(node);
63
67
  } else {
64
68
  yield node;
@@ -338,6 +338,7 @@ var BasisCurve = class {
338
338
  switch (this._point) {
339
339
  case 3:
340
340
  this.$point(this._x1, this._y1);
341
+ // falls through
341
342
  case 2:
342
343
  this._context.lineTo(this._x1, this._y1);
343
344
  break;
@@ -362,6 +363,7 @@ var BasisCurve = class {
362
363
  (5 * this._x0 + this._x1) / 6,
363
364
  (5 * this._y0 + this._y1) / 6
364
365
  );
366
+ // falls through
365
367
  default:
366
368
  this.$point(x, y);
367
369
  break;
@@ -420,7 +422,7 @@ function buildStatechartSvg({
420
422
  fill: "currentColor"
421
423
  });
422
424
  for (const edge of edges) {
423
- const { id, points, event: text } = edge;
425
+ const { id, points, text } = edge;
424
426
  println(` <g class="transition" data-transition-id="${id}">`);
425
427
  const markerId = newId("marker");
426
428
  println(` <defs>`);
@@ -493,7 +495,7 @@ function buildStatechartSvg({
493
495
  const finalStateRadius = initialStateRadius / 2;
494
496
  println(`<g class="statechart__states">`);
495
497
  for (const node of nodes) {
496
- const { key, id, state: text } = node;
498
+ const { key, id, text } = node;
497
499
  const { x, y, width: width2, height: height2 } = getBoxParams({ ...node, padding: shift });
498
500
  println(` <g class="state" data-state-id="${id}">`);
499
501
  if (key === initialStateKey || key === finalStateKey) {
@@ -1008,6 +1008,15 @@ function shiftRanks(t, g, delta) {
1008
1008
  });
1009
1009
  }
1010
1010
 
1011
+ // src/graphlib/alg/dijkstra.js
1012
+ _.constant(1);
1013
+
1014
+ // src/graphlib/alg/floyd-warshall.js
1015
+ _.constant(1);
1016
+ function CycleException() {
1017
+ }
1018
+ CycleException.prototype = new Error();
1019
+
1011
1020
  // src/graphlib/alg/dfs.js
1012
1021
  function dfs(g, vs, order2) {
1013
1022
  if (!_.isArray(vs)) {
@@ -2570,37 +2579,62 @@ function buildCharts({
2570
2579
  direction
2571
2580
  }) {
2572
2581
  return buildChart(config);
2573
- function buildChart(config2, id = newId("s")) {
2574
- const graph = buildFlatCharts({
2575
- lodash,
2576
- transitions: config2.transitions || [],
2577
- newId,
2578
- getStateParams,
2579
- getTransitionParams,
2580
- padding,
2581
- initialStateKey,
2582
- finalStateKey,
2583
- vertical,
2584
- direction
2585
- });
2586
- const index = graph.nodes.reduce((index2, node) => {
2587
- index2[node.key] = node.id;
2588
- return index2;
2589
- }, {});
2590
- const children = [];
2591
- if (config2.states) {
2592
- for (const child of config2.states) {
2593
- const childId = index[child.key];
2594
- children.push(buildChart(child, childId));
2582
+ function buildChart(config2, id = newId("s"), stack = []) {
2583
+ stack.push(config2);
2584
+ try {
2585
+ const getStateLabel = (state, key = state) => {
2586
+ if (key === "<initial>" || key === "<final>") {
2587
+ return "";
2588
+ }
2589
+ let result;
2590
+ for (let i = stack.length - 1; result === void 0 && i >= 0; i--) {
2591
+ const conf = stack[i];
2592
+ console.log("WT", state, key, "=>", conf);
2593
+ if (conf.key !== state) continue;
2594
+ result = conf.label;
2595
+ }
2596
+ return result === void 0 ? state : result;
2597
+ };
2598
+ const graph = buildFlatCharts({
2599
+ lodash,
2600
+ transitions: config2.transitions || [],
2601
+ newId,
2602
+ getStateParams: (state, key) => {
2603
+ const params = getStateParams(state, key);
2604
+ params.text = getStateLabel(state, key);
2605
+ return params;
2606
+ },
2607
+ getTransitionParams,
2608
+ padding,
2609
+ initialStateKey,
2610
+ finalStateKey,
2611
+ vertical,
2612
+ direction
2613
+ });
2614
+ const index = graph.nodes.reduce(
2615
+ (index2, node) => {
2616
+ index2[node.key] = node.id;
2617
+ return index2;
2618
+ },
2619
+ {}
2620
+ );
2621
+ const children = [];
2622
+ if (config2.states) {
2623
+ for (const child of config2.states) {
2624
+ const childId = index[child.key];
2625
+ children.push(buildChart(child, childId));
2626
+ }
2595
2627
  }
2628
+ return {
2629
+ id,
2630
+ key: config2.key,
2631
+ state: config2.key,
2632
+ ...graph,
2633
+ children
2634
+ };
2635
+ } finally {
2636
+ stack.pop();
2596
2637
  }
2597
- return {
2598
- id,
2599
- key: config2.key,
2600
- state: config2.key,
2601
- ...graph,
2602
- children
2603
- };
2604
2638
  }
2605
2639
  }
2606
2640
 
@@ -2655,18 +2689,22 @@ function getGraphParamsProvider({
2655
2689
  stateFontSize = fontSize,
2656
2690
  stateTextPadding = 0,
2657
2691
  transitionsFontSize = fontSize,
2658
- transitionsTextPadding = 0
2692
+ transitionsTextPadding = 0,
2693
+ getStateLabel = (state) => state,
2694
+ getTransitionLabel = (fromState, event, toState) => event
2659
2695
  } = {}) {
2660
2696
  return {
2661
2697
  getStateParams: (stateKey, state = stateKey) => {
2662
2698
  const padding = getPadding(stateTextPadding);
2663
2699
  const fontSize2 = stateFontSize;
2700
+ const stateLabel = getStateLabel(state);
2664
2701
  return {
2665
- ...getLabelDimensions(state, {
2702
+ ...getLabelDimensions(stateLabel, {
2666
2703
  padding,
2667
2704
  fontSize: fontSize2
2668
2705
  }),
2669
2706
  state,
2707
+ text: stateLabel,
2670
2708
  key: stateKey,
2671
2709
  padding,
2672
2710
  fontSize: fontSize2
@@ -2675,14 +2713,16 @@ function getGraphParamsProvider({
2675
2713
  getTransitionParams: (fromStateKey, event, toStateKey) => {
2676
2714
  const padding = getPadding(transitionsTextPadding);
2677
2715
  const fontSize2 = transitionsFontSize;
2716
+ const eventLabel = getTransitionLabel(fromStateKey, event, toStateKey);
2678
2717
  return {
2679
- ...getLabelDimensions(event, {
2718
+ ...getLabelDimensions(eventLabel, {
2680
2719
  padding,
2681
2720
  fontSize: fontSize2
2682
2721
  }),
2683
2722
  from: fromStateKey,
2684
2723
  event,
2685
2724
  to: toStateKey,
2725
+ text: eventLabel,
2686
2726
  padding,
2687
2727
  fontSize: fontSize2
2688
2728
  };
@@ -1,5 +1,5 @@
1
- import { T as Transition, F as FsmStateConfig } from './StateChart-DlcWaRml.js';
2
- export { D as Dimensions, G as GraphParamsProvider, P as Padding, a as Position, S as StateChart, b as StateGraphEdge, c as StateGraphNode, d as TransitionsGraph } from './StateChart-DlcWaRml.js';
1
+ import { T as Transition, F as FsmStateConfig } from './StateChart-CdOU9XAq.js';
2
+ export { D as Dimensions, G as GraphParamsProvider, L as Label, P as Padding, a as Position, S as StateChart, b as StateGraphEdge, c as StateGraphNode, d as TransitionsGraph } from './StateChart-CdOU9XAq.js';
3
3
 
4
4
  declare function concatTransitionsToString(transitions: Transition[]): string[];
5
5
 
@@ -1 +1 @@
1
- export { concatTransitionsToString, serializeProcessConfig, splitTransitionString, toFsmStateConfig } from './chunk-SLWDNGWK.js';
1
+ export { concatTransitionsToString, serializeProcessConfig, splitTransitionString, toFsmStateConfig } from './chunk-SVKVQY7B.js';
@@ -6,8 +6,8 @@ type DomSection = {
6
6
  declare function getStateDescriptionRenderer({ element, rootStateKey, splitHeader, }: {
7
7
  element: HTMLElement;
8
8
  rootStateKey: string;
9
- splitHeader: (header?: HTMLElement) => [stateKey: undefined | string, label: string];
10
- }): (() => void) | ((statesStack: string[]) => HTMLDivElement | undefined);
9
+ splitHeader?: (header?: HTMLElement) => [stateKey: undefined | string, label: string];
10
+ }): (statesStack: string[]) => HTMLDivElement | undefined;
11
11
  declare function visitDom(elm: Node): Iterable<Node>;
12
12
  declare function visitSectionNodes(section: DomSection): Iterable<Node>;
13
13
  declare function vistSections(root: DomSection, ignoreRoot?: boolean): Generator<DomSection>;
package/dist/index-dom.js CHANGED
@@ -1 +1 @@
1
- export { buildSections, findSection, getStateDescriptionRenderer, renderSections, visitDom, visitSectionNodes, vistSections } from './chunk-TZRPE2VD.js';
1
+ export { buildSections, findSection, getStateDescriptionRenderer, renderSections, visitDom, visitSectionNodes, vistSections } from './chunk-AVTSJE25.js';
@@ -1,4 +1,4 @@
1
- import { S as StateChart, d as TransitionsGraph } from './StateChart-DlcWaRml.js';
1
+ import { S as StateChart, d as TransitionsGraph } from './StateChart-CdOU9XAq.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-DlcWaRml.js';
2
- export { c as activeStatesStyle, d as activeTransitionsStyle, f as buildStateDetailsStyle, g as buildStateDetailsStyleWithModifier, b as buildStatechartCss, i as buildStatechartStyles, h as buildStatechartStylesWithModifier, j as buildStatechartSvg, a as buildStatechartsPanel, s as selectedStatesStyle, e as selectedTransitionsStyle } from './index-html-De8e33ol.js';
1
+ export { D as Dimensions, F as FsmStateConfig, G as GraphParamsProvider, L as Label, P as Padding, a as Position, S as StateChart, b as StateGraphEdge, c as StateGraphNode, T as Transition, d as TransitionsGraph } from './StateChart-CdOU9XAq.js';
2
+ export { c as activeStatesStyle, d as activeTransitionsStyle, f as buildStateDetailsStyle, g as buildStateDetailsStyleWithModifier, b as buildStatechartCss, i as buildStatechartStyles, h as buildStatechartStylesWithModifier, j as buildStatechartSvg, a as buildStatechartsPanel, s as selectedStatesStyle, e as selectedTransitionsStyle } from './index-html-BKMwwc5Q.js';
@@ -1,2 +1,2 @@
1
- export { activeStatesStyle, activeTransitionsStyle, buildStateDetailsStyle, buildStateDetailsStyleWithModifier, buildStatechartCss, buildStatechartStyles, buildStatechartStylesWithModifier, buildStatechartSvg, buildStatechartsPanel, selectedStatesStyle, selectedTransitionsStyle } from './chunk-2XPO6T2M.js';
1
+ export { activeStatesStyle, activeTransitionsStyle, buildStateDetailsStyle, buildStateDetailsStyleWithModifier, buildStatechartCss, buildStatechartStyles, buildStatechartStylesWithModifier, buildStatechartSvg, buildStatechartsPanel, selectedStatesStyle, selectedTransitionsStyle } from './chunk-GCVBCAOL.js';
2
2
  import './chunk-FIQDLBWD.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-DlcWaRml.js';
2
- export { D as Dimensions, a as Position, b as StateGraphEdge, c as StateGraphNode } from './StateChart-DlcWaRml.js';
1
+ import { T as Transition, P as Padding, G as GraphParamsProvider, d as TransitionsGraph, F as FsmStateConfig, S as StateChart } from './StateChart-CdOU9XAq.js';
2
+ export { D as Dimensions, L as Label, a as Position, b as StateGraphEdge, c as StateGraphNode } from './StateChart-CdOU9XAq.js';
3
3
 
4
4
  /**
5
5
  * Build graphs corresponding to the specified transitions.
@@ -52,12 +52,14 @@ declare function buildCharts({ lodash, config, newId, getStateParams, getTransit
52
52
  * @param transitionsFontSize - The font size for the transition labels.
53
53
  * @param transitionsTextPadding - The padding around the transition labels.
54
54
  */
55
- declare function getGraphParamsProvider({ fontSize, stateFontSize, stateTextPadding, transitionsFontSize, transitionsTextPadding, }?: {
55
+ declare function getGraphParamsProvider({ fontSize, stateFontSize, stateTextPadding, transitionsFontSize, transitionsTextPadding, getStateLabel, getTransitionLabel, }?: {
56
56
  fontSize?: number;
57
57
  stateFontSize?: number;
58
58
  stateTextPadding?: Padding;
59
59
  transitionsFontSize?: number;
60
60
  transitionsTextPadding?: Padding;
61
+ getStateLabel?: (state: string) => string;
62
+ getTransitionLabel?: (fromState: string, event: string, toState: string) => string;
61
63
  }): GraphParamsProvider;
62
64
 
63
65
  declare function getLabelDimensions(label: string, { padding, fontSize, getCharWidth, // Golden ratio and all that jazz :-)
@@ -1,2 +1,2 @@
1
- export { buildCharts, buildFlatCharts, getGraphParamsProvider, getLabelDimensions } from './chunk-U5LUJ7JS.js';
1
+ export { buildCharts, buildFlatCharts, getGraphParamsProvider, getLabelDimensions } from './chunk-GNTY7KMJ.js';
2
2
  import './chunk-FIQDLBWD.js';
@@ -1,5 +1,5 @@
1
- import { S as StateChart, c as StateGraphNode, b as StateGraphEdge } from './StateChart-DlcWaRml.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-DlcWaRml.js';
1
+ import { S as StateChart, c as StateGraphNode, b as StateGraphEdge } from './StateChart-CdOU9XAq.js';
2
+ export { D as Dimensions, F as FsmStateConfig, G as GraphParamsProvider, L as Label, P as Padding, a as Position, T as Transition, d as TransitionsGraph } from './StateChart-CdOU9XAq.js';
3
3
 
4
4
  type RuntimeListener = (id: string) => void;
5
5
  declare class RuntimeStatechartApi {
@@ -1 +1 @@
1
- export { RuntimeStatechartApi, StateChartIndex } from './chunk-FS3L6FBI.js';
1
+ export { RuntimeStatechartApi, StateChartIndex } from './chunk-N77KKO5K.js';
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
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-DlcWaRml.js';
1
+ export { D as Dimensions, F as FsmStateConfig, G as GraphParamsProvider, L as Label, P as Padding, a as Position, S as StateChart, b as StateGraphEdge, c as StateGraphNode, T as Transition, d as TransitionsGraph } from './StateChart-CdOU9XAq.js';
2
2
  export { DomSection, buildSections, findSection, getStateDescriptionRenderer, renderSections, visitDom, visitSectionNodes, vistSections } from './index-dom.js';
3
3
  export { concatTransitionsToString, serializeProcessConfig, splitTransitionString, toFsmStateConfig } from './index-config.js';
4
4
  export { buildCharts, buildFlatCharts, getGraphParamsProvider, getLabelDimensions } from './index-layout.js';
5
- export { C as CssTree, c as activeStatesStyle, d as activeTransitionsStyle, f as buildStateDetailsStyle, g as buildStateDetailsStyleWithModifier, b as buildStatechartCss, i as buildStatechartStyles, h as buildStatechartStylesWithModifier, j as buildStatechartSvg, a as buildStatechartsPanel, s as selectedStatesStyle, e as selectedTransitionsStyle, k as serializeCss } from './index-html-De8e33ol.js';
5
+ export { C as CssTree, c as activeStatesStyle, d as activeTransitionsStyle, f as buildStateDetailsStyle, g as buildStateDetailsStyleWithModifier, b as buildStatechartCss, i as buildStatechartStyles, h as buildStatechartStylesWithModifier, j as buildStatechartSvg, a as buildStatechartsPanel, s as selectedStatesStyle, e as selectedTransitionsStyle, k as serializeCss } from './index-html-BKMwwc5Q.js';
6
6
  export { RuntimeListener, RuntimeStatechartApi, StateChartIndex } from './index-runtime.js';
7
7
 
8
8
  declare function toKebabCase(str?: string): string;
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- export { buildSections, findSection, getStateDescriptionRenderer, renderSections, visitDom, visitSectionNodes, vistSections } from './chunk-TZRPE2VD.js';
2
- export { concatTransitionsToString, serializeProcessConfig, splitTransitionString, toFsmStateConfig } from './chunk-SLWDNGWK.js';
3
- export { buildCharts, buildFlatCharts, getGraphParamsProvider, getLabelDimensions } from './chunk-U5LUJ7JS.js';
4
- export { activeStatesStyle, activeTransitionsStyle, buildStateDetailsStyle, buildStateDetailsStyleWithModifier, buildStatechartCss, buildStatechartStyles, buildStatechartStylesWithModifier, buildStatechartSvg, buildStatechartsPanel, selectedStatesStyle, selectedTransitionsStyle, serializeCss, toKebabCase } from './chunk-2XPO6T2M.js';
1
+ export { concatTransitionsToString, serializeProcessConfig, splitTransitionString, toFsmStateConfig } from './chunk-SVKVQY7B.js';
2
+ export { buildSections, findSection, getStateDescriptionRenderer, renderSections, visitDom, visitSectionNodes, vistSections } from './chunk-AVTSJE25.js';
3
+ export { activeStatesStyle, activeTransitionsStyle, buildStateDetailsStyle, buildStateDetailsStyleWithModifier, buildStatechartCss, buildStatechartStyles, buildStatechartStylesWithModifier, buildStatechartSvg, buildStatechartsPanel, selectedStatesStyle, selectedTransitionsStyle, serializeCss, toKebabCase } from './chunk-GCVBCAOL.js';
4
+ export { buildCharts, buildFlatCharts, getGraphParamsProvider, getLabelDimensions } from './chunk-GNTY7KMJ.js';
5
5
  import './chunk-FIQDLBWD.js';
6
- export { RuntimeStatechartApi, StateChartIndex } from './chunk-FS3L6FBI.js';
6
+ export { RuntimeStatechartApi, StateChartIndex } from './chunk-N77KKO5K.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@statewalker/fsm-charts",
3
- "version": "0.1.9",
3
+ "version": "0.1.12",
4
4
  "description": "HFSM Implementation",
5
5
  "keywords": [],
6
6
  "homepage": "https://github.com/statewalker/statewalker-fsm-charts",
@@ -14,6 +14,7 @@
14
14
  "dist",
15
15
  "src"
16
16
  ],
17
+ "source": "./src/index.ts",
17
18
  "module": "./dist/index.js",
18
19
  "main": "./dist/index.js",
19
20
  "jsdelivr": "./dist/index.js",
@@ -21,14 +22,10 @@
21
22
  "types": "./dist/index.d.ts",
22
23
  "exports": {
23
24
  ".": {
25
+ "source": "./src/index.ts",
26
+ "types": "./dist/index.d.ts",
24
27
  "import": "./dist/index.js",
25
- "require": "./dist/index.js"
26
- },
27
- "./src": {
28
- "import": "./src"
29
- },
30
- "./src/index.ts": {
31
- "import": "./src/index.ts"
28
+ "default": "./dist/index.js"
32
29
  }
33
30
  },
34
31
  "devDependencies": {
@@ -60,9 +57,9 @@
60
57
  "lint": "eslint",
61
58
  "lint:fix": "yarn lint -- --fix",
62
59
  "test": "vitest --run",
63
- "test:watch": "vitest"
60
+ "test:watch": "vitest",
61
+ "prepublish": "yarn build"
64
62
  },
65
- "sideEffects": false,
66
63
  "publishConfig": {
67
64
  "access": "public"
68
65
  }
package/src/dom/index.ts CHANGED
@@ -24,7 +24,7 @@ export function getStateDescriptionRenderer({
24
24
  }: {
25
25
  element: HTMLElement;
26
26
  rootStateKey: string;
27
- splitHeader: (
27
+ splitHeader?: (
28
28
  header?: HTMLElement,
29
29
  ) => [stateKey: undefined | string, label: string];
30
30
  }) {
@@ -33,7 +33,9 @@ export function getStateDescriptionRenderer({
33
33
  const rootDescription = findSection(docSections, rootStateFilter);
34
34
 
35
35
  if (!rootDescription) {
36
- return () => {};
36
+ return (statesStack: string[]) => {
37
+ return undefined;
38
+ };
37
39
  }
38
40
 
39
41
  // Remove description nodes from DOM
@@ -88,9 +90,12 @@ export function getStateDescriptionRenderer({
88
90
  }
89
91
 
90
92
  export function* visitDom(elm: Node): Iterable<Node> {
93
+ if (isDomElement(elm) && elm.tagName === "TEMPLATE") {
94
+ elm = (elm as HTMLTemplateElement).content;
95
+ }
91
96
  for (let node = elm.firstChild; node; node = node.nextSibling) {
92
97
  if (isDomElement(node)) {
93
- if (node.tagName === "DIV") {
98
+ if (node.tagName === "DIV" || node.tagName === "TEMPLATE") {
94
99
  yield* visitDom(node);
95
100
  } else {
96
101
  yield node;
@@ -51,7 +51,7 @@ export function buildStatechartSvg({
51
51
  height,
52
52
  viewbox: `0 0 ${width} ${height}`,
53
53
  xmlns: "http://www.w3.org/2000/svg",
54
- })}>`
54
+ })}>`,
55
55
  );
56
56
 
57
57
  /*
@@ -79,7 +79,7 @@ export function buildStatechartSvg({
79
79
  });
80
80
 
81
81
  for (const edge of edges) {
82
- const { id, points, event: text } = edge;
82
+ const { id, points, text } = edge;
83
83
  println(` <g class="transition" data-transition-id="${id}">`);
84
84
  const markerId = newId("marker");
85
85
 
@@ -98,7 +98,7 @@ export function buildStatechartSvg({
98
98
  x1: number,
99
99
  y1: number,
100
100
  x2: number,
101
- y2: number
101
+ y2: number,
102
102
  ) {
103
103
  path.push("C" + round(x0, y0, x1, y1, x2, y2).join(","));
104
104
  },
@@ -181,7 +181,7 @@ export function buildStatechartSvg({
181
181
 
182
182
  println(`<g class="statechart__states">`);
183
183
  for (const node of nodes) {
184
- const { key, id, state: text } = node;
184
+ const { key, id, text } = node;
185
185
  const { x, y, width, height } = getBoxParams({ ...node, padding: shift });
186
186
 
187
187
  println(` <g class="state" data-state-id="${id}">`);
@@ -39,38 +39,66 @@ export function buildCharts({
39
39
 
40
40
  function buildChart(
41
41
  config: FsmStateConfig,
42
- id: string = newId("s")
42
+ id: string = newId("s"),
43
+ stack: Array<FsmStateConfig> = [],
43
44
  ): StateChart {
44
- const graph = buildFlatCharts({
45
- lodash,
46
- transitions: config.transitions || [],
47
- newId,
48
- getStateParams,
49
- getTransitionParams,
50
- padding,
51
- initialStateKey,
52
- finalStateKey,
53
- vertical,
54
- direction
55
- });
56
- const index = graph.nodes.reduce((index, node) => {
57
- index[node.key as string] = node.id as string;
58
- return index;
59
- }, {} as Record<string, string>);
45
+ stack.push(config);
46
+ try {
47
+ const getStateLabel = (state: string, key: string = state) => {
48
+ if (key === "<initial>" || key === "<final>") {
49
+ return "";
50
+ }
51
+ // TODO: search labels in sub-states of the current state.
52
+ let result: string | undefined;
53
+ for (let i = stack.length - 1; result === undefined && i >= 0; i--) {
54
+ const conf = stack[i];
55
+ console.log('WT', state, key, '=>', conf)
56
+ if (conf.key !== state) continue;
57
+ result = conf.label;
58
+ }
60
59
 
61
- const children: StateChart[] = [];
62
- if (config.states) {
63
- for (const child of config.states) {
64
- const childId = index[child.key];
65
- children.push(buildChart(child, childId));
60
+ return result === undefined ? state : result;
61
+ };
62
+ const graph = buildFlatCharts({
63
+ lodash,
64
+ transitions: config.transitions || [],
65
+ newId,
66
+ getStateParams: (state: string, key?: string) => {
67
+ const params = getStateParams(state, key);
68
+ params.text = getStateLabel(state, key);
69
+ return params;
70
+ },
71
+ getTransitionParams,
72
+ padding,
73
+ initialStateKey,
74
+ finalStateKey,
75
+ vertical,
76
+ direction,
77
+ });
78
+ const index = graph.nodes.reduce(
79
+ (index, node) => {
80
+ index[node.key as string] = node.id as string;
81
+ return index;
82
+ },
83
+ {} as Record<string, string>,
84
+ );
85
+
86
+ const children: StateChart[] = [];
87
+ if (config.states) {
88
+ for (const child of config.states) {
89
+ const childId = index[child.key];
90
+ children.push(buildChart(child, childId));
91
+ }
66
92
  }
93
+ return {
94
+ id,
95
+ key: config.key,
96
+ state: config.key,
97
+ ...graph,
98
+ children,
99
+ };
100
+ } finally {
101
+ stack.pop();
67
102
  }
68
- return {
69
- id,
70
- key: config.key,
71
- state: config.key,
72
- ...graph,
73
- children,
74
- };
75
103
  }
76
104
  }
@@ -4,6 +4,7 @@ import type { Padding } from "../types/Padding.ts";
4
4
 
5
5
  import { getLabelDimensions } from "./getLabelDimensions.ts";
6
6
  import { getPadding } from "../utils/getPadding.ts";
7
+ import { Label } from "../types/Label.ts";
7
8
 
8
9
  /**
9
10
  * Provides default functions measuring dimensions for state nodes and transition edges in the graph.
@@ -19,23 +20,34 @@ export function getGraphParamsProvider({
19
20
  stateTextPadding = 0,
20
21
  transitionsFontSize = fontSize,
21
22
  transitionsTextPadding = 0,
23
+ getStateLabel = (state: string) => state,
24
+ getTransitionLabel = (fromState: string, event: string, toState: string) =>
25
+ event,
22
26
  }: {
23
27
  fontSize?: number;
24
28
  stateFontSize?: number;
25
29
  stateTextPadding?: Padding;
26
30
  transitionsFontSize?: number;
27
31
  transitionsTextPadding?: Padding;
32
+ getStateLabel?: (state: string) => string;
33
+ getTransitionLabel?: (
34
+ fromState: string,
35
+ event: string,
36
+ toState: string,
37
+ ) => string;
28
38
  } = {}): GraphParamsProvider {
29
39
  return {
30
40
  getStateParams: (stateKey: string, state: string = stateKey) => {
31
41
  const padding = getPadding(stateTextPadding);
32
42
  const fontSize = stateFontSize;
43
+ const stateLabel = getStateLabel(state);
33
44
  return {
34
- ...getLabelDimensions(state, {
45
+ ...getLabelDimensions(stateLabel, {
35
46
  padding,
36
47
  fontSize,
37
48
  }),
38
49
  state,
50
+ text: stateLabel,
39
51
  key: stateKey,
40
52
  padding,
41
53
  fontSize,
@@ -44,18 +56,20 @@ export function getGraphParamsProvider({
44
56
  getTransitionParams: (
45
57
  fromStateKey: string,
46
58
  event: string,
47
- toStateKey: string
48
- ): Dimensions & Record<string, any> => {
59
+ toStateKey: string,
60
+ ) => {
49
61
  const padding = getPadding(transitionsTextPadding);
50
62
  const fontSize = transitionsFontSize;
63
+ const eventLabel = getTransitionLabel(fromStateKey, event, toStateKey);
51
64
  return {
52
- ...getLabelDimensions(event, {
65
+ ...getLabelDimensions(eventLabel, {
53
66
  padding,
54
67
  fontSize,
55
68
  }),
56
69
  from: fromStateKey,
57
70
  event,
58
71
  to: toStateKey,
72
+ text: eventLabel,
59
73
  padding,
60
74
  fontSize,
61
75
  };
@@ -1,4 +1,5 @@
1
1
  import type { Dimensions } from "./Dimensions.ts";
2
+ import { Label } from "./Label.ts";
2
3
 
3
4
  /**
4
5
  * Provides default functions measuring dimensions for state nodes and transition edges in the graph.
@@ -6,12 +7,11 @@ import type { Dimensions } from "./Dimensions.ts";
6
7
  export type GraphParamsProvider = {
7
8
  getStateParams: (
8
9
  stateKey: string,
9
- state?: string
10
- ) => Dimensions & Record<string, any>;
10
+ state?: string,
11
+ ) => Dimensions & Label & Record<string, any>;
11
12
  getTransitionParams: (
12
13
  fromStateKey: string,
13
14
  event: string,
14
- toStateKey: string
15
- ) => Dimensions & Record<string, any>;
15
+ toStateKey: string,
16
+ ) => Dimensions & Label & Record<string, any>;
16
17
  };
17
-
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Human-readable label
3
+ */
4
+ export type Label = {
5
+ // The text of the label
6
+ text: string;
7
+ };
@@ -1,6 +1,7 @@
1
1
  export type * from "./Dimensions.ts";
2
2
  export type * from "./FsmStateConfig.ts";
3
3
  export type * from "./GraphParamsProvider.ts";
4
+ export type * from "./Label.ts";
4
5
  export type * from "./Padding.ts";
5
6
  export type * from "./Position.ts";
6
7
  export type * from "./StateChart.ts";
File without changes
File without changes