jssm 5.162.21 → 5.162.22

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.
@@ -24226,7 +24226,7 @@ function fslSemanticSpans(text) {
24226
24226
  * Useful for runtime diagnostics and for embedding in serialized machine
24227
24227
  * snapshots so that deserializers can detect version-skew.
24228
24228
  */
24229
- const version = "5.162.21";
24229
+ const version = "5.162.22";
24230
24230
 
24231
24231
  /**
24232
24232
  * The FSL Markdown fence convention parser — pure, host-agnostic logic that
@@ -28146,6 +28146,20 @@ class Machine {
28146
28146
  }
28147
28147
  }
28148
28148
  // all hooks passed! let's now establish the result
28149
+ // a hook may have redirected the destination via a complex result's
28150
+ // `state` (carried on hook_args.to). Apply it now, validating it names
28151
+ // a real state. Pre-transition hooks (including entry/exit) fired for
28152
+ // the original edge; the committed state and the post-hooks, observation
28153
+ // events, and after-timer all reflect the override. Last writer wins.
28154
+ // StoneCypher/fsl#1947
28155
+ if (hook_args.to !== newState) {
28156
+ const override_id = this._state_interner.id_of(hook_args.to);
28157
+ if (override_id === undefined) {
28158
+ throw new JssmError(this, `A hook overrode the transition destination to '${hook_args.to}', which is not a state in this machine`);
28159
+ }
28160
+ newState = hook_args.to;
28161
+ newStateId = override_id;
28162
+ }
28149
28163
  if (this._history_length) {
28150
28164
  this._history.shove([this._state, this._data]);
28151
28165
  }
@@ -29732,12 +29746,19 @@ function is_hook_complex_result(hr) {
29732
29746
  function _update_hook_fields(hook_args, res) {
29733
29747
  // HOOK_PASSED is the shared frozen outcome for "no hook installed" and for
29734
29748
  // hooks returning true/undefined — the overwhelming majority of the up-to-
29735
- // ~10 steps per hooked transition. It can never carry `data` (frozen, built
29736
- // without one), so one pointer compare replaces the hasOwnProperty
29749
+ // ~10 steps per hooked transition. It can never carry `data`/`state` (frozen,
29750
+ // built without them), so one pointer compare replaces the hasOwnProperty
29737
29751
  // reflection call for the common case.
29738
29752
  if (res === HOOK_PASSED) {
29739
29753
  return false;
29740
29754
  }
29755
+ // a complex result's `state` redirects the transition's destination; carry it
29756
+ // on hook_args.to (the destination field), which transition_impl applies at
29757
+ // commit (last writer wins). An explicit `state: undefined` is not a
29758
+ // redirect. StoneCypher/fsl#1947
29759
+ if (Object.prototype.hasOwnProperty.call(res, 'state') && res.state !== undefined) {
29760
+ hook_args.to = res.state;
29761
+ }
29741
29762
  if (Object.prototype.hasOwnProperty.call(res, 'data')) {
29742
29763
  hook_args.data = res.data;
29743
29764
  hook_args.next_data = res.next_data;