jssm 5.162.6 → 5.162.7

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.
@@ -21912,6 +21912,14 @@ function nth_matching_loc(tree, predicate, n) {
21912
21912
  *
21913
21913
  */
21914
21914
  function makeTransition(this_se, from, to, isRight, _wasList, _wasIndex) {
21915
+ // the explicit quotation syntax lets `""` through the grammar; a nameless
21916
+ // state can never be addressed, so reject at edge assembly (fsl#653)
21917
+ if (from === '') {
21918
+ throw new JssmError(undefined, 'A state name may not be the empty string (transition source)');
21919
+ }
21920
+ if (to === '') {
21921
+ throw new JssmError(undefined, 'A state name may not be the empty string (transition target)');
21922
+ }
21915
21923
  const kind = isRight
21916
21924
  ? arrow_right_kind(this_se.kind)
21917
21925
  : arrow_left_kind(this_se.kind),
@@ -21951,6 +21959,11 @@ function makeTransition(this_se, from, to, isRight, _wasList, _wasIndex) {
21951
21959
  if (this_se[probability] != null) {
21952
21960
  edge.probability = this_se[probability];
21953
21961
  }
21962
+ // same rejection for `''` action quotation — an action nobody can name
21963
+ // can never be dispatched (fsl#653)
21964
+ if (edge.action === '') {
21965
+ throw new JssmError(undefined, 'An action name may not be the empty string');
21966
+ }
21954
21967
  return edge;
21955
21968
  }
21956
21969
  /*********
@@ -23790,7 +23803,7 @@ function fslSemanticSpans(text) {
23790
23803
  * Useful for runtime diagnostics and for embedding in serialized machine
23791
23804
  * snapshots so that deserializers can detect version-skew.
23792
23805
  */
23793
- const version = "5.162.6";
23806
+ const version = "5.162.7";
23794
23807
 
23795
23808
  /**
23796
23809
  * The FSL Markdown fence convention parser — pure, host-agnostic logic that
@@ -26600,11 +26613,14 @@ class Machine {
26600
26613
  }
26601
26614
  for (const field of hook_spatial_fields) {
26602
26615
  const needed = required.includes(field);
26603
- const present = HookDesc[field] !== undefined;
26604
- if (needed && !present) {
26605
- throw new JssmError(this, `${HookDesc.kind} hook requires '${field}'`);
26606
- }
26607
- if (!needed && present) {
26616
+ const value = HookDesc[field];
26617
+ // a required spatial field must be a usable key: a non-empty string.
26618
+ // presence alone isn't enough `action: false` or `from: ''` would
26619
+ // register a hook nothing can ever fire (fsl#653, fsl#659)
26620
+ if (needed && ((typeof value !== 'string') || (value === ''))) {
26621
+ throw new JssmError(this, `${HookDesc.kind} hook requires '${field}' to be a non-empty string`);
26622
+ }
26623
+ if (!needed && (value !== undefined)) {
26608
26624
  throw new JssmError(this, `${HookDesc.kind} hook does not take '${field}'`);
26609
26625
  }
26610
26626
  }