jssm 5.162.26 → 5.162.28
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 +1 -1
- package/dist/cdn/viz.js +1 -1
- package/dist/cli/fsl-export-system-prompt.cjs +1 -1
- package/dist/cli/fsl-render.cjs +1 -1
- package/dist/cli/fsl.cjs +1 -1
- package/dist/cli/lib.cjs +1 -1
- package/dist/cli/lib.mjs +1 -1
- package/dist/deno/README.md +6 -6
- package/dist/deno/jssm.d.ts +8 -0
- package/dist/deno/jssm.js +1 -1
- package/dist/fence/fence.js +205 -149
- 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/jssm.es5.d.cts +8 -0
- package/jssm.es6.d.ts +8 -0
- package/jssm.fence.d.ts +8 -0
- package/jssm_viz.es5.d.cts +8 -0
- package/jssm_viz.es6.d.ts +8 -0
- package/package.json +1 -1
package/dist/fence/fence.js
CHANGED
|
@@ -24454,7 +24454,7 @@ function fslSemanticSpans(text) {
|
|
|
24454
24454
|
* Useful for runtime diagnostics and for embedding in serialized machine
|
|
24455
24455
|
* snapshots so that deserializers can detect version-skew.
|
|
24456
24456
|
*/
|
|
24457
|
-
const version = "5.162.
|
|
24457
|
+
const version = "5.162.28";
|
|
24458
24458
|
|
|
24459
24459
|
/**
|
|
24460
24460
|
* The FSL Markdown fence convention parser — pure, host-agnostic logic that
|
|
@@ -24994,7 +24994,23 @@ const STOCHASTIC_DEFAULT_MAX_STEPS = 1000;
|
|
|
24994
24994
|
* @internal
|
|
24995
24995
|
*/
|
|
24996
24996
|
const DEFAULT_TIME_SOURCE = () => Date.now();
|
|
24997
|
-
const DEFAULT_TIMEOUT_SOURCE = (f, a) =>
|
|
24997
|
+
const DEFAULT_TIMEOUT_SOURCE = (f, a) => {
|
|
24998
|
+
const handle = setTimeout(f, a);
|
|
24999
|
+
// In Node, setTimeout returns a Timeout with .unref(), so a pending `after`
|
|
25000
|
+
// timer does NOT by itself keep the process alive -- an abandoned machine can
|
|
25001
|
+
// be collected and the process can exit instead of hanging until the timer
|
|
25002
|
+
// fires go() on it. The browser returns a plain number with no such method.
|
|
25003
|
+
// A consumer who wants the timer to hold the loop open can supply their own
|
|
25004
|
+
// timeout_source. StoneCypher/fsl#1952
|
|
25005
|
+
const maybe_unref = handle;
|
|
25006
|
+
// The no-unref path is the browser's numeric handle; it can't be reached in
|
|
25007
|
+
// the node-only coverage environment, so the false branch is ignored here.
|
|
25008
|
+
/* v8 ignore next */
|
|
25009
|
+
if (typeof maybe_unref.unref === 'function') {
|
|
25010
|
+
maybe_unref.unref();
|
|
25011
|
+
}
|
|
25012
|
+
return handle;
|
|
25013
|
+
};
|
|
24998
25014
|
const DEFAULT_CLEAR_TIMEOUT_SOURCE = (h) => clearTimeout(h);
|
|
24999
25015
|
class Machine {
|
|
25000
25016
|
// whargarbl this badly needs to be broken up, monolith master
|
|
@@ -25172,6 +25188,7 @@ class Machine {
|
|
|
25172
25188
|
this._event_handlers = new Map();
|
|
25173
25189
|
this._event_listener_count = 0;
|
|
25174
25190
|
this._firing_error = false;
|
|
25191
|
+
this._committing_transition = false;
|
|
25175
25192
|
// Boundary-hook action cascade guard. Limit defaults to 100 but is
|
|
25176
25193
|
// configurable via the `boundary_depth_limit` constructor option so tests
|
|
25177
25194
|
// can tighten the cap and deep pipelines can raise it.
|
|
@@ -28110,10 +28127,25 @@ class Machine {
|
|
|
28110
28127
|
* @returns `true` if the transition was valid and every hook passed;
|
|
28111
28128
|
* `false` if the transition was invalid or any hook rejected.
|
|
28112
28129
|
*
|
|
28130
|
+
* @throws {JssmError} If called reentrantly from inside a hook that is still
|
|
28131
|
+
* running in the enclosing transition's pre-commit pipeline — a hook that
|
|
28132
|
+
* calls `transition`/`go`/`do`/`action`. Committing the inner transition
|
|
28133
|
+
* and then the outer one would silently discard the inner result, so the
|
|
28134
|
+
* reentry is rejected instead (StoneCypher/fsl#1953). Post-commit reentry
|
|
28135
|
+
* (from a post-hook or the boundary-action cascade) is permitted.
|
|
28136
|
+
*
|
|
28113
28137
|
* @internal
|
|
28114
28138
|
*
|
|
28115
28139
|
*/
|
|
28116
28140
|
transition_impl(newStateOrAction, newData, wasForced, wasAction, dataProvided = newData !== undefined) {
|
|
28141
|
+
// Reject reentry from inside the pre-commit hook pipeline. Without this, a
|
|
28142
|
+
// hook that itself transitions the machine would commit an inner transition
|
|
28143
|
+
// that this outer, not-yet-committed frame then silently overwrites. Post-
|
|
28144
|
+
// commit reentry (post-hooks, the boundary-action cascade) is fine: the flag
|
|
28145
|
+
// is already cleared by then. StoneCypher/fsl#1953
|
|
28146
|
+
if (this._committing_transition) {
|
|
28147
|
+
throw new JssmError(this, 'cannot start a transition from within a transition hook: the enclosing transition has not committed yet, so the inner result would be silently discarded');
|
|
28148
|
+
}
|
|
28117
28149
|
let valid = false,
|
|
28118
28150
|
// deliberately `string`, not `JssmArrowKind`, though only arrow kinds are
|
|
28119
28151
|
// ever assigned: declaring this local as the 4-member union makes tsc's
|
|
@@ -28222,185 +28254,203 @@ class Machine {
|
|
|
28222
28254
|
const oldData = this._data;
|
|
28223
28255
|
if (valid) {
|
|
28224
28256
|
if (this._has_hooks) {
|
|
28225
|
-
|
|
28226
|
-
//
|
|
28227
|
-
|
|
28228
|
-
|
|
28229
|
-
|
|
28230
|
-
|
|
28231
|
-
|
|
28232
|
-
|
|
28233
|
-
|
|
28234
|
-
|
|
28235
|
-
|
|
28236
|
-
|
|
28237
|
-
|
|
28238
|
-
|
|
28239
|
-
|
|
28240
|
-
|
|
28241
|
-
|
|
28242
|
-
|
|
28243
|
-
|
|
28244
|
-
|
|
28245
|
-
data_changed = true;
|
|
28246
|
-
}
|
|
28247
|
-
// 1b. global specific action hook
|
|
28248
|
-
const outcome2 = abstract_hook_step(this._global_action_hooks.get(actionId), hook_args);
|
|
28249
|
-
if (!outcome2.pass) {
|
|
28250
|
-
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire_hook_rejection).call(this, 'global action', fromState, newState, fromAction, oldData, newData, wasForced);
|
|
28251
|
-
return false;
|
|
28252
|
-
}
|
|
28253
|
-
if (_update_hook_fields(hook_args, outcome2)) {
|
|
28254
|
-
data_changed = true;
|
|
28255
|
-
}
|
|
28256
|
-
}
|
|
28257
|
-
// 2. (removed) After hooks do NOT fire on dispatch. They are the
|
|
28258
|
-
// `after`-timer's companion (fsl#698: "delay over!") and fire only from
|
|
28259
|
-
// the state-timeout path. Through v5.143.28 a probe here keyed on
|
|
28260
|
-
// newStateOrAction spuriously fired them on entering the hooked state —
|
|
28261
|
-
// or on a same-named action — making one timer elapse read as two
|
|
28262
|
-
// handler calls (StoneCypher/fsl#1327).
|
|
28263
|
-
// 3. any transition hook
|
|
28264
|
-
if (this._any_transition_hook !== undefined) {
|
|
28265
|
-
const outcome = abstract_hook_step(this._any_transition_hook, hook_args);
|
|
28266
|
-
if (!outcome.pass) {
|
|
28267
|
-
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire_hook_rejection).call(this, 'any transition', fromState, newState, fromAction, oldData, newData, wasForced);
|
|
28268
|
-
return false;
|
|
28269
|
-
}
|
|
28270
|
-
if (_update_hook_fields(hook_args, outcome)) {
|
|
28271
|
-
data_changed = true;
|
|
28272
|
-
}
|
|
28273
|
-
}
|
|
28274
|
-
// 4. exit hook
|
|
28275
|
-
if (this._has_exit_hooks) {
|
|
28276
|
-
const outcome = abstract_hook_step(this._exit_hooks.get(this._state_id), hook_args);
|
|
28277
|
-
if (!outcome.pass) {
|
|
28278
|
-
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire_hook_rejection).call(this, 'exit', fromState, newState, fromAction, oldData, newData, wasForced);
|
|
28279
|
-
return false;
|
|
28280
|
-
}
|
|
28281
|
-
if (_update_hook_fields(hook_args, outcome)) {
|
|
28282
|
-
data_changed = true;
|
|
28283
|
-
}
|
|
28284
|
-
}
|
|
28285
|
-
// shared by steps 5 and 6: pre-commit, this._state_id is still the
|
|
28286
|
-
// from-state, so both probes key on the same pair; compute it once
|
|
28287
|
-
const pre_pair_id = pair_key(this._state_id, newStateId);
|
|
28288
|
-
// 5. named transition / action hook
|
|
28289
|
-
if (this._has_named_hooks && wasAction) {
|
|
28290
|
-
// Numeric pair probe, then the action id captured at dispatch (#729).
|
|
28291
|
-
const byPair = this._named_hooks.get(pre_pair_id);
|
|
28292
|
-
const nh = byPair === undefined ? undefined : byPair.get(actionId);
|
|
28293
|
-
const outcome = abstract_hook_step(nh, hook_args);
|
|
28294
|
-
if (!outcome.pass) {
|
|
28295
|
-
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire_hook_rejection).call(this, 'named', fromState, newState, fromAction, oldData, newData, wasForced);
|
|
28296
|
-
return false;
|
|
28257
|
+
// Open the pre-commit window: from here until the commit below, any
|
|
28258
|
+
// reentrant transition_impl call (a hook transitioning the machine)
|
|
28259
|
+
// throws instead of being silently reverted. The `finally` below closes
|
|
28260
|
+
// it on every exit path; #fire_hook_rejection additionally clears it
|
|
28261
|
+
// before firing the rejection event so a rejection listener may itself
|
|
28262
|
+
// transition. The pipeline body is intentionally left at its original
|
|
28263
|
+
// indentation to keep this fix's diff focused. #1953
|
|
28264
|
+
this._committing_transition = true;
|
|
28265
|
+
try {
|
|
28266
|
+
let data_changed = false;
|
|
28267
|
+
// 0. pre everything hook (fires before all other pre-hooks)
|
|
28268
|
+
if (this._pre_everything_hook !== undefined) {
|
|
28269
|
+
const outcome = abstract_everything_hook_step(this._pre_everything_hook, Object.assign(Object.assign({}, hook_args), { hook_name: 'pre everything' }));
|
|
28270
|
+
if (!outcome.pass) {
|
|
28271
|
+
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire_hook_rejection).call(this, 'pre everything', fromState, newState, fromAction, oldData, newData, wasForced);
|
|
28272
|
+
return false;
|
|
28273
|
+
}
|
|
28274
|
+
if (_update_hook_fields(hook_args, outcome)) {
|
|
28275
|
+
data_changed = true;
|
|
28276
|
+
}
|
|
28297
28277
|
}
|
|
28298
|
-
if (
|
|
28299
|
-
|
|
28278
|
+
if (wasAction) {
|
|
28279
|
+
// 1a. any action hook
|
|
28280
|
+
const outcome = abstract_hook_step(this._any_action_hook, hook_args);
|
|
28281
|
+
if (!outcome.pass) {
|
|
28282
|
+
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire_hook_rejection).call(this, 'any action', fromState, newState, fromAction, oldData, newData, wasForced);
|
|
28283
|
+
return false;
|
|
28284
|
+
}
|
|
28285
|
+
if (_update_hook_fields(hook_args, outcome)) {
|
|
28286
|
+
data_changed = true;
|
|
28287
|
+
}
|
|
28288
|
+
// 1b. global specific action hook
|
|
28289
|
+
const outcome2 = abstract_hook_step(this._global_action_hooks.get(actionId), hook_args);
|
|
28290
|
+
if (!outcome2.pass) {
|
|
28291
|
+
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire_hook_rejection).call(this, 'global action', fromState, newState, fromAction, oldData, newData, wasForced);
|
|
28292
|
+
return false;
|
|
28293
|
+
}
|
|
28294
|
+
if (_update_hook_fields(hook_args, outcome2)) {
|
|
28295
|
+
data_changed = true;
|
|
28296
|
+
}
|
|
28300
28297
|
}
|
|
28301
|
-
|
|
28302
|
-
|
|
28303
|
-
|
|
28304
|
-
//
|
|
28305
|
-
|
|
28306
|
-
|
|
28307
|
-
|
|
28308
|
-
|
|
28309
|
-
|
|
28298
|
+
// 2. (removed) After hooks do NOT fire on dispatch. They are the
|
|
28299
|
+
// `after`-timer's companion (fsl#698: "delay over!") and fire only from
|
|
28300
|
+
// the state-timeout path. Through v5.143.28 a probe here keyed on
|
|
28301
|
+
// newStateOrAction spuriously fired them on entering the hooked state —
|
|
28302
|
+
// or on a same-named action — making one timer elapse read as two
|
|
28303
|
+
// handler calls (StoneCypher/fsl#1327).
|
|
28304
|
+
// 3. any transition hook
|
|
28305
|
+
if (this._any_transition_hook !== undefined) {
|
|
28306
|
+
const outcome = abstract_hook_step(this._any_transition_hook, hook_args);
|
|
28307
|
+
if (!outcome.pass) {
|
|
28308
|
+
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire_hook_rejection).call(this, 'any transition', fromState, newState, fromAction, oldData, newData, wasForced);
|
|
28309
|
+
return false;
|
|
28310
|
+
}
|
|
28311
|
+
if (_update_hook_fields(hook_args, outcome)) {
|
|
28312
|
+
data_changed = true;
|
|
28313
|
+
}
|
|
28310
28314
|
}
|
|
28311
|
-
|
|
28312
|
-
|
|
28315
|
+
// 4. exit hook
|
|
28316
|
+
if (this._has_exit_hooks) {
|
|
28317
|
+
const outcome = abstract_hook_step(this._exit_hooks.get(this._state_id), hook_args);
|
|
28318
|
+
if (!outcome.pass) {
|
|
28319
|
+
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire_hook_rejection).call(this, 'exit', fromState, newState, fromAction, oldData, newData, wasForced);
|
|
28320
|
+
return false;
|
|
28321
|
+
}
|
|
28322
|
+
if (_update_hook_fields(hook_args, outcome)) {
|
|
28323
|
+
data_changed = true;
|
|
28324
|
+
}
|
|
28313
28325
|
}
|
|
28314
|
-
|
|
28315
|
-
|
|
28316
|
-
|
|
28317
|
-
//
|
|
28318
|
-
|
|
28319
|
-
|
|
28326
|
+
// shared by steps 5 and 6: pre-commit, this._state_id is still the
|
|
28327
|
+
// from-state, so both probes key on the same pair; compute it once
|
|
28328
|
+
const pre_pair_id = pair_key(this._state_id, newStateId);
|
|
28329
|
+
// 5. named transition / action hook
|
|
28330
|
+
if (this._has_named_hooks && wasAction) {
|
|
28331
|
+
// Numeric pair probe, then the action id captured at dispatch (#729).
|
|
28332
|
+
const byPair = this._named_hooks.get(pre_pair_id);
|
|
28333
|
+
const nh = byPair === undefined ? undefined : byPair.get(actionId);
|
|
28334
|
+
const outcome = abstract_hook_step(nh, hook_args);
|
|
28320
28335
|
if (!outcome.pass) {
|
|
28321
|
-
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire_hook_rejection).call(this, '
|
|
28336
|
+
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire_hook_rejection).call(this, 'named', fromState, newState, fromAction, oldData, newData, wasForced);
|
|
28322
28337
|
return false;
|
|
28323
28338
|
}
|
|
28324
28339
|
if (_update_hook_fields(hook_args, outcome)) {
|
|
28325
28340
|
data_changed = true;
|
|
28326
28341
|
}
|
|
28327
|
-
break;
|
|
28328
28342
|
}
|
|
28329
|
-
//
|
|
28330
|
-
|
|
28331
|
-
|
|
28343
|
+
// 6. regular hook
|
|
28344
|
+
if (this._has_basic_hooks) {
|
|
28345
|
+
// Numeric pair probe (#729); one integer hash replaces two string maps.
|
|
28346
|
+
const h = this._hooks.get(pre_pair_id);
|
|
28347
|
+
const outcome = abstract_hook_step(h, hook_args);
|
|
28332
28348
|
if (!outcome.pass) {
|
|
28333
|
-
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire_hook_rejection).call(this, '
|
|
28349
|
+
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire_hook_rejection).call(this, 'hook', fromState, newState, fromAction, oldData, newData, wasForced);
|
|
28334
28350
|
return false;
|
|
28335
28351
|
}
|
|
28336
28352
|
if (_update_hook_fields(hook_args, outcome)) {
|
|
28337
28353
|
data_changed = true;
|
|
28338
28354
|
}
|
|
28339
|
-
break;
|
|
28340
28355
|
}
|
|
28341
|
-
//
|
|
28342
|
-
|
|
28343
|
-
|
|
28356
|
+
// 7. edge type hook
|
|
28357
|
+
switch (trans_type) {
|
|
28358
|
+
// 7a. standard transition hook
|
|
28359
|
+
case 'legal': {
|
|
28360
|
+
const outcome = abstract_hook_step(this._standard_transition_hook, hook_args);
|
|
28361
|
+
if (!outcome.pass) {
|
|
28362
|
+
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire_hook_rejection).call(this, 'standard transition', fromState, newState, fromAction, oldData, newData, wasForced);
|
|
28363
|
+
return false;
|
|
28364
|
+
}
|
|
28365
|
+
if (_update_hook_fields(hook_args, outcome)) {
|
|
28366
|
+
data_changed = true;
|
|
28367
|
+
}
|
|
28368
|
+
break;
|
|
28369
|
+
}
|
|
28370
|
+
// 7b. main type hook
|
|
28371
|
+
case 'main': {
|
|
28372
|
+
const outcome = abstract_hook_step(this._main_transition_hook, hook_args);
|
|
28373
|
+
if (!outcome.pass) {
|
|
28374
|
+
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire_hook_rejection).call(this, 'main transition', fromState, newState, fromAction, oldData, newData, wasForced);
|
|
28375
|
+
return false;
|
|
28376
|
+
}
|
|
28377
|
+
if (_update_hook_fields(hook_args, outcome)) {
|
|
28378
|
+
data_changed = true;
|
|
28379
|
+
}
|
|
28380
|
+
break;
|
|
28381
|
+
}
|
|
28382
|
+
// 7c. forced transition hook
|
|
28383
|
+
case 'forced': {
|
|
28384
|
+
const outcome = abstract_hook_step(this._forced_transition_hook, hook_args);
|
|
28385
|
+
if (!outcome.pass) {
|
|
28386
|
+
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire_hook_rejection).call(this, 'forced transition', fromState, newState, fromAction, oldData, newData, wasForced);
|
|
28387
|
+
return false;
|
|
28388
|
+
}
|
|
28389
|
+
if (_update_hook_fields(hook_args, outcome)) {
|
|
28390
|
+
data_changed = true;
|
|
28391
|
+
}
|
|
28392
|
+
break;
|
|
28393
|
+
}
|
|
28394
|
+
}
|
|
28395
|
+
// 8. entry hook
|
|
28396
|
+
if (this._has_entry_hooks) {
|
|
28397
|
+
const outcome = abstract_hook_step(this._entry_hooks.get(newStateId), hook_args);
|
|
28344
28398
|
if (!outcome.pass) {
|
|
28345
|
-
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire_hook_rejection).call(this, '
|
|
28399
|
+
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire_hook_rejection).call(this, 'entry', fromState, newState, fromAction, oldData, newData, wasForced);
|
|
28346
28400
|
return false;
|
|
28347
28401
|
}
|
|
28348
28402
|
if (_update_hook_fields(hook_args, outcome)) {
|
|
28349
28403
|
data_changed = true;
|
|
28350
28404
|
}
|
|
28351
|
-
break;
|
|
28352
28405
|
}
|
|
28353
|
-
|
|
28354
|
-
|
|
28355
|
-
|
|
28356
|
-
|
|
28357
|
-
|
|
28358
|
-
|
|
28359
|
-
|
|
28406
|
+
// 9. everything hook (fires after all other pre-hooks)
|
|
28407
|
+
if (this._everything_hook !== undefined) {
|
|
28408
|
+
const outcome = abstract_everything_hook_step(this._everything_hook, Object.assign(Object.assign({}, hook_args), { hook_name: 'everything' }));
|
|
28409
|
+
if (!outcome.pass) {
|
|
28410
|
+
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire_hook_rejection).call(this, 'everything', fromState, newState, fromAction, oldData, newData, wasForced);
|
|
28411
|
+
return false;
|
|
28412
|
+
}
|
|
28413
|
+
if (_update_hook_fields(hook_args, outcome)) {
|
|
28414
|
+
data_changed = true;
|
|
28415
|
+
}
|
|
28360
28416
|
}
|
|
28361
|
-
|
|
28362
|
-
|
|
28417
|
+
// all hooks passed! let's now establish the result
|
|
28418
|
+
// a hook may have redirected the destination via a complex result's
|
|
28419
|
+
// `state` (carried on hook_args.to). Apply it now, validating it names
|
|
28420
|
+
// a real state. Pre-transition hooks (including entry/exit) fired for
|
|
28421
|
+
// the original edge; the committed state and the post-hooks, observation
|
|
28422
|
+
// events, and after-timer all reflect the override. Last writer wins.
|
|
28423
|
+
// StoneCypher/fsl#1947
|
|
28424
|
+
if (hook_args.to !== newState) {
|
|
28425
|
+
const override_id = this._state_interner.id_of(hook_args.to);
|
|
28426
|
+
if (override_id === undefined) {
|
|
28427
|
+
throw new JssmError(this, `A hook overrode the transition destination to '${hook_args.to}', which is not a state in this machine`);
|
|
28428
|
+
}
|
|
28429
|
+
newState = hook_args.to;
|
|
28430
|
+
newStateId = override_id;
|
|
28363
28431
|
}
|
|
28364
|
-
|
|
28365
|
-
|
|
28366
|
-
if (this._everything_hook !== undefined) {
|
|
28367
|
-
const outcome = abstract_everything_hook_step(this._everything_hook, Object.assign(Object.assign({}, hook_args), { hook_name: 'everything' }));
|
|
28368
|
-
if (!outcome.pass) {
|
|
28369
|
-
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire_hook_rejection).call(this, 'everything', fromState, newState, fromAction, oldData, newData, wasForced);
|
|
28370
|
-
return false;
|
|
28432
|
+
if (this._history_length) {
|
|
28433
|
+
this._history.shove([this._state, this._data]);
|
|
28371
28434
|
}
|
|
28372
|
-
|
|
28373
|
-
|
|
28435
|
+
this._state = newState;
|
|
28436
|
+
this._state_id = newStateId;
|
|
28437
|
+
if (data_changed) {
|
|
28438
|
+
this._data = hook_args.next_data;
|
|
28374
28439
|
}
|
|
28375
|
-
|
|
28376
|
-
|
|
28377
|
-
// a hook may have redirected the destination via a complex result's
|
|
28378
|
-
// `state` (carried on hook_args.to). Apply it now, validating it names
|
|
28379
|
-
// a real state. Pre-transition hooks (including entry/exit) fired for
|
|
28380
|
-
// the original edge; the committed state and the post-hooks, observation
|
|
28381
|
-
// events, and after-timer all reflect the override. Last writer wins.
|
|
28382
|
-
// StoneCypher/fsl#1947
|
|
28383
|
-
if (hook_args.to !== newState) {
|
|
28384
|
-
const override_id = this._state_interner.id_of(hook_args.to);
|
|
28385
|
-
if (override_id === undefined) {
|
|
28386
|
-
throw new JssmError(this, `A hook overrode the transition destination to '${hook_args.to}', which is not a state in this machine`);
|
|
28440
|
+
else if (dataProvided) {
|
|
28441
|
+
this._data = newData;
|
|
28387
28442
|
}
|
|
28388
|
-
|
|
28389
|
-
|
|
28443
|
+
// success fallthrough to posthooks; intentionally no return here
|
|
28444
|
+
// look for "posthooks begin here"
|
|
28390
28445
|
}
|
|
28391
|
-
|
|
28392
|
-
|
|
28446
|
+
finally {
|
|
28447
|
+
// Close the pre-commit window on EVERY exit from the pipeline: normal
|
|
28448
|
+
// fallthrough after commit, a hook veto's `return false`, the
|
|
28449
|
+
// destination-override throw, or a user hook throwing. Post-hooks and
|
|
28450
|
+
// the boundary-action cascade run after this and may re-enter the
|
|
28451
|
+
// machine coherently from the committed state. #1953
|
|
28452
|
+
this._committing_transition = false;
|
|
28393
28453
|
}
|
|
28394
|
-
this._state = newState;
|
|
28395
|
-
this._state_id = newStateId;
|
|
28396
|
-
if (data_changed) {
|
|
28397
|
-
this._data = hook_args.next_data;
|
|
28398
|
-
}
|
|
28399
|
-
else if (dataProvided) {
|
|
28400
|
-
this._data = newData;
|
|
28401
|
-
}
|
|
28402
|
-
// success fallthrough to posthooks; intentionally no return here
|
|
28403
|
-
// look for "posthooks begin here"
|
|
28404
28454
|
// or without hooks
|
|
28405
28455
|
}
|
|
28406
28456
|
else {
|
|
@@ -29695,6 +29745,12 @@ _Machine_states = new WeakMap(), _Machine_edges = new WeakMap(), _Machine_edge_m
|
|
|
29695
29745
|
}
|
|
29696
29746
|
}
|
|
29697
29747
|
}, _Machine_fire_hook_rejection = function _Machine_fire_hook_rejection(hook_name, fromState, newState, fromAction, oldData, newData, wasForced) {
|
|
29748
|
+
// Every hook veto in transition_impl's pre-commit pipeline exits through
|
|
29749
|
+
// here, so this is the single close point for the reentrancy guard on the
|
|
29750
|
+
// rejection path: clear it before firing the event so a `rejection` listener
|
|
29751
|
+
// may itself transition (the outer transition is abandoned, not reverted).
|
|
29752
|
+
// #1953
|
|
29753
|
+
this._committing_transition = false;
|
|
29698
29754
|
__classPrivateFieldGet(this, _Machine_instances, "m", _Machine_fire).call(this, 'rejection', {
|
|
29699
29755
|
from: fromState,
|
|
29700
29756
|
to: newState,
|