jssm 5.143.16 → 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 +6 -6
- package/dist/cdn/instance.js +47 -17
- package/dist/cdn/viz.js +47 -17
- 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/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/package.json +3 -2
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.
|
|
21
|
+
* Generated for version 5.143.21 at 6/12/2026, 1:26:44 PM
|
|
22
22
|
|
|
23
23
|
-->
|
|
24
|
-
# jssm 5.143.
|
|
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/) ·
|
|
@@ -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.**
|
|
284
|
+
library.** 7,009 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
|
-
***
|
|
417
|
+
***7,009 tests***, run 81,853 times.
|
|
418
418
|
|
|
419
|
-
- 6,
|
|
419
|
+
- 6,253 specs with 100.0% coverage
|
|
420
420
|
- 756 fuzz tests with 83.6% coverage
|
|
421
|
-
- 5,
|
|
421
|
+
- 5,870 TypeScript lines - 1.2 tests per line, 13.9 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/instance.js
CHANGED
|
@@ -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
|
-
|
|
20755
|
-
|
|
20756
|
-
|
|
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) =>
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
24345
|
-
//
|
|
24346
|
-
|
|
24347
|
-
|
|
24348
|
-
|
|
24349
|
-
|
|
24350
|
-
|
|
24351
|
-
|
|
24352
|
-
|
|
24353
|
-
|
|
24354
|
-
|
|
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
|
-
|
|
20780
|
-
|
|
20781
|
-
|
|
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) =>
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
24370
|
-
//
|
|
24371
|
-
|
|
24372
|
-
|
|
24373
|
-
|
|
24374
|
-
|
|
24375
|
-
|
|
24376
|
-
|
|
24377
|
-
|
|
24378
|
-
|
|
24379
|
-
|
|
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
|