state-machine-cat 10.1.6 → 10.1.7

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.
Files changed (79) hide show
  1. package/bin/smcat.mjs +5 -4
  2. package/dist/commonjs/bundle.js +67 -67
  3. package/{src → dist/esm}/cli/actions.mjs +24 -40
  4. package/dist/esm/cli/attributes-parser.mjs +981 -0
  5. package/dist/esm/cli/file-name-to-stream.mjs +13 -0
  6. package/dist/esm/cli/make-description.mjs +21 -0
  7. package/dist/esm/cli/normalize.mjs +95 -0
  8. package/dist/esm/cli/validations.mjs +70 -0
  9. package/dist/esm/index-node.mjs +16 -0
  10. package/dist/esm/index.mjs +19 -0
  11. package/dist/esm/options.mjs +61 -0
  12. package/dist/esm/parse/index.mjs +27 -0
  13. package/dist/esm/parse/parser-helpers.mjs +175 -0
  14. package/dist/esm/parse/scxml/index.mjs +136 -0
  15. package/dist/esm/parse/scxml/normalize-machine.mjs +44 -0
  16. package/dist/esm/parse/smcat/smcat-parser.mjs +2924 -0
  17. package/dist/esm/parse/smcat-ast.schema.mjs +170 -0
  18. package/dist/esm/render/dot/attributebuilder.mjs +51 -0
  19. package/dist/esm/render/dot/counter.mjs +16 -0
  20. package/dist/esm/render/dot/dot.states.template.js +26 -0
  21. package/dist/esm/render/dot/dot.template.js +14 -0
  22. package/dist/esm/render/dot/index.mjs +106 -0
  23. package/dist/esm/render/dot/render-dot-from-ast.js +29 -0
  24. package/dist/esm/render/dot/state-transformers.mjs +113 -0
  25. package/dist/esm/render/dot/transition-transformers.mjs +49 -0
  26. package/dist/esm/render/dot/utl.mjs +29 -0
  27. package/dist/esm/render/index-node.mjs +28 -0
  28. package/dist/esm/render/index.mjs +20 -0
  29. package/dist/esm/render/scjson/index.mjs +121 -0
  30. package/dist/esm/render/scjson/make-valid-event-names.mjs +27 -0
  31. package/dist/esm/render/scjson/make-valid-xml-name.mjs +19 -0
  32. package/dist/esm/render/scxml/index.mjs +4 -0
  33. package/dist/esm/render/scxml/render-from-scjson.js +9 -0
  34. package/dist/esm/render/scxml/scxml.states.template.js +14 -0
  35. package/dist/esm/render/scxml/scxml.template.js +6 -0
  36. package/dist/esm/render/smcat/index.js +63 -0
  37. package/dist/esm/render/smcat/smcat.template.js +13 -0
  38. package/dist/esm/render/vector/dot-to-vector-native.mjs +35 -0
  39. package/dist/esm/render/vector/vector-native-dot-with-fallback.mjs +37 -0
  40. package/dist/esm/render/vector/vector-with-viz-js.mjs +13 -0
  41. package/dist/esm/state-machine-model.mjs +58 -0
  42. package/dist/esm/transform/desugar.mjs +77 -0
  43. package/dist/esm/transform/utl.mjs +16 -0
  44. package/dist/esm/version.mjs +1 -0
  45. package/package.json +32 -41
  46. package/src/render/dot/dot.states.template.js +1 -1
  47. package/src/render/dot/index.mjs +14 -14
  48. package/types/state-machine-cat.d.ts +4 -4
  49. package/src/cli/file-name-to-stream.mjs +0 -25
  50. package/src/cli/make-description.mjs +0 -45
  51. package/src/cli/normalize.mjs +0 -204
  52. package/src/cli/validations.mjs +0 -140
  53. package/src/index-node.mjs +0 -55
  54. package/src/index.mjs +0 -58
  55. package/src/options.mjs +0 -78
  56. package/src/parse/index.mjs +0 -47
  57. package/src/parse/parser-helpers.mjs +0 -297
  58. package/src/parse/scxml/normalize-machine.mjs +0 -73
  59. package/src/parse/smcat-ast.schema.mjs +0 -187
  60. package/src/render/dot/attributebuilder.mjs +0 -68
  61. package/src/render/dot/counter.mjs +0 -33
  62. package/src/render/dot/render-dot-from-ast.js +0 -70
  63. package/src/render/dot/state-transformers.mjs +0 -128
  64. package/src/render/dot/transition-transformers.mjs +0 -52
  65. package/src/render/dot/utl.mjs +0 -56
  66. package/src/render/index-node.mjs +0 -36
  67. package/src/render/index.mjs +0 -22
  68. package/src/render/scjson/index.mjs +0 -175
  69. package/src/render/scjson/make-valid-event-names.mjs +0 -71
  70. package/src/render/scjson/make-valid-xml-name.mjs +0 -70
  71. package/src/render/scxml/index.mjs +0 -8
  72. package/src/render/smcat/index.js +0 -129
  73. package/src/render/vector/dot-to-vector-native.mjs +0 -60
  74. package/src/render/vector/vector-native-dot-with-fallback.mjs +0 -55
  75. package/src/render/vector/vector-with-viz-js.mjs +0 -18
  76. package/src/state-machine-model.mjs +0 -124
  77. package/src/transform/desugar.mjs +0 -222
  78. package/src/transform/utl.mjs +0 -26
  79. package/src/version.mjs +0 -2
