jssm 5.112.3 → 5.113.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.
Files changed (78) hide show
  1. package/README.md +3 -3
  2. package/dist/deno/README.md +347 -0
  3. package/dist/deno/jssm.js +1 -0
  4. package/dist/{es6 → deno}/jssm_constants.d.ts +5 -0
  5. package/dist/{es6 → deno}/jssm_types.d.ts +298 -5
  6. package/dist/jssm.es5.cjs +1 -1
  7. package/dist/jssm.es5.iife.js +1 -1
  8. package/dist/jssm.es6.mjs +1 -1
  9. package/dist/jssm_viz.cjs +1 -1
  10. package/dist/jssm_viz.iife.cjs +1 -1
  11. package/dist/jssm_viz.mjs +1 -1
  12. package/jssm.es5.d.cts +241 -2
  13. package/jssm.es6.d.ts +241 -2
  14. package/jssm_viz.es5.d.cts +216 -2
  15. package/jssm_viz.es6.d.ts +216 -2
  16. package/package.json +18 -2
  17. package/.clocignore +0 -1
  18. package/.codeclimate.yml +0 -22
  19. package/.editorconfig +0 -12
  20. package/.eslintrc +0 -20
  21. package/.gitattributes +0 -17
  22. package/.log-progress.json +0 -9
  23. package/.nycrc +0 -6
  24. package/.travis.yml +0 -9
  25. package/CHANGELOG.md +0 -263
  26. package/CLAUDE.md +0 -11
  27. package/dist/es6/fsl_parser.js +0 -1
  28. package/dist/es6/jssm.js +0 -3320
  29. package/dist/es6/jssm_arrow.js +0 -211
  30. package/dist/es6/jssm_compiler.js +0 -380
  31. package/dist/es6/jssm_constants.js +0 -121
  32. package/dist/es6/jssm_error.js +0 -47
  33. package/dist/es6/jssm_theme.js +0 -24
  34. package/dist/es6/jssm_types.js +0 -3
  35. package/dist/es6/jssm_util.js +0 -337
  36. package/dist/es6/jssm_viz.js +0 -560
  37. package/dist/es6/jssm_viz_colors.js +0 -63
  38. package/dist/es6/themes/jssm_base_stylesheet.d.ts +0 -11
  39. package/dist/es6/themes/jssm_base_stylesheet.js +0 -58
  40. package/dist/es6/themes/jssm_theme_bold.d.ts +0 -11
  41. package/dist/es6/themes/jssm_theme_bold.js +0 -58
  42. package/dist/es6/themes/jssm_theme_default.d.ts +0 -11
  43. package/dist/es6/themes/jssm_theme_default.js +0 -58
  44. package/dist/es6/themes/jssm_theme_modern.d.ts +0 -11
  45. package/dist/es6/themes/jssm_theme_modern.js +0 -58
  46. package/dist/es6/themes/jssm_theme_ocean.d.ts +0 -11
  47. package/dist/es6/themes/jssm_theme_ocean.js +0 -56
  48. package/dist/es6/themes/jssm_theme_plain.d.ts +0 -11
  49. package/dist/es6/themes/jssm_theme_plain.js +0 -70
  50. package/dist/es6/version.js +0 -2
  51. package/dist/jssm.es5.nonmin.cjs +0 -24506
  52. package/dist/jssm.es6.nonmin.cjs +0 -24473
  53. package/dist/jssm_viz.es5.iife.nonmin.cjs +0 -24679
  54. package/dist/jssm_viz.es5.nonmin.cjs +0 -24674
  55. package/dist/jssm_viz.es6.nonmin.cjs +0 -24661
  56. package/jest-dragon.config.cjs +0 -36
  57. package/jest-spec.config.cjs +0 -36
  58. package/jest-stoch.config.cjs +0 -36
  59. package/jest-unicode.config.cjs +0 -36
  60. package/log-progress.data.json +0 -28
  61. package/rollup.config.deno.js +0 -44
  62. package/rollup.config.es5.js +0 -52
  63. package/rollup.config.es6.js +0 -55
  64. package/rollup.config.viz.es5.js +0 -46
  65. package/rollup.config.viz.es6.js +0 -46
  66. package/rollup.config.viz.iife.js +0 -36
  67. package/tutorial_learn_testing.md +0 -168
  68. package/typedoc-options.cjs +0 -69
  69. /package/dist/{es6 → deno}/fsl_parser.d.ts +0 -0
  70. /package/dist/{es6 → deno}/jssm.d.ts +0 -0
  71. /package/dist/{es6 → deno}/jssm_arrow.d.ts +0 -0
  72. /package/dist/{es6 → deno}/jssm_compiler.d.ts +0 -0
  73. /package/dist/{es6 → deno}/jssm_error.d.ts +0 -0
  74. /package/dist/{es6 → deno}/jssm_theme.d.ts +0 -0
  75. /package/dist/{es6 → deno}/jssm_util.d.ts +0 -0
  76. /package/dist/{es6 → deno}/jssm_viz.d.ts +0 -0
  77. /package/dist/{es6 → deno}/jssm_viz_colors.d.ts +0 -0
  78. /package/dist/{es6 → deno}/version.d.ts +0 -0
