jssm 5.143.24 → 5.143.25
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 +7 -7
- package/dist/cdn/instance.js +26 -4
- package/dist/cdn/viz.js +26 -4
- package/dist/cli/fsl-render.cjs +1 -1
- package/dist/cli/fsl.cjs +1 -1
- package/dist/deno/README.md +7 -7
- 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 +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.143.
|
|
21
|
+
* Generated for version 5.143.25 at 6/12/2026, 2:28:30 PM
|
|
22
22
|
|
|
23
23
|
-->
|
|
24
|
-
# jssm 5.143.
|
|
24
|
+
# jssm 5.143.25
|
|
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.** 7,
|
|
284
|
+
library.** 7,013 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
|
-
***7,
|
|
417
|
+
***7,013 tests***, run 81,857 times.
|
|
418
418
|
|
|
419
|
-
- 6,
|
|
420
|
-
- 756 fuzz tests with 83.
|
|
421
|
-
- 5,
|
|
419
|
+
- 6,257 specs with 100.0% coverage
|
|
420
|
+
- 756 fuzz tests with 83.4% coverage
|
|
421
|
+
- 5,880 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
|
@@ -22402,7 +22402,7 @@ var constants = /*#__PURE__*/Object.freeze({
|
|
|
22402
22402
|
* Useful for runtime diagnostics and for embedding in serialized machine
|
|
22403
22403
|
* snapshots so that deserializers can detect version-skew.
|
|
22404
22404
|
*/
|
|
22405
|
-
const version = "5.143.
|
|
22405
|
+
const version = "5.143.25";
|
|
22406
22406
|
|
|
22407
22407
|
// whargarbl lots of these return arrays could/should be sets
|
|
22408
22408
|
const { state_name_chars, state_name_first_chars, action_label_chars } = constants;
|
|
@@ -25221,7 +25221,19 @@ class Machine {
|
|
|
25221
25221
|
const edgeId = (to_id === undefined) ? undefined : this._edge_id_by_pair.get(pair_key(this._state_id, to_id));
|
|
25222
25222
|
if ((edgeId !== undefined) && (!(this._edges[edgeId].forced_only))) {
|
|
25223
25223
|
if (this._has_transition_hooks || this._has_post_transition_hooks) {
|
|
25224
|
-
|
|
25224
|
+
// first matching outbound edge's kind, without building the result
|
|
25225
|
+
// array edges_between allocated here on every hooked transition.
|
|
25226
|
+
// First-match semantics are kept deliberately: _edge_map is
|
|
25227
|
+
// last-wins for multi-edge (from, to) pairs, so lookup_transition_for
|
|
25228
|
+
// could disagree with the old edges_between(...)[0]. #735
|
|
25229
|
+
// TODO this won't do the right thing if various edges have different types
|
|
25230
|
+
for (const ob_eid of this._outbound_edge_ids.get(this._state)) {
|
|
25231
|
+
const ob_edge = this._edges[ob_eid];
|
|
25232
|
+
if (ob_edge.to === newStateOrAction) {
|
|
25233
|
+
trans_type = ob_edge.kind;
|
|
25234
|
+
break;
|
|
25235
|
+
}
|
|
25236
|
+
}
|
|
25225
25237
|
}
|
|
25226
25238
|
valid = true;
|
|
25227
25239
|
newState = newStateOrAction;
|
|
@@ -25235,6 +25247,11 @@ class Machine {
|
|
|
25235
25247
|
// unchanged for all downstream uses without introducing an impossible
|
|
25236
25248
|
// (uncoverable) branch; the value is only dereferenced under the guards
|
|
25237
25249
|
// that imply it was built. #670
|
|
25250
|
+
// NOTE (#735): the { ...hook_args, hook_name } spreads at the four
|
|
25251
|
+
// everything-hook sites are contractual, not waste — handlers may capture
|
|
25252
|
+
// their context, and each captured context must durably carry its own
|
|
25253
|
+
// hook_name (pinned by the simultaneous-everything-hook specs). A shared
|
|
25254
|
+
// mutated object cannot satisfy that; do not "optimize" the spreads away.
|
|
25238
25255
|
const hook_args_obj = (this._has_hooks || this._has_post_hooks)
|
|
25239
25256
|
? {
|
|
25240
25257
|
data: this._data,
|
|
@@ -25594,10 +25611,15 @@ class Machine {
|
|
|
25594
25611
|
cause: 'transition'
|
|
25595
25612
|
});
|
|
25596
25613
|
}
|
|
25597
|
-
|
|
25614
|
+
// one state-record fetch answers both checks; newState is known-valid
|
|
25615
|
+
// here, and the public state_is_terminal / state_is_complete pair would
|
|
25616
|
+
// each redo has_state plus its own map walk. Same predicates:
|
|
25617
|
+
// terminal = no exits, complete = the constructor-set flag. #735
|
|
25618
|
+
const new_state_rec = this._states.get(newState);
|
|
25619
|
+
if (new_state_rec.to.length === 0) {
|
|
25598
25620
|
this._fire('terminal', { state: newState, data: newData_after });
|
|
25599
25621
|
}
|
|
25600
|
-
if (
|
|
25622
|
+
if (new_state_rec.complete) {
|
|
25601
25623
|
this._fire('complete', { state: newState, data: newData_after });
|
|
25602
25624
|
}
|
|
25603
25625
|
}
|
package/dist/cdn/viz.js
CHANGED
|
@@ -22427,7 +22427,7 @@ var constants = /*#__PURE__*/Object.freeze({
|
|
|
22427
22427
|
* Useful for runtime diagnostics and for embedding in serialized machine
|
|
22428
22428
|
* snapshots so that deserializers can detect version-skew.
|
|
22429
22429
|
*/
|
|
22430
|
-
const version = "5.143.
|
|
22430
|
+
const version = "5.143.25";
|
|
22431
22431
|
|
|
22432
22432
|
// whargarbl lots of these return arrays could/should be sets
|
|
22433
22433
|
const { state_name_chars, state_name_first_chars, action_label_chars } = constants;
|
|
@@ -25246,7 +25246,19 @@ class Machine {
|
|
|
25246
25246
|
const edgeId = (to_id === undefined) ? undefined : this._edge_id_by_pair.get(pair_key(this._state_id, to_id));
|
|
25247
25247
|
if ((edgeId !== undefined) && (!(this._edges[edgeId].forced_only))) {
|
|
25248
25248
|
if (this._has_transition_hooks || this._has_post_transition_hooks) {
|
|
25249
|
-
|
|
25249
|
+
// first matching outbound edge's kind, without building the result
|
|
25250
|
+
// array edges_between allocated here on every hooked transition.
|
|
25251
|
+
// First-match semantics are kept deliberately: _edge_map is
|
|
25252
|
+
// last-wins for multi-edge (from, to) pairs, so lookup_transition_for
|
|
25253
|
+
// could disagree with the old edges_between(...)[0]. #735
|
|
25254
|
+
// TODO this won't do the right thing if various edges have different types
|
|
25255
|
+
for (const ob_eid of this._outbound_edge_ids.get(this._state)) {
|
|
25256
|
+
const ob_edge = this._edges[ob_eid];
|
|
25257
|
+
if (ob_edge.to === newStateOrAction) {
|
|
25258
|
+
trans_type = ob_edge.kind;
|
|
25259
|
+
break;
|
|
25260
|
+
}
|
|
25261
|
+
}
|
|
25250
25262
|
}
|
|
25251
25263
|
valid = true;
|
|
25252
25264
|
newState = newStateOrAction;
|
|
@@ -25260,6 +25272,11 @@ class Machine {
|
|
|
25260
25272
|
// unchanged for all downstream uses without introducing an impossible
|
|
25261
25273
|
// (uncoverable) branch; the value is only dereferenced under the guards
|
|
25262
25274
|
// that imply it was built. #670
|
|
25275
|
+
// NOTE (#735): the { ...hook_args, hook_name } spreads at the four
|
|
25276
|
+
// everything-hook sites are contractual, not waste — handlers may capture
|
|
25277
|
+
// their context, and each captured context must durably carry its own
|
|
25278
|
+
// hook_name (pinned by the simultaneous-everything-hook specs). A shared
|
|
25279
|
+
// mutated object cannot satisfy that; do not "optimize" the spreads away.
|
|
25263
25280
|
const hook_args_obj = (this._has_hooks || this._has_post_hooks)
|
|
25264
25281
|
? {
|
|
25265
25282
|
data: this._data,
|
|
@@ -25619,10 +25636,15 @@ class Machine {
|
|
|
25619
25636
|
cause: 'transition'
|
|
25620
25637
|
});
|
|
25621
25638
|
}
|
|
25622
|
-
|
|
25639
|
+
// one state-record fetch answers both checks; newState is known-valid
|
|
25640
|
+
// here, and the public state_is_terminal / state_is_complete pair would
|
|
25641
|
+
// each redo has_state plus its own map walk. Same predicates:
|
|
25642
|
+
// terminal = no exits, complete = the constructor-set flag. #735
|
|
25643
|
+
const new_state_rec = this._states.get(newState);
|
|
25644
|
+
if (new_state_rec.to.length === 0) {
|
|
25623
25645
|
this._fire('terminal', { state: newState, data: newData_after });
|
|
25624
25646
|
}
|
|
25625
|
-
if (
|
|
25647
|
+
if (new_state_rec.complete) {
|
|
25626
25648
|
this._fire('complete', { state: newState, data: newData_after });
|
|
25627
25649
|
}
|
|
25628
25650
|
}
|