jssm 5.144.2 → 5.144.3

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 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.144.2 at 6/22/2026, 6:51:17 AM
21
+ * Generated for version 5.144.3 at 6/22/2026, 7:57:57 AM
22
22
 
23
23
  -->
24
- # jssm 5.144.2
24
+ # jssm 5.144.3
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/) ·
@@ -312,7 +312,7 @@ That decision shows up everywhere downstream:
312
312
  or run `npm run benny` against your own machine.
313
313
 
314
314
  - **More thoroughly tested than any other JavaScript state-machine
315
- library.** 7,310 tests at 100.0% line coverage
315
+ library.** 7,313 tests at 100.0% line coverage
316
316
  ([report](https://coveralls.io/github/StoneCypher/jssm)), plus
317
317
  fuzz testing via `fast-check`, with parser test data across ten natural
318
318
  languages and Emoji.
@@ -445,11 +445,11 @@ If your contribution is missing here, please open an issue.
445
445
 
446
446
  <br/>
447
447
 
448
- ***7,310 tests***, run 82,352 times.
448
+ ***7,313 tests***, run 82,355 times.
449
449
 
450
- - 6,552 specs with 100.0% coverage
451
- - 758 fuzz tests with 73.9% coverage
452
- - 6,892 TypeScript lines - 1.1 tests per line, 11.9 generated tests per line
450
+ - 6,555 specs with 100.0% coverage
451
+ - 758 fuzz tests with 73.8% coverage
452
+ - 6,888 TypeScript lines - 1.1 tests per line, 12.0 generated tests per line
453
453
 
454
454
  [![Actions Status](https://github.com/StoneCypher/jssm/workflows/Node%20CI/badge.svg)](https://github.com/StoneCypher/jssm/actions)
455
455
  [![NPM version](https://img.shields.io/npm/v/jssm.svg)](https://www.npmjs.com/package/jssm)
@@ -22423,26 +22423,24 @@ function resolve_group_refs(tree, registry) {
22423
22423
  *
22424
22424
  */
22425
22425
  function compile_rule_transition_step(acc, from, to, this_se, next_se) {
22426
- const edges = [];
22427
22426
  const uFrom = (Array.isArray(from) ? from : [from]), uTo = (Array.isArray(to) ? to : [to]);
22428
- uFrom.map((f) => {
22429
- uTo.map((t) => {
22427
+ for (const f of uFrom) {
22428
+ for (const t of uTo) {
22430
22429
  const right = makeTransition(this_se, f, t, true);
22431
22430
  if (right.kind !== 'none') {
22432
- edges.push(right);
22431
+ acc.push(right);
22433
22432
  }
22434
22433
  const left = makeTransition(this_se, t, f, false);
22435
22434
  if (left.kind !== 'none') {
22436
- edges.push(left);
22435
+ acc.push(left);
22437
22436
  }
22438
- });
22439
- });
22440
- const new_acc = acc.concat(edges);
22437
+ }
22438
+ }
22441
22439
  if (next_se) {
22442
- return compile_rule_transition_step(new_acc, to, next_se.to, next_se, next_se.se);
22440
+ return compile_rule_transition_step(acc, to, next_se.to, next_se, next_se.se);
22443
22441
  }
22444
22442
  else {
22445
- return new_acc;
22443
+ return acc;
22446
22444
  }
22447
22445
  }
22448
22446
  /*********
@@ -23514,10 +23512,11 @@ var constants = /*#__PURE__*/Object.freeze({
23514
23512
  * Useful for runtime diagnostics and for embedding in serialized machine
23515
23513
  * snapshots so that deserializers can detect version-skew.
23516
23514
  */
23517
- const version = "5.144.2";
23515
+ const version = "5.144.3";
23518
23516
 
23519
23517
  // whargarbl lots of these return arrays could/should be sets
23520
23518
  const { state_name_chars, state_name_first_chars, action_label_chars } = constants;
23519
+ const empty_string_set = new Set();
23521
23520
  /*********
23522
23521
  *
23523
23522
  * An internal method meant to take a series of declarations and fold them into
@@ -25377,10 +25376,10 @@ class Machine {
25377
25376
  }
25378
25377
  throw new JssmError(this, `No such state ${JSON.stringify(whichState)}`);
25379
25378
  }
25380
- return Array.from(ra_base.values())
25381
- .map((edgeId) => this._edges[edgeId])
25382
- .filter((o) => o.from === whichState)
25383
- .map((filtered) => filtered.action);
25379
+ // `_reverse_actions` is keyed by edge.from (see its population), so every
25380
+ // action stored under whichState belongs to whichState by construction — no
25381
+ // from-filter is needed, and the keys are exactly the exit actions.
25382
+ return Array.from(ra_base.keys());
25384
25383
  }
25385
25384
  /** List all action exits from a state with their probabilities.
25386
25385
  * @param whichState - The state to inspect. Defaults to the current state.
@@ -25395,13 +25394,16 @@ class Machine {
25395
25394
  }
25396
25395
  throw new JssmError(this, `No such state ${JSON.stringify(whichState)}`);
25397
25396
  }
25398
- return Array.from(ra_base.values())
25399
- .map((edgeId) => this._edges[edgeId])
25400
- .filter((o) => o.from === whichState)
25401
- .map((filtered) => ({
25402
- action: filtered.action,
25403
- probability: filtered.probability
25404
- }));
25397
+ const exits = []; // TODO FIXME no any
25398
+ // `_reverse_actions` is keyed by edge.from, so every entry belongs to
25399
+ // whichState by construction; no from-filter is needed.
25400
+ ra_base.forEach((edgeId, action) => {
25401
+ exits.push({
25402
+ action,
25403
+ probability: this._edges[edgeId].probability
25404
+ });
25405
+ });
25406
+ return exits;
25405
25407
  }
25406
25408
  /** Check whether a state has no incoming transitions (unreachable after start).
25407
25409
  * @param whichState - The state to check.
@@ -26597,8 +26599,8 @@ class Machine {
26597
26599
  + `crossing from ${JSON.stringify(prev_state)} to ${JSON.stringify(next_state)} `
26598
26600
  + `(possible infinite loop)`);
26599
26601
  }
26600
- const prev_groups = (_a = this._state_to_groups.get(prev_state)) !== null && _a !== void 0 ? _a : new Set();
26601
- const next_groups = (_b = this._state_to_groups.get(next_state)) !== null && _b !== void 0 ? _b : new Set();
26602
+ const prev_groups = (_a = this._state_to_groups.get(prev_state)) !== null && _a !== void 0 ? _a : empty_string_set;
26603
+ const next_groups = (_b = this._state_to_groups.get(next_state)) !== null && _b !== void 0 ? _b : empty_string_set;
26602
26604
  // The labels to dispatch, gathered before any firing so that re-entrant
26603
26605
  // transitions caused by an early action cannot perturb which boundaries the
26604
26606
  // *current* crossing fires. Exits precede enters (statechart convention).
package/dist/cdn/viz.js CHANGED
@@ -22448,26 +22448,24 @@ function resolve_group_refs(tree, registry) {
22448
22448
  *
22449
22449
  */
22450
22450
  function compile_rule_transition_step(acc, from, to, this_se, next_se) {
22451
- const edges = [];
22452
22451
  const uFrom = (Array.isArray(from) ? from : [from]), uTo = (Array.isArray(to) ? to : [to]);
22453
- uFrom.map((f) => {
22454
- uTo.map((t) => {
22452
+ for (const f of uFrom) {
22453
+ for (const t of uTo) {
22455
22454
  const right = makeTransition(this_se, f, t, true);
22456
22455
  if (right.kind !== 'none') {
22457
- edges.push(right);
22456
+ acc.push(right);
22458
22457
  }
22459
22458
  const left = makeTransition(this_se, t, f, false);
22460
22459
  if (left.kind !== 'none') {
22461
- edges.push(left);
22460
+ acc.push(left);
22462
22461
  }
22463
- });
22464
- });
22465
- const new_acc = acc.concat(edges);
22462
+ }
22463
+ }
22466
22464
  if (next_se) {
22467
- return compile_rule_transition_step(new_acc, to, next_se.to, next_se, next_se.se);
22465
+ return compile_rule_transition_step(acc, to, next_se.to, next_se, next_se.se);
22468
22466
  }
22469
22467
  else {
22470
- return new_acc;
22468
+ return acc;
22471
22469
  }
22472
22470
  }
22473
22471
  /*********
@@ -23539,10 +23537,11 @@ var constants = /*#__PURE__*/Object.freeze({
23539
23537
  * Useful for runtime diagnostics and for embedding in serialized machine
23540
23538
  * snapshots so that deserializers can detect version-skew.
23541
23539
  */
23542
- const version = "5.144.2";
23540
+ const version = "5.144.3";
23543
23541
 
23544
23542
  // whargarbl lots of these return arrays could/should be sets
23545
23543
  const { state_name_chars, state_name_first_chars, action_label_chars } = constants;
23544
+ const empty_string_set = new Set();
23546
23545
  /*********
23547
23546
  *
23548
23547
  * An internal method meant to take a series of declarations and fold them into
@@ -25402,10 +25401,10 @@ class Machine {
25402
25401
  }
25403
25402
  throw new JssmError(this, `No such state ${JSON.stringify(whichState)}`);
25404
25403
  }
25405
- return Array.from(ra_base.values())
25406
- .map((edgeId) => this._edges[edgeId])
25407
- .filter((o) => o.from === whichState)
25408
- .map((filtered) => filtered.action);
25404
+ // `_reverse_actions` is keyed by edge.from (see its population), so every
25405
+ // action stored under whichState belongs to whichState by construction — no
25406
+ // from-filter is needed, and the keys are exactly the exit actions.
25407
+ return Array.from(ra_base.keys());
25409
25408
  }
25410
25409
  /** List all action exits from a state with their probabilities.
25411
25410
  * @param whichState - The state to inspect. Defaults to the current state.
@@ -25420,13 +25419,16 @@ class Machine {
25420
25419
  }
25421
25420
  throw new JssmError(this, `No such state ${JSON.stringify(whichState)}`);
25422
25421
  }
25423
- return Array.from(ra_base.values())
25424
- .map((edgeId) => this._edges[edgeId])
25425
- .filter((o) => o.from === whichState)
25426
- .map((filtered) => ({
25427
- action: filtered.action,
25428
- probability: filtered.probability
25429
- }));
25422
+ const exits = []; // TODO FIXME no any
25423
+ // `_reverse_actions` is keyed by edge.from, so every entry belongs to
25424
+ // whichState by construction; no from-filter is needed.
25425
+ ra_base.forEach((edgeId, action) => {
25426
+ exits.push({
25427
+ action,
25428
+ probability: this._edges[edgeId].probability
25429
+ });
25430
+ });
25431
+ return exits;
25430
25432
  }
25431
25433
  /** Check whether a state has no incoming transitions (unreachable after start).
25432
25434
  * @param whichState - The state to check.
@@ -26622,8 +26624,8 @@ class Machine {
26622
26624
  + `crossing from ${JSON.stringify(prev_state)} to ${JSON.stringify(next_state)} `
26623
26625
  + `(possible infinite loop)`);
26624
26626
  }
26625
- const prev_groups = (_a = this._state_to_groups.get(prev_state)) !== null && _a !== void 0 ? _a : new Set();
26626
- const next_groups = (_b = this._state_to_groups.get(next_state)) !== null && _b !== void 0 ? _b : new Set();
26627
+ const prev_groups = (_a = this._state_to_groups.get(prev_state)) !== null && _a !== void 0 ? _a : empty_string_set;
26628
+ const next_groups = (_b = this._state_to_groups.get(next_state)) !== null && _b !== void 0 ? _b : empty_string_set;
26627
26629
  // The labels to dispatch, gathered before any firing so that re-entrant
26628
26630
  // transitions caused by an early action cannot perturb which boundaries the
26629
26631
  // *current* crossing fires. Exits precede enters (statechart convention).
@@ -108,7 +108,7 @@ function parseFslArgs(argv, spec) {
108
108
  return { positional, flags, helpText };
109
109
  }
110
110
 
111
- const getVersion = () => "5.144.2";
111
+ const getVersion = () => "5.144.3";
112
112
  const SPEC = {
113
113
  flags: {
114
114
  help: { short: "h", boolean: true },