jssm 5.149.2 → 5.150.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/README.md +7 -7
- package/custom-elements.json +261 -11
- package/dist/cdn/instance.js +929 -443
- package/dist/cdn/viz.js +761 -332
- 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 +3 -1
- package/dist/deno/README.md +7 -7
- package/dist/deno/jssm.d.ts +14 -2
- package/dist/deno/jssm.js +1 -1
- package/dist/deno/jssm_types.d.ts +11 -1
- 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.js +88 -31
- package/dist/wc/widgets.js +137 -18
- package/jssm.es5.d.cts +23 -1
- package/jssm.es6.d.ts +23 -1
- package/jssm_viz.es5.d.cts +23 -1
- package/jssm_viz.es6.d.ts +23 -1
- package/package.json +1 -1
package/dist/wc/instance.js
CHANGED
|
@@ -908,8 +908,20 @@ class FslInstance extends LitElement {
|
|
|
908
908
|
this._autoMode = 'lr';
|
|
909
909
|
/** Window-resize listener installed while `layout="auto"`, or null. */
|
|
910
910
|
this._autoListener = null;
|
|
911
|
-
/**
|
|
912
|
-
|
|
911
|
+
/** Per-panel runtime visibility overrides set by the user via the toolbar
|
|
912
|
+
* toggles; a slot absent here falls back to its mode-resolved base. */
|
|
913
|
+
this._overrides = new Map();
|
|
914
|
+
/** Control-level default {@link PanelMode}; {@link panelModes} overrides it
|
|
915
|
+
* per panel. `default` shows only the editor + renderer; every other panel
|
|
916
|
+
* starts hidden and is opt-in. */
|
|
917
|
+
this.panelMode = 'default';
|
|
918
|
+
/** Per-panel {@link PanelMode} overrides (slot → mode), each overriding the
|
|
919
|
+
* control-level {@link panelMode}. */
|
|
920
|
+
this.panelModes = {};
|
|
921
|
+
/** Panels the FSL "requests" — the embedder-set stand-in for the
|
|
922
|
+
* editor-defaults-in-FSL mechanism (fsl#1334). `request`-mode panels listed
|
|
923
|
+
* here are shown; others fall back to the default. */
|
|
924
|
+
this.requestedPanels = [];
|
|
913
925
|
/**
|
|
914
926
|
* The underlying machine instance, constructed at `connectedCallback`.
|
|
915
927
|
* Exposed raw (not proxied) per the #639/#648 design decision so that
|
|
@@ -1102,39 +1114,67 @@ class FslInstance extends LitElement {
|
|
|
1102
1114
|
this._tab = tab;
|
|
1103
1115
|
this.requestUpdate();
|
|
1104
1116
|
}
|
|
1117
|
+
/** The built-in default hidden state: only the editor + renderer (viz) show. */
|
|
1118
|
+
_defaultHidden(slot) {
|
|
1119
|
+
return slot !== 'viz' && slot !== 'editor';
|
|
1120
|
+
}
|
|
1105
1121
|
/**
|
|
1106
|
-
* Whether the panel slotted under `slot` is currently hidden
|
|
1122
|
+
* Whether the panel slotted under `slot` is currently hidden, resolving its
|
|
1123
|
+
* {@link PanelMode} ({@link panelModes} for the slot, else {@link panelMode}):
|
|
1124
|
+
* `hide`/`show` force the state; otherwise a user toggle wins, then a
|
|
1125
|
+
* `request`ed panel shows, then the built-in default.
|
|
1107
1126
|
*
|
|
1108
1127
|
* @param slot - A panel slot name (e.g. `"viz"`, `"editor"`, `"history"`).
|
|
1109
1128
|
* @returns `true` when the panel is hidden.
|
|
1129
|
+
*
|
|
1130
|
+
* @example
|
|
1131
|
+
* el.panelModes = { history: 'show' };
|
|
1132
|
+
* el.isPanelHidden('history'); // false
|
|
1110
1133
|
*/
|
|
1111
1134
|
isPanelHidden(slot) {
|
|
1112
|
-
|
|
1135
|
+
var _a;
|
|
1136
|
+
const mode = (_a = this.panelModes[slot]) !== null && _a !== void 0 ? _a : this.panelMode;
|
|
1137
|
+
if (mode === 'hide') {
|
|
1138
|
+
return true;
|
|
1139
|
+
}
|
|
1140
|
+
if (mode === 'show') {
|
|
1141
|
+
return false;
|
|
1142
|
+
}
|
|
1143
|
+
const override = this._overrides.get(slot);
|
|
1144
|
+
if (override !== undefined) {
|
|
1145
|
+
return override;
|
|
1146
|
+
}
|
|
1147
|
+
if (mode === 'request' && this.requestedPanels.includes(slot)) {
|
|
1148
|
+
return false;
|
|
1149
|
+
}
|
|
1150
|
+
return this._defaultHidden(slot);
|
|
1113
1151
|
}
|
|
1114
1152
|
/**
|
|
1115
|
-
* Show or hide the panel slotted under `slot
|
|
1116
|
-
* collapses that workbench pane (the other fills); hiding
|
|
1117
|
-
* removes its section. `<fsl-toolbar>` drives this from its
|
|
1153
|
+
* Show or hide the panel slotted under `slot` (a runtime override). Hiding
|
|
1154
|
+
* `viz` or `editor` collapses that workbench pane (the other fills); hiding
|
|
1155
|
+
* an aux panel removes its section. `<fsl-toolbar>` drives this from its
|
|
1156
|
+
* panel toggles.
|
|
1118
1157
|
*
|
|
1119
1158
|
* @param slot - A panel slot name (e.g. `"viz"`, `"editor"`, `"history"`).
|
|
1120
1159
|
* @param hidden - `true` to hide, `false` to show.
|
|
1121
1160
|
*/
|
|
1122
1161
|
setPanelHidden(slot, hidden) {
|
|
1123
|
-
|
|
1124
|
-
this._hiddenPanels.add(slot);
|
|
1125
|
-
}
|
|
1126
|
-
else {
|
|
1127
|
-
this._hiddenPanels.delete(slot);
|
|
1128
|
-
}
|
|
1162
|
+
this._overrides.set(slot, hidden);
|
|
1129
1163
|
this.requestUpdate();
|
|
1130
1164
|
}
|
|
1131
1165
|
/**
|
|
1132
|
-
* Toggle the visibility of the panel slotted under `slot`.
|
|
1166
|
+
* Toggle the visibility of the panel slotted under `slot`. A no-op when the
|
|
1167
|
+
* panel's mode is `hide` or `show` — those lock the visibility.
|
|
1133
1168
|
*
|
|
1134
1169
|
* @param slot - A panel slot name (e.g. `"viz"`, `"editor"`, `"history"`).
|
|
1135
1170
|
*/
|
|
1136
1171
|
togglePanel(slot) {
|
|
1137
|
-
|
|
1172
|
+
var _a;
|
|
1173
|
+
const mode = (_a = this.panelModes[slot]) !== null && _a !== void 0 ? _a : this.panelMode;
|
|
1174
|
+
if (mode === 'hide' || mode === 'show') {
|
|
1175
|
+
return;
|
|
1176
|
+
}
|
|
1177
|
+
this.setPanelHidden(slot, !this.isPanelHidden(slot));
|
|
1138
1178
|
}
|
|
1139
1179
|
/**
|
|
1140
1180
|
* Install or remove the window-resize listener that resolves `layout="auto"`
|
|
@@ -1181,6 +1221,7 @@ class FslInstance extends LitElement {
|
|
|
1181
1221
|
// (The resolver guarantees `fsl` is a non-empty string when error is undefined.)
|
|
1182
1222
|
const fsl_source = resolved.fsl;
|
|
1183
1223
|
this._machine = this._build_machine(fsl_source);
|
|
1224
|
+
this._applyEditorConfig();
|
|
1184
1225
|
// Step 3: paint initial host attributes + CSS custom properties.
|
|
1185
1226
|
this._paint_state_reflection();
|
|
1186
1227
|
// Step 4: shadow DOM render is automatic via Lit; requesting an update
|
|
@@ -1352,6 +1393,17 @@ class FslInstance extends LitElement {
|
|
|
1352
1393
|
? sm `${fsl_source}`
|
|
1353
1394
|
: from(fsl_source, { data: this.data }));
|
|
1354
1395
|
}
|
|
1396
|
+
/** Adopt the FSL's `editor: {}` panel request (fsl#1334): when the machine
|
|
1397
|
+
* declares `panels`, drive {@link requestedPanels} from it so `request` panel
|
|
1398
|
+
* mode honors the source. The embedder's value persists when the FSL is
|
|
1399
|
+
* silent. Called after each (re)build, with `_machine` freshly assigned. */
|
|
1400
|
+
_applyEditorConfig() {
|
|
1401
|
+
var _a;
|
|
1402
|
+
const panels = (_a = this._machine.editor_config()) === null || _a === void 0 ? void 0 : _a.panels;
|
|
1403
|
+
if (panels !== undefined) {
|
|
1404
|
+
this.requestedPanels = panels;
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1355
1407
|
_rebuild_machine() {
|
|
1356
1408
|
if (typeof this.fsl !== 'string' || this.fsl.trim().length === 0) {
|
|
1357
1409
|
return;
|
|
@@ -1367,6 +1419,7 @@ class FslInstance extends LitElement {
|
|
|
1367
1419
|
this._unbind_machine_subscriptions();
|
|
1368
1420
|
// Swap to the new machine and re-bind everything machine-scoped.
|
|
1369
1421
|
this._machine = next;
|
|
1422
|
+
this._applyEditorConfig();
|
|
1370
1423
|
this._paint_state_reflection();
|
|
1371
1424
|
this._install_event_reemission();
|
|
1372
1425
|
this._install_declarative_hooks();
|
|
@@ -1592,10 +1645,10 @@ class FslInstance extends LitElement {
|
|
|
1592
1645
|
${header}
|
|
1593
1646
|
${toolbar}
|
|
1594
1647
|
<div class="middle">
|
|
1595
|
-
<section class="dock
|
|
1596
|
-
<slot name="
|
|
1648
|
+
<section class="dock events-dock${this.isPanelHidden('hook-log') ? '' : ' open'}" part="events-dock">
|
|
1649
|
+
<slot name="hook-log"></slot>
|
|
1597
1650
|
</section>
|
|
1598
|
-
<div class="workbench${this.
|
|
1651
|
+
<div class="workbench${this.isPanelHidden('viz') ? ' hide-viz' : ''}${this.isPanelHidden('editor') ? ' hide-editor' : ''}"
|
|
1599
1652
|
data-mode=${mode} style="--fsl-split:${this._split}%">
|
|
1600
1653
|
${mode === 'tabs' ? this._renderTabbar() : ''}
|
|
1601
1654
|
<section class="pane viz" ?hidden=${mode === 'tabs' && this._tab !== 'viz'}>${viz}</section>
|
|
@@ -1604,7 +1657,7 @@ class FslInstance extends LitElement {
|
|
|
1604
1657
|
@dblclick=${this._onGutterReset}></div>
|
|
1605
1658
|
<section class="pane editor" ?hidden=${mode === 'tabs' && this._tab !== 'editor'}>${editor}</section>
|
|
1606
1659
|
</div>
|
|
1607
|
-
<section class="dock data-dock${this.
|
|
1660
|
+
<section class="dock data-dock${this.isPanelHidden('data-inspector') ? '' : ' open'}" part="data-dock">
|
|
1608
1661
|
<slot name="data-inspector"></slot>
|
|
1609
1662
|
</section>
|
|
1610
1663
|
</div>
|
|
@@ -1618,8 +1671,8 @@ class FslInstance extends LitElement {
|
|
|
1618
1671
|
<div class="container">
|
|
1619
1672
|
${header}
|
|
1620
1673
|
${toolbar}
|
|
1621
|
-
<section class="viz" ?hidden=${this.
|
|
1622
|
-
<section class="editor" ?hidden=${this.
|
|
1674
|
+
<section class="viz" ?hidden=${this.isPanelHidden('viz')}>${viz}</section>
|
|
1675
|
+
<section class="editor" ?hidden=${this.isPanelHidden('editor')}>${editor}</section>
|
|
1623
1676
|
${this._renderAuxPanels(false)}
|
|
1624
1677
|
<section class="state-section"><slot name=${state_slot_name}></slot></section>
|
|
1625
1678
|
<footer><slot name="footer"></slot></footer>
|
|
@@ -1627,22 +1680,23 @@ class FslInstance extends LitElement {
|
|
|
1627
1680
|
`;
|
|
1628
1681
|
}
|
|
1629
1682
|
/** The stacked middle panels, shared by both layouts. The toolbar slot is
|
|
1630
|
-
* rendered at the top of {@link render}. In split mode the `
|
|
1631
|
-
* `data-inspector` panels are lifted out into easing side docks, so
|
|
1683
|
+
* rendered at the top of {@link render}. In split mode the `hook-log` (events)
|
|
1684
|
+
* and `data-inspector` panels are lifted out into easing side docks, so
|
|
1632
1685
|
* `docked` is true there and they are skipped here to avoid duplicating
|
|
1633
|
-
* their slots
|
|
1634
|
-
*
|
|
1686
|
+
* their slots; `actions` instead lives here as a horizontal bar. The
|
|
1687
|
+
* state-section + footer stay in {@link render} so the dynamic state-slot
|
|
1688
|
+
* name binds at the top level.
|
|
1635
1689
|
*
|
|
1636
|
-
* @param docked - True when
|
|
1690
|
+
* @param docked - True when hook-log + data-inspector are rendered as side
|
|
1637
1691
|
* docks (split layouts); they are then omitted from this stack. */
|
|
1638
1692
|
_renderAuxPanels(docked) {
|
|
1639
|
-
const h = (slot) => this.
|
|
1693
|
+
const h = (slot) => this.isPanelHidden(slot);
|
|
1640
1694
|
return html `
|
|
1641
|
-
|
|
1695
|
+
<section class="actions" ?hidden=${h('actions')}><slot name="actions"></slot></section>
|
|
1642
1696
|
<section class="info-panel" ?hidden=${h('info-panel')}><slot name="info-panel"></slot></section>
|
|
1643
1697
|
<section class="history" ?hidden=${h('history')}><slot name="history"></slot></section>
|
|
1644
1698
|
${docked ? '' : html `<section class="data-inspector" ?hidden=${h('data-inspector')}><slot name="data-inspector"></slot></section>`}
|
|
1645
|
-
|
|
1699
|
+
${docked ? '' : html `<section class="hook-log" ?hidden=${h('hook-log')}><slot name="hook-log"></slot></section>`}
|
|
1646
1700
|
<section class="effective-properties" ?hidden=${h('effective-properties')}><slot name="effective-properties"></slot></section>
|
|
1647
1701
|
<section class="simulation" ?hidden=${h('simulation')}><slot name="simulation"></slot></section>
|
|
1648
1702
|
<section class="export" ?hidden=${h('export')}><slot name="export"></slot></section>
|
|
@@ -1682,7 +1736,7 @@ FslInstance.styles = css `
|
|
|
1682
1736
|
|
|
1683
1737
|
/* layout modes: lr/rl (row) · tb/bt (column) · editor/viewer (single) · tabs. */
|
|
1684
1738
|
.container.is-split { display: flex; flex-direction: column; }
|
|
1685
|
-
/* the middle band:
|
|
1739
|
+
/* the middle band: events dock | workbench | data dock */
|
|
1686
1740
|
.middle { display: flex; flex: 1 1 auto; min-height: 0; }
|
|
1687
1741
|
.workbench { display: flex; flex: 1 1 auto; min-height: 0; min-width: 0; }
|
|
1688
1742
|
/* side docks ease their width like the help drawer; closed = 0, open = a
|
|
@@ -1693,7 +1747,7 @@ FslInstance.styles = css `
|
|
|
1693
1747
|
transition: flex-basis 0.28s ease;
|
|
1694
1748
|
}
|
|
1695
1749
|
.dock.open { flex-basis: var(--fsl-dock-width, 17em); }
|
|
1696
|
-
.
|
|
1750
|
+
.events-dock.open { border-right: 1px solid var(--fsl-color-border, #e5e5e5); }
|
|
1697
1751
|
.data-dock.open { border-left: 1px solid var(--fsl-color-border, #e5e5e5); }
|
|
1698
1752
|
/* a docked panel fills the band's height; the data inspector then scrolls
|
|
1699
1753
|
to the dock instead of its own 16em cap. */
|
|
@@ -1774,6 +1828,9 @@ FslInstance.properties = {
|
|
|
1774
1828
|
themeName: { type: String, attribute: 'theme-name', reflect: true },
|
|
1775
1829
|
themes: { type: Object, reflect: false },
|
|
1776
1830
|
data: { type: Object, reflect: false },
|
|
1831
|
+
panelMode: { type: String, attribute: 'panel-mode', reflect: true },
|
|
1832
|
+
panelModes: { type: Object, attribute: false },
|
|
1833
|
+
requestedPanels: { type: Array, attribute: false },
|
|
1777
1834
|
};
|
|
1778
1835
|
|
|
1779
1836
|
export { FslInstance, JSSM_ON_EVENT_NAMES, auto_mode, compile_inline_body, jssm_handler_registry, parse_jssm_on_element, resolve_fsl_source, resolve_named_handler, split_ratio };
|
package/dist/wc/widgets.js
CHANGED
|
@@ -95,7 +95,42 @@ const EXPORT_FORMATS = [
|
|
|
95
95
|
{ value: 'json', label: 'JSON (serialized)' },
|
|
96
96
|
{ value: 'fsl', label: 'FSL source' },
|
|
97
97
|
{ value: 'svg', label: 'SVG' },
|
|
98
|
+
{ value: 'permalink', label: 'Permalink (URL)' },
|
|
99
|
+
{ value: 'embed', label: 'Embed snippet' },
|
|
98
100
|
];
|
|
101
|
+
/**
|
|
102
|
+
* A shareable URL for the given FSL: the current page URL with the source
|
|
103
|
+
* encoded in the hash (`#fsl=...`). A page that reads the hash on load can
|
|
104
|
+
* restore the machine. Browser-only (uses `location`), like the rest of the
|
|
105
|
+
* toolbar.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* permalink_for("a -> b;"); // "https://host/path#fsl=a%20-%3E%20b%3B"
|
|
109
|
+
*/
|
|
110
|
+
function permalink_for(fsl) {
|
|
111
|
+
return `${location.href.split('#')[0]}#fsl=${encodeURIComponent(fsl)}`;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* A paste-able HTML snippet that renders the given FSL from the CDN builds: an
|
|
115
|
+
* `<fsl-instance>` reading its source from a `<script type="text/fsl">` child,
|
|
116
|
+
* with a slotted `<fsl-viz>` for the graph.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* embed_snippet_for("a -> b;"); // "<script …instance.js …><fsl-instance>…</fsl-instance>"
|
|
120
|
+
*/
|
|
121
|
+
function embed_snippet_for(fsl) {
|
|
122
|
+
const CDN = 'https://cdn.jsdelivr.net/npm/jssm/dist/cdn';
|
|
123
|
+
return [
|
|
124
|
+
`<script type="module" src="${CDN}/instance.js"></script>`,
|
|
125
|
+
`<script type="module" src="${CDN}/viz.js"></script>`,
|
|
126
|
+
'<fsl-instance>',
|
|
127
|
+
' <fsl-viz slot="viz"></fsl-viz>',
|
|
128
|
+
' <script type="text/fsl">',
|
|
129
|
+
fsl,
|
|
130
|
+
' </script>',
|
|
131
|
+
'</fsl-instance>',
|
|
132
|
+
].join('\n');
|
|
133
|
+
}
|
|
99
134
|
/* Panel icons — Solar (CC BY 4.0) bold-duotone. Layout icons — hand-drawn
|
|
100
135
|
duotone split-rects. All use currentColor (+ baked opacity on the secondary
|
|
101
136
|
tone), so they theme with the button's text color and pressed state. Each is
|
|
@@ -121,6 +156,9 @@ const ICON_AUTO = html `<svg class="ico" viewBox="0 0 24 24" aria-hidden="true">
|
|
|
121
156
|
const ICON_ACTIONS = html `<svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" fill-rule="evenodd" d="M8.732 5.771L5.67 9.914c-1.285 1.739-1.928 2.608-1.574 3.291l.018.034c.375.673 1.485.673 3.704.673c1.233 0 1.85 0 2.236.363l.02.02l3.872-4.57l-.02-.02c-.379-.371-.379-.963-.379-2.148v-.31c0-3.285 0-4.927-.923-5.21s-1.913 1.056-3.892 3.734" clip-rule="evenodd"/><path fill="currentColor" d="M10.453 16.443v.31c0 3.284 0 4.927.923 5.21s1.913-1.056 3.893-3.734l3.062-4.143c1.284-1.739 1.927-2.608 1.573-3.291l-.018-.034c-.375-.673-1.485-.673-3.704-.673c-1.233 0-1.85 0-2.236-.363l-3.872 4.57c.379.371.379.963.379 2.148" opacity=".5"/></svg>`;
|
|
122
157
|
/* Solar palette-round-bold-duotone — the theme pulldown. */
|
|
123
158
|
const ICON_THEME = html `<svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M7 18a1 1 0 1 1-2 0a1 1 0 0 1 2 0"/><path fill="currentColor" d="M10 6v12a4 4 0 0 1-8 0V6a4 4 0 1 1 8 0" opacity=".4"/><path fill="currentColor" d="m9.248 20.336l3.974-3.975l5.838-6.09a4.042 4.042 0 0 0-5.776-5.655L10 7.9V18c0 .872-.279 1.679-.752 2.336" opacity=".7"/><path fill="currentColor" d="m13.222 16.362l-3.974 3.974A4 4 0 0 1 6 22h11.9a4 4 0 1 0 0-8h-2.414z"/></svg>`;
|
|
159
|
+
/* Validate — a duotone check-circle. Lint — a duotone document with rule lines. */
|
|
160
|
+
const ICON_VALIDATE = html `<svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M22 12c0 5.523-4.477 10-10 10S2 17.523 2 12S6.477 2 12 2s10 4.477 10 10" opacity=".4"/><path fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" d="m8.5 12.5l2.5 2.5l4.5-5.5"/></svg>`;
|
|
161
|
+
const ICON_LINT = html `<svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M3 10c0-3.771 0-5.657 1.172-6.828S7.229 2 11 2h2c3.771 0 5.657 0 6.828 1.172S21 6.229 21 10v4c0 3.771 0 5.657-1.172 6.828S16.771 22 13 22h-2c-3.771 0-5.657 0-6.828-1.172S3 17.771 3 14z" opacity=".4"/><path fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" d="M7.5 8.5h9M7.5 12h6M7.5 15.5h3"/></svg>`;
|
|
124
162
|
const PANELS = [
|
|
125
163
|
{ slot: 'actions', label: 'Actions', icon: ICON_ACTIONS },
|
|
126
164
|
{ slot: 'viz', label: 'Renderer', icon: ICON_VIZ },
|
|
@@ -144,11 +182,13 @@ const LAYOUTS = [
|
|
|
144
182
|
{ value: 'tabs', label: 'Tabbed', icon: ICON_TABS },
|
|
145
183
|
];
|
|
146
184
|
/**
|
|
147
|
-
* `<fsl-toolbar>` — a control bar for a parent `<fsl-instance>`.
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
185
|
+
* `<fsl-toolbar>` — a control bar for a parent `<fsl-instance>`. Validate + Lint
|
|
186
|
+
* action buttons (fired as `fsl-validate` / `fsl-lint` events for the embedder
|
|
187
|
+
* to fulfill, each suppressible via `no-validate` / `no-lint`); an icon toggle
|
|
188
|
+
* to show/hide each panel present in the host (renderer, code, history, …); and
|
|
189
|
+
* Layout / Export / Theme pulldowns (the Layout button shows the current
|
|
190
|
+
* layout's icon). Standalone (no host) the host-dependent controls disappear.
|
|
191
|
+
* A trailing slot carries extra buttons.
|
|
152
192
|
*
|
|
153
193
|
* @element fsl-toolbar
|
|
154
194
|
* @csspart toolbar - The bar container.
|
|
@@ -166,6 +206,10 @@ class FslToolbar extends LitElement {
|
|
|
166
206
|
* The embedder sets this after fulfilling a `pick` export.
|
|
167
207
|
*/
|
|
168
208
|
this.lastDirectory = '';
|
|
209
|
+
/** Hide the Validate button (e.g. when the consumer validates inline). */
|
|
210
|
+
this.noValidate = false;
|
|
211
|
+
/** Hide the Lint button. */
|
|
212
|
+
this.noLint = false;
|
|
169
213
|
this._host = null;
|
|
170
214
|
/** Panels actually present in the host — one toggle each. */
|
|
171
215
|
this._present = [];
|
|
@@ -218,11 +262,24 @@ class FslToolbar extends LitElement {
|
|
|
218
262
|
else if (format === 'svg') {
|
|
219
263
|
content = await machine_to_svg_string(host.machine);
|
|
220
264
|
}
|
|
265
|
+
else if (format === 'permalink') {
|
|
266
|
+
content = permalink_for(host.fsl);
|
|
267
|
+
}
|
|
268
|
+
else if (format === 'embed') {
|
|
269
|
+
content = embed_snippet_for(host.fsl);
|
|
270
|
+
}
|
|
221
271
|
else {
|
|
222
272
|
content = host.fsl;
|
|
223
273
|
}
|
|
224
274
|
this.dispatchEvent(new CustomEvent('fsl-export', { detail: { format, content, destination }, bubbles: true, composed: true }));
|
|
225
275
|
}
|
|
276
|
+
/** Fire a workspace-action intent (validate / lint) for the consumer to
|
|
277
|
+
* fulfill — the toolbar presents the action; the embedder runs it. The
|
|
278
|
+
* current machine source rides along in the detail as a convenience. The
|
|
279
|
+
* buttons only render with a host, so `_host` is non-null here. */
|
|
280
|
+
_fireAction(type) {
|
|
281
|
+
this.dispatchEvent(new CustomEvent(type, { detail: { fsl: this._host.fsl }, bubbles: true, composed: true }));
|
|
282
|
+
}
|
|
226
283
|
_toggleMenu(which) { this._openMenu = this._openMenu === which ? '' : which; }
|
|
227
284
|
render() {
|
|
228
285
|
var _a, _b, _c, _d, _e;
|
|
@@ -235,6 +292,13 @@ class FslToolbar extends LitElement {
|
|
|
235
292
|
return html `
|
|
236
293
|
<div class="toolbar" part="toolbar" role="toolbar" aria-label="Workbench controls">
|
|
237
294
|
<span class="spacer"></span>
|
|
295
|
+
${host ? html `
|
|
296
|
+
<div class="grp">
|
|
297
|
+
${this.noValidate ? '' : html `
|
|
298
|
+
<button class="tb icon" aria-label="Validate" title="Validate" @click=${() => this._fireAction('fsl-validate')}>${ICON_VALIDATE}</button>`}
|
|
299
|
+
${this.noLint ? '' : html `
|
|
300
|
+
<button class="tb icon" aria-label="Lint" title="Lint" @click=${() => this._fireAction('fsl-lint')}>${ICON_LINT}</button>`}
|
|
301
|
+
</div>` : ''}
|
|
238
302
|
<div class="grp">
|
|
239
303
|
${host
|
|
240
304
|
? this._present.map(p => html `
|
|
@@ -336,6 +400,12 @@ __decorate$7([
|
|
|
336
400
|
__decorate$7([
|
|
337
401
|
property({ attribute: false })
|
|
338
402
|
], FslToolbar.prototype, "lastDirectory", void 0);
|
|
403
|
+
__decorate$7([
|
|
404
|
+
property({ type: Boolean, attribute: 'no-validate' })
|
|
405
|
+
], FslToolbar.prototype, "noValidate", void 0);
|
|
406
|
+
__decorate$7([
|
|
407
|
+
property({ type: Boolean, attribute: 'no-lint' })
|
|
408
|
+
], FslToolbar.prototype, "noLint", void 0);
|
|
339
409
|
|
|
340
410
|
var __decorate$6 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
341
411
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -465,18 +535,21 @@ class FslActions extends LitElement {
|
|
|
465
535
|
}
|
|
466
536
|
FslActions.styles = css `
|
|
467
537
|
:host { display: block; }
|
|
538
|
+
/* Horizontal bar: groups flow left-to-right and wrap; within a group the
|
|
539
|
+
label sits inline before its buttons. Suits the panel's home below the
|
|
540
|
+
workbench rather than a tall side dock. */
|
|
468
541
|
.actions {
|
|
469
|
-
display: flex; flex-direction:
|
|
542
|
+
display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 0.4rem 1.1rem;
|
|
470
543
|
padding: 0.55rem 0.65rem; background: var(--_fsl-surface);
|
|
471
544
|
color: var(--_fsl-text); font: 0.8rem var(--_fsl-font);
|
|
472
545
|
}
|
|
473
|
-
.group { display: flex; flex-direction:
|
|
546
|
+
.group { display: flex; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 0.3rem; }
|
|
474
547
|
.label {
|
|
475
548
|
font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.05em;
|
|
476
|
-
color: var(--_fsl-muted);
|
|
549
|
+
color: var(--_fsl-muted); white-space: nowrap;
|
|
477
550
|
}
|
|
478
551
|
button {
|
|
479
|
-
text-align:
|
|
552
|
+
text-align: center; padding: 0.4rem 0.6rem; cursor: pointer; border-radius: 4px;
|
|
480
553
|
border: 1px solid var(--_fsl-border); background: var(--_fsl-surface);
|
|
481
554
|
color: var(--_fsl-text); font: 600 0.8rem var(--_fsl-font);
|
|
482
555
|
}
|
|
@@ -503,15 +576,23 @@ var __decorate$5 = (undefined && undefined.__decorate) || function (decorators,
|
|
|
503
576
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
504
577
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
505
578
|
};
|
|
579
|
+
/** `<n> word`, with a regular plural `s` unless `n === 1`. */
|
|
580
|
+
function plural(n, word) {
|
|
581
|
+
return `${n} ${word}${n === 1 ? '' : 's'}`;
|
|
582
|
+
}
|
|
506
583
|
/**
|
|
507
584
|
* `<fsl-footer>` — a status bar for a parent `<fsl-instance>`.
|
|
508
585
|
*
|
|
509
|
-
*
|
|
510
|
-
*
|
|
511
|
-
*
|
|
512
|
-
*
|
|
513
|
-
*
|
|
514
|
-
*
|
|
586
|
+
* Shows the current state with both **local** counts (actions firable from
|
|
587
|
+
* here + transitions out of here) and **global** machine counts: distinct
|
|
588
|
+
* action *names*, **action-starts** (action-bearing edges — each place an
|
|
589
|
+
* action fires from), and total transitions. Plus terminal/complete badges.
|
|
590
|
+
*
|
|
591
|
+
* Local counts track transitions by observing the host's reflected
|
|
592
|
+
* `current-state` / `legal-actions` attributes; the global counts refresh on
|
|
593
|
+
* `fsl-machine-rebuilt`, so the footer survives a live rebuild (#1387). A
|
|
594
|
+
* default slot carries embedder status. Standalone (no `<fsl-instance>`
|
|
595
|
+
* ancestor) it renders just the slot.
|
|
515
596
|
*
|
|
516
597
|
* @element fsl-footer
|
|
517
598
|
* @csspart bar - The footer bar container.
|
|
@@ -521,14 +602,21 @@ class FslFooter extends LitElement {
|
|
|
521
602
|
constructor() {
|
|
522
603
|
super(...arguments);
|
|
523
604
|
this._state = '';
|
|
524
|
-
this._actions = 0;
|
|
605
|
+
this._actions = 0; // local: actions firable from the current state
|
|
606
|
+
this._transitions = 0; // local: transitions out of the current state
|
|
525
607
|
this._terminal = false;
|
|
526
608
|
this._complete = false;
|
|
609
|
+
this._gActions = 0; // global: distinct action names
|
|
610
|
+
this._gStarts = 0; // global: action-starts (action-bearing edges)
|
|
611
|
+
this._gTransitions = 0; // global: total transitions (all edges)
|
|
527
612
|
this._observer = null;
|
|
613
|
+
this._host = null;
|
|
614
|
+
this._onRebuilt = () => { this._syncMachine(); };
|
|
528
615
|
}
|
|
529
616
|
connectedCallback() {
|
|
530
617
|
super.connectedCallback();
|
|
531
618
|
const host = closest_wc(this, 'instance');
|
|
619
|
+
this._host = host;
|
|
532
620
|
if (host === null) {
|
|
533
621
|
return;
|
|
534
622
|
}
|
|
@@ -539,12 +627,14 @@ class FslFooter extends LitElement {
|
|
|
539
627
|
this._actions = la === '' ? 0 : la.split(/\s+/).length;
|
|
540
628
|
this._terminal = host.hasAttribute('terminal');
|
|
541
629
|
this._complete = host.hasAttribute('complete');
|
|
630
|
+
this._syncMachine();
|
|
542
631
|
};
|
|
543
632
|
this._observer = new MutationObserver(sync);
|
|
544
633
|
this._observer.observe(host, {
|
|
545
634
|
attributes: true,
|
|
546
635
|
attributeFilter: ['current-state', 'legal-actions', 'terminal', 'complete'],
|
|
547
636
|
});
|
|
637
|
+
host.addEventListener('fsl-machine-rebuilt', this._onRebuilt);
|
|
548
638
|
sync();
|
|
549
639
|
}
|
|
550
640
|
disconnectedCallback() {
|
|
@@ -553,12 +643,29 @@ class FslFooter extends LitElement {
|
|
|
553
643
|
this._observer.disconnect();
|
|
554
644
|
this._observer = null;
|
|
555
645
|
}
|
|
646
|
+
if (this._host !== null) {
|
|
647
|
+
this._host.removeEventListener('fsl-machine-rebuilt', this._onRebuilt);
|
|
648
|
+
this._host = null;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
/** Recompute the machine-derived counts: local transitions out of the current
|
|
652
|
+
* state, and the global action / action-start / transition totals. Only
|
|
653
|
+
* called while a host is attached, so `_host` is non-null here. */
|
|
654
|
+
_syncMachine() {
|
|
655
|
+
var _a;
|
|
656
|
+
const host = this._host;
|
|
657
|
+
const current = (_a = host.getAttribute('current-state')) !== null && _a !== void 0 ? _a : '';
|
|
658
|
+
const edges = host.machine.list_edges();
|
|
659
|
+
this._transitions = edges.filter(e => String(e.from) === current).length;
|
|
660
|
+
const actionEdges = edges.filter(e => typeof e.action === 'string');
|
|
661
|
+
this._gStarts = actionEdges.length;
|
|
662
|
+
this._gActions = new Set(actionEdges.map(e => e.action)).size;
|
|
663
|
+
this._gTransitions = edges.length;
|
|
556
664
|
}
|
|
557
665
|
render() {
|
|
558
666
|
return html `
|
|
559
667
|
<div class="bar" part="bar">
|
|
560
|
-
|
|
561
|
-
<span>${this._actions} action${this._actions === 1 ? '' : 's'}</span>
|
|
668
|
+
<span>${this._state ? html `<span class="state">${this._state}</span>, ` : ''}${plural(this._actions, 'action')}, ${plural(this._transitions, 'transition')}; globally ${plural(this._gActions, 'action')}, ${plural(this._gStarts, 'start')}, ${plural(this._gTransitions, 'transition')}</span>
|
|
562
669
|
${this._terminal ? html `<span class="badge">terminal</span>` : ''}
|
|
563
670
|
${this._complete ? html `<span class="badge">complete</span>` : ''}
|
|
564
671
|
<span class="spacer"></span>
|
|
@@ -585,12 +692,24 @@ __decorate$5([
|
|
|
585
692
|
__decorate$5([
|
|
586
693
|
state()
|
|
587
694
|
], FslFooter.prototype, "_actions", void 0);
|
|
695
|
+
__decorate$5([
|
|
696
|
+
state()
|
|
697
|
+
], FslFooter.prototype, "_transitions", void 0);
|
|
588
698
|
__decorate$5([
|
|
589
699
|
state()
|
|
590
700
|
], FslFooter.prototype, "_terminal", void 0);
|
|
591
701
|
__decorate$5([
|
|
592
702
|
state()
|
|
593
703
|
], FslFooter.prototype, "_complete", void 0);
|
|
704
|
+
__decorate$5([
|
|
705
|
+
state()
|
|
706
|
+
], FslFooter.prototype, "_gActions", void 0);
|
|
707
|
+
__decorate$5([
|
|
708
|
+
state()
|
|
709
|
+
], FslFooter.prototype, "_gStarts", void 0);
|
|
710
|
+
__decorate$5([
|
|
711
|
+
state()
|
|
712
|
+
], FslFooter.prototype, "_gTransitions", void 0);
|
|
594
713
|
|
|
595
714
|
var __decorate$4 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
|
|
596
715
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
package/jssm.es5.d.cts
CHANGED
|
@@ -515,6 +515,15 @@ declare type JssmBaseTheme = {
|
|
|
515
515
|
* @typeParam StateType - The state-name type (usually `string`).
|
|
516
516
|
* @typeParam DataType - The user-supplied data payload type (`mDT`).
|
|
517
517
|
*/
|
|
518
|
+
/**
|
|
519
|
+
* Editor/panel defaults an FSL machine declares in an `editor: {}` block
|
|
520
|
+
* (fsl#1334), read by the all-widgets web control: a stochastic run-count
|
|
521
|
+
* and the panels the machine requests under `request` panel mode.
|
|
522
|
+
*/
|
|
523
|
+
declare type JssmEditorConfig = {
|
|
524
|
+
stochastic_run_count?: number;
|
|
525
|
+
panels?: Array<string>;
|
|
526
|
+
};
|
|
518
527
|
declare type JssmGenericConfig<StateType, DataType> = {
|
|
519
528
|
graph_layout?: JssmLayout;
|
|
520
529
|
complete?: Array<StateType>;
|
|
@@ -544,6 +553,7 @@ declare type JssmGenericConfig<StateType, DataType> = {
|
|
|
544
553
|
min_exits?: number;
|
|
545
554
|
max_exits?: number;
|
|
546
555
|
allow_islands?: JssmAllowIslands;
|
|
556
|
+
editor_config?: JssmEditorConfig;
|
|
547
557
|
allow_force?: false;
|
|
548
558
|
actions?: JssmPermittedOpt;
|
|
549
559
|
simplify_bidi?: boolean;
|
|
@@ -2044,6 +2054,7 @@ declare class Machine<mDT> {
|
|
|
2044
2054
|
_code_allows_override: JssmAllowsOverride;
|
|
2045
2055
|
_config_allows_override: JssmAllowsOverride;
|
|
2046
2056
|
_allow_islands: JssmAllowIslands;
|
|
2057
|
+
_editor_config?: JssmEditorConfig;
|
|
2047
2058
|
_post_hooks: Map<number, HookHandler<mDT>>;
|
|
2048
2059
|
_post_named_hooks: Map<number, Map<number, HookHandler<mDT>>>;
|
|
2049
2060
|
_post_entry_hooks: Map<number, HookHandler<mDT>>;
|
|
@@ -2093,7 +2104,7 @@ declare class Machine<mDT> {
|
|
|
2093
2104
|
_firing_error: boolean;
|
|
2094
2105
|
_boundary_depth: number;
|
|
2095
2106
|
_boundary_depth_limit: number;
|
|
2096
|
-
constructor({ start_states, end_states, failed_outputs, initial_state, start_states_no_enforce, complete, transitions, machine_author, machine_comment, machine_contributor, machine_definition, machine_language, machine_license, machine_name, machine_version, npm_name, default_size, state_declaration, property_definition, state_property, fsl_version, dot_preamble, arrange_declaration, arrange_start_declaration, arrange_end_declaration, theme, flow, graph_layout, instance_name, history, boundary_depth_limit, data, default_state_config, default_active_state_config, default_hooked_state_config, default_terminal_state_config, default_start_state_config, default_end_state_config, default_transition_config, default_graph_config, group_registry, group_metadata, group_hooks, state_hooks, allows_override, config_allows_override, allow_islands, rng_seed, time_source, timeout_source, clear_timeout_source }: JssmGenericConfig<StateType, mDT>);
|
|
2107
|
+
constructor({ start_states, end_states, failed_outputs, initial_state, start_states_no_enforce, complete, transitions, machine_author, machine_comment, machine_contributor, machine_definition, machine_language, machine_license, machine_name, machine_version, npm_name, default_size, state_declaration, property_definition, state_property, fsl_version, dot_preamble, arrange_declaration, arrange_start_declaration, arrange_end_declaration, theme, flow, graph_layout, instance_name, history, boundary_depth_limit, data, default_state_config, default_active_state_config, default_hooked_state_config, default_terminal_state_config, default_start_state_config, default_end_state_config, default_transition_config, default_graph_config, group_registry, group_metadata, group_hooks, state_hooks, allows_override, config_allows_override, allow_islands, editor_config, rng_seed, time_source, timeout_source, clear_timeout_source }: JssmGenericConfig<StateType, mDT>);
|
|
2097
2108
|
/********
|
|
2098
2109
|
*
|
|
2099
2110
|
* Internal method for fabricating states. Not meant for external use.
|
|
@@ -2521,6 +2532,17 @@ declare class Machine<mDT> {
|
|
|
2521
2532
|
* @returns The machine name string.
|
|
2522
2533
|
*/
|
|
2523
2534
|
machine_name(): string;
|
|
2535
|
+
/** The editor/panel defaults declared in the FSL `editor: {}` block, or
|
|
2536
|
+
* `undefined` when none was given. Read by the all-widgets web control
|
|
2537
|
+
* (fsl#1334) — `panels` drives `request` panel mode.
|
|
2538
|
+
*
|
|
2539
|
+
* @returns `{ stochastic_run_count?, panels? }`, or `undefined`.
|
|
2540
|
+
*
|
|
2541
|
+
* @example
|
|
2542
|
+
* const m = sm`editor: { panels: [history]; }; a -> b;`;
|
|
2543
|
+
* m.editor_config(); // => { panels: ['history'] }
|
|
2544
|
+
*/
|
|
2545
|
+
editor_config(): JssmEditorConfig | undefined;
|
|
2524
2546
|
/** Get the npm package name associated with the machine. Set via the FSL `npm_name` directive.
|
|
2525
2547
|
* Returns `undefined` when not present.
|
|
2526
2548
|
* @returns The npm package name string, or `undefined`.
|
package/jssm.es6.d.ts
CHANGED
|
@@ -515,6 +515,15 @@ declare type JssmBaseTheme = {
|
|
|
515
515
|
* @typeParam StateType - The state-name type (usually `string`).
|
|
516
516
|
* @typeParam DataType - The user-supplied data payload type (`mDT`).
|
|
517
517
|
*/
|
|
518
|
+
/**
|
|
519
|
+
* Editor/panel defaults an FSL machine declares in an `editor: {}` block
|
|
520
|
+
* (fsl#1334), read by the all-widgets web control: a stochastic run-count
|
|
521
|
+
* and the panels the machine requests under `request` panel mode.
|
|
522
|
+
*/
|
|
523
|
+
declare type JssmEditorConfig = {
|
|
524
|
+
stochastic_run_count?: number;
|
|
525
|
+
panels?: Array<string>;
|
|
526
|
+
};
|
|
518
527
|
declare type JssmGenericConfig<StateType, DataType> = {
|
|
519
528
|
graph_layout?: JssmLayout;
|
|
520
529
|
complete?: Array<StateType>;
|
|
@@ -544,6 +553,7 @@ declare type JssmGenericConfig<StateType, DataType> = {
|
|
|
544
553
|
min_exits?: number;
|
|
545
554
|
max_exits?: number;
|
|
546
555
|
allow_islands?: JssmAllowIslands;
|
|
556
|
+
editor_config?: JssmEditorConfig;
|
|
547
557
|
allow_force?: false;
|
|
548
558
|
actions?: JssmPermittedOpt;
|
|
549
559
|
simplify_bidi?: boolean;
|
|
@@ -2044,6 +2054,7 @@ declare class Machine<mDT> {
|
|
|
2044
2054
|
_code_allows_override: JssmAllowsOverride;
|
|
2045
2055
|
_config_allows_override: JssmAllowsOverride;
|
|
2046
2056
|
_allow_islands: JssmAllowIslands;
|
|
2057
|
+
_editor_config?: JssmEditorConfig;
|
|
2047
2058
|
_post_hooks: Map<number, HookHandler<mDT>>;
|
|
2048
2059
|
_post_named_hooks: Map<number, Map<number, HookHandler<mDT>>>;
|
|
2049
2060
|
_post_entry_hooks: Map<number, HookHandler<mDT>>;
|
|
@@ -2093,7 +2104,7 @@ declare class Machine<mDT> {
|
|
|
2093
2104
|
_firing_error: boolean;
|
|
2094
2105
|
_boundary_depth: number;
|
|
2095
2106
|
_boundary_depth_limit: number;
|
|
2096
|
-
constructor({ start_states, end_states, failed_outputs, initial_state, start_states_no_enforce, complete, transitions, machine_author, machine_comment, machine_contributor, machine_definition, machine_language, machine_license, machine_name, machine_version, npm_name, default_size, state_declaration, property_definition, state_property, fsl_version, dot_preamble, arrange_declaration, arrange_start_declaration, arrange_end_declaration, theme, flow, graph_layout, instance_name, history, boundary_depth_limit, data, default_state_config, default_active_state_config, default_hooked_state_config, default_terminal_state_config, default_start_state_config, default_end_state_config, default_transition_config, default_graph_config, group_registry, group_metadata, group_hooks, state_hooks, allows_override, config_allows_override, allow_islands, rng_seed, time_source, timeout_source, clear_timeout_source }: JssmGenericConfig<StateType, mDT>);
|
|
2107
|
+
constructor({ start_states, end_states, failed_outputs, initial_state, start_states_no_enforce, complete, transitions, machine_author, machine_comment, machine_contributor, machine_definition, machine_language, machine_license, machine_name, machine_version, npm_name, default_size, state_declaration, property_definition, state_property, fsl_version, dot_preamble, arrange_declaration, arrange_start_declaration, arrange_end_declaration, theme, flow, graph_layout, instance_name, history, boundary_depth_limit, data, default_state_config, default_active_state_config, default_hooked_state_config, default_terminal_state_config, default_start_state_config, default_end_state_config, default_transition_config, default_graph_config, group_registry, group_metadata, group_hooks, state_hooks, allows_override, config_allows_override, allow_islands, editor_config, rng_seed, time_source, timeout_source, clear_timeout_source }: JssmGenericConfig<StateType, mDT>);
|
|
2097
2108
|
/********
|
|
2098
2109
|
*
|
|
2099
2110
|
* Internal method for fabricating states. Not meant for external use.
|
|
@@ -2521,6 +2532,17 @@ declare class Machine<mDT> {
|
|
|
2521
2532
|
* @returns The machine name string.
|
|
2522
2533
|
*/
|
|
2523
2534
|
machine_name(): string;
|
|
2535
|
+
/** The editor/panel defaults declared in the FSL `editor: {}` block, or
|
|
2536
|
+
* `undefined` when none was given. Read by the all-widgets web control
|
|
2537
|
+
* (fsl#1334) — `panels` drives `request` panel mode.
|
|
2538
|
+
*
|
|
2539
|
+
* @returns `{ stochastic_run_count?, panels? }`, or `undefined`.
|
|
2540
|
+
*
|
|
2541
|
+
* @example
|
|
2542
|
+
* const m = sm`editor: { panels: [history]; }; a -> b;`;
|
|
2543
|
+
* m.editor_config(); // => { panels: ['history'] }
|
|
2544
|
+
*/
|
|
2545
|
+
editor_config(): JssmEditorConfig | undefined;
|
|
2524
2546
|
/** Get the npm package name associated with the machine. Set via the FSL `npm_name` directive.
|
|
2525
2547
|
* Returns `undefined` when not present.
|
|
2526
2548
|
* @returns The npm package name string, or `undefined`.
|