@jbrowse/product-core 4.3.0 → 5.0.0-beta.10
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/esm/RootModel/BaseRootModel.d.ts +514 -323
- package/esm/RootModel/BaseRootModel.js +141 -14
- package/esm/RootModel/HierarchicalConfig.d.ts +30 -20
- package/esm/RootModel/HierarchicalConfig.js +36 -0
- package/esm/RootModel/InternetAccounts.d.ts +18 -1
- package/esm/RootModel/InternetAccounts.js +120 -22
- package/esm/RootModel/PreferencesConfig.d.ts +37 -0
- package/esm/RootModel/PreferencesConfig.js +75 -0
- package/esm/RootModel/createConfigModel.d.ts +257 -0
- package/esm/RootModel/createConfigModel.js +77 -0
- package/esm/RootModel/index.d.ts +10 -5
- package/esm/RootModel/index.js +10 -5
- package/esm/RootModel/menuItems.d.ts +24 -0
- package/esm/RootModel/menuItems.js +141 -0
- package/esm/Session/BaseSession.d.ts +285 -11
- package/esm/Session/BaseSession.js +383 -15
- package/esm/Session/Connections.d.ts +115 -8
- package/esm/Session/Connections.js +196 -74
- package/esm/Session/DrawerWidgets.d.ts +145 -13
- package/esm/Session/DrawerWidgets.js +219 -49
- package/esm/Session/MultipleViews.d.ts +1067 -1177
- package/esm/Session/MultipleViews.js +395 -64
- package/esm/Session/Preferences.d.ts +1389 -0
- package/esm/Session/Preferences.js +58 -0
- package/esm/Session/ReferenceManagement.d.ts +28 -3
- package/esm/Session/ReferenceManagement.js +56 -41
- package/esm/Session/SessionTracks.d.ts +1101 -1180
- package/esm/Session/SessionTracks.js +584 -34
- package/esm/Session/Themes.d.ts +136 -2
- package/esm/Session/Themes.js +267 -21
- package/esm/Session/TrackMenu.d.ts +88 -0
- package/esm/Session/TrackMenu.js +175 -0
- package/esm/Session/TrackMenuSessionMixin.d.ts +27 -0
- package/esm/Session/TrackMenuSessionMixin.js +42 -0
- package/esm/Session/Tracks.d.ts +945 -1159
- package/esm/Session/Tracks.js +229 -30
- package/esm/Session/assertSessionModel.d.ts +21 -0
- package/esm/Session/assertSessionModel.js +1 -0
- package/esm/Session/copyTrackSnapshot.d.ts +21 -0
- package/esm/Session/copyTrackSnapshot.js +20 -0
- package/esm/Session/developerMode.d.ts +7 -0
- package/esm/Session/developerMode.js +43 -0
- package/esm/Session/finalizeSession.d.ts +15 -0
- package/esm/Session/finalizeSession.js +28 -0
- package/esm/Session/hydratedForms.d.ts +16 -0
- package/esm/Session/hydratedForms.js +13 -0
- package/esm/Session/index.d.ts +27 -10
- package/esm/Session/index.js +16 -10
- package/esm/Session/pluginExtraTrackItems.d.ts +11 -0
- package/esm/Session/pluginExtraTrackItems.js +13 -0
- package/esm/Session/readdedTrackConf.d.ts +8 -0
- package/esm/Session/readdedTrackConf.js +24 -0
- package/esm/Session/shareableSnapshot.d.ts +23 -0
- package/esm/Session/shareableSnapshot.js +66 -0
- package/esm/Session/temporaryAssemblyTracks.d.ts +24 -0
- package/esm/Session/temporaryAssemblyTracks.js +37 -0
- package/esm/assertExtends.d.ts +55 -0
- package/esm/assertExtends.js +1 -0
- package/esm/controllerTracks.d.ts +76 -0
- package/esm/controllerTracks.js +125 -0
- package/esm/destroyViewState.d.ts +21 -0
- package/esm/destroyViewState.js +29 -0
- package/esm/embeddedController.d.ts +57 -0
- package/esm/embeddedController.js +100 -0
- package/esm/index.d.ts +32 -4
- package/esm/index.js +31 -4
- package/esm/loadPlugins.d.ts +38 -0
- package/esm/loadPlugins.js +45 -0
- package/esm/localFiles.d.ts +74 -0
- package/esm/localFiles.js +156 -0
- package/esm/observeSession.d.ts +55 -0
- package/esm/observeSession.js +90 -0
- package/esm/parallelChunkLoading.d.ts +30 -0
- package/esm/parallelChunkLoading.js +71 -0
- package/esm/pluginInput.d.ts +32 -0
- package/esm/pluginInput.js +19 -0
- package/esm/pruneUnbuildableNodes.d.ts +109 -0
- package/esm/pruneUnbuildableNodes.js +562 -0
- package/esm/resolveAssemblies.d.ts +68 -0
- package/esm/resolveAssemblies.js +77 -0
- package/esm/rpcWorker.d.ts +36 -4
- package/esm/rpcWorker.js +126 -20
- package/esm/sessionMigrations/index.d.ts +15 -0
- package/esm/sessionMigrations/index.js +178 -0
- package/esm/sessionUrl.d.ts +40 -0
- package/esm/sessionUrl.js +66 -0
- package/esm/sessionUtils.d.ts +74 -0
- package/esm/sessionUtils.js +599 -0
- package/esm/siblingCast.d.ts +14 -0
- package/esm/siblingCast.js +16 -0
- package/esm/snapshotUtils.d.ts +8 -0
- package/esm/snapshotUtils.js +12 -0
- package/esm/ui/AboutDialog.d.ts +8 -3
- package/esm/ui/AboutDialog.js +14 -5
- package/esm/ui/AboutDialogContents.d.ts +2 -6
- package/esm/ui/AboutDialogContents.js +13 -17
- package/esm/ui/AssemblyInfoPanel.d.ts +5 -0
- package/esm/ui/AssemblyInfoPanel.js +63 -0
- package/esm/ui/DescriptionPanel.d.ts +3 -0
- package/esm/ui/DescriptionPanel.js +25 -0
- package/esm/ui/Drawer.d.ts +21 -0
- package/esm/ui/Drawer.js +60 -0
- package/esm/ui/DrawerControls.d.ts +5 -0
- package/esm/ui/DrawerControls.js +28 -0
- package/esm/ui/DrawerHeader.d.ts +6 -0
- package/esm/ui/DrawerHeader.js +36 -0
- package/esm/ui/DrawerWidget.d.ts +5 -0
- package/esm/ui/DrawerWidget.js +12 -0
- package/esm/ui/DrawerWidgetSelector.d.ts +5 -0
- package/esm/ui/DrawerWidgetSelector.js +40 -0
- package/esm/ui/FileInfoPanel.d.ts +3 -6
- package/esm/ui/FileInfoPanel.js +36 -26
- package/esm/ui/GeneralPreferencesTab.d.ts +17 -0
- package/esm/ui/GeneralPreferencesTab.js +34 -0
- package/esm/ui/HeaderButtons.d.ts +2 -1
- package/esm/ui/HeaderButtons.js +15 -17
- package/esm/ui/ModalWidget.d.ts +13 -0
- package/esm/ui/ModalWidget.js +48 -0
- package/esm/ui/ModalWidgetAppBar.d.ts +8 -0
- package/esm/ui/ModalWidgetAppBar.js +9 -0
- package/esm/ui/PreferenceCheckbox.d.ts +6 -0
- package/esm/ui/PreferenceCheckbox.js +16 -0
- package/esm/ui/PreferencesDialog.d.ts +34 -0
- package/esm/ui/PreferencesDialog.js +55 -0
- package/esm/ui/PreferencesResetDialog.d.ts +8 -0
- package/esm/ui/PreferencesResetDialog.js +19 -0
- package/esm/ui/RefNameAliasesDialog.d.ts +9 -0
- package/esm/ui/RefNameAliasesDialog.js +65 -0
- package/esm/ui/RefNameInfoDialog.d.ts +3 -6
- package/esm/ui/RefNameInfoDialog.js +45 -63
- package/esm/ui/ViewPreferencesTab.d.ts +12 -0
- package/esm/ui/ViewPreferencesTab.js +15 -0
- package/esm/ui/WidgetBody.d.ts +18 -0
- package/esm/ui/WidgetBody.js +22 -0
- package/esm/ui/WidgetHeading.d.ts +7 -0
- package/esm/ui/WidgetHeading.js +7 -0
- package/esm/ui/aboutTestUtils.d.ts +140 -0
- package/esm/ui/aboutTestUtils.js +25 -0
- package/esm/ui/descriptionHtml.d.ts +25 -0
- package/esm/ui/descriptionHtml.js +64 -0
- package/esm/ui/drawerLayout.d.ts +18 -0
- package/esm/ui/drawerLayout.js +22 -0
- package/esm/ui/index.d.ts +15 -1
- package/esm/ui/index.js +13 -1
- package/esm/ui/preferencesReset.d.ts +18 -0
- package/esm/ui/preferencesReset.js +69 -0
- package/esm/ui/util.d.ts +22 -7
- package/esm/ui/util.js +19 -41
- package/esm/useEngineLifecycle.d.ts +19 -0
- package/esm/useEngineLifecycle.js +44 -0
- package/package.json +15 -18
- package/esm/RootModel/FormatAbout.d.ts +0 -12
- package/esm/RootModel/FormatAbout.js +0 -15
- package/esm/RootModel/FormatDetails.d.ts +0 -24
- package/esm/RootModel/FormatDetails.js +0 -27
- package/esm/Session/DialogQueue.d.ts +0 -17
- package/esm/Session/DialogQueue.js +0 -31
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { getSnapshot } from '@jbrowse/mobx-state-tree';
|
|
2
|
+
/**
|
|
3
|
+
* The session snapshot to hand to anyone else — a share link, an exported
|
|
4
|
+
* `session.json`, a desktop→web export. Snapshotting and baking are one call so
|
|
5
|
+
* the pair can't be split: a bare `getSnapshot(session)` is never a correct
|
|
6
|
+
* outgoing snapshot (see `bakeSessionCascades`), and three of the four
|
|
7
|
+
* boundaries were spelling the two steps out identically.
|
|
8
|
+
*
|
|
9
|
+
* The fourth (desktop `ExportToWebDialog`) bakes a *transformed* snapshot from
|
|
10
|
+
* `planWebExport`, so it calls `bakeSessionCascades` directly.
|
|
11
|
+
*/
|
|
12
|
+
export function getShareableSessionSnapshot(session) {
|
|
13
|
+
return bakeSessionCascades(session, getSnapshot(session));
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Everything an outgoing snapshot has to resolve because the live session
|
|
17
|
+
* resolves it at read time against state that is staying behind — currently the
|
|
18
|
+
* workspaces intent alone.
|
|
19
|
+
*
|
|
20
|
+
* It keeps its own entry point rather than being inlined into the one caller
|
|
21
|
+
* because the failure of a boundary that performs half of them is invisible at
|
|
22
|
+
* that boundary: the export succeeds, and what is missing only shows up on
|
|
23
|
+
* someone else's screen.
|
|
24
|
+
*/
|
|
25
|
+
export function bakeSessionCascades(session, snapshot) {
|
|
26
|
+
const snap = structuredClone(snapshot);
|
|
27
|
+
bakeWorkspacesIntent(session, snap);
|
|
28
|
+
return snap;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The workspaces cascade: session property -> user preference -> admin
|
|
32
|
+
* `configuration.preferences.useWorkspaces`, of which only the first is in the
|
|
33
|
+
* snapshot.
|
|
34
|
+
*
|
|
35
|
+
* So a sender whose workspace is on because *their admin turned it on* exports
|
|
36
|
+
* a fully arranged `layout` with no statement that it is a workspace at all,
|
|
37
|
+
* and a recipient resolving their own cascade to false renders the classic
|
|
38
|
+
* stack: the arrangement arrives intact and invisible, with nothing to say it
|
|
39
|
+
* was dropped.
|
|
40
|
+
*
|
|
41
|
+
* Only the on case is baked. At `false` there is no arrangement to carry, so
|
|
42
|
+
* stamping it would be a sender with nothing to say overriding a recipient who
|
|
43
|
+
* prefers workspaces.
|
|
44
|
+
*
|
|
45
|
+
* The paths that build a layout through an explicit user intent already set the
|
|
46
|
+
* property themselves (`setUseWorkspacesPreference`, ViewMenu's move-view-out,
|
|
47
|
+
* a spec `layout`), which is exactly what hides this: every arrangement made by
|
|
48
|
+
* a *drag* — split a cell, drag a tab into it, open a new tab — goes through
|
|
49
|
+
* `WorkspaceLayoutMixin` alone, which owns the tree and knows nothing about the
|
|
50
|
+
* preference.
|
|
51
|
+
*
|
|
52
|
+
* `effectiveUseWorkspaces` is read behind an `in` guard because
|
|
53
|
+
* `AbstractSessionModel` cannot name it (it lives on MultipleViewsSessionMixin,
|
|
54
|
+
* one layer up), so renaming that getter silently stops the bake rather than
|
|
55
|
+
* failing to compile — the hazard app-core/src/WorkspaceLayout/CLAUDE.md describes for
|
|
56
|
+
* `setPendingMove`. jbrowse-web's `sessionModel/exportLayout.test.ts` is the
|
|
57
|
+
* canary, since the bake needs a real session to have a cascade at all.
|
|
58
|
+
*/
|
|
59
|
+
function bakeWorkspacesIntent(session, snap) {
|
|
60
|
+
if (snap.useWorkspaces === undefined &&
|
|
61
|
+
'effectiveUseWorkspaces' in session &&
|
|
62
|
+
session.effectiveUseWorkspaces ===
|
|
63
|
+
true) {
|
|
64
|
+
snap.useWorkspaces = true;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AnyConfigurationModel } from '@jbrowse/core/configuration';
|
|
2
|
+
/**
|
|
3
|
+
* Checks that a track config being written into a session or config list is one
|
|
4
|
+
* something can still draw tomorrow.
|
|
5
|
+
*
|
|
6
|
+
* A config naming nothing but a temporary assembly is dead the moment its view
|
|
7
|
+
* closes, and no list outside that view has anyone to sweep it — which is the
|
|
8
|
+
* whole of ADR-084. A track only one view can draw carries its config on the
|
|
9
|
+
* track instead (`showTrackGeneric`'s `inlineConf`), so reaching a session list
|
|
10
|
+
* with one is the mistake, not the cleanup afterwards.
|
|
11
|
+
*
|
|
12
|
+
* **This reports a write, not a click.** The two flows a user can drive into it
|
|
13
|
+
* are answered before they get here — the track menu greys its copy actions, and
|
|
14
|
+
* `addTrackFromWidget` opens the track inline instead of adding it — so what
|
|
15
|
+
* survives to report is a caller that had `inlineConf` available and did not
|
|
16
|
+
* take it. That is the reading the message is written for.
|
|
17
|
+
*
|
|
18
|
+
* `console.error` and never `throw`, matching `assertDisplayContract`: these
|
|
19
|
+
* writes happen inside launchers and menu handlers where an exception is caught
|
|
20
|
+
* and reported as a failed track, which would hide the violation. The jest gate
|
|
21
|
+
* (`config/jest/contractGate.js`) is what listens in tree; out of tree
|
|
22
|
+
* `contractReports` does, once a host arms it.
|
|
23
|
+
*/
|
|
24
|
+
export declare function assertTrackConfOutlivesItsAssemblies(session: unknown, trackConf: AnyConfigurationModel | Record<string, unknown>, destination: string): void;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { namesTemporaryAssembly } from '@jbrowse/core/util';
|
|
2
|
+
import { reportContractViolation } from '@jbrowse/render-core/contractReports';
|
|
3
|
+
/**
|
|
4
|
+
* Checks that a track config being written into a session or config list is one
|
|
5
|
+
* something can still draw tomorrow.
|
|
6
|
+
*
|
|
7
|
+
* A config naming nothing but a temporary assembly is dead the moment its view
|
|
8
|
+
* closes, and no list outside that view has anyone to sweep it — which is the
|
|
9
|
+
* whole of ADR-084. A track only one view can draw carries its config on the
|
|
10
|
+
* track instead (`showTrackGeneric`'s `inlineConf`), so reaching a session list
|
|
11
|
+
* with one is the mistake, not the cleanup afterwards.
|
|
12
|
+
*
|
|
13
|
+
* **This reports a write, not a click.** The two flows a user can drive into it
|
|
14
|
+
* are answered before they get here — the track menu greys its copy actions, and
|
|
15
|
+
* `addTrackFromWidget` opens the track inline instead of adding it — so what
|
|
16
|
+
* survives to report is a caller that had `inlineConf` available and did not
|
|
17
|
+
* take it. That is the reading the message is written for.
|
|
18
|
+
*
|
|
19
|
+
* `console.error` and never `throw`, matching `assertDisplayContract`: these
|
|
20
|
+
* writes happen inside launchers and menu handlers where an exception is caught
|
|
21
|
+
* and reported as a failed track, which would hide the violation. The jest gate
|
|
22
|
+
* (`config/jest/contractGate.js`) is what listens in tree; out of tree
|
|
23
|
+
* `contractReports` does, once a host arms it.
|
|
24
|
+
*/
|
|
25
|
+
export function assertTrackConfOutlivesItsAssemblies(session, trackConf, destination) {
|
|
26
|
+
if (!namesTemporaryAssembly(session, trackConf)) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const { trackId } = trackConf;
|
|
30
|
+
reportContractViolation('session', `${destination} was given "${trackId}", ` +
|
|
31
|
+
`which names a temporary assembly — one a comparative view synthesized ` +
|
|
32
|
+
`and gives back when it closes, so this config outlives the only ` +
|
|
33
|
+
`assembly that could draw it and nothing sweeps the list it landed in. ` +
|
|
34
|
+
`A track only one view can draw passes its config to that view's ` +
|
|
35
|
+
`showTrack as \`inlineConf\` instead, which puts it on the track and ` +
|
|
36
|
+
`takes it out with the view. See ADR-084.`);
|
|
37
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compile-time assertion that `Actual` is assignable to `Expected`, evaluating
|
|
3
|
+
* to `Actual`. There is no runtime component — referencing the alias forces the
|
|
4
|
+
* check, and a mismatch surfaces as a type error at the reference site.
|
|
5
|
+
*
|
|
6
|
+
* The main use is binding a hand-written "shadow" contract to the real type it
|
|
7
|
+
* shadows so the two can't silently drift. MST's `getParent<T>(self)` is an
|
|
8
|
+
* unchecked assertion (`T` has no structural link to the actual parent), so a
|
|
9
|
+
* child model that reaches into its parent via a local shape can keep compiling
|
|
10
|
+
* after the real parent renames or drops a member — until it throws at runtime.
|
|
11
|
+
* Pinning `AssertExtends<RealRootModel, ShadowParent>` turns that into a build
|
|
12
|
+
* error:
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* interface SessionModelParent {
|
|
16
|
+
* version: string
|
|
17
|
+
* assemblyManager: AssemblyManager
|
|
18
|
+
* }
|
|
19
|
+
* // real root must satisfy the shadow the session reaches for
|
|
20
|
+
* export type _Check = AssertExtends<ViewModel, SessionModelParent>
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export type AssertExtends<Actual extends Expected, Expected> = Actual;
|
|
24
|
+
/**
|
|
25
|
+
* Compile-time assertion that a type has not degraded to `any`. Pass it the
|
|
26
|
+
* `IsAny` of the type you are pinning; a failure reads `Type 'true' does not
|
|
27
|
+
* satisfy the constraint 'false'`.
|
|
28
|
+
*
|
|
29
|
+
* ```ts
|
|
30
|
+
* export type _ViewIsTyped = AssertNotAny<IsAny<ViewModel['session']['view']>>
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* This is the one check the others cannot make for you. `any` satisfies every
|
|
34
|
+
* `AssertExtends`, implements every `SessionWith*` contract, and passes tsc,
|
|
35
|
+
* jest and lint — so a surface that silently becomes `any` switches off type
|
|
36
|
+
* checking everywhere downstream while every gate stays green.
|
|
37
|
+
*
|
|
38
|
+
* Composed MST models are where it happens here. `types.compose`'s overloads
|
|
39
|
+
* are declared over `IModelType<P, O, FC, FS>`, so a model passed in as a naked
|
|
40
|
+
* type parameter has nothing to infer those four from and the composed result
|
|
41
|
+
* degrades.
|
|
42
|
+
*
|
|
43
|
+
* Naming `any` twice at the call site is not an oversight. It takes the computed
|
|
44
|
+
* boolean because the constraint has to be checked where it is concrete, and all
|
|
45
|
+
* three single-argument spellings were tried and fail:
|
|
46
|
+
*
|
|
47
|
+
* - `AssertNotAny<T> = AssertExtends<IsAny<T>, false>` — unbound, `IsAny<T>` is
|
|
48
|
+
* `boolean`, so the alias fails at its own declaration.
|
|
49
|
+
* - `AssertNotAny<T, _ extends false = IsAny<T>> = T` — the tempting one. Same
|
|
50
|
+
* declaration-site failure, and it does not even catch: instantiated at `any`
|
|
51
|
+
* it reports nothing.
|
|
52
|
+
* - `AssertNotAny<T extends IsAny<T> extends true ? never : unknown>` — TS2313,
|
|
53
|
+
* circular constraint.
|
|
54
|
+
*/
|
|
55
|
+
export type AssertNotAny<IsItAny extends false> = IsItAny;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { BlobLocation } from '@jbrowse/core/util';
|
|
2
|
+
import type { LooseSearchIndex } from '@jbrowse/core/util/expandLooseSearchIndex';
|
|
3
|
+
import type { LooseTrackInput } from '@jbrowse/core/util/tracks';
|
|
4
|
+
import type { IStateTreeNode } from '@jbrowse/mobx-state-tree';
|
|
5
|
+
export type TrackConf = Record<string, unknown>;
|
|
6
|
+
/**
|
|
7
|
+
* What a controller accepts per track: a full config, the trackId of one the
|
|
8
|
+
* catalog already holds (a hub's, when the assembly came from one), a bare
|
|
9
|
+
* data-file URL, or `{ uri, index?, ...extra }`. The loose forms expand through
|
|
10
|
+
* core's `guessTrackConf`, the same inference the "Add track" flow runs.
|
|
11
|
+
*/
|
|
12
|
+
export type TrackInput = string | TrackConf;
|
|
13
|
+
interface ControllerView {
|
|
14
|
+
tracks: {
|
|
15
|
+
configuration: {
|
|
16
|
+
trackId: string;
|
|
17
|
+
};
|
|
18
|
+
}[];
|
|
19
|
+
launchTrack: (trackId: string) => Promise<unknown>;
|
|
20
|
+
hideTrack: (trackId: string) => unknown;
|
|
21
|
+
}
|
|
22
|
+
export interface ControllerSession extends IStateTreeNode {
|
|
23
|
+
view: ControllerView;
|
|
24
|
+
getTrackById: (trackId: string) => unknown;
|
|
25
|
+
addSessionTrackConf: (conf: TrackConf) => unknown;
|
|
26
|
+
}
|
|
27
|
+
export declare function isLooseTrack(track: TrackInput): track is string | LooseTrackInput;
|
|
28
|
+
/**
|
|
29
|
+
* Stamp the view's assembly onto a full-config track that omits
|
|
30
|
+
* `assemblyNames`. A single-view embed has exactly one assembly, so it is
|
|
31
|
+
* unambiguous — and doing it here frees every host (R htmlwidgets, anywidget,
|
|
32
|
+
* vanilla JS) from computing the name itself, which it often cannot: the
|
|
33
|
+
* assembly may have arrived as a hub name only the view resolved. Loose tracks
|
|
34
|
+
* take the same name through `guessTrackConf`'s `assemblyName` argument.
|
|
35
|
+
*/
|
|
36
|
+
export declare function withAssemblyName(track: TrackConf, assemblyName?: string): TrackConf;
|
|
37
|
+
/**
|
|
38
|
+
* Expand every loose entry into a full track config; stamp the assembly name
|
|
39
|
+
* onto the ones already written out. A string the catalog already resolves is
|
|
40
|
+
* that track, and is tried before the file guess: "not URL-shaped" cannot tell
|
|
41
|
+
* an id from a relative path like `data/reads.bam`.
|
|
42
|
+
*/
|
|
43
|
+
export declare function resolveTracks(tracks: TrackInput[], session: ControllerSession, assemblyName?: string, localFiles?: Record<string, BlobLocation>): TrackConf[];
|
|
44
|
+
/**
|
|
45
|
+
* Register each track config only if the session cannot already resolve it, then
|
|
46
|
+
* show it. `getTrackById` resolves catalog + connection + session tracks, so a
|
|
47
|
+
* config already seeded into the catalog is left alone rather than shadowed by a
|
|
48
|
+
* duplicate in `sessionTracks` — which is also what `addSessionTrackConf`
|
|
49
|
+
* dedupes on, so this states the intent rather than supplying it.
|
|
50
|
+
*
|
|
51
|
+
* Session-scoped: these are the host's declared tracks for one embed, not a
|
|
52
|
+
* catalog an admin curates.
|
|
53
|
+
*/
|
|
54
|
+
export declare function openTracks(session: ControllerSession, tracks: TrackConf[]): Promise<void>;
|
|
55
|
+
/** Open every wanted track and close any others the view currently shows. */
|
|
56
|
+
export declare function reconcileTracks(session: ControllerSession, tracks: TrackConf[]): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* A hub's entries followed by the host's own, the host's winning where both
|
|
59
|
+
* carry the same id: the `idKey` member, or what an `idKey` function returns.
|
|
60
|
+
*/
|
|
61
|
+
export declare function withHostOverrides<T>(hub: readonly T[] | undefined, host: readonly T[] | undefined, idKey: string | ((entry: T) => unknown)): T[];
|
|
62
|
+
/**
|
|
63
|
+
* A search index is the trix file it reads, so a host's entry naming the same
|
|
64
|
+
* file replaces the hub's, however each spells it: a hub's relative `.ix` is
|
|
65
|
+
* resolved against its `baseUri`. An index with no trix file is only ever
|
|
66
|
+
* itself.
|
|
67
|
+
*/
|
|
68
|
+
export declare function searchIndexKey(entry: LooseSearchIndex): string | {
|
|
69
|
+
uri: string;
|
|
70
|
+
baseUri?: string;
|
|
71
|
+
assemblyNames?: string[];
|
|
72
|
+
} | {
|
|
73
|
+
[key: string]: unknown;
|
|
74
|
+
type: string;
|
|
75
|
+
};
|
|
76
|
+
export {};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { getEnv } from '@jbrowse/core/util';
|
|
2
|
+
import { withPageBaseUri } from '@jbrowse/core/util/addRelativeUris';
|
|
3
|
+
import { guessTrackConf } from '@jbrowse/core/util/tracks';
|
|
4
|
+
import { isAlive } from '@jbrowse/mobx-state-tree';
|
|
5
|
+
import { resolveLocalFileUris } from './localFiles.js';
|
|
6
|
+
export function isLooseTrack(track) {
|
|
7
|
+
return typeof track === 'string' || (!('adapter' in track) && 'uri' in track);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Stamp the view's assembly onto a full-config track that omits
|
|
11
|
+
* `assemblyNames`. A single-view embed has exactly one assembly, so it is
|
|
12
|
+
* unambiguous — and doing it here frees every host (R htmlwidgets, anywidget,
|
|
13
|
+
* vanilla JS) from computing the name itself, which it often cannot: the
|
|
14
|
+
* assembly may have arrived as a hub name only the view resolved. Loose tracks
|
|
15
|
+
* take the same name through `guessTrackConf`'s `assemblyName` argument.
|
|
16
|
+
*/
|
|
17
|
+
export function withAssemblyName(track, assemblyName) {
|
|
18
|
+
return assemblyName !== undefined && !('assemblyNames' in track)
|
|
19
|
+
? { ...track, assemblyNames: [assemblyName] }
|
|
20
|
+
: track;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Expand every loose entry into a full track config; stamp the assembly name
|
|
24
|
+
* onto the ones already written out. A string the catalog already resolves is
|
|
25
|
+
* that track, and is tried before the file guess: "not URL-shaped" cannot tell
|
|
26
|
+
* an id from a relative path like `data/reads.bam`.
|
|
27
|
+
*/
|
|
28
|
+
export function resolveTracks(tracks, session, assemblyName, localFiles) {
|
|
29
|
+
const { pluginManager } = getEnv(session);
|
|
30
|
+
return tracks.map(track => {
|
|
31
|
+
if (typeof track === 'string' && session.getTrackById(track)) {
|
|
32
|
+
return { trackId: track };
|
|
33
|
+
}
|
|
34
|
+
const conf = isLooseTrack(track)
|
|
35
|
+
? guessTrackConf(track, pluginManager, assemblyName)
|
|
36
|
+
: // full configs are stamped here too, not just in the build() catalog
|
|
37
|
+
// seed: a config that first appears through addTrack never passes
|
|
38
|
+
// through that seed, and would otherwise reach addSessionTrackConf with no
|
|
39
|
+
// assemblyNames and silently fail to display
|
|
40
|
+
withAssemblyName(track, assemblyName);
|
|
41
|
+
// after the guess, so the adapter has already derived its index sibling
|
|
42
|
+
// from the uri string and both get swapped for blobs together
|
|
43
|
+
return withPageBaseUri(localFiles ? resolveLocalFileUris(conf, localFiles) : conf);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Register each track config only if the session cannot already resolve it, then
|
|
48
|
+
* show it. `getTrackById` resolves catalog + connection + session tracks, so a
|
|
49
|
+
* config already seeded into the catalog is left alone rather than shadowed by a
|
|
50
|
+
* duplicate in `sessionTracks` — which is also what `addSessionTrackConf`
|
|
51
|
+
* dedupes on, so this states the intent rather than supplying it.
|
|
52
|
+
*
|
|
53
|
+
* Session-scoped: these are the host's declared tracks for one embed, not a
|
|
54
|
+
* catalog an admin curates.
|
|
55
|
+
*/
|
|
56
|
+
export async function openTracks(session, tracks) {
|
|
57
|
+
// sequential, not Promise.all: each display's state model may be a separate
|
|
58
|
+
// dynamic import, and racing them would land the tracks on the view in
|
|
59
|
+
// whatever order the chunks happen to resolve rather than the caller's
|
|
60
|
+
for (const conf of tracks) {
|
|
61
|
+
// the engine can be destroyed while a chunk is in flight (an unmounted
|
|
62
|
+
// embed); reading the dead tree from this floating promise would throw
|
|
63
|
+
// uncatchably
|
|
64
|
+
if (!isAlive(session.view)) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const trackId = conf.trackId;
|
|
68
|
+
if (!session.getTrackById(trackId)) {
|
|
69
|
+
session.addSessionTrackConf(conf);
|
|
70
|
+
}
|
|
71
|
+
await session.view.launchTrack(trackId);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/** Open every wanted track and close any others the view currently shows. */
|
|
75
|
+
export async function reconcileTracks(session, tracks) {
|
|
76
|
+
const { view } = session;
|
|
77
|
+
const wanted = new Set(tracks.map(t => t.trackId));
|
|
78
|
+
await openTracks(session, tracks);
|
|
79
|
+
if (!isAlive(view)) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
// materialize the ids first: hideTrack splices view.tracks, so iterating it
|
|
83
|
+
// live would skip entries
|
|
84
|
+
const unwanted = view.tracks
|
|
85
|
+
.map(track => track.configuration.trackId)
|
|
86
|
+
.filter(trackId => !wanted.has(trackId));
|
|
87
|
+
for (const trackId of unwanted) {
|
|
88
|
+
view.hideTrack(trackId);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* A hub's entries followed by the host's own, the host's winning where both
|
|
93
|
+
* carry the same id: the `idKey` member, or what an `idKey` function returns.
|
|
94
|
+
*/
|
|
95
|
+
export function withHostOverrides(hub = [], host = [], idKey) {
|
|
96
|
+
const idOf = (entry) => typeof idKey === 'function'
|
|
97
|
+
? idKey(entry)
|
|
98
|
+
: entry[idKey];
|
|
99
|
+
const hostIds = new Set(host.map(idOf).filter(id => id !== undefined));
|
|
100
|
+
return [...hub.filter(entry => !hostIds.has(idOf(entry))), ...host];
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* A search index is the trix file it reads, so a host's entry naming the same
|
|
104
|
+
* file replaces the hub's, however each spells it: a hub's relative `.ix` is
|
|
105
|
+
* resolved against its `baseUri`. An index with no trix file is only ever
|
|
106
|
+
* itself.
|
|
107
|
+
*/
|
|
108
|
+
export function searchIndexKey(entry) {
|
|
109
|
+
if (typeof entry === 'string') {
|
|
110
|
+
return entry;
|
|
111
|
+
}
|
|
112
|
+
const { uri, baseUri, ixFilePath } = entry;
|
|
113
|
+
return ixFilePath?.uri !== undefined
|
|
114
|
+
? resolved(ixFilePath.uri, ixFilePath.baseUri)
|
|
115
|
+
: (ixFilePath?.localPath ??
|
|
116
|
+
(uri !== undefined ? resolved(uri, baseUri) : entry));
|
|
117
|
+
}
|
|
118
|
+
function resolved(uri, baseUri) {
|
|
119
|
+
try {
|
|
120
|
+
return baseUri ? new URL(uri, baseUri).href : uri;
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return uri;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { IStateTreeNode } from '@jbrowse/mobx-state-tree';
|
|
2
|
+
export interface EmbeddedRoot extends IStateTreeNode {
|
|
3
|
+
session?: unknown;
|
|
4
|
+
rpcManager: {
|
|
5
|
+
destroy: () => void;
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Tear down an engine built by an embedded product's `createViewState`:
|
|
10
|
+
* terminate its RPC worker threads and destroy the MST tree so its
|
|
11
|
+
* `addDisposer`'d autoruns stop.
|
|
12
|
+
*
|
|
13
|
+
* Unmounting the React tree is not enough — the engine is not owned by React.
|
|
14
|
+
* A host that builds and discards engines (a Jupyter cell re-run, an SPA route
|
|
15
|
+
* change, a controller's `destroy()`) otherwise orphans a whole worker pool and
|
|
16
|
+
* a live autorun set per discarded engine. A component that owns one engine for
|
|
17
|
+
* the lifetime of the page never needs this.
|
|
18
|
+
*
|
|
19
|
+
* Idempotent: destroying an already-destroyed engine is a no-op.
|
|
20
|
+
*/
|
|
21
|
+
export declare function destroyViewState(viewState: EmbeddedRoot): void;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { destroy, isAlive } from '@jbrowse/mobx-state-tree';
|
|
2
|
+
/**
|
|
3
|
+
* Tear down an engine built by an embedded product's `createViewState`:
|
|
4
|
+
* terminate its RPC worker threads and destroy the MST tree so its
|
|
5
|
+
* `addDisposer`'d autoruns stop.
|
|
6
|
+
*
|
|
7
|
+
* Unmounting the React tree is not enough — the engine is not owned by React.
|
|
8
|
+
* A host that builds and discards engines (a Jupyter cell re-run, an SPA route
|
|
9
|
+
* change, a controller's `destroy()`) otherwise orphans a whole worker pool and
|
|
10
|
+
* a live autorun set per discarded engine. A component that owns one engine for
|
|
11
|
+
* the lifetime of the page never needs this.
|
|
12
|
+
*
|
|
13
|
+
* Idempotent: destroying an already-destroyed engine is a no-op.
|
|
14
|
+
*/
|
|
15
|
+
export function destroyViewState(viewState) {
|
|
16
|
+
if (isAlive(viewState)) {
|
|
17
|
+
// Materialize the session before killing the tree. MST snapshots each dying
|
|
18
|
+
// node on the way down, and snapshotting a node that was never observed
|
|
19
|
+
// instantiates it right then — running its afterAttach during death
|
|
20
|
+
// finalization, where creating a further observable (the config it reads)
|
|
21
|
+
// throws "the creation of the observable instance must be done on the
|
|
22
|
+
// initializing phase". Reachable whenever an engine is destroyed before it
|
|
23
|
+
// ever rendered, which is exactly what React StrictMode does to the
|
|
24
|
+
// build-in-a-ref-callback pattern: mount, clean up, mount again.
|
|
25
|
+
void viewState.session;
|
|
26
|
+
viewState.rpcManager.destroy();
|
|
27
|
+
destroy(viewState);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { ControllerSession, TrackConf, TrackInput } from './controllerTracks.ts';
|
|
2
|
+
import type { EmbeddedRoot } from './destroyViewState.ts';
|
|
3
|
+
import type { LocalFileInput } from './localFiles.ts';
|
|
4
|
+
import type { ObservedSession, SessionObservers } from './observeSession.ts';
|
|
5
|
+
import type { AssemblyInput, ResolvedAssembly } from './resolveAssemblies.ts';
|
|
6
|
+
import type { ComponentType } from 'react';
|
|
7
|
+
/** The fields every embedded controller's `update` takes. */
|
|
8
|
+
export interface ControllerState {
|
|
9
|
+
tracks?: TrackInput[];
|
|
10
|
+
localFiles?: LocalFileInput;
|
|
11
|
+
}
|
|
12
|
+
interface ControllerRoot extends EmbeddedRoot {
|
|
13
|
+
session: ControllerSession & ObservedSession & {
|
|
14
|
+
view: {
|
|
15
|
+
setLaunch(launch: {
|
|
16
|
+
assembly: string;
|
|
17
|
+
}): void;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export interface EngineSeed<Launch> {
|
|
22
|
+
resolved: ResolvedAssembly;
|
|
23
|
+
/** the hub's catalog and the host's full configs, the host's winning an id */
|
|
24
|
+
tracks: TrackConf[];
|
|
25
|
+
/** the view to open, absent when a restored session positions it */
|
|
26
|
+
view: Launch | undefined;
|
|
27
|
+
}
|
|
28
|
+
export interface EmbeddedControllerSpec<VM, State, Launch> {
|
|
29
|
+
assembly: AssemblyInput;
|
|
30
|
+
/** a restored session, which owns the initial layout */
|
|
31
|
+
session?: unknown;
|
|
32
|
+
state: NoInfer<State>;
|
|
33
|
+
observers: SessionObservers;
|
|
34
|
+
onError?: (error: unknown) => void;
|
|
35
|
+
Component: ComponentType<{
|
|
36
|
+
viewState: VM;
|
|
37
|
+
}>;
|
|
38
|
+
build: (seed: EngineSeed<Launch>) => Promise<VM>;
|
|
39
|
+
/**
|
|
40
|
+
* The view launch `stated` asks for, read off `wanted` and less its
|
|
41
|
+
* assembly, or undefined when `stated` names nothing a launch carries. The
|
|
42
|
+
* build asks with the initial state as both.
|
|
43
|
+
*/
|
|
44
|
+
launchFor: (stated: State, wanted: State) => Launch | undefined;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The lifecycle behind each embedded product's imperative controller: resolve
|
|
48
|
+
* the genome, build the engine, open the wanted tracks, mount, then reconcile
|
|
49
|
+
* each `update` and tear everything down on `destroy`. The product supplies
|
|
50
|
+
* the engine and the view launch its own state fields ask for.
|
|
51
|
+
*/
|
|
52
|
+
export declare function createEmbeddedController<VM extends ControllerRoot, State extends ControllerState, Launch extends object>(el: HTMLElement, spec: EmbeddedControllerSpec<VM, State, Launch>): {
|
|
53
|
+
whenReady(): Promise<VM>;
|
|
54
|
+
update(stated: State): Promise<void>;
|
|
55
|
+
destroy(): void;
|
|
56
|
+
};
|
|
57
|
+
export {};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { createElement } from 'react';
|
|
2
|
+
import { createRoot } from 'react-dom/client';
|
|
3
|
+
import { isLooseTrack, reconcileTracks, resolveTracks, withAssemblyName, withHostOverrides, } from './controllerTracks.js';
|
|
4
|
+
import { destroyViewState } from './destroyViewState.js';
|
|
5
|
+
import { mergeLocalFiles, registerLocalFiles, resolveLocalFileUris, } from './localFiles.js';
|
|
6
|
+
import { observeSession } from './observeSession.js';
|
|
7
|
+
import { resolveAssembly } from './resolveAssemblies.js';
|
|
8
|
+
function restate(wanted, stated) {
|
|
9
|
+
const next = { ...wanted };
|
|
10
|
+
for (const key of Object.keys(stated)) {
|
|
11
|
+
if (stated[key] !== undefined) {
|
|
12
|
+
next[key] = stated[key];
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return next;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The lifecycle behind each embedded product's imperative controller: resolve
|
|
19
|
+
* the genome, build the engine, open the wanted tracks, mount, then reconcile
|
|
20
|
+
* each `update` and tear everything down on `destroy`. The product supplies
|
|
21
|
+
* the engine and the view launch its own state fields ask for.
|
|
22
|
+
*/
|
|
23
|
+
export function createEmbeddedController(el, spec) {
|
|
24
|
+
const { Component, launchFor, onError = (e) => {
|
|
25
|
+
console.error(e);
|
|
26
|
+
}, } = spec;
|
|
27
|
+
const hasSession = spec.session !== undefined;
|
|
28
|
+
let wanted = spec.state;
|
|
29
|
+
let localFiles = registerLocalFiles(wanted.localFiles ?? {});
|
|
30
|
+
let assemblyName;
|
|
31
|
+
let current;
|
|
32
|
+
let stopObserving;
|
|
33
|
+
let destroyed = false;
|
|
34
|
+
const root = createRoot(el);
|
|
35
|
+
function wantedTracks(viewState) {
|
|
36
|
+
return resolveTracks(wanted.tracks ?? [], viewState.session, assemblyName, localFiles);
|
|
37
|
+
}
|
|
38
|
+
async function build() {
|
|
39
|
+
const resolved = await resolveAssembly(spec.assembly);
|
|
40
|
+
const { name } = resolved.assembly;
|
|
41
|
+
assemblyName = typeof name === 'string' ? name : undefined;
|
|
42
|
+
const viewState = await spec.build({
|
|
43
|
+
resolved,
|
|
44
|
+
tracks: withHostOverrides(resolved.tracks, (wanted.tracks ?? [])
|
|
45
|
+
.filter((track) => !isLooseTrack(track))
|
|
46
|
+
.map(track => resolveLocalFileUris(withAssemblyName(track, assemblyName), localFiles)), 'trackId'),
|
|
47
|
+
view: hasSession ? undefined : launchFor(wanted, wanted),
|
|
48
|
+
});
|
|
49
|
+
if (!hasSession) {
|
|
50
|
+
await reconcileTracks(viewState.session, wantedTracks(viewState));
|
|
51
|
+
}
|
|
52
|
+
// destroy() can land during any await above, before there was an engine
|
|
53
|
+
// for it to tear down
|
|
54
|
+
if (destroyed) {
|
|
55
|
+
destroyViewState(viewState);
|
|
56
|
+
return viewState;
|
|
57
|
+
}
|
|
58
|
+
current = viewState;
|
|
59
|
+
stopObserving = observeSession(viewState, spec.observers);
|
|
60
|
+
root.render(createElement(Component, { viewState }));
|
|
61
|
+
return viewState;
|
|
62
|
+
}
|
|
63
|
+
const ready = build();
|
|
64
|
+
ready.catch(onError);
|
|
65
|
+
async function apply(stated) {
|
|
66
|
+
const viewState = current;
|
|
67
|
+
if (!viewState) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (stated.tracks) {
|
|
71
|
+
await reconcileTracks(viewState.session, wantedTracks(viewState));
|
|
72
|
+
}
|
|
73
|
+
const launch = launchFor(stated, wanted);
|
|
74
|
+
if (launch && assemblyName && !destroyed) {
|
|
75
|
+
viewState.session.view.setLaunch({ ...launch, assembly: assemblyName });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
whenReady() {
|
|
80
|
+
return ready;
|
|
81
|
+
},
|
|
82
|
+
async update(stated) {
|
|
83
|
+
if (stated.localFiles) {
|
|
84
|
+
localFiles = mergeLocalFiles(localFiles, stated.localFiles);
|
|
85
|
+
}
|
|
86
|
+
wanted = restate(wanted, stated);
|
|
87
|
+
await ready;
|
|
88
|
+
await apply(stated);
|
|
89
|
+
},
|
|
90
|
+
destroy() {
|
|
91
|
+
destroyed = true;
|
|
92
|
+
stopObserving?.();
|
|
93
|
+
root.unmount();
|
|
94
|
+
if (current) {
|
|
95
|
+
destroyViewState(current);
|
|
96
|
+
}
|
|
97
|
+
current = undefined;
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
package/esm/index.d.ts
CHANGED
|
@@ -1,4 +1,32 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
1
|
+
export type { AssertExtends, AssertNotAny } from './assertExtends.ts';
|
|
2
|
+
export { asRoot, asSession } from './siblingCast.ts';
|
|
3
|
+
export { scheduleDetachedDestroy } from '@jbrowse/core/util';
|
|
4
|
+
export { BaseRootModelFactory, FormatAboutConfigSchemaFactory, FormatDetailsConfigSchemaFactory, HierarchicalConfigSchemaFactory, InternetAccountsRootModelMixin, PreferencesConfigSchemaFactory, createConfigModel, exportSessionMenuItem, importSessionMenuItem, isRootModel, newSessionMenuItem, openConnectionMenuItem, openTrackMenuItem, pluginStoreMenuItem, preferencesMenuItem, redoMenuItem, undoMenuItem, workspacesMenuItem, } from './RootModel/index.ts';
|
|
5
|
+
export type { BaseRootModel, BaseRootModelType, RootConfigurationSnapshot, RootModelWithInternetAccounts, RootModelWithInternetAccountsType, } from './RootModel/index.ts';
|
|
6
|
+
export { BaseSessionModel, ConnectionManagementSessionMixin, DrawerWidgetSessionMixin, MultipleViewsSessionMixin, PreferencesSessionMixin, ReferenceManagementSessionMixin, SessionTracksManagerSessionMixin, ThemeManagerSessionMixin, TrackMenuItemsSessionMixin, TrackMenuSessionMixin, TracksManagerSessionMixin, aboutTrackMenuItem, bakeSessionCascades, getShareableSessionSnapshot, copyTrackSnapshot, finalizeSession, hydratedForms, isBaseSession, isSession, isSessionWithConnections, isSessionWithDrawerWidgets, isSessionWithMultipleViews, isSessionWithReferenceManagement, isSessionWithThemes, isSessionWithTracks, pluginExtraTrackItems, storedThemeArgs, trackActionItems, trackActionMenuItems, trackListMenuItems, } from './Session/index.ts';
|
|
7
|
+
export type { AssertSessionModel, BaseSession, BaseSessionType, ConnectionTrackConfigEntry, EditableTrackConfig, HydratedForms, PlainTrackConfig, ReferringNode, SessionWithConnections, SessionWithConnectionsType, SessionWithDrawerWidgets, SessionWithDrawerWidgetsType, SessionWithMultipleViews, SessionWithMultipleViewsType, SessionWithReferenceManagement, SessionWithReferenceManagementType, SessionWithSessionTracks, SessionWithSessionTracksType, SessionWithThemes, SessionWithThemesType, SessionWithTracks, SessionWithTracksType, ThemeModeSelection, } from './Session/index.ts';
|
|
8
|
+
export { AboutDialog, AppReadyMarker, Drawer, DrawerControls, DrawerHeader, DrawerWidget, DrawerWidgetSelector, ModalWidget, ModalWidgetAppBar, PreferencesDialog, WidgetBody, WidgetHeading, drawerGridTemplateColumns, } from './ui/index.ts';
|
|
9
|
+
export type { AboutPanelProps, PreferencesDialogSession, PreferencesPanelDescriptor, } from './ui/index.ts';
|
|
10
|
+
export { initializeWorker } from './rpcWorker.ts';
|
|
11
|
+
export { toPluginLoadRecord } from './pluginInput.ts';
|
|
12
|
+
export type { PluginInput } from './pluginInput.ts';
|
|
13
|
+
export { loadRuntimePlugins } from './loadPlugins.ts';
|
|
14
|
+
export type { LoadPluginsArgs } from './loadPlugins.ts';
|
|
15
|
+
export { decodeSessionFromUrl, encodeSessionToUrl } from './sessionUrl.ts';
|
|
16
|
+
export type { SessionSnapshot } from './sessionUrl.ts';
|
|
17
|
+
export { normalizeAdapterSnapshots, registerLocalFiles, resolveLocalFileUris, } from './localFiles.ts';
|
|
18
|
+
export type { LocalFileInput } from './localFiles.ts';
|
|
19
|
+
export { searchIndexKey, withHostOverrides } from './controllerTracks.ts';
|
|
20
|
+
export type { TrackInput } from './controllerTracks.ts';
|
|
21
|
+
export { createEmbeddedController } from './embeddedController.ts';
|
|
22
|
+
export { resolveAssemblies, resolveAssembly } from './resolveAssemblies.ts';
|
|
23
|
+
export type { AssemblyInput, ResolvedAssemblies } from './resolveAssemblies.ts';
|
|
24
|
+
export { destroyViewState } from './destroyViewState.ts';
|
|
25
|
+
export { useAsyncEngineLifecycle, useCreateOnce, useCreateOnceAsync, useDestroyOnUnmount, } from './useEngineLifecycle.ts';
|
|
26
|
+
export { getSessionSnapshot, observeSession } from './observeSession.ts';
|
|
27
|
+
export type { SessionObservers, ViewLocation } from './observeSession.ts';
|
|
28
|
+
export { migrateSessionSnapshot, migratedDisplayInstanceKeys, } from './sessionMigrations/index.ts';
|
|
29
|
+
export { DEFAULT_WEB_BASE_URL, analyzeWebPortability, buildWebExportUrl, filterSessionInPlace, planWebExport, } from './sessionUtils.ts';
|
|
30
|
+
export type { AssemblySnapshot, DroppedSessionNode, HostedBase, HostedBaseConfig, NonPortableLocation, SelfContainedReason, TrackSnapshot, WebExportInput, WebExportPlan, WebPortabilityReport, } from './sessionUtils.ts';
|
|
31
|
+
export { describeUnbuildableNodes, pruneUnbuildableNodes, } from './pruneUnbuildableNodes.ts';
|
|
32
|
+
export type { HeldNode, UnbuildableNode } from './pruneUnbuildableNodes.ts';
|