jssm 5.124.1 → 5.125.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.
- package/README.md +6 -6
- package/dist/cdn/viz.js +105 -10
- package/dist/cli/fsl-render.cjs +1 -1
- package/dist/cli/fsl.cjs +1 -1
- package/dist/deno/README.md +6 -6
- package/dist/deno/jssm.js +1 -1
- package/dist/deno/jssm_viz.d.ts +78 -6
- package/dist/jssm.es5.cjs +1 -1
- package/dist/jssm.es5.iife.js +1 -1
- package/dist/jssm.es6.mjs +1 -1
- package/dist/jssm_viz.cjs +1 -1
- package/dist/jssm_viz.iife.cjs +1 -1
- package/dist/jssm_viz.mjs +1 -1
- package/jssm_viz.es5.d.cts +78 -6
- package/jssm_viz.es6.d.ts +78 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,10 +18,10 @@ Please edit the file it's derived from, instead: `./src/md/readme_base.md`
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
* Generated for version 5.
|
|
21
|
+
* Generated for version 5.125.0 at 5/19/2026, 6:05:01 PM
|
|
22
22
|
|
|
23
23
|
-->
|
|
24
|
-
# jssm 5.
|
|
24
|
+
# jssm 5.125.0
|
|
25
25
|
|
|
26
26
|
[**Try the live editor**](https://stonecypher.github.io/jssm-viz-demo/graph_explorer.html) ·
|
|
27
27
|
[Documentation](https://stonecypher.github.io/jssm/docs/) ·
|
|
@@ -281,7 +281,7 @@ That decision shows up everywhere downstream:
|
|
|
281
281
|
or run `npm run benny` against your own machine.
|
|
282
282
|
|
|
283
283
|
- **More thoroughly tested than any other JavaScript state-machine
|
|
284
|
-
library.** 6,
|
|
284
|
+
library.** 6,095 tests at 100.0% line coverage
|
|
285
285
|
([report](https://coveralls.io/github/StoneCypher/jssm)), plus
|
|
286
286
|
fuzz testing via `fast-check`, with parser test data across ten natural
|
|
287
287
|
languages and Emoji.
|
|
@@ -414,11 +414,11 @@ If your contribution is missing here, please open an issue.
|
|
|
414
414
|
|
|
415
415
|
<br/>
|
|
416
416
|
|
|
417
|
-
***6,
|
|
417
|
+
***6,095 tests***, run 56,882 times.
|
|
418
418
|
|
|
419
|
-
- 5,
|
|
419
|
+
- 5,582 specs with 100.0% coverage
|
|
420
420
|
- 513 fuzz tests with 4.5% coverage
|
|
421
|
-
- 4,
|
|
421
|
+
- 4,355 TypeScript lines - 1.4 tests per line, 13.1 generated tests per line
|
|
422
422
|
|
|
423
423
|
[](https://github.com/StoneCypher/jssm/actions)
|
|
424
424
|
[](https://www.npmjs.com/package/jssm)
|
package/dist/cdn/viz.js
CHANGED
|
@@ -21041,7 +21041,7 @@ var constants = /*#__PURE__*/Object.freeze({
|
|
|
21041
21041
|
* Useful for runtime diagnostics and for embedding in serialized machine
|
|
21042
21042
|
* snapshots so that deserializers can detect version-skew.
|
|
21043
21043
|
*/
|
|
21044
|
-
const version = "5.
|
|
21044
|
+
const version = "5.125.0";
|
|
21045
21045
|
|
|
21046
21046
|
// whargarbl lots of these return arrays could/should be sets
|
|
21047
21047
|
const { state_name_chars, state_name_first_chars, action_label_chars } = constants;
|
|
@@ -24357,18 +24357,113 @@ function vc(col) {
|
|
|
24357
24357
|
return (_a = default_viz_colors[col]) !== null && _a !== void 0 ? _a : '';
|
|
24358
24358
|
}
|
|
24359
24359
|
/**
|
|
24360
|
-
*
|
|
24361
|
-
*
|
|
24362
|
-
*
|
|
24363
|
-
*
|
|
24364
|
-
*
|
|
24360
|
+
* Convert a state name into a URL-friendly slug suitable for use as the
|
|
24361
|
+
* body of a dot/SVG node identifier. The transformation is:
|
|
24362
|
+
*
|
|
24363
|
+
* 1. Lowercase
|
|
24364
|
+
* 2. Any run of characters outside `[a-z0-9]` (after lowercasing) becomes
|
|
24365
|
+
* a single `-`
|
|
24366
|
+
* 3. Leading and trailing `-` are trimmed
|
|
24367
|
+
*
|
|
24368
|
+
* If the result is empty (e.g. for a state named `"!!!"`), the empty
|
|
24369
|
+
* string is returned — callers are expected to fall back to an indexed
|
|
24370
|
+
* placeholder like `node-N`. See {@link slug_states} for the collision-
|
|
24371
|
+
* resolving wrapper that consumes this helper.
|
|
24372
|
+
*
|
|
24373
|
+
* ```typescript
|
|
24374
|
+
* slug_for('Green Light'); // 'green-light'
|
|
24375
|
+
* slug_for('!!!'); // ''
|
|
24376
|
+
* slug_for(' Foo Bar '); // 'foo-bar'
|
|
24377
|
+
* ```
|
|
24378
|
+
*
|
|
24379
|
+
* @param state The state name to slugify.
|
|
24380
|
+
* @returns The lowercase hyphen-separated slug, or empty string if none of
|
|
24381
|
+
* the characters were retainable.
|
|
24382
|
+
*
|
|
24383
|
+
* @internal
|
|
24384
|
+
*/
|
|
24385
|
+
function slug_for(state) {
|
|
24386
|
+
return state
|
|
24387
|
+
.toLowerCase()
|
|
24388
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
24389
|
+
.replace(/^-+|-+$/g, '');
|
|
24390
|
+
}
|
|
24391
|
+
/**
|
|
24392
|
+
* Build a `Map<state, slug>` assigning every state in `states` a unique,
|
|
24393
|
+
* deterministic, URL-safe slug used as its dot/SVG node identifier.
|
|
24394
|
+
*
|
|
24395
|
+
* Algorithm:
|
|
24396
|
+
*
|
|
24397
|
+
* 1. Slug each state via {@link slug_for}. States whose slug comes out
|
|
24398
|
+
* empty fall back to `node-N`, where `N` is the state's declaration
|
|
24399
|
+
* index (1-based, to match user-visible numbering).
|
|
24400
|
+
* 2. Walk the state list in declaration order, tracking how many times
|
|
24401
|
+
* each base slug has already been used. The first occurrence keeps
|
|
24402
|
+
* the base slug; subsequent collisions get `-2`, `-3`, … suffixes.
|
|
24403
|
+
* If the proposed suffixed slug itself collides with a base slug
|
|
24404
|
+
* used later, the counter advances until a free slot is found.
|
|
24405
|
+
*
|
|
24406
|
+
* This yields a deterministic mapping given the state-declaration order,
|
|
24407
|
+
* so output is stable across runs.
|
|
24408
|
+
*
|
|
24409
|
+
* ```typescript
|
|
24410
|
+
* slug_states(['Red Light', 'red-light']);
|
|
24411
|
+
* // Map { 'Red Light' => 'red-light', 'red-light' => 'red-light-2' }
|
|
24412
|
+
*
|
|
24413
|
+
* slug_states(['!!!', '???']);
|
|
24414
|
+
* // Map { '!!!' => 'node-1', '???' => 'node-2' }
|
|
24415
|
+
* ```
|
|
24416
|
+
*
|
|
24417
|
+
* @param states States in declaration order.
|
|
24418
|
+
* @returns A `Map` from each state name to its unique slug.
|
|
24419
|
+
*
|
|
24420
|
+
* @internal
|
|
24421
|
+
*/
|
|
24422
|
+
function slug_states(states) {
|
|
24423
|
+
const used = new Set();
|
|
24424
|
+
const out = new Map();
|
|
24425
|
+
states.forEach((s, i) => {
|
|
24426
|
+
const base = slug_for(s) || `node-${i + 1}`;
|
|
24427
|
+
let candidate = base;
|
|
24428
|
+
let n = 2;
|
|
24429
|
+
while (used.has(candidate)) {
|
|
24430
|
+
candidate = `${base}-${n}`;
|
|
24431
|
+
n += 1;
|
|
24432
|
+
}
|
|
24433
|
+
used.add(candidate);
|
|
24434
|
+
out.set(s, candidate);
|
|
24435
|
+
});
|
|
24436
|
+
return out;
|
|
24437
|
+
}
|
|
24438
|
+
/**
|
|
24439
|
+
* Build a graphviz-safe node identifier for a state. Accepts either a
|
|
24440
|
+
* `string[]` (legacy test-only path; returns an index-based `n0`/`n1`
|
|
24441
|
+
* identifier via `indexOf`), or a precomputed `Map<state, slug>` produced
|
|
24442
|
+
* by {@link slug_states} (used by all rendering hot paths).
|
|
24443
|
+
*
|
|
24444
|
+
* When a slug map is supplied, the identifier is the slug wrapped in
|
|
24445
|
+
* double quotes — dot allows quoted identifiers, and the slug alphabet
|
|
24446
|
+
* (lowercase alphanumerics + `-`) requires quoting because bare dot IDs
|
|
24447
|
+
* may not contain `-`. Graphviz round-trips the quoted form through to
|
|
24448
|
+
* the SVG `<title>` element and uses the slug as a stable basis for the
|
|
24449
|
+
* generated SVG element `id` attribute.
|
|
24450
|
+
*
|
|
24451
|
+
* ```typescript
|
|
24452
|
+
* node_of('Red Light', new Map([['Red Light', 'red-light']]));
|
|
24453
|
+
* // '"red-light"'
|
|
24454
|
+
* ```
|
|
24365
24455
|
*
|
|
24366
24456
|
* @internal
|
|
24367
24457
|
*/
|
|
24368
24458
|
function node_of(state, state_index) {
|
|
24369
|
-
|
|
24370
|
-
|
|
24371
|
-
|
|
24459
|
+
if (Array.isArray(state_index)) {
|
|
24460
|
+
return `n${state_index.indexOf(state)}`;
|
|
24461
|
+
}
|
|
24462
|
+
const v = state_index.get(state);
|
|
24463
|
+
if (typeof v === 'string') {
|
|
24464
|
+
return `"${v}"`;
|
|
24465
|
+
}
|
|
24466
|
+
return `n${v}`;
|
|
24372
24467
|
}
|
|
24373
24468
|
/**
|
|
24374
24469
|
* Compose a graphviz `style` string from a pre-computed
|
|
@@ -24706,7 +24801,7 @@ function arranges_for(u_jssm, state_index) {
|
|
|
24706
24801
|
function machine_to_dot(u_jssm, opts = {}) {
|
|
24707
24802
|
var _a;
|
|
24708
24803
|
const l_states = u_jssm.states();
|
|
24709
|
-
const state_index =
|
|
24804
|
+
const state_index = slug_states(l_states);
|
|
24710
24805
|
const state_kinds = classify_states(u_jssm, l_states);
|
|
24711
24806
|
const nodes = states_to_nodes_string(u_jssm, l_states, state_index, state_kinds, opts.hide_state_labels === true);
|
|
24712
24807
|
const edges = states_to_edges_string(u_jssm, l_states, state_index, state_kinds);
|