jssm 5.162.7 → 5.162.9

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.
Files changed (53) hide show
  1. package/README.md +7 -7
  2. package/custom-elements.json +24 -24
  3. package/dist/cdn/instance.js +5 -3
  4. package/dist/cdn/viz.js +1 -1
  5. package/dist/cli/fsl-export-system-prompt.cjs +27 -24
  6. package/dist/cli/fsl-render.cjs +1 -1
  7. package/dist/cli/fsl.cjs +1 -1
  8. package/dist/cli/lib.cjs +1 -1
  9. package/dist/cli/lib.mjs +1 -1
  10. package/dist/cm6/fsl_language.js +10 -14
  11. package/dist/deno/README.md +7 -7
  12. package/dist/deno/fence.d.ts +0 -1
  13. package/dist/deno/fsl_fence_highlight.d.ts +0 -4
  14. package/dist/deno/fsl_fence_render.d.ts +0 -8
  15. package/dist/deno/fsl_gif.d.ts +0 -8
  16. package/dist/deno/fsl_markdown_fence.d.ts +0 -5
  17. package/dist/deno/fsl_svg_patch.d.ts +0 -6
  18. package/dist/deno/fsl_walk.d.ts +0 -2
  19. package/dist/deno/jssm.d.ts +214 -503
  20. package/dist/deno/jssm.js +1 -1
  21. package/dist/deno/jssm_compiler.d.ts +1 -1
  22. package/dist/deno/jssm_constants.d.ts +0 -3
  23. package/dist/deno/jssm_intern.d.ts +0 -15
  24. package/dist/deno/jssm_theme.d.ts +2 -2
  25. package/dist/deno/jssm_types.d.ts +13 -34
  26. package/dist/deno/jssm_util.d.ts +20 -6
  27. package/dist/deno/jssm_viz.d.ts +5 -51
  28. package/dist/es6/cm6/fsl_language.d.ts +0 -2
  29. package/dist/fence/fence.js +2052 -1857
  30. package/dist/jssm.es5.cjs +1 -1
  31. package/dist/jssm.es5.iife.js +1 -1
  32. package/dist/jssm.es6.mjs +1 -1
  33. package/dist/jssm_viz.cjs +1 -1
  34. package/dist/jssm_viz.iife.cjs +1 -1
  35. package/dist/jssm_viz.mjs +1 -1
  36. package/dist/wc/docs.define.js +0 -5
  37. package/dist/wc/docs.js +79 -43
  38. package/dist/wc/editor.define.js +0 -5
  39. package/dist/wc/editor.js +1 -7
  40. package/dist/wc/instance.define.js +0 -6
  41. package/dist/wc/instance.js +93 -115
  42. package/dist/wc/viz.define.js +0 -6
  43. package/dist/wc/viz.js +22 -36
  44. package/dist/wc/widgets.define.js +0 -5
  45. package/dist/wc/widgets.js +117 -95
  46. package/jssm.cli.d.cts +0 -8
  47. package/jssm.cli.d.ts +0 -8
  48. package/jssm.es5.d.cts +449 -808
  49. package/jssm.es6.d.ts +449 -808
  50. package/jssm.fence.d.ts +213 -508
  51. package/jssm_viz.es5.d.cts +216 -529
  52. package/jssm_viz.es6.d.ts +216 -529
  53. package/package.json +21 -11
@@ -77,13 +77,13 @@ const ENUM_KEYWORDS = new Set([
77
77
  ]);
78
78
  /** Custom token-type string emitted for deprecated keywords; mapped in `tokenTable`. */
79
79
  const DEPRECATED_TOKEN = 'fslDeprecatedKeyword';
80
- const ARROWS = /^(?:<-=>|<-~>|<=->|<=~>|<~->|<~=>|<->|<=>|<~>|->|<-|=>|<=|~>|<~|↔|←|→|⇔|⇐|⇒|↮|↚|↛)/;
80
+ const ARROWS = /^(?:<-=>|<-~>|<=->|<=~>|<~->|<~=>|<->|<=>|<~>|->|<-|=>|<=|~>|<~|[↔←→⇔⇐⇒↮↚↛])/;
81
81
  const COMPARATORS = /^(?:>=|<=|>|<)/;
