jssm 5.120.2 → 5.121.1

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/dist/cli/fsl.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- "use strict";var fs=require("fs");var path=require("path");var child_process=require("child_process");var _a;const IS_WINDOWS=process.platform==="win32";const PATH_SEP=IS_WINDOWS?";":":";const PATHEXT=IS_WINDOWS?((_a=process.env.PATHEXT)!==null&&_a!==void 0?_a:".COM;.EXE;.BAT;.CMD").split(";").map(s=>s.toLowerCase()):[""];async function findPluginOnPath(subcommand,pathEnv=process.env.PATH){if(!pathEnv)return null;const dirs=pathEnv.split(PATH_SEP).filter(d=>d.length>0);const baseName=`fsl-${subcommand}`;const NODE_EXTS=[".cjs",".mjs",".js"];const exts=IS_WINDOWS?[...PATHEXT,...NODE_EXTS]:["",...NODE_EXTS];for(const dir of dirs){for(const ext of exts){const candidate=path.join(dir,baseName+ext);try{const st=await fs.promises.stat(candidate);if(st.isFile())return candidate}catch(_a){}}}return null}function isInProcessEligible(resolvedPath){const ext=path.extname(resolvedPath).toLowerCase();if(ext!==".js"&&ext!==".mjs"&&ext!==".cjs")return false;const norm=resolvedPath.replace(/\\/g,"/");return norm.includes("/node_modules/")}async function invokeInProcess(pluginPath,argv){var _a,_b;const originalExit=process.exit;const originalArgv=process.argv;let interceptedExit=null;const ExitInterception=Symbol("ExitInterception");process.exit=code=>{interceptedExit=typeof code==="number"?code:0;throw ExitInterception};process.argv=[originalArgv[0],pluginPath,...argv];let result;try{const mod=await import(pluginPath);const cli=mod&&((_a=mod.default)!==null&&_a!==void 0?_a:mod);if(typeof cli!=="function"){process.stderr.write(`fsl: error: plugin ${pluginPath} is missing default cli() export\n`);result=2}else{const r=await cli(argv);result=typeof r==="number"?r:0}}catch(e){if(e===ExitInterception){result=interceptedExit}else{process.stderr.write(`fsl: error: plugin threw: ${(_b=e.message)!==null&&_b!==void 0?_b:String(e)}\n`);result=2}}process.exit=originalExit;process.argv=originalArgv;return result}async function invokeBySpawn(pluginPath,argv){return new Promise(res=>{const ext=path.extname(pluginPath).toLowerCase();const isCmdScript=IS_WINDOWS&&(ext===".cmd"||ext===".bat");const isNodeScript=ext===".cjs"||ext===".mjs"||ext===".js";const[spawnCmd,spawnArgs]=isCmdScript?["cmd.exe",["/c",pluginPath,...argv]]:isNodeScript?[process.execPath,[pluginPath,...argv]]:[pluginPath,argv];const child=child_process.spawn(spawnCmd,spawnArgs,{stdio:"inherit"});child.on("exit",code=>res(code));child.on("error",err=>{process.stderr.write(`fsl: error: failed to spawn plugin: ${err.message}\n`);res(2)})})}const RESERVED_FLAGS=new Set(["--help","-h","--version","-V"]);const RESERVED_NAMES=new Set(["help","version"]);const getDispatcherVersion=()=>"5.120.2";const printDispatcherHelp=()=>{process.stdout.write(`fsl — finite-state language toolchain dispatcher\n\nUsage:\n fsl <subcommand> [options] [args...]\n fsl [--help|--version]\n\nBuilt-in subcommands (resolved via PATH):\n render Render FSL machines to SVG, DOT, PNG, JPEG, or HTML\n\nDiscovery:\n Any \`fsl-<name>\` executable on PATH is dispatched when you run\n \`fsl <name>\`. Third-party plugins follow the same contract as\n first-party ones.\n\n See: https://github.com/StoneCypher/jssm\n`)};async function dispatch(argv){let verbose=false;if(argv[0]==="--verbose"){verbose=true;argv=argv.slice(1)}if(argv.length===0||RESERVED_FLAGS.has(argv[0])){if(argv[0]==="--version"||argv[0]==="-V"){process.stdout.write(`fsl ${getDispatcherVersion()}\n`);return 0}printDispatcherHelp();return 0}const subcommand=argv[0];const rest=argv.slice(1);if(RESERVED_NAMES.has(subcommand)){if(subcommand==="version"){process.stdout.write(`fsl ${getDispatcherVersion()}\n`);return 0}printDispatcherHelp();return 0}const pluginPath=await findPluginOnPath(subcommand);if(!pluginPath){process.stderr.write(`fsl: '${subcommand}' is not a known subcommand and no \`fsl-${subcommand}\` was found on PATH\n`);return 1}if(verbose){process.stderr.write(`fsl: resolved '${subcommand}' to ${pluginPath}\n`)}if(isInProcessEligible(pluginPath)){return invokeInProcess(pluginPath,rest)}return invokeBySpawn(pluginPath,rest)}
2
+ "use strict";var fs=require("fs");var path=require("path");var child_process=require("child_process");var _a;const IS_WINDOWS=process.platform==="win32";const PATH_SEP=IS_WINDOWS?";":":";const PATHEXT=IS_WINDOWS?((_a=process.env.PATHEXT)!==null&&_a!==void 0?_a:".COM;.EXE;.BAT;.CMD").split(";").map(s=>s.toLowerCase()):[""];async function findPluginOnPath(subcommand,pathEnv=process.env.PATH){if(!pathEnv)return null;const dirs=pathEnv.split(PATH_SEP).filter(d=>d.length>0);const baseName=`fsl-${subcommand}`;const NODE_EXTS=[".cjs",".mjs",".js"];const exts=IS_WINDOWS?[...PATHEXT,...NODE_EXTS]:["",...NODE_EXTS];for(const dir of dirs){for(const ext of exts){const candidate=path.join(dir,baseName+ext);try{const st=await fs.promises.stat(candidate);if(st.isFile())return candidate}catch(_a){}}}return null}function isInProcessEligible(resolvedPath){const ext=path.extname(resolvedPath).toLowerCase();if(ext!==".js"&&ext!==".mjs"&&ext!==".cjs")return false;const norm=resolvedPath.replace(/\\/g,"/");return norm.includes("/node_modules/")}async function invokeInProcess(pluginPath,argv){var _a,_b;const originalExit=process.exit;const originalArgv=process.argv;let interceptedExit=null;const ExitInterception=Symbol("ExitInterception");process.exit=code=>{interceptedExit=typeof code==="number"?code:0;throw ExitInterception};process.argv=[originalArgv[0],pluginPath,...argv];let result;try{const mod=await import(pluginPath);const cli=mod&&((_a=mod.default)!==null&&_a!==void 0?_a:mod);if(typeof cli!=="function"){process.stderr.write(`fsl: error: plugin ${pluginPath} is missing default cli() export\n`);result=2}else{const r=await cli(argv);result=typeof r==="number"?r:0}}catch(e){if(e===ExitInterception){result=interceptedExit}else{process.stderr.write(`fsl: error: plugin threw: ${(_b=e.message)!==null&&_b!==void 0?_b:String(e)}\n`);result=2}}process.exit=originalExit;process.argv=originalArgv;return result}async function invokeBySpawn(pluginPath,argv){return new Promise(res=>{const ext=path.extname(pluginPath).toLowerCase();const isCmdScript=IS_WINDOWS&&(ext===".cmd"||ext===".bat");const isNodeScript=ext===".cjs"||ext===".mjs"||ext===".js";const[spawnCmd,spawnArgs]=isCmdScript?["cmd.exe",["/c",pluginPath,...argv]]:isNodeScript?[process.execPath,[pluginPath,...argv]]:[pluginPath,argv];const child=child_process.spawn(spawnCmd,spawnArgs,{stdio:"inherit"});child.on("exit",code=>res(code));child.on("error",err=>{process.stderr.write(`fsl: error: failed to spawn plugin: ${err.message}\n`);res(2)})})}const RESERVED_FLAGS=new Set(["--help","-h","--version","-V"]);const RESERVED_NAMES=new Set(["help","version"]);const getDispatcherVersion=()=>"5.121.1";const printDispatcherHelp=()=>{process.stdout.write(`fsl — finite-state language toolchain dispatcher\n\nUsage:\n fsl <subcommand> [options] [args...]\n fsl [--help|--version]\n\nBuilt-in subcommands (resolved via PATH):\n render Render FSL machines to SVG, DOT, PNG, JPEG, or HTML\n\nDiscovery:\n Any \`fsl-<name>\` executable on PATH is dispatched when you run\n \`fsl <name>\`. Third-party plugins follow the same contract as\n first-party ones.\n\n See: https://github.com/StoneCypher/jssm\n`)};async function dispatch(argv){let verbose=false;if(argv[0]==="--verbose"){verbose=true;argv=argv.slice(1)}if(argv.length===0||RESERVED_FLAGS.has(argv[0])){if(argv[0]==="--version"||argv[0]==="-V"){process.stdout.write(`fsl ${getDispatcherVersion()}\n`);return 0}printDispatcherHelp();return 0}const subcommand=argv[0];const rest=argv.slice(1);if(RESERVED_NAMES.has(subcommand)){if(subcommand==="version"){process.stdout.write(`fsl ${getDispatcherVersion()}\n`);return 0}printDispatcherHelp();return 0}const pluginPath=await findPluginOnPath(subcommand);if(!pluginPath){process.stderr.write(`fsl: '${subcommand}' is not a known subcommand and no \`fsl-${subcommand}\` was found on PATH\n`);return 1}if(verbose){process.stderr.write(`fsl: resolved '${subcommand}' to ${pluginPath}\n`)}if(isInProcessEligible(pluginPath)){return invokeInProcess(pluginPath,rest)}return invokeBySpawn(pluginPath,rest)}
3
3
  /**
4
4
  * Binary entry for `fsl` (and its alias `jssm`). Forwards argv to
5
5
  * `dispatch()` and exits with the returned code.
@@ -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.120.2 at 5/16/2026, 5:12:50 PM
21
+ * Generated for version 5.121.1 at 5/17/2026, 11:02:30 AM
22
22
 
23
23
  -->
24
- # jssm 5.120.2
24
+ # jssm 5.121.1
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.** 5,990 tests at 100.0% line coverage
284
+ library.** 6,027 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
- ***5,990 tests***, run 56,777 times.
417
+ ***6,027 tests***, run 56,814 times.
418
418
 
419
- - 5,477 specs with 100.0% coverage
419
+ - 5,514 specs with 100.0% coverage
420
420
  - 513 fuzz tests with 20.2% coverage
421
- - 4,280 TypeScript lines - 1.4 tests per line, 13.3 generated tests per line
421
+ - 4,281 TypeScript lines - 1.4 tests per line, 13.3 generated tests per line
422
422
 
423
423
  [![Actions Status](https://github.com/StoneCypher/jssm/workflows/Node%20CI/badge.svg)](https://github.com/StoneCypher/jssm/actions)
424
424
  [![NPM version](https://img.shields.io/npm/v/jssm.svg)](https://www.npmjs.com/package/jssm)
@@ -702,8 +702,9 @@ declare class Machine<mDT> {
702
702
  * @returns An array of `{from, to}` inclusive character ranges.
703
703
  *
704
704
  * @example
705
+ * import { sm } from 'jssm';
705
706
  * const m = sm`a -> b;`;
706
- * m.all_state_name_chars().some(r => '+' >= r.from && '+' <= r.to); // true
707
+ * m.all_state_name_chars().some(r => '+' >= r.from && '+' <= r.to); // => true
707
708
  */
