jssm 5.143.20 → 5.143.21

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.143.20 at 6/12/2026, 11:19:59 AM
21
+ * Generated for version 5.143.21 at 6/12/2026, 1:26:44 PM
22
22
 
23
23
  -->
24
- # jssm 5.143.20
24
+ # jssm 5.143.21
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/) ·
@@ -418,7 +418,7 @@ If your contribution is missing here, please open an issue.
418
418
 
419
419
  - 6,253 specs with 100.0% coverage
420
420
  - 756 fuzz tests with 83.6% coverage
421
- - 5,865 TypeScript lines - 1.2 tests per line, 14.0 generated tests per line
421
+ - 5,870 TypeScript lines - 1.2 tests per line, 13.9 generated tests per line
422
422
 
423
423
  [![Actions Status](https://github.com/StoneCypher/jssm/workflows/Node%20CI/badge.svg)](https://github.com/StoneCypher/jssm/actions)
424
424
  [![NPM version](https://img.shields.io/npm/v/jssm.svg)](https://www.npmjs.com/package/jssm)
@@ -20751,9 +20751,9 @@ function seq(n) {
20751
20751
  if (n < 0) {
20752
20752
  throw new TypeError('seq/1 takes a non-negative integer n as an argument');
20753
20753
  }
20754
- return (new Array(n))
20755
- .fill(true)
20756
- .map((_, i) => i);
20754
+ // single-allocation form; the old new Array(n).fill().map() chain built
20755
+ // three arrays per call, and seq runs per probabilistic walk / sample
20756
+ return Array.from({ length: n }, (_, i) => i);
20757
20757
  }
20758
20758
  /*******
20759
20759
  *
@@ -20836,7 +20836,22 @@ function gen_splitmix32(a) {
20836
20836
  * ```
20837
20837
  *
20838
20838
  */
20839
- const unique = (arr) => arr.filter((v, i, a) => a.indexOf(v) === i);
20839
+ const unique = (arr) => {
20840
+ // Set membership makes this O(n); the old indexOf-per-element filter was
20841
+ // O(n^2). NaN is dropped *explicitly* here because Sets self-match NaN
20842
+ // (SameValueZero) where the documented indexOf behavior (===) never did.
20843
+ const seen = new Set();
20844
+ return arr.filter((v) => {
20845
+ if (v !== v) {
20846
+ return false;
20847
+ } // NaN: preserve documented dropping
20848
+ if (seen.has(v)) {
20849
+ return false;
20850
+ }
20851
+ seen.add(v);
20852
+ return true;
20853
+ });
20854
+ };
20840
20855
  /*******
20841
20856
  *
20842
20857
  * Lists all repeated items in an array along with their counts. Subject to
@@ -22788,7 +22803,7 @@ var constants = /*#__PURE__*/Object.freeze({
22788
22803
  * Useful for runtime diagnostics and for embedding in serialized machine
22789
22804
  * snapshots so that deserializers can detect version-skew.
22790
22805
  */
22791
- const version = "5.143.20";
22806
+ const version = "5.143.21";
22792
22807
 
22793
22808
  // whargarbl lots of these return arrays could/should be sets
22794
22809
  const { state_name_chars, state_name_first_chars, action_label_chars } = constants;
@@ -24064,7 +24079,8 @@ class Machine {
24064
24079
  * @returns `true` if the machine has at least one action.
24065
24080
  */
24066
24081
  get uses_actions() {
24067
- return Array.from(this._actions.keys()).length > 0;
24082
+ // Map.size answers emptiness without materializing the key list
24083
+ return this._actions.size > 0;
24068
24084
  }
24069
24085
  /** Whether any forced (`~>`) transitions exist in this machine.
24070
24086
  * @returns `true` if at least one forced transition is defined.
@@ -24341,17 +24357,31 @@ class Machine {
24341
24357
  if (!(wstate)) {
24342
24358
  throw new JssmError(this, `No such state ${JSON.stringify(whichState)} in probable_exits_for`);
24343
24359
  }
24344
- const wstate_to = wstate.to,
24345
- // every transition that exits whichState
24346
- all_exits = wstate_to
24347
- .map((ws) => this.lookup_transition_for(whichState, ws))
24348
- .filter(Boolean),
24349
- // forced-only exits cannot be reached by transition(), so they are
24350
- // never legal probabilistic outcomes
24351
- legal_exits = all_exits.filter((e) => !e.forced_only),
24352
- // if any legal exit declares a probability, filter to those only so
24353
- // that probability-bearing edges are not diluted by their peers
24354
- probability_bearing = legal_exits.filter((e) => e.probability !== undefined);
24360
+ // single pass over the state's exits, replacing the old map -> filter ->
24361
+ // filter -> filter chain and its three intermediate arrays; selection and
24362
+ // ordering semantics are unchanged
24363
+ const legal_exits = [], probability_bearing = [];
24364
+ for (const ws of wstate.to) {
24365
+ // wstate.to is built from the same edge set lookup_transition_for
24366
+ // resolves against, so the lookup cannot miss; the guard mirrors the
24367
+ // old defensive .filter(Boolean) and is equally unreachable.
24368
+ const edge = this.lookup_transition_for(whichState, ws);
24369
+ /* v8 ignore next */
24370
+ if (!edge) {
24371
+ continue;
24372
+ }
24373
+ // forced-only exits cannot be reached by transition(), so they are
24374
+ // never legal probabilistic outcomes
24375
+ if (edge.forced_only) {
24376
+ continue;
24377
+ }
24378
+ legal_exits.push(edge);
24379
+ // if any legal exit declares a probability, only those are returned, so
24380
+ // that probability-bearing edges are not diluted by their peers
24381
+ if (edge.probability !== undefined) {
24382
+ probability_bearing.push(edge);
24383
+ }
24384
+ }
24355
24385
  return (probability_bearing.length > 0) ? probability_bearing : legal_exits;
24356
24386
  }
24357
24387
  /** Take a single random transition from the current state, weighted by
package/dist/cdn/viz.js CHANGED
@@ -20776,9 +20776,9 @@ function seq(n) {
20776
20776
  if (n < 0) {
20777
20777
  throw new TypeError('seq/1 takes a non-negative integer n as an argument');
20778
20778
  }
20779
- return (new Array(n))
20780
- .fill(true)
20781
- .map((_, i) => i);
20779
+ // single-allocation form; the old new Array(n).fill().map() chain built
20780
+ // three arrays per call, and seq runs per probabilistic walk / sample
20781
+ return Array.from({ length: n }, (_, i) => i);
20782
20782
  }
20783
20783
  /*******
20784
20784
  *
@@ -20861,7 +20861,22 @@ function gen_splitmix32(a) {
20861
20861
  * ```
20862
20862
  *
20863
20863
  */
20864
- const unique = (arr) => arr.filter((v, i, a) => a.indexOf(v) === i);
20864
+ const unique = (arr) => {
20865
+ // Set membership makes this O(n); the old indexOf-per-element filter was
20866
+ // O(n^2). NaN is dropped *explicitly* here because Sets self-match NaN
20867
+ // (SameValueZero) where the documented indexOf behavior (===) never did.
20868
+ const seen = new Set();
20869
+ return arr.filter((v) => {
20870
+ if (v !== v) {
20871
+ return false;
20872
+ } // NaN: preserve documented dropping
20873
+ if (seen.has(v)) {
20874
+ return false;
20875
+ }
20876
+ seen.add(v);
20877
+ return true;
20878
+ });
20879
+ };
20865
20880
  /*******
20866
20881
  *
20867
20882
  * Lists all repeated items in an array along with their counts. Subject to
@@ -22813,7 +22828,7 @@ var constants = /*#__PURE__*/Object.freeze({
22813
22828
  * Useful for runtime diagnostics and for embedding in serialized machine
22814
22829
  * snapshots so that deserializers can detect version-skew.
22815
22830
  */
22816
- const version = "5.143.20";
22831
+ const version = "5.143.21";
22817
22832
 
22818
22833
  // whargarbl lots of these return arrays could/should be sets
22819
22834
  const { state_name_chars, state_name_first_chars, action_label_chars } = constants;
@@ -24089,7 +24104,8 @@ class Machine {
24089
24104
  * @returns `true` if the machine has at least one action.
24090
24105
  */
24091
24106
  get uses_actions() {
24092
- return Array.from(this._actions.keys()).length > 0;
24107
+ // Map.size answers emptiness without materializing the key list
24108
+ return this._actions.size > 0;
24093
24109
  }
24094
24110
  /** Whether any forced (`~>`) transitions exist in this machine.
24095
24111
  * @returns `true` if at least one forced transition is defined.
@@ -24366,17 +24382,31 @@ class Machine {
24366
24382
  if (!(wstate)) {
24367
24383
  throw new JssmError(this, `No such state ${JSON.stringify(whichState)} in probable_exits_for`);
24368
24384
  }
24369
- const wstate_to = wstate.to,
24370
- // every transition that exits whichState
24371
- all_exits = wstate_to
24372
- .map((ws) => this.lookup_transition_for(whichState, ws))
24373
- .filter(Boolean),
24374
- // forced-only exits cannot be reached by transition(), so they are
24375
- // never legal probabilistic outcomes
24376
- legal_exits = all_exits.filter((e) => !e.forced_only),
24377
- // if any legal exit declares a probability, filter to those only so
24378
- // that probability-bearing edges are not diluted by their peers
24379
- probability_bearing = legal_exits.filter((e) => e.probability !== undefined);
24385
+ // single pass over the state's exits, replacing the old map -> filter ->
24386
+ // filter -> filter chain and its three intermediate arrays; selection and
24387
+ // ordering semantics are unchanged
24388
+ const legal_exits = [], probability_bearing = [];
24389
+ for (const ws of wstate.to) {
24390
+ // wstate.to is built from the same edge set lookup_transition_for
24391
+ // resolves against, so the lookup cannot miss; the guard mirrors the
24392
+ // old defensive .filter(Boolean) and is equally unreachable.
24393
+ const edge = this.lookup_transition_for(whichState, ws);
24394
+ /* v8 ignore next */
24395
+ if (!edge) {
24396
+ continue;
24397
+ }
24398
+ // forced-only exits cannot be reached by transition(), so they are
24399
+ // never legal probabilistic outcomes
24400
+ if (edge.forced_only) {
24401
+ continue;
24402
+ }
24403
+ legal_exits.push(edge);
24404
+ // if any legal exit declares a probability, only those are returned, so
24405
+ // that probability-bearing edges are not diluted by their peers
24406
+ if (edge.probability !== undefined) {
24407
+ probability_bearing.push(edge);
24408
+ }
24409
+ }
24380
24410
  return (probability_bearing.length > 0) ? probability_bearing : legal_exits;
24381
24411
  }
24382
24412
  /** Take a single random transition from the current state, weighted by