82
82
  // Mirrors the grammar's AtomFirstLetter / AtomLetter rules (fsl_parser.peg:263-267).
83
83
  // The high-unicode tail is the range U+0080..U+FFFF (escaped below). The
84
84
  // original sketch anchored the range at the comma, wrongly swallowing { } ; : |.
85
- const ATOM_START = /[0-9a-zA-Z._!$^*?,\u0080-\uFFFF]/;
86
- const ATOM_BODY = /[0-9a-zA-Z.+_^()*&$#@!?,\u0080-\uFFFF]/;
85
+ const ATOM_START = /[\w.!$^*?,\u{80}-\u{FFFF}]/u;
86
+ const ATOM_BODY = /[\w.+^()*&$#@!?,\u{80}-\u{FFFF}]/u;
87
87
  /**
88
88
  * The StreamLanguage tokenizer for FSL. Classifies each token into a standard
89
89
  * CodeMirror highlight name, or {@link DEPRECATED_TOKEN} (mapped through
@@ -129,7 +129,7 @@ const fslStreamParser = {
129
129
  if (stream.match(/^\d+(?:\.\d+)*/)) {
130
130
  return 'number';
131
131
  }
132
- if (stream.match(/^&[A-Za-z_]\w*/)) {
132
+ if (stream.match(/^&[A-Z_]\w*/i)) {
133
133
  return 'variableName.special';
134
134
  }
135
135
  // Invariant: the loop guards `!eol` and `eatSpace()` returned false above,
@@ -139,13 +139,11 @@ const fslStreamParser = {
139
139
  let tok = '';
140
140
  let next = stream.peek();
141
141
  while (next !== undefined) {
142
- if (ATOM_BODY.test(next)) {
143
- tok += stream.next();
144
- }
145
- else if (next === '-' && ATOM_BODY.test(stream.string.slice(stream.pos + 1, stream.pos + 2))) {
146
- // An interior hyphen (between word chars) joins a compound key like
147
- // `background-color`; a trailing one (before `>` of `->`, or at EOL)
148
- // does not. `slice` yields '' past the end, so no nullish branch.
142
+ // An interior hyphen (between word chars) joins a compound key like
143
+ // `background-color`; a trailing one (before `>` of `->`, or at EOL)
144
+ // does not. `slice` yields '' past the end, so no nullish branch.
145
+ const interior_hyphen = next === '-' && ATOM_BODY.test(stream.string.slice(stream.pos + 1, stream.pos + 2));
146
+ if (ATOM_BODY.test(next) || interior_hyphen) {
149
147
  tok += stream.next();
150
148
  }
151
149
  else {
@@ -167,7 +165,7 @@ const fslStreamParser = {
167
165
  }
168
166
  return 'variableName';
169
167
  }
170
- if (stream.match(/^[\[\]{}()]/)) {
168
+ if (stream.match(/^[[\]{}()]/)) {
171
169
  return 'bracket';
172
170
  }
173
171
  if (stream.match(/^[;:,|]/)) {
@@ -198,9 +196,7 @@ const fslHighlightStyle = HighlightStyle.define([
198
196
  ]);
199
197
  /**
200
198
  * CodeMirror 6 `LanguageSupport` for FSL. Drop into an editor's `extensions`.
201
- *
202
199
  * @returns A `LanguageSupport` extension for FSL highlighting.
203
- *
204
200
  * @example
205
201
  * import { EditorView, basicSetup } from 'codemirror';
206
202
  * import { fsl } from 'jssm/cm6';
@@ -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.162.7 at 7/10/2026, 1:56:00 PM
21
+ * Generated for version 5.162.9 at 7/12/2026, 3:21:43 AM
22
22
 
23
23
  -->
24
- # jssm 5.162.7
24
+ # jssm 5.162.9
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/) ·
@@ -333,7 +333,7 @@ That decision shows up everywhere downstream:
333
333
  or run `npm run benny` against your own machine.
334
334
 
335
335
  - **More thoroughly tested than any other JavaScript state-machine
336
- library.** 8,090 tests at 100.0% line coverage
336
+ library.** 8,151 tests at 100.0% line coverage
337
337
  ([report](https://coveralls.io/github/StoneCypher/jssm)), plus
338
338
  fuzz testing via `fast-check`, with parser test data across ten natural
339
339
  languages and Emoji.
@@ -466,11 +466,11 @@ If your contribution is missing here, please open an issue.
466
466
 
467
467
  <br/>
468
468
 
469
- ***8,090 tests***, run 83,528 times.
469
+ ***8,151 tests***, run 83,589 times.
470
470
 
471
- - 7,328 specs with 100.0% coverage
472
- - 762 fuzz tests with 48.1% coverage
473
- - 10,751 TypeScript lines - 0.8 tests per line, 7.8 generated tests per line
471
+ - 7,389 specs with 100.0% coverage
472
+ - 762 fuzz tests with 47.9% coverage
473
+ - 10,882 TypeScript lines - 0.7 tests per line, 7.7 generated tests per line
474
474
 
475
475
  [![Actions Status](https://github.com/StoneCypher/jssm/workflows/Node%20CI/badge.svg)](https://github.com/StoneCypher/jssm/actions)
476
476
  [![NPM version](https://img.shields.io/npm/v/jssm.svg)](https://www.npmjs.com/package/jssm)
@@ -4,7 +4,6 @@
4
4
  * highlighting, animated walk GIFs, and a whole-document Markdown
5
5
  * transformer — plus the reusable primitives behind them (GIF89a encoder,
6
6
  * walk planner, SVG patching).
7
- *
8
7
  * @see render_fence_html
9
8
  * @see transform_markdown
10
9
  */
@@ -22,10 +22,8 @@ export interface HighlightRun {
22
22
  *
23
23
  * This is the parity guarantee: there is no third tokenizer, so static
24
24
  * output can never disagree with the editor.
25
- *
26
25
  * @param source FSL source text to classify.
27
26
  * @returns Flat, gap-free, order-preserving runs; `runs.map(r => r.text).join('')` is `source`.
28
- *
29
27
  * @example
30
28
  * highlight_fsl_runs('Red -> Green;').find(r => r.state === 'Red');
31
29
  * // { text: 'Red', classes: 'fsl-tok-variableName fsl-sem-state', state: 'Red' }
@@ -37,12 +35,10 @@ export declare function highlight_fsl_runs(source: string): HighlightRun[];
37
35
  * `data-state`; when `inline_colors` (default true) and the state appears in
38
36
  * `state_colors`, an inline `style="color:…"` ties the code block's state
39
37
  * names to the diagram's node colors with zero host CSS.
40
- *
41
38
  * @param source FSL source text to render.
42
39
  * @param opts.state_colors Maps a state name to its diagram fill color (e.g. from `extract_state_fills`).
43
40
  * @param opts.inline_colors Whether to emit inline `style="color:…"` for matched states. Defaults to `true`.
44
41
  * @returns HTML markup for the highlighted source; unclassed runs are emitted as escaped text with no wrapping span.
45
- *
46
42
  * @example
47
43
  * highlight_fsl_html('Red -> Green;', { state_colors: new Map([['Red', '#a00']]) });
48
44
  * // '…<span class="… fsl-sem-state" data-state="Red" style="color:#a00">Red</span>…'
@@ -9,12 +9,10 @@ export interface FenceRenderOptions {
9
9
  * editor-parity code highlighting whose state names carry the diagram's own
10
10
  * node colors. Invalid FSL renders a visible error box — this function
11
11
  * never throws for bad machine source.
12
- *
13
12
  * @param source - The FSL machine source (fence body).
14
13
  * @param info - The fence info string (e.g. `'fsl image code width=300'`).
15
14
  * @param opts.inline_colors - Whether code spans carry inline diagram colors (default true).
16
15
  * @returns The rendered `<div class="fsl-fence">…</div>` markup.
17
- *
18
16
  * @example
19
17
  * await render_fence_html('Red => Green => Red;', 'fsl');
20
18
  * // '<div class="fsl-fence" …><svg…/svg><pre class="fsl-code">…</pre></div>'
@@ -26,11 +24,9 @@ export declare function render_fence_html(source: string, info: string, opts?: F
26
24
  * Each fence is isolated — a broken machine becomes its own error box and
27
25
  * the rest of the document still renders. Backtick fences of length ≥3
28
26
  * are recognized; tilde fences are out of scope (v1, spec §9).
29
- *
30
27
  * @param markdown - The full Markdown document source.
31
28
  * @param opts.inline_colors - Whether code spans carry inline diagram colors (default true).
32
29
  * @returns The document with every `fsl`/`jssm` fence replaced by rendered HTML.
33
- *
34
30
  * @example
35
31
  * await transform_markdown('# Doc\n\n```fsl\na -> b;\n```\n');
36
32
  * // '# Doc\n\n<div class="fsl-fence">…</div>\n'
@@ -55,7 +51,6 @@ export interface GifRenderOptions {
55
51
  * every-edge tour. Graphviz lays the machine out ONCE; each frame patches
56
52
  * one state's fill in the SVG string and rasterizes — identical geometry
57
53
  * across frames, no layout jitter.
58
- *
59
54
  * @param source - The FSL machine source.
60
55
  * @param opts.delay_cs - Per-frame delay in centiseconds (default 70).
61
56
  * @param opts.loop - Netscape loop count, 0 = forever (default 0).
@@ -63,14 +58,11 @@ export interface GifRenderOptions {
63
58
  * @param opts.scale - Raster zoom percentage, 100 = 3× natural size (default 100).
64
59
  * @param opts.highlight_fill - Fill painted on the walked state (default '#ff9930').
65
60
  * @returns The encoded GIF89a bytes.
66
- *
67
61
  * @throws {JssmError} on invalid FSL (programmatic callers want exceptions;
68
62
  * the HTML renderers catch and box instead).
69
- *
70
63
  * @example
71
64
  * const gif = await render_fence_gif('Red => Green => Yellow => Red;');
72
65
  * // Uint8Array starting "GIF89a", three frames, looping forever
73
- *
74
66
  * @see plan_walk
75
67
  * @see encode_gif
76
68
  */
@@ -14,16 +14,13 @@ export interface Quantized {
14
14
  * `max_colors` or fewer distinct colors they are preserved exactly;
15
15
  * otherwise a median-cut partition supplies the palette and each pixel maps
16
16
  * to its box's weighted-average color.
17
- *
18
17
  * @param rgba - Straight RGBA bytes; length must be a multiple of 4.
19
18
  * @param max_colors - Palette ceiling, 2..256.
20
- *
21
19
  * @throws {JssmError} when `rgba.length` is not a multiple of 4.
22
20
  * @throws {JssmError} when `max_colors` is outside 2..256 — above 256 the
23
21
  * palette index no longer fits the `Uint8Array` indices this module packs
24
22
  * into GIF codes (silent index corruption instead of a clear failure);
25
23
  * below 2 there is no palette to quantize into.
26
- *
27
24
  * @example
28
25
  * const q = quantize(new Uint8Array([255,0,0,255, 0,255,0,255]));
29
26
  * q.palette_count; // 2
@@ -34,10 +31,8 @@ export declare function quantize(rgba: Uint8Array, max_colors?: number): Quantiz
34
31
  * from `min_code_size + 1` up to the format's 12-bit ceiling, resets the
35
32
  * dictionary when full, terminates with EOI, and packs codes LSB-first.
36
33
  * Returns raw compressed bytes; the caller wraps them in GIF data sub-blocks.
37
- *
38
34
  * @param indices - Palette indices, each `< 2^min_code_size`.
39
35
  * @param min_code_size - Bits needed for the palette (2..8 for GIF).
40
- *
41
36
  * @example
42
37
  * lzw_encode(new Uint8Array([0, 0, 1]), 2); // Uint8Array of packed codes
43
38
  */
@@ -62,14 +57,11 @@ export interface GifOptions {
62
57
  * palette, so every frame is pixel-exact while the union stays within 256
63
58
  * distinct colors. Frames must share dimensions. No transparency,
64
59
  * full-frame disposal — simple and correct first.
65
- *
66
60
  * @param frames - At least one frame; all with identical width/height and
67
61
  * `rgba.length === 4 · width · height`.
68
- *
69
62
  * @throws {JssmError} on zero frames, a zero-width or zero-height frame,
70
63
  * mismatched dimensions, or an rgba buffer whose length contradicts its
71
64
  * stated dimensions.
72
- *
73
65
  * @example
74
66
  * const red = { rgba: new Uint8Array([255,0,0,255]), width: 1, height: 1 };
75
67
  * const gif = encode_gif([red], { delay_cs: 50 });
@@ -3,7 +3,6 @@
3
3
  * turns a fenced-code-block info string into a {@link FenceDescriptor}. Hosts
4
4
  * (a VS Code preview plugin, a static-site generator, …) each interpret the
5
5
  * descriptor according to their capabilities.
6
- *
7
6
  * @see notes/superpowers/specs/2026-06-23-fsl-markdown-fence-convention-design.md
8
7
  */
9
8
  /** A single renderable part of a fence block (stacks in listed order, first on top). */
@@ -31,10 +30,8 @@ export interface FenceDescriptor {
31
30
  * Canonical fence language for an info string, or `null` if the block is not
32
31
  * an FSL fence. Reads only the first whitespace-delimited token,
33
32
  * case-insensitively.
34
- *
35
33
  * @param info The full fence info string (everything after the opening fence).
36
34
  * @returns `'fsl'` or `'jssm'` for our fences; `null` otherwise.
37
- *
38
35
  * @example fsl_fence_lang('fsl image code') // => 'fsl'
39
36
  * @example fsl_fence_lang('JSSM') // => 'jssm'
40
37
  * @example fsl_fence_lang('mermaid') // => null
@@ -46,10 +43,8 @@ export declare function fsl_fence_lang(info: string): 'fsl' | 'jssm' | null;
46
43
  * classified as parts, image formats, the `ide` macro, or `width`/`height`
47
44
  * options. Unrecognized or conflicting tokens are dropped and recorded in
48
45
  * `notes` rather than throwing, so a host can render forward-compatibly.
49
- *
50
46
  * @param info The full fence info string, e.g. `'fsl image code width=300'`.
51
47
  * @returns The validated descriptor; `notes` lists anything ignored or overridden.
52
- *
53
48
  * @example parse_fence_info('fsl').parts // => ['image', 'code']
54
49
  * @example parse_fence_info('fsl code image').parts // => ['code', 'image']
55
50
  */
@@ -2,12 +2,9 @@
2
2
  * Read each state's current fill color out of a graphviz-rendered machine
3
3
  * SVG, keyed by state name. States whose shape carries no `fill` attribute
4
4
  * are omitted.
5
- *
6
5
  * @param svg - SVG markup from the jssm viz pipeline (`fsl_to_svg_string`).
7
- *
8
6
  * @example
9
7
  * extract_state_fills(await fsl_to_svg_string('A -> B;')); // Map { 'A' => '#…', 'B' => '#…' }
10
- *
11
8
  * @see patch_state_fill
12
9
  */
13
10
  export declare function extract_state_fills(svg: string): Map<string, string>;
@@ -15,14 +12,11 @@ export declare function extract_state_fills(svg: string): Map<string, string>;
15
12
  * Return a copy of the SVG with the named state's first shape fill replaced.
16
13
  * The unmatched-state case returns the input unchanged (walk truncation and
17
14
  * render races surface as a missing highlight, never a throw).
18
- *
19
15
  * @param svg - SVG markup from the jssm viz pipeline.
20
16
  * @param state - State name as written in FSL (unescaped).
21
17
  * @param fill - Any SVG paint value, e.g. `'#ff9930'`.
22
- *
23
18
  * @example
24
19
  * patch_state_fill(svg, 'Red', '#ff9930'); // Red's node now renders orange
25
- *
26
20
  * @see extract_state_fills
27
21
  */
28
22
  export declare function patch_state_fill(svg: string, state: string, fill: string): string;
@@ -12,10 +12,8 @@ import type { Machine } from './jssm.js';
12
12
  *
13
13
  * This is presentation, not simulation — a tour's consecutive entries need
14
14
  * not be legal transitions, and no machine state is mutated.
15
- *
16
15
  * @example
17
16
  * plan_walk(sm`Red => Green => Yellow => Red;`); // ['Red', 'Green', 'Yellow']
18
- *
19
17
  * @see encode_gif
20
18
  */
21
19
  export declare function plan_walk(machine: Machine<unknown>): string[];