@@ -1,560 +0,0 @@
1
- import * as jssm from './jssm';
2
- import { JssmError } from './jssm_error';
3
- import { default_viz_colors } from './jssm_viz_colors';
4
- import { version, build_time } from './version';
5
- /**
6
- * Cached resolved viz.js instance. Populated on first call to
7
- * {@link get_viz}; later calls reuse it directly. Internal.
8
- */
9
- let viz_instance = null;
10
- /**
11
- * DOM parser injected via {@link configure} for environments without a
12
- * global `DOMParser` (e.g. Node). Internal.
13
- */
14
- let injected_dom_parser = null;
15
- /**
16
- * Returns a cached @viz-js/viz instance, lazily instantiated on first call.
17
- * Internal helper for the rendering functions.
18
- *
19
- * @internal
20
- */
21
- async function get_viz() {
22
- if (viz_instance === null) {
23
- const mod = await import('@viz-js/viz');
24
- viz_instance = await mod.instance();
25
- }
26
- return viz_instance;
27
- }
28
- /**
29
- * Inject runtime configuration for jssm/viz. Currently only accepts a
30
- * custom `DOMParser` constructor for use by `*_svg_element` functions in
31
- * environments that do not provide one globally (e.g. Node + jsdom).
32
- *
33
- * Idempotent — last call wins. No-op if called with no recognized keys.
34
- *
35
- * ```typescript
36
- * // Node, with jsdom:
37
- * import { JSDOM } from 'jsdom';
38
- * import { configure, fsl_to_svg_element } from 'jssm/viz';
39
- *
40
- * configure({ DOMParser: new JSDOM().window.DOMParser });
41
- * const el = await fsl_to_svg_element('a -> b;');
42
- * ```
43
- *
44
- * @param opts Configuration overrides.
45
- * @param opts.DOMParser Constructor compatible with the WHATWG `DOMParser`
46
- * interface. Used as a fallback when `globalThis.DOMParser` is undefined.
47
- *
48
- * @throws {JssmError} if `DOMParser` is provided and is not a constructor.
49
- */
50
- function configure(opts) {
51
- if (opts.DOMParser !== undefined) {
52
- if (typeof opts.DOMParser !== 'function') {
53
- throw new JssmError(undefined, 'jssm/viz: configure({ DOMParser }) — value must be a constructor');
54
- }
55
- injected_dom_parser = opts.DOMParser;
56
- }
57
- }
58
- /**
59
- * Look up a color from the default viz palette by key, returning empty
60
- * string if the key is unknown (so it disappears in feature concatenation).
61
- *
62
- * @internal
63
- */
64
- function vc(col) {
65
- var _a;
66
- return (_a = default_viz_colors[col]) !== null && _a !== void 0 ? _a : '';
67
- }
68
- /**
69
- * Build a graphviz-safe node identifier for a state, by index. Accepts
70
- * either a `string[]` (used historically; O(n) per call) or a
71
- * precomputed `Map<state, index>` (used by rendering hot paths; O(1)
72
- * per call). The map form is used during dot generation; the array
73
- * form is retained for direct test access via `_test`.
74
- *
75
- * @internal
76
- */
77
- function node_of(state, state_index) {
78
- return Array.isArray(state_index)
79
- ? `n${state_index.indexOf(state)}`
80
- : `n${state_index.get(state)}`;
81
- }
82
- /**
83
- * Convert an 8-channel hex color (`#RRGGBBAA`) to a 6-channel hex color
84
- * (`#RRGGBB`), discarding the alpha channel. Throws if the input is not
85
- * a 9-character `#`-prefixed string.
86
- *
87
- * Graphviz dot does not support alpha; this is a lossy projection.
88
- *
89
- * @internal
90
- */
91
- function color8to6(color8) {
92
- if ((color8.length !== 9) || (color8[0] !== '#')) {
93
- throw new JssmError(undefined, `not a color8: ${color8}`);
94
- }
95
- return `#${color8.substring(1, 7)}`;
96
- }
97
- /**
98
- * Variant of {@link color8to6} that passes `undefined` through.
99
- *
100
- * @internal
101
- */
102
- function u_color8to6(color8) {
103
- return color8 === undefined ? undefined : color8to6(color8);
104
- }
105
- /**
106
- * Read the graphviz shape for a state through {@link jssm.Machine.style_for},
107
- * so theme-supplied shapes are honoured along with per-state declarations.
108
- * Returns `undefined` if neither a theme nor a state declaration supplies a
109
- * shape.
110
- *
111
- * @internal
112
- */
113
- function shape_for_state(u_jssm, state) {
114
- return u_jssm.style_for(state).shape;
115
- }
116
- /**
117
- * Read the image filename for a state through {@link jssm.Machine.style_for},
118
- * so theme-supplied images are honoured along with per-state declarations.
119
- * Returns `undefined` if neither a theme nor a state declaration supplies an
120
- * image.
121
- *
122
- * @internal
123
- */
124
- function image_for_state(u_jssm, state) {
125
- return u_jssm.style_for(state).image;
126
- }
127
- /**
128
- * Compose a graphviz `style` string from a pre-computed
129
- * {@link jssm.JssmStateConfig}, combining its `corners` and `lineStyle`
130
- * fields. Returns either the empty string (when neither field is set
131
- * anywhere — state declaration nor theme) or a `corners,line,filled`-shape
132
- * string.
133
- *
134
- * Production callers should pass the result of `u_jssm.style_for(state)`
135
- * so theme-supplied values are honoured uniformly with the rest of the
136
- * rendering pipeline.
137
- *
138
- * @internal
139
- */
140
- function compose_style_string(style) {
141
- var _a, _b;
142
- if (style.corners === undefined && style.lineStyle === undefined) {
143
- return '';
144
- }
145
- const corners_map = { rounded: 'rounded', lined: 'diagonals', regular: 'regular' };
146
- const lines_map = { dashed: 'dashed', dotted: 'dotted', solid: 'solid' };
147
- const corners = corners_map[(_a = style.corners) !== null && _a !== void 0 ? _a : 'regular'];
148
- const lines = lines_map[(_b = style.lineStyle) !== null && _b !== void 0 ? _b : 'solid'];
149
- return `${corners},${lines},filled`;
150
- }
151
- /**
152
- * Compose a graphviz `style` string for a state by looking up its merged
153
- * style via {@link jssm.Machine.style_for}, then delegating to
154
- * {@link compose_style_string}. Theme-supplied `corners` and `lineStyle`
155
- * are honoured along with per-state declarations.
156
- *
157
- * @internal
158
- */
159
- function style_for_state(u_jssm, state) {
160
- return compose_style_string(u_jssm.style_for(state));
161
- }
162
- /**
163
- * Convert an FSL flow direction (`up`/`right`/`down`/`left`) to a graphviz
164
- * `rankdir=` declaration line. Throws on unknown input.
165
- *
166
- * @internal
167
- */
168
- function flow_direction_to_rankdir(flow_direction) {
169
- switch (flow_direction) {
170
- case 'up': return 'rankdir=BT;';
171
- case 'right': return 'rankdir=LR;';
172
- case 'down': return 'rankdir=TB;';
173
- case 'left': return 'rankdir=RL;';
174
- default: throw new JssmError(undefined, `unknown flow direction '${flow_direction}'`);
175
- }
176
- }
177
- /**
178
- * Build the graphviz `digraph G { ... }` envelope from rendered fragments.
179
- *
180
- * @internal
181
- */
182
- function dot_template(rank_dir, graph_bg_color, nodes, edges, arranges, preamble = '') {
183
- return `digraph G {
184
- ${preamble}
185
-
186
- ${rank_dir}
187
- fontname="Open Sans";
188
- style=filled;
189
- bgcolor="${graph_bg_color}";
190
- node [fontsize=14; shape=box; style=filled; fillcolor=white; fontname="Times New Roman"];
191
- edge [fontsize=6; fontname="Open Sans"];
192
-
193
- ${nodes}
194
-
195
- ${edges}
196
-
197
- ${arranges}
198
- }`;
199
- }
200
- /**
201
- * Compute state-kind classification for every state once per render.
202
- * Replaces per-edge calls to `state_is_complete` / `state_is_terminal`
203
- * (the latter rebuilds a fresh `list_exits` array each call) with O(1)
204
- * Map lookups. Significant win on machines with many edges.
205
- *
206
- * The conjunction (`final` = complete AND terminal) is computed directly
207
- * rather than via `state_is_final`, which returns the disjunction
208
- * (terminal OR complete) and would collapse the three named buckets
209
- * into two — see the type docstring above.
210
- *
211
- * @internal
212
- */
213
- function classify_states(u_jssm, l_states) {
214
- const kinds = new Map();
215
- for (const s of l_states) {
216
- const is_complete = u_jssm.state_is_complete(s);
217
- const is_terminal = u_jssm.state_is_terminal(s);
218
- if (is_complete && is_terminal) {
219
- kinds.set(s, 'final');
220
- }
221
- else if (is_complete) {
222
- kinds.set(s, 'complete');
223
- }
224
- else if (is_terminal) {
225
- kinds.set(s, 'terminal');
226
- }
227
- else {
228
- kinds.set(s, 'base');
229
- }
230
- }
231
- return kinds;
232
- }
233
- /**
234
- * Pick the default fill color for a state, by state-kind precedence
235
- * (final > complete > terminal > none). Returns empty string if no
236
- * kind applies.
237
- *
238
- * @internal
239
- */
240
- function default_fillcolor_for(kind) {
241
- switch (kind) {
242
- case 'final': return vc('fill_final');
243
- case 'complete': return vc('fill_complete');
244
- case 'terminal': return vc('fill_terminal');
245
- default: return '';
246
- }
247
- }
248
- /**
249
- * Render the node-feature list for one machine, one node per state.
250
- * All style reads route through {@link jssm.Machine.style_for} so that
251
- * theme-supplied values (corners, lineStyle, image, shape, colours) are
252
- * honoured uniformly. A single `style_for` call per state — downstream
253
- * helpers operate on the cached result rather than re-querying.
254
- *
255
- * @internal
256
- */
257
- function states_to_nodes_string(u_jssm, l_states, state_index, state_kinds) {
258
- return l_states.map((s) => {
259
- var _a;
260
- const style = u_jssm.style_for(s);
261
- const fillcolor = style.backgroundColor || default_fillcolor_for((_a = state_kinds.get(s)) !== null && _a !== void 0 ? _a : 'base');
262
- const features = [
263
- ['label', u_jssm.display_text(s)],
264
- ['shape', style.shape || ''],
265
- ['color', style.borderColor || ''],
266
- ['style', compose_style_string(style)],
267
- ['fontcolor', style.textColor || ''],
268
- ['image', style.image || ''],
269
- ['fillcolor', fillcolor]
270
- ]
271
- .filter(r => r[1])
272
- .map(r => `${r[0]}="${r[1]}"`)
273
- .join(' ');
274
- return `${node_of(s, state_index)} [${features}];`;
275
- }).join(' ');
276
- }
277
- /**
278
- * Compose a multi-line `action\nprobability` label for a transition.
279
- * Returns `undefined` when both fields are absent, so callers can skip
280
- * emitting the attribute entirely.
281
- *
282
- * @internal
283
- */
284
- function transition_label(tr) {
285
- if (!tr) {
286
- return undefined;
287
- }
288
- const parts = [`${tr.action || ''}`, `${tr.probability || ''}`].filter(x => x !== '');
289
- return parts.length ? parts.join('\n') : undefined;
290
- }
291
- /**
292
- * Pick the graphviz arrowhead style for a transition, by transition kind
293
- * (forced > main > normal).
294
- *
295
- * @internal
296
- */
297
- function arrow_for(tr) {
298
- if (!tr) {
299
- return '';
300
- }
301
- if (tr.forced_only) {
302
- return 'ediamond';
303
- }
304
- if (tr.main_path) {
305
- return 'normal;weight=5';
306
- }
307
- return 'empty';
308
- }
309
- /**
310
- * Pick the line color for a transition end-position from a precomputed
311
- * state-kind classification (final > complete > terminal > base).
312
- *
313
- * @internal
314
- */
315
- function line_color(kind, lkind, suffix) {
316
- switch (kind) {
317
- case 'final': return vc(`${lkind}_final${suffix}`);
318
- case 'complete': return vc(`${lkind}_complete${suffix}`);
319
- case 'terminal': return vc(`${lkind}_terminal${suffix}`);
320
- default: return vc(`${lkind}${suffix}`);
321
- }
322
- }
323
- /**
324
- * Pick the text color for a transition label end-position from a precomputed
325
- * state-kind classification (final > complete > terminal > none).
326
- *
327
- * @internal
328
- */
329
- function text_color(kind, suffix) {
330
- switch (kind) {
331
- case 'final': return vc(`text_final${suffix}`);
332
- case 'complete': return vc(`text_complete${suffix}`);
333
- case 'terminal': return vc(`text_terminal${suffix}`);
334
- default: return '';
335
- }
336
- }
337
- /**
338
- * Build the colored-HTML `headlabel=` / `taillabel=` fragment for a
339
- * transition end, concatenating `name`, `probability`, and `action`
340
- * fields when present. Returns the empty string when nothing should
341
- * be emitted.
342
- *
343
- * Historical note: the original jssm-viz code passed `JssmTransitionList`
344
- * wrappers to this builder by mistake, so this colored-HTML label path
345
- * silently produced empty strings for years; only the simpler
346
- * `taillabel="..."` form below kept user-visible labels rendering.
347
- * Fixed during the merge.
348
- *
349
- * @internal
350
- */
351
- function colored_label(tr, which, color) {
352
- if (!tr) {
353
- return '';
354
- }
355
- const text = [tr.name, tr.probability, tr.action].filter(q => q).join('<br/>');
356
- if (!text) {
357
- return '';
358
- }
359
- const body = color ? `<<font color="${color}">${text}</font>>` : `"${text}"`;
360
- return `${which}=${body};`;
361
- }
362
- /**
363
- * Render the edge-feature list, including bidirectional fold-up and
364
- * per-direction action / probability labels. Suppressed-edge tracking
365
- * uses an internally-owned `Set<string>` keyed by `"from|to"` for O(1)
366
- * duplicate detection, replacing the previous `[string, string][]`
367
- * accumulator and O(n) `find` probe.
368
- *
369
- * @internal
370
- */
371
- function states_to_edges_string(u_jssm, l_states, state_index, state_kinds) {
372
- const doublequote = (txt) => txt.replace(/"/g, '\\"');
373
- const strike = new Set();
374
- const kind_of = (s) => { var _a; return (_a = state_kinds.get(s)) !== null && _a !== void 0 ? _a : 'base'; };
375
- return l_states.map((s) => u_jssm.list_exits(s).map((ex) => {
376
- if (strike.has(`${s}|${ex}`)) {
377
- return '';
378
- }
379
- const edge_tr = u_jssm.lookup_transition_for(s, ex);
380
- if (!edge_tr) {
381
- return '';
382
- } // belt-and-suspenders; list_exits should always have a corresponding transition
383
- const pair_tr = u_jssm.lookup_transition_for(ex, s);
384
- const double = (pair_tr !== undefined) && (s !== ex);
385
- const s_kind = kind_of(s);
386
- const ex_kind = kind_of(ex);
387
- // colored-HTML labels (per-direction, with text colors)
388
- const headColor = text_color(s_kind, double ? '_1' : '_solo');
389
- const tailColor = text_color(ex_kind, double ? '_2' : '_solo');
390
- const labelInline = colored_label(double ? pair_tr : undefined, 'headlabel', headColor) +
391
- colored_label(edge_tr, 'taillabel', tailColor);
392
- // plain `headlabel="..."` / `taillabel="..."` fallback
393
- const label = transition_label(edge_tr);
394
- const rlabel = transition_label(pair_tr);
395
- const maybeLabel = label ? `taillabel="${doublequote(label)}";` : '';
396
- const maybeRLabel = rlabel ? `headlabel="${doublequote(rlabel)}";` : '';
397
- const arrowHead = arrow_for(edge_tr);
398
- const arrowTail = arrow_for(pair_tr);
399
- const edgeInline = double
400
- ? `${maybeLabel}${maybeRLabel}arrowhead=${arrowHead};arrowtail=${arrowTail};dir=both;color="${line_color(ex_kind, edge_tr.kind, '_1')}:${line_color(s_kind, (pair_tr !== null && pair_tr !== void 0 ? pair_tr : { kind: 'legal' }).kind, '_2')}"`
401
- : `${maybeLabel}arrowhead=${arrowHead};color="${line_color(ex_kind, edge_tr.kind, '_solo')}"`;
402
- if (pair_tr) {
403
- strike.add(`${ex}|${s}`);
404
- }
405
- return `${node_of(s, state_index)}->${node_of(ex, state_index)} [${labelInline}${edgeInline}];`;
406
- }).join(' ')).join(' ');
407
- }
408
- /**
409
- * Render `arrange`, `arrange_start`, and `arrange_end` declarations to
410
- * rank-grouped subgraphs (`rank=same`/`rank=min`/`rank=max`).
411
- *
412
- * @internal
413
- */
414
- function arranges_for(u_jssm, state_index) {
415
- const group = (decls, rank) => decls
416
- ? decls.map(d => `{rank=${rank}; ${d.map(di => node_of(di, state_index)).join('; ')};};`).join('\n')
417
- : '';
418
- return group(u_jssm._arrange_declaration, 'same')
419
- + group(u_jssm._arrange_start_declaration, 'min')
420
- + group(u_jssm._arrange_end_declaration, 'max');
421
- }
422
- /**
423
- * Render a {@link jssm.Machine} as a graphviz dot string.
424
- *
425
- * ```typescript
426
- * import { sm } from 'jssm';
427
- * import { machine_to_dot } from 'jssm/viz';
428
- *
429
- * const dot = machine_to_dot(sm`a -> b;`);
430
- * // 'digraph G { ... }'
431
- * ```
432
- *
433
- * @param u_jssm The machine to render.
434
- * @returns A complete graphviz dot source string.
435
- */
436
- function machine_to_dot(u_jssm) {
437
- const l_states = u_jssm.states();
438
- const state_index = new Map(l_states.map((s, i) => [s, i]));
439
- const state_kinds = classify_states(u_jssm, l_states);
440
- const nodes = states_to_nodes_string(u_jssm, l_states, state_index, state_kinds);
441
- const edges = states_to_edges_string(u_jssm, l_states, state_index, state_kinds);
442
- const arranges = arranges_for(u_jssm, state_index);
443
- const rank_dir = flow_direction_to_rankdir(u_jssm.flow() || 'down');
444
- const preamble = u_jssm.dot_preamble() || '';
445
- return dot_template(rank_dir, vc('graph_bg_color'), nodes, edges, arranges, preamble);
446
- }
447
- /**
448
- * Render an FSL string directly to graphviz dot source.
449
- *
450
- * ```typescript
451
- * import { fsl_to_dot } from 'jssm/viz';
452
- * const dot = fsl_to_dot('a -> b;');
453
- * ```
454
- *
455
- * @param fsl The FSL source.
456
- * @returns A complete graphviz dot source string.
457
- */
458
- function fsl_to_dot(fsl) {
459
- return machine_to_dot(jssm.sm `${fsl}`);
460
- }
461
- /**
462
- * Render a graphviz dot source string to SVG using `@viz-js/viz`. The
463
- * underlying viz instance is lazy-initialized on first call and cached for
464
- * the lifetime of the module.
465
- *
466
- * ```typescript
467
- * const svg = await dot_to_svg('digraph G { a -> b }');
468
- * ```
469
- *
470
- * @param dot Graphviz dot source.
471
- * @returns A promise resolving to an SVG XML string.
472
- */
473
- async function dot_to_svg(dot) {
474
- const viz = await get_viz();
475
- return viz.renderString(dot, { format: 'svg' });
476
- }
477
- /**
478
- * Render an FSL string directly to SVG.
479
- *
480
- * @param fsl The FSL source.
481
- * @returns A promise resolving to an SVG XML string.
482
- */
483
- async function fsl_to_svg_string(fsl) {
484
- return dot_to_svg(fsl_to_dot(fsl));
485
- }
486
- /**
487
- * Render a {@link jssm.Machine} to SVG.
488
- *
489
- * @param u_jssm The machine to render.
490
- * @returns A promise resolving to an SVG XML string.
491
- */
492
- async function machine_to_svg_string(u_jssm) {
493
- return dot_to_svg(machine_to_dot(u_jssm));
494
- }
495
- /**
496
- * Resolve a `DOMParser` constructor: prefer `globalThis.DOMParser` (browsers,
497
- * jsdom test environment), fall back to the value passed to {@link configure},
498
- * throw `JssmError` if neither is available.
499
- *
500
- * @internal
501
- */
502
- function get_dom_parser() {
503
- if (typeof globalThis.DOMParser === 'function') {
504
- return globalThis.DOMParser;
505
- }
506
- if (injected_dom_parser !== null) {
507
- return injected_dom_parser;
508
- }
509
- throw new JssmError(undefined, 'jssm/viz: *_svg_element requires a browser DOM. Use *_svg_string in Node, or call configure({ DOMParser }) with a parser from jsdom or @xmldom/xmldom.');
510
- }
511
- /**
512
- * Render dot source to a parsed `SVGSVGElement`. Browser-by-default; in
513
- * Node, requires a `DOMParser` to have been injected via {@link configure}.
514
- *
515
- * @param dot Graphviz dot source.
516
- * @returns A promise resolving to a parsed `SVGSVGElement`.
517
- * @throws {JssmError} if no `DOMParser` is available.
518
- */
519
- async function dot_to_svg_element(dot) {
520
- const ParserCtor = get_dom_parser();
521
- const svg_string = await dot_to_svg(dot);
522
- const parser = new ParserCtor();
523
- const doc = parser.parseFromString(svg_string, 'image/svg+xml');
524
- return doc.documentElement;
525
- }
526
- /**
527
- * Render an FSL string directly to a parsed `SVGSVGElement`.
528
- *
529
- * @param fsl The FSL source.
530
- * @returns A promise resolving to a parsed `SVGSVGElement`.
531
- * @throws {JssmError} if no `DOMParser` is available (Node without `configure`).
532
- */
533
- async function fsl_to_svg_element(fsl) {
534
- return dot_to_svg_element(fsl_to_dot(fsl));
535
- }
536
- /**
537
- * Render a {@link jssm.Machine} to a parsed `SVGSVGElement`.
538
- *
539
- * @param u_jssm The machine to render.
540
- * @returns A promise resolving to a parsed `SVGSVGElement`.
541
- * @throws {JssmError} if no `DOMParser` is available (Node without `configure`).
542
- */
543
- async function machine_to_svg_element(u_jssm) {
544
- return dot_to_svg_element(machine_to_dot(u_jssm));
545
- }
546
- /**
547
- * Compatibility wrapper for {@link machine_to_dot}, retained from
548
- * jssm-viz. Will be removed in the next major.
549
- *
550
- * @deprecated Use {@link machine_to_dot} instead.
551
- */
552
- function dot(machine) {
553
- return machine_to_dot(machine);
554
- }
555
- export { configure, dot, dot_to_svg, fsl_to_dot, fsl_to_svg_string, fsl_to_svg_element, machine_to_dot, machine_to_svg_string, machine_to_svg_element, version, build_time };
556
- /** @internal — test-only access to private helpers. */
557
- export const _test = {
558
- color8to6, u_color8to6, vc, node_of,
559
- shape_for_state, image_for_state, style_for_state
560
- };
@@ -1,63 +0,0 @@
1
- /**
2
- * Default color palette for jssm/viz dot/svg output. Used by the graphviz
3
- * rendering helpers in jssm_viz.ts to colorize nodes and edges based on
4
- * state type (terminal/final/complete/normal) and arrow kind
5
- * (legal/main/forced).
6
- *
7
- * Keys are flat strings of the form `<arrow_kind>_<modifier>_<position>`
8
- * (e.g. `legal_final_solo`, `main_terminal_2`); also the special node fill
9
- * colors (`fill_final`, `fill_terminal`, `fill_complete`) and the graph
10
- * background.
11
- */
12
- const default_viz_colors = {
13
- 'graph_bg_color': '#eeeeee',
14
- 'fill_final': '#ddddff',
15
- 'fill_terminal': '#ffdddd',
16
- 'fill_complete': '#ddffdd',
17
- 'legal_1': '#888888',
18
- 'legal_2': '#777777',
19
- 'legal_solo': '#777777',
20
- 'legal_final_1': '#7777aa',
21
- 'legal_final_2': '#666699',
22
- 'legal_final_solo': '#666699',
23
- 'legal_terminal_1': '#aa7777',
24
- 'legal_terminal_2': '#996666',
25
- 'legal_terminal_solo': '#996666',
26
- 'legal_complete_1': '#77aa77',
27
- 'legal_complete_2': '#669966',
28
- 'legal_complete_solo': '#669966',
29
- 'main_1': '#444444',
30
- 'main_2': '#333333',
31
- 'main_solo': '#333333',
32
- 'main_final_1': '#333366',
33
- 'main_final_2': '#222255',
34
- 'main_final_solo': '#222255',
35
- 'main_terminal_1': '#663333',
36
- 'main_terminal_2': '#552222',
37
- 'main_terminal_solo': '#552222',
38
- 'main_complete_1': '#336633',
39
- 'main_complete_2': '#225522',
40
- 'main_complete_solo': '#225522',
41
- 'forced_1': '#cccccc',
42
- 'forced_2': '#bbbbbb',
43
- 'forced_solo': '#bbbbbb',
44
- 'forced_final_1': '#bbbbee',
45
- 'forced_final_2': '#aaaadd',
46
- 'forced_final_solo': '#aaaadd',
47
- 'forced_terminal_1': '#eebbbb',
48
- 'forced_terminal_2': '#ddaaaa',
49
- 'forced_terminal_solo': '#ddaaaa',
50
- 'forced_complete_1': '#bbeebb',
51
- 'forced_complete_2': '#aaddaa',
52
- 'forced_complete_solo': '#aaddaa',
53
- 'text_final_1': '#000088',
54
- 'text_final_2': '#000088',
55
- 'text_final_solo': '#000088',
56
- 'text_terminal_1': '#880000',
57
- 'text_terminal_2': '#880000',
58
- 'text_terminal_solo': '#880000',
59
- 'text_complete_1': '#007700',
60
- 'text_complete_2': '#007700',
61
- 'text_complete_solo': '#007700'
62
- };
63
- export { default_viz_colors };
@@ -1,11 +0,0 @@
1
- import { JssmStateConfig, JssmBaseTheme } from '../jssm_types';
2
- declare const base_state_style: JssmStateConfig;
3
- declare const base_active_state_style: JssmStateConfig;
4
- declare const base_terminal_state_style: JssmStateConfig;
5
- declare const base_active_terminal_state_style: JssmStateConfig;
6
- declare const base_start_state_style: JssmStateConfig;
7
- declare const base_active_start_state_style: JssmStateConfig;
8
- declare const base_end_state_style: JssmStateConfig;
9
- declare const base_active_end_state_style: JssmStateConfig;
10
- declare const base_theme: JssmBaseTheme;
11
- export { base_state_style, base_active_state_style, base_terminal_state_style, base_active_terminal_state_style, base_start_state_style, base_active_start_state_style, base_end_state_style, base_active_end_state_style, base_theme, base_theme as theme };
@@ -1,58 +0,0 @@
1
- const base_state_style = {
2
- shape: 'rectangle',
3
- backgroundColor: 'white',
4
- textColor: 'black',
5
- borderColor: 'black'
6
- };
7
- const base_active_state_style = {
8
- textColor: 'white',
9
- backgroundColor: 'dodgerblue4'
10
- };
11
- const base_hooked_state_style = {
12
- shape: 'component'
13
- };
14
- const base_terminal_state_style = {
15
- textColor: 'white',
16
- backgroundColor: 'crimson'
17
- };
18
- const base_active_terminal_state_style = {
19
- textColor: 'white',
20
- backgroundColor: 'indigo'
21
- };
22
- const base_start_state_style = {
23
- backgroundColor: 'yellow'
24
- };
25
- const base_active_start_state_style = {
26
- backgroundColor: 'yellowgreen'
27
- };
28
- const base_active_hooked_state_style = {
29
- backgroundColor: 'yellowgreen'
30
- };
31
- const base_end_state_style = {
32
- textColor: 'white',
33
- backgroundColor: 'darkolivegreen'
34
- };
35
- const base_active_end_state_style = {
36
- textColor: 'white',
37
- backgroundColor: 'darkgreen'
38
- };
39
- const base_theme = {
40
- name: 'base',
41
- state: base_state_style,
42
- start: base_start_state_style,
43
- end: base_end_state_style,
44
- terminal: base_terminal_state_style,
45
- hooked: base_hooked_state_style,
46
- active: base_active_state_style,
47
- active_start: base_active_start_state_style,
48
- active_end: base_active_end_state_style,
49
- active_terminal: base_active_terminal_state_style,
50
- active_hooked: base_active_hooked_state_style,
51
- legal: undefined,
52
- main: undefined,
53
- forced: undefined,
54
- action: undefined,
55
- graph: undefined,
56
- title: undefined // TODO FIXME
57
- };
58
- export { base_state_style, base_active_state_style, base_terminal_state_style, base_active_terminal_state_style, base_start_state_style, base_active_start_state_style, base_end_state_style, base_active_end_state_style, base_theme, base_theme as theme };