708
709
  all_state_name_chars(): ReadonlyArray<{
709
710
  from: string;
@@ -716,8 +717,9 @@ declare class Machine<mDT> {
716
717
  * @returns An array of `{from, to}` inclusive character ranges.
717
718
  *
718
719
  * @example
720
+ * import { sm } from 'jssm';
719
721
  * const m = sm`a -> b;`;
720
- * m.all_state_name_first_chars().some(r => '+' >= r.from && '+' <= r.to); // false
722
+ * m.all_state_name_first_chars().some(r => '+' >= r.from && '+' <= r.to); // => false
721
723
  */
722
724
  all_state_name_first_chars(): ReadonlyArray<{
723
725
  from: string;
@@ -730,9 +732,10 @@ declare class Machine<mDT> {
730
732
  * @returns An array of `{from, to}` inclusive character ranges.
731
733
  *
732
734
  * @example
735
+ * import { sm } from 'jssm';
733
736
  * const m = sm`a -> b;`;
734
- * m.all_action_label_chars().some(r => ' ' >= r.from && ' ' <= r.to); // true
735
- * m.all_action_label_chars().some(r => "'" >= r.from && "'" <= r.to); // false
737
+ * m.all_action_label_chars().some(r => ' ' >= r.from && ' ' <= r.to); // => true
738
+ * m.all_action_label_chars().some(r => "'" >= r.from && "'" <= r.to); // => false
736
739
  */
737
740
  all_action_label_chars(): ReadonlyArray<{
738
741
  from: string;
@@ -1915,6 +1918,27 @@ declare function abstract_hook_step<mDT>(maybe_hook: HookHandler<mDT> | undefine
1915
1918
  *
1916
1919
  */
1917
1920
  declare function abstract_everything_hook_step<mDT>(maybe_hook: EverythingHookHandler<mDT> | undefined, hook_args: EverythingHookContext<mDT>): HookComplexResult<mDT>;
1921
+ /**
1922
+ * Compares two semantic version strings.
1923
+ *
1924
+ * @param {string} v1 - First version string (e.g., "5.104.2")
1925
+ * @param {string} v2 - Second version string (e.g., "5.103.1")
1926
+ *
1927
+ * @returns {number} - Negative if v1 < v2, 0 if equal, positive if v1 > v2
1928
+ *
1929
+ * @example
1930
+ * import { compareVersions } from 'jssm';
1931
+ * compareVersions("5.104.2", "5.103.1"); // => 1
1932
+ *
1933
+ * @example
1934
+ * import { compareVersions } from 'jssm';
1935
+ * compareVersions("5.104.2", "6.0.0"); // => -1
1936
+ *
1937
+ * @example
1938
+ * import { compareVersions } from 'jssm';
1939
+ * compareVersions("5.104.2", "5.104.2"); // => 0
1940
+ */
1941
+ declare function compareVersions(v1: string, v2: string): number;
1918
1942
  /**
1919
1943
  * Deserializes a previously serialized machine state.
1920
1944
  *
@@ -1932,9 +1956,11 @@ declare function abstract_everything_hook_step<mDT>(maybe_hook: EverythingHookHa
1932
1956
  * @throws {Error} If the serialization is from a future version
1933
1957
  *
1934
1958
  * @example
1935
- * const machine = jssm.from("a -> b;");
1959
+ * import { from, deserialize } from 'jssm';
1960
+ * const machine = from("a -> b;");
1936
1961
  * const serialized = machine.serialize();
1937
- * const restored = jssm.deserialize("a -> b;", serialized);
1962
+ * const restored = deserialize("a -> b;", serialized);
1963
+ * restored.state(); // => 'a'
1938
1964
  */
1939
1965
  declare function deserialize<mDT>(machine_string: string, ser: JssmSerialization<mDT>): Machine<mDT>;
1940
- export { version, build_time, transfer_state_properties, Machine, deserialize, make, wrap_parse as parse, compile, sm, from, arrow_direction, arrow_left_kind, arrow_right_kind, seq, unique, find_repeated, weighted_rand_select, histograph, weighted_sample_select, weighted_histo_key, gen_splitmix32, sleep, constants, shapes, gviz_shapes, named_colors, state_name_chars, state_name_first_chars, action_label_chars, is_hook_rejection, is_hook_complex_result, abstract_hook_step, abstract_everything_hook_step, state_style_condense, FslDirections };
1966
+ export { version, build_time, transfer_state_properties, Machine, deserialize, compareVersions, make, wrap_parse as parse, compile, sm, from, arrow_direction, arrow_left_kind, arrow_right_kind, seq, unique, find_repeated, weighted_rand_select, histograph, weighted_sample_select, weighted_histo_key, gen_splitmix32, sleep, constants, shapes, gviz_shapes, named_colors, state_name_chars, state_name_first_chars, action_label_chars, is_hook_rejection, is_hook_complex_result, abstract_hook_step, abstract_everything_hook_step, state_style_condense, FslDirections };