jssm 5.162.13 → 5.162.16
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 +1 -1
- package/dist/cdn/viz.js +1 -1
- package/dist/cli/fsl-export-system-prompt.cjs +1 -221
- 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 +7 -7
- package/dist/deno/jssm.js +1 -1
- package/dist/deno/jssm_types.d.ts +57 -6
- package/dist/deno/jssm_util.d.ts +1 -1
- package/dist/fence/fence.js +63 -7
- 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 +58 -7
- package/jssm.es6.d.ts +58 -7
- package/jssm.fence.d.ts +48 -10
- package/jssm_viz.es5.d.cts +48 -10
- package/jssm_viz.es6.d.ts +48 -10
- package/package.json +4 -3
|
@@ -38,12 +38,18 @@ type JssmPermitted = 'required' | 'disallowed';
|
|
|
38
38
|
*/
|
|
39
39
|
type JssmPermittedOpt = 'required' | 'disallowed' | 'optional';
|
|
40
40
|
/**
|
|
41
|
-
*
|
|
42
|
-
* encodes a direction (one-way left/right, or two-way) and a "kind" for
|
|
41
|
+
* Every arrow token recognized by the FSL grammar — all 42 spellings. Each
|
|
42
|
+
* arrow encodes a direction (one-way left/right, or two-way) and a "kind" for
|
|
43
43
|
* each direction (`-` legal, `=` main path, `~` forced-only). See the
|
|
44
44
|
* Language Reference docs for the full semantic table.
|
|
45
|
+
*
|
|
46
|
+
* Every arrow has an ASCII spelling and a unicode spelling, and each half of a
|
|
47
|
+
* two-way arrow may be spelled independently, so the two-way arrows also have
|
|
48
|
+
* mixed ASCII/unicode spellings (`←=>`, `<-⇒`, and so on). All of them are
|
|
49
|
+
* accepted, by the grammar and by {@link arrow_direction},
|
|
50
|
+
* {@link arrow_left_kind}, and {@link arrow_right_kind}.
|
|
45
51
|
*/
|
|
46
|
-
type JssmArrow = '->' | '
|
|
52
|
+
type JssmArrow = '->' | '→' | '=>' | '⇒' | '~>' | '↛' | '<-' | '←' | '<=' | '⇐' | '<~' | '↚' | '<->' | '↔' | '<=>' | '⇔' | '<~>' | '↮' | '<-=>' | '←⇒' | '←=>' | '<-⇒' | '<-~>' | '←↛' | '←~>' | '<-↛' | '<=->' | '⇐→' | '⇐->' | '<=→' | '<=~>' | '⇐↛' | '⇐~>' | '<=↛' | '<~->' | '↚→' | '↚->' | '<~→' | '<~=>' | '↚⇒' | '↚=>' | '<~⇒';
|
|
47
53
|
/**
|
|
48
54
|
* A type teaching Typescript the various supported shapes for nodes, mostly inherited from GraphViz
|
|
49
55
|
*/
|
|
@@ -786,8 +792,22 @@ type JssmGenericConfig<StateType, DataType> = {
|
|
|
786
792
|
state_hooks?: JssmStateHooks;
|
|
787
793
|
rng_seed?: number | undefined;
|
|
788
794
|
time_source?: () => number;
|
|
789
|
-
|
|
790
|
-
|
|
795
|
+
/**
|
|
796
|
+
* Schedules `fn` to run after `delay_ms`, and returns a handle that will be
|
|
797
|
+
* handed back to `clear_timeout_source` untouched. Defaults to `setTimeout`.
|
|
798
|
+
*
|
|
799
|
+
* The handle is typed `number` — the browser shape. Node's `setTimeout`
|
|
800
|
+
* returns a `Timeout` object instead, so a Node-shaped source casts it (as
|
|
801
|
+
* jssm's own `DEFAULT_TIMEOUT_SOURCE` does); jssm never inspects the handle,
|
|
802
|
+
* it only stores it and gives it back.
|
|
803
|
+
*
|
|
804
|
+
* (Before 5.162.14 these read `(Function, number) => number`, in which
|
|
805
|
+
* `Function` and `number` were *parameter names*, not types — so both
|
|
806
|
+
* parameters were silently `any`.)
|
|
807
|
+
*/
|
|
808
|
+
timeout_source?: (fn: () => void, delay_ms: number) => number;
|
|
809
|
+
/** Cancels a timer previously scheduled by `timeout_source`. Defaults to `clearTimeout`. */
|
|
810
|
+
clear_timeout_source?: (handle: number) => void;
|
|
791
811
|
};
|
|
792
812
|
/**
|
|
793
813
|
* Internal compiler intermediate: a single aggregated rule produced while
|
|
@@ -810,7 +830,15 @@ type JssmCompileRule<StateType> = {
|
|
|
810
830
|
type JssmCompileSe<StateType, mDT> = {
|
|
811
831
|
to: StateType;
|
|
812
832
|
se?: JssmCompileSe<StateType, mDT>;
|
|
813
|
-
|
|
833
|
+
/**
|
|
834
|
+
* The arrow token as the parser emitted it. Deliberately `string` and not
|
|
835
|
+
* {@link JssmArrow}: this internal intermediate flows through the whole
|
|
836
|
+
* compiler, and threading a 42-member string-literal union through that much
|
|
837
|
+
* control-flow analysis overflows `tsc`'s stack (it type-checks standalone
|
|
838
|
+
* but dies under `npm run make`). The value *is* a `JssmArrow` — the two
|
|
839
|
+
* places that care re-assert it on the way into the arrow classifiers.
|
|
840
|
+
*/
|
|
841
|
+
kind: string;
|
|
814
842
|
l_action?: StateType;
|
|
815
843
|
r_action?: StateType;
|
|
816
844
|
l_probability: number;
|
|
@@ -1101,10 +1129,33 @@ type HookResult<mDT> = true | false | undefined | void | HookComplexResult<mDT>;
|
|
|
1101
1129
|
* the payload that will be committed if the transition is accepted —
|
|
1102
1130
|
* handlers may inspect or mutate the latter via a
|
|
1103
1131
|
* {@link HookComplexResult} return value.
|
|
1132
|
+
*
|
|
1133
|
+
* The remaining fields describe the transition the hook is firing on. They
|
|
1134
|
+
* are optional because a handler is not obliged to care about them, but the
|
|
1135
|
+
* transition path always supplies all of them; `action` is `undefined` when
|
|
1136
|
+
* the transition was not driven by an action.
|
|
1104
1137
|
*/
|
|
1105
1138
|
type HookContext<mDT> = {
|
|
1106
1139
|
data: mDT;
|
|
1107
1140
|
next_data: mDT;
|
|
1141
|
+
/** The state being left. */
|
|
1142
|
+
from?: string;
|
|
1143
|
+
/** The state being entered. */
|
|
1144
|
+
to?: string;
|
|
1145
|
+
/** The action that drove the transition, or `undefined` if none did. */
|
|
1146
|
+
action?: string;
|
|
1147
|
+
/** Whether this transition came from `force_transition` rather than `transition`. */
|
|
1148
|
+
forced?: boolean;
|
|
1149
|
+
/**
|
|
1150
|
+
* Which arrow kind the traversed edge carries — `legal`, `main`, or `forced`.
|
|
1151
|
+
*
|
|
1152
|
+
* Populated **only when a transition-kind hook is installed** (a standard,
|
|
1153
|
+
* main, or forced transition hook, or their post- equivalents). With no such
|
|
1154
|
+
* hook registered there is nothing to switch on, so jssm skips resolving the
|
|
1155
|
+
* edge's kind and this is `undefined`. Install `hook_standard_transition`
|
|
1156
|
+
* (or a sibling) if a general handler needs to read it.
|
|
1157
|
+
*/
|
|
1158
|
+
trans_type?: JssmArrowKind;
|
|
1108
1159
|
};
|
|
1109
1160
|
/**
|
|
1110
1161
|
* Context object passed to "everything" hooks ({@link EverythingHookHandler}
|
package/dist/deno/jssm_util.d.ts
CHANGED
|
@@ -63,7 +63,7 @@ declare const array_box_if_string: (n: any) => any;
|
|
|
63
63
|
* @throws {TypeError} If `options` is not a non-empty array of objects.
|
|
64
64
|
*
|
|
65
65
|
*/
|
|
66
|
-
declare const weighted_rand_select: (options: Array<any>, probability_property
|
|
66
|
+
declare const weighted_rand_select: (options: Array<any>, probability_property?: string, rng?: JssmRng) => any;
|
|
67
67
|
/*******
|
|
68
68
|
*
|
|
69
69
|
* Returns, for a non-negative integer argument `n`, the series `[0 .. n]`.
|
package/dist/fence/fence.js
CHANGED
|
@@ -22318,9 +22318,12 @@ function makeTransition(this_se, from, to, isRight, _wasList, _wasIndex) {
|
|
|
22318
22318
|
if (to === '') {
|
|
22319
22319
|
throw new JssmError(undefined, 'A state name may not be the empty string (transition target)');
|
|
22320
22320
|
}
|
|
22321
|
-
|
|
22322
|
-
|
|
22323
|
-
|
|
22321
|
+
// `this_se.kind` is typed `string` rather than JssmArrow — see the field's own
|
|
22322
|
+
// note in jssm_types.ts. The classifiers reject anything that isn't a real
|
|
22323
|
+
// arrow, so an unsound value throws here rather than passing silently.
|
|
22324
|
+
const arrow = this_se.kind, kind = isRight
|
|
22325
|
+
? arrow_right_kind(arrow)
|
|
22326
|
+
: arrow_left_kind(arrow),
|
|
22324
22327
|
// action and probability are pre-declared (as after_time always was)
|
|
22325
22328
|
// so every compiled edge shares ONE hidden class regardless of which
|
|
22326
22329
|
// optional fields its declaration carries. The conditional assigns
|
|
@@ -24223,7 +24226,7 @@ function fslSemanticSpans(text) {
|
|
|
24223
24226
|
* Useful for runtime diagnostics and for embedding in serialized machine
|
|
24224
24227
|
* snapshots so that deserializers can detect version-skew.
|
|
24225
24228
|
*/
|
|
24226
|
-
const version = "5.162.
|
|
24229
|
+
const version = "5.162.16";
|
|
24227
24230
|
|
|
24228
24231
|
/**
|
|
24229
24232
|
* The FSL Markdown fence convention parser — pure, host-agnostic logic that
|
|
@@ -27883,7 +27886,13 @@ class Machine {
|
|
|
27883
27886
|
*
|
|
27884
27887
|
*/
|
|
27885
27888
|
transition_impl(newStateOrAction, newData, wasForced, wasAction, dataProvided = newData !== undefined) {
|
|
27886
|
-
let valid = false,
|
|
27889
|
+
let valid = false,
|
|
27890
|
+
// deliberately `string`, not `JssmArrowKind`, though only arrow kinds are
|
|
27891
|
+
// ever assigned: declaring this local as the 4-member union makes tsc's
|
|
27892
|
+
// control-flow analysis narrow it across the whole of this (very large)
|
|
27893
|
+
// function, which overflows the checker's stack under `npm run make`.
|
|
27894
|
+
// The union is recovered at the hook boundary below -- see hook_args_obj.
|
|
27895
|
+
trans_type, newState, newStateId = NaN, actionId = NaN, fromAction;
|
|
27887
27896
|
if (wasForced) {
|
|
27888
27897
|
// numeric inline of valid_force_transition: any existing edge
|
|
27889
27898
|
// qualifies, forced or not. one string probe (the user's target name)
|
|
@@ -27955,7 +27964,10 @@ class Machine {
|
|
|
27955
27964
|
to: newState,
|
|
27956
27965
|
next_data: newData,
|
|
27957
27966
|
forced: wasForced,
|
|
27958
|
-
trans_type
|
|
27967
|
+
// sound: the only values ever assigned to trans_type are an edge's
|
|
27968
|
+
// `kind` and the literal 'forced'. The local is typed `string` only
|
|
27969
|
+
// to keep tsc's flow analysis off it (see its declaration above).
|
|
27970
|
+
trans_type: trans_type
|
|
27959
27971
|
}
|
|
27960
27972
|
: undefined;
|
|
27961
27973
|
const hook_args = hook_args_obj;
|
|
@@ -29963,6 +29975,50 @@ function vc(col) {
|
|
|
29963
29975
|
function doublequote(txt) {
|
|
29964
29976
|
return txt.replace(/"/g, String.raw `\"`);
|
|
29965
29977
|
}
|
|
29978
|
+
/**
|
|
29979
|
+
* URL schemes that are safe to emit into a rendered diagram's `<a xlink:href>`.
|
|
29980
|
+
* Anything not in this set (notably `javascript:`, `data:`, `vbscript:`) is a
|
|
29981
|
+
* script-execution vector once the SVG is injected into a live DOM.
|
|
29982
|
+
* @internal
|
|
29983
|
+
*/
|
|
29984
|
+
const SAFE_URL_SCHEMES = new Set(['http', 'https', 'mailto', 'ftp', 'ftps', 'tel']);
|
|
29985
|
+
/**
|
|
29986
|
+
* Sanitize a state's `url` before it is embedded in DOT (and thence in the
|
|
29987
|
+
* rendered SVG's `xlink:href`). A URL with a scheme is kept only when that
|
|
29988
|
+
* scheme is on the {@link SAFE_URL_SCHEMES} allowlist; a schemeless URL
|
|
29989
|
+
* (relative path, `#anchor`, query) is always safe and kept as-is. An unsafe
|
|
29990
|
+
* URL is dropped (returns `''`) and a warning is emitted, so the diagram still
|
|
29991
|
+
* renders — just without the dangerous link.
|
|
29992
|
+
*
|
|
29993
|
+
* Leading ASCII control characters and whitespace are stripped **before**
|
|
29994
|
+
* inspecting the scheme, because browsers ignore them when parsing a URL — so
|
|
29995
|
+
* `java\tscript:alert(1)` is recognized and dropped rather than smuggled past.
|
|
29996
|
+
*
|
|
29997
|
+
* ```typescript
|
|
29998
|
+
* render_safe_url('https://example.com'); // 'https://example.com'
|
|
29999
|
+
* render_safe_url('#node'); // '#node'
|
|
30000
|
+
* render_safe_url('javascript:alert(1)'); // '' (dropped + warned)
|
|
30001
|
+
* ```
|
|
30002
|
+
* @param raw The raw `url` value from a state's config.
|
|
30003
|
+
* @returns The original URL if its scheme is safe or absent, otherwise `''`.
|
|
30004
|
+
* @internal
|
|
30005
|
+
*/
|
|
30006
|
+
function render_safe_url(raw) {
|
|
30007
|
+
if (!raw) {
|
|
30008
|
+
return '';
|
|
30009
|
+
}
|
|
30010
|
+
// eslint-disable-next-line no-control-regex -- browsers strip these before scheme parsing
|
|
30011
|
+
const stripped = raw.replace(/[\u{0}-\u{20}]+/gu, '');
|
|
30012
|
+
const scheme_match = /^([a-z][a-z0-9+.-]*):/i.exec(stripped);
|
|
30013
|
+
if (scheme_match) {
|
|
30014
|
+
const scheme = scheme_match[1].toLowerCase();
|
|
30015
|
+
if (!SAFE_URL_SCHEMES.has(scheme)) {
|
|
30016
|
+
console.warn(`jssm-viz: dropping state url with unsafe scheme "${scheme}:"`);
|
|
30017
|
+
return '';
|
|
30018
|
+
}
|
|
30019
|
+
}
|
|
30020
|
+
return raw;
|
|
30021
|
+
}
|
|
29966
30022
|
/**
|
|
29967
30023
|
* Reverse {@link doublequote}: turn DOT's `\"` escape back into the literal
|
|
29968
30024
|
* `"` that graphviz renders into SVG `<text>` content. Used by
|
|
@@ -30398,7 +30454,7 @@ function state_node_line(u_jssm, s, state_index, state_kinds, hide_state_labels,
|
|
|
30398
30454
|
['style', compose_style_string(style)],
|
|
30399
30455
|
['fontcolor', style.textColor || ''],
|
|
30400
30456
|
['image', style.image || ''],
|
|
30401
|
-
['URL', style.url || ''],
|
|
30457
|
+
['URL', render_safe_url(style.url || '')],
|
|
30402
30458
|
['fillcolor', fillcolor]
|
|
30403
30459
|
]
|
|
30404
30460
|
.filter(r => r[1])
|