# JBrowseDesktopSessionModel

Auto-generated @jbrowse/mobx-state-tree API for the current JBrowse release —
see [pluggable elements](https://jbrowse.org/jb2-staging/docs/developer_guide/) for concepts.
[View source](https://github.com/GMOD/jbrowse-components/blob/main/products/jbrowse-desktop/src/sessionModel/sessionModel.ts).

JBrowseDesktopSessionModel declares no members of its own — it composes the
models below, and everything here is theirs.

## Properties

<!-- prettier-ignore -->
| Member | Description | Defined by |
| --- | --- | --- |
| <span id="property-connectioninstances">**connectionInstances**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>connectionInstances: types.stripDefault( types.array(pluginMana…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>connectionInstances: types.stripDefault(&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;types.array(pluginManager.pluggableMstType('connection', 'stateModel')),&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;[],&#10;&#160;&#160;&#160;&#160;&#160;&#160;)</code></pre></dialog></span> |  | [ConnectionManagementSessionMixin](../connectionmanagementsessionmixin#property-connectioninstances) |
| <span id="property-connectiontrackconfigs">**connectionTrackConfigs**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>connectionTrackConfigs: types.stripDefault( types.frozen&lt;Record…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>connectionTrackConfigs: types.stripDefault(&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;types.frozen&lt;Record&lt;string, ConnectionTrackConfigEntry&gt;&gt;(),&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{},&#10;&#160;&#160;&#160;&#160;&#160;&#160;)</code></pre></dialog></span> | <span data-pagefind-ignore>Persisted configs of connection tracks the user has opened, keyed by trackId. Unlike `connectionInstances` (stripped from snapshots, holds the whole fetched hub), this holds only the tracks in use, so an open connection track resolves synchronously on session load without re-establishing the connection.</span> | [ConnectionManagementSessionMixin](../connectionmanagementsessionmixin#property-connectiontrackconfigs) |
| <span id="property-id">**id**</span><br><code>id: ElementId</code> |  | [BaseSessionModel](../basesessionmodel#property-id) |
| <span id="property-name">**name**</span><br><code>name: types.string</code> |  | [BaseSessionModel](../basesessionmodel#property-name) |
| <span id="property-focusedviewid">**focusedViewId**</span><br><code>focusedViewId: types.maybe(types.string)</code> | <span data-pagefind-ignore>used to keep track of which view is in focus</span> | [BaseSessionModel](../basesessionmodel#property-focusedviewid) |
| <span id="property-highlightsvisible">**highlightsVisible**</span><br><code>highlightsVisible: types.stripDefault(types.boolean, true)</code> | <span data-pagefind-ignore>one session-wide toggle for all region highlight bands (URL/view highlights and bookmark overlays)</span> | [BaseSessionModel](../basesessionmodel#property-highlightsvisible) |
| <span id="property-sessionassemblies">**sessionAssemblies**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>sessionAssemblies: types.stripDefault( types.array(assemblyConf…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>sessionAssemblies: types.stripDefault(&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;types.array(assemblyConfigSchemasType),&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;[],&#10;&#160;&#160;&#160;&#160;&#160;&#160;)</code></pre></dialog></span> |  | [AssembliesMixin](../assembliesmixin#property-sessionassemblies) |
| <span id="property-temporaryassemblies">**temporaryAssemblies**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>temporaryAssemblies: types.stripDefault( types.array(assemblyCo…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>temporaryAssemblies: types.stripDefault(&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;types.array(assemblyConfigSchemasType),&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;[],&#10;&#160;&#160;&#160;&#160;&#160;&#160;)</code></pre></dialog></span> |  | [AssembliesMixin](../assembliesmixin#property-temporaryassemblies) |
| <span id="property-viewids">**viewIds**</span><br><code>viewIds: types.array(types.string)</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#property-viewids) |
| <span id="property-title">**title**</span><br><code>title: types.maybe(types.string)</code> | <span data-pagefind-ignore>set only by an explicit rename; otherwise the name is derived from views</span> | [WorkspaceLayoutMixin](../workspacelayoutmixin#property-title) |
| <span id="property-size">**size**</span><br><code>size: types.optional(types.number, 1)</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#property-size) |
| <span id="property-tabs">**tabs**</span><br><code>tabs: types.array(LayoutTab)</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#property-tabs) |
| <span id="property-activetabid">**activeTabId**</span><br><code>activeTabId: types.maybe(types.string)</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#property-activetabid) |
| **size**<br><code>size: types.optional(types.number, 1)</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#property-size) |
| <span id="property-direction">**direction**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>direction: types.enumeration('LayoutDirection', ['row', 'column…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>direction: types.enumeration('LayoutDirection', ['row', 'column'])</code></pre></dialog></span> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#property-direction) |
| <span id="property-children">**children**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>children: types.array( types.late((): typeof LayoutPanel =&gt; Lay…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>children: types.array(&#10;&#160;&#160;&#160;&#160;types.late((): typeof LayoutPanel =&gt; LayoutNode as never),&#10;&#160;&#160;)</code></pre></dialog></span> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#property-children) |
| <span id="property-layout">**layout**</span><br><code>layout: types.optional(LayoutNode, emptyPanel)</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#property-layout) |
| <span id="property-activepanelid">**activePanelId**</span><br><code>activePanelId: types.maybe(types.string)</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#property-activepanelid) |
| <span id="property-maximizedpanelid">**maximizedPanelId**</span><br><code>maximizedPanelId: types.maybe(types.string)</code> | <span data-pagefind-ignore>Show only this cell, at the size of the whole workspace.<br><br>Deliberately HERE and not a `maximized` flag on `PanelNode`. On the node it would be inside `tree.ts`, the half that carries the risk and is proven by a randomised operation sequence asserting canonical form after every step — and every operation would then have to say what it does to the flag: a split of a maximized panel, a drag of its last tab out, a normalize that collapses it into its parent. Beside `activePanelId` it is the same class of thing as `activePanelId`, including its failure mode, which `livePanelIds` already repairs.</span> | [WorkspaceLayoutMixin](../workspacelayoutmixin#property-maximizedpanelid) |
| <span id="property-views">**views**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>views: types.array( pluginManager.pluggableMstType('view', 'sta…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>views: types.array(&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;pluginManager.pluggableMstType('view', 'stateModel'),&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;)</code></pre></dialog></span> |  | [MultipleViewsSessionMixin](../multipleviewssessionmixin#property-views) |
| <span id="property-stickyviewheaders">**stickyViewHeaders**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>stickyViewHeaders: types.optional(types.boolean, () =&gt; localSto…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>stickyViewHeaders: types.optional(types.boolean, () =&gt;&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;localStorageGetBoolean('stickyViewHeaders', true),&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;)</code></pre></dialog></span> |  | [MultipleViewsSessionMixin](../multipleviewssessionmixin#property-stickyviewheaders) |
| <span id="property-useworkspaces">**useWorkspaces**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>useWorkspaces: types.stripDefault( types.maybe(types.boolean),…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>useWorkspaces: types.stripDefault(&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;types.maybe(types.boolean),&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;undefined,&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;)</code></pre></dialog></span> | <span data-pagefind-ignore>enables the tabbed/tiled workspace layout for this session. Undefined means unspecified — read `effectiveUseWorkspaces`.</span> | [MultipleViewsSessionMixin](../multipleviewssessionmixin#property-useworkspaces) |
| <span id="property-drawerposition">**drawerPosition**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>drawerPosition: types.optional( types.string, () =&gt; localStorag…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>drawerPosition: types.optional(&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;types.string,&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;() =&gt; localStorageGetItem('drawerPosition') ?? 'right',&#10;&#160;&#160;&#160;&#160;&#160;&#160;)</code></pre></dialog></span> |  | [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin#property-drawerposition) |
| <span id="property-drawerwidth">**drawerWidth**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>drawerWidth: types.stripDefault( types.refinement(types.integer…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>drawerWidth: types.stripDefault(&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;types.refinement(types.integer, width =&gt; width &gt;= minDrawerWidth),&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;384,&#10;&#160;&#160;&#160;&#160;&#160;&#160;)</code></pre></dialog></span> |  | [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin#property-drawerwidth) |
| <span id="property-widgets">**widgets**</span><br><code>widgets: types.stripDefault(types.map(widgetStateModelType), {})</code> |  | [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin#property-widgets) |
| <span id="property-activewidgets">**activeWidgets**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>activeWidgets: types.stripDefault( types.map(types.safeReferenc…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>activeWidgets: types.stripDefault(&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;types.map(types.safeReference(widgetStateModelType)),&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{},&#10;&#160;&#160;&#160;&#160;&#160;&#160;)</code></pre></dialog></span> |  | [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin#property-activewidgets) |
| <span id="property-minimized">**minimized**</span><br><code>minimized: types.stripDefault(types.boolean, false)</code> |  | [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin#property-minimized) |

## Volatiles

<!-- prettier-ignore -->
| Member | Description | Defined by |
| --- | --- | --- |
| <span id="volatile-sessionthemename">**sessionThemeName**</span><br><code>sessionThemeName: localStorageGetItem('themeName') ?? 'default'</code> |  | [ThemeManagerSessionMixin](../thememanagersessionmixin#volatile-sessionthemename) |
| <span id="volatile-selection">**selection**</span><br><code>selection: undefined as unknown</code> | <span data-pagefind-ignore>this is the globally "selected" object. can be anything. code that wants to deal with this should examine it to see what kind of thing it is.</span> | [BaseSessionModel](../basesessionmodel#volatile-selection) |
| <span id="volatile-hovered">**hovered**</span><br><code>hovered: undefined as unknown</code> | <span data-pagefind-ignore>this is the globally "hovered" object. can be anything. code that wants to deal with this should examine it to see what kind of thing it is.</span> | [BaseSessionModel](../basesessionmodel#volatile-hovered) |
| <span id="volatile-queueofdialogs">**queueOfDialogs**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>queueOfDialogs: [] as [DialogComponentType, Record&lt;string, unkn…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>queueOfDialogs: [] as [DialogComponentType, Record&lt;string, unknown&gt;][]</code></pre></dialog></span> |  | [BaseSessionModel](../basesessionmodel#volatile-queueofdialogs) |
| <span id="volatile-preferencesoverrides">**preferencesOverrides**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>preferencesOverrides: observable.map&lt;string, unknown&gt;(undefined…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>preferencesOverrides: observable.map&lt;string, unknown&gt;(undefined, {&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;deep: false,&#10;&#160;&#160;&#160;&#160;&#160;&#160;})</code></pre></dialog></span> | <span data-pagefind-ignore>runtime user-preference overrides keyed by preference id, resolved by `getPreference` against the `configuration.preferences` admin defaults. Empty here (config-only); products that let users edit preferences load and persist these via localStorage. A runtime override map layered over config defaults, kept off the snapshot since prefs are local UI.<br><br>An `observable.map` (not a plain object reassigned wholesale) so each preference is its own tracked key: writing one (`setScrollZoom`) can't invalidate a reader of another (`getDisplayTypeDefault` in a track's `rpcProps`). A single spread-replaced object made every setter wake every reader, so toggling scroll-to-zoom re-fetched every track. For the same reason each promoted per-display-type default is a flat composite key (see `displayTypeDefaultKey`), not a single nested `displayTypeDefaults` object — promoting one default can't wake readers of a different one.<br><br>`deep: false` is load-bearing, not a micro-optimization. The default enhancer wraps an object/array value in a MobX Proxy on `set`, and a promoted default is handed straight back out by `getConf` — so an object-valued promotable slot (alignments `colorBy`) put a Proxy into `rpcProps()`, and V8's structured-clone serializer rejects a Proxy: `worker.postMessage` threw `DataCloneError` on the next fetch of any track following that default (electron IPC and `structuredClone` in the share bake likewise). The map still notifies per key on `set`, so shallow values lose no reactivity — and nothing can mutate a preference in place, because `setPreferenceOverride` freezes what it stores.</span> | [BaseSessionModel](../basesessionmodel#volatile-preferencesoverrides) |
| <span id="volatile-snackbarmessages">**snackbarMessages**</span><br><code>snackbarMessages: observable.array&lt;SnackbarMessage&gt;()</code> |  | [SnackbarModel](../snackbarmodel#volatile-snackbarmessages) |
| <span id="volatile-errordialog">**errorDialog**</span><br><code>errorDialog: undefined as ErrorDialogState &#124; undefined</code> | <span data-pagefind-ignore>the error currently shown in the stack-trace dialog. Kept off the dialog queue so it can stack on top of an already-open dialog (e.g. the one whose action raised the error) instead of waiting behind it</span> | [SnackbarModel](../snackbarmodel#volatile-errordialog) |
| <span id="volatile-poppedout">**poppedOut**</span><br><code>poppedOut: false</code> | <span data-pagefind-ignore>true while the visible widget is shown in a modal dialog instead of the drawer. Volatile because a restored session that opened straight into a modal, with no drawer behind it, is disorienting</span> | [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin#volatile-poppedout) |

## Getters

<!-- prettier-ignore -->
| Member | Description | Defined by |
| --- | --- | --- |
| <span id="getter-connections">**connections**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(ModelInstanceTypeProps&lt;…&gt; &amp; { setSubschema(slotName: string, d…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(ModelInstanceTypeProps&lt;…&gt; &amp; { setSubschema(slotName: string, data: Record&lt;string, unknown&gt;): any; setSlot(slotName: string, value: unknown): void; } &amp; IStateTreeNode&lt;...&gt;)[]</code></pre></dialog></span> |  | [ConnectionManagementSessionMixin](../connectionmanagementsessionmixin#getter-connections) |
| <span id="getter-themename">**themeName**</span><br><code>string</code> |  | [ThemeManagerSessionMixin](../thememanagersessionmixin#getter-themename) |
| <span id="getter-themeoptions">**themeOptions**</span><br><code>SerializableThemeArgs</code> |  | [ThemeManagerSessionMixin](../thememanagersessionmixin#getter-themeoptions) |
| <span id="getter-palette">**palette**</span><br><code>JBrowsePalette</code> | <span data-pagefind-ignore>Every color JBrowse renders, resolved to plain strings. This is what rendering reads: it needs no React context, it crosses the RPC worker boundary as itself, and it costs no UI toolkit. Prefer it over `theme` anywhere the answer wanted is a color rather than a Material UI component style.</span> | [ThemeManagerSessionMixin](../thememanagersessionmixin#getter-palette) |
| <span id="getter-styletheme">**styleTheme**</span><br><code>JBrowseStyleTheme</code> | <span data-pagefind-ignore>The palette plus the sizing tokens `makeStyles` reads — spacing, corner radius, type scale. This is what a product mounts on `StyleThemeProvider`; it costs no UI toolkit, and it is derived from the same `themeOptions` as `theme`, so a config `theme` that sets `spacing` moves JBrowse's own styles and its Material components together.</span> | [ThemeManagerSessionMixin](../thememanagersessionmixin#getter-styletheme) |
| <span id="getter-theme">**theme**</span><br><code>Theme</code> | <span data-pagefind-ignore>The Material UI theme, for the components that are Material UI. Its palette is spliced from the same `resolvePalette` call as `palette` above, so the two cannot disagree.</span> | [ThemeManagerSessionMixin](../thememanagersessionmixin#getter-theme) |
| <span id="getter-tracks">**tracks**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(ModelInstanceTypeProps&lt;…&gt; &amp; { setSubschema(slotName: string, d…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(ModelInstanceTypeProps&lt;…&gt; &amp; { setSubschema(slotName: string, data: Record&lt;string, unknown&gt;): any; setSlot(slotName: string, value: unknown): void; } &amp; IStateTreeNode&lt;...&gt;)[]</code></pre></dialog></span> |  | [TracksManagerSessionMixin](../tracksmanagersessionmixin#getter-tracks) |
| <span id="getter-root">**root**</span><br><code>TypeOrStateTreeNodeToStateTreeNode&lt;ROOT_MODEL_TYPE&gt;</code> |  | [BaseSessionModel](../basesessionmodel#getter-root) |
| <span id="getter-jbrowse">**jbrowse**</span><br><code>any</code> |  | [BaseSessionModel](../basesessionmodel#getter-jbrowse) |
| <span id="getter-rpcmanager">**rpcManager**</span><br><code>RpcManager</code> |  | [BaseSessionModel](../basesessionmodel#getter-rpcmanager) |
| <span id="getter-configuration">**configuration**</span><br><code>Instance&lt;JB_CONFIG_SCHEMA&gt;</code> |  | [BaseSessionModel](../basesessionmodel#getter-configuration) |
| <span id="getter-adminmode">**adminMode**</span><br><code>boolean</code> |  | [BaseSessionModel](../basesessionmodel#getter-adminmode) |
| <span id="getter-textsearchmanager">**textSearchManager**</span><br><code>TextSearchManager</code> |  | [BaseSessionModel](../basesessionmodel#getter-textsearchmanager) |
| <span id="getter-assemblies">**assemblies**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(ModelInstanceTypeProps&lt;…&gt; &amp; { setSubschema(slotName: string, d…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(ModelInstanceTypeProps&lt;…&gt; &amp; { setSubschema(slotName: string, data: Record&lt;string, unknown&gt;): any; setSlot(slotName: string, value: unknown): void; } &amp; IStateTreeNode&lt;...&gt;)[]</code></pre></dialog></span> |  | [BaseSessionModel](../basesessionmodel#getter-assemblies) |
| <span id="getter-dialogcomponent">**DialogComponent**</span><br><code>DialogComponentType</code> |  | [BaseSessionModel](../basesessionmodel#getter-dialogcomponent) |
| <span id="getter-dialogprops">**DialogProps**</span><br><code>Record&lt;string, unknown&gt;</code> |  | [BaseSessionModel](../basesessionmodel#getter-dialogprops) |
| <span id="getter-animationmode">**animationMode**</span><br><code>AnimationMode</code> | <span data-pagefind-ignore>resolved feature-layout animation mode (never undefined)</span> | [BaseSessionModel](../basesessionmodel#getter-animationmode) |
| <span id="getter-scrollzoom">**scrollZoom**</span><br><code>boolean</code> | <span data-pagefind-ignore>resolved scroll-to-zoom preference. Global and personal (never shared in a session snapshot); every wheel-zoom view reads this single value.</span> | [BaseSessionModel](../basesessionmodel#getter-scrollzoom) |
| <span id="getter-numbergrouping">**numberGrouping**</span><br><code>boolean</code> | <span data-pagefind-ignore>resolved thousand-separator preference. Read for display in the Preferences dialog; the formatter itself reads a plain module variable set at startup in each realm (see `setNumberGrouping`), because worker- built strings can't see a main-thread observable.</span> | [BaseSessionModel](../basesessionmodel#getter-numbergrouping) |
| <span id="getter-snackbarmessageset">**snackbarMessageSet**</span><br><code>Map&lt;string, SnackbarMessage&gt;</code> |  | [SnackbarModel](../snackbarmodel#getter-snackbarmessageset) |
| <span id="getter-assemblynames">**assemblyNames**</span><br><code>string[]</code> | <span data-pagefind-ignore>names of the assemblies returned by the `assemblies` getter</span> | [AssembliesMixin](../assembliesmixin#getter-assemblynames) |
| <span id="getter-version">**version**</span><br><code>string</code> |  | [AppSessionMixin](../appsessionmixin#getter-version) |
| <span id="getter-gitcommit">**gitCommit**</span><br><code>string &#124; undefined</code> |  | [AppSessionMixin](../appsessionmixin#getter-gitcommit) |
| <span id="getter-history">**history**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>{ canUndo: boolean; canRedo: boolean; undo(): void; redo(): voi…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>{ canUndo: boolean; canRedo: boolean; undo(): void; redo(): void; } &#124; undefined</code></pre></dialog></span> |  | [AppSessionMixin](../appsessionmixin#getter-history) |
| <span id="getter-assemblymanager">**assemblyManager**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>ModelInstanceTypeProps&lt;…&gt; &amp; {…} &amp; {…} &amp; {…} &amp; {…} &amp; {…} &amp; {…} &amp;…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>ModelInstanceTypeProps&lt;…&gt; &amp; {…} &amp; {…} &amp; {…} &amp; {…} &amp; {…} &amp; {…} &amp; IStateTreeNode&lt;…&gt;</code></pre></dialog></span> |  | [AppSessionMixin](../appsessionmixin#getter-assemblymanager) |
| <span id="getter-tree">**tree**</span><br><code>LayoutTree</code> | <span data-pagefind-ignore>The plain tree the pure functions take.<br><br>`getSnapshot` is a `keepAlive` computed, so this is cached and referentially stable — which also lets MST's reconcile short-circuit on identity when `apply` writes an untouched subtree back.<br><br>Uncast on purpose: the models below and the interfaces in `tree.ts` are two spellings of one shape, and this assignment is the only thing that checks they agree.</span> | [WorkspaceLayoutMixin](../workspacelayoutmixin#getter-tree) |
| <span id="getter-panels">**panels**</span><br><code>PanelNode[]</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#getter-panels) |
| <span id="getter-tabs">**tabs**</span><br><code>TabNode[]</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#getter-tabs) |
| <span id="getter-visibletree">**visibleTree**</span><br><code>LayoutTree</code> | <span data-pagefind-ignore>What to render: the maximized cell alone, or the whole tree.<br><br>Sized to 1 rather than handed over as it sits. A pane's `size` is its share of its siblings, and CSS distributes free space by grow factor only up to a total of 1 — so a cell that was a third of a row, alone in the workspace with `flexGrow: 0.33`, draws a third of the window and leaves the rest blank.</span> | [WorkspaceLayoutMixin](../workspacelayoutmixin#getter-visibletree) |
| <span id="getter-effectiveuseworkspaces">**effectiveUseWorkspaces**</span><br><code>boolean</code> | <span data-pagefind-ignore>resolved workspaces flag (never undefined): this session's value, else the user preference over the `configuration.preferences.useWorkspaces` admin default. Every consumer reads this, not the raw property — only sessions built from a snapshot or a spec `layout` set that, so the admin default is what reaches the arrivals that bypass defaultSession.</span> | [MultipleViewsSessionMixin](../multipleviewssessionmixin#getter-effectiveuseworkspaces) |
| <span id="getter-defaultuseworkspaces">**defaultUseWorkspaces**</span><br><code>boolean</code> | <span data-pagefind-ignore>what `effectiveUseWorkspaces` becomes after `resetUseWorkspaces` — the admin default, with both this session's own value and the user's override out of the way. The Preferences reset diff needs this rather than the override map, which can't see a session-scoped value (a spec `layout`, a "move view to a tab") and so reported nothing to reset.</span> | [MultipleViewsSessionMixin](../multipleviewssessionmixin#getter-defaultuseworkspaces) |
| <span id="getter-visiblewidget">**visibleWidget**</span><br><code>Widget &#124; undefined</code> |  | [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin#getter-visiblewidget) |

## Methods

<!-- prettier-ignore -->
| Member | Description | Defined by |
| --- | --- | --- |
| <span id="method-getreferringmultiple">**getReferringMultiple**</span><br><code>(trackIds: string[]) =&gt; Map&lt;string, ReferringNode[]&gt;</code> | <span data-pagefind-ignore>Walk the tree once and map each requested trackId to the nodes holding a `types.reference` that resolves to it (a view's track entry, a config editor widget). Track configs are matched by trackId, not identity, so a frozen base and its hydrated MST node compare equal.</span> | [ReferenceManagementSessionMixin](../referencemanagementsessionmixin#method-getreferringmultiple) |
| <span id="method-getreferring">**getReferring**</span><br><code>(trackId: string) =&gt; ReferringNode[]</code> | <span data-pagefind-ignore>The nodes currently referring to `trackId` (see getReferringMultiple).</span> | [ReferenceManagementSessionMixin](../referencemanagementsessionmixin#method-getreferring) |
| <span id="method-allthemes">**allThemes**</span><br><code>() =&gt; ThemeMap</code> |  | [ThemeManagerSessionMixin](../thememanagersessionmixin#method-allthemes) |
| <span id="method-getactivethemeoptions">**getActiveThemeOptions**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(name?: string &#124; undefined) =&gt; ThemeOptions &amp; { name?: string &#124;…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(name?: string &#124; undefined) =&gt; ThemeOptions &amp; { name?: string &#124; undefined; }</code></pre></dialog></span> | <span data-pagefind-ignore>Raw `ThemeOptions` for the active theme, or a named override (used by the SVG-export theme picker). Unlike `theme` (a built, non-serializable MUI theme), this is the plain options object every view's SVG export threads into each display's `renderSvg`, which rebuilds the theme via `createJBrowseTheme` outside React context.<br><br>The `default` entry is spliced with the config `theme` slot, because the preset is only half of what that entry means — the picker calls it "Default (from config)" and `resolvePalette` merges the two for every other consumer. Returning the bare preset made `view.exportSvg()` silently drop a host's configured palette: a config setting `primary.main` drew `#123456` on screen and exported the stock `#0D233F`, with the export dialog reporting the theme it had not used. Every other named theme is a fixed preset that ignores config, which is the distinction this ternary keeps.</span> | [ThemeManagerSessionMixin](../thememanagersessionmixin#method-getactivethemeoptions) |
| <span id="method-gettrackbyid">**getTrackById**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(id: string) =&gt; (ModelInstanceTypeProps&lt;…&gt; &amp; {…} &amp; IStateTreeNo…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(id: string) =&gt; (ModelInstanceTypeProps&lt;…&gt; &amp; {…} &amp; IStateTreeNode&lt;…&gt;) &#124; undefined</code></pre></dialog></span> | <span data-pagefind-ignore>Config for one trackId — a track, assembly sequence, or connection track — or undefined. Per-id reactive: every display resolves its config through this (via TrackConfigurationReference) and subscribes only to its own id, so one track's settings edit doesn't re-render the others.</span> | [TracksManagerSessionMixin](../tracksmanagersessionmixin#method-gettrackbyid) |
| <span id="method-gettracksbyid">**getTracksById**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>() =&gt; Record&lt;string, ModelInstanceTypeProps&lt;…&gt; &amp; { setSubschema…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>() =&gt; Record&lt;string, ModelInstanceTypeProps&lt;…&gt; &amp; { setSubschema(slotName: string, data: Record&lt;…&gt;): any; setSlot(slotName: string, value: unknown): void; } &amp; IStateTreeNode&lt;...&gt;&gt;</code></pre></dialog></span> | <span data-pagefind-ignore>Every track config the session can resolve, keyed by trackId. Prefer the per-id reactive `getTrackById(id)`: reading this whole map subscribes the caller to *every* track, so an edit to any one of them wakes it — the reason internal display config resolution moved off it. Kept for plugins that look up ids in a non-reactive context.</span> | [TracksManagerSessionMixin](../tracksmanagersessionmixin#method-gettracksbyid) |
| <span id="method-getpreferencedefault">**getPreferenceDefault**</span><br><code>(key: string) =&gt; unknown</code> | <span data-pagefind-ignore>the admin/embedder `configuration.preferences` value for a key, ignoring any runtime override — i.e. what a reset falls back to. Exposed rather than inlined because "differs from the default" is a question the Preferences reset diff asks about settings this map doesn't hold (see `defaultUseWorkspaces`).</span> | [BaseSessionModel](../basesessionmodel#method-getpreferencedefault) |
| <span id="method-getpreference">**getPreference**</span><br><code>(key: string) =&gt; unknown</code> | <span data-pagefind-ignore>resolved value of a user preference: a runtime override if the user set one, otherwise the admin/embedder `configuration.preferences` default. The override map is empty unless the product loads it (web/desktop).</span> | [BaseSessionModel](../basesessionmodel#method-getpreference) |
| <span id="method-getdisplaytypedefault">**getDisplayTypeDefault**</span><br><code>(displayType: string, slot: string) =&gt; unknown</code> | <span data-pagefind-ignore>resolved value of a per-display-type slot default the user promoted (see `setDisplayTypeDefault`); undefined when nothing was promoted.</span> | [BaseSessionModel](../basesessionmodel#method-getdisplaytypedefault) |
| <span id="method-getdisplaytypedefaults">**getDisplayTypeDefaults**</span><br><code>() =&gt; { displayType: string; slot: string; value: unknown; }[]</code> | <span data-pagefind-ignore>every per-display-type default the user has promoted, as `{ displayType, slot, value }` — the inventory the Preferences dialog lists and clears one at a time (`setDisplayTypeDefault(…, undefined)`).<br><br>Here rather than filtered out of `getPreferenceChanges` by the dialog, because the composite-key layout is this file's: a consumer that recognized these rows by matching the path head is exactly the coupling `DISPLAY_TYPE_DEFAULTS_PATH_HEAD` stopped being exported over, where a rename on one side alone silently no-ops the other.</span> | [BaseSessionModel](../basesessionmodel#method-getdisplaytypedefaults) |
| <span id="method-getpreferencechanges">**getPreferenceChanges**</span><br><code>() =&gt; TrackConfigChange[]</code> | <span data-pagefind-ignore>every runtime preference-override that currently differs from its config/admin default, as `{ path, from, to }` rows — the exact set `clearPreferenceOverrides` reverts. Backs the confirmation diff shown before "Reset to defaults" (mirrors the per-track changes dialog). A scalar pref (animationMode, scrollZoom) whose override equals the default is omitted (reverting it is a no-op); each promoted per-display-type default is always a difference from the un-promoted state, so `from` reads "(default)".</span> | [BaseSessionModel](../basesessionmodel#method-getpreferencechanges) |
| <span id="method-findassemblyconf">**findAssemblyConf**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(name: unknown) =&gt; (ModelInstanceTypeProps&lt;…&gt; &amp; {…} &amp; IStateTre…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(name: unknown) =&gt; (ModelInstanceTypeProps&lt;…&gt; &amp; {…} &amp; IStateTreeNode&lt;…&gt;) &#124; undefined</code></pre></dialog></span> | <span data-pagefind-ignore>The assembly config already carrying `name`, from any of the three arrays the assemblyManager draws on, or undefined.<br><br>One namespace, because `name` is the assembly config's MST identifier: a second config carrying a name one of the others already has doesn't fail at the add, it makes every `assembly.configuration` safeReference in the manager ambiguous, and MST then throws on every read of one — inside the manager's own autorun and inside `assemblyNameMap`, which takes the session down. So each add path checks all three, not just the array it pushes to.</span> | [AssembliesMixin](../assembliesmixin#method-findassemblyconf) |
| <span id="method-menus">**menus**</span><br><code>() =&gt; Menu[]</code> |  | [AppSessionMixin](../appsessionmixin#method-menus) |
| <span id="method-gettrackactions">**getTrackActions**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(trackConfig: ModelInstanceTypeProps&lt;…&gt; &amp; {…} &amp; IStateTreeNode&lt;…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(trackConfig: ModelInstanceTypeProps&lt;…&gt; &amp; {…} &amp; IStateTreeNode&lt;…&gt;, view?: TrackActionView &#124; undefined) =&gt; MenuItem[]</code></pre></dialog></span> | <span data-pagefind-ignore>raw track actions (Settings, Copy, Delete, Index) without submenu wrapper</span> | [DesktopSessionTrackMenuMixin](../desktopsessiontrackmenumixin#method-gettrackactions) |
| <span id="method-gettracklistmenuitems">**getTrackListMenuItems**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(config: ModelInstanceTypeProps&lt;…&gt; &amp; {…} &amp; IStateTreeNode&lt;…&gt;, v…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(config: ModelInstanceTypeProps&lt;…&gt; &amp; {…} &amp; IStateTreeNode&lt;…&gt;, view?: TrackActionView &#124; undefined) =&gt; MenuItem[]</code></pre></dialog></span> | <span data-pagefind-ignore>flattened menu items for use in hierarchical track selector</span> | [TrackMenuItemsSessionMixin](../trackmenuitemssessionmixin#method-gettracklistmenuitems) |
| <span id="method-gettrackactionmenuitems">**getTrackActionMenuItems**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>({…}: { config: ModelInstanceTypeProps&lt;…&gt; &amp; {…} &amp; IStateTreeNod…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>({…}: { config: ModelInstanceTypeProps&lt;…&gt; &amp; {…} &amp; IStateTreeNode&lt;…&gt;; view?: TrackActionView &#124; undefined; }) =&gt; MenuItem[]</code></pre></dialog></span> | <span data-pagefind-ignore>track menu with About + "Track actions" submenu for the in-view label</span> | [TrackMenuItemsSessionMixin](../trackmenuitemssessionmixin#method-gettrackactionmenuitems) |
| <span id="method-haspanel">**hasPanel**</span><br><code>(panelId: string) =&gt; boolean</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#method-haspanel) |
| <span id="method-findtab">**findTab**</span><br><code>(tabId: string) =&gt; TabHome &#124; undefined</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#method-findtab) |
| <span id="method-tabcontainingview">**tabContainingView**</span><br><code>(viewId: string) =&gt; TabHome &#124; undefined</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#method-tabcontainingview) |
| <span id="method-panelcontainingview">**panelContainingView**</span><br><code>(viewId: string) =&gt; PanelNode &#124; undefined</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#method-panelcontainingview) |
| <span id="method-viewidsfortab">**viewIdsForTab**</span><br><code>(tabId: string, order: string[]) =&gt; string[]</code> | <span data-pagefind-ignore>The views a tab renders: its members, in `session.views` order.</span> | [WorkspaceLayoutMixin](../workspacelayoutmixin#method-viewidsfortab) |
| <span id="method-activetabof">**activeTabOf**</span><br><code>(panelId: string) =&gt; TabNode &#124; undefined</code> | <span data-pagefind-ignore>The tab a panel is showing, or its first.</span> | [WorkspaceLayoutMixin](../workspacelayoutmixin#method-activetabof) |

## Actions

<!-- prettier-ignore -->
| Member | Description | Defined by |
| --- | --- | --- |
| <span id="action-dereferencetrack">**dereferenceTrack**</span><br><code>(trackId: string, referring: ReferringNode[]) =&gt; void</code> | <span data-pagefind-ignore>Remove `trackId` from every view referring to it and close any config editor widget open on it. Runs immediately: the walk that produced `referring` has finished, so mutating those views here is safe.</span> | [ReferenceManagementSessionMixin](../referencemanagementsessionmixin#action-dereferencetrack) |
| <span id="action-makeconnection">**makeConnection**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(configuration: ModelInstanceTypeProps&lt;…&gt; &amp; {…} &amp; IStateTreeNod…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(configuration: ModelInstanceTypeProps&lt;…&gt; &amp; {…} &amp; IStateTreeNode&lt;…&gt;, initialSnapshot?: object) =&gt; any</code></pre></dialog></span> |  | [ConnectionManagementSessionMixin](../connectionmanagementsessionmixin#action-makeconnection) |
| <span id="action-breakconnection">**breakConnection**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(configuration: ModelInstanceTypeProps&lt;…&gt; &amp; { setSubschema(slot…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(configuration: ModelInstanceTypeProps&lt;…&gt; &amp; { setSubschema(slotName: string, data: Record&lt;…&gt;): any; setSlot(slotName: string, value: unknown): void; } &amp; IStateTreeNode&lt;…&gt;) =&gt; void</code></pre></dialog></span> | <span data-pagefind-ignore>Remove a live connection instance. Tolerant of an already-dormant connection (its instance is stripped from the session on reload). Leaves persisted open-track configs alone — the connect() error path calls this and the user's already-open tracks must survive a transient failure. Full removal goes through `deleteConnection`.</span> | [ConnectionManagementSessionMixin](../connectionmanagementsessionmixin#action-breakconnection) |
| <span id="action-teardownconnection">**teardownConnection**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(configuration: ModelInstanceTypeProps&lt;…&gt; &amp; { setSubschema(slot…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(configuration: ModelInstanceTypeProps&lt;…&gt; &amp; { setSubschema(slotName: string, data: Record&lt;…&gt;): any; setSlot(slotName: string, value: unknown): void; } &amp; IStateTreeNode&lt;…&gt;) =&gt; void</code></pre></dialog></span> | <span data-pagefind-ignore>Close every track a connection contributed — the live instance's tracks plus any persisted open-track configs (a dormant connection, never expanded this session, still renders its opened tracks from `connectionTrackConfigs`) — from all views/widgets, drop the live instance, and drop the persisted configs. The session is left as if the connection had never loaded.</span> | [ConnectionManagementSessionMixin](../connectionmanagementsessionmixin#action-teardownconnection) |
| <span id="action-deleteconnection">**deleteConnection**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(configuration: ModelInstanceTypeProps&lt;…&gt; &amp; { setSubschema(slot…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(configuration: ModelInstanceTypeProps&lt;…&gt; &amp; { setSubschema(slotName: string, data: Record&lt;…&gt;): any; setSlot(slotName: string, value: unknown): void; } &amp; IStateTreeNode&lt;...&gt;) =&gt; any</code></pre></dialog></span> | <span data-pagefind-ignore>Fully remove a connection: tear down its tracks and live instance, then delete its config.</span> | [ConnectionManagementSessionMixin](../connectionmanagementsessionmixin#action-deleteconnection) |
| <span id="action-addconnectionconf">**addConnectionConf**</span><br><code>(connectionConf: AnyConfiguration) =&gt; any</code> | <span data-pagefind-ignore>Adds to the **config**, not the session: `jbrowse.connections`, which every visitor to this instance loads. jbrowse-web overrides this so a non-admin's connection lands in `sessionConnections` instead — see WebSessionConnectionsMixin, whose `addSessionConnectionConf` is what to call when you mean the session specifically rather than "wherever this user's edits go".<br><br>Applications without that override (Desktop, the embedded products) have only this one destination, and it is the right one there: their config and session are saved as a single document.</span> | [ConnectionManagementSessionMixin](../connectionmanagementsessionmixin#action-addconnectionconf) |
| <span id="action-clearconnections">**clearConnections**</span><br><code>() =&gt; void</code> |  | [ConnectionManagementSessionMixin](../connectionmanagementsessionmixin#action-clearconnections) |
| <span id="action-captureconnectiontrack">**captureConnectionTrack**</span><br><code>(trackId: string) =&gt; void</code> | <span data-pagefind-ignore>Snapshot a just-opened connection track's config into `connectionTrackConfigs` so it survives session reload. No-op if the track isn't connection-provided or is already captured (edits go through `updateConnectionTrackConfig`).</span> | [ConnectionManagementSessionMixin](../connectionmanagementsessionmixin#action-captureconnectiontrack) |
| <span id="action-updateconnectiontrackconfig">**updateConnectionTrackConfig**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(trackConf: Record&lt;string, unknown&gt; &amp; { trackId: string; }) =&gt;…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(trackConf: Record&lt;string, unknown&gt; &amp; { trackId: string; }) =&gt; void</code></pre></dialog></span> | <span data-pagefind-ignore>Persist an edit to an opened connection track. The full config is stored (not a delta): the connection's fetched "base" isn't present at load, so only a complete config resolves synchronously.</span> | [ConnectionManagementSessionMixin](../connectionmanagementsessionmixin#action-updateconnectiontrackconfig) |
| <span id="action-setconnectiontrackconfig">**setConnectionTrackConfig**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(trackId: string, connectionId: string, config: Record&lt;string,…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(trackId: string, connectionId: string, config: Record&lt;string, unknown&gt;) =&gt; void</code></pre></dialog></span> | <span data-pagefind-ignore>Upsert one opened connection track's persisted config.</span> | [ConnectionManagementSessionMixin](../connectionmanagementsessionmixin#action-setconnectiontrackconfig) |
| <span id="action-pruneconnectiontrackconfig">**pruneConnectionTrackConfig**</span><br><code>(trackId: string) =&gt; void</code> | <span data-pagefind-ignore>Drop a connection track's persisted config once no open view still references it, so the session doesn't accumulate closed tracks.</span> | [ConnectionManagementSessionMixin](../connectionmanagementsessionmixin#action-pruneconnectiontrackconfig) |
| <span id="action-hydrateconnection">**hydrateConnection**</span><br><code>(connectionId: string) =&gt; void</code> | <span data-pagefind-ignore>Lazily establish a single connection by id if it isn't already live — used when its category is expanded in the track selector. Fetches silently (no view launch / success snackbar); already-open tracks keep rendering from `connectionTrackConfigs` meanwhile. Idempotent.</span> | [ConnectionManagementSessionMixin](../connectionmanagementsessionmixin#action-hydrateconnection) |
| <span id="action-setthemename">**setThemeName**</span><br><code>(name: string) =&gt; void</code> |  | [ThemeManagerSessionMixin](../thememanagersessionmixin#action-setthemename) |
| <span id="action-setthememode">**setThemeMode**</span><br><code>(mode: "dark" &#124; "light") =&gt; void</code> | <span data-pagefind-ignore>Point the session at light or dark, for a host that follows its own dark-mode state rather than offering JBrowse's theme menu. Satisfies `ThemeModeSession`, so `useSessionPalette` works against an app session and an embedded one alike.<br><br>Expressed as a write to the config `theme` slot plus a return to the `default` theme, not as `setThemeName('darkStock')`. Only the `default` theme merges `configTheme.palette` (see `resolvePalette`), so selecting a stock theme would discard whatever the host passed as `configuration.theme` — their brand `primary`, say — the first time their toggle fired. Merging at both levels for the same reason: `theme` is a frozen slot, and `mode` and `primary` are siblings under `palette`.<br><br>One write, not two: `themeOptions` is derived from the same slot and is what ships to the RPC worker, so the labels baked into a rendered image follow the mode along with what React draws.</span> | [ThemeManagerSessionMixin](../thememanagersessionmixin#action-setthememode) |
| <span id="action-addsessiontrackconf">**addSessionTrackConf**</span><br><code>(trackConf: AnyConfiguration) =&gt; any</code> | <span data-pagefind-ignore>Add a track config to *this session*.<br><br>This mixin's session has no separate session-track store, so the destination is the jbrowse config — which in the products that compose it (desktop) is the single user's own file rather than something a server hands other visitors, so the two scopes are the same place. Defined here anyway so that every session has it: a feature standing a track up on the user's behalf can then call one action everywhere instead of asking which mixin it landed on. `SessionTracksManagerSessionMixin` overrides it with the real session-scoped store.</span> | [TracksManagerSessionMixin](../tracksmanagersessionmixin#action-addsessiontrackconf) |
| <span id="action-publishtrackconf">**publishTrackConf**</span><br><code>(trackConf: AnyConfiguration) =&gt; any</code> | <span data-pagefind-ignore>Add a track config wherever *this user's* catalog edits belong — the "Add track" workflows, where an admin adding a track means to add it for the whole site. `SessionTracksManagerSessionMixin` overrides it to send a non-admin's to the session instead; here there is only the one destination.<br><br>Anything that is not an Add-track workflow wants `addSessionTrackConf`: a track a feature stands up on the user's behalf — a search result, a computed consensus, a reconstruction's labels — is not a catalog entry, and publishing one writes it into the config.json every visitor is served, once per click.</span> | [TracksManagerSessionMixin](../tracksmanagersessionmixin#action-publishtrackconf) |
| <span id="action-addtrackconf">**addTrackConf**</span><br><code>(trackConf: AnyConfiguration) =&gt; any</code> | <span data-pagefind-ignore>Deprecated alias of `addSessionTrackConf`. Call that, or `publishTrackConf`, which say which destination they mean.</span> | [TracksManagerSessionMixin](../tracksmanagersessionmixin#action-addtrackconf) |
| <span id="action-updatetrackconfiguration">**updateTrackConfiguration**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(trackConf: { [key: string]: unknown; trackId: string; }) =&gt; vo…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(trackConf: { [key: string]: unknown; trackId: string; }) =&gt; void</code></pre></dialog></span> | <span data-pagefind-ignore>Persist edited track config back to the in-memory jbrowse config. The session-tracks mixin overrides this so a non-admin's edits become a shareable session-track override instead.</span> | [TracksManagerSessionMixin](../tracksmanagersessionmixin#action-updatetrackconfiguration) |
| <span id="action-deletetrackconf">**deleteTrackConf**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(trackConf: ModelInstanceTypeProps&lt;…&gt; &amp; { setSubschema(slotName…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(trackConf: ModelInstanceTypeProps&lt;…&gt; &amp; { setSubschema(slotName: string, data: Record&lt;…&gt;): any; setSlot(slotName: string, value: unknown): void; } &amp; IStateTreeNode&lt;...&gt;) =&gt; any</code></pre></dialog></span> |  | [TracksManagerSessionMixin](../tracksmanagersessionmixin#action-deletetrackconf) |
| <span id="action-setselection">**setSelection**</span><br><code>(thing: unknown) =&gt; void</code> | <span data-pagefind-ignore>set the global selection, i.e. the globally-selected object. can be a feature, a view, just about anything<br><br>A feature is unwrapped on the way in, so app state never holds a jexlFeatureProxy. `isFeature` accepts a proxy, but on one `id` is a data field rather than the method the Feature type promises — every consumer doing `isFeature(selection) ? selection.id() : …` would throw.</span> | [BaseSessionModel](../basesessionmodel#action-setselection) |
| <span id="action-clearselection">**clearSelection**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>clears the global selection</span> | [BaseSessionModel](../basesessionmodel#action-clearselection) |
| <span id="action-sethovered">**setHovered**</span><br><code>(thing: unknown) =&gt; void</code> |  | [BaseSessionModel](../basesessionmodel#action-sethovered) |
| <span id="action-sethighlightsvisible">**setHighlightsVisible**</span><br><code>(arg: boolean) =&gt; void</code> | <span data-pagefind-ignore>toggle all region highlight bands across every view</span> | [BaseSessionModel](../basesessionmodel#action-sethighlightsvisible) |
| <span id="action-revealhighlights">**revealHighlights**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>turn highlight bands back on, so a newly made highlight or bookmark is never silently swallowed by an earlier "highlights off"</span> | [BaseSessionModel](../basesessionmodel#action-revealhighlights) |
| <span id="action-setpreferenceoverride">**setPreferenceOverride**</span><br><code>(key: string, value: unknown) =&gt; void</code> | <span data-pagefind-ignore>set a runtime user-preference override (see `getPreference`). Mutates volatile state; products persist these to localStorage. An `undefined` value deletes the key (rather than leaving a phantom entry that `getPreference` reads as absent) so the store never holds dead keys.</span> | [BaseSessionModel](../basesessionmodel#action-setpreferenceoverride) |
| <span id="action-clearpreferenceoverrides">**clearPreferenceOverrides**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>clear every runtime preference override at once — scrollZoom, animationMode, and every promoted per-display-type default (see `setDisplayTypeDefault`) — so each falls back to its config/admin default. Backs the Preferences dialog "Reset to defaults" button.</span> | [BaseSessionModel](../basesessionmodel#action-clearpreferenceoverrides) |
| <span id="action-clearpreferenceoverride">**clearPreferenceOverride**</span><br><code>(key: string) =&gt; void</code> | <span data-pagefind-ignore>clear a single runtime preference override (see `getPreference`) so it falls back to its config/admin default. Backs the per-entry reset in the Preferences dialog "Reset to defaults" confirmation.</span> | [BaseSessionModel](../basesessionmodel#action-clearpreferenceoverride) |
| <span id="action-resetpreferencechange">**resetPreferenceChange**</span><br><code>(path: string[]) =&gt; void</code> | <span data-pagefind-ignore>revert one row emitted by `getPreferenceChanges`, addressed by its display `path`. Backs the per-entry reset in the Preferences dialog's "Reset to defaults" confirmation.<br><br>Lives here rather than in that dialog because this model owns both path shapes it has to undo: a promoted per-display-type default, whose row path is a readable label over a flat composite storage key, and every other override, whose path *is* its key. The dialog used to re-derive the first case from an exported path-head constant.</span> | [BaseSessionModel](../basesessionmodel#action-resetpreferencechange) |
| <span id="action-setscrollzoom">**setScrollZoom**</span><br><code>(flag: boolean) =&gt; void</code> | <span data-pagefind-ignore>set the global scroll-to-zoom preference (see the `scrollZoom` getter)</span> | [BaseSessionModel](../basesessionmodel#action-setscrollzoom) |
| <span id="action-setdisplaytypedefault">**setDisplayTypeDefault**</span><br><code>(displayType: string, slot: string, value: unknown) =&gt; void</code> | <span data-pagefind-ignore>promote (or, with `value` undefined, clear) a per-display-type slot default. Just a preference override under one flat composite key (see `displayTypeDefaultKey`), so it persists and independently tracks like any other pref, and clearing deletes only that key.</span> | [BaseSessionModel](../basesessionmodel#action-setdisplaytypedefault) |
| <span id="action-setname">**setName**</span><br><code>(str: string) =&gt; void</code> |  | [BaseSessionModel](../basesessionmodel#action-setname) |
| <span id="action-setfocusedviewid">**setFocusedViewId**</span><br><code>(viewId: string &#124; undefined) =&gt; void</code> | <span data-pagefind-ignore>`undefined` is "no view is focused", which the property has always been able to hold (`types.maybe`) and this had no way to spell. Nothing cleared it on teardown as a result: a view that was focused when it left the session left its id behind, and since every consumer compares `focusedViewId === view.id`, the id matched nothing, the focus ring vanished with nothing to say why, and the dead id persisted into a saved or shared session. `takeOut` clears it now.</span> | [BaseSessionModel](../basesessionmodel#action-setfocusedviewid) |
| <span id="action-removeactivedialog">**removeActiveDialog**</span><br><code>() =&gt; void</code> |  | [BaseSessionModel](../basesessionmodel#action-removeactivedialog) |
| <span id="action-queuedialog">**queueDialog**</span><br><code>(doneCallback: DoneCallback) =&gt; void</code> |  | [BaseSessionModel](../basesessionmodel#action-queuedialog) |
| <span id="action-notify">**notify**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(message: string, level?: NotificationLevel &#124; undefined, action…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(message: string, level?: NotificationLevel &#124; undefined, action?: SnackAction &#124; SnackAction[] &#124; undefined) =&gt; void</code></pre></dialog></span> |  | [SnackbarModel](../snackbarmodel#action-notify) |
| <span id="action-notifyerror">**notifyError**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(errorMessage: string, error?: unknown, extra?: unknown, action…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(errorMessage: string, error?: unknown, extra?: unknown, action?: SnackAction &#124; undefined) =&gt; void</code></pre></dialog></span> |  | [SnackbarModel](../snackbarmodel#action-notifyerror) |
| <span id="action-seterrordialog">**setErrorDialog**</span><br><code>(state: ErrorDialogState &#124; undefined) =&gt; void</code> |  | [SnackbarModel](../snackbarmodel#action-seterrordialog) |
| <span id="action-pushsnackbarmessage">**pushSnackbarMessage**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(message: string, level?: NotificationLevel &#124; undefined, action…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(message: string, level?: NotificationLevel &#124; undefined, actions?: SnackAction[] &#124; undefined) =&gt; void</code></pre></dialog></span> |  | [SnackbarModel](../snackbarmodel#action-pushsnackbarmessage) |
| <span id="action-popsnackbarmessage">**popSnackbarMessage**</span><br><code>() =&gt; SnackbarMessage &#124; undefined</code> |  | [SnackbarModel](../snackbarmodel#action-popsnackbarmessage) |
| <span id="action-removesnackbarmessage">**removeSnackbarMessage**</span><br><code>(message: string) =&gt; void</code> |  | [SnackbarModel](../snackbarmodel#action-removesnackbarmessage) |
| <span id="action-addsessionassembly">**addSessionAssembly**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(conf: AnyConfiguration) =&gt; ModelInstanceTypeProps&lt;…&gt; &amp; {…} &amp; I…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(conf: AnyConfiguration) =&gt; ModelInstanceTypeProps&lt;…&gt; &amp; {…} &amp; IStateTreeNode&lt;…&gt;</code></pre></dialog></span> |  | [AssembliesMixin](../assembliesmixin#action-addsessionassembly) |
| <span id="action-addassembly">**addAssembly**</span><br><code>(conf: AnyConfiguration) =&gt; void</code> |  | [AssembliesMixin](../assembliesmixin#action-addassembly) |
| <span id="action-removeassembly">**removeAssembly**</span><br><code>(name: string) =&gt; void</code> |  | [AssembliesMixin](../assembliesmixin#action-removeassembly) |
| <span id="action-removesessionassembly">**removeSessionAssembly**</span><br><code>(assemblyName: string) =&gt; void</code> |  | [AssembliesMixin](../assembliesmixin#action-removesessionassembly) |
| <span id="action-addtemporaryassembly">**addTemporaryAssembly**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(conf: AnyConfiguration) =&gt; ModelInstanceTypeProps&lt;…&gt; &amp; {…} &amp; I…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(conf: AnyConfiguration) =&gt; ModelInstanceTypeProps&lt;…&gt; &amp; {…} &amp; IStateTreeNode&lt;…&gt;</code></pre></dialog></span> | <span data-pagefind-ignore>used for read vs ref type assemblies.</span> | [AssembliesMixin](../assembliesmixin#action-addtemporaryassembly) |
| <span id="action-removetemporaryassembly">**removeTemporaryAssembly**</span><br><code>(name: string) =&gt; void</code> |  | [AssembliesMixin](../assembliesmixin#action-removetemporaryassembly) |
| <span id="action-renamecurrentsession">**renameCurrentSession**</span><br><code>(sessionName: string) =&gt; void</code> |  | [AppSessionMixin](../appsessionmixin#action-renamecurrentsession) |
| <span id="action-setactivepanelid">**setActivePanelId**</span><br><code>(panelId: string &#124; undefined) =&gt; void</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#action-setactivepanelid) |
| <span id="action-togglemaximizedpanel">**toggleMaximizedPanel**</span><br><code>(panelId: string) =&gt; void</code> | <span data-pagefind-ignore>Show one cell at the size of the workspace, or go back.<br><br>A toggle rather than a pair, because the gesture is a toggle: the strip's double-click and the cell menu's one item both mean "this cell, or not any more". Maximizing a DIFFERENT cell while one is already maximized moves the mode rather than restoring, which is what the menu item on another cell's strip is asking for.<br><br>Mounts no views that were not mounted — it is the same cell showing the same tab — and unmounts every other cell's, so the WebGL2 context ceiling (`agent-docs/reference/GPU_CONTEXT_BUDGET.md`) can only go down. That is the reason it is this and not a `display: none` over a still-mounted workspace.</span> | [WorkspaceLayoutMixin](../workspacelayoutmixin#action-togglemaximizedpanel) |
| <span id="action-restorepanels">**restorePanels**</span><br><code>() =&gt; void</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#action-restorepanels) |
| <span id="action-setactivetab">**setActiveTab**</span><br><code>(panelId: string, tabId: string) =&gt; void</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#action-setactivetab) |
| <span id="action-renametab">**renameTab**</span><br><code>(tabId: string, title: string &#124; undefined) =&gt; void</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#action-renametab) |
| <span id="action-splitpanel">**splitPanel**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(panelId: string, direction: "column" &#124; "row", before?: any) =&gt;…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(panelId: string, direction: "column" &#124; "row", before?: any) =&gt; PanelNode &#124; undefined</code></pre></dialog></span> | <span data-pagefind-ignore>Split a grid cell; the new cell gets one empty tab.</span> | [WorkspaceLayoutMixin](../workspacelayoutmixin#action-splitpanel) |
| <span id="action-closepanel">**closePanel**</span><br><code>(panelId: string) =&gt; void</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#action-closepanel) |
| <span id="action-addtab">**addTab**</span><br><code>(panelId: string, viewIds?: string[]) =&gt; TabNode &#124; undefined</code> | <span data-pagefind-ignore>"New empty tab": a tab in an existing cell, showing the launcher.</span> | [WorkspaceLayoutMixin](../workspacelayoutmixin#action-addtab) |
| <span id="action-closetab">**closeTab**</span><br><code>(tabId: string) =&gt; void</code> | <span data-pagefind-ignore>Close a tab, and the cell with it if that was its last.<br><br>A cell whose tabs are all gone is the state `pruneEmptyPanel` was written for — "dragging the last tab out of a split and leaving a blank half is the one place an empty panel is clearly not what was meant" — and closing that tab arrives at the identical half by a different gesture. It rendered nothing at all, not even the launcher an empty TAB shows, so the only way back out of it was the `+`.<br><br>`pruneEmptyPanel` carries both guards already: a cell with tabs left stays, and the last cell in the workspace stays whatever happens to it, since there is nowhere for the tree to collapse to.</span> | [WorkspaceLayoutMixin](../workspacelayoutmixin#action-closetab) |
| <span id="action-addviewtotab">**addViewToTab**</span><br><code>(tabId: string, viewId: string) =&gt; void</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#action-addviewtotab) |
| <span id="action-droptabinpanel">**dropTabInPanel**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(tabId: string, targetPanelId: string, index?: number &#124; undefin…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(tabId: string, targetPanelId: string, index?: number &#124; undefined) =&gt; void</code></pre></dialog></span> | <span data-pagefind-ignore>Drop a dragged tab into an existing panel, as a tab.<br><br>One action, so the tree never exists in a state where the tab is in both panels or neither. The imperative bridge needed an explicit `runInAction` around the unassign+reassign pair for exactly this, and a comment explaining that without it the reconcile autorun would observe the gap and re-home the view.</span> | [WorkspaceLayoutMixin](../workspacelayoutmixin#action-droptabinpanel) |
| <span id="action-droptabinnewsplit">**dropTabInNewSplit**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(tabId: string, targetPanelId: string, direction: "column" &#124; "r…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(tabId: string, targetPanelId: string, direction: "column" &#124; "row", before: boolean) =&gt; string &#124; undefined</code></pre></dialog></span> | <span data-pagefind-ignore>Drop a dragged tab on a panel edge: split, and land in the new half.</span> | [WorkspaceLayoutMixin](../workspacelayoutmixin#action-droptabinnewsplit) |
| <span id="action-setsizes">**setSizes**</span><br><code>(branchId: string, sizes: number[]) =&gt; void</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#action-setsizes) |
| <span id="action-applylayoutspec">**applyLayoutSpec**</span><br><code>(spec: LayoutSpecNode) =&gt; string[]</code> | <span data-pagefind-ignore>Arrange the workspace as a spec states.<br><br>There is no `init` property and no standing request: the spec is converted and *becomes* the layout, here and now. `init` existed only because dockview had to be told, could not be told before it mounted, and had to be told again afterwards — three problems that all came from the layout living somewhere this action could not reach.</span> | [WorkspaceLayoutMixin](../workspacelayoutmixin#action-applylayoutspec) |
| <span id="action-moveviewtonewtab">**moveViewToNewTab**</span><br><code>(viewId: string, allViewIds: string[]) =&gt; string &#124; undefined</code> | <span data-pagefind-ignore>ViewMenu's "move to new tab": the view leaves its tab for a new one.<br><br>`allViewIds` is EVERY view in the session, and is required for that reason — homing drops any view the list does not name, so the `[viewId]` default this used to carry unhomed all the others.</span> | [WorkspaceLayoutMixin](../workspacelayoutmixin#action-moveviewtonewtab) |
| <span id="action-moveviewtosplitright">**moveViewToSplitRight**</span><br><code>(viewId: string, allViewIds: string[]) =&gt; string &#124; undefined</code> | <span data-pagefind-ignore>ViewMenu's "move to split view": the view leaves for a new cell. `allViewIds` is every view in the session — see `moveViewToNewTab`.</span> | [WorkspaceLayoutMixin](../workspacelayoutmixin#action-moveviewtosplitright) |
| <span id="action-homeunassignedviews">**homeUnassignedViews**</span><br><code>(viewIds: string[]) =&gt; void</code> |  | [WorkspaceLayoutMixin](../workspacelayoutmixin#action-homeunassignedviews) |
| <span id="action-setpendingmove">**setPendingMove**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(move: PendingMove &#124; undefined, allViewIds?: string[] &#124; undefin…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(move: PendingMove &#124; undefined, allViewIds?: string[] &#124; undefined) =&gt; void</code></pre></dialog></span> | <span data-pagefind-ignore>Move one view relative to the others. PUBLIC API: an external plugin calls this behind a `'setPendingMove' in session` guard (jbrowse-plugin-protein3d, putting a protein view beside its genome view). It survived the last storage change by being kept as sugar, and it survives this one the same way — a capability-detecting caller cannot tell you it lost a capability.<br><br>**`allViewIds` is therefore OPTIONAL, and has to stay that way.** The plugin passes the move alone, because that was the whole signature when its call site was written; requiring the second argument threw `undefined.filter` out of a launch the plugin does not wrap, and the figure was again the only thing that noticed. Keeping the NAME is half of not breaking a runtime lookup — the call has to keep working as it is spelled.</span> | [WorkspaceLayoutMixin](../workspacelayoutmixin#action-setpendingmove) |
| <span id="action-tileviews">**tileViews**</span><br><code>(mode: TileMode, allViewIds: string[]) =&gt; void</code> | <span data-pagefind-ignore>The whole-workspace re-arrange: every view one cell, in one of four shapes. Restored from the dockview header's four "Global:" commands, which went with that component and were not reimplemented.<br><br>`allViewIds` is passed in rather than read off the session for the same reason `moveViewToNewTab` takes it: this mixin owns the tree and has no view list of its own. Passing `session.views` order means the arrangement it states is already the order views render in, so unlike a session spec's layout there is nothing for `orderViews` to apply.</span> | [WorkspaceLayoutMixin](../workspacelayoutmixin#action-tileviews) |
| <span id="action-moveviewdown">**moveViewDown**</span><br><code>(id: string, scopeIds?: string[] &#124; undefined) =&gt; void</code> |  | [MultipleViewsSessionMixin](../multipleviewssessionmixin#action-moveviewdown) |
| <span id="action-moveviewup">**moveViewUp**</span><br><code>(id: string, scopeIds?: string[] &#124; undefined) =&gt; void</code> |  | [MultipleViewsSessionMixin](../multipleviewssessionmixin#action-moveviewup) |
| <span id="action-moveviewtotop">**moveViewToTop**</span><br><code>(id: string, scopeIds?: string[] &#124; undefined) =&gt; void</code> |  | [MultipleViewsSessionMixin](../multipleviewssessionmixin#action-moveviewtotop) |
| <span id="action-moveviewtobottom">**moveViewToBottom**</span><br><code>(id: string, scopeIds?: string[] &#124; undefined) =&gt; void</code> |  | [MultipleViewsSessionMixin](../multipleviewssessionmixin#action-moveviewtobottom) |
| <span id="action-orderviews">**orderViews**</span><br><code>(ids: string[]) =&gt; void</code> | <span data-pagefind-ignore>Put the named views into the given relative order, leaving views not named in their own slots.<br><br>`session.views` is the one ordering, so this is how a channel that states an order in some other vocabulary gets it applied: a session spec's `layout` names views per panel, top to bottom, and that used to be honoured by the panel assignment array's order. Now the assignment carries membership only, so the layout says it here instead, once.</span> | [MultipleViewsSessionMixin](../multipleviewssessionmixin#action-orderviews) |
| <span id="action-addview">**addView**</span><br><code>(typeName: string, initialState?: any) =&gt; any</code> |  | [MultipleViewsSessionMixin](../multipleviewssessionmixin#action-addview) |
| <span id="action-replaceview">**replaceView**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(view: IBaseViewModel, typeName: string, initialState?: any) =&gt;…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(view: IBaseViewModel, typeName: string, initialState?: any) =&gt; any</code></pre></dialog></span> | <span data-pagefind-ignore>swap `view` for a new view of `typeName`, in the slot it occupied.<br><br>The launchers that build a view of a DIFFERENT type out of one you are already looking at — launch synteny view, read-vs-ref, split view — otherwise append, leaving the source view above the thing it produced and a stack of two views showing the same locus. This is the "replace" half of that offer, and a slot swap rather than remove-then-add so the new view lands where the reader was looking instead of at the bottom of the session.<br><br>A launcher whose result is the SAME type as its source does not come here and should not: collapse introns offers "Replace current view" by navigating the view it was invoked on, which keeps the view's identity and so lets its snackbar offer an Undo. Swapping in a new node would leave nothing to undo onto.<br><br>The slot is `session.views`, which is the order views render in under both layout modes (a tab's `viewIds` says which tab a view is in, not where in it), so the swap lands in place either way.<br><br>WHICH panel is a separate question and this does not answer it: the new view arrives in no tab, and `homeUnassignedViews` puts it in the active panel — the same panel only when the replaced view was in the active one. In practice it is, since clicking into a view activates its panel, and the launch that offers a replace is a click on that view's own menu.</span> | [MultipleViewsSessionMixin](../multipleviewssessionmixin#action-replaceview) |
| <span id="action-removeview">**removeView**</span><br><code>(view: IBaseViewModel) =&gt; void</code> |  | [MultipleViewsSessionMixin](../multipleviewssessionmixin#action-removeview) |
| <span id="action-takeoutviewsmissingfrom">**takeOutViewsMissingFrom**</span><br><code>(snapshot: unknown) =&gt; void</code> | <span data-pagefind-ignore>Take out every view the given session snapshot will not keep, before a whole-tree `applySnapshot` destroys it where it stands.<br><br>Undo and redo are `applySnapshot` on the session (`core/util/TimeTraveller`, which calls this), and every view carries an `ElementId` — so MST reconciles by identifier and destroys what the target lacks, inside the action, with the components still mounted. Measured on a redo across a closed view, with the restored view repainted first: 4 liveliness reads of its display before this, 0 after.<br><br>A view that is present but has changed `type` is destroyed by that same reconciliation (`areSame` runs the type's `is()` before its id check), so identity here is the pair, not the id.<br><br>**Views, and deliberately not what is under them.** A track or a display the snapshot drops is still destroyed in place, and that is not this door being worse than the others: `hideTrackGeneric` is a plain `tracks.remove` and measures louder (5 reads to undo's 4). Detaching one would be worse than the destroy it replaced — a detached display is a LIVE root, and `getContainingView` walks parents and throws when the walk finds no view, where a dead node only warns. At or above the view is the only place that walk still lands, which is why ADR-069's rule stops there.</span> | [MultipleViewsSessionMixin](../multipleviewssessionmixin#action-takeoutviewsmissingfrom) |
| <span id="action-setstickyviewheaders">**setStickyViewHeaders**</span><br><code>(sticky: boolean) =&gt; void</code> |  | [MultipleViewsSessionMixin](../multipleviewssessionmixin#action-setstickyviewheaders) |
| <span id="action-setuseworkspaces">**setUseWorkspaces**</span><br><code>(useWorkspaces: boolean) =&gt; void</code> | <span data-pagefind-ignore>set the workspaces layout for this session only, leaving the user's personal default untouched. For session-scoped intent — a spec carrying a `layout`, or an ad-hoc "move view to a tab/split" — where rewriting the visitor's global preference would be a surprise. The user-facing default toggle is `setUseWorkspacesPreference`.</span> | [MultipleViewsSessionMixin](../multipleviewssessionmixin#action-setuseworkspaces) |
| <span id="action-setuseworkspacespreference">**setUseWorkspacesPreference**</span><br><code>(useWorkspaces: boolean) =&gt; void</code> | <span data-pagefind-ignore>the user-facing workspaces toggle: applies to this session and becomes their default for sessions that don't specify one. Persisted only here, on an explicit toggle — an autorun mirroring the resolved value would bake the admin default into every visitor's localStorage on first load, so a later admin change could never reach them.</span> | [MultipleViewsSessionMixin](../multipleviewssessionmixin#action-setuseworkspacespreference) |
| <span id="action-resetuseworkspaces">**resetUseWorkspaces**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>drop both this session's explicit value and the user's override so workspaces falls back to the admin default</span> | [MultipleViewsSessionMixin](../multipleviewssessionmixin#action-resetuseworkspaces) |
| <span id="action-setdrawerposition">**setDrawerPosition**</span><br><code>(arg: string) =&gt; void</code> |  | [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin#action-setdrawerposition) |
| <span id="action-updatedrawerwidth">**updateDrawerWidth**</span><br><code>(drawerWidth: number) =&gt; number</code> |  | [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin#action-updatedrawerwidth) |
| <span id="action-resizedrawer">**resizeDrawer**</span><br><code>(distance: number) =&gt; number</code> |  | [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin#action-resizedrawer) |
| <span id="action-addwidget">**addWidget**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(typeName: string, id: string, initialState?: any, conf?: unkno…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(typeName: string, id: string, initialState?: any, conf?: unknown) =&gt; any</code></pre></dialog></span> |  | [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin#action-addwidget) |
| <span id="action-showwidget">**showWidget**</span><br><code>(widget: any) =&gt; void</code> |  | [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin#action-showwidget) |
| <span id="action-hidewidget">**hideWidget**</span><br><code>(widget: any) =&gt; void</code> |  | [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin#action-hidewidget) |
| <span id="action-minimizewidgetdrawer">**minimizeWidgetDrawer**</span><br><code>() =&gt; void</code> |  | [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin#action-minimizewidgetdrawer) |
| <span id="action-showwidgetdrawer">**showWidgetDrawer**</span><br><code>() =&gt; void</code> |  | [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin#action-showwidgetdrawer) |
| <span id="action-popoutwidget">**popoutWidget**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>show the visible widget in a modal dialog, freeing the drawer column</span> | [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin#action-popoutwidget) |
| <span id="action-returnwidgettodrawer">**returnWidgetToDrawer**</span><br><code>() =&gt; void</code> |  | [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin#action-returnwidgettodrawer) |
| <span id="action-hideallwidgets">**hideAllWidgets**</span><br><code>() =&gt; void</code> |  | [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin#action-hideallwidgets) |
| <span id="action-editconfiguration">**editConfiguration**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(configuration: (ModelInstanceTypeProps&lt;…&gt; &amp; {…} &amp; IStateTreeNo…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(configuration: (ModelInstanceTypeProps&lt;…&gt; &amp; {…} &amp; IStateTreeNode&lt;…&gt;) &#124; { ...; }, opts?: { ...; } &#124; undefined) =&gt; void</code></pre></dialog></span> | <span data-pagefind-ignore>opens a configuration editor to configure the given thing, and sets the current task to be configuring it</span> | [DrawerWidgetSessionMixin](../drawerwidgetsessionmixin#action-editconfiguration) |

