jssm 5.145.6 → 5.147.0
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/custom-elements.json +342 -3
- package/dist/cdn/instance.js +144 -9
- package/dist/cdn/viz.js +10 -2
- 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/cm6/fsl_language.js +199 -0
- package/dist/deno/README.md +7 -7
- package/dist/deno/jssm.js +1 -1
- package/dist/es6/cm6/fsl_language.d.ts +81 -0
- 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/dist/wc/instance.define.js +9 -1
- package/dist/wc/instance.js +134 -7
- package/dist/wc/viz.define.js +9 -1
- package/package.json +27 -4
package/README.md
CHANGED
|
@@ -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.
|
|
21
|
+
* Generated for version 5.147.0 at 6/23/2026, 6:50:50 AM
|
|
22
22
|
|
|
23
23
|
-->
|
|
24
|
-
# jssm 5.
|
|
24
|
+
# jssm 5.147.0
|
|
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/) ·
|
|
@@ -312,7 +312,7 @@ That decision shows up everywhere downstream:
|
|
|
312
312
|
or run `npm run benny` against your own machine.
|
|
313
313
|
|
|
314
314
|
- **More thoroughly tested than any other JavaScript state-machine
|
|
315
|
-
library.** 7,
|
|
315
|
+
library.** 7,443 tests at 100.0% line coverage
|
|
316
316
|
([report](https://coveralls.io/github/StoneCypher/jssm)), plus
|
|
317
317
|
fuzz testing via `fast-check`, with parser test data across ten natural
|
|
318
318
|
languages and Emoji.
|
|
@@ -445,11 +445,11 @@ If your contribution is missing here, please open an issue.
|
|
|
445
445
|
|
|
446
446
|
<br/>
|
|
447
447
|
|
|
448
|
-
***7,
|
|
448
|
+
***7,443 tests***, run 82,485 times.
|
|
449
449
|
|
|
450
|
-
- 6,
|
|
451
|
-
- 758 fuzz tests with
|
|
452
|
-
-
|
|
450
|
+
- 6,685 specs with 100.0% coverage
|
|
451
|
+
- 758 fuzz tests with 69.6% coverage
|
|
452
|
+
- 7,276 TypeScript lines - 1.0 tests per line, 11.3 generated tests per line
|
|
453
453
|
|
|
454
454
|
[](https://github.com/StoneCypher/jssm/actions)
|
|
455
455
|
[](https://www.npmjs.com/package/jssm)
|
package/custom-elements.json
CHANGED
|
@@ -187,6 +187,92 @@
|
|
|
187
187
|
}
|
|
188
188
|
]
|
|
189
189
|
},
|
|
190
|
+
{
|
|
191
|
+
"kind": "javascript-module",
|
|
192
|
+
"path": "src/ts/wc/fsl_effective_properties_wc.ts",
|
|
193
|
+
"declarations": [
|
|
194
|
+
{
|
|
195
|
+
"kind": "class",
|
|
196
|
+
"description": "Read-only panel that displays the parent machine's **resolved FSL\nproperties** for the current state — the values produced by the full\noverride chain (machine `property … default …` → per-state\n`state X: { property … }`), as returned by `machine.props()`. Refreshes on\nevery transition, so consumers can watch a property's effective value change\nas the machine moves between states.\n\nBinds to the host via closest_wc (matching both `fsl-instance` and\nthe deprecated `jssm-instance`). Display-only; never drives the machine.\n\nv1 shows the FSL `property` bag (`machine.props()`). The render-time visual\nstyle resolution (shape/color used by `<fsl-viz>`) is a separate viz-pipeline\nconcern and is not surfaced here.",
|
|
197
|
+
"name": "FslEffectiveProperties",
|
|
198
|
+
"cssProperties": [
|
|
199
|
+
{
|
|
200
|
+
"description": "Gap between rows.",
|
|
201
|
+
"name": "--fsl-effective-properties-gap",
|
|
202
|
+
"default": "0.25rem"
|
|
203
|
+
}
|
|
204
|
+
],
|
|
205
|
+
"members": [
|
|
206
|
+
{
|
|
207
|
+
"kind": "field",
|
|
208
|
+
"name": "_host",
|
|
209
|
+
"type": {
|
|
210
|
+
"text": "JssmInstanceHost | null"
|
|
211
|
+
},
|
|
212
|
+
"privacy": "private",
|
|
213
|
+
"default": "null",
|
|
214
|
+
"description": "Parent host reference; cleared on disconnect."
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
"kind": "field",
|
|
218
|
+
"name": "_sub",
|
|
219
|
+
"type": {
|
|
220
|
+
"text": "(() => void) | null"
|
|
221
|
+
},
|
|
222
|
+
"privacy": "private",
|
|
223
|
+
"default": "null",
|
|
224
|
+
"description": "Unsubscribe callback from the host machine's `transition` subscription."
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"kind": "field",
|
|
228
|
+
"name": "_entries",
|
|
229
|
+
"type": {
|
|
230
|
+
"text": "Array<[string, string]> | null"
|
|
231
|
+
},
|
|
232
|
+
"privacy": "private",
|
|
233
|
+
"default": "null",
|
|
234
|
+
"description": "Resolved property entries (`[name, stringified value]`) for the current\nstate, or `null` before the panel has bound to a host machine."
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"kind": "method",
|
|
238
|
+
"name": "_refresh",
|
|
239
|
+
"privacy": "private",
|
|
240
|
+
"return": {
|
|
241
|
+
"type": {
|
|
242
|
+
"text": "void"
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
"parameters": [
|
|
246
|
+
{
|
|
247
|
+
"name": "host",
|
|
248
|
+
"type": {
|
|
249
|
+
"text": "JssmInstanceHost"
|
|
250
|
+
},
|
|
251
|
+
"description": "The bound parent host whose machine to snapshot."
|
|
252
|
+
}
|
|
253
|
+
],
|
|
254
|
+
"description": "Read the resolved property bag (`machine.props()`) into reactive entries,\ntriggering a re-render."
|
|
255
|
+
}
|
|
256
|
+
],
|
|
257
|
+
"superclass": {
|
|
258
|
+
"name": "LitElement",
|
|
259
|
+
"package": "lit"
|
|
260
|
+
},
|
|
261
|
+
"tagName": "fsl-effective-properties",
|
|
262
|
+
"customElement": true
|
|
263
|
+
}
|
|
264
|
+
],
|
|
265
|
+
"exports": [
|
|
266
|
+
{
|
|
267
|
+
"kind": "js",
|
|
268
|
+
"name": "FslEffectiveProperties",
|
|
269
|
+
"declaration": {
|
|
270
|
+
"name": "FslEffectiveProperties",
|
|
271
|
+
"module": "src/ts/wc/fsl_effective_properties_wc.ts"
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
]
|
|
275
|
+
},
|
|
190
276
|
{
|
|
191
277
|
"kind": "javascript-module",
|
|
192
278
|
"path": "src/ts/wc/fsl_hook_wc.ts",
|
|
@@ -435,6 +521,132 @@
|
|
|
435
521
|
}
|
|
436
522
|
]
|
|
437
523
|
},
|
|
524
|
+
{
|
|
525
|
+
"kind": "javascript-module",
|
|
526
|
+
"path": "src/ts/wc/fsl_info_panel_wc.ts",
|
|
527
|
+
"declarations": [
|
|
528
|
+
{
|
|
529
|
+
"kind": "class",
|
|
530
|
+
"description": "Read-only state-inspector web component for a parent `<fsl-instance>`.\n\nSlotted into the host's `info-panel` slot (or nested anywhere inside it), it\ndisplays the machine's current state, the most recent transition\n(`from → to via action`), the currently-legal exit actions, and the\nterminal / complete flags. Every field refreshes on each `transition`\nevent.\n\nDisplay-only: it never drives the machine. It binds by walking up to the\nhost via closest_wc (which matches both the canonical `fsl-instance`\nand the deprecated `jssm-instance` host tags), so it works under either.",
|
|
531
|
+
"name": "FslInfoPanel",
|
|
532
|
+
"cssProperties": [
|
|
533
|
+
{
|
|
534
|
+
"description": "Vertical gap between rows.",
|
|
535
|
+
"name": "--fsl-info-panel-gap",
|
|
536
|
+
"default": "0.25rem"
|
|
537
|
+
}
|
|
538
|
+
],
|
|
539
|
+
"members": [
|
|
540
|
+
{
|
|
541
|
+
"kind": "field",
|
|
542
|
+
"name": "_host",
|
|
543
|
+
"type": {
|
|
544
|
+
"text": "JssmInstanceHost | null"
|
|
545
|
+
},
|
|
546
|
+
"privacy": "private",
|
|
547
|
+
"default": "null",
|
|
548
|
+
"description": "Parent host reference, set in `connectedCallback` when one is found.\nCleared on disconnect so a stale deferred subscription cannot fire."
|
|
549
|
+
},
|
|
550
|
+
{
|
|
551
|
+
"kind": "field",
|
|
552
|
+
"name": "_sub",
|
|
553
|
+
"type": {
|
|
554
|
+
"text": "(() => void) | null"
|
|
555
|
+
},
|
|
556
|
+
"privacy": "private",
|
|
557
|
+
"default": "null",
|
|
558
|
+
"description": "Unsubscribe callback from the host machine's `transition` subscription."
|
|
559
|
+
},
|
|
560
|
+
{
|
|
561
|
+
"kind": "field",
|
|
562
|
+
"name": "_current",
|
|
563
|
+
"type": {
|
|
564
|
+
"text": "string | null"
|
|
565
|
+
},
|
|
566
|
+
"privacy": "private",
|
|
567
|
+
"default": "null",
|
|
568
|
+
"description": "Current state name; `null` until the panel has bound to a host machine."
|
|
569
|
+
},
|
|
570
|
+
{
|
|
571
|
+
"kind": "field",
|
|
572
|
+
"name": "_actions",
|
|
573
|
+
"type": {
|
|
574
|
+
"text": "string"
|
|
575
|
+
},
|
|
576
|
+
"privacy": "private",
|
|
577
|
+
"default": "''",
|
|
578
|
+
"description": "Space-separated legal exit actions for the current state."
|
|
579
|
+
},
|
|
580
|
+
{
|
|
581
|
+
"kind": "field",
|
|
582
|
+
"name": "_terminal",
|
|
583
|
+
"type": {
|
|
584
|
+
"text": "boolean"
|
|
585
|
+
},
|
|
586
|
+
"privacy": "private",
|
|
587
|
+
"default": "false",
|
|
588
|
+
"description": "Whether the current state has no exits."
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
"kind": "field",
|
|
592
|
+
"name": "_complete",
|
|
593
|
+
"type": {
|
|
594
|
+
"text": "boolean"
|
|
595
|
+
},
|
|
596
|
+
"privacy": "private",
|
|
597
|
+
"default": "false",
|
|
598
|
+
"description": "Whether the current state is a `complete` state."
|
|
599
|
+
},
|
|
600
|
+
{
|
|
601
|
+
"kind": "field",
|
|
602
|
+
"name": "_last",
|
|
603
|
+
"type": {
|
|
604
|
+
"text": "LastTransition | null"
|
|
605
|
+
},
|
|
606
|
+
"privacy": "private",
|
|
607
|
+
"default": "null",
|
|
608
|
+
"description": "Most recent transition, or `null` before the first one."
|
|
609
|
+
},
|
|
610
|
+
{
|
|
611
|
+
"kind": "method",
|
|
612
|
+
"name": "_refresh",
|
|
613
|
+
"privacy": "private",
|
|
614
|
+
"return": {
|
|
615
|
+
"type": {
|
|
616
|
+
"text": "void"
|
|
617
|
+
}
|
|
618
|
+
},
|
|
619
|
+
"parameters": [
|
|
620
|
+
{
|
|
621
|
+
"name": "host",
|
|
622
|
+
"type": {
|
|
623
|
+
"text": "JssmInstanceHost"
|
|
624
|
+
},
|
|
625
|
+
"description": "The bound parent host whose machine to snapshot."
|
|
626
|
+
}
|
|
627
|
+
],
|
|
628
|
+
"description": "Read the current machine snapshot into the reactive fields, triggering a\nre-render. Called once on bind and again on every transition. The bound\nhost is passed in by the caller (which already holds a non-null reference),\nso no re-null-check is needed here."
|
|
629
|
+
}
|
|
630
|
+
],
|
|
631
|
+
"superclass": {
|
|
632
|
+
"name": "LitElement",
|
|
633
|
+
"package": "lit"
|
|
634
|
+
},
|
|
635
|
+
"tagName": "fsl-info-panel",
|
|
636
|
+
"customElement": true
|
|
637
|
+
}
|
|
638
|
+
],
|
|
639
|
+
"exports": [
|
|
640
|
+
{
|
|
641
|
+
"kind": "js",
|
|
642
|
+
"name": "FslInfoPanel",
|
|
643
|
+
"declaration": {
|
|
644
|
+
"name": "FslInfoPanel",
|
|
645
|
+
"module": "src/ts/wc/fsl_info_panel_wc.ts"
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
]
|
|
649
|
+
},
|
|
438
650
|
{
|
|
439
651
|
"kind": "javascript-module",
|
|
440
652
|
"path": "src/ts/wc/fsl_instance_wc.ts",
|
|
@@ -564,7 +776,7 @@
|
|
|
564
776
|
"name": "viz"
|
|
565
777
|
},
|
|
566
778
|
{
|
|
567
|
-
"description": "Editor surface slot.",
|
|
779
|
+
"description": "Editor surface slot (`<fsl-editor>`, #659).",
|
|
568
780
|
"name": "editor"
|
|
569
781
|
},
|
|
570
782
|
{
|
|
@@ -572,13 +784,37 @@
|
|
|
572
784
|
"name": "actions"
|
|
573
785
|
},
|
|
574
786
|
{
|
|
575
|
-
"description": "Slot for toolbar UI.",
|
|
787
|
+
"description": "Slot for toolbar UI (`<fsl-toolbar>`, #660).",
|
|
576
788
|
"name": "toolbar"
|
|
577
789
|
},
|
|
578
790
|
{
|
|
579
|
-
"description": "Slot for an info / status panel.",
|
|
791
|
+
"description": "Slot for an info / status panel (`<fsl-info-panel>`, #661).",
|
|
580
792
|
"name": "info-panel"
|
|
581
793
|
},
|
|
794
|
+
{
|
|
795
|
+
"description": "Slot for the visited-state timeline (`<fsl-history>`, #662).",
|
|
796
|
+
"name": "history"
|
|
797
|
+
},
|
|
798
|
+
{
|
|
799
|
+
"description": "Slot for the typed-data tree view (`<fsl-data-inspector>`, #663).",
|
|
800
|
+
"name": "data-inspector"
|
|
801
|
+
},
|
|
802
|
+
{
|
|
803
|
+
"description": "Slot for the hook-firing log (`<fsl-hook-log>`, #664).",
|
|
804
|
+
"name": "hook-log"
|
|
805
|
+
},
|
|
806
|
+
{
|
|
807
|
+
"description": "Slot for the resolved-properties panel (`<fsl-effective-properties>`, #665).",
|
|
808
|
+
"name": "effective-properties"
|
|
809
|
+
},
|
|
810
|
+
{
|
|
811
|
+
"description": "Slot for the random-walk simulation (`<fsl-simulation>`, #668).",
|
|
812
|
+
"name": "simulation"
|
|
813
|
+
},
|
|
814
|
+
{
|
|
815
|
+
"description": "Slot for the export menu (`<fsl-export>`, #667).",
|
|
816
|
+
"name": "export"
|
|
817
|
+
},
|
|
582
818
|
{
|
|
583
819
|
"description": "Footer slot.",
|
|
584
820
|
"name": "footer"
|
|
@@ -626,6 +862,38 @@
|
|
|
626
862
|
"default": "[]",
|
|
627
863
|
"description": "Unsubscribe callbacks for every `machine.on(...)` / `machine.once(...)`\r\nsubscription installed from a `<jssm-on>` child during\r\n`connectedCallback`. Walked in `disconnectedCallback`."
|
|
628
864
|
},
|
|
865
|
+
{
|
|
866
|
+
"kind": "field",
|
|
867
|
+
"name": "REEMITTED_EVENTS",
|
|
868
|
+
"type": {
|
|
869
|
+
"text": "readonly string[]"
|
|
870
|
+
},
|
|
871
|
+
"privacy": "private",
|
|
872
|
+
"static": true,
|
|
873
|
+
"readonly": true,
|
|
874
|
+
"default": "[ 'transition', 'entry', 'exit', 'terminal', 'complete', 'action', 'rejection', 'override', 'data-change', 'timeout', 'error', ]",
|
|
875
|
+
"description": "Library event names this WC re-emits as DOM `CustomEvent`s, fulfilling\r\nmechanism 4 of #639. Each library `machine.on(name, ...)` is bridged to\r\na `fsl-<name>` DOM event (`composed`, `bubbling`) so slotted content and\r\noutside consumers can observe machine activity declaratively.\r\n\r\n`fsl-` is the canonical prefix (matching the canonical `<fsl-*>` tag\r\nnames); the older `jssm-*` event prose in #639 predates that naming flip.\r\nEvents are NOT double-emitted under both prefixes — a symmetric listener\r\nwould otherwise run twice per machine event."
|
|
876
|
+
},
|
|
877
|
+
{
|
|
878
|
+
"kind": "field",
|
|
879
|
+
"name": "_reemit_unsubscribes",
|
|
880
|
+
"type": {
|
|
881
|
+
"text": "Array<() => void>"
|
|
882
|
+
},
|
|
883
|
+
"privacy": "private",
|
|
884
|
+
"default": "[]",
|
|
885
|
+
"description": "Unsubscribe callbacks for the host-level mechanism-4 re-emission\r\nsubscriptions installed in _install_event_reemission. Distinct\r\nfrom _on_unsubscribes (which belongs to `<jssm-on>` children)."
|
|
886
|
+
},
|
|
887
|
+
{
|
|
888
|
+
"kind": "field",
|
|
889
|
+
"name": "_pending_dom_events",
|
|
890
|
+
"type": {
|
|
891
|
+
"text": "Array<{ name: string; detail: unknown }>"
|
|
892
|
+
},
|
|
893
|
+
"privacy": "private",
|
|
894
|
+
"default": "[]",
|
|
895
|
+
"description": "Library events captured during the current transition, awaiting DOM\r\nre-dispatch once Lit commits the next render. Dispatching here (rather\r\nthan synchronously from the machine subscription) guarantees the #639\r\nordering: mechanism 1/3 reflection and mechanism 2 slot re-pick are all\r\nin place before a mechanism-4 listener runs."
|
|
896
|
+
},
|
|
629
897
|
{
|
|
630
898
|
"kind": "field",
|
|
631
899
|
"name": "registry",
|
|
@@ -745,6 +1013,28 @@
|
|
|
745
1013
|
},
|
|
746
1014
|
"description": "Prefix used in synthetic `//# sourceURL=jssm-hook:<prefix><n>` annotations\r\nfor inline-body hooks compiled by this element."
|
|
747
1015
|
},
|
|
1016
|
+
{
|
|
1017
|
+
"kind": "method",
|
|
1018
|
+
"name": "_install_event_reemission",
|
|
1019
|
+
"privacy": "private",
|
|
1020
|
+
"return": {
|
|
1021
|
+
"type": {
|
|
1022
|
+
"text": "void"
|
|
1023
|
+
}
|
|
1024
|
+
},
|
|
1025
|
+
"description": "Install the mechanism-4 (#639) re-emission subscriptions: one\r\n`machine.on(name, ...)` per entry in REEMITTED_EVENTS. Each\r\ncaptured library event is queued and re-dispatched as a `fsl-<name>` DOM\r\nevent after the next render commit (see updated).\r\n\r\nSubscribing is also what *enables* the gated observation events: the\r\nlibrary suppresses `transition` / `entry` / `exit` / etc. while no\r\nlisteners exist (#670), so this host subscription is the bridge that\r\nturns them on.\r\n\r\nThe subscription handler paints state reflection eagerly so that a host\r\ndriven directly via `host.machine.action(...)` (bypassing do)\r\nstill updates its `current-state` attribute and `--current-state`\r\nproperty."
|
|
1026
|
+
},
|
|
1027
|
+
{
|
|
1028
|
+
"kind": "method",
|
|
1029
|
+
"name": "_flush_pending_dom_events",
|
|
1030
|
+
"privacy": "private",
|
|
1031
|
+
"return": {
|
|
1032
|
+
"type": {
|
|
1033
|
+
"text": "void"
|
|
1034
|
+
}
|
|
1035
|
+
},
|
|
1036
|
+
"description": "Dispatch and clear the queue of pending DOM events. The queue is\r\nsnapshotted and reset *before* dispatching so that a listener which\r\nre-enters the machine (e.g. calls `host.machine.action(...)`\r\nsynchronously) enqueues into a fresh batch handled by the next update\r\ncycle, rather than mutating the array mid-iteration. This is the\r\ndocumented re-entrancy behavior: re-entrant transitions are deferred,\r\nnot dropped."
|
|
1037
|
+
},
|
|
748
1038
|
{
|
|
749
1039
|
"kind": "method",
|
|
750
1040
|
"name": "_discover_jssm_actions",
|
|
@@ -787,6 +1077,13 @@
|
|
|
787
1077
|
"description": "Reflect machine state onto host attributes and CSS custom properties.\r\nCalled after every transition and once during `connectedCallback`.\r\n\r\nMechanism 1 (#639): writes to host attributes.\r\nMechanism 3 (#639): writes to host inline-style custom properties."
|
|
788
1078
|
}
|
|
789
1079
|
],
|
|
1080
|
+
"events": [
|
|
1081
|
+
{
|
|
1082
|
+
"type": {
|
|
1083
|
+
"text": "CustomEvent"
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
],
|
|
790
1087
|
"attributes": [
|
|
791
1088
|
{
|
|
792
1089
|
"name": "fsl",
|
|
@@ -1123,6 +1420,32 @@
|
|
|
1123
1420
|
}
|
|
1124
1421
|
],
|
|
1125
1422
|
"description": "Registers a canonical custom-element tag and its synonym tag.\r\n\r\n`customElements.define` requires a distinct constructor per tag name, so\r\ncallers pass the canonical class and a thin subclass for the synonym.\r\nThe function is idempotent: if either tag is already registered it skips\r\nthat `define` call rather than throwing."
|
|
1423
|
+
},
|
|
1424
|
+
{
|
|
1425
|
+
"kind": "function",
|
|
1426
|
+
"name": "define_canonical",
|
|
1427
|
+
"return": {
|
|
1428
|
+
"type": {
|
|
1429
|
+
"text": "void"
|
|
1430
|
+
}
|
|
1431
|
+
},
|
|
1432
|
+
"parameters": [
|
|
1433
|
+
{
|
|
1434
|
+
"name": "canonical_tag",
|
|
1435
|
+
"type": {
|
|
1436
|
+
"text": "string"
|
|
1437
|
+
},
|
|
1438
|
+
"description": "The `fsl-*` tag name (e.g. `\"fsl-info-panel\"`)."
|
|
1439
|
+
},
|
|
1440
|
+
{
|
|
1441
|
+
"name": "CanonicalClass",
|
|
1442
|
+
"type": {
|
|
1443
|
+
"text": "CustomElementConstructor"
|
|
1444
|
+
},
|
|
1445
|
+
"description": "Constructor to register under `canonical_tag`."
|
|
1446
|
+
}
|
|
1447
|
+
],
|
|
1448
|
+
"description": "Registers a single canonical `fsl-*` custom-element tag, with no `jssm-*`\r\nsynonym.\r\n\r\nThis is the registration path for **new** web components. The `jssm-*`\r\nprefix is a deprecated backward-compatibility alias retained only for the\r\ncomponents that shipped under that name (`<jssm-viz>`, `<jssm-instance>`,\r\n`<jssm-bind>`); new components are `fsl-*`-only for fsl.tools brand\r\nalignment, and the legacy synonyms are slated for removal in v6. Use\r\ndefine_with_synonym only when maintaining one of those pre-existing\r\ndual-named components.\r\n\r\nIdempotent: skips the `define` call when the tag is already registered."
|
|
1126
1449
|
}
|
|
1127
1450
|
],
|
|
1128
1451
|
"exports": [
|
|
@@ -1165,6 +1488,22 @@
|
|
|
1165
1488
|
"name": "SynonymClass",
|
|
1166
1489
|
"module": "src/ts/wc/wc_tag_helpers.ts"
|
|
1167
1490
|
}
|
|
1491
|
+
},
|
|
1492
|
+
{
|
|
1493
|
+
"kind": "js",
|
|
1494
|
+
"name": "define_canonical",
|
|
1495
|
+
"declaration": {
|
|
1496
|
+
"name": "define_canonical",
|
|
1497
|
+
"module": "src/ts/wc/wc_tag_helpers.ts"
|
|
1498
|
+
}
|
|
1499
|
+
},
|
|
1500
|
+
{
|
|
1501
|
+
"kind": "custom-element-definition",
|
|
1502
|
+
"name": "canonical_tag",
|
|
1503
|
+
"declaration": {
|
|
1504
|
+
"name": "CanonicalClass",
|
|
1505
|
+
"module": "src/ts/wc/wc_tag_helpers.ts"
|
|
1506
|
+
}
|
|
1168
1507
|
}
|
|
1169
1508
|
]
|
|
1170
1509
|
}
|
package/dist/cdn/instance.js
CHANGED
|
@@ -23512,7 +23512,7 @@ var constants = /*#__PURE__*/Object.freeze({
|
|
|
23512
23512
|
* Useful for runtime diagnostics and for embedding in serialized machine
|
|
23513
23513
|
* snapshots so that deserializers can detect version-skew.
|
|
23514
23514
|
*/
|
|
23515
|
-
const version = "5.
|
|
23515
|
+
const version = "5.147.0";
|
|
23516
23516
|
|
|
23517
23517
|
// whargarbl lots of these return arrays could/should be sets
|
|
23518
23518
|
const { state_name_chars, state_name_first_chars, action_label_chars } = constants;
|
|
@@ -29386,10 +29386,16 @@ function resolve_fsl_source(host, fsl_attr) {
|
|
|
29386
29386
|
* @cssproperty [--current-state] - The machine's current state name as a CSS string token.
|
|
29387
29387
|
* @slot title - Heading area for the instance.
|
|
29388
29388
|
* @slot viz - Visualization slot; fallback is a placeholder string.
|
|
29389
|
-
* @slot editor - Editor surface slot.
|
|
29389
|
+
* @slot editor - Editor surface slot (`<fsl-editor>`, #659).
|
|
29390
29390
|
* @slot actions - Slot for action buttons / UI.
|
|
29391
|
-
* @slot toolbar - Slot for toolbar UI.
|
|
29392
|
-
* @slot info-panel - Slot for an info / status panel.
|
|
29391
|
+
* @slot toolbar - Slot for toolbar UI (`<fsl-toolbar>`, #660).
|
|
29392
|
+
* @slot info-panel - Slot for an info / status panel (`<fsl-info-panel>`, #661).
|
|
29393
|
+
* @slot history - Slot for the visited-state timeline (`<fsl-history>`, #662).
|
|
29394
|
+
* @slot data-inspector - Slot for the typed-data tree view (`<fsl-data-inspector>`, #663).
|
|
29395
|
+
* @slot hook-log - Slot for the hook-firing log (`<fsl-hook-log>`, #664).
|
|
29396
|
+
* @slot effective-properties - Slot for the resolved-properties panel (`<fsl-effective-properties>`, #665).
|
|
29397
|
+
* @slot simulation - Slot for the random-walk simulation (`<fsl-simulation>`, #668).
|
|
29398
|
+
* @slot export - Slot for the export menu (`<fsl-export>`, #667).
|
|
29393
29399
|
* @slot footer - Footer slot.
|
|
29394
29400
|
*/
|
|
29395
29401
|
class FslInstance extends i {
|
|
@@ -29423,6 +29429,20 @@ class FslInstance extends i {
|
|
|
29423
29429
|
* `connectedCallback`. Walked in `disconnectedCallback`.
|
|
29424
29430
|
*/
|
|
29425
29431
|
this._on_unsubscribes = [];
|
|
29432
|
+
/**
|
|
29433
|
+
* Unsubscribe callbacks for the host-level mechanism-4 re-emission
|
|
29434
|
+
* subscriptions installed in {@link _install_event_reemission}. Distinct
|
|
29435
|
+
* from {@link _on_unsubscribes} (which belongs to `<jssm-on>` children).
|
|
29436
|
+
*/
|
|
29437
|
+
this._reemit_unsubscribes = [];
|
|
29438
|
+
/**
|
|
29439
|
+
* Library events captured during the current transition, awaiting DOM
|
|
29440
|
+
* re-dispatch once Lit commits the next render. Dispatching here (rather
|
|
29441
|
+
* than synchronously from the machine subscription) guarantees the #639
|
|
29442
|
+
* ordering: mechanism 1/3 reflection and mechanism 2 slot re-pick are all
|
|
29443
|
+
* in place before a mechanism-4 listener runs.
|
|
29444
|
+
*/
|
|
29445
|
+
this._pending_dom_events = [];
|
|
29426
29446
|
/**
|
|
29427
29447
|
* Per-instance registry of named hook handlers consulted before
|
|
29428
29448
|
* `globalThis` when resolving `<fsl-hook handler="name">` /
|
|
@@ -29503,8 +29523,9 @@ class FslInstance extends i {
|
|
|
29503
29523
|
// Step 4: shadow DOM render is automatic via Lit; requesting an update
|
|
29504
29524
|
// here ensures the first paint sees the freshly painted attributes.
|
|
29505
29525
|
this.requestUpdate();
|
|
29506
|
-
//
|
|
29507
|
-
//
|
|
29526
|
+
// #639 mechanism 4: subscribe to library events and re-emit them as
|
|
29527
|
+
// DOM CustomEvents from this host (#638 supplies the event API).
|
|
29528
|
+
this._install_event_reemission();
|
|
29508
29529
|
// #641: <jssm-hook> declarative discovery.
|
|
29509
29530
|
this._install_declarative_hooks();
|
|
29510
29531
|
// #643: <jssm-on> declarative event observation.
|
|
@@ -29583,14 +29604,87 @@ class FslInstance extends i {
|
|
|
29583
29604
|
const host_id = this.getAttribute('id');
|
|
29584
29605
|
return host_id !== null && host_id.length > 0 ? `${host_id}-` : '';
|
|
29585
29606
|
}
|
|
29607
|
+
/**
|
|
29608
|
+
* Install the mechanism-4 (#639) re-emission subscriptions: one
|
|
29609
|
+
* `machine.on(name, ...)` per entry in {@link REEMITTED_EVENTS}. Each
|
|
29610
|
+
* captured library event is queued and re-dispatched as a `fsl-<name>` DOM
|
|
29611
|
+
* event after the next render commit (see {@link updated}).
|
|
29612
|
+
*
|
|
29613
|
+
* Subscribing is also what *enables* the gated observation events: the
|
|
29614
|
+
* library suppresses `transition` / `entry` / `exit` / etc. while no
|
|
29615
|
+
* listeners exist (#670), so this host subscription is the bridge that
|
|
29616
|
+
* turns them on.
|
|
29617
|
+
*
|
|
29618
|
+
* The subscription handler paints state reflection eagerly so that a host
|
|
29619
|
+
* driven directly via `host.machine.action(...)` (bypassing {@link do})
|
|
29620
|
+
* still updates its `current-state` attribute and `--current-state`
|
|
29621
|
+
* property.
|
|
29622
|
+
*/
|
|
29623
|
+
_install_event_reemission() {
|
|
29624
|
+
const machine = this._machine;
|
|
29625
|
+
for (const name of FslInstance.REEMITTED_EVENTS) {
|
|
29626
|
+
// `as any` collapses the per-event detail typing — the WC is a
|
|
29627
|
+
// schema-erased entry point; per-event payload typing belongs upstream.
|
|
29628
|
+
const off = machine.on(name, (detail) => {
|
|
29629
|
+
this._pending_dom_events.push({ name, detail });
|
|
29630
|
+
this._paint_state_reflection();
|
|
29631
|
+
this.requestUpdate();
|
|
29632
|
+
});
|
|
29633
|
+
this._reemit_unsubscribes.push(off);
|
|
29634
|
+
}
|
|
29635
|
+
}
|
|
29636
|
+
/**
|
|
29637
|
+
* Lit lifecycle. After every committed render, flush any library events
|
|
29638
|
+
* captured since the last commit as DOM `CustomEvent`s. Deferring to this
|
|
29639
|
+
* point is what gives mechanism-4 listeners the #639 ordering guarantee:
|
|
29640
|
+
* host attributes (mechanism 1), CSS custom properties (mechanism 3), and
|
|
29641
|
+
* the state-specific slot (mechanism 2) are all current by the time a
|
|
29642
|
+
* `fsl-*` listener runs.
|
|
29643
|
+
*
|
|
29644
|
+
* @param changed - Lit's changed-property map (forwarded to super).
|
|
29645
|
+
*/
|
|
29646
|
+
updated(changed) {
|
|
29647
|
+
super.updated(changed);
|
|
29648
|
+
this._flush_pending_dom_events();
|
|
29649
|
+
}
|
|
29650
|
+
/**
|
|
29651
|
+
* Dispatch and clear the queue of pending DOM events. The queue is
|
|
29652
|
+
* snapshotted and reset *before* dispatching so that a listener which
|
|
29653
|
+
* re-enters the machine (e.g. calls `host.machine.action(...)`
|
|
29654
|
+
* synchronously) enqueues into a fresh batch handled by the next update
|
|
29655
|
+
* cycle, rather than mutating the array mid-iteration. This is the
|
|
29656
|
+
* documented re-entrancy behavior: re-entrant transitions are deferred,
|
|
29657
|
+
* not dropped.
|
|
29658
|
+
*/
|
|
29659
|
+
_flush_pending_dom_events() {
|
|
29660
|
+
if (this._pending_dom_events.length === 0) {
|
|
29661
|
+
return;
|
|
29662
|
+
}
|
|
29663
|
+
const batch = this._pending_dom_events;
|
|
29664
|
+
this._pending_dom_events = [];
|
|
29665
|
+
for (const ev of batch) {
|
|
29666
|
+
this.dispatchEvent(new CustomEvent(`fsl-${ev.name}`, {
|
|
29667
|
+
detail: ev.detail,
|
|
29668
|
+
bubbles: true,
|
|
29669
|
+
composed: true,
|
|
29670
|
+
}));
|
|
29671
|
+
}
|
|
29672
|
+
}
|
|
29586
29673
|
/**
|
|
29587
29674
|
* Lifecycle hook. Cleans up everything the WC installed at connect: hook
|
|
29588
29675
|
* registrations from `<jssm-hook>`, event subscriptions from `<jssm-on>`,
|
|
29589
|
-
* and DOM listeners from
|
|
29676
|
+
* mechanism-4 re-emission subscriptions, and DOM listeners from
|
|
29677
|
+
* `<jssm-action>` / `data-jssm-action`.
|
|
29590
29678
|
*/
|
|
29591
29679
|
disconnectedCallback() {
|
|
29592
29680
|
super.disconnectedCallback();
|
|
29593
|
-
//
|
|
29681
|
+
// #639 mechanism 4: release host-level re-emission subscriptions and drop
|
|
29682
|
+
// any events that were queued but not yet flushed.
|
|
29683
|
+
for (const off of this._reemit_unsubscribes) {
|
|
29684
|
+
off();
|
|
29685
|
+
}
|
|
29686
|
+
this._reemit_unsubscribes = [];
|
|
29687
|
+
this._pending_dom_events = [];
|
|
29594
29688
|
// #641: remove installed hooks.
|
|
29595
29689
|
if (this._machine !== undefined) {
|
|
29596
29690
|
const machine = this._machine;
|
|
@@ -29746,6 +29840,24 @@ class FslInstance extends i {
|
|
|
29746
29840
|
<section class="info-panel">
|
|
29747
29841
|
<slot name="info-panel"></slot>
|
|
29748
29842
|
</section>
|
|
29843
|
+
<section class="history">
|
|
29844
|
+
<slot name="history"></slot>
|
|
29845
|
+
</section>
|
|
29846
|
+
<section class="data-inspector">
|
|
29847
|
+
<slot name="data-inspector"></slot>
|
|
29848
|
+
</section>
|
|
29849
|
+
<section class="hook-log">
|
|
29850
|
+
<slot name="hook-log"></slot>
|
|
29851
|
+
</section>
|
|
29852
|
+
<section class="effective-properties">
|
|
29853
|
+
<slot name="effective-properties"></slot>
|
|
29854
|
+
</section>
|
|
29855
|
+
<section class="simulation">
|
|
29856
|
+
<slot name="simulation"></slot>
|
|
29857
|
+
</section>
|
|
29858
|
+
<section class="export">
|
|
29859
|
+
<slot name="export"></slot>
|
|
29860
|
+
</section>
|
|
29749
29861
|
<section class="state-section">
|
|
29750
29862
|
<slot name=${state_slot_name}></slot>
|
|
29751
29863
|
</section>
|
|
@@ -29769,6 +29881,21 @@ FslInstance.styles = i$3 `
|
|
|
29769
29881
|
font-style: italic;
|
|
29770
29882
|
}
|
|
29771
29883
|
`;
|
|
29884
|
+
/**
|
|
29885
|
+
* Library event names this WC re-emits as DOM `CustomEvent`s, fulfilling
|
|
29886
|
+
* mechanism 4 of #639. Each library `machine.on(name, ...)` is bridged to
|
|
29887
|
+
* a `fsl-<name>` DOM event (`composed`, `bubbling`) so slotted content and
|
|
29888
|
+
* outside consumers can observe machine activity declaratively.
|
|
29889
|
+
*
|
|
29890
|
+
* `fsl-` is the canonical prefix (matching the canonical `<fsl-*>` tag
|
|
29891
|
+
* names); the older `jssm-*` event prose in #639 predates that naming flip.
|
|
29892
|
+
* Events are NOT double-emitted under both prefixes — a symmetric listener
|
|
29893
|
+
* would otherwise run twice per machine event.
|
|
29894
|
+
*/
|
|
29895
|
+
FslInstance.REEMITTED_EVENTS = [
|
|
29896
|
+
'transition', 'entry', 'exit', 'terminal', 'complete',
|
|
29897
|
+
'action', 'rejection', 'override', 'data-change', 'timeout', 'error',
|
|
29898
|
+
];
|
|
29772
29899
|
/**
|
|
29773
29900
|
* Lit reactive properties declaration. We declare `fsl` here (rather
|
|
29774
29901
|
* than via a decorator) so the attribute observation stays explicit and
|
|
@@ -29779,7 +29906,15 @@ FslInstance.properties = {
|
|
|
29779
29906
|
fsl: { type: String, reflect: false },
|
|
29780
29907
|
};
|
|
29781
29908
|
|
|
29782
|
-
/**
|
|
29909
|
+
/**
|
|
29910
|
+
* Thin subclass so `<jssm-instance>` registers under a distinct constructor.
|
|
29911
|
+
*
|
|
29912
|
+
* @deprecated The `jssm-*` tag and the `JssmInstance` class alias are
|
|
29913
|
+
* deprecated since v5 in favor of the canonical `<fsl-instance>` /
|
|
29914
|
+
* {@link FslInstance}, for fsl.tools brand alignment. They remain functional
|
|
29915
|
+
* but are slated for removal in v6 (tracked in `v6_breaking_changes.json` on
|
|
29916
|
+
* the `v6` branch). New components are `fsl-*`-only.
|
|
29917
|
+
*/
|
|
29783
29918
|
class JssmInstance extends FslInstance {
|
|
29784
29919
|
}
|
|
29785
29920
|
define_with_synonym('fsl-instance', 'jssm-instance', FslInstance, JssmInstance);
|