@@ -1,297 +0,0 @@
1
- // @ts-check
2
- /* eslint-disable security/detect-object-injection */
3
- import StateMachineModel from "../state-machine-model.mjs";
4
-
5
- const TRIGGER_RE_AS_A_STRING =
6
- "^(entry|activity|exit)\\s*/\\s*([^\\n$]*)(\\n|$)";
7
- /* eslint security/detect-non-literal-regexp:0 */
8
- const TRIGGER_RE = new RegExp(TRIGGER_RE_AS_A_STRING);
9
-
10
- /**
11
- * @param {string[]} pKnownStateNames
12
- * @param {string} pName
13
- * @returns {boolean}
14
- */
15
- function stateExists(pKnownStateNames, pName) {
16
- return pKnownStateNames.includes(pName);
17
- }
18
- /**
19
- * @type {{
20
- * re:RegExp;
21
- * stateType: import("../../types/state-machine-cat.js").StateType;
22
- * }[]}
23
- */
24
- const RE2STATE_TYPE = [
25
- {
26
- re: /initial/,
27
- stateType: "initial",
28
- },
29
- {
30
- re: /final/,
31
- stateType: "final",
32
- },
33
- {
34
- re: /parallel/,
35
- stateType: "parallel",
36
- },
37
- {
38
- re: /(deep.*history)|(history.*deep)/,
39
- stateType: "deephistory",
40
- },
41
- {
42
- re: /history/,
43
- stateType: "history",
44
- },
45
- {
46
- re: /^\^.*/,
47
- stateType: "choice",
48
- },
49
- {
50
- re: /^].*/,
51
- stateType: "forkjoin",
52
- },
53
- ];
54
-
55
- function matches(pName) {
56
- return (pEntry) => pEntry.re.test(pName);
57
- }
58
-
59
- /**
60
- * @param {string} [pName]
61
- * @returns {import("../../types/state-machine-cat.js").StateType}
62
- */
63
- function getStateType(pName) {
64
- return (RE2STATE_TYPE.find(matches(pName)) || { stateType: "regular" })
65
- .stateType;
66
- }
67
-
68
- /**
69
- * @param {string} pName
70
- * @returns {import("../../types/state-machine-cat.js").IState}
71
- */
72
- function initState(pName) {
73
- return {
74
- name: pName,
75
- type: getStateType(pName),
76
- };
77
- }
78
-
79
- /**
80
- * @param {import("../../types/state-machine-cat.js").IState} pState
81
- * @returns {boolean}
82
- */
83
- function isComposite(pState) {
84
- return Boolean(pState.statemachine);
85
- }
86
-
87
- /**
88
- * @param {import("../../types/state-machine-cat.js").IStateMachine} [pStateMachine]
89
- * @returns {string[]}
90
- */
91
- function getAlreadyDeclaredStates(pStateMachine) {
92
- const lStates = pStateMachine?.states ?? [];
93
-
94
- return lStates.filter(isComposite).reduce(
95
- (pAllStateNames, pThisState) =>
96
- pAllStateNames.concat(getAlreadyDeclaredStates(pThisState.statemachine)),
97
- lStates.map(({ name }) => name)
98
- );
99
- }
100
-
101
- /**
102
- * @param {import("../../types/state-machine-cat.js").IStateMachine} pStateMachine
103
- * @param {string[]} pKnownStateNames
104
- * @returns {import("../../types/state-machine-cat.js").IState[]}
105
- */
106
- function extractUndeclaredStates(pStateMachine, pKnownStateNames) {
107
- pKnownStateNames = pKnownStateNames
108
- ? pKnownStateNames
109
- : getAlreadyDeclaredStates(pStateMachine);
110
-
111
- pStateMachine.states = pStateMachine?.states ?? [];
112
- const lTransitions = pStateMachine?.transitions ?? [];
113
-
114
- pStateMachine.states.filter(isComposite).forEach((pState) => {
115
- // @ts-expect-error isComposite guarantees the statemachine attribute exists, TS doesn't understand that yet, though
116
- pState.statemachine.states = extractUndeclaredStates(
117
- // @ts-expect-error isComposite guarantees the statemachine attribute exists, TS doesn't understand that yet, though
118
- pState.statemachine,
119
- pKnownStateNames
120
- );
121
- });
122
-
123
- lTransitions.forEach((pTransition) => {
124
- if (!stateExists(pKnownStateNames, pTransition.from)) {
125
- pKnownStateNames.push(pTransition.from);
126
- pStateMachine.states.push(initState(pTransition.from));
127
- }
128
- if (!stateExists(pKnownStateNames, pTransition.to)) {
129
- pKnownStateNames.push(pTransition.to);
130
- pStateMachine.states.push(initState(pTransition.to));
131
- }
132
- });
133
- return pStateMachine.states;
134
- }
135
-
136
- /**
137
- * @param {number} pInComingCount
138
- * @param {number} pOutGoingCount
139
- * @returns {import("../../types/state-machine-cat.js").StateType}
140
- */
141
- function classifyForkJoin(pInComingCount, pOutGoingCount) {
142
- /** @type {import("../../types/state-machine-cat.js").StateType} */
143
- let lReturnValue = "junction";
144
-
145
- if (pInComingCount <= 1 && pOutGoingCount > 1) {
146
- lReturnValue = "fork";
147
- }
148
- if (pInComingCount > 1 && pOutGoingCount <= 1) {
149
- lReturnValue = "join";
150
- }
151
-
152
- return lReturnValue;
153
- }
154
-
155
- /**
156
- * @param {import("../../types/state-machine-cat.js").IStateMachine} pStateMachine
157
- * @param {StateMachineModel} pFlattenedStateMachineModel
158
- * @returns {import("../../types/state-machine-cat.js").IStateMachine}
159
- */
160
- function classifyForkJoins(
161
- pStateMachine,
162
- pFlattenedStateMachineModel = new StateMachineModel(pStateMachine)
163
- ) {
164
- // TODO: mutates parameter
165
- pStateMachine.states = pStateMachine.states.map((pState) => {
166
- if (pState.type === "forkjoin" && !pState.typeExplicitlySet) {
167
- const lInComingCount = pFlattenedStateMachineModel.findTransitionsByTo(
168
- pState.name
169
- ).length;
170
- const lOutGoingCount = pFlattenedStateMachineModel.findTransitionsByFrom(
171
- pState.name
172
- ).length;
173
-
174
- pState.type = classifyForkJoin(lInComingCount, lOutGoingCount);
175
- }
176
- if (pState.statemachine) {
177
- pState.statemachine = classifyForkJoins(
178
- pState.statemachine,
179
- pFlattenedStateMachineModel
180
- );
181
- }
182
- return pState;
183
- });
184
-
185
- return pStateMachine;
186
- }
187
-
188
- /**
189
- * @param {import("../../types/state-machine-cat.js").IState} pStateOne
190
- * @param {import("../../types/state-machine-cat.js").IState} pStateTwo
191
- * @returns {boolean}
192
- */
193
- function stateEqual(pStateOne, pStateTwo) {
194
- return pStateOne.name === pStateTwo.name;
195
- }
196
-
197
- function uniq(pArray, pEqualFunction) {
198
- return pArray.reduce((pBag, pMarble) => {
199
- const lMarbleIndex = pBag.findIndex((pBagItem) =>
200
- pEqualFunction(pBagItem, pMarble)
201
- );
202
-
203
- if (lMarbleIndex > -1) {
204
- // ensures the _last_ marble we find is in the bag on that position
205
- pBag[lMarbleIndex] = pMarble;
206
- return pBag;
207
- }
208
- return pBag.concat(pMarble);
209
- }, []);
210
- }
211
-
212
- /**
213
- * @param {String} pString
214
- * @returns {{event?: string; cond?: string; action?: string}}
215
- */
216
- function parseTransitionExpression(pString) {
217
- // eslint-disable-next-line security/detect-unsafe-regex, unicorn/no-unsafe-regex
218
- const lTransitionExpressionRe = /([^[/]+)?(\[[^\]]+\])?[^/]*(\/.+)?/;
219
- const lReturnValue = {};
220
-
221
- /** @type {RegExpMatchArray} */
222
- // @ts-expect-error match has no fallback because lTransitionExpressionRe will match
223
- // any string (every part is optional)
224
- const lMatchResult = pString.match(lTransitionExpressionRe);
225
- const lEventPos = 1;
226
- const lConditionPos = 2;
227
- const lActionPos = 3;
228
-
229
- if (lMatchResult[lEventPos]) {
230
- lReturnValue.event = lMatchResult[lEventPos].trim();
231
- }
232
- if (lMatchResult[lConditionPos]) {
233
- lReturnValue.cond = lMatchResult[lConditionPos].slice(1, -1).trim();
234
- }
235
- if (lMatchResult[lActionPos]) {
236
- lReturnValue.action = lMatchResult[lActionPos]
237
- .slice(1, lMatchResult[lActionPos].length)
238
- .trim();
239
- }
240
-
241
- return lReturnValue;
242
- }
243
-
244
- function setIf(pObject, pProperty, pValue, pCondition = (pX) => pX) {
245
- if (pCondition(pValue)) {
246
- pObject[pProperty] = pValue;
247
- }
248
- }
249
-
250
- function setIfNotEmpty(pObject, pProperty, pValue) {
251
- setIf(pObject, pProperty, pValue, (pX) => pX && pX.length > 0);
252
- }
253
-
254
- /**
255
- * @param {string} pActivityCandidate
256
- * @returns {{type: string; body: string}}
257
- */
258
- function extractAction(pActivityCandidate) {
259
- const lMatch = pActivityCandidate.match(TRIGGER_RE);
260
- const lTypePos = 1;
261
- const lBodyPos = 2;
262
-
263
- if (lMatch) {
264
- return {
265
- type: lMatch[lTypePos],
266
- body: lMatch[lBodyPos],
267
- };
268
- }
269
- return {
270
- type: "activity",
271
- body: pActivityCandidate,
272
- };
273
- }
274
-
275
- /**
276
- * @param {string} pString
277
- * @returns {{type: string; body: string}[]}
278
- */
279
- function extractActions(pString) {
280
- return pString
281
- .split(/\n\s*/g)
282
- .map((pActivityCandidate) => pActivityCandidate.trim())
283
- .map(extractAction);
284
- }
285
-
286
- export default {
287
- initState,
288
- extractUndeclaredStates,
289
- classifyForkJoins,
290
- getStateType,
291
- stateEqual,
292
- uniq,
293
- parseTransitionExpression,
294
- extractActions,
295
- setIf,
296
- setIfNotEmpty,
297
- };
@@ -1,73 +0,0 @@
1
- import castArray from "lodash/castArray.js";
2
-
3
- /**
4
- * @param {Partial<import("./scxml").ISCXMLInitialState>} pInitialObject
5
- * @param {string} [pId]
6
- * @returns {import("./scxml").ISCXMLInitialState}
7
- */
8
- function normalizeInitialFromObject(pInitialObject, pId) {
9
- const lReturnValue = {
10
- // ensure the 'initial' state has a unique name
11
- id: pId ? `${pId}.initial` : "initial",
12
- };
13
-
14
- if (pInitialObject.transition) {
15
- Object.assign(lReturnValue, {
16
- transition: [pInitialObject.transition],
17
- });
18
- }
19
-
20
- return lReturnValue;
21
- }
22
-
23
- /**
24
- * @param {string} pString
25
- * @returns {import("./scxml").ISCXMLInitialState}
26
- */
27
- function normalizeInitialFromString(pString) {
28
- return {
29
- id: "initial",
30
- transition: [
31
- {
32
- target: pString,
33
- },
34
- ],
35
- };
36
- }
37
-
38
- /**
39
- * @param {any} pMachine
40
- * @returns {import("./scxml").ISCXMLInitialState[]}
41
- */
42
- function normalizeInitial(pMachine) {
43
- const lReturnValue = [];
44
-
45
- if (pMachine.initial) {
46
- if (typeof pMachine.initial === "string") {
47
- lReturnValue.push(normalizeInitialFromString(pMachine.initial));
48
- } else {
49
- lReturnValue.push(
50
- normalizeInitialFromObject(pMachine.initial, pMachine.id)
51
- );
52
- }
53
- }
54
- return lReturnValue;
55
- }
56
-
57
- /**
58
- * Massages SCXML-as-json to be uniform:
59
- *
60
- * @param {any} pMachine SCXML-as-json state machine
61
- * @returns {import("./scxml").INormalizedSCXMLMachine} Still an SCXML-as-json state machine,
62
- * but more consistent and easier to use
63
- */
64
- export function normalizeMachine(pMachine) {
65
- return {
66
- ...pMachine,
67
- initial: normalizeInitial(pMachine),
68
- state: castArray(pMachine?.state ?? []),
69
- parallel: castArray(pMachine?.parallel ?? []),
70
- history: castArray(pMachine?.history ?? []),
71
- final: castArray(pMachine?.final ?? []),
72
- };
73
- }
@@ -1,187 +0,0 @@
1
- export default {
2
- $schema: "http://json-schema.org/draft-07/schema#",
3
- title: "state-machine-cat abstract syntax tree schema",
4
- $ref: "#/definitions/StateMachineType",
5
- $id: "org.js.state-machine-cat/v7.4.0",
6
- definitions: {
7
- StateType: {
8
- type: "string",
9
- enum: [
10
- "regular",
11
- "initial",
12
- "terminate",
13
- "final",
14
- "parallel",
15
- "history",
16
- "deephistory",
17
- "choice",
18
- "forkjoin",
19
- "fork",
20
- "join",
21
- "junction",
22
- ],
23
- },
24
- TransitionType: {
25
- type: "string",
26
- enum: ["internal", "external"],
27
- },
28
- NoteType: {
29
- type: "array",
30
- items: {
31
- type: "string",
32
- },
33
- },
34
- ActionTypeType: {
35
- type: "string",
36
- enum: ["entry", "activity", "exit"],
37
- },
38
- ActionType: {
39
- type: "object",
40
- required: ["type", "body"],
41
- additionalProperties: false,
42
- properties: {
43
- type: { $ref: "#/definitions/ActionTypeType" },
44
- body: { type: "string" },
45
- },
46
- },
47
- ClassType: {
48
- type: "string",
49
- pattern: "^[a-zA-Z0-9_\\- ]*$",
50
- },
51
- StateMachineType: {
52
- type: "object",
53
- additionalProperties: false,
54
- required: ["states"],
55
- properties: {
56
- states: {
57
- type: "array",
58
- items: {
59
- type: "object",
60
- required: ["name", "type"],
61
- additionalProperties: false,
62
- properties: {
63
- name: {
64
- description:
65
- "The name and identifier of the state. Unique within the root state machine.",
66
- type: "string",
67
- },
68
- type: {
69
- description:
70
- "What kind of state (or pseudo state) this state is. E.g. 'regular' for normal states or 'initial', 'final', 'choice' etc for pseudo states. Most UML (pseudo-) states are supported.",
71
- $ref: "#/definitions/StateType",
72
- },
73
- label: {
74
- description:
75
- "The display label of the state. If it's not present, most renderers will use the states' name in stead.",
76
- type: "string",
77
- },
78
- color: {
79
- description:
80
- 'Color to use for rendering the state. Accepts all css color names ("blue") and hex notation - with ("#0000FF77") or without ("#0000FF") transparency.',
81
- type: "string",
82
- },
83
- class: {
84
- description:
85
- "Class name to give the state in dot and svg output.",
86
- $ref: "#/definitions/ClassType",
87
- },
88
- active: {
89
- description:
90
- "If true the state is considered to be active and rendered as such.",
91
- type: "boolean",
92
- },
93
- typeExplicitlySet: {
94
- description:
95
- "The default parser derives the `type` from the `name` with inband signaling. The user can override that behavior by explicitly setting the `type`. This attribute is there to express that (and make sure that on next parses & processing it doesn't get accidentily re-derived from the name again).",
96
- type: "boolean",
97
- },
98
- isComposite: {
99
- description:
100
- "convenience, derived attribute - set to true if there's a state machine inside the state; false in all other cases. For internal use - @deprecated",
101
- type: "boolean",
102
- },
103
- actions: {
104
- type: "array",
105
- description:
106
- "A series of actions and their types. The type describe when the action takes place (on entry, exit, or otherwise ('activity'))",
107
- items: { $ref: "#/definitions/ActionType" },
108
- },
109
- note: {
110
- description:
111
- "Comments related to this state. Some renderers will use the note attribute to render a note (i.e. as a post-it) attached to the state.",
112
- $ref: "#/definitions/NoteType",
113
- },
114
- statemachine: {
115
- description: "state machine nested within the state.",
116
- $ref: "#/definitions/StateMachineType",
117
- },
118
- },
119
- },
120
- },
121
- transitions: {
122
- type: "array",
123
- items: {
124
- type: "object",
125
- required: ["from", "to"],
126
- additionalProperties: false,
127
- properties: {
128
- from: {
129
- description:
130
- "The name of the state this transition transitions from",
131
- type: "string",
132
- },
133
- to: {
134
- description:
135
- "The name of the state this transition transitions to",
136
- type: "string",
137
- },
138
- label: {
139
- description:
140
- "A display label to represent this transition. Parsers can parse this label into events conditions and actions.",
141
- type: "string",
142
- },
143
- event: {
144
- description: "Event triggering the transition",
145
- type: "string",
146
- },
147
- cond: {
148
- description: "Condition for the transition to occur.",
149
- type: "string",
150
- },
151
- action: {
152
- description: "Action to execute when the transition occurs.",
153
- type: "string",
154
- },
155
- note: {
156
- description: "Comments related to this transition",
157
- $ref: "#/definitions/NoteType",
158
- },
159
- color: {
160
- description:
161
- 'Color to use for rendering the transition. Accepts all css color names ("blue") and hex notation - with ("#0000FF77") or without ("#0000FF") transparency.',
162
- type: "string",
163
- },
164
- width: {
165
- description:
166
- "The line width to use for rendering the transition",
167
- type: "number",
168
- minimum: 0,
169
- maximum: 30,
170
- },
171
- class: {
172
- description:
173
- "Class name to give the state in dot and svg output.",
174
- $ref: "#/definitions/ClassType",
175
- },
176
- type: {
177
- description:
178
- "Whether the transition is external (default) or internal. See https://www.w3.org/TR/scxml/#transition for details.",
179
- $ref: "#/definitions/TransitionType",
180
- },
181
- },
182
- },
183
- },
184
- },
185
- },
186
- },
187
- };
@@ -1,68 +0,0 @@
1
- /* eslint-disable security/detect-object-injection */
2
- const GENERIC_GRAPH_ATTRIBUTES = [
3
- { name: "fontname", value: '"Helvetica"' },
4
- { name: "fontsize", value: "12" },
5
- { name: "penwidth", value: "2.0" },
6
- ];
7
-
8
- const GRAPH_ATTRIBUTES = {
9
- dot: [
10
- { name: "splines", value: "true" },
11
- { name: "ordering", value: "out" },
12
- { name: "compound", value: "true" },
13
- { name: "overlap", value: "scale" },
14
- { name: "nodesep", value: "0.3" },
15
- { name: "ranksep", value: "0.1" },
16
- ],
17
- fdp: [{ name: "K", value: "0.9" }],
18
- osage: [{ name: "pack", value: "42" }],
19
- neato: [{ name: "epsilon", value: "0.9" }],
20
- };
21
-
22
- const DIRECTION_ATTRIBUTES = {
23
- "bottom-top": [{ name: "rankdir", value: "BT" }],
24
- "left-right": [{ name: "rankdir", value: "LR" }],
25
- "right-left": [{ name: "rankdir", value: "RL" }],
26
- };
27
-
28
- const NODE_ATTRIBUTES = [
29
- { name: "shape", value: "plaintext" },
30
- { name: "style", value: "filled" },
31
- { name: "fillcolor", value: '"#FFFFFF01"' },
32
- { name: "fontname", value: "Helvetica" },
33
- { name: "fontsize", value: 12 },
34
- { name: "penwidth", value: "2.0" },
35
- ];
36
-
37
- const EDGE_ATTRIBUTES = [
38
- { name: "fontname", value: "Helvetica" },
39
- { name: "fontsize", value: 10 },
40
- ];
41
-
42
- function toNameValueString(pAttribute) {
43
- return `${pAttribute.name}=${pAttribute.value}`;
44
- }
45
-
46
- export default {
47
- /**
48
- *
49
- * @param {string} pEngine
50
- * @param {string} pDirection
51
- * @param {*} pDotGraphAttributes
52
- * @returns {string}
53
- */
54
- buildGraphAttributes: (pEngine, pDirection, pDotGraphAttributes) =>
55
- GENERIC_GRAPH_ATTRIBUTES.concat(GRAPH_ATTRIBUTES[pEngine] || [])
56
- .concat(DIRECTION_ATTRIBUTES[pDirection] || [])
57
- .concat(pDotGraphAttributes || [])
58
- .map(toNameValueString)
59
- .join(" "),
60
- buildNodeAttributes: (pDotNodeAttributes) =>
61
- NODE_ATTRIBUTES.concat(pDotNodeAttributes || [])
62
- .map(toNameValueString)
63
- .join(" "),
64
- buildEdgeAttributes: (pDotEdgeAttributes) =>
65
- EDGE_ATTRIBUTES.concat(pDotEdgeAttributes || [])
66
- .map(toNameValueString)
67
- .join(" "),
68
- };
@@ -1,33 +0,0 @@
1
- // @ts-check
2
- export default class Counter {
3
- constructor() {
4
- this.reset();
5
- }
6
-
7
- /**
8
- * @returns {void}
9
- */
10
- reset() {
11
- this.COUNTER = 0;
12
- }
13
-
14
- /**
15
- * @returns {number}
16
- */
17
- next() {
18
- // @ts-expect-error TS thinks COUNTER can possibly be null as it doesn't
19
- // see that the function the constructor calls ensures it won't
20
- // eslint-disable-next-line no-plusplus
21
- return ++this.COUNTER;
22
- }
23
-
24
- /**
25
- * @returns {string}
26
- */
27
- nextAsString() {
28
- /** @type {number} */
29
- const lBase = 10;
30
-
31
- return this.next().toString(lBase);
32
- }
